Bug 881954 - Only initialize DXVA when we're decoding video. r=padenot
authorChris Pearce <cpearce@mozilla.com>
Fri, 14 Jun 2013 09:07:28 +1200
changeset 146483 dc08e8496fc6c00f47307ebf8ca38cc95011053b
parent 146482 a40c0f052f758aed0a6e8592cc953b716469a674
child 146484 3d4a1926278d0f03a412cfc92592f3df626cbfca
push id2697
push userbbajaj@mozilla.com
push dateMon, 05 Aug 2013 18:49:53 +0000
treeherdermozilla-beta@dfec938c7b63 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerspadenot
bugs881954
milestone24.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 881954 - Only initialize DXVA when we're decoding video. r=padenot
content/media/wmf/DXVA2Manager.cpp
content/media/wmf/WMFReader.cpp
--- a/content/media/wmf/DXVA2Manager.cpp
+++ b/content/media/wmf/DXVA2Manager.cpp
@@ -163,37 +163,51 @@ D3D9DXVA2Manager::CopyToImage(IMFSample*
   D3D9SurfaceImage* videoImage = static_cast<D3D9SurfaceImage*>(image.get());
   hr = videoImage->SetData(D3D9SurfaceImage::Data(surface, aRegion));
 
   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.
+static uint32_t sDXVAVideosCount = 0;
+
 /* static */
 DXVA2Manager*
 DXVA2Manager::Create()
 {
   MOZ_ASSERT(NS_IsMainThread());
   HRESULT hr;
 
+  // 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 =
+    Preferences::GetInt("media.windows-media-foundation.max-dxva-videos", 8);
+  if (sDXVAVideosCount == dxvaLimit) {
+    return nullptr;
+  }
+
   nsAutoPtr<D3D9DXVA2Manager> d3d9Manager(new D3D9DXVA2Manager());
   hr = d3d9Manager->Init();
   if (SUCCEEDED(hr)) {
     return d3d9Manager.forget();
   }
 
   // No hardware accelerated video decoding. :(
   return nullptr;
 }
 
 DXVA2Manager::DXVA2Manager()
   : mLock("DXVA2Manager")
 {
   MOZ_ASSERT(NS_IsMainThread());
+  ++sDXVAVideosCount;
 }
 
 DXVA2Manager::~DXVA2Manager()
 {
   MOZ_ASSERT(NS_IsMainThread());
+  --sDXVAVideosCount;
 }
 
 } // namespace mozilla
--- a/content/media/wmf/WMFReader.cpp
+++ b/content/media/wmf/WMFReader.cpp
@@ -115,19 +115,28 @@ WMFReader::InitializeDXVA()
   NS_ENSURE_TRUE(layerManager, false);
 
   if (layerManager->GetBackendType() != LayersBackend::LAYERS_D3D9 &&
       layerManager->GetBackendType() != LayersBackend::LAYERS_D3D10) {
     return false;
   }
 
   mDXVA2Manager = DXVA2Manager::Create();
-  NS_ENSURE_TRUE(mDXVA2Manager, false);
+
+  return mDXVA2Manager != nullptr;
+}
 
-  return true;
+static bool
+IsVideoContentType(const nsCString& aContentType)
+{
+  NS_NAMED_LITERAL_CSTRING(video, "video");
+  if (FindInReadable(video, aContentType)) {
+    return true;
+  }
+  return false;
 }
 
 nsresult
 WMFReader::Init(MediaDecoderReader* aCloneDonor)
 {
   NS_ASSERTION(NS_IsMainThread(), "Must be on main thread.");
 
   nsresult rv = WMFDecoder::LoadDLLs();
@@ -140,17 +149,21 @@ WMFReader::Init(MediaDecoderReader* aClo
 
   mSourceReaderCallback = new WMFSourceReaderCallback();
 
   // Must be created on main thread.
   mByteStream = new WMFByteStream(mDecoder->GetResource(), mSourceReaderCallback);
   rv = mByteStream->Init();
   NS_ENSURE_SUCCESS(rv, rv);
 
-  mUseHwAccel = InitializeDXVA();
+  if (IsVideoContentType(mDecoder->GetResource()->GetContentType())) {
+    mUseHwAccel = InitializeDXVA();
+  } else {
+    mUseHwAccel = false;
+  }
 
   return NS_OK;
 }
 
 bool
 WMFReader::HasAudio()
 {
   NS_ASSERTION(mDecoder->OnDecodeThread(), "Should be on decode thread.");