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 a83d6a45a13caf64f0f5db535da7c40304d055c0..e288cc5ebba93dcfdc66851dbec7947fbec5e881 100644 |
--- a/chromecast/media/cma/backend/alsa/audio_decoder_alsa.cc |
+++ b/chromecast/media/cma/backend/alsa/audio_decoder_alsa.cc |
@@ -153,10 +153,18 @@ bool AudioDecoderAlsa::SetPlaybackRate(float rate) { |
} |
LOG(INFO) << "SetPlaybackRate to " << rate; |
- while (!rate_shifter_info_.empty() && |
- rate_shifter_info_.back().input_frames == 0) { |
- rate_shifter_info_.pop_back(); |
+ // Remove info for rates that have no pending output left. |
+ while (!rate_shifter_info_.empty()) { |
+ RateShifterInfo* rate_info = &rate_shifter_info_.back(); |
+ int64_t possible_output_frames = rate_info->input_frames / rate_info->rate; |
+ DCHECK_GE(possible_output_frames, rate_info->output_frames); |
+ if (rate_info->output_frames == possible_output_frames) { |
+ rate_shifter_info_.pop_back(); |
+ } else { |
+ break; |
+ } |
} |
+ |
rate_shifter_info_.push_back(RateShifterInfo(rate)); |
return true; |
} |
@@ -351,7 +359,8 @@ void AudioDecoderAlsa::OnBufferDecoded( |
// Bypass rate shifter if the rate is 1.0, and there are no frames queued |
// in the rate shifter. |
if (rate_info->rate == 1.0 && rate_shifter_->frames_buffered() == 0 && |
- pending_output_frames_ == kNoPendingOutput) { |
+ pending_output_frames_ == kNoPendingOutput && |
+ rate_shifter_info_.size() == 1) { |
DCHECK_EQ(rate_info->output_frames, rate_info->input_frames); |
pending_output_frames_ = input_frames; |
if (got_eos_) { |
@@ -463,7 +472,7 @@ void AudioDecoderAlsa::PushRateShifted() { |
mixer_input_->WritePcm(output_buffer); |
if (rate_shifter_info_.size() > 1 && |
- possible_output_frames == rate_info->output_frames) { |
+ rate_info->output_frames == possible_output_frames) { |
double remaining_input_frames = |
rate_info->input_frames - (rate_info->output_frames * rate_info->rate); |
rate_shifter_info_.pop_front(); |