| Index: media/base/pipeline_impl_unittest.cc
|
| diff --git a/media/base/pipeline_impl_unittest.cc b/media/base/pipeline_impl_unittest.cc
|
| index 56aa2469659e9910987396e9b94d01e36c74c932..418312623ccc7d3a7318dec447adf96ff6837b85 100644
|
| --- a/media/base/pipeline_impl_unittest.cc
|
| +++ b/media/base/pipeline_impl_unittest.cc
|
| @@ -10,34 +10,38 @@
|
| #include "media/base/filters.h"
|
| #include "media/base/factory.h"
|
| #include "media/base/filter_host.h"
|
| -#include "media/base/mock_media_filters.h"
|
| +#include "media/base/mock_filters.h"
|
| #include "testing/gtest/include/gtest/gtest.h"
|
|
|
| -namespace {
|
| +using ::testing::DoAll;
|
| +using ::testing::Return;
|
| +using ::testing::StrictMock;
|
|
|
| -class PipelineImplTest : public testing::Test {
|
| - protected:
|
| +namespace media {
|
| +
|
| +typedef std::vector<MockDemuxerStream*> MockDemuxerStreamVector;
|
| +
|
| +class PipelineImplTest : public ::testing::Test {
|
| + public:
|
| PipelineImplTest()
|
| - : initialize_result_(false),
|
| + : mocks_(new MockFilterFactory()),
|
| + initialize_result_(false),
|
| seek_result_(false),
|
| initialize_event_(false, false),
|
| seek_event_(false, false) {
|
| }
|
|
|
| - virtual ~PipelineImplTest() {}
|
| -
|
| - virtual void TearDown() {
|
| + virtual ~PipelineImplTest() {
|
| // Force the pipeline to shut down its thread.
|
| pipeline_.Stop();
|
| }
|
|
|
| + protected:
|
| // Called by tests after they have finished setting up MockFilterConfig.
|
| // Initializes the pipeline and returns true if the initialization callback
|
| // was executed, false otherwise.
|
| bool InitializeAndWait() {
|
| - DCHECK(!filters_);
|
| - filters_ = new media::old_mocks::MockFilterFactory(&config_);
|
| - pipeline_.Start(filters_, "",
|
| + pipeline_.Start(mocks_, "",
|
| NewCallback(this, &PipelineImplTest::OnInitialize));
|
| return initialize_event_.TimedWait(base::TimeDelta::FromMilliseconds(500));
|
| }
|
| @@ -49,10 +53,66 @@ class PipelineImplTest : public testing::Test {
|
| return seek_event_.TimedWait(base::TimeDelta::FromMilliseconds(500));
|
| }
|
|
|
| + // Sets up expectations to allow the data source to initialize.
|
| + void InitializeDataSource() {
|
| + EXPECT_CALL(*mocks_->data_source(), Initialize(""))
|
| + .WillOnce(DoAll(InitializationComplete(mocks_->data_source()),
|
| + Return(true)));
|
| + EXPECT_CALL(*mocks_->data_source(), Stop());
|
| + }
|
| +
|
| + // Sets up expectations to allow the demuxer to initialize.
|
| + void InitializeDemuxer(MockDemuxerStreamVector* streams) {
|
| + 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(), Stop());
|
| +
|
| + // Configure the demuxer to return the streams.
|
| + for (size_t i = 0; i < streams->size(); ++i) {
|
| + scoped_refptr<DemuxerStream> stream = (*streams)[i];
|
| + EXPECT_CALL(*mocks_->demuxer(), GetStream(i))
|
| + .WillRepeatedly(Return(stream));
|
| + }
|
| + }
|
| +
|
| + // Sets up expectations to allow the video decoder to initialize.
|
| + void InitializeVideoDecoder(MockDemuxerStream* stream) {
|
| + EXPECT_CALL(*mocks_->video_decoder(), Initialize(stream))
|
| + .WillOnce(DoAll(InitializationComplete(mocks_->video_decoder()),
|
| + Return(true)));
|
| + 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))
|
| + .WillOnce(DoAll(InitializationComplete(mocks_->audio_decoder()),
|
| + Return(true)));
|
| + 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()))
|
| + .WillOnce(DoAll(InitializationComplete(mocks_->video_renderer()),
|
| + Return(true)));
|
| + 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()))
|
| + .WillOnce(DoAll(InitializationComplete(mocks_->audio_renderer()),
|
| + Return(true)));
|
| + EXPECT_CALL(*mocks_->audio_renderer(), Stop());
|
| + }
|
| +
|
| // Fixture members.
|
| media::PipelineImpl pipeline_;
|
| - scoped_refptr<media::old_mocks::MockFilterFactory> filters_;
|
| - media::old_mocks::MockFilterConfig config_;
|
| + scoped_refptr<media::MockFilterFactory> mocks_;
|
| bool initialize_result_;
|
| bool seek_result_;
|
|
|
| @@ -75,7 +135,9 @@ class PipelineImplTest : public testing::Test {
|
| };
|
|
|
| TEST_F(PipelineImplTest, NeverInitializes) {
|
| - config_.data_source_behavior = media::old_mocks::MOCK_DATA_SOURCE_NEVER_INIT;
|
| + EXPECT_CALL(*mocks_->data_source(), Initialize(""))
|
| + .WillOnce(Return(true));
|
| + EXPECT_CALL(*mocks_->data_source(), Stop());
|
|
|
| // This test hangs during initialization by never calling
|
| // InitializationComplete(). Make sure we tear down the pipeline properly.
|
| @@ -86,7 +148,7 @@ TEST_F(PipelineImplTest, NeverInitializes) {
|
| }
|
|
|
| TEST_F(PipelineImplTest, RequiredFilterMissing) {
|
| - config_.create_filter = false;
|
| + mocks_->set_creation_successful(false);
|
|
|
| ASSERT_TRUE(InitializeAndWait());
|
| EXPECT_FALSE(initialize_result_);
|
| @@ -96,8 +158,11 @@ TEST_F(PipelineImplTest, RequiredFilterMissing) {
|
| }
|
|
|
| TEST_F(PipelineImplTest, URLNotFound) {
|
| - config_.data_source_behavior =
|
| - media::old_mocks::MOCK_DATA_SOURCE_URL_ERROR_IN_INIT;
|
| + EXPECT_CALL(*mocks_->data_source(), Initialize(""))
|
| + .WillOnce(DoAll(Error(mocks_->data_source(),
|
| + PIPELINE_ERROR_URL_NOT_FOUND),
|
| + Return(false)));
|
| + EXPECT_CALL(*mocks_->data_source(), Stop());
|
|
|
| ASSERT_TRUE(InitializeAndWait());
|
| EXPECT_FALSE(initialize_result_);
|
| @@ -106,117 +171,128 @@ TEST_F(PipelineImplTest, URLNotFound) {
|
| }
|
|
|
| TEST_F(PipelineImplTest, NoStreams) {
|
| - config_.has_audio = false;
|
| - config_.has_video = false;
|
| + MockDemuxerStreamVector streams;
|
| + InitializeDataSource();
|
| + InitializeDemuxer(&streams);
|
|
|
| ASSERT_TRUE(InitializeAndWait());
|
| EXPECT_FALSE(initialize_result_);
|
| EXPECT_FALSE(pipeline_.IsInitialized());
|
| EXPECT_EQ(media::PIPELINE_ERROR_COULD_NOT_RENDER, pipeline_.GetError());
|
| -
|
| - EXPECT_FALSE(filters_->audio_decoder());
|
| - EXPECT_FALSE(filters_->audio_renderer());
|
| - EXPECT_FALSE(filters_->video_decoder());
|
| - EXPECT_FALSE(filters_->video_renderer());
|
| }
|
|
|
| TEST_F(PipelineImplTest, AudioStream) {
|
| - config_.has_video = false;
|
| + scoped_refptr<StrictMock<MockDemuxerStream> > stream =
|
| + new StrictMock<MockDemuxerStream>("audio/x-foo");
|
| + MockDemuxerStreamVector streams;
|
| + streams.push_back(stream);
|
| +
|
| + InitializeDataSource();
|
| + InitializeDemuxer(&streams);
|
| + InitializeAudioDecoder(stream);
|
| + InitializeAudioRenderer();
|
|
|
| ASSERT_TRUE(InitializeAndWait());
|
| EXPECT_TRUE(initialize_result_);
|
| EXPECT_TRUE(pipeline_.IsInitialized());
|
| EXPECT_EQ(media::PIPELINE_OK, pipeline_.GetError());
|
| -
|
| - size_t width, height;
|
| - pipeline_.GetVideoSize(&width, &height);
|
| - EXPECT_EQ(0u, width);
|
| - EXPECT_EQ(0u, height);
|
| EXPECT_TRUE(pipeline_.IsRendered(media::mime_type::kMajorTypeAudio));
|
| EXPECT_FALSE(pipeline_.IsRendered(media::mime_type::kMajorTypeVideo));
|
| -
|
| - EXPECT_TRUE(filters_->audio_decoder());
|
| - EXPECT_TRUE(filters_->audio_renderer());
|
| - EXPECT_FALSE(filters_->video_decoder());
|
| - EXPECT_FALSE(filters_->video_renderer());
|
| }
|
|
|
| TEST_F(PipelineImplTest, VideoStream) {
|
| - config_.has_audio = false;
|
| + scoped_refptr<StrictMock<MockDemuxerStream> > stream =
|
| + new StrictMock<MockDemuxerStream>("video/x-foo");
|
| + MockDemuxerStreamVector streams;
|
| + streams.push_back(stream);
|
| +
|
| + InitializeDataSource();
|
| + InitializeDemuxer(&streams);
|
| + InitializeVideoDecoder(stream);
|
| + InitializeVideoRenderer();
|
|
|
| ASSERT_TRUE(InitializeAndWait());
|
| EXPECT_TRUE(initialize_result_);
|
| EXPECT_TRUE(pipeline_.IsInitialized());
|
| EXPECT_EQ(media::PIPELINE_OK, pipeline_.GetError());
|
| -
|
| - size_t width, height;
|
| - pipeline_.GetVideoSize(&width, &height);
|
| - EXPECT_EQ(config_.video_width, width);
|
| - EXPECT_EQ(config_.video_height, height);
|
| EXPECT_FALSE(pipeline_.IsRendered(media::mime_type::kMajorTypeAudio));
|
| EXPECT_TRUE(pipeline_.IsRendered(media::mime_type::kMajorTypeVideo));
|
| -
|
| - EXPECT_FALSE(filters_->audio_decoder());
|
| - EXPECT_FALSE(filters_->audio_renderer());
|
| - EXPECT_TRUE(filters_->video_decoder());
|
| - EXPECT_TRUE(filters_->video_renderer());
|
| }
|
|
|
| TEST_F(PipelineImplTest, AudioVideoStream) {
|
| + scoped_refptr<StrictMock<MockDemuxerStream> > audio_stream =
|
| + new StrictMock<MockDemuxerStream>("audio/x-foo");
|
| + scoped_refptr<StrictMock<MockDemuxerStream> > video_stream =
|
| + new StrictMock<MockDemuxerStream>("video/x-foo");
|
| + MockDemuxerStreamVector streams;
|
| + streams.push_back(audio_stream);
|
| + streams.push_back(video_stream);
|
| +
|
| + InitializeDataSource();
|
| + InitializeDemuxer(&streams);
|
| + InitializeAudioDecoder(audio_stream);
|
| + InitializeAudioRenderer();
|
| + InitializeVideoDecoder(video_stream);
|
| + InitializeVideoRenderer();
|
| +
|
| ASSERT_TRUE(InitializeAndWait());
|
| EXPECT_TRUE(initialize_result_);
|
| EXPECT_TRUE(pipeline_.IsInitialized());
|
| EXPECT_EQ(media::PIPELINE_OK, pipeline_.GetError());
|
| -
|
| - size_t width, height;
|
| - pipeline_.GetVideoSize(&width, &height);
|
| - EXPECT_EQ(config_.video_width, width);
|
| - EXPECT_EQ(config_.video_height, height);
|
| EXPECT_TRUE(pipeline_.IsRendered(media::mime_type::kMajorTypeAudio));
|
| EXPECT_TRUE(pipeline_.IsRendered(media::mime_type::kMajorTypeVideo));
|
| -
|
| - EXPECT_TRUE(filters_->audio_decoder());
|
| - EXPECT_TRUE(filters_->audio_renderer());
|
| - EXPECT_TRUE(filters_->video_decoder());
|
| - EXPECT_TRUE(filters_->video_renderer());
|
| }
|
|
|
| TEST_F(PipelineImplTest, Seek) {
|
| - ASSERT_TRUE(InitializeAndWait());
|
| -
|
| - // Seek and verify callback returned true.
|
| + scoped_refptr<StrictMock<MockDemuxerStream> > audio_stream =
|
| + new StrictMock<MockDemuxerStream>("audio/x-foo");
|
| + scoped_refptr<StrictMock<MockDemuxerStream> > video_stream =
|
| + new StrictMock<MockDemuxerStream>("video/x-foo");
|
| + MockDemuxerStreamVector streams;
|
| + streams.push_back(audio_stream);
|
| + streams.push_back(video_stream);
|
| +
|
| + InitializeDataSource();
|
| + InitializeDemuxer(&streams);
|
| + InitializeAudioDecoder(audio_stream);
|
| + InitializeAudioRenderer();
|
| + InitializeVideoDecoder(video_stream);
|
| + InitializeVideoRenderer();
|
| +
|
| + // Every filter should receive a call to Seek().
|
| base::TimeDelta expected = base::TimeDelta::FromSeconds(2000);
|
| + 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));
|
| +
|
| + // Initialize then seek!
|
| + ASSERT_TRUE(InitializeAndWait());
|
| EXPECT_TRUE(SeekAndWait(expected));
|
| EXPECT_TRUE(seek_result_);
|
| -
|
| - // Verify every filter received the seek.
|
| - // TODO(scherkus): implement whatever it takes so I can use EXPECT_EQ with
|
| - // base::TimeDelta.
|
| - EXPECT_TRUE(expected == filters_->data_source()->seek_time());
|
| - EXPECT_TRUE(expected == filters_->demuxer()->seek_time());
|
| - EXPECT_TRUE(expected == filters_->audio_decoder()->seek_time());
|
| - EXPECT_TRUE(expected == filters_->audio_renderer()->seek_time());
|
| - EXPECT_TRUE(expected == filters_->video_decoder()->seek_time());
|
| - EXPECT_TRUE(expected == filters_->video_renderer()->seek_time());
|
| }
|
|
|
| -// Try to execute Start()/Stop() on the Pipeline many times and very fast. This
|
| -// test is trying to simulate the situation where the pipeline can get dead
|
| -// locked very easily by quickly calling Start()/Stop().
|
| -TEST_F(PipelineImplTest, StressTestPipelineStartStop) {
|
| - media::old_mocks::MockFilterConfig config;
|
| - const int kTimes = 1000;
|
| - for (int i = 0; i < kTimes; ++i) {
|
| - scoped_refptr<media::old_mocks::MockFilterFactory> factory =
|
| - new media::old_mocks::MockFilterFactory(&config);
|
| - media::PipelineImpl pipeline;
|
| - pipeline.Start(factory.get(), "", NULL);
|
| - pipeline.Stop();
|
| - }
|
| +TEST_F(PipelineImplTest, SetVolume) {
|
| + scoped_refptr<StrictMock<MockDemuxerStream> > audio_stream =
|
| + new StrictMock<MockDemuxerStream>("audio/x-foo");
|
| + MockDemuxerStreamVector streams;
|
| + streams.push_back(audio_stream);
|
| +
|
| + InitializeDataSource();
|
| + InitializeDemuxer(&streams);
|
| + InitializeAudioDecoder(audio_stream);
|
| + InitializeAudioRenderer();
|
| +
|
| + // The audio renderer should receive a call to SetVolume().
|
| + float expected = 0.5f;
|
| + EXPECT_CALL(*mocks_->audio_renderer(), SetVolume(expected));
|
| +
|
| + // Initialize then set volume!
|
| + ASSERT_TRUE(InitializeAndWait());
|
| + pipeline_.SetVolume(expected);
|
| }
|
|
|
| -// TODO(ralphl): Add a unit test that makes sure that the mock audio filter
|
| -// is actually called on a SetVolume() call to the pipeline. I almost checked
|
| -// in code that broke this, but all unit tests were passing.
|
| +} // namespace media
|
|
|
| -} // namespace
|
|
|