Bug 1191833: P1. Properly check webm mimetype against codec type. r=cpearce

Also move the logic inside WebMDecoder, this continue on with the logic used by MP4Decoder
This commit is contained in:
Jean-Yves Avenard 2015-12-03 17:36:36 +11:00
parent af7fa05328
commit cc0d27a37f
3 changed files with 85 additions and 24 deletions

View File

@ -154,32 +154,19 @@ IsWaveType(const nsACString& aType)
#endif
#ifdef MOZ_WEBM
static const char* const gWebMTypes[3] = {
"video/webm",
"audio/webm",
nullptr
};
static char const *const gWebMCodecs[7] = {
"vp8",
"vp8.0",
"vp9",
"vp9.0",
"vorbis",
"opus",
nullptr
};
static bool
IsWebMSupportedType(const nsACString& aType,
const nsAString& aCodecs = EmptyString())
{
return WebMDecoder::CanHandleMediaType(aType, aCodecs);
}
#endif
/* static */ bool
DecoderTraits::IsWebMTypeAndEnabled(const nsACString& aType)
{
#ifdef MOZ_WEBM
if (!MediaDecoder::IsWebMEnabled()) {
return false;
}
return CodecListContains(gWebMTypes, aType);
return IsWebMSupportedType(aType);
#endif
return false;
}
@ -395,7 +382,13 @@ DecoderTraits::CanHandleCodecsType(const char* aMIMEType,
#endif
#if !defined(MOZ_OMX_WEBM_DECODER)
if (IsWebMTypeAndEnabled(nsDependentCString(aMIMEType))) {
codecList = gWebMCodecs;
if (IsWebMSupportedType(nsDependentCString(aMIMEType), aRequestedCodecs)) {
return CANPLAY_YES;
} 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
@ -601,10 +594,12 @@ InstantiateDecoder(const nsACString& aType, MediaDecoderOwner* aOwner)
return decoder.forget();
}
#endif
if (DecoderTraits::IsWebMTypeAndEnabled(aType)) {
#ifdef MOZ_WEBM
if (IsWebMSupportedType(aType)) {
decoder = new WebMDecoder(aOwner);
return decoder.forget();
}
#endif
#ifdef MOZ_DIRECTSHOW
// Note: DirectShow should come before WMF, so that we prefer DirectShow's
// MP3 support over WMF's.
@ -671,11 +666,13 @@ MediaDecoderReader* DecoderTraits::CreateReader(const nsACString& aType, Abstrac
decoderReader = new AndroidMediaReader(aDecoder, aType);
} else
#endif
if (IsWebMTypeAndEnabled(aType)) {
#ifdef MOZ_WEBM
if (IsWebMSupportedType(aType)) {
decoderReader = Preferences::GetBool("media.format-reader.webm", true) ?
static_cast<MediaDecoderReader*>(new MediaFormatReader(aDecoder, new WebMDemuxer(aDecoder->GetResource()))) :
new WebMReader(aDecoder);
} else
#endif
#ifdef MOZ_DIRECTSHOW
if (IsDirectShowSupportedType(aType)) {
decoderReader = new DirectShowReader(aDecoder);
@ -706,7 +703,9 @@ bool DecoderTraits::IsSupportedInVideoDocument(const nsACString& aType)
(IsOmxSupportedType(aType) &&
!IsB2GSupportOnlyType(aType)) ||
#endif
IsWebMTypeAndEnabled(aType) ||
#ifdef MOZ_WEBM
IsWebMSupportedType(aType) ||
#endif
#ifdef MOZ_GSTREAMER
IsGStreamerSupportedType(aType) ||
#endif

View File

@ -10,6 +10,7 @@
#include "WebMDemuxer.h"
#include "WebMReader.h"
#include "WebMDecoder.h"
#include "VideoUtils.h"
namespace mozilla {
@ -23,5 +24,56 @@ MediaDecoderStateMachine* WebMDecoder::CreateStateMachine()
return new MediaDecoderStateMachine(this, reader);
}
/* static */
bool
WebMDecoder::IsEnabled()
{
return Preferences::GetBool("media.webm.enabled");
}
/* static */
bool
WebMDecoder::CanHandleMediaType(const nsACString& aMIMETypeExcludingCodecs,
const nsAString& aCodecs)
{
if (!IsEnabled()) {
return false;
}
const bool isWebMAudio = aMIMETypeExcludingCodecs.EqualsASCII("audio/webm");
const bool isWebMVideo = aMIMETypeExcludingCodecs.EqualsASCII("video/webm");
if (!isWebMAudio && !isWebMVideo) {
return false;
}
nsTArray<nsCString> codecMimes;
if (aCodecs.IsEmpty()) {
// WebM guarantees that the only codecs it contained are vp8, vp9, opus or vorbis.
return true;
}
// 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 (codec.EqualsLiteral("opus") || codec.EqualsLiteral("vorbis")) {
continue;
}
// Note: Only accept VP8/VP9 in a video content type, not in an audio
// content type.
if (isWebMVideo &&
(codec.EqualsLiteral("vp8") || codec.EqualsLiteral("vp8.0") ||
codec.EqualsLiteral("vp9") || codec.EqualsLiteral("vp9.0"))) {
continue;
}
// Some unsupported codec.
return false;
}
return true;
}
} // namespace mozilla

View File

@ -21,6 +21,16 @@ public:
return new WebMDecoder(aOwner);
}
virtual MediaDecoderStateMachine* CreateStateMachine();
// Returns true if the WebM backend is preffed on.
static bool IsEnabled();
// Returns true if aMIMEType is a type that we think we can render with the
// a WebM 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 whether the codecs string contains Opus/Vorbis or VP8/VP9.
static bool CanHandleMediaType(const nsACString& aMIMETypeExcludingCodecs,
const nsAString& aCodecs);
};
} // namespace mozilla