summaryrefslogtreecommitdiffstats
path: root/media
diff options
context:
space:
mode:
authorscherkus@chromium.org <scherkus@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-07-09 23:00:10 +0000
committerscherkus@chromium.org <scherkus@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-07-09 23:00:10 +0000
commitc691aae93911859a45dabf6d1fca8a7f319c523f (patch)
tree35965d7141fd74509da51d56a53daa3b60415b41 /media
parentecc703929354d51b5e48854d41e222c51497f5d3 (diff)
downloadchromium_src-c691aae93911859a45dabf6d1fca8a7f319c523f.zip
chromium_src-c691aae93911859a45dabf6d1fca8a7f319c523f.tar.gz
chromium_src-c691aae93911859a45dabf6d1fca8a7f319c523f.tar.bz2
Remove default implementations for media::Filter methods.
Another step towards eliminating the Filter class altogether! While attempting to refactor AudioRenderer out of Filter I noticed that Filter's default implementations caused Pipeline tests to not set appropriate expectations leading to unexpected gmock warnings. With this change we should be able to continue refactoring with no changes to unit tests. BUG=108341, 108342 TEST=none Review URL: https://chromiumcodereview.appspot.com/10749003 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@145771 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'media')
-rw-r--r--media/base/composite_filter.cc21
-rw-r--r--media/base/composite_filter.h9
-rw-r--r--media/base/composite_filter_unittest.cc10
-rw-r--r--media/base/filters.cc44
-rw-r--r--media/base/filters.h32
-rw-r--r--media/base/mock_filters.cc6
-rw-r--r--media/base/mock_filters.h24
-rw-r--r--media/base/pipeline.cc19
-rw-r--r--media/base/pipeline_unittest.cc95
-rw-r--r--media/filters/audio_renderer_impl.cc13
-rw-r--r--media/filters/audio_renderer_impl.h3
-rw-r--r--media/filters/audio_renderer_impl_unittest.cc2
-rw-r--r--media/filters/video_renderer_base.cc29
-rw-r--r--media/filters/video_renderer_base.h3
-rw-r--r--media/filters/video_renderer_base_unittest.cc2
15 files changed, 158 insertions, 154 deletions
diff --git a/media/base/composite_filter.cc b/media/base/composite_filter.cc
index 6023846..d6f2951 100644
--- a/media/base/composite_filter.cc
+++ b/media/base/composite_filter.cc
@@ -56,21 +56,17 @@ void CompositeFilter::AddFilter(scoped_refptr<Filter> filter) {
CHECK(filter && state_ == kCreated && host());
// Register ourselves as the filter's host.
- filter->set_host(host_impl_.get());
+ filter->SetHost(host_impl_.get());
filters_.push_back(make_scoped_refptr(filter.get()));
}
-void CompositeFilter::set_host(FilterHost* host) {
+void CompositeFilter::SetHost(FilterHost* host) {
DCHECK(message_loop_->BelongsToCurrentThread());
DCHECK(host);
DCHECK(!host_impl_.get());
host_impl_.reset(new FilterHostImpl(this, host));
}
-FilterHost* CompositeFilter::host() {
- return host_impl_.get() ? host_impl_->host() : NULL;
-}
-
void CompositeFilter::Play(const base::Closure& play_cb) {
DCHECK(message_loop_->BelongsToCurrentThread());
if (IsOperationPending()) {
@@ -202,15 +198,6 @@ void CompositeFilter::Seek(base::TimeDelta time,
StartSerialCallSequence();
}
-void CompositeFilter::OnAudioRendererDisabled() {
- DCHECK(message_loop_->BelongsToCurrentThread());
- for (FilterVector::iterator iter = filters_.begin();
- iter != filters_.end();
- ++iter) {
- (*iter)->OnAudioRendererDisabled();
- }
-}
-
void CompositeFilter::ChangeState(State new_state) {
DCHECK(message_loop_->BelongsToCurrentThread());
state_ = new_state;
@@ -425,6 +412,10 @@ void CompositeFilter::OnStatusCB(const base::Closure& callback,
callback.Run();
}
+FilterHost* CompositeFilter::host() {
+ return host_impl_.get()->host();
+}
+
void CompositeFilter::SetError(PipelineStatus error) {
if (!message_loop_->BelongsToCurrentThread()) {
message_loop_->PostTask(FROM_HERE,
diff --git a/media/base/composite_filter.h b/media/base/composite_filter.h
index 4feea54..8393f73 100644
--- a/media/base/composite_filter.h
+++ b/media/base/composite_filter.h
@@ -23,14 +23,13 @@ class MEDIA_EXPORT CompositeFilter : public Filter {
explicit CompositeFilter(
const scoped_refptr<base::MessageLoopProxy>& message_loop);
- // Adds a filter to the composite. This is only allowed after set_host()
+ // Adds a filter to the composite. This is only allowed after SetHost()
// is called and before the first state changing operation such as Play(),
// Flush(), Stop(), or Seek(). CHECK-fails if preconditions are not met.
void AddFilter(scoped_refptr<Filter> filter);
// media::Filter methods.
- virtual void set_host(FilterHost* host) OVERRIDE;
- virtual FilterHost* host() OVERRIDE;
+ virtual void SetHost(FilterHost* host) OVERRIDE;
virtual void Play(const base::Closure& play_cb) OVERRIDE;
virtual void Pause(const base::Closure& pause_cb) OVERRIDE;
virtual void Flush(const base::Closure& flush_cb) OVERRIDE;
@@ -38,7 +37,6 @@ class MEDIA_EXPORT CompositeFilter : public Filter {
virtual void SetPlaybackRate(float playback_rate) OVERRIDE;
virtual void Seek(
base::TimeDelta time, const PipelineStatusCB& seek_cb) OVERRIDE;
- virtual void OnAudioRendererDisabled() OVERRIDE;
protected:
virtual ~CompositeFilter();
@@ -112,6 +110,9 @@ class MEDIA_EXPORT CompositeFilter : public Filter {
// TODO: Remove when Closures are replaced by PipelineStatusCB.
void OnStatusCB(const base::Closure& callback, PipelineStatus status);
+ // Convenience method for accessing the FilterHost object.
+ FilterHost* host();
+
// Vector of the filters added to the composite.
typedef std::vector<scoped_refptr<Filter> > FilterVector;
FilterVector filters_;
diff --git a/media/base/composite_filter_unittest.cc b/media/base/composite_filter_unittest.cc
index 2dfd070..44aeaad 100644
--- a/media/base/composite_filter_unittest.cc
+++ b/media/base/composite_filter_unittest.cc
@@ -134,7 +134,7 @@ class CompositeFilterTest : public testing::Test {
// Callback passed to |filter_2_| during last Seek() call.
PipelineStatusCB filter_2_status_cb_;
- // FilterHost implementation passed to |composite_| via set_host().
+ // FilterHost implementation passed to |composite_| via SetHost().
scoped_ptr<StrictMock<MockFilterHost> > mock_filter_host_;
DISALLOW_COPY_AND_ASSIGN(CompositeFilterTest);
@@ -152,7 +152,7 @@ CompositeFilterTest::~CompositeFilterTest() {}
void CompositeFilterTest::SetupAndAdd2Filters() {
mock_filter_host_.reset(new StrictMock<MockFilterHost>());
composite_ = new CompositeFilter(message_loop_.message_loop_proxy());
- composite_->set_host(mock_filter_host_.get());
+ composite_->SetHost(mock_filter_host_.get());
// Setup |filter_1_| and arrange for methods to set
// |filter_1_cb_| when they are called.
@@ -370,7 +370,7 @@ void CompositeFilterTest::RunFilter2Callback() {
// Test successful AddFilter() cases.
TEST_F(CompositeFilterTest, TestAddFilter) {
- composite_->set_host(mock_filter_host_.get());
+ composite_->SetHost(mock_filter_host_.get());
// Add a filter.
scoped_refptr<StrictMock<MockFilter> > filter = new StrictMock<MockFilter>();
@@ -396,7 +396,7 @@ TEST_F(CompositeFilterDeathTest, TestAddFilterFailCases) {
scoped_refptr<StrictMock<MockFilter> > filter = new StrictMock<MockFilter>();
EXPECT_EQ(NULL, filter->host());
- // Test failing because set_host() hasn't been called yet.
+ // Test failing because SetHost() hasn't been called yet.
EXPECT_DEATH_IF_SUPPORTED(composite_->AddFilter(filter), "");
}
@@ -769,7 +769,7 @@ TEST_F(CompositeFilterTest, TestErrorWhilePlaying) {
TEST_F(CompositeFilterTest, TestEmptyComposite) {
InSequence sequence;
- composite_->set_host(mock_filter_host_.get());
+ composite_->SetHost(mock_filter_host_.get());
// Issue a Play() and expect no errors.
composite_->Play(NewExpectedClosure());
diff --git a/media/base/filters.cc b/media/base/filters.cc
index 94bd623..17be8a5 100644
--- a/media/base/filters.cc
+++ b/media/base/filters.cc
@@ -4,52 +4,10 @@
#include "media/base/filters.h"
-#include "base/logging.h"
-
namespace media {
-Filter::Filter() : host_(NULL) {}
+Filter::Filter() {}
Filter::~Filter() {}
-void Filter::set_host(FilterHost* host) {
- DCHECK(host);
- DCHECK(!host_);
- host_ = host;
-}
-
-FilterHost* Filter::host() {
- return host_;
-}
-
-void Filter::Play(const base::Closure& callback) {
- DCHECK(!callback.is_null());
- callback.Run();
-}
-
-void Filter::Pause(const base::Closure& callback) {
- DCHECK(!callback.is_null());
- callback.Run();
-}
-
-void Filter::Flush(const base::Closure& callback) {
- DCHECK(!callback.is_null());
- callback.Run();
-}
-
-void Filter::Stop(const base::Closure& callback) {
- DCHECK(!callback.is_null());
- callback.Run();
-}
-
-void Filter::SetPlaybackRate(float playback_rate) {}
-
-void Filter::Seek(base::TimeDelta time, const PipelineStatusCB& callback) {
- DCHECK(!callback.is_null());
- callback.Run(PIPELINE_OK);
-}
-
-void Filter::OnAudioRendererDisabled() {
-}
-
} // namespace media
diff --git a/media/base/filters.h b/media/base/filters.h
index 5f9d5ef..9cec12a 100644
--- a/media/base/filters.h
+++ b/media/base/filters.h
@@ -37,57 +37,41 @@ class MEDIA_EXPORT Filter : public base::RefCountedThreadSafe<Filter> {
public:
Filter();
- // Sets the private member |host_|. This is the first method called by
- // the FilterHost after a filter is created. The host holds a strong
+ // Sets the host that owns this filter. The host holds a strong
// reference to the filter. The reference held by the host is guaranteed
// to be released before the host object is destroyed by the pipeline.
- virtual void set_host(FilterHost* host);
-
- virtual FilterHost* host();
+ virtual void SetHost(FilterHost* host) = 0;
// The pipeline has resumed playback. Filters can continue requesting reads.
// Filters may implement this method if they need to respond to this call.
- // TODO(boliu): Check that callback is not NULL in subclasses.
- virtual void Play(const base::Closure& callback);
+ virtual void Play(const base::Closure& callback) = 0;
// The pipeline has paused playback. Filters should stop buffer exchange.
// Filters may implement this method if they need to respond to this call.
- // TODO(boliu): Check that callback is not NULL in subclasses.
- virtual void Pause(const base::Closure& callback);
+ virtual void Pause(const base::Closure& callback) = 0;
// The pipeline has been flushed. Filters should return buffer to owners.
// Filters may implement this method if they need to respond to this call.
- // TODO(boliu): Check that callback is not NULL in subclasses.
- virtual void Flush(const base::Closure& callback);
+ virtual void Flush(const base::Closure& callback) = 0;
// The pipeline is being stopped either as a result of an error or because
// the client called Stop().
- // TODO(boliu): Check that callback is not NULL in subclasses.
- virtual void Stop(const base::Closure& callback);
+ virtual void Stop(const base::Closure& callback) = 0;
// The pipeline playback rate has been changed. Filters may implement this
// method if they need to respond to this call.
- virtual void SetPlaybackRate(float playback_rate);
+ virtual void SetPlaybackRate(float playback_rate) = 0;
// Carry out any actions required to seek to the given time, executing the
// callback upon completion.
- virtual void Seek(base::TimeDelta time, const PipelineStatusCB& callback);
-
- // This method is called from the pipeline when the audio renderer
- // is disabled. Filters can ignore the notification if they do not
- // need to react to this event.
- virtual void OnAudioRendererDisabled();
+ virtual void Seek(base::TimeDelta time, const PipelineStatusCB& callback) = 0;
protected:
// Only allow scoped_refptr<> to delete filters.
friend class base::RefCountedThreadSafe<Filter>;
virtual ~Filter();
- FilterHost* host() const { return host_; }
-
private:
- FilterHost* host_;
-
DISALLOW_COPY_AND_ASSIGN(Filter);
};
diff --git a/media/base/mock_filters.cc b/media/base/mock_filters.cc
index b10d42a..cd6e71c 100644
--- a/media/base/mock_filters.cc
+++ b/media/base/mock_filters.cc
@@ -104,10 +104,14 @@ void RunClosure(const base::Closure& closure) {
closure.Run();
}
-MockFilter::MockFilter() {}
+MockFilter::MockFilter() : host_(NULL) {}
MockFilter::~MockFilter() {}
+void MockFilter::SetHost(FilterHost* host) {
+ host_ = host;
+}
+
MockStatisticsCB::MockStatisticsCB() {}
MockStatisticsCB::~MockStatisticsCB() {}
diff --git a/media/base/mock_filters.h b/media/base/mock_filters.h
index 88e16bf..c52cc82 100644
--- a/media/base/mock_filters.h
+++ b/media/base/mock_filters.h
@@ -52,23 +52,29 @@ class Destroyable : public MockClass {
DISALLOW_COPY_AND_ASSIGN(Destroyable);
};
+// TODO(scherkus): remove when CompositeFilter is removed, see
+// http://crbug.com/126069
class MockFilter : public Filter {
public:
MockFilter();
// Filter implementation.
+ void SetHost(FilterHost* host) OVERRIDE;
MOCK_METHOD1(Play, void(const base::Closure& callback));
MOCK_METHOD1(Pause, void(const base::Closure& callback));
MOCK_METHOD1(Flush, void(const base::Closure& callback));
MOCK_METHOD1(Stop, void(const base::Closure& callback));
MOCK_METHOD1(SetPlaybackRate, void(float playback_rate));
MOCK_METHOD2(Seek, void(base::TimeDelta time, const PipelineStatusCB& cb));
- MOCK_METHOD0(OnAudioRendererDisabled, void());
+
+ FilterHost* host() { return host_; }
protected:
virtual ~MockFilter();
private:
+ FilterHost* host_;
+
DISALLOW_COPY_AND_ASSIGN(MockFilter);
};
@@ -160,10 +166,13 @@ class MockVideoRenderer : public VideoRenderer {
MockVideoRenderer();
// Filter implementation.
+ MOCK_METHOD1(SetHost, void(FilterHost* host));
+ MOCK_METHOD1(Play, void(const base::Closure& callback));
+ MOCK_METHOD1(Pause, void(const base::Closure& callback));
+ MOCK_METHOD1(Flush, void(const base::Closure& callback));
MOCK_METHOD1(Stop, void(const base::Closure& callback));
MOCK_METHOD1(SetPlaybackRate, void(float playback_rate));
MOCK_METHOD2(Seek, void(base::TimeDelta time, const PipelineStatusCB& cb));
- MOCK_METHOD0(OnAudioRendererDisabled, void());
// VideoRenderer implementation.
MOCK_METHOD4(Initialize, void(const scoped_refptr<VideoDecoder>& decoder,
@@ -189,10 +198,13 @@ class MockAudioRenderer : public AudioRenderer {
MockAudioRenderer();
// Filter implementation.
+ MOCK_METHOD1(SetHost, void(FilterHost* host));
+ MOCK_METHOD1(Play, void(const base::Closure& callback));
+ MOCK_METHOD1(Pause, void(const base::Closure& callback));
+ MOCK_METHOD1(Flush, void(const base::Closure& callback));
MOCK_METHOD1(Stop, void(const base::Closure& callback));
MOCK_METHOD1(SetPlaybackRate, void(float playback_rate));
MOCK_METHOD2(Seek, void(base::TimeDelta time, const PipelineStatusCB& cb));
- MOCK_METHOD0(OnAudioRendererDisabled, void());
// AudioRenderer implementation.
MOCK_METHOD4(Initialize, void(const scoped_refptr<AudioDecoder>& decoder,
@@ -297,12 +309,6 @@ ACTION_P2(SetDuration, filter, duration) {
filter->host()->SetDuration(duration);
}
-// Helper gmock action that calls DisableAudioRenderer() on behalf of the
-// provided filter.
-ACTION_P(DisableAudioRenderer, filter) {
- filter->host()->DisableAudioRenderer();
-}
-
// Helper mock statistics callback.
class MockStatisticsCB {
public:
diff --git a/media/base/pipeline.cc b/media/base/pipeline.cc
index b8f7755f..fd59a130 100644
--- a/media/base/pipeline.cc
+++ b/media/base/pipeline.cc
@@ -549,7 +549,7 @@ void Pipeline::StartTask(scoped_ptr<FilterCollection> filter_collection,
// Kick off initialization.
pipeline_init_state_.reset(new PipelineInitState());
pipeline_init_state_->composite = new CompositeFilter(message_loop_);
- pipeline_init_state_->composite->set_host(this);
+ pipeline_init_state_->composite->SetHost(this);
SetState(kInitDemuxer);
InitializeDemuxer();
@@ -647,13 +647,6 @@ void Pipeline::InitializeTask(PipelineStatus last_stage_status) {
// Clear init state since we're done initializing.
pipeline_init_state_.reset();
- if (audio_disabled_) {
- // Audio was disabled at some point during initialization. Notify
- // the pipeline filter now that it has been initialized.
- demuxer_->OnAudioRendererDisabled();
- pipeline_filter_->OnAudioRendererDisabled();
- }
-
// Initialization was successful, we are now considered paused, so it's safe
// to set the initial playback rate and volume.
PlaybackRateChangedTask(GetPlaybackRate());
@@ -849,14 +842,8 @@ void Pipeline::DisableAudioRendererTask() {
has_audio_ = false;
audio_disabled_ = true;
- // Notify all filters of disabled audio renderer. If the filter isn't
- // initialized yet, OnAudioRendererDisabled() will be called when
- // initialization is complete.
- if (pipeline_filter_) {
- DCHECK(demuxer_);
- demuxer_->OnAudioRendererDisabled();
- pipeline_filter_->OnAudioRendererDisabled();
- }
+ // Notify our demuxer that we're no longer rendering audio.
+ demuxer_->OnAudioRendererDisabled();
// Start clock since there is no more audio to
// trigger clock updates.
diff --git a/media/base/pipeline_unittest.cc b/media/base/pipeline_unittest.cc
index 5133695..6261345 100644
--- a/media/base/pipeline_unittest.cc
+++ b/media/base/pipeline_unittest.cc
@@ -46,6 +46,11 @@ ACTION_P(SetDemuxerProperties, duration) {
arg0->SetDuration(duration);
}
+ACTION_P(DisableAudioRenderer, pipeline) {
+ FilterHost* host = pipeline;
+ host->DisableAudioRenderer();
+}
+
// Used for setting expectations on pipeline callbacks. Using a StrictMock
// also lets us test for missing callbacks.
class CallbackHelper {
@@ -90,6 +95,30 @@ class PipelineTest : public ::testing::Test {
return;
}
+ // Shutdown sequence.
+ if (pipeline_->IsInitialized()) {
+ EXPECT_CALL(*mocks_->demuxer(), Stop(_))
+ .WillOnce(Invoke(&RunClosure));
+
+ if (audio_stream_) {
+ EXPECT_CALL(*mocks_->audio_renderer(), Pause(_))
+ .WillOnce(Invoke(&RunClosure));
+ EXPECT_CALL(*mocks_->audio_renderer(), Flush(_))
+ .WillOnce(Invoke(&RunClosure));
+ EXPECT_CALL(*mocks_->audio_renderer(), Stop(_))
+ .WillOnce(Invoke(&RunClosure));
+ }
+
+ if (video_stream_) {
+ EXPECT_CALL(*mocks_->video_renderer(), Pause(_))
+ .WillOnce(Invoke(&RunClosure));
+ EXPECT_CALL(*mocks_->video_renderer(), Flush(_))
+ .WillOnce(Invoke(&RunClosure));
+ EXPECT_CALL(*mocks_->video_renderer(), Stop(_))
+ .WillOnce(Invoke(&RunClosure));
+ }
+ }
+
// Expect a stop callback if we were started.
EXPECT_CALL(callbacks_, OnStop());
pipeline_->Stop(base::Bind(&CallbackHelper::OnStop,
@@ -109,8 +138,6 @@ class PipelineTest : public ::testing::Test {
.WillOnce(DoAll(SetDemuxerProperties(duration),
Invoke(&RunPipelineStatusCB2)));
EXPECT_CALL(*mocks_->demuxer(), SetPlaybackRate(0.0f));
- EXPECT_CALL(*mocks_->demuxer(), Stop(_))
- .WillOnce(Invoke(&RunClosure));
// Demuxer properties.
EXPECT_CALL(*mocks_->demuxer(), GetBitrate())
@@ -152,24 +179,28 @@ class PipelineTest : public ::testing::Test {
// Sets up expectations to allow the video renderer to initialize.
void InitializeVideoRenderer() {
+ EXPECT_CALL(*mocks_->video_renderer(), SetHost(NotNull()));
EXPECT_CALL(*mocks_->video_renderer(), Initialize(
scoped_refptr<VideoDecoder>(mocks_->video_decoder()), _, _, _))
.WillOnce(Invoke(&RunPipelineStatusCB4));
EXPECT_CALL(*mocks_->video_renderer(), SetPlaybackRate(0.0f));
+
+ // Startup sequence.
EXPECT_CALL(*mocks_->video_renderer(),
Seek(mocks_->demuxer()->GetStartTime(), _))
.WillOnce(Invoke(&RunPipelineStatusCB2));
- EXPECT_CALL(*mocks_->video_renderer(), Stop(_))
+ EXPECT_CALL(*mocks_->video_renderer(), Play(_))
.WillOnce(Invoke(&RunClosure));
}
// Sets up expectations to allow the audio renderer to initialize.
void InitializeAudioRenderer(bool disable_after_init_cb = false) {
+ EXPECT_CALL(*mocks_->audio_renderer(), SetHost(NotNull()));
if (disable_after_init_cb) {
EXPECT_CALL(*mocks_->audio_renderer(), Initialize(
scoped_refptr<AudioDecoder>(mocks_->audio_decoder()), _, _, _))
.WillOnce(DoAll(Invoke(&RunPipelineStatusCB4),
- DisableAudioRenderer(mocks_->audio_renderer())));
+ DisableAudioRenderer(pipeline_)));
} else {
EXPECT_CALL(*mocks_->audio_renderer(), Initialize(
scoped_refptr<AudioDecoder>(mocks_->audio_decoder()), _, _, _))
@@ -177,9 +208,11 @@ class PipelineTest : public ::testing::Test {
}
EXPECT_CALL(*mocks_->audio_renderer(), SetPlaybackRate(0.0f));
EXPECT_CALL(*mocks_->audio_renderer(), SetVolume(1.0f));
+
+ // Startup sequence.
EXPECT_CALL(*mocks_->audio_renderer(), Seek(base::TimeDelta(), _))
.WillOnce(Invoke(&RunPipelineStatusCB2));
- EXPECT_CALL(*mocks_->audio_renderer(), Stop(_))
+ EXPECT_CALL(*mocks_->audio_renderer(), Play(_))
.WillOnce(Invoke(&RunClosure));
}
@@ -218,13 +251,25 @@ class PipelineTest : public ::testing::Test {
.WillOnce(Invoke(&RunPipelineStatusCB2));
if (audio_stream_) {
+ EXPECT_CALL(*mocks_->audio_renderer(), Pause(_))
+ .WillOnce(Invoke(&RunClosure));
+ EXPECT_CALL(*mocks_->audio_renderer(), Flush(_))
+ .WillOnce(Invoke(&RunClosure));
EXPECT_CALL(*mocks_->audio_renderer(), Seek(seek_time, _))
.WillOnce(Invoke(&RunPipelineStatusCB2));
+ EXPECT_CALL(*mocks_->audio_renderer(), Play(_))
+ .WillOnce(Invoke(&RunClosure));
}
if (video_stream_) {
+ EXPECT_CALL(*mocks_->video_renderer(), Pause(_))
+ .WillOnce(Invoke(&RunClosure));
+ EXPECT_CALL(*mocks_->video_renderer(), Flush(_))
+ .WillOnce(Invoke(&RunClosure));
EXPECT_CALL(*mocks_->video_renderer(), Seek(seek_time, _))
.WillOnce(Invoke(&RunPipelineStatusCB2));
+ EXPECT_CALL(*mocks_->video_renderer(), Play(_))
+ .WillOnce(Invoke(&RunClosure));
}
// We expect a successful seek callback.
@@ -413,12 +458,12 @@ TEST_F(PipelineTest, Seek) {
InitializeVideoDecoder(video_stream());
InitializeVideoRenderer();
+ // Initialize then seek!
+ InitializePipeline(PIPELINE_OK);
+
// Every filter should receive a call to Seek().
base::TimeDelta expected = base::TimeDelta::FromSeconds(2000);
ExpectSeek(expected);
-
- // Initialize then seek!
- InitializePipeline(PIPELINE_OK);
DoSeek(expected);
}
@@ -530,13 +575,9 @@ TEST_F(PipelineTest, DisableAudioRenderer) {
EXPECT_TRUE(pipeline_->HasVideo());
EXPECT_CALL(*mocks_->audio_renderer(), SetPlaybackRate(1.0f))
- .WillOnce(DisableAudioRenderer(mocks_->audio_renderer()));
+ .WillOnce(DisableAudioRenderer(pipeline_));
EXPECT_CALL(*mocks_->demuxer(),
OnAudioRendererDisabled());
- EXPECT_CALL(*mocks_->audio_renderer(),
- OnAudioRendererDisabled());
- EXPECT_CALL(*mocks_->video_renderer(),
- OnAudioRendererDisabled());
mocks_->audio_renderer()->SetPlaybackRate(1.0f);
@@ -563,10 +604,6 @@ TEST_F(PipelineTest, DisableAudioRendererDuringInit) {
EXPECT_CALL(*mocks_->demuxer(),
OnAudioRendererDisabled());
- EXPECT_CALL(*mocks_->audio_renderer(),
- OnAudioRendererDisabled());
- EXPECT_CALL(*mocks_->video_renderer(),
- OnAudioRendererDisabled());
InitializePipeline(PIPELINE_OK);
EXPECT_TRUE(pipeline_->IsInitialized());
@@ -708,12 +745,20 @@ TEST_F(PipelineTest, ErrorDuringSeek) {
pipeline_->SetPlaybackRate(playback_rate);
message_loop_.RunAllPending();
- InSequence s;
-
base::TimeDelta seek_time = base::TimeDelta::FromSeconds(5);
+ // Seek() isn't called as the demuxer errors out first.
+ EXPECT_CALL(*mocks_->audio_renderer(), Pause(_))
+ .WillOnce(Invoke(&RunClosure));
+ EXPECT_CALL(*mocks_->audio_renderer(), Flush(_))
+ .WillOnce(Invoke(&RunClosure));
+ EXPECT_CALL(*mocks_->audio_renderer(), Stop(_))
+ .WillOnce(Invoke(&RunClosure));
+
EXPECT_CALL(*mocks_->demuxer(), Seek(seek_time, _))
.WillOnce(Invoke(&SendReadErrorToCB));
+ EXPECT_CALL(*mocks_->demuxer(), Stop(_))
+ .WillOnce(Invoke(&RunClosure));
pipeline_->Seek(seek_time, base::Bind(&CallbackHelper::OnSeek,
base::Unretained(&callbacks_)));
@@ -756,12 +801,20 @@ TEST_F(PipelineTest, NoMessageDuringTearDownFromError) {
ON_CALL(callbacks_, OnError(_))
.WillByDefault(Invoke(&cb, &base::Callback<void(PipelineStatus)>::Run));
- InSequence s;
-
base::TimeDelta seek_time = base::TimeDelta::FromSeconds(5);
+ // Seek() isn't called as the demuxer errors out first.
+ EXPECT_CALL(*mocks_->audio_renderer(), Pause(_))
+ .WillOnce(Invoke(&RunClosure));
+ EXPECT_CALL(*mocks_->audio_renderer(), Flush(_))
+ .WillOnce(Invoke(&RunClosure));
+ EXPECT_CALL(*mocks_->audio_renderer(), Stop(_))
+ .WillOnce(Invoke(&RunClosure));
+
EXPECT_CALL(*mocks_->demuxer(), Seek(seek_time, _))
.WillOnce(Invoke(&SendReadErrorToCB));
+ EXPECT_CALL(*mocks_->demuxer(), Stop(_))
+ .WillOnce(Invoke(&RunClosure));
pipeline_->Seek(seek_time, base::Bind(&CallbackHelper::OnSeek,
base::Unretained(&callbacks_)));
diff --git a/media/filters/audio_renderer_impl.cc b/media/filters/audio_renderer_impl.cc
index 4af31fc..c8841cd 100644
--- a/media/filters/audio_renderer_impl.cc
+++ b/media/filters/audio_renderer_impl.cc
@@ -16,7 +16,8 @@
namespace media {
AudioRendererImpl::AudioRendererImpl(media::AudioRendererSink* sink)
- : state_(kUninitialized),
+ : host_(NULL),
+ state_(kUninitialized),
pending_read_(false),
received_end_of_stream_(false),
rendered_end_of_stream_(false),
@@ -32,6 +33,12 @@ AudioRendererImpl::AudioRendererImpl(media::AudioRendererSink* sink)
base::Unretained(this))) {
}
+void AudioRendererImpl::SetHost(FilterHost* host) {
+ DCHECK(host);
+ DCHECK(!host_);
+ host_ = host;
+}
+
void AudioRendererImpl::Play(const base::Closure& callback) {
{
base::AutoLock auto_lock(lock_);
@@ -417,7 +424,7 @@ uint32 AudioRendererImpl::FillBuffer(uint8* dest,
if (!algorithm_->CanFillBuffer() && received_end_of_stream_ &&
!rendered_end_of_stream_ && base::Time::Now() >= earliest_end_time_) {
rendered_end_of_stream_ = true;
- host()->NotifyEnded();
+ host_->NotifyEnded();
} else if (!algorithm_->CanFillBuffer() && !received_end_of_stream_ &&
state_ == kPlaying && !underflow_disabled_) {
state_ = kUnderflow;
@@ -500,7 +507,7 @@ base::TimeDelta AudioRendererImpl::ConvertToDuration(int bytes) {
}
void AudioRendererImpl::OnRenderError() {
- host()->DisableAudioRenderer();
+ host_->DisableAudioRenderer();
}
void AudioRendererImpl::DisableUnderflowForTesting() {
diff --git a/media/filters/audio_renderer_impl.h b/media/filters/audio_renderer_impl.h
index efa59e7..3be42f8 100644
--- a/media/filters/audio_renderer_impl.h
+++ b/media/filters/audio_renderer_impl.h
@@ -41,6 +41,7 @@ class MEDIA_EXPORT AudioRendererImpl
// Methods called on pipeline thread ----------------------------------------
// Filter implementation.
+ virtual void SetHost(FilterHost* host) OVERRIDE;
virtual void Play(const base::Closure& callback) OVERRIDE;
virtual void Pause(const base::Closure& callback) OVERRIDE;
virtual void Flush(const base::Closure& callback) OVERRIDE;
@@ -130,6 +131,8 @@ class MEDIA_EXPORT AudioRendererImpl
// in the kSeeking state.
bool IsBeforeSeekTime(const scoped_refptr<Buffer>& buffer);
+ FilterHost* host_;
+
// Audio decoder.
scoped_refptr<AudioDecoder> decoder_;
diff --git a/media/filters/audio_renderer_impl_unittest.cc b/media/filters/audio_renderer_impl_unittest.cc
index 84921b9..1633087 100644
--- a/media/filters/audio_renderer_impl_unittest.cc
+++ b/media/filters/audio_renderer_impl_unittest.cc
@@ -52,7 +52,7 @@ class AudioRendererImplTest : public ::testing::Test {
AudioRendererImplTest()
: renderer_(new AudioRendererImpl(new NiceMock<MockAudioSink>())),
decoder_(new MockAudioDecoder()) {
- renderer_->set_host(&host_);
+ renderer_->SetHost(&host_);
// Queue all reads from the decoder by default.
ON_CALL(*decoder_, Read(_))
diff --git a/media/filters/video_renderer_base.cc b/media/filters/video_renderer_base.cc
index f6cfe7f..8451201 100644
--- a/media/filters/video_renderer_base.cc
+++ b/media/filters/video_renderer_base.cc
@@ -18,7 +18,8 @@ namespace media {
VideoRendererBase::VideoRendererBase(const base::Closure& paint_cb,
const SetOpaqueCB& set_opaque_cb,
bool drop_frames)
- : frame_available_(&lock_),
+ : host_(NULL),
+ frame_available_(&lock_),
state_(kUninitialized),
thread_(base::kNullThreadHandle),
pending_read_(false),
@@ -31,6 +32,12 @@ VideoRendererBase::VideoRendererBase(const base::Closure& paint_cb,
DCHECK(!paint_cb_.is_null());
}
+void VideoRendererBase::SetHost(FilterHost* host) {
+ DCHECK(host);
+ DCHECK(!host_);
+ host_ = host;
+}
+
void VideoRendererBase::Play(const base::Closure& callback) {
base::AutoLock auto_lock(lock_);
DCHECK_EQ(kPrerolled, state_);
@@ -122,7 +129,7 @@ void VideoRendererBase::Initialize(const scoped_refptr<VideoDecoder>& decoder,
time_cb_ = time_cb;
// Notify the pipeline of the video dimensions.
- host()->SetNaturalVideoSize(decoder_->natural_size());
+ host_->SetNaturalVideoSize(decoder_->natural_size());
// We're all good! Consider ourselves flushed. (ThreadMain() should never
// see us in the kUninitialized state).
@@ -201,7 +208,7 @@ void VideoRendererBase::ThreadMain() {
// This can happen if our preroll only contains end of stream frames.
if (ready_frames_.front()->IsEndOfStream()) {
state_ = kEnded;
- host()->NotifyEnded();
+ host_->NotifyEnded();
ready_frames_.clear();
// No need to sleep here as we idle when |state_ != kPlaying|.
@@ -240,7 +247,7 @@ void VideoRendererBase::ThreadMain() {
// |current_frame_|.
if (ready_frames_.front()->IsEndOfStream()) {
state_ = kEnded;
- host()->NotifyEnded();
+ host_->NotifyEnded();
ready_frames_.clear();
// No need to sleep here as we idle when |state_ != kPlaying|.
@@ -258,7 +265,7 @@ void VideoRendererBase::ThreadMain() {
break;
base::TimeDelta remaining_time =
- ready_frames_.front()->GetTimestamp() - host()->GetTime();
+ ready_frames_.front()->GetTimestamp() - host_->GetTime();
// Still a chance we can render the frame!
if (remaining_time.InMicroseconds() > 0)
@@ -377,7 +384,7 @@ void VideoRendererBase::FrameReady(VideoDecoder::DecoderStatus status,
return;
}
- host()->SetError(error);
+ host_->SetError(error);
return;
}
@@ -417,10 +424,10 @@ void VideoRendererBase::FrameReady(VideoDecoder::DecoderStatus status,
// frame rate. Another way for this to happen is for the container to state a
// smaller duration than the largest packet timestamp.
if (!frame->IsEndOfStream()) {
- if (frame->GetTimestamp() > host()->GetDuration())
- frame->SetTimestamp(host()->GetDuration());
- if ((frame->GetTimestamp() + frame->GetDuration()) > host()->GetDuration())
- frame->SetDuration(host()->GetDuration() - frame->GetTimestamp());
+ if (frame->GetTimestamp() > host_->GetDuration())
+ frame->SetTimestamp(host_->GetDuration());
+ if ((frame->GetTimestamp() + frame->GetDuration()) > host_->GetDuration())
+ frame->SetDuration(host_->GetDuration() - frame->GetTimestamp());
}
// This one's a keeper! Place it in the ready queue.
@@ -509,7 +516,7 @@ base::TimeDelta VideoRendererBase::CalculateSleepDuration(
const scoped_refptr<VideoFrame>& next_frame,
float playback_rate) {
// Determine the current and next presentation timestamps.
- base::TimeDelta now = host()->GetTime();
+ base::TimeDelta now = host_->GetTime();
base::TimeDelta this_pts = current_frame_->GetTimestamp();
base::TimeDelta next_pts;
if (!next_frame->IsEndOfStream()) {
diff --git a/media/filters/video_renderer_base.h b/media/filters/video_renderer_base.h
index ed8472d..76ac213 100644
--- a/media/filters/video_renderer_base.h
+++ b/media/filters/video_renderer_base.h
@@ -47,6 +47,7 @@ class MEDIA_EXPORT VideoRendererBase
bool drop_frames);
// Filter implementation.
+ virtual void SetHost(FilterHost* host) OVERRIDE;
virtual void Play(const base::Closure& callback) OVERRIDE;
virtual void Pause(const base::Closure& callback) OVERRIDE;
virtual void Flush(const base::Closure& callback) OVERRIDE;
@@ -109,6 +110,8 @@ class MEDIA_EXPORT VideoRendererBase
// Return the number of frames currently held by this class.
int NumFrames_Locked() const;
+ FilterHost* host_;
+
// Used for accessing data members.
base::Lock lock_;
diff --git a/media/filters/video_renderer_base_unittest.cc b/media/filters/video_renderer_base_unittest.cc
index 29f087c..db1e699 100644
--- a/media/filters/video_renderer_base_unittest.cc
+++ b/media/filters/video_renderer_base_unittest.cc
@@ -52,7 +52,7 @@ class VideoRendererBaseTest : public ::testing::Test {
base::Bind(&VideoRendererBaseTest::SetOpaqueCBWasCalled,
base::Unretained(this)),
true);
- renderer_->set_host(&host_);
+ renderer_->SetHost(&host_);
EXPECT_CALL(*decoder_, natural_size())
.WillRepeatedly(ReturnRef(kNaturalSize));