/src/mozilla-central/dom/media/webrtc/MediaEngineRemoteVideoSource.h
Line | Count | Source (jump to first uncovered line) |
1 | | /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ |
2 | | /* vim: set sw=2 ts=8 et ft=cpp : */ |
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 file, |
5 | | * You can obtain one at http://mozilla.org/MPL/2.0/. */ |
6 | | |
7 | | #ifndef MEDIAENGINE_REMOTE_VIDEO_SOURCE_H_ |
8 | | #define MEDIAENGINE_REMOTE_VIDEO_SOURCE_H_ |
9 | | |
10 | | #include "prcvar.h" |
11 | | #include "prthread.h" |
12 | | #include "nsIThread.h" |
13 | | #include "nsIRunnable.h" |
14 | | |
15 | | #include "mozilla/Mutex.h" |
16 | | #include "nsCOMPtr.h" |
17 | | #include "nsThreadUtils.h" |
18 | | #include "DOMMediaStream.h" |
19 | | #include "nsDirectoryServiceDefs.h" |
20 | | #include "nsComponentManagerUtils.h" |
21 | | |
22 | | // Avoid warnings about redefinition of WARN_UNUSED_RESULT |
23 | | #include "ipc/IPCMessageUtils.h" |
24 | | #include "VideoUtils.h" |
25 | | #include "MediaEngineSource.h" |
26 | | #include "VideoSegment.h" |
27 | | #include "AudioSegment.h" |
28 | | #include "StreamTracks.h" |
29 | | #include "MediaStreamGraph.h" |
30 | | |
31 | | #include "MediaEngineWrapper.h" |
32 | | #include "mozilla/dom/MediaStreamTrackBinding.h" |
33 | | |
34 | | // Camera Access via IPC |
35 | | #include "CamerasChild.h" |
36 | | |
37 | | #include "NullTransport.h" |
38 | | |
39 | | // WebRTC includes |
40 | | #include "webrtc/common_video/include/i420_buffer_pool.h" |
41 | | #include "webrtc/modules/video_capture/video_capture_defines.h" |
42 | | |
43 | | namespace webrtc { |
44 | | using CaptureCapability = VideoCaptureCapability; |
45 | | } |
46 | | |
47 | | namespace mozilla { |
48 | | |
49 | | // Fitness distance is defined in |
50 | | // https://w3c.github.io/mediacapture-main/getusermedia.html#dfn-selectsettings |
51 | | |
52 | | // The main difference of feasibility and fitness distance is that if the |
53 | | // constraint is required ('max', or 'exact'), and the settings dictionary's value |
54 | | // for the constraint does not satisfy the constraint, the fitness distance is |
55 | | // positive infinity. Given a continuous space of settings dictionaries comprising |
56 | | // all discrete combinations of dimension and frame-rate related properties, |
57 | | // the feasibility distance is still in keeping with the constraints algorithm. |
58 | | enum DistanceCalculation { |
59 | | kFitness, |
60 | | kFeasibility |
61 | | }; |
62 | | |
63 | | /** |
64 | | * The WebRTC implementation of the MediaEngine interface. |
65 | | */ |
66 | | class MediaEngineRemoteVideoSource : public MediaEngineSource, |
67 | | public camera::FrameRelay |
68 | | { |
69 | 0 | ~MediaEngineRemoteVideoSource() = default; |
70 | | |
71 | | struct CapabilityCandidate { |
72 | | explicit CapabilityCandidate(webrtc::CaptureCapability&& aCapability, |
73 | | uint32_t aDistance = 0) |
74 | | : mCapability(std::forward<webrtc::CaptureCapability>(aCapability)) |
75 | 0 | , mDistance(aDistance) {} |
76 | | |
77 | | const webrtc::CaptureCapability mCapability; |
78 | | uint32_t mDistance; |
79 | | }; |
80 | | |
81 | | class CapabilityComparator { |
82 | | public: |
83 | | bool Equals(const CapabilityCandidate& aCandidate, |
84 | | const webrtc::CaptureCapability& aCapability) const |
85 | 0 | { |
86 | 0 | return aCandidate.mCapability == aCapability; |
87 | 0 | } |
88 | | }; |
89 | | |
90 | | bool ChooseCapability(const NormalizedConstraints& aConstraints, |
91 | | const MediaEnginePrefs& aPrefs, |
92 | | const nsString& aDeviceId, |
93 | | webrtc::CaptureCapability& aCapability, |
94 | | const DistanceCalculation aCalculate); |
95 | | |
96 | | uint32_t GetDistance(const webrtc::CaptureCapability& aCandidate, |
97 | | const NormalizedConstraintSet &aConstraints, |
98 | | const nsString& aDeviceId, |
99 | | const DistanceCalculation aCalculate) const; |
100 | | |
101 | | uint32_t GetFitnessDistance(const webrtc::CaptureCapability& aCandidate, |
102 | | const NormalizedConstraintSet &aConstraints, |
103 | | const nsString& aDeviceId) const; |
104 | | |
105 | | uint32_t GetFeasibilityDistance(const webrtc::CaptureCapability& aCandidate, |
106 | | const NormalizedConstraintSet &aConstraints, |
107 | | const nsString& aDeviceId) const; |
108 | | |
109 | | static void TrimLessFitCandidates(nsTArray<CapabilityCandidate>& aSet); |
110 | | |
111 | | uint32_t GetBestFitnessDistance( |
112 | | const nsTArray<const NormalizedConstraintSet*>& aConstraintSets, |
113 | | const nsString& aDeviceId) const override; |
114 | | |
115 | | public: |
116 | | MediaEngineRemoteVideoSource(int aIndex, |
117 | | camera::CaptureEngine aCapEngine, |
118 | | dom::MediaSourceEnum aMediaSource, |
119 | | bool aScary); |
120 | | |
121 | | // ExternalRenderer |
122 | | int DeliverFrame(uint8_t* buffer, |
123 | | const camera::VideoFrameProperties& properties) override; |
124 | | |
125 | | // MediaEngineSource |
126 | | dom::MediaSourceEnum GetMediaSource() const override |
127 | 0 | { |
128 | 0 | return mMediaSource; |
129 | 0 | } |
130 | | nsresult Allocate(const dom::MediaTrackConstraints &aConstraints, |
131 | | const MediaEnginePrefs &aPrefs, |
132 | | const nsString& aDeviceId, |
133 | | const ipc::PrincipalInfo& aPrincipalInfo, |
134 | | AllocationHandle** aOutHandle, |
135 | | const char** aOutBadConstraint) override; |
136 | | nsresult Deallocate(const RefPtr<const AllocationHandle>& aHandle) override; |
137 | | nsresult SetTrack(const RefPtr<const AllocationHandle>& aHandle, |
138 | | const RefPtr<SourceMediaStream>& aStream, |
139 | | TrackID aTrackID, |
140 | | const PrincipalHandle& aPrincipal) override; |
141 | | nsresult Start(const RefPtr<const AllocationHandle>& aHandle) override; |
142 | | nsresult Reconfigure(const RefPtr<AllocationHandle>& aHandle, |
143 | | const dom::MediaTrackConstraints& aConstraints, |
144 | | const MediaEnginePrefs& aPrefs, |
145 | | const nsString& aDeviceId, |
146 | | const char** aOutBadConstraint) override; |
147 | | nsresult FocusOnSelectedSource(const RefPtr<const AllocationHandle>& aHandle) override; |
148 | | nsresult Stop(const RefPtr<const AllocationHandle>& aHandle) override; |
149 | | void Pull(const RefPtr<const AllocationHandle>& aHandle, |
150 | | const RefPtr<SourceMediaStream>& aStream, |
151 | | TrackID aTrackID, |
152 | | StreamTime aDesiredTime, |
153 | | const PrincipalHandle& aPrincipalHandle) override; |
154 | | |
155 | | |
156 | | void GetSettings(dom::MediaTrackSettings& aOutSettings) const override; |
157 | | |
158 | | void Refresh(int aIndex); |
159 | | |
160 | | void Shutdown() override; |
161 | | |
162 | | nsString GetName() const override; |
163 | | void SetName(nsString aName); |
164 | | |
165 | | nsCString GetUUID() const override; |
166 | | void SetUUID(const char* aUUID); |
167 | | |
168 | 0 | bool GetScary() const override { return mScary; } |
169 | | |
170 | | private: |
171 | | // Initialize the needed Video engine interfaces. |
172 | | void Init(); |
173 | | |
174 | | /** |
175 | | * Returns the number of capabilities for the underlying device. |
176 | | * |
177 | | * Guaranteed to return at least one capability. |
178 | | */ |
179 | | size_t NumCapabilities() const; |
180 | | |
181 | | /** |
182 | | * Returns the capability with index `aIndex` for our assigned device. |
183 | | * |
184 | | * It is an error to call this with `aIndex >= NumCapabilities()`. |
185 | | */ |
186 | | webrtc::CaptureCapability GetCapability(size_t aIndex) const; |
187 | | |
188 | | int mCaptureIndex; |
189 | | const dom::MediaSourceEnum mMediaSource; // source of media (camera | application | screen) |
190 | | const camera::CaptureEngine mCapEngine; |
191 | | const bool mScary; |
192 | | |
193 | | // mMutex protects certain members on 3 threads: |
194 | | // MediaManager, Cameras IPC and MediaStreamGraph. |
195 | | Mutex mMutex; |
196 | | |
197 | | // Current state of this source. |
198 | | // Set under mMutex on the owning thread. Accessed under one of the two. |
199 | | MediaEngineSourceState mState = kReleased; |
200 | | |
201 | | // The source stream that we feed video data to. |
202 | | // Set under mMutex on the owning thread. Accessed under one of the two. |
203 | | RefPtr<SourceMediaStream> mStream; |
204 | | |
205 | | // The TrackID in mStream that we feed video data to. |
206 | | // Set under mMutex on the owning thread. Accessed under one of the two. |
207 | | TrackID mTrackID = TRACK_NONE; |
208 | | |
209 | | // The PrincipalHandle that gets attached to the frames we feed to mStream. |
210 | | // Set under mMutex on the owning thread. Accessed under one of the two. |
211 | | PrincipalHandle mPrincipal = PRINCIPAL_HANDLE_NONE; |
212 | | |
213 | | // Set in Start() and Deallocate() on the owning thread. |
214 | | // Accessed in DeliverFrame() on the camera IPC thread, guaranteed to happen |
215 | | // after Start() and before the end of Stop(). |
216 | | RefPtr<layers::ImageContainer> mImageContainer; |
217 | | |
218 | | // The latest frame delivered from the video capture backend. |
219 | | // Protected by mMutex. |
220 | | RefPtr<layers::Image> mImage; |
221 | | |
222 | | // A buffer pool used to manage the temporary buffer used when rescaling |
223 | | // incoming images. Cameras IPC thread only. |
224 | | webrtc::I420BufferPool mRescalingBufferPool; |
225 | | |
226 | | // The intrinsic size of the latest captured image, so we can feed black |
227 | | // images of the same size while stopped. |
228 | | // Set under mMutex on the Cameras IPC thread. Accessed under one of the two. |
229 | | gfx::IntSize mImageSize = gfx::IntSize(0, 0); |
230 | | |
231 | | struct AtomicBool { |
232 | | Atomic<bool> mValue; |
233 | | }; |
234 | | |
235 | | // True when resolution settings have been updated from a real frame's |
236 | | // resolution. Threadsafe. |
237 | | // TODO: This can be removed in bug 1453269. |
238 | | const RefPtr<media::Refcountable<AtomicBool>> mSettingsUpdatedByFrame; |
239 | | |
240 | | // The current settings of this source. |
241 | | // Note that these may be different from the settings of the underlying device |
242 | | // since we scale frames to avoid fingerprinting. |
243 | | // Members are main thread only. |
244 | | const RefPtr<media::Refcountable<dom::MediaTrackSettings>> mSettings; |
245 | | |
246 | | // The capability currently chosen by constraints of the user of this source. |
247 | | // Set under mMutex on the owning thread. Accessed under one of the two. |
248 | | webrtc::CaptureCapability mCapability; |
249 | | |
250 | | /** |
251 | | * Capabilities that we choose between when applying constraints. |
252 | | * |
253 | | * This is mutable so that the const method NumCapabilities() can reset it. |
254 | | * Owning thread only. |
255 | | */ |
256 | | mutable nsTArray<webrtc::CaptureCapability> mHardcodedCapabilities; |
257 | | |
258 | | nsString mDeviceName; |
259 | | nsCString mUniqueId; |
260 | | nsString mFacingMode; |
261 | | |
262 | | // Whether init has successfully completed. |
263 | | // Set in Init(), reset in Shutdown(). |
264 | | // Owning thread only. |
265 | | bool mInitDone = false; |
266 | | }; |
267 | | |
268 | | } |
269 | | |
270 | | #endif /* MEDIAENGINE_REMOTE_VIDEO_SOURCE_H_ */ |