diff options
Diffstat (limited to 'dom/media/platforms/agnostic/AgnosticDecoderModule.cpp')
-rw-r--r-- | dom/media/platforms/agnostic/AgnosticDecoderModule.cpp | 218 |
1 files changed, 218 insertions, 0 deletions
diff --git a/dom/media/platforms/agnostic/AgnosticDecoderModule.cpp b/dom/media/platforms/agnostic/AgnosticDecoderModule.cpp new file mode 100644 index 0000000000..22723a6a04 --- /dev/null +++ b/dom/media/platforms/agnostic/AgnosticDecoderModule.cpp @@ -0,0 +1,218 @@ +/* -*- 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 "AgnosticDecoderModule.h" + +#include "OpusDecoder.h" +#include "TheoraDecoder.h" +#include "VPXDecoder.h" +#include "VorbisDecoder.h" +#include "WAVDecoder.h" +#include "mozilla/Logging.h" +#include "mozilla/StaticPrefs_media.h" +#include "VideoUtils.h" + +#ifdef MOZ_AV1 +# include "AOMDecoder.h" +# include "DAV1DDecoder.h" +#endif + +namespace mozilla { + +enum class DecoderType { +#ifdef MOZ_AV1 + AV1, +#endif + Opus, + Theora, + Vorbis, + VPX, + Wave, +}; + +static bool IsAvailableInDefault(DecoderType type) { + switch (type) { +#ifdef MOZ_AV1 + case DecoderType::AV1: + return StaticPrefs::media_av1_enabled(); +#endif + case DecoderType::Opus: + case DecoderType::Theora: + case DecoderType::Vorbis: + case DecoderType::VPX: + case DecoderType::Wave: + return true; + default: + return false; + } +} + +static bool IsAvailableInRdd(DecoderType type) { + switch (type) { +#ifdef MOZ_AV1 + case DecoderType::AV1: + return StaticPrefs::media_av1_enabled(); +#endif + case DecoderType::Opus: + return StaticPrefs::media_rdd_opus_enabled(); + case DecoderType::Theora: + return StaticPrefs::media_rdd_theora_enabled(); + case DecoderType::Vorbis: +#if defined(__MINGW32__) + // If this is a MinGW build we need to force AgnosticDecoderModule to + // handle the decision to support Vorbis decoding (instead of + // RDD/RemoteDecoderModule) because of Bug 1597408 (Vorbis decoding on + // RDD causing sandboxing failure on MinGW-clang). Typically this + // would be dealt with using defines in StaticPrefList.yaml, but we + // must handle it here because of Bug 1598426 (the __MINGW32__ define + // isn't supported in StaticPrefList.yaml). + return false; +#else + return StaticPrefs::media_rdd_vorbis_enabled(); +#endif + case DecoderType::VPX: + return StaticPrefs::media_rdd_vpx_enabled(); + case DecoderType::Wave: + return StaticPrefs::media_rdd_wav_enabled(); + default: + return false; + } +} + +static bool IsAvailableInUtility(DecoderType type) { + switch (type) { + case DecoderType::Opus: + return StaticPrefs::media_utility_opus_enabled(); + case DecoderType::Vorbis: +#if defined(__MINGW32__) + // If this is a MinGW build we need to force AgnosticDecoderModule to + // handle the decision to support Vorbis decoding (instead of + // Utility/RemoteDecoderModule) because of Bug 1597408 (Vorbis decoding on + // Utility causing sandboxing failure on MinGW-clang). Typically this + // would be dealt with using defines in StaticPrefList.yaml, but we + // must handle it here because of Bug 1598426 (the __MINGW32__ define + // isn't supported in StaticPrefList.yaml). + return false; +#else + return StaticPrefs::media_utility_vorbis_enabled(); +#endif + case DecoderType::Wave: + return StaticPrefs::media_utility_wav_enabled(); + case DecoderType::Theora: // Video codecs, dont take care of them + case DecoderType::VPX: + default: + return false; + } +} + +// Checks if decoder is available in the current process +static bool IsAvailable(DecoderType type) { + return XRE_IsRDDProcess() ? IsAvailableInRdd(type) + : XRE_IsUtilityProcess() ? IsAvailableInUtility(type) + : IsAvailableInDefault(type); +} + +media::DecodeSupportSet AgnosticDecoderModule::SupportsMimeType( + const nsACString& aMimeType, DecoderDoctorDiagnostics* aDiagnostics) const { + UniquePtr<TrackInfo> trackInfo = CreateTrackInfoWithMIMEType(aMimeType); + if (!trackInfo) { + return media::DecodeSupport::Unsupported; + } + return Supports(SupportDecoderParams(*trackInfo), aDiagnostics); +} + +media::DecodeSupportSet AgnosticDecoderModule::Supports( + const SupportDecoderParams& aParams, + DecoderDoctorDiagnostics* aDiagnostics) const { + // This should only be supported by MFMediaEngineDecoderModule. + if (aParams.mMediaEngineId) { + return media::DecodeSupport::Unsupported; + } + + const auto& trackInfo = aParams.mConfig; + const nsACString& mimeType = trackInfo.mMimeType; + + bool supports = +#ifdef MOZ_AV1 + // We remove support for decoding AV1 here if RDD is enabled so that + // decoding on the content process doesn't accidentally happen in case + // something goes wrong with launching the RDD process. + (AOMDecoder::IsAV1(mimeType) && IsAvailable(DecoderType::AV1)) || +#endif + (VPXDecoder::IsVPX(mimeType) && IsAvailable(DecoderType::VPX)) || + (TheoraDecoder::IsTheora(mimeType) && IsAvailable(DecoderType::Theora)) || + (VorbisDataDecoder::IsVorbis(mimeType) && + IsAvailable(DecoderType::Vorbis)) || + (WaveDataDecoder::IsWave(mimeType) && IsAvailable(DecoderType::Wave)) || + (OpusDataDecoder::IsOpus(mimeType) && IsAvailable(DecoderType::Opus)); + MOZ_LOG(sPDMLog, LogLevel::Debug, + ("Agnostic decoder %s requested type '%s'", + supports ? "supports" : "rejects", mimeType.BeginReading())); + if (supports) { + return media::DecodeSupport::SoftwareDecode; + } + return media::DecodeSupport::Unsupported; +} + +already_AddRefed<MediaDataDecoder> AgnosticDecoderModule::CreateVideoDecoder( + const CreateDecoderParams& aParams) { + if (Supports(SupportDecoderParams(aParams), nullptr /* diagnostic */) == + media::DecodeSupport::Unsupported) { + return nullptr; + } + RefPtr<MediaDataDecoder> m; + + if (VPXDecoder::IsVPX(aParams.mConfig.mMimeType)) { + m = new VPXDecoder(aParams); + } +#ifdef MOZ_AV1 + // We remove support for decoding AV1 here if RDD is enabled so that + // decoding on the content process doesn't accidentally happen in case + // something goes wrong with launching the RDD process. + if (StaticPrefs::media_av1_enabled() && + (!StaticPrefs::media_rdd_process_enabled() || XRE_IsRDDProcess()) && + AOMDecoder::IsAV1(aParams.mConfig.mMimeType)) { + if (StaticPrefs::media_av1_use_dav1d()) { + m = new DAV1DDecoder(aParams); + } else { + m = new AOMDecoder(aParams); + } + } +#endif + else if (TheoraDecoder::IsTheora(aParams.mConfig.mMimeType)) { + m = new TheoraDecoder(aParams); + } + + return m.forget(); +} + +already_AddRefed<MediaDataDecoder> AgnosticDecoderModule::CreateAudioDecoder( + const CreateDecoderParams& aParams) { + if (Supports(SupportDecoderParams(aParams), nullptr /* diagnostic */) == + media::DecodeSupport::Unsupported) { + return nullptr; + } + RefPtr<MediaDataDecoder> m; + + const TrackInfo& config = aParams.mConfig; + if (VorbisDataDecoder::IsVorbis(config.mMimeType)) { + m = new VorbisDataDecoder(aParams); + } else if (OpusDataDecoder::IsOpus(config.mMimeType)) { + m = new OpusDataDecoder(aParams); + } else if (WaveDataDecoder::IsWave(config.mMimeType)) { + m = new WaveDataDecoder(aParams); + } + + return m.forget(); +} + +/* static */ +already_AddRefed<PlatformDecoderModule> AgnosticDecoderModule::Create() { + RefPtr<PlatformDecoderModule> pdm = new AgnosticDecoderModule(); + return pdm.forget(); +} + +} // namespace mozilla |