diff options
Diffstat (limited to 'media/base/pipeline_impl_unittest.cc')
-rw-r--r-- | media/base/pipeline_impl_unittest.cc | 248 |
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 |