Chromium Code Reviews| Index: chromecast/media/cma/backend/alsa/audio_decoder_alsa.cc |
| diff --git a/chromecast/media/cma/backend/alsa/audio_decoder_alsa.cc b/chromecast/media/cma/backend/alsa/audio_decoder_alsa.cc |
| index 4ed98894aa6d1cbd8c557e8e5833573f74babc19..a83d6a45a13caf64f0f5db535da7c40304d055c0 100644 |
| --- a/chromecast/media/cma/backend/alsa/audio_decoder_alsa.cc |
| +++ b/chromecast/media/cma/backend/alsa/audio_decoder_alsa.cc |
| @@ -218,12 +218,14 @@ bool AudioDecoderAlsa::SetConfig(const AudioConfig& config) { |
| return false; |
| } |
| - if (!rate_shifter_ || |
| - config.samples_per_second != config_.samples_per_second) { |
| + bool changed_sample_rate = |
| + (config.samples_per_second != config_.samples_per_second); |
| + |
| + if (!rate_shifter_ || changed_sample_rate) { |
| CreateRateShifter(config.samples_per_second); |
| } |
| - if (mixer_input_ && config.samples_per_second != config_.samples_per_second) { |
| + if (mixer_input_ && changed_sample_rate) { |
| // Destroy the old input first to ensure that the mixer output sample rate |
| // is updated. |
| mixer_input_.reset(); |
| @@ -237,7 +239,7 @@ bool AudioDecoderAlsa::SetConfig(const AudioConfig& config) { |
| decoder_.reset(); |
| CreateDecoder(); |
| - if (pending_buffer_complete_ && !rate_shifter_->IsQueueFull()) { |
| + if (pending_buffer_complete_ && changed_sample_rate) { |
|
slan
2017/01/06 01:14:47
This code is now liable to call OnPushBufferComple
kmackay
2017/01/06 01:21:04
In this case, the rate shifter was just (re)create
|
| pending_buffer_complete_ = false; |
| delegate_->OnPushBufferComplete(MediaPipelineBackendAlsa::kBufferSuccess); |
| } |
| @@ -338,6 +340,7 @@ void AudioDecoderAlsa::OnBufferDecoded( |
| delta.decoded_bytes = input_bytes; |
| UpdateStatistics(delta); |
| + pending_buffer_complete_ = true; |
| if (decoded->end_of_stream()) { |
| got_eos_ = true; |
| } else { |
| @@ -350,7 +353,6 @@ void AudioDecoderAlsa::OnBufferDecoded( |
| if (rate_info->rate == 1.0 && rate_shifter_->frames_buffered() == 0 && |
| pending_output_frames_ == kNoPendingOutput) { |
| DCHECK_EQ(rate_info->output_frames, rate_info->input_frames); |
| - pending_buffer_complete_ = true; |
| pending_output_frames_ = input_frames; |
| if (got_eos_) { |
| DCHECK(!pushed_eos_); |
| @@ -374,20 +376,34 @@ void AudioDecoderAlsa::OnBufferDecoded( |
| PushRateShifted(); |
| DCHECK(!rate_shifter_info_.empty()); |
| - // Can't check got_eos_ here, since it may have already been reset by a call |
| - // to Stop(). |
| - if (decoded->end_of_stream() || (!rate_shifter_->IsQueueFull() && |
| - rate_shifter_info_.front().rate != 1.0)) { |
| + CheckBufferComplete(); |
| +} |
| + |
| +void AudioDecoderAlsa::CheckBufferComplete() { |
| + if (!pending_buffer_complete_) { |
| + return; |
| + } |
| + |
| + bool rate_shifter_queue_full = rate_shifter_->IsQueueFull(); |
| + DCHECK(!rate_shifter_info_.empty()); |
| + if (rate_shifter_info_.front().rate == 1.0) { |
| + // If the current rate is 1.0, drain any data in the rate shifter before |
| + // calling PushBufferComplete, so that the next PushBuffer call can skip the |
| + // rate shifter entirely. |
| + rate_shifter_queue_full = (rate_shifter_->frames_buffered() > 0 || |
| + pending_output_frames_ != kNoPendingOutput); |
| + } |
| + |
| + if (pushed_eos_ || !rate_shifter_queue_full) { |
| + pending_buffer_complete_ = false; |
| delegate_->OnPushBufferComplete(MediaPipelineBackendAlsa::kBufferSuccess); |
| - } else { |
| - pending_buffer_complete_ = true; |
| } |
| } |
| void AudioDecoderAlsa::PushRateShifted() { |
| DCHECK(mixer_input_); |
| - if (pending_output_frames_ != kNoPendingOutput) { |
| + if (pushed_eos_ || pending_output_frames_ != kNoPendingOutput) { |
| return; |
| } |
| @@ -492,29 +508,18 @@ void AudioDecoderAlsa::OnWritePcmCompletion(BufferStatus status, |
| pending_output_frames_ = kNoPendingOutput; |
| last_mixer_delay_ = delay; |
| - if (pushed_eos_) { |
| - if (pending_buffer_complete_) { |
| - pending_buffer_complete_ = false; |
| - delegate_->OnPushBufferComplete(MediaPipelineBackendAlsa::kBufferSuccess); |
| - } |
| - delegate_->OnEndOfStream(); |
| - } else { |
| - task_runner_->PostTask(FROM_HERE, base::Bind(&AudioDecoderAlsa::PushMorePcm, |
| - weak_factory_.GetWeakPtr())); |
| - } |
| + task_runner_->PostTask(FROM_HERE, base::Bind(&AudioDecoderAlsa::PushMorePcm, |
| + weak_factory_.GetWeakPtr())); |
| } |
| void AudioDecoderAlsa::PushMorePcm() { |
| PushRateShifted(); |
| DCHECK(!rate_shifter_info_.empty()); |
| - if (pending_buffer_complete_) { |
| - double rate = rate_shifter_info_.front().rate; |
| - if ((rate == 1.0 && pending_output_frames_ == kNoPendingOutput) || |
| - (rate != 1.0 && !rate_shifter_->IsQueueFull())) { |
| - pending_buffer_complete_ = false; |
| - delegate_->OnPushBufferComplete(MediaPipelineBackendAlsa::kBufferSuccess); |
| - } |
| + CheckBufferComplete(); |
| + |
| + if (pushed_eos_) { |
| + delegate_->OnEndOfStream(); |
| } |
| } |