Bug 1056032 - Make sure COM is initialized when trying to decode an mp3 using decodeAudioData. r=cpearce
authorPaul Adenot <paul@paul.cx>
Wed, 20 Aug 2014 17:23:22 -0400
changeset 200886 2423b6217200526c227496ac8a2c4cf5f8625c3b
parent 200885 b7529dcda6eb9675b0e207e0130efa77ecda4b47
child 200887 232e907a893fd0f93824407ea88d12138b5ff8cd
push id27358
push userkwierso@gmail.com
push dateFri, 22 Aug 2014 01:22:28 +0000
treeherdermozilla-central@cd2acc7ab2f8 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerscpearce
bugs1056032
milestone34.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1056032 - Make sure COM is initialized when trying to decode an mp3 using decodeAudioData. r=cpearce
content/media/SharedThreadPool.cpp
content/media/ThreadPoolCOMListener.cpp
content/media/ThreadPoolCOMListener.h
content/media/moz.build
content/media/webaudio/MediaBufferDecoder.cpp
--- a/content/media/SharedThreadPool.cpp
+++ b/content/media/SharedThreadPool.cpp
@@ -6,20 +6,18 @@
 
 #include "SharedThreadPool.h"
 #include "mozilla/Monitor.h"
 #include "mozilla/StaticPtr.h"
 #include "nsDataHashtable.h"
 #include "VideoUtils.h"
 #include "nsXPCOMCIDInternal.h"
 #include "nsComponentManagerUtils.h"
-
 #ifdef XP_WIN
-// Required to init MSCOM by MSCOMInitThreadPoolListener.
-#include <objbase.h>
+#include "ThreadPoolCOMListener.h"
 #endif
 
 namespace mozilla {
 
 // Created and destroyed on the main thread.
 static StaticAutoPtr<ReentrantMonitor> sMonitor;
 
 // Hashtable, maps thread pool name to SharedThreadPool instance.
@@ -182,50 +180,16 @@ SharedThreadPool::SharedThreadPool(const
   mEventTarget = do_QueryInterface(aPool);
 }
 
 SharedThreadPool::~SharedThreadPool()
 {
   MOZ_COUNT_DTOR(SharedThreadPool);
 }
 
-#ifdef XP_WIN
-
-// Thread pool listener which ensures that MSCOM is initialized and
-// deinitialized on the thread pool thread. We may call into WMF or
-// DirectShow on this thread, so we need MSCOM working.
-class MSCOMInitThreadPoolListener MOZ_FINAL : public nsIThreadPoolListener {
-  ~MSCOMInitThreadPoolListener() {}
-
-public:
-  NS_DECL_THREADSAFE_ISUPPORTS
-  NS_DECL_NSITHREADPOOLLISTENER
-};
-
-NS_IMPL_ISUPPORTS(MSCOMInitThreadPoolListener, nsIThreadPoolListener)
-
-NS_IMETHODIMP
-MSCOMInitThreadPoolListener::OnThreadCreated()
-{
-  HRESULT hr = CoInitializeEx(0, COINIT_MULTITHREADED);
-  if (FAILED(hr)) {
-    NS_WARNING("Failed to initialize MSCOM on WMFByteStream thread.");
-  }
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-MSCOMInitThreadPoolListener::OnThreadShuttingDown()
-{
-  CoUninitialize();
-  return NS_OK;
-}
-
-#endif // XP_WIN
-
 nsresult
 SharedThreadPool::EnsureThreadLimitIsAtLeast(uint32_t aLimit)
 {
   // We limit the number of threads that we use for media. Note that we
   // set the thread limit to the same as the idle limit so that we're not
   // constantly creating and destroying threads (see Bug 881954). When the
   // thread pool threads shutdown they dispatch an event to the main thread
   // to call nsIThread::Shutdown(), and if we're very busy that can take a
new file mode 100644
--- /dev/null
+++ b/content/media/ThreadPoolCOMListener.cpp
@@ -0,0 +1,30 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim:set ts=2 sw=2 sts=2 et cindent: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "ThreadPoolCOMListener.h"
+
+namespace mozilla {
+
+NS_IMPL_ISUPPORTS(MSCOMInitThreadPoolListener, nsIThreadPoolListener)
+
+NS_IMETHODIMP
+MSCOMInitThreadPoolListener::OnThreadCreated()
+{
+  HRESULT hr = CoInitializeEx(0, COINIT_MULTITHREADED);
+  if (FAILED(hr)) {
+    NS_WARNING("Failed to initialize MSCOM on decoder thread.");
+  }
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+MSCOMInitThreadPoolListener::OnThreadShuttingDown()
+{
+  CoUninitialize();
+  return NS_OK;
+}
+
+}
new file mode 100644
--- /dev/null
+++ b/content/media/ThreadPoolCOMListener.h
@@ -0,0 +1,28 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim:set ts=2 sw=2 sts=2 et cindent: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef MSCOMInitThreadPoolListener_h_
+#define MSCOMInitThreadPoolListener_h_
+
+#include "nsIThreadPool.h"
+#include <objbase.h>
+
+namespace mozilla {
+
+// Thread pool listener which ensures that MSCOM is initialized and
+// deinitialized on the thread pool thread. We may call into WMF or
+// DirectShow on this thread, so we need MSCOM working.
+class MSCOMInitThreadPoolListener MOZ_FINAL : public nsIThreadPoolListener {
+  ~MSCOMInitThreadPoolListener() {}
+  public:
+  NS_DECL_THREADSAFE_ISUPPORTS
+  NS_DECL_NSITHREADPOOLLISTENER
+};
+
+} // namespace mozilla
+
+
+#endif // MSCOMInitThreadPoolListener_h_
--- a/content/media/moz.build
+++ b/content/media/moz.build
@@ -95,16 +95,17 @@ EXPORTS += [
     'MediaTrack.h',
     'MediaTrackList.h',
     'MP3FrameParser.h',
     'nsIDocumentActivity.h',
     'RtspMediaResource.h',
     'SharedBuffer.h',
     'SharedThreadPool.h',
     'StreamBuffer.h',
+    'ThreadPoolCOMListener.h',
     'TimeVarying.h',
     'TrackUnionStream.h',
     'VideoFrameContainer.h',
     'VideoSegment.h',
     'VideoUtils.h',
     'VorbisUtils.h',
 ]
 
@@ -165,16 +166,19 @@ UNIFIED_SOURCES += [
     'VideoSegment.cpp',
     'VideoStreamTrack.cpp',
     'VideoTrack.cpp',
     'VideoTrackList.cpp',
     'VideoUtils.cpp',
     'WebVTTListener.cpp',
 ]
 
+if CONFIG['OS_TARGET'] == 'WINNT':
+  SOURCES += [ 'ThreadPoolCOMListener.cpp' ]
+
 # DecoderTraits.cpp needs to be built separately because of Mac OS X headers.
 # Latency.cpp needs to be built separately because it forces NSPR logging.
 SOURCES += [
     'DecoderTraits.cpp',
     'Latency.cpp',
 ]
 
 FAIL_ON_WARNINGS = True
--- a/content/media/webaudio/MediaBufferDecoder.cpp
+++ b/content/media/webaudio/MediaBufferDecoder.cpp
@@ -16,16 +16,19 @@
 #include "DecoderTraits.h"
 #include "AudioContext.h"
 #include "AudioBuffer.h"
 #include "nsAutoPtr.h"
 #include "nsIScriptObjectPrincipal.h"
 #include "nsIScriptError.h"
 #include "nsMimeTypes.h"
 #include "WebAudioUtils.h"
+#ifdef XP_WIN
+#include "ThreadPoolCOMListener.h"
+#endif
 
 namespace mozilla {
 
 NS_IMPL_CYCLE_COLLECTION_CLASS(WebAudioDecodeJob)
 
 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(WebAudioDecodeJob)
   NS_IMPL_CYCLE_COLLECTION_UNLINK(mContext)
   NS_IMPL_CYCLE_COLLECTION_UNLINK(mOutput)
@@ -481,16 +484,22 @@ bool
 MediaBufferDecoder::EnsureThreadPoolInitialized()
 {
   if (!mThreadPool) {
     mThreadPool = do_CreateInstance(NS_THREADPOOL_CONTRACTID);
     if (!mThreadPool) {
       return false;
     }
     mThreadPool->SetName(NS_LITERAL_CSTRING("MediaBufferDecoder"));
+#ifdef XP_WIN
+  // Ensure MSCOM is initialized on the thread pools threads.
+  nsCOMPtr<nsIThreadPoolListener> listener = new MSCOMInitThreadPoolListener();
+  nsresult rv = mThreadPool->SetListener(listener);
+  NS_ENSURE_SUCCESS(rv, nullptr);
+#endif
   }
   return true;
 }
 
 void
 MediaBufferDecoder::Shutdown() {
   if (mThreadPool) {
     // Setting threadLimit to 0 causes threads to exit when all events have