| Index: media/base/pipeline.cc
|
| diff --git a/media/base/pipeline.cc b/media/base/pipeline.cc
|
| index 03eb1a3a708a506949f093e6723672cd8fa08332..5cfc144bc3823e0de96eed5345a952526709fc57 100644
|
| --- a/media/base/pipeline.cc
|
| +++ b/media/base/pipeline.cc
|
| @@ -414,10 +414,6 @@
|
| PlaybackRateChangedTask(GetPlaybackRate());
|
| VolumeChangedTask(GetVolume());
|
|
|
| - // Handle renderers that immediately signal they have enough data.
|
| - if (!WaitingForEnoughData())
|
| - StartPlayback();
|
| -
|
| // We enter this state from either kInitPrerolling or kSeeking. As of now
|
| // both those states call Preroll(), which means by time we enter this
|
| // state we've already buffered enough data. Forcefully update the
|
| @@ -426,10 +422,11 @@
|
| //
|
| // TODO(scherkus): Remove after renderers are taught to fire buffering
|
| // state callbacks http://crbug.com/144683
|
| - if (video_renderer_) {
|
| - DCHECK(WaitingForEnoughData());
|
| + DCHECK(WaitingForEnoughData());
|
| + if (audio_renderer_)
|
| + BufferingStateChanged(&audio_buffering_state_, BUFFERING_HAVE_ENOUGH);
|
| + if (video_renderer_)
|
| BufferingStateChanged(&video_buffering_state_, BUFFERING_HAVE_ENOUGH);
|
| - }
|
| return;
|
|
|
| case kStopping:
|
| @@ -456,9 +453,9 @@
|
|
|
| // Preroll renderers.
|
| if (audio_renderer_) {
|
| - bound_fns.Push(base::Bind(&AudioRenderer::StartPlayingFrom,
|
| - base::Unretained(audio_renderer_.get()),
|
| - seek_timestamp));
|
| + bound_fns.Push(base::Bind(
|
| + &AudioRenderer::Preroll, base::Unretained(audio_renderer_.get()),
|
| + seek_timestamp));
|
| }
|
|
|
| if (video_renderer_) {
|
| @@ -480,14 +477,6 @@
|
| pending_callbacks_ = SerialRunner::Run(bound_fns, done_cb);
|
| }
|
|
|
| -#if DCHECK_IS_ON
|
| -static void VerifyBufferingStates(BufferingState* audio_buffering_state,
|
| - BufferingState* video_buffering_state) {
|
| - DCHECK_EQ(*audio_buffering_state, BUFFERING_HAVE_NOTHING);
|
| - DCHECK_EQ(*video_buffering_state, BUFFERING_HAVE_NOTHING);
|
| -}
|
| -#endif
|
| -
|
| void Pipeline::DoSeek(
|
| base::TimeDelta seek_timestamp,
|
| const PipelineStatusCB& done_cb) {
|
| @@ -505,8 +494,14 @@
|
| if (audio_renderer_) {
|
| bound_fns.Push(base::Bind(
|
| &AudioRenderer::Flush, base::Unretained(audio_renderer_.get())));
|
| - }
|
| -
|
| +
|
| + // TODO(scherkus): Remove after AudioRenderer is taught to fire buffering
|
| + // state callbacks http://crbug.com/144683
|
| + bound_fns.Push(base::Bind(&Pipeline::BufferingStateChanged,
|
| + base::Unretained(this),
|
| + &audio_buffering_state_,
|
| + BUFFERING_HAVE_NOTHING));
|
| + }
|
| if (video_renderer_) {
|
| bound_fns.Push(base::Bind(
|
| &VideoRenderer::Flush, base::Unretained(video_renderer_.get())));
|
| @@ -518,14 +513,6 @@
|
| &video_buffering_state_,
|
| BUFFERING_HAVE_NOTHING));
|
| }
|
| -
|
| -#if DCHECK_IS_ON
|
| - // Verify renderers reset their buffering states.
|
| - bound_fns.Push(base::Bind(&VerifyBufferingStates,
|
| - &audio_buffering_state_,
|
| - &video_buffering_state_));
|
| -#endif
|
| -
|
| if (text_renderer_) {
|
| bound_fns.Push(base::Bind(
|
| &TextRenderer::Flush, base::Unretained(text_renderer_.get())));
|
| @@ -537,9 +524,9 @@
|
|
|
| // Preroll renderers.
|
| if (audio_renderer_) {
|
| - bound_fns.Push(base::Bind(&AudioRenderer::StartPlayingFrom,
|
| - base::Unretained(audio_renderer_.get()),
|
| - seek_timestamp));
|
| + bound_fns.Push(base::Bind(
|
| + &AudioRenderer::Preroll, base::Unretained(audio_renderer_.get()),
|
| + seek_timestamp));
|
| }
|
|
|
| if (video_renderer_) {
|
| @@ -869,9 +856,8 @@
|
| demuxer_->GetStream(DemuxerStream::AUDIO),
|
| done_cb,
|
| base::Bind(&Pipeline::OnUpdateStatistics, base::Unretained(this)),
|
| + base::Bind(&Pipeline::OnAudioUnderflow, base::Unretained(this)),
|
| base::Bind(&Pipeline::OnAudioTimeUpdate, base::Unretained(this)),
|
| - base::Bind(&Pipeline::BufferingStateChanged, base::Unretained(this),
|
| - &audio_buffering_state_),
|
| base::Bind(&Pipeline::OnAudioRendererEnded, base::Unretained(this)),
|
| base::Bind(&Pipeline::SetError, base::Unretained(this)));
|
| }
|
| @@ -892,6 +878,20 @@
|
| base::Bind(&Pipeline::GetMediaDuration, base::Unretained(this)));
|
| }
|
|
|
| +void Pipeline::OnAudioUnderflow() {
|
| + if (!task_runner_->BelongsToCurrentThread()) {
|
| + task_runner_->PostTask(FROM_HERE, base::Bind(
|
| + &Pipeline::OnAudioUnderflow, base::Unretained(this)));
|
| + return;
|
| + }
|
| +
|
| + if (state_ != kPlaying)
|
| + return;
|
| +
|
| + if (audio_renderer_)
|
| + audio_renderer_->ResumeAfterUnderflow();
|
| +}
|
| +
|
| void Pipeline::BufferingStateChanged(BufferingState* buffering_state,
|
| BufferingState new_buffering_state) {
|
| DVLOG(1) << __FUNCTION__ << "(" << *buffering_state << ", "
|
| @@ -903,7 +903,7 @@
|
|
|
| // Renderer underflowed.
|
| if (!was_waiting_for_enough_data && WaitingForEnoughData()) {
|
| - PausePlayback();
|
| + StartWaitingForEnoughData();
|
| return;
|
| }
|
|
|
| @@ -925,11 +925,10 @@
|
| return false;
|
| }
|
|
|
| -void Pipeline::PausePlayback() {
|
| +void Pipeline::StartWaitingForEnoughData() {
|
| DVLOG(1) << __FUNCTION__;
|
| DCHECK_EQ(state_, kPlaying);
|
| DCHECK(WaitingForEnoughData());
|
| - DCHECK(task_runner_->BelongsToCurrentThread());
|
|
|
| base::AutoLock auto_lock(lock_);
|
| PauseClockAndStopRendering_Locked();
|
| @@ -940,7 +939,6 @@
|
| DCHECK_EQ(state_, kPlaying);
|
| DCHECK_EQ(clock_state_, CLOCK_PAUSED);
|
| DCHECK(!WaitingForEnoughData());
|
| - DCHECK(task_runner_->BelongsToCurrentThread());
|
|
|
| if (audio_renderer_) {
|
| // We use audio stream to update the clock. So if there is such a
|
|
|