summaryrefslogtreecommitdiffstats
path: root/media/base/pipeline_impl_unittest.cc
diff options
context:
space:
mode:
Diffstat (limited to 'media/base/pipeline_impl_unittest.cc')
-rw-r--r--media/base/pipeline_impl_unittest.cc248
1 files changed, 162 insertions, 86 deletions
diff --git a/media/base/pipeline_impl_unittest.cc b/media/base/pipeline_impl_unittest.cc
index 56aa246..4183126 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