Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "media/renderers/audio_renderer_impl.h" | 5 #include "media/renderers/audio_renderer_impl.h" |
| 6 | 6 |
| 7 #include <math.h> | 7 #include <math.h> |
| 8 #include <stddef.h> | 8 #include <stddef.h> |
| 9 #include <algorithm> | 9 #include <algorithm> |
| 10 #include <utility> | 10 #include <utility> |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 42 expecting_config_changes_(false), | 42 expecting_config_changes_(false), |
| 43 sink_(sink), | 43 sink_(sink), |
| 44 audio_buffer_stream_( | 44 audio_buffer_stream_( |
| 45 new AudioBufferStream(task_runner, std::move(decoders), media_log)), | 45 new AudioBufferStream(task_runner, std::move(decoders), media_log)), |
| 46 media_log_(media_log), | 46 media_log_(media_log), |
| 47 client_(nullptr), | 47 client_(nullptr), |
| 48 tick_clock_(new base::DefaultTickClock()), | 48 tick_clock_(new base::DefaultTickClock()), |
| 49 last_audio_memory_usage_(0), | 49 last_audio_memory_usage_(0), |
| 50 last_decoded_sample_rate_(0), | 50 last_decoded_sample_rate_(0), |
| 51 last_decoded_channel_layout_(CHANNEL_LAYOUT_NONE), | 51 last_decoded_channel_layout_(CHANNEL_LAYOUT_NONE), |
| 52 last_decoded_channels_(0), | |
| 52 playback_rate_(0.0), | 53 playback_rate_(0.0), |
| 53 state_(kUninitialized), | 54 state_(kUninitialized), |
| 54 buffering_state_(BUFFERING_HAVE_NOTHING), | 55 buffering_state_(BUFFERING_HAVE_NOTHING), |
| 55 rendering_(false), | 56 rendering_(false), |
| 56 sink_playing_(false), | 57 sink_playing_(false), |
| 57 pending_read_(false), | 58 pending_read_(false), |
| 58 received_end_of_stream_(false), | 59 received_end_of_stream_(false), |
| 59 rendered_end_of_stream_(false), | 60 rendered_end_of_stream_(false), |
| 60 is_suspending_(false), | 61 is_suspending_(false), |
| 61 weak_factory_(this) { | 62 weak_factory_(this) { |
| (...skipping 292 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 354 // parameters if possible since it affects the initial buffer size used by | 355 // parameters if possible since it affects the initial buffer size used by |
| 355 // the algorithm. Too little will cause underflow on Bluetooth devices. | 356 // the algorithm. Too little will cause underflow on Bluetooth devices. |
| 356 int buffer_size = | 357 int buffer_size = |
| 357 std::max(stream->audio_decoder_config().samples_per_second() / 100, | 358 std::max(stream->audio_decoder_config().samples_per_second() / 100, |
| 358 hw_params.IsValid() ? hw_params.frames_per_buffer() : 0); | 359 hw_params.IsValid() ? hw_params.frames_per_buffer() : 0); |
| 359 audio_parameters_.Reset(AudioParameters::AUDIO_PCM_LOW_LATENCY, | 360 audio_parameters_.Reset(AudioParameters::AUDIO_PCM_LOW_LATENCY, |
| 360 stream->audio_decoder_config().channel_layout(), | 361 stream->audio_decoder_config().channel_layout(), |
| 361 stream->audio_decoder_config().samples_per_second(), | 362 stream->audio_decoder_config().samples_per_second(), |
| 362 stream->audio_decoder_config().bits_per_channel(), | 363 stream->audio_decoder_config().bits_per_channel(), |
| 363 buffer_size); | 364 buffer_size); |
| 365 audio_parameters_.set_channels_for_discrete(stream->audio_decoder_config().c hannels()); | |
| 364 buffer_converter_.reset(); | 366 buffer_converter_.reset(); |
| 365 } else { | 367 } else { |
| 366 // To allow for seamless sample rate adaptations (i.e. changes from say | 368 // To allow for seamless sample rate adaptations (i.e. changes from say |
| 367 // 16kHz to 48kHz), always resample to the hardware rate. | 369 // 16kHz to 48kHz), always resample to the hardware rate. |
| 368 int sample_rate = hw_params.sample_rate(); | 370 int sample_rate = hw_params.sample_rate(); |
| 369 int preferred_buffer_size = hw_params.frames_per_buffer(); | 371 int preferred_buffer_size = hw_params.frames_per_buffer(); |
| 370 | 372 |
| 371 #if defined(OS_CHROMEOS) | 373 #if defined(OS_CHROMEOS) |
| 372 // On ChromeOS let the OS level resampler handle resampling unless the | 374 // On ChromeOS let the OS level resampler handle resampling unless the |
| 373 // initial sample rate is too low; this allows support for sample rate | 375 // initial sample rate is too low; this allows support for sample rate |
| 374 // adaptations where necessary. | 376 // adaptations where necessary. |
| 375 if (stream->audio_decoder_config().samples_per_second() >= 44100) { | 377 if (stream->audio_decoder_config().samples_per_second() >= 44100) { |
| 376 sample_rate = stream->audio_decoder_config().samples_per_second(); | 378 sample_rate = stream->audio_decoder_config().samples_per_second(); |
| 377 preferred_buffer_size = 0; // No preference. | 379 preferred_buffer_size = 0; // No preference. |
| 378 } | 380 } |
| 379 #endif | 381 #endif |
| 380 | 382 |
| 381 int stream_channel_count = ChannelLayoutToChannelCount( | 383 int stream_channel_count = stream->audio_decoder_config().channels(); |
| 382 stream->audio_decoder_config().channel_layout()); | |
| 383 | 384 |
| 384 bool try_supported_channel_layouts = false; | 385 bool try_supported_channel_layouts = false; |
| 385 #if defined(OS_WIN) | 386 #if defined(OS_WIN) |
| 386 try_supported_channel_layouts = | 387 try_supported_channel_layouts = |
| 387 base::CommandLine::ForCurrentProcess()->HasSwitch( | 388 base::CommandLine::ForCurrentProcess()->HasSwitch( |
| 388 switches::kTrySupportedChannelLayouts); | 389 switches::kTrySupportedChannelLayouts); |
| 389 #endif | 390 #endif |
| 390 | 391 |
| 391 // We don't know how to up-mix for DISCRETE layouts (fancy multichannel | 392 // We don't know how to up-mix for DISCRETE layouts (fancy multichannel |
| 392 // hardware with non-standard speaker arrangement). Instead, pretend the | 393 // hardware with non-standard speaker arrangement). Instead, pretend the |
| (...skipping 19 matching lines...) Expand all Loading... | |
| 412 // premature down-mixing - http://crbug.com/379288). | 413 // premature down-mixing - http://crbug.com/379288). |
| 413 // If stream_channels < hw_channels: | 414 // If stream_channels < hw_channels: |
| 414 // Taking max means we up-mix to hardware layout. If stream later changes | 415 // Taking max means we up-mix to hardware layout. If stream later changes |
| 415 // to have more channels, we aren't locked into down-mixing to the | 416 // to have more channels, we aren't locked into down-mixing to the |
| 416 // initial stream layout. | 417 // initial stream layout. |
| 417 // If stream_channels > hw_channels: | 418 // If stream_channels > hw_channels: |
| 418 // We choose to output stream's layout, meaning mixing is a no-op for the | 419 // We choose to output stream's layout, meaning mixing is a no-op for the |
| 419 // renderer. Browser-side will down-mix to the hardware config. If the | 420 // renderer. Browser-side will down-mix to the hardware config. If the |
| 420 // hardware later changes to equal stream channels, browser-side will stop | 421 // hardware later changes to equal stream channels, browser-side will stop |
| 421 // down-mixing and use the data from all stream channels. | 422 // down-mixing and use the data from all stream channels. |
| 423 bool use_hw_config = hw_channel_count > stream_channel_count; | |
| 422 ChannelLayout renderer_channel_layout = | 424 ChannelLayout renderer_channel_layout = |
| 423 hw_channel_count > stream_channel_count | 425 use_hw_config ? hw_channel_layout |
| 424 ? hw_channel_layout | 426 : stream->audio_decoder_config().channel_layout(); |
| 425 : stream->audio_decoder_config().channel_layout(); | |
| 426 | 427 |
| 427 audio_parameters_.Reset(hw_params.format(), renderer_channel_layout, | 428 audio_parameters_.Reset(hw_params.format(), renderer_channel_layout, |
| 428 sample_rate, hw_params.bits_per_sample(), | 429 sample_rate, hw_params.bits_per_sample(), |
| 429 media::AudioLatency::GetHighLatencyBufferSize( | 430 media::AudioLatency::GetHighLatencyBufferSize( |
| 430 sample_rate, preferred_buffer_size)); | 431 sample_rate, preferred_buffer_size)); |
| 432 if (!use_hw_config) | |
| 433 audio_parameters_.set_channels_for_discrete(stream_channel_count); | |
| 431 } | 434 } |
| 432 | 435 |
| 433 last_decoded_channel_layout_ = | 436 last_decoded_channel_layout_ = |
| 434 stream->audio_decoder_config().channel_layout(); | 437 stream->audio_decoder_config().channel_layout(); |
| 435 | 438 |
| 439 last_decoded_channels_ = | |
| 440 stream->audio_decoder_config().channels(); | |
| 441 | |
| 436 audio_clock_.reset( | 442 audio_clock_.reset( |
| 437 new AudioClock(base::TimeDelta(), audio_parameters_.sample_rate())); | 443 new AudioClock(base::TimeDelta(), audio_parameters_.sample_rate())); |
| 438 | 444 |
| 439 audio_buffer_stream_->Initialize( | 445 audio_buffer_stream_->Initialize( |
| 440 stream, base::Bind(&AudioRendererImpl::OnAudioBufferStreamInitialized, | 446 stream, base::Bind(&AudioRendererImpl::OnAudioBufferStreamInitialized, |
| 441 weak_factory_.GetWeakPtr()), | 447 weak_factory_.GetWeakPtr()), |
| 442 cdm_context, base::Bind(&AudioRendererImpl::OnStatisticsUpdate, | 448 cdm_context, base::Bind(&AudioRendererImpl::OnStatisticsUpdate, |
| 443 weak_factory_.GetWeakPtr()), | 449 weak_factory_.GetWeakPtr()), |
| 444 base::Bind(&AudioRendererImpl::OnWaitingForDecryptionKey, | 450 base::Bind(&AudioRendererImpl::OnWaitingForDecryptionKey, |
| 445 weak_factory_.GetWeakPtr())); | 451 weak_factory_.GetWeakPtr())); |
| (...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 573 DVLOG(1) << __func__ << " Updating audio sample_rate." | 579 DVLOG(1) << __func__ << " Updating audio sample_rate." |
| 574 << " ts:" << buffer->timestamp().InMicroseconds() | 580 << " ts:" << buffer->timestamp().InMicroseconds() |
| 575 << " old:" << last_decoded_sample_rate_ | 581 << " old:" << last_decoded_sample_rate_ |
| 576 << " new:" << buffer->sample_rate(); | 582 << " new:" << buffer->sample_rate(); |
| 577 OnConfigChange(); | 583 OnConfigChange(); |
| 578 } | 584 } |
| 579 last_decoded_sample_rate_ = buffer->sample_rate(); | 585 last_decoded_sample_rate_ = buffer->sample_rate(); |
| 580 | 586 |
| 581 if (last_decoded_channel_layout_ != buffer->channel_layout()) { | 587 if (last_decoded_channel_layout_ != buffer->channel_layout()) { |
| 582 last_decoded_channel_layout_ = buffer->channel_layout(); | 588 last_decoded_channel_layout_ = buffer->channel_layout(); |
| 589 last_decoded_channels_ = buffer->channel_count(); | |
| 583 | 590 |
| 584 // Input layouts should never be discrete. | 591 // Input layouts should never be discrete. |
| 585 DCHECK_NE(last_decoded_channel_layout_, CHANNEL_LAYOUT_DISCRETE); | 592 DCHECK_NE(last_decoded_channel_layout_, CHANNEL_LAYOUT_DISCRETE); |
| 586 ConfigureChannelMask(); | 593 ConfigureChannelMask(); |
| 587 } | 594 } |
| 588 } | 595 } |
| 589 | 596 |
| 590 DCHECK(buffer_converter_); | 597 DCHECK(buffer_converter_); |
| 591 buffer_converter_->AddInput(buffer); | 598 buffer_converter_->AddInput(buffer); |
| 592 | 599 |
| (...skipping 365 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 958 task_runner_->PostTask( | 965 task_runner_->PostTask( |
| 959 FROM_HERE, base::Bind(&AudioRendererImpl::OnBufferingStateChange, | 966 FROM_HERE, base::Bind(&AudioRendererImpl::OnBufferingStateChange, |
| 960 weak_factory_.GetWeakPtr(), buffering_state_)); | 967 weak_factory_.GetWeakPtr(), buffering_state_)); |
| 961 } | 968 } |
| 962 | 969 |
| 963 void AudioRendererImpl::ConfigureChannelMask() { | 970 void AudioRendererImpl::ConfigureChannelMask() { |
| 964 DCHECK(algorithm_); | 971 DCHECK(algorithm_); |
| 965 DCHECK(audio_parameters_.IsValid()); | 972 DCHECK(audio_parameters_.IsValid()); |
| 966 DCHECK_NE(last_decoded_channel_layout_, CHANNEL_LAYOUT_NONE); | 973 DCHECK_NE(last_decoded_channel_layout_, CHANNEL_LAYOUT_NONE); |
| 967 DCHECK_NE(last_decoded_channel_layout_, CHANNEL_LAYOUT_UNSUPPORTED); | 974 DCHECK_NE(last_decoded_channel_layout_, CHANNEL_LAYOUT_UNSUPPORTED); |
| 968 DCHECK_NE(last_decoded_channel_layout_, CHANNEL_LAYOUT_DISCRETE); | |
| 969 | 975 |
| 970 const int input_channel_count = | 976 const int input_channel_count = |
|
DaleCurtis
2017/03/20 17:38:58
Just always use last_decoded_channels_ ?
flim-chromium
2017/03/22 06:20:51
Done.
| |
| 971 ChannelLayoutToChannelCount(last_decoded_channel_layout_); | 977 last_decoded_channel_layout_ == CHANNEL_LAYOUT_DISCRETE |
| 978 ? last_decoded_channels_ | |
| 979 : ChannelLayoutToChannelCount(last_decoded_channel_layout_); | |
| 972 | 980 |
| 973 // If we're actually downmixing the signal, no mask is necessary, but ensure | 981 // If we're actually downmixing the signal, no mask is necessary, but ensure |
| 974 // we clear any existing mask if present. | 982 // we clear any existing mask if present. |
| 975 if (input_channel_count >= audio_parameters_.channels()) { | 983 if (input_channel_count >= audio_parameters_.channels()) { |
| 976 algorithm_->SetChannelMask( | 984 algorithm_->SetChannelMask( |
| 977 std::vector<bool>(audio_parameters_.channels(), true)); | 985 std::vector<bool>(audio_parameters_.channels(), true)); |
| 978 return; | 986 return; |
| 979 } | 987 } |
| 980 | 988 |
| 981 // Determine the matrix used to upmix the channels. | 989 // Determine the matrix used to upmix the channels. |
| 982 std::vector<std::vector<float>> matrix; | 990 std::vector<std::vector<float>> matrix; |
| 983 ChannelMixingMatrix(last_decoded_channel_layout_, input_channel_count, | 991 ChannelMixingMatrix(last_decoded_channel_layout_, input_channel_count, |
| 984 audio_parameters_.channel_layout(), | 992 audio_parameters_.channel_layout(), |
| 985 audio_parameters_.channels()) | 993 audio_parameters_.channels()) |
| 986 .CreateTransformationMatrix(&matrix); | 994 .CreateTransformationMatrix(&matrix); |
| 987 | 995 |
| 988 // All channels with a zero mix are muted and can be ignored. | 996 // All channels with a zero mix are muted and can be ignored. |
| 989 std::vector<bool> channel_mask(audio_parameters_.channels(), false); | 997 std::vector<bool> channel_mask(audio_parameters_.channels(), false); |
| 990 for (size_t ch = 0; ch < matrix.size(); ++ch) { | 998 for (size_t ch = 0; ch < matrix.size(); ++ch) { |
| 991 channel_mask[ch] = std::any_of(matrix[ch].begin(), matrix[ch].end(), | 999 channel_mask[ch] = std::any_of(matrix[ch].begin(), matrix[ch].end(), |
| 992 [](float mix) { return !!mix; }); | 1000 [](float mix) { return !!mix; }); |
| 993 } | 1001 } |
| 994 algorithm_->SetChannelMask(std::move(channel_mask)); | 1002 algorithm_->SetChannelMask(std::move(channel_mask)); |
| 995 } | 1003 } |
| 996 | 1004 |
| 997 } // namespace media | 1005 } // namespace media |
| OLD | NEW |