Bug 1107889 - On Windows, detect when unable to play H.264/AAC (for example due to lacking service pack on Vista). r=kinetik,r=dmajor
authorChris Pearce <cpearce@mozilla.com>
Fri, 09 Jan 2015 13:17:11 +1300
changeset 222865 61d64583cfe57514e97d14c24b1077ea5ae00ed6
parent 222864 536e7f7a6d276ae7c8e0e934202d70308fce3d39
child 222866 901e53fd2486a56905744801181ee7833b744de8
push id10731
push usercbook@mozilla.com
push dateFri, 09 Jan 2015 14:51:37 +0000
treeherderfx-team@e6756043d930 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerskinetik, dmajor
bugs1107889
milestone37.0a1
Bug 1107889 - On Windows, detect when unable to play H.264/AAC (for example due to lacking service pack on Vista). r=kinetik,r=dmajor
dom/media/fmp4/MP4Decoder.cpp
dom/media/fmp4/wmf/WMFDecoderModule.cpp
dom/media/fmp4/wmf/WMFDecoderModule.h
--- a/dom/media/fmp4/MP4Decoder.cpp
+++ b/dom/media/fmp4/MP4Decoder.cpp
@@ -11,16 +11,17 @@
 #include "nsCharSeparatedTokenizer.h"
 #ifdef MOZ_EME
 #include "mozilla/CDMProxy.h"
 #endif
 #include "prlog.h"
 
 #ifdef XP_WIN
 #include "mozilla/WindowsVersion.h"
+#include "WMFDecoderModule.h"
 #endif
 #ifdef MOZ_FFMPEG
 #include "FFmpegRuntimeLinker.h"
 #endif
 #ifdef MOZ_APPLEMEDIA
 #include "apple/AppleDecoderModule.h"
 #endif
 #ifdef MOZ_WIDGET_ANDROID
@@ -58,16 +59,22 @@ static bool
 IsSupportedAudioCodec(const nsAString& aCodec,
                       bool& aOutContainsAAC,
                       bool& aOutContainsMP3)
 {
   // AAC-LC or HE-AAC in M4A.
   aOutContainsAAC = aCodec.EqualsASCII("mp4a.40.2") ||
                     aCodec.EqualsASCII("mp4a.40.5");
   if (aOutContainsAAC) {
+#ifdef XP_WIN
+    if (!Preferences::GetBool("media.fragmented-mp4.use-blank-decoder") &&
+        !WMFDecoderModule::HasAAC()) {
+      return false;
+    }
+#endif
     return true;
   }
 #ifndef MOZ_GONK_MEDIACODEC // B2G doesn't support MP3 in MP4 yet.
   aOutContainsMP3 = aCodec.EqualsASCII("mp3");
   if (aOutContainsMP3) {
     return true;
   }
 #else
@@ -80,16 +87,23 @@ static bool
 IsSupportedH264Codec(const nsAString& aCodec)
 {
   int16_t profile = 0, level = 0;
 
   if (!ExtractH264CodecDetails(aCodec, profile, level)) {
     return false;
   }
 
+#ifdef XP_WIN
+  if (!Preferences::GetBool("media.fragmented-mp4.use-blank-decoder") &&
+      !WMFDecoderModule::HasH264()) {
+    return false;
+  }
+#endif
+
   // Just assume what we can play on all platforms the codecs/formats that
   // WMF can play, since we don't have documentation about what other
   // platforms can play... According to the WMF documentation:
   // http://msdn.microsoft.com/en-us/library/windows/desktop/dd797815%28v=vs.85%29.aspx
   // "The Media Foundation H.264 video decoder is a Media Foundation Transform
   // that supports decoding of Baseline, Main, and High profiles, up to level
   // 5.1.". We also report that we can play Extended profile, as there are
   // bitstreams that are Extended compliant that are also Baseline compliant.
--- a/dom/media/fmp4/wmf/WMFDecoderModule.cpp
+++ b/dom/media/fmp4/wmf/WMFDecoderModule.cpp
@@ -7,16 +7,18 @@
 #include "WMF.h"
 #include "WMFDecoderModule.h"
 #include "WMFDecoder.h"
 #include "WMFVideoMFTManager.h"
 #include "WMFAudioMFTManager.h"
 #include "mozilla/Preferences.h"
 #include "mozilla/DebugOnly.h"
 #include "WMFMediaDataDecoder.h"
+#include "nsIWindowsRegKey.h"
+#include "nsComponentManagerUtils.h"
 
 namespace mozilla {
 
 bool WMFDecoderModule::sIsWMFEnabled = false;
 bool WMFDecoderModule::sDXVAEnabled = false;
 
 WMFDecoderModule::WMFDecoderModule()
 {
@@ -102,9 +104,48 @@ WMFDecoderModule::SupportsVideoMimeType(
 
 bool
 WMFDecoderModule::SupportsAudioMimeType(const char* aMimeType)
 {
   return !strcmp(aMimeType, "audio/mp4a-latm") ||
          !strcmp(aMimeType, "audio/mpeg");
 }
 
+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/fmp4/wmf/WMFDecoderModule.h
+++ b/dom/media/fmp4/wmf/WMFDecoderModule.h
@@ -32,16 +32,23 @@ public:
   virtual already_AddRefed<MediaDataDecoder>
   CreateAudioDecoder(const mp4_demuxer::AudioDecoderConfig& aConfig,
                      MediaTaskQueue* aAudioTaskQueue,
                      MediaDataDecoderCallback* aCallback) MOZ_OVERRIDE;
 
   bool SupportsVideoMimeType(const char* aMimeType) MOZ_OVERRIDE;
   bool SupportsAudioMimeType(const char* aMimeType) MOZ_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();
 private:
   static bool sIsWMFEnabled;
   static bool sDXVAEnabled;
 };
 
 } // namespace mozilla