| Index: media/filters/audio_renderer_impl.cc
|
| diff --git a/media/filters/audio_renderer_impl.cc b/media/filters/audio_renderer_impl.cc
|
| index 9ade30dc0dc6fdbba1dae9d7e8cbd041aee6638e..130aa5d99f4113c981aa68275cfec7d3dd19b71d 100644
|
| --- a/media/filters/audio_renderer_impl.cc
|
| +++ b/media/filters/audio_renderer_impl.cc
|
| @@ -147,8 +147,8 @@ void AudioRendererImpl::DoFlush_Locked() {
|
| DCHECK_EQ(state_, kPaused);
|
|
|
| if (decrypting_demuxer_stream_) {
|
| - decrypting_demuxer_stream_->Reset(BindToCurrentLoop(
|
| - base::Bind(&AudioRendererImpl::ResetDecoder, weak_this_)));
|
| + decrypting_demuxer_stream_->Reset(
|
| + base::Bind(&AudioRendererImpl::ResetDecoder, weak_this_));
|
| return;
|
| }
|
|
|
| @@ -157,54 +157,72 @@ void AudioRendererImpl::DoFlush_Locked() {
|
|
|
| void AudioRendererImpl::ResetDecoder() {
|
| DCHECK(task_runner_->BelongsToCurrentThread());
|
| - decoder_->Reset(BindToCurrentLoop(
|
| - base::Bind(&AudioRendererImpl::ResetDecoderDone, weak_this_)));
|
| + decoder_->Reset(base::Bind(&AudioRendererImpl::ResetDecoderDone, weak_this_));
|
| }
|
|
|
| void AudioRendererImpl::ResetDecoderDone() {
|
| - base::AutoLock auto_lock(lock_);
|
| - if (state_ == kStopped)
|
| - return;
|
| -
|
| - DCHECK_EQ(state_, kPaused);
|
| - DCHECK(!flush_cb_.is_null());
|
| + DCHECK(task_runner_->BelongsToCurrentThread());
|
| + {
|
| + base::AutoLock auto_lock(lock_);
|
| + if (state_ == kStopped)
|
| + return;
|
|
|
| - audio_time_buffered_ = kNoTimestamp();
|
| - current_time_ = kNoTimestamp();
|
| - received_end_of_stream_ = false;
|
| - rendered_end_of_stream_ = false;
|
| - preroll_aborted_ = false;
|
| + DCHECK_EQ(state_, kPaused);
|
| + DCHECK(!flush_cb_.is_null());
|
|
|
| - earliest_end_time_ = now_cb_.Run();
|
| - splicer_->Reset();
|
| - algorithm_->FlushBuffers();
|
| + audio_time_buffered_ = kNoTimestamp();
|
| + current_time_ = kNoTimestamp();
|
| + received_end_of_stream_ = false;
|
| + rendered_end_of_stream_ = false;
|
| + preroll_aborted_ = false;
|
|
|
| + earliest_end_time_ = now_cb_.Run();
|
| + splicer_->Reset();
|
| + algorithm_->FlushBuffers();
|
| + }
|
| base::ResetAndReturn(&flush_cb_).Run();
|
| }
|
|
|
| void AudioRendererImpl::Stop(const base::Closure& callback) {
|
| DCHECK(task_runner_->BelongsToCurrentThread());
|
| DCHECK(!callback.is_null());
|
| + DCHECK(stop_cb_.is_null());
|
| +
|
| + stop_cb_ = callback;
|
|
|
| // TODO(scherkus): Consider invalidating |weak_factory_| and replacing
|
| // task-running guards that check |state_| with DCHECK().
|
|
|
| - if (sink_) {
|
| - sink_->Stop();
|
| - sink_ = NULL;
|
| - }
|
| -
|
| {
|
| base::AutoLock auto_lock(lock_);
|
| + if (state_ == kInitializing) {
|
| + decoder_selector_->Abort();
|
| + return;
|
| + }
|
| +
|
| + if (state_ == kStopped) {
|
| + task_runner_->PostTask(FROM_HERE, base::ResetAndReturn(&stop_cb_));
|
| + return;
|
| + }
|
| +
|
| ChangeState_Locked(kStopped);
|
| - algorithm_.reset(NULL);
|
| - init_cb_.Reset();
|
| + algorithm_.reset();
|
| underflow_cb_.Reset();
|
| time_cb_.Reset();
|
| flush_cb_.Reset();
|
| }
|
|
|
| - callback.Run();
|
| + if (sink_) {
|
| + sink_->Stop();
|
| + sink_ = NULL;
|
| + }
|
| +
|
| + if (decoder_) {
|
| + decoder_->Stop(base::ResetAndReturn(&stop_cb_));
|
| + return;
|
| + }
|
| +
|
| + task_runner_->PostTask(FROM_HERE, base::ResetAndReturn(&stop_cb_));
|
| }
|
|
|
| void AudioRendererImpl::Preroll(base::TimeDelta time,
|
| @@ -245,6 +263,8 @@ void AudioRendererImpl::Initialize(DemuxerStream* stream,
|
| DCHECK_EQ(kUninitialized, state_);
|
| DCHECK(sink_);
|
|
|
| + state_ = kInitializing;
|
| +
|
| weak_this_ = weak_factory_.GetWeakPtr();
|
| init_cb_ = init_cb;
|
| statistics_cb_ = statistics_cb;
|
| @@ -265,39 +285,45 @@ void AudioRendererImpl::OnDecoderSelected(
|
| scoped_ptr<DecryptingDemuxerStream> decrypting_demuxer_stream) {
|
| DCHECK(task_runner_->BelongsToCurrentThread());
|
|
|
| - base::AutoLock auto_lock(lock_);
|
| scoped_ptr<AudioDecoderSelector> deleter(decoder_selector_.Pass());
|
|
|
| - if (state_ == kStopped) {
|
| - DCHECK(!sink_);
|
| - return;
|
| - }
|
| -
|
| if (!decoder) {
|
| - base::ResetAndReturn(&init_cb_).Run(DECODER_ERROR_NOT_SUPPORTED);
|
| + {
|
| + base::AutoLock auto_lock(lock_);
|
| + ChangeState_Locked(kUninitialized);
|
| + }
|
| + // Stop() called during initialization.
|
| + if (!stop_cb_.is_null()) {
|
| + base::ResetAndReturn(&init_cb_).Run(PIPELINE_ERROR_ABORT);
|
| + Stop(base::ResetAndReturn(&stop_cb_));
|
| + } else {
|
| + base::ResetAndReturn(&init_cb_).Run(DECODER_ERROR_NOT_SUPPORTED);
|
| + }
|
| return;
|
| }
|
|
|
| + base::AutoLock auto_lock(lock_);
|
| decoder_ = decoder.Pass();
|
| decrypting_demuxer_stream_ = decrypting_demuxer_stream.Pass();
|
|
|
| int sample_rate = decoder_->samples_per_second();
|
|
|
| - // The actual buffer size is controlled via the size of the AudioBus provided
|
| - // to Render(), so just choose something reasonable here for looks.
|
| + // The actual buffer size is controlled via the size of the AudioBus
|
| + // provided to Render(), so just choose something reasonable here for looks.
|
| int buffer_size = decoder_->samples_per_second() / 100;
|
| audio_parameters_ = AudioParameters(
|
| AudioParameters::AUDIO_PCM_LOW_LATENCY, decoder_->channel_layout(),
|
| sample_rate, decoder_->bits_per_channel(), buffer_size);
|
| if (!audio_parameters_.IsValid()) {
|
| + ChangeState_Locked(kUninitialized);
|
| base::ResetAndReturn(&init_cb_).Run(PIPELINE_ERROR_INITIALIZATION_FAILED);
|
| return;
|
| }
|
|
|
| splicer_.reset(new AudioSplicer(sample_rate));
|
|
|
| - // We're all good! Continue initializing the rest of the audio renderer based
|
| - // on the decoder format.
|
| + // We're all good! Continue initializing the rest of the audio renderer
|
| + // based on the decoder format.
|
| algorithm_.reset(new AudioRendererAlgorithm());
|
| algorithm_->Initialize(0, audio_parameters_);
|
|
|
| @@ -426,6 +452,7 @@ bool AudioRendererImpl::HandleSplicerBuffer(
|
|
|
| switch (state_) {
|
| case kUninitialized:
|
| + case kInitializing:
|
| case kFlushing:
|
| NOTREACHED();
|
| return false;
|
| @@ -478,6 +505,7 @@ bool AudioRendererImpl::CanRead_Locked() {
|
|
|
| switch (state_) {
|
| case kUninitialized:
|
| + case kInitializing:
|
| case kPaused:
|
| case kFlushing:
|
| case kStopped:
|
| @@ -667,6 +695,7 @@ void AudioRendererImpl::HandleAbortedReadOrDecodeError(bool is_decode_error) {
|
| PipelineStatus status = is_decode_error ? PIPELINE_ERROR_DECODE : PIPELINE_OK;
|
| switch (state_) {
|
| case kUninitialized:
|
| + case kInitializing:
|
| NOTREACHED();
|
| return;
|
| case kPaused:
|
|
|