tor-browser

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

MediaTrackListener.h (7681B)


      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 MOZILLA_MEDIATRACKLISTENER_h_
      8 #define MOZILLA_MEDIATRACKLISTENER_h_
      9 
     10 #include "MediaTrackGraph.h"
     11 #include "PrincipalHandle.h"
     12 
     13 namespace mozilla {
     14 
     15 class AudioSegment;
     16 class MediaTrackGraph;
     17 class MediaStreamVideoSink;
     18 class VideoSegment;
     19 
     20 /**
     21 * This is a base class for media graph thread listener callbacks locked to
     22 * specific tracks. Override methods to be notified of audio or video data or
     23 * changes in track state.
     24 *
     25 * All notification methods are called from the media graph thread. Overriders
     26 * of these methods are responsible for all synchronization. Beware!
     27 * These methods are called without the media graph monitor held, so
     28 * reentry into media graph methods is possible, although very much discouraged!
     29 * You should do something non-blocking and non-reentrant (e.g. dispatch an
     30 * event to some thread) and return.
     31 * The listener is not allowed to add/remove any listeners from the parent
     32 * track.
     33 *
     34 * If a listener is attached to a track that has already ended, we guarantee
     35 * to call NotifyEnded.
     36 */
     37 class MediaTrackListener {
     38  NS_INLINE_DECL_THREADSAFE_REFCOUNTING(MediaTrackListener)
     39 
     40 public:
     41  /**
     42   * When a SourceMediaTrack has pulling enabled, and the MediaTrackGraph
     43   * control loop is ready to pull, this gets called for each track in the
     44   * SourceMediaTrack that is lacking data for the current iteration.
     45   * A NotifyPull implementation is allowed to call the SourceMediaTrack
     46   * methods that alter track data.
     47   *
     48   * It is not allowed to make other MediaTrack API calls, including
     49   * calls to add or remove MediaTrackListeners. It is not allowed to
     50   * block for any length of time.
     51   *
     52   * aEndOfAppendedData is the duration of the data that has already been
     53   * appended to this track, in track time.
     54   *
     55   * aDesiredTime is the track time we should append data up to. Data
     56   * beyond this point will not be played until NotifyPull runs again, so
     57   * there's not much point in providing it. Note that if the track is blocked
     58   * for some reason, then data before aDesiredTime may not be played
     59   * immediately.
     60   */
     61  virtual void NotifyPull(MediaTrackGraph* aGraph, TrackTime aEndOfAppendedData,
     62                          TrackTime aDesiredTime) {}
     63 
     64  virtual void NotifyQueuedChanges(MediaTrackGraph* aGraph,
     65                                   TrackTime aTrackOffset,
     66                                   const MediaSegment& aQueuedMedia) {}
     67 
     68  virtual void NotifyPrincipalHandleChanged(
     69      MediaTrackGraph* aGraph, const PrincipalHandle& aNewPrincipalHandle) {}
     70 
     71  /**
     72   * Notify that the enabled state for the track this listener is attached to
     73   * has changed.
     74   *
     75   * The enabled state here is referring to whether audio should be audible
     76   * (enabled) or silent (not enabled); or whether video should be displayed as
     77   * is (enabled), or black (not enabled).
     78   */
     79  virtual void NotifyEnabledStateChanged(MediaTrackGraph* aGraph,
     80                                         bool aEnabled) {}
     81 
     82  /**
     83   * Notify that the track output is advancing. aCurrentTrackTime is the number
     84   * of samples that has been played out for this track in track time.
     85   */
     86  virtual void NotifyOutput(MediaTrackGraph* aGraph,
     87                            TrackTime aCurrentTrackTime) {}
     88 
     89  /**
     90   * Notify that this track has been ended and all data has been played out.
     91   */
     92  virtual void NotifyEnded(MediaTrackGraph* aGraph) {}
     93 
     94  /**
     95   * Notify that this track listener has been removed from the graph, either
     96   * after shutdown or through MediaTrack::RemoveListener().
     97   */
     98  virtual void NotifyRemoved(MediaTrackGraph* aGraph) {}
     99 
    100 protected:
    101  virtual ~MediaTrackListener() = default;
    102 };
    103 
    104 /**
    105 * This is a base class for media graph thread listener direct callbacks from
    106 * within AppendToTrack(). It is bound to a certain track and can only be
    107 * installed on audio tracks. Once added to a track on any track in the graph,
    108 * the graph will try to install it at that track's source of media data.
    109 *
    110 * This works for ForwardedInputTracks, which will forward the listener to the
    111 * track's input track if it exists, or wait for it to be created before
    112 * forwarding if it doesn't.
    113 * Once it reaches a SourceMediaTrack, it can be successfully installed.
    114 * Other types of tracks will fail installation since they are not supported.
    115 *
    116 * Note that this listener and others for the same track will still get
    117 * NotifyQueuedChanges() callbacks from the MTG tread, so you must be careful
    118 * to ignore them if this listener was successfully installed.
    119 */
    120 class DirectMediaTrackListener : public MediaTrackListener {
    121  friend class SourceMediaTrack;
    122  friend class ForwardedInputTrack;
    123 
    124 public:
    125  /*
    126   * This will be called on any DirectMediaTrackListener added to a
    127   * SourceMediaTrack when AppendToTrack() is called for the listener's bound
    128   * track, using the thread of the AppendToTrack() caller. The MediaSegment
    129   * will be the RawSegment (unresampled) if available in AppendToTrack().
    130   * If the track is enabled at the source but has been disabled in one of the
    131   * tracks in between the source and where it was originally added, aMedia
    132   * will be a disabled version of the one passed to AppendToTrack() as well.
    133   * Note that NotifyQueuedTrackChanges() calls will also still occur.
    134   */
    135  virtual void NotifyRealtimeTrackData(MediaTrackGraph* aGraph,
    136                                       TrackTime aTrackOffset,
    137                                       const MediaSegment& aMedia) {}
    138 
    139  /**
    140   * When a direct listener is processed for installation by the
    141   * MediaTrackGraph it will be notified with whether the installation was
    142   * successful or not. The results of this installation are the following:
    143   * TRACK_NOT_SUPPORTED
    144   *    While looking for the data source of this track, we found a MediaTrack
    145   *    that is not a SourceMediaTrack or a ForwardedInputTrack.
    146   * ALREADY_EXISTS
    147   *    This DirectMediaTrackListener already exists in the
    148   *    SourceMediaTrack.
    149   * SUCCESS
    150   *    Installation was successful and this listener will start receiving
    151   *    NotifyRealtimeData on the next AppendData().
    152   */
    153  enum class InstallationResult {
    154    TRACK_NOT_SUPPORTED,
    155    ALREADY_EXISTS,
    156    SUCCESS
    157  };
    158  virtual void NotifyDirectListenerInstalled(InstallationResult aResult) {}
    159  virtual void NotifyDirectListenerUninstalled() {}
    160 
    161 protected:
    162  virtual ~DirectMediaTrackListener() = default;
    163 
    164  void MirrorAndDisableSegment(AudioSegment& aFrom, AudioSegment& aTo);
    165  void MirrorAndDisableSegment(VideoSegment& aFrom, VideoSegment& aTo,
    166                               DisabledTrackMode aMode);
    167  void NotifyRealtimeTrackDataAndApplyTrackDisabling(MediaTrackGraph* aGraph,
    168                                                     TrackTime aTrackOffset,
    169                                                     MediaSegment& aMedia);
    170 
    171  void IncreaseDisabled(DisabledTrackMode aMode);
    172  void DecreaseDisabled(DisabledTrackMode aMode);
    173 
    174  // Matches the number of disabled tracks to which this listener is attached.
    175  // The number of tracks are those between the track where the listener was
    176  // added and the SourceMediaTrack that is the source of the data reaching
    177  // this listener.
    178  Atomic<int32_t> mDisabledFreezeCount;
    179  Atomic<int32_t> mDisabledBlackCount;
    180 };
    181 
    182 }  // namespace mozilla
    183 
    184 #endif  // MOZILLA_MEDIATRACKLISTENER_h_