Bug 1278198 - Enforce codecs match the capability and content type in GetSupportedCapabilities(). r=gerald
☠☠ backed out by 4988d24a6d7c ☠ ☠
authorChris Pearce <cpearce@mozilla.com>
Thu, 21 Jul 2016 19:22:59 +1200
changeset 346148 3ab20077e16df40c9e4a61860c69f7b1eec024da
parent 346147 c9e56c91112ef3fd3c66f1b1c27c22d288ef8c31
child 346149 d78a8f4bd9ccf817a199ed1f0a55c6813c78a481
push id6389
push userraliiev@mozilla.com
push dateMon, 19 Sep 2016 13:38:22 +0000
treeherdermozilla-beta@01d67bfe6c81 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersgerald
bugs1278198
milestone50.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 1278198 - Enforce codecs match the capability and content type in GetSupportedCapabilities(). r=gerald We're supposed to reject MediaKeySystemCapabilities which have a contentType that has codecs which don't match their major type, i.e. audio codecs in a video container type. I missed that, and it's causing us to fail the test_eme_requestMediaKeySystemAccess case "MP4 video container with both audio and video codec type in videoType". MozReview-Commit-ID: KQVGk9hX3eC
dom/media/eme/MediaKeySystemAccess.cpp
--- a/dom/media/eme/MediaKeySystemAccess.cpp
+++ b/dom/media/eme/MediaKeySystemAccess.cpp
@@ -614,19 +614,47 @@ GetMajorType(const nsAString& aContentTy
     return Audio;
   }
   if (CaseInsensitiveFindInReadable(NS_LITERAL_STRING("video/"), aContentType)) {
     return Video;
   }
   return Invalid;
 }
 
+static CodecType
+GetCodecType(const GMPCodecString& aCodec)
+{
+  if (aCodec.Equals(GMP_CODEC_AAC) ||
+      aCodec.Equals(GMP_CODEC_OPUS) ||
+      aCodec.Equals(GMP_CODEC_VORBIS)) {
+    return Audio;
+  }
+  if (aCodec.Equals(GMP_CODEC_H264) ||
+      aCodec.Equals(GMP_CODEC_VP8) ||
+      aCodec.Equals(GMP_CODEC_VP9)) {
+    return Video;
+  }
+  return Invalid;
+}
+
+static bool
+AllCodecsOfType(const nsTArray<GMPCodecString>& aCodecs, const CodecType aCodecType)
+{
+  for (const GMPCodecString& codec : aCodecs) {
+    if (GetCodecType(codec) != aCodecType) {
+      return false;
+    }
+  }
+  return true;
+}
+
 // 3.1.2.3 Get Supported Capabilities for Audio/Video Type
 static Sequence<MediaKeySystemMediaCapability>
-GetSupportedCapabilities(mozIGeckoMediaPluginService* aGMPService,
+GetSupportedCapabilities(const CodecType aCodecType,
+                         mozIGeckoMediaPluginService* aGMPService,
                          const nsTArray<MediaKeySystemMediaCapability>& aRequestedCapabilities,
                          const MediaKeySystemConfiguration& aPartialConfig,
                          const KeySystemConfig& aKeySystem,
                          DecoderDoctorDiagnostics* aDiagnostics)
 {
   // Let local accumulated configuration be a local copy of partial configuration.
   // (Note: It's not necessary for us to maintain a local copy, as we don't need
   // to test whether capabilites from previous calls to this algorithm work with
@@ -727,48 +755,57 @@ GetSupportedCapabilities(mozIGeckoMediaP
     // If the user agent does not recognize one or more parameters, continue to
     // the next iteration.
     // Let media types be the set of codecs and codec constraints specified by
     // parameters. The case-sensitivity of string comparisons is determined by
     // the appropriate RFC or other specification.
     // (Note: codecs array is 'parameter').
 
     // If media types is empty:
-    const auto majorType = GetMajorType(container);
     if (codecs.IsEmpty()) {
       // If container normatively implies a specific set of codecs and codec constraints:
       // Let parameters be that set.
       if (isMP4) {
-        if (majorType == Audio) {
+        if (aCodecType == Audio) {
           codecs.AppendElement(GMP_CODEC_AAC);
-        } else if (majorType == Video) {
+        } else if (aCodecType == Video) {
           codecs.AppendElement(GMP_CODEC_H264);
         }
       } else if (isWebM) {
-        if (majorType == Audio) {
+        if (aCodecType == Audio) {
           codecs.AppendElement(GMP_CODEC_VORBIS);
-        } else if (majorType == Video) {
+        } else if (aCodecType == Video) {
           codecs.AppendElement(GMP_CODEC_VP8);
         }
       }
       // Otherwise: Continue to the next iteration.
       // (Note: all containers we support have implied codecs, so don't continue here.)
     }
 
     // If content type is not strictly a audio/video type, continue to the next iteration.
+    const auto majorType = GetMajorType(container);
     if (majorType == Invalid) {
       EME_LOG("MediaKeySystemConfiguration (label='%s') "
               "MediaKeySystemMediaCapability('%s','%s') unsupported; "
               "MIME type is not an audio or video MIME type.",
               NS_ConvertUTF16toUTF8(aPartialConfig.mLabel).get(),
               NS_ConvertUTF16toUTF8(contentType).get(),
               NS_ConvertUTF16toUTF8(robustness).get());
       continue;
     }
-
+    if (majorType != aCodecType || !AllCodecsOfType(codecs, aCodecType)) {
+      EME_LOG("MediaKeySystemConfiguration (label='%s') "
+              "MediaKeySystemMediaCapability('%s','%s') unsupported; "
+              "MIME type mixes audio codecs in video capabilities "
+              "or video codecs in audio capabilities.",
+              NS_ConvertUTF16toUTF8(aPartialConfig.mLabel).get(),
+              NS_ConvertUTF16toUTF8(contentType).get(),
+              NS_ConvertUTF16toUTF8(robustness).get());
+      continue;
+    }
     // If robustness is not the empty string and contains an unrecognized
     // value or a value not supported by implementation, continue to the
     // next iteration. String comparison is case-sensitive.
     if (!robustness.IsEmpty()) {
       if (majorType == Audio && !aKeySystem.mAudioRobustness.Contains(robustness)) {
         EME_LOG("MediaKeySystemConfiguration (label='%s') "
                 "MediaKeySystemMediaCapability('%s','%s') unsupported; "
                 "unsupported robustness string.",
@@ -1011,17 +1048,18 @@ GetSupportedConfig(mozIGeckoMediaPluginS
 
   // If the videoCapabilities member in candidate configuration is non-empty:
   if (!aCandidate.mVideoCapabilities.IsEmpty()) {
     // Let video capabilities be the result of executing the Get Supported
     // Capabilities for Audio/Video Type algorithm on Video, candidate
     // configuration's videoCapabilities member, accumulated configuration,
     // and restrictions.
     Sequence<MediaKeySystemMediaCapability> caps =
-      GetSupportedCapabilities(aGMPService,
+      GetSupportedCapabilities(Video,
+                               aGMPService,
                                aCandidate.mVideoCapabilities,
                                config,
                                aKeySystem,
                                aDiagnostics);
     // If video capabilities is null, return NotSupported.
     if (caps.IsEmpty()) {
       EME_LOG("MediaKeySystemConfiguration (label='%s') rejected; "
               "no supported video capabilities.",
@@ -1036,17 +1074,18 @@ GetSupportedConfig(mozIGeckoMediaPluginS
   }
 
   // If the audioCapabilities member in candidate configuration is non-empty:
   if (!aCandidate.mAudioCapabilities.IsEmpty()) {
     // Let audio capabilities be the result of executing the Get Supported Capabilities
     // for Audio/Video Type algorithm on Audio, candidate configuration's audioCapabilities
     // member, accumulated configuration, and restrictions.
     Sequence<MediaKeySystemMediaCapability> caps =
-      GetSupportedCapabilities(aGMPService,
+      GetSupportedCapabilities(Audio,
+                               aGMPService,
                                aCandidate.mAudioCapabilities,
                                config,
                                aKeySystem,
                                aDiagnostics);
     // If audio capabilities is null, return NotSupported.
     if (caps.IsEmpty()) {
       EME_LOG("MediaKeySystemConfiguration (label='%s') rejected; "
               "no supported audio capabilities.",