Bug 1852754: part 9) Add tests for dynamically loading <link rel="prefetch"> elements...
[gecko.git] / dom / media / MediaTrackListener.h
blob162482f7efb4bdca97e16c2206dc5047a380f81b
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/. */
7 #ifndef MOZILLA_MEDIATRACKLISTENER_h_
8 #define MOZILLA_MEDIATRACKLISTENER_h_
10 #include "MediaTrackGraph.h"
11 #include "PrincipalHandle.h"
13 namespace mozilla {
15 class AudioSegment;
16 class MediaTrackGraph;
17 class MediaStreamVideoSink;
18 class VideoSegment;
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.
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.
34 * If a listener is attached to a track that has already ended, we guarantee
35 * to call NotifyEnded.
37 class MediaTrackListener {
38 NS_INLINE_DECL_THREADSAFE_REFCOUNTING(MediaTrackListener)
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.
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.
52 * aEndOfAppendedData is the duration of the data that has already been
53 * appended to this track, in track time.
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.
61 virtual void NotifyPull(MediaTrackGraph* aGraph, TrackTime aEndOfAppendedData,
62 TrackTime aDesiredTime) {}
64 virtual void NotifyQueuedChanges(MediaTrackGraph* aGraph,
65 TrackTime aTrackOffset,
66 const MediaSegment& aQueuedMedia) {}
68 virtual void NotifyPrincipalHandleChanged(
69 MediaTrackGraph* aGraph, const PrincipalHandle& aNewPrincipalHandle) {}
71 /**
72 * Notify that the enabled state for the track this listener is attached to
73 * has changed.
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).
79 virtual void NotifyEnabledStateChanged(MediaTrackGraph* aGraph,
80 bool aEnabled) {}
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.
86 virtual void NotifyOutput(MediaTrackGraph* aGraph,
87 TrackTime aCurrentTrackTime) {}
89 /**
90 * Notify that this track has been ended and all data has been played out.
92 virtual void NotifyEnded(MediaTrackGraph* aGraph) {}
94 /**
95 * Notify that this track listener has been removed from the graph, either
96 * after shutdown or through MediaTrack::RemoveListener().
98 virtual void NotifyRemoved(MediaTrackGraph* aGraph) {}
100 protected:
101 virtual ~MediaTrackListener() = default;
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.
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.
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.
120 class DirectMediaTrackListener : public MediaTrackListener {
121 friend class SourceMediaTrack;
122 friend class ForwardedInputTrack;
124 public:
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.
135 virtual void NotifyRealtimeTrackData(MediaTrackGraph* aGraph,
136 TrackTime aTrackOffset,
137 const MediaSegment& aMedia) {}
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().
153 enum class InstallationResult {
154 TRACK_NOT_SUPPORTED,
155 ALREADY_EXISTS,
156 SUCCESS
158 virtual void NotifyDirectListenerInstalled(InstallationResult aResult) {}
159 virtual void NotifyDirectListenerUninstalled() {}
161 protected:
162 virtual ~DirectMediaTrackListener() = default;
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);
171 void IncreaseDisabled(DisabledTrackMode aMode);
172 void DecreaseDisabled(DisabledTrackMode aMode);
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;
182 } // namespace mozilla
184 #endif // MOZILLA_MEDIATRACKLISTENER_h_