OLD | NEW |
---|---|
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 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
53 const scoped_refptr<MediaLog>& media_log) | 53 const scoped_refptr<MediaLog>& media_log) |
54 : task_runner_(task_runner), | 54 : task_runner_(task_runner), |
55 expecting_config_changes_(false), | 55 expecting_config_changes_(false), |
56 sink_(sink), | 56 sink_(sink), |
57 audio_buffer_stream_( | 57 audio_buffer_stream_( |
58 new AudioBufferStream(task_runner, std::move(decoders), media_log)), | 58 new AudioBufferStream(task_runner, std::move(decoders), media_log)), |
59 hardware_config_(hardware_config), | 59 hardware_config_(hardware_config), |
60 media_log_(media_log), | 60 media_log_(media_log), |
61 tick_clock_(new base::DefaultTickClock()), | 61 tick_clock_(new base::DefaultTickClock()), |
62 last_audio_memory_usage_(0), | 62 last_audio_memory_usage_(0), |
63 last_decoded_sample_rate_(0), | |
63 playback_rate_(0.0), | 64 playback_rate_(0.0), |
64 state_(kUninitialized), | 65 state_(kUninitialized), |
65 buffering_state_(BUFFERING_HAVE_NOTHING), | 66 buffering_state_(BUFFERING_HAVE_NOTHING), |
66 rendering_(false), | 67 rendering_(false), |
67 sink_playing_(false), | 68 sink_playing_(false), |
68 pending_read_(false), | 69 pending_read_(false), |
69 received_end_of_stream_(false), | 70 received_end_of_stream_(false), |
70 rendered_end_of_stream_(false), | 71 rendered_end_of_stream_(false), |
71 weak_factory_(this) { | 72 weak_factory_(this) { |
72 audio_buffer_stream_->set_splice_observer(base::Bind( | 73 audio_buffer_stream_->set_splice_observer(base::Bind( |
(...skipping 305 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
378 #if defined(OS_CHROMEOS) | 379 #if defined(OS_CHROMEOS) |
379 // On ChromeOS let the OS level resampler handle resampling unless the | 380 // On ChromeOS let the OS level resampler handle resampling unless the |
380 // initial sample rate is too low; this allows support for sample rate | 381 // initial sample rate is too low; this allows support for sample rate |
381 // adaptations where necessary. | 382 // adaptations where necessary. |
382 if (stream->audio_decoder_config().samples_per_second() >= 44100) { | 383 if (stream->audio_decoder_config().samples_per_second() >= 44100) { |
383 sample_rate = stream->audio_decoder_config().samples_per_second(); | 384 sample_rate = stream->audio_decoder_config().samples_per_second(); |
384 preferred_buffer_size = 0; // No preference. | 385 preferred_buffer_size = 0; // No preference. |
385 } | 386 } |
386 #endif | 387 #endif |
387 | 388 |
389 int stream_channel_count = ChannelLayoutToChannelCount(stream->audio_decoder _config().channel_layout()); | |
390 int fiveptone_channel_count = ChannelLayoutToChannelCount(CHANNEL_LAYOUT_5_1 ); | |
391 | |
392 // The layout we pass to |audio_parameters_| will be used for the lifetime | |
393 // of this audio renderer, regardless of changes to hardware and/or stream | |
394 // properties. Below we choose the max of stream layout vs. hardware layout | |
395 // to leave room for changes to the hardware and/or stream (i.e. avoid | |
396 // premature down-mixing). | |
397 // If stream_channels < hw_channels: | |
398 // Taking max means we up-mix to hardware layout. If stream later changes | |
399 // to have more channels, we aren't locked into down-mixing to the | |
400 // initial layout. | |
401 // If stream_channels > hw_channels: | |
402 // We choose to output stream's layout, meaning mixing is a no-op for the | |
403 // renderer. Browser-side will down-mix to the hardware config. If the | |
404 // hardware later changes to equal stream channels, browser-side will stop | |
405 // down-mixing and use the data from all stream channels. | |
406 ChannelLayout renderer_channel_layout = CHANNEL_LAYOUT_NONE; | |
407 | |
408 // WORRY: IF STREAM CHANGES, WHERE DOES MIXER LEARN OF THE NEW INPUT CHANNEL COU NT? | |
chcunningham
2016/03/17 21:48:19
This happens in AudioBufferConverter::AddBuffer. E
| |
409 // WORRY: WHERE IS BROWSER LEARNING OF NEW HW CHANNEL COUNT IF SOMETHING GETS PL UGGED IN? WHERE IS BROWSER-SIDE MIXER? | |
chcunningham
2016/03/17 21:48:19
The HW channel count is updated via audio_device_l
| |
410 // TODO ABOVE: ADD CRBUGS TO COMMENT. ADD TODO FOR TO BE ABLE TO CHANGE LAYOUTS ON FLY | |
411 // TODO BELOW: TRY USING INTERMEDIATE hw_layout = discrete ? 5.1 : hw_params TO SIMPLIFY CODE. | |
412 | |
413 | |
414 // We don't know how to mix for DISCRETE layouts (fancy multichannel | |
415 // hardware). Instead we choose the max of 5.1 and the stream layout with | |
416 // the hope that the OS will know best how to up-mix to the DISCRETE layout. | |
417 // Choosing the max avoids pre-maturely down-mixing. | |
418 if (hw_params.channel_layout() == CHANNEL_LAYOUT_DISCRETE) { | |
DaleCurtis
2016/03/18 00:16:23
Why not just always use the discrete layout in thi
chcunningham
2016/03/25 01:41:16
We chatted - thing is we aren't confident that we
| |
419 renderer_channel_layout = stream_channel_count < fiveptone_channel_count ? | |
420 CHANNEL_LAYOUT_5_1 : stream->audio_decoder_config().channel_layout(); | |
421 } else { | |
422 // For all non-discrete layouts we know how to up-mix to the hardware | |
423 // layout. Using the max of stream and hardware channel counts avoids | |
424 // premature down-mixing should either the stream or hardware later change | |
425 // to have more channels. | |
426 renderer_channel_layout = stream_channel_count < ChannelLayoutToChannelCou nt(hw_params.channel_layout()) ? | |
427 hw_params.channel_layout() : stream->audio_decoder_config().channel_la yout(); | |
428 } | |
429 | |
388 audio_parameters_.Reset( | 430 audio_parameters_.Reset( |
389 hw_params.format(), | 431 hw_params.format(), |
390 // Always use the source's channel layout to avoid premature downmixing | 432 renderer_channel_layout, |
391 // (http://crbug.com/379288), platform specific issues around channel | 433 sample_rate, |
392 // layouts (http://crbug.com/266674), and unnecessary upmixing overhead. | |
393 stream->audio_decoder_config().channel_layout(), sample_rate, | |
394 hw_params.bits_per_sample(), | 434 hw_params.bits_per_sample(), |
395 AudioHardwareConfig::GetHighLatencyBufferSize(sample_rate, | 435 AudioHardwareConfig::GetHighLatencyBufferSize(sample_rate, |
396 preferred_buffer_size)); | 436 preferred_buffer_size)); |
397 } | 437 } |
398 | 438 |
399 audio_clock_.reset( | 439 audio_clock_.reset( |
400 new AudioClock(base::TimeDelta(), audio_parameters_.sample_rate())); | 440 new AudioClock(base::TimeDelta(), audio_parameters_.sample_rate())); |
401 | 441 |
402 audio_buffer_stream_->Initialize( | 442 audio_buffer_stream_->Initialize( |
403 stream, base::Bind(&AudioRendererImpl::OnAudioBufferStreamInitialized, | 443 stream, base::Bind(&AudioRendererImpl::OnAudioBufferStreamInitialized, |
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
483 DCHECK_EQ(status, AudioBufferStream::OK); | 523 DCHECK_EQ(status, AudioBufferStream::OK); |
484 DCHECK(buffer.get()); | 524 DCHECK(buffer.get()); |
485 | 525 |
486 if (state_ == kFlushing) { | 526 if (state_ == kFlushing) { |
487 ChangeState_Locked(kFlushed); | 527 ChangeState_Locked(kFlushed); |
488 DoFlush_Locked(); | 528 DoFlush_Locked(); |
489 return; | 529 return; |
490 } | 530 } |
491 | 531 |
492 if (expecting_config_changes_) { | 532 if (expecting_config_changes_) { |
533 if (buffer->sample_rate() != last_decoded_sample_rate_) { | |
534 DVLOG(1) << __FUNCTION__ << " Updating audio sample_rate." | |
535 << " ts:" << buffer->timestamp().InMicroseconds() | |
536 << " old:" << last_decoded_sample_rate_ | |
537 << " new:" << buffer->sample_rate(); | |
538 OnConfigChange(); | |
539 } | |
540 last_decoded_sample_rate_ = buffer->sample_rate(); | |
541 | |
493 DCHECK(buffer_converter_); | 542 DCHECK(buffer_converter_); |
494 buffer_converter_->AddInput(buffer); | 543 buffer_converter_->AddInput(buffer); |
495 while (buffer_converter_->HasNextBuffer()) { | 544 while (buffer_converter_->HasNextBuffer()) { |
496 if (!splicer_->AddInput(buffer_converter_->GetNextBuffer())) { | 545 if (!splicer_->AddInput(buffer_converter_->GetNextBuffer())) { |
497 HandleAbortedReadOrDecodeError(true); | 546 HandleAbortedReadOrDecodeError(true); |
498 return; | 547 return; |
499 } | 548 } |
500 } | 549 } |
501 } else { | 550 } else { |
502 if (!splicer_->AddInput(buffer)) { | 551 if (!splicer_->AddInput(buffer)) { |
(...skipping 346 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
849 << buffering_state; | 898 << buffering_state; |
850 DCHECK_NE(buffering_state_, buffering_state); | 899 DCHECK_NE(buffering_state_, buffering_state); |
851 lock_.AssertAcquired(); | 900 lock_.AssertAcquired(); |
852 buffering_state_ = buffering_state; | 901 buffering_state_ = buffering_state; |
853 | 902 |
854 task_runner_->PostTask(FROM_HERE, | 903 task_runner_->PostTask(FROM_HERE, |
855 base::Bind(buffering_state_cb_, buffering_state_)); | 904 base::Bind(buffering_state_cb_, buffering_state_)); |
856 } | 905 } |
857 | 906 |
858 } // namespace media | 907 } // namespace media |
OLD | NEW |