| Index: media/filters/chunk_demuxer_unittest.cc
|
| diff --git a/media/filters/chunk_demuxer_unittest.cc b/media/filters/chunk_demuxer_unittest.cc
|
| index 43ec4ad0a82bf3eb12a6cd746b99a4cefbf906ff..45c3a7d67a7dd30df1695dbdd1d022410a9f1f9a 100644
|
| --- a/media/filters/chunk_demuxer_unittest.cc
|
| +++ b/media/filters/chunk_demuxer_unittest.cc
|
| @@ -39,6 +39,9 @@ static const int kVideoTrackEntryHeaderSize = kVideoTrackSizeOffset +
|
| static const int kVideoTrackNum = 1;
|
| static const int kAudioTrackNum = 2;
|
|
|
| +static const int kAudioBlockDuration = 23;
|
| +static const int kVideoBlockDuration = 33;
|
| +
|
| static const char* kSourceId = "SourceId";
|
|
|
| base::TimeDelta kDefaultDuration() {
|
| @@ -59,7 +62,7 @@ static void WriteInt64(uint8* buffer, int64 number) {
|
| }
|
|
|
| MATCHER_P(HasTimestamp, timestamp_in_ms, "") {
|
| - return !arg->IsEndOfStream() &&
|
| + return arg && !arg->IsEndOfStream() &&
|
| arg->GetTimestamp().InMilliseconds() == timestamp_in_ms;
|
| }
|
|
|
| @@ -177,6 +180,7 @@ class ChunkDemuxerTest : public testing::Test {
|
| }
|
|
|
| bool AppendData(const uint8* data, size_t length) {
|
| + CHECK(length);
|
| EXPECT_CALL(host_, SetBufferedBytes(_)).Times(AnyNumber());
|
| EXPECT_CALL(host_, SetNetworkActivity(true))
|
| .Times(AnyNumber());
|
| @@ -253,10 +257,74 @@ class ChunkDemuxerTest : public testing::Test {
|
| cb->AddSimpleBlock(track_num, timecode, 0, data, sizeof(data));
|
| }
|
|
|
| - void AddSimpleBlock(ClusterBuilder* cb, int track_num, int64 timecode,
|
| - int size) {
|
| + scoped_ptr<Cluster> GenerateCluster(int timecode, int block_count) {
|
| + CHECK_GT(block_count, 0);
|
| +
|
| + int size = 10;
|
| scoped_array<uint8> data(new uint8[size]);
|
| - cb->AddSimpleBlock(track_num, timecode, 0, data.get(), size);
|
| +
|
| + ClusterBuilder cb;
|
| + cb.SetClusterTimecode(timecode);
|
| + int audio_timecode = timecode;
|
| + int video_timecode = timecode + 1;
|
| +
|
| + if (block_count == 1) {
|
| + cb.AddBlockGroup(kAudioTrackNum, audio_timecode, kAudioBlockDuration, 0,
|
| + data.get(), size);
|
| + return cb.Finish();
|
| + }
|
| +
|
| + // Create simple blocks for everything except the last 2 blocks.
|
| + for (int i = 0; i < block_count - 2; i++) {
|
| + if (audio_timecode <= video_timecode) {
|
| + cb.AddSimpleBlock(kAudioTrackNum, audio_timecode, 0, data.get(), size);
|
| + audio_timecode += kAudioBlockDuration;
|
| + continue;
|
| + }
|
| +
|
| + cb.AddSimpleBlock(kVideoTrackNum, video_timecode, 0, data.get(), size);
|
| + video_timecode += kVideoBlockDuration;
|
| + }
|
| +
|
| + // Make the last 2 blocks BlockGroups so that they don't get delayed by the
|
| + // block duration calculation logic.
|
| + if (audio_timecode <= video_timecode) {
|
| + cb.AddBlockGroup(kAudioTrackNum, audio_timecode, kAudioBlockDuration, 0,
|
| + data.get(), size);
|
| + cb.AddBlockGroup(kVideoTrackNum, video_timecode, kVideoBlockDuration, 0,
|
| + data.get(), size);
|
| + } else {
|
| + cb.AddBlockGroup(kVideoTrackNum, video_timecode, kVideoBlockDuration, 0,
|
| + data.get(), size);
|
| + cb.AddBlockGroup(kAudioTrackNum, audio_timecode, kAudioBlockDuration, 0,
|
| + data.get(), size);
|
| + }
|
| +
|
| + return cb.Finish();
|
| + }
|
| +
|
| + void GenerateExpectedReads(int timecode, int block_count,
|
| + DemuxerStream* audio,
|
| + DemuxerStream* video) {
|
| + CHECK_GT(block_count, 0);
|
| + int audio_timecode = timecode;
|
| + int video_timecode = timecode + 1;
|
| +
|
| + if (block_count == 1) {
|
| + ExpectRead(audio, audio_timecode);
|
| + return;
|
| + }
|
| +
|
| + for (int i = 0; i < block_count; i++) {
|
| + if (audio_timecode <= video_timecode) {
|
| + ExpectRead(audio, audio_timecode);
|
| + audio_timecode += kAudioBlockDuration;
|
| + continue;
|
| + }
|
| +
|
| + ExpectRead(video, video_timecode);
|
| + video_timecode += kVideoBlockDuration;
|
| + }
|
| }
|
|
|
| MOCK_METHOD1(ReadDone, void(const scoped_refptr<Buffer>&));
|
| @@ -416,10 +484,7 @@ TEST_F(ChunkDemuxerTest, TestAppendDataAfterSeek) {
|
|
|
| EXPECT_CALL(*this, Checkpoint(2));
|
|
|
| - ClusterBuilder cb;
|
| - cb.SetClusterTimecode(0);
|
| - AddSimpleBlock(&cb, kVideoTrackNum, 0);
|
| - scoped_ptr<Cluster> cluster(cb.Finish());
|
| + scoped_ptr<Cluster> cluster(GenerateCluster(0, 4));
|
|
|
| Checkpoint(1);
|
|
|
| @@ -442,28 +507,20 @@ TEST_F(ChunkDemuxerTest, TestSeekWhileParsingCluster) {
|
|
|
| InSequence s;
|
|
|
| - ClusterBuilder cb;
|
| - cb.SetClusterTimecode(0);
|
| - AddSimpleBlock(&cb, kAudioTrackNum, 1);
|
| - AddSimpleBlock(&cb, kVideoTrackNum, 2);
|
| - AddSimpleBlock(&cb, kAudioTrackNum, 10);
|
| - AddSimpleBlock(&cb, kVideoTrackNum, 20);
|
| - scoped_ptr<Cluster> cluster_a(cb.Finish());
|
| -
|
| - cb.SetClusterTimecode(5000);
|
| - AddSimpleBlock(&cb, kAudioTrackNum, 5000);
|
| - AddSimpleBlock(&cb, kVideoTrackNum, 5005);
|
| - AddSimpleBlock(&cb, kAudioTrackNum, 5007);
|
| - AddSimpleBlock(&cb, kVideoTrackNum, 5035);
|
| - scoped_ptr<Cluster> cluster_b(cb.Finish());
|
| + scoped_ptr<Cluster> cluster_a(GenerateCluster(0, 6));
|
| + scoped_ptr<Cluster> cluster_b(GenerateCluster(5000, 6));
|
|
|
| // Append all but the last byte so that everything but
|
| // the last block can be parsed.
|
| ASSERT_TRUE(AppendData(cluster_a->data(), cluster_a->size() - 1));
|
|
|
| - ExpectRead(audio, 1);
|
| - ExpectRead(video, 2);
|
| - ExpectRead(audio, 10);
|
| + ExpectRead(audio, 0);
|
| + ExpectRead(video, 1);
|
| + ExpectRead(audio, kAudioBlockDuration);
|
| + // Note: We skip trying to read a video buffer here because computing
|
| + // the duration for this block relies on successfully parsing the last block
|
| + // in the cluster the cluster.
|
| + ExpectRead(audio, 2 * kAudioBlockDuration);
|
|
|
| demuxer_->FlushData();
|
| demuxer_->Seek(base::TimeDelta::FromSeconds(5),
|
| @@ -473,10 +530,7 @@ TEST_F(ChunkDemuxerTest, TestSeekWhileParsingCluster) {
|
| // Append the new cluster and verify that only the blocks
|
| // in the new cluster are returned.
|
| ASSERT_TRUE(AppendData(cluster_b->data(), cluster_b->size()));
|
| - ExpectRead(audio, 5000);
|
| - ExpectRead(video, 5005);
|
| - ExpectRead(audio, 5007);
|
| - ExpectRead(video, 5035);
|
| + GenerateExpectedReads(5000, 6, audio, video);
|
| }
|
|
|
| // Test the case where AppendData() is called before Init().
|
| @@ -501,18 +555,14 @@ TEST_F(ChunkDemuxerTest, TestRead) {
|
| bool audio_read_done = false;
|
| bool video_read_done = false;
|
| audio->Read(base::Bind(&OnReadDone,
|
| - base::TimeDelta::FromMilliseconds(32),
|
| + base::TimeDelta::FromMilliseconds(0),
|
| &audio_read_done));
|
|
|
| video->Read(base::Bind(&OnReadDone,
|
| - base::TimeDelta::FromMilliseconds(123),
|
| + base::TimeDelta::FromMilliseconds(1),
|
| &video_read_done));
|
|
|
| - ClusterBuilder cb;
|
| - cb.SetClusterTimecode(0);
|
| - AddSimpleBlock(&cb, kAudioTrackNum, 32);
|
| - AddSimpleBlock(&cb, kVideoTrackNum, 123);
|
| - scoped_ptr<Cluster> cluster(cb.Finish());
|
| + scoped_ptr<Cluster> cluster(GenerateCluster(0, 4));
|
|
|
| ASSERT_TRUE(AppendData(cluster->data(), cluster->size()));
|
|
|
| @@ -523,25 +573,13 @@ TEST_F(ChunkDemuxerTest, TestRead) {
|
| TEST_F(ChunkDemuxerTest, TestOutOfOrderClusters) {
|
| ASSERT_TRUE(InitDemuxer(true, true, false));
|
|
|
| - ClusterBuilder cb;
|
| -
|
| - cb.SetClusterTimecode(10);
|
| - AddSimpleBlock(&cb, kAudioTrackNum, 10);
|
| - AddSimpleBlock(&cb, kVideoTrackNum, 10);
|
| - AddSimpleBlock(&cb, kAudioTrackNum, 33);
|
| - AddSimpleBlock(&cb, kVideoTrackNum, 43);
|
| - scoped_ptr<Cluster> cluster_a(cb.Finish());
|
| + scoped_ptr<Cluster> cluster_a(GenerateCluster(10, 4));
|
|
|
| ASSERT_TRUE(AppendData(cluster_a->data(), cluster_a->size()));
|
|
|
| // Cluster B starts before cluster_a and has data
|
| // that overlaps.
|
| - cb.SetClusterTimecode(5);
|
| - AddSimpleBlock(&cb, kAudioTrackNum, 5);
|
| - AddSimpleBlock(&cb, kVideoTrackNum, 7);
|
| - AddSimpleBlock(&cb, kAudioTrackNum, 28);
|
| - AddSimpleBlock(&cb, kVideoTrackNum, 40);
|
| - scoped_ptr<Cluster> cluster_b(cb.Finish());
|
| + scoped_ptr<Cluster> cluster_b(GenerateCluster(5, 4));
|
|
|
| // Make sure that AppendData() fails because this cluster data
|
| // is before previous data.
|
| @@ -549,10 +587,7 @@ TEST_F(ChunkDemuxerTest, TestOutOfOrderClusters) {
|
| ASSERT_TRUE(AppendData(cluster_b->data(), cluster_b->size()));
|
|
|
| // Verify that AppendData() doesn't accept more data now.
|
| - cb.SetClusterTimecode(45);
|
| - AddSimpleBlock(&cb, kAudioTrackNum, 45);
|
| - AddSimpleBlock(&cb, kVideoTrackNum, 45);
|
| - scoped_ptr<Cluster> cluster_c(cb.Finish());
|
| + scoped_ptr<Cluster> cluster_c(GenerateCluster(45, 2));
|
| EXPECT_FALSE(demuxer_->AppendData(kSourceId, cluster_c->data(),
|
| cluster_c->size()));
|
| }
|
| @@ -575,10 +610,7 @@ TEST_F(ChunkDemuxerTest, TestNonMonotonicButAboveClusterTimecode) {
|
| ASSERT_TRUE(AppendData(cluster_a->data(), cluster_a->size()));
|
|
|
| // Verify that AppendData() doesn't accept more data now.
|
| - cb.SetClusterTimecode(20);
|
| - AddSimpleBlock(&cb, kAudioTrackNum, 20);
|
| - AddSimpleBlock(&cb, kVideoTrackNum, 20);
|
| - scoped_ptr<Cluster> cluster_b(cb.Finish());
|
| + scoped_ptr<Cluster> cluster_b(GenerateCluster(20, 2));
|
| EXPECT_FALSE(demuxer_->AppendData(kSourceId, cluster_b->data(),
|
| cluster_b->size()));
|
| }
|
| @@ -601,10 +633,7 @@ TEST_F(ChunkDemuxerTest, TestBackwardsAndBeforeClusterTimecode) {
|
| ASSERT_TRUE(AppendData(cluster_a->data(), cluster_a->size()));
|
|
|
| // Verify that AppendData() doesn't accept more data now.
|
| - cb.SetClusterTimecode(6);
|
| - AddSimpleBlock(&cb, kAudioTrackNum, 6);
|
| - AddSimpleBlock(&cb, kVideoTrackNum, 6);
|
| - scoped_ptr<Cluster> cluster_b(cb.Finish());
|
| + scoped_ptr<Cluster> cluster_b(GenerateCluster(6, 2));
|
| EXPECT_FALSE(demuxer_->AppendData(kSourceId, cluster_b->data(),
|
| cluster_b->size()));
|
| }
|
| @@ -651,10 +680,7 @@ TEST_F(ChunkDemuxerTest, TestMonotonicallyIncreasingTimestampsAcrossClusters) {
|
| ASSERT_TRUE(AppendData(cluster_b->data(), cluster_b->size()));
|
|
|
| // Verify that AppendData() doesn't accept more data now.
|
| - cb.SetClusterTimecode(10);
|
| - AddSimpleBlock(&cb, kAudioTrackNum, 10);
|
| - AddSimpleBlock(&cb, kVideoTrackNum, 10);
|
| - scoped_ptr<Cluster> cluster_c(cb.Finish());
|
| + scoped_ptr<Cluster> cluster_c(GenerateCluster(10, 2));
|
| EXPECT_FALSE(demuxer_->AppendData(kSourceId, cluster_c->data(),
|
| cluster_c->size()));
|
| }
|
| @@ -668,10 +694,7 @@ TEST_F(ChunkDemuxerTest, TestClusterBeforeInfoTracks) {
|
|
|
| ASSERT_EQ(AddId(), ChunkDemuxer::kOk);
|
|
|
| - ClusterBuilder cb;
|
| - cb.SetClusterTimecode(0);
|
| - AddSimpleBlock(&cb, kVideoTrackNum, 0);
|
| - scoped_ptr<Cluster> cluster(cb.Finish());
|
| + scoped_ptr<Cluster> cluster(GenerateCluster(0, 1));
|
|
|
| ASSERT_TRUE(AppendData(cluster->data(), cluster->size()));
|
| }
|
| @@ -687,13 +710,7 @@ TEST_F(ChunkDemuxerTest, TestEOSDuringInit) {
|
| TEST_F(ChunkDemuxerTest, TestDecodeErrorEndOfStream) {
|
| ASSERT_TRUE(InitDemuxer(true, true, false));
|
|
|
| - ClusterBuilder cb;
|
| - cb.SetClusterTimecode(0);
|
| - AddSimpleBlock(&cb, kAudioTrackNum, 0);
|
| - AddSimpleBlock(&cb, kVideoTrackNum, 0);
|
| - AddSimpleBlock(&cb, kAudioTrackNum, 23);
|
| - AddSimpleBlock(&cb, kVideoTrackNum, 33);
|
| - scoped_ptr<Cluster> cluster(cb.Finish());
|
| + scoped_ptr<Cluster> cluster(GenerateCluster(0, 4));
|
| ASSERT_TRUE(AppendData(cluster->data(), cluster->size()));
|
|
|
| EXPECT_CALL(host_, OnDemuxerError(PIPELINE_ERROR_DECODE));
|
| @@ -703,13 +720,7 @@ TEST_F(ChunkDemuxerTest, TestDecodeErrorEndOfStream) {
|
| TEST_F(ChunkDemuxerTest, TestNetworkErrorEndOfStream) {
|
| ASSERT_TRUE(InitDemuxer(true, true, false));
|
|
|
| - ClusterBuilder cb;
|
| - cb.SetClusterTimecode(0);
|
| - AddSimpleBlock(&cb, kAudioTrackNum, 0);
|
| - AddSimpleBlock(&cb, kVideoTrackNum, 0);
|
| - AddSimpleBlock(&cb, kAudioTrackNum, 23);
|
| - AddSimpleBlock(&cb, kVideoTrackNum, 33);
|
| - scoped_ptr<Cluster> cluster(cb.Finish());
|
| + scoped_ptr<Cluster> cluster(GenerateCluster(0, 4));
|
| ASSERT_TRUE(AppendData(cluster->data(), cluster->size()));
|
|
|
| EXPECT_CALL(host_, OnDemuxerError(PIPELINE_ERROR_NETWORK));
|
| @@ -780,21 +791,17 @@ TEST_F(ChunkDemuxerTest, TestEndOfStreamWithPendingReads) {
|
| EndOfStreamHelper end_of_stream_helper_2(demuxer_);
|
|
|
| audio->Read(base::Bind(&OnReadDone,
|
| - base::TimeDelta::FromMilliseconds(32),
|
| + base::TimeDelta::FromMilliseconds(0),
|
| &audio_read_done_1));
|
|
|
| video->Read(base::Bind(&OnReadDone,
|
| - base::TimeDelta::FromMilliseconds(123),
|
| + base::TimeDelta::FromMilliseconds(1),
|
| &video_read_done_1));
|
|
|
| end_of_stream_helper_1.RequestReads();
|
| end_of_stream_helper_2.RequestReads();
|
|
|
| - ClusterBuilder cb;
|
| - cb.SetClusterTimecode(0);
|
| - AddSimpleBlock(&cb, kAudioTrackNum, 32);
|
| - AddSimpleBlock(&cb, kVideoTrackNum, 123);
|
| - scoped_ptr<Cluster> cluster(cb.Finish());
|
| + scoped_ptr<Cluster> cluster(GenerateCluster(0, 2));
|
|
|
| ASSERT_TRUE(AppendData(cluster->data(), cluster->size()));
|
|
|
| @@ -826,20 +833,16 @@ TEST_F(ChunkDemuxerTest, TestReadsAfterEndOfStream) {
|
| EndOfStreamHelper end_of_stream_helper_3(demuxer_);
|
|
|
| audio->Read(base::Bind(&OnReadDone,
|
| - base::TimeDelta::FromMilliseconds(32),
|
| + base::TimeDelta::FromMilliseconds(0),
|
| &audio_read_done_1));
|
|
|
| video->Read(base::Bind(&OnReadDone,
|
| - base::TimeDelta::FromMilliseconds(123),
|
| + base::TimeDelta::FromMilliseconds(1),
|
| &video_read_done_1));
|
|
|
| end_of_stream_helper_1.RequestReads();
|
|
|
| - ClusterBuilder cb;
|
| - cb.SetClusterTimecode(0);
|
| - AddSimpleBlock(&cb, kAudioTrackNum, 32);
|
| - AddSimpleBlock(&cb, kVideoTrackNum, 123);
|
| - scoped_ptr<Cluster> cluster(cb.Finish());
|
| + scoped_ptr<Cluster> cluster(GenerateCluster(0, 2));
|
|
|
| ASSERT_TRUE(AppendData(cluster->data(), cluster->size()));
|
|
|
| @@ -873,16 +876,8 @@ TEST_F(ChunkDemuxerTest, TestAppendingInPieces) {
|
| int info_tracks_size = 0;
|
| CreateInfoTracks(true, true, false, &info_tracks, &info_tracks_size);
|
|
|
| - ClusterBuilder cb;
|
| - cb.SetClusterTimecode(0);
|
| - AddSimpleBlock(&cb, kAudioTrackNum, 32, 512);
|
| - AddSimpleBlock(&cb, kVideoTrackNum, 123, 1024);
|
| - scoped_ptr<Cluster> cluster_a(cb.Finish());
|
| -
|
| - cb.SetClusterTimecode(125);
|
| - AddSimpleBlock(&cb, kAudioTrackNum, 125, 2048);
|
| - AddSimpleBlock(&cb, kVideoTrackNum, 150, 2048);
|
| - scoped_ptr<Cluster> cluster_b(cb.Finish());
|
| + scoped_ptr<Cluster> cluster_a(GenerateCluster(0, 4));
|
| + scoped_ptr<Cluster> cluster_b(GenerateCluster(68, 4));
|
|
|
| size_t buffer_size = info_tracks_size + cluster_a->size() + cluster_b->size();
|
| scoped_array<uint8> buffer(new uint8[buffer_size]);
|
| @@ -906,31 +901,8 @@ TEST_F(ChunkDemuxerTest, TestAppendingInPieces) {
|
| ASSERT_TRUE(audio);
|
| ASSERT_TRUE(video);
|
|
|
| - bool audio_read_done = false;
|
| - bool video_read_done = false;
|
| - audio->Read(base::Bind(&OnReadDone,
|
| - base::TimeDelta::FromMilliseconds(32),
|
| - &audio_read_done));
|
| -
|
| - video->Read(base::Bind(&OnReadDone,
|
| - base::TimeDelta::FromMilliseconds(123),
|
| - &video_read_done));
|
| -
|
| - EXPECT_TRUE(audio_read_done);
|
| - EXPECT_TRUE(video_read_done);
|
| -
|
| - audio_read_done = false;
|
| - video_read_done = false;
|
| - audio->Read(base::Bind(&OnReadDone,
|
| - base::TimeDelta::FromMilliseconds(125),
|
| - &audio_read_done));
|
| -
|
| - video->Read(base::Bind(&OnReadDone,
|
| - base::TimeDelta::FromMilliseconds(150),
|
| - &video_read_done));
|
| -
|
| - EXPECT_TRUE(audio_read_done);
|
| - EXPECT_TRUE(video_read_done);
|
| + GenerateExpectedReads(0, 4, audio, video);
|
| + GenerateExpectedReads(68, 4, audio, video);
|
| }
|
|
|
| TEST_F(ChunkDemuxerTest, TestWebMFile_AudioAndVideo) {
|
| @@ -993,14 +965,7 @@ TEST_F(ChunkDemuxerTest, TestWebMFile_VideoOnly) {
|
| TEST_F(ChunkDemuxerTest, TestIncrementalClusterParsing) {
|
| ASSERT_TRUE(InitDemuxer(true, true, false));
|
|
|
| - ClusterBuilder cb;
|
| - cb.SetClusterTimecode(0);
|
| - AddSimpleBlock(&cb, kAudioTrackNum, 0, 10);
|
| - AddSimpleBlock(&cb, kVideoTrackNum, 1, 10);
|
| - AddSimpleBlock(&cb, kVideoTrackNum, 2, 10);
|
| - AddSimpleBlock(&cb, kAudioTrackNum, 3, 10);
|
| - scoped_ptr<Cluster> cluster(cb.Finish());
|
| -
|
| + scoped_ptr<Cluster> cluster(GenerateCluster(0, 6));
|
| scoped_refptr<DemuxerStream> audio =
|
| demuxer_->GetStream(DemuxerStream::AUDIO);
|
| scoped_refptr<DemuxerStream> video =
|
| @@ -1042,11 +1007,11 @@ TEST_F(ChunkDemuxerTest, TestIncrementalClusterParsing) {
|
| audio_read_done = false;
|
| video_read_done = false;
|
| audio->Read(base::Bind(&OnReadDone,
|
| - base::TimeDelta::FromMilliseconds(3),
|
| + base::TimeDelta::FromMilliseconds(23),
|
| &audio_read_done));
|
|
|
| video->Read(base::Bind(&OnReadDone,
|
| - base::TimeDelta::FromMilliseconds(2),
|
| + base::TimeDelta::FromMilliseconds(34),
|
| &video_read_done));
|
|
|
| // Make sure the reads haven't completed yet.
|
| @@ -1054,6 +1019,7 @@ TEST_F(ChunkDemuxerTest, TestIncrementalClusterParsing) {
|
| EXPECT_FALSE(video_read_done);
|
|
|
| // Append the remaining data.
|
| + ASSERT_LT(i, cluster->size());
|
| ASSERT_TRUE(AppendData(cluster->data() + i, cluster->size() - i));
|
|
|
| EXPECT_TRUE(audio_read_done);
|
|
|