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

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

Issue 2752323002: Support Opus Ambisonics playback (Closed)
Patch Set: another fix for unreliable ffmpeg channels vs layout Created 3 years, 6 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
« 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 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() ==
379 CHANNEL_LAYOUT_DISCRETE &&
380 sink_->IsOptimizedForHardwareParameters()) {
381 use_stream_params = false;
382 }
383
384 if (use_stream_params) {
375 // The actual buffer size is controlled via the size of the AudioBus 385 // 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 386 // 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 387 // parameters if possible since it affects the initial buffer size used by
378 // the algorithm. Too little will cause underflow on Bluetooth devices. 388 // the algorithm. Too little will cause underflow on Bluetooth devices.
379 int buffer_size = 389 int buffer_size =
380 std::max(stream->audio_decoder_config().samples_per_second() / 100, 390 std::max(stream->audio_decoder_config().samples_per_second() / 100,
381 hw_params.IsValid() ? hw_params.frames_per_buffer() : 0); 391 hw_params.IsValid() ? hw_params.frames_per_buffer() : 0);
382 audio_parameters_.Reset(AudioParameters::AUDIO_PCM_LOW_LATENCY, 392 audio_parameters_.Reset(AudioParameters::AUDIO_PCM_LOW_LATENCY,
383 stream->audio_decoder_config().channel_layout(), 393 stream->audio_decoder_config().channel_layout(),
384 stream->audio_decoder_config().samples_per_second(), 394 stream->audio_decoder_config().samples_per_second(),
385 stream->audio_decoder_config().bits_per_channel(), 395 stream->audio_decoder_config().bits_per_channel(),
386 buffer_size); 396 buffer_size);
397 audio_parameters_.set_channels_for_discrete(
398 stream->audio_decoder_config().channels());
387 buffer_converter_.reset(); 399 buffer_converter_.reset();
388 } else { 400 } else {
389 // To allow for seamless sample rate adaptations (i.e. changes from say 401 // To allow for seamless sample rate adaptations (i.e. changes from say
390 // 16kHz to 48kHz), always resample to the hardware rate. 402 // 16kHz to 48kHz), always resample to the hardware rate.
391 int sample_rate = hw_params.sample_rate(); 403 int sample_rate = hw_params.sample_rate();
392 int preferred_buffer_size = hw_params.frames_per_buffer(); 404 int preferred_buffer_size = hw_params.frames_per_buffer();
393 405
394 #if defined(OS_CHROMEOS) 406 #if defined(OS_CHROMEOS)
395 // On ChromeOS let the OS level resampler handle resampling unless the 407 // On ChromeOS let the OS level resampler handle resampling unless the
396 // initial sample rate is too low; this allows support for sample rate 408 // initial sample rate is too low; this allows support for sample rate
397 // adaptations where necessary. 409 // adaptations where necessary.
398 if (stream->audio_decoder_config().samples_per_second() >= 44100) { 410 if (stream->audio_decoder_config().samples_per_second() >= 44100) {
399 sample_rate = stream->audio_decoder_config().samples_per_second(); 411 sample_rate = stream->audio_decoder_config().samples_per_second();
400 preferred_buffer_size = 0; // No preference. 412 preferred_buffer_size = 0; // No preference.
401 } 413 }
402 #endif 414 #endif
403 415
404 int stream_channel_count = ChannelLayoutToChannelCount( 416 int stream_channel_count = stream->audio_decoder_config().channels();
405 stream->audio_decoder_config().channel_layout());
406 417
407 bool try_supported_channel_layouts = false; 418 bool try_supported_channel_layouts = false;
408 #if defined(OS_WIN) 419 #if defined(OS_WIN)
409 try_supported_channel_layouts = 420 try_supported_channel_layouts =
410 base::CommandLine::ForCurrentProcess()->HasSwitch( 421 base::CommandLine::ForCurrentProcess()->HasSwitch(
411 switches::kTrySupportedChannelLayouts); 422 switches::kTrySupportedChannelLayouts);
412 #endif 423 #endif
413 424
414 // We don't know how to up-mix for DISCRETE layouts (fancy multichannel 425 // We don't know how to up-mix for DISCRETE layouts (fancy multichannel
415 // hardware with non-standard speaker arrangement). Instead, pretend the 426 // 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(), 462 sample_rate, hw_params.bits_per_sample(),
452 media::AudioLatency::GetHighLatencyBufferSize( 463 media::AudioLatency::GetHighLatencyBufferSize(
453 sample_rate, preferred_buffer_size)); 464 sample_rate, preferred_buffer_size));
454 } 465 }
455 466
456 last_decoded_channel_layout_ = 467 last_decoded_channel_layout_ =
457 stream->audio_decoder_config().channel_layout(); 468 stream->audio_decoder_config().channel_layout();
458 469
459 is_encrypted_ = stream->audio_decoder_config().is_encrypted(); 470 is_encrypted_ = stream->audio_decoder_config().is_encrypted();
460 471
472 last_decoded_channels_ = stream->audio_decoder_config().channels();
473
461 audio_clock_.reset( 474 audio_clock_.reset(
462 new AudioClock(base::TimeDelta(), audio_parameters_.sample_rate())); 475 new AudioClock(base::TimeDelta(), audio_parameters_.sample_rate()));
463 476
464 audio_buffer_stream_->Initialize( 477 audio_buffer_stream_->Initialize(
465 stream, base::Bind(&AudioRendererImpl::OnAudioBufferStreamInitialized, 478 stream, base::Bind(&AudioRendererImpl::OnAudioBufferStreamInitialized,
466 weak_factory_.GetWeakPtr()), 479 weak_factory_.GetWeakPtr()),
467 cdm_context, base::Bind(&AudioRendererImpl::OnStatisticsUpdate, 480 cdm_context, base::Bind(&AudioRendererImpl::OnStatisticsUpdate,
468 weak_factory_.GetWeakPtr()), 481 weak_factory_.GetWeakPtr()),
469 base::Bind(&AudioRendererImpl::OnWaitingForDecryptionKey, 482 base::Bind(&AudioRendererImpl::OnWaitingForDecryptionKey,
470 weak_factory_.GetWeakPtr())); 483 weak_factory_.GetWeakPtr()));
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after
598 DVLOG(1) << __func__ << " Updating audio sample_rate." 611 DVLOG(1) << __func__ << " Updating audio sample_rate."
599 << " ts:" << buffer->timestamp().InMicroseconds() 612 << " ts:" << buffer->timestamp().InMicroseconds()
600 << " old:" << last_decoded_sample_rate_ 613 << " old:" << last_decoded_sample_rate_
601 << " new:" << buffer->sample_rate(); 614 << " new:" << buffer->sample_rate();
602 OnConfigChange(); 615 OnConfigChange();
603 } 616 }
604 last_decoded_sample_rate_ = buffer->sample_rate(); 617 last_decoded_sample_rate_ = buffer->sample_rate();
605 618
606 if (last_decoded_channel_layout_ != buffer->channel_layout()) { 619 if (last_decoded_channel_layout_ != buffer->channel_layout()) {
607 last_decoded_channel_layout_ = buffer->channel_layout(); 620 last_decoded_channel_layout_ = buffer->channel_layout();
621 last_decoded_channels_ = buffer->channel_count();
608 622
609 // Input layouts should never be discrete. 623 // Input layouts should never be discrete.
610 DCHECK_NE(last_decoded_channel_layout_, CHANNEL_LAYOUT_DISCRETE); 624 DCHECK_NE(last_decoded_channel_layout_, CHANNEL_LAYOUT_DISCRETE);
611 ConfigureChannelMask(); 625 ConfigureChannelMask();
612 } 626 }
613 } 627 }
614 628
615 DCHECK(buffer_converter_); 629 DCHECK(buffer_converter_);
616 buffer_converter_->AddInput(buffer); 630 buffer_converter_->AddInput(buffer);
617 631
(...skipping 365 matching lines...) Expand 10 before | Expand all | Expand 10 after
983 task_runner_->PostTask( 997 task_runner_->PostTask(
984 FROM_HERE, base::Bind(&AudioRendererImpl::OnBufferingStateChange, 998 FROM_HERE, base::Bind(&AudioRendererImpl::OnBufferingStateChange,
985 weak_factory_.GetWeakPtr(), buffering_state_)); 999 weak_factory_.GetWeakPtr(), buffering_state_));
986 } 1000 }
987 1001
988 void AudioRendererImpl::ConfigureChannelMask() { 1002 void AudioRendererImpl::ConfigureChannelMask() {
989 DCHECK(algorithm_); 1003 DCHECK(algorithm_);
990 DCHECK(audio_parameters_.IsValid()); 1004 DCHECK(audio_parameters_.IsValid());
991 DCHECK_NE(last_decoded_channel_layout_, CHANNEL_LAYOUT_NONE); 1005 DCHECK_NE(last_decoded_channel_layout_, CHANNEL_LAYOUT_NONE);
992 DCHECK_NE(last_decoded_channel_layout_, CHANNEL_LAYOUT_UNSUPPORTED); 1006 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 1007
998 // If we're actually downmixing the signal, no mask is necessary, but ensure 1008 // If we're actually downmixing the signal, no mask is necessary, but ensure
999 // we clear any existing mask if present. 1009 // we clear any existing mask if present.
1000 if (input_channel_count >= audio_parameters_.channels()) { 1010 if (last_decoded_channels_ >= audio_parameters_.channels()) {
1001 algorithm_->SetChannelMask( 1011 algorithm_->SetChannelMask(
1002 std::vector<bool>(audio_parameters_.channels(), true)); 1012 std::vector<bool>(audio_parameters_.channels(), true));
1003 return; 1013 return;
1004 } 1014 }
1005 1015
1006 // Determine the matrix used to upmix the channels. 1016 // Determine the matrix used to upmix the channels.
1007 std::vector<std::vector<float>> matrix; 1017 std::vector<std::vector<float>> matrix;
1008 ChannelMixingMatrix(last_decoded_channel_layout_, input_channel_count, 1018 ChannelMixingMatrix(last_decoded_channel_layout_, last_decoded_channels_,
1009 audio_parameters_.channel_layout(), 1019 audio_parameters_.channel_layout(),
1010 audio_parameters_.channels()) 1020 audio_parameters_.channels())
1011 .CreateTransformationMatrix(&matrix); 1021 .CreateTransformationMatrix(&matrix);
1012 1022
1013 // All channels with a zero mix are muted and can be ignored. 1023 // All channels with a zero mix are muted and can be ignored.
1014 std::vector<bool> channel_mask(audio_parameters_.channels(), false); 1024 std::vector<bool> channel_mask(audio_parameters_.channels(), false);
1015 for (size_t ch = 0; ch < matrix.size(); ++ch) { 1025 for (size_t ch = 0; ch < matrix.size(); ++ch) {
1016 channel_mask[ch] = std::any_of(matrix[ch].begin(), matrix[ch].end(), 1026 channel_mask[ch] = std::any_of(matrix[ch].begin(), matrix[ch].end(),
1017 [](float mix) { return !!mix; }); 1027 [](float mix) { return !!mix; });
1018 } 1028 }
1019 algorithm_->SetChannelMask(std::move(channel_mask)); 1029 algorithm_->SetChannelMask(std::move(channel_mask));
1020 } 1030 }
1021 1031
1022 } // namespace media 1032 } // 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