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"); |