/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* vim: set ts=8 sts=2 et sw=2 tw=80: */ /* 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_RemoteDecoderManagerChild_h #define include_dom_media_ipc_RemoteDecoderManagerChild_h #include "GPUVideoImage.h" #include "PDMFactory.h" #include "ipc/EnumSerializer.h" #include "mozilla/EnumTypeTraits.h" #include "mozilla/PRemoteDecoderManagerChild.h" #include "mozilla/layers/VideoBridgeUtils.h" #include "mozilla/ipc/UtilityProcessSandboxing.h" namespace mozilla { class PMFCDMChild; class PMFMediaEngineChild; class RemoteDecoderChild; enum class RemoteDecodeIn { Unspecified, RddProcess, GpuProcess, UtilityProcess_Generic, UtilityProcess_AppleMedia, UtilityProcess_WMF, UtilityProcess_MFMediaEngineCDM, SENTINEL, }; enum class TrackSupport { None, Audio, Video, }; using TrackSupportSet = EnumSet<TrackSupport, uint8_t>; class RemoteDecoderManagerChild final : public PRemoteDecoderManagerChild, public mozilla::ipc::IShmemAllocator, public mozilla::layers::IGPUVideoSurfaceManager { friend class PRemoteDecoderManagerChild; public: NS_INLINE_DECL_THREADSAFE_REFCOUNTING(RemoteDecoderManagerChild, override) // Can only be called from the manager thread static RemoteDecoderManagerChild* GetSingleton(RemoteDecodeIn aLocation); static void Init(); static void SetSupported(RemoteDecodeIn aLocation, const media::MediaCodecsSupported& aSupported); // Can be called from any thread. static bool Supports(RemoteDecodeIn aLocation, const SupportDecoderParams& aParams, DecoderDoctorDiagnostics* aDiagnostics); static RefPtr<PlatformDecoderModule::CreateDecoderPromise> CreateAudioDecoder( const CreateDecoderParams& aParams, RemoteDecodeIn aLocation); static RefPtr<PlatformDecoderModule::CreateDecoderPromise> CreateVideoDecoder( const CreateDecoderParams& aParams, RemoteDecodeIn aLocation); // Can be called from any thread. static nsISerialEventTarget* GetManagerThread(); // Return the track support information based on the location of the remote // process. Thread-safe. static TrackSupportSet GetTrackSupport(RemoteDecodeIn 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<gfx::SourceSurface> Readback( const SurfaceDescriptorGPUVideo& aSD) override; void DeallocateSurfaceDescriptor( const SurfaceDescriptorGPUVideo& aSD) override; bool AllocShmem(size_t aSize, mozilla::ipc::Shmem* aShmem) override { return PRemoteDecoderManagerChild::AllocShmem(aSize, aShmem); } bool AllocUnsafeShmem(size_t aSize, mozilla::ipc::Shmem* aShmem) override { return PRemoteDecoderManagerChild::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<PRemoteDecoderManagerChild>&& aVideoManager); static void Shutdown(); // 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. void RunWhenGPUProcessRecreated(already_AddRefed<Runnable> aTask); RemoteDecodeIn Location() const { return mLocation; } // A thread-safe method to launch the utility process if it hasn't launched // yet. static RefPtr<GenericNonExclusivePromise> LaunchUtilityProcessIfNeeded( RemoteDecodeIn aLocation); protected: void HandleFatalError(const char* aMsg) override; PRemoteDecoderChild* AllocPRemoteDecoderChild( const RemoteDecoderInfoIPDL& aRemoteDecoderInfo, const CreateDecoderParams::OptionSet& aOptions, const Maybe<layers::TextureFactoryIdentifier>& aIdentifier, const Maybe<uint64_t>& aMediaEngineId, const Maybe<TrackingId>& aTrackingId); bool DeallocPRemoteDecoderChild(PRemoteDecoderChild* actor); PMFMediaEngineChild* AllocPMFMediaEngineChild(); bool DeallocPMFMediaEngineChild(PMFMediaEngineChild* actor); PMFCDMChild* AllocPMFCDMChild(const nsAString& aKeySystem); bool DeallocPMFCDMChild(PMFCDMChild* actor); private: explicit RemoteDecoderManagerChild(RemoteDecodeIn aLocation); ~RemoteDecoderManagerChild() = default; static RefPtr<PlatformDecoderModule::CreateDecoderPromise> Construct( RefPtr<RemoteDecoderChild>&& aChild, RemoteDecodeIn aLocation); static void OpenRemoteDecoderManagerChildForProcess( Endpoint<PRemoteDecoderManagerChild>&& aEndpoint, RemoteDecodeIn aLocation); // A thread-safe method to launch the RDD process if it hasn't launched yet. static RefPtr<GenericNonExclusivePromise> LaunchRDDProcessIfNeeded(); // The location for decoding, Rdd or Gpu process. const RemoteDecodeIn mLocation; }; } // namespace mozilla namespace IPC { template <> struct ParamTraits<mozilla::RemoteDecodeIn> : public ContiguousEnumSerializer<mozilla::RemoteDecodeIn, mozilla::RemoteDecodeIn::Unspecified, mozilla::RemoteDecodeIn::SENTINEL> {}; } // namespace IPC #endif // include_dom_media_ipc_RemoteDecoderManagerChild_h