diff options
Diffstat (limited to '')
-rw-r--r-- | dom/media/webrtc/MediaEngineSource.h | 255 |
1 files changed, 255 insertions, 0 deletions
diff --git a/dom/media/webrtc/MediaEngineSource.h b/dom/media/webrtc/MediaEngineSource.h new file mode 100644 index 0000000000..d32796b094 --- /dev/null +++ b/dom/media/webrtc/MediaEngineSource.h @@ -0,0 +1,255 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef MediaEngineSource_h +#define MediaEngineSource_h + +#include "MediaSegment.h" +#include "MediaTrackConstraints.h" +#include "mozilla/dom/MediaStreamTrackBinding.h" +#include "mozilla/media/MediaUtils.h" +#include "mozilla/RefPtr.h" +#include "mozilla/ThreadSafeWeakPtr.h" +#include "nsStringFwd.h" +#include "PerformanceRecorder.h" + +namespace mozilla { + +namespace dom { +class Blob; +struct MediaTrackSettings; +} // namespace dom + +namespace ipc { +class PrincipalInfo; +} // namespace ipc + +class MediaEnginePhotoCallback; +class MediaEnginePrefs; +class MediaTrack; + +/** + * Callback interface for TakePhoto(). Either PhotoComplete() or PhotoError() + * should be called. + */ +class MediaEnginePhotoCallback { + public: + NS_INLINE_DECL_THREADSAFE_REFCOUNTING(MediaEnginePhotoCallback) + + // aBlob is the image captured by MediaEngineSource. It is + // called on main thread. + virtual nsresult PhotoComplete(already_AddRefed<dom::Blob> aBlob) = 0; + + // It is called on main thread. aRv is the error code. + virtual nsresult PhotoError(nsresult aRv) = 0; + + protected: + virtual ~MediaEnginePhotoCallback() = default; +}; + +/** + * Lifecycle state of MediaEngineSource. + */ +enum MediaEngineSourceState { + kAllocated, // Allocated, not yet started. + kStarted, // Previously allocated or stopped, then started. + kStopped, // Previously started, then stopped. + kReleased // Not allocated. +}; + +/** + * The pure interface of a MediaEngineSource. + * + * Most sources are helped by the defaults implemented in MediaEngineSource. + */ +class MediaEngineSourceInterface { + public: + /** + * Return true if this is a fake source. I.e., if it is generating media + * itself rather than being an interface to underlying hardware. + */ + virtual bool IsFake() const = 0; + + /** + * Override w/a promise if source has frames, in order to potentially allow + * deferring success of source acquisition until first frame has arrived. + */ + virtual RefPtr<GenericNonExclusivePromise> GetFirstFramePromise() const { + return nullptr; + } + + /** + * Get an id uniquely identifying the source of video frames that this + * MediaEngineSource represents. This can be used in profiler markers to + * separate markers from different sources into different lanes. + */ + virtual const TrackingId& GetTrackingId() const = 0; + + /** + * Called by MediaEngine to allocate an instance of this source. + */ + virtual nsresult Allocate(const dom::MediaTrackConstraints& aConstraints, + const MediaEnginePrefs& aPrefs, uint64_t aWindowID, + const char** aOutBadConstraint) = 0; + + /** + * Called by MediaEngine when a MediaTrack has been provided for the source to + * feed data to. + * + * This must be called before Start. + */ + virtual void SetTrack(const RefPtr<MediaTrack>& aTrack, + const PrincipalHandle& aPrincipal) = 0; + + /** + * Called by MediaEngine to start feeding data to the track. + * + * NB: Audio sources handle the enabling of pulling themselves. + */ + virtual nsresult Start() = 0; + + /** + * This brings focus to the selected source, e.g. to bring a captured window + * to the front. + * + * We return one of the following: + * NS_OK - Success. + * NS_ERROR_NOT_AVAILABLE - For backends where focusing does not make sense. + * NS_ERROR_NOT_IMPLEMENTED - For backends where focusing makes sense, but + * is not yet implemented. + * NS_ERROR_FAILURE - Failures reported from underlying code. + */ + virtual nsresult FocusOnSelectedSource() = 0; + + /** + * Applies new constraints to the capability selection for the underlying + * device. + * + * Should the constraints lead to choosing a new capability while the device + * is actively being captured, the device will restart using the new + * capability. + * + * We return one of the following: + * NS_OK - Successful reconfigure. + * NS_ERROR_INVALID_ARG - Couldn't find a capability fitting aConstraints. + * See aBadConstraint for details. + * NS_ERROR_UNEXPECTED - Reconfiguring the underlying device failed + * unexpectedly. This leaves the device in a stopped + * state. + */ + virtual nsresult Reconfigure(const dom::MediaTrackConstraints& aConstraints, + const MediaEnginePrefs& aPrefs, + const char** aOutBadConstraint) = 0; + + /** + * Called by MediaEngine to stop feeding data to the track. + * + * Double-stopping is allowed and will return NS_OK. This is necessary + * sometimes during shutdown. + * + * NB: Audio sources handle the disabling of pulling themselves. + */ + virtual nsresult Stop() = 0; + + /** + * Called by MediaEngine to deallocate an underlying device. + */ + virtual nsresult Deallocate() = 0; + + /** + * If implementation of MediaEngineSource supports TakePhoto(), the picture + * should be returned via aCallback object. Otherwise, it returns + * NS_ERROR_NOT_IMPLEMENTED. + */ + virtual nsresult TakePhoto(MediaEnginePhotoCallback* aCallback) = 0; + + /** + * GetBestFitnessDistance returns the best distance the capture device can + * offer as a whole, given an accumulated number of ConstraintSets. Ideal + * values are considered in the first ConstraintSet only. Plain values are + * treated as Ideal in the first ConstraintSet. Plain values are treated as + * Exact in subsequent ConstraintSets. Infinity = UINT32_MAX e.g. device + * cannot satisfy accumulated ConstraintSets. A finite result may be used to + * calculate this device's ranking as a choice. + */ + virtual uint32_t GetBestFitnessDistance( + const nsTArray<const NormalizedConstraintSet*>& aConstraintSets) + const = 0; + + /** + * Returns the current settings of the underlying device. + * + * Note that this might not be the settings of the underlying hardware. + * In case of a camera where we intervene and scale frames to avoid + * leaking information from other documents than the current one, + * GetSettings() will return the scaled resolution. I.e., the + * device settings as seen by js. + */ + virtual void GetSettings(dom::MediaTrackSettings& aOutSettings) const = 0; +}; + +/** + * Abstract base class for MediaEngineSources. + * + * Implements defaults for some common MediaEngineSourceInterface methods below. + * Also implements RefPtr support and an owning-thread model for thread safety + * checks in subclasses. + */ +class MediaEngineSource : public MediaEngineSourceInterface { + public: + // code inside webrtc.org assumes these sizes; don't use anything smaller + // without verifying it's ok + static const unsigned int kMaxDeviceNameLength = 128; + static const unsigned int kMaxUniqueIdLength = 256; + + /** + * Returns true if the given source type is for video, false otherwise. + * Only call with real types. + */ + static bool IsVideo(dom::MediaSourceEnum aSource); + + /** + * Returns true if the given source type is for audio, false otherwise. + * Only call with real types. + */ + static bool IsAudio(dom::MediaSourceEnum aSource); + + NS_INLINE_DECL_THREADSAFE_REFCOUNTING(MediaEngineSource) + NS_DECL_OWNINGEVENTTARGET + + void AssertIsOnOwningThread() const { + NS_ASSERT_OWNINGTHREAD(MediaEngineSource); + } + + const TrackingId& GetTrackingId() const override { + static auto notImplementedId = TrackingId(); + return notImplementedId; + } + + // Not fake by default. + bool IsFake() const override; + + // Returns NS_ERROR_NOT_AVAILABLE by default. + nsresult FocusOnSelectedSource() override; + + // TakePhoto returns NS_ERROR_NOT_IMPLEMENTED by default, + // to tell the caller to fallback to other methods. + nsresult TakePhoto(MediaEnginePhotoCallback* aCallback) override; + + // Returns a default distance of 0 for devices that don't have capabilities. + uint32_t GetBestFitnessDistance( + const nsTArray<const NormalizedConstraintSet*>& aConstraintSets) + const override { + return 0; + } + + protected: + virtual ~MediaEngineSource(); +}; + +} // namespace mozilla + +#endif /* MediaEngineSource_h */ |