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 |
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
140 | 140 |
141 void AudioRendererImpl::SetMediaTime(base::TimeDelta time) { | 141 void AudioRendererImpl::SetMediaTime(base::TimeDelta time) { |
142 DVLOG(1) << __FUNCTION__ << "(" << time.InMicroseconds() << ")"; | 142 DVLOG(1) << __FUNCTION__ << "(" << time.InMicroseconds() << ")"; |
143 DCHECK(task_runner_->BelongsToCurrentThread()); | 143 DCHECK(task_runner_->BelongsToCurrentThread()); |
144 | 144 |
145 base::AutoLock auto_lock(lock_); | 145 base::AutoLock auto_lock(lock_); |
146 DCHECK(!rendering_); | 146 DCHECK(!rendering_); |
147 DCHECK_EQ(state_, kFlushed); | 147 DCHECK_EQ(state_, kFlushed); |
148 | 148 |
149 start_timestamp_ = time; | 149 start_timestamp_ = time; |
| 150 audio_clock_.reset(new AudioClock(time, audio_parameters_.sample_rate())); |
150 } | 151 } |
151 | 152 |
152 base::TimeDelta AudioRendererImpl::CurrentMediaTime() { | 153 base::TimeDelta AudioRendererImpl::CurrentMediaTime() { |
153 DVLOG(1) << __FUNCTION__; | 154 DVLOG(1) << __FUNCTION__; |
154 DCHECK(task_runner_->BelongsToCurrentThread()); | 155 DCHECK(task_runner_->BelongsToCurrentThread()); |
155 | 156 |
156 // TODO(scherkus): Finish implementing when ready to switch Pipeline to using | 157 // TODO(scherkus): Finish implementing when ready to switch Pipeline to using |
157 // TimeSource http://crbug.com/370634 | 158 // TimeSource http://crbug.com/370634 |
158 NOTIMPLEMENTED(); | 159 NOTIMPLEMENTED(); |
159 | 160 |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
194 } | 195 } |
195 | 196 |
196 void AudioRendererImpl::ResetDecoderDone() { | 197 void AudioRendererImpl::ResetDecoderDone() { |
197 DCHECK(task_runner_->BelongsToCurrentThread()); | 198 DCHECK(task_runner_->BelongsToCurrentThread()); |
198 { | 199 { |
199 base::AutoLock auto_lock(lock_); | 200 base::AutoLock auto_lock(lock_); |
200 | 201 |
201 DCHECK_EQ(state_, kFlushed); | 202 DCHECK_EQ(state_, kFlushed); |
202 DCHECK(!flush_cb_.is_null()); | 203 DCHECK(!flush_cb_.is_null()); |
203 | 204 |
204 audio_clock_.reset(new AudioClock(audio_parameters_.sample_rate())); | 205 audio_clock_.reset(); |
205 received_end_of_stream_ = false; | 206 received_end_of_stream_ = false; |
206 rendered_end_of_stream_ = false; | 207 rendered_end_of_stream_ = false; |
207 | 208 |
208 // Flush() may have been called while underflowed/not fully buffered. | 209 // Flush() may have been called while underflowed/not fully buffered. |
209 if (buffering_state_ != BUFFERING_HAVE_NOTHING) | 210 if (buffering_state_ != BUFFERING_HAVE_NOTHING) |
210 SetBufferingState_Locked(BUFFERING_HAVE_NOTHING); | 211 SetBufferingState_Locked(BUFFERING_HAVE_NOTHING); |
211 | 212 |
212 splicer_->Reset(); | 213 splicer_->Reset(); |
213 if (buffer_converter_) | 214 if (buffer_converter_) |
214 buffer_converter_->Reset(); | 215 buffer_converter_->Reset(); |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
287 // unnecessary upmixing overhead. | 288 // unnecessary upmixing overhead. |
288 stream->audio_decoder_config().channel_layout(), | 289 stream->audio_decoder_config().channel_layout(), |
289 ChannelLayoutToChannelCount( | 290 ChannelLayoutToChannelCount( |
290 stream->audio_decoder_config().channel_layout()), | 291 stream->audio_decoder_config().channel_layout()), |
291 hw_params.input_channels(), | 292 hw_params.input_channels(), |
292 hw_params.sample_rate(), | 293 hw_params.sample_rate(), |
293 hw_params.bits_per_sample(), | 294 hw_params.bits_per_sample(), |
294 hardware_config_->GetHighLatencyBufferSize()); | 295 hardware_config_->GetHighLatencyBufferSize()); |
295 } | 296 } |
296 | 297 |
297 audio_clock_.reset(new AudioClock(audio_parameters_.sample_rate())); | 298 audio_clock_.reset( |
| 299 new AudioClock(base::TimeDelta(), audio_parameters_.sample_rate())); |
298 | 300 |
299 audio_buffer_stream_->Initialize( | 301 audio_buffer_stream_->Initialize( |
300 stream, | 302 stream, |
301 false, | 303 false, |
302 statistics_cb, | 304 statistics_cb, |
303 base::Bind(&AudioRendererImpl::OnAudioBufferStreamInitialized, | 305 base::Bind(&AudioRendererImpl::OnAudioBufferStreamInitialized, |
304 weak_factory_.GetWeakPtr())); | 306 weak_factory_.GetWeakPtr())); |
305 } | 307 } |
306 | 308 |
307 void AudioRendererImpl::OnAudioBufferStreamInitialized(bool success) { | 309 void AudioRendererImpl::OnAudioBufferStreamInitialized(bool success) { |
(...skipping 234 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
542 audio_delay_milliseconds); | 544 audio_delay_milliseconds); |
543 const int delay_frames = static_cast<int>(playback_delay.InSecondsF() * | 545 const int delay_frames = static_cast<int>(playback_delay.InSecondsF() * |
544 audio_parameters_.sample_rate()); | 546 audio_parameters_.sample_rate()); |
545 int frames_written = 0; | 547 int frames_written = 0; |
546 base::Closure time_cb; | 548 base::Closure time_cb; |
547 { | 549 { |
548 base::AutoLock auto_lock(lock_); | 550 base::AutoLock auto_lock(lock_); |
549 | 551 |
550 // Ensure Stop() hasn't destroyed our |algorithm_| on the pipeline thread. | 552 // Ensure Stop() hasn't destroyed our |algorithm_| on the pipeline thread. |
551 if (!algorithm_) { | 553 if (!algorithm_) { |
552 audio_clock_->WroteSilence(requested_frames, delay_frames); | 554 audio_clock_->WroteAudio( |
| 555 0, requested_frames, delay_frames, playback_rate_); |
553 return 0; | 556 return 0; |
554 } | 557 } |
555 | 558 |
556 if (playback_rate_ == 0) { | 559 if (playback_rate_ == 0) { |
557 audio_clock_->WroteSilence(requested_frames, delay_frames); | 560 audio_clock_->WroteAudio( |
| 561 0, requested_frames, delay_frames, playback_rate_); |
558 return 0; | 562 return 0; |
559 } | 563 } |
560 | 564 |
561 // Mute audio by returning 0 when not playing. | 565 // Mute audio by returning 0 when not playing. |
562 if (state_ != kPlaying) { | 566 if (state_ != kPlaying) { |
563 audio_clock_->WroteSilence(requested_frames, delay_frames); | 567 audio_clock_->WroteAudio( |
| 568 0, requested_frames, delay_frames, playback_rate_); |
564 return 0; | 569 return 0; |
565 } | 570 } |
566 | 571 |
567 // We use the following conditions to determine end of playback: | 572 // We use the following conditions to determine end of playback: |
568 // 1) Algorithm can not fill the audio callback buffer | 573 // 1) Algorithm can not fill the audio callback buffer |
569 // 2) We received an end of stream buffer | 574 // 2) We received an end of stream buffer |
570 // 3) We haven't already signalled that we've ended | 575 // 3) We haven't already signalled that we've ended |
571 // 4) We've played all known audio data sent to hardware | 576 // 4) We've played all known audio data sent to hardware |
572 // | 577 // |
573 // We use the following conditions to determine underflow: | 578 // We use the following conditions to determine underflow: |
574 // 1) Algorithm can not fill the audio callback buffer | 579 // 1) Algorithm can not fill the audio callback buffer |
575 // 2) We have NOT received an end of stream buffer | 580 // 2) We have NOT received an end of stream buffer |
576 // 3) We are in the kPlaying state | 581 // 3) We are in the kPlaying state |
577 // | 582 // |
578 // Otherwise the buffer has data we can send to the device. | 583 // Otherwise the buffer has data we can send to the device. |
579 const base::TimeDelta media_timestamp_before_filling = | |
580 audio_clock_->CurrentMediaTimestamp(base::TimeDelta()); | |
581 if (algorithm_->frames_buffered() > 0) { | 584 if (algorithm_->frames_buffered() > 0) { |
582 frames_written = | 585 frames_written = |
583 algorithm_->FillBuffer(audio_bus, requested_frames, playback_rate_); | 586 algorithm_->FillBuffer(audio_bus, requested_frames, playback_rate_); |
584 audio_clock_->WroteAudio( | |
585 frames_written, delay_frames, playback_rate_, algorithm_->GetTime()); | |
586 } | 587 } |
587 audio_clock_->WroteSilence(requested_frames - frames_written, delay_frames); | 588 audio_clock_->WroteAudio( |
| 589 frames_written, requested_frames, delay_frames, playback_rate_); |
588 | 590 |
589 if (frames_written == 0) { | 591 if (frames_written == 0) { |
590 if (received_end_of_stream_ && !rendered_end_of_stream_ && | 592 if (received_end_of_stream_ && !rendered_end_of_stream_ && |
591 audio_clock_->CurrentMediaTimestamp(base::TimeDelta()) == | 593 !audio_clock_->AudioDataBuffered()) { |
592 audio_clock_->last_endpoint_timestamp()) { | |
593 rendered_end_of_stream_ = true; | 594 rendered_end_of_stream_ = true; |
594 task_runner_->PostTask(FROM_HERE, ended_cb_); | 595 task_runner_->PostTask(FROM_HERE, ended_cb_); |
595 } else if (!received_end_of_stream_ && state_ == kPlaying) { | 596 } else if (!received_end_of_stream_ && state_ == kPlaying) { |
596 if (buffering_state_ != BUFFERING_HAVE_NOTHING) { | 597 if (buffering_state_ != BUFFERING_HAVE_NOTHING) { |
597 algorithm_->IncreaseQueueCapacity(); | 598 algorithm_->IncreaseQueueCapacity(); |
598 SetBufferingState_Locked(BUFFERING_HAVE_NOTHING); | 599 SetBufferingState_Locked(BUFFERING_HAVE_NOTHING); |
599 } | 600 } |
600 } | 601 } |
601 } | 602 } |
602 | 603 |
603 if (CanRead_Locked()) { | 604 if (CanRead_Locked()) { |
604 task_runner_->PostTask(FROM_HERE, | 605 task_runner_->PostTask(FROM_HERE, |
605 base::Bind(&AudioRendererImpl::AttemptRead, | 606 base::Bind(&AudioRendererImpl::AttemptRead, |
606 weak_factory_.GetWeakPtr())); | 607 weak_factory_.GetWeakPtr())); |
607 } | 608 } |
608 | 609 |
609 // We only want to execute |time_cb_| if time has progressed and we haven't | 610 // Firing |ended_cb_| means we no longer need to run |time_cb_|. |
610 // signaled end of stream yet. | 611 if (!rendered_end_of_stream_) { |
611 if (media_timestamp_before_filling != | 612 // Since |max_time| uses linear interpolation, only provide an upper bound |
612 audio_clock_->CurrentMediaTimestamp(base::TimeDelta()) && | 613 // that is for audio data at the same playback rate. Failing to do so can |
613 !rendered_end_of_stream_) { | 614 // make time jump backwards when the linear interpolated time advances |
614 time_cb = | 615 // past buffered regions of audio at different rates. |
615 base::Bind(time_cb_, | 616 base::TimeDelta current_timestamp = |
616 audio_clock_->CurrentMediaTimestamp(base::TimeDelta()), | 617 audio_clock_->CurrentMediaTimestamp(base::TimeDelta()); |
617 audio_clock_->last_endpoint_timestamp()); | 618 base::TimeDelta max_time = |
| 619 current_timestamp + |
| 620 audio_clock_->ContiguousAudioDataBufferedAtSameRate(); |
| 621 time_cb = base::Bind(time_cb_, current_timestamp, max_time); |
618 } | 622 } |
619 } | 623 } |
620 | 624 |
621 if (!time_cb.is_null()) | 625 if (!time_cb.is_null()) |
622 task_runner_->PostTask(FROM_HERE, time_cb); | 626 task_runner_->PostTask(FROM_HERE, time_cb); |
623 | 627 |
624 DCHECK_LE(frames_written, requested_frames); | 628 DCHECK_LE(frames_written, requested_frames); |
625 return frames_written; | 629 return frames_written; |
626 } | 630 } |
627 | 631 |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
693 << buffering_state; | 697 << buffering_state; |
694 DCHECK_NE(buffering_state_, buffering_state); | 698 DCHECK_NE(buffering_state_, buffering_state); |
695 lock_.AssertAcquired(); | 699 lock_.AssertAcquired(); |
696 buffering_state_ = buffering_state; | 700 buffering_state_ = buffering_state; |
697 | 701 |
698 task_runner_->PostTask(FROM_HERE, | 702 task_runner_->PostTask(FROM_HERE, |
699 base::Bind(buffering_state_cb_, buffering_state_)); | 703 base::Bind(buffering_state_cb_, buffering_state_)); |
700 } | 704 } |
701 | 705 |
702 } // namespace media | 706 } // namespace media |
OLD | NEW |