diff --git a/dom/media/ipc/RemoteDecoderModule.cpp b/dom/media/ipc/RemoteDecoderModule.cpp index dfbb2305091a..af0827d0ca94 100644 --- a/dom/media/ipc/RemoteDecoderModule.cpp +++ b/dom/media/ipc/RemoteDecoderModule.cpp @@ -19,6 +19,7 @@ #include "RemoteMediaDataDecoder.h" #include "RemoteVideoDecoder.h" #include "OpusDecoder.h" +#include "VideoUtils.h" #include "VorbisDecoder.h" #include "WAVDecoder.h" @@ -105,6 +106,16 @@ already_AddRefed RemoteDecoderModule::CreateAudioDecoder( return nullptr; } + // OpusDataDecoder will check this option to provide the same info + // that IsDefaultPlaybackDeviceMono provides. We want to avoid calls + // to IsDefaultPlaybackDeviceMono on RDD because initializing audio + // backends on RDD will be blocked by the sandbox. + CreateDecoderParams::OptionSet options(aParams.mOptions); + if (OpusDataDecoder::IsOpus(aParams.mConfig.mMimeType) && + IsDefaultPlaybackDeviceMono()) { + options += CreateDecoderParams::Option::DefaultPlaybackDeviceMono; + } + RefPtr child = new RemoteAudioDecoderChild(); MediaResult result(NS_OK); // We can use child as a ref here because this is a sync dispatch. In @@ -116,7 +127,7 @@ already_AddRefed RemoteDecoderModule::CreateAudioDecoder( // thread during this single dispatch. RefPtr task = NS_NewRunnableFunction("RemoteDecoderModule::CreateAudioDecoder", [&]() { - result = child->InitIPDL(aParams.AudioConfig(), aParams.mOptions); + result = child->InitIPDL(aParams.AudioConfig(), options); if (NS_FAILED(result)) { // Release RemoteAudioDecoderChild here, while we're on // manager thread. Don't just let the RefPtr go out of scope. diff --git a/dom/media/platforms/PlatformDecoderModule.h b/dom/media/platforms/PlatformDecoderModule.h index feba83226fcf..a5ba14775cbb 100644 --- a/dom/media/platforms/PlatformDecoderModule.h +++ b/dom/media/platforms/PlatformDecoderModule.h @@ -53,6 +53,8 @@ struct MOZ_STACK_CLASS CreateDecoderParams final { // initialization data are dropped. Pass this // option to raise an error if frames are // delivered before initialization data. + DefaultPlaybackDeviceMono, // Currently only used by Opus on RDD to avoid + // initialization of audio backends on RDD SENTINEL // one past the last valid value }; diff --git a/dom/media/platforms/agnostic/AgnosticDecoderModule.cpp b/dom/media/platforms/agnostic/AgnosticDecoderModule.cpp index 8ff8acbccdcb..c23466dc22a9 100644 --- a/dom/media/platforms/agnostic/AgnosticDecoderModule.cpp +++ b/dom/media/platforms/agnostic/AgnosticDecoderModule.cpp @@ -88,7 +88,14 @@ already_AddRefed AgnosticDecoderModule::CreateAudioDecoder( if (VorbisDataDecoder::IsVorbis(config.mMimeType)) { m = new VorbisDataDecoder(aParams); } else if (OpusDataDecoder::IsOpus(config.mMimeType)) { - m = new OpusDataDecoder(aParams); + CreateDecoderParams params(aParams); + // Check IsDefaultPlaybackDeviceMono here and set the option in + // mOptions so OpusDataDecoder doesn't have to do it later (in case + // it is running on RDD). + if (IsDefaultPlaybackDeviceMono()) { + params.mOptions += CreateDecoderParams::Option::DefaultPlaybackDeviceMono; + } + m = new OpusDataDecoder(params); } else if (WaveDataDecoder::IsWave(config.mMimeType)) { m = new WaveDataDecoder(aParams); } diff --git a/dom/media/platforms/agnostic/OpusDecoder.cpp b/dom/media/platforms/agnostic/OpusDecoder.cpp index 1808a7415195..b53387c53fc3 100644 --- a/dom/media/platforms/agnostic/OpusDecoder.cpp +++ b/dom/media/platforms/agnostic/OpusDecoder.cpp @@ -35,7 +35,9 @@ OpusDataDecoder::OpusDataDecoder(const CreateDecoderParams& aParams) mDecodedHeader(false), mPaddingDiscarded(false), mFrames(0), - mChannelMap(AudioConfig::ChannelLayout::UNKNOWN_MAP) {} + mChannelMap(AudioConfig::ChannelLayout::UNKNOWN_MAP), + mDefaultPlaybackDeviceMono(aParams.mOptions.contains( + CreateDecoderParams::Option::DefaultPlaybackDeviceMono)) {} OpusDataDecoder::~OpusDataDecoder() { if (mOpusDecoder) { @@ -99,8 +101,7 @@ RefPtr OpusDataDecoder::Init() { // needs to be disabled when the output is downmixed to mono. Playback number // of channels are set in AudioSink, using the same method // `DecideAudioPlaybackChannels()`, and triggers downmix if needed. - if (IsDefaultPlaybackDeviceMono() || - DecideAudioPlaybackChannels(mInfo) == 1) { + if (mDefaultPlaybackDeviceMono || DecideAudioPlaybackChannels(mInfo) == 1) { opus_multistream_decoder_ctl(mOpusDecoder, OPUS_SET_PHASE_INVERSION_DISABLED(1)); } diff --git a/dom/media/platforms/agnostic/OpusDecoder.h b/dom/media/platforms/agnostic/OpusDecoder.h index 91c02f03ae99..c134ef1e6f4a 100644 --- a/dom/media/platforms/agnostic/OpusDecoder.h +++ b/dom/media/platforms/agnostic/OpusDecoder.h @@ -68,6 +68,7 @@ class OpusDataDecoder : public MediaDataDecoder, Maybe mLastFrameTime; AutoTArray mMappingTable; AudioConfig::ChannelLayout::ChannelMap mChannelMap; + bool mDefaultPlaybackDeviceMono; }; } // namespace mozilla