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 30 matching lines...) Expand all Loading... | |
| 41 : task_runner_(task_runner), | 41 : task_runner_(task_runner), |
| 42 expecting_config_changes_(false), | 42 expecting_config_changes_(false), |
| 43 sink_(sink), | 43 sink_(sink), |
| 44 media_log_(media_log), | 44 media_log_(media_log), |
| 45 client_(nullptr), | 45 client_(nullptr), |
| 46 tick_clock_(new base::DefaultTickClock()), | 46 tick_clock_(new base::DefaultTickClock()), |
| 47 last_audio_memory_usage_(0), | 47 last_audio_memory_usage_(0), |
| 48 last_decoded_sample_rate_(0), | 48 last_decoded_sample_rate_(0), |
| 49 last_decoded_channel_layout_(CHANNEL_LAYOUT_NONE), | 49 last_decoded_channel_layout_(CHANNEL_LAYOUT_NONE), |
| 50 is_encrypted_(false), | 50 is_encrypted_(false), |
| 51 last_decoded_channels_(0), | |
| 51 playback_rate_(0.0), | 52 playback_rate_(0.0), |
| 52 state_(kUninitialized), | 53 state_(kUninitialized), |
| 53 create_audio_decoders_cb_(create_audio_decoders_cb), | 54 create_audio_decoders_cb_(create_audio_decoders_cb), |
| 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), |
| (...skipping 301 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 362 audio_buffer_stream_->set_config_change_observer(base::Bind( | 363 audio_buffer_stream_->set_config_change_observer(base::Bind( |
| 363 &AudioRendererImpl::OnConfigChange, weak_factory_.GetWeakPtr())); | 364 &AudioRendererImpl::OnConfigChange, weak_factory_.GetWeakPtr())); |
| 364 | 365 |
| 365 // Always post |init_cb_| because |this| could be destroyed if initialization | 366 // Always post |init_cb_| because |this| could be destroyed if initialization |
| 366 // failed. | 367 // failed. |
| 367 init_cb_ = BindToCurrentLoop(init_cb); | 368 init_cb_ = BindToCurrentLoop(init_cb); |
| 368 | 369 |
| 369 auto output_device_info = sink_->GetOutputDeviceInfo(); | 370 auto output_device_info = sink_->GetOutputDeviceInfo(); |
| 370 const AudioParameters& hw_params = output_device_info.output_params(); | 371 const AudioParameters& hw_params = output_device_info.output_params(); |
| 371 expecting_config_changes_ = stream->SupportsConfigChanges(); | 372 expecting_config_changes_ = stream->SupportsConfigChanges(); |
| 372 if (!expecting_config_changes_ || !hw_params.IsValid() || | 373 |
| 373 hw_params.format() == AudioParameters::AUDIO_FAKE || | 374 bool use_stream_params = !expecting_config_changes_ || !hw_params.IsValid() || |
| 374 !sink_->IsOptimizedForHardwareParameters()) { | 375 hw_params.format() == AudioParameters::AUDIO_FAKE || |
| 376 !sink_->IsOptimizedForHardwareParameters(); | |
| 377 | |
| 378 if (stream->audio_decoder_config().channel_layout() == | |
|
DaleCurtis
2017/05/25 00:29:16
Why do we need this? I think what you had before i
flim-chromium
2017/05/25 00:46:06
Yep, that's still there in line 376. But if webaud
DaleCurtis
2017/05/25 00:53:38
Seems like you could just drop this and always cal
flim-chromium
2017/05/25 02:16:41
We'd have to set the channels in AudioRendererMixe
DaleCurtis
2017/05/25 18:51:01
Hmm, I was proposing a simplified logic, but after
flim-chromium
2017/05/25 22:00:40
Done.
| |
| 379 CHANNEL_LAYOUT_DISCRETE && | |
| 380 sink_->IsOptimizedForHardwareParameters()) | |
| 381 use_stream_params = false; | |
| 382 | |
| 383 if (use_stream_params) { | |
| 375 // The actual buffer size is controlled via the size of the AudioBus | 384 // The actual buffer size is controlled via the size of the AudioBus |
| 376 // provided to Render(), but we should choose a value here based on hardware | 385 // provided to Render(), but we should choose a value here based on hardware |
| 377 // parameters if possible since it affects the initial buffer size used by | 386 // parameters if possible since it affects the initial buffer size used by |
| 378 // the algorithm. Too little will cause underflow on Bluetooth devices. | 387 // the algorithm. Too little will cause underflow on Bluetooth devices. |
| 379 int buffer_size = | 388 int buffer_size = |
| 380 std::max(stream->audio_decoder_config().samples_per_second() / 100, | 389 std::max(stream->audio_decoder_config().samples_per_second() / 100, |
| 381 hw_params.IsValid() ? hw_params.frames_per_buffer() : 0); | 390 hw_params.IsValid() ? hw_params.frames_per_buffer() : 0); |
| 382 audio_parameters_.Reset(AudioParameters::AUDIO_PCM_LOW_LATENCY, | 391 audio_parameters_.Reset(AudioParameters::AUDIO_PCM_LOW_LATENCY, |
| 383 stream->audio_decoder_config().channel_layout(), | 392 stream->audio_decoder_config().channel_layout(), |
| 384 stream->audio_decoder_config().samples_per_second(), | 393 stream->audio_decoder_config().samples_per_second(), |
| 385 stream->audio_decoder_config().bits_per_channel(), | 394 stream->audio_decoder_config().bits_per_channel(), |
| 386 buffer_size); | 395 buffer_size); |
| 396 audio_parameters_.set_channels_for_discrete( | |
| 397 stream->audio_decoder_config().channels()); | |
| 387 buffer_converter_.reset(); | 398 buffer_converter_.reset(); |
| 388 } else { | 399 } else { |
| 389 // To allow for seamless sample rate adaptations (i.e. changes from say | 400 // To allow for seamless sample rate adaptations (i.e. changes from say |
| 390 // 16kHz to 48kHz), always resample to the hardware rate. | 401 // 16kHz to 48kHz), always resample to the hardware rate. |
| 391 int sample_rate = hw_params.sample_rate(); | 402 int sample_rate = hw_params.sample_rate(); |
| 392 int preferred_buffer_size = hw_params.frames_per_buffer(); | 403 int preferred_buffer_size = hw_params.frames_per_buffer(); |
| 393 | 404 |
| 394 #if defined(OS_CHROMEOS) | 405 #if defined(OS_CHROMEOS) |
| 395 // On ChromeOS let the OS level resampler handle resampling unless the | 406 // On ChromeOS let the OS level resampler handle resampling unless the |
| 396 // initial sample rate is too low; this allows support for sample rate | 407 // initial sample rate is too low; this allows support for sample rate |
| 397 // adaptations where necessary. | 408 // adaptations where necessary. |
| 398 if (stream->audio_decoder_config().samples_per_second() >= 44100) { | 409 if (stream->audio_decoder_config().samples_per_second() >= 44100) { |
| 399 sample_rate = stream->audio_decoder_config().samples_per_second(); | 410 sample_rate = stream->audio_decoder_config().samples_per_second(); |
| 400 preferred_buffer_size = 0; // No preference. | 411 preferred_buffer_size = 0; // No preference. |
| 401 } | 412 } |
| 402 #endif | 413 #endif |
| 403 | 414 |
| 404 int stream_channel_count = ChannelLayoutToChannelCount( | 415 int stream_channel_count = stream->audio_decoder_config().channels(); |
| 405 stream->audio_decoder_config().channel_layout()); | |
| 406 | 416 |
| 407 bool try_supported_channel_layouts = false; | 417 bool try_supported_channel_layouts = false; |
| 408 #if defined(OS_WIN) | 418 #if defined(OS_WIN) |
| 409 try_supported_channel_layouts = | 419 try_supported_channel_layouts = |
| 410 base::CommandLine::ForCurrentProcess()->HasSwitch( | 420 base::CommandLine::ForCurrentProcess()->HasSwitch( |
| 411 switches::kTrySupportedChannelLayouts); | 421 switches::kTrySupportedChannelLayouts); |
| 412 #endif | 422 #endif |
| 413 | 423 |
| 414 // We don't know how to up-mix for DISCRETE layouts (fancy multichannel | 424 // We don't know how to up-mix for DISCRETE layouts (fancy multichannel |
| 415 // hardware with non-standard speaker arrangement). Instead, pretend the | 425 // hardware with non-standard speaker arrangement). Instead, pretend the |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 451 sample_rate, hw_params.bits_per_sample(), | 461 sample_rate, hw_params.bits_per_sample(), |
| 452 media::AudioLatency::GetHighLatencyBufferSize( | 462 media::AudioLatency::GetHighLatencyBufferSize( |
| 453 sample_rate, preferred_buffer_size)); | 463 sample_rate, preferred_buffer_size)); |
| 454 } | 464 } |
| 455 | 465 |
| 456 last_decoded_channel_layout_ = | 466 last_decoded_channel_layout_ = |
| 457 stream->audio_decoder_config().channel_layout(); | 467 stream->audio_decoder_config().channel_layout(); |
| 458 | 468 |
| 459 is_encrypted_ = stream->audio_decoder_config().is_encrypted(); | 469 is_encrypted_ = stream->audio_decoder_config().is_encrypted(); |
| 460 | 470 |
| 471 last_decoded_channels_ = stream->audio_decoder_config().channels(); | |
| 472 | |
| 461 audio_clock_.reset( | 473 audio_clock_.reset( |
| 462 new AudioClock(base::TimeDelta(), audio_parameters_.sample_rate())); | 474 new AudioClock(base::TimeDelta(), audio_parameters_.sample_rate())); |
| 463 | 475 |
| 464 audio_buffer_stream_->Initialize( | 476 audio_buffer_stream_->Initialize( |
| 465 stream, base::Bind(&AudioRendererImpl::OnAudioBufferStreamInitialized, | 477 stream, base::Bind(&AudioRendererImpl::OnAudioBufferStreamInitialized, |
| 466 weak_factory_.GetWeakPtr()), | 478 weak_factory_.GetWeakPtr()), |
| 467 cdm_context, base::Bind(&AudioRendererImpl::OnStatisticsUpdate, | 479 cdm_context, base::Bind(&AudioRendererImpl::OnStatisticsUpdate, |
| 468 weak_factory_.GetWeakPtr()), | 480 weak_factory_.GetWeakPtr()), |
| 469 base::Bind(&AudioRendererImpl::OnWaitingForDecryptionKey, | 481 base::Bind(&AudioRendererImpl::OnWaitingForDecryptionKey, |
| 470 weak_factory_.GetWeakPtr())); | 482 weak_factory_.GetWeakPtr())); |
| (...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 598 DVLOG(1) << __func__ << " Updating audio sample_rate." | 610 DVLOG(1) << __func__ << " Updating audio sample_rate." |
| 599 << " ts:" << buffer->timestamp().InMicroseconds() | 611 << " ts:" << buffer->timestamp().InMicroseconds() |
| 600 << " old:" << last_decoded_sample_rate_ | 612 << " old:" << last_decoded_sample_rate_ |
| 601 << " new:" << buffer->sample_rate(); | 613 << " new:" << buffer->sample_rate(); |
| 602 OnConfigChange(); | 614 OnConfigChange(); |
| 603 } | 615 } |
| 604 last_decoded_sample_rate_ = buffer->sample_rate(); | 616 last_decoded_sample_rate_ = buffer->sample_rate(); |
| 605 | 617 |
| 606 if (last_decoded_channel_layout_ != buffer->channel_layout()) { | 618 if (last_decoded_channel_layout_ != buffer->channel_layout()) { |
| 607 last_decoded_channel_layout_ = buffer->channel_layout(); | 619 last_decoded_channel_layout_ = buffer->channel_layout(); |
| 620 last_decoded_channels_ = buffer->channel_count(); | |
| 608 | 621 |
| 609 // Input layouts should never be discrete. | 622 // Input layouts should never be discrete. |
| 610 DCHECK_NE(last_decoded_channel_layout_, CHANNEL_LAYOUT_DISCRETE); | 623 DCHECK_NE(last_decoded_channel_layout_, CHANNEL_LAYOUT_DISCRETE); |
| 611 ConfigureChannelMask(); | 624 ConfigureChannelMask(); |
| 612 } | 625 } |
| 613 } | 626 } |
| 614 | 627 |
| 615 DCHECK(buffer_converter_); | 628 DCHECK(buffer_converter_); |
| 616 buffer_converter_->AddInput(buffer); | 629 buffer_converter_->AddInput(buffer); |
| 617 | 630 |
| (...skipping 365 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 983 task_runner_->PostTask( | 996 task_runner_->PostTask( |
| 984 FROM_HERE, base::Bind(&AudioRendererImpl::OnBufferingStateChange, | 997 FROM_HERE, base::Bind(&AudioRendererImpl::OnBufferingStateChange, |
| 985 weak_factory_.GetWeakPtr(), buffering_state_)); | 998 weak_factory_.GetWeakPtr(), buffering_state_)); |
| 986 } | 999 } |
| 987 | 1000 |
| 988 void AudioRendererImpl::ConfigureChannelMask() { | 1001 void AudioRendererImpl::ConfigureChannelMask() { |
| 989 DCHECK(algorithm_); | 1002 DCHECK(algorithm_); |
| 990 DCHECK(audio_parameters_.IsValid()); | 1003 DCHECK(audio_parameters_.IsValid()); |
| 991 DCHECK_NE(last_decoded_channel_layout_, CHANNEL_LAYOUT_NONE); | 1004 DCHECK_NE(last_decoded_channel_layout_, CHANNEL_LAYOUT_NONE); |
| 992 DCHECK_NE(last_decoded_channel_layout_, CHANNEL_LAYOUT_UNSUPPORTED); | 1005 DCHECK_NE(last_decoded_channel_layout_, CHANNEL_LAYOUT_UNSUPPORTED); |
| 993 DCHECK_NE(last_decoded_channel_layout_, CHANNEL_LAYOUT_DISCRETE); | |
| 994 | |
| 995 const int input_channel_count = | |
| 996 ChannelLayoutToChannelCount(last_decoded_channel_layout_); | |
| 997 | 1006 |
| 998 // If we're actually downmixing the signal, no mask is necessary, but ensure | 1007 // If we're actually downmixing the signal, no mask is necessary, but ensure |
| 999 // we clear any existing mask if present. | 1008 // we clear any existing mask if present. |
| 1000 if (input_channel_count >= audio_parameters_.channels()) { | 1009 if (last_decoded_channels_ >= audio_parameters_.channels()) { |
| 1001 algorithm_->SetChannelMask( | 1010 algorithm_->SetChannelMask( |
| 1002 std::vector<bool>(audio_parameters_.channels(), true)); | 1011 std::vector<bool>(audio_parameters_.channels(), true)); |
| 1003 return; | 1012 return; |
| 1004 } | 1013 } |
| 1005 | 1014 |
| 1006 // Determine the matrix used to upmix the channels. | 1015 // Determine the matrix used to upmix the channels. |
| 1007 std::vector<std::vector<float>> matrix; | 1016 std::vector<std::vector<float>> matrix; |
| 1008 ChannelMixingMatrix(last_decoded_channel_layout_, input_channel_count, | 1017 ChannelMixingMatrix(last_decoded_channel_layout_, last_decoded_channels_, |
| 1009 audio_parameters_.channel_layout(), | 1018 audio_parameters_.channel_layout(), |
| 1010 audio_parameters_.channels()) | 1019 audio_parameters_.channels()) |
| 1011 .CreateTransformationMatrix(&matrix); | 1020 .CreateTransformationMatrix(&matrix); |
| 1012 | 1021 |
| 1013 // All channels with a zero mix are muted and can be ignored. | 1022 // All channels with a zero mix are muted and can be ignored. |
| 1014 std::vector<bool> channel_mask(audio_parameters_.channels(), false); | 1023 std::vector<bool> channel_mask(audio_parameters_.channels(), false); |
| 1015 for (size_t ch = 0; ch < matrix.size(); ++ch) { | 1024 for (size_t ch = 0; ch < matrix.size(); ++ch) { |
| 1016 channel_mask[ch] = std::any_of(matrix[ch].begin(), matrix[ch].end(), | 1025 channel_mask[ch] = std::any_of(matrix[ch].begin(), matrix[ch].end(), |
| 1017 [](float mix) { return !!mix; }); | 1026 [](float mix) { return !!mix; }); |
| 1018 } | 1027 } |
| 1019 algorithm_->SetChannelMask(std::move(channel_mask)); | 1028 algorithm_->SetChannelMask(std::move(channel_mask)); |
| 1020 } | 1029 } |
| 1021 | 1030 |
| 1022 } // namespace media | 1031 } // namespace media |
| OLD | NEW |