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

Side by Side 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 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>
(...skipping 30 matching lines...) Expand all
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 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 playback_rate_(0.0), 52 playback_rate_(0.0),
52 state_(kUninitialized), 53 state_(kUninitialized),
53 buffering_state_(BUFFERING_HAVE_NOTHING), 54 buffering_state_(BUFFERING_HAVE_NOTHING),
54 rendering_(false), 55 rendering_(false),
55 sink_playing_(false), 56 sink_playing_(false),
56 pending_read_(false), 57 pending_read_(false),
57 received_end_of_stream_(false), 58 received_end_of_stream_(false),
58 rendered_end_of_stream_(false), 59 rendered_end_of_stream_(false),
59 is_suspending_(false), 60 is_suspending_(false),
60 weak_factory_(this) { 61 weak_factory_(this) {
(...skipping 359 matching lines...) Expand 10 before | Expand all | Expand 10 after
420 // down-mixing and use the data from all stream channels. 421 // down-mixing and use the data from all stream channels.
421 ChannelLayout renderer_channel_layout = 422 ChannelLayout renderer_channel_layout =
422 hw_channel_count > stream_channel_count 423 hw_channel_count > stream_channel_count
423 ? hw_channel_layout 424 ? hw_channel_layout
424 : stream->audio_decoder_config().channel_layout(); 425 : stream->audio_decoder_config().channel_layout();
425 426
426 audio_parameters_.Reset(hw_params.format(), renderer_channel_layout, 427 audio_parameters_.Reset(hw_params.format(), renderer_channel_layout,
427 sample_rate, hw_params.bits_per_sample(), 428 sample_rate, hw_params.bits_per_sample(),
428 media::AudioLatency::GetHighLatencyBufferSize( 429 media::AudioLatency::GetHighLatencyBufferSize(
429 sample_rate, preferred_buffer_size)); 430 sample_rate, preferred_buffer_size));
431 }
430 432
431 // Figure out if there are muted channels that we should ignore when 433 last_decoded_channel_layout_ =
432 // playback rate adapatation is requested (it's expensive). 434 stream->audio_decoder_config().channel_layout();
433 if (stream_channel_count < audio_parameters_.channels()) {
434 std::vector<std::vector<float>> matrix;
435 ChannelMixingMatrix(
436 stream->audio_decoder_config().channel_layout(), stream_channel_count,
437 audio_parameters_.channel_layout(), audio_parameters_.channels())
438 .CreateTransformationMatrix(&matrix);
439
440 // All channels with a zero mix are muted and can be ignored.
441 channel_mask_ = std::vector<bool>(audio_parameters_.channels(), false);
442 for (size_t ch = 0; ch < matrix.size(); ++ch) {
443 channel_mask_[ch] = std::any_of(matrix[ch].begin(), matrix[ch].end(),
444 [](float mix) { return !!mix; });
445 }
446 }
447 }
448 435
449 audio_clock_.reset( 436 audio_clock_.reset(
450 new AudioClock(base::TimeDelta(), audio_parameters_.sample_rate())); 437 new AudioClock(base::TimeDelta(), audio_parameters_.sample_rate()));
451 438
452 audio_buffer_stream_->Initialize( 439 audio_buffer_stream_->Initialize(
453 stream, base::Bind(&AudioRendererImpl::OnAudioBufferStreamInitialized, 440 stream, base::Bind(&AudioRendererImpl::OnAudioBufferStreamInitialized,
454 weak_factory_.GetWeakPtr()), 441 weak_factory_.GetWeakPtr()),
455 cdm_context, base::Bind(&AudioRendererImpl::OnStatisticsUpdate, 442 cdm_context, base::Bind(&AudioRendererImpl::OnStatisticsUpdate,
456 weak_factory_.GetWeakPtr()), 443 weak_factory_.GetWeakPtr()),
457 base::Bind(&AudioRendererImpl::OnWaitingForDecryptionKey, 444 base::Bind(&AudioRendererImpl::OnWaitingForDecryptionKey,
(...skipping 19 matching lines...) Expand all
477 base::ResetAndReturn(&init_cb_).Run(PIPELINE_ERROR_INITIALIZATION_FAILED); 464 base::ResetAndReturn(&init_cb_).Run(PIPELINE_ERROR_INITIALIZATION_FAILED);
478 return; 465 return;
479 } 466 }
480 467
481 if (expecting_config_changes_) 468 if (expecting_config_changes_)
482 buffer_converter_.reset(new AudioBufferConverter(audio_parameters_)); 469 buffer_converter_.reset(new AudioBufferConverter(audio_parameters_));
483 470
484 // 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
485 // based on the decoder format. 472 // based on the decoder format.
486 algorithm_.reset(new AudioRendererAlgorithm()); 473 algorithm_.reset(new AudioRendererAlgorithm());
487 algorithm_->Initialize(audio_parameters_, channel_mask_); 474 algorithm_->Initialize(audio_parameters_);
475 ConfigureChannelMask();
488 476
489 ChangeState_Locked(kFlushed); 477 ChangeState_Locked(kFlushed);
490 478
491 { 479 {
492 base::AutoUnlock auto_unlock(lock_); 480 base::AutoUnlock auto_unlock(lock_);
493 sink_->Initialize(audio_parameters_, this); 481 sink_->Initialize(audio_parameters_, this);
494 sink_->Start(); 482 sink_->Start();
495 483
496 // Some sinks play on start... 484 // Some sinks play on start...
497 sink_->Pause(); 485 sink_->Pause();
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
570 558
571 if (state_ == kFlushing) { 559 if (state_ == kFlushing) {
572 ChangeState_Locked(kFlushed); 560 ChangeState_Locked(kFlushed);
573 DoFlush_Locked(); 561 DoFlush_Locked();
574 return; 562 return;
575 } 563 }
576 564
577 bool need_another_buffer = true; 565 bool need_another_buffer = true;
578 566
579 if (expecting_config_changes_) { 567 if (expecting_config_changes_) {
580 if (last_decoded_sample_rate_ && 568 if (!buffer->end_of_stream()) {
581 buffer->sample_rate() != last_decoded_sample_rate_) { 569 if (last_decoded_sample_rate_ &&
582 DVLOG(1) << __func__ << " Updating audio sample_rate." 570 buffer->sample_rate() != last_decoded_sample_rate_) {
583 << " ts:" << buffer->timestamp().InMicroseconds() 571 DVLOG(1) << __func__ << " Updating audio sample_rate."
584 << " old:" << last_decoded_sample_rate_ 572 << " ts:" << buffer->timestamp().InMicroseconds()
585 << " new:" << buffer->sample_rate(); 573 << " old:" << last_decoded_sample_rate_
586 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 }
587 } 586 }
588 last_decoded_sample_rate_ = buffer->sample_rate();
589 587
590 DCHECK(buffer_converter_); 588 DCHECK(buffer_converter_);
591 buffer_converter_->AddInput(buffer); 589 buffer_converter_->AddInput(buffer);
592 590
593 while (buffer_converter_->HasNextBuffer()) { 591 while (buffer_converter_->HasNextBuffer()) {
594 need_another_buffer = 592 need_another_buffer =
595 HandleDecodedBuffer_Locked(buffer_converter_->GetNextBuffer()); 593 HandleDecodedBuffer_Locked(buffer_converter_->GetNextBuffer());
596 } 594 }
597 } else { 595 } else {
598 // 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
949 << buffering_state; 947 << buffering_state;
950 DCHECK_NE(buffering_state_, buffering_state); 948 DCHECK_NE(buffering_state_, buffering_state);
951 lock_.AssertAcquired(); 949 lock_.AssertAcquired();
952 buffering_state_ = buffering_state; 950 buffering_state_ = buffering_state;
953 951
954 task_runner_->PostTask( 952 task_runner_->PostTask(
955 FROM_HERE, base::Bind(&AudioRendererImpl::OnBufferingStateChange, 953 FROM_HERE, base::Bind(&AudioRendererImpl::OnBufferingStateChange,
956 weak_factory_.GetWeakPtr(), buffering_state_)); 954 weak_factory_.GetWeakPtr(), buffering_state_));
957 } 955 }
958 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
959 } // 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