Removed unused VideoCaptureCapability parameters.
[chromium-blink-merge.git] / media / base / pipeline.h
blob09ff90416390fc8a3cc5d1f5071ee515df939c58
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.
5 #ifndef MEDIA_BASE_PIPELINE_H_
6 #define MEDIA_BASE_PIPELINE_H_
8 #include <string>
10 #include "base/gtest_prod_util.h"
11 #include "base/synchronization/condition_variable.h"
12 #include "base/synchronization/lock.h"
13 #include "base/threading/thread_checker.h"
14 #include "base/time/default_tick_clock.h"
15 #include "media/base/audio_renderer.h"
16 #include "media/base/demuxer.h"
17 #include "media/base/media_export.h"
18 #include "media/base/pipeline_status.h"
19 #include "media/base/ranges.h"
20 #include "media/base/serial_runner.h"
21 #include "ui/gfx/size.h"
23 namespace base {
24 class MessageLoopProxy;
25 class TimeDelta;
28 namespace media {
30 class Clock;
31 class FilterCollection;
32 class MediaLog;
33 class VideoRenderer;
35 // Pipeline runs the media pipeline. Filters are created and called on the
36 // message loop injected into this object. Pipeline works like a state
37 // machine to perform asynchronous initialization, pausing, seeking and playing.
39 // Here's a state diagram that describes the lifetime of this object.
41 // [ *Created ] [ Any State ]
42 // | Start() | Stop() / SetError()
43 // V V
44 // [ InitXXX (for each filter) ] [ Stopping ]
45 // | |
46 // V V
47 // [ InitPreroll ] [ Stopped ]
48 // |
49 // V
50 // [ Starting ] <-- [ Seeking ]
51 // | ^
52 // V |
53 // [ Started ] ----------'
54 // Seek()
56 // Initialization is a series of state transitions from "Created" through each
57 // filter initialization state. When all filter initialization states have
58 // completed, we are implicitly in a "Paused" state. At that point we simulate
59 // a Seek() to the beginning of the media to give filters a chance to preroll.
60 // From then on the normal Seek() transitions are carried out and we start
61 // playing the media.
63 // If any error ever happens, this object will transition to the "Error" state
64 // from any state. If Stop() is ever called, this object will transition to
65 // "Stopped" state.
66 class MEDIA_EXPORT Pipeline : public DemuxerHost {
67 public:
68 // Buffering states the pipeline transitions between during playback.
69 // kHaveMetadata:
70 // Indicates that the following things are known:
71 // content duration, natural size, start time, and whether the content has
72 // audio and/or video in supported formats.
73 // kPrerollCompleted:
74 // All renderers have buffered enough data to satisfy preroll and are ready
75 // to start playback.
76 enum BufferingState {
77 kHaveMetadata,
78 kPrerollCompleted,
81 typedef base::Callback<void(BufferingState)> BufferingStateCB;
83 // Constructs a media pipeline that will execute on |message_loop|.
84 Pipeline(const scoped_refptr<base::MessageLoopProxy>& message_loop,
85 MediaLog* media_log);
86 virtual ~Pipeline();
88 // Build a pipeline to using the given filter collection to construct a filter
89 // chain, executing |seek_cb| when the initial seek/preroll has completed.
91 // |filter_collection| must be a complete collection containing a demuxer,
92 // audio/video decoders, and audio/video renderers. Failing to do so will
93 // result in a crash.
95 // The following permanent callbacks will be executed as follows up until
96 // Stop() has completed:
97 // |ended_cb| will be executed whenever the media reaches the end.
98 // |error_cb| will be executed whenever an error occurs but hasn't
99 // been reported already through another callback.
100 // |buffering_state_cb| Optional callback that will be executed whenever the
101 // pipeline's buffering state changes.
102 // |duration_change_cb| Optional callback that will be executed whenever the
103 // presentation duration changes.
104 // It is an error to call this method after the pipeline has already started.
105 void Start(scoped_ptr<FilterCollection> filter_collection,
106 const base::Closure& ended_cb,
107 const PipelineStatusCB& error_cb,
108 const PipelineStatusCB& seek_cb,
109 const BufferingStateCB& buffering_state_cb,
110 const base::Closure& duration_change_cb);
112 // Asynchronously stops the pipeline, executing |stop_cb| when the pipeline
113 // teardown has completed.
115 // Stop() must complete before destroying the pipeline. It it permissible to
116 // call Stop() at any point during the lifetime of the pipeline.
118 // It is safe to delete the pipeline during the execution of |stop_cb|.
119 void Stop(const base::Closure& stop_cb);
121 // Attempt to seek to the position specified by time. |seek_cb| will be
122 // executed when the all filters in the pipeline have processed the seek.
124 // Clients are expected to call GetMediaTime() to check whether the seek
125 // succeeded.
127 // It is an error to call this method if the pipeline has not started.
128 void Seek(base::TimeDelta time, const PipelineStatusCB& seek_cb);
130 // Returns true if the pipeline has been started via Start(). If IsRunning()
131 // returns true, it is expected that Stop() will be called before destroying
132 // the pipeline.
133 bool IsRunning() const;
135 // Returns true if the media has audio.
136 bool HasAudio() const;
138 // Returns true if the media has video.
139 bool HasVideo() const;
141 // Gets the current playback rate of the pipeline. When the pipeline is
142 // started, the playback rate will be 0.0f. A rate of 1.0f indicates
143 // that the pipeline is rendering the media at the standard rate. Valid
144 // values for playback rate are >= 0.0f.
145 float GetPlaybackRate() const;
147 // Attempt to adjust the playback rate. Setting a playback rate of 0.0f pauses
148 // all rendering of the media. A rate of 1.0f indicates a normal playback
149 // rate. Values for the playback rate must be greater than or equal to 0.0f.
151 // TODO(scherkus): What about maximum rate? Does HTML5 specify a max?
152 void SetPlaybackRate(float playback_rate);
154 // Gets the current volume setting being used by the audio renderer. When
155 // the pipeline is started, this value will be 1.0f. Valid values range
156 // from 0.0f to 1.0f.
157 float GetVolume() const;
159 // Attempt to set the volume of the audio renderer. Valid values for volume
160 // range from 0.0f (muted) to 1.0f (full volume). This value affects all
161 // channels proportionately for multi-channel audio streams.
162 void SetVolume(float volume);
164 // Returns the current media playback time, which progresses from 0 until
165 // GetMediaDuration().
166 base::TimeDelta GetMediaTime() const;
168 // Get approximate time ranges of buffered media.
169 Ranges<base::TimeDelta> GetBufferedTimeRanges();
171 // Get the duration of the media in microseconds. If the duration has not
172 // been determined yet, then returns 0.
173 base::TimeDelta GetMediaDuration() const;
175 // Get the total size of the media file. If the size has not yet been
176 // determined or can not be determined, this value is 0.
177 int64 GetTotalBytes() const;
179 // Gets the natural size of the video output in pixel units. If there is no
180 // video or the video has not been rendered yet, the width and height will
181 // be 0.
182 void GetNaturalVideoSize(gfx::Size* out_size) const;
184 // Return true if loading progress has been made since the last time this
185 // method was called.
186 bool DidLoadingProgress() const;
188 // Gets the current pipeline statistics.
189 PipelineStatistics GetStatistics() const;
191 void SetClockForTesting(Clock* clock);
192 void SetErrorForTesting(PipelineStatus status);
194 private:
195 FRIEND_TEST_ALL_PREFIXES(PipelineTest, GetBufferedTimeRanges);
196 FRIEND_TEST_ALL_PREFIXES(PipelineTest, DisableAudioRenderer);
197 FRIEND_TEST_ALL_PREFIXES(PipelineTest, DisableAudioRendererDuringInit);
198 FRIEND_TEST_ALL_PREFIXES(PipelineTest, EndedCallback);
199 FRIEND_TEST_ALL_PREFIXES(PipelineTest, AudioStreamShorterThanVideo);
200 friend class MediaLog;
202 // Pipeline states, as described above.
203 enum State {
204 kCreated,
205 kInitDemuxer,
206 kInitAudioRenderer,
207 kInitVideoRenderer,
208 kInitPrerolling,
209 kSeeking,
210 kStarting,
211 kStarted,
212 kStopping,
213 kStopped,
216 // Updates |state_|. All state transitions should use this call.
217 void SetState(State next_state);
219 static const char* GetStateString(State state);
220 State GetNextState() const;
222 // Helper method that runs & resets |seek_cb_| and resets |seek_timestamp_|
223 // and |seek_pending_|.
224 void FinishSeek();
226 // DataSourceHost (by way of DemuxerHost) implementation.
227 virtual void SetTotalBytes(int64 total_bytes) OVERRIDE;
228 virtual void AddBufferedByteRange(int64 start, int64 end) OVERRIDE;
229 virtual void AddBufferedTimeRange(base::TimeDelta start,
230 base::TimeDelta end) OVERRIDE;
232 // DemuxerHost implementaion.
233 virtual void SetDuration(base::TimeDelta duration) OVERRIDE;
234 virtual void OnDemuxerError(PipelineStatus error) OVERRIDE;
236 // Initiates teardown sequence in response to a runtime error.
238 // Safe to call from any thread.
239 void SetError(PipelineStatus error);
241 // Callback executed when the natural size of the video has changed.
242 void OnNaturalVideoSizeChanged(const gfx::Size& size);
244 // Callbacks executed when a renderer has ended.
245 void OnAudioRendererEnded();
246 void OnVideoRendererEnded();
248 // Callback executed by filters to update statistics.
249 void OnUpdateStatistics(const PipelineStatistics& stats);
251 // Callback executed by audio renderer when it has been disabled.
252 void OnAudioDisabled();
254 // Callback executed by audio renderer to update clock time.
255 void OnAudioTimeUpdate(base::TimeDelta time, base::TimeDelta max_time);
257 // Callback executed by video renderer to update clock time.
258 void OnVideoTimeUpdate(base::TimeDelta max_time);
260 // The following "task" methods correspond to the public methods, but these
261 // methods are run as the result of posting a task to the PipelineInternal's
262 // message loop.
263 void StartTask(scoped_ptr<FilterCollection> filter_collection,
264 const base::Closure& ended_cb,
265 const PipelineStatusCB& error_cb,
266 const PipelineStatusCB& seek_cb,
267 const BufferingStateCB& buffering_state_cb,
268 const base::Closure& duration_change_cb);
270 // Stops and destroys all filters, placing the pipeline in the kStopped state.
271 void StopTask(const base::Closure& stop_cb);
273 // Carries out stopping and destroying all filters, placing the pipeline in
274 // the kStopped state.
275 void ErrorChangedTask(PipelineStatus error);
277 // Carries out notifying filters that the playback rate has changed.
278 void PlaybackRateChangedTask(float playback_rate);
280 // Carries out notifying filters that the volume has changed.
281 void VolumeChangedTask(float volume);
283 // Carries out notifying filters that we are seeking to a new timestamp.
284 void SeekTask(base::TimeDelta time, const PipelineStatusCB& seek_cb);
286 // Handles audio/video ended logic and running |ended_cb_|.
287 void DoAudioRendererEnded();
288 void DoVideoRendererEnded();
289 void RunEndedCallbackIfNeeded();
291 // Carries out disabling the audio renderer.
292 void AudioDisabledTask();
294 // Kicks off initialization for each media object, executing |done_cb| with
295 // the result when completed.
296 void InitializeDemuxer(const PipelineStatusCB& done_cb);
297 void InitializeAudioRenderer(const PipelineStatusCB& done_cb);
298 void InitializeVideoRenderer(const PipelineStatusCB& done_cb);
300 // Kicks off destroying filters. Called by StopTask() and ErrorChangedTask().
301 // When we start to tear down the pipeline, we will consider two cases:
302 // 1. when pipeline has not been initialized, we will transit to stopping
303 // state first.
304 // 2. when pipeline has been initialized, we will first transit to pausing
305 // => flushing => stopping => stopped state.
306 // This will remove the race condition during stop between filters.
307 void TearDownPipeline();
309 // Compute the time corresponding to a byte offset.
310 base::TimeDelta TimeForByteOffset_Locked(int64 byte_offset) const;
312 void OnStateTransition(PipelineStatus status);
313 void StateTransitionTask(PipelineStatus status);
315 // Initiates an asynchronous preroll call sequence executing |done_cb|
316 // with the final status when completed.
317 void DoInitialPreroll(const PipelineStatusCB& done_cb);
319 // Initiates an asynchronous pause-flush-seek-preroll call sequence
320 // executing |done_cb| with the final status when completed.
322 // TODO(scherkus): Prerolling should be separate from seeking so we can report
323 // finer grained ready states (HAVE_CURRENT_DATA vs. HAVE_FUTURE_DATA)
324 // indepentent from seeking.
325 void DoSeek(base::TimeDelta seek_timestamp, const PipelineStatusCB& done_cb);
327 // Updates playback rate and volume and initiates an asynchronous play call
328 // sequence executing |done_cb| with the final status when completed.
329 void DoPlay(const PipelineStatusCB& done_cb);
331 // Initiates an asynchronous pause-flush-stop call sequence executing
332 // |done_cb| when completed.
333 void DoStop(const PipelineStatusCB& done_cb);
334 void OnStopCompleted(PipelineStatus status);
336 void OnAudioUnderflow();
338 void StartClockIfWaitingForTimeUpdate_Locked();
340 // Message loop used to execute pipeline tasks.
341 scoped_refptr<base::MessageLoopProxy> message_loop_;
343 // MediaLog to which to log events.
344 scoped_refptr<MediaLog> media_log_;
346 // Lock used to serialize access for the following data members.
347 mutable base::Lock lock_;
349 // Whether or not the pipeline is running.
350 bool running_;
352 // Amount of available buffered data. Set by filters.
353 Ranges<int64> buffered_byte_ranges_;
354 Ranges<base::TimeDelta> buffered_time_ranges_;
356 // True when AddBufferedByteRange() has been called more recently than
357 // DidLoadingProgress().
358 mutable bool did_loading_progress_;
360 // Total size of the media. Set by filters.
361 int64 total_bytes_;
363 // Video's natural width and height. Set by filters.
364 gfx::Size natural_size_;
366 // Current volume level (from 0.0f to 1.0f). This value is set immediately
367 // via SetVolume() and a task is dispatched on the message loop to notify the
368 // filters.
369 float volume_;
371 // Current playback rate (>= 0.0f). This value is set immediately via
372 // SetPlaybackRate() and a task is dispatched on the message loop to notify
373 // the filters.
374 float playback_rate_;
376 // base::TickClock used by |clock_|.
377 base::DefaultTickClock default_tick_clock_;
379 // Reference clock. Keeps track of current playback time. Uses system
380 // clock and linear interpolation, but can have its time manually set
381 // by filters.
382 scoped_ptr<Clock> clock_;
384 // If this value is set to true, then |clock_| is paused and we are waiting
385 // for an update of the clock greater than or equal to the elapsed time to
386 // start the clock.
387 bool waiting_for_clock_update_;
389 // Status of the pipeline. Initialized to PIPELINE_OK which indicates that
390 // the pipeline is operating correctly. Any other value indicates that the
391 // pipeline is stopped or is stopping. Clients can call the Stop() method to
392 // reset the pipeline state, and restore this to PIPELINE_OK.
393 PipelineStatus status_;
395 // Whether the media contains rendered audio and video streams.
396 // TODO(fischman,scherkus): replace these with checks for
397 // {audio,video}_decoder_ once extraction of {Audio,Video}Decoder from the
398 // Filter heirarchy is done.
399 bool has_audio_;
400 bool has_video_;
402 // The following data members are only accessed by tasks posted to
403 // |message_loop_|.
405 // Member that tracks the current state.
406 State state_;
408 // Whether we've received the audio/video ended events.
409 bool audio_ended_;
410 bool video_ended_;
412 // Set to true in DisableAudioRendererTask().
413 bool audio_disabled_;
415 // Temporary callback used for Start() and Seek().
416 PipelineStatusCB seek_cb_;
418 // Temporary callback used for Stop().
419 base::Closure stop_cb_;
421 // Permanent callbacks passed in via Start().
422 base::Closure ended_cb_;
423 PipelineStatusCB error_cb_;
424 BufferingStateCB buffering_state_cb_;
425 base::Closure duration_change_cb_;
427 // Contains the demuxer and renderers to use when initializing.
428 scoped_ptr<FilterCollection> filter_collection_;
430 // Holds the initialized demuxer. Used for seeking. Owned by client.
431 Demuxer* demuxer_;
433 // Holds the initialized renderers. Used for setting the volume,
434 // playback rate, and determining when playback has finished.
435 scoped_ptr<AudioRenderer> audio_renderer_;
436 scoped_ptr<VideoRenderer> video_renderer_;
438 PipelineStatistics statistics_;
440 // Time of pipeline creation; is non-zero only until the pipeline first
441 // reaches "kStarted", at which point it is used & zeroed out.
442 base::TimeTicks creation_time_;
444 scoped_ptr<SerialRunner> pending_callbacks_;
446 base::ThreadChecker thread_checker_;
448 DISALLOW_COPY_AND_ASSIGN(Pipeline);
451 } // namespace media
453 #endif // MEDIA_BASE_PIPELINE_H_