1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef MEDIA_BASE_PIPELINE_H_ 6 #define MEDIA_BASE_PIPELINE_H_ 7 8 #include <memory> 9 10 #include "base/memory/ref_counted.h" 11 #include "base/optional.h" 12 #include "base/time/time.h" 13 #include "media/base/audio_decoder_config.h" 14 #include "media/base/buffering_state.h" 15 #include "media/base/media_export.h" 16 #include "media/base/media_status.h" 17 #include "media/base/media_track.h" 18 #include "media/base/pipeline_metadata.h" 19 #include "media/base/pipeline_status.h" 20 #include "media/base/ranges.h" 21 #include "media/base/text_track.h" 22 #include "media/base/video_decoder_config.h" 23 #include "media/base/video_transformation.h" 24 #include "media/base/waiting.h" 25 #include "ui/gfx/geometry/size.h" 26 27 namespace media { 28 29 class CdmContext; 30 class Demuxer; 31 32 class MEDIA_EXPORT Pipeline { 33 public: 34 class Client { 35 public: 36 // Executed whenever an error occurs except when the error occurs during 37 // Start/Seek/Resume or Suspend. Those errors are reported via |seek_cb| 38 // and |suspend_cb| respectively. 39 // NOTE: The client is responsible for calling Pipeline::Stop(). 40 virtual void OnError(PipelineStatus status) = 0; 41 42 // Executed whenever the media reaches the end. 43 virtual void OnEnded() = 0; 44 45 // Executed when the content duration, container video size, start time, 46 // and whether the content has audio and/or video in supported formats are 47 // known. 48 virtual void OnMetadata(const PipelineMetadata& metadata) = 0; 49 50 // Executed whenever there are changes in the buffering state of the 51 // pipeline. |reason| indicates the cause of the state change, when known. 52 virtual void OnBufferingStateChange(BufferingState state, 53 BufferingStateChangeReason reason) = 0; 54 55 // Executed whenever the presentation duration changes. 56 virtual void OnDurationChange() = 0; 57 58 // Executed whenever a text track is added. 59 // The client is expected to create a TextTrack and call |done_cb|. 60 virtual void OnAddTextTrack(const TextTrackConfig& config, 61 AddTextTrackDoneCB done_cb) = 0; 62 63 // Executed whenever the pipeline is waiting because of |reason|. 64 virtual void OnWaiting(WaitingReason reason) = 0; 65 66 // Executed for the first video frame and whenever natural size changes. 67 virtual void OnVideoNaturalSizeChange(const gfx::Size& size) = 0; 68 69 // Executed for the first video frame and whenever opacity changes. 70 virtual void OnVideoOpacityChange(bool opaque) = 0; 71 72 // Executed when the average keyframe distance for the video changes. 73 virtual void OnVideoAverageKeyframeDistanceUpdate() = 0; 74 75 // Executed whenever DemuxerStream status returns kConfigChange. Initial 76 // configs provided by OnMetadata. 77 virtual void OnAudioConfigChange(const AudioDecoderConfig& config) = 0; 78 virtual void OnVideoConfigChange(const VideoDecoderConfig& config) = 0; 79 80 // Executed whenever the underlying AudioDecoder or VideoDecoder changes 81 // during playback. 82 virtual void OnAudioDecoderChange(const PipelineDecoderInfo& info) = 0; 83 virtual void OnVideoDecoderChange(const PipelineDecoderInfo& info) = 0; 84 85 // Executed whenever the video frame rate changes. |fps| will be unset if 86 // the frame rate is unstable. The duration used for the frame rate is 87 // based on wall clock time, not media time. 88 virtual void OnVideoFrameRateChange(base::Optional<int> fps) = 0; 89 }; 90 ~Pipeline()91 virtual ~Pipeline() {} 92 93 // StartType provides the option to start the pipeline without a renderer; 94 // pipeline initialization will stop once metadata has been retrieved. The 95 // flags below indicate when suspended start will be invoked. 96 enum class StartType { 97 kNormal, // Follow the normal startup path. 98 kSuspendAfterMetadataForAudioOnly, // Suspend after metadata for audio 99 // only. 100 kSuspendAfterMetadata, // Always suspend after metadata. 101 }; 102 103 // Build a pipeline to using the given |demuxer| to construct a filter chain, 104 // executing |seek_cb| when the initial seek has completed. Methods on 105 // PipelineClient may be called up until Stop() has completed. It is an error 106 // to call this method after the pipeline has already started. 107 // 108 // If a |start_type| is specified which allows suspension, pipeline startup 109 // will halt after metadata has been retrieved and the pipeline will be in a 110 // suspended state. 111 virtual void Start(StartType start_type, 112 Demuxer* demuxer, 113 Client* client, 114 PipelineStatusCallback seek_cb) = 0; 115 116 // Track switching works similarly for both audio and video. Callbacks are 117 // used to notify when it is time to procede to the next step, since many of 118 // the operations are asynchronous. 119 // ──────────────────── Track Switch Control Flow ─────────────────────── 120 // pipeline | demuxer | demuxer_stream | renderer | video/audio_renderer 121 // | | | | 122 // | | | | 123 // | | | | 124 // switch track | | | 125 // ---------> | | | 126 // | disable/enable stream | | 127 // | -----------> | | 128 // active streams | | | 129 // <--------- | | | 130 // | switch track | | 131 // --------------------------------------> | 132 // | | | Flush/Restart/Reset 133 // | | | ---------------> 134 // Notify pipeline of completed track change (via callback) 135 // <----------------------------------------------------- 136 // ──────────────────── Sometime in the future ────────────────────────── 137 // | | | OnBufferingStateChange 138 // | | | <---------------- 139 // | OnBufferingStateChange | | 140 // <-------------------------------------- | 141 // | | | | 142 // | | | | 143 // |enabled_track_ids| contains track ids of enabled audio tracks. 144 virtual void OnEnabledAudioTracksChanged( 145 const std::vector<MediaTrack::Id>& enabled_track_ids, 146 base::OnceClosure change_completed_cb) = 0; 147 148 // |selected_track_id| is either empty, which means no video track is 149 // selected, or contains the selected video track id. 150 virtual void OnSelectedVideoTrackChanged( 151 base::Optional<MediaTrack::Id> selected_track_id, 152 base::OnceClosure change_completed_cb) = 0; 153 154 // Stops the pipeline. This is a blocking function. 155 // If the pipeline is started, it must be stopped before destroying it. 156 // It it permissible to call Stop() at any point during the lifetime of the 157 // pipeline. 158 // 159 // Once Stop is called any outstanding completion callbacks 160 // for Start/Seek/Suspend/Resume or Client methods will *not* be called. 161 virtual void Stop() = 0; 162 163 // Attempt to seek to the position specified by time. |seek_cb| will be 164 // executed when the all filters in the pipeline have processed the seek. 165 // 166 // Clients are expected to call GetMediaTime() to check whether the seek 167 // succeeded. 168 // 169 // It is an error to call this method if the pipeline has not started or 170 // has been suspended. 171 virtual void Seek(base::TimeDelta time, PipelineStatusCallback seek_cb) = 0; 172 173 // Suspends the pipeline, discarding the current renderer. 174 // 175 // While suspended, GetMediaTime() returns the presentation timestamp of the 176 // last rendered frame. 177 // 178 // It is an error to call this method if the pipeline has not started or is 179 // seeking. 180 virtual void Suspend(PipelineStatusCallback suspend_cb) = 0; 181 182 // Resume the pipeline and seek to |timestamp|. 183 // 184 // It is an error to call this method if the pipeline has not finished 185 // suspending. 186 virtual void Resume(base::TimeDelta timestamp, 187 PipelineStatusCallback seek_cb) = 0; 188 189 // Returns true if the pipeline has been started via Start(). If IsRunning() 190 // returns true, it is expected that Stop() will be called before destroying 191 // the pipeline. 192 virtual bool IsRunning() const = 0; 193 194 // Returns true if the pipeline has been suspended via Suspend() or during 195 // Start(). If IsSuspended() returns true, it is expected that Resume() will 196 // be called to resume playback. 197 virtual bool IsSuspended() const = 0; 198 199 // Gets the current playback rate of the pipeline. When the pipeline is 200 // started, the playback rate will be 0.0. A rate of 1.0 indicates 201 // that the pipeline is rendering the media at the standard rate. Valid 202 // values for playback rate are >= 0.0. 203 virtual double GetPlaybackRate() const = 0; 204 205 // Attempt to adjust the playback rate. Setting a playback rate of 0.0 pauses 206 // all rendering of the media. A rate of 1.0 indicates a normal playback 207 // rate. Values for the playback rate must be greater than or equal to 0.0. 208 // 209 // TODO(scherkus): What about maximum rate? Does HTML5 specify a max? 210 virtual void SetPlaybackRate(double playback_rate) = 0; 211 212 // Gets the current volume setting being used by the audio renderer. When 213 // the pipeline is started, this value will be 1.0f. Valid values range 214 // from 0.0f to 1.0f. 215 virtual float GetVolume() const = 0; 216 217 // Attempt to set the volume of the audio renderer. Valid values for volume 218 // range from 0.0f (muted) to 1.0f (full volume). This value affects all 219 // channels proportionately for multi-channel audio streams. 220 virtual void SetVolume(float volume) = 0; 221 222 // Hint from player about target latency as a guide for the desired amount of 223 // post-decode buffering required to start playback or resume from 224 // seek/underflow. A null option indicates the hint is unset and the pipeline 225 // can choose its own default. 226 virtual void SetLatencyHint(base::Optional<base::TimeDelta> latency_hint) = 0; 227 228 // Sets whether pitch adjustment should be applied when the playback rate is 229 // different than 1.0. 230 virtual void SetPreservesPitch(bool preserves_pitch) = 0; 231 232 // Returns the current media playback time, which progresses from 0 until 233 // GetMediaDuration(). 234 virtual base::TimeDelta GetMediaTime() const = 0; 235 236 // Get approximate time ranges of buffered media. 237 virtual Ranges<base::TimeDelta> GetBufferedTimeRanges() const = 0; 238 239 // Get the duration of the media in microseconds. If the duration has not 240 // been determined yet, then returns 0. 241 virtual base::TimeDelta GetMediaDuration() const = 0; 242 243 // Return true if loading progress has been made since the last time this 244 // method was called. 245 virtual bool DidLoadingProgress() = 0; 246 247 // Gets the current pipeline statistics. 248 virtual PipelineStatistics GetStatistics() const = 0; 249 250 using CdmAttachedCB = base::OnceCallback<void(bool)>; 251 virtual void SetCdm(CdmContext* cdm_context, 252 CdmAttachedCB cdm_attached_cb) = 0; 253 }; 254 255 } // namespace media 256 257 #endif // MEDIA_BASE_PIPELINE_H_ 258