Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(45)

Unified Diff: media/renderers/audio_renderer_impl.cc

Issue 2536013002: Fix implicit channel layout configurations at non-1.0 playback rates. (Closed)
Patch Set: Created 4 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « media/renderers/audio_renderer_impl.h ('k') | media/renderers/audio_renderer_impl_unittest.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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
« no previous file with comments | « media/renderers/audio_renderer_impl.h ('k') | media/renderers/audio_renderer_impl_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698