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