Bug 1056032 - Make sure COM is initialized when trying to decode an mp3 using decodeAudioData. r=cpearce, a=lmandel
authorPaul Adenot <paul@paul.cx>
Wed, 20 Aug 2014 17:23:22 -0400
changeset 208366 f17ade17a846
parent 208365 ac551f43e2b4
child 208367 53d300e03f5b
push id3843
push userryanvm@gmail.com
push date2014-08-21 19:12 +0000
treeherdermozilla-beta@53d300e03f5b [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerscpearce, lmandel
bugs1056032
milestone32.0
Bug 1056032 - Make sure COM is initialized when trying to decode an mp3 using decodeAudioData. r=cpearce, a=lmandel
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,48 +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 {
-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
@@ -90,16 +90,17 @@ EXPORTS += [
     'MediaSegment.h',
     'MediaStreamGraph.h',
     'MediaTaskQueue.h',
     'MP3FrameParser.h',
     'RtspMediaResource.h',
     'SharedBuffer.h',
     'SharedThreadPool.h',
     'StreamBuffer.h',
+    'ThreadPoolCOMListener.h',
     'TimeVarying.h',
     'TrackUnionStream.h',
     'VideoFrameContainer.h',
     'VideoSegment.h',
     'VideoUtils.h',
     'VorbisUtils.h',
 ]
 
@@ -151,16 +152,19 @@ UNIFIED_SOURCES += [
     'VideoFrameContainer.cpp',
     'VideoPlaybackQuality.cpp',
     'VideoSegment.cpp',
     'VideoStreamTrack.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
@@ -15,16 +15,19 @@
 #include "BufferMediaResource.h"
 #include "DecoderTraits.h"
 #include "AudioContext.h"
 #include "AudioBuffer.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)
@@ -469,16 +472,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