| Index: media/filters/chunk_demuxer_unittest.cc
|
| diff --git a/media/filters/chunk_demuxer_unittest.cc b/media/filters/chunk_demuxer_unittest.cc
|
| index 1b4719f318e61d4f121caa8cb98b465a311c076d..4f628d64babd93e15531ae13bc591109fa729caf 100644
|
| --- a/media/filters/chunk_demuxer_unittest.cc
|
| +++ b/media/filters/chunk_demuxer_unittest.cc
|
| @@ -16,7 +16,6 @@ using ::testing::AnyNumber;
|
| using ::testing::InSequence;
|
| using ::testing::Return;
|
| using ::testing::SetArgumentPointee;
|
| -using ::testing::NiceMock;
|
| using ::testing::_;
|
|
|
| namespace media {
|
| @@ -32,6 +31,11 @@ static const int kTracksSizeOffset = 4;
|
| static const int kVideoTrackNum = 1;
|
| static const int kAudioTrackNum = 2;
|
|
|
| +MATCHER_P(HasTimestamp, timestamp_in_ms, "") {
|
| + return !arg->IsEndOfStream() &&
|
| + arg->GetTimestamp().InMilliseconds() == timestamp_in_ms;
|
| +}
|
| +
|
| class MockChunkDemuxerClient : public ChunkDemuxerClient {
|
| public:
|
| MockChunkDemuxerClient() {}
|
| @@ -192,6 +196,14 @@ class ChunkDemuxerTest : public testing::Test {
|
| cb->AddSimpleBlock(track_num, timecode, 0, data.get(), size);
|
| }
|
|
|
| + MOCK_METHOD1(ReadDone, void(const scoped_refptr<Buffer>&));
|
| +
|
| + void ExpectRead(DemuxerStream* stream, int64 timestamp_in_ms) {
|
| + EXPECT_CALL(*this, ReadDone(HasTimestamp(timestamp_in_ms)));
|
| + stream->Read(base::Bind(&ChunkDemuxerTest::ReadDone,
|
| + base::Unretained(this)));
|
| + }
|
| +
|
| MOCK_METHOD1(Checkpoint, void(int id));
|
|
|
| MockDemuxerHost mock_demuxer_host_;
|
| @@ -277,6 +289,57 @@ TEST_F(ChunkDemuxerTest, TestAppendDataAfterSeek) {
|
| Checkpoint(2);
|
| }
|
|
|
| +// Test the case where a Seek() is requested while the parser
|
| +// is in the middle of cluster. This is to verify that the parser
|
| +// resets itself on seek and is in the right state when data from
|
| +// the new seek point arrives.
|
| +TEST_F(ChunkDemuxerTest, TestSeekWhileParsingCluster) {
|
| + InitDemuxer(true, true);
|
| +
|
| + scoped_refptr<DemuxerStream> audio =
|
| + demuxer_->GetStream(DemuxerStream::AUDIO);
|
| + scoped_refptr<DemuxerStream> video =
|
| + demuxer_->GetStream(DemuxerStream::VIDEO);
|
| +
|
| + 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());
|
| +
|
| + // Append all but the last byte so that everything but
|
| + // the last block can be parsed.
|
| + AppendData(cluster_a->data(), cluster_a->size() - 1);
|
| +
|
| + ExpectRead(audio, 1);
|
| + ExpectRead(video, 2);
|
| + ExpectRead(audio, 10);
|
| +
|
| + demuxer_->FlushData();
|
| + demuxer_->Seek(base::TimeDelta::FromSeconds(5),
|
| + NewExpectedStatusCB(PIPELINE_OK));
|
| +
|
| +
|
| + // Append the new cluster and verify that only the blocks
|
| + // in the new cluster are returned.
|
| + AppendData(cluster_b->data(), cluster_b->size());
|
| + ExpectRead(audio, 5000);
|
| + ExpectRead(video, 5005);
|
| + ExpectRead(audio, 5007);
|
| + ExpectRead(video, 5035);
|
| +}
|
| +
|
| // Test the case where AppendData() is called before Init().
|
| TEST_F(ChunkDemuxerTest, TestAppendDataBeforeInit) {
|
| scoped_array<uint8> info_tracks;
|
| @@ -334,30 +397,30 @@ TEST_F(ChunkDemuxerTest, TestOutOfOrderClusters) {
|
| AddSimpleBlock(&cb, kVideoTrackNum, 10);
|
| AddSimpleBlock(&cb, kAudioTrackNum, 33);
|
| AddSimpleBlock(&cb, kVideoTrackNum, 43);
|
| - scoped_ptr<Cluster> clusterA(cb.Finish());
|
| + scoped_ptr<Cluster> cluster_a(cb.Finish());
|
|
|
| - AppendData(clusterA->data(), clusterA->size());
|
| + AppendData(cluster_a->data(), cluster_a->size());
|
|
|
| - // Cluster B starts before clusterA and has data
|
| + // 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> clusterB(cb.Finish());
|
| + scoped_ptr<Cluster> cluster_b(cb.Finish());
|
|
|
| // Make sure that AppendData() fails because this cluster data
|
| // is before previous data.
|
| EXPECT_CALL(mock_demuxer_host_, OnDemuxerError(PIPELINE_ERROR_DECODE));
|
| - AppendData(clusterB->data(), clusterB->size());
|
| + 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> clusterC(cb.Finish());
|
| - EXPECT_FALSE(demuxer_->AppendData(clusterC->data(), clusterC->size()));
|
| + scoped_ptr<Cluster> cluster_c(cb.Finish());
|
| + EXPECT_FALSE(demuxer_->AppendData(cluster_c->data(), cluster_c->size()));
|
| }
|
|
|
| TEST_F(ChunkDemuxerTest, TestNonMonotonicButAboveClusterTimecode) {
|
| @@ -372,17 +435,17 @@ TEST_F(ChunkDemuxerTest, TestNonMonotonicButAboveClusterTimecode) {
|
| AddSimpleBlock(&cb, kVideoTrackNum, 10);
|
| AddSimpleBlock(&cb, kAudioTrackNum, 7);
|
| AddSimpleBlock(&cb, kVideoTrackNum, 15);
|
| - scoped_ptr<Cluster> clusterA(cb.Finish());
|
| + scoped_ptr<Cluster> cluster_a(cb.Finish());
|
|
|
| EXPECT_CALL(mock_demuxer_host_, OnDemuxerError(PIPELINE_ERROR_DECODE));
|
| - AppendData(clusterA->data(), clusterA->size());
|
| + 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> clusterB(cb.Finish());
|
| - EXPECT_FALSE(demuxer_->AppendData(clusterB->data(), clusterB->size()));
|
| + scoped_ptr<Cluster> cluster_b(cb.Finish());
|
| + EXPECT_FALSE(demuxer_->AppendData(cluster_b->data(), cluster_b->size()));
|
| }
|
|
|
| TEST_F(ChunkDemuxerTest, TestBackwardsAndBeforeClusterTimecode) {
|
| @@ -397,17 +460,17 @@ TEST_F(ChunkDemuxerTest, TestBackwardsAndBeforeClusterTimecode) {
|
| AddSimpleBlock(&cb, kVideoTrackNum, 5);
|
| AddSimpleBlock(&cb, kAudioTrackNum, 3);
|
| AddSimpleBlock(&cb, kVideoTrackNum, 3);
|
| - scoped_ptr<Cluster> clusterA(cb.Finish());
|
| + scoped_ptr<Cluster> cluster_a(cb.Finish());
|
|
|
| EXPECT_CALL(mock_demuxer_host_, OnDemuxerError(PIPELINE_ERROR_DECODE));
|
| - AppendData(clusterA->data(), clusterA->size());
|
| + 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> clusterB(cb.Finish());
|
| - EXPECT_FALSE(demuxer_->AppendData(clusterB->data(), clusterB->size()));
|
| + scoped_ptr<Cluster> cluster_b(cb.Finish());
|
| + EXPECT_FALSE(demuxer_->AppendData(cluster_b->data(), cluster_b->size()));
|
| }
|
|
|
|
|
| @@ -439,24 +502,24 @@ TEST_F(ChunkDemuxerTest, TestMonotonicallyIncreasingTimestampsAcrossClusters) {
|
| cb.SetClusterTimecode(5);
|
| AddSimpleBlock(&cb, kAudioTrackNum, 5);
|
| AddSimpleBlock(&cb, kVideoTrackNum, 5);
|
| - scoped_ptr<Cluster> clusterA(cb.Finish());
|
| + scoped_ptr<Cluster> cluster_a(cb.Finish());
|
|
|
| - AppendData(clusterA->data(), clusterA->size());
|
| + AppendData(cluster_a->data(), cluster_a->size());
|
|
|
| cb.SetClusterTimecode(5);
|
| AddSimpleBlock(&cb, kAudioTrackNum, 5);
|
| AddSimpleBlock(&cb, kVideoTrackNum, 7);
|
| - scoped_ptr<Cluster> clusterB(cb.Finish());
|
| + scoped_ptr<Cluster> cluster_b(cb.Finish());
|
|
|
| EXPECT_CALL(mock_demuxer_host_, OnDemuxerError(PIPELINE_ERROR_DECODE));
|
| - AppendData(clusterB->data(), clusterB->size());
|
| + 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> clusterC(cb.Finish());
|
| - EXPECT_FALSE(demuxer_->AppendData(clusterC->data(), clusterC->size()));
|
| + scoped_ptr<Cluster> cluster_c(cb.Finish());
|
| + EXPECT_FALSE(demuxer_->AppendData(cluster_c->data(), cluster_c->size()));
|
| }
|
|
|
| // Test the case where a cluster is passed to AppendData() before
|
| @@ -670,24 +733,24 @@ TEST_F(ChunkDemuxerTest, TestAppendingInPieces) {
|
| cb.SetClusterTimecode(0);
|
| AddSimpleBlock(&cb, kAudioTrackNum, 32, 512);
|
| AddSimpleBlock(&cb, kVideoTrackNum, 123, 1024);
|
| - scoped_ptr<Cluster> clusterA(cb.Finish());
|
| + scoped_ptr<Cluster> cluster_a(cb.Finish());
|
|
|
| cb.SetClusterTimecode(125);
|
| AddSimpleBlock(&cb, kAudioTrackNum, 125, 2048);
|
| AddSimpleBlock(&cb, kVideoTrackNum, 150, 2048);
|
| - scoped_ptr<Cluster> clusterB(cb.Finish());
|
| + scoped_ptr<Cluster> cluster_b(cb.Finish());
|
|
|
| - size_t buffer_size = info_tracks_size + clusterA->size() + clusterB->size();
|
| + size_t buffer_size = info_tracks_size + cluster_a->size() + cluster_b->size();
|
| scoped_array<uint8> buffer(new uint8[buffer_size]);
|
| uint8* dst = buffer.get();
|
| memcpy(dst, info_tracks.get(), info_tracks_size);
|
| dst += info_tracks_size;
|
|
|
| - memcpy(dst, clusterA->data(), clusterA->size());
|
| - dst += clusterA->size();
|
| + memcpy(dst, cluster_a->data(), cluster_a->size());
|
| + dst += cluster_a->size();
|
|
|
| - memcpy(dst, clusterB->data(), clusterB->size());
|
| - dst += clusterB->size();
|
| + memcpy(dst, cluster_b->data(), cluster_b->size());
|
| + dst += cluster_b->size();
|
|
|
| AppendDataInPieces(buffer.get(), buffer_size);
|
|
|
|
|