diff --git a/dom/media/ipc/PRemoteDecoderManager.ipdl b/dom/media/ipc/PRemoteDecoderManager.ipdl index a538ba93e9fb..b955e5edf81b 100644 --- a/dom/media/ipc/PRemoteDecoderManager.ipdl +++ b/dom/media/ipc/PRemoteDecoderManager.ipdl @@ -46,7 +46,8 @@ parent: #endif async PRemoteDecoder(RemoteDecoderInfoIPDL info, OptionSet options, - TextureFactoryIdentifier? identifier); + TextureFactoryIdentifier? identifier, + uint64_t? mediaEngineId); sync Readback(SurfaceDescriptorGPUVideo sd) returns (SurfaceDescriptor aResult); diff --git a/dom/media/ipc/RemoteAudioDecoder.cpp b/dom/media/ipc/RemoteAudioDecoder.cpp index 7b085e208a2d..9e8ee2ebb736 100644 --- a/dom/media/ipc/RemoteAudioDecoder.cpp +++ b/dom/media/ipc/RemoteAudioDecoder.cpp @@ -39,8 +39,8 @@ MediaResult RemoteAudioDecoderChild::ProcessOutput( } MediaResult RemoteAudioDecoderChild::InitIPDL( - const AudioInfo& aAudioInfo, - const CreateDecoderParams::OptionSet& aOptions) { + const AudioInfo& aAudioInfo, const CreateDecoderParams::OptionSet& aOptions, + const Maybe& aMediaEngineId) { RefPtr manager = RemoteDecoderManagerChild::GetSingleton(mLocation); @@ -59,21 +59,24 @@ MediaResult RemoteAudioDecoderChild::InitIPDL( mIPDLSelfRef = this; Unused << manager->SendPRemoteDecoderConstructor(this, aAudioInfo, aOptions, - Nothing()); + Nothing(), aMediaEngineId); return NS_OK; } RemoteAudioDecoderParent::RemoteAudioDecoderParent( RemoteDecoderManagerParent* aParent, const AudioInfo& aAudioInfo, const CreateDecoderParams::OptionSet& aOptions, - nsISerialEventTarget* aManagerThread, TaskQueue* aDecodeTaskQueue) - : RemoteDecoderParent(aParent, aOptions, aManagerThread, aDecodeTaskQueue), + nsISerialEventTarget* aManagerThread, TaskQueue* aDecodeTaskQueue, + Maybe aMediaEngineId) + : RemoteDecoderParent(aParent, aOptions, aManagerThread, aDecodeTaskQueue, + aMediaEngineId), mAudioInfo(aAudioInfo) {} IPCResult RemoteAudioDecoderParent::RecvConstruct( ConstructResolver&& aResolver) { - auto params = CreateDecoderParams{mAudioInfo, mOptions, - CreateDecoderParams::NoWrapper(true)}; + auto params = + CreateDecoderParams{mAudioInfo, mOptions, + CreateDecoderParams::NoWrapper(true), mMediaEngineId}; mParent->EnsurePDMFactory().CreateDecoder(params)->Then( GetCurrentSerialEventTarget(), __func__, diff --git a/dom/media/ipc/RemoteAudioDecoder.h b/dom/media/ipc/RemoteAudioDecoder.h index c09834eac003..d14eebb2ba5a 100644 --- a/dom/media/ipc/RemoteAudioDecoder.h +++ b/dom/media/ipc/RemoteAudioDecoder.h @@ -18,7 +18,8 @@ class RemoteAudioDecoderChild final : public RemoteDecoderChild { MOZ_IS_CLASS_INIT MediaResult InitIPDL(const AudioInfo& aAudioInfo, - const CreateDecoderParams::OptionSet& aOptions); + const CreateDecoderParams::OptionSet& aOptions, + const Maybe& aMediaEngineId); MediaResult ProcessOutput(DecodedOutputIPDL&& aDecodedData) override; }; @@ -29,7 +30,8 @@ class RemoteAudioDecoderParent final : public RemoteDecoderParent { const AudioInfo& aAudioInfo, const CreateDecoderParams::OptionSet& aOptions, nsISerialEventTarget* aManagerThread, - TaskQueue* aDecodeTaskQueue); + TaskQueue* aDecodeTaskQueue, + Maybe aMediaEngineId); protected: IPCResult RecvConstruct(ConstructResolver&& aResolver) override; diff --git a/dom/media/ipc/RemoteDecoderManagerChild.cpp b/dom/media/ipc/RemoteDecoderManagerChild.cpp index 35bf0ea3f80b..49d537efee63 100644 --- a/dom/media/ipc/RemoteDecoderManagerChild.cpp +++ b/dom/media/ipc/RemoteDecoderManagerChild.cpp @@ -269,18 +269,26 @@ RemoteDecoderManagerChild::CreateAudioDecoder( return PlatformDecoderModule::CreateDecoderPromise::CreateAndReject( NS_ERROR_DOM_MEDIA_CANCELED, __func__); } + + bool useUtilityAudioDecoding = StaticPrefs::media_utility_process_enabled() && + aLocation == RemoteDecodeIn::UtilityProcess; +#ifdef MOZ_WMF + // If the media engine Id is specified, using the media engine in the RDD + // process instead. + useUtilityAudioDecoding = useUtilityAudioDecoding && + !(aParams.mMediaEngineId && + StaticPrefs::media_wmf_media_engine_enabled()); +#endif RefPtr launchPromise = - (StaticPrefs::media_utility_process_enabled() && - aLocation == RemoteDecodeIn::UtilityProcess) - ? LaunchUtilityProcessIfNeeded() - : LaunchRDDProcessIfNeeded(); + useUtilityAudioDecoding ? LaunchUtilityProcessIfNeeded() + : LaunchRDDProcessIfNeeded(); return launchPromise->Then( managerThread, __func__, [params = CreateDecoderParamsForAsync(aParams), aLocation](bool) { auto child = MakeRefPtr(); - MediaResult result = - child->InitIPDL(params.AudioConfig(), params.mOptions); + MediaResult result = child->InitIPDL( + params.AudioConfig(), params.mOptions, params.mMediaEngineId); if (NS_FAILED(result)) { return PlatformDecoderModule::CreateDecoderPromise::CreateAndReject( result, __func__); @@ -332,7 +340,8 @@ RemoteDecoderManagerChild::CreateVideoDecoder( params.VideoConfig(), params.mRate.mValue, params.mOptions, params.mKnowsCompositor ? Some(params.mKnowsCompositor->GetTextureFactoryIdentifier()) - : Nothing()); + : Nothing(), + params.mMediaEngineId); if (NS_FAILED(result)) { return PlatformDecoderModule::CreateDecoderPromise::CreateAndReject( result, __func__); @@ -548,7 +557,8 @@ RemoteDecoderManagerChild::LaunchUtilityProcessIfNeeded() { PRemoteDecoderChild* RemoteDecoderManagerChild::AllocPRemoteDecoderChild( const RemoteDecoderInfoIPDL& /* not used */, const CreateDecoderParams::OptionSet& aOptions, - const Maybe& aIdentifier) { + const Maybe& aIdentifier, + const Maybe& aMediaEngineId) { // RemoteDecoderModule is responsible for creating RemoteDecoderChild // classes. MOZ_ASSERT(false, diff --git a/dom/media/ipc/RemoteDecoderManagerChild.h b/dom/media/ipc/RemoteDecoderManagerChild.h index bcab768dd9ad..9c5804a7bb29 100644 --- a/dom/media/ipc/RemoteDecoderManagerChild.h +++ b/dom/media/ipc/RemoteDecoderManagerChild.h @@ -92,6 +92,9 @@ class RemoteDecoderManagerChild final RemoteDecodeIn Location() const { return mLocation; } layers::VideoBridgeSource GetSource() const; + // A thread-safe method to launch the RDD process if it hasn't launched yet. + static RefPtr LaunchRDDProcessIfNeeded(); + protected: void InitIPDL(); @@ -102,7 +105,8 @@ class RemoteDecoderManagerChild final PRemoteDecoderChild* AllocPRemoteDecoderChild( const RemoteDecoderInfoIPDL& aRemoteDecoderInfo, const CreateDecoderParams::OptionSet& aOptions, - const Maybe& aIdentifier); + const Maybe& aIdentifier, + const Maybe& aMediaEngineId); bool DeallocPRemoteDecoderChild(PRemoteDecoderChild* actor); PMFMediaEngineChild* AllocPMFMediaEngineChild(); @@ -120,7 +124,6 @@ class RemoteDecoderManagerChild final Endpoint&& aEndpoint); static void OpenForUtilityProcess( Endpoint&& aEndpoint); - static RefPtr LaunchRDDProcessIfNeeded(); static RefPtr LaunchUtilityProcessIfNeeded(); RefPtr mIPDLSelfRef; diff --git a/dom/media/ipc/RemoteDecoderManagerParent.cpp b/dom/media/ipc/RemoteDecoderManagerParent.cpp index 859a3babd568..d69086dfb5b3 100644 --- a/dom/media/ipc/RemoteDecoderManagerParent.cpp +++ b/dom/media/ipc/RemoteDecoderManagerParent.cpp @@ -191,7 +191,8 @@ void RemoteDecoderManagerParent::ActorDestroy( PRemoteDecoderParent* RemoteDecoderManagerParent::AllocPRemoteDecoderParent( const RemoteDecoderInfoIPDL& aRemoteDecoderInfo, const CreateDecoderParams::OptionSet& aOptions, - const Maybe& aIdentifier) { + const Maybe& aIdentifier, + const Maybe& aMediaEngineId) { RefPtr decodeTaskQueue = TaskQueue::Create(GetMediaThreadPool(MediaThreadType::PLATFORM_DECODER), "RemoteVideoDecoderParent::mDecodeTaskQueue"); @@ -202,13 +203,14 @@ PRemoteDecoderParent* RemoteDecoderManagerParent::AllocPRemoteDecoderParent( aRemoteDecoderInfo.get_VideoDecoderInfoIPDL(); return new RemoteVideoDecoderParent( this, decoderInfo.videoInfo(), decoderInfo.framerate(), aOptions, - aIdentifier, sRemoteDecoderManagerParentThread, decodeTaskQueue); + aIdentifier, sRemoteDecoderManagerParentThread, decodeTaskQueue, + aMediaEngineId); } if (aRemoteDecoderInfo.type() == RemoteDecoderInfoIPDL::TAudioInfo) { return new RemoteAudioDecoderParent( this, aRemoteDecoderInfo.get_AudioInfo(), aOptions, - sRemoteDecoderManagerParentThread, decodeTaskQueue); + sRemoteDecoderManagerParentThread, decodeTaskQueue, aMediaEngineId); } MOZ_CRASH("unrecognized type of RemoteDecoderInfoIPDL union"); diff --git a/dom/media/ipc/RemoteDecoderManagerParent.h b/dom/media/ipc/RemoteDecoderManagerParent.h index 27f0ea6984cf..218fed0a95a9 100644 --- a/dom/media/ipc/RemoteDecoderManagerParent.h +++ b/dom/media/ipc/RemoteDecoderManagerParent.h @@ -58,7 +58,8 @@ class RemoteDecoderManagerParent final PRemoteDecoderParent* AllocPRemoteDecoderParent( const RemoteDecoderInfoIPDL& aRemoteDecoderInfo, const CreateDecoderParams::OptionSet& aOptions, - const Maybe& aIdentifier); + const Maybe& aIdentifier, + const Maybe& aMediaEngineId); bool DeallocPRemoteDecoderParent(PRemoteDecoderParent* actor); PMFMediaEngineParent* AllocPMFMediaEngineParent(); diff --git a/dom/media/ipc/RemoteDecoderParent.cpp b/dom/media/ipc/RemoteDecoderParent.cpp index 4ae4cfe9007b..5116a0f6d156 100644 --- a/dom/media/ipc/RemoteDecoderParent.cpp +++ b/dom/media/ipc/RemoteDecoderParent.cpp @@ -13,11 +13,13 @@ namespace mozilla { RemoteDecoderParent::RemoteDecoderParent( RemoteDecoderManagerParent* aParent, const CreateDecoderParams::OptionSet& aOptions, - nsISerialEventTarget* aManagerThread, TaskQueue* aDecodeTaskQueue) + nsISerialEventTarget* aManagerThread, TaskQueue* aDecodeTaskQueue, + Maybe aMediaEngineId) : ShmemRecycleAllocator(this), mParent(aParent), mOptions(aOptions), mDecodeTaskQueue(aDecodeTaskQueue), + mMediaEngineId(aMediaEngineId), mManagerThread(aManagerThread) { MOZ_COUNT_CTOR(RemoteDecoderParent); MOZ_ASSERT(OnManagerThread()); diff --git a/dom/media/ipc/RemoteDecoderParent.h b/dom/media/ipc/RemoteDecoderParent.h index bce56ee77e25..df6f3796771f 100644 --- a/dom/media/ipc/RemoteDecoderParent.h +++ b/dom/media/ipc/RemoteDecoderParent.h @@ -26,7 +26,8 @@ class RemoteDecoderParent : public ShmemRecycleAllocator, RemoteDecoderParent(RemoteDecoderManagerParent* aParent, const CreateDecoderParams::OptionSet& aOptions, nsISerialEventTarget* aManagerThread, - TaskQueue* aDecodeTaskQueue); + TaskQueue* aDecodeTaskQueue, + Maybe aMediaEngineId); void Destroy(); @@ -55,6 +56,9 @@ class RemoteDecoderParent : public ShmemRecycleAllocator, const RefPtr mDecodeTaskQueue; RefPtr mDecoder; + // Only be used on Windows when the media engine playback is enabled. + const Maybe mMediaEngineId; + private: void DecodeNextSample(const RefPtr& aData, size_t aIndex, MediaDataDecoder::DecodedData&& aOutput, diff --git a/dom/media/ipc/RemoteVideoDecoder.cpp b/dom/media/ipc/RemoteVideoDecoder.cpp index a13a6fafb8af..c90dcb17d15d 100644 --- a/dom/media/ipc/RemoteVideoDecoder.cpp +++ b/dom/media/ipc/RemoteVideoDecoder.cpp @@ -91,7 +91,8 @@ MediaResult RemoteVideoDecoderChild::ProcessOutput( MediaResult RemoteVideoDecoderChild::InitIPDL( const VideoInfo& aVideoInfo, float aFramerate, const CreateDecoderParams::OptionSet& aOptions, - Maybe aIdentifier) { + Maybe aIdentifier, + const Maybe& aMediaEngineId) { MOZ_ASSERT_IF(mLocation == RemoteDecodeIn::GpuProcess, aIdentifier); RefPtr manager = @@ -123,7 +124,7 @@ MediaResult RemoteVideoDecoderChild::InitIPDL( mIPDLSelfRef = this; VideoDecoderInfoIPDL decoderInfo(aVideoInfo, aFramerate); Unused << manager->SendPRemoteDecoderConstructor(this, decoderInfo, aOptions, - aIdentifier); + aIdentifier, aMediaEngineId); return NS_OK; } @@ -132,8 +133,10 @@ RemoteVideoDecoderParent::RemoteVideoDecoderParent( RemoteDecoderManagerParent* aParent, const VideoInfo& aVideoInfo, float aFramerate, const CreateDecoderParams::OptionSet& aOptions, const Maybe& aIdentifier, - nsISerialEventTarget* aManagerThread, TaskQueue* aDecodeTaskQueue) - : RemoteDecoderParent(aParent, aOptions, aManagerThread, aDecodeTaskQueue), + nsISerialEventTarget* aManagerThread, TaskQueue* aDecodeTaskQueue, + Maybe aMediaEngineId) + : RemoteDecoderParent(aParent, aOptions, aManagerThread, aDecodeTaskQueue, + aMediaEngineId), mVideoInfo(aVideoInfo), mFramerate(aFramerate) { if (aIdentifier) { @@ -157,6 +160,7 @@ IPCResult RemoteVideoDecoderParent::RecvConstruct( mVideoInfo, mKnowsCompositor, imageContainer, CreateDecoderParams::VideoFrameRate(mFramerate), mOptions, CreateDecoderParams::NoWrapper(true), + mMediaEngineId, }; mParent->EnsurePDMFactory().CreateDecoder(params)->Then( diff --git a/dom/media/ipc/RemoteVideoDecoder.h b/dom/media/ipc/RemoteVideoDecoder.h index cb5ea6bda65a..259471da1f8e 100644 --- a/dom/media/ipc/RemoteVideoDecoder.h +++ b/dom/media/ipc/RemoteVideoDecoder.h @@ -39,7 +39,8 @@ class RemoteVideoDecoderChild : public RemoteDecoderChild { MOZ_IS_CLASS_INIT MediaResult InitIPDL(const VideoInfo& aVideoInfo, float aFramerate, const CreateDecoderParams::OptionSet& aOptions, - mozilla::Maybe aIdentifier); + mozilla::Maybe aIdentifier, + const Maybe& aMediaEngineId); MediaResult ProcessOutput(DecodedOutputIPDL&& aDecodedData) override; @@ -53,7 +54,8 @@ class RemoteVideoDecoderParent final : public RemoteDecoderParent { RemoteDecoderManagerParent* aParent, const VideoInfo& aVideoInfo, float aFramerate, const CreateDecoderParams::OptionSet& aOptions, const Maybe& aIdentifier, - nsISerialEventTarget* aManagerThread, TaskQueue* aDecodeTaskQueue); + nsISerialEventTarget* aManagerThread, TaskQueue* aDecodeTaskQueue, + Maybe aMediaEngineId); protected: IPCResult RecvConstruct(ConstructResolver&& aResolver) override; diff --git a/dom/media/ipc/moz.build b/dom/media/ipc/moz.build index 1657c39d13d4..879388db8ee6 100644 --- a/dom/media/ipc/moz.build +++ b/dom/media/ipc/moz.build @@ -67,6 +67,9 @@ if CONFIG["MOZ_WMF"]: "MFMediaEngineParent.h", "MFMediaEngineUtils.h", ] + LOCAL_INCLUDES += [ + "../platforms/wmf", + ] # so we can include nsMacUtilsImpl.h in RDDParent.cpp for sandboxing LOCAL_INCLUDES += [ diff --git a/modules/libpref/init/StaticPrefList.yaml b/modules/libpref/init/StaticPrefList.yaml index beb862102885..d87e157c2aa3 100644 --- a/modules/libpref/init/StaticPrefList.yaml +++ b/modules/libpref/init/StaticPrefList.yaml @@ -9164,6 +9164,12 @@ value: true mirror: always +# Using Windows Media Foundation Media Engine for encrypted playback +- name: media.wmf.media-engine.enabled + type: RelaxedAtomicBool + value: false + mirror: always + #endif # MOZ_WMF - name: media.decoder-doctor.testing