MFMediaEngineChild.h (5333B)
1 /* This Source Code Form is subject to the terms of the Mozilla Public 2 * License, v. 2.0. If a copy of the MPL was not distributed with this 3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 5 #ifndef DOM_MEDIA_IPC_MFMEDIAENGINECHILD_H_ 6 #define DOM_MEDIA_IPC_MFMEDIAENGINECHILD_H_ 7 8 #include "ExternalEngineStateMachine.h" 9 #include "MFMediaEngineUtils.h" 10 #include "TimeUnits.h" 11 #include "mozilla/Atomics.h" 12 #include "mozilla/NotNull.h" 13 #include "mozilla/PMFMediaEngineChild.h" 14 15 namespace mozilla { 16 17 class MFMediaEngineWrapper; 18 19 /** 20 * MFMediaEngineChild is a wrapper class for a MediaEngine in the content 21 * process. It communicates with MFMediaEngineParent in the remote process by 22 * using IPDL interfaces to send commands to the MediaEngine. 23 * https://docs.microsoft.com/en-us/windows/win32/api/mfmediaengine/nn-mfmediaengine-imfmediaengine 24 */ 25 class MFMediaEngineChild final : public PMFMediaEngineChild { 26 public: 27 NS_INLINE_DECL_THREADSAFE_REFCOUNTING(MFMediaEngineChild); 28 29 MFMediaEngineChild(MFMediaEngineWrapper* aOwner, 30 FrameStatistics* aFrameStats); 31 32 void OwnerDestroyed(); 33 void IPDLActorDestroyed(); 34 35 RefPtr<GenericNonExclusivePromise> Init( 36 const MediaInfo& aInfo, 37 const ExternalPlaybackEngine::InitFlagSet& aFlags); 38 void Shutdown(); 39 40 // Methods for PMFMediaEngineChild 41 mozilla::ipc::IPCResult RecvRequestSample(TrackInfo::TrackType aType, 42 bool aIsEnough); 43 mozilla::ipc::IPCResult RecvUpdateCurrentTime(double aCurrentTimeInSecond); 44 mozilla::ipc::IPCResult RecvNotifyEvent(MFMediaEngineEvent aEvent); 45 mozilla::ipc::IPCResult RecvNotifyError(const MediaResult& aError); 46 mozilla::ipc::IPCResult RecvUpdateStatisticData(const StatisticData& aData); 47 mozilla::ipc::IPCResult RecvNotifyResizing(uint32_t aWidth, uint32_t aHeight); 48 49 nsISerialEventTarget* ManagerThread() const { return mManagerThread; } 50 void AssertOnManagerThread() const { 51 MOZ_ASSERT(mManagerThread->IsOnCurrentThread()); 52 } 53 54 uint64_t Id() const { return mMediaEngineId; } 55 56 private: 57 ~MFMediaEngineChild() = default; 58 59 uint64_t GetUpdatedRenderedFrames(const StatisticData& aData); 60 uint64_t GetUpdatedDroppedFrames(const StatisticData& aData); 61 62 // Only modified on the manager thread. 63 MFMediaEngineWrapper* MOZ_NON_OWNING_REF mOwner; 64 65 const nsCOMPtr<nsISerialEventTarget> mManagerThread; 66 67 // This represents an unique Id to indentify the media engine in the remote 68 // process. Zero is used for the status before initializaing Id from the 69 // remote process. 70 // Modified on the manager thread, and read on other threads. 71 Atomic<uint64_t> mMediaEngineId; 72 73 RefPtr<MFMediaEngineChild> mIPDLSelfRef; 74 75 MozPromiseHolder<GenericNonExclusivePromise> mInitPromiseHolder; 76 MozPromiseRequestHolder<InitMediaEnginePromise> mInitEngineRequest; 77 78 // This is guaranteed always being alive in our lifetime. 79 NotNull<FrameStatistics*> const MOZ_NON_OWNING_REF mFrameStats; 80 81 bool mShutdown = false; 82 83 // Whenever the remote media engine process crashes, we will create a new 84 // engine child to rebuild the connection. These engine child shares the same 85 // frame stats data so we need to keep accumulate same data from previous 86 // engine. 87 Maybe<uint64_t> mAccumulatedPresentedFramesFromPrevEngine; 88 Maybe<uint64_t> mAccumulatedDroppedFramesFromPrevEngine; 89 }; 90 91 /** 92 * MFMediaEngineWrapper acts as an external playback engine, which is 93 * implemented by using the Media Foundation Media Engine. It holds hold an 94 * actor used to communicate with the engine in the remote process. Its methods 95 * are all thread-safe. 96 */ 97 class MFMediaEngineWrapper final : public ExternalPlaybackEngine { 98 public: 99 MFMediaEngineWrapper(ExternalEngineStateMachine* aOwner, 100 FrameStatistics* aFrameStats); 101 ~MFMediaEngineWrapper(); 102 103 // Methods for ExternalPlaybackEngine 104 RefPtr<GenericNonExclusivePromise> Init(const MediaInfo& aInfo, 105 const InitFlagSet& aFlags) override; 106 void Play() override; 107 void Pause() override; 108 void Seek(const media::TimeUnit& aTargetTime) override; 109 void Shutdown() override; 110 void SetPlaybackRate(double aPlaybackRate) override; 111 void SetVolume(double aVolume) override; 112 void SetLooping(bool aLooping) override; 113 void SetPreservesPitch(bool aPreservesPitch) override; 114 media::TimeUnit GetCurrentPosition() override; 115 void NotifyEndOfStream(TrackInfo::TrackType aType) override; 116 uint64_t Id() const override { return mEngine->Id(); } 117 bool IsInited() const { return mEngine->Id() != 0; } 118 bool SetCDMProxy(CDMProxy* aProxy) override; 119 void NotifyResizing(uint32_t aWidth, uint32_t aHeight) override; 120 121 nsISerialEventTarget* ManagerThread() { return mEngine->ManagerThread(); } 122 void AssertOnManagerThread() const { mEngine->AssertOnManagerThread(); } 123 124 private: 125 friend class MFMediaEngineChild; 126 127 void UpdateCurrentTime(double aCurrentTimeInSecond); 128 void NotifyEvent(ExternalEngineEvent aEvent); 129 void NotifyError(const MediaResult& aError); 130 131 const RefPtr<MFMediaEngineChild> mEngine; 132 133 // The current time which we receive from the MediaEngine or set by the state 134 // machine when seeking. 135 std::atomic<double> mCurrentTimeInSecond; 136 }; 137 138 } // namespace mozilla 139 140 #endif // DOM_MEDIA_IPC_MFMEDIAENGINECHILD_H_