зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1211339 Part 2 - Make MP4Decoder::CanHandleMediaType() check all codecs are supported by a PDM before reporting support. r=jya
This commit is contained in:
Родитель
494f013e18
Коммит
aaf1f72ba5
|
@ -347,9 +347,7 @@ static bool
|
|||
IsMP4SupportedType(const nsACString& aType,
|
||||
const nsAString& aCodecs = EmptyString())
|
||||
{
|
||||
// MP4Decoder/Reader is currently used for MSE and mp4 files local playback.
|
||||
bool haveAAC, haveMP3, haveH264;
|
||||
return MP4Decoder::CanHandleMediaType(aType, aCodecs, haveAAC, haveH264, haveMP3);
|
||||
return MP4Decoder::CanHandleMediaType(aType, aCodecs);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
|
@ -469,6 +469,15 @@ LogToBrowserConsole(const nsAString& aMsg)
|
|||
console->LogStringMessage(msg.get());
|
||||
}
|
||||
|
||||
bool
|
||||
IsAACCodecString(const nsAString& aCodec)
|
||||
{
|
||||
return
|
||||
aCodec.EqualsLiteral("mp4a.40.2") || // MPEG4 AAC-LC
|
||||
aCodec.EqualsLiteral("mp4a.40.5") || // MPEG4 HE-AAC
|
||||
aCodec.EqualsLiteral("mp4a.67"); // MPEG2 AAC-LC}
|
||||
}
|
||||
|
||||
bool
|
||||
ParseCodecsString(const nsAString& aCodecs, nsTArray<nsString>& aOutCodecs)
|
||||
{
|
||||
|
|
|
@ -338,6 +338,9 @@ IsH264ContentType(const nsAString& aContentType);
|
|||
bool
|
||||
IsAACContentType(const nsAString& aContentType);
|
||||
|
||||
bool
|
||||
IsAACCodecString(const nsAString& aCodec);
|
||||
|
||||
} // end namespace mozilla
|
||||
|
||||
#endif
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
#include "mozilla/Logging.h"
|
||||
#include "nsMimeTypes.h"
|
||||
#include "nsContentTypeParser.h"
|
||||
#include "VideoUtils.h"
|
||||
|
||||
#ifdef XP_WIN
|
||||
#include "mozilla/WindowsVersion.h"
|
||||
|
@ -53,30 +54,7 @@ MediaDecoderStateMachine* MP4Decoder::CreateStateMachine()
|
|||
}
|
||||
|
||||
static bool
|
||||
IsSupportedAudioCodec(const nsAString& aCodec,
|
||||
bool& aOutContainsAAC,
|
||||
bool& aOutContainsMP3)
|
||||
{
|
||||
// AAC-LC or HE-AAC in M4A.
|
||||
aOutContainsAAC = aCodec.EqualsASCII("mp4a.40.2") // MPEG4 AAC-LC
|
||||
|| aCodec.EqualsASCII("mp4a.40.5") // MPEG4 HE-AAC
|
||||
|| aCodec.EqualsASCII("mp4a.67"); // MPEG2 AAC-LC
|
||||
if (aOutContainsAAC) {
|
||||
return true;
|
||||
}
|
||||
#ifndef MOZ_GONK_MEDIACODEC // B2G doesn't support MP3 in MP4 yet.
|
||||
aOutContainsMP3 = aCodec.EqualsASCII("mp3");
|
||||
if (aOutContainsMP3) {
|
||||
return true;
|
||||
}
|
||||
#else
|
||||
aOutContainsMP3 = false;
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool
|
||||
IsSupportedH264Codec(const nsAString& aCodec)
|
||||
IsWhitelistedH264Codec(const nsAString& aCodec)
|
||||
{
|
||||
int16_t profile = 0, level = 0;
|
||||
|
||||
|
@ -110,52 +88,74 @@ IsSupportedH264Codec(const nsAString& aCodec)
|
|||
|
||||
/* static */
|
||||
bool
|
||||
MP4Decoder::CanHandleMediaType(const nsACString& aType,
|
||||
const nsAString& aCodecs,
|
||||
bool& aOutContainsAAC,
|
||||
bool& aOutContainsH264,
|
||||
bool& aOutContainsMP3)
|
||||
MP4Decoder::CanHandleMediaType(const nsACString& aMIMETypeExcludingCodecs,
|
||||
const nsAString& aCodecs)
|
||||
{
|
||||
if (!IsEnabled()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (aType.EqualsASCII("audio/mp4") || aType.EqualsASCII("audio/x-m4a")) {
|
||||
return MP4Decoder::CanCreateAACDecoder() &&
|
||||
(aCodecs.IsEmpty() ||
|
||||
IsSupportedAudioCodec(aCodecs,
|
||||
aOutContainsAAC,
|
||||
aOutContainsMP3));
|
||||
// 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).
|
||||
if (!aMIMETypeExcludingCodecs.EqualsASCII("audio/mp4") &&
|
||||
!aMIMETypeExcludingCodecs.EqualsASCII("audio/x-m4a") &&
|
||||
!aMIMETypeExcludingCodecs.EqualsASCII("video/mp4") &&
|
||||
!aMIMETypeExcludingCodecs.EqualsASCII("video/x-m4v")) {
|
||||
return false;
|
||||
}
|
||||
|
||||
#ifdef MOZ_GONK_MEDIACODEC
|
||||
if (aType.EqualsASCII(VIDEO_3GPP)) {
|
||||
if (aMIMETypeExcludingCodecs.EqualsASCII(VIDEO_3GPP)) {
|
||||
return Preferences::GetBool("media.fragmented-mp4.gonk.enabled", false);
|
||||
}
|
||||
#endif
|
||||
if ((!aType.EqualsASCII("video/mp4") && !aType.EqualsASCII("video/x-m4v")) ||
|
||||
!MP4Decoder::CanCreateH264Decoder()) {
|
||||
return false;
|
||||
|
||||
nsTArray<nsCString> codecMimes;
|
||||
if (aCodecs.IsEmpty()) {
|
||||
// No codecs specified. Assume AAC/H.264
|
||||
if (aMIMETypeExcludingCodecs.EqualsLiteral("audio/mp4") ||
|
||||
aMIMETypeExcludingCodecs.EqualsLiteral("audio/x-m4a")) {
|
||||
codecMimes.AppendElement(NS_LITERAL_CSTRING("audio/mp4a-latm"));
|
||||
} else if (aMIMETypeExcludingCodecs.EqualsLiteral("video/mp4") ||
|
||||
aMIMETypeExcludingCodecs.EqualsLiteral("video/x-m4v")) {
|
||||
codecMimes.AppendElement(NS_LITERAL_CSTRING("video/avc"));
|
||||
}
|
||||
} else {
|
||||
// Verify that all the codecs specified are ones that we expect that
|
||||
// we can play.
|
||||
nsTArray<nsString> codecs;
|
||||
if (!ParseCodecsString(aCodecs, codecs)) {
|
||||
return false;
|
||||
}
|
||||
for (const nsString& codec : codecs) {
|
||||
if (IsAACCodecString(codec)) {
|
||||
codecMimes.AppendElement(NS_LITERAL_CSTRING("audio/mp4a-latm"));
|
||||
continue;
|
||||
}
|
||||
if (codec.EqualsLiteral("mp3")) {
|
||||
codecMimes.AppendElement(NS_LITERAL_CSTRING("audio/mpeg"));
|
||||
continue;
|
||||
}
|
||||
if (IsWhitelistedH264Codec(codec)) {
|
||||
codecMimes.AppendElement(NS_LITERAL_CSTRING("video/avc"));
|
||||
continue;
|
||||
}
|
||||
// Some unsupported codec.
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Verify that all the codecs specifed are ones that we expect that
|
||||
// we can play.
|
||||
nsTArray<nsString> codecs;
|
||||
if (!ParseCodecsString(aCodecs, codecs)) {
|
||||
// Verify that we have a PDM that supports the whitelisted types.
|
||||
PlatformDecoderModule::Init();
|
||||
nsRefPtr<PlatformDecoderModule> platform = PlatformDecoderModule::Create();
|
||||
if (!platform) {
|
||||
return false;
|
||||
}
|
||||
for (const nsString& codec : codecs) {
|
||||
if (IsSupportedAudioCodec(codec,
|
||||
aOutContainsAAC,
|
||||
aOutContainsMP3)) {
|
||||
continue;
|
||||
for (const nsCString& codecMime : codecMimes) {
|
||||
if (!platform->SupportsMimeType(codecMime)) {
|
||||
return false;
|
||||
}
|
||||
if (IsSupportedH264Codec(codec)) {
|
||||
aOutContainsH264 = true;
|
||||
continue;
|
||||
}
|
||||
// Some unsupported codec.
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
|
@ -173,10 +173,7 @@ MP4Decoder::CanHandleMediaType(const nsAString& aContentType)
|
|||
nsString codecs;
|
||||
parser.GetParameter("codecs", codecs);
|
||||
|
||||
bool ignoreAAC, ignoreH264, ignoreMP3;
|
||||
return CanHandleMediaType(NS_ConvertUTF16toUTF8(mimeType),
|
||||
codecs,
|
||||
ignoreAAC, ignoreH264, ignoreMP3);
|
||||
return CanHandleMediaType(NS_ConvertUTF16toUTF8(mimeType), codecs);
|
||||
}
|
||||
|
||||
static bool
|
||||
|
|
|
@ -29,11 +29,8 @@ public:
|
|||
// a MP4 platform decoder backend. If aCodecs is non emtpy, it is filled
|
||||
// with a comma-delimited list of codecs to check support for. Notes in
|
||||
// out params wether the codecs string contains AAC or H.264.
|
||||
static bool CanHandleMediaType(const nsACString& aMIMEType,
|
||||
const nsAString& aCodecs,
|
||||
bool& aOutContainsAAC,
|
||||
bool& aOutContainsH264,
|
||||
bool& aOutContainsMP3);
|
||||
static bool CanHandleMediaType(const nsACString& aMIMETypeExcludingCodecs,
|
||||
const nsAString& aCodecs);
|
||||
|
||||
static bool CanHandleMediaType(const nsAString& aMIMEType);
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче