Bug 1271491: [WMF] P2. Allow creation of DXVA manager on any thread. r?cpearce
MozReview-Commit-ID: 8sbA3x0Pge5
--- a/dom/media/platforms/wmf/DXVA2Manager.cpp
+++ b/dom/media/platforms/wmf/DXVA2Manager.cpp
@@ -7,16 +7,17 @@
#include "DXVA2Manager.h"
#include <d3d11.h>
#include "nsThreadUtils.h"
#include "ImageContainer.h"
#include "gfxWindowsPlatform.h"
#include "D3D9SurfaceImage.h"
#include "mozilla/layers/D3D11ShareHandleImage.h"
#include "mozilla/layers/ImageBridgeChild.h"
+#include "mozilla/StaticMutex.h"
#include "mozilla/Telemetry.h"
#include "MediaTelemetryConstants.h"
#include "mfapi.h"
#include "MediaPrefs.h"
#include "MFTDecoder.h"
#include "DriverCrashGuard.h"
#include "nsPrintfCString.h"
@@ -231,37 +232,33 @@ D3D9DXVA2Manager::SupportsConfig(IMFMedi
}
D3D9DXVA2Manager::D3D9DXVA2Manager()
: mResetToken(0)
, mFirstFrame(true)
, mIsAMDPreUVD4(false)
{
MOZ_COUNT_CTOR(D3D9DXVA2Manager);
- MOZ_ASSERT(NS_IsMainThread());
}
D3D9DXVA2Manager::~D3D9DXVA2Manager()
{
MOZ_COUNT_DTOR(D3D9DXVA2Manager);
- MOZ_ASSERT(NS_IsMainThread());
}
IUnknown*
D3D9DXVA2Manager::GetDXVADeviceManager()
{
MutexAutoLock lock(mLock);
return mDeviceManager;
}
HRESULT
D3D9DXVA2Manager::Init(nsACString& aFailureReason)
{
- MOZ_ASSERT(NS_IsMainThread());
-
gfx::D3D9VideoCrashGuard crashGuard;
if (crashGuard.Crashed()) {
NS_WARNING("DXVA2D3D9 crash detected");
aFailureReason.AssignLiteral("DXVA2D3D9 crashes detected in the past");
return E_FAIL;
}
// Create D3D9Ex.
@@ -458,38 +455,39 @@ D3D9DXVA2Manager::CopyToImage(IMFSample*
hr = mSyncSurface->UnlockRect();
NS_ENSURE_TRUE(SUCCEEDED(hr), hr);
image.forget(aOutImage);
return S_OK;
}
// Count of the number of DXVAManager's we've created. This is also the
-// number of videos we're decoding with DXVA. Use on main thread only.
+// number of videos we're decoding with DXVA.
+static StaticMutex sMutex;
static uint32_t sDXVAVideosCount = 0;
/* static */
DXVA2Manager*
DXVA2Manager::CreateD3D9DXVA(nsACString& aFailureReason)
{
- MOZ_ASSERT(NS_IsMainThread());
- HRESULT hr;
-
+ nsAutoPtr<D3D9DXVA2Manager> d3d9Manager;
// DXVA processing takes up a lot of GPU resources, so limit the number of
// videos we use DXVA with at any one time.
const uint32_t dxvaLimit = MediaPrefs::PDMWMFMaxDXVAVideos();
- if (sDXVAVideosCount == dxvaLimit) {
- aFailureReason.AssignLiteral("Too many DXVA videos playing");
- return nullptr;
- }
-
- nsAutoPtr<D3D9DXVA2Manager> d3d9Manager(new D3D9DXVA2Manager());
- hr = d3d9Manager->Init(aFailureReason);
- if (SUCCEEDED(hr)) {
- return d3d9Manager.forget();
+ {
+ StaticMutexAutoLock mon(sMutex);
+ if (sDXVAVideosCount == dxvaLimit) {
+ aFailureReason.AssignLiteral("Too many DXVA videos playing");
+ return nullptr;
+ }
+ d3d9Manager = new D3D9DXVA2Manager();
+ HRESULT hr = d3d9Manager->Init(aFailureReason);
+ if (SUCCEEDED(hr)) {
+ return d3d9Manager.forget();
+ }
}
// No hardware accelerated video decoding. :(
return nullptr;
}
class D3D11DXVA2Manager : public DXVA2Manager
{
@@ -865,37 +863,41 @@ D3D11DXVA2Manager::ConfigureForSize(uint
return S_OK;
}
/* static */
DXVA2Manager*
DXVA2Manager::CreateD3D11DXVA(nsACString& aFailureReason)
{
+ nsAutoPtr<D3D11DXVA2Manager> manager;
// DXVA processing takes up a lot of GPU resources, so limit the number of
// videos we use DXVA with at any one time.
const uint32_t dxvaLimit = MediaPrefs::PDMWMFMaxDXVAVideos();
- if (sDXVAVideosCount == dxvaLimit) {
- aFailureReason.AssignLiteral("Too many DXVA videos playing");
- return nullptr;
+ {
+ StaticMutexAutoLock mon(sMutex);
+ if (sDXVAVideosCount == dxvaLimit) {
+ aFailureReason.AssignLiteral("Too many DXVA videos playing");
+ return nullptr;
+ }
+ manager = new D3D11DXVA2Manager();
+ HRESULT hr = manager->Init(aFailureReason);
+ if (SUCCEEDED(hr)) {
+ return manager.forget();
+ }
}
-
- nsAutoPtr<D3D11DXVA2Manager> manager(new D3D11DXVA2Manager());
- HRESULT hr = manager->Init(aFailureReason);
- NS_ENSURE_TRUE(SUCCEEDED(hr), nullptr);
-
- return manager.forget();
+ return nullptr;
}
DXVA2Manager::DXVA2Manager()
: mLock("DXVA2Manager")
{
- MOZ_ASSERT(NS_IsMainThread());
+ sMutex.AssertCurrentThreadOwns();
++sDXVAVideosCount;
}
DXVA2Manager::~DXVA2Manager()
{
- MOZ_ASSERT(NS_IsMainThread());
+ StaticMutexAutoLock mon(sMutex);
--sDXVAVideosCount;
}
} // namespace mozilla
--- a/dom/media/platforms/wmf/WMFVideoMFTManager.cpp
+++ b/dom/media/platforms/wmf/WMFVideoMFTManager.cpp
@@ -101,20 +101,16 @@ WMFVideoMFTManager::WMFVideoMFTManager(
} else {
mStreamType = Unknown;
}
}
WMFVideoMFTManager::~WMFVideoMFTManager()
{
MOZ_COUNT_DTOR(WMFVideoMFTManager);
- // Ensure DXVA/D3D9 related objects are released on the main thread.
- if (mDXVA2Manager) {
- DeleteOnMainThread(mDXVA2Manager);
- }
// Record whether the video decoder successfully decoded, or output null
// samples but did/didn't recover.
uint32_t telemetry = (mNullOutputCount == 0) ? 0 :
(mGotValidOutputAfterNullOutput && mGotExcessiveNullOutput) ? 1 :
mGotExcessiveNullOutput ? 2 :
mGotValidOutputAfterNullOutput ? 3 :
4;
@@ -660,17 +656,17 @@ WMFVideoMFTManager::Output(int64_t aStre
return S_OK;
}
void
WMFVideoMFTManager::Shutdown()
{
mDecoder = nullptr;
- DeleteOnMainThread(mDXVA2Manager);
+ mDXVA2Manager = nullptr;
}
bool
WMFVideoMFTManager::IsHardwareAccelerated(nsACString& aFailureReason) const
{
aFailureReason = mDXVAFailureReason;
return mDecoder && mUseHwAccel;
}