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 |