Coverage Report

Created: 2018-09-25 14:53

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