From f3a92fa0a6dcc425be6dd892bbe9f397ea1acf4f Mon Sep 17 00:00:00 2001 From: Gerald Squelart Date: Sun, 1 Jan 2017 12:27:45 +1100 Subject: [PATCH] Bug 1330284 - Use MediaContentType in MP4Decoder - r=jya MozReview-Commit-ID: 9Npl40Iicjc --HG-- extra : rebase_source : 27df1df1cdf8eb8b608e155c0146c8b09d655de4 --- dom/media/DecoderTraits.cpp | 41 ++++++++---------------- dom/media/DecoderTraits.h | 6 ++-- dom/media/eme/MediaKeySystemAccess.cpp | 3 +- dom/media/fmp4/MP4Decoder.cpp | 32 ++++++++---------- dom/media/fmp4/MP4Decoder.h | 9 +++--- dom/media/gtest/TestMediaDataDecoder.cpp | 6 ++-- dom/media/mediasource/MediaSource.cpp | 4 +-- 7 files changed, 43 insertions(+), 58 deletions(-) diff --git a/dom/media/DecoderTraits.cpp b/dom/media/DecoderTraits.cpp index 30c20f765f1e..f253ad7fae58 100644 --- a/dom/media/DecoderTraits.cpp +++ b/dom/media/DecoderTraits.cpp @@ -101,31 +101,12 @@ IsDirectShowSupportedType(const nsACString& aType) } #endif -#ifdef MOZ_FMP4 -static bool -IsMP4SupportedType(const MediaContentType& aParsedType, - DecoderDoctorDiagnostics* aDiagnostics) -{ - return MP4Decoder::CanHandleMediaType(aParsedType, aDiagnostics); -} -static bool -IsMP4SupportedType(const nsACString& aType, - DecoderDoctorDiagnostics* aDiagnostics) -{ - Maybe contentType = MakeMediaContentType(aType); - if (!contentType) { - return false; - } - return IsMP4SupportedType(*contentType, aDiagnostics); -} -#endif - /* static */ bool -DecoderTraits::IsMP4TypeAndEnabled(const nsACString& aType, - DecoderDoctorDiagnostics* aDiagnostics) +DecoderTraits::IsMP4SupportedType(const MediaContentType& aType, + DecoderDoctorDiagnostics* aDiagnostics) { #ifdef MOZ_FMP4 - return IsMP4SupportedType(aType, aDiagnostics); + return MP4Decoder::IsSupportedType(aType, aDiagnostics); #else return false; #endif @@ -202,8 +183,9 @@ CanHandleCodecsType(const MediaContentType& aType, } #endif #ifdef MOZ_FMP4 - if (DecoderTraits::IsMP4TypeAndEnabled(mimeType.Type().AsString(), aDiagnostics)) { - if (IsMP4SupportedType(aType, aDiagnostics)) { + if (MP4Decoder::IsSupportedType(mimeType, + /* DecoderDoctorDiagnostics* */ nullptr)) { + if (MP4Decoder::IsSupportedType(aType, aDiagnostics)) { return CANPLAY_YES; } else { // We can only reach this position if a particular codec was requested, @@ -286,9 +268,11 @@ CanHandleMediaType(const MediaContentType& aType, if (IsWaveSupportedType(mimeType.Type().AsString())) { return CANPLAY_MAYBE; } - if (DecoderTraits::IsMP4TypeAndEnabled(mimeType.Type().AsString(), aDiagnostics)) { +#ifdef MOZ_FMP4 + if (MP4Decoder::IsSupportedType(mimeType, aDiagnostics)) { return CANPLAY_MAYBE; } +#endif #if !defined(MOZ_OMX_WEBM_DECODER) if (WebMDecoder::IsSupportedType(mimeType)) { return CANPLAY_MAYBE; @@ -368,7 +352,7 @@ InstantiateDecoder(const MediaContentType& aType, RefPtr decoder; #ifdef MOZ_FMP4 - if (IsMP4SupportedType(aType.Type().AsString(), aDiagnostics)) { + if (MP4Decoder::IsSupportedType(aType, aDiagnostics)) { decoder = new MP4Decoder(aOwner); return decoder.forget(); } @@ -453,7 +437,8 @@ MediaDecoderReader* DecoderTraits::CreateReader(const nsACString& aType, Abstrac } #ifdef MOZ_FMP4 - if (IsMP4SupportedType(aType, /* DecoderDoctorDiagnostics* */ nullptr)) { + if (MP4Decoder::IsSupportedType(*type, + /* DecoderDoctorDiagnostics* */ nullptr)) { decoderReader = new MediaFormatReader(aDecoder, new MP4Demuxer(aDecoder->GetResource())); } else #endif @@ -515,7 +500,7 @@ bool DecoderTraits::IsSupportedInVideoDocument(const nsACString& aType) (MediaDecoder::IsAndroidMediaPluginEnabled() && IsAndroidMediaType(aType)) || #endif #ifdef MOZ_FMP4 - IsMP4SupportedType(aType, /* DecoderDoctorDiagnostics* */ nullptr) || + MP4Decoder::IsSupportedType(*type, /* DecoderDoctorDiagnostics* */ nullptr) || #endif IsMP3SupportedType(aType) || IsAACSupportedType(aType) || diff --git a/dom/media/DecoderTraits.h b/dom/media/DecoderTraits.h index 57fee60b350d..ab87a703d229 100644 --- a/dom/media/DecoderTraits.h +++ b/dom/media/DecoderTraits.h @@ -56,8 +56,10 @@ public: // vice versa. static bool IsSupportedInVideoDocument(const nsACString& aType); - static bool IsMP4TypeAndEnabled(const nsACString& aType, - DecoderDoctorDiagnostics* aDiagnostics); + // Convenience function that returns false if MOZ_FMP4 is not defined, + // otherwise defers to MP4Decoder::IsSupportedType(). + static bool IsMP4SupportedType(const MediaContentType& aType, + DecoderDoctorDiagnostics* aDiagnostics); }; } // namespace mozilla diff --git a/dom/media/eme/MediaKeySystemAccess.cpp b/dom/media/eme/MediaKeySystemAccess.cpp index 34fb8faaa66d..80d0ce2d7c0f 100644 --- a/dom/media/eme/MediaKeySystemAccess.cpp +++ b/dom/media/eme/MediaKeySystemAccess.cpp @@ -640,8 +640,7 @@ GetSupportedCapabilities(const CodecType aCodecType, // case-insensitive."'. We're using nsContentTypeParser and that is // case-insensitive and converts all its parameter outputs to lower case.) const bool isMP4 = - DecoderTraits::IsMP4TypeAndEnabled(contentType.Type().AsString(), - aDiagnostics); + DecoderTraits::IsMP4SupportedType(contentType, aDiagnostics); if (isMP4 && !aKeySystem.mMP4.IsSupported()) { EME_LOG("MediaKeySystemConfiguration (label='%s') " "MediaKeySystemMediaCapability('%s','%s') unsupported; " diff --git a/dom/media/fmp4/MP4Decoder.cpp b/dom/media/fmp4/MP4Decoder.cpp index c5f79a03fec0..a51e43147895 100644 --- a/dom/media/fmp4/MP4Decoder.cpp +++ b/dom/media/fmp4/MP4Decoder.cpp @@ -67,8 +67,8 @@ IsWhitelistedH264Codec(const nsAString& aCodec) /* static */ bool -MP4Decoder::CanHandleMediaType(const MediaContentType& aType, - DecoderDoctorDiagnostics* aDiagnostics) +MP4Decoder::IsSupportedType(const MediaContentType& aType, + DecoderDoctorDiagnostics* aDiagnostics) { if (!IsEnabled()) { return false; @@ -77,29 +77,29 @@ MP4Decoder::CanHandleMediaType(const MediaContentType& aType, // Whitelist MP4 types, so they explicitly match what we encounter on // the web, as opposed to what we use internally (i.e. what our demuxers // etc output). - const bool isMP4Audio = aType.Type() == MEDIAMIMETYPE("audio/mp4") || - aType.Type() == MEDIAMIMETYPE("audio/x-m4a"); - const bool isMP4Video = + const bool isAudio = aType.Type() == MEDIAMIMETYPE("audio/mp4") + || aType.Type() == MEDIAMIMETYPE("audio/x-m4a"); + const bool isVideo = aType.Type() == MEDIAMIMETYPE("video/mp4") + || aType.Type() == MEDIAMIMETYPE("video/quicktime") // On B2G, treat 3GPP as MP4 when Gonk PDM is available. #ifdef MOZ_GONK_MEDIACODEC - aType.Type() == MEDIAMIMETYPE(VIDEO_3GPP) || + || aType.Type() == MEDIAMIMETYPE(VIDEO_3GPP) #endif - aType.Type() == MEDIAMIMETYPE("video/mp4") || - aType.Type() == MEDIAMIMETYPE("video/quicktime") || - aType.Type() == MEDIAMIMETYPE("video/x-m4v"); - if (!isMP4Audio && !isMP4Video) { + || aType.Type() == MEDIAMIMETYPE("video/x-m4v"); + + if (!isAudio && !isVideo) { return false; } nsTArray> trackInfos; if (aType.ExtendedType().Codecs().IsEmpty()) { // No codecs specified. Assume H.264 - if (isMP4Audio) { + if (isAudio) { trackInfos.AppendElement( CreateTrackInfoWithMIMETypeAndContentTypeExtraParameters( NS_LITERAL_CSTRING("audio/mp4a-latm"), aType)); } else { - MOZ_ASSERT(isMP4Video); + MOZ_ASSERT(isVideo); trackInfos.AppendElement( CreateTrackInfoWithMIMETypeAndContentTypeExtraParameters( NS_LITERAL_CSTRING("video/avc"), aType)); @@ -107,11 +107,7 @@ MP4Decoder::CanHandleMediaType(const MediaContentType& aType, } else { // Verify that all the codecs specified are ones that we expect that // we can play. - nsTArray codecs; - if (!ParseCodecsString(aType.ExtendedType().Codecs().AsString(), codecs)) { - return false; - } - for (const nsString& codec : codecs) { + for (const auto& codec : aType.ExtendedType().Codecs().Range()) { if (IsAACCodecString(codec)) { trackInfos.AppendElement( CreateTrackInfoWithMIMETypeAndContentTypeExtraParameters( @@ -138,7 +134,7 @@ MP4Decoder::CanHandleMediaType(const MediaContentType& aType, } // Note: Only accept H.264 in a video content type, not in an audio // content type. - if (IsWhitelistedH264Codec(codec) && isMP4Video) { + if (IsWhitelistedH264Codec(codec) && isVideo) { trackInfos.AppendElement( CreateTrackInfoWithMIMETypeAndContentTypeExtraParameters( NS_LITERAL_CSTRING("video/avc"), aType)); diff --git a/dom/media/fmp4/MP4Decoder.h b/dom/media/fmp4/MP4Decoder.h index ad5fba7b5440..133e41cc2d81 100644 --- a/dom/media/fmp4/MP4Decoder.h +++ b/dom/media/fmp4/MP4Decoder.h @@ -30,10 +30,11 @@ public: MediaDecoderStateMachine* CreateStateMachine() override; - // Returns true if aType is a type that we think we can render with the - // a MP4 platform decoder backend. - static bool CanHandleMediaType(const MediaContentType& aType, - DecoderDoctorDiagnostics* aDiagnostics); + // Returns true if aContentType is an MP4 type that we think we can render + // with the a platform decoder backend. + // If provided, codecs are checked for support. + static bool IsSupportedType(const MediaContentType& aContentType, + DecoderDoctorDiagnostics* aDiagnostics); // Return true if aMimeType is a one of the strings used by our demuxers to // identify H264. Does not parse general content type strings, i.e. white diff --git a/dom/media/gtest/TestMediaDataDecoder.cpp b/dom/media/gtest/TestMediaDataDecoder.cpp index dbd56c2fa338..c8a28eb2a924 100644 --- a/dom/media/gtest/TestMediaDataDecoder.cpp +++ b/dom/media/gtest/TestMediaDataDecoder.cpp @@ -8,6 +8,7 @@ #include "MockMediaResource.h" #include "DecoderTraits.h" #include "MediaContentType.h" +#include "MP4Decoder.h" #include "MP4Demuxer.h" #include "WebMDecoder.h" #include "WebMDemuxer.h" @@ -44,8 +45,9 @@ private: TEST(MediaDataDecoder, H264) { - if (!DecoderTraits::IsMP4TypeAndEnabled(NS_LITERAL_CSTRING("video/mp4") - , /* DecoderDoctorDiagnostics* */ nullptr)) { + if (!DecoderTraits::IsMP4SupportedType( + MediaContentType(MEDIAMIMETYPE("video/mp4")), + /* DecoderDoctorDiagnostics* */ nullptr)) { EXPECT_TRUE(true); } else { RefPtr resource = diff --git a/dom/media/mediasource/MediaSource.cpp b/dom/media/mediasource/MediaSource.cpp index 8a3184f591cc..3b3d02174fe3 100644 --- a/dom/media/mediasource/MediaSource.cpp +++ b/dom/media/mediasource/MediaSource.cpp @@ -72,8 +72,8 @@ static bool IsWebMForced(DecoderDoctorDiagnostics* aDiagnostics) { bool mp4supported = - DecoderTraits::IsMP4TypeAndEnabled(NS_LITERAL_CSTRING("video/mp4"), - aDiagnostics); + DecoderTraits::IsMP4SupportedType(MediaContentType(MEDIAMIMETYPE("video/mp4")), + aDiagnostics); bool hwsupported = gfx::gfxVars::CanUseHardwareVideoDecoding(); #ifdef MOZ_WIDGET_ANDROID return !mp4supported || !hwsupported || VP9Benchmark::IsVP9DecodeFast() ||