From 980fea9d8f13fdb18c6a50c0aef4906d7d557cca Mon Sep 17 00:00:00 2001 From: Ehsan Akhgari Date: Wed, 21 Nov 2012 22:10:41 -0500 Subject: [PATCH] Bug 814284 - Part 1: Refactor the code necessary for detection of codec support out of nsHTMLMediaElement; r=cpearce --- content/base/src/nsContentUtils.cpp | 9 +- .../html/content/public/nsHTMLMediaElement.h | 66 +--- .../html/content/src/nsHTMLMediaElement.cpp | 364 +----------------- content/media/DecoderTraits.cpp | 362 +++++++++++++++++ content/media/DecoderTraits.h | 75 ++++ content/media/Makefile.in | 2 + layout/build/nsContentDLF.cpp | 6 +- 7 files changed, 458 insertions(+), 426 deletions(-) create mode 100644 content/media/DecoderTraits.cpp create mode 100644 content/media/DecoderTraits.h diff --git a/content/base/src/nsContentUtils.cpp b/content/base/src/nsContentUtils.cpp index 0fd31f5593ea..f8109bd64d66 100644 --- a/content/base/src/nsContentUtils.cpp +++ b/content/base/src/nsContentUtils.cpp @@ -169,6 +169,7 @@ #include "nsSandboxFlags.h" #include "nsSVGFeatures.h" #include "MediaDecoder.h" +#include "DecoderTraits.h" #include "nsWrapperCacheInlines.h" @@ -6591,7 +6592,7 @@ nsContentUtils::FindInternalContentViewer(const char* aType, #ifdef MOZ_MEDIA #ifdef MOZ_OGG - if (nsHTMLMediaElement::IsOggType(nsDependentCString(aType))) { + if (DecoderTraits::IsOggType(nsDependentCString(aType))) { docFactory = do_GetService("@mozilla.org/content/document-loader-factory;1"); if (docFactory && aLoaderType) { *aLoaderType = TYPE_CONTENT; @@ -6601,7 +6602,7 @@ nsContentUtils::FindInternalContentViewer(const char* aType, #endif #ifdef MOZ_WEBM - if (nsHTMLMediaElement::IsWebMType(nsDependentCString(aType))) { + if (DecoderTraits::IsWebMType(nsDependentCString(aType))) { docFactory = do_GetService("@mozilla.org/content/document-loader-factory;1"); if (docFactory && aLoaderType) { *aLoaderType = TYPE_CONTENT; @@ -6611,7 +6612,7 @@ nsContentUtils::FindInternalContentViewer(const char* aType, #endif #ifdef MOZ_GSTREAMER - if (nsHTMLMediaElement::IsGStreamerSupportedType(nsDependentCString(aType))) { + if (DecoderTraits::IsGStreamerSupportedType(nsDependentCString(aType))) { docFactory = do_GetService("@mozilla.org/content/document-loader-factory;1"); if (docFactory && aLoaderType) { *aLoaderType = TYPE_CONTENT; @@ -6622,7 +6623,7 @@ nsContentUtils::FindInternalContentViewer(const char* aType, #ifdef MOZ_MEDIA_PLUGINS if (mozilla::MediaDecoder::IsMediaPluginsEnabled() && - nsHTMLMediaElement::IsMediaPluginsType(nsDependentCString(aType))) { + DecoderTraits::IsMediaPluginsType(nsDependentCString(aType))) { docFactory = do_GetService("@mozilla.org/content/document-loader-factory;1"); if (docFactory && aLoaderType) { *aLoaderType = TYPE_CONTENT; diff --git a/content/html/content/public/nsHTMLMediaElement.h b/content/html/content/public/nsHTMLMediaElement.h index db89b2d1ad50..22b9e62b0af8 100644 --- a/content/html/content/public/nsHTMLMediaElement.h +++ b/content/html/content/public/nsHTMLMediaElement.h @@ -24,6 +24,7 @@ #include "nsTimeRanges.h" #include "nsIDOMWakeLock.h" #include "AudioChannelCommon.h" +#include "DecoderTraits.h" // Define to output information on decoding and painting framerate /* #define DEBUG_FRAME_RATE 1 */ @@ -58,12 +59,6 @@ public: friend class DASHDecoder; #endif - enum CanPlayStatus { - CANPLAY_NO, - CANPLAY_MAYBE, - CANPLAY_YES - }; - mozilla::CORSMode GetCORSMode() { return mCORSMode; } @@ -254,66 +249,9 @@ public: // main thread when/if the size changes. void UpdateMediaSize(nsIntSize size); - // 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. - static CanPlayStatus CanHandleMediaType(const char* aMIMEType, - char const *const ** aSupportedCodecs); - // Returns the CanPlayStatus indicating if we can handle the // full MIME type including the optional codecs parameter. - static CanPlayStatus GetCanPlay(const nsAString& aType); - - // Returns true if we should handle this MIME type when it appears - // as an or as a toplevel page. If, in practice, our support - // for the type is more limited than appears in the wild, we should return - // false here even if CanHandleMediaType would return true. - static bool ShouldHandleMediaType(const char* aMIMEType); - -#ifdef MOZ_OGG - static bool IsOggType(const nsACString& aType); - static const char gOggTypes[3][16]; - static char const *const gOggCodecs[3]; - static char const *const gOggCodecsWithOpus[4]; -#endif - -#ifdef MOZ_WAVE - static bool IsWaveType(const nsACString& aType); - static const char gWaveTypes[4][15]; - static char const *const gWaveCodecs[2]; -#endif - -#ifdef MOZ_WEBM - static bool IsWebMType(const nsACString& aType); - static const char gWebMTypes[2][11]; - static char const *const gWebMCodecs[4]; -#endif - -#ifdef MOZ_GSTREAMER - static bool IsGStreamerSupportedType(const nsACString& aType); - static bool IsH264Type(const nsACString& aType); - static const char gH264Types[3][16]; -#endif - -#ifdef MOZ_WIDGET_GONK - static bool IsOmxSupportedType(const nsACString& aType); - static const char gOmxTypes[5][16]; -#endif - -#if defined(MOZ_GSTREAMER) || defined(MOZ_WIDGET_GONK) - static char const *const gH264Codecs[9]; -#endif - -#ifdef MOZ_MEDIA_PLUGINS - static bool IsMediaPluginsType(const nsACString& aType); -#endif - -#ifdef MOZ_DASH - static bool IsDASHMPDType(const nsACString& aType); - static const char gDASHMPDTypes[1][21]; -#endif + static mozilla::CanPlayStatus GetCanPlay(const nsAString& aType); /** * Get the mime type for this element. diff --git a/content/html/content/src/nsHTMLMediaElement.cpp b/content/html/content/src/nsHTMLMediaElement.cpp index 0e663c255bc7..cc8275b98f42 100644 --- a/content/html/content/src/nsHTMLMediaElement.cpp +++ b/content/html/content/src/nsHTMLMediaElement.cpp @@ -2049,328 +2049,6 @@ void nsHTMLMediaElement::UnbindFromTree(bool aDeep, nsGenericHTMLElement::UnbindFromTree(aDeep, aNullParent); } -#ifdef MOZ_RAW -static const char gRawTypes[2][16] = { - "video/x-raw", - "video/x-raw-yuv" -}; - -static const char* gRawCodecs[1] = { - nullptr -}; - -static bool IsRawType(const nsACString& aType) -{ - if (!MediaDecoder::IsRawEnabled()) { - return false; - } - - for (uint32_t i = 0; i < ArrayLength(gRawTypes); ++i) { - if (aType.EqualsASCII(gRawTypes[i])) { - return true; - } - } - - return false; -} -#endif -#ifdef MOZ_OGG -// See http://www.rfc-editor.org/rfc/rfc5334.txt for the definitions -// of Ogg media types and codec types -const char nsHTMLMediaElement::gOggTypes[3][16] = { - "video/ogg", - "audio/ogg", - "application/ogg" -}; - -char const *const nsHTMLMediaElement::gOggCodecs[3] = { - "vorbis", - "theora", - nullptr -}; - -char const *const nsHTMLMediaElement::gOggCodecsWithOpus[4] = { - "vorbis", - "opus", - "theora", - nullptr -}; - -bool -nsHTMLMediaElement::IsOggType(const nsACString& aType) -{ - if (!MediaDecoder::IsOggEnabled()) { - return false; - } - - for (uint32_t i = 0; i < ArrayLength(gOggTypes); ++i) { - if (aType.EqualsASCII(gOggTypes[i])) { - return true; - } - } - - return false; -} -#endif - -#ifdef MOZ_WAVE -// See http://www.rfc-editor.org/rfc/rfc2361.txt for the definitions -// of WAVE media types and codec types. However, the audio/vnd.wave -// MIME type described there is not used. -const char nsHTMLMediaElement::gWaveTypes[4][15] = { - "audio/x-wav", - "audio/wav", - "audio/wave", - "audio/x-pn-wav" -}; - -char const *const nsHTMLMediaElement::gWaveCodecs[2] = { - "1", // Microsoft PCM Format - nullptr -}; - -bool -nsHTMLMediaElement::IsWaveType(const nsACString& aType) -{ - if (!MediaDecoder::IsWaveEnabled()) { - return false; - } - - for (uint32_t i = 0; i < ArrayLength(gWaveTypes); ++i) { - if (aType.EqualsASCII(gWaveTypes[i])) { - return true; - } - } - - return false; -} -#endif - -#ifdef MOZ_WEBM -const char nsHTMLMediaElement::gWebMTypes[2][11] = { - "video/webm", - "audio/webm" -}; - -char const *const nsHTMLMediaElement::gWebMCodecs[4] = { - "vp8", - "vp8.0", - "vorbis", - nullptr -}; - -bool -nsHTMLMediaElement::IsWebMType(const nsACString& aType) -{ - if (!MediaDecoder::IsWebMEnabled()) { - return false; - } - - for (uint32_t i = 0; i < ArrayLength(gWebMTypes); ++i) { - if (aType.EqualsASCII(gWebMTypes[i])) { - return true; - } - } - - return false; -} -#endif - -#if defined(MOZ_GSTREAMER) || defined(MOZ_WIDGET_GONK) -char const *const nsHTMLMediaElement::gH264Codecs[9] = { - "avc1.42E01E", // H.264 Constrained Baseline Profile Level 3.0 - "avc1.42001E", // H.264 Baseline Profile Level 3.0 - "avc1.58A01E", // H.264 Extended Profile Level 3.0 - "avc1.4D401E", // H.264 Main Profile Level 3.0 - "avc1.64001E", // H.264 High Profile Level 3.0 - "avc1.64001F", // H.264 High Profile Level 3.1 - "mp4v.20.3", // 3GPP - "mp4a.40.2", // AAC-LC - nullptr -}; -#endif - -#ifdef MOZ_GSTREAMER -const char nsHTMLMediaElement::gH264Types[3][16] = { - "video/mp4", - "video/3gpp", - "video/quicktime", -}; - -bool -nsHTMLMediaElement::IsH264Type(const nsACString& aType) -{ - for (uint32_t i = 0; i < ArrayLength(gH264Types); ++i) { - if (aType.EqualsASCII(gH264Types[i])) { - return true; - } - } - return false; -} -#endif - -#ifdef MOZ_WIDGET_GONK -const char nsHTMLMediaElement::gOmxTypes[5][16] = { - "audio/mpeg", - "audio/mp4", - "video/mp4", - "video/3gpp", - "video/quicktime", -}; - -bool -nsHTMLMediaElement::IsOmxSupportedType(const nsACString& aType) -{ - if (!MediaDecoder::IsOmxEnabled()) { - return false; - } - - for (uint32_t i = 0; i < ArrayLength(gOmxTypes); ++i) { - if (aType.EqualsASCII(gOmxTypes[i])) { - return true; - } - } - - return false; -} -#endif - -#ifdef MOZ_MEDIA_PLUGINS -bool -nsHTMLMediaElement::IsMediaPluginsType(const nsACString& aType) -{ - if (!MediaDecoder::IsMediaPluginsEnabled()) { - return false; - } - - static const char* supportedTypes[] = { - "audio/mpeg", "audio/mp4", "video/mp4" - }; - for (uint32_t i = 0; i < ArrayLength(supportedTypes); ++i) { - if (aType.EqualsASCII(supportedTypes[i])) { - return true; - } - } - return false; -} -#endif - -#ifdef MOZ_DASH -/* static */ -const char nsHTMLMediaElement::gDASHMPDTypes[1][21] = { - "application/dash+xml" -}; - -/* static */ -bool -nsHTMLMediaElement::IsDASHMPDType(const nsACString& aType) -{ - if (!MediaDecoder::IsDASHEnabled()) { - return false; - } - - for (uint32_t i = 0; i < ArrayLength(gDASHMPDTypes); ++i) { - if (aType.EqualsASCII(gDASHMPDTypes[i])) { - return true; - } - } - - return false; -} -#endif - -/* static */ -nsHTMLMediaElement::CanPlayStatus -nsHTMLMediaElement::CanHandleMediaType(const char* aMIMEType, - char const *const ** aCodecList) -{ -#ifdef MOZ_RAW - if (IsRawType(nsDependentCString(aMIMEType))) { - *aCodecList = gRawCodecs; - return CANPLAY_MAYBE; - } -#endif -#ifdef MOZ_OGG - if (IsOggType(nsDependentCString(aMIMEType))) { - *aCodecList = MediaDecoder::IsOpusEnabled() ? gOggCodecsWithOpus : gOggCodecs; - return CANPLAY_MAYBE; - } -#endif -#ifdef MOZ_WAVE - if (IsWaveType(nsDependentCString(aMIMEType))) { - *aCodecList = gWaveCodecs; - return CANPLAY_MAYBE; - } -#endif -#ifdef MOZ_WEBM - if (IsWebMType(nsDependentCString(aMIMEType))) { - *aCodecList = gWebMCodecs; - return CANPLAY_YES; - } -#endif -#ifdef MOZ_DASH - if (IsDASHMPDType(nsDependentCString(aMIMEType))) { - // DASH manifest uses WebM codecs only. - *aCodecList = gWebMCodecs; - return CANPLAY_YES; - } -#endif - -#ifdef MOZ_GSTREAMER - if (IsH264Type(nsDependentCString(aMIMEType))) { - *aCodecList = gH264Codecs; - return CANPLAY_MAYBE; - } -#endif -#ifdef MOZ_WIDGET_GONK - if (IsOmxSupportedType(nsDependentCString(aMIMEType))) { - *aCodecList = gH264Codecs; - return CANPLAY_MAYBE; - } -#endif -#ifdef MOZ_MEDIA_PLUGINS - if (MediaDecoder::IsMediaPluginsEnabled() && GetMediaPluginHost()->FindDecoder(nsDependentCString(aMIMEType), aCodecList)) - return CANPLAY_MAYBE; -#endif - return CANPLAY_NO; -} - -/* static */ -bool nsHTMLMediaElement::ShouldHandleMediaType(const char* aMIMEType) -{ -#ifdef MOZ_RAW - if (IsRawType(nsDependentCString(aMIMEType))) - return true; -#endif -#ifdef MOZ_OGG - if (IsOggType(nsDependentCString(aMIMEType))) - return true; -#endif -#ifdef MOZ_WEBM - if (IsWebMType(nsDependentCString(aMIMEType))) - return true; -#endif -#ifdef MOZ_GSTREAMER - if (IsH264Type(nsDependentCString(aMIMEType))) - return true; -#endif -#ifdef MOZ_WIDGET_GONK - if (IsOmxSupportedType(nsDependentCString(aMIMEType))) { - return true; - } -#endif -#ifdef MOZ_MEDIA_PLUGINS - if (MediaDecoder::IsMediaPluginsEnabled() && GetMediaPluginHost()->FindDecoder(nsDependentCString(aMIMEType), NULL)) - return true; -#endif - // We should not return true for Wave types, since there are some - // Wave codecs actually in use in the wild that we don't support, and - // we should allow those to be handled by plugins or helper apps. - // Furthermore people can play Wave files on most platforms by other - // means. - return false; -} - static bool CodecListContains(char const *const * aCodecs, const nsAString& aCodec) { @@ -2382,7 +2060,7 @@ CodecListContains(char const *const * aCodecs, const nsAString& aCodec) } /* static */ -nsHTMLMediaElement::CanPlayStatus +CanPlayStatus nsHTMLMediaElement::GetCanPlay(const nsAString& aType) { nsContentTypeParser parser(aType); @@ -2393,8 +2071,8 @@ nsHTMLMediaElement::GetCanPlay(const nsAString& aType) NS_ConvertUTF16toUTF8 mimeTypeUTF8(mimeType); char const *const * supportedCodecs; - CanPlayStatus status = CanHandleMediaType(mimeTypeUTF8.get(), - &supportedCodecs); + CanPlayStatus status = DecoderTraits::CanHandleMediaType(mimeTypeUTF8.get(), + &supportedCodecs); if (status == CANPLAY_NO) return CANPLAY_NO; @@ -2444,28 +2122,6 @@ nsHTMLMediaElement::CanPlayType(const nsAString& aType, nsAString& aResult) return NS_OK; } -#ifdef MOZ_GSTREAMER -bool -nsHTMLMediaElement::IsGStreamerSupportedType(const nsACString& aMimeType) -{ - if (!MediaDecoder::IsGStreamerEnabled()) - return false; - if (IsH264Type(aMimeType)) - return true; - if (!Preferences::GetBool("media.prefer-gstreamer", false)) - return false; -#ifdef MOZ_WEBM - if (IsWebMType(aMimeType)) - return true; -#endif -#ifdef MOZ_OGG - if (IsOggType(aMimeType)) - return true; -#endif - return false; -} -#endif - already_AddRefed nsHTMLMediaElement::CreateDecoder(const nsACString& aType) { @@ -2473,7 +2129,7 @@ nsHTMLMediaElement::CreateDecoder(const nsACString& aType) #ifdef MOZ_GSTREAMER // When enabled, use GStreamer for H.264, but not for codecs handled by our // bundled decoders, unless the "media.prefer-gstreamer" pref is set. - if (IsGStreamerSupportedType(aType)) { + if (DecoderTraits::IsGStreamerSupportedType(aType)) { nsRefPtr decoder = new GStreamerDecoder(); if (decoder->Init(this)) { return decoder.forget(); @@ -2482,7 +2138,7 @@ nsHTMLMediaElement::CreateDecoder(const nsACString& aType) #endif #ifdef MOZ_RAW - if (IsRawType(aType)) { + if (DecoderTraits::IsRawType(aType)) { nsRefPtr decoder = new RawDecoder(); if (decoder->Init(this)) { return decoder.forget(); @@ -2490,7 +2146,7 @@ nsHTMLMediaElement::CreateDecoder(const nsACString& aType) } #endif #ifdef MOZ_OGG - if (IsOggType(aType)) { + if (DecoderTraits::IsOggType(aType)) { nsRefPtr decoder = new OggDecoder(); if (decoder->Init(this)) { return decoder.forget(); @@ -2498,7 +2154,7 @@ nsHTMLMediaElement::CreateDecoder(const nsACString& aType) } #endif #ifdef MOZ_WAVE - if (IsWaveType(aType)) { + if (DecoderTraits::IsWaveType(aType)) { nsRefPtr decoder = new WaveDecoder(); if (decoder->Init(this)) { return decoder.forget(); @@ -2506,7 +2162,7 @@ nsHTMLMediaElement::CreateDecoder(const nsACString& aType) } #endif #ifdef MOZ_WIDGET_GONK - if (IsOmxSupportedType(aType)) { + if (DecoderTraits::IsOmxSupportedType(aType)) { nsRefPtr decoder = new MediaOmxDecoder(); if (decoder->Init(this)) { return decoder.forget(); @@ -2522,7 +2178,7 @@ nsHTMLMediaElement::CreateDecoder(const nsACString& aType) } #endif #ifdef MOZ_WEBM - if (IsWebMType(aType)) { + if (DecoderTraits::IsWebMType(aType)) { nsRefPtr decoder = new WebMDecoder(); if (decoder->Init(this)) { return decoder.forget(); @@ -2531,7 +2187,7 @@ nsHTMLMediaElement::CreateDecoder(const nsACString& aType) #endif #ifdef MOZ_DASH - if (IsDASHMPDType(aType)) { + if (DecoderTraits::IsDASHMPDType(aType)) { nsRefPtr decoder = new DASHDecoder(); if (decoder->Init(this)) { return decoder.forget(); diff --git a/content/media/DecoderTraits.cpp b/content/media/DecoderTraits.cpp new file mode 100644 index 000000000000..49a4d4d520b4 --- /dev/null +++ b/content/media/DecoderTraits.cpp @@ -0,0 +1,362 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim:set ts=2 sw=2 sts=2 et cindent: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * 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 "DecoderTraits.h" +#include "MediaDecoder.h" +#ifdef MOZ_MEDIA_PLUGINS +#include "MediaPluginHost.h" +#endif + +namespace mozilla +{ + +#ifdef MOZ_RAW +static const char gRawTypes[2][16] = { + "video/x-raw", + "video/x-raw-yuv" +}; + +static const char* gRawCodecs[1] = { + nullptr +}; + +/* static */ +bool +DecoderTraits::IsRawType(const nsACString& aType) +{ + if (!MediaDecoder::IsRawEnabled()) { + return false; + } + + for (uint32_t i = 0; i < ArrayLength(gRawTypes); ++i) { + if (aType.EqualsASCII(gRawTypes[i])) { + return true; + } + } + + return false; +} +#endif + +#ifdef MOZ_OGG +// See http://www.rfc-editor.org/rfc/rfc5334.txt for the definitions +// of Ogg media types and codec types +static const char gOggTypes[3][16] = { + "video/ogg", + "audio/ogg", + "application/ogg" +}; + +static char const *const gOggCodecs[3] = { + "vorbis", + "theora", + nullptr +}; + +static char const *const gOggCodecsWithOpus[4] = { + "vorbis", + "opus", + "theora", + nullptr +}; + +bool +DecoderTraits::IsOggType(const nsACString& aType) +{ + if (!MediaDecoder::IsOggEnabled()) { + return false; + } + + for (uint32_t i = 0; i < ArrayLength(gOggTypes); ++i) { + if (aType.EqualsASCII(gOggTypes[i])) { + return true; + } + } + + return false; +} +#endif + +#ifdef MOZ_WAVE +// See http://www.rfc-editor.org/rfc/rfc2361.txt for the definitions +// of WAVE media types and codec types. However, the audio/vnd.wave +// MIME type described there is not used. +static const char gWaveTypes[4][15] = { + "audio/x-wav", + "audio/wav", + "audio/wave", + "audio/x-pn-wav" +}; + +static char const *const gWaveCodecs[2] = { + "1", // Microsoft PCM Format + nullptr +}; + +bool +DecoderTraits::IsWaveType(const nsACString& aType) +{ + if (!MediaDecoder::IsWaveEnabled()) { + return false; + } + + for (uint32_t i = 0; i < ArrayLength(gWaveTypes); ++i) { + if (aType.EqualsASCII(gWaveTypes[i])) { + return true; + } + } + + return false; +} +#endif + +#ifdef MOZ_WEBM +static const char gWebMTypes[2][11] = { + "video/webm", + "audio/webm" +}; + +static char const *const gWebMCodecs[4] = { + "vp8", + "vp8.0", + "vorbis", + nullptr +}; + +bool +DecoderTraits::IsWebMType(const nsACString& aType) +{ + if (!MediaDecoder::IsWebMEnabled()) { + return false; + } + + for (uint32_t i = 0; i < ArrayLength(gWebMTypes); ++i) { + if (aType.EqualsASCII(gWebMTypes[i])) { + return true; + } + } + + return false; +} +#endif + +#ifdef MOZ_GSTREAMER +static const char gH264Types[3][16] = { + "video/mp4", + "video/3gpp", + "video/quicktime", +}; + +bool +DecoderTraits::IsGStreamerSupportedType(const nsACString& aMimeType) +{ + if (!MediaDecoder::IsGStreamerEnabled()) + return false; + if (IsH264Type(aMimeType)) + return true; + if (!Preferences::GetBool("media.prefer-gstreamer", false)) + return false; +#ifdef MOZ_WEBM + if (IsWebMType(aMimeType)) + return true; +#endif +#ifdef MOZ_OGG + if (IsOggType(aMimeType)) + return true; +#endif + return false; +} + +bool +DecoderTraits::IsH264Type(const nsACString& aType) +{ + for (uint32_t i = 0; i < ArrayLength(gH264Types); ++i) { + if (aType.EqualsASCII(gH264Types[i])) { + return true; + } + } + return false; +} +#endif + +#ifdef MOZ_WIDGET_GONK +static const char gOmxTypes[5][16] = { + "audio/mpeg", + "audio/mp4", + "video/mp4", + "video/3gpp", + "video/quicktime", +}; + +bool +DecoderTraits::IsOmxSupportedType(const nsACString& aType) +{ + if (!MediaDecoder::IsOmxEnabled()) { + return false; + } + + for (uint32_t i = 0; i < ArrayLength(gOmxTypes); ++i) { + if (aType.EqualsASCII(gOmxTypes[i])) { + return true; + } + } + + return false; +} +#endif + +#if defined(MOZ_GSTREAMER) || defined(MOZ_WIDGET_GONK) +static char const *const gH264Codecs[9] = { + "avc1.42E01E", // H.264 Constrained Baseline Profile Level 3.0 + "avc1.42001E", // H.264 Baseline Profile Level 3.0 + "avc1.58A01E", // H.264 Extended Profile Level 3.0 + "avc1.4D401E", // H.264 Main Profile Level 3.0 + "avc1.64001E", // H.264 High Profile Level 3.0 + "avc1.64001F", // H.264 High Profile Level 3.1 + "mp4v.20.3", // 3GPP + "mp4a.40.2", // AAC-LC + nullptr +}; +#endif + +#ifdef MOZ_MEDIA_PLUGINS +bool +DecoderTraits::IsMediaPluginsType(const nsACString& aType) +{ + if (!MediaDecoder::IsMediaPluginsEnabled()) { + return false; + } + + static const char* supportedTypes[] = { + "audio/mpeg", "audio/mp4", "video/mp4" + }; + for (uint32_t i = 0; i < ArrayLength(supportedTypes); ++i) { + if (aType.EqualsASCII(supportedTypes[i])) { + return true; + } + } + return false; +} +#endif + +#ifdef MOZ_DASH +/* static */ +static const char gDASHMPDTypes[1][21] = { + "application/dash+xml" +}; + +/* static */ +bool +DecoderTraits::IsDASHMPDType(const nsACString& aType) +{ + if (!MediaDecoder::IsDASHEnabled()) { + return false; + } + + for (uint32_t i = 0; i < ArrayLength(gDASHMPDTypes); ++i) { + if (aType.EqualsASCII(gDASHMPDTypes[i])) { + return true; + } + } + + return false; +} +#endif + +/* static */ +bool DecoderTraits::ShouldHandleMediaType(const char* aMIMEType) +{ +#ifdef MOZ_RAW + if (IsRawType(nsDependentCString(aMIMEType))) + return true; +#endif +#ifdef MOZ_OGG + if (IsOggType(nsDependentCString(aMIMEType))) + return true; +#endif +#ifdef MOZ_WEBM + if (IsWebMType(nsDependentCString(aMIMEType))) + return true; +#endif +#ifdef MOZ_GSTREAMER + if (IsH264Type(nsDependentCString(aMIMEType))) + return true; +#endif +#ifdef MOZ_WIDGET_GONK + if (IsOmxSupportedType(nsDependentCString(aMIMEType))) { + return true; + } +#endif +#ifdef MOZ_MEDIA_PLUGINS + if (MediaDecoder::IsMediaPluginsEnabled() && GetMediaPluginHost()->FindDecoder(nsDependentCString(aMIMEType), NULL)) + return true; +#endif + // We should not return true for Wave types, since there are some + // Wave codecs actually in use in the wild that we don't support, and + // we should allow those to be handled by plugins or helper apps. + // Furthermore people can play Wave files on most platforms by other + // means. + return false; +} + +/* static */ +CanPlayStatus +DecoderTraits::CanHandleMediaType(const char* aMIMEType, + char const *const ** aCodecList) +{ +#ifdef MOZ_RAW + if (IsRawType(nsDependentCString(aMIMEType))) { + *aCodecList = gRawCodecs; + return CANPLAY_MAYBE; + } +#endif +#ifdef MOZ_OGG + if (IsOggType(nsDependentCString(aMIMEType))) { + *aCodecList = MediaDecoder::IsOpusEnabled() ? gOggCodecsWithOpus : gOggCodecs; + return CANPLAY_MAYBE; + } +#endif +#ifdef MOZ_WAVE + if (IsWaveType(nsDependentCString(aMIMEType))) { + *aCodecList = gWaveCodecs; + return CANPLAY_MAYBE; + } +#endif +#ifdef MOZ_WEBM + if (IsWebMType(nsDependentCString(aMIMEType))) { + *aCodecList = gWebMCodecs; + return CANPLAY_YES; + } +#endif +#ifdef MOZ_DASH + if (IsDASHMPDType(nsDependentCString(aMIMEType))) { + // DASH manifest uses WebM codecs only. + *aCodecList = gWebMCodecs; + return CANPLAY_YES; + } +#endif + +#ifdef MOZ_GSTREAMER + if (IsH264Type(nsDependentCString(aMIMEType))) { + *aCodecList = gH264Codecs; + return CANPLAY_MAYBE; + } +#endif +#ifdef MOZ_WIDGET_GONK + if (IsOmxSupportedType(nsDependentCString(aMIMEType))) { + *aCodecList = gH264Codecs; + return CANPLAY_MAYBE; + } +#endif +#ifdef MOZ_MEDIA_PLUGINS + if (MediaDecoder::IsMediaPluginsEnabled() && GetMediaPluginHost()->FindDecoder(nsDependentCString(aMIMEType), aCodecList)) + return CANPLAY_MAYBE; +#endif + return CANPLAY_NO; +} + +} + diff --git a/content/media/DecoderTraits.h b/content/media/DecoderTraits.h new file mode 100644 index 000000000000..6ae023d2bd16 --- /dev/null +++ b/content/media/DecoderTraits.h @@ -0,0 +1,75 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim:set ts=2 sw=2 sts=2 et cindent: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * 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/. */ + +#ifndef DecoderTraits_h_ +#define DecoderTraits_h_ + +#include "nsAString.h" + +namespace mozilla +{ + +enum CanPlayStatus { + CANPLAY_NO, + CANPLAY_MAYBE, + CANPLAY_YES +}; + +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. + static CanPlayStatus CanHandleMediaType(const char* aMIMEType, + char const *const ** aSupportedCodecs); + + // Returns true if we should handle this MIME type when it appears + // as an or as a toplevel page. If, in practice, our support + // for the type is more limited than appears in the wild, we should return + // false here even if CanHandleMediaType would return true. + static bool ShouldHandleMediaType(const char* aMIMEType); + +#ifdef MOZ_RAW + static bool IsRawType(const nsACString& aType); +#endif + +#ifdef MOZ_OGG + static bool IsOggType(const nsACString& aType); +#endif + +#ifdef MOZ_WAVE + static bool IsWaveType(const nsACString& aType); +#endif + +#ifdef MOZ_WEBM + static bool IsWebMType(const nsACString& aType); +#endif + +#ifdef MOZ_GSTREAMER + static bool IsGStreamerSupportedType(const nsACString& aType); + static bool IsH264Type(const nsACString& aType); +#endif + +#ifdef MOZ_WIDGET_GONK + static bool IsOmxSupportedType(const nsACString& aType); +#endif + +#ifdef MOZ_MEDIA_PLUGINS + static bool IsMediaPluginsType(const nsACString& aType); +#endif + +#ifdef MOZ_DASH + static bool IsDASHMPDType(const nsACString& aType); +#endif + +}; + +} + +#endif + diff --git a/content/media/Makefile.in b/content/media/Makefile.in index b1481aecc69c..7d7917855c0c 100644 --- a/content/media/Makefile.in +++ b/content/media/Makefile.in @@ -18,6 +18,7 @@ EXPORTS = \ AbstractMediaDecoder.h \ AudioSampleFormat.h \ AudioSegment.h \ + DecoderTraits.h \ FileBlockCache.h \ MediaDecoderOwner.h \ MediaResource.h \ @@ -40,6 +41,7 @@ EXPORTS = \ CPPSRCS = \ AudioSegment.cpp \ + DecoderTraits.cpp \ FileBlockCache.cpp \ MediaResource.cpp \ MediaStreamGraph.cpp \ diff --git a/layout/build/nsContentDLF.cpp b/layout/build/nsContentDLF.cpp index 16b3932b7227..4a38c9fb32ab 100644 --- a/layout/build/nsContentDLF.cpp +++ b/layout/build/nsContentDLF.cpp @@ -23,13 +23,11 @@ #include "nsNetUtil.h" #include "nsCRT.h" #include "nsIViewSourceChannel.h" -#ifdef MOZ_MEDIA -#include "nsHTMLMediaElement.h" -#endif #include "nsContentUtils.h" #include "imgLoader.h" #include "nsCharsetSource.h" #include "nsMimeTypes.h" +#include "DecoderTraits.h" // plugins @@ -249,7 +247,7 @@ nsContentDLF::CreateInstance(const char* aCommand, } #ifdef MOZ_MEDIA - if (nsHTMLMediaElement::ShouldHandleMediaType(aContentType)) { + if (mozilla::DecoderTraits::ShouldHandleMediaType(aContentType)) { return CreateDocument(aCommand, aChannel, aLoadGroup, aContainer, kVideoDocumentCID,