Chromium Code Reviews| Index: media/base/pipeline.cc |
| diff --git a/media/base/pipeline.cc b/media/base/pipeline.cc |
| index cb4469bf893ff0934d6dd4e25b176072a1321d6d..11e8e8d40a5b1f2958ea1a42b5b92336809902a8 100644 |
| --- a/media/base/pipeline.cc |
| +++ b/media/base/pipeline.cc |
| @@ -19,6 +19,7 @@ |
| #include "base/synchronization/condition_variable.h" |
| #include "media/base/audio_decoder.h" |
| #include "media/base/audio_renderer.h" |
| +#include "media/base/bind_to_current_loop.h" |
| #include "media/base/clock.h" |
| #include "media/base/filter_collection.h" |
| #include "media/base/media_log.h" |
| @@ -412,6 +413,10 @@ void Pipeline::StateTransitionTask(PipelineStatus status) { |
| PlaybackRateChangedTask(GetPlaybackRate()); |
| VolumeChangedTask(GetVolume()); |
| + // Handle renderers that immediately signal they have enough data. |
| + if (!WaitingForEnoughData()) |
| + TransitionToNonWaiting(); |
| + |
| // 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 |
| @@ -420,11 +425,10 @@ void Pipeline::StateTransitionTask(PipelineStatus status) { |
| // |
| // TODO(scherkus): Remove after renderers are taught to fire buffering |
| // state callbacks http://crbug.com/144683 |
| - DCHECK(WaitingForEnoughData()); |
| - if (audio_renderer_) |
| - BufferingStateChanged(&audio_buffering_state_, BUFFERING_HAVE_ENOUGH); |
| - if (video_renderer_) |
| + if (video_renderer_) { |
| + DCHECK(WaitingForEnoughData()); |
| BufferingStateChanged(&video_buffering_state_, BUFFERING_HAVE_ENOUGH); |
| + } |
| return; |
| case kStopping: |
| @@ -451,9 +455,9 @@ void Pipeline::DoInitialPreroll(const PipelineStatusCB& done_cb) { |
| // Preroll renderers. |
| if (audio_renderer_) { |
| - bound_fns.Push(base::Bind( |
| - &AudioRenderer::Preroll, base::Unretained(audio_renderer_.get()), |
| - seek_timestamp)); |
| + bound_fns.Push(base::Bind(&AudioRenderer::StartPlayingFrom, |
| + base::Unretained(audio_renderer_.get()), |
| + seek_timestamp)); |
| } |
| if (video_renderer_) { |
| @@ -522,9 +526,9 @@ void Pipeline::DoSeek( |
| // Preroll renderers. |
| if (audio_renderer_) { |
| - bound_fns.Push(base::Bind( |
| - &AudioRenderer::Preroll, base::Unretained(audio_renderer_.get()), |
| - seek_timestamp)); |
| + bound_fns.Push(base::Bind(&AudioRenderer::StartPlayingFrom, |
| + base::Unretained(audio_renderer_.get()), |
| + seek_timestamp)); |
| } |
| if (video_renderer_) { |
| @@ -857,8 +861,11 @@ void Pipeline::InitializeAudioRenderer(const PipelineStatusCB& done_cb) { |
| 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)), |
| + // TODO(scherkus): Enforce AudioRendererImpl to call on right thread. |
| + BindToCurrentLoop(base::Bind(&Pipeline::BufferingStateChanged, |
|
acolwell GONE FROM CHROMIUM
2014/05/13 20:44:27
nit: Shouldn't we hide this wrapping in the AudioR
scherkus (not reviewing)
2014/05/15 23:28:43
Done.
|
| + base::Unretained(this), |
| + &audio_buffering_state_)), |
| base::Bind(&Pipeline::OnAudioRendererEnded, base::Unretained(this)), |
| base::Bind(&Pipeline::SetError, base::Unretained(this))); |
| } |
| @@ -879,20 +886,6 @@ void Pipeline::InitializeVideoRenderer(const PipelineStatusCB& done_cb) { |
| base::Bind(&Pipeline::GetMediaDuration, base::Unretained(this))); |
| } |
| -void Pipeline::OnAudioUnderflow() { |
| - if (!task_runner_->BelongsToCurrentThread()) { |
|
acolwell GONE FROM CHROMIUM
2014/05/13 20:44:27
\o/ I'm happy to see this method die. It lived WAY
|
| - 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 << ", " |
| @@ -904,13 +897,13 @@ void Pipeline::BufferingStateChanged(BufferingState* buffering_state, |
| // Renderer underflowed. |
| if (!was_waiting_for_enough_data && WaitingForEnoughData()) { |
| - StartWaitingForEnoughData(); |
| + TransitionToWaiting(); |
| return; |
| } |
| // Renderer prerolled. |
| if (was_waiting_for_enough_data && !WaitingForEnoughData()) { |
| - StartPlayback(); |
| + TransitionToNonWaiting(); |
| return; |
| } |
| } |
| @@ -926,10 +919,25 @@ bool Pipeline::WaitingForEnoughData() const { |
| return false; |
| } |
| -void Pipeline::StartWaitingForEnoughData() { |
| +void Pipeline::TransitionToWaiting() { |
| DVLOG(1) << __FUNCTION__; |
| DCHECK_EQ(state_, kPlaying); |
| DCHECK(WaitingForEnoughData()); |
| + task_runner_->PostTask( |
| + FROM_HERE, base::Bind(&Pipeline::PausePlayback, base::Unretained(this))); |
| +} |
| + |
| +void Pipeline::TransitionToNonWaiting() { |
| + DVLOG(1) << __FUNCTION__; |
| + DCHECK_EQ(state_, kPlaying); |
| + DCHECK(!WaitingForEnoughData()); |
| + task_runner_->PostTask( |
|
acolwell GONE FROM CHROMIUM
2014/05/13 20:44:27
Why do you need to PostTask() here and above now?
scherkus (not reviewing)
2014/05/15 23:28:43
it's to avoid reentrancy into renderers ... but I
|
| + FROM_HERE, base::Bind(&Pipeline::StartPlayback, base::Unretained(this))); |
| +} |
| + |
| +void Pipeline::PausePlayback() { |
| + DVLOG(1) << __FUNCTION__; |
| + DCHECK(task_runner_->BelongsToCurrentThread()); |
| if (audio_renderer_) |
| audio_renderer_->StopRendering(); |
| @@ -940,8 +948,7 @@ void Pipeline::StartWaitingForEnoughData() { |
| void Pipeline::StartPlayback() { |
| DVLOG(1) << __FUNCTION__; |
| - DCHECK_EQ(state_, kPlaying); |
| - DCHECK(!WaitingForEnoughData()); |
| + DCHECK(task_runner_->BelongsToCurrentThread()); |
| if (audio_renderer_) { |
| // We use audio stream to update the clock. So if there is such a |