diff --git a/dom/media/DecoderTraits.cpp b/dom/media/DecoderTraits.cpp index c645889742b..0d46a19eefe 100644 --- a/dom/media/DecoderTraits.cpp +++ b/dom/media/DecoderTraits.cpp @@ -23,6 +23,7 @@ #ifdef MOZ_WEBM #include "WebMDecoder.h" #include "WebMReader.h" +#include "WebMDemuxer.h" #endif #ifdef MOZ_RAW #include "RawDecoder.h" @@ -698,7 +699,9 @@ MediaDecoderReader* DecoderTraits::CreateReader(const nsACString& aType, Abstrac #endif #ifdef MOZ_WEBM if (IsWebMType(aType)) { - decoderReader = new WebMReader(aDecoder); + decoderReader = Preferences::GetBool("media.format-reader.webm", true) ? + static_cast(new MediaFormatReader(aDecoder, new WebMDemuxer(aDecoder->GetResource()))) : + new WebMReader(aDecoder); } else #endif #ifdef MOZ_DIRECTSHOW diff --git a/dom/media/MediaFormatReader.cpp b/dom/media/MediaFormatReader.cpp index 1ff2bc8949b..bd53a11325d 100644 --- a/dom/media/MediaFormatReader.cpp +++ b/dom/media/MediaFormatReader.cpp @@ -258,13 +258,15 @@ bool MediaFormatReader::IsWaitingOnCDMResource() { bool MediaFormatReader::IsSupportedAudioMimeType(const nsACString& aMimeType) { - return mPlatform && mPlatform->SupportsMimeType(aMimeType); + return mPlatform && (mPlatform->SupportsMimeType(aMimeType) || + PlatformDecoderModule::AgnosticMimeType(aMimeType)); } bool MediaFormatReader::IsSupportedVideoMimeType(const nsACString& aMimeType) { - return mPlatform && mPlatform->SupportsMimeType(aMimeType); + return mPlatform && (mPlatform->SupportsMimeType(aMimeType) || + PlatformDecoderModule::AgnosticMimeType(aMimeType)); } nsRefPtr diff --git a/dom/media/mediasource/MediaSourceReader.cpp b/dom/media/mediasource/MediaSourceReader.cpp index e11a01ff489..fae257e2783 100644 --- a/dom/media/mediasource/MediaSourceReader.cpp +++ b/dom/media/mediasource/MediaSourceReader.cpp @@ -25,6 +25,7 @@ #ifdef MOZ_WEBM #include "WebMReader.h" +#include "WebMDemuxer.h" #endif extern PRLogModuleInfo* GetMediaSourceLog(); @@ -718,7 +719,12 @@ CreateReaderForType(const nsACString& aType, AbstractMediaDecoder* aDecoder, #ifdef MOZ_WEBM if (DecoderTraits::IsWebMType(aType)) { - return new WebMReader(aDecoder, aBorrowedTaskQueue); + bool useFormatDecoder = + Preferences::GetBool("media.mediasource.format-reader.webm", true); + MediaDecoderReader* reader = useFormatDecoder ? + static_cast(new MediaFormatReader(aDecoder, new WebMDemuxer(aDecoder->GetResource()), aBorrowedTaskQueue)) : + new WebMReader(aDecoder, aBorrowedTaskQueue); + return reader; } #endif diff --git a/dom/media/platforms/PlatformDecoderModule.cpp b/dom/media/platforms/PlatformDecoderModule.cpp index c1e088053a2..14f80d89d1f 100644 --- a/dom/media/platforms/PlatformDecoderModule.cpp +++ b/dom/media/platforms/PlatformDecoderModule.cpp @@ -35,8 +35,13 @@ #include "MediaInfo.h" #include "H264Converter.h" +#include "OpusDecoder.h" +#include "VorbisDecoder.h" +#include "VPXDecoder.h" + namespace mozilla { +extern already_AddRefed CreateAgnosticDecoderModule(); extern already_AddRefed CreateBlankDecoderModule(); bool PlatformDecoderModule::sUseBlankDecoder = false; @@ -124,7 +129,7 @@ PlatformDecoderModule::Create() if (m && NS_SUCCEEDED(m->Startup())) { return m.forget(); } - return nullptr; + return CreateAgnosticDecoderModule(); } /* static */ @@ -184,10 +189,22 @@ PlatformDecoderModule::CreateDecoder(const TrackInfo& aConfig, { nsRefPtr m; + bool hasPlatformDecoder = SupportsMimeType(aConfig.mMimeType); + if (aConfig.GetAsAudioInfo()) { - m = CreateAudioDecoder(*aConfig.GetAsAudioInfo(), - aTaskQueue, - aCallback); + if (!hasPlatformDecoder && VorbisDataDecoder::IsVorbis(aConfig.mMimeType)) { + m = new VorbisDataDecoder(*aConfig.GetAsAudioInfo(), + aTaskQueue, + aCallback); + } else if (!hasPlatformDecoder && OpusDataDecoder::IsOpus(aConfig.mMimeType)) { + m = new OpusDataDecoder(*aConfig.GetAsAudioInfo(), + aTaskQueue, + aCallback); + } else { + m = CreateAudioDecoder(*aConfig.GetAsAudioInfo(), + aTaskQueue, + aCallback); + } return m.forget(); } @@ -202,6 +219,11 @@ PlatformDecoderModule::CreateDecoder(const TrackInfo& aConfig, aImageContainer, aTaskQueue, aCallback); + } else if (!hasPlatformDecoder && VPXDecoder::IsVPX(aConfig.mMimeType)) { + m = new VPXDecoder(*aConfig.GetAsVideoInfo(), + aImageContainer, + aTaskQueue, + aCallback); } else { m = CreateVideoDecoder(*aConfig.GetAsVideoInfo(), aLayersBackend, @@ -220,4 +242,14 @@ PlatformDecoderModule::SupportsMimeType(const nsACString& aMimeType) aMimeType.EqualsLiteral("video/avc"); } +/* static */ +bool +PlatformDecoderModule::AgnosticMimeType(const nsACString& aMimeType) +{ + return VPXDecoder::IsVPX(aMimeType) || + OpusDataDecoder::IsOpus(aMimeType) || + VorbisDataDecoder::IsVorbis(aMimeType); +} + + } // namespace mozilla diff --git a/dom/media/platforms/PlatformDecoderModule.h b/dom/media/platforms/PlatformDecoderModule.h index dc1fc7f13f2..113d089c193 100644 --- a/dom/media/platforms/PlatformDecoderModule.h +++ b/dom/media/platforms/PlatformDecoderModule.h @@ -93,6 +93,10 @@ public: // to be extended virtual bool SupportsMimeType(const nsACString& aMimeType); + // MimeType can be decoded with shipped decoders if no platform decoders exist + static bool AgnosticMimeType(const nsACString& aMimeType); + + enum ConversionRequired { kNeedNone, kNeedAVCC, @@ -107,7 +111,7 @@ public: virtual void DisableHardwareAcceleration() {} virtual bool SupportsSharedDecoders(const VideoInfo& aConfig) const { - return true; + return !AgnosticMimeType(aConfig.mMimeType); } protected: diff --git a/dom/media/platforms/agnostic/BlankDecoderModule.cpp b/dom/media/platforms/agnostic/BlankDecoderModule.cpp index 968b4792167..62bfef72f07 100644 --- a/dom/media/platforms/agnostic/BlankDecoderModule.cpp +++ b/dom/media/platforms/agnostic/BlankDecoderModule.cpp @@ -246,6 +246,11 @@ public: return true; } + virtual bool + SupportsSharedDecoders(const VideoInfo& aConfig) const override { + return false; + } + virtual ConversionRequired DecoderNeedsConversion(const TrackInfo& aConfig) const override { @@ -254,10 +259,27 @@ public: }; +class AgnosticDecoderModule : public BlankDecoderModule { +public: + + bool SupportsMimeType(const nsACString& aMimeType) override + { + // This module does not support any decoders itself, + // agnostic decoders are created in PlatformDecoderModule::CreateDecoder + return false; + } +}; + already_AddRefed CreateBlankDecoderModule() { nsRefPtr pdm = new BlankDecoderModule(); return pdm.forget(); } +already_AddRefed CreateAgnosticDecoderModule() +{ + nsRefPtr adm = new AgnosticDecoderModule(); + return adm.forget(); +} + } // namespace mozilla diff --git a/dom/media/platforms/wmf/WMFDecoderModule.cpp b/dom/media/platforms/wmf/WMFDecoderModule.cpp index 6f814633f89..f070642d2f2 100644 --- a/dom/media/platforms/wmf/WMFDecoderModule.cpp +++ b/dom/media/platforms/wmf/WMFDecoderModule.cpp @@ -26,6 +26,7 @@ namespace mozilla { static bool sIsWMFEnabled = false; static bool sDXVAEnabled = false; static int sNumDecoderThreads = -1; +static bool sIsIntelDecoderEnabled = false; WMFDecoderModule::WMFDecoderModule() : mWMFInitialized(false) @@ -44,6 +45,7 @@ void WMFDecoderModule::DisableHardwareAcceleration() { sDXVAEnabled = false; + sIsIntelDecoderEnabled = false; } static void @@ -72,6 +74,7 @@ WMFDecoderModule::Init() MOZ_ASSERT(NS_IsMainThread(), "Must be on main thread."); sIsWMFEnabled = Preferences::GetBool("media.windows-media-foundation.enabled", false); sDXVAEnabled = gfxPlatform::GetPlatform()->CanUseHardwareVideoDecoding(); + sIsIntelDecoderEnabled = Preferences::GetBool("media.webm.intel_decoder.enabled", false); SetNumOfDecoderThreads(); } @@ -145,7 +148,8 @@ WMFDecoderModule::SupportsSharedDecoders(const VideoInfo& aConfig) const { // If DXVA is enabled, but we're not going to use it for this specific config, then // we can't use the shared decoder. - return !sDXVAEnabled || ShouldUseDXVA(aConfig); + return !AgnosticMimeType(aConfig.mMimeType) && + (!sDXVAEnabled || ShouldUseDXVA(aConfig)); } bool @@ -153,10 +157,11 @@ WMFDecoderModule::SupportsMimeType(const nsACString& aMimeType) { return aMimeType.EqualsLiteral("video/mp4") || aMimeType.EqualsLiteral("video/avc") || - aMimeType.EqualsLiteral("video/webm; codecs=vp8") || - aMimeType.EqualsLiteral("video/webm; codecs=vp9") || aMimeType.EqualsLiteral("audio/mp4a-latm") || - aMimeType.EqualsLiteral("audio/mpeg"); + aMimeType.EqualsLiteral("audio/mpeg") || + (sIsIntelDecoderEnabled && + (aMimeType.EqualsLiteral("video/webm; codecs=vp8") || + aMimeType.EqualsLiteral("video/webm; codecs=vp9"))); } PlatformDecoderModule::ConversionRequired diff --git a/dom/media/webm/WebMDecoder.cpp b/dom/media/webm/WebMDecoder.cpp index e80380144f7..7a74a3dc0b1 100644 --- a/dom/media/webm/WebMDecoder.cpp +++ b/dom/media/webm/WebMDecoder.cpp @@ -4,7 +4,10 @@ * 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 "mozilla/Preferences.h" #include "MediaDecoderStateMachine.h" +#include "MediaFormatReader.h" +#include "WebMDemuxer.h" #include "WebMReader.h" #include "WebMDecoder.h" @@ -12,7 +15,12 @@ namespace mozilla { MediaDecoderStateMachine* WebMDecoder::CreateStateMachine() { - return new MediaDecoderStateMachine(this, new WebMReader(this)); + bool useFormatDecoder = + Preferences::GetBool("media.format-reader.webm", true); + nsRefPtr reader = useFormatDecoder ? + static_cast(new MediaFormatReader(this, new WebMDemuxer(GetResource()))) : + new WebMReader(this); + return new MediaDecoderStateMachine(this, reader); } } // namespace mozilla diff --git a/modules/libpref/init/all.js b/modules/libpref/init/all.js index 0011dbe539a..4eae30299ea 100644 --- a/modules/libpref/init/all.js +++ b/modules/libpref/init/all.js @@ -480,6 +480,11 @@ pref("media.mediasource.format-reader.mp4", true); // Enable new MediaFormatReader architecture for plain mp4. pref("media.format-reader.mp4", true); +// Enable new MediaFormatReader architecture for webm in MSE +pref("media.mediasource.format-reader.webm", false); +// Enable new MediaFormatReader architecture for plain webm. +pref("media.format-reader.webm", false); + #ifdef MOZ_WEBSPEECH pref("media.webspeech.recognition.enable", false); pref("media.webspeech.synth.enabled", false);