| Index: media/filters/chunk_demuxer_unittest.cc
|
| diff --git a/media/filters/chunk_demuxer_unittest.cc b/media/filters/chunk_demuxer_unittest.cc
|
| index d55dff4fc2d00fff1676bf6badba0e24d0afe798..afbf9793580dfa0a66d4c5f0264eaba9a549df03 100644
|
| --- a/media/filters/chunk_demuxer_unittest.cc
|
| +++ b/media/filters/chunk_demuxer_unittest.cc
|
| @@ -46,6 +46,7 @@ static const int kAudioBlockDuration = 23;
|
| static const int kVideoBlockDuration = 33;
|
|
|
| static const char* kSourceId = "SourceId";
|
| +static const char* kDefaultFirstClusterRange = "{ [0,46) }";
|
|
|
| base::TimeDelta kDefaultDuration() {
|
| return base::TimeDelta::FromMilliseconds(201224);
|
| @@ -256,7 +257,7 @@ class ChunkDemuxerTest : public testing::Test {
|
| return false;
|
| start += append_size;
|
|
|
| - EXPECT_GT(buffered_bytes_, old_buffered_bytes);
|
| + EXPECT_GE(buffered_bytes_, old_buffered_bytes);
|
| }
|
| return true;
|
| }
|
| @@ -284,8 +285,11 @@ class ChunkDemuxerTest : public testing::Test {
|
|
|
| PipelineStatusCB CreateInitDoneCB(const base::TimeDelta& expected_duration,
|
| PipelineStatus expected_status) {
|
| - if (expected_status == PIPELINE_OK)
|
| + if (expected_status == PIPELINE_OK) {
|
| + if (expected_duration != kInfiniteDuration())
|
| + EXPECT_CALL(host_, SetTotalBytes(_));
|
| EXPECT_CALL(host_, SetDuration(expected_duration));
|
| + }
|
|
|
| return base::Bind(&ChunkDemuxerTest::InitDoneCalled,
|
| base::Unretained(this),
|
| @@ -395,10 +399,10 @@ class ChunkDemuxerTest : public testing::Test {
|
| }
|
|
|
| scoped_ptr<Cluster> GenerateSingleStreamCluster(int timecode,
|
| - int block_count,
|
| + int end_timecode,
|
| int track_number,
|
| int block_duration) {
|
| - CHECK_GT(block_count, 0);
|
| + CHECK_GT(end_timecode, timecode);
|
|
|
| int size = 10;
|
| scoped_array<uint8> data(new uint8[size]);
|
| @@ -407,7 +411,7 @@ class ChunkDemuxerTest : public testing::Test {
|
| cb.SetClusterTimecode(timecode);
|
|
|
| // Create simple blocks for everything except the last block.
|
| - for (int i = 0; i < block_count - 1; i++) {
|
| + for (int i = 0; timecode < (end_timecode - block_duration); i++) {
|
| cb.AddSimpleBlock(track_number, timecode, kWebMFlagKeyframe,
|
| data.get(), size);
|
| timecode += block_duration;
|
| @@ -463,26 +467,22 @@ class ChunkDemuxerTest : public testing::Test {
|
| }
|
| }
|
|
|
| - std::pair<base::TimeDelta, base::TimeDelta> CreateRange(
|
| - int start_time, int block_count, int block_duration) {
|
| - return std::make_pair(base::TimeDelta::FromMilliseconds(start_time),
|
| - base::TimeDelta::FromMilliseconds(start_time +
|
| - (block_count * block_duration)));
|
| + void CheckExpectedRanges(const std::string& expected) {
|
| + CheckExpectedRanges(kSourceId, expected);
|
| }
|
|
|
| - void CheckExpectedRanges(const ChunkDemuxer::Ranges& expected_times) {
|
| - ChunkDemuxer::Ranges actual_times;
|
| - demuxer_->GetBufferedRanges(kSourceId, &actual_times);
|
| - EXPECT_EQ(expected_times.size(), actual_times.size());
|
| -
|
| - for (ChunkDemuxer::Ranges::const_iterator actual_itr =
|
| - actual_times.begin(), expected_itr = expected_times.begin();
|
| - actual_itr != actual_times.end() &&
|
| - expected_itr != expected_times.end();
|
| - actual_itr++, expected_itr++) {
|
| - EXPECT_EQ(expected_itr->first, actual_itr->first);
|
| - EXPECT_EQ(expected_itr->second, actual_itr->second);
|
| + void CheckExpectedRanges(const std::string& id,
|
| + const std::string& expected) {
|
| + Ranges<base::TimeDelta> r = demuxer_->GetBufferedRanges(id);
|
| +
|
| + std::stringstream ss;
|
| + ss << "{ ";
|
| + for (size_t i = 0; i < r.size(); ++i) {
|
| + ss << "[" << r.start(i).InMilliseconds() << ","
|
| + << r.end(i).InMilliseconds() << ") ";
|
| }
|
| + ss << "}";
|
| + EXPECT_EQ(ss.str(), expected);
|
| }
|
|
|
| MOCK_METHOD1(ReadDone, void(const scoped_refptr<DecoderBuffer>&));
|
| @@ -873,14 +873,24 @@ TEST_F(ChunkDemuxerTest, TestEOSDuringInit) {
|
| demuxer_->EndOfStream(PIPELINE_OK);
|
| }
|
|
|
| +TEST_F(ChunkDemuxerTest, TestEndOfStreamWithNoAppend) {
|
| + ASSERT_TRUE(InitDemuxer(true, true, false));
|
| +
|
| + CheckExpectedRanges("{ }");
|
| + demuxer_->EndOfStream(PIPELINE_OK);
|
| + CheckExpectedRanges("{ }");
|
| +}
|
| +
|
| TEST_F(ChunkDemuxerTest, TestDecodeErrorEndOfStream) {
|
| ASSERT_TRUE(InitDemuxer(true, true, false));
|
|
|
| scoped_ptr<Cluster> cluster(kDefaultFirstCluster());
|
| ASSERT_TRUE(AppendData(cluster->data(), cluster->size()));
|
| + CheckExpectedRanges(kDefaultFirstClusterRange);
|
|
|
| EXPECT_CALL(host_, OnDemuxerError(PIPELINE_ERROR_DECODE));
|
| demuxer_->EndOfStream(PIPELINE_ERROR_DECODE);
|
| + CheckExpectedRanges(kDefaultFirstClusterRange);
|
| }
|
|
|
| TEST_F(ChunkDemuxerTest, TestNetworkErrorEndOfStream) {
|
| @@ -888,6 +898,7 @@ TEST_F(ChunkDemuxerTest, TestNetworkErrorEndOfStream) {
|
|
|
| scoped_ptr<Cluster> cluster(kDefaultFirstCluster());
|
| ASSERT_TRUE(AppendData(cluster->data(), cluster->size()));
|
| + CheckExpectedRanges(kDefaultFirstClusterRange);
|
|
|
| EXPECT_CALL(host_, OnDemuxerError(PIPELINE_ERROR_NETWORK));
|
| demuxer_->EndOfStream(PIPELINE_ERROR_NETWORK);
|
| @@ -1282,10 +1293,10 @@ TEST_F(ChunkDemuxerTest, TestAddSeparateSourcesForAudioAndVideo) {
|
| demuxer_->GetStream(DemuxerStream::VIDEO);
|
|
|
| scoped_ptr<Cluster> cluster_a(
|
| - GenerateSingleStreamCluster(0, 4, kAudioTrackNum, kAudioBlockDuration));
|
| + GenerateSingleStreamCluster(0, 92, kAudioTrackNum, kAudioBlockDuration));
|
|
|
| scoped_ptr<Cluster> cluster_v(
|
| - GenerateSingleStreamCluster(0, 4, kVideoTrackNum, kVideoBlockDuration));
|
| + GenerateSingleStreamCluster(0, 132, kVideoTrackNum, kVideoBlockDuration));
|
|
|
| // Append audio and video data into separate source ids.
|
| ASSERT_TRUE(AppendData(audio_id, cluster_a->data(), cluster_a->size()));
|
| @@ -1320,10 +1331,10 @@ TEST_F(ChunkDemuxerTest, TestRemoveId) {
|
| ASSERT_TRUE(InitDemuxerAudioAndVideoSources(audio_id, video_id));
|
|
|
| scoped_ptr<Cluster> cluster_a(
|
| - GenerateSingleStreamCluster(0, 4, kAudioTrackNum, kAudioBlockDuration));
|
| + GenerateSingleStreamCluster(0, 92, kAudioTrackNum, kAudioBlockDuration));
|
|
|
| scoped_ptr<Cluster> cluster_v(
|
| - GenerateSingleStreamCluster(0, 4, kVideoTrackNum, kVideoBlockDuration));
|
| + GenerateSingleStreamCluster(0, 132, kVideoTrackNum, kVideoBlockDuration));
|
|
|
| // Append audio and video data into separate source ids.
|
| ASSERT_TRUE(AppendData(audio_id, cluster_a->data(), cluster_a->size()));
|
| @@ -1356,10 +1367,10 @@ TEST_F(ChunkDemuxerTest, TestSeekAudioAndVideoSources) {
|
| ASSERT_TRUE(InitDemuxerAudioAndVideoSources(audio_id, video_id));
|
|
|
| scoped_ptr<Cluster> cluster_a1(
|
| - GenerateSingleStreamCluster(0, 4, kAudioTrackNum, kAudioBlockDuration));
|
| + GenerateSingleStreamCluster(0, 92, kAudioTrackNum, kAudioBlockDuration));
|
|
|
| scoped_ptr<Cluster> cluster_v1(
|
| - GenerateSingleStreamCluster(0, 4, kVideoTrackNum, kVideoBlockDuration));
|
| + GenerateSingleStreamCluster(0, 132, kVideoTrackNum, kVideoBlockDuration));
|
|
|
| ASSERT_TRUE(AppendData(audio_id, cluster_a1->data(), cluster_a1->size()));
|
| ASSERT_TRUE(AppendData(video_id, cluster_v1->data(), cluster_v1->size()));
|
| @@ -1400,11 +1411,11 @@ TEST_F(ChunkDemuxerTest, TestSeekAudioAndVideoSources) {
|
| EXPECT_FALSE(video_read_done);
|
|
|
| scoped_ptr<Cluster> cluster_a2(
|
| - GenerateSingleStreamCluster(3000, 4, kAudioTrackNum,
|
| + GenerateSingleStreamCluster(3000, 3092, kAudioTrackNum,
|
| kAudioBlockDuration));
|
|
|
| scoped_ptr<Cluster> cluster_v2(
|
| - GenerateSingleStreamCluster(3000, 4, kVideoTrackNum,
|
| + GenerateSingleStreamCluster(3000, 3132, kVideoTrackNum,
|
| kVideoBlockDuration));
|
|
|
| ASSERT_TRUE(AppendData(audio_id, cluster_a2->data(), cluster_a2->size()));
|
| @@ -1425,23 +1436,19 @@ TEST_F(ChunkDemuxerTest, GetBufferedRanges_AudioIdOnly) {
|
| ASSERT_TRUE(AppendInitSegment(true, false, false));
|
|
|
| // Test a simple cluster.
|
| - scoped_ptr<Cluster> cluster_1(GenerateSingleStreamCluster(0, 4,
|
| + scoped_ptr<Cluster> cluster_1(GenerateSingleStreamCluster(0, 92,
|
| kAudioTrackNum, kAudioBlockDuration));
|
| - ChunkDemuxer::Ranges expected;
|
| - expected.push_back(CreateRange(0, 4, kAudioBlockDuration));
|
| -
|
| ASSERT_TRUE(AppendData(cluster_1->data(), cluster_1->size()));
|
|
|
| - CheckExpectedRanges(expected);
|
| + CheckExpectedRanges("{ [0,92) }");
|
|
|
| // Append a disjoint cluster to check for two separate ranges.
|
| - scoped_ptr<Cluster> cluster_2(GenerateSingleStreamCluster(150, 3,
|
| + scoped_ptr<Cluster> cluster_2(GenerateSingleStreamCluster(150, 219,
|
| kAudioTrackNum, kAudioBlockDuration));
|
| - expected.push_back(CreateRange(150, 3, kAudioBlockDuration));
|
|
|
| ASSERT_TRUE(AppendData(cluster_2->data(), cluster_2->size()));
|
|
|
| - CheckExpectedRanges(expected);
|
| + CheckExpectedRanges("{ [0,92) [150,219) }");
|
| }
|
|
|
| // Test ranges in a video-only stream.
|
| @@ -1454,23 +1461,20 @@ TEST_F(ChunkDemuxerTest, GetBufferedRanges_VideoIdOnly) {
|
| ASSERT_TRUE(AppendInitSegment(false, true, false));
|
|
|
| // Test a simple cluster.
|
| - scoped_ptr<Cluster> cluster_1(GenerateSingleStreamCluster(0, 4,
|
| + scoped_ptr<Cluster> cluster_1(GenerateSingleStreamCluster(0, 132,
|
| kVideoTrackNum, kVideoBlockDuration));
|
| - ChunkDemuxer::Ranges expected;
|
| - expected.push_back(CreateRange(0, 4, kVideoBlockDuration));
|
|
|
| ASSERT_TRUE(AppendData(cluster_1->data(), cluster_1->size()));
|
|
|
| - CheckExpectedRanges(expected);
|
| + CheckExpectedRanges("{ [0,132) }");
|
|
|
| // Append a disjoint cluster to check for two separate ranges.
|
| - scoped_ptr<Cluster> cluster_2(GenerateSingleStreamCluster(150, 3,
|
| + scoped_ptr<Cluster> cluster_2(GenerateSingleStreamCluster(150, 249,
|
| kVideoTrackNum, kVideoBlockDuration));
|
| - expected.push_back(CreateRange(150, 3, kVideoBlockDuration));
|
|
|
| ASSERT_TRUE(AppendData(cluster_2->data(), cluster_2->size()));
|
|
|
| - CheckExpectedRanges(expected);
|
| + CheckExpectedRanges("{ [0,132) [150,249) }");
|
| }
|
|
|
| TEST_F(ChunkDemuxerTest, GetBufferedRanges_AudioVideo) {
|
| @@ -1482,95 +1486,86 @@ TEST_F(ChunkDemuxerTest, GetBufferedRanges_AudioVideo) {
|
| // Audio block duration is smaller than video block duration,
|
| // so the buffered ranges should correspond to the audio blocks.
|
| scoped_ptr<Cluster> cluster_a0(
|
| - GenerateSingleStreamCluster(0, 1, kAudioTrackNum, kAudioBlockDuration));
|
| + GenerateSingleStreamCluster(0, kAudioBlockDuration, kAudioTrackNum,
|
| + kAudioBlockDuration));
|
|
|
| scoped_ptr<Cluster> cluster_v0(
|
| - GenerateSingleStreamCluster(0, 1, kVideoTrackNum, kVideoBlockDuration));
|
| -
|
| - ChunkDemuxer::Ranges expected;
|
| - expected.push_back(CreateRange(0, 1, kAudioBlockDuration));
|
| + GenerateSingleStreamCluster(0, kVideoBlockDuration, kVideoTrackNum,
|
| + kVideoBlockDuration));
|
|
|
| ASSERT_TRUE(AppendData(cluster_a0->data(), cluster_a0->size()));
|
| ASSERT_TRUE(AppendData(cluster_v0->data(), cluster_v0->size()));
|
|
|
| - CheckExpectedRanges(expected);
|
| + CheckExpectedRanges("{ [0,23) }");
|
|
|
| // Audio: 100 -> 150
|
| // Video: 120 -> 170
|
| // Buffered Range: 120 -> 150 (end overlap)
|
| scoped_ptr<Cluster> cluster_a1(
|
| - GenerateSingleStreamCluster(100, 1, kAudioTrackNum, 50));
|
| + GenerateSingleStreamCluster(100, 150, kAudioTrackNum, 50));
|
|
|
| scoped_ptr<Cluster> cluster_v1(
|
| - GenerateSingleStreamCluster(120, 1, kVideoTrackNum, 50));
|
| -
|
| - expected.push_back(CreateRange(120, 1, 30));
|
| + GenerateSingleStreamCluster(120, 170, kVideoTrackNum, 50));
|
|
|
| ASSERT_TRUE(AppendData(cluster_a1->data(), cluster_a1->size()));
|
| ASSERT_TRUE(AppendData(cluster_v1->data(), cluster_v1->size()));
|
|
|
| - CheckExpectedRanges(expected);
|
| + CheckExpectedRanges("{ [0,23) [120,150) }");
|
|
|
| // Audio: 220 -> 290
|
| // Video: 200 -> 270
|
| // Buffered Range: 220 -> 270 (front overlap)
|
| scoped_ptr<Cluster> cluster_a2(
|
| - GenerateSingleStreamCluster(220, 1, kAudioTrackNum, 70));
|
| + GenerateSingleStreamCluster(220, 290, kAudioTrackNum, 70));
|
|
|
| scoped_ptr<Cluster> cluster_v2(
|
| - GenerateSingleStreamCluster(200, 1, kVideoTrackNum, 70));
|
| -
|
| - expected.push_back(CreateRange(220, 1, 50));
|
| + GenerateSingleStreamCluster(200, 270, kVideoTrackNum, 70));
|
|
|
| ASSERT_TRUE(AppendData(cluster_a2->data(), cluster_a2->size()));
|
| ASSERT_TRUE(AppendData(cluster_v2->data(), cluster_v2->size()));
|
|
|
| - CheckExpectedRanges(expected);
|
| + CheckExpectedRanges("{ [0,23) [120,150) [220,270) }");
|
|
|
| // Audio: 320 -> 350
|
| // Video: 300 -> 370
|
| // Buffered Range: 320 -> 350 (complete overlap, audio)
|
| scoped_ptr<Cluster> cluster_a3(
|
| - GenerateSingleStreamCluster(320, 1, kAudioTrackNum, 30));
|
| + GenerateSingleStreamCluster(320, 350, kAudioTrackNum, 30));
|
|
|
| scoped_ptr<Cluster> cluster_v3(
|
| - GenerateSingleStreamCluster(300, 1, kVideoTrackNum, 70));
|
| -
|
| - expected.push_back(CreateRange(320, 1, 30));
|
| + GenerateSingleStreamCluster(300, 370, kVideoTrackNum, 70));
|
|
|
| ASSERT_TRUE(AppendData(cluster_a3->data(), cluster_a3->size()));
|
| ASSERT_TRUE(AppendData(cluster_v3->data(), cluster_v3->size()));
|
|
|
| - CheckExpectedRanges(expected);
|
| + CheckExpectedRanges("{ [0,23) [120,150) [220,270) [320,350) }");
|
|
|
| // Audio: 400 -> 470
|
| // Video: 420 -> 450
|
| // Buffered Range: 420 -> 450 (complete overlap, video)
|
| scoped_ptr<Cluster> cluster_a4(
|
| - GenerateSingleStreamCluster(400, 1, kAudioTrackNum, 70));
|
| + GenerateSingleStreamCluster(400, 470, kAudioTrackNum, 70));
|
|
|
| scoped_ptr<Cluster> cluster_v4(
|
| - GenerateSingleStreamCluster(420, 1, kVideoTrackNum, 30));
|
| -
|
| - expected.push_back(CreateRange(420, 1, 30));
|
| + GenerateSingleStreamCluster(420, 450, kVideoTrackNum, 30));
|
|
|
| ASSERT_TRUE(AppendData(cluster_a4->data(), cluster_a4->size()));
|
| ASSERT_TRUE(AppendData(cluster_v4->data(), cluster_v4->size()));
|
|
|
| - CheckExpectedRanges(expected);
|
| + CheckExpectedRanges("{ [0,23) [120,150) [220,270) [320,350) [420,450) }");
|
|
|
| // Appending within buffered range should not affect buffered ranges.
|
| scoped_ptr<Cluster> cluster_a5(
|
| - GenerateSingleStreamCluster(430, 1, kAudioTrackNum, 20));
|
| + GenerateSingleStreamCluster(430, 450, kAudioTrackNum, 20));
|
| ASSERT_TRUE(AppendData(cluster_a5->data(), cluster_a5->size()));
|
| - CheckExpectedRanges(expected);
|
| + CheckExpectedRanges("{ [0,23) [120,150) [220,270) [320,350) [420,450) }");
|
|
|
| // Appending to single stream outside buffered ranges should not affect
|
| // buffered ranges.
|
| scoped_ptr<Cluster> cluster_v5(
|
| - GenerateSingleStreamCluster(530, 1, kVideoTrackNum, 10));
|
| + GenerateSingleStreamCluster(530, 540, kVideoTrackNum, 10));
|
| ASSERT_TRUE(AppendData(cluster_v5->data(), cluster_v5->size()));
|
| - CheckExpectedRanges(expected);
|
| + CheckExpectedRanges("{ [0,23) [120,150) [220,270) [320,350) [420,450) }");
|
| }
|
|
|
| // Once EndOfStream() is called, GetBufferedRanges should not cut off any
|
| @@ -1580,17 +1575,18 @@ TEST_F(ChunkDemuxerTest, GetBufferedRanges_EndOfStream) {
|
| ASSERT_TRUE(InitDemuxer(true, true, false));
|
|
|
| scoped_ptr<Cluster> cluster_a(
|
| - GenerateSingleStreamCluster(0, 1, kAudioTrackNum, 90));
|
| + GenerateSingleStreamCluster(0, 90, kAudioTrackNum, 90));
|
| scoped_ptr<Cluster> cluster_v(
|
| - GenerateSingleStreamCluster(0, 1, kVideoTrackNum, 100));
|
| - ChunkDemuxer::Ranges expected;
|
| - expected.push_back(CreateRange(0, 1, 100));
|
| + GenerateSingleStreamCluster(0, 100, kVideoTrackNum, 100));
|
|
|
| ASSERT_TRUE(AppendData(cluster_a->data(), cluster_a->size()));
|
| ASSERT_TRUE(AppendData(cluster_v->data(), cluster_v->size()));
|
|
|
| + CheckExpectedRanges("{ [0,90) }");
|
| +
|
| demuxer_->EndOfStream(PIPELINE_OK);
|
| - CheckExpectedRanges(expected);
|
| +
|
| + CheckExpectedRanges("{ [0,100) }");
|
| }
|
|
|
| TEST_F(ChunkDemuxerTest, TestDifferentStreamTimecodes) {
|
| @@ -1632,4 +1628,54 @@ TEST_F(ChunkDemuxerTest, TestCodecPrefixMatching) {
|
| demuxer_->AddId("source_id", "video/mp4", codecs));
|
| }
|
|
|
| +TEST_F(ChunkDemuxerTest, TestEndOfStreamFailures) {
|
| + std::string audio_id = "audio";
|
| + std::string video_id = "video";
|
| +
|
| + ASSERT_TRUE(InitDemuxerAudioAndVideoSources(audio_id, video_id));
|
| +
|
| + scoped_ptr<Cluster> cluster_a1(
|
| + GenerateSingleStreamCluster(0, 15, kAudioTrackNum, 15));
|
| + scoped_ptr<Cluster> cluster_v1(
|
| + GenerateSingleStreamCluster(0, 5, kVideoTrackNum, 5));
|
| + scoped_ptr<Cluster> cluster_v2(
|
| + GenerateSingleStreamCluster(5, 10, kVideoTrackNum, 5));
|
| + scoped_ptr<Cluster> cluster_v3(
|
| + GenerateSingleStreamCluster(10, 20, kVideoTrackNum, 10));
|
| +
|
| + ASSERT_TRUE(AppendData(audio_id, cluster_a1->data(), cluster_a1->size()));
|
| + ASSERT_TRUE(AppendData(video_id, cluster_v1->data(), cluster_v1->size()));
|
| + ASSERT_TRUE(AppendData(video_id, cluster_v3->data(), cluster_v3->size()));
|
| +
|
| + CheckExpectedRanges(audio_id, "{ [0,15) }");
|
| + CheckExpectedRanges(video_id, "{ [0,5) [10,20) }");
|
| +
|
| + // Make sure that end of stream fails because there is a gap between
|
| + // the current position(0) and the end of the appended data.
|
| + ASSERT_FALSE(demuxer_->EndOfStream(PIPELINE_OK));
|
| +
|
| + // Seek to an time that is inside the last ranges for both streams
|
| + // and verify that the EndOfStream() is successful.
|
| + demuxer_->StartWaitingForSeek();
|
| + demuxer_->Seek(base::TimeDelta::FromMilliseconds(10),
|
| + NewExpectedStatusCB(PIPELINE_OK));
|
| +
|
| + ASSERT_TRUE(demuxer_->EndOfStream(PIPELINE_OK));
|
| +
|
| + // Seek back to 0 and verify that EndOfStream() fails again.
|
| + demuxer_->StartWaitingForSeek();
|
| + demuxer_->Seek(base::TimeDelta::FromMilliseconds(0),
|
| + NewExpectedStatusCB(PIPELINE_OK));
|
| +
|
| + ASSERT_FALSE(demuxer_->EndOfStream(PIPELINE_OK));
|
| +
|
| + // Append the missing range and verify that EndOfStream() succeeds now.
|
| + ASSERT_TRUE(AppendData(video_id, cluster_v2->data(), cluster_v2->size()));
|
| +
|
| + CheckExpectedRanges(audio_id, "{ [0,15) }");
|
| + CheckExpectedRanges(video_id, "{ [0,20) }");
|
| +
|
| + ASSERT_TRUE(demuxer_->EndOfStream(PIPELINE_OK));
|
| +}
|
| +
|
| } // namespace media
|
|
|