summaryrefslogtreecommitdiffstats
path: root/media
diff options
context:
space:
mode:
authorscherkus@chromium.org <scherkus@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-07-15 17:39:56 +0000
committerscherkus@chromium.org <scherkus@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-07-15 17:39:56 +0000
commit2216d02d83e8c7ef50187384f6ce24ebeb16962c (patch)
tree4eab5dbf6b59a363925d7fa4f7cc1e12c360f752 /media
parentaa8cc5a24cb681eb307635679a69512548896b5e (diff)
downloadchromium_src-2216d02d83e8c7ef50187384f6ce24ebeb16962c.zip
chromium_src-2216d02d83e8c7ef50187384f6ce24ebeb16962c.tar.gz
chromium_src-2216d02d83e8c7ef50187384f6ce24ebeb16962c.tar.bz2
Revert "Splitting media filter's Initialize() into Create() + callback and Seek() + callback."
Review URL: http://codereview.chromium.org/149682 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@20745 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'media')
-rw-r--r--media/base/filter_host.h5
-rw-r--r--media/base/filter_host_impl.cc4
-rw-r--r--media/base/filter_host_impl.h1
-rw-r--r--media/base/filters.h44
-rw-r--r--media/base/mock_filters.cc18
-rw-r--r--media/base/mock_filters.h97
-rw-r--r--media/base/pipeline_impl.cc34
-rw-r--r--media/base/pipeline_impl.h9
-rw-r--r--media/base/pipeline_impl_unittest.cc71
-rw-r--r--media/filters/audio_renderer_base.cc16
-rw-r--r--media/filters/audio_renderer_base.h7
-rw-r--r--media/filters/audio_renderer_base_unittest.cc135
-rw-r--r--media/filters/decoder_base.h25
-rw-r--r--media/filters/ffmpeg_demuxer.cc26
-rw-r--r--media/filters/ffmpeg_demuxer.h8
-rw-r--r--media/filters/ffmpeg_demuxer_unittest.cc30
-rw-r--r--media/filters/ffmpeg_video_decoder_unittest.cc22
-rw-r--r--media/filters/file_data_source.cc10
-rw-r--r--media/filters/file_data_source.h3
-rw-r--r--media/filters/file_data_source_unittest.cc21
-rw-r--r--media/filters/video_renderer_base.cc44
-rw-r--r--media/filters/video_renderer_base.h8
-rw-r--r--media/filters/video_renderer_base_unittest.cc215
-rw-r--r--media/media.gyp3
24 files changed, 159 insertions, 697 deletions
diff --git a/media/base/filter_host.h b/media/base/filter_host.h
index 982b3e5..4907df2a 100644
--- a/media/base/filter_host.h
+++ b/media/base/filter_host.h
@@ -24,6 +24,11 @@ namespace media {
class FilterHost {
public:
+ // Filters must call this method to indicate that their initialization is
+ // complete. They may call this from within their Initialize() method or may
+ // choose call it after processing some data.
+ virtual void InitializationComplete() = 0;
+
// Stops execution of the pipeline due to a fatal error. Do not call this
// method with PIPELINE_OK or PIPELINE_STOPPING (used internally by pipeline).
virtual void Error(PipelineError error) = 0;
diff --git a/media/base/filter_host_impl.cc b/media/base/filter_host_impl.cc
index 4192afd..09f1791 100644
--- a/media/base/filter_host_impl.cc
+++ b/media/base/filter_host_impl.cc
@@ -6,6 +6,10 @@
namespace media {
+void FilterHostImpl::InitializationComplete() {
+ pipeline_internal_->InitializationComplete(this);
+}
+
void FilterHostImpl::Error(PipelineError error) {
pipeline_internal_->Error(error);
}
diff --git a/media/base/filter_host_impl.h b/media/base/filter_host_impl.h
index cb33a48..71e2417 100644
--- a/media/base/filter_host_impl.h
+++ b/media/base/filter_host_impl.h
@@ -16,6 +16,7 @@ namespace media {
class FilterHostImpl : public FilterHost {
public:
// FilterHost interface.
+ virtual void InitializationComplete();
virtual void Error(PipelineError error);
virtual base::TimeDelta GetTime() const;
virtual void SetTime(base::TimeDelta time);
diff --git a/media/base/filters.h b/media/base/filters.h
index 84df0966..b892961 100644
--- a/media/base/filters.h
+++ b/media/base/filters.h
@@ -53,8 +53,6 @@ enum FilterType {
FILTER_VIDEO_RENDERER
};
-// Used for completing asynchronous methods.
-typedef Callback0::Type FilterCallback;
class MediaFilter : public base::RefCountedThreadSafe<MediaFilter> {
public:
@@ -96,14 +94,9 @@ class MediaFilter : public base::RefCountedThreadSafe<MediaFilter> {
// method if they need to respond to this call.
virtual void SetPlaybackRate(float playback_rate) {}
- // Carry out any actions required to seek to the given time, executing the
- // callback upon completion.
- virtual void Seek(base::TimeDelta time, FilterCallback* callback) {
- scoped_ptr<FilterCallback> seek_callback(callback);
- if (seek_callback.get()) {
- seek_callback->Run();
- }
- }
+ // The pipeline is seeking to the specified time. Filters may implement
+ // this method if they need to respond to this call.
+ virtual void Seek(base::TimeDelta time) {}
protected:
// Only allow scoped_refptr<> to delete filters.
@@ -135,9 +128,8 @@ class DataSource : public MediaFilter {
static const size_t kReadError = static_cast<size_t>(-1);
- // Initialize a DataSource for the given URL, executing the callback upon
- // completion.
- virtual void Initialize(const std::string& url, FilterCallback* callback) = 0;
+ // Initializes this filter, returns true if successful, false otherwise.
+ virtual bool Initialize(const std::string& url) = 0;
// Returns the MediaFormat for this filter.
virtual const MediaFormat& media_format() = 0;
@@ -174,10 +166,8 @@ class Demuxer : public MediaFilter {
mime_type == mime_type::kApplicationOctetStream);
}
- // Initialize a Demuxer with the given DataSource, executing the callback upon
- // completion.
- virtual void Initialize(DataSource* data_source,
- FilterCallback* callback) = 0;
+ // Initializes this filter, returns true if successful, false otherwise.
+ virtual bool Initialize(DataSource* data_source) = 0;
// Returns the number of streams available
virtual size_t GetNumberOfStreams() = 0;
@@ -233,9 +223,8 @@ class VideoDecoder : public MediaFilter {
return mime_type::kMajorTypeVideo;
}
- // Initialize a VideoDecoder with the given DemuxerStream, executing the
- // callback upon completion.
- virtual void Initialize(DemuxerStream* stream, FilterCallback* callback) = 0;
+ // Initializes this filter, returns true if successful, false otherwise.
+ virtual bool Initialize(DemuxerStream* demuxer_stream) = 0;
// Returns the MediaFormat for this filter.
virtual const MediaFormat& media_format() = 0;
@@ -257,9 +246,8 @@ class AudioDecoder : public MediaFilter {
return mime_type::kMajorTypeAudio;
}
- // Initialize a AudioDecoder with the given DemuxerStream, executing the
- // callback upon completion.
- virtual void Initialize(DemuxerStream* stream, FilterCallback* callback) = 0;
+ // Initializes this filter, returns true if successful, false otherwise.
+ virtual bool Initialize(DemuxerStream* demuxer_stream) = 0;
// Returns the MediaFormat for this filter.
virtual const MediaFormat& media_format() = 0;
@@ -281,9 +269,8 @@ class VideoRenderer : public MediaFilter {
return mime_type::kMajorTypeVideo;
}
- // Initialize a VideoRenderer with the given VideoDecoder, executing the
- // callback upon completion.
- virtual void Initialize(VideoDecoder* decoder, FilterCallback* callback) = 0;
+ // Initializes this filter, returns true if successful, false otherwise.
+ virtual bool Initialize(VideoDecoder* decoder) = 0;
};
@@ -297,9 +284,8 @@ class AudioRenderer : public MediaFilter {
return mime_type::kMajorTypeAudio;
}
- // Initialize a AudioRenderer with the given AudioDecoder, executing the
- // callback upon completion.
- virtual void Initialize(AudioDecoder* decoder, FilterCallback* callback) = 0;
+ // Initializes this filter, returns true if successful, false otherwise.
+ virtual bool Initialize(AudioDecoder* decoder) = 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
deleted file mode 100644
index 7b854fc..0000000
--- a/media/base/mock_filters.cc
+++ /dev/null
@@ -1,18 +0,0 @@
-// Copyright (c) 2009 The Chromium Authors. All rights reserved. Use of this
-// source code is governed by a BSD-style license that can be found in the
-// LICENSE file.
-
-#include "media/base/mock_filters.h"
-
-namespace media {
-
-void RunFilterCallback(::testing::Unused, FilterCallback* callback) {
- callback->Run();
- delete callback;
-}
-
-void DestroyFilterCallback(::testing::Unused, FilterCallback* callback) {
- delete callback;
-}
-
-} // namespace media
diff --git a/media/base/mock_filters.h b/media/base/mock_filters.h
index 6d8c8a9..bffba6f 100644
--- a/media/base/mock_filters.h
+++ b/media/base/mock_filters.h
@@ -40,52 +40,6 @@ class Destroyable : public MockClass {
DISALLOW_COPY_AND_ASSIGN(Destroyable);
};
-// Helper class used to test that callbacks are executed. It is recommend you
-// combine this class with StrictMock<> to verify that the callback is executed.
-// You can reuse the same instance of a MockFilterCallback many times since
-// gmock will track the number of times the methods are executed.
-class MockFilterCallback {
- public:
- MockFilterCallback() {}
- virtual ~MockFilterCallback() {}
-
- MOCK_METHOD0(OnCallbackDestroyed, void());
- MOCK_METHOD0(OnFilterCallback, void());
-
- // Helper method to create a new callback for this mock. The callback will
- // call OnFilterCallback() when executed and OnCallbackDestroyed() when
- // destroyed. Clients should use NiceMock<> or StrictMock<> depending on the
- // test.
- FilterCallback* NewCallback() {
- return new CallbackImpl(this);
- }
-
- private:
- // Private implementation of CallbackRunner used to trigger expectations on
- // MockFilterCallback.
- class CallbackImpl : public CallbackRunner<Tuple0> {
- public:
- CallbackImpl(MockFilterCallback* mock_callback)
- : mock_callback_(mock_callback) {
- }
-
- virtual ~CallbackImpl() {
- mock_callback_->OnCallbackDestroyed();
- }
-
- virtual void RunWithParams(const Tuple0& params) {
- mock_callback_->OnFilterCallback();
- }
-
- private:
- MockFilterCallback* mock_callback_;
-
- DISALLOW_COPY_AND_ASSIGN(CallbackImpl);
- };
-
- DISALLOW_COPY_AND_ASSIGN(MockFilterCallback);
-};
-
class MockDataSource : public DataSource {
public:
MockDataSource() {}
@@ -93,11 +47,10 @@ class MockDataSource : public DataSource {
// MediaFilter implementation.
MOCK_METHOD0(Stop, void());
MOCK_METHOD1(SetPlaybackRate, void(float playback_rate));
- MOCK_METHOD2(Seek, void(base::TimeDelta time, FilterCallback* callback));
+ MOCK_METHOD1(Seek, void(base::TimeDelta time));
// DataSource implementation.
- MOCK_METHOD2(Initialize, void(const std::string& url,
- FilterCallback* callback));
+ MOCK_METHOD1(Initialize, bool(const std::string& url));
const MediaFormat& media_format() { return media_format_; }
MOCK_METHOD2(Read, size_t(uint8* data, size_t size));
MOCK_METHOD1(GetPosition, bool(int64* position_out));
@@ -121,11 +74,10 @@ class MockDemuxer : public Demuxer {
// MediaFilter implementation.
MOCK_METHOD0(Stop, void());
MOCK_METHOD1(SetPlaybackRate, void(float playback_rate));
- MOCK_METHOD2(Seek, void(base::TimeDelta time, FilterCallback* callback));
+ MOCK_METHOD1(Seek, void(base::TimeDelta time));
// Demuxer implementation.
- MOCK_METHOD2(Initialize, void(DataSource* data_source,
- FilterCallback* callback));
+ MOCK_METHOD1(Initialize, bool(DataSource* data_source));
MOCK_METHOD0(GetNumberOfStreams, size_t());
MOCK_METHOD1(GetStream, scoped_refptr<DemuxerStream>(int stream_id));
@@ -164,21 +116,13 @@ class MockVideoDecoder : public VideoDecoder {
public:
MockVideoDecoder() {}
- // Sets the essential media format keys for this decoder.
- MockVideoDecoder(const std::string& mime_type, int width, int height) {
- media_format_.SetAsString(MediaFormat::kMimeType, mime_type);
- media_format_.SetAsInteger(MediaFormat::kWidth, width);
- media_format_.SetAsInteger(MediaFormat::kHeight, height);
- }
-
// MediaFilter implementation.
MOCK_METHOD0(Stop, void());
MOCK_METHOD1(SetPlaybackRate, void(float playback_rate));
- MOCK_METHOD2(Seek, void(base::TimeDelta time, FilterCallback* callback));
+ MOCK_METHOD1(Seek, void(base::TimeDelta time));
// VideoDecoder implementation.
- MOCK_METHOD2(Initialize, void(DemuxerStream* stream,
- FilterCallback* callback));
+ MOCK_METHOD1(Initialize, bool(DemuxerStream* demuxer_stream));
const MediaFormat& media_format() { return media_format_; }
MOCK_METHOD1(Read, void(Callback1<VideoFrame*>::Type* read_callback));
@@ -198,11 +142,10 @@ class MockAudioDecoder : public AudioDecoder {
// MediaFilter implementation.
MOCK_METHOD0(Stop, void());
MOCK_METHOD1(SetPlaybackRate, void(float playback_rate));
- MOCK_METHOD2(Seek, void(base::TimeDelta time, FilterCallback* callback));
+ MOCK_METHOD1(Seek, void(base::TimeDelta time));
// AudioDecoder implementation.
- MOCK_METHOD2(Initialize, void(DemuxerStream* stream,
- FilterCallback* callback));
+ MOCK_METHOD1(Initialize, bool(DemuxerStream* demuxer_stream));
const MediaFormat& media_format() { return media_format_; }
MOCK_METHOD1(Read, void(Callback1<Buffer*>::Type* read_callback));
@@ -222,11 +165,10 @@ class MockVideoRenderer : public VideoRenderer {
// MediaFilter implementation.
MOCK_METHOD0(Stop, void());
MOCK_METHOD1(SetPlaybackRate, void(float playback_rate));
- MOCK_METHOD2(Seek, void(base::TimeDelta time, FilterCallback* callback));
+ MOCK_METHOD1(Seek, void(base::TimeDelta time));
// VideoRenderer implementation.
- MOCK_METHOD2(Initialize, void(VideoDecoder* decoder,
- FilterCallback* callback));
+ MOCK_METHOD1(Initialize, bool(VideoDecoder* decoder));
protected:
virtual ~MockVideoRenderer() {}
@@ -242,11 +184,10 @@ class MockAudioRenderer : public AudioRenderer {
// MediaFilter implementation.
MOCK_METHOD0(Stop, void());
MOCK_METHOD1(SetPlaybackRate, void(float playback_rate));
- MOCK_METHOD2(Seek, void(base::TimeDelta time, FilterCallback* callback));
+ MOCK_METHOD1(Seek, void(base::TimeDelta time));
// AudioRenderer implementation.
- MOCK_METHOD2(Initialize, void(AudioDecoder* decoder,
- FilterCallback* callback));
+ MOCK_METHOD1(Initialize, bool(AudioDecoder* decoder));
MOCK_METHOD1(SetVolume, void(float volume));
protected:
@@ -322,15 +263,11 @@ class MockFilterFactory : public FilterFactory {
DISALLOW_COPY_AND_ASSIGN(MockFilterFactory);
};
-// Helper gmock function that immediately executes and destroys the
-// FilterCallback on behalf of the provided filter. Can be used when mocking
-// the Initialize() and Seek() methods.
-void RunFilterCallback(::testing::Unused, FilterCallback* callback);
-
-// Helper gmock function that immediately destroys the FilterCallback on behalf
-// of the provided filter. Can be used when mocking the Initialize() and Seek()
-// methods.
-void DestroyFilterCallback(::testing::Unused, FilterCallback* callback);
+// Helper gmock action that calls InitializationComplete() on behalf of the
+// provided filter.
+ACTION_P(InitializationComplete, filter) {
+ filter->host()->InitializationComplete();
+}
// Helper gmock action that calls Error() on behalf of the provided filter.
ACTION_P2(Error, filter, error) {
diff --git a/media/base/pipeline_impl.cc b/media/base/pipeline_impl.cc
index 7ef051d..f021ad3 100644
--- a/media/base/pipeline_impl.cc
+++ b/media/base/pipeline_impl.cc
@@ -328,6 +328,15 @@ void PipelineInternal::VolumeChanged(float volume) {
NewRunnableMethod(this, &PipelineInternal::VolumeChangedTask, volume));
}
+// Called from any thread.
+void PipelineInternal::InitializationComplete(FilterHostImpl* host) {
+ if (IsPipelineOk()) {
+ // Continue the initialize task by proceeding to the next stage.
+ message_loop_->PostTask(FROM_HERE,
+ NewRunnableMethod(this, &PipelineInternal::InitializeTask));
+ }
+}
+
// Called from any thread. Updates the pipeline time.
void PipelineInternal::SetTime(base::TimeDelta time) {
// TODO(scherkus): why not post a task?
@@ -341,19 +350,6 @@ void PipelineInternal::Error(PipelineError error) {
NewRunnableMethod(this, &PipelineInternal::ErrorTask, error));
}
-// Called from any thread.
-void PipelineInternal::OnFilterInitialize() {
- // Continue the initialize task by proceeding to the next stage.
- message_loop_->PostTask(FROM_HERE,
- NewRunnableMethod(this, &PipelineInternal::InitializeTask));
-}
-
-// Called from any thread.
-void PipelineInternal::OnFilterSeek() {
- // TODO(scherkus): have PipelineInternal wait to receive replies from every
- // filter before calling the client's |seek_callback_|.
-}
-
void PipelineInternal::StartTask(FilterFactory* filter_factory,
const std::string& url,
PipelineCallback* start_callback) {
@@ -387,8 +383,8 @@ void PipelineInternal::StartTask(FilterFactory* filter_factory,
void PipelineInternal::InitializeTask() {
DCHECK_EQ(MessageLoop::current(), message_loop_);
- // If we have received the stop or error signal, return immediately.
- if (state_ == kStopped || state_ == kError)
+ // If we have received the stop signal, return immediately.
+ if (state_ == kStopped)
return;
DCHECK(state_ == kCreated || IsPipelineInitializing());
@@ -555,8 +551,7 @@ void PipelineInternal::SeekTask(base::TimeDelta time,
for (FilterHostVector::iterator iter = filter_hosts_.begin();
iter != filter_hosts_.end();
++iter) {
- (*iter)->media_filter()->Seek(time,
- NewCallback(this, &PipelineInternal::OnFilterSeek));
+ (*iter)->media_filter()->Seek(time);
}
// TODO(hclam): we should set the time when the above seek operations were all
@@ -607,8 +602,9 @@ void PipelineInternal::CreateFilter(FilterFactory* filter_factory,
filter_hosts_.push_back(host.release());
// Now initialize the filter.
- filter->Initialize(source,
- NewCallback(this, &PipelineInternal::OnFilterInitialize));
+ if (!filter->Initialize(source)) {
+ Error(PIPELINE_ERROR_INITIALIZATION_FAILED);
+ }
}
void PipelineInternal::CreateDataSource() {
diff --git a/media/base/pipeline_impl.h b/media/base/pipeline_impl.h
index e9f44d5..911d253 100644
--- a/media/base/pipeline_impl.h
+++ b/media/base/pipeline_impl.h
@@ -191,6 +191,11 @@ class PipelineInternal : public base::RefCountedThreadSafe<PipelineInternal> {
// Methods called by a FilterHostImpl object. These methods may be called
// on any thread, either the pipeline's thread or any other.
+ // When a filter calls it's FilterHost, the filter host calls back to the
+ // pipeline thread. If the pipeline thread is running a nested message loop
+ // then it will be exited.
+ void InitializationComplete(FilterHostImpl* host);
+
// Sets the pipeline time and schedules a task to call back to any filters
// that have registered a time update callback.
void SetTime(base::TimeDelta time);
@@ -240,10 +245,6 @@ class PipelineInternal : public base::RefCountedThreadSafe<PipelineInternal> {
state_ == kInitVideoRenderer;
}
- // Callback executed by filters upon completing initialization and seeking.
- void OnFilterInitialize();
- void OnFilterSeek();
-
// The following "task" methods correspond to the public methods, but these
// methods are run as the result of posting a task to the PipelineInternal's
// message loop.
diff --git a/media/base/pipeline_impl_unittest.cc b/media/base/pipeline_impl_unittest.cc
index d6bd285..b673cfb 100644
--- a/media/base/pipeline_impl_unittest.cc
+++ b/media/base/pipeline_impl_unittest.cc
@@ -14,9 +14,7 @@
#include "testing/gtest/include/gtest/gtest.h"
using ::testing::DoAll;
-using ::testing::Invoke;
using ::testing::Mock;
-using ::testing::NotNull;
using ::testing::Return;
using ::testing::StrictMock;
@@ -65,8 +63,9 @@ class PipelineImplTest : public ::testing::Test {
protected:
// Sets up expectations to allow the data source to initialize.
void InitializeDataSource() {
- EXPECT_CALL(*mocks_->data_source(), Initialize("", NotNull()))
- .WillOnce(Invoke(&RunFilterCallback));
+ EXPECT_CALL(*mocks_->data_source(), Initialize(""))
+ .WillOnce(DoAll(InitializationComplete(mocks_->data_source()),
+ Return(true)));
EXPECT_CALL(*mocks_->data_source(), SetPlaybackRate(0.0f));
EXPECT_CALL(*mocks_->data_source(), Stop());
}
@@ -74,9 +73,9 @@ class PipelineImplTest : public ::testing::Test {
// Sets up expectations to allow the demuxer to initialize.
typedef std::vector<MockDemuxerStream*> MockDemuxerStreamVector;
void InitializeDemuxer(MockDemuxerStreamVector* streams) {
- EXPECT_CALL(*mocks_->demuxer(),
- Initialize(mocks_->data_source(), NotNull()))
- .WillOnce(Invoke(&RunFilterCallback));
+ EXPECT_CALL(*mocks_->demuxer(), Initialize(mocks_->data_source()))
+ .WillOnce(DoAll(InitializationComplete(mocks_->demuxer()),
+ Return(true)));
EXPECT_CALL(*mocks_->demuxer(), GetNumberOfStreams())
.WillRepeatedly(Return(streams->size()));
EXPECT_CALL(*mocks_->demuxer(), SetPlaybackRate(0.0f));
@@ -92,34 +91,36 @@ class PipelineImplTest : public ::testing::Test {
// Sets up expectations to allow the video decoder to initialize.
void InitializeVideoDecoder(MockDemuxerStream* stream) {
- EXPECT_CALL(*mocks_->video_decoder(), Initialize(stream, NotNull()))
- .WillOnce(Invoke(&RunFilterCallback));
+ EXPECT_CALL(*mocks_->video_decoder(), Initialize(stream))
+ .WillOnce(DoAll(InitializationComplete(mocks_->video_decoder()),
+ Return(true)));
EXPECT_CALL(*mocks_->video_decoder(), SetPlaybackRate(0.0f));
EXPECT_CALL(*mocks_->video_decoder(), Stop());
}
// Sets up expectations to allow the audio decoder to initialize.
void InitializeAudioDecoder(MockDemuxerStream* stream) {
- EXPECT_CALL(*mocks_->audio_decoder(), Initialize(stream, NotNull()))
- .WillOnce(Invoke(&RunFilterCallback));
+ EXPECT_CALL(*mocks_->audio_decoder(), Initialize(stream))
+ .WillOnce(DoAll(InitializationComplete(mocks_->audio_decoder()),
+ Return(true)));
EXPECT_CALL(*mocks_->audio_decoder(), SetPlaybackRate(0.0f));
EXPECT_CALL(*mocks_->audio_decoder(), Stop());
}
// Sets up expectations to allow the video renderer to initialize.
void InitializeVideoRenderer() {
- EXPECT_CALL(*mocks_->video_renderer(),
- Initialize(mocks_->video_decoder(), NotNull()))
- .WillOnce(Invoke(&RunFilterCallback));
+ EXPECT_CALL(*mocks_->video_renderer(), Initialize(mocks_->video_decoder()))
+ .WillOnce(DoAll(InitializationComplete(mocks_->video_renderer()),
+ Return(true)));
EXPECT_CALL(*mocks_->video_renderer(), SetPlaybackRate(0.0f));
EXPECT_CALL(*mocks_->video_renderer(), Stop());
}
// Sets up expectations to allow the audio renderer to initialize.
void InitializeAudioRenderer() {
- EXPECT_CALL(*mocks_->audio_renderer(),
- Initialize(mocks_->audio_decoder(), NotNull()))
- .WillOnce(Invoke(&RunFilterCallback));
+ EXPECT_CALL(*mocks_->audio_renderer(), Initialize(mocks_->audio_decoder()))
+ .WillOnce(DoAll(InitializationComplete(mocks_->audio_renderer()),
+ Return(true)));
EXPECT_CALL(*mocks_->audio_renderer(), SetPlaybackRate(0.0f));
EXPECT_CALL(*mocks_->audio_renderer(), SetVolume(1.0f));
EXPECT_CALL(*mocks_->audio_renderer(), Stop());
@@ -200,8 +201,8 @@ TEST_F(PipelineImplTest, NotStarted) {
}
TEST_F(PipelineImplTest, NeverInitializes) {
- EXPECT_CALL(*mocks_->data_source(), Initialize("", NotNull()))
- .WillOnce(Invoke(&DestroyFilterCallback));
+ EXPECT_CALL(*mocks_->data_source(), Initialize(""))
+ .WillOnce(Return(true));
EXPECT_CALL(*mocks_->data_source(), Stop());
// This test hangs during initialization by never calling
@@ -232,10 +233,10 @@ TEST_F(PipelineImplTest, RequiredFilterMissing) {
}
TEST_F(PipelineImplTest, URLNotFound) {
- EXPECT_CALL(*mocks_->data_source(), Initialize("", NotNull()))
+ EXPECT_CALL(*mocks_->data_source(), Initialize(""))
.WillOnce(DoAll(Error(mocks_->data_source(),
PIPELINE_ERROR_URL_NOT_FOUND),
- Invoke(&RunFilterCallback)));
+ Return(false)));
EXPECT_CALL(*mocks_->data_source(), Stop());
InitializePipeline();
@@ -246,12 +247,14 @@ TEST_F(PipelineImplTest, URLNotFound) {
TEST_F(PipelineImplTest, NoStreams) {
// Manually set these expecations because SetPlaybackRate() is not called if
// we cannot fully initialize the pipeline.
- EXPECT_CALL(*mocks_->data_source(), Initialize("", NotNull()))
- .WillOnce(Invoke(&RunFilterCallback));
+ EXPECT_CALL(*mocks_->data_source(), Initialize(""))
+ .WillOnce(DoAll(InitializationComplete(mocks_->data_source()),
+ Return(true)));
EXPECT_CALL(*mocks_->data_source(), Stop());
- EXPECT_CALL(*mocks_->demuxer(), Initialize(mocks_->data_source(), NotNull()))
- .WillOnce(Invoke(&RunFilterCallback));
+ EXPECT_CALL(*mocks_->demuxer(), Initialize(mocks_->data_source()))
+ .WillOnce(DoAll(InitializationComplete(mocks_->demuxer()),
+ Return(true)));
EXPECT_CALL(*mocks_->demuxer(), GetNumberOfStreams())
.WillRepeatedly(Return(0));
EXPECT_CALL(*mocks_->demuxer(), Stop());
@@ -338,18 +341,12 @@ TEST_F(PipelineImplTest, Seek) {
// Every filter should receive a call to Seek().
base::TimeDelta expected = base::TimeDelta::FromSeconds(2000);
- EXPECT_CALL(*mocks_->data_source(), Seek(expected, NotNull()))
- .WillOnce(Invoke(&RunFilterCallback));
- EXPECT_CALL(*mocks_->demuxer(), Seek(expected, NotNull()))
- .WillOnce(Invoke(&RunFilterCallback));
- EXPECT_CALL(*mocks_->audio_decoder(), Seek(expected, NotNull()))
- .WillOnce(Invoke(&RunFilterCallback));
- EXPECT_CALL(*mocks_->audio_renderer(), Seek(expected, NotNull()))
- .WillOnce(Invoke(&RunFilterCallback));
- EXPECT_CALL(*mocks_->video_decoder(), Seek(expected, NotNull()))
- .WillOnce(Invoke(&RunFilterCallback));
- EXPECT_CALL(*mocks_->video_renderer(), Seek(expected, NotNull()))
- .WillOnce(Invoke(&RunFilterCallback));
+ EXPECT_CALL(*mocks_->data_source(), Seek(expected));
+ EXPECT_CALL(*mocks_->demuxer(), Seek(expected));
+ EXPECT_CALL(*mocks_->audio_decoder(), Seek(expected));
+ EXPECT_CALL(*mocks_->audio_renderer(), Seek(expected));
+ EXPECT_CALL(*mocks_->video_decoder(), Seek(expected));
+ EXPECT_CALL(*mocks_->video_renderer(), Seek(expected));
// We expect a successful seek callback.
EXPECT_CALL(callbacks_, OnSeek());
diff --git a/media/filters/audio_renderer_base.cc b/media/filters/audio_renderer_base.cc
index d0bad99..ba52fe0 100644
--- a/media/filters/audio_renderer_base.cc
+++ b/media/filters/audio_renderer_base.cc
@@ -38,7 +38,7 @@ void AudioRendererBase::Stop() {
stopped_ = true;
}
-void AudioRendererBase::Seek(base::TimeDelta time, FilterCallback* callback) {
+void AudioRendererBase::Seek(base::TimeDelta time) {
AutoLock auto_lock(lock_);
last_fill_buffer_time_ = base::TimeDelta();
@@ -53,12 +53,9 @@ void AudioRendererBase::Seek(base::TimeDelta time, FilterCallback* callback) {
}
}
-void AudioRendererBase::Initialize(AudioDecoder* decoder,
- FilterCallback* callback) {
+bool AudioRendererBase::Initialize(AudioDecoder* decoder) {
DCHECK(decoder);
- DCHECK(callback);
decoder_ = decoder;
- initialize_callback_.reset(callback);
// Schedule our initial reads.
for (size_t i = 0; i < max_queue_size_; ++i) {
@@ -66,11 +63,7 @@ void AudioRendererBase::Initialize(AudioDecoder* decoder,
}
// Defer initialization until all scheduled reads have completed.
- if (!OnInitialize(decoder_->media_format())) {
- host()->Error(PIPELINE_ERROR_INITIALIZATION_FAILED);
- initialize_callback_->Run();
- initialize_callback_.reset();
- }
+ return OnInitialize(decoder_->media_format());
}
void AudioRendererBase::OnReadComplete(Buffer* buffer_in) {
@@ -99,9 +92,8 @@ void AudioRendererBase::OnReadComplete(Buffer* buffer_in) {
host()->Error(PIPELINE_ERROR_NO_DATA);
} else {
initialized_ = true;
+ host()->InitializationComplete();
}
- initialize_callback_->Run();
- initialize_callback_.reset();
}
}
diff --git a/media/filters/audio_renderer_base.h b/media/filters/audio_renderer_base.h
index 3d31474..e3ec686 100644
--- a/media/filters/audio_renderer_base.h
+++ b/media/filters/audio_renderer_base.h
@@ -32,10 +32,10 @@ class AudioRendererBase : public AudioRenderer {
// MediaFilter implementation.
virtual void Stop();
- virtual void Seek(base::TimeDelta time, FilterCallback* callback);
+ virtual void Seek(base::TimeDelta time);
// AudioRenderer implementation.
- virtual void Initialize(AudioDecoder* decoder, FilterCallback* callback);
+ virtual bool Initialize(AudioDecoder* decoder);
protected:
// The default maximum size of the queue.
@@ -116,9 +116,6 @@ class AudioRendererBase : public AudioRenderer {
// TODO(ralphl): Update this value after seeking.
base::TimeDelta last_fill_buffer_time_;
- // Filter callbacks.
- scoped_ptr<FilterCallback> initialize_callback_;
-
DISALLOW_COPY_AND_ASSIGN(AudioRendererBase);
};
diff --git a/media/filters/audio_renderer_base_unittest.cc b/media/filters/audio_renderer_base_unittest.cc
deleted file mode 100644
index aa0808c..0000000
--- a/media/filters/audio_renderer_base_unittest.cc
+++ /dev/null
@@ -1,135 +0,0 @@
-// Copyright (c) 2009 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "base/stl_util-inl.h"
-#include "media/base/data_buffer.h"
-#include "media/base/mock_filter_host.h"
-#include "media/base/mock_filters.h"
-#include "media/filters/audio_renderer_base.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-using ::testing::_;
-using ::testing::InSequence;
-using ::testing::Invoke;
-using ::testing::NotNull;
-using ::testing::Return;
-using ::testing::StrictMock;
-
-namespace media {
-
-// Mocked subclass of AudioRendererBase for testing purposes.
-class MockAudioRendererBase : public AudioRendererBase {
- public:
- MockAudioRendererBase(size_t max_queue_size)
- : AudioRendererBase(max_queue_size) {}
- virtual ~MockAudioRendererBase() {}
-
- // AudioRenderer implementation.
- MOCK_METHOD1(SetVolume, void(float volume));
-
- // AudioRendererBase implementation.
- MOCK_METHOD1(OnInitialize, bool(const MediaFormat& media_format));
- MOCK_METHOD0(OnStop, void());
-
- // Used for verifying check points during tests.
- MOCK_METHOD1(CheckPoint, void(int id));
-
- private:
- DISALLOW_COPY_AND_ASSIGN(MockAudioRendererBase);
-};
-
-class AudioRendererBaseTest : public ::testing::Test {
- public:
- AudioRendererBaseTest()
- : renderer_(new MockAudioRendererBase(kMaxQueueSize)),
- decoder_(new MockAudioDecoder()) {
- renderer_->set_host(&host_);
-
- // Queue all reads from the decoder.
- EXPECT_CALL(*decoder_, Read(NotNull()))
- .WillRepeatedly(Invoke(this, &AudioRendererBaseTest::EnqueueCallback));
- }
-
- virtual ~AudioRendererBaseTest() {
- STLDeleteElements(&read_queue_);
-
- // Expect a call into the subclass.
- EXPECT_CALL(*renderer_, OnStop());
- renderer_->Stop();
- }
-
- protected:
- static const size_t kMaxQueueSize;
-
- // Fixture members.
- scoped_refptr<MockAudioRendererBase> renderer_;
- scoped_refptr<MockAudioDecoder> decoder_;
- StrictMock<MockFilterHost> host_;
- StrictMock<MockFilterCallback> callback_;
-
- // Receives asynchronous read requests sent to |decoder_|.
- std::deque<Callback1<Buffer*>::Type*> read_queue_;
-
- private:
- void EnqueueCallback(Callback1<Buffer*>::Type* callback) {
- read_queue_.push_back(callback);
- }
-
- DISALLOW_COPY_AND_ASSIGN(AudioRendererBaseTest);
-};
-
-const size_t AudioRendererBaseTest::kMaxQueueSize = 16u;
-
-TEST_F(AudioRendererBaseTest, Initialize_Failed) {
- InSequence s;
-
- // Our subclass will fail when asked to initialize.
- EXPECT_CALL(*renderer_, OnInitialize(_))
- .WillOnce(Return(false));
-
- // We expect to receive an error.
- EXPECT_CALL(host_, Error(PIPELINE_ERROR_INITIALIZATION_FAILED));
-
- // We expect our callback to be executed.
- EXPECT_CALL(callback_, OnFilterCallback());
- EXPECT_CALL(callback_, OnCallbackDestroyed());
-
- // Initialize, we expect to get a bunch of read requests.
- renderer_->Initialize(decoder_, callback_.NewCallback());
- EXPECT_EQ(kMaxQueueSize, read_queue_.size());
-}
-
-TEST_F(AudioRendererBaseTest, Initialize_Successful) {
- InSequence s;
-
- // Then our subclass will be asked to initialize.
- EXPECT_CALL(*renderer_, OnInitialize(_))
- .WillOnce(Return(true));
-
- // Set up a check point to verify that the callback hasn't been executed yet.
- EXPECT_CALL(*renderer_, CheckPoint(0));
-
- // After finishing preroll, we expect our callback to be executed.
- EXPECT_CALL(callback_, OnFilterCallback());
- EXPECT_CALL(callback_, OnCallbackDestroyed());
-
- // Initialize, we expect to get a bunch of read requests.
- renderer_->Initialize(decoder_, callback_.NewCallback());
- EXPECT_EQ(kMaxQueueSize, read_queue_.size());
-
- // Verify our callback hasn't been executed yet.
- renderer_->CheckPoint(0);
-
- // Now satisfy the read requests. Our callback should be executed after
- // exiting this loop.
- while (!read_queue_.empty()) {
- scoped_refptr<DataBuffer> buffer = new DataBuffer();
- buffer->GetWritableData(1);
- read_queue_.front()->Run(buffer);
- delete read_queue_.front();
- read_queue_.pop_front();
- }
-}
-
-} // namespace media
diff --git a/media/filters/decoder_base.h b/media/filters/decoder_base.h
index 3e1ba52c..775d3f9 100644
--- a/media/filters/decoder_base.h
+++ b/media/filters/decoder_base.h
@@ -33,18 +33,16 @@ class DecoderBase : public Decoder {
NewRunnableMethod(this, &DecoderBase::StopTask));
}
- virtual void Seek(base::TimeDelta time,
- FilterCallback* callback) {
+ virtual void Seek(base::TimeDelta time) {
this->message_loop()->PostTask(FROM_HERE,
- NewRunnableMethod(this, &DecoderBase::SeekTask, time, callback));
+ NewRunnableMethod(this, &DecoderBase::SeekTask, time));
}
// Decoder implementation.
- virtual void Initialize(DemuxerStream* demuxer_stream,
- FilterCallback* callback) {
+ virtual bool Initialize(DemuxerStream* demuxer_stream) {
this->message_loop()->PostTask(FROM_HERE,
- NewRunnableMethod(this, &DecoderBase::InitializeTask, demuxer_stream,
- callback));
+ NewRunnableMethod(this, &DecoderBase::InitializeTask, demuxer_stream));
+ return true;
}
virtual const MediaFormat& media_format() { return media_format_; }
@@ -129,9 +127,8 @@ class DecoderBase : public Decoder {
state_ = STOPPED;
}
- void SeekTask(base::TimeDelta time, FilterCallback* callback) {
+ void SeekTask(base::TimeDelta time) {
DCHECK_EQ(MessageLoop::current(), this->message_loop());
- scoped_ptr<FilterCallback> c(callback);
// Delegate to the subclass first.
OnSeek(time);
@@ -142,30 +139,24 @@ class DecoderBase : public Decoder {
// Turn on the seeking flag so that we can discard buffers until a
// discontinuous buffer is received.
seeking_ = true;
-
- // For now, signal that we're done seeking.
- // TODO(scherkus): implement asynchronous seeking for decoder_base.h
- callback->Run();
}
- void InitializeTask(DemuxerStream* demuxer_stream, FilterCallback* callback) {
+ void InitializeTask(DemuxerStream* demuxer_stream) {
DCHECK_EQ(MessageLoop::current(), this->message_loop());
DCHECK(state_ == UNINITIALIZED);
DCHECK(!demuxer_stream_);
- scoped_ptr<FilterCallback> c(callback);
demuxer_stream_ = demuxer_stream;
// Delegate to subclass first.
if (!OnInitialize(demuxer_stream_)) {
this->host()->Error(PIPELINE_ERROR_DECODE);
- callback->Run();
return;
}
// TODO(scherkus): subclass shouldn't mutate superclass media format.
DCHECK(!media_format_.empty()) << "Subclass did not set media_format_";
state_ = INITIALIZED;
- callback->Run();
+ this->host()->InitializationComplete();
}
void ReadTask(ReadCallback* read_callback) {
diff --git a/media/filters/ffmpeg_demuxer.cc b/media/filters/ffmpeg_demuxer.cc
index 8526b4e..aa7ff27 100644
--- a/media/filters/ffmpeg_demuxer.cc
+++ b/media/filters/ffmpeg_demuxer.cc
@@ -261,20 +261,19 @@ void FFmpegDemuxer::Stop() {
NewRunnableMethod(this, &FFmpegDemuxer::StopTask));
}
-void FFmpegDemuxer::Seek(base::TimeDelta time, FilterCallback* callback) {
+void FFmpegDemuxer::Seek(base::TimeDelta time) {
// TODO(hclam): by returning from this method, it is assumed that the seek
// operation is completed and filters behind the demuxer is good to issue
// more reads, but we are posting a task here, which makes the seek operation
// asynchronous, should change how seek works to make it fully asynchronous.
message_loop()->PostTask(FROM_HERE,
- NewRunnableMethod(this, &FFmpegDemuxer::SeekTask, time, callback));
+ NewRunnableMethod(this, &FFmpegDemuxer::SeekTask, time));
}
-void FFmpegDemuxer::Initialize(DataSource* data_source,
- FilterCallback* callback) {
+bool FFmpegDemuxer::Initialize(DataSource* data_source) {
message_loop()->PostTask(FROM_HERE,
- NewRunnableMethod(this, &FFmpegDemuxer::InititalizeTask, data_source,
- callback));
+ NewRunnableMethod(this, &FFmpegDemuxer::InititalizeTask, data_source));
+ return true;
}
size_t FFmpegDemuxer::GetNumberOfStreams() {
@@ -287,10 +286,8 @@ scoped_refptr<DemuxerStream> FFmpegDemuxer::GetStream(int stream) {
return streams_[stream].get();
}
-void FFmpegDemuxer::InititalizeTask(DataSource* data_source,
- FilterCallback* callback) {
+void FFmpegDemuxer::InititalizeTask(DataSource* data_source) {
DCHECK_EQ(MessageLoop::current(), message_loop());
- scoped_ptr<FilterCallback> c(callback);
// In order to get FFmpeg to use |data_source| for file IO we must transfer
// ownership via FFmpegGlue. We'll add |data_source| to FFmpegGlue and pass
@@ -314,7 +311,6 @@ void FFmpegDemuxer::InititalizeTask(DataSource* data_source,
if (result < 0) {
host()->Error(DEMUXER_ERROR_COULD_NOT_OPEN);
- callback->Run();
return;
}
@@ -329,7 +325,6 @@ void FFmpegDemuxer::InititalizeTask(DataSource* data_source,
result = av_find_stream_info(format_context_);
if (result < 0) {
host()->Error(DEMUXER_ERROR_COULD_NOT_PARSE);
- callback->Run();
return;
}
}
@@ -352,18 +347,16 @@ void FFmpegDemuxer::InititalizeTask(DataSource* data_source,
}
if (streams_.empty()) {
host()->Error(DEMUXER_ERROR_NO_SUPPORTED_STREAMS);
- callback->Run();
return;
}
// Good to go: set the duration and notify we're done initializing.
host()->SetDuration(max_duration);
- callback->Run();
+ host()->InitializationComplete();
}
-void FFmpegDemuxer::SeekTask(base::TimeDelta time, FilterCallback* callback) {
+void FFmpegDemuxer::SeekTask(base::TimeDelta time) {
DCHECK_EQ(MessageLoop::current(), message_loop());
- scoped_ptr<FilterCallback> c(callback);
// Tell streams to flush buffers due to seeking.
StreamVector::iterator iter;
@@ -382,9 +375,6 @@ void FFmpegDemuxer::SeekTask(base::TimeDelta time, FilterCallback* callback) {
// TODO(scherkus): signal error.
NOTIMPLEMENTED();
}
-
- // Notify we're finished seeking.
- callback->Run();
}
void FFmpegDemuxer::DemuxTask() {
diff --git a/media/filters/ffmpeg_demuxer.h b/media/filters/ffmpeg_demuxer.h
index 20b77e4..9d68e35 100644
--- a/media/filters/ffmpeg_demuxer.h
+++ b/media/filters/ffmpeg_demuxer.h
@@ -120,10 +120,10 @@ class FFmpegDemuxer : public Demuxer {
// MediaFilter implementation.
virtual void Stop();
- virtual void Seek(base::TimeDelta time, FilterCallback* callback);
+ virtual void Seek(base::TimeDelta time);
// Demuxer implementation.
- virtual void Initialize(DataSource* data_source, FilterCallback* callback);
+ virtual bool Initialize(DataSource* data_source);
virtual size_t GetNumberOfStreams();
virtual scoped_refptr<DemuxerStream> GetStream(int stream_id);
@@ -134,10 +134,10 @@ class FFmpegDemuxer : public Demuxer {
virtual ~FFmpegDemuxer();
// Carries out initialization on the demuxer thread.
- void InititalizeTask(DataSource* data_source, FilterCallback* callback);
+ void InititalizeTask(DataSource* data_source);
// Carries out a seek on the demuxer thread.
- void SeekTask(base::TimeDelta time, FilterCallback* callback);
+ void SeekTask(base::TimeDelta time);
// Carries out demuxing and satisfying stream reads on the demuxer thread.
void DemuxTask();
diff --git a/media/filters/ffmpeg_demuxer_unittest.cc b/media/filters/ffmpeg_demuxer_unittest.cc
index 18cec27..43b14c7 100644
--- a/media/filters/ffmpeg_demuxer_unittest.cc
+++ b/media/filters/ffmpeg_demuxer_unittest.cc
@@ -133,8 +133,7 @@ class FFmpegDemuxerTest : public testing::Test {
InitializeDemuxerMocks();
// We expect a successful initialization.
- EXPECT_CALL(callback_, OnFilterCallback());
- EXPECT_CALL(callback_, OnCallbackDestroyed());
+ EXPECT_CALL(host_, InitializationComplete());
// Since we ignore data streams, the duration should be equal to the longest
// supported stream's duration (audio, in this case).
@@ -142,7 +141,7 @@ class FFmpegDemuxerTest : public testing::Test {
base::TimeDelta::FromMicroseconds(kDurations[AV_STREAM_AUDIO]);
EXPECT_CALL(host_, SetDuration(expected_duration));
- demuxer_->Initialize(data_source_.get(), callback_.NewCallback());
+ EXPECT_TRUE(demuxer_->Initialize(data_source_.get()));
message_loop_.RunAllPending();
}
@@ -151,7 +150,6 @@ class FFmpegDemuxerTest : public testing::Test {
scoped_refptr<FFmpegDemuxer> demuxer_;
scoped_refptr<StrictMock<MockDataSource> > data_source_;
StrictMock<MockFilterHost> host_;
- StrictMock<MockFilterCallback> callback_;
MessageLoop message_loop_;
// FFmpeg fixtures.
@@ -198,10 +196,8 @@ TEST_F(FFmpegDemuxerTest, Initialize_OpenFails) {
EXPECT_CALL(*MockFFmpeg::get(), AVOpenInputFile(_, _, NULL, 0, NULL))
.WillOnce(Return(-1));
EXPECT_CALL(host_, Error(DEMUXER_ERROR_COULD_NOT_OPEN));
- EXPECT_CALL(callback_, OnFilterCallback());
- EXPECT_CALL(callback_, OnCallbackDestroyed());
- demuxer_->Initialize(data_source_.get(), callback_.NewCallback());
+ EXPECT_TRUE(demuxer_->Initialize(data_source_.get()));
message_loop_.RunAllPending();
}
@@ -213,10 +209,8 @@ TEST_F(FFmpegDemuxerTest, Initialize_ParseFails) {
.WillOnce(Return(AVERROR_IO));
EXPECT_CALL(*MockFFmpeg::get(), AVCloseInputFile(&format_context_));
EXPECT_CALL(host_, Error(DEMUXER_ERROR_COULD_NOT_PARSE));
- EXPECT_CALL(callback_, OnFilterCallback());
- EXPECT_CALL(callback_, OnCallbackDestroyed());
- demuxer_->Initialize(data_source_.get(), callback_.NewCallback());
+ EXPECT_TRUE(demuxer_->Initialize(data_source_.get()));
message_loop_.RunAllPending();
}
@@ -227,11 +221,9 @@ TEST_F(FFmpegDemuxerTest, Initialize_NoStreams) {
InitializeDemuxerMocks();
}
EXPECT_CALL(host_, Error(DEMUXER_ERROR_NO_SUPPORTED_STREAMS));
- EXPECT_CALL(callback_, OnFilterCallback());
- EXPECT_CALL(callback_, OnCallbackDestroyed());
format_context_.nb_streams = 0;
- demuxer_->Initialize(data_source_.get(), callback_.NewCallback());
+ EXPECT_TRUE(demuxer_->Initialize(data_source_.get()));
message_loop_.RunAllPending();
}
@@ -242,12 +234,10 @@ TEST_F(FFmpegDemuxerTest, Initialize_DataStreamOnly) {
InitializeDemuxerMocks();
}
EXPECT_CALL(host_, Error(DEMUXER_ERROR_NO_SUPPORTED_STREAMS));
- EXPECT_CALL(callback_, OnFilterCallback());
- EXPECT_CALL(callback_, OnCallbackDestroyed());
EXPECT_EQ(format_context_.streams[0], &streams_[AV_STREAM_DATA]);
format_context_.nb_streams = 1;
- demuxer_->Initialize(data_source_.get(), callback_.NewCallback());
+ EXPECT_TRUE(demuxer_->Initialize(data_source_.get()));
message_loop_.RunAllPending();
}
@@ -456,11 +446,6 @@ TEST_F(FFmpegDemuxerTest, Seek) {
EXPECT_CALL(*MockFFmpeg::get(),
AVSeekFrame(&format_context_, -1, kExpectedTimestamp, kExpectedFlags))
.WillOnce(Return(0));
-
- // ...then our callback will be executed...
- StrictMock<MockFilterCallback> seek_callback;
- EXPECT_CALL(seek_callback, OnFilterCallback());
- EXPECT_CALL(seek_callback, OnCallbackDestroyed());
EXPECT_CALL(*MockFFmpeg::get(), CheckPoint(2));
// ...followed by two audio packet reads we'll trigger...
@@ -498,8 +483,7 @@ TEST_F(FFmpegDemuxerTest, Seek) {
MockFFmpeg::get()->CheckPoint(1);
// Now issue a simple forward seek, which should discard queued packets.
- demuxer_->Seek(base::TimeDelta::FromMicroseconds(kExpectedTimestamp),
- seek_callback.NewCallback());
+ demuxer_->Seek(base::TimeDelta::FromMicroseconds(kExpectedTimestamp));
message_loop_.RunAllPending();
MockFFmpeg::get()->CheckPoint(2);
diff --git a/media/filters/ffmpeg_video_decoder_unittest.cc b/media/filters/ffmpeg_video_decoder_unittest.cc
index 407f685..b4d4ace 100644
--- a/media/filters/ffmpeg_video_decoder_unittest.cc
+++ b/media/filters/ffmpeg_video_decoder_unittest.cc
@@ -118,7 +118,6 @@ class FFmpegVideoDecoderTest : public testing::Test {
scoped_refptr<DataBuffer> buffer_;
scoped_refptr<DataBuffer> end_of_stream_buffer_;
StrictMock<MockFilterHost> host_;
- StrictMock<MockFilterCallback> callback_;
MessageLoop message_loop_;
// FFmpeg fixtures.
@@ -163,10 +162,8 @@ TEST_F(FFmpegVideoDecoderTest, Initialize_QueryInterfaceFails) {
EXPECT_CALL(*demuxer_, QueryInterface(AVStreamProvider::interface_id()))
.WillOnce(ReturnNull());
EXPECT_CALL(host_, Error(PIPELINE_ERROR_DECODE));
- EXPECT_CALL(callback_, OnFilterCallback());
- EXPECT_CALL(callback_, OnCallbackDestroyed());
- decoder_->Initialize(demuxer_, callback_.NewCallback());
+ EXPECT_TRUE(decoder_->Initialize(demuxer_));
message_loop_.RunAllPending();
}
@@ -180,10 +177,8 @@ TEST_F(FFmpegVideoDecoderTest, Initialize_FindDecoderFails) {
EXPECT_CALL(*MockFFmpeg::get(), AVCodecFindDecoder(CODEC_ID_NONE))
.WillOnce(ReturnNull());
EXPECT_CALL(host_, Error(PIPELINE_ERROR_DECODE));
- EXPECT_CALL(callback_, OnFilterCallback());
- EXPECT_CALL(callback_, OnCallbackDestroyed());
- decoder_->Initialize(demuxer_, callback_.NewCallback());
+ EXPECT_TRUE(decoder_->Initialize(demuxer_));
message_loop_.RunAllPending();
}
@@ -199,10 +194,8 @@ TEST_F(FFmpegVideoDecoderTest, Initialize_InitThreadFails) {
EXPECT_CALL(*MockFFmpeg::get(), AVCodecThreadInit(&codec_context_, 2))
.WillOnce(Return(-1));
EXPECT_CALL(host_, Error(PIPELINE_ERROR_DECODE));
- EXPECT_CALL(callback_, OnFilterCallback());
- EXPECT_CALL(callback_, OnCallbackDestroyed());
- decoder_->Initialize(demuxer_, callback_.NewCallback());
+ EXPECT_TRUE(decoder_->Initialize(demuxer_));
message_loop_.RunAllPending();
}
@@ -220,10 +213,8 @@ TEST_F(FFmpegVideoDecoderTest, Initialize_OpenDecoderFails) {
EXPECT_CALL(*MockFFmpeg::get(), AVCodecOpen(&codec_context_, &codec_))
.WillOnce(Return(-1));
EXPECT_CALL(host_, Error(PIPELINE_ERROR_DECODE));
- EXPECT_CALL(callback_, OnFilterCallback());
- EXPECT_CALL(callback_, OnCallbackDestroyed());
- decoder_->Initialize(demuxer_, callback_.NewCallback());
+ EXPECT_TRUE(decoder_->Initialize(demuxer_));
message_loop_.RunAllPending();
}
@@ -240,10 +231,9 @@ TEST_F(FFmpegVideoDecoderTest, Initialize_Successful) {
.WillOnce(Return(0));
EXPECT_CALL(*MockFFmpeg::get(), AVCodecOpen(&codec_context_, &codec_))
.WillOnce(Return(0));
- EXPECT_CALL(callback_, OnFilterCallback());
- EXPECT_CALL(callback_, OnCallbackDestroyed());
+ EXPECT_CALL(host_, InitializationComplete());
- decoder_->Initialize(demuxer_, callback_.NewCallback());
+ EXPECT_TRUE(decoder_->Initialize(demuxer_));
message_loop_.RunAllPending();
// Test that the output media format is an uncompressed video surface that
diff --git a/media/filters/file_data_source.cc b/media/filters/file_data_source.cc
index 8ac4499..2e13a59 100644
--- a/media/filters/file_data_source.cc
+++ b/media/filters/file_data_source.cc
@@ -20,10 +20,8 @@ FileDataSource::~FileDataSource() {
Stop();
}
-void FileDataSource::Initialize(const std::string& url,
- FilterCallback* callback) {
+bool FileDataSource::Initialize(const std::string& url) {
DCHECK(!file_);
- scoped_ptr<FilterCallback> c(callback);
#if defined(OS_WIN)
FilePath file_path(UTF8ToWide(url));
#else
@@ -35,15 +33,15 @@ void FileDataSource::Initialize(const std::string& url,
if (!file_) {
file_size_ = 0;
host()->Error(PIPELINE_ERROR_URL_NOT_FOUND);
- callback->Run();
- return;
+ return false;
}
media_format_.SetAsString(MediaFormat::kMimeType,
mime_type::kApplicationOctetStream);
media_format_.SetAsString(MediaFormat::kURL, url);
host()->SetTotalBytes(file_size_);
host()->SetBufferedBytes(file_size_);
- callback->Run();
+ host()->InitializationComplete();
+ return true;
}
void FileDataSource::Stop() {
diff --git a/media/filters/file_data_source.h b/media/filters/file_data_source.h
index 5c91ce1..e58e4aa 100644
--- a/media/filters/file_data_source.h
+++ b/media/filters/file_data_source.h
@@ -26,7 +26,7 @@ class FileDataSource : public DataSource {
virtual void Stop();
// Implementation of DataSource.
- virtual void Initialize(const std::string& url, FilterCallback* callback);
+ virtual bool Initialize(const std::string& url);
virtual const MediaFormat& media_format();
virtual size_t Read(uint8* data, size_t size);
virtual bool GetPosition(int64* position_out);
@@ -41,7 +41,6 @@ class FileDataSource : public DataSource {
// of my tests!!!
FRIEND_TEST(FileDataSourceTest, OpenFile);
FRIEND_TEST(FileDataSourceTest, ReadData);
- FRIEND_TEST(FileDataSourceTest, Seek);
friend class FilterFactoryImpl0<FileDataSource>;
FileDataSource();
virtual ~FileDataSource();
diff --git a/media/filters/file_data_source_unittest.cc b/media/filters/file_data_source_unittest.cc
index 9c4b9ee8..dd41e88 100644
--- a/media/filters/file_data_source_unittest.cc
+++ b/media/filters/file_data_source_unittest.cc
@@ -8,7 +8,6 @@
#include "base/file_path.h"
#include "base/string_util.h"
#include "media/base/mock_filter_host.h"
-#include "media/base/mock_filters.h"
#include "media/filters/file_data_source.h"
using ::testing::NiceMock;
@@ -39,15 +38,13 @@ std::string TestFileURL() {
// Test that FileDataSource call the appropriate methods on its filter host.
TEST(FileDataSourceTest, OpenFile) {
StrictMock<MockFilterHost> host;
- StrictMock<MockFilterCallback> callback;
EXPECT_CALL(host, SetTotalBytes(10));
EXPECT_CALL(host, SetBufferedBytes(10));
- EXPECT_CALL(callback, OnFilterCallback());
- EXPECT_CALL(callback, OnCallbackDestroyed());
+ EXPECT_CALL(host, InitializationComplete());
scoped_refptr<FileDataSource> filter = new FileDataSource();
filter->set_host(&host);
- filter->Initialize(TestFileURL(), callback.NewCallback());
+ EXPECT_TRUE(filter->Initialize(TestFileURL()));
}
// Use the mock filter host to directly call the Read and GetPosition methods.
@@ -58,10 +55,9 @@ TEST(FileDataSourceTest, ReadData) {
// Create our mock filter host and initialize the data source.
NiceMock<MockFilterHost> host;
- NiceMock<MockFilterCallback> callback;
scoped_refptr<FileDataSource> filter = new FileDataSource();
filter->set_host(&host);
- filter->Initialize(TestFileURL(), callback.NewCallback());
+ EXPECT_TRUE(filter->Initialize(TestFileURL()));
EXPECT_TRUE(filter->GetSize(&size));
EXPECT_EQ(10, size);
@@ -84,15 +80,4 @@ TEST(FileDataSourceTest, ReadData) {
EXPECT_EQ(10, position);
}
-// Test that FileDataSource does nothing on Seek().
-TEST(FileDataSourceTest, Seek) {
- StrictMock<MockFilterCallback> callback;
- EXPECT_CALL(callback, OnFilterCallback());
- EXPECT_CALL(callback, OnCallbackDestroyed());
- const base::TimeDelta kZero;
-
- scoped_refptr<FileDataSource> filter = new FileDataSource();
- filter->Seek(kZero, callback.NewCallback());
-}
-
} // namespace media
diff --git a/media/filters/video_renderer_base.cc b/media/filters/video_renderer_base.cc
index 3ca45dc..7eace6f 100644
--- a/media/filters/video_renderer_base.cc
+++ b/media/filters/video_renderer_base.cc
@@ -81,7 +81,7 @@ void VideoRendererBase::SetPlaybackRate(float playback_rate) {
playback_rate_ = playback_rate;
}
-void VideoRendererBase::Seek(base::TimeDelta time, FilterCallback* callback) {
+void VideoRendererBase::Seek(base::TimeDelta time) {
AutoLock auto_lock(lock_);
// We need the first frame in |frames_| to run the VideoRendererBase main
// loop, but we don't need decoded frames after the first frame since we are
@@ -93,44 +93,29 @@ void VideoRendererBase::Seek(base::TimeDelta time, FilterCallback* callback) {
}
}
-void VideoRendererBase::Initialize(VideoDecoder* decoder,
- FilterCallback* callback) {
+bool VideoRendererBase::Initialize(VideoDecoder* decoder) {
AutoLock auto_lock(lock_);
- DCHECK(decoder);
- DCHECK(callback);
DCHECK_EQ(state_, UNINITIALIZED);
state_ = INITIALIZING;
decoder_ = decoder;
- initialize_callback_.reset(callback);
// Notify the pipeline of the video dimensions.
int width = 0;
int height = 0;
- if (!ParseMediaFormat(decoder->media_format(), &width, &height)) {
- host()->Error(PIPELINE_ERROR_INITIALIZATION_FAILED);
- initialize_callback_->Run();
- initialize_callback_.reset();
- return;
- }
+ if (!ParseMediaFormat(decoder->media_format(), &width, &height))
+ return false;
host()->SetVideoSize(width, height);
// Initialize the subclass.
// TODO(scherkus): do we trust subclasses not to do something silly while
// we're holding the lock?
- if (!OnInitialize(decoder)) {
- host()->Error(PIPELINE_ERROR_INITIALIZATION_FAILED);
- initialize_callback_->Run();
- initialize_callback_.reset();
- return;
- }
+ if (!OnInitialize(decoder))
+ return false;
// Create our video thread.
if (!PlatformThread::Create(0, this, &thread_)) {
NOTREACHED() << "Video thread creation failed";
- host()->Error(PIPELINE_ERROR_INITIALIZATION_FAILED);
- initialize_callback_->Run();
- initialize_callback_.reset();
- return;
+ return false;
}
#if defined(OS_WIN)
@@ -143,6 +128,8 @@ void VideoRendererBase::Initialize(VideoDecoder* decoder,
for (size_t i = 0; i < kMaxFrames; ++i) {
ScheduleRead();
}
+
+ return true;
}
// PlatformThread::Delegate implementation.
@@ -261,15 +248,11 @@ void VideoRendererBase::OnReadComplete(VideoFrame* frame) {
if (frames_.empty()) {
// We should have initialized but there's no decoded frames in the queue.
// Raise an error.
- state_ = ERRORED;
host()->Error(PIPELINE_ERROR_NO_DATA);
- initialize_callback_->Run();
- initialize_callback_.reset();
} else {
state_ = INITIALIZED;
current_frame_ = frames_.front();
- initialize_callback_->Run();
- initialize_callback_.reset();
+ host()->InitializationComplete();
}
}
}
@@ -283,11 +266,12 @@ bool VideoRendererBase::WaitForInitialized() {
// initialized so we can call OnFrameAvailable() to provide subclasses with
// the first frame.
AutoLock auto_lock(lock_);
+ DCHECK_EQ(state_, INITIALIZING);
while (state_ == INITIALIZING) {
frame_available_.Wait();
- }
- if (state_ == STOPPED || state_ == ERRORED) {
- return false;
+ if (state_ == STOPPED) {
+ return false;
+ }
}
DCHECK_EQ(state_, INITIALIZED);
DCHECK(current_frame_);
diff --git a/media/filters/video_renderer_base.h b/media/filters/video_renderer_base.h
index b1b46ab..e71befa 100644
--- a/media/filters/video_renderer_base.h
+++ b/media/filters/video_renderer_base.h
@@ -39,10 +39,10 @@ class VideoRendererBase : public VideoRenderer,
// MediaFilter implementation.
virtual void Stop();
virtual void SetPlaybackRate(float playback_rate);
- virtual void Seek(base::TimeDelta time, FilterCallback* callback);
+ virtual void Seek(base::TimeDelta time);
// VideoRenderer implementation.
- virtual void Initialize(VideoDecoder* decoder, FilterCallback* callback);
+ virtual bool Initialize(VideoDecoder* decoder);
// PlatformThread::Delegate implementation.
virtual void ThreadMain();
@@ -106,7 +106,6 @@ class VideoRendererBase : public VideoRenderer,
INITIALIZING,
INITIALIZED,
STOPPED,
- ERRORED,
};
State state_;
@@ -118,9 +117,6 @@ class VideoRendererBase : public VideoRenderer,
float playback_rate_;
- // Filter callbacks.
- scoped_ptr<FilterCallback> initialize_callback_;
-
DISALLOW_COPY_AND_ASSIGN(VideoRendererBase);
};
diff --git a/media/filters/video_renderer_base_unittest.cc b/media/filters/video_renderer_base_unittest.cc
deleted file mode 100644
index 691815d..0000000
--- a/media/filters/video_renderer_base_unittest.cc
+++ /dev/null
@@ -1,215 +0,0 @@
-// Copyright (c) 2009 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "base/stl_util-inl.h"
-#include "media/base/data_buffer.h"
-#include "media/base/mock_filter_host.h"
-#include "media/base/mock_filters.h"
-#include "media/base/video_frame_impl.h"
-#include "media/filters/video_renderer_base.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-using ::testing::_;
-using ::testing::AnyNumber;
-using ::testing::InSequence;
-using ::testing::Invoke;
-using ::testing::NotNull;
-using ::testing::Return;
-using ::testing::StrictMock;
-
-namespace media {
-
-// Mocked subclass of VideoRendererBase for testing purposes.
-class MockVideoRendererBase : public VideoRendererBase {
- public:
- MockVideoRendererBase() {}
- virtual ~MockVideoRendererBase() {}
-
- // VideoRendererBase implementation.
- MOCK_METHOD1(OnInitialize, bool (VideoDecoder* decoder));
- MOCK_METHOD0(OnStop, void());
- MOCK_METHOD0(OnFrameAvailable, void());
-
- // Used for verifying check points during tests.
- MOCK_METHOD1(CheckPoint, void(int id));
-
- private:
- DISALLOW_COPY_AND_ASSIGN(MockVideoRendererBase);
-};
-
-class VideoRendererBaseTest : public ::testing::Test {
- public:
- VideoRendererBaseTest()
- : renderer_(new MockVideoRendererBase()),
- decoder_(new MockVideoDecoder(mime_type::kUncompressedVideo, kWidth,
- kHeight)) {
- renderer_->set_host(&host_);
-
- // Queue all reads from the decoder.
- EXPECT_CALL(*decoder_, Read(NotNull()))
- .WillRepeatedly(Invoke(this, &VideoRendererBaseTest::EnqueueCallback));
- }
-
- virtual ~VideoRendererBaseTest() {
- STLDeleteElements(&read_queue_);
-
- // Expect a call into the subclass.
- EXPECT_CALL(*renderer_, OnStop());
- renderer_->Stop();
- }
-
- protected:
- static const size_t kWidth;
- static const size_t kHeight;
-
- // Fixture members.
- scoped_refptr<MockVideoRendererBase> renderer_;
- scoped_refptr<MockVideoDecoder> decoder_;
- StrictMock<MockFilterHost> host_;
- StrictMock<MockFilterCallback> callback_;
-
- // Receives asynchronous read requests sent to |decoder_|.
- std::deque<Callback1<VideoFrame*>::Type*> read_queue_;
-
- private:
- void EnqueueCallback(Callback1<VideoFrame*>::Type* callback) {
- read_queue_.push_back(callback);
- }
-
- DISALLOW_COPY_AND_ASSIGN(VideoRendererBaseTest);
-};
-
-const size_t VideoRendererBaseTest::kWidth = 16u;
-const size_t VideoRendererBaseTest::kHeight = 16u;
-
-// Test initialization where the decoder's media format is malformed.
-TEST_F(VideoRendererBaseTest, Initialize_BadMediaFormat) {
- InSequence s;
-
- // Don't set a media format.
- scoped_refptr<MockVideoDecoder> bad_decoder = new MockVideoDecoder();
-
- // We expect to receive an error.
- EXPECT_CALL(host_, Error(PIPELINE_ERROR_INITIALIZATION_FAILED));
-
- // We expect our callback to be executed.
- EXPECT_CALL(callback_, OnFilterCallback());
- EXPECT_CALL(callback_, OnCallbackDestroyed());
-
- // Initialize, we expect to have no reads.
- renderer_->Initialize(bad_decoder, callback_.NewCallback());
- EXPECT_EQ(0u, read_queue_.size());
-}
-
-// Test initialization where the subclass failed for some reason.
-TEST_F(VideoRendererBaseTest, Initialize_Failed) {
- InSequence s;
-
- // We expect the video size to be set.
- EXPECT_CALL(host_, SetVideoSize(kWidth, kHeight));
-
- // Our subclass will fail when asked to initialize.
- EXPECT_CALL(*renderer_, OnInitialize(_))
- .WillOnce(Return(false));
-
- // We expect to receive an error.
- EXPECT_CALL(host_, Error(PIPELINE_ERROR_INITIALIZATION_FAILED));
-
- // We expect our callback to be executed.
- EXPECT_CALL(callback_, OnFilterCallback());
- EXPECT_CALL(callback_, OnCallbackDestroyed());
-
- // Initialize, we expect to have no reads.
- renderer_->Initialize(decoder_, callback_.NewCallback());
- EXPECT_EQ(0u, read_queue_.size());
-}
-
-// Tests successful initialization, but when we immediately return an end of
-// stream frame.
-TEST_F(VideoRendererBaseTest, Initialize_NoData) {
- InSequence s;
-
- // We expect the video size to be set.
- EXPECT_CALL(host_, SetVideoSize(kWidth, kHeight));
-
- // Then our subclass will be asked to initialize.
- EXPECT_CALL(*renderer_, OnInitialize(_))
- .WillOnce(Return(true));
-
- // Set up a check point to verify that the callback hasn't been executed yet.
- EXPECT_CALL(*renderer_, CheckPoint(0));
-
- // We'll provide end-of-stream immediately, which results in an error.
- EXPECT_CALL(host_, Error(PIPELINE_ERROR_NO_DATA));
-
- // Then we expect our callback to be executed.
- EXPECT_CALL(callback_, OnFilterCallback());
- EXPECT_CALL(callback_, OnCallbackDestroyed());
-
- // Since the callbacks are on a separate thread, expect any number of calls.
- EXPECT_CALL(*renderer_, OnFrameAvailable())
- .Times(AnyNumber());
-
- // Initialize, we should expect to get a bunch of read requests.
- renderer_->Initialize(decoder_, callback_.NewCallback());
- EXPECT_EQ(3u, read_queue_.size());
-
- // Verify our callback hasn't been executed yet.
- renderer_->CheckPoint(0);
-
- // Now satisfy the read requests. Our callback should be executed after
- // exiting this loop.
- while (!read_queue_.empty()) {
- const base::TimeDelta kZero;
- scoped_refptr<VideoFrame> frame;
- VideoFrameImpl::CreateEmptyFrame(&frame);
- read_queue_.front()->Run(frame);
- delete read_queue_.front();
- read_queue_.pop_front();
- }
-}
-
-// Test successful initialization and preroll.
-TEST_F(VideoRendererBaseTest, Initialize_Successful) {
- InSequence s;
-
- // We expect the video size to be set.
- EXPECT_CALL(host_, SetVideoSize(kWidth, kHeight));
-
- // Then our subclass will be asked to initialize.
- EXPECT_CALL(*renderer_, OnInitialize(_))
- .WillOnce(Return(true));
-
- // Set up a check point to verify that the callback hasn't been executed yet.
- EXPECT_CALL(*renderer_, CheckPoint(0));
-
- // After finishing preroll, we expect our callback to be executed.
- EXPECT_CALL(callback_, OnFilterCallback());
- EXPECT_CALL(callback_, OnCallbackDestroyed());
-
- // Since the callbacks are on a separate thread, expect any number of calls.
- EXPECT_CALL(*renderer_, OnFrameAvailable())
- .Times(AnyNumber());
-
- // Initialize, we should expect to get a bunch of read requests.
- renderer_->Initialize(decoder_, callback_.NewCallback());
- EXPECT_EQ(3u, read_queue_.size());
-
- // Verify our callback hasn't been executed yet.
- renderer_->CheckPoint(0);
-
- // Now satisfy the read requests. Our callback should be executed after
- // exiting this loop.
- while (!read_queue_.empty()) {
- const base::TimeDelta kZero;
- scoped_refptr<VideoFrame> frame;
- VideoFrameImpl::CreateFrame(VideoSurface::RGB32, kWidth, kHeight, kZero,
- kZero, &frame);
- read_queue_.front()->Run(frame);
- delete read_queue_.front();
- read_queue_.pop_front();
- }
-}
-
-} // namespace media
diff --git a/media/media.gyp b/media/media.gyp
index 5b4b96a..3b15e80 100644
--- a/media/media.gyp
+++ b/media/media.gyp
@@ -155,7 +155,6 @@
'base/mock_ffmpeg.cc',
'base/mock_ffmpeg.h',
'base/mock_filter_host.h',
- 'base/mock_filters.cc',
'base/mock_filters.h',
'base/mock_reader.h',
'base/pipeline_impl_unittest.cc',
@@ -163,12 +162,10 @@
'base/seekable_buffer_unittest.cc',
'base/video_frame_impl_unittest.cc',
'base/yuv_convert_unittest.cc',
- 'filters/audio_renderer_base_unittest.cc',
'filters/ffmpeg_demuxer_unittest.cc',
'filters/ffmpeg_glue_unittest.cc',
'filters/ffmpeg_video_decoder_unittest.cc',
'filters/file_data_source_unittest.cc',
- 'filters/video_renderer_base_unittest.cc',
],
'conditions': [
['OS=="linux"', {