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

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

Issue 2752323002: Support Opus Ambisonics playback (Closed)
Patch Set: actually add config_ change Created 3 years, 8 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 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
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 last_decoded_channel_layout_(CHANNEL_LAYOUT_NONE),
52 last_decoded_channels_(0),
52 playback_rate_(0.0), 53 playback_rate_(0.0),
53 state_(kUninitialized), 54 state_(kUninitialized),
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),
61 weak_factory_(this) { 62 weak_factory_(this) {
(...skipping 289 matching lines...) Expand 10 before | Expand all | Expand 10 after
351 state_ = kInitializing; 352 state_ = kInitializing;
352 client_ = client; 353 client_ = client;
353 354
354 // Always post |init_cb_| because |this| could be destroyed if initialization 355 // Always post |init_cb_| because |this| could be destroyed if initialization
355 // failed. 356 // failed.
356 init_cb_ = BindToCurrentLoop(init_cb); 357 init_cb_ = BindToCurrentLoop(init_cb);
357 358
358 auto output_device_info = sink_->GetOutputDeviceInfo(); 359 auto output_device_info = sink_->GetOutputDeviceInfo();
359 const AudioParameters& hw_params = output_device_info.output_params(); 360 const AudioParameters& hw_params = output_device_info.output_params();
360 expecting_config_changes_ = stream->SupportsConfigChanges(); 361 expecting_config_changes_ = stream->SupportsConfigChanges();
361 if (!expecting_config_changes_ || !hw_params.IsValid() || 362
362 hw_params.format() == AudioParameters::AUDIO_FAKE) { 363 bool invalid_discrete_layout_sink =
364 stream->audio_decoder_config().channel_layout() ==
365 CHANNEL_LAYOUT_DISCRETE &&
366 !output_device_info.is_webaudio_source();
367 DCHECK(!invalid_discrete_layout_sink);
368
369 if ((!expecting_config_changes_ || !hw_params.IsValid() ||
370 hw_params.format() == AudioParameters::AUDIO_FAKE) &&
371 !invalid_discrete_layout_sink) {
363 // The actual buffer size is controlled via the size of the AudioBus 372 // The actual buffer size is controlled via the size of the AudioBus
364 // provided to Render(), but we should choose a value here based on hardware 373 // provided to Render(), but we should choose a value here based on hardware
365 // parameters if possible since it affects the initial buffer size used by 374 // parameters if possible since it affects the initial buffer size used by
366 // the algorithm. Too little will cause underflow on Bluetooth devices. 375 // the algorithm. Too little will cause underflow on Bluetooth devices.
367 int buffer_size = 376 int buffer_size =
368 std::max(stream->audio_decoder_config().samples_per_second() / 100, 377 std::max(stream->audio_decoder_config().samples_per_second() / 100,
369 hw_params.IsValid() ? hw_params.frames_per_buffer() : 0); 378 hw_params.IsValid() ? hw_params.frames_per_buffer() : 0);
370 audio_parameters_.Reset(AudioParameters::AUDIO_PCM_LOW_LATENCY, 379 audio_parameters_.Reset(AudioParameters::AUDIO_PCM_LOW_LATENCY,
371 stream->audio_decoder_config().channel_layout(), 380 stream->audio_decoder_config().channel_layout(),
372 stream->audio_decoder_config().samples_per_second(), 381 stream->audio_decoder_config().samples_per_second(),
373 stream->audio_decoder_config().bits_per_channel(), 382 stream->audio_decoder_config().bits_per_channel(),
374 buffer_size); 383 buffer_size);
384 audio_parameters_.set_channels_for_discrete(
385 stream->audio_decoder_config().channels());
375 buffer_converter_.reset(); 386 buffer_converter_.reset();
376 } else { 387 } else {
377 // To allow for seamless sample rate adaptations (i.e. changes from say 388 // To allow for seamless sample rate adaptations (i.e. changes from say
378 // 16kHz to 48kHz), always resample to the hardware rate. 389 // 16kHz to 48kHz), always resample to the hardware rate.
379 int sample_rate = hw_params.sample_rate(); 390 int sample_rate = hw_params.sample_rate();
380 int preferred_buffer_size = hw_params.frames_per_buffer(); 391 int preferred_buffer_size = hw_params.frames_per_buffer();
381 392
382 #if defined(OS_CHROMEOS) 393 #if defined(OS_CHROMEOS)
383 // On ChromeOS let the OS level resampler handle resampling unless the 394 // On ChromeOS let the OS level resampler handle resampling unless the
384 // initial sample rate is too low; this allows support for sample rate 395 // initial sample rate is too low; this allows support for sample rate
385 // adaptations where necessary. 396 // adaptations where necessary.
386 if (stream->audio_decoder_config().samples_per_second() >= 44100) { 397 if (stream->audio_decoder_config().samples_per_second() >= 44100) {
387 sample_rate = stream->audio_decoder_config().samples_per_second(); 398 sample_rate = stream->audio_decoder_config().samples_per_second();
388 preferred_buffer_size = 0; // No preference. 399 preferred_buffer_size = 0; // No preference.
389 } 400 }
390 #endif 401 #endif
391 402
392 int stream_channel_count = ChannelLayoutToChannelCount( 403 int stream_channel_count = stream->audio_decoder_config().channels();
393 stream->audio_decoder_config().channel_layout());
394 404
395 bool try_supported_channel_layouts = false; 405 bool try_supported_channel_layouts = false;
396 #if defined(OS_WIN) 406 #if defined(OS_WIN)
397 try_supported_channel_layouts = 407 try_supported_channel_layouts =
398 base::CommandLine::ForCurrentProcess()->HasSwitch( 408 base::CommandLine::ForCurrentProcess()->HasSwitch(
399 switches::kTrySupportedChannelLayouts); 409 switches::kTrySupportedChannelLayouts);
400 #endif 410 #endif
401 411
402 // We don't know how to up-mix for DISCRETE layouts (fancy multichannel 412 // We don't know how to up-mix for DISCRETE layouts (fancy multichannel
403 // hardware with non-standard speaker arrangement). Instead, pretend the 413 // hardware with non-standard speaker arrangement). Instead, pretend the
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
437 447
438 audio_parameters_.Reset(hw_params.format(), renderer_channel_layout, 448 audio_parameters_.Reset(hw_params.format(), renderer_channel_layout,
439 sample_rate, hw_params.bits_per_sample(), 449 sample_rate, hw_params.bits_per_sample(),
440 media::AudioLatency::GetHighLatencyBufferSize( 450 media::AudioLatency::GetHighLatencyBufferSize(
441 sample_rate, preferred_buffer_size)); 451 sample_rate, preferred_buffer_size));
442 } 452 }
443 453
444 last_decoded_channel_layout_ = 454 last_decoded_channel_layout_ =
445 stream->audio_decoder_config().channel_layout(); 455 stream->audio_decoder_config().channel_layout();
446 456
457 last_decoded_channels_ = stream->audio_decoder_config().channels();
458
447 audio_clock_.reset( 459 audio_clock_.reset(
448 new AudioClock(base::TimeDelta(), audio_parameters_.sample_rate())); 460 new AudioClock(base::TimeDelta(), audio_parameters_.sample_rate()));
449 461
450 audio_buffer_stream_->Initialize( 462 audio_buffer_stream_->Initialize(
451 stream, base::Bind(&AudioRendererImpl::OnAudioBufferStreamInitialized, 463 stream, base::Bind(&AudioRendererImpl::OnAudioBufferStreamInitialized,
452 weak_factory_.GetWeakPtr()), 464 weak_factory_.GetWeakPtr()),
453 cdm_context, base::Bind(&AudioRendererImpl::OnStatisticsUpdate, 465 cdm_context, base::Bind(&AudioRendererImpl::OnStatisticsUpdate,
454 weak_factory_.GetWeakPtr()), 466 weak_factory_.GetWeakPtr()),
455 base::Bind(&AudioRendererImpl::OnWaitingForDecryptionKey, 467 base::Bind(&AudioRendererImpl::OnWaitingForDecryptionKey,
456 weak_factory_.GetWeakPtr())); 468 weak_factory_.GetWeakPtr()));
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after
584 DVLOG(1) << __func__ << " Updating audio sample_rate." 596 DVLOG(1) << __func__ << " Updating audio sample_rate."
585 << " ts:" << buffer->timestamp().InMicroseconds() 597 << " ts:" << buffer->timestamp().InMicroseconds()
586 << " old:" << last_decoded_sample_rate_ 598 << " old:" << last_decoded_sample_rate_
587 << " new:" << buffer->sample_rate(); 599 << " new:" << buffer->sample_rate();
588 OnConfigChange(); 600 OnConfigChange();
589 } 601 }
590 last_decoded_sample_rate_ = buffer->sample_rate(); 602 last_decoded_sample_rate_ = buffer->sample_rate();
591 603
592 if (last_decoded_channel_layout_ != buffer->channel_layout()) { 604 if (last_decoded_channel_layout_ != buffer->channel_layout()) {
593 last_decoded_channel_layout_ = buffer->channel_layout(); 605 last_decoded_channel_layout_ = buffer->channel_layout();
606 last_decoded_channels_ = buffer->channel_count();
594 607
595 // Input layouts should never be discrete. 608 // Input layouts should never be discrete.
596 DCHECK_NE(last_decoded_channel_layout_, CHANNEL_LAYOUT_DISCRETE); 609 DCHECK_NE(last_decoded_channel_layout_, CHANNEL_LAYOUT_DISCRETE);
597 ConfigureChannelMask(); 610 ConfigureChannelMask();
598 } 611 }
599 } 612 }
600 613
601 DCHECK(buffer_converter_); 614 DCHECK(buffer_converter_);
602 buffer_converter_->AddInput(buffer); 615 buffer_converter_->AddInput(buffer);
603 616
(...skipping 365 matching lines...) Expand 10 before | Expand all | Expand 10 after
969 task_runner_->PostTask( 982 task_runner_->PostTask(
970 FROM_HERE, base::Bind(&AudioRendererImpl::OnBufferingStateChange, 983 FROM_HERE, base::Bind(&AudioRendererImpl::OnBufferingStateChange,
971 weak_factory_.GetWeakPtr(), buffering_state_)); 984 weak_factory_.GetWeakPtr(), buffering_state_));
972 } 985 }
973 986
974 void AudioRendererImpl::ConfigureChannelMask() { 987 void AudioRendererImpl::ConfigureChannelMask() {
975 DCHECK(algorithm_); 988 DCHECK(algorithm_);
976 DCHECK(audio_parameters_.IsValid()); 989 DCHECK(audio_parameters_.IsValid());
977 DCHECK_NE(last_decoded_channel_layout_, CHANNEL_LAYOUT_NONE); 990 DCHECK_NE(last_decoded_channel_layout_, CHANNEL_LAYOUT_NONE);
978 DCHECK_NE(last_decoded_channel_layout_, CHANNEL_LAYOUT_UNSUPPORTED); 991 DCHECK_NE(last_decoded_channel_layout_, CHANNEL_LAYOUT_UNSUPPORTED);
979 DCHECK_NE(last_decoded_channel_layout_, CHANNEL_LAYOUT_DISCRETE);
980
981 const int input_channel_count =
982 ChannelLayoutToChannelCount(last_decoded_channel_layout_);
983 992
984 // If we're actually downmixing the signal, no mask is necessary, but ensure 993 // If we're actually downmixing the signal, no mask is necessary, but ensure
985 // we clear any existing mask if present. 994 // we clear any existing mask if present.
986 if (input_channel_count >= audio_parameters_.channels()) { 995 if (last_decoded_channels_ >= audio_parameters_.channels()) {
987 algorithm_->SetChannelMask( 996 algorithm_->SetChannelMask(
988 std::vector<bool>(audio_parameters_.channels(), true)); 997 std::vector<bool>(audio_parameters_.channels(), true));
989 return; 998 return;
990 } 999 }
991 1000
992 // Determine the matrix used to upmix the channels. 1001 // Determine the matrix used to upmix the channels.
993 std::vector<std::vector<float>> matrix; 1002 std::vector<std::vector<float>> matrix;
994 ChannelMixingMatrix(last_decoded_channel_layout_, input_channel_count, 1003 ChannelMixingMatrix(last_decoded_channel_layout_, last_decoded_channels_,
995 audio_parameters_.channel_layout(), 1004 audio_parameters_.channel_layout(),
996 audio_parameters_.channels()) 1005 audio_parameters_.channels())
997 .CreateTransformationMatrix(&matrix); 1006 .CreateTransformationMatrix(&matrix);
998 1007
999 // All channels with a zero mix are muted and can be ignored. 1008 // All channels with a zero mix are muted and can be ignored.
1000 std::vector<bool> channel_mask(audio_parameters_.channels(), false); 1009 std::vector<bool> channel_mask(audio_parameters_.channels(), false);
1001 for (size_t ch = 0; ch < matrix.size(); ++ch) { 1010 for (size_t ch = 0; ch < matrix.size(); ++ch) {
1002 channel_mask[ch] = std::any_of(matrix[ch].begin(), matrix[ch].end(), 1011 channel_mask[ch] = std::any_of(matrix[ch].begin(), matrix[ch].end(),
1003 [](float mix) { return !!mix; }); 1012 [](float mix) { return !!mix; });
1004 } 1013 }
1005 algorithm_->SetChannelMask(std::move(channel_mask)); 1014 algorithm_->SetChannelMask(std::move(channel_mask));
1006 } 1015 }
1007 1016
1008 } // namespace media 1017 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698