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

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

Issue 2752323002: Support Opus Ambisonics playback (Closed)
Patch Set: Address comments Created 3 years, 7 months 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
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 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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698