| 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
|
|
|