From 6bf0a5cb5034a7e684dcc3500e841785237ce2dd Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sun, 7 Apr 2024 19:32:43 +0200 Subject: Adding upstream version 1:115.7.0. Signed-off-by: Daniel Baumann --- dom/media/MediaTrackListener.h | 184 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 184 insertions(+) create mode 100644 dom/media/MediaTrackListener.h (limited to 'dom/media/MediaTrackListener.h') diff --git a/dom/media/MediaTrackListener.h b/dom/media/MediaTrackListener.h new file mode 100644 index 0000000000..162482f7ef --- /dev/null +++ b/dom/media/MediaTrackListener.h @@ -0,0 +1,184 @@ +/* -*- 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 MOZILLA_MEDIATRACKLISTENER_h_ +#define MOZILLA_MEDIATRACKLISTENER_h_ + +#include "MediaTrackGraph.h" +#include "PrincipalHandle.h" + +namespace mozilla { + +class AudioSegment; +class MediaTrackGraph; +class MediaStreamVideoSink; +class VideoSegment; + +/** + * This is a base class for media graph thread listener callbacks locked to + * specific tracks. Override methods to be notified of audio or video data or + * changes in track state. + * + * All notification methods are called from the media graph thread. Overriders + * of these methods are responsible for all synchronization. Beware! + * These methods are called without the media graph monitor held, so + * reentry into media graph methods is possible, although very much discouraged! + * You should do something non-blocking and non-reentrant (e.g. dispatch an + * event to some thread) and return. + * The listener is not allowed to add/remove any listeners from the parent + * track. + * + * If a listener is attached to a track that has already ended, we guarantee + * to call NotifyEnded. + */ +class MediaTrackListener { + NS_INLINE_DECL_THREADSAFE_REFCOUNTING(MediaTrackListener) + + public: + /** + * When a SourceMediaTrack has pulling enabled, and the MediaTrackGraph + * control loop is ready to pull, this gets called for each track in the + * SourceMediaTrack that is lacking data for the current iteration. + * A NotifyPull implementation is allowed to call the SourceMediaTrack + * methods that alter track data. + * + * It is not allowed to make other MediaTrack API calls, including + * calls to add or remove MediaTrackListeners. It is not allowed to + * block for any length of time. + * + * aEndOfAppendedData is the duration of the data that has already been + * appended to this track, in track time. + * + * aDesiredTime is the track time we should append data up to. Data + * beyond this point will not be played until NotifyPull runs again, so + * there's not much point in providing it. Note that if the track is blocked + * for some reason, then data before aDesiredTime may not be played + * immediately. + */ + virtual void NotifyPull(MediaTrackGraph* aGraph, TrackTime aEndOfAppendedData, + TrackTime aDesiredTime) {} + + virtual void NotifyQueuedChanges(MediaTrackGraph* aGraph, + TrackTime aTrackOffset, + const MediaSegment& aQueuedMedia) {} + + virtual void NotifyPrincipalHandleChanged( + MediaTrackGraph* aGraph, const PrincipalHandle& aNewPrincipalHandle) {} + + /** + * Notify that the enabled state for the track this listener is attached to + * has changed. + * + * The enabled state here is referring to whether audio should be audible + * (enabled) or silent (not enabled); or whether video should be displayed as + * is (enabled), or black (not enabled). + */ + virtual void NotifyEnabledStateChanged(MediaTrackGraph* aGraph, + bool aEnabled) {} + + /** + * Notify that the track output is advancing. aCurrentTrackTime is the number + * of samples that has been played out for this track in track time. + */ + virtual void NotifyOutput(MediaTrackGraph* aGraph, + TrackTime aCurrentTrackTime) {} + + /** + * Notify that this track has been ended and all data has been played out. + */ + virtual void NotifyEnded(MediaTrackGraph* aGraph) {} + + /** + * Notify that this track listener has been removed from the graph, either + * after shutdown or through MediaTrack::RemoveListener(). + */ + virtual void NotifyRemoved(MediaTrackGraph* aGraph) {} + + protected: + virtual ~MediaTrackListener() = default; +}; + +/** + * This is a base class for media graph thread listener direct callbacks from + * within AppendToTrack(). It is bound to a certain track and can only be + * installed on audio tracks. Once added to a track on any track in the graph, + * the graph will try to install it at that track's source of media data. + * + * This works for ForwardedInputTracks, which will forward the listener to the + * track's input track if it exists, or wait for it to be created before + * forwarding if it doesn't. + * Once it reaches a SourceMediaTrack, it can be successfully installed. + * Other types of tracks will fail installation since they are not supported. + * + * Note that this listener and others for the same track will still get + * NotifyQueuedChanges() callbacks from the MTG tread, so you must be careful + * to ignore them if this listener was successfully installed. + */ +class DirectMediaTrackListener : public MediaTrackListener { + friend class SourceMediaTrack; + friend class ForwardedInputTrack; + + public: + /* + * This will be called on any DirectMediaTrackListener added to a + * SourceMediaTrack when AppendToTrack() is called for the listener's bound + * track, using the thread of the AppendToTrack() caller. The MediaSegment + * will be the RawSegment (unresampled) if available in AppendToTrack(). + * If the track is enabled at the source but has been disabled in one of the + * tracks in between the source and where it was originally added, aMedia + * will be a disabled version of the one passed to AppendToTrack() as well. + * Note that NotifyQueuedTrackChanges() calls will also still occur. + */ + virtual void NotifyRealtimeTrackData(MediaTrackGraph* aGraph, + TrackTime aTrackOffset, + const MediaSegment& aMedia) {} + + /** + * When a direct listener is processed for installation by the + * MediaTrackGraph it will be notified with whether the installation was + * successful or not. The results of this installation are the following: + * TRACK_NOT_SUPPORTED + * While looking for the data source of this track, we found a MediaTrack + * that is not a SourceMediaTrack or a ForwardedInputTrack. + * ALREADY_EXISTS + * This DirectMediaTrackListener already exists in the + * SourceMediaTrack. + * SUCCESS + * Installation was successful and this listener will start receiving + * NotifyRealtimeData on the next AppendData(). + */ + enum class InstallationResult { + TRACK_NOT_SUPPORTED, + ALREADY_EXISTS, + SUCCESS + }; + virtual void NotifyDirectListenerInstalled(InstallationResult aResult) {} + virtual void NotifyDirectListenerUninstalled() {} + + protected: + virtual ~DirectMediaTrackListener() = default; + + void MirrorAndDisableSegment(AudioSegment& aFrom, AudioSegment& aTo); + void MirrorAndDisableSegment(VideoSegment& aFrom, VideoSegment& aTo, + DisabledTrackMode aMode); + void NotifyRealtimeTrackDataAndApplyTrackDisabling(MediaTrackGraph* aGraph, + TrackTime aTrackOffset, + MediaSegment& aMedia); + + void IncreaseDisabled(DisabledTrackMode aMode); + void DecreaseDisabled(DisabledTrackMode aMode); + + // Matches the number of disabled tracks to which this listener is attached. + // The number of tracks are those between the track where the listener was + // added and the SourceMediaTrack that is the source of the data reaching + // this listener. + Atomic mDisabledFreezeCount; + Atomic mDisabledBlackCount; +}; + +} // namespace mozilla + +#endif // MOZILLA_MEDIATRACKLISTENER_h_ -- cgit v1.2.3