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

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

Issue 2466463005: Support (E)AC3 passthrough
Patch Set: Improve CastMediaClient::IsSupportedPassthroughAudio() Created 4 years, 1 month 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>
11 11
12 #include "base/bind.h" 12 #include "base/bind.h"
13 #include "base/callback.h" 13 #include "base/callback.h"
14 #include "base/callback_helpers.h" 14 #include "base/callback_helpers.h"
15 #include "base/command_line.h" 15 #include "base/command_line.h"
16 #include "base/logging.h" 16 #include "base/logging.h"
17 #include "base/power_monitor/power_monitor.h" 17 #include "base/power_monitor/power_monitor.h"
18 #include "base/single_thread_task_runner.h" 18 #include "base/single_thread_task_runner.h"
19 #include "base/time/default_tick_clock.h" 19 #include "base/time/default_tick_clock.h"
20 #include "build/build_config.h" 20 #include "build/build_config.h"
21 #include "media/base/audio_buffer.h" 21 #include "media/base/audio_buffer.h"
22 #include "media/base/audio_buffer_converter.h" 22 #include "media/base/audio_buffer_converter.h"
23 #include "media/base/audio_latency.h" 23 #include "media/base/audio_latency.h"
24 #include "media/base/audio_splicer.h" 24 #include "media/base/audio_splicer.h"
25 #include "media/base/bind_to_current_loop.h" 25 #include "media/base/bind_to_current_loop.h"
26 #include "media/base/demuxer_stream.h" 26 #include "media/base/demuxer_stream.h"
27 #include "media/base/media_client.h"
27 #include "media/base/media_log.h" 28 #include "media/base/media_log.h"
28 #include "media/base/media_switches.h" 29 #include "media/base/media_switches.h"
29 #include "media/base/renderer_client.h" 30 #include "media/base/renderer_client.h"
30 #include "media/base/timestamp_constants.h" 31 #include "media/base/timestamp_constants.h"
31 #include "media/filters/audio_clock.h" 32 #include "media/filters/audio_clock.h"
32 #include "media/filters/decrypting_demuxer_stream.h" 33 #include "media/filters/decrypting_demuxer_stream.h"
33 34
34 namespace media { 35 namespace media {
35 36
37 static const int kMaxFramesPerCompressedAudioBuffer = 4096;
38
36 AudioRendererImpl::AudioRendererImpl( 39 AudioRendererImpl::AudioRendererImpl(
37 const scoped_refptr<base::SingleThreadTaskRunner>& task_runner, 40 const scoped_refptr<base::SingleThreadTaskRunner>& task_runner,
38 media::AudioRendererSink* sink, 41 media::AudioRendererSink* sink,
39 ScopedVector<AudioDecoder> decoders, 42 ScopedVector<AudioDecoder> decoders,
40 const scoped_refptr<MediaLog>& media_log) 43 const scoped_refptr<MediaLog>& media_log)
41 : task_runner_(task_runner), 44 : task_runner_(task_runner),
42 expecting_config_changes_(false), 45 expecting_config_changes_(false),
43 sink_(sink), 46 sink_(sink),
44 audio_buffer_stream_( 47 audio_buffer_stream_(
45 new AudioBufferStream(task_runner, std::move(decoders), media_log)), 48 new AudioBufferStream(task_runner, std::move(decoders), media_log)),
46 media_log_(media_log), 49 media_log_(media_log),
47 client_(nullptr), 50 client_(nullptr),
48 tick_clock_(new base::DefaultTickClock()), 51 tick_clock_(new base::DefaultTickClock()),
49 last_audio_memory_usage_(0), 52 last_audio_memory_usage_(0),
50 last_decoded_sample_rate_(0), 53 last_decoded_sample_rate_(0),
51 playback_rate_(0.0), 54 playback_rate_(0.0),
52 state_(kUninitialized), 55 state_(kUninitialized),
53 buffering_state_(BUFFERING_HAVE_NOTHING), 56 buffering_state_(BUFFERING_HAVE_NOTHING),
54 rendering_(false), 57 rendering_(false),
55 sink_playing_(false), 58 sink_playing_(false),
56 pending_read_(false), 59 pending_read_(false),
57 received_end_of_stream_(false), 60 received_end_of_stream_(false),
58 rendered_end_of_stream_(false), 61 rendered_end_of_stream_(false),
59 is_suspending_(false), 62 is_suspending_(false),
63 is_passthrough_(false),
60 last_reported_media_time_(kNoTimestamp), 64 last_reported_media_time_(kNoTimestamp),
61 weak_factory_(this) { 65 weak_factory_(this) {
62 audio_buffer_stream_->set_splice_observer(base::Bind( 66 audio_buffer_stream_->set_splice_observer(base::Bind(
63 &AudioRendererImpl::OnNewSpliceBuffer, weak_factory_.GetWeakPtr())); 67 &AudioRendererImpl::OnNewSpliceBuffer, weak_factory_.GetWeakPtr()));
64 audio_buffer_stream_->set_config_change_observer(base::Bind( 68 audio_buffer_stream_->set_config_change_observer(base::Bind(
65 &AudioRendererImpl::OnConfigChange, weak_factory_.GetWeakPtr())); 69 &AudioRendererImpl::OnConfigChange, weak_factory_.GetWeakPtr()));
66 70
67 // Tests may not have a power monitor. 71 // Tests may not have a power monitor.
68 base::PowerMonitor* monitor = base::PowerMonitor::Get(); 72 base::PowerMonitor* monitor = base::PowerMonitor::Get();
69 if (!monitor) 73 if (!monitor)
(...skipping 287 matching lines...) Expand 10 before | Expand all | Expand 10 after
357 DCHECK_EQ(kUninitialized, state_); 361 DCHECK_EQ(kUninitialized, state_);
358 DCHECK(sink_.get()); 362 DCHECK(sink_.get());
359 363
360 state_ = kInitializing; 364 state_ = kInitializing;
361 client_ = client; 365 client_ = client;
362 366
363 // Always post |init_cb_| because |this| could be destroyed if initialization 367 // Always post |init_cb_| because |this| could be destroyed if initialization
364 // failed. 368 // failed.
365 init_cb_ = BindToCurrentLoop(init_cb); 369 init_cb_ = BindToCurrentLoop(init_cb);
366 370
371 AudioCodec codec = stream->audio_decoder_config().codec();
372 MediaClient* media_client = GetMediaClient();
373 is_passthrough_ =
374 media_client && media_client->IsSupportedPassthroughAudio(codec);
375
367 const AudioParameters& hw_params = 376 const AudioParameters& hw_params =
368 sink_->GetOutputDeviceInfo().output_params(); 377 sink_->GetOutputDeviceInfo().output_params();
369 expecting_config_changes_ = stream->SupportsConfigChanges(); 378 expecting_config_changes_ = stream->SupportsConfigChanges();
370 if (!expecting_config_changes_ || !hw_params.IsValid() || 379
371 hw_params.format() == AudioParameters::AUDIO_FAKE) { 380 if (is_passthrough_) {
381 AudioParameters::Format format = AudioParameters::AUDIO_FAKE;
382 if (codec == kCodecAC3) {
383 format = AudioParameters::AUDIO_RAW_AC3;
384 } else if (codec == kCodecEAC3) {
385 format = AudioParameters::AUDIO_RAW_EAC3;
386 } else {
387 NOTREACHED();
388 }
389
390 const int buffer_size = kMaxFramesPerCompressedAudioBuffer *
391 stream->audio_decoder_config().bytes_per_frame();
392
393 audio_parameters_.Reset(
394 format, stream->audio_decoder_config().channel_layout(),
395 stream->audio_decoder_config().samples_per_second(),
396 stream->audio_decoder_config().bits_per_channel(), buffer_size);
397 buffer_converter_.reset();
398 } else if (!expecting_config_changes_ || !hw_params.IsValid() ||
399 hw_params.format() == AudioParameters::AUDIO_FAKE) {
372 // The actual buffer size is controlled via the size of the AudioBus 400 // The actual buffer size is controlled via the size of the AudioBus
373 // provided to Render(), but we should choose a value here based on hardware 401 // provided to Render(), but we should choose a value here based on hardware
374 // parameters if possible since it affects the initial buffer size used by 402 // parameters if possible since it affects the initial buffer size used by
375 // the algorithm. Too little will cause underflow on Bluetooth devices. 403 // the algorithm. Too little will cause underflow on Bluetooth devices.
376 int buffer_size = 404 int buffer_size =
377 std::max(stream->audio_decoder_config().samples_per_second() / 100, 405 std::max(stream->audio_decoder_config().samples_per_second() / 100,
378 hw_params.IsValid() ? hw_params.frames_per_buffer() : 0); 406 hw_params.IsValid() ? hw_params.frames_per_buffer() : 0);
379 audio_parameters_.Reset(AudioParameters::AUDIO_PCM_LOW_LATENCY, 407 audio_parameters_.Reset(AudioParameters::AUDIO_PCM_LOW_LATENCY,
380 stream->audio_decoder_config().channel_layout(), 408 stream->audio_decoder_config().channel_layout(),
381 stream->audio_decoder_config().samples_per_second(), 409 stream->audio_decoder_config().samples_per_second(),
(...skipping 191 matching lines...) Expand 10 before | Expand all | Expand 10 after
573 601
574 DCHECK_EQ(status, AudioBufferStream::OK); 602 DCHECK_EQ(status, AudioBufferStream::OK);
575 DCHECK(buffer.get()); 603 DCHECK(buffer.get());
576 604
577 if (state_ == kFlushing) { 605 if (state_ == kFlushing) {
578 ChangeState_Locked(kFlushed); 606 ChangeState_Locked(kFlushed);
579 DoFlush_Locked(); 607 DoFlush_Locked();
580 return; 608 return;
581 } 609 }
582 610
611 if (buffer->sample_format() == kSampleFormatRaw) {
612 if (last_decoded_sample_rate_ &&
613 buffer->sample_rate() != last_decoded_sample_rate_) {
614 OnConfigChange();
615 }
616 last_decoded_sample_rate_ = buffer->sample_rate();
617
618 if (!HandleSplicerBuffer_Locked(buffer) && !CanRead_Locked())
619 return;
620
621 AttemptRead_Locked();
622 return;
623 }
624
583 if (expecting_config_changes_) { 625 if (expecting_config_changes_) {
584 if (last_decoded_sample_rate_ && 626 if (last_decoded_sample_rate_ &&
585 buffer->sample_rate() != last_decoded_sample_rate_) { 627 buffer->sample_rate() != last_decoded_sample_rate_) {
586 DVLOG(1) << __func__ << " Updating audio sample_rate." 628 DVLOG(1) << __func__ << " Updating audio sample_rate."
587 << " ts:" << buffer->timestamp().InMicroseconds() 629 << " ts:" << buffer->timestamp().InMicroseconds()
588 << " old:" << last_decoded_sample_rate_ 630 << " old:" << last_decoded_sample_rate_
589 << " new:" << buffer->sample_rate(); 631 << " new:" << buffer->sample_rate();
590 OnConfigChange(); 632 OnConfigChange();
591 } 633 }
592 last_decoded_sample_rate_ = buffer->sample_rate(); 634 last_decoded_sample_rate_ = buffer->sample_rate();
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
640 682
641 AttemptRead_Locked(); 683 AttemptRead_Locked();
642 } 684 }
643 685
644 bool AudioRendererImpl::HandleSplicerBuffer_Locked( 686 bool AudioRendererImpl::HandleSplicerBuffer_Locked(
645 const scoped_refptr<AudioBuffer>& buffer) { 687 const scoped_refptr<AudioBuffer>& buffer) {
646 lock_.AssertAcquired(); 688 lock_.AssertAcquired();
647 if (buffer->end_of_stream()) { 689 if (buffer->end_of_stream()) {
648 received_end_of_stream_ = true; 690 received_end_of_stream_ = true;
649 } else { 691 } else {
650 if (state_ == kPlaying) { 692 if (state_ == kPlaying && buffer->sample_format() != kSampleFormatRaw) {
DaleCurtis 2016/11/01 23:05:13 This is incorrect, seeking is going to return the
AndyWu 2016/11/04 18:04:24 Thanks for pointing it out. Mark reporting time as
DaleCurtis 2016/11/04 19:48:29 No, AV sync will never recover for this case since
AndyWu 2016/11/08 00:04:21 I see. I reset start_timestamp_and audio_clock_in
DaleCurtis 2016/11/08 00:11:47 I don't think this will work. There is code in oth
watk 2016/11/08 19:59:30 PipelineImpl::GetMediaTime() tracks the last repor
AndyWu 2016/11/11 17:52:48 Thanks a lot for your information. I guess I can d
651 if (IsBeforeStartTime(buffer)) 693 if (IsBeforeStartTime(buffer))
652 return true; 694 return true;
653 695
654 // Trim off any additional time before the start timestamp. 696 // Trim off any additional time before the start timestamp.
655 const base::TimeDelta trim_time = start_timestamp_ - buffer->timestamp(); 697 const base::TimeDelta trim_time = start_timestamp_ - buffer->timestamp();
656 if (trim_time > base::TimeDelta()) { 698 if (trim_time > base::TimeDelta()) {
657 buffer->TrimStart(buffer->frame_count() * 699 buffer->TrimStart(buffer->frame_count() *
658 (static_cast<double>(trim_time.InMicroseconds()) / 700 (static_cast<double>(trim_time.InMicroseconds()) /
659 buffer->duration().InMicroseconds())); 701 buffer->duration().InMicroseconds()));
660 buffer->set_timestamp(start_timestamp_); 702 buffer->set_timestamp(start_timestamp_);
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
731 return false; 773 return false;
732 774
733 case kPlaying: 775 case kPlaying:
734 break; 776 break;
735 } 777 }
736 778
737 return !pending_read_ && !received_end_of_stream_ && 779 return !pending_read_ && !received_end_of_stream_ &&
738 !algorithm_->IsQueueFull(); 780 !algorithm_->IsQueueFull();
739 } 781 }
740 782
741 void AudioRendererImpl::SetPlaybackRate(double playback_rate) { 783 void AudioRendererImpl::SetPlaybackRate(double playback_rate) {
DaleCurtis 2016/11/01 23:05:13 Values other than 0 or 1 need to be ignored when o
AndyWu 2016/11/04 18:04:24 Done.
742 DVLOG(1) << __func__ << "(" << playback_rate << ")"; 784 DVLOG(1) << __func__ << "(" << playback_rate << ")";
743 DCHECK(task_runner_->BelongsToCurrentThread()); 785 DCHECK(task_runner_->BelongsToCurrentThread());
744 DCHECK_GE(playback_rate, 0); 786 DCHECK_GE(playback_rate, 0);
745 DCHECK(sink_.get()); 787 DCHECK(sink_.get());
746 788
747 base::AutoLock auto_lock(lock_); 789 base::AutoLock auto_lock(lock_);
748 790
749 // We have two cases here: 791 // We have two cases here:
750 // Play: current_playback_rate == 0 && playback_rate != 0 792 // Play: current_playback_rate == 0 && playback_rate != 0
751 // Pause: current_playback_rate != 0 && playback_rate == 0 793 // Pause: current_playback_rate != 0 && playback_rate == 0
(...skipping 17 matching lines...) Expand all
769 bool AudioRendererImpl::IsBeforeStartTime( 811 bool AudioRendererImpl::IsBeforeStartTime(
770 const scoped_refptr<AudioBuffer>& buffer) { 812 const scoped_refptr<AudioBuffer>& buffer) {
771 DCHECK_EQ(state_, kPlaying); 813 DCHECK_EQ(state_, kPlaying);
772 return buffer.get() && !buffer->end_of_stream() && 814 return buffer.get() && !buffer->end_of_stream() &&
773 (buffer->timestamp() + buffer->duration()) < start_timestamp_; 815 (buffer->timestamp() + buffer->duration()) < start_timestamp_;
774 } 816 }
775 817
776 int AudioRendererImpl::Render(AudioBus* audio_bus, 818 int AudioRendererImpl::Render(AudioBus* audio_bus,
777 uint32_t frames_delayed, 819 uint32_t frames_delayed,
778 uint32_t frames_skipped) { 820 uint32_t frames_skipped) {
779 const int frames_requested = audio_bus->frames(); 821 int frames_requested = audio_bus->frames();
780 DVLOG(4) << __func__ << " frames_delayed:" << frames_delayed 822 DVLOG(4) << __func__ << " frames_delayed:" << frames_delayed
781 << " frames_skipped:" << frames_skipped 823 << " frames_skipped:" << frames_skipped
782 << " frames_requested:" << frames_requested; 824 << " frames_requested:" << frames_requested;
783 825
784 int frames_written = 0; 826 int frames_written = 0;
785 { 827 {
786 base::AutoLock auto_lock(lock_); 828 base::AutoLock auto_lock(lock_);
787 last_render_time_ = tick_clock_->NowTicks(); 829 last_render_time_ = tick_clock_->NowTicks();
788 830
789 if (!stop_rendering_time_.is_null()) { 831 if (!stop_rendering_time_.is_null()) {
(...skipping 15 matching lines...) Expand all
805 return 0; 847 return 0;
806 } 848 }
807 849
808 // Mute audio by returning 0 when not playing. 850 // Mute audio by returning 0 when not playing.
809 if (state_ != kPlaying) { 851 if (state_ != kPlaying) {
810 audio_clock_->WroteAudio(0, frames_requested, frames_delayed, 852 audio_clock_->WroteAudio(0, frames_requested, frames_delayed,
811 playback_rate_); 853 playback_rate_);
812 return 0; 854 return 0;
813 } 855 }
814 856
815 // Delay playback by writing silence if we haven't reached the first 857 if (is_passthrough_ && algorithm_->frames_buffered() > 0) {
816 // timestamp yet; this can occur if the video starts before the audio. 858 frames_written += algorithm_->FillBuffer(audio_bus, 0, frames_requested,
817 if (algorithm_->frames_buffered() > 0) { 859 playback_rate_);
860 frames_requested = frames_written;
861 } else if (algorithm_->frames_buffered() > 0) {
862 // Delay playback by writing silence if we haven't reached the first
863 // timestamp yet; this can occur if the video starts before the audio.
818 CHECK_NE(first_packet_timestamp_, kNoTimestamp); 864 CHECK_NE(first_packet_timestamp_, kNoTimestamp);
819 CHECK_GE(first_packet_timestamp_, base::TimeDelta()); 865 CHECK_GE(first_packet_timestamp_, base::TimeDelta());
820 const base::TimeDelta play_delay = 866 const base::TimeDelta play_delay =
821 first_packet_timestamp_ - audio_clock_->back_timestamp(); 867 first_packet_timestamp_ - audio_clock_->back_timestamp();
822 if (play_delay > base::TimeDelta()) { 868 if (play_delay > base::TimeDelta()) {
823 DCHECK_EQ(frames_written, 0); 869 DCHECK_EQ(frames_written, 0);
824 870
825 // Don't multiply |play_delay| out since it can be a huge value on 871 // Don't multiply |play_delay| out since it can be a huge value on
826 // poorly encoded media and multiplying by the sample rate could cause 872 // poorly encoded media and multiplying by the sample rate could cause
827 // the value to overflow. 873 // the value to overflow.
(...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after
977 DCHECK_NE(buffering_state_, buffering_state); 1023 DCHECK_NE(buffering_state_, buffering_state);
978 lock_.AssertAcquired(); 1024 lock_.AssertAcquired();
979 buffering_state_ = buffering_state; 1025 buffering_state_ = buffering_state;
980 1026
981 task_runner_->PostTask( 1027 task_runner_->PostTask(
982 FROM_HERE, base::Bind(&AudioRendererImpl::OnBufferingStateChange, 1028 FROM_HERE, base::Bind(&AudioRendererImpl::OnBufferingStateChange,
983 weak_factory_.GetWeakPtr(), buffering_state_)); 1029 weak_factory_.GetWeakPtr(), buffering_state_));
984 } 1030 }
985 1031
986 } // namespace media 1032 } // namespace media
OLDNEW
« media/filters/android/media_codec_audio_decoder.cc ('K') | « media/renderers/audio_renderer_impl.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698