Index: media/renderers/audio_renderer_impl.cc |
diff --git a/media/renderers/audio_renderer_impl.cc b/media/renderers/audio_renderer_impl.cc |
index 98ad2816324e92568b18670ffd418be73d3627be..b7c45ddafe473c01b010afabdae38878f04324a3 100644 |
--- a/media/renderers/audio_renderer_impl.cc |
+++ b/media/renderers/audio_renderer_impl.cc |
@@ -48,6 +48,7 @@ AudioRendererImpl::AudioRendererImpl( |
tick_clock_(new base::DefaultTickClock()), |
last_audio_memory_usage_(0), |
last_decoded_sample_rate_(0), |
+ last_decoded_channel_layout_(CHANNEL_LAYOUT_NONE), |
playback_rate_(0.0), |
state_(kUninitialized), |
buffering_state_(BUFFERING_HAVE_NOTHING), |
@@ -427,25 +428,11 @@ void AudioRendererImpl::Initialize(DemuxerStream* stream, |
sample_rate, hw_params.bits_per_sample(), |
media::AudioLatency::GetHighLatencyBufferSize( |
sample_rate, preferred_buffer_size)); |
- |
- // Figure out if there are muted channels that we should ignore when |
- // playback rate adapatation is requested (it's expensive). |
- if (stream_channel_count < audio_parameters_.channels()) { |
- std::vector<std::vector<float>> matrix; |
- ChannelMixingMatrix( |
- stream->audio_decoder_config().channel_layout(), stream_channel_count, |
- audio_parameters_.channel_layout(), audio_parameters_.channels()) |
- .CreateTransformationMatrix(&matrix); |
- |
- // All channels with a zero mix are muted and can be ignored. |
- channel_mask_ = std::vector<bool>(audio_parameters_.channels(), false); |
- for (size_t ch = 0; ch < matrix.size(); ++ch) { |
- channel_mask_[ch] = std::any_of(matrix[ch].begin(), matrix[ch].end(), |
- [](float mix) { return !!mix; }); |
- } |
- } |
} |
+ last_decoded_channel_layout_ = |
+ stream->audio_decoder_config().channel_layout(); |
+ |
audio_clock_.reset( |
new AudioClock(base::TimeDelta(), audio_parameters_.sample_rate())); |
@@ -484,7 +471,8 @@ void AudioRendererImpl::OnAudioBufferStreamInitialized(bool success) { |
// We're all good! Continue initializing the rest of the audio renderer |
// based on the decoder format. |
algorithm_.reset(new AudioRendererAlgorithm()); |
- algorithm_->Initialize(audio_parameters_, channel_mask_); |
+ algorithm_->Initialize(audio_parameters_); |
+ ConfigureChannelMask(); |
ChangeState_Locked(kFlushed); |
@@ -577,15 +565,25 @@ void AudioRendererImpl::DecodedAudioReady( |
bool need_another_buffer = true; |
if (expecting_config_changes_) { |
- if (last_decoded_sample_rate_ && |
- buffer->sample_rate() != last_decoded_sample_rate_) { |
- DVLOG(1) << __func__ << " Updating audio sample_rate." |
- << " ts:" << buffer->timestamp().InMicroseconds() |
- << " old:" << last_decoded_sample_rate_ |
- << " new:" << buffer->sample_rate(); |
- OnConfigChange(); |
+ if (!buffer->end_of_stream()) { |
+ if (last_decoded_sample_rate_ && |
+ buffer->sample_rate() != last_decoded_sample_rate_) { |
+ DVLOG(1) << __func__ << " Updating audio sample_rate." |
+ << " ts:" << buffer->timestamp().InMicroseconds() |
+ << " old:" << last_decoded_sample_rate_ |
+ << " new:" << buffer->sample_rate(); |
+ OnConfigChange(); |
+ } |
+ last_decoded_sample_rate_ = buffer->sample_rate(); |
+ |
+ if (last_decoded_channel_layout_ != buffer->channel_layout()) { |
+ last_decoded_channel_layout_ = buffer->channel_layout(); |
+ |
+ // Input layouts should never be discrete. |
+ DCHECK_NE(last_decoded_channel_layout_, CHANNEL_LAYOUT_DISCRETE); |
+ ConfigureChannelMask(); |
+ } |
} |
- last_decoded_sample_rate_ = buffer->sample_rate(); |
DCHECK(buffer_converter_); |
buffer_converter_->AddInput(buffer); |
@@ -956,4 +954,38 @@ void AudioRendererImpl::SetBufferingState_Locked( |
weak_factory_.GetWeakPtr(), buffering_state_)); |
} |
+void AudioRendererImpl::ConfigureChannelMask() { |
+ DCHECK(algorithm_); |
+ DCHECK(audio_parameters_.IsValid()); |
+ DCHECK_NE(last_decoded_channel_layout_, CHANNEL_LAYOUT_NONE); |
+ DCHECK_NE(last_decoded_channel_layout_, CHANNEL_LAYOUT_UNSUPPORTED); |
+ DCHECK_NE(last_decoded_channel_layout_, CHANNEL_LAYOUT_DISCRETE); |
+ |
+ const int input_channel_count = |
+ ChannelLayoutToChannelCount(last_decoded_channel_layout_); |
+ |
+ // If we're actually downmixing the signal, no mask is necessary, but ensure |
+ // we clear any existing mask if present. |
+ if (input_channel_count >= audio_parameters_.channels()) { |
+ algorithm_->SetChannelMask( |
+ std::vector<bool>(audio_parameters_.channels(), true)); |
+ return; |
+ } |
+ |
+ // Determine the matrix used to upmix the channels. |
+ std::vector<std::vector<float>> matrix; |
+ ChannelMixingMatrix(last_decoded_channel_layout_, input_channel_count, |
+ audio_parameters_.channel_layout(), |
+ audio_parameters_.channels()) |
+ .CreateTransformationMatrix(&matrix); |
+ |
+ // All channels with a zero mix are muted and can be ignored. |
+ std::vector<bool> channel_mask(audio_parameters_.channels(), false); |
+ for (size_t ch = 0; ch < matrix.size(); ++ch) { |
+ channel_mask[ch] = std::any_of(matrix[ch].begin(), matrix[ch].end(), |
+ [](float mix) { return !!mix; }); |
+ } |
+ algorithm_->SetChannelMask(std::move(channel_mask)); |
+} |
+ |
} // namespace media |