tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

MediaEngineRemoteVideoSource.h (10298B)


      1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
      2 /* vim: set sw=2 ts=8 et ft=cpp : */
      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 file,
      5 * You can obtain one at http://mozilla.org/MPL/2.0/. */
      6 
      7 #ifndef MEDIAENGINE_REMOTE_VIDEO_SOURCE_H_
      8 #define MEDIAENGINE_REMOTE_VIDEO_SOURCE_H_
      9 
     10 #include "CamerasChild.h"
     11 #include "DOMMediaStream.h"
     12 #include "MediaEngineSource.h"
     13 #include "MediaTrackGraph.h"
     14 #include "common_video/include/video_frame_buffer_pool.h"
     15 #include "modules/video_capture/video_capture_defines.h"
     16 #include "mozilla/Mutex.h"
     17 #include "mozilla/dom/MediaStreamTrackBinding.h"
     18 
     19 namespace webrtc {
     20 using CaptureCapability = VideoCaptureCapability;
     21 }
     22 
     23 namespace mozilla {
     24 namespace dom {
     25 enum class VideoResizeModeEnum : uint8_t;
     26 }
     27 
     28 // Fitness distance is defined in
     29 // https://w3c.github.io/mediacapture-main/getusermedia.html#dfn-selectsettings
     30 
     31 // In contrast, feasibility distance — used in the implementatioon of
     32 // crop_and_scale — effectively rounds width and height up to the nearest
     33 // native width and height before calculating distance (sorta).
     34 //
     35 // Another difference is that if the constraint is required
     36 // (min, 'max', or 'exact'), and the settings dictionary's
     37 // value for the constraint does not satisfy the constraint, the fitness
     38 // distance is positive infinity. Given a continuous space of settings
     39 // dictionaries comprising all discrete combinations of dimension and frame-rate
     40 // related properties, the feasibility distance is still in keeping with the
     41 // constraints algorithm.
     42 enum DistanceCalculation { kFitness, kFeasibility };
     43 
     44 /**
     45 * The WebRTC implementation of the MediaEngine interface.
     46 */
     47 class MediaEngineRemoteVideoSource : public MediaEngineSource,
     48                                     public camera::FrameRelay {
     49  ~MediaEngineRemoteVideoSource();
     50 
     51  struct CapabilityCandidate {
     52    explicit CapabilityCandidate(webrtc::CaptureCapability aCapability,
     53                                 uint32_t aDistance = 0)
     54        : mCapability(aCapability), mDistance(aDistance) {}
     55 
     56    const webrtc::CaptureCapability mCapability;
     57    uint32_t mDistance;
     58  };
     59 
     60  class CapabilityComparator {
     61   public:
     62    bool Equals(const CapabilityCandidate& aCandidate,
     63                const webrtc::CaptureCapability& aCapability) const {
     64      return aCandidate.mCapability == aCapability;
     65    }
     66  };
     67 
     68  bool ChooseCapability(const NormalizedConstraints& aConstraints,
     69                        const MediaEnginePrefs& aPrefs,
     70                        webrtc::CaptureCapability& aCapability,
     71                        const DistanceCalculation aCalculate,
     72                        const char** aOutBadConstraint);
     73 
     74  uint32_t GetDistance(const webrtc::CaptureCapability& aCandidate,
     75                       const NormalizedConstraintSet& aConstraints,
     76                       const DistanceCalculation aCalculate) const;
     77 
     78  uint32_t GetFitnessDistance(
     79      const webrtc::CaptureCapability& aCandidate,
     80      const NormalizedConstraintSet& aConstraints) const;
     81 
     82  uint32_t GetFeasibilityDistance(
     83      const webrtc::CaptureCapability& aCandidate,
     84      const NormalizedConstraintSet& aConstraints) const;
     85 
     86  static void TrimLessFitCandidates(nsTArray<CapabilityCandidate>& aSet);
     87 
     88 public:
     89  explicit MediaEngineRemoteVideoSource(const MediaDevice* aMediaDevice);
     90 
     91  static already_AddRefed<MediaEngineRemoteVideoSource> CreateFrom(
     92      const MediaEngineRemoteVideoSource* aSource,
     93      const MediaDevice* aMediaDevice);
     94 
     95  // ExternalRenderer
     96  /**
     97   * Signals that the capture stream has ended
     98   **/
     99  void OnCaptureEnded() override;
    100  int DeliverFrame(uint8_t* aBuffer,
    101                   const camera::VideoFrameProperties& aProps) override;
    102 
    103  // MediaEngineSource
    104  nsresult Allocate(const dom::MediaTrackConstraints& aConstraints,
    105                    const MediaEnginePrefs& aPrefs, uint64_t aWindowID,
    106                    const char** aOutBadConstraint) override;
    107  nsresult Deallocate() override;
    108  void SetTrack(const RefPtr<MediaTrack>& aTrack,
    109                const PrincipalHandle& aPrincipal) override;
    110  nsresult Start() override;
    111  nsresult Reconfigure(const dom::MediaTrackConstraints& aConstraints,
    112                       const MediaEnginePrefs& aPrefs,
    113                       const char** aOutBadConstraint) override;
    114  nsresult FocusOnSelectedSource() override;
    115  nsresult Stop() override;
    116 
    117  nsresult StartCapture(const NormalizedConstraints& aConstraints,
    118                        const dom::VideoResizeModeEnum& aResizeMode);
    119  uint32_t GetBestFitnessDistance(
    120      const nsTArray<const NormalizedConstraintSet*>& aConstraintSets,
    121      const MediaEnginePrefs& aPrefs) const override;
    122  void GetSettings(dom::MediaTrackSettings& aOutSettings) const override;
    123 
    124  RefPtr<GenericNonExclusivePromise> GetFirstFramePromise() const override {
    125    return mFirstFramePromise;
    126  }
    127 
    128  const TrackingId& GetTrackingId() const override;
    129 
    130  static camera::CaptureEngine CaptureEngine(dom::MediaSourceEnum aMediaSource);
    131 
    132  MediaEventSource<void>* CaptureEndedEvent() override {
    133    return &mCaptureEndedEvent;
    134  }
    135 
    136  void GetCapabilities(
    137      dom::MediaTrackCapabilities& aOutCapabilities) const override;
    138 
    139 private:
    140  /**
    141   * Returns the number of capabilities for the underlying device.
    142   *
    143   * Guaranteed to return at least one capability.
    144   */
    145  size_t NumCapabilities() const;
    146 
    147  /**
    148   * Returns the capability with index `aIndex` for our assigned device.
    149   *
    150   * It is an error to call this with `aIndex >= NumCapabilities()`.
    151   *
    152   * The lifetime of the returned capability is the same as for this source.
    153   */
    154  webrtc::CaptureCapability& GetCapability(size_t aIndex) const;
    155 
    156  int mCaptureId = -1;
    157  const camera::CaptureEngine mCapEngine;  // source of media (cam, screen etc)
    158 
    159  // A tracking id used to uniquely identify the source of video frames.
    160  // Set under mMutex on the owning thread. Accessed under one of the two.
    161  TrackingId mTrackingId;
    162 
    163  // Mirror of mTrackingId on the frame-delivering thread (Cameras IPC).
    164  Maybe<TrackingId> mFrameDeliveringTrackingId;
    165 
    166  // mMutex protects certain members on 3 threads:
    167  // MediaManager, Cameras IPC and MediaTrackGraph.
    168  mutable Mutex mMutex MOZ_UNANNOTATED;
    169 
    170  // Current state of this source.
    171  // Set under mMutex on the owning thread. Accessed under one of the two.
    172  MediaEngineSourceState mState = kReleased;
    173 
    174  // The source track that we feed video data to.
    175  // Set under mMutex on the owning thread. Accessed under one of the two.
    176  RefPtr<SourceMediaTrack> mTrack;
    177 
    178  // The PrincipalHandle that gets attached to the frames we feed to mTrack.
    179  // Set under mMutex on the owning thread. Accessed under one of the two.
    180  PrincipalHandle mPrincipal = PRINCIPAL_HANDLE_NONE;
    181 
    182  // Set in Start() and Deallocate() on the owning thread.
    183  // Accessed in DeliverFrame() on the camera IPC thread, guaranteed to happen
    184  // after Start() and before the end of Stop().
    185  RefPtr<layers::ImageContainer> mImageContainer;
    186 
    187  // A buffer pool used to manage the temporary buffer used when rescaling
    188  // incoming images. Cameras IPC thread only.
    189  webrtc::VideoFrameBufferPool mRescalingBufferPool;
    190 
    191  // The intrinsic size of the latest received image, before cropping and
    192  // scaling down. So we can provide a decent guess to settings for desktop
    193  // sources, since they don't provide capabilities.
    194  // Set under mMutex on the Cameras IPC thread. Accessed under one of the two.
    195  gfx::IntSize mIncomingImageSize = gfx::IntSize(0, 0);
    196 
    197  // The intrinsic size of the latest processed image, after cropping and
    198  // scaling down. So we can update settings on main thread in response to size
    199  // changes.
    200  // Set under mMutex on the Cameras IPC thread. Accessed under one of the two.
    201  gfx::IntSize mScaledImageSize = gfx::IntSize(0, 0);
    202 
    203  struct AtomicBool {
    204    Atomic<bool> mValue;
    205  };
    206 
    207  // True when resolution settings have been updated from a real frame's
    208  // resolution. Threadsafe. Set to false on the owning thread. Set to true on
    209  // main thread.
    210  const RefPtr<media::Refcountable<AtomicBool>> mSettingsUpdatedByFrame;
    211 
    212  // The current settings of this source.
    213  // Note that these may be different from the settings of the underlying device
    214  // since we scale frames to avoid fingerprinting.
    215  // Members are main thread only.
    216  const RefPtr<media::Refcountable<dom::MediaTrackSettings>> mSettings;
    217  const RefPtr<media::Refcountable<dom::MediaTrackCapabilities>>
    218      mTrackCapabilities;
    219  MozPromiseHolder<GenericNonExclusivePromise> mFirstFramePromiseHolder;
    220  RefPtr<GenericNonExclusivePromise> mFirstFramePromise;
    221 
    222  // The capability currently chosen by constraints of the user of this source,
    223  // and the distance calculation used when applying them.
    224  // Set under mMutex on the owning thread. Accessed under one of the two.
    225  webrtc::CaptureCapability mCapability;
    226  DistanceCalculation mCalculation;
    227 
    228  // The constraints we're currently operating under, for calculating incoming
    229  // video resolution.
    230  Maybe<NormalizedConstraints> mConstraints MOZ_GUARDED_BY(mMutex);
    231 
    232  // Owning thread only.
    233  UniquePtr<MediaEnginePrefs> mPrefs;
    234 
    235  /**
    236   * Capabilities that we choose between when applying constraints.
    237   *
    238   * This allows for memoization of capabilities as they're requested from the
    239   * parent process.
    240   *
    241   * This is mutable so that the const methods NumCapabilities() and
    242   * GetCapability() can reset it. Owning thread only.
    243   */
    244  mutable nsTArray<UniquePtr<webrtc::CaptureCapability>> mCapabilities;
    245 
    246  /**
    247   * True if mCapabilities only contains hardcoded capabilities. This can happen
    248   * if the underlying device is not reporting any capabilities. These can be
    249   * affected by constraints, so they're evaluated in ChooseCapability() rather
    250   * than GetCapability().
    251   *
    252   * This is mutable so that the const methods NumCapabilities() and
    253   * GetCapability() can reset it. Owning thread only.
    254   */
    255  mutable bool mCapabilitiesAreHardcoded = false;
    256 
    257  const RefPtr<const MediaDevice> mMediaDevice;
    258  const nsCString mDeviceUUID;
    259  Maybe<nsString> mFacingMode;
    260  MediaEventProducer<void> mCaptureEndedEvent;
    261 };
    262 
    263 }  // namespace mozilla
    264 
    265 #endif /* MEDIAENGINE_REMOTE_VIDEO_SOURCE_H_ */