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

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

Issue 436053002: Make media::AudioClock track frames written to compute time. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: fix things up Created 6 years, 4 months 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 | Annotate | Revision Log
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/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
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
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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698