summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorscherkus@chromium.org <scherkus@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-07-22 02:30:06 +0000
committerscherkus@chromium.org <scherkus@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-07-22 02:30:06 +0000
commit196b96a7c3f572f0325740e8fc1180dcaefe66c3 (patch)
treeb7730cc7e20a83b418e15813ebcf56e73f5df1ed
parent1e89d82e532fad41802603a12ee758eee0955f67 (diff)
downloadchromium_src-196b96a7c3f572f0325740e8fc1180dcaefe66c3.zip
chromium_src-196b96a7c3f572f0325740e8fc1180dcaefe66c3.tar.gz
chromium_src-196b96a7c3f572f0325740e8fc1180dcaefe66c3.tar.bz2
Make media::AudioRenderer return a media::TimeSource.
Mostly mechanical change to finish migrating time-related methods from AudioRenderer to TimeSource. BUG=370634 Review URL: https://codereview.chromium.org/403723006 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@284598 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--media/base/audio_renderer.h26
-rw-r--r--media/base/mock_filters.cc4
-rw-r--r--media/base/mock_filters.h23
-rw-r--r--media/base/pipeline.cc33
-rw-r--r--media/base/pipeline.h6
-rw-r--r--media/base/pipeline_unittest.cc56
-rw-r--r--media/filters/audio_renderer_impl.cc19
-rw-r--r--media/filters/audio_renderer_impl.h14
-rw-r--r--media/filters/audio_renderer_impl_unittest.cc48
9 files changed, 129 insertions, 100 deletions
diff --git a/media/base/audio_renderer.h b/media/base/audio_renderer.h
index 00a8e7f..dc202be 100644
--- a/media/base/audio_renderer.h
+++ b/media/base/audio_renderer.h
@@ -6,7 +6,6 @@
#define MEDIA_BASE_AUDIO_RENDERER_H_
#include "base/callback.h"
-#include "base/memory/ref_counted.h"
#include "base/time/time.h"
#include "media/base/buffering_state.h"
#include "media/base/media_export.h"
@@ -15,6 +14,7 @@
namespace media {
class DemuxerStream;
+class TimeSource;
class MEDIA_EXPORT AudioRenderer {
public:
@@ -46,23 +46,8 @@ class MEDIA_EXPORT AudioRenderer {
const base::Closure& ended_cb,
const PipelineStatusCB& error_cb) = 0;
- // Signal audio playback to start at the current rate. It is expected that
- // |time_cb| will eventually start being run with time updates.
- //
- // TODO(scherkus): Fold into TimeSource API.
- virtual void StartRendering() = 0;
-
- // Signal audio playback to stop until further notice. It is expected that
- // |time_cb| will no longer be run.
- //
- // TODO(scherkus): Fold into TimeSource API.
- virtual void StopRendering() = 0;
-
- // Sets the media time to start rendering from. Only valid to call while not
- // currently rendering.
- //
- // TODO(scherkus): Fold into TimeSource API.
- virtual void SetMediaTime(base::TimeDelta time) = 0;
+ // Returns the TimeSource associated with audio rendering.
+ virtual TimeSource* GetTimeSource() = 0;
// Discard any audio data, executing |callback| when completed.
//
@@ -79,11 +64,6 @@ class MEDIA_EXPORT AudioRenderer {
// when complete.
virtual void Stop(const base::Closure& callback) = 0;
- // Updates the current playback rate.
- //
- // TODO(scherkus): Fold into TimeSource API.
- virtual void SetPlaybackRate(float playback_rate) = 0;
-
// Sets the output volume.
virtual void SetVolume(float volume) = 0;
diff --git a/media/base/mock_filters.cc b/media/base/mock_filters.cc
index 42ec9bb..b608ecb 100644
--- a/media/base/mock_filters.cc
+++ b/media/base/mock_filters.cc
@@ -70,6 +70,10 @@ MockAudioRenderer::MockAudioRenderer() {}
MockAudioRenderer::~MockAudioRenderer() {}
+MockTimeSource::MockTimeSource() {}
+
+MockTimeSource::~MockTimeSource() {}
+
MockTextTrack::MockTextTrack() {}
MockTextTrack::~MockTextTrack() {}
diff --git a/media/base/mock_filters.h b/media/base/mock_filters.h
index 1de94f0..06a6c1f 100644
--- a/media/base/mock_filters.h
+++ b/media/base/mock_filters.h
@@ -17,6 +17,7 @@
#include "media/base/filter_collection.h"
#include "media/base/pipeline_status.h"
#include "media/base/text_track.h"
+#include "media/base/time_source.h"
#include "media/base/video_decoder.h"
#include "media/base/video_decoder_config.h"
#include "media/base/video_frame.h"
@@ -146,20 +147,32 @@ class MockAudioRenderer : public AudioRenderer {
const BufferingStateCB& buffering_state_cb,
const base::Closure& ended_cb,
const PipelineStatusCB& error_cb));
- MOCK_METHOD0(StartRendering, void());
- MOCK_METHOD0(StopRendering, void());
- MOCK_METHOD1(SetMediaTime, void(base::TimeDelta));
+ MOCK_METHOD0(GetTimeSource, TimeSource*());
MOCK_METHOD1(Flush, void(const base::Closure& callback));
MOCK_METHOD1(Stop, void(const base::Closure& callback));
- MOCK_METHOD1(SetPlaybackRate, void(float playback_rate));
MOCK_METHOD0(StartPlaying, void());
MOCK_METHOD1(SetVolume, void(float volume));
- MOCK_METHOD0(ResumeAfterUnderflow, void());
private:
DISALLOW_COPY_AND_ASSIGN(MockAudioRenderer);
};
+class MockTimeSource : public TimeSource {
+ public:
+ MockTimeSource();
+ virtual ~MockTimeSource();
+
+ // TimeSource implementation.
+ MOCK_METHOD0(StartTicking, void());
+ MOCK_METHOD0(StopTicking, void());
+ MOCK_METHOD1(SetPlaybackRate, void(float));
+ MOCK_METHOD1(SetMediaTime, void(base::TimeDelta));
+ MOCK_METHOD0(CurrentMediaTime, base::TimeDelta());
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(MockTimeSource);
+};
+
class MockTextTrack : public TextTrack {
public:
MockTextTrack();
diff --git a/media/base/pipeline.cc b/media/base/pipeline.cc
index e1af611..efe91f6 100644
--- a/media/base/pipeline.cc
+++ b/media/base/pipeline.cc
@@ -24,6 +24,7 @@
#include "media/base/text_renderer.h"
#include "media/base/text_track_config.h"
#include "media/base/time_delta_interpolator.h"
+#include "media/base/time_source.h"
#include "media/base/video_decoder.h"
#include "media/base/video_decoder_config.h"
#include "media/base/video_renderer.h"
@@ -51,6 +52,7 @@ Pipeline::Pipeline(
audio_buffering_state_(BUFFERING_HAVE_NOTHING),
video_buffering_state_(BUFFERING_HAVE_NOTHING),
demuxer_(NULL),
+ time_source_(NULL),
underflow_disabled_for_testing_(false) {
media_log_->AddEvent(media_log_->CreatePipelineStateChangedEvent(kCreated));
media_log_->AddEvent(
@@ -380,6 +382,9 @@ void Pipeline::StateTransitionTask(PipelineStatus status) {
return;
}
+ if (audio_renderer_)
+ time_source_ = audio_renderer_->GetTimeSource();
+
{
PipelineMetadata metadata;
metadata.has_audio = audio_renderer_;
@@ -402,10 +407,10 @@ void Pipeline::StateTransitionTask(PipelineStatus status) {
interpolator_->SetBounds(start_timestamp_, start_timestamp_);
}
- if (audio_renderer_) {
- audio_renderer_->SetMediaTime(start_timestamp_);
+ if (time_source_)
+ time_source_->SetMediaTime(start_timestamp_);
+ if (audio_renderer_)
audio_renderer_->StartPlaying();
- }
if (video_renderer_)
video_renderer_->StartPlaying();
if (text_renderer_)
@@ -447,7 +452,7 @@ void Pipeline::DoSeek(
SerialRunner::Queue bound_fns;
{
base::AutoLock auto_lock(lock_);
- PauseClockAndStopRendering_Locked();
+ PauseClockAndStopTicking_Locked();
}
// Pause.
@@ -649,8 +654,8 @@ void Pipeline::PlaybackRateChangedTask(float playback_rate) {
interpolator_->SetPlaybackRate(playback_rate);
}
- if (audio_renderer_)
- audio_renderer_->SetPlaybackRate(playback_rate_);
+ if (time_source_)
+ time_source_->SetPlaybackRate(playback_rate_);
}
void Pipeline::VolumeChangedTask(float volume) {
@@ -750,7 +755,7 @@ void Pipeline::RunEndedCallbackIfNeeded() {
{
base::AutoLock auto_lock(lock_);
- PauseClockAndStopRendering_Locked();
+ PauseClockAndStopTicking_Locked();
interpolator_->SetBounds(duration_, duration_);
}
@@ -863,7 +868,7 @@ void Pipeline::PausePlayback() {
DCHECK(task_runner_->BelongsToCurrentThread());
base::AutoLock auto_lock(lock_);
- PauseClockAndStopRendering_Locked();
+ PauseClockAndStopTicking_Locked();
}
void Pipeline::StartPlayback() {
@@ -873,12 +878,12 @@ void Pipeline::StartPlayback() {
DCHECK(!WaitingForEnoughData());
DCHECK(task_runner_->BelongsToCurrentThread());
- if (audio_renderer_) {
+ if (time_source_) {
// We use audio stream to update the clock. So if there is such a
// stream, we pause the clock until we receive a valid timestamp.
base::AutoLock auto_lock(lock_);
interpolation_state_ = INTERPOLATION_WAITING_FOR_AUDIO_TIME_UPDATE;
- audio_renderer_->StartRendering();
+ time_source_->StartTicking();
} else {
base::AutoLock auto_lock(lock_);
interpolation_state_ = INTERPOLATION_STARTED;
@@ -887,19 +892,19 @@ void Pipeline::StartPlayback() {
}
}
-void Pipeline::PauseClockAndStopRendering_Locked() {
+void Pipeline::PauseClockAndStopTicking_Locked() {
lock_.AssertAcquired();
switch (interpolation_state_) {
case INTERPOLATION_STOPPED:
return;
case INTERPOLATION_WAITING_FOR_AUDIO_TIME_UPDATE:
- audio_renderer_->StopRendering();
+ time_source_->StopTicking();
break;
case INTERPOLATION_STARTED:
- if (audio_renderer_)
- audio_renderer_->StopRendering();
+ if (time_source_)
+ time_source_->StopTicking();
interpolator_->StopInterpolating();
break;
}
diff --git a/media/base/pipeline.h b/media/base/pipeline.h
index 6a408da..9bfa785 100644
--- a/media/base/pipeline.h
+++ b/media/base/pipeline.h
@@ -34,6 +34,7 @@ class MediaLog;
class TextRenderer;
class TextTrackConfig;
class TimeDeltaInterpolator;
+class TimeSource;
class VideoRenderer;
// Metadata describing a pipeline once it has been initialized.
@@ -317,7 +318,7 @@ class MEDIA_EXPORT Pipeline : public DemuxerHost {
void PausePlayback();
void StartPlayback();
- void PauseClockAndStopRendering_Locked();
+ void PauseClockAndStopTicking_Locked();
void StartClockIfWaitingForTimeUpdate_Locked();
// Task runner used to execute pipeline tasks.
@@ -420,6 +421,9 @@ class MEDIA_EXPORT Pipeline : public DemuxerHost {
scoped_ptr<VideoRenderer> video_renderer_;
scoped_ptr<TextRenderer> text_renderer_;
+ // Renderer-provided time source used to control playback.
+ TimeSource* time_source_;
+
PipelineStatistics statistics_;
scoped_ptr<SerialRunner> pending_callbacks_;
diff --git a/media/base/pipeline_unittest.cc b/media/base/pipeline_unittest.cc
index f5c6d0b..6fdb4b3a 100644
--- a/media/base/pipeline_unittest.cc
+++ b/media/base/pipeline_unittest.cc
@@ -201,13 +201,15 @@ class PipelineTest : public ::testing::Test {
EXPECT_CALL(callbacks_, OnMetadata(_)).WillOnce(SaveArg<0>(&metadata_));
if (audio_stream_) {
- EXPECT_CALL(*audio_renderer_, SetPlaybackRate(0.0f));
+ EXPECT_CALL(*audio_renderer_, GetTimeSource())
+ .WillOnce(Return(&time_source_));
+ EXPECT_CALL(time_source_, SetPlaybackRate(0.0f));
+ EXPECT_CALL(time_source_, SetMediaTime(base::TimeDelta()));
+ EXPECT_CALL(time_source_, StartTicking());
EXPECT_CALL(*audio_renderer_, SetVolume(1.0f));
- EXPECT_CALL(*audio_renderer_, SetMediaTime(base::TimeDelta()));
EXPECT_CALL(*audio_renderer_, StartPlaying())
.WillOnce(SetBufferingState(&audio_buffering_state_cb_,
BUFFERING_HAVE_ENOUGH));
- EXPECT_CALL(*audio_renderer_, StartRendering());
}
if (video_stream_) {
@@ -266,18 +268,18 @@ class PipelineTest : public ::testing::Test {
if (audio_stream_) {
if (!underflowed)
- EXPECT_CALL(*audio_renderer_, StopRendering());
+ EXPECT_CALL(time_source_, StopTicking());
EXPECT_CALL(*audio_renderer_, Flush(_))
.WillOnce(DoAll(SetBufferingState(&audio_buffering_state_cb_,
BUFFERING_HAVE_NOTHING),
RunClosure<0>()));
- EXPECT_CALL(*audio_renderer_, SetMediaTime(seek_time));
+ EXPECT_CALL(time_source_, SetMediaTime(seek_time));
+ EXPECT_CALL(time_source_, SetPlaybackRate(_));
+ EXPECT_CALL(time_source_, StartTicking());
EXPECT_CALL(*audio_renderer_, StartPlaying())
.WillOnce(SetBufferingState(&audio_buffering_state_cb_,
BUFFERING_HAVE_ENOUGH));
- EXPECT_CALL(*audio_renderer_, SetPlaybackRate(_));
EXPECT_CALL(*audio_renderer_, SetVolume(_));
- EXPECT_CALL(*audio_renderer_, StartRendering());
}
if (video_stream_) {
@@ -336,6 +338,7 @@ class PipelineTest : public ::testing::Test {
scoped_ptr<StrictMock<MockDemuxer> > demuxer_;
StrictMock<MockVideoRenderer>* video_renderer_;
StrictMock<MockAudioRenderer>* audio_renderer_;
+ StrictMock<MockTimeSource> time_source_;
StrictMock<CallbackHelper> text_renderer_callbacks_;
TextRenderer* text_renderer_;
scoped_ptr<StrictMock<MockDemuxerStream> > audio_stream_;
@@ -608,7 +611,7 @@ TEST_F(PipelineTest, EndedCallback) {
video_ended_cb_.Run();
message_loop_.RunUntilIdle();
- EXPECT_CALL(*audio_renderer_, StopRendering());
+ EXPECT_CALL(time_source_, StopTicking());
EXPECT_CALL(callbacks_, OnEnded());
text_stream()->SendEosNotification();
message_loop_.RunUntilIdle();
@@ -635,7 +638,7 @@ TEST_F(PipelineTest, AudioStreamShorterThanVideo) {
EXPECT_EQ(0, pipeline_->GetMediaTime().ToInternalValue());
float playback_rate = 1.0f;
- EXPECT_CALL(*audio_renderer_, SetPlaybackRate(playback_rate));
+ EXPECT_CALL(time_source_, SetPlaybackRate(playback_rate));
pipeline_->SetPlaybackRate(playback_rate);
message_loop_.RunUntilIdle();
@@ -657,7 +660,7 @@ TEST_F(PipelineTest, AudioStreamShorterThanVideo) {
EXPECT_GT(pipeline_->GetMediaTime().ToInternalValue(), start_time);
// Signal end of video stream and make sure OnEnded() callback occurs.
- EXPECT_CALL(*audio_renderer_, StopRendering());
+ EXPECT_CALL(time_source_, StopTicking());
EXPECT_CALL(callbacks_, OnEnded());
video_ended_cb_.Run();
}
@@ -672,14 +675,14 @@ TEST_F(PipelineTest, ErrorDuringSeek) {
StartPipeline(PIPELINE_OK);
float playback_rate = 1.0f;
- EXPECT_CALL(*audio_renderer_, SetPlaybackRate(playback_rate));
+ EXPECT_CALL(time_source_, SetPlaybackRate(playback_rate));
pipeline_->SetPlaybackRate(playback_rate);
message_loop_.RunUntilIdle();
base::TimeDelta seek_time = base::TimeDelta::FromSeconds(5);
// Preroll() isn't called as the demuxer errors out first.
- EXPECT_CALL(*audio_renderer_, StopRendering());
+ EXPECT_CALL(time_source_, StopTicking());
EXPECT_CALL(*audio_renderer_, Flush(_))
.WillOnce(DoAll(SetBufferingState(&audio_buffering_state_cb_,
BUFFERING_HAVE_NOTHING),
@@ -735,7 +738,7 @@ TEST_F(PipelineTest, NoMessageDuringTearDownFromError) {
base::TimeDelta seek_time = base::TimeDelta::FromSeconds(5);
// Seek() isn't called as the demuxer errors out first.
- EXPECT_CALL(*audio_renderer_, StopRendering());
+ EXPECT_CALL(time_source_, StopTicking());
EXPECT_CALL(*audio_renderer_, Flush(_))
.WillOnce(DoAll(SetBufferingState(&audio_buffering_state_cb_,
BUFFERING_HAVE_NOTHING),
@@ -771,7 +774,7 @@ TEST_F(PipelineTest, AudioTimeUpdateDuringSeek) {
StartPipeline(PIPELINE_OK);
float playback_rate = 1.0f;
- EXPECT_CALL(*audio_renderer_, SetPlaybackRate(playback_rate));
+ EXPECT_CALL(time_source_, SetPlaybackRate(playback_rate));
pipeline_->SetPlaybackRate(playback_rate);
message_loop_.RunUntilIdle();
@@ -790,18 +793,18 @@ TEST_F(PipelineTest, AudioTimeUpdateDuringSeek) {
.WillOnce(DoAll(InvokeWithoutArgs(&closure, &base::Closure::Run),
RunCallback<1>(PIPELINE_OK)));
- EXPECT_CALL(*audio_renderer_, StopRendering());
+ EXPECT_CALL(time_source_, StopTicking());
EXPECT_CALL(*audio_renderer_, Flush(_))
.WillOnce(DoAll(SetBufferingState(&audio_buffering_state_cb_,
BUFFERING_HAVE_NOTHING),
RunClosure<0>()));
- EXPECT_CALL(*audio_renderer_, SetMediaTime(seek_time));
+ EXPECT_CALL(time_source_, SetMediaTime(seek_time));
+ EXPECT_CALL(time_source_, SetPlaybackRate(_));
+ EXPECT_CALL(time_source_, StartTicking());
EXPECT_CALL(*audio_renderer_, StartPlaying())
.WillOnce(SetBufferingState(&audio_buffering_state_cb_,
BUFFERING_HAVE_ENOUGH));
- EXPECT_CALL(*audio_renderer_, SetPlaybackRate(_));
EXPECT_CALL(*audio_renderer_, SetVolume(_));
- EXPECT_CALL(*audio_renderer_, StartRendering());
EXPECT_CALL(callbacks_, OnSeek(PIPELINE_OK));
EXPECT_CALL(callbacks_, OnBufferingStateChange(BUFFERING_HAVE_ENOUGH));
@@ -849,10 +852,10 @@ TEST_F(PipelineTest, Underflow) {
StartPipeline(PIPELINE_OK);
// Simulate underflow.
- EXPECT_CALL(*audio_renderer_, StopRendering());
+ EXPECT_CALL(time_source_, StopTicking());
audio_buffering_state_cb_.Run(BUFFERING_HAVE_NOTHING);
- // Seek while underflowed. We shouldn't call StopRendering() again.
+ // Seek while underflowed. We shouldn't call StopTicking() again.
base::TimeDelta expected = base::TimeDelta::FromSeconds(5);
ExpectSeek(expected, true);
DoSeek(expected);
@@ -996,7 +999,12 @@ class PipelineTeardownTest : public PipelineTest {
EXPECT_CALL(callbacks_, OnMetadata(_));
// If we get here it's a successful initialization.
- EXPECT_CALL(*audio_renderer_, SetMediaTime(base::TimeDelta()));
+ EXPECT_CALL(*audio_renderer_, GetTimeSource())
+ .WillOnce(Return(&time_source_));
+ EXPECT_CALL(time_source_, SetMediaTime(base::TimeDelta()));
+ EXPECT_CALL(time_source_, SetPlaybackRate(0.0f));
+ EXPECT_CALL(time_source_, StartTicking());
+ EXPECT_CALL(*audio_renderer_, SetVolume(1.0f));
EXPECT_CALL(*audio_renderer_, StartPlaying())
.WillOnce(SetBufferingState(&audio_buffering_state_cb_,
BUFFERING_HAVE_ENOUGH));
@@ -1004,10 +1012,6 @@ class PipelineTeardownTest : public PipelineTest {
.WillOnce(SetBufferingState(&video_buffering_state_cb_,
BUFFERING_HAVE_ENOUGH));
- EXPECT_CALL(*audio_renderer_, SetPlaybackRate(0.0f));
- EXPECT_CALL(*audio_renderer_, SetVolume(1.0f));
- EXPECT_CALL(*audio_renderer_, StartRendering());
-
if (status == PIPELINE_OK)
EXPECT_CALL(callbacks_, OnBufferingStateChange(BUFFERING_HAVE_ENOUGH));
@@ -1038,7 +1042,7 @@ class PipelineTeardownTest : public PipelineTest {
base::Closure stop_cb = base::Bind(
&CallbackHelper::OnStop, base::Unretained(&callbacks_));
- EXPECT_CALL(*audio_renderer_, StopRendering());
+ EXPECT_CALL(time_source_, StopTicking());
if (state == kFlushing) {
if (stop_or_error == kStop) {
diff --git a/media/filters/audio_renderer_impl.cc b/media/filters/audio_renderer_impl.cc
index 9b0c098..cfdf016 100644
--- a/media/filters/audio_renderer_impl.cc
+++ b/media/filters/audio_renderer_impl.cc
@@ -72,7 +72,7 @@ AudioRendererImpl::~AudioRendererImpl() {
DCHECK(!algorithm_.get());
}
-void AudioRendererImpl::StartRendering() {
+void AudioRendererImpl::StartTicking() {
DVLOG(1) << __FUNCTION__;
DCHECK(task_runner_->BelongsToCurrentThread());
DCHECK(!rendering_);
@@ -102,7 +102,7 @@ void AudioRendererImpl::StartRendering_Locked() {
sink_->Play();
}
-void AudioRendererImpl::StopRendering() {
+void AudioRendererImpl::StopTicking() {
DVLOG(1) << __FUNCTION__;
DCHECK(task_runner_->BelongsToCurrentThread());
DCHECK(rendering_);
@@ -141,6 +141,21 @@ void AudioRendererImpl::SetMediaTime(base::TimeDelta time) {
start_timestamp_ = time;
}
+base::TimeDelta AudioRendererImpl::CurrentMediaTime() {
+ DVLOG(1) << __FUNCTION__;
+ 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() {
+ return this;
+}
+
void AudioRendererImpl::Flush(const base::Closure& callback) {
DVLOG(1) << __FUNCTION__;
DCHECK(task_runner_->BelongsToCurrentThread());
diff --git a/media/filters/audio_renderer_impl.h b/media/filters/audio_renderer_impl.h
index 6986562..28d62ab 100644
--- a/media/filters/audio_renderer_impl.h
+++ b/media/filters/audio_renderer_impl.h
@@ -29,6 +29,7 @@
#include "media/base/audio_renderer.h"
#include "media/base/audio_renderer_sink.h"
#include "media/base/decryptor.h"
+#include "media/base/time_source.h"
#include "media/filters/audio_renderer_algorithm.h"
#include "media/filters/decoder_stream.h"
@@ -47,6 +48,7 @@ class DecryptingDemuxerStream;
class MEDIA_EXPORT AudioRendererImpl
: public AudioRenderer,
+ public TimeSource,
NON_EXPORTED_BASE(public AudioRendererSink::RenderCallback) {
public:
// |task_runner| is the thread on which AudioRendererImpl will execute.
@@ -65,6 +67,13 @@ class MEDIA_EXPORT AudioRendererImpl
AudioHardwareConfig* hardware_params);
virtual ~AudioRendererImpl();
+ // TimeSource implementation.
+ virtual void StartTicking() OVERRIDE;
+ virtual void StopTicking() OVERRIDE;
+ virtual void SetPlaybackRate(float rate) OVERRIDE;
+ virtual void SetMediaTime(base::TimeDelta time) OVERRIDE;
+ virtual base::TimeDelta CurrentMediaTime() OVERRIDE;
+
// AudioRenderer implementation.
virtual void Initialize(DemuxerStream* stream,
const PipelineStatusCB& init_cb,
@@ -73,12 +82,9 @@ class MEDIA_EXPORT AudioRendererImpl
const BufferingStateCB& buffering_state_cb,
const base::Closure& ended_cb,
const PipelineStatusCB& error_cb) OVERRIDE;
- virtual void StartRendering() OVERRIDE;
- virtual void StopRendering() OVERRIDE;
- virtual void SetMediaTime(base::TimeDelta time) OVERRIDE;
+ virtual TimeSource* GetTimeSource() OVERRIDE;
virtual void Flush(const base::Closure& callback) OVERRIDE;
virtual void Stop(const base::Closure& callback) OVERRIDE;
- virtual void SetPlaybackRate(float rate) OVERRIDE;
virtual void StartPlaying() OVERRIDE;
virtual void SetVolume(float volume) OVERRIDE;
diff --git a/media/filters/audio_renderer_impl_unittest.cc b/media/filters/audio_renderer_impl_unittest.cc
index 1504c71..5aae0af 100644
--- a/media/filters/audio_renderer_impl_unittest.cc
+++ b/media/filters/audio_renderer_impl_unittest.cc
@@ -227,14 +227,12 @@ class AudioRendererImplTest : public ::testing::Test {
DeliverRemainingAudio();
}
- void StartRendering() {
- renderer_->StartRendering();
+ void StartTicking() {
+ renderer_->StartTicking();
renderer_->SetPlaybackRate(1.0f);
}
- void StopRendering() {
- renderer_->StopRendering();
- }
+ void StopTicking() { renderer_->StopTicking(); }
bool IsReadPending() const {
return !decode_cb_.is_null();
@@ -446,10 +444,10 @@ TEST_F(AudioRendererImplTest, Preroll) {
Preroll();
}
-TEST_F(AudioRendererImplTest, StartRendering) {
+TEST_F(AudioRendererImplTest, StartTicking) {
Initialize();
Preroll();
- StartRendering();
+ StartTicking();
// Drain internal buffer, we should have a pending read.
EXPECT_TRUE(ConsumeBufferedData(frames_buffered()));
@@ -459,7 +457,7 @@ TEST_F(AudioRendererImplTest, StartRendering) {
TEST_F(AudioRendererImplTest, EndOfStream) {
Initialize();
Preroll();
- StartRendering();
+ StartTicking();
// Drain internal buffer, we should have a pending read.
EXPECT_TRUE(ConsumeBufferedData(frames_buffered()));
@@ -486,7 +484,7 @@ TEST_F(AudioRendererImplTest, EndOfStream) {
TEST_F(AudioRendererImplTest, Underflow) {
Initialize();
Preroll();
- StartRendering();
+ StartTicking();
// Drain internal buffer, we should have a pending read.
EXPECT_TRUE(ConsumeBufferedData(frames_buffered()));
@@ -512,7 +510,7 @@ TEST_F(AudioRendererImplTest, Underflow) {
TEST_F(AudioRendererImplTest, Underflow_CapacityResetsAfterFlush) {
Initialize();
Preroll();
- StartRendering();
+ StartTicking();
// Drain internal buffer, we should have a pending read.
EXPECT_TRUE(ConsumeBufferedData(frames_buffered()));
@@ -535,7 +533,7 @@ TEST_F(AudioRendererImplTest, Underflow_CapacityResetsAfterFlush) {
TEST_F(AudioRendererImplTest, Underflow_Flush) {
Initialize();
Preroll();
- StartRendering();
+ StartTicking();
// Force underflow.
EXPECT_TRUE(ConsumeBufferedData(frames_buffered()));
@@ -543,7 +541,7 @@ TEST_F(AudioRendererImplTest, Underflow_Flush) {
EXPECT_CALL(*this, OnBufferingStateChange(BUFFERING_HAVE_NOTHING));
EXPECT_FALSE(ConsumeBufferedData(OutputFrames(1)));
WaitForPendingRead();
- StopRendering();
+ StopTicking();
// We shouldn't expect another buffering state change when flushing.
FlushDuringPendingRead();
@@ -553,13 +551,13 @@ TEST_F(AudioRendererImplTest, PendingRead_Flush) {
Initialize();
Preroll();
- StartRendering();
+ StartTicking();
// Partially drain internal buffer so we get a pending read.
EXPECT_TRUE(ConsumeBufferedData(OutputFrames(256)));
WaitForPendingRead();
- StopRendering();
+ StopTicking();
EXPECT_TRUE(IsReadPending());
@@ -575,13 +573,13 @@ TEST_F(AudioRendererImplTest, PendingRead_Stop) {
Initialize();
Preroll();
- StartRendering();
+ StartTicking();
// Partially drain internal buffer so we get a pending read.
EXPECT_TRUE(ConsumeBufferedData(OutputFrames(256)));
WaitForPendingRead();
- StopRendering();
+ StopTicking();
EXPECT_TRUE(IsReadPending());
@@ -600,13 +598,13 @@ TEST_F(AudioRendererImplTest, PendingFlush_Stop) {
Initialize();
Preroll();
- StartRendering();
+ StartTicking();
// Partially drain internal buffer so we get a pending read.
EXPECT_TRUE(ConsumeBufferedData(OutputFrames(256)));
WaitForPendingRead();
- StopRendering();
+ StopTicking();
EXPECT_TRUE(IsReadPending());
@@ -634,7 +632,7 @@ TEST_F(AudioRendererImplTest, InitializeThenStopDuringDecoderInit) {
TEST_F(AudioRendererImplTest, ConfigChangeDrainsConverter) {
Initialize();
Preroll();
- StartRendering();
+ StartTicking();
// Drain internal buffer, we should have a pending read.
EXPECT_TRUE(ConsumeBufferedData(frames_buffered()));
@@ -656,7 +654,7 @@ TEST_F(AudioRendererImplTest, ConfigChangeDrainsConverter) {
TEST_F(AudioRendererImplTest, TimeUpdatesOnFirstBuffer) {
Initialize();
Preroll();
- StartRendering();
+ StartTicking();
AudioTimestampHelper timestamp_helper(kOutputSamplesPerSecond);
EXPECT_EQ(kNoTimestamp(), last_time_update());
@@ -693,7 +691,7 @@ TEST_F(AudioRendererImplTest, ImmediateEndOfStream) {
EXPECT_CALL(*this, OnBufferingStateChange(BUFFERING_HAVE_ENOUGH));
DeliverEndOfStream();
}
- StartRendering();
+ StartTicking();
// Read a single frame. We shouldn't be able to satisfy it.
EXPECT_FALSE(ended());
@@ -704,7 +702,7 @@ TEST_F(AudioRendererImplTest, ImmediateEndOfStream) {
TEST_F(AudioRendererImplTest, OnRenderErrorCausesDecodeError) {
Initialize();
Preroll();
- StartRendering();
+ StartTicking();
EXPECT_CALL(*this, OnError(PIPELINE_ERROR_DECODE));
sink_->OnRenderError();
@@ -725,7 +723,7 @@ TEST_F(AudioRendererImplTest, SetPlaybackRate) {
// Rendering has started with non-zero rate. Rate changes will affect sink
// state.
- renderer_->StartRendering();
+ renderer_->StartTicking();
EXPECT_EQ(FakeAudioRendererSink::kPlaying, sink_->state());
renderer_->SetPlaybackRate(0.0f);
EXPECT_EQ(FakeAudioRendererSink::kPaused, sink_->state());
@@ -733,13 +731,13 @@ TEST_F(AudioRendererImplTest, SetPlaybackRate) {
EXPECT_EQ(FakeAudioRendererSink::kPlaying, sink_->state());
// Rendering has stopped. Sink should be paused.
- renderer_->StopRendering();
+ renderer_->StopTicking();
EXPECT_EQ(FakeAudioRendererSink::kPaused, sink_->state());
// Start rendering with zero playback rate. Sink should be paused until
// non-zero rate is set.
renderer_->SetPlaybackRate(0.0f);
- renderer_->StartRendering();
+ renderer_->StartTicking();
EXPECT_EQ(FakeAudioRendererSink::kPaused, sink_->state());
renderer_->SetPlaybackRate(1.0f);
EXPECT_EQ(FakeAudioRendererSink::kPlaying, sink_->state());