Bug 1278198 - Enforce codecs match the capability and content type in GetSupportedCapabilities(). r=gerald
authorChris Pearce <cpearce@mozilla.com>
Thu, 21 Jul 2016 19:22:59 +1200
changeset 348532 ad262be679de3659068498c891c5bd5e0e3baf56
parent 348531 aec9905b06fe603d99b3d1b5748ff85d6776d00a
child 348533 48bcc4d343b3a33d08b13300f5a8b0d71e793a32
push id1230
push userjlund@mozilla.com
push dateMon, 31 Oct 2016 18:13:35 +0000
treeherdermozilla-release@5e06e3766db2 [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.",