| Index: media/filters/audio_renderer_impl.cc
|
| diff --git a/media/filters/audio_renderer_impl.cc b/media/filters/audio_renderer_impl.cc
|
| index 5a536998d4ce6f1fb1f2f4c54d59f0a48b24e9c8..166b51fee6026cc7d4536df3512cb64575cd7136 100644
|
| --- a/media/filters/audio_renderer_impl.cc
|
| +++ b/media/filters/audio_renderer_impl.cc
|
| @@ -63,6 +63,7 @@
|
| pending_read_(false),
|
| received_end_of_stream_(false),
|
| rendered_end_of_stream_(false),
|
| + last_timestamp_update_(kNoTimestamp()),
|
| weak_factory_(this) {
|
| audio_buffer_stream_->set_splice_observer(base::Bind(
|
| &AudioRendererImpl::OnNewSpliceBuffer, weak_factory_.GetWeakPtr()));
|
| @@ -150,29 +151,18 @@
|
|
|
| start_timestamp_ = time;
|
| ended_timestamp_ = kInfiniteDuration();
|
| - last_render_ticks_ = base::TimeTicks();
|
| audio_clock_.reset(new AudioClock(time, audio_parameters_.sample_rate()));
|
| }
|
|
|
| base::TimeDelta AudioRendererImpl::CurrentMediaTime() {
|
| DVLOG(2) << __FUNCTION__;
|
| -
|
| - // In practice the Render() method is called with a high enough frequency
|
| - // that returning only the front timestamp is good enough and also prevents
|
| - // returning values that go backwards in time.
|
| - base::AutoLock auto_lock(lock_);
|
| - return audio_clock_->front_timestamp();
|
| -}
|
| -
|
| -base::TimeDelta AudioRendererImpl::CurrentMediaTimeForSyncingVideo() {
|
| - DVLOG(2) << __FUNCTION__;
|
| -
|
| - base::AutoLock auto_lock(lock_);
|
| - if (last_render_ticks_.is_null())
|
| - return audio_clock_->front_timestamp();
|
| -
|
| - return audio_clock_->TimestampSinceWriting(base::TimeTicks::Now() -
|
| - last_render_ticks_);
|
| + DCHECK(task_runner_->BelongsToCurrentThread());
|
| +
|
| + // TODO(scherkus): Finish implementing when ready to switch Pipeline to using
|
| + // TimeSource http://crbug.com/370634
|
| + NOTIMPLEMENTED();
|
| +
|
| + return base::TimeDelta();
|
| }
|
|
|
| TimeSource* AudioRendererImpl::GetTimeSource() {
|
| @@ -216,8 +206,10 @@
|
| DCHECK_EQ(state_, kFlushed);
|
| DCHECK(!flush_cb_.is_null());
|
|
|
| + audio_clock_.reset();
|
| received_end_of_stream_ = false;
|
| rendered_end_of_stream_ = false;
|
| + last_timestamp_update_ = kNoTimestamp();
|
|
|
| // Flush() may have been called while underflowed/not fully buffered.
|
| if (buffering_state_ != BUFFERING_HAVE_NOTHING)
|
| @@ -251,6 +243,7 @@
|
| void AudioRendererImpl::Initialize(DemuxerStream* stream,
|
| const PipelineStatusCB& init_cb,
|
| const StatisticsCB& statistics_cb,
|
| + const TimeCB& time_cb,
|
| const BufferingStateCB& buffering_state_cb,
|
| const base::Closure& ended_cb,
|
| const PipelineStatusCB& error_cb) {
|
| @@ -259,6 +252,7 @@
|
| DCHECK_EQ(stream->type(), DemuxerStream::AUDIO);
|
| DCHECK(!init_cb.is_null());
|
| DCHECK(!statistics_cb.is_null());
|
| + DCHECK(!time_cb.is_null());
|
| DCHECK(!buffering_state_cb.is_null());
|
| DCHECK(!ended_cb.is_null());
|
| DCHECK(!error_cb.is_null());
|
| @@ -271,6 +265,7 @@
|
| // failed.
|
| init_cb_ = BindToCurrentLoop(init_cb);
|
|
|
| + time_cb_ = time_cb;
|
| buffering_state_cb_ = buffering_state_cb;
|
| ended_cb_ = ended_cb;
|
| error_cb_ = error_cb;
|
| @@ -557,7 +552,6 @@
|
| int frames_written = 0;
|
| {
|
| base::AutoLock auto_lock(lock_);
|
| - last_render_ticks_ = base::TimeTicks::Now();
|
|
|
| // Ensure Stop() hasn't destroyed our |algorithm_| on the pipeline thread.
|
| if (!algorithm_) {
|
| @@ -628,10 +622,23 @@
|
| weak_factory_.GetWeakPtr()));
|
| }
|
|
|
| - if (audio_clock_->front_timestamp() >= ended_timestamp_ &&
|
| - !rendered_end_of_stream_) {
|
| - rendered_end_of_stream_ = true;
|
| - task_runner_->PostTask(FROM_HERE, ended_cb_);
|
| + if (last_timestamp_update_ != audio_clock_->front_timestamp()) {
|
| + // Since |max_time| uses linear interpolation, only provide an upper bound
|
| + // that is for audio data at the same playback rate. Failing to do so can
|
| + // make time jump backwards when the linear interpolated time advances
|
| + // past buffered regions of audio at different rates.
|
| + last_timestamp_update_ = audio_clock_->front_timestamp();
|
| + base::TimeDelta max_time =
|
| + last_timestamp_update_ +
|
| + audio_clock_->contiguous_audio_data_buffered_at_same_rate();
|
| + task_runner_->PostTask(
|
| + FROM_HERE, base::Bind(time_cb_, last_timestamp_update_, max_time));
|
| +
|
| + if (last_timestamp_update_ >= ended_timestamp_ &&
|
| + !rendered_end_of_stream_) {
|
| + rendered_end_of_stream_ = true;
|
| + task_runner_->PostTask(FROM_HERE, ended_cb_);
|
| + }
|
| }
|
| }
|
|
|
|
|