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

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

Issue 2752323002: Support Opus Ambisonics playback (Closed)
Patch Set: +pipeline integration tests, +test media, minor fixes 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 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(
366 stream->audio_decoder_config().channels());
364 buffer_converter_.reset(); 367 buffer_converter_.reset();
365 } else { 368 } else {
366 // To allow for seamless sample rate adaptations (i.e. changes from say 369 // To allow for seamless sample rate adaptations (i.e. changes from say
367 // 16kHz to 48kHz), always resample to the hardware rate. 370 // 16kHz to 48kHz), always resample to the hardware rate.
368 int sample_rate = hw_params.sample_rate(); 371 int sample_rate = hw_params.sample_rate();
369 int preferred_buffer_size = hw_params.frames_per_buffer(); 372 int preferred_buffer_size = hw_params.frames_per_buffer();
370 373
371 #if defined(OS_CHROMEOS) 374 #if defined(OS_CHROMEOS)
372 // On ChromeOS let the OS level resampler handle resampling unless the 375 // On ChromeOS let the OS level resampler handle resampling unless the
373 // initial sample rate is too low; this allows support for sample rate 376 // initial sample rate is too low; this allows support for sample rate
374 // adaptations where necessary. 377 // adaptations where necessary.
375 if (stream->audio_decoder_config().samples_per_second() >= 44100) { 378 if (stream->audio_decoder_config().samples_per_second() >= 44100) {
376 sample_rate = stream->audio_decoder_config().samples_per_second(); 379 sample_rate = stream->audio_decoder_config().samples_per_second();
377 preferred_buffer_size = 0; // No preference. 380 preferred_buffer_size = 0; // No preference.
378 } 381 }
379 #endif 382 #endif
380 383
381 int stream_channel_count = ChannelLayoutToChannelCount( 384 int stream_channel_count = stream->audio_decoder_config().channels();
382 stream->audio_decoder_config().channel_layout());
383 385
384 bool try_supported_channel_layouts = false; 386 bool try_supported_channel_layouts = false;
385 #if defined(OS_WIN) 387 #if defined(OS_WIN)
386 try_supported_channel_layouts = 388 try_supported_channel_layouts =
387 base::CommandLine::ForCurrentProcess()->HasSwitch( 389 base::CommandLine::ForCurrentProcess()->HasSwitch(
388 switches::kTrySupportedChannelLayouts); 390 switches::kTrySupportedChannelLayouts);
389 #endif 391 #endif
390 392
391 // We don't know how to up-mix for DISCRETE layouts (fancy multichannel 393 // We don't know how to up-mix for DISCRETE layouts (fancy multichannel
392 // hardware with non-standard speaker arrangement). Instead, pretend the 394 // hardware with non-standard speaker arrangement). Instead, pretend the
(...skipping 19 matching lines...) Expand all
412 // premature down-mixing - http://crbug.com/379288). 414 // premature down-mixing - http://crbug.com/379288).
413 // If stream_channels < hw_channels: 415 // If stream_channels < hw_channels:
414 // Taking max means we up-mix to hardware layout. If stream later changes 416 // 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 417 // to have more channels, we aren't locked into down-mixing to the
416 // initial stream layout. 418 // initial stream layout.
417 // If stream_channels > hw_channels: 419 // If stream_channels > hw_channels:
418 // We choose to output stream's layout, meaning mixing is a no-op for the 420 // 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 421 // renderer. Browser-side will down-mix to the hardware config. If the
420 // hardware later changes to equal stream channels, browser-side will stop 422 // hardware later changes to equal stream channels, browser-side will stop
421 // down-mixing and use the data from all stream channels. 423 // down-mixing and use the data from all stream channels.
424 bool use_hw_config = hw_channel_count > stream_channel_count;
422 ChannelLayout renderer_channel_layout = 425 ChannelLayout renderer_channel_layout =
423 hw_channel_count > stream_channel_count 426 use_hw_config ? hw_channel_layout
424 ? hw_channel_layout 427 : stream->audio_decoder_config().channel_layout();
425 : stream->audio_decoder_config().channel_layout();
426 428
427 audio_parameters_.Reset(hw_params.format(), renderer_channel_layout, 429 audio_parameters_.Reset(hw_params.format(), renderer_channel_layout,
428 sample_rate, hw_params.bits_per_sample(), 430 sample_rate, hw_params.bits_per_sample(),
429 media::AudioLatency::GetHighLatencyBufferSize( 431 media::AudioLatency::GetHighLatencyBufferSize(
430 sample_rate, preferred_buffer_size)); 432 sample_rate, preferred_buffer_size));
433 if (!use_hw_config)
434 audio_parameters_.set_channels_for_discrete(stream_channel_count);
431 } 435 }
432 436
433 last_decoded_channel_layout_ = 437 last_decoded_channel_layout_ =
434 stream->audio_decoder_config().channel_layout(); 438 stream->audio_decoder_config().channel_layout();
435 439
440 last_decoded_channels_ = 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
970 const int input_channel_count =
971 ChannelLayoutToChannelCount(last_decoded_channel_layout_);
972 975
973 // If we're actually downmixing the signal, no mask is necessary, but ensure 976 // If we're actually downmixing the signal, no mask is necessary, but ensure
974 // we clear any existing mask if present. 977 // we clear any existing mask if present.
975 if (input_channel_count >= audio_parameters_.channels()) { 978 if (last_decoded_channels_ >= audio_parameters_.channels()) {
976 algorithm_->SetChannelMask( 979 algorithm_->SetChannelMask(
977 std::vector<bool>(audio_parameters_.channels(), true)); 980 std::vector<bool>(audio_parameters_.channels(), true));
978 return; 981 return;
979 } 982 }
980 983
981 // Determine the matrix used to upmix the channels. 984 // Determine the matrix used to upmix the channels.
982 std::vector<std::vector<float>> matrix; 985 std::vector<std::vector<float>> matrix;
983 ChannelMixingMatrix(last_decoded_channel_layout_, input_channel_count, 986 ChannelMixingMatrix(last_decoded_channel_layout_, last_decoded_channels_,
984 audio_parameters_.channel_layout(), 987 audio_parameters_.channel_layout(),
985 audio_parameters_.channels()) 988 audio_parameters_.channels())
986 .CreateTransformationMatrix(&matrix); 989 .CreateTransformationMatrix(&matrix);
987 990
988 // All channels with a zero mix are muted and can be ignored. 991 // All channels with a zero mix are muted and can be ignored.
989 std::vector<bool> channel_mask(audio_parameters_.channels(), false); 992 std::vector<bool> channel_mask(audio_parameters_.channels(), false);
990 for (size_t ch = 0; ch < matrix.size(); ++ch) { 993 for (size_t ch = 0; ch < matrix.size(); ++ch) {
991 channel_mask[ch] = std::any_of(matrix[ch].begin(), matrix[ch].end(), 994 channel_mask[ch] = std::any_of(matrix[ch].begin(), matrix[ch].end(),
992 [](float mix) { return !!mix; }); 995 [](float mix) { return !!mix; });
993 } 996 }
994 algorithm_->SetChannelMask(std::move(channel_mask)); 997 algorithm_->SetChannelMask(std::move(channel_mask));
995 } 998 }
996 999
997 } // namespace media 1000 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698