--- 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.",