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

Side by Side Diff: media/renderers/audio_renderer_impl.cc

Issue 2541873005: Roll up of playback rate efficiency improvements for M56. (Closed)
Patch Set: Created 4 years 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 unified diff | 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 »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
OLDNEW
« 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