Bug 1245789 - Push detection of WMF decoding for clearkey into GMPParent to simplify request media key system access logic. r=gerald
authorChris Pearce <cpearce@mozilla.com>
Tue, 12 Apr 2016 16:12:22 +1200
changeset 316518 e0dbbeb2ae3b14d3ef948010829138a47c2310d5
parent 316517 d69c88b741832f1546d90a0a233d9cfe76dc873c
child 316519 0b9c34023af8201c6623877db40e14fc1deafda2
push id9480
push userjlund@mozilla.com
push dateMon, 25 Apr 2016 17:12:58 +0000
treeherdermozilla-aurora@0d6a91c76a9e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersgerald
bugs1245789
milestone48.0a1
Bug 1245789 - Push detection of WMF decoding for clearkey into GMPParent to simplify request media key system access logic. r=gerald 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__);