summaryrefslogtreecommitdiffstats
path: root/media
diff options
context:
space:
mode:
authorscherkus@chromium.org <scherkus@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-04-30 01:59:21 +0000
committerscherkus@chromium.org <scherkus@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-04-30 01:59:21 +0000
commit4fbba5a5375b1f6327e25ecdba4794e34ff43e68 (patch)
tree86cc9224df8d43b79ba30eef68da2c84089f710f /media
parent2e8d1b025c993d70ec8145060f5448997b8238db (diff)
downloadchromium_src-4fbba5a5375b1f6327e25ecdba4794e34ff43e68.zip
chromium_src-4fbba5a5375b1f6327e25ecdba4794e34ff43e68.tar.gz
chromium_src-4fbba5a5375b1f6327e25ecdba4794e34ff43e68.tar.bz2
Refactored FFmpegDemuxerTest to use a test fixture, fixing flakiness in the process.
BUG=10863 Review URL: http://codereview.chromium.org/100178 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@14926 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'media')
-rw-r--r--media/filters/ffmpeg_demuxer_unittest.cc269
1 files changed, 131 insertions, 138 deletions
diff --git a/media/filters/ffmpeg_demuxer_unittest.cc b/media/filters/ffmpeg_demuxer_unittest.cc
index e82ca10..378552f 100644
--- a/media/filters/ffmpeg_demuxer_unittest.cc
+++ b/media/filters/ffmpeg_demuxer_unittest.cc
@@ -165,40 +165,6 @@ using namespace media;
namespace {
-void InitializeFFmpegMocks() {
- // Initialize function return codes.
- g_av_open_input_file = 0;
- g_av_find_stream_info = 0;
- g_av_read_frame = 0;
-
- // Initialize AVFormatContext structure.
- memset(&g_format, 0, sizeof(g_format));
-
- // Initialize AVStream structures.
- for (size_t i = 0; i < kMaxStreams; ++i) {
- memset(&g_streams[i], 0, sizeof(g_streams[i]));
- g_streams[i].time_base.den = 1 * base::Time::kMicrosecondsPerSecond;
- g_streams[i].time_base.num = 1;
- }
-
- // Initialize AVCodexContext structures.
- memset(&g_audio_codec, 0, sizeof(g_audio_codec));
- g_audio_codec.codec_type = CODEC_TYPE_AUDIO;
- g_audio_codec.codec_id = CODEC_ID_VORBIS;
- g_audio_codec.channels = 2;
- g_audio_codec.sample_rate = 44100;
-
- memset(&g_video_codec, 0, sizeof(g_video_codec));
- g_video_codec.codec_type = CODEC_TYPE_VIDEO;
- g_video_codec.codec_id = CODEC_ID_THEORA;
- g_video_codec.height = 720;
- g_video_codec.width = 1280;
-
- memset(&g_data_codec, 0, sizeof(g_data_codec));
- g_data_codec.codec_type = CODEC_TYPE_DATA;
- g_data_codec.codec_id = CODEC_ID_NONE;
-}
-
// Ref counted object so we can create callbacks to call DemuxerStream::Read().
class TestReader : public base::RefCountedThreadSafe<TestReader> {
public:
@@ -250,76 +216,139 @@ class TestReader : public base::RefCountedThreadSafe<TestReader> {
base::WaitableEvent wait_for_read_;
};
-} // namespace
+// Fixture class to facilitate writing tests. Takes care of setting up the
+// FFmpeg, pipeline and filter host mocks.
+class FFmpegDemuxerTest : public testing::Test {
+ protected:
+ FFmpegDemuxerTest() {}
+ virtual ~FFmpegDemuxerTest() {}
+
+ virtual void SetUp() {
+ InitializeFFmpegMocks();
+
+ // Create an FFmpegDemuxer.
+ factory_ = FFmpegDemuxer::CreateFilterFactory();
+ MediaFormat media_format;
+ media_format.SetAsString(MediaFormat::kMimeType,
+ mime_type::kApplicationOctetStream);
+ demuxer_ = factory_->Create<Demuxer>(media_format);
+ DCHECK(demuxer_);
+
+ // Prepare a filter host and data source for the demuxer.
+ pipeline_.reset(new MockPipeline());
+ filter_host_.reset(new MockFilterHost<Demuxer>(pipeline_.get(), demuxer_));
+ MockFilterConfig config;
+ data_source_ = new MockDataSource(&config);
+ }
-// TODO(scherkus): http://crbug.com/10863
-TEST(FFmpegDemuxerTest, DISABLED_InitializeFailure) {
- InitializeFFmpegMocks();
+ virtual void TearDown() {
+ // Call Stop() to shut down internal threads.
+ demuxer_->Stop();
+ }
- // Get FFmpegDemuxer's filter factory.
- scoped_refptr<FilterFactory> factory = FFmpegDemuxer::CreateFilterFactory();
+ // Fixture members.
+ scoped_refptr<FilterFactory> factory_;
+ scoped_refptr<Demuxer> demuxer_;
+ scoped_ptr<MockPipeline> pipeline_;
+ scoped_ptr< MockFilterHost<Demuxer> > filter_host_;
+ scoped_refptr<MockDataSource> data_source_;
+
+ private:
+ static void InitializeFFmpegMocks() {
+ // Initialize function return codes.
+ g_av_open_input_file = 0;
+ g_av_find_stream_info = 0;
+ g_av_read_frame = 0;
+
+ // Initialize AVFormatContext structure.
+ memset(&g_format, 0, sizeof(g_format));
+
+ // Initialize AVStream structures.
+ for (size_t i = 0; i < kMaxStreams; ++i) {
+ memset(&g_streams[i], 0, sizeof(g_streams[i]));
+ g_streams[i].time_base.den = 1 * base::Time::kMicrosecondsPerSecond;
+ g_streams[i].time_base.num = 1;
+ }
+
+ // Initialize AVCodexContext structures.
+ memset(&g_audio_codec, 0, sizeof(g_audio_codec));
+ g_audio_codec.codec_type = CODEC_TYPE_AUDIO;
+ g_audio_codec.codec_id = CODEC_ID_VORBIS;
+ g_audio_codec.channels = 2;
+ g_audio_codec.sample_rate = 44100;
+
+ memset(&g_video_codec, 0, sizeof(g_video_codec));
+ g_video_codec.codec_type = CODEC_TYPE_VIDEO;
+ g_video_codec.codec_id = CODEC_ID_THEORA;
+ g_video_codec.height = 720;
+ g_video_codec.width = 1280;
+
+ memset(&g_data_codec, 0, sizeof(g_data_codec));
+ g_data_codec.codec_type = CODEC_TYPE_DATA;
+ g_data_codec.codec_id = CODEC_ID_NONE;
+ }
+
+ DISALLOW_COPY_AND_ASSIGN(FFmpegDemuxerTest);
+};
+
+} // namespace
+TEST(FFmpegDemuxerFactoryTest, Create) {
// Should only accept application/octet-stream type.
+ scoped_refptr<FilterFactory> factory = FFmpegDemuxer::CreateFilterFactory();
MediaFormat media_format;
media_format.SetAsString(MediaFormat::kMimeType, "foo/x-bar");
scoped_refptr<Demuxer> demuxer(factory->Create<Demuxer>(media_format));
ASSERT_FALSE(demuxer);
+
+ // Try again with application/octet-stream mime type.
media_format.Clear();
media_format.SetAsString(MediaFormat::kMimeType,
mime_type::kApplicationOctetStream);
demuxer = factory->Create<Demuxer>(media_format);
ASSERT_TRUE(demuxer);
+}
- // Prepare a filter host and data source for the demuxer.
- MockPipeline pipeline;
- scoped_ptr< MockFilterHost<Demuxer> > filter_host;
- filter_host.reset(new MockFilterHost<Demuxer>(&pipeline, demuxer));
- MockFilterConfig config;
- scoped_refptr<MockDataSource> data_source(new MockDataSource(&config));
-
+TEST_F(FFmpegDemuxerTest, InitializeCouldNotOpen) {
// Simulate av_open_input_fail failing.
g_av_open_input_file = AVERROR_IO;
g_av_find_stream_info = 0;
- EXPECT_TRUE(demuxer->Initialize(data_source));
- EXPECT_TRUE(filter_host->WaitForError(DEMUXER_ERROR_COULD_NOT_OPEN));
- EXPECT_FALSE(filter_host->IsInitialized());
+ EXPECT_TRUE(demuxer_->Initialize(data_source_.get()));
+ EXPECT_TRUE(filter_host_->WaitForError(DEMUXER_ERROR_COULD_NOT_OPEN));
+ EXPECT_FALSE(filter_host_->IsInitialized());
+}
+TEST_F(FFmpegDemuxerTest, InitializeCouldNotParse) {
// Simulate av_find_stream_info failing.
g_av_open_input_file = 0;
g_av_find_stream_info = AVERROR_IO;
- pipeline.Reset(false);
- demuxer = factory->Create<Demuxer>(media_format);
- filter_host.reset(new MockFilterHost<Demuxer>(&pipeline, demuxer));
- EXPECT_TRUE(demuxer->Initialize(data_source));
- EXPECT_TRUE(filter_host->WaitForError(DEMUXER_ERROR_COULD_NOT_PARSE));
- EXPECT_FALSE(filter_host->IsInitialized());
+ EXPECT_TRUE(demuxer_->Initialize(data_source_.get()));
+ EXPECT_TRUE(filter_host_->WaitForError(DEMUXER_ERROR_COULD_NOT_PARSE));
+ EXPECT_FALSE(filter_host_->IsInitialized());
+}
+
+TEST_F(FFmpegDemuxerTest, InitializeNoStreams) {
// Simulate media with no parseable streams.
- InitializeFFmpegMocks();
- pipeline.Reset(false);
- demuxer = factory->Create<Demuxer>(media_format);
- filter_host.reset(new MockFilterHost<Demuxer>(&pipeline, demuxer));
- EXPECT_TRUE(demuxer->Initialize(data_source));
- EXPECT_TRUE(filter_host->WaitForError(DEMUXER_ERROR_NO_SUPPORTED_STREAMS));
- EXPECT_FALSE(filter_host->IsInitialized());
+ EXPECT_TRUE(demuxer_->Initialize(data_source_.get()));
+ EXPECT_TRUE(filter_host_->WaitForError(DEMUXER_ERROR_NO_SUPPORTED_STREAMS));
+ EXPECT_FALSE(filter_host_->IsInitialized());
+}
+TEST_F(FFmpegDemuxerTest, InitializeDataStreamOnly) {
// Simulate media with a data stream but no audio or video streams.
g_format.nb_streams = 1;
g_format.streams[0] = &g_streams[0];
g_streams[0].codec = &g_data_codec;
g_streams[0].duration = 10;
- pipeline.Reset(false);
- demuxer = factory->Create<Demuxer>(media_format);
- filter_host.reset(new MockFilterHost<Demuxer>(&pipeline, demuxer));
- EXPECT_TRUE(demuxer->Initialize(data_source));
- EXPECT_TRUE(filter_host->WaitForError(DEMUXER_ERROR_NO_SUPPORTED_STREAMS));
- EXPECT_FALSE(filter_host->IsInitialized());
+
+ EXPECT_TRUE(demuxer_->Initialize(data_source_.get()));
+ EXPECT_TRUE(filter_host_->WaitForError(DEMUXER_ERROR_NO_SUPPORTED_STREAMS));
+ EXPECT_FALSE(filter_host_->IsInitialized());
}
-// TODO(scherkus): http://crbug.com/10863
-TEST(FFmpegDemuxerTest, DISABLED_InitializeStreams) {
+TEST_F(FFmpegDemuxerTest, InitializeStreams) {
// Simulate media with a data stream, a video stream and audio stream.
- InitializeFFmpegMocks();
g_format.nb_streams = 3;
g_format.streams[0] = &g_streams[0];
g_format.streams[1] = &g_streams[1];
@@ -331,36 +360,21 @@ TEST(FFmpegDemuxerTest, DISABLED_InitializeStreams) {
g_streams[2].duration = 10;
g_streams[2].codec = &g_audio_codec;
- // Create our pipeline.
- MockPipeline pipeline;
-
- // Create our data source.
- MockFilterConfig config;
- scoped_refptr<MockDataSource> data_source = new MockDataSource(&config);
- MockFilterHost<DataSource> filter_host_a(&pipeline, data_source);
- EXPECT_TRUE(data_source->Initialize("foo"));
- EXPECT_TRUE(filter_host_a.IsInitialized());
-
- // Create our demuxer.
- scoped_refptr<FilterFactory> factory = FFmpegDemuxer::CreateFilterFactory();
- scoped_refptr<Demuxer> demuxer
- = factory->Create<Demuxer>(data_source->media_format());
- EXPECT_TRUE(demuxer);
- MockFilterHost<Demuxer> filter_host_b(&pipeline, demuxer);
- EXPECT_TRUE(demuxer->Initialize(data_source));
- EXPECT_TRUE(filter_host_b.WaitForInitialized());
- EXPECT_TRUE(filter_host_b.IsInitialized());
- EXPECT_EQ(PIPELINE_OK, pipeline.GetError());
+ // Initialize the demuxer.
+ EXPECT_TRUE(demuxer_->Initialize(data_source_.get()));
+ EXPECT_TRUE(filter_host_->WaitForInitialized());
+ EXPECT_TRUE(filter_host_->IsInitialized());
+ EXPECT_EQ(PIPELINE_OK, pipeline_->GetError());
// Since we ignore data streams, the duration should be equal to the video
// stream's duration.
- EXPECT_EQ(g_streams[1].duration, pipeline.GetDuration().InMicroseconds());
+ EXPECT_EQ(g_streams[1].duration, pipeline_->GetDuration().InMicroseconds());
// Verify that 2 out of 3 streams were created.
- EXPECT_EQ(2, demuxer->GetNumberOfStreams());
+ EXPECT_EQ(2, demuxer_->GetNumberOfStreams());
// First stream should be video and support FFmpegDemuxerStream interface.
- scoped_refptr<DemuxerStream> stream = demuxer->GetStream(0);
+ scoped_refptr<DemuxerStream> stream = demuxer_->GetStream(0);
scoped_refptr<FFmpegDemuxerStream> ffmpeg_demuxer_stream;
ASSERT_TRUE(stream);
std::string mime_type;
@@ -372,23 +386,18 @@ TEST(FFmpegDemuxerTest, DISABLED_InitializeStreams) {
EXPECT_EQ(&g_streams[1], ffmpeg_demuxer_stream->av_stream());
// Second stream should be audio and support FFmpegDemuxerStream interface.
- stream = demuxer->GetStream(1);
+ stream = demuxer_->GetStream(1);
ffmpeg_demuxer_stream = NULL;
ASSERT_TRUE(stream);
- EXPECT_TRUE(
- stream->media_format().GetAsString(MediaFormat::kMimeType, &mime_type));
+ EXPECT_TRUE(stream->media_format().GetAsString(MediaFormat::kMimeType,
+ &mime_type));
EXPECT_STREQ(mime_type::kFFmpegAudio, mime_type.c_str());
EXPECT_TRUE(stream->QueryInterface(&ffmpeg_demuxer_stream));
EXPECT_TRUE(ffmpeg_demuxer_stream);
EXPECT_EQ(&g_streams[2], ffmpeg_demuxer_stream->av_stream());
}
-// TODO(scherkus): as we keep refactoring and improving our mocks (both FFmpeg
-// and pipeline/filters), try to break this test into two. Big issue right now
-// is that it takes ~50 lines of code just to set up FFmpegDemuxer.
-//
-// TODO(scherkus): http://crbug.com/10863
-TEST(FFmpegDemuxerTest, DISABLED_ReadAndSeek) {
+TEST_F(FFmpegDemuxerTest, ReadAndSeek) {
// Prepare some test data.
const int kPacketData = 0;
const int kPacketAudio = 1;
@@ -403,7 +412,6 @@ TEST(FFmpegDemuxerTest, DISABLED_ReadAndSeek) {
// the data stream first forces the audio and video streams to get remapped
// from indices {1,2} to {0,1} respectively, which covers an important test
// case.
- InitializeFFmpegMocks();
g_format.nb_streams = 3;
g_format.streams[kPacketData] = &g_streams[0];
g_format.streams[kPacketAudio] = &g_streams[1];
@@ -415,33 +423,18 @@ TEST(FFmpegDemuxerTest, DISABLED_ReadAndSeek) {
g_streams[2].duration = 10;
g_streams[2].codec = &g_video_codec;
- // Create our pipeline.
- MockPipeline pipeline;
-
- // Create our data source.
- MockFilterConfig config;
- scoped_refptr<MockDataSource> data_source = new MockDataSource(&config);
- MockFilterHost<DataSource> filter_host_a(&pipeline, data_source);
- EXPECT_TRUE(data_source->Initialize("foo"));
- EXPECT_TRUE(filter_host_a.IsInitialized());
-
- // Create our demuxer.
- scoped_refptr<FilterFactory> factory = FFmpegDemuxer::CreateFilterFactory();
- scoped_refptr<Demuxer> demuxer
- = factory->Create<Demuxer>(data_source->media_format());
- EXPECT_TRUE(demuxer);
- MockFilterHost<Demuxer> filter_host_b(&pipeline, demuxer);
- EXPECT_TRUE(demuxer->Initialize(data_source));
- EXPECT_TRUE(filter_host_b.WaitForInitialized());
- EXPECT_TRUE(filter_host_b.IsInitialized());
- EXPECT_EQ(PIPELINE_OK, pipeline.GetError());
+ // Initialize the demuxer.
+ EXPECT_TRUE(demuxer_->Initialize(data_source_.get()));
+ EXPECT_TRUE(filter_host_->WaitForInitialized());
+ EXPECT_TRUE(filter_host_->IsInitialized());
+ EXPECT_EQ(PIPELINE_OK, pipeline_->GetError());
// Verify both streams were created.
- EXPECT_EQ(2, demuxer->GetNumberOfStreams());
+ EXPECT_EQ(2, demuxer_->GetNumberOfStreams());
// Get our streams.
- scoped_refptr<DemuxerStream> audio_stream = demuxer->GetStream(kAudio);
- scoped_refptr<DemuxerStream> video_stream = demuxer->GetStream(kVideo);
+ scoped_refptr<DemuxerStream> audio_stream = demuxer_->GetStream(kAudio);
+ scoped_refptr<DemuxerStream> video_stream = demuxer_->GetStream(kVideo);
ASSERT_TRUE(audio_stream);
ASSERT_TRUE(video_stream);
@@ -456,7 +449,7 @@ TEST(FFmpegDemuxerTest, DISABLED_ReadAndSeek) {
// Attempt a read from the audio stream and run the message loop until done.
scoped_refptr<TestReader> reader(new TestReader());
reader->Read(audio_stream);
- pipeline.RunAllTasks();
+ pipeline_->RunAllTasks();
EXPECT_TRUE(reader->WaitForRead());
EXPECT_TRUE(reader->called());
ASSERT_TRUE(reader->buffer());
@@ -470,7 +463,7 @@ TEST(FFmpegDemuxerTest, DISABLED_ReadAndSeek) {
// Attempt a read from the video stream and run the message loop until done.
reader->Reset();
reader->Read(video_stream);
- pipeline.RunAllTasks();
+ pipeline_->RunAllTasks();
EXPECT_TRUE(reader->WaitForRead());
EXPECT_TRUE(reader->called());
ASSERT_TRUE(reader->buffer());
@@ -490,7 +483,7 @@ TEST(FFmpegDemuxerTest, DISABLED_ReadAndSeek) {
// Let's trigger a simple forward seek with no outstanding packets.
g_expected_seek_timestamp = 1234;
g_expected_seek_flags = 0;
- demuxer->Seek(base::TimeDelta::FromMicroseconds(g_expected_seek_timestamp));
+ demuxer_->Seek(base::TimeDelta::FromMicroseconds(g_expected_seek_timestamp));
EXPECT_TRUE(g_seek_event->TimedWait(base::TimeDelta::FromSeconds(1)));
// The next read from each stream should now be discontinuous, but subsequent
@@ -503,7 +496,7 @@ TEST(FFmpegDemuxerTest, DISABLED_ReadAndSeek) {
// Audio read #1, should be discontinuous.
reader = new TestReader();
reader->Read(audio_stream);
- pipeline.RunAllTasks();
+ pipeline_->RunAllTasks();
EXPECT_TRUE(reader->WaitForRead());
EXPECT_TRUE(reader->called());
ASSERT_TRUE(reader->buffer());
@@ -514,7 +507,7 @@ TEST(FFmpegDemuxerTest, DISABLED_ReadAndSeek) {
// Audio read #2, should not be discontinuous.
reader->Reset();
reader->Read(audio_stream);
- pipeline.RunAllTasks();
+ pipeline_->RunAllTasks();
EXPECT_TRUE(reader->WaitForRead());
EXPECT_TRUE(reader->called());
ASSERT_TRUE(reader->buffer());
@@ -529,7 +522,7 @@ TEST(FFmpegDemuxerTest, DISABLED_ReadAndSeek) {
// Video read #1, should be discontinuous.
reader->Reset();
reader->Read(video_stream);
- pipeline.RunAllTasks();
+ pipeline_->RunAllTasks();
EXPECT_TRUE(reader->WaitForRead());
EXPECT_TRUE(reader->called());
ASSERT_TRUE(reader->buffer());
@@ -540,7 +533,7 @@ TEST(FFmpegDemuxerTest, DISABLED_ReadAndSeek) {
// Video read #2, should not be discontinuous.
reader->Reset();
reader->Read(video_stream);
- pipeline.RunAllTasks();
+ pipeline_->RunAllTasks();
EXPECT_TRUE(reader->WaitForRead());
EXPECT_TRUE(reader->called());
ASSERT_TRUE(reader->buffer());
@@ -563,7 +556,7 @@ TEST(FFmpegDemuxerTest, DISABLED_ReadAndSeek) {
// the audio packets preceding the video packet.
reader = new TestReader();
reader->Read(video_stream);
- pipeline.RunAllTasks();
+ pipeline_->RunAllTasks();
EXPECT_TRUE(reader->WaitForRead());
EXPECT_TRUE(reader->called());
ASSERT_TRUE(reader->buffer());
@@ -578,7 +571,7 @@ TEST(FFmpegDemuxerTest, DISABLED_ReadAndSeek) {
// Trigger the seek.
g_expected_seek_timestamp = 1234;
g_expected_seek_flags = 0;
- demuxer->Seek(base::TimeDelta::FromMicroseconds(g_expected_seek_timestamp));
+ demuxer_->Seek(base::TimeDelta::FromMicroseconds(g_expected_seek_timestamp));
EXPECT_TRUE(g_seek_event->TimedWait(base::TimeDelta::FromSeconds(1)));
// All outstanding packets should have been freed.
@@ -597,7 +590,7 @@ TEST(FFmpegDemuxerTest, DISABLED_ReadAndSeek) {
// Attempt a read from the audio stream and run the message loop until done.
reader = new TestReader();
reader->Read(audio_stream);
- pipeline.RunAllTasks();
+ pipeline_->RunAllTasks();
EXPECT_FALSE(reader->WaitForRead());
EXPECT_FALSE(reader->called());
EXPECT_FALSE(reader->buffer());