Bug 814284 - Part 2: Move the logic of dealing with requested codecs down into DecoderTraits::CanHandleMediaType; r=cpearce

This commit is contained in:
Ehsan Akhgari 2012-11-22 13:49:37 -05:00
parent e83a5e9f35
commit 6248361b00
3 changed files with 64 additions and 63 deletions

View File

@ -41,7 +41,6 @@
#include "nsMediaError.h"
#include "MediaDecoder.h"
#include "nsICategoryManager.h"
#include "nsCharSeparatedTokenizer.h"
#include "MediaResource.h"
#include "nsIDOMHTMLVideoElement.h"
@ -2049,16 +2048,6 @@ void nsHTMLMediaElement::UnbindFromTree(bool aDeep,
nsGenericHTMLElement::UnbindFromTree(aDeep, aNullParent);
}
static bool
CodecListContains(char const *const * aCodecs, const nsAString& aCodec)
{
for (int32_t i = 0; aCodecs[i]; ++i) {
if (aCodec.EqualsASCII(aCodecs[i]))
return true;
}
return false;
}
/* static */
CanPlayStatus
nsHTMLMediaElement::GetCanPlay(const nsAString& aType)
@ -2069,39 +2058,13 @@ nsHTMLMediaElement::GetCanPlay(const nsAString& aType)
if (NS_FAILED(rv))
return CANPLAY_NO;
NS_ConvertUTF16toUTF8 mimeTypeUTF8(mimeType);
char const *const * supportedCodecs;
CanPlayStatus status = DecoderTraits::CanHandleMediaType(mimeTypeUTF8.get(),
&supportedCodecs);
if (status == CANPLAY_NO)
return CANPLAY_NO;
nsAutoString codecs;
rv = parser.GetParameter("codecs", codecs);
if (NS_FAILED(rv)) {
// Parameter not found or whatever
return status;
}
CanPlayStatus result = CANPLAY_YES;
// See http://www.rfc-editor.org/rfc/rfc4281.txt for the description
// of the 'codecs' parameter
nsCharSeparatedTokenizer tokenizer(codecs, ',');
bool expectMoreTokens = false;
while (tokenizer.hasMoreTokens()) {
const nsSubstring& token = tokenizer.nextToken();
if (!CodecListContains(supportedCodecs, token)) {
// Totally unsupported codec
return CANPLAY_NO;
}
expectMoreTokens = tokenizer.lastTokenEndedWithSeparator();
}
if (expectMoreTokens) {
// Last codec name was empty
return CANPLAY_NO;
}
return result;
NS_ConvertUTF16toUTF8 mimeTypeUTF8(mimeType);
return DecoderTraits::CanHandleMediaType(mimeTypeUTF8.get(),
NS_SUCCEEDED(rv),
codecs);
}
NS_IMETHODIMP

View File

@ -6,6 +6,7 @@
#include "DecoderTraits.h"
#include "MediaDecoder.h"
#include "nsCharSeparatedTokenizer.h"
#ifdef MOZ_MEDIA_PLUGINS
#include "MediaPluginHost.h"
#endif
@ -13,6 +14,16 @@
namespace mozilla
{
static bool
CodecListContains(char const *const * aCodecs, const nsAString& aCodec)
{
for (int32_t i = 0; aCodecs[i]; ++i) {
if (aCodec.EqualsASCII(aCodecs[i]))
return true;
}
return false;
}
#ifdef MOZ_RAW
static const char gRawTypes[2][16] = {
"video/x-raw",
@ -305,57 +316,82 @@ bool DecoderTraits::ShouldHandleMediaType(const char* aMIMEType)
/* static */
CanPlayStatus
DecoderTraits::CanHandleMediaType(const char* aMIMEType,
char const *const ** aCodecList)
bool aHaveRequestedCodecs,
const nsAString& aRequestedCodecs)
{
char const* const* codecList = nullptr;
CanPlayStatus result = CANPLAY_NO;
#ifdef MOZ_RAW
if (IsRawType(nsDependentCString(aMIMEType))) {
*aCodecList = gRawCodecs;
return CANPLAY_MAYBE;
codecList = gRawCodecs;
result = CANPLAY_MAYBE;
}
#endif
#ifdef MOZ_OGG
if (IsOggType(nsDependentCString(aMIMEType))) {
*aCodecList = MediaDecoder::IsOpusEnabled() ? gOggCodecsWithOpus : gOggCodecs;
return CANPLAY_MAYBE;
codecList = MediaDecoder::IsOpusEnabled() ? gOggCodecsWithOpus : gOggCodecs;
result = CANPLAY_MAYBE;
}
#endif
#ifdef MOZ_WAVE
if (IsWaveType(nsDependentCString(aMIMEType))) {
*aCodecList = gWaveCodecs;
return CANPLAY_MAYBE;
codecList = gWaveCodecs;
result = CANPLAY_MAYBE;
}
#endif
#ifdef MOZ_WEBM
if (IsWebMType(nsDependentCString(aMIMEType))) {
*aCodecList = gWebMCodecs;
return CANPLAY_YES;
codecList = gWebMCodecs;
result = CANPLAY_YES;
}
#endif
#ifdef MOZ_DASH
if (IsDASHMPDType(nsDependentCString(aMIMEType))) {
// DASH manifest uses WebM codecs only.
*aCodecList = gWebMCodecs;
return CANPLAY_YES;
codecList = gWebMCodecs;
result = CANPLAY_YES;
}
#endif
#ifdef MOZ_GSTREAMER
if (IsH264Type(nsDependentCString(aMIMEType))) {
*aCodecList = gH264Codecs;
return CANPLAY_MAYBE;
codecList = gH264Codecs;
result = CANPLAY_MAYBE;
}
#endif
#ifdef MOZ_WIDGET_GONK
if (IsOmxSupportedType(nsDependentCString(aMIMEType))) {
*aCodecList = gH264Codecs;
return CANPLAY_MAYBE;
codecList = gH264Codecs;
result = CANPLAY_MAYBE;
}
#endif
#ifdef MOZ_MEDIA_PLUGINS
if (MediaDecoder::IsMediaPluginsEnabled() && GetMediaPluginHost()->FindDecoder(nsDependentCString(aMIMEType), aCodecList))
return CANPLAY_MAYBE;
if (MediaDecoder::IsMediaPluginsEnabled() &&
GetMediaPluginHost()->FindDecoder(nsDependentCString(aMIMEType), &codecList))
result = CANPLAY_MAYBE;
#endif
return CANPLAY_NO;
if (result == CANPLAY_NO || !aHaveRequestedCodecs) {
return result;
}
// See http://www.rfc-editor.org/rfc/rfc4281.txt for the description
// of the 'codecs' parameter
nsCharSeparatedTokenizer tokenizer(aRequestedCodecs, ',');
bool expectMoreTokens = false;
while (tokenizer.hasMoreTokens()) {
const nsSubstring& token = tokenizer.nextToken();
if (!CodecListContains(codecList, token)) {
// Totally unsupported codec
return CANPLAY_NO;
}
expectMoreTokens = tokenizer.lastTokenEndedWithSeparator();
}
if (expectMoreTokens) {
// Last codec name was empty
return CANPLAY_NO;
}
return CANPLAY_YES;
}
}

View File

@ -22,11 +22,13 @@ class DecoderTraits {
public:
// Returns the CanPlayStatus indicating if we can handle this
// MIME type. The MIME type should not include the codecs parameter.
// If it returns anything other than CANPLAY_NO then it also
// returns a null-terminated list of supported codecs
// in *aSupportedCodecs. This list should not be freed, it is static data.
// That parameter should be passed in aCodecs, and will only be
// used if whether a given MIME type being handled depends on the
// codec that will be used. If the codecs parameter has not been
// specified, pass false in aHaveRequestedCodecs.
static CanPlayStatus CanHandleMediaType(const char* aMIMEType,
char const *const ** aSupportedCodecs);
bool aHaveRequestedCodecs,
const nsAString& aRequestedCodecs);
// Returns true if we should handle this MIME type when it appears
// as an <object> or as a toplevel page. If, in practice, our support