Chromium Code Reviews| Index: media/filters/audio_renderer_impl.cc |
| diff --git a/media/filters/audio_renderer_impl.cc b/media/filters/audio_renderer_impl.cc |
| index 820cf6ee58e0a3036ffbbb479926d844becb9124..aea0ddcc8d75702f632aff787138f8170406f39f 100644 |
| --- a/media/filters/audio_renderer_impl.cc |
| +++ b/media/filters/audio_renderer_impl.cc |
| @@ -11,6 +11,7 @@ |
| #include "base/callback_helpers.h" |
| #include "base/logging.h" |
| #include "media/audio/audio_util.h" |
| +#include "media/base/demuxer_stream.h" |
| namespace media { |
| @@ -130,14 +131,19 @@ void AudioRendererImpl::Preroll(base::TimeDelta time, |
| sink_->Pause(true); |
| } |
| -void AudioRendererImpl::Initialize(const scoped_refptr<AudioDecoder>& decoder, |
| +void AudioRendererImpl::Initialize(const scoped_refptr<DemuxerStream>& stream, |
| + const AudioDecoderList& decoders, |
| const PipelineStatusCB& init_cb, |
| + const StatisticsCB& statistics_cb, |
| const base::Closure& underflow_cb, |
| const TimeCB& time_cb, |
| const base::Closure& ended_cb, |
| const base::Closure& disabled_cb, |
| const PipelineStatusCB& error_cb) { |
| - DCHECK(decoder); |
| + base::AutoLock auto_lock(lock_); |
| + DCHECK(stream); |
| + DCHECK(!decoders.empty()); |
| + DCHECK_EQ(stream->type(), DemuxerStream::AUDIO); |
| DCHECK(!init_cb.is_null()); |
| DCHECK(!underflow_cb.is_null()); |
| DCHECK(!time_cb.is_null()); |
| @@ -145,13 +151,63 @@ void AudioRendererImpl::Initialize(const scoped_refptr<AudioDecoder>& decoder, |
| DCHECK(!disabled_cb.is_null()); |
| DCHECK(!error_cb.is_null()); |
| DCHECK_EQ(kUninitialized, state_); |
| - decoder_ = decoder; |
| + |
| + init_cb_ = init_cb; |
| + statistics_cb_ = statistics_cb; |
| underflow_cb_ = underflow_cb; |
| time_cb_ = time_cb; |
| ended_cb_ = ended_cb; |
| disabled_cb_ = disabled_cb; |
| error_cb_ = error_cb; |
| + scoped_ptr<AudioDecoderList> decoder_list(new AudioDecoderList(decoders)); |
| + InitializeNextDecoder(stream, decoder_list.Pass()); |
| +} |
| + |
| +void AudioRendererImpl::InitializeNextDecoder( |
| + const scoped_refptr<DemuxerStream>& demuxer_stream, |
| + scoped_ptr<AudioDecoderList> decoders) { |
| + lock_.AssertAcquired(); |
| + DCHECK(!decoders->empty()); |
| + |
| + scoped_refptr<AudioDecoder> decoder = decoders->front(); |
| + decoders->pop_front(); |
| + |
| + DCHECK(decoder); |
| + decoder_ = decoder; |
| + |
| + base::AutoUnlock auto_unlock(lock_); |
| + decoder->Initialize( |
| + demuxer_stream, |
| + base::Bind(&AudioRendererImpl::OnDecoderInitDone, this, |
| + demuxer_stream, |
| + base::Passed(&decoders)), |
| + statistics_cb_); |
| +} |
| + |
| +void AudioRendererImpl::OnDecoderInitDone( |
| + const scoped_refptr<DemuxerStream>& demuxer_stream, |
| + scoped_ptr<AudioDecoderList> decoders, |
| + PipelineStatus status) { |
| + base::AutoLock auto_lock(lock_); |
| + |
| + if (state_ == kStopped) { |
| + // TODO(xhwang): Question! Do we need to return init_cb here? Is the |
| + // pipeline teardown waiting for this? |
|
xhwang
2012/10/15 17:50:28
In VideoRendererBase we return directly here w/o r
|
| + base::ResetAndReturn(&init_cb_).Run(PIPELINE_ERROR_ABORT); |
|
acolwell GONE FROM CHROMIUM
2012/10/15 21:00:07
No. You should not call init_cb_ here. init_cb_ sh
xhwang
2012/10/15 22:52:23
Done. Also added init_cb_.Reset() in Stop().
|
| + return; |
| + } |
| + |
| + if (!decoders->empty() && status == DECODER_ERROR_NOT_SUPPORTED) { |
| + InitializeNextDecoder(demuxer_stream, decoders.Pass()); |
| + return; |
| + } |
| + |
| + if (status != PIPELINE_OK) { |
| + base::ResetAndReturn(&init_cb_).Run(status); |
| + return; |
| + } |
| + |
| // Create a callback so our algorithm can request more reads. |
| base::Closure cb = base::Bind(&AudioRendererImpl::ScheduleRead_Locked, this); |
| @@ -170,7 +226,7 @@ void AudioRendererImpl::Initialize(const scoped_refptr<AudioDecoder>& decoder, |
| bool config_ok = algorithm_->ValidateConfig(channels, sample_rate, |
| bits_per_channel); |
| if (!config_ok || is_initialized_) { |
| - init_cb.Run(PIPELINE_ERROR_INITIALIZATION_FAILED); |
| + init_cb_.Run(PIPELINE_ERROR_INITIALIZATION_FAILED); |
|
acolwell GONE FROM CHROMIUM
2012/10/15 21:00:07
nit: Change to base::ResetAndReturn(&init_cb_)
xhwang
2012/10/15 22:52:23
Done.
|
| return; |
| } |
| @@ -197,7 +253,7 @@ void AudioRendererImpl::Initialize(const scoped_refptr<AudioDecoder>& decoder, |
| // Finally, execute the start callback. |
| state_ = kPaused; |
| - init_cb.Run(PIPELINE_OK); |
| + init_cb_.Run(PIPELINE_OK); |
|
acolwell GONE FROM CHROMIUM
2012/10/15 21:00:07
ditto
xhwang
2012/10/15 22:52:23
Done.
|
| } |
| void AudioRendererImpl::ResumeAfterUnderflow(bool buffer_more_audio) { |