| Index: media/renderers/renderer_impl.cc
|
| diff --git a/media/renderers/renderer_impl.cc b/media/renderers/renderer_impl.cc
|
| index 210e5cc574f2437b4368c498f56b02facf5c1e61..bbdbea16c5cc8ac0264bdc9fc30014e15c6a16b2 100644
|
| --- a/media/renderers/renderer_impl.cc
|
| +++ b/media/renderers/renderer_impl.cc
|
| @@ -208,28 +208,32 @@ void RendererImpl::StartPlayingFrom(base::TimeDelta time) {
|
| video_renderer_->StartPlayingFrom(time);
|
| }
|
|
|
| -void RendererImpl::RestartStreamPlayback(DemuxerStream* stream,
|
| +void RendererImpl::OnStreamStatusChanged(DemuxerStream* stream,
|
| bool enabled,
|
| base::TimeDelta time) {
|
| DCHECK(task_runner_->BelongsToCurrentThread());
|
| DCHECK(stream);
|
| bool video = (stream->type() == DemuxerStream::VIDEO);
|
| DVLOG(1) << __func__ << (video ? " video" : " audio") << " stream=" << stream
|
| - << " enabled=" << stream->enabled() << " time=" << time.InSecondsF();
|
| + << " enabled=" << enabled << " time=" << time.InSecondsF();
|
| if ((state_ != STATE_PLAYING) || (audio_ended_ && video_ended_))
|
| return;
|
| + if (restarting_audio_ || restarting_video_) {
|
| + DVLOG(3) << __func__ << ": postponed stream " << stream
|
| + << " status change handling.";
|
| + pending_stream_status_notifications_.push_back(
|
| + base::Bind(&RendererImpl::OnStreamStatusChanged, weak_this_, stream,
|
| + enabled, time));
|
| + return;
|
| + }
|
| if (stream->type() == DemuxerStream::VIDEO) {
|
| DCHECK(video_renderer_);
|
| - if (restarting_video_)
|
| - return;
|
| restarting_video_ = true;
|
| video_renderer_->Flush(
|
| base::Bind(&RendererImpl::RestartVideoRenderer, weak_this_, time));
|
| } else if (stream->type() == DemuxerStream::AUDIO) {
|
| DCHECK(audio_renderer_);
|
| DCHECK(time_source_);
|
| - if (restarting_audio_)
|
| - return;
|
| restarting_audio_ = true;
|
| // Stop ticking (transition into paused state) in audio renderer before
|
| // calling Flush, since after Flush we are going to restart playback by
|
| @@ -380,7 +384,7 @@ void RendererImpl::InitializeAudioRenderer() {
|
| }
|
|
|
| audio_stream->SetStreamStatusChangeCB(base::Bind(
|
| - &RendererImpl::RestartStreamPlayback, weak_this_, audio_stream));
|
| + &RendererImpl::OnStreamStatusChanged, weak_this_, audio_stream));
|
|
|
| audio_renderer_client_.reset(
|
| new RendererClientInternal(DemuxerStream::AUDIO, this));
|
| @@ -429,7 +433,7 @@ void RendererImpl::InitializeVideoRenderer() {
|
| }
|
|
|
| video_stream->SetStreamStatusChangeCB(base::Bind(
|
| - &RendererImpl::RestartStreamPlayback, weak_this_, video_stream));
|
| + &RendererImpl::OnStreamStatusChanged, weak_this_, video_stream));
|
|
|
| video_renderer_client_.reset(
|
| new RendererClientInternal(DemuxerStream::VIDEO, this));
|
| @@ -564,6 +568,7 @@ const char* BufferingStateStr(BufferingState state) {
|
| bool RendererImpl::HandleRestartedStreamBufferingChanges(
|
| DemuxerStream::Type type,
|
| BufferingState new_buffering_state) {
|
| + DCHECK(task_runner_->BelongsToCurrentThread());
|
| // When restarting playback we want to defer the BUFFERING_HAVE_NOTHING for
|
| // the stream being restarted, to allow continuing uninterrupted playback on
|
| // the other stream.
|
| @@ -571,7 +576,9 @@ bool RendererImpl::HandleRestartedStreamBufferingChanges(
|
| if (new_buffering_state == BUFFERING_HAVE_ENOUGH) {
|
| DVLOG(1) << __func__ << " Got BUFFERING_HAVE_ENOUGH for video stream,"
|
| " resuming playback.";
|
| - restarting_video_ = false;
|
| + task_runner_->PostTask(
|
| + FROM_HERE,
|
| + base::Bind(&RendererImpl::OnStreamRestartCompleted, weak_this_));
|
| if (state_ == STATE_PLAYING &&
|
| !deferred_video_underflow_cb_.IsCancelled()) {
|
| // If deferred_video_underflow_cb_ wasn't triggered, then audio should
|
| @@ -616,12 +623,24 @@ bool RendererImpl::HandleRestartedStreamBufferingChanges(
|
| // Now that we have decoded enough audio, pause playback momentarily to
|
| // ensure video renderer is synchronised with audio.
|
| PausePlayback();
|
| - restarting_audio_ = false;
|
| + task_runner_->PostTask(
|
| + FROM_HERE,
|
| + base::Bind(&RendererImpl::OnStreamRestartCompleted, weak_this_));
|
| }
|
| }
|
| return false;
|
| }
|
|
|
| +void RendererImpl::OnStreamRestartCompleted() {
|
| + DCHECK(restarting_audio_ || restarting_video_);
|
| + restarting_audio_ = false;
|
| + restarting_video_ = false;
|
| + if (!pending_stream_status_notifications_.empty()) {
|
| + pending_stream_status_notifications_.front().Run();
|
| + pending_stream_status_notifications_.pop_front();
|
| + }
|
| +}
|
| +
|
| void RendererImpl::OnBufferingStateChange(DemuxerStream::Type type,
|
| BufferingState new_buffering_state) {
|
| DCHECK((type == DemuxerStream::AUDIO) || (type == DemuxerStream::VIDEO));
|
|
|