| 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> |
| 11 | 11 |
| 12 #include "base/bind.h" | 12 #include "base/bind.h" |
| 13 #include "base/callback.h" | 13 #include "base/callback.h" |
| 14 #include "base/callback_helpers.h" | 14 #include "base/callback_helpers.h" |
| 15 #include "base/command_line.h" | 15 #include "base/command_line.h" |
| 16 #include "base/logging.h" | 16 #include "base/logging.h" |
| 17 #include "base/power_monitor/power_monitor.h" | 17 #include "base/power_monitor/power_monitor.h" |
| 18 #include "base/single_thread_task_runner.h" | 18 #include "base/single_thread_task_runner.h" |
| 19 #include "base/time/default_tick_clock.h" | 19 #include "base/time/default_tick_clock.h" |
| 20 #include "build/build_config.h" | 20 #include "build/build_config.h" |
| 21 #include "media/base/audio_buffer.h" | 21 #include "media/base/audio_buffer.h" |
| 22 #include "media/base/audio_buffer_converter.h" | 22 #include "media/base/audio_buffer_converter.h" |
| 23 #include "media/base/audio_latency.h" | 23 #include "media/base/audio_latency.h" |
| 24 #include "media/base/bind_to_current_loop.h" | 24 #include "media/base/bind_to_current_loop.h" |
| 25 #include "media/base/channel_mixing_matrix.h" |
| 25 #include "media/base/demuxer_stream.h" | 26 #include "media/base/demuxer_stream.h" |
| 26 #include "media/base/media_log.h" | 27 #include "media/base/media_log.h" |
| 27 #include "media/base/media_switches.h" | 28 #include "media/base/media_switches.h" |
| 28 #include "media/base/renderer_client.h" | 29 #include "media/base/renderer_client.h" |
| 29 #include "media/base/timestamp_constants.h" | 30 #include "media/base/timestamp_constants.h" |
| 30 #include "media/filters/audio_clock.h" | 31 #include "media/filters/audio_clock.h" |
| 31 #include "media/filters/decrypting_demuxer_stream.h" | 32 #include "media/filters/decrypting_demuxer_stream.h" |
| 32 | 33 |
| 33 namespace media { | 34 namespace media { |
| 34 | 35 |
| 35 AudioRendererImpl::AudioRendererImpl( | 36 AudioRendererImpl::AudioRendererImpl( |
| 36 const scoped_refptr<base::SingleThreadTaskRunner>& task_runner, | 37 const scoped_refptr<base::SingleThreadTaskRunner>& task_runner, |
| 37 media::AudioRendererSink* sink, | 38 media::AudioRendererSink* sink, |
| 38 ScopedVector<AudioDecoder> decoders, | 39 ScopedVector<AudioDecoder> decoders, |
| 39 const scoped_refptr<MediaLog>& media_log) | 40 const scoped_refptr<MediaLog>& media_log) |
| 40 : task_runner_(task_runner), | 41 : task_runner_(task_runner), |
| 41 expecting_config_changes_(false), | 42 expecting_config_changes_(false), |
| 42 sink_(sink), | 43 sink_(sink), |
| 43 audio_buffer_stream_( | 44 audio_buffer_stream_( |
| 44 new AudioBufferStream(task_runner, std::move(decoders), media_log)), | 45 new AudioBufferStream(task_runner, std::move(decoders), media_log)), |
| 45 media_log_(media_log), | 46 media_log_(media_log), |
| 46 client_(nullptr), | 47 client_(nullptr), |
| 47 tick_clock_(new base::DefaultTickClock()), | 48 tick_clock_(new base::DefaultTickClock()), |
| 48 last_audio_memory_usage_(0), | 49 last_audio_memory_usage_(0), |
| 49 last_decoded_sample_rate_(0), | 50 last_decoded_sample_rate_(0), |
| 51 last_decoded_channel_layout_(CHANNEL_LAYOUT_NONE), |
| 50 playback_rate_(0.0), | 52 playback_rate_(0.0), |
| 51 state_(kUninitialized), | 53 state_(kUninitialized), |
| 52 buffering_state_(BUFFERING_HAVE_NOTHING), | 54 buffering_state_(BUFFERING_HAVE_NOTHING), |
| 53 rendering_(false), | 55 rendering_(false), |
| 54 sink_playing_(false), | 56 sink_playing_(false), |
| 55 pending_read_(false), | 57 pending_read_(false), |
| 56 received_end_of_stream_(false), | 58 received_end_of_stream_(false), |
| 57 rendered_end_of_stream_(false), | 59 rendered_end_of_stream_(false), |
| 58 is_suspending_(false), | 60 is_suspending_(false), |
| 59 weak_factory_(this) { | 61 weak_factory_(this) { |
| (...skipping 361 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 421 hw_channel_count > stream_channel_count | 423 hw_channel_count > stream_channel_count |
| 422 ? hw_channel_layout | 424 ? hw_channel_layout |
| 423 : stream->audio_decoder_config().channel_layout(); | 425 : stream->audio_decoder_config().channel_layout(); |
| 424 | 426 |
| 425 audio_parameters_.Reset(hw_params.format(), renderer_channel_layout, | 427 audio_parameters_.Reset(hw_params.format(), renderer_channel_layout, |
| 426 sample_rate, hw_params.bits_per_sample(), | 428 sample_rate, hw_params.bits_per_sample(), |
| 427 media::AudioLatency::GetHighLatencyBufferSize( | 429 media::AudioLatency::GetHighLatencyBufferSize( |
| 428 sample_rate, preferred_buffer_size)); | 430 sample_rate, preferred_buffer_size)); |
| 429 } | 431 } |
| 430 | 432 |
| 433 last_decoded_channel_layout_ = |
| 434 stream->audio_decoder_config().channel_layout(); |
| 435 |
| 431 audio_clock_.reset( | 436 audio_clock_.reset( |
| 432 new AudioClock(base::TimeDelta(), audio_parameters_.sample_rate())); | 437 new AudioClock(base::TimeDelta(), audio_parameters_.sample_rate())); |
| 433 | 438 |
| 434 audio_buffer_stream_->Initialize( | 439 audio_buffer_stream_->Initialize( |
| 435 stream, base::Bind(&AudioRendererImpl::OnAudioBufferStreamInitialized, | 440 stream, base::Bind(&AudioRendererImpl::OnAudioBufferStreamInitialized, |
| 436 weak_factory_.GetWeakPtr()), | 441 weak_factory_.GetWeakPtr()), |
| 437 cdm_context, base::Bind(&AudioRendererImpl::OnStatisticsUpdate, | 442 cdm_context, base::Bind(&AudioRendererImpl::OnStatisticsUpdate, |
| 438 weak_factory_.GetWeakPtr()), | 443 weak_factory_.GetWeakPtr()), |
| 439 base::Bind(&AudioRendererImpl::OnWaitingForDecryptionKey, | 444 base::Bind(&AudioRendererImpl::OnWaitingForDecryptionKey, |
| 440 weak_factory_.GetWeakPtr())); | 445 weak_factory_.GetWeakPtr())); |
| (...skipping 19 matching lines...) Expand all Loading... |
| 460 return; | 465 return; |
| 461 } | 466 } |
| 462 | 467 |
| 463 if (expecting_config_changes_) | 468 if (expecting_config_changes_) |
| 464 buffer_converter_.reset(new AudioBufferConverter(audio_parameters_)); | 469 buffer_converter_.reset(new AudioBufferConverter(audio_parameters_)); |
| 465 | 470 |
| 466 // We're all good! Continue initializing the rest of the audio renderer | 471 // We're all good! Continue initializing the rest of the audio renderer |
| 467 // based on the decoder format. | 472 // based on the decoder format. |
| 468 algorithm_.reset(new AudioRendererAlgorithm()); | 473 algorithm_.reset(new AudioRendererAlgorithm()); |
| 469 algorithm_->Initialize(audio_parameters_); | 474 algorithm_->Initialize(audio_parameters_); |
| 475 ConfigureChannelMask(); |
| 470 | 476 |
| 471 ChangeState_Locked(kFlushed); | 477 ChangeState_Locked(kFlushed); |
| 472 | 478 |
| 473 { | 479 { |
| 474 base::AutoUnlock auto_unlock(lock_); | 480 base::AutoUnlock auto_unlock(lock_); |
| 475 sink_->Initialize(audio_parameters_, this); | 481 sink_->Initialize(audio_parameters_, this); |
| 476 sink_->Start(); | 482 sink_->Start(); |
| 477 | 483 |
| 478 // Some sinks play on start... | 484 // Some sinks play on start... |
| 479 sink_->Pause(); | 485 sink_->Pause(); |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 552 | 558 |
| 553 if (state_ == kFlushing) { | 559 if (state_ == kFlushing) { |
| 554 ChangeState_Locked(kFlushed); | 560 ChangeState_Locked(kFlushed); |
| 555 DoFlush_Locked(); | 561 DoFlush_Locked(); |
| 556 return; | 562 return; |
| 557 } | 563 } |
| 558 | 564 |
| 559 bool need_another_buffer = true; | 565 bool need_another_buffer = true; |
| 560 | 566 |
| 561 if (expecting_config_changes_) { | 567 if (expecting_config_changes_) { |
| 562 if (last_decoded_sample_rate_ && | 568 if (!buffer->end_of_stream()) { |
| 563 buffer->sample_rate() != last_decoded_sample_rate_) { | 569 if (last_decoded_sample_rate_ && |
| 564 DVLOG(1) << __func__ << " Updating audio sample_rate." | 570 buffer->sample_rate() != last_decoded_sample_rate_) { |
| 565 << " ts:" << buffer->timestamp().InMicroseconds() | 571 DVLOG(1) << __func__ << " Updating audio sample_rate." |
| 566 << " old:" << last_decoded_sample_rate_ | 572 << " ts:" << buffer->timestamp().InMicroseconds() |
| 567 << " new:" << buffer->sample_rate(); | 573 << " old:" << last_decoded_sample_rate_ |
| 568 OnConfigChange(); | 574 << " new:" << buffer->sample_rate(); |
| 575 OnConfigChange(); |
| 576 } |
| 577 last_decoded_sample_rate_ = buffer->sample_rate(); |
| 578 |
| 579 if (last_decoded_channel_layout_ != buffer->channel_layout()) { |
| 580 last_decoded_channel_layout_ = buffer->channel_layout(); |
| 581 |
| 582 // Input layouts should never be discrete. |
| 583 DCHECK_NE(last_decoded_channel_layout_, CHANNEL_LAYOUT_DISCRETE); |
| 584 ConfigureChannelMask(); |
| 585 } |
| 569 } | 586 } |
| 570 last_decoded_sample_rate_ = buffer->sample_rate(); | |
| 571 | 587 |
| 572 DCHECK(buffer_converter_); | 588 DCHECK(buffer_converter_); |
| 573 buffer_converter_->AddInput(buffer); | 589 buffer_converter_->AddInput(buffer); |
| 574 | 590 |
| 575 while (buffer_converter_->HasNextBuffer()) { | 591 while (buffer_converter_->HasNextBuffer()) { |
| 576 need_another_buffer = | 592 need_another_buffer = |
| 577 HandleDecodedBuffer_Locked(buffer_converter_->GetNextBuffer()); | 593 HandleDecodedBuffer_Locked(buffer_converter_->GetNextBuffer()); |
| 578 } | 594 } |
| 579 } else { | 595 } else { |
| 580 // TODO(chcunningham, tguilbert): Figure out if we want to support implicit | 596 // TODO(chcunningham, tguilbert): Figure out if we want to support implicit |
| (...skipping 350 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 931 << buffering_state; | 947 << buffering_state; |
| 932 DCHECK_NE(buffering_state_, buffering_state); | 948 DCHECK_NE(buffering_state_, buffering_state); |
| 933 lock_.AssertAcquired(); | 949 lock_.AssertAcquired(); |
| 934 buffering_state_ = buffering_state; | 950 buffering_state_ = buffering_state; |
| 935 | 951 |
| 936 task_runner_->PostTask( | 952 task_runner_->PostTask( |
| 937 FROM_HERE, base::Bind(&AudioRendererImpl::OnBufferingStateChange, | 953 FROM_HERE, base::Bind(&AudioRendererImpl::OnBufferingStateChange, |
| 938 weak_factory_.GetWeakPtr(), buffering_state_)); | 954 weak_factory_.GetWeakPtr(), buffering_state_)); |
| 939 } | 955 } |
| 940 | 956 |
| 957 void AudioRendererImpl::ConfigureChannelMask() { |
| 958 DCHECK(algorithm_); |
| 959 DCHECK(audio_parameters_.IsValid()); |
| 960 DCHECK_NE(last_decoded_channel_layout_, CHANNEL_LAYOUT_NONE); |
| 961 DCHECK_NE(last_decoded_channel_layout_, CHANNEL_LAYOUT_UNSUPPORTED); |
| 962 DCHECK_NE(last_decoded_channel_layout_, CHANNEL_LAYOUT_DISCRETE); |
| 963 |
| 964 const int input_channel_count = |
| 965 ChannelLayoutToChannelCount(last_decoded_channel_layout_); |
| 966 |
| 967 // If we're actually downmixing the signal, no mask is necessary, but ensure |
| 968 // we clear any existing mask if present. |
| 969 if (input_channel_count >= audio_parameters_.channels()) { |
| 970 algorithm_->SetChannelMask( |
| 971 std::vector<bool>(audio_parameters_.channels(), true)); |
| 972 return; |
| 973 } |
| 974 |
| 975 // Determine the matrix used to upmix the channels. |
| 976 std::vector<std::vector<float>> matrix; |
| 977 ChannelMixingMatrix(last_decoded_channel_layout_, input_channel_count, |
| 978 audio_parameters_.channel_layout(), |
| 979 audio_parameters_.channels()) |
| 980 .CreateTransformationMatrix(&matrix); |
| 981 |
| 982 // All channels with a zero mix are muted and can be ignored. |
| 983 std::vector<bool> channel_mask(audio_parameters_.channels(), false); |
| 984 for (size_t ch = 0; ch < matrix.size(); ++ch) { |
| 985 channel_mask[ch] = std::any_of(matrix[ch].begin(), matrix[ch].end(), |
| 986 [](float mix) { return !!mix; }); |
| 987 } |
| 988 algorithm_->SetChannelMask(std::move(channel_mask)); |
| 989 } |
| 990 |
| 941 } // namespace media | 991 } // namespace media |
| OLD | NEW |