Bug 1211339 - Ensure WMFDecoderModule::SupportsMimeType checks it can create decoders. r=jya
authorChris Pearce <cpearce@mozilla.com>
Tue, 06 Oct 2015 16:52:52 +1300
changeset 266147 b374a409750b9a1f9cec2270eecb3646fadcf3f1
parent 266146 5d303b961af13344deea83453371cd67934dad01
child 266148 cf49f4d6c83c8a3b05a7f71a37a0c6cb8ef69efa
push id66133
push usercpearce@mozilla.com
push dateTue, 06 Oct 2015 03:53:39 +0000
treeherdermozilla-inbound@dbe8d3254ccd [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjya
bugs1211339
milestone44.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 1211339 - Ensure WMFDecoderModule::SupportsMimeType checks it can create decoders. r=jya
dom/media/platforms/wmf/WMFAudioMFTManager.h
dom/media/platforms/wmf/WMFDecoderModule.cpp
dom/media/platforms/wmf/WMFDecoderModule.h
dom/media/platforms/wmf/WMFVideoMFTManager.cpp
--- a/dom/media/platforms/wmf/WMFAudioMFTManager.h
+++ b/dom/media/platforms/wmf/WMFAudioMFTManager.h
@@ -7,16 +7,19 @@
 #if !defined(WMFAudioOutputSource_h_)
 #define WMFAudioOutputSource_h_
 
 #include "WMF.h"
 #include "MFTDecoder.h"
 #include "mozilla/RefPtr.h"
 #include "WMFMediaDataDecoder.h"
 
+extern const GUID CLSID_WebmMfVp8Dec;
+extern const GUID CLSID_WebmMfVp9Dec;
+
 namespace mozilla {
 
 class WMFAudioMFTManager : public MFTManager {
 public:
   WMFAudioMFTManager(const AudioInfo& aConfig);
   ~WMFAudioMFTManager();
 
   bool Init();
--- a/dom/media/platforms/wmf/WMFDecoderModule.cpp
+++ b/dom/media/platforms/wmf/WMFDecoderModule.cpp
@@ -16,16 +16,17 @@
 #include "nsIWindowsRegKey.h"
 #include "nsComponentManagerUtils.h"
 #include "nsServiceManagerUtils.h"
 #include "nsIGfxInfo.h"
 #include "GfxDriverInfo.h"
 #include "gfxWindowsPlatform.h"
 #include "MediaInfo.h"
 #include "prsystem.h"
+#include "mozilla/Maybe.h"
 
 namespace mozilla {
 
 static bool sDXVAEnabled = false;
 static int  sNumDecoderThreads = -1;
 static bool sIsIntelDecoderEnabled = false;
 
 WMFDecoderModule::WMFDecoderModule()
@@ -118,72 +119,76 @@ WMFDecoderModule::CreateAudioDecoder(con
     return nullptr;
   }
 
   nsRefPtr<MediaDataDecoder> decoder =
     new WMFMediaDataDecoder(manager.forget(), aAudioTaskQueue, aCallback);
   return decoder.forget();
 }
 
+static bool
+CanCreateMFTDecoder(const GUID& aGuid)
+{
+  if (FAILED(wmf::MFStartup())) {
+    return false;
+  }
+  RefPtr<MFTDecoder> decoder(new MFTDecoder());
+  bool hasH264 = SUCCEEDED(decoder->Create(aGuid));
+  wmf::MFShutdown();
+  return hasH264;
+}
+
+template<const GUID& aGuid>
+static bool
+CanCreateWMFDecoder()
+{
+  static Maybe<bool> result;
+  if (result.isNothing()) {
+    result.emplace(CanCreateMFTDecoder(aGuid));
+  }
+  return result.value();
+}
+
 bool
 WMFDecoderModule::SupportsMimeType(const nsACString& aMimeType)
 {
-  return aMimeType.EqualsLiteral("video/mp4") ||
-         aMimeType.EqualsLiteral("video/avc") ||
-         aMimeType.EqualsLiteral("audio/mp4a-latm") ||
-         aMimeType.EqualsLiteral("audio/mpeg") ||
-         (sIsIntelDecoderEnabled &&
-          (aMimeType.EqualsLiteral("video/webm; codecs=vp8") ||
-           aMimeType.EqualsLiteral("video/webm; codecs=vp9")));
+  if ((aMimeType.EqualsLiteral("audio/mp4a-latm") ||
+       aMimeType.EqualsLiteral("audio/mp4")) &&
+      CanCreateWMFDecoder<CLSID_CMSAACDecMFT>()) {
+    return true;
+  }
+  if ((aMimeType.EqualsLiteral("video/avc") ||
+       aMimeType.EqualsLiteral("video/mp4")) &&
+      CanCreateWMFDecoder<CLSID_CMSH264DecoderMFT>()) {
+    return true;
+  }
+  if (aMimeType.EqualsLiteral("audio/mpeg") &&
+      CanCreateWMFDecoder<CLSID_CMP3DecMediaObject>()) {
+    return true;
+  }
+  if (sIsIntelDecoderEnabled) {
+    if (aMimeType.EqualsLiteral("video/webm; codecs=vp8") &&
+        CanCreateWMFDecoder<CLSID_WebmMfVp8Dec>()) {
+      return true;
+    }
+    if (aMimeType.EqualsLiteral("video/webm; codecs=vp9") &&
+        CanCreateWMFDecoder<CLSID_WebmMfVp9Dec>()) {
+      return true;
+    }
+  }
+
+  // Some unsupported codec.
+  return false;
 }
 
 PlatformDecoderModule::ConversionRequired
 WMFDecoderModule::DecoderNeedsConversion(const TrackInfo& aConfig) const
 {
   if (aConfig.IsVideo() &&
       (aConfig.mMimeType.EqualsLiteral("video/avc") ||
        aConfig.mMimeType.EqualsLiteral("video/mp4"))) {
     return kNeedAnnexB;
   } else {
     return kNeedNone;
   }
 }
 
-static bool
-ClassesRootRegKeyExists(const nsAString& aRegKeyPath)
-{
-  nsresult rv;
-
-  nsCOMPtr<nsIWindowsRegKey> regKey =
-    do_CreateInstance("@mozilla.org/windows-registry-key;1", &rv);
-  if (NS_WARN_IF(NS_FAILED(rv))) {
-    return false;
-  }
-
-  rv = regKey->Open(nsIWindowsRegKey::ROOT_KEY_CLASSES_ROOT,
-                    aRegKeyPath,
-                    nsIWindowsRegKey::ACCESS_READ);
-  if (NS_FAILED(rv)) {
-    return false;
-  }
-
-  regKey->Close();
-
-  return true;
-}
-
-/* static */ bool
-WMFDecoderModule::HasH264()
-{
-  // CLSID_CMSH264DecoderMFT
-  return ClassesRootRegKeyExists(
-    NS_LITERAL_STRING("CLSID\\{32D186A7-218F-4C75-8876-DD77273A8999}"));
-}
-
-/* static */ bool
-WMFDecoderModule::HasAAC()
-{
-  // CLSID_CMSAACDecMFT
-  return ClassesRootRegKeyExists(
-    NS_LITERAL_STRING("CLSID\\{62CE7E72-4C71-4D20-B15D-452831A87D9D}"));
-}
-
 } // namespace mozilla
--- a/dom/media/platforms/wmf/WMFDecoderModule.h
+++ b/dom/media/platforms/wmf/WMFDecoderModule.h
@@ -31,23 +31,16 @@ public:
                      FlushableTaskQueue* aAudioTaskQueue,
                      MediaDataDecoderCallback* aCallback) override;
 
   bool SupportsMimeType(const nsACString& aMimeType) override;
 
   ConversionRequired
   DecoderNeedsConversion(const TrackInfo& aConfig) const override;
 
-  // Accessors that report whether we have the required MFTs available
-  // on the system to play various codecs. Windows Vista doesn't have the
-  // H.264/AAC decoders if the "Platform Update Supplement for Windows Vista"
-  // is not installed.
-  static bool HasAAC();
-  static bool HasH264();
-
   // Called on main thread.
   static void Init();
 
   // Called from any thread, must call init first
   static int GetNumDecoderThreads();
 private:
   bool mWMFInitialized;
 };
--- a/dom/media/platforms/wmf/WMFVideoMFTManager.cpp
+++ b/dom/media/platforms/wmf/WMFVideoMFTManager.cpp
@@ -163,17 +163,17 @@ WMFVideoMFTManager::InitializeDXVA(bool 
   MOZ_ASSERT(!mDXVA2Manager);
   if (mLayersBackend != LayersBackend::LAYERS_D3D9 &&
       mLayersBackend != LayersBackend::LAYERS_D3D11) {
     mDXVAFailureReason.AssignLiteral("Unsupported layers backend");
     return false;
   }
 
   // The DXVA manager must be created on the main thread.
-  nsRefPtr<CreateDXVAManagerEvent> event = 
+  nsRefPtr<CreateDXVAManagerEvent> event =
     new CreateDXVAManagerEvent(aForceD3D9 ? LayersBackend::LAYERS_D3D9 : mLayersBackend, mDXVAFailureReason);
 
   if (NS_IsMainThread()) {
     event->Run();
   } else {
     NS_DispatchToMainThread(event, NS_DISPATCH_SYNC);
   }
   mDXVA2Manager = event->mDXVA2Manager;