Bug 1245789 - Push detection of WMF decoding for clearkey into GMPParent to simplify request media key system access logic. r=gerald,a=ritu
authorChris Pearce <cpearce@mozilla.com>
Tue, 12 Apr 2016 16:12:22 +1200
changeset 324041 c95419cb1a3d1571a1b22d7d377d14593dbd0cb1
parent 324040 c9c73c8fba8c0d4bcc4c8f6dc1dfa57532e01f51
child 324042 b9a267eecc3c0986c0064f189e404395ca444e45
push id5913
push userjlund@mozilla.com
push dateMon, 25 Apr 2016 16:57:49 +0000
treeherdermozilla-beta@dcaf0a6fa115 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersgerald, ritu
bugs1245789
milestone47.0a2
Bug 1245789 - Push detection of WMF decoding for clearkey into GMPParent to simplify request media key system access logic. r=gerald,a=ritu The logic in MediaKeySystemAccess is convoluted because it needs to keep checking whether we're servicing a clearkey request and whether WMF is available for gmp-clearkey to decode with. If we instead push those checks down into GMPParent at the time where we parse the GMP info file, we can just not add the decode capability to the GMPParent, and can remove the special cases in MediaKeySystemAccess. This simplifies adding the (similar) special cases for Widevine in the next patch. MozReview-Commit-ID: IKD5LU86zIv
dom/media/eme/MediaKeySystemAccess.cpp
dom/media/gmp/GMPParent.cpp
--- a/dom/media/eme/MediaKeySystemAccess.cpp
+++ b/dom/media/eme/MediaKeySystemAccess.cpp
@@ -9,17 +9,16 @@
 #include "mozilla/dom/MediaKeySystemAccessBinding.h"
 #include "mozilla/Preferences.h"
 #include "nsContentTypeParser.h"
 #ifdef MOZ_FMP4
 #include "MP4Decoder.h"
 #endif
 #ifdef XP_WIN
 #include "mozilla/WindowsVersion.h"
-#include "WMFDecoderModule.h"
 #endif
 #ifdef XP_MACOSX
 #include "nsCocoaFeatures.h"
 #endif
 #include "nsContentCID.h"
 #include "nsServiceManagerUtils.h"
 #include "mozIGeckoMediaPluginService.h"
 #include "VideoUtils.h"
@@ -28,19 +27,16 @@
 #include "mozilla/EMEUtils.h"
 #include "GMPUtils.h"
 #include "nsAppDirectoryServiceDefs.h"
 #include "nsDirectoryServiceUtils.h"
 #include "nsDirectoryServiceDefs.h"
 #include "nsXULAppAPI.h"
 #include "gmp-audio-decode.h"
 #include "gmp-video-decode.h"
-#ifdef XP_WIN
-#include "WMFDecoderModule.h"
-#endif
 
 #if defined(XP_WIN) || defined(XP_MACOSX)
 #define PRIMETIME_EME_SUPPORTED 1
 #endif
 
 namespace mozilla {
 namespace dom {
 
@@ -331,103 +327,66 @@ GMPDecryptsAndDecodesAAC(mozIGeckoMediaP
                          const nsAString& aKeySystem)
 {
   MOZ_ASSERT(HaveGMPFor(aGMPS,
                         NS_ConvertUTF16toUTF8(aKeySystem),
                         NS_LITERAL_CSTRING(GMP_API_DECRYPTOR)));
   return HaveGMPFor(aGMPS,
                     NS_ConvertUTF16toUTF8(aKeySystem),
                     NS_LITERAL_CSTRING(GMP_API_AUDIO_DECODER),
-                    NS_LITERAL_CSTRING("aac"))
-#ifdef XP_WIN
-    // Clearkey on Windows advertises that it can decode in its GMP info
-    // file, but uses Windows Media Foundation to decode. That's not present
-    // on Windows XP, and on some Vista, Windows N, and KN variants without
-    // certain services packs. So for ClearKey we must check that WMF will
-    // work.
-    && (!aKeySystem.EqualsLiteral("org.w3.clearkey") || WMFDecoderModule::HasAAC())
-#endif
-  ;
+                    NS_LITERAL_CSTRING("aac"));
 }
 
 static bool
 GMPDecryptsAndDecodesH264(mozIGeckoMediaPluginService* aGMPS,
                           const nsAString& aKeySystem)
 {
   MOZ_ASSERT(HaveGMPFor(aGMPS,
                         NS_ConvertUTF16toUTF8(aKeySystem),
                         NS_LITERAL_CSTRING(GMP_API_DECRYPTOR)));
   return HaveGMPFor(aGMPS,
                     NS_ConvertUTF16toUTF8(aKeySystem),
                     NS_LITERAL_CSTRING(GMP_API_VIDEO_DECODER),
-                    NS_LITERAL_CSTRING("h264"))
-#ifdef XP_WIN
-    // Clearkey on Windows advertises that it can decode in its GMP info
-    // file, but uses Windows Media Foundation to decode. That's not present
-    // on Windows XP, and on some Vista, Windows N, and KN variants without
-    // certain services packs. So for ClearKey we must check that WMF will
-    // work.
-    && (!aKeySystem.EqualsLiteral("org.w3.clearkey") || WMFDecoderModule::HasH264())
-#endif
-  ;
+                    NS_LITERAL_CSTRING("h264"));
 }
 
 // If this keysystem's CDM explicitly says it doesn't support decoding,
 // that means it's OK with passing the decrypted samples back to Gecko
-// for decoding. Note we special case Clearkey on Windows, where we need
-// to check for whether WMF is usable because the CDM uses that
-// to decode.
+// for decoding.
 static bool
 GMPDecryptsAndGeckoDecodesH264(mozIGeckoMediaPluginService* aGMPService,
                                const nsAString& aKeySystem,
                                const nsAString& aContentType)
 {
   MOZ_ASSERT(HaveGMPFor(aGMPService,
                         NS_ConvertUTF16toUTF8(aKeySystem),
                         NS_LITERAL_CSTRING(GMP_API_DECRYPTOR)));
   MOZ_ASSERT(IsH264ContentType(aContentType));
-  return
-    (!HaveGMPFor(aGMPService,
-                 NS_ConvertUTF16toUTF8(aKeySystem),
-                 NS_LITERAL_CSTRING(GMP_API_VIDEO_DECODER),
-                 NS_LITERAL_CSTRING("h264"))
-#ifdef XP_WIN
-    // Clearkey on Windows advertises that it can decode in its GMP info
-    // file, but uses Windows Media Foundation to decode. That's not present
-    // on Windows XP, and on some Vista, Windows N, and KN variants without
-    // certain services packs. So don't try to use gmp-clearkey for decoding
-    // if we don't have a decoder here.
-    || (aKeySystem.EqualsLiteral("org.w3.clearkey") && !WMFDecoderModule::HasH264())
-#endif
-    ) && MP4Decoder::CanHandleMediaType(aContentType);
+  return !HaveGMPFor(aGMPService,
+                     NS_ConvertUTF16toUTF8(aKeySystem),
+                     NS_LITERAL_CSTRING(GMP_API_VIDEO_DECODER),
+                     NS_LITERAL_CSTRING("h264")) &&
+         MP4Decoder::CanHandleMediaType(aContentType);
 }
 
 static bool
 GMPDecryptsAndGeckoDecodesAAC(mozIGeckoMediaPluginService* aGMPService,
                               const nsAString& aKeySystem,
                               const nsAString& aContentType)
 {
   MOZ_ASSERT(HaveGMPFor(aGMPService,
                         NS_ConvertUTF16toUTF8(aKeySystem),
                         NS_LITERAL_CSTRING(GMP_API_DECRYPTOR)));
   MOZ_ASSERT(IsAACContentType(aContentType));
-  return
-    (!HaveGMPFor(aGMPService,
-                 NS_ConvertUTF16toUTF8(aKeySystem),
-                 NS_LITERAL_CSTRING(GMP_API_AUDIO_DECODER),
-                 NS_LITERAL_CSTRING("aac"))
-#ifdef XP_WIN
-    // Clearkey on Windows advertises that it can decode in its GMP info
-    // file, but uses Windows Media Foundation to decode. That's not present
-    // on Windows XP, and on some Vista, Windows N, and KN variants without
-    // certain services packs. So don't try to use gmp-clearkey for decoding
-    // if we don't have a decoder here.
-    || (aKeySystem.EqualsLiteral("org.w3.clearkey") && !WMFDecoderModule::HasAAC())
-#endif
-    ) && MP4Decoder::CanHandleMediaType(aContentType);
+
+  return !HaveGMPFor(aGMPService,
+                     NS_ConvertUTF16toUTF8(aKeySystem),
+                     NS_LITERAL_CSTRING(GMP_API_AUDIO_DECODER),
+                     NS_LITERAL_CSTRING("aac")) &&
+         MP4Decoder::CanHandleMediaType(aContentType);
 }
 
 static bool
 IsSupportedAudio(mozIGeckoMediaPluginService* aGMPService,
                  const nsAString& aKeySystem,
                  const nsAString& aAudioType)
 {
   return IsAACContentType(aAudioType) &&
@@ -470,33 +429,37 @@ IsSupported(mozIGeckoMediaPluginService*
       !IsSupportedVideo(aGMPService, aKeySystem, aConfig.mVideoType)) {
     return false;
   }
 
   return true;
 }
 
 static bool
+IsSupportedInitDataType(const nsString& aCandidate, const nsAString& aKeySystem)
+{
+  // All supported keySystems can handle "cenc" initDataType.
+  // ClearKey also supports "keyids" and "webm" initDataTypes.
+  return aCandidate.EqualsLiteral("cenc") ||
+    (aKeySystem.EqualsLiteral("org.w3.clearkey") &&
+    (aCandidate.EqualsLiteral("keyids") || aCandidate.EqualsLiteral("webm)")));
+}
+
+static bool
 GetSupportedConfig(mozIGeckoMediaPluginService* aGMPService,
                    const nsAString& aKeySystem,
                    const MediaKeySystemConfiguration& aCandidate,
                    MediaKeySystemConfiguration& aOutConfig)
 {
   MediaKeySystemConfiguration config;
   config.mLabel = aCandidate.mLabel;
   if (aCandidate.mInitDataTypes.WasPassed()) {
     nsTArray<nsString> initDataTypes;
     for (const nsString& candidate : aCandidate.mInitDataTypes.Value()) {
-      // All supported keySystems can handle "cenc" initDataType.
-      // ClearKey also supports "keyids" and "webm" initDataTypes.
-      if (candidate.EqualsLiteral("cenc")) {
-        initDataTypes.AppendElement(candidate);
-      } else if ((candidate.EqualsLiteral("keyids") ||
-                  candidate.EqualsLiteral("webm)")) &&
-                 aKeySystem.EqualsLiteral("org.w3.clearkey")) {
+      if (IsSupportedInitDataType(candidate, aKeySystem)) {
         initDataTypes.AppendElement(candidate);
       }
     }
     if (initDataTypes.IsEmpty()) {
       return false;
     }
     config.mInitDataTypes.Construct();
     config.mInitDataTypes.Value().Assign(initDataTypes);
--- a/dom/media/gmp/GMPParent.cpp
+++ b/dom/media/gmp/GMPParent.cpp
@@ -30,16 +30,20 @@ using mozilla::ipc::GeckoChildProcessHos
 #ifdef MOZ_CRASHREPORTER
 #include "nsPrintfCString.h"
 using CrashReporter::AnnotationTable;
 using CrashReporter::GetIDFromMinidump;
 #endif
 
 #include "mozilla/Telemetry.h"
 
+#ifdef XP_WIN
+#include "WMFDecoderModule.h"
+#endif
+
 #ifdef MOZ_WIDEVINE_EME
 #include "mozilla/dom/WidevineCDMManifestBinding.h"
 #include "widevine-adapter/WidevineAdapter.h"
 #endif
 
 namespace mozilla {
 
 #undef LOG
@@ -872,28 +876,42 @@ GMPParent::ReadGMPInfoFile(nsIFile* aFil
                       mDisplayName.get());
         return InitPromise::CreateAndReject(NS_ERROR_FAILURE, __func__);
       }
 #endif
 #ifdef XP_WIN
       // Adobe GMP doesn't work without SSE2. Check the tags to see if
       // the decryptor is for the Adobe GMP, and refuse to load it if
       // SSE2 isn't supported.
-      for (const nsCString& tag : cap.mAPITags) {
-        if (!tag.EqualsLiteral("com.adobe.primetime")) {
-          continue;
-        }
-        if (!mozilla::supports_sse2()) {
-          return InitPromise::CreateAndReject(NS_ERROR_FAILURE, __func__);
-        }
-        break;
+      if (cap.mAPITags.Contains(NS_LITERAL_CSTRING("com.adobe.primetime")) &&
+          !mozilla::supports_sse2()) {
+        return InitPromise::CreateAndReject(NS_ERROR_FAILURE, __func__);
       }
 #endif // XP_WIN
     }
 
+#ifdef XP_WIN
+    // Clearkey on Windows advertises that it can decode in its GMP info
+    // file, but uses Windows Media Foundation to decode. That's not present
+    // on Windows XP, and on some Vista, Windows N, and KN variants without
+    // certain services packs. So don't add the decoding capability to
+    // gmp-clearkey's GMPParent if it's not going to be able to use WMF to
+    // decode.
+    if (cap.mAPIName.EqualsLiteral(GMP_API_VIDEO_DECODER) &&
+        cap.mAPITags.Contains(NS_LITERAL_CSTRING("org.w3.clearkey")) &&
+        !WMFDecoderModule::HasH264()) {
+      continue;
+    }
+    if (cap.mAPIName.EqualsLiteral(GMP_API_AUDIO_DECODER) &&
+        cap.mAPITags.Contains(NS_LITERAL_CSTRING("org.w3.clearkey")) &&
+        !WMFDecoderModule::HasAAC()) {
+      continue;
+    }
+#endif
+
     mCapabilities.AppendElement(Move(cap));
   }
 
   if (mCapabilities.IsEmpty()) {
     return InitPromise::CreateAndReject(NS_ERROR_FAILURE, __func__);
   }
 
   return InitPromise::CreateAndResolve(NS_OK, __func__);