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