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

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

Issue 2752323002: Support Opus Ambisonics playback (Closed)
Patch Set: +tests Created 3 years, 9 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 292 matching lines...) Expand 10 before | Expand all | Expand 10 after
354 // parameters if possible since it affects the initial buffer size used by 355 // parameters if possible since it affects the initial buffer size used by
355 // the algorithm. Too little will cause underflow on Bluetooth devices. 356 // the algorithm. Too little will cause underflow on Bluetooth devices.
356 int buffer_size = 357 int buffer_size =
357 std::max(stream->audio_decoder_config().samples_per_second() / 100, 358 std::max(stream->audio_decoder_config().samples_per_second() / 100,
358 hw_params.IsValid() ? hw_params.frames_per_buffer() : 0); 359 hw_params.IsValid() ? hw_params.frames_per_buffer() : 0);
359 audio_parameters_.Reset(AudioParameters::AUDIO_PCM_LOW_LATENCY, 360 audio_parameters_.Reset(AudioParameters::AUDIO_PCM_LOW_LATENCY,
360 stream->audio_decoder_config().channel_layout(), 361 stream->audio_decoder_config().channel_layout(),
361 stream->audio_decoder_config().samples_per_second(), 362 stream->audio_decoder_config().samples_per_second(),
362 stream->audio_decoder_config().bits_per_channel(), 363 stream->audio_decoder_config().bits_per_channel(),
363 buffer_size); 364 buffer_size);
365 audio_parameters_.set_channels_for_discrete(stream->audio_decoder_config().c hannels());
364 buffer_converter_.reset(); 366 buffer_converter_.reset();
365 } else { 367 } else {
366 // To allow for seamless sample rate adaptations (i.e. changes from say 368 // To allow for seamless sample rate adaptations (i.e. changes from say
367 // 16kHz to 48kHz), always resample to the hardware rate. 369 // 16kHz to 48kHz), always resample to the hardware rate.
368 int sample_rate = hw_params.sample_rate(); 370 int sample_rate = hw_params.sample_rate();
369 int preferred_buffer_size = hw_params.frames_per_buffer(); 371 int preferred_buffer_size = hw_params.frames_per_buffer();
370 372
371 #if defined(OS_CHROMEOS) 373 #if defined(OS_CHROMEOS)
372 // On ChromeOS let the OS level resampler handle resampling unless the 374 // On ChromeOS let the OS level resampler handle resampling unless the
373 // initial sample rate is too low; this allows support for sample rate 375 // initial sample rate is too low; this allows support for sample rate
374 // adaptations where necessary. 376 // adaptations where necessary.
375 if (stream->audio_decoder_config().samples_per_second() >= 44100) { 377 if (stream->audio_decoder_config().samples_per_second() >= 44100) {
376 sample_rate = stream->audio_decoder_config().samples_per_second(); 378 sample_rate = stream->audio_decoder_config().samples_per_second();
377 preferred_buffer_size = 0; // No preference. 379 preferred_buffer_size = 0; // No preference.
378 } 380 }
379 #endif 381 #endif
380 382
381 int stream_channel_count = ChannelLayoutToChannelCount( 383 int stream_channel_count = stream->audio_decoder_config().channels();
382 stream->audio_decoder_config().channel_layout());
383 384
384 bool try_supported_channel_layouts = false; 385 bool try_supported_channel_layouts = false;
385 #if defined(OS_WIN) 386 #if defined(OS_WIN)
386 try_supported_channel_layouts = 387 try_supported_channel_layouts =
387 base::CommandLine::ForCurrentProcess()->HasSwitch( 388 base::CommandLine::ForCurrentProcess()->HasSwitch(
388 switches::kTrySupportedChannelLayouts); 389 switches::kTrySupportedChannelLayouts);
389 #endif 390 #endif
390 391
391 // We don't know how to up-mix for DISCRETE layouts (fancy multichannel 392 // We don't know how to up-mix for DISCRETE layouts (fancy multichannel
392 // hardware with non-standard speaker arrangement). Instead, pretend the 393 // hardware with non-standard speaker arrangement). Instead, pretend the
(...skipping 19 matching lines...) Expand all
412 // premature down-mixing - http://crbug.com/379288). 413 // premature down-mixing - http://crbug.com/379288).
413 // If stream_channels < hw_channels: 414 // If stream_channels < hw_channels:
414 // Taking max means we up-mix to hardware layout. If stream later changes 415 // Taking max means we up-mix to hardware layout. If stream later changes
415 // to have more channels, we aren't locked into down-mixing to the 416 // to have more channels, we aren't locked into down-mixing to the
416 // initial stream layout. 417 // initial stream layout.
417 // If stream_channels > hw_channels: 418 // If stream_channels > hw_channels:
418 // We choose to output stream's layout, meaning mixing is a no-op for the 419 // We choose to output stream's layout, meaning mixing is a no-op for the
419 // renderer. Browser-side will down-mix to the hardware config. If the 420 // renderer. Browser-side will down-mix to the hardware config. If the
420 // hardware later changes to equal stream channels, browser-side will stop 421 // hardware later changes to equal stream channels, browser-side will stop
421 // down-mixing and use the data from all stream channels. 422 // down-mixing and use the data from all stream channels.
423 bool use_hw_config = hw_channel_count > stream_channel_count;
422 ChannelLayout renderer_channel_layout = 424 ChannelLayout renderer_channel_layout =
423 hw_channel_count > stream_channel_count 425 use_hw_config ? hw_channel_layout
424 ? hw_channel_layout 426 : stream->audio_decoder_config().channel_layout();
425 : stream->audio_decoder_config().channel_layout();
426 427
427 audio_parameters_.Reset(hw_params.format(), renderer_channel_layout, 428 audio_parameters_.Reset(hw_params.format(), renderer_channel_layout,
428 sample_rate, hw_params.bits_per_sample(), 429 sample_rate, hw_params.bits_per_sample(),
429 media::AudioLatency::GetHighLatencyBufferSize( 430 media::AudioLatency::GetHighLatencyBufferSize(
430 sample_rate, preferred_buffer_size)); 431 sample_rate, preferred_buffer_size));
432 if (!use_hw_config)
433 audio_parameters_.set_channels_for_discrete(stream_channel_count);
431 } 434 }
432 435
433 last_decoded_channel_layout_ = 436 last_decoded_channel_layout_ =
434 stream->audio_decoder_config().channel_layout(); 437 stream->audio_decoder_config().channel_layout();
435 438
439 last_decoded_channels_ =
440 stream->audio_decoder_config().channels();
441
436 audio_clock_.reset( 442 audio_clock_.reset(
437 new AudioClock(base::TimeDelta(), audio_parameters_.sample_rate())); 443 new AudioClock(base::TimeDelta(), audio_parameters_.sample_rate()));
438 444
439 audio_buffer_stream_->Initialize( 445 audio_buffer_stream_->Initialize(
440 stream, base::Bind(&AudioRendererImpl::OnAudioBufferStreamInitialized, 446 stream, base::Bind(&AudioRendererImpl::OnAudioBufferStreamInitialized,
441 weak_factory_.GetWeakPtr()), 447 weak_factory_.GetWeakPtr()),
442 cdm_context, base::Bind(&AudioRendererImpl::OnStatisticsUpdate, 448 cdm_context, base::Bind(&AudioRendererImpl::OnStatisticsUpdate,
443 weak_factory_.GetWeakPtr()), 449 weak_factory_.GetWeakPtr()),
444 base::Bind(&AudioRendererImpl::OnWaitingForDecryptionKey, 450 base::Bind(&AudioRendererImpl::OnWaitingForDecryptionKey,
445 weak_factory_.GetWeakPtr())); 451 weak_factory_.GetWeakPtr()));
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after
573 DVLOG(1) << __func__ << " Updating audio sample_rate." 579 DVLOG(1) << __func__ << " Updating audio sample_rate."
574 << " ts:" << buffer->timestamp().InMicroseconds() 580 << " ts:" << buffer->timestamp().InMicroseconds()
575 << " old:" << last_decoded_sample_rate_ 581 << " old:" << last_decoded_sample_rate_
576 << " new:" << buffer->sample_rate(); 582 << " new:" << buffer->sample_rate();
577 OnConfigChange(); 583 OnConfigChange();
578 } 584 }
579 last_decoded_sample_rate_ = buffer->sample_rate(); 585 last_decoded_sample_rate_ = buffer->sample_rate();
580 586
581 if (last_decoded_channel_layout_ != buffer->channel_layout()) { 587 if (last_decoded_channel_layout_ != buffer->channel_layout()) {
582 last_decoded_channel_layout_ = buffer->channel_layout(); 588 last_decoded_channel_layout_ = buffer->channel_layout();
589 last_decoded_channels_ = buffer->channel_count();
583 590
584 // Input layouts should never be discrete. 591 // Input layouts should never be discrete.
585 DCHECK_NE(last_decoded_channel_layout_, CHANNEL_LAYOUT_DISCRETE); 592 DCHECK_NE(last_decoded_channel_layout_, CHANNEL_LAYOUT_DISCRETE);
586 ConfigureChannelMask(); 593 ConfigureChannelMask();
587 } 594 }
588 } 595 }
589 596
590 DCHECK(buffer_converter_); 597 DCHECK(buffer_converter_);
591 buffer_converter_->AddInput(buffer); 598 buffer_converter_->AddInput(buffer);
592 599
(...skipping 365 matching lines...) Expand 10 before | Expand all | Expand 10 after
958 task_runner_->PostTask( 965 task_runner_->PostTask(
959 FROM_HERE, base::Bind(&AudioRendererImpl::OnBufferingStateChange, 966 FROM_HERE, base::Bind(&AudioRendererImpl::OnBufferingStateChange,
960 weak_factory_.GetWeakPtr(), buffering_state_)); 967 weak_factory_.GetWeakPtr(), buffering_state_));
961 } 968 }
962 969
963 void AudioRendererImpl::ConfigureChannelMask() { 970 void AudioRendererImpl::ConfigureChannelMask() {
964 DCHECK(algorithm_); 971 DCHECK(algorithm_);
965 DCHECK(audio_parameters_.IsValid()); 972 DCHECK(audio_parameters_.IsValid());
966 DCHECK_NE(last_decoded_channel_layout_, CHANNEL_LAYOUT_NONE); 973 DCHECK_NE(last_decoded_channel_layout_, CHANNEL_LAYOUT_NONE);
967 DCHECK_NE(last_decoded_channel_layout_, CHANNEL_LAYOUT_UNSUPPORTED); 974 DCHECK_NE(last_decoded_channel_layout_, CHANNEL_LAYOUT_UNSUPPORTED);
968 DCHECK_NE(last_decoded_channel_layout_, CHANNEL_LAYOUT_DISCRETE);
969 975
970 const int input_channel_count = 976 const int input_channel_count =
DaleCurtis 2017/03/20 17:38:58 Just always use last_decoded_channels_ ?
flim-chromium 2017/03/22 06:20:51 Done.
971 ChannelLayoutToChannelCount(last_decoded_channel_layout_); 977 last_decoded_channel_layout_ == CHANNEL_LAYOUT_DISCRETE
978 ? last_decoded_channels_
979 : ChannelLayoutToChannelCount(last_decoded_channel_layout_);
972 980
973 // If we're actually downmixing the signal, no mask is necessary, but ensure 981 // If we're actually downmixing the signal, no mask is necessary, but ensure
974 // we clear any existing mask if present. 982 // we clear any existing mask if present.
975 if (input_channel_count >= audio_parameters_.channels()) { 983 if (input_channel_count >= audio_parameters_.channels()) {
976 algorithm_->SetChannelMask( 984 algorithm_->SetChannelMask(
977 std::vector<bool>(audio_parameters_.channels(), true)); 985 std::vector<bool>(audio_parameters_.channels(), true));
978 return; 986 return;
979 } 987 }
980 988
981 // Determine the matrix used to upmix the channels. 989 // Determine the matrix used to upmix the channels.
982 std::vector<std::vector<float>> matrix; 990 std::vector<std::vector<float>> matrix;
983 ChannelMixingMatrix(last_decoded_channel_layout_, input_channel_count, 991 ChannelMixingMatrix(last_decoded_channel_layout_, input_channel_count,
984 audio_parameters_.channel_layout(), 992 audio_parameters_.channel_layout(),
985 audio_parameters_.channels()) 993 audio_parameters_.channels())
986 .CreateTransformationMatrix(&matrix); 994 .CreateTransformationMatrix(&matrix);
987 995
988 // All channels with a zero mix are muted and can be ignored. 996 // All channels with a zero mix are muted and can be ignored.
989 std::vector<bool> channel_mask(audio_parameters_.channels(), false); 997 std::vector<bool> channel_mask(audio_parameters_.channels(), false);
990 for (size_t ch = 0; ch < matrix.size(); ++ch) { 998 for (size_t ch = 0; ch < matrix.size(); ++ch) {
991 channel_mask[ch] = std::any_of(matrix[ch].begin(), matrix[ch].end(), 999 channel_mask[ch] = std::any_of(matrix[ch].begin(), matrix[ch].end(),
992 [](float mix) { return !!mix; }); 1000 [](float mix) { return !!mix; });
993 } 1001 }
994 algorithm_->SetChannelMask(std::move(channel_mask)); 1002 algorithm_->SetChannelMask(std::move(channel_mask));
995 } 1003 }
996 1004
997 } // namespace media 1005 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698