FrameTransformerProxy.h (5065B)
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 /* vim: set ts=2 et sw=2 tw=80: */ 3 /* This Source Code Form is subject to the terms of the Mozilla Public 4 * License, v. 2.0. If a copy of the MPL was not distributed with this 5 * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ 6 7 #ifndef MOZILLA_DOM_MEDIA_WEBRTC_LIBWEBRTCGLUE_FRAMETRANSFORMERPROXY_H_ 8 #define MOZILLA_DOM_MEDIA_WEBRTC_LIBWEBRTCGLUE_FRAMETRANSFORMERPROXY_H_ 9 10 #include <list> 11 #include <memory> 12 13 #include "mozilla/Maybe.h" 14 #include "mozilla/Mutex.h" 15 #include "nsISupportsImpl.h" 16 17 class nsIEventTarget; 18 19 namespace webrtc { 20 class TransformableFrameInterface; 21 class VideoReceiveStreamInterface; 22 } // namespace webrtc 23 24 namespace mozilla { 25 26 class FrameTransformer; 27 class WebrtcVideoConduit; 28 class CopyableErrorResult; 29 30 namespace dom { 31 class RTCRtpScriptTransformer; 32 class RTCRtpSender; 33 class RTCRtpReceiver; 34 } // namespace dom 35 36 // This corresponds to a single RTCRtpScriptTransform (and its 37 // RTCRtpScriptTransformer, once that is created on the worker thread). This 38 // is intended to decouple threading/lifecycle/include-dependencies between 39 // FrameTransformer (on the libwebrtc side of things), RTCRtpScriptTransformer 40 // (on the worker side of things), RTCRtpScriptTransform and 41 // RTCRtpSender/Receiver (on the main thread), and prevents frames from being 42 // lost while we're setting things up on the worker. In other words, this 43 // handles the inconvenient stuff. 44 class FrameTransformerProxy { 45 public: 46 NS_INLINE_DECL_THREADSAFE_REFCOUNTING(FrameTransformerProxy); 47 48 FrameTransformerProxy(); 49 FrameTransformerProxy(const FrameTransformerProxy& aRhs) = delete; 50 FrameTransformerProxy(FrameTransformerProxy&& aRhs) = delete; 51 FrameTransformerProxy& operator=(const FrameTransformerProxy& aRhs) = delete; 52 FrameTransformerProxy& operator=(FrameTransformerProxy&& aRhs) = delete; 53 54 // Called at most once (might not be called if the worker is shutting down), 55 // on the worker thread. 56 void SetScriptTransformer(dom::RTCRtpScriptTransformer& aTransformer); 57 58 // Can be called from the worker thread (if the worker is shutting down), or 59 // main (if RTCRtpSender/RTCRtpReceiver is done with us). 60 void ReleaseScriptTransformer(); 61 62 // RTCRtpScriptTransformer calls this when it is done transforming a frame. 63 void OnTransformedFrame( 64 std::unique_ptr<webrtc::TransformableFrameInterface> aFrame); 65 66 Maybe<bool> IsVideo() const; 67 68 // Called by FrameTransformer, on main. Only one FrameTransformer will ever 69 // be registered over the lifetime of this object. This is where we route 70 // transformed frames. If this is set, we can also expect to receive calls to 71 // Transform. 72 void SetLibwebrtcTransformer(FrameTransformer* aLibwebrtcTransformer); 73 74 // FrameTransformer calls this while we're registered with it (by 75 // SetLibwebrtcTransformer) 76 void Transform(std::unique_ptr<webrtc::TransformableFrameInterface> aFrame); 77 78 void SetSender(dom::RTCRtpSender* aSender); 79 void SetReceiver(dom::RTCRtpReceiver* aReceiver); 80 81 // Called on worker thread 82 bool RequestKeyFrame(); 83 // Called on call thread 84 void KeyFrameRequestDone(); 85 86 bool GenerateKeyFrame(const Maybe<std::string>& aRid); 87 void GenerateKeyFrameError(const Maybe<std::string>& aRid, 88 const CopyableErrorResult& aResult); 89 90 private: 91 virtual ~FrameTransformerProxy(); 92 93 // Worker thread only. Set at most once. 94 // Does not need any mutex protection. 95 RefPtr<dom::RTCRtpScriptTransformer> mScriptTransformer; 96 97 mutable Mutex mMutex; 98 // Written on the worker thread. Read on libwebrtc threads, mainthread, and 99 // the worker thread. 100 RefPtr<nsIEventTarget> mWorkerThread MOZ_GUARDED_BY(mMutex); 101 // We need a flag for this in case the ReleaseScriptTransformer call comes 102 // _before_ the script transformer is set, to disable SetScriptTransformer. 103 // Could be written on main or the worker thread. Read on main, worker, and 104 // libwebrtc threads. 105 bool mReleaseScriptTransformerCalled MOZ_GUARDED_BY(mMutex) = false; 106 // Used when frames arrive before the script transformer is created, which 107 // should be pretty rare. Accessed on worker and libwebrtc threads. 108 std::list<std::unique_ptr<webrtc::TransformableFrameInterface>> mQueue 109 MOZ_GUARDED_BY(mMutex); 110 // Written on main, read on the worker thread. 111 FrameTransformer* mLibwebrtcTransformer MOZ_GUARDED_BY(mMutex) = nullptr; 112 113 // TODO: Will be used to route GenerateKeyFrame. Details TBD. 114 RefPtr<dom::RTCRtpSender> mSender MOZ_GUARDED_BY(mMutex); 115 // Set on mainthread. This is where we route RequestKeyFrame calls from the 116 // worker thread. Mutex protected because spec wants sync errors if the 117 // receiver is not set (or the right type). If spec drops this requirement, 118 // this could be mainthread only and non-mutex-protected. 119 RefPtr<dom::RTCRtpReceiver> mReceiver MOZ_GUARDED_BY(mMutex); 120 Maybe<bool> mVideo MOZ_GUARDED_BY(mMutex); 121 }; 122 123 } // namespace mozilla 124 125 #endif // MOZILLA_DOM_MEDIA_WEBRTC_LIBWEBRTCGLUE_FRAMETRANSFORMERPROXY_H_