Chromium Code Reviews| Index: media/renderers/renderer_impl.cc | 
| diff --git a/media/renderers/renderer_impl.cc b/media/renderers/renderer_impl.cc | 
| index f03b2da865c7f2b02b748b4f9f7f26f2627ebd50..f701ba7806386b036721944396a203951df491de 100644 | 
| --- a/media/renderers/renderer_impl.cc | 
| +++ b/media/renderers/renderer_impl.cc | 
| @@ -80,6 +80,8 @@ RendererImpl::RendererImpl( | 
| task_runner_(task_runner), | 
| audio_renderer_(std::move(audio_renderer)), | 
| video_renderer_(std::move(video_renderer)), | 
| + current_audio_stream_(nullptr), | 
| + current_video_stream_(nullptr), | 
| time_source_(NULL), | 
| time_ticking_(false), | 
| playback_rate_(0.0), | 
| @@ -236,8 +238,8 @@ void RendererImpl::OnStreamStatusChanged(DemuxerStream* stream, | 
| if (stream->type() == DemuxerStream::VIDEO) { | 
| DCHECK(video_renderer_); | 
| restarting_video_ = true; | 
| - video_renderer_->Flush( | 
| - base::Bind(&RendererImpl::RestartVideoRenderer, weak_this_, time)); | 
| + video_renderer_->Flush(base::Bind(&RendererImpl::RestartVideoRenderer, | 
| + weak_this_, stream, time)); | 
| } else if (stream->type() == DemuxerStream::AUDIO) { | 
| DCHECK(audio_renderer_); | 
| DCHECK(time_source_); | 
| @@ -249,30 +251,76 @@ void RendererImpl::OnStreamStatusChanged(DemuxerStream* stream, | 
| time_ticking_ = false; | 
| time_source_->StopTicking(); | 
| } | 
| - audio_renderer_->Flush( | 
| - base::Bind(&RendererImpl::RestartAudioRenderer, weak_this_, time)); | 
| + audio_renderer_->Flush(base::Bind(&RendererImpl::RestartAudioRenderer, | 
| + weak_this_, stream, time)); | 
| } | 
| } | 
| -void RendererImpl::RestartVideoRenderer(base::TimeDelta time) { | 
| - DVLOG(3) << __func__; | 
| +void RendererImpl::RestartVideoRenderer(DemuxerStream* stream, | 
| + base::TimeDelta time) { | 
| 
 
xhwang
2017/03/27 19:13:53
I see what you are doing, but feel it's a bit hard
 
servolk
2017/03/27 22:34:13
Ok, sure, I've refactored it a bit to hopefully ma
 
 | 
| + DVLOG(3) << __func__ << " stream=" << stream << " time=" << time.InSecondsF(); | 
| DCHECK(task_runner_->BelongsToCurrentThread()); | 
| DCHECK(video_renderer_); | 
| DCHECK_EQ(state_, STATE_PLAYING); | 
| + if (stream != current_video_stream_) { | 
| + DVLOG(3) << __func__ << ": detected stream change, reinitializing decoder"; | 
| + current_video_stream_ = stream; | 
| + video_renderer_->OnTimeStopped(); | 
| + video_renderer_->Initialize( | 
| + stream, cdm_context_, video_renderer_client_.get(), | 
| + base::Bind(&RendererImpl::GetWallClockTimes, base::Unretained(this)), | 
| + base::Bind(&RendererImpl::OnVideoRendererReinitCompleted, weak_this_, | 
| + stream, time)); | 
| + return; | 
| + } | 
| 
 
xhwang
2017/03/27 19:13:53
nit: empty line here
 
servolk
2017/03/27 22:34:13
Done.
 
 | 
| video_ended_ = false; | 
| video_renderer_->StartPlayingFrom(time); | 
| } | 
| -void RendererImpl::RestartAudioRenderer(base::TimeDelta time) { | 
| - DVLOG(3) << __func__; | 
| +void RendererImpl::OnVideoRendererReinitCompleted(DemuxerStream* stream, | 
| + base::TimeDelta time, | 
| + PipelineStatus status) { | 
| + DVLOG(3) << __func__ << ": status=" << status; | 
| + if (status != PIPELINE_OK) { | 
| + OnError(status); | 
| + return; | 
| + } | 
| + DCHECK_EQ(stream, current_video_stream_); | 
| + RestartVideoRenderer(stream, time); | 
| +} | 
| + | 
| +void RendererImpl::RestartAudioRenderer(DemuxerStream* stream, | 
| + base::TimeDelta time) { | 
| + DVLOG(3) << __func__ << " stream=" << stream << " time=" << time.InSecondsF(); | 
| DCHECK(task_runner_->BelongsToCurrentThread()); | 
| DCHECK_EQ(state_, STATE_PLAYING); | 
| DCHECK(time_source_); | 
| DCHECK(audio_renderer_); | 
| + if (stream != current_audio_stream_) { | 
| + DVLOG(3) << __func__ << ": detected stream change, reinitializing decoder"; | 
| + current_audio_stream_ = stream; | 
| + audio_renderer_->Initialize( | 
| + stream, cdm_context_, audio_renderer_client_.get(), | 
| + base::Bind(&RendererImpl::OnAudioRendererReinitCompleted, weak_this_, | 
| + stream, time)); | 
| + return; | 
| + } | 
| audio_ended_ = false; | 
| audio_renderer_->StartPlaying(); | 
| } | 
| +void RendererImpl::OnAudioRendererReinitCompleted(DemuxerStream* stream, | 
| + base::TimeDelta time, | 
| + PipelineStatus status) { | 
| + DVLOG(3) << __func__ << ": status=" << status; | 
| + if (status != PIPELINE_OK) { | 
| + OnError(status); | 
| + return; | 
| + } | 
| + DCHECK_EQ(stream, current_audio_stream_); | 
| + RestartAudioRenderer(stream, time); | 
| +} | 
| + | 
| void RendererImpl::SetPlaybackRate(double playback_rate) { | 
| DVLOG(1) << __func__ << "(" << playback_rate << ")"; | 
| DCHECK(task_runner_->BelongsToCurrentThread()); | 
| @@ -394,6 +442,8 @@ void RendererImpl::InitializeAudioRenderer() { | 
| return; | 
| } | 
| + current_audio_stream_ = audio_stream; | 
| + | 
| audio_renderer_client_.reset( | 
| new RendererClientInternal(DemuxerStream::AUDIO, this)); | 
| // Note: After the initialization of a renderer, error events from it may | 
| @@ -442,6 +492,8 @@ void RendererImpl::InitializeVideoRenderer() { | 
| return; | 
| } | 
| + current_video_stream_ = video_stream; | 
| + | 
| video_renderer_client_.reset( | 
| new RendererClientInternal(DemuxerStream::VIDEO, this)); | 
| video_renderer_->Initialize( |