MediaEngineSource.h (8699B)
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 /* vim: set ts=8 sts=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 http://mozilla.org/MPL/2.0/. */ 6 7 #ifndef MediaEngineSource_h 8 #define MediaEngineSource_h 9 10 #include "MediaSegment.h" 11 #include "MediaTrackConstraints.h" 12 #include "PerformanceRecorder.h" 13 #include "mozilla/RefPtr.h" 14 #include "mozilla/dom/MediaStreamTrackBinding.h" 15 #include "mozilla/media/MediaUtils.h" 16 #include "nsStringFwd.h" 17 18 namespace mozilla { 19 20 namespace dom { 21 class Blob; 22 struct MediaTrackCapabilities; 23 struct MediaTrackSettings; 24 } // namespace dom 25 26 namespace ipc { 27 class PrincipalInfo; 28 } // namespace ipc 29 30 class MediaEnginePhotoCallback; 31 class MediaEnginePrefs; 32 class MediaTrack; 33 34 /** 35 * Callback interface for TakePhoto(). Either PhotoComplete() or PhotoError() 36 * should be called. 37 */ 38 class MediaEnginePhotoCallback { 39 public: 40 NS_INLINE_DECL_THREADSAFE_REFCOUNTING(MediaEnginePhotoCallback) 41 42 // aBlob is the image captured by MediaEngineSource. It is 43 // called on main thread. 44 virtual nsresult PhotoComplete(already_AddRefed<dom::Blob> aBlob) = 0; 45 46 // It is called on main thread. aRv is the error code. 47 virtual nsresult PhotoError(nsresult aRv) = 0; 48 49 protected: 50 virtual ~MediaEnginePhotoCallback() = default; 51 }; 52 53 /** 54 * Lifecycle state of MediaEngineSource. 55 */ 56 enum MediaEngineSourceState { 57 kAllocated, // Allocated, not yet started. 58 kStarted, // Previously allocated or stopped, then started. 59 kStopped, // Previously started, then stopped. 60 kReleased // Not allocated. 61 }; 62 63 /** 64 * The pure interface of a MediaEngineSource. 65 * 66 * Most sources are helped by the defaults implemented in MediaEngineSource. 67 */ 68 class MediaEngineSourceInterface { 69 public: 70 /** 71 * Return true if this is a fake source. I.e., if it is generating media 72 * itself rather than being an interface to underlying hardware. 73 */ 74 virtual bool IsFake() const = 0; 75 76 /** 77 * Override w/a promise if source has frames, in order to potentially allow 78 * deferring success of source acquisition until first frame has arrived. 79 */ 80 virtual RefPtr<GenericNonExclusivePromise> GetFirstFramePromise() const { 81 return nullptr; 82 } 83 84 /** 85 * Get an id uniquely identifying the source of video frames that this 86 * MediaEngineSource represents. This can be used in profiler markers to 87 * separate markers from different sources into different lanes. 88 */ 89 virtual const TrackingId& GetTrackingId() const = 0; 90 91 /** 92 * Called by MediaEngine to allocate an instance of this source. 93 */ 94 virtual nsresult Allocate(const dom::MediaTrackConstraints& aConstraints, 95 const MediaEnginePrefs& aPrefs, uint64_t aWindowID, 96 const char** aOutBadConstraint) = 0; 97 98 /** 99 * Called by MediaEngine when a MediaTrack has been provided for the source to 100 * feed data to. 101 * 102 * This must be called before Start. 103 */ 104 virtual void SetTrack(const RefPtr<MediaTrack>& aTrack, 105 const PrincipalHandle& aPrincipal) = 0; 106 107 /** 108 * Called by MediaEngine to start feeding data to the track. 109 * 110 * NB: Audio sources handle the enabling of pulling themselves. 111 */ 112 virtual nsresult Start() = 0; 113 114 /** 115 * This brings focus to the selected source, e.g. to bring a captured window 116 * to the front. 117 * 118 * We return one of the following: 119 * NS_OK - Success. 120 * NS_ERROR_NOT_AVAILABLE - For backends where focusing does not make sense. 121 * NS_ERROR_NOT_IMPLEMENTED - For backends where focusing makes sense, but 122 * is not yet implemented. 123 * NS_ERROR_FAILURE - Failures reported from underlying code. 124 */ 125 virtual nsresult FocusOnSelectedSource() = 0; 126 127 /** 128 * Applies new constraints to the capability selection for the underlying 129 * device. 130 * 131 * Should the constraints lead to choosing a new capability while the device 132 * is actively being captured, the device will restart using the new 133 * capability. 134 * 135 * We return one of the following: 136 * NS_OK - Successful reconfigure. 137 * NS_ERROR_INVALID_ARG - Couldn't find a capability fitting aConstraints. 138 * See aBadConstraint for details. 139 * NS_ERROR_UNEXPECTED - Reconfiguring the underlying device failed 140 * unexpectedly. This leaves the device in a stopped 141 * state. 142 */ 143 virtual nsresult Reconfigure(const dom::MediaTrackConstraints& aConstraints, 144 const MediaEnginePrefs& aPrefs, 145 const char** aOutBadConstraint) = 0; 146 147 /** 148 * Called by MediaEngine to stop feeding data to the track. 149 * 150 * Double-stopping is allowed and will return NS_OK. This is necessary 151 * sometimes during shutdown. 152 * 153 * NB: Audio sources handle the disabling of pulling themselves. 154 */ 155 virtual nsresult Stop() = 0; 156 157 /** 158 * Called by MediaEngine to deallocate an underlying device. 159 */ 160 virtual nsresult Deallocate() = 0; 161 162 /** 163 * If implementation of MediaEngineSource supports TakePhoto(), the picture 164 * should be returned via aCallback object. Otherwise, it returns 165 * NS_ERROR_NOT_IMPLEMENTED. 166 */ 167 virtual nsresult TakePhoto(MediaEnginePhotoCallback* aCallback) = 0; 168 169 /** 170 * GetBestFitnessDistance returns the best distance the capture device can 171 * offer as a whole, given an accumulated number of ConstraintSets. Ideal 172 * values are considered in the first ConstraintSet only. Plain values are 173 * treated as Ideal in the first ConstraintSet. Plain values are treated as 174 * Exact in subsequent ConstraintSets. Infinity = UINT32_MAX e.g. device 175 * cannot satisfy accumulated ConstraintSets. A finite result may be used to 176 * calculate this device's ranking as a choice. 177 */ 178 virtual uint32_t GetBestFitnessDistance( 179 const nsTArray<const NormalizedConstraintSet*>& aConstraintSets, 180 const MediaEnginePrefs& aPrefs) const = 0; 181 182 /** 183 * Returns the current settings of the underlying device. 184 * 185 * Note that this might not be the settings of the underlying hardware. 186 * In case of a camera where we intervene and scale frames to avoid 187 * leaking information from other documents than the current one, 188 * GetSettings() will return the scaled resolution. I.e., the 189 * device settings as seen by js. 190 */ 191 virtual void GetSettings(dom::MediaTrackSettings& aOutSettings) const = 0; 192 193 virtual void GetCapabilities( 194 dom::MediaTrackCapabilities& aOutCapabilities) const = 0; 195 }; 196 197 /** 198 * Abstract base class for MediaEngineSources. 199 * 200 * Implements defaults for some common MediaEngineSourceInterface methods below. 201 * Also implements RefPtr support and an owning-thread model for thread safety 202 * checks in subclasses. 203 */ 204 class MediaEngineSource : public MediaEngineSourceInterface { 205 public: 206 // code inside webrtc.org assumes these sizes; don't use anything smaller 207 // without verifying it's ok 208 static const unsigned int kMaxDeviceNameLength = 128; 209 static const unsigned int kMaxUniqueIdLength = 256; 210 211 /** 212 * Returns true if the given source type is for video, false otherwise. 213 * Only call with real types. 214 */ 215 static bool IsVideo(dom::MediaSourceEnum aSource); 216 217 /** 218 * Returns true if the given source type is for audio, false otherwise. 219 * Only call with real types. 220 */ 221 static bool IsAudio(dom::MediaSourceEnum aSource); 222 223 NS_INLINE_DECL_THREADSAFE_REFCOUNTING(MediaEngineSource) 224 NS_DECL_OWNINGEVENTTARGET 225 226 void AssertIsOnOwningThread() const { 227 NS_ASSERT_OWNINGTHREAD(MediaEngineSource); 228 } 229 230 const TrackingId& GetTrackingId() const override { 231 static auto notImplementedId = TrackingId(); 232 return notImplementedId; 233 } 234 235 // Not fake by default. 236 bool IsFake() const override; 237 238 // Returns NS_ERROR_NOT_AVAILABLE by default. 239 nsresult FocusOnSelectedSource() override; 240 241 // TakePhoto returns NS_ERROR_NOT_IMPLEMENTED by default, 242 // to tell the caller to fallback to other methods. 243 nsresult TakePhoto(MediaEnginePhotoCallback* aCallback) override; 244 245 // Returns a default distance of 0 for devices that don't have capabilities. 246 uint32_t GetBestFitnessDistance( 247 const nsTArray<const NormalizedConstraintSet*>& aConstraintSets, 248 const MediaEnginePrefs& aPrefs) const override { 249 return 0; 250 } 251 252 virtual MediaEventSource<void>* CaptureEndedEvent() { return nullptr; } 253 254 protected: 255 virtual ~MediaEngineSource(); 256 }; 257 258 } // namespace mozilla 259 260 #endif /* MediaEngineSource_h */