diff options
Diffstat (limited to '')
-rw-r--r-- | dom/media/webrtc/MediaEngineRemoteVideoSource.h | 242 |
1 files changed, 242 insertions, 0 deletions
diff --git a/dom/media/webrtc/MediaEngineRemoteVideoSource.h b/dom/media/webrtc/MediaEngineRemoteVideoSource.h new file mode 100644 index 0000000000..7e4f852701 --- /dev/null +++ b/dom/media/webrtc/MediaEngineRemoteVideoSource.h @@ -0,0 +1,242 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set sw=2 ts=8 et ft=cpp : */ +/* 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 MEDIAENGINE_REMOTE_VIDEO_SOURCE_H_ +#define MEDIAENGINE_REMOTE_VIDEO_SOURCE_H_ + +#include "prcvar.h" +#include "prthread.h" + +#include "mozilla/Mutex.h" +#include "nsCOMPtr.h" +#include "nsThreadUtils.h" +#include "DOMMediaStream.h" +#include "nsDirectoryServiceDefs.h" +#include "nsComponentManagerUtils.h" + +// Avoid warnings about redefinition of WARN_UNUSED_RESULT +#include "ipc/IPCMessageUtils.h" +#include "VideoUtils.h" +#include "MediaEngineSource.h" +#include "VideoSegment.h" +#include "AudioSegment.h" +#include "MediaTrackGraph.h" + +#include "MediaEngineWrapper.h" +#include "mozilla/dom/MediaStreamTrackBinding.h" + +// Camera Access via IPC +#include "CamerasChild.h" + +#include "NullTransport.h" + +// WebRTC includes +#include "common_video/include/video_frame_buffer_pool.h" +#include "modules/video_capture/video_capture_defines.h" + +namespace webrtc { +using CaptureCapability = VideoCaptureCapability; +} + +namespace mozilla { + +// Fitness distance is defined in +// https://w3c.github.io/mediacapture-main/getusermedia.html#dfn-selectsettings + +// The main difference of feasibility and fitness distance is that if the +// constraint is required ('max', or 'exact'), and the settings dictionary's +// value for the constraint does not satisfy the constraint, the fitness +// distance is positive infinity. Given a continuous space of settings +// dictionaries comprising all discrete combinations of dimension and frame-rate +// related properties, the feasibility distance is still in keeping with the +// constraints algorithm. +enum DistanceCalculation { kFitness, kFeasibility }; + +/** + * The WebRTC implementation of the MediaEngine interface. + */ +class MediaEngineRemoteVideoSource : public MediaEngineSource, + public camera::FrameRelay { + ~MediaEngineRemoteVideoSource(); + + struct CapabilityCandidate { + explicit CapabilityCandidate(webrtc::CaptureCapability aCapability, + uint32_t aDistance = 0) + : mCapability(aCapability), mDistance(aDistance) {} + + const webrtc::CaptureCapability mCapability; + uint32_t mDistance; + }; + + class CapabilityComparator { + public: + bool Equals(const CapabilityCandidate& aCandidate, + const webrtc::CaptureCapability& aCapability) const { + return aCandidate.mCapability == aCapability; + } + }; + + bool ChooseCapability(const NormalizedConstraints& aConstraints, + const MediaEnginePrefs& aPrefs, + webrtc::CaptureCapability& aCapability, + const DistanceCalculation aCalculate); + + uint32_t GetDistance(const webrtc::CaptureCapability& aCandidate, + const NormalizedConstraintSet& aConstraints, + const DistanceCalculation aCalculate) const; + + uint32_t GetFitnessDistance( + const webrtc::CaptureCapability& aCandidate, + const NormalizedConstraintSet& aConstraints) const; + + uint32_t GetFeasibilityDistance( + const webrtc::CaptureCapability& aCandidate, + const NormalizedConstraintSet& aConstraints) const; + + static void TrimLessFitCandidates(nsTArray<CapabilityCandidate>& aSet); + + public: + explicit MediaEngineRemoteVideoSource(const MediaDevice* aMediaDevice); + + // ExternalRenderer + int DeliverFrame(uint8_t* aBuffer, + const camera::VideoFrameProperties& aProps) override; + + // MediaEngineSource + nsresult Allocate(const dom::MediaTrackConstraints& aConstraints, + const MediaEnginePrefs& aPrefs, uint64_t aWindowID, + const char** aOutBadConstraint) override; + nsresult Deallocate() override; + void SetTrack(const RefPtr<MediaTrack>& aTrack, + const PrincipalHandle& aPrincipal) override; + nsresult Start() override; + nsresult Reconfigure(const dom::MediaTrackConstraints& aConstraints, + const MediaEnginePrefs& aPrefs, + const char** aOutBadConstraint) override; + nsresult FocusOnSelectedSource() override; + nsresult Stop() override; + + uint32_t GetBestFitnessDistance( + const nsTArray<const NormalizedConstraintSet*>& aConstraintSets) + const override; + void GetSettings(dom::MediaTrackSettings& aOutSettings) const override; + + RefPtr<GenericNonExclusivePromise> GetFirstFramePromise() const override { + return mFirstFramePromise; + } + + const TrackingId& GetTrackingId() const override; + + static camera::CaptureEngine CaptureEngine(dom::MediaSourceEnum aMediaSource); + + private: + /** + * Returns the number of capabilities for the underlying device. + * + * Guaranteed to return at least one capability. + */ + size_t NumCapabilities() const; + + /** + * Returns the capability with index `aIndex` for our assigned device. + * + * It is an error to call this with `aIndex >= NumCapabilities()`. + * + * The lifetime of the returned capability is the same as for this source. + */ + webrtc::CaptureCapability& GetCapability(size_t aIndex) const; + + int mCaptureId = -1; + const camera::CaptureEngine mCapEngine; // source of media (cam, screen etc) + + // A tracking id used to uniquely identify the source of video frames. + // Set under mMutex on the owning thread. Accessed under one of the two. + TrackingId mTrackingId; + + // Mirror of mTrackingId on the frame-delivering thread (Cameras IPC). + Maybe<TrackingId> mFrameDeliveringTrackingId; + + // mMutex protects certain members on 3 threads: + // MediaManager, Cameras IPC and MediaTrackGraph. + Mutex mMutex MOZ_UNANNOTATED; + + // Current state of this source. + // Set under mMutex on the owning thread. Accessed under one of the two. + MediaEngineSourceState mState = kReleased; + + // The source track that we feed video data to. + // Set under mMutex on the owning thread. Accessed under one of the two. + RefPtr<SourceMediaTrack> mTrack; + + // The PrincipalHandle that gets attached to the frames we feed to mTrack. + // Set under mMutex on the owning thread. Accessed under one of the two. + PrincipalHandle mPrincipal = PRINCIPAL_HANDLE_NONE; + + // Set in Start() and Deallocate() on the owning thread. + // Accessed in DeliverFrame() on the camera IPC thread, guaranteed to happen + // after Start() and before the end of Stop(). + RefPtr<layers::ImageContainer> mImageContainer; + + // A buffer pool used to manage the temporary buffer used when rescaling + // incoming images. Cameras IPC thread only. + webrtc::VideoFrameBufferPool mRescalingBufferPool; + + // The intrinsic size of the latest captured image, so we can feed black + // images of the same size while stopped. + // Set under mMutex on the Cameras IPC thread. Accessed under one of the two. + gfx::IntSize mImageSize = gfx::IntSize(0, 0); + + struct AtomicBool { + Atomic<bool> mValue; + }; + + // True when resolution settings have been updated from a real frame's + // resolution. Threadsafe. + // TODO: This can be removed in bug 1453269. + const RefPtr<media::Refcountable<AtomicBool>> mSettingsUpdatedByFrame; + + // The current settings of this source. + // Note that these may be different from the settings of the underlying device + // since we scale frames to avoid fingerprinting. + // Members are main thread only. + const RefPtr<media::Refcountable<dom::MediaTrackSettings>> mSettings; + MozPromiseHolder<GenericNonExclusivePromise> mFirstFramePromiseHolder; + RefPtr<GenericNonExclusivePromise> mFirstFramePromise; + + // The capability currently chosen by constraints of the user of this source. + // Set under mMutex on the owning thread. Accessed under one of the two. + webrtc::CaptureCapability mCapability; + + /** + * Capabilities that we choose between when applying constraints. + * + * This allows for memoization of capabilities as they're requested from the + * parent process. + * + * This is mutable so that the const methods NumCapabilities() and + * GetCapability() can reset it. Owning thread only. + */ + mutable nsTArray<UniquePtr<webrtc::CaptureCapability>> mCapabilities; + + /** + * True if mCapabilities only contains hardcoded capabilities. This can happen + * if the underlying device is not reporting any capabilities. These can be + * affected by constraints, so they're evaluated in ChooseCapability() rather + * than GetCapability(). + * + * This is mutable so that the const methods NumCapabilities() and + * GetCapability() can reset it. Owning thread only. + */ + mutable bool mCapabilitiesAreHardcoded = false; + + const RefPtr<const MediaDevice> mMediaDevice; + const nsCString mDeviceUUID; + Maybe<nsString> mFacingMode; +}; + +} // namespace mozilla + +#endif /* MEDIAENGINE_REMOTE_VIDEO_SOURCE_H_ */ |