Bug 1330284 - Use MediaContentType in MP4Decoder - r?jya
MozReview-Commit-ID: 9Npl40Iicjc
--- a/dom/media/DecoderTraits.cpp
+++ b/dom/media/DecoderTraits.cpp
@@ -96,41 +96,22 @@ IsAndroidMediaType(const nsACString& aTy
#ifdef MOZ_DIRECTSHOW
static bool
IsDirectShowSupportedType(const nsACString& aType)
{
return DirectShowDecoder::GetSupportedCodecs(aType, nullptr);
}
#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<MediaContentType> 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
}
static bool
IsMP3SupportedType(const nsACString& aType,
const nsAString& aCodecs = EmptyString())
@@ -197,18 +178,19 @@ CanHandleCodecsType(const MediaContentTy
} else {
// We can only reach this position if a particular codec was requested,
// webm is supported and working: the codec must be invalid.
return CANPLAY_NO;
}
}
#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,
// fmp4 is supported and working: the codec must be invalid.
return CANPLAY_NO;
}
}
#endif
@@ -281,19 +263,21 @@ CanHandleMediaType(const MediaContentTyp
const MediaContentType mimeType(aType.Type());
if (OggDecoder::IsSupportedType(mimeType)) {
return CANPLAY_MAYBE;
}
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;
}
#endif
if (IsMP3SupportedType(mimeType.Type().AsString())) {
return CANPLAY_MAYBE;
}
@@ -363,17 +347,17 @@ already_AddRefed<MediaDecoder>
InstantiateDecoder(const MediaContentType& aType,
MediaDecoderOwner* aOwner,
DecoderDoctorDiagnostics* aDiagnostics)
{
MOZ_ASSERT(NS_IsMainThread());
RefPtr<MediaDecoder> decoder;
#ifdef MOZ_FMP4
- if (IsMP4SupportedType(aType.Type().AsString(), aDiagnostics)) {
+ if (MP4Decoder::IsSupportedType(aType, aDiagnostics)) {
decoder = new MP4Decoder(aOwner);
return decoder.forget();
}
#endif
if (IsMP3SupportedType(aType.Type().AsString())) {
decoder = new MP3Decoder(aOwner);
return decoder.forget();
}
@@ -448,17 +432,18 @@ MediaDecoderReader* DecoderTraits::Creat
return decoderReader;
}
Maybe<MediaContentType> type = MakeMediaContentType(aType);
if (!type) {
return decoderReader;
}
#ifdef MOZ_FMP4
- if (IsMP4SupportedType(aType, /* DecoderDoctorDiagnostics* */ nullptr)) {
+ if (MP4Decoder::IsSupportedType(*type,
+ /* DecoderDoctorDiagnostics* */ nullptr)) {
decoderReader = new MediaFormatReader(aDecoder, new MP4Demuxer(aDecoder->GetResource()));
} else
#endif
if (IsMP3SupportedType(aType)) {
decoderReader = new MediaFormatReader(aDecoder, new mp3::MP3Demuxer(aDecoder->GetResource()));
} else
if (IsAACSupportedType(aType)) {
decoderReader = new MediaFormatReader(aDecoder, new ADTSDemuxer(aDecoder->GetResource()));
@@ -510,17 +495,17 @@ bool DecoderTraits::IsSupportedInVideoDo
return
OggDecoder::IsSupportedType(*type) ||
WebMDecoder::IsSupportedType(*type) ||
#ifdef MOZ_ANDROID_OMX
(MediaDecoder::IsAndroidMediaPluginEnabled() && IsAndroidMediaType(aType)) ||
#endif
#ifdef MOZ_FMP4
- IsMP4SupportedType(aType, /* DecoderDoctorDiagnostics* */ nullptr) ||
+ MP4Decoder::IsSupportedType(*type, /* DecoderDoctorDiagnostics* */ nullptr) ||
#endif
IsMP3SupportedType(aType) ||
IsAACSupportedType(aType) ||
IsFlacSupportedType(aType) ||
#ifdef MOZ_DIRECTSHOW
IsDirectShowSupportedType(aType) ||
#endif
false;
--- a/dom/media/DecoderTraits.h
+++ b/dom/media/DecoderTraits.h
@@ -51,16 +51,18 @@ public:
static MediaDecoderReader* CreateReader(const nsACString& aType,
AbstractMediaDecoder* aDecoder);
// Returns true if MIME type aType is supported in video documents,
// or false otherwise. Not all platforms support all MIME types, and
// 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
#endif
--- a/dom/media/eme/MediaKeySystemAccess.cpp
+++ b/dom/media/eme/MediaKeySystemAccess.cpp
@@ -635,18 +635,17 @@ GetSupportedCapabilities(const CodecType
}
// If the user agent does not support container, continue to the next iteration.
// The case-sensitivity of string comparisons is determined by the appropriate RFC.
// (Note: Per RFC 6838 [RFC6838], "Both top-level type and subtype names are
// 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; "
"MP4 requested but unsupported.",
NS_ConvertUTF16toUTF8(aPartialConfig.mLabel).get(),
NS_ConvertUTF16toUTF8(contentTypeString).get(),
NS_ConvertUTF16toUTF8(robustness).get());
continue;
--- a/dom/media/fmp4/MP4Decoder.cpp
+++ b/dom/media/fmp4/MP4Decoder.cpp
@@ -62,61 +62,57 @@ IsWhitelistedH264Codec(const nsAString&
(profile == H264_PROFILE_BASE ||
profile == H264_PROFILE_MAIN ||
profile == H264_PROFILE_EXTENDED ||
profile == H264_PROFILE_HIGH);
}
/* static */
bool
-MP4Decoder::CanHandleMediaType(const MediaContentType& aType,
- DecoderDoctorDiagnostics* aDiagnostics)
+MP4Decoder::IsSupportedType(const MediaContentType& aType,
+ DecoderDoctorDiagnostics* aDiagnostics)
{
if (!IsEnabled()) {
return false;
}
// 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<UniquePtr<TrackInfo>> 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));
}
} else {
// Verify that all the codecs specified are ones that we expect that
// we can play.
- nsTArray<nsString> 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(
NS_LITERAL_CSTRING("audio/mp4a-latm"), aType));
continue;
}
if (codec.EqualsLiteral("mp3")) {
trackInfos.AppendElement(
@@ -133,17 +129,17 @@ MP4Decoder::CanHandleMediaType(const Med
if (codec.EqualsLiteral("flac")) {
trackInfos.AppendElement(
CreateTrackInfoWithMIMETypeAndContentTypeExtraParameters(
NS_LITERAL_CSTRING("audio/flac"), aType));
continue;
}
// 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));
continue;
}
// Some unsupported codec.
return false;
}
--- a/dom/media/fmp4/MP4Decoder.h
+++ b/dom/media/fmp4/MP4Decoder.h
@@ -25,20 +25,21 @@ public:
if (!IsEnabled()) {
return nullptr;
}
return new MP4Decoder(aOwner);
}
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
// space matters.
static bool IsH264(const nsACString& aMimeType);
// Return true if aMimeType is a one of the strings used by our demuxers to
// identify AAC. Does not parse general content type strings, i.e. white
--- a/dom/media/gtest/TestMediaDataDecoder.cpp
+++ b/dom/media/gtest/TestMediaDataDecoder.cpp
@@ -3,16 +3,17 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "gtest/gtest.h"
#include "Benchmark.h"
#include "MockMediaResource.h"
#include "DecoderTraits.h"
#include "MediaContentType.h"
+#include "MP4Decoder.h"
#include "MP4Demuxer.h"
#include "WebMDecoder.h"
#include "WebMDemuxer.h"
using namespace mozilla;
class BenchmarkRunner
{
@@ -39,18 +40,19 @@ public:
}
private:
RefPtr<Benchmark> mBenchmark;
};
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<MediaResource> resource =
new MockMediaResource("gizmo.mp4", NS_LITERAL_CSTRING("video/mp4"));
nsresult rv = resource->Open(nullptr);
EXPECT_TRUE(NS_SUCCEEDED(rv));
BenchmarkRunner runner(new Benchmark(new MP4Demuxer(resource)));
--- a/dom/media/mediasource/MediaSource.cpp
+++ b/dom/media/mediasource/MediaSource.cpp
@@ -67,18 +67,18 @@ namespace mozilla {
// * N/KN editions (Europe and Korea) of Windows 7/8/8.1/10 without the
// optional "Windows Media Feature Pack"
// 2. If H264 hardware acceleration is not available.
// 3. The CPU is considered to be fast enough
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() ||
java::HardwareCodecCapabilityUtils::HasHWVP9();
#else
return !mp4supported || !hwsupported || VP9Benchmark::IsVP9DecodeFast();
#endif
}