Index: media/base/pipeline.h |
diff --git a/media/base/pipeline.h b/media/base/pipeline.h |
index fed95a3f2743dde7971c3b4711f34978d91cdc2d..fe5962a4dd2831dc05ed5309270e1667b6ff67cb 100644 |
--- a/media/base/pipeline.h |
+++ b/media/base/pipeline.h |
@@ -5,11 +5,15 @@ |
#ifndef MEDIA_BASE_PIPELINE_H_ |
#define MEDIA_BASE_PIPELINE_H_ |
+#include <string> |
+ |
#include "base/gtest_prod_util.h" |
#include "base/memory/weak_ptr.h" |
+#include "base/synchronization/condition_variable.h" |
#include "base/synchronization/lock.h" |
#include "base/threading/thread_checker.h" |
#include "base/time/default_tick_clock.h" |
+#include "media/base/audio_renderer.h" |
#include "media/base/buffering_state.h" |
#include "media/base/demuxer.h" |
#include "media/base/media_export.h" |
@@ -28,10 +32,11 @@ |
class FilterCollection; |
class MediaLog; |
-class Renderer; |
class TextRenderer; |
class TextTrackConfig; |
class TimeDeltaInterpolator; |
+class TimeSource; |
+class VideoRenderer; |
// Metadata describing a pipeline once it has been initialized. |
struct PipelineMetadata { |
@@ -173,6 +178,10 @@ |
// Gets the current pipeline statistics. |
PipelineStatistics GetStatistics() const; |
+ void set_underflow_disabled_for_testing(bool disabled) { |
+ underflow_disabled_for_testing_ = disabled; |
+ } |
+ void SetTimeDeltaInterpolatorForTesting(TimeDeltaInterpolator* interpolator); |
void SetErrorForTesting(PipelineStatus status); |
bool HasWeakPtrsForTesting() const; |
@@ -186,7 +195,8 @@ |
enum State { |
kCreated, |
kInitDemuxer, |
- kInitRenderer, |
+ kInitAudioRenderer, |
+ kInitVideoRenderer, |
kSeeking, |
kPlaying, |
kStopping, |
@@ -219,6 +229,12 @@ |
// Callback executed by filters to update statistics. |
void OnUpdateStatistics(const PipelineStatistics& stats); |
+ // Callback executed by audio renderer to update clock time. |
+ void OnAudioTimeUpdate(base::TimeDelta time, base::TimeDelta max_time); |
+ |
+ // Callback executed by video renderer to update clock time. |
+ void OnVideoTimeUpdate(base::TimeDelta max_time); |
+ |
// The following "task" methods correspond to the public methods, but these |
// methods are run as the result of posting a task to the Pipeline's |
// task runner. |
@@ -241,7 +257,8 @@ |
void SeekTask(base::TimeDelta time, const PipelineStatusCB& seek_cb); |
// Callbacks executed when a renderer has ended. |
- void OnRendererEnded(); |
+ void OnAudioRendererEnded(); |
+ void OnVideoRendererEnded(); |
void OnTextRendererEnded(); |
void RunEndedCallbackIfNeeded(); |
@@ -255,7 +272,20 @@ |
// Kicks off initialization for each media object, executing |done_cb| with |
// the result when completed. |
void InitializeDemuxer(const PipelineStatusCB& done_cb); |
- void InitializeRenderer(const PipelineStatusCB& done_cb); |
+ void InitializeAudioRenderer(const PipelineStatusCB& done_cb); |
+ void InitializeVideoRenderer(const PipelineStatusCB& done_cb); |
+ |
+ // Kicks off destroying filters. Called by StopTask() and ErrorChangedTask(). |
+ // When we start to tear down the pipeline, we will consider two cases: |
+ // 1. when pipeline has not been initialized, we will transit to stopping |
+ // state first. |
+ // 2. when pipeline has been initialized, we will first transit to pausing |
+ // => flushing => stopping => stopped state. |
+ // This will remove the race condition during stop between filters. |
+ void TearDownPipeline(); |
+ |
+ // Compute the time corresponding to a byte offset. |
+ base::TimeDelta TimeForByteOffset_Locked(int64 byte_offset) const; |
void OnStateTransition(PipelineStatus status); |
void StateTransitionTask(PipelineStatus status); |
@@ -269,7 +299,23 @@ |
void DoStop(const PipelineStatusCB& done_cb); |
void OnStopCompleted(PipelineStatus status); |
- void BufferingStateChanged(BufferingState new_buffering_state); |
+ // Collection of callback methods and helpers for tracking changes in |
+ // buffering state and transition from paused/underflow states and playing |
+ // states. |
+ // |
+ // While in the kPlaying state: |
+ // - A waiting to non-waiting transition indicates preroll has completed |
+ // and StartPlayback() should be called |
+ // - A non-waiting to waiting transition indicates underflow has occurred |
+ // and PausePlayback() should be called |
+ void BufferingStateChanged(BufferingState* buffering_state, |
+ BufferingState new_buffering_state); |
+ bool WaitingForEnoughData() const; |
+ void PausePlayback(); |
+ void StartPlayback(); |
+ |
+ void PauseClockAndStopTicking_Locked(); |
+ void StartClockIfWaitingForTimeUpdate_Locked(); |
// Task runner used to execute pipeline tasks. |
scoped_refptr<base::SingleThreadTaskRunner> task_runner_; |
@@ -302,6 +348,26 @@ |
// Current duration as reported by |demuxer_|. |
base::TimeDelta duration_; |
+ |
+ // base::TickClock used by |interpolator_|. |
+ base::DefaultTickClock default_tick_clock_; |
+ |
+ // Tracks the most recent media time update and provides interpolated values |
+ // as playback progresses. |
+ scoped_ptr<TimeDeltaInterpolator> interpolator_; |
+ |
+ enum InterpolationState { |
+ // Audio (if present) is not rendering. Time isn't being interpolated. |
+ INTERPOLATION_STOPPED, |
+ |
+ // Audio (if present) is rendering. Time isn't being interpolated. |
+ INTERPOLATION_WAITING_FOR_AUDIO_TIME_UPDATE, |
+ |
+ // Audio (if present) is rendering. Time is being interpolated. |
+ INTERPOLATION_STARTED, |
+ }; |
+ |
+ InterpolationState interpolation_state_; |
// Status of the pipeline. Initialized to PIPELINE_OK which indicates that |
// the pipeline is operating correctly. Any other value indicates that the |
@@ -312,8 +378,6 @@ |
// The following data members are only accessed by tasks posted to |
// |task_runner_|. |
- bool is_initialized_; |
- |
// Member that tracks the current state. |
State state_; |
@@ -321,8 +385,12 @@ |
base::TimeDelta start_timestamp_; |
// Whether we've received the audio/video/text ended events. |
- bool renderer_ended_; |
- bool text_renderer_ended_; |
+ bool audio_ended_; |
+ bool video_ended_; |
+ bool text_ended_; |
+ |
+ BufferingState audio_buffering_state_; |
+ BufferingState video_buffering_state_; |
// Temporary callback used for Start() and Seek(). |
PipelineStatusCB seek_cb_; |
@@ -345,12 +413,18 @@ |
// Holds the initialized renderers. Used for setting the volume, |
// playback rate, and determining when playback has finished. |
- scoped_ptr<Renderer> renderer_; |
+ scoped_ptr<AudioRenderer> audio_renderer_; |
+ scoped_ptr<VideoRenderer> video_renderer_; |
scoped_ptr<TextRenderer> text_renderer_; |
+ // Renderer-provided time source used to control playback. |
+ TimeSource* time_source_; |
+ |
PipelineStatistics statistics_; |
scoped_ptr<SerialRunner> pending_callbacks_; |
+ |
+ bool underflow_disabled_for_testing_; |
base::ThreadChecker thread_checker_; |