/* 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 include_dom_media_ipc_RemoteMediaManagerChild_h #define include_dom_media_ipc_RemoteMediaManagerChild_h #include #include "GPUVideoImage.h" #include "PDMFactory.h" #include "PlatformEncoderModule.h" #include "ipc/EnumSerializer.h" #include "mozilla/PRemoteMediaManagerChild.h" #include "mozilla/ipc/UtilityProcessSandboxing.h" #include "mozilla/layers/VideoBridgeUtils.h" namespace mozilla { namespace dom { class MediaKeys; } class PMFCDMChild; class PMFMediaEngineChild; class RemoteCDMProxy; class RemoteDecoderChild; class RemoteMediaDataEncoder; enum class RemoteMediaIn { Unspecified, RddProcess, GpuProcess, UtilityProcess_Generic, UtilityProcess_AppleMedia, UtilityProcess_WMF, UtilityProcess_MFMediaEngineCDM, SENTINEL, }; enum class TrackSupport { None, DecodeAudio, DecodeVideo, EncodeAudio, EncodeVideo, }; using TrackSupportSet = EnumSet; class RemoteMediaManagerChild final : public PRemoteMediaManagerChild, public mozilla::ipc::IShmemAllocator, public mozilla::layers::IGPUVideoSurfaceManager { friend class PRemoteMediaManagerChild; public: NS_INLINE_DECL_THREADSAFE_REFCOUNTING(RemoteMediaManagerChild, override) // Can only be called from the manager thread static RemoteMediaManagerChild* GetSingleton(RemoteMediaIn aLocation); static void Init(); static void SetSupported(RemoteMediaIn aLocation, const media::MediaCodecsSupported& aSupported); // Can be called from any thread. static bool Supports(RemoteMediaIn aLocation, const SupportDecoderParams& aParams, DecoderDoctorDiagnostics* aDiagnostics); static RefPtr CreateAudioDecoder( const CreateDecoderParams& aParams, RemoteMediaIn aLocation); static RefPtr CreateVideoDecoder( const CreateDecoderParams& aParams, RemoteMediaIn aLocation); static RefPtr CreateCDM(RemoteMediaIn aLocation, dom::MediaKeys* aKeys, const nsAString& aKeySystem, bool aDistinctiveIdentifierRequired, bool aPersistentStateRequired); static media::EncodeSupportSet Supports(RemoteMediaIn aLocation, CodecType aCodec); static RefPtr InitializeEncoder( RefPtr&& aEncoder, const EncoderConfig& aConfig); // Can be called from any thread. static nsCOMPtr GetManagerThread(); // Return the track support information based on the location of the remote // process. Thread-safe. static TrackSupportSet GetTrackSupport(RemoteMediaIn aLocation); // Can be called from any thread, dispatches the request to the IPDL thread // internally and will be ignored if the IPDL actor has been destroyed. already_AddRefed Readback( const SurfaceDescriptorGPUVideo& aSD) override; already_AddRefed TransferToImage( const SurfaceDescriptorGPUVideo& aSD, const gfx::IntSize& aSize, const gfx::ColorDepth& aColorDepth, gfx::YUVColorSpace aYUVColorSpace, gfx::ColorSpace2 aColorPrimaries, gfx::TransferFunction aTransferFunction, gfx::ColorRange aColorRange) override; void DeallocateSurfaceDescriptor( const SurfaceDescriptorGPUVideo& aSD) override; void OnSetCurrent(const SurfaceDescriptorGPUVideo& aSD) override; bool AllocShmem(size_t aSize, mozilla::ipc::Shmem* aShmem) override { return PRemoteMediaManagerChild::AllocShmem(aSize, aShmem); } bool AllocUnsafeShmem(size_t aSize, mozilla::ipc::Shmem* aShmem) override { return PRemoteMediaManagerChild::AllocUnsafeShmem(aSize, aShmem); } // Can be called from any thread, dispatches the request to the IPDL thread // internally and will be ignored if the IPDL actor has been destroyed. bool DeallocShmem(mozilla::ipc::Shmem& aShmem) override; // Main thread only static void InitForGPUProcess( Endpoint&& aVideoManager); static void Shutdown(); // Helper method to handle IPDL promise rejections. This will allow the // caller in the layers above to recover gracefully by recreating the encoder // or decoder. static void HandleRejectionError( const RemoteMediaManagerChild* aDyingManager, RemoteMediaIn aLocation, const mozilla::ipc::ResponseRejectReason& aReason, std::function&& aCallback); // Run aTask (on the manager thread) when we next attempt to create a new // manager (even if creation fails). Intended to be called from ActorDestroy // when we get notified that the old manager is being destroyed. Can only be // called from the manager thread. static void RunWhenGPUProcessRecreated( const RemoteMediaManagerChild* aDyingManager, already_AddRefed aTask); RemoteMediaIn Location() const { return mLocation; } // A thread-safe method to launch the utility process if it hasn't launched // yet. static RefPtr LaunchUtilityProcessIfNeeded( RemoteMediaIn aLocation); protected: void HandleFatalError(const char* aMsg) override; PRemoteDecoderChild* AllocPRemoteDecoderChild( const RemoteDecoderInfoIPDL& aRemoteDecoderInfo, const CreateDecoderParams::OptionSet& aOptions, const Maybe& aIdentifier, const Maybe& aMediaEngineId, const Maybe& aTrackingId, PRemoteCDMChild* aCDM); bool DeallocPRemoteDecoderChild(PRemoteDecoderChild* actor); PMFMediaEngineChild* AllocPMFMediaEngineChild(); bool DeallocPMFMediaEngineChild(PMFMediaEngineChild* actor); PMFCDMChild* AllocPMFCDMChild(const nsAString& aKeySystem); bool DeallocPMFCDMChild(PMFCDMChild* actor); private: explicit RemoteMediaManagerChild(RemoteMediaIn aLocation); ~RemoteMediaManagerChild() = default; static RefPtr Construct( RefPtr&& aChild, CreateDecoderParamsForAsync&& aParams, RemoteMediaIn aLocation); static void OpenRemoteMediaManagerChildForProcess( Endpoint&& aEndpoint, RemoteMediaIn aLocation); // A thread-safe method to launch the RDD process if it hasn't launched yet. static RefPtr LaunchRDDProcessIfNeeded(); // The location for decoding, Rdd or Gpu process. const RemoteMediaIn mLocation; }; } // namespace mozilla namespace IPC { template <> struct ParamTraits : public ContiguousEnumSerializer {}; } // namespace IPC #endif // include_dom_media_ipc_RemoteMediaManagerChild_h