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/filters/audio_renderer_impl.h" | 5 #include "media/filters/audio_renderer_impl.h" |
6 | 6 |
7 #include <math.h> | 7 #include <math.h> |
8 | 8 |
9 #include <algorithm> | 9 #include <algorithm> |
10 | 10 |
11 #include "base/bind.h" | 11 #include "base/bind.h" |
12 #include "base/callback.h" | 12 #include "base/callback.h" |
13 #include "base/callback_helpers.h" | 13 #include "base/callback_helpers.h" |
14 #include "base/logging.h" | 14 #include "base/logging.h" |
15 #include "base/metrics/histogram.h" | 15 #include "base/metrics/histogram.h" |
16 #include "base/single_thread_task_runner.h" | 16 #include "base/single_thread_task_runner.h" |
17 #include "media/base/audio_buffer.h" | 17 #include "media/base/audio_buffer.h" |
18 #include "media/base/audio_buffer_converter.h" | 18 #include "media/base/audio_buffer_converter.h" |
19 #include "media/base/audio_hardware_config.h" | 19 #include "media/base/audio_hardware_config.h" |
20 #include "media/base/audio_splicer.h" | 20 #include "media/base/audio_splicer.h" |
21 #include "media/base/bind_to_current_loop.h" | 21 #include "media/base/bind_to_current_loop.h" |
22 #include "media/base/demuxer_stream.h" | 22 #include "media/base/demuxer_stream.h" |
| 23 #include "media/filters/audio_clock.h" |
23 #include "media/filters/decrypting_demuxer_stream.h" | 24 #include "media/filters/decrypting_demuxer_stream.h" |
24 | 25 |
25 namespace media { | 26 namespace media { |
26 | 27 |
27 namespace { | 28 namespace { |
28 | 29 |
29 enum AudioRendererEvent { | 30 enum AudioRendererEvent { |
30 INITIALIZED, | 31 INITIALIZED, |
31 RENDER_ERROR, | 32 RENDER_ERROR, |
32 RENDER_EVENT_MAX = RENDER_ERROR, | 33 RENDER_EVENT_MAX = RENDER_ERROR, |
(...skipping 17 matching lines...) Expand all Loading... |
50 audio_buffer_stream_(task_runner, | 51 audio_buffer_stream_(task_runner, |
51 decoders.Pass(), | 52 decoders.Pass(), |
52 set_decryptor_ready_cb), | 53 set_decryptor_ready_cb), |
53 hardware_config_(hardware_config), | 54 hardware_config_(hardware_config), |
54 now_cb_(base::Bind(&base::TimeTicks::Now)), | 55 now_cb_(base::Bind(&base::TimeTicks::Now)), |
55 state_(kUninitialized), | 56 state_(kUninitialized), |
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 audio_time_buffered_(kNoTimestamp()), | |
61 current_time_(kNoTimestamp()), | |
62 underflow_disabled_(false), | 61 underflow_disabled_(false), |
63 preroll_aborted_(false), | 62 preroll_aborted_(false), |
64 weak_factory_(this) { | 63 weak_factory_(this) { |
65 audio_buffer_stream_.set_splice_observer(base::Bind( | 64 audio_buffer_stream_.set_splice_observer(base::Bind( |
66 &AudioRendererImpl::OnNewSpliceBuffer, weak_factory_.GetWeakPtr())); | 65 &AudioRendererImpl::OnNewSpliceBuffer, weak_factory_.GetWeakPtr())); |
67 audio_buffer_stream_.set_config_change_observer(base::Bind( | 66 audio_buffer_stream_.set_config_change_observer(base::Bind( |
68 &AudioRendererImpl::OnConfigChange, weak_factory_.GetWeakPtr())); | 67 &AudioRendererImpl::OnConfigChange, weak_factory_.GetWeakPtr())); |
69 } | 68 } |
70 | 69 |
71 AudioRendererImpl::~AudioRendererImpl() { | 70 AudioRendererImpl::~AudioRendererImpl() { |
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
162 void AudioRendererImpl::ResetDecoderDone() { | 161 void AudioRendererImpl::ResetDecoderDone() { |
163 DCHECK(task_runner_->BelongsToCurrentThread()); | 162 DCHECK(task_runner_->BelongsToCurrentThread()); |
164 { | 163 { |
165 base::AutoLock auto_lock(lock_); | 164 base::AutoLock auto_lock(lock_); |
166 if (state_ == kStopped) | 165 if (state_ == kStopped) |
167 return; | 166 return; |
168 | 167 |
169 DCHECK_EQ(state_, kPaused); | 168 DCHECK_EQ(state_, kPaused); |
170 DCHECK(!flush_cb_.is_null()); | 169 DCHECK(!flush_cb_.is_null()); |
171 | 170 |
172 audio_time_buffered_ = kNoTimestamp(); | 171 audio_clock_.reset(new AudioClock(audio_parameters_.sample_rate())); |
173 current_time_ = kNoTimestamp(); | |
174 received_end_of_stream_ = false; | 172 received_end_of_stream_ = false; |
175 rendered_end_of_stream_ = false; | 173 rendered_end_of_stream_ = false; |
176 preroll_aborted_ = false; | 174 preroll_aborted_ = false; |
177 | 175 |
178 earliest_end_time_ = now_cb_.Run(); | 176 earliest_end_time_ = now_cb_.Run(); |
179 splicer_->Reset(); | 177 splicer_->Reset(); |
180 if (buffer_converter_) | 178 if (buffer_converter_) |
181 buffer_converter_->Reset(); | 179 buffer_converter_->Reset(); |
182 algorithm_->FlushBuffers(); | 180 algorithm_->FlushBuffers(); |
183 } | 181 } |
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
281 const AudioParameters& hw_params = hardware_config_->GetOutputConfig(); | 279 const AudioParameters& hw_params = hardware_config_->GetOutputConfig(); |
282 audio_parameters_.Reset(hw_params.format(), | 280 audio_parameters_.Reset(hw_params.format(), |
283 hw_params.channel_layout(), | 281 hw_params.channel_layout(), |
284 hw_params.channels(), | 282 hw_params.channels(), |
285 hw_params.input_channels(), | 283 hw_params.input_channels(), |
286 hw_params.sample_rate(), | 284 hw_params.sample_rate(), |
287 hw_params.bits_per_sample(), | 285 hw_params.bits_per_sample(), |
288 hardware_config_->GetHighLatencyBufferSize()); | 286 hardware_config_->GetHighLatencyBufferSize()); |
289 } | 287 } |
290 | 288 |
| 289 audio_clock_.reset(new AudioClock(audio_parameters_.sample_rate())); |
| 290 |
291 audio_buffer_stream_.Initialize( | 291 audio_buffer_stream_.Initialize( |
292 stream, | 292 stream, |
293 false, | 293 false, |
294 statistics_cb, | 294 statistics_cb, |
295 base::Bind(&AudioRendererImpl::OnAudioBufferStreamInitialized, | 295 base::Bind(&AudioRendererImpl::OnAudioBufferStreamInitialized, |
296 weak_factory_.GetWeakPtr())); | 296 weak_factory_.GetWeakPtr())); |
297 } | 297 } |
298 | 298 |
299 void AudioRendererImpl::OnAudioBufferStreamInitialized(bool success) { | 299 void AudioRendererImpl::OnAudioBufferStreamInitialized(bool success) { |
300 DCHECK(task_runner_->BelongsToCurrentThread()); | 300 DCHECK(task_runner_->BelongsToCurrentThread()); |
(...skipping 257 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
558 bool AudioRendererImpl::IsBeforePrerollTime( | 558 bool AudioRendererImpl::IsBeforePrerollTime( |
559 const scoped_refptr<AudioBuffer>& buffer) { | 559 const scoped_refptr<AudioBuffer>& buffer) { |
560 DCHECK_EQ(state_, kPrerolling); | 560 DCHECK_EQ(state_, kPrerolling); |
561 return buffer && !buffer->end_of_stream() && | 561 return buffer && !buffer->end_of_stream() && |
562 (buffer->timestamp() + buffer->duration()) < preroll_timestamp_; | 562 (buffer->timestamp() + buffer->duration()) < preroll_timestamp_; |
563 } | 563 } |
564 | 564 |
565 int AudioRendererImpl::Render(AudioBus* audio_bus, | 565 int AudioRendererImpl::Render(AudioBus* audio_bus, |
566 int audio_delay_milliseconds) { | 566 int audio_delay_milliseconds) { |
567 const int requested_frames = audio_bus->frames(); | 567 const int requested_frames = audio_bus->frames(); |
568 base::TimeDelta current_time = kNoTimestamp(); | |
569 base::TimeDelta max_time = kNoTimestamp(); | |
570 base::TimeDelta playback_delay = base::TimeDelta::FromMilliseconds( | 568 base::TimeDelta playback_delay = base::TimeDelta::FromMilliseconds( |
571 audio_delay_milliseconds); | 569 audio_delay_milliseconds); |
572 | 570 const int delay_frames = static_cast<int>(playback_delay.InSecondsF() * |
| 571 audio_parameters_.sample_rate()); |
573 int frames_written = 0; | 572 int frames_written = 0; |
| 573 base::Closure time_cb; |
574 base::Closure underflow_cb; | 574 base::Closure underflow_cb; |
575 { | 575 { |
576 base::AutoLock auto_lock(lock_); | 576 base::AutoLock auto_lock(lock_); |
577 | 577 |
578 // Ensure Stop() hasn't destroyed our |algorithm_| on the pipeline thread. | 578 // Ensure Stop() hasn't destroyed our |algorithm_| on the pipeline thread. |
579 if (!algorithm_) | 579 if (!algorithm_) { |
| 580 audio_clock_->WroteSilence(requested_frames, delay_frames); |
580 return 0; | 581 return 0; |
| 582 } |
581 | 583 |
582 float playback_rate = algorithm_->playback_rate(); | 584 float playback_rate = algorithm_->playback_rate(); |
583 if (playback_rate == 0) | 585 if (playback_rate == 0) { |
| 586 audio_clock_->WroteSilence(requested_frames, delay_frames); |
584 return 0; | 587 return 0; |
| 588 } |
585 | 589 |
586 // Mute audio by returning 0 when not playing. | 590 // Mute audio by returning 0 when not playing. |
587 if (state_ != kPlaying) | 591 if (state_ != kPlaying) { |
| 592 audio_clock_->WroteSilence(requested_frames, delay_frames); |
588 return 0; | 593 return 0; |
| 594 } |
589 | 595 |
590 // We use the following conditions to determine end of playback: | 596 // We use the following conditions to determine end of playback: |
591 // 1) Algorithm can not fill the audio callback buffer | 597 // 1) Algorithm can not fill the audio callback buffer |
592 // 2) We received an end of stream buffer | 598 // 2) We received an end of stream buffer |
593 // 3) We haven't already signalled that we've ended | 599 // 3) We haven't already signalled that we've ended |
594 // 4) Our estimated earliest end time has expired | 600 // 4) Our estimated earliest end time has expired |
595 // | 601 // |
596 // TODO(enal): we should replace (4) with a check that the browser has no | 602 // TODO(enal): we should replace (4) with a check that the browser has no |
597 // more audio data or at least use a delayed callback. | 603 // more audio data or at least use a delayed callback. |
598 // | 604 // |
599 // We use the following conditions to determine underflow: | 605 // We use the following conditions to determine underflow: |
600 // 1) Algorithm can not fill the audio callback buffer | 606 // 1) Algorithm can not fill the audio callback buffer |
601 // 2) We have NOT received an end of stream buffer | 607 // 2) We have NOT received an end of stream buffer |
602 // 3) We are in the kPlaying state | 608 // 3) We are in the kPlaying state |
603 // | 609 // |
604 // Otherwise the buffer has data we can send to the device. | 610 // Otherwise the buffer has data we can send to the device. |
605 const base::TimeDelta time_before_filling = algorithm_->GetTime(); | 611 const base::TimeDelta media_timestamp_before_filling = |
606 frames_written = algorithm_->FillBuffer(audio_bus, requested_frames); | 612 audio_clock_->CurrentMediaTimestamp(); |
| 613 if (algorithm_->frames_buffered() > 0) { |
| 614 frames_written = algorithm_->FillBuffer(audio_bus, requested_frames); |
| 615 audio_clock_->WroteAudio( |
| 616 frames_written, delay_frames, playback_rate, algorithm_->GetTime()); |
| 617 } |
| 618 audio_clock_->WroteSilence(requested_frames - frames_written, delay_frames); |
| 619 |
607 if (frames_written == 0) { | 620 if (frames_written == 0) { |
608 const base::TimeTicks now = now_cb_.Run(); | 621 const base::TimeTicks now = now_cb_.Run(); |
609 | 622 |
610 if (received_end_of_stream_ && !rendered_end_of_stream_ && | 623 if (received_end_of_stream_ && !rendered_end_of_stream_ && |
611 now >= earliest_end_time_) { | 624 now >= earliest_end_time_) { |
612 rendered_end_of_stream_ = true; | 625 rendered_end_of_stream_ = true; |
613 ended_cb_.Run(); | 626 ended_cb_.Run(); |
614 } else if (!received_end_of_stream_ && state_ == kPlaying && | 627 } else if (!received_end_of_stream_ && state_ == kPlaying && |
615 !underflow_disabled_) { | 628 !underflow_disabled_) { |
616 ChangeState_Locked(kUnderflow); | 629 ChangeState_Locked(kUnderflow); |
617 underflow_cb = underflow_cb_; | 630 underflow_cb = underflow_cb_; |
618 } else { | 631 } else { |
619 // We can't write any data this cycle. For example, we may have | 632 // We can't write any data this cycle. For example, we may have |
620 // sent all available data to the audio device while not reaching | 633 // sent all available data to the audio device while not reaching |
621 // |earliest_end_time_|. | 634 // |earliest_end_time_|. |
622 } | 635 } |
623 } | 636 } |
624 | 637 |
625 if (CanRead_Locked()) { | 638 if (CanRead_Locked()) { |
626 task_runner_->PostTask(FROM_HERE, | 639 task_runner_->PostTask(FROM_HERE, |
627 base::Bind(&AudioRendererImpl::AttemptRead, | 640 base::Bind(&AudioRendererImpl::AttemptRead, |
628 weak_factory_.GetWeakPtr())); | 641 weak_factory_.GetWeakPtr())); |
629 } | 642 } |
630 | 643 |
631 // Adjust the delay according to playback rate. | 644 // We only want to execute |time_cb_| if time has progressed and we haven't |
632 base::TimeDelta adjusted_playback_delay = base::TimeDelta::FromMicroseconds( | 645 // signaled end of stream yet. |
633 ceil(playback_delay.InMicroseconds() * playback_rate)); | 646 if (media_timestamp_before_filling != |
634 | 647 audio_clock_->CurrentMediaTimestamp() && |
635 // The |audio_time_buffered_| is the ending timestamp of the last frame | 648 !rendered_end_of_stream_) { |
636 // buffered at the audio device. |playback_delay| is the amount of time | 649 time_cb = base::Bind(time_cb_, |
637 // buffered at the audio device. The current time can be computed by their | 650 audio_clock_->CurrentMediaTimestamp(), |
638 // difference. | 651 audio_clock_->last_endpoint_timestamp()); |
639 if (audio_time_buffered_ != kNoTimestamp()) { | |
640 base::TimeDelta previous_time = current_time_; | |
641 current_time_ = audio_time_buffered_ - adjusted_playback_delay; | |
642 | |
643 // Time can change in one of two ways: | |
644 // 1) The time of the audio data at the audio device changed, or | |
645 // 2) The playback delay value has changed | |
646 // | |
647 // We only want to set |current_time| (and thus execute |time_cb_|) if | |
648 // time has progressed and we haven't signaled end of stream yet. | |
649 // | |
650 // Why? The current latency of the system results in getting the last call | |
651 // to FillBuffer() later than we'd like, which delays firing the 'ended' | |
652 // event, which delays the looping/trigging performance of short sound | |
653 // effects. | |
654 // | |
655 // TODO(scherkus): revisit this and switch back to relying on playback | |
656 // delay after we've revamped our audio IPC subsystem. | |
657 if (current_time_ > previous_time && !rendered_end_of_stream_) { | |
658 current_time = current_time_; | |
659 } | |
660 } else if (frames_written > 0) { | |
661 // Nothing has been buffered yet, so use the first buffer's timestamp. | |
662 DCHECK(time_before_filling != kNoTimestamp()); | |
663 current_time_ = current_time = | |
664 time_before_filling - adjusted_playback_delay; | |
665 } | 652 } |
666 | 653 |
667 // The call to FillBuffer() on |algorithm_| has increased the amount of | |
668 // buffered audio data. Update the new amount of time buffered. | |
669 max_time = algorithm_->GetTime(); | |
670 audio_time_buffered_ = max_time; | |
671 | |
672 if (frames_written > 0) { | 654 if (frames_written > 0) { |
673 UpdateEarliestEndTime_Locked( | 655 UpdateEarliestEndTime_Locked( |
674 frames_written, playback_delay, now_cb_.Run()); | 656 frames_written, playback_delay, now_cb_.Run()); |
675 } | 657 } |
676 } | 658 } |
677 | 659 |
678 if (current_time != kNoTimestamp() && max_time != kNoTimestamp()) | 660 if (!time_cb.is_null()) |
679 time_cb_.Run(current_time, max_time); | 661 time_cb.Run(); |
680 | 662 |
681 if (!underflow_cb.is_null()) | 663 if (!underflow_cb.is_null()) |
682 underflow_cb.Run(); | 664 underflow_cb.Run(); |
683 | 665 |
684 DCHECK_LE(frames_written, requested_frames); | 666 DCHECK_LE(frames_written, requested_frames); |
685 return frames_written; | 667 return frames_written; |
686 } | 668 } |
687 | 669 |
688 void AudioRendererImpl::UpdateEarliestEndTime_Locked( | 670 void AudioRendererImpl::UpdateEarliestEndTime_Locked( |
689 int frames_filled, const base::TimeDelta& playback_delay, | 671 int frames_filled, const base::TimeDelta& playback_delay, |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
764 DCHECK(expecting_config_changes_); | 746 DCHECK(expecting_config_changes_); |
765 buffer_converter_->ResetTimestampState(); | 747 buffer_converter_->ResetTimestampState(); |
766 // Drain flushed buffers from the converter so the AudioSplicer receives all | 748 // Drain flushed buffers from the converter so the AudioSplicer receives all |
767 // data ahead of any OnNewSpliceBuffer() calls. Since discontinuities should | 749 // data ahead of any OnNewSpliceBuffer() calls. Since discontinuities should |
768 // only appear after config changes, AddInput() should never fail here. | 750 // only appear after config changes, AddInput() should never fail here. |
769 while (buffer_converter_->HasNextBuffer()) | 751 while (buffer_converter_->HasNextBuffer()) |
770 CHECK(splicer_->AddInput(buffer_converter_->GetNextBuffer())); | 752 CHECK(splicer_->AddInput(buffer_converter_->GetNextBuffer())); |
771 } | 753 } |
772 | 754 |
773 } // namespace media | 755 } // namespace media |
OLD | NEW |