Bug 1056032 - Make sure COM is initialized when trying to decode an mp3 using decodeAudioData. r=cpearce

This commit is contained in:
Paul Adenot 2014-08-20 17:23:22 -04:00
parent b85813c411
commit 042a35b651
5 changed files with 72 additions and 37 deletions

View File

@ -11,10 +11,8 @@
#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 {
@ -187,40 +185,6 @@ 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)
{

View File

@ -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;
}
}

View File

@ -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_

View File

@ -100,6 +100,7 @@ EXPORTS += [
'SharedBuffer.h',
'SharedThreadPool.h',
'StreamBuffer.h',
'ThreadPoolCOMListener.h',
'TimeVarying.h',
'TrackUnionStream.h',
'VideoFrameContainer.h',
@ -170,6 +171,9 @@ UNIFIED_SOURCES += [
'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 += [

View File

@ -21,6 +21,9 @@
#include "nsIScriptError.h"
#include "nsMimeTypes.h"
#include "WebAudioUtils.h"
#ifdef XP_WIN
#include "ThreadPoolCOMListener.h"
#endif
namespace mozilla {
@ -486,6 +489,12 @@ MediaBufferDecoder::EnsureThreadPoolInitialized()
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;
}