Chromium Code Reviews| Index: media/filters/video_renderer_base.cc |
| diff --git a/media/filters/video_renderer_base.cc b/media/filters/video_renderer_base.cc |
| index aab55e14b8dec3314caba54f417e5ff240cf6a2c..a02b0ec9995076f241125d2798665609a13fb443 100644 |
| --- a/media/filters/video_renderer_base.cc |
| +++ b/media/filters/video_renderer_base.cc |
| @@ -112,7 +112,8 @@ void VideoRendererBase::Preroll(base::TimeDelta time, |
| AttemptRead_Locked(); |
| } |
| -void VideoRendererBase::Initialize(const scoped_refptr<VideoDecoder>& decoder, |
| +void VideoRendererBase::Initialize(const scoped_refptr<DemuxerStream>& stream, |
| + const VideoDecoderList& decoders, |
| const PipelineStatusCB& init_cb, |
| const StatisticsCB& statistics_cb, |
| const TimeCB& max_time_cb, |
| @@ -122,7 +123,9 @@ void VideoRendererBase::Initialize(const scoped_refptr<VideoDecoder>& decoder, |
| const TimeDeltaCB& get_time_cb, |
| const TimeDeltaCB& get_duration_cb) { |
| base::AutoLock auto_lock(lock_); |
| - DCHECK(decoder); |
| + DCHECK(stream); |
| + DCHECK(!decoders.empty()); |
| + DCHECK_EQ(stream->type(), DemuxerStream::VIDEO); |
| DCHECK(!init_cb.is_null()); |
| DCHECK(!statistics_cb.is_null()); |
| DCHECK(!max_time_cb.is_null()); |
| @@ -131,8 +134,10 @@ void VideoRendererBase::Initialize(const scoped_refptr<VideoDecoder>& decoder, |
| DCHECK(!get_time_cb.is_null()); |
| DCHECK(!get_duration_cb.is_null()); |
| DCHECK_EQ(kUninitialized, state_); |
| - decoder_ = decoder; |
| + demuxer_stream_ = stream; |
| + decoders_ = decoders; |
| + init_cb_ = init_cb; |
| statistics_cb_ = statistics_cb; |
| max_time_cb_ = max_time_cb; |
| size_changed_cb_ = size_changed_cb; |
| @@ -141,20 +146,60 @@ void VideoRendererBase::Initialize(const scoped_refptr<VideoDecoder>& decoder, |
| get_time_cb_ = get_time_cb; |
| get_duration_cb_ = get_duration_cb; |
| + InitializeNextDecoder(); |
| +} |
| + |
| +void VideoRendererBase::InitializeNextDecoder() { |
| + lock_.AssertAcquired(); |
| + DCHECK(!decoders_.empty()); |
| + |
| + scoped_refptr<VideoDecoder> decoder = decoders_.front(); |
| + decoders_.pop_front(); |
| + |
| + DCHECK(decoder); |
| + decoder_ = decoder; |
| + |
| + base::AutoUnlock auto_unlock(lock_); |
| + decoder->Initialize( |
| + demuxer_stream_, |
| + base::Bind(&VideoRendererBase::OnDecoderInitDone, this), |
| + statistics_cb_); |
| +} |
| + |
| +void VideoRendererBase::OnDecoderInitDone(PipelineStatus status) { |
| + base::AutoLock auto_lock(lock_); |
| + if (!decoders_.empty() && status == DECODER_ERROR_NOT_SUPPORTED) { |
| + InitializeNextDecoder(); |
| + return; |
| + } |
| + |
| + if (state_ == kStopped) |
|
xhwang
2012/08/09 21:38:29
Q: if VBR is already stopped, do we want to Initia
acolwell GONE FROM CHROMIUM
2012/08/09 22:23:32
Good point. Moved this to the top.
|
| + return; |
| + |
| + if (status != PIPELINE_OK) { |
| + state_ = kError; |
| + base::ResetAndReturn(&init_cb_).Run(status); |
| + return; |
| + } |
| + |
| // We're all good! Consider ourselves flushed. (ThreadMain() should never |
| // see us in the kUninitialized state). |
| // Since we had an initial Preroll(), we consider ourself flushed, because we |
| // have not populated any buffers yet. |
| + |
| + // Clear out remaining decoders since we don't need them now. |
| + decoders_.clear(); |
| + |
| state_ = kFlushed; |
| - set_opaque_cb_.Run(!decoder->HasAlpha()); |
| + set_opaque_cb_.Run(!decoder_->HasAlpha()); |
| set_opaque_cb_.Reset(); |
| // Create our video thread. |
| if (!base::PlatformThread::Create(0, this, &thread_)) { |
| NOTREACHED() << "Video thread creation failed"; |
| state_ = kError; |
| - init_cb.Run(PIPELINE_ERROR_INITIALIZATION_FAILED); |
| + base::ResetAndReturn(&init_cb_).Run(PIPELINE_ERROR_INITIALIZATION_FAILED); |
| return; |
| } |
| @@ -163,7 +208,7 @@ void VideoRendererBase::Initialize(const scoped_refptr<VideoDecoder>& decoder, |
| // TODO(scherkus): find out if this is necessary, but it seems to help. |
| ::SetThreadPriority(thread_, THREAD_PRIORITY_ABOVE_NORMAL); |
| #endif // defined(OS_WIN) |
| - init_cb.Run(PIPELINE_OK); |
| + base::ResetAndReturn(&init_cb_).Run(PIPELINE_OK); |
| } |
| bool VideoRendererBase::HasEnded() { |
| @@ -171,6 +216,12 @@ bool VideoRendererBase::HasEnded() { |
| return state_ == kEnded; |
| } |
| +void VideoRendererBase::PrepareForShutdownHack() { |
| + base::AutoLock auto_lock(lock_); |
| + if (decoder_) |
| + decoder_->PrepareForShutdownHack(); |
| +} |
| + |
| // PlatformThread::Delegate implementation. |
| void VideoRendererBase::ThreadMain() { |
| base::PlatformThread::SetName("CrVideoRenderer"); |