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_); |
+ } |
} |
} |