OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "base/bind.h" | 5 #include "base/bind.h" |
6 #include "media/base/audio_decoder_config.h" | 6 #include "media/base/audio_decoder_config.h" |
7 #include "media/base/decoder_buffer.h" | 7 #include "media/base/decoder_buffer.h" |
8 #include "media/base/mock_callback.h" | 8 #include "media/base/mock_callback.h" |
9 #include "media/base/mock_demuxer_host.h" | 9 #include "media/base/mock_demuxer_host.h" |
10 #include "media/base/test_data_util.h" | 10 #include "media/base/test_data_util.h" |
(...skipping 28 matching lines...) Expand all Loading... |
39 static const int kVideoTrackEntryHeaderSize = kVideoTrackSizeOffset + | 39 static const int kVideoTrackEntryHeaderSize = kVideoTrackSizeOffset + |
40 kVideoTrackSizeWidth; | 40 kVideoTrackSizeWidth; |
41 | 41 |
42 static const int kVideoTrackNum = 1; | 42 static const int kVideoTrackNum = 1; |
43 static const int kAudioTrackNum = 2; | 43 static const int kAudioTrackNum = 2; |
44 | 44 |
45 static const int kAudioBlockDuration = 23; | 45 static const int kAudioBlockDuration = 23; |
46 static const int kVideoBlockDuration = 33; | 46 static const int kVideoBlockDuration = 33; |
47 | 47 |
48 static const char* kSourceId = "SourceId"; | 48 static const char* kSourceId = "SourceId"; |
| 49 static const char* kDefaultFirstClusterRange = "{ [0,46) }"; |
49 | 50 |
50 base::TimeDelta kDefaultDuration() { | 51 base::TimeDelta kDefaultDuration() { |
51 return base::TimeDelta::FromMilliseconds(201224); | 52 return base::TimeDelta::FromMilliseconds(201224); |
52 } | 53 } |
53 | 54 |
54 // Write an integer into buffer in the form of vint that spans 8 bytes. | 55 // Write an integer into buffer in the form of vint that spans 8 bytes. |
55 // The data pointed by |buffer| should be at least 8 bytes long. | 56 // The data pointed by |buffer| should be at least 8 bytes long. |
56 // |number| should be in the range 0 <= number < 0x00FFFFFFFFFFFFFF. | 57 // |number| should be in the range 0 <= number < 0x00FFFFFFFFFFFFFF. |
57 static void WriteInt64(uint8* buffer, int64 number) { | 58 static void WriteInt64(uint8* buffer, int64 number) { |
58 DCHECK(number >= 0 && number < GG_LONGLONG(0x00FFFFFFFFFFFFFF)); | 59 DCHECK(number >= 0 && number < GG_LONGLONG(0x00FFFFFFFFFFFFFF)); |
(...skipping 190 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
249 const uint8* start = data; | 250 const uint8* start = data; |
250 const uint8* end = data + length; | 251 const uint8* end = data + length; |
251 while (start < end) { | 252 while (start < end) { |
252 int64 old_buffered_bytes = buffered_bytes_; | 253 int64 old_buffered_bytes = buffered_bytes_; |
253 size_t append_size = std::min(piece_size, | 254 size_t append_size = std::min(piece_size, |
254 static_cast<size_t>(end - start)); | 255 static_cast<size_t>(end - start)); |
255 if (!AppendData(start, append_size)) | 256 if (!AppendData(start, append_size)) |
256 return false; | 257 return false; |
257 start += append_size; | 258 start += append_size; |
258 | 259 |
259 EXPECT_GT(buffered_bytes_, old_buffered_bytes); | 260 EXPECT_GE(buffered_bytes_, old_buffered_bytes); |
260 } | 261 } |
261 return true; | 262 return true; |
262 } | 263 } |
263 | 264 |
264 bool AppendInitSegment(bool has_audio, bool has_video, | 265 bool AppendInitSegment(bool has_audio, bool has_video, |
265 bool video_content_encoded) { | 266 bool video_content_encoded) { |
266 return AppendInitSegment(kSourceId, has_audio, has_video, | 267 return AppendInitSegment(kSourceId, has_audio, has_video, |
267 video_content_encoded); | 268 video_content_encoded); |
268 } | 269 } |
269 | 270 |
270 bool AppendInitSegment(const std::string& source_id, | 271 bool AppendInitSegment(const std::string& source_id, |
271 bool has_audio, bool has_video, | 272 bool has_audio, bool has_video, |
272 bool video_content_encoded) { | 273 bool video_content_encoded) { |
273 scoped_array<uint8> info_tracks; | 274 scoped_array<uint8> info_tracks; |
274 int info_tracks_size = 0; | 275 int info_tracks_size = 0; |
275 CreateInitSegment(has_audio, has_video, video_content_encoded, | 276 CreateInitSegment(has_audio, has_video, video_content_encoded, |
276 &info_tracks, &info_tracks_size); | 277 &info_tracks, &info_tracks_size); |
277 return AppendData(source_id, info_tracks.get(), info_tracks_size); | 278 return AppendData(source_id, info_tracks.get(), info_tracks_size); |
278 } | 279 } |
279 | 280 |
280 void InitDoneCalled(PipelineStatus expected_status, | 281 void InitDoneCalled(PipelineStatus expected_status, |
281 PipelineStatus status) { | 282 PipelineStatus status) { |
282 EXPECT_EQ(status, expected_status); | 283 EXPECT_EQ(status, expected_status); |
283 } | 284 } |
284 | 285 |
285 PipelineStatusCB CreateInitDoneCB(const base::TimeDelta& expected_duration, | 286 PipelineStatusCB CreateInitDoneCB(const base::TimeDelta& expected_duration, |
286 PipelineStatus expected_status) { | 287 PipelineStatus expected_status) { |
287 if (expected_status == PIPELINE_OK) | 288 if (expected_status == PIPELINE_OK) { |
| 289 if (expected_duration != kInfiniteDuration()) |
| 290 EXPECT_CALL(host_, SetTotalBytes(_)); |
288 EXPECT_CALL(host_, SetDuration(expected_duration)); | 291 EXPECT_CALL(host_, SetDuration(expected_duration)); |
| 292 } |
289 | 293 |
290 return base::Bind(&ChunkDemuxerTest::InitDoneCalled, | 294 return base::Bind(&ChunkDemuxerTest::InitDoneCalled, |
291 base::Unretained(this), | 295 base::Unretained(this), |
292 expected_status); | 296 expected_status); |
293 } | 297 } |
294 | 298 |
295 bool InitDemuxer(bool has_audio, bool has_video, | 299 bool InitDemuxer(bool has_audio, bool has_video, |
296 bool video_content_encoded) { | 300 bool video_content_encoded) { |
297 PipelineStatus expected_status = | 301 PipelineStatus expected_status = |
298 (has_audio || has_video) ? PIPELINE_OK : DEMUXER_ERROR_COULD_NOT_OPEN; | 302 (has_audio || has_video) ? PIPELINE_OK : DEMUXER_ERROR_COULD_NOT_OPEN; |
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
388 cb.AddBlockGroup(kVideoTrackNum, video_timecode, kVideoBlockDuration, | 392 cb.AddBlockGroup(kVideoTrackNum, video_timecode, kVideoBlockDuration, |
389 video_flag, data.get(), size); | 393 video_flag, data.get(), size); |
390 cb.AddBlockGroup(kAudioTrackNum, audio_timecode, kAudioBlockDuration, | 394 cb.AddBlockGroup(kAudioTrackNum, audio_timecode, kAudioBlockDuration, |
391 kWebMFlagKeyframe, data.get(), size); | 395 kWebMFlagKeyframe, data.get(), size); |
392 } | 396 } |
393 | 397 |
394 return cb.Finish(); | 398 return cb.Finish(); |
395 } | 399 } |
396 | 400 |
397 scoped_ptr<Cluster> GenerateSingleStreamCluster(int timecode, | 401 scoped_ptr<Cluster> GenerateSingleStreamCluster(int timecode, |
398 int block_count, | 402 int end_timecode, |
399 int track_number, | 403 int track_number, |
400 int block_duration) { | 404 int block_duration) { |
401 CHECK_GT(block_count, 0); | 405 CHECK_GT(end_timecode, timecode); |
402 | 406 |
403 int size = 10; | 407 int size = 10; |
404 scoped_array<uint8> data(new uint8[size]); | 408 scoped_array<uint8> data(new uint8[size]); |
405 | 409 |
406 ClusterBuilder cb; | 410 ClusterBuilder cb; |
407 cb.SetClusterTimecode(timecode); | 411 cb.SetClusterTimecode(timecode); |
408 | 412 |
409 // Create simple blocks for everything except the last block. | 413 // Create simple blocks for everything except the last block. |
410 for (int i = 0; i < block_count - 1; i++) { | 414 for (int i = 0; timecode < (end_timecode - block_duration); i++) { |
411 cb.AddSimpleBlock(track_number, timecode, kWebMFlagKeyframe, | 415 cb.AddSimpleBlock(track_number, timecode, kWebMFlagKeyframe, |
412 data.get(), size); | 416 data.get(), size); |
413 timecode += block_duration; | 417 timecode += block_duration; |
414 } | 418 } |
415 | 419 |
416 // Make the last block a BlockGroup so that it doesn't get delayed by the | 420 // Make the last block a BlockGroup so that it doesn't get delayed by the |
417 // block duration calculation logic. | 421 // block duration calculation logic. |
418 cb.AddBlockGroup(track_number, timecode, block_duration, | 422 cb.AddBlockGroup(track_number, timecode, block_duration, |
419 kWebMFlagKeyframe, data.get(), size); | 423 kWebMFlagKeyframe, data.get(), size); |
420 return cb.Finish(); | 424 return cb.Finish(); |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
456 DemuxerStream* stream, int block_duration) { | 460 DemuxerStream* stream, int block_duration) { |
457 CHECK_GT(block_count, 0); | 461 CHECK_GT(block_count, 0); |
458 int stream_timecode = timecode; | 462 int stream_timecode = timecode; |
459 | 463 |
460 for (int i = 0; i < block_count; i++) { | 464 for (int i = 0; i < block_count; i++) { |
461 ExpectRead(stream, stream_timecode); | 465 ExpectRead(stream, stream_timecode); |
462 stream_timecode += block_duration; | 466 stream_timecode += block_duration; |
463 } | 467 } |
464 } | 468 } |
465 | 469 |
466 std::pair<base::TimeDelta, base::TimeDelta> CreateRange( | 470 void CheckExpectedRanges(const std::string& expected) { |
467 int start_time, int block_count, int block_duration) { | 471 CheckExpectedRanges(kSourceId, expected); |
468 return std::make_pair(base::TimeDelta::FromMilliseconds(start_time), | |
469 base::TimeDelta::FromMilliseconds(start_time + | |
470 (block_count * block_duration))); | |
471 } | 472 } |
472 | 473 |
473 void CheckExpectedRanges(const ChunkDemuxer::Ranges& expected_times) { | 474 void CheckExpectedRanges(const std::string& id, |
474 ChunkDemuxer::Ranges actual_times; | 475 const std::string& expected) { |
475 demuxer_->GetBufferedRanges(kSourceId, &actual_times); | 476 Ranges<base::TimeDelta> r = demuxer_->GetBufferedRanges(id); |
476 EXPECT_EQ(expected_times.size(), actual_times.size()); | |
477 | 477 |
478 for (ChunkDemuxer::Ranges::const_iterator actual_itr = | 478 std::stringstream ss; |
479 actual_times.begin(), expected_itr = expected_times.begin(); | 479 ss << "{ "; |
480 actual_itr != actual_times.end() && | 480 for (size_t i = 0; i < r.size(); ++i) { |
481 expected_itr != expected_times.end(); | 481 ss << "[" << r.start(i).InMilliseconds() << "," |
482 actual_itr++, expected_itr++) { | 482 << r.end(i).InMilliseconds() << ") "; |
483 EXPECT_EQ(expected_itr->first, actual_itr->first); | |
484 EXPECT_EQ(expected_itr->second, actual_itr->second); | |
485 } | 483 } |
| 484 ss << "}"; |
| 485 EXPECT_EQ(ss.str(), expected); |
486 } | 486 } |
487 | 487 |
488 MOCK_METHOD1(ReadDone, void(const scoped_refptr<DecoderBuffer>&)); | 488 MOCK_METHOD1(ReadDone, void(const scoped_refptr<DecoderBuffer>&)); |
489 | 489 |
490 void ExpectRead(DemuxerStream* stream, int64 timestamp_in_ms) { | 490 void ExpectRead(DemuxerStream* stream, int64 timestamp_in_ms) { |
491 EXPECT_CALL(*this, ReadDone(HasTimestamp(timestamp_in_ms))); | 491 EXPECT_CALL(*this, ReadDone(HasTimestamp(timestamp_in_ms))); |
492 stream->Read(base::Bind(&ChunkDemuxerTest::ReadDone, | 492 stream->Read(base::Bind(&ChunkDemuxerTest::ReadDone, |
493 base::Unretained(this))); | 493 base::Unretained(this))); |
494 } | 494 } |
495 | 495 |
(...skipping 370 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
866 } | 866 } |
867 | 867 |
868 // Test cases where we get an EndOfStream() call during initialization. | 868 // Test cases where we get an EndOfStream() call during initialization. |
869 TEST_F(ChunkDemuxerTest, TestEOSDuringInit) { | 869 TEST_F(ChunkDemuxerTest, TestEOSDuringInit) { |
870 EXPECT_CALL(*client_, DemuxerOpened(_)); | 870 EXPECT_CALL(*client_, DemuxerOpened(_)); |
871 demuxer_->Initialize( | 871 demuxer_->Initialize( |
872 &host_, NewExpectedStatusCB(DEMUXER_ERROR_COULD_NOT_OPEN)); | 872 &host_, NewExpectedStatusCB(DEMUXER_ERROR_COULD_NOT_OPEN)); |
873 demuxer_->EndOfStream(PIPELINE_OK); | 873 demuxer_->EndOfStream(PIPELINE_OK); |
874 } | 874 } |
875 | 875 |
| 876 TEST_F(ChunkDemuxerTest, TestEndOfStreamWithNoAppend) { |
| 877 ASSERT_TRUE(InitDemuxer(true, true, false)); |
| 878 |
| 879 CheckExpectedRanges("{ }"); |
| 880 demuxer_->EndOfStream(PIPELINE_OK); |
| 881 CheckExpectedRanges("{ }"); |
| 882 } |
| 883 |
876 TEST_F(ChunkDemuxerTest, TestDecodeErrorEndOfStream) { | 884 TEST_F(ChunkDemuxerTest, TestDecodeErrorEndOfStream) { |
877 ASSERT_TRUE(InitDemuxer(true, true, false)); | 885 ASSERT_TRUE(InitDemuxer(true, true, false)); |
878 | 886 |
879 scoped_ptr<Cluster> cluster(kDefaultFirstCluster()); | 887 scoped_ptr<Cluster> cluster(kDefaultFirstCluster()); |
880 ASSERT_TRUE(AppendData(cluster->data(), cluster->size())); | 888 ASSERT_TRUE(AppendData(cluster->data(), cluster->size())); |
| 889 CheckExpectedRanges(kDefaultFirstClusterRange); |
881 | 890 |
882 EXPECT_CALL(host_, OnDemuxerError(PIPELINE_ERROR_DECODE)); | 891 EXPECT_CALL(host_, OnDemuxerError(PIPELINE_ERROR_DECODE)); |
883 demuxer_->EndOfStream(PIPELINE_ERROR_DECODE); | 892 demuxer_->EndOfStream(PIPELINE_ERROR_DECODE); |
| 893 CheckExpectedRanges(kDefaultFirstClusterRange); |
884 } | 894 } |
885 | 895 |
886 TEST_F(ChunkDemuxerTest, TestNetworkErrorEndOfStream) { | 896 TEST_F(ChunkDemuxerTest, TestNetworkErrorEndOfStream) { |
887 ASSERT_TRUE(InitDemuxer(true, true, false)); | 897 ASSERT_TRUE(InitDemuxer(true, true, false)); |
888 | 898 |
889 scoped_ptr<Cluster> cluster(kDefaultFirstCluster()); | 899 scoped_ptr<Cluster> cluster(kDefaultFirstCluster()); |
890 ASSERT_TRUE(AppendData(cluster->data(), cluster->size())); | 900 ASSERT_TRUE(AppendData(cluster->data(), cluster->size())); |
| 901 CheckExpectedRanges(kDefaultFirstClusterRange); |
891 | 902 |
892 EXPECT_CALL(host_, OnDemuxerError(PIPELINE_ERROR_NETWORK)); | 903 EXPECT_CALL(host_, OnDemuxerError(PIPELINE_ERROR_NETWORK)); |
893 demuxer_->EndOfStream(PIPELINE_ERROR_NETWORK); | 904 demuxer_->EndOfStream(PIPELINE_ERROR_NETWORK); |
894 } | 905 } |
895 | 906 |
896 // Helper class to reduce duplicate code when testing end of stream | 907 // Helper class to reduce duplicate code when testing end of stream |
897 // Read() behavior. | 908 // Read() behavior. |
898 class EndOfStreamHelper { | 909 class EndOfStreamHelper { |
899 public: | 910 public: |
900 explicit EndOfStreamHelper(const scoped_refptr<Demuxer> demuxer) | 911 explicit EndOfStreamHelper(const scoped_refptr<Demuxer> demuxer) |
(...skipping 374 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1275 std::string audio_id = "audio1"; | 1286 std::string audio_id = "audio1"; |
1276 std::string video_id = "video1"; | 1287 std::string video_id = "video1"; |
1277 ASSERT_TRUE(InitDemuxerAudioAndVideoSources(audio_id, video_id)); | 1288 ASSERT_TRUE(InitDemuxerAudioAndVideoSources(audio_id, video_id)); |
1278 | 1289 |
1279 scoped_refptr<DemuxerStream> audio = | 1290 scoped_refptr<DemuxerStream> audio = |
1280 demuxer_->GetStream(DemuxerStream::AUDIO); | 1291 demuxer_->GetStream(DemuxerStream::AUDIO); |
1281 scoped_refptr<DemuxerStream> video = | 1292 scoped_refptr<DemuxerStream> video = |
1282 demuxer_->GetStream(DemuxerStream::VIDEO); | 1293 demuxer_->GetStream(DemuxerStream::VIDEO); |
1283 | 1294 |
1284 scoped_ptr<Cluster> cluster_a( | 1295 scoped_ptr<Cluster> cluster_a( |
1285 GenerateSingleStreamCluster(0, 4, kAudioTrackNum, kAudioBlockDuration)); | 1296 GenerateSingleStreamCluster(0, 92, kAudioTrackNum, kAudioBlockDuration)); |
1286 | 1297 |
1287 scoped_ptr<Cluster> cluster_v( | 1298 scoped_ptr<Cluster> cluster_v( |
1288 GenerateSingleStreamCluster(0, 4, kVideoTrackNum, kVideoBlockDuration)); | 1299 GenerateSingleStreamCluster(0, 132, kVideoTrackNum, kVideoBlockDuration)); |
1289 | 1300 |
1290 // Append audio and video data into separate source ids. | 1301 // Append audio and video data into separate source ids. |
1291 ASSERT_TRUE(AppendData(audio_id, cluster_a->data(), cluster_a->size())); | 1302 ASSERT_TRUE(AppendData(audio_id, cluster_a->data(), cluster_a->size())); |
1292 GenerateExpectedReads(0, 4, audio, kAudioBlockDuration); | 1303 GenerateExpectedReads(0, 4, audio, kAudioBlockDuration); |
1293 ASSERT_TRUE(AppendData(video_id, cluster_v->data(), cluster_v->size())); | 1304 ASSERT_TRUE(AppendData(video_id, cluster_v->data(), cluster_v->size())); |
1294 GenerateExpectedReads(0, 4, video, kVideoBlockDuration); | 1305 GenerateExpectedReads(0, 4, video, kVideoBlockDuration); |
1295 } | 1306 } |
1296 | 1307 |
1297 TEST_F(ChunkDemuxerTest, TestAddIdFailures) { | 1308 TEST_F(ChunkDemuxerTest, TestAddIdFailures) { |
1298 EXPECT_CALL(*client_, DemuxerOpened(_)); | 1309 EXPECT_CALL(*client_, DemuxerOpened(_)); |
(...skipping 14 matching lines...) Expand all Loading... |
1313 ASSERT_EQ(AddId(video_id, false, true), ChunkDemuxer::kReachedIdLimit); | 1324 ASSERT_EQ(AddId(video_id, false, true), ChunkDemuxer::kReachedIdLimit); |
1314 } | 1325 } |
1315 | 1326 |
1316 // Test that Read() calls after a RemoveId() return "end of stream" buffers. | 1327 // Test that Read() calls after a RemoveId() return "end of stream" buffers. |
1317 TEST_F(ChunkDemuxerTest, TestRemoveId) { | 1328 TEST_F(ChunkDemuxerTest, TestRemoveId) { |
1318 std::string audio_id = "audio1"; | 1329 std::string audio_id = "audio1"; |
1319 std::string video_id = "video1"; | 1330 std::string video_id = "video1"; |
1320 ASSERT_TRUE(InitDemuxerAudioAndVideoSources(audio_id, video_id)); | 1331 ASSERT_TRUE(InitDemuxerAudioAndVideoSources(audio_id, video_id)); |
1321 | 1332 |
1322 scoped_ptr<Cluster> cluster_a( | 1333 scoped_ptr<Cluster> cluster_a( |
1323 GenerateSingleStreamCluster(0, 4, kAudioTrackNum, kAudioBlockDuration)); | 1334 GenerateSingleStreamCluster(0, 92, kAudioTrackNum, kAudioBlockDuration)); |
1324 | 1335 |
1325 scoped_ptr<Cluster> cluster_v( | 1336 scoped_ptr<Cluster> cluster_v( |
1326 GenerateSingleStreamCluster(0, 4, kVideoTrackNum, kVideoBlockDuration)); | 1337 GenerateSingleStreamCluster(0, 132, kVideoTrackNum, kVideoBlockDuration)); |
1327 | 1338 |
1328 // Append audio and video data into separate source ids. | 1339 // Append audio and video data into separate source ids. |
1329 ASSERT_TRUE(AppendData(audio_id, cluster_a->data(), cluster_a->size())); | 1340 ASSERT_TRUE(AppendData(audio_id, cluster_a->data(), cluster_a->size())); |
1330 ASSERT_TRUE(AppendData(video_id, cluster_v->data(), cluster_v->size())); | 1341 ASSERT_TRUE(AppendData(video_id, cluster_v->data(), cluster_v->size())); |
1331 | 1342 |
1332 // Read() from audio should return normal buffers. | 1343 // Read() from audio should return normal buffers. |
1333 scoped_refptr<DemuxerStream> audio = | 1344 scoped_refptr<DemuxerStream> audio = |
1334 demuxer_->GetStream(DemuxerStream::AUDIO); | 1345 demuxer_->GetStream(DemuxerStream::AUDIO); |
1335 GenerateExpectedReads(0, 4, audio, kAudioBlockDuration); | 1346 GenerateExpectedReads(0, 4, audio, kAudioBlockDuration); |
1336 | 1347 |
(...skipping 12 matching lines...) Expand all Loading... |
1349 GenerateExpectedReads(0, 4, video, kVideoBlockDuration); | 1360 GenerateExpectedReads(0, 4, video, kVideoBlockDuration); |
1350 } | 1361 } |
1351 | 1362 |
1352 // Test that Seek() successfully seeks to all source IDs. | 1363 // Test that Seek() successfully seeks to all source IDs. |
1353 TEST_F(ChunkDemuxerTest, TestSeekAudioAndVideoSources) { | 1364 TEST_F(ChunkDemuxerTest, TestSeekAudioAndVideoSources) { |
1354 std::string audio_id = "audio1"; | 1365 std::string audio_id = "audio1"; |
1355 std::string video_id = "video1"; | 1366 std::string video_id = "video1"; |
1356 ASSERT_TRUE(InitDemuxerAudioAndVideoSources(audio_id, video_id)); | 1367 ASSERT_TRUE(InitDemuxerAudioAndVideoSources(audio_id, video_id)); |
1357 | 1368 |
1358 scoped_ptr<Cluster> cluster_a1( | 1369 scoped_ptr<Cluster> cluster_a1( |
1359 GenerateSingleStreamCluster(0, 4, kAudioTrackNum, kAudioBlockDuration)); | 1370 GenerateSingleStreamCluster(0, 92, kAudioTrackNum, kAudioBlockDuration)); |
1360 | 1371 |
1361 scoped_ptr<Cluster> cluster_v1( | 1372 scoped_ptr<Cluster> cluster_v1( |
1362 GenerateSingleStreamCluster(0, 4, kVideoTrackNum, kVideoBlockDuration)); | 1373 GenerateSingleStreamCluster(0, 132, kVideoTrackNum, kVideoBlockDuration)); |
1363 | 1374 |
1364 ASSERT_TRUE(AppendData(audio_id, cluster_a1->data(), cluster_a1->size())); | 1375 ASSERT_TRUE(AppendData(audio_id, cluster_a1->data(), cluster_a1->size())); |
1365 ASSERT_TRUE(AppendData(video_id, cluster_v1->data(), cluster_v1->size())); | 1376 ASSERT_TRUE(AppendData(video_id, cluster_v1->data(), cluster_v1->size())); |
1366 | 1377 |
1367 // Read() should return buffers at 0. | 1378 // Read() should return buffers at 0. |
1368 bool audio_read_done = false; | 1379 bool audio_read_done = false; |
1369 bool video_read_done = false; | 1380 bool video_read_done = false; |
1370 scoped_refptr<DemuxerStream> audio = | 1381 scoped_refptr<DemuxerStream> audio = |
1371 demuxer_->GetStream(DemuxerStream::AUDIO); | 1382 demuxer_->GetStream(DemuxerStream::AUDIO); |
1372 scoped_refptr<DemuxerStream> video = | 1383 scoped_refptr<DemuxerStream> video = |
(...skipping 20 matching lines...) Expand all Loading... |
1393 &audio_read_done)); | 1404 &audio_read_done)); |
1394 video->Read(base::Bind(&OnReadDone, | 1405 video->Read(base::Bind(&OnReadDone, |
1395 base::TimeDelta::FromSeconds(3), | 1406 base::TimeDelta::FromSeconds(3), |
1396 &video_read_done)); | 1407 &video_read_done)); |
1397 | 1408 |
1398 // Read()s should not return until after data is appended at the Seek point. | 1409 // Read()s should not return until after data is appended at the Seek point. |
1399 EXPECT_FALSE(audio_read_done); | 1410 EXPECT_FALSE(audio_read_done); |
1400 EXPECT_FALSE(video_read_done); | 1411 EXPECT_FALSE(video_read_done); |
1401 | 1412 |
1402 scoped_ptr<Cluster> cluster_a2( | 1413 scoped_ptr<Cluster> cluster_a2( |
1403 GenerateSingleStreamCluster(3000, 4, kAudioTrackNum, | 1414 GenerateSingleStreamCluster(3000, 3092, kAudioTrackNum, |
1404 kAudioBlockDuration)); | 1415 kAudioBlockDuration)); |
1405 | 1416 |
1406 scoped_ptr<Cluster> cluster_v2( | 1417 scoped_ptr<Cluster> cluster_v2( |
1407 GenerateSingleStreamCluster(3000, 4, kVideoTrackNum, | 1418 GenerateSingleStreamCluster(3000, 3132, kVideoTrackNum, |
1408 kVideoBlockDuration)); | 1419 kVideoBlockDuration)); |
1409 | 1420 |
1410 ASSERT_TRUE(AppendData(audio_id, cluster_a2->data(), cluster_a2->size())); | 1421 ASSERT_TRUE(AppendData(audio_id, cluster_a2->data(), cluster_a2->size())); |
1411 ASSERT_TRUE(AppendData(video_id, cluster_v2->data(), cluster_v2->size())); | 1422 ASSERT_TRUE(AppendData(video_id, cluster_v2->data(), cluster_v2->size())); |
1412 | 1423 |
1413 // Read() should return buffers at 3. | 1424 // Read() should return buffers at 3. |
1414 EXPECT_TRUE(audio_read_done); | 1425 EXPECT_TRUE(audio_read_done); |
1415 EXPECT_TRUE(video_read_done); | 1426 EXPECT_TRUE(video_read_done); |
1416 } | 1427 } |
1417 | 1428 |
1418 // Test ranges in an audio-only stream. | 1429 // Test ranges in an audio-only stream. |
1419 TEST_F(ChunkDemuxerTest, GetBufferedRanges_AudioIdOnly) { | 1430 TEST_F(ChunkDemuxerTest, GetBufferedRanges_AudioIdOnly) { |
1420 EXPECT_CALL(*client_, DemuxerOpened(_)); | 1431 EXPECT_CALL(*client_, DemuxerOpened(_)); |
1421 demuxer_->Initialize( | 1432 demuxer_->Initialize( |
1422 &host_, CreateInitDoneCB(kDefaultDuration(), PIPELINE_OK)); | 1433 &host_, CreateInitDoneCB(kDefaultDuration(), PIPELINE_OK)); |
1423 | 1434 |
1424 ASSERT_EQ(AddId(kSourceId, true, false), ChunkDemuxer::kOk); | 1435 ASSERT_EQ(AddId(kSourceId, true, false), ChunkDemuxer::kOk); |
1425 ASSERT_TRUE(AppendInitSegment(true, false, false)); | 1436 ASSERT_TRUE(AppendInitSegment(true, false, false)); |
1426 | 1437 |
1427 // Test a simple cluster. | 1438 // Test a simple cluster. |
1428 scoped_ptr<Cluster> cluster_1(GenerateSingleStreamCluster(0, 4, | 1439 scoped_ptr<Cluster> cluster_1(GenerateSingleStreamCluster(0, 92, |
1429 kAudioTrackNum, kAudioBlockDuration)); | 1440 kAudioTrackNum, kAudioBlockDuration)); |
1430 ChunkDemuxer::Ranges expected; | |
1431 expected.push_back(CreateRange(0, 4, kAudioBlockDuration)); | |
1432 | |
1433 ASSERT_TRUE(AppendData(cluster_1->data(), cluster_1->size())); | 1441 ASSERT_TRUE(AppendData(cluster_1->data(), cluster_1->size())); |
1434 | 1442 |
1435 CheckExpectedRanges(expected); | 1443 CheckExpectedRanges("{ [0,92) }"); |
1436 | 1444 |
1437 // Append a disjoint cluster to check for two separate ranges. | 1445 // Append a disjoint cluster to check for two separate ranges. |
1438 scoped_ptr<Cluster> cluster_2(GenerateSingleStreamCluster(150, 3, | 1446 scoped_ptr<Cluster> cluster_2(GenerateSingleStreamCluster(150, 219, |
1439 kAudioTrackNum, kAudioBlockDuration)); | 1447 kAudioTrackNum, kAudioBlockDuration)); |
1440 expected.push_back(CreateRange(150, 3, kAudioBlockDuration)); | |
1441 | 1448 |
1442 ASSERT_TRUE(AppendData(cluster_2->data(), cluster_2->size())); | 1449 ASSERT_TRUE(AppendData(cluster_2->data(), cluster_2->size())); |
1443 | 1450 |
1444 CheckExpectedRanges(expected); | 1451 CheckExpectedRanges("{ [0,92) [150,219) }"); |
1445 } | 1452 } |
1446 | 1453 |
1447 // Test ranges in a video-only stream. | 1454 // Test ranges in a video-only stream. |
1448 TEST_F(ChunkDemuxerTest, GetBufferedRanges_VideoIdOnly) { | 1455 TEST_F(ChunkDemuxerTest, GetBufferedRanges_VideoIdOnly) { |
1449 EXPECT_CALL(*client_, DemuxerOpened(_)); | 1456 EXPECT_CALL(*client_, DemuxerOpened(_)); |
1450 demuxer_->Initialize( | 1457 demuxer_->Initialize( |
1451 &host_, CreateInitDoneCB(kDefaultDuration(), PIPELINE_OK)); | 1458 &host_, CreateInitDoneCB(kDefaultDuration(), PIPELINE_OK)); |
1452 | 1459 |
1453 ASSERT_EQ(AddId(kSourceId, false, true), ChunkDemuxer::kOk); | 1460 ASSERT_EQ(AddId(kSourceId, false, true), ChunkDemuxer::kOk); |
1454 ASSERT_TRUE(AppendInitSegment(false, true, false)); | 1461 ASSERT_TRUE(AppendInitSegment(false, true, false)); |
1455 | 1462 |
1456 // Test a simple cluster. | 1463 // Test a simple cluster. |
1457 scoped_ptr<Cluster> cluster_1(GenerateSingleStreamCluster(0, 4, | 1464 scoped_ptr<Cluster> cluster_1(GenerateSingleStreamCluster(0, 132, |
1458 kVideoTrackNum, kVideoBlockDuration)); | 1465 kVideoTrackNum, kVideoBlockDuration)); |
1459 ChunkDemuxer::Ranges expected; | |
1460 expected.push_back(CreateRange(0, 4, kVideoBlockDuration)); | |
1461 | 1466 |
1462 ASSERT_TRUE(AppendData(cluster_1->data(), cluster_1->size())); | 1467 ASSERT_TRUE(AppendData(cluster_1->data(), cluster_1->size())); |
1463 | 1468 |
1464 CheckExpectedRanges(expected); | 1469 CheckExpectedRanges("{ [0,132) }"); |
1465 | 1470 |
1466 // Append a disjoint cluster to check for two separate ranges. | 1471 // Append a disjoint cluster to check for two separate ranges. |
1467 scoped_ptr<Cluster> cluster_2(GenerateSingleStreamCluster(150, 3, | 1472 scoped_ptr<Cluster> cluster_2(GenerateSingleStreamCluster(150, 249, |
1468 kVideoTrackNum, kVideoBlockDuration)); | 1473 kVideoTrackNum, kVideoBlockDuration)); |
1469 expected.push_back(CreateRange(150, 3, kVideoBlockDuration)); | |
1470 | 1474 |
1471 ASSERT_TRUE(AppendData(cluster_2->data(), cluster_2->size())); | 1475 ASSERT_TRUE(AppendData(cluster_2->data(), cluster_2->size())); |
1472 | 1476 |
1473 CheckExpectedRanges(expected); | 1477 CheckExpectedRanges("{ [0,132) [150,249) }"); |
1474 } | 1478 } |
1475 | 1479 |
1476 TEST_F(ChunkDemuxerTest, GetBufferedRanges_AudioVideo) { | 1480 TEST_F(ChunkDemuxerTest, GetBufferedRanges_AudioVideo) { |
1477 ASSERT_TRUE(InitDemuxer(true, true, false)); | 1481 ASSERT_TRUE(InitDemuxer(true, true, false)); |
1478 | 1482 |
1479 // Audio: 0 -> 23 | 1483 // Audio: 0 -> 23 |
1480 // Video: 0 -> 33 | 1484 // Video: 0 -> 33 |
1481 // Buffered Range: 0 -> 23 | 1485 // Buffered Range: 0 -> 23 |
1482 // Audio block duration is smaller than video block duration, | 1486 // Audio block duration is smaller than video block duration, |
1483 // so the buffered ranges should correspond to the audio blocks. | 1487 // so the buffered ranges should correspond to the audio blocks. |
1484 scoped_ptr<Cluster> cluster_a0( | 1488 scoped_ptr<Cluster> cluster_a0( |
1485 GenerateSingleStreamCluster(0, 1, kAudioTrackNum, kAudioBlockDuration)); | 1489 GenerateSingleStreamCluster(0, kAudioBlockDuration, kAudioTrackNum, |
| 1490 kAudioBlockDuration)); |
1486 | 1491 |
1487 scoped_ptr<Cluster> cluster_v0( | 1492 scoped_ptr<Cluster> cluster_v0( |
1488 GenerateSingleStreamCluster(0, 1, kVideoTrackNum, kVideoBlockDuration)); | 1493 GenerateSingleStreamCluster(0, kVideoBlockDuration, kVideoTrackNum, |
1489 | 1494 kVideoBlockDuration)); |
1490 ChunkDemuxer::Ranges expected; | |
1491 expected.push_back(CreateRange(0, 1, kAudioBlockDuration)); | |
1492 | 1495 |
1493 ASSERT_TRUE(AppendData(cluster_a0->data(), cluster_a0->size())); | 1496 ASSERT_TRUE(AppendData(cluster_a0->data(), cluster_a0->size())); |
1494 ASSERT_TRUE(AppendData(cluster_v0->data(), cluster_v0->size())); | 1497 ASSERT_TRUE(AppendData(cluster_v0->data(), cluster_v0->size())); |
1495 | 1498 |
1496 CheckExpectedRanges(expected); | 1499 CheckExpectedRanges("{ [0,23) }"); |
1497 | 1500 |
1498 // Audio: 100 -> 150 | 1501 // Audio: 100 -> 150 |
1499 // Video: 120 -> 170 | 1502 // Video: 120 -> 170 |
1500 // Buffered Range: 120 -> 150 (end overlap) | 1503 // Buffered Range: 120 -> 150 (end overlap) |
1501 scoped_ptr<Cluster> cluster_a1( | 1504 scoped_ptr<Cluster> cluster_a1( |
1502 GenerateSingleStreamCluster(100, 1, kAudioTrackNum, 50)); | 1505 GenerateSingleStreamCluster(100, 150, kAudioTrackNum, 50)); |
1503 | 1506 |
1504 scoped_ptr<Cluster> cluster_v1( | 1507 scoped_ptr<Cluster> cluster_v1( |
1505 GenerateSingleStreamCluster(120, 1, kVideoTrackNum, 50)); | 1508 GenerateSingleStreamCluster(120, 170, kVideoTrackNum, 50)); |
1506 | |
1507 expected.push_back(CreateRange(120, 1, 30)); | |
1508 | 1509 |
1509 ASSERT_TRUE(AppendData(cluster_a1->data(), cluster_a1->size())); | 1510 ASSERT_TRUE(AppendData(cluster_a1->data(), cluster_a1->size())); |
1510 ASSERT_TRUE(AppendData(cluster_v1->data(), cluster_v1->size())); | 1511 ASSERT_TRUE(AppendData(cluster_v1->data(), cluster_v1->size())); |
1511 | 1512 |
1512 CheckExpectedRanges(expected); | 1513 CheckExpectedRanges("{ [0,23) [120,150) }"); |
1513 | 1514 |
1514 // Audio: 220 -> 290 | 1515 // Audio: 220 -> 290 |
1515 // Video: 200 -> 270 | 1516 // Video: 200 -> 270 |
1516 // Buffered Range: 220 -> 270 (front overlap) | 1517 // Buffered Range: 220 -> 270 (front overlap) |
1517 scoped_ptr<Cluster> cluster_a2( | 1518 scoped_ptr<Cluster> cluster_a2( |
1518 GenerateSingleStreamCluster(220, 1, kAudioTrackNum, 70)); | 1519 GenerateSingleStreamCluster(220, 290, kAudioTrackNum, 70)); |
1519 | 1520 |
1520 scoped_ptr<Cluster> cluster_v2( | 1521 scoped_ptr<Cluster> cluster_v2( |
1521 GenerateSingleStreamCluster(200, 1, kVideoTrackNum, 70)); | 1522 GenerateSingleStreamCluster(200, 270, kVideoTrackNum, 70)); |
1522 | |
1523 expected.push_back(CreateRange(220, 1, 50)); | |
1524 | 1523 |
1525 ASSERT_TRUE(AppendData(cluster_a2->data(), cluster_a2->size())); | 1524 ASSERT_TRUE(AppendData(cluster_a2->data(), cluster_a2->size())); |
1526 ASSERT_TRUE(AppendData(cluster_v2->data(), cluster_v2->size())); | 1525 ASSERT_TRUE(AppendData(cluster_v2->data(), cluster_v2->size())); |
1527 | 1526 |
1528 CheckExpectedRanges(expected); | 1527 CheckExpectedRanges("{ [0,23) [120,150) [220,270) }"); |
1529 | 1528 |
1530 // Audio: 320 -> 350 | 1529 // Audio: 320 -> 350 |
1531 // Video: 300 -> 370 | 1530 // Video: 300 -> 370 |
1532 // Buffered Range: 320 -> 350 (complete overlap, audio) | 1531 // Buffered Range: 320 -> 350 (complete overlap, audio) |
1533 scoped_ptr<Cluster> cluster_a3( | 1532 scoped_ptr<Cluster> cluster_a3( |
1534 GenerateSingleStreamCluster(320, 1, kAudioTrackNum, 30)); | 1533 GenerateSingleStreamCluster(320, 350, kAudioTrackNum, 30)); |
1535 | 1534 |
1536 scoped_ptr<Cluster> cluster_v3( | 1535 scoped_ptr<Cluster> cluster_v3( |
1537 GenerateSingleStreamCluster(300, 1, kVideoTrackNum, 70)); | 1536 GenerateSingleStreamCluster(300, 370, kVideoTrackNum, 70)); |
1538 | |
1539 expected.push_back(CreateRange(320, 1, 30)); | |
1540 | 1537 |
1541 ASSERT_TRUE(AppendData(cluster_a3->data(), cluster_a3->size())); | 1538 ASSERT_TRUE(AppendData(cluster_a3->data(), cluster_a3->size())); |
1542 ASSERT_TRUE(AppendData(cluster_v3->data(), cluster_v3->size())); | 1539 ASSERT_TRUE(AppendData(cluster_v3->data(), cluster_v3->size())); |
1543 | 1540 |
1544 CheckExpectedRanges(expected); | 1541 CheckExpectedRanges("{ [0,23) [120,150) [220,270) [320,350) }"); |
1545 | 1542 |
1546 // Audio: 400 -> 470 | 1543 // Audio: 400 -> 470 |
1547 // Video: 420 -> 450 | 1544 // Video: 420 -> 450 |
1548 // Buffered Range: 420 -> 450 (complete overlap, video) | 1545 // Buffered Range: 420 -> 450 (complete overlap, video) |
1549 scoped_ptr<Cluster> cluster_a4( | 1546 scoped_ptr<Cluster> cluster_a4( |
1550 GenerateSingleStreamCluster(400, 1, kAudioTrackNum, 70)); | 1547 GenerateSingleStreamCluster(400, 470, kAudioTrackNum, 70)); |
1551 | 1548 |
1552 scoped_ptr<Cluster> cluster_v4( | 1549 scoped_ptr<Cluster> cluster_v4( |
1553 GenerateSingleStreamCluster(420, 1, kVideoTrackNum, 30)); | 1550 GenerateSingleStreamCluster(420, 450, kVideoTrackNum, 30)); |
1554 | |
1555 expected.push_back(CreateRange(420, 1, 30)); | |
1556 | 1551 |
1557 ASSERT_TRUE(AppendData(cluster_a4->data(), cluster_a4->size())); | 1552 ASSERT_TRUE(AppendData(cluster_a4->data(), cluster_a4->size())); |
1558 ASSERT_TRUE(AppendData(cluster_v4->data(), cluster_v4->size())); | 1553 ASSERT_TRUE(AppendData(cluster_v4->data(), cluster_v4->size())); |
1559 | 1554 |
1560 CheckExpectedRanges(expected); | 1555 CheckExpectedRanges("{ [0,23) [120,150) [220,270) [320,350) [420,450) }"); |
1561 | 1556 |
1562 // Appending within buffered range should not affect buffered ranges. | 1557 // Appending within buffered range should not affect buffered ranges. |
1563 scoped_ptr<Cluster> cluster_a5( | 1558 scoped_ptr<Cluster> cluster_a5( |
1564 GenerateSingleStreamCluster(430, 1, kAudioTrackNum, 20)); | 1559 GenerateSingleStreamCluster(430, 450, kAudioTrackNum, 20)); |
1565 ASSERT_TRUE(AppendData(cluster_a5->data(), cluster_a5->size())); | 1560 ASSERT_TRUE(AppendData(cluster_a5->data(), cluster_a5->size())); |
1566 CheckExpectedRanges(expected); | 1561 CheckExpectedRanges("{ [0,23) [120,150) [220,270) [320,350) [420,450) }"); |
1567 | 1562 |
1568 // Appending to single stream outside buffered ranges should not affect | 1563 // Appending to single stream outside buffered ranges should not affect |
1569 // buffered ranges. | 1564 // buffered ranges. |
1570 scoped_ptr<Cluster> cluster_v5( | 1565 scoped_ptr<Cluster> cluster_v5( |
1571 GenerateSingleStreamCluster(530, 1, kVideoTrackNum, 10)); | 1566 GenerateSingleStreamCluster(530, 540, kVideoTrackNum, 10)); |
1572 ASSERT_TRUE(AppendData(cluster_v5->data(), cluster_v5->size())); | 1567 ASSERT_TRUE(AppendData(cluster_v5->data(), cluster_v5->size())); |
1573 CheckExpectedRanges(expected); | 1568 CheckExpectedRanges("{ [0,23) [120,150) [220,270) [320,350) [420,450) }"); |
1574 } | 1569 } |
1575 | 1570 |
1576 // Once EndOfStream() is called, GetBufferedRanges should not cut off any | 1571 // Once EndOfStream() is called, GetBufferedRanges should not cut off any |
1577 // over-hanging tails at the end of the ranges as this is likely due to block | 1572 // over-hanging tails at the end of the ranges as this is likely due to block |
1578 // duration differences. | 1573 // duration differences. |
1579 TEST_F(ChunkDemuxerTest, GetBufferedRanges_EndOfStream) { | 1574 TEST_F(ChunkDemuxerTest, GetBufferedRanges_EndOfStream) { |
1580 ASSERT_TRUE(InitDemuxer(true, true, false)); | 1575 ASSERT_TRUE(InitDemuxer(true, true, false)); |
1581 | 1576 |
1582 scoped_ptr<Cluster> cluster_a( | 1577 scoped_ptr<Cluster> cluster_a( |
1583 GenerateSingleStreamCluster(0, 1, kAudioTrackNum, 90)); | 1578 GenerateSingleStreamCluster(0, 90, kAudioTrackNum, 90)); |
1584 scoped_ptr<Cluster> cluster_v( | 1579 scoped_ptr<Cluster> cluster_v( |
1585 GenerateSingleStreamCluster(0, 1, kVideoTrackNum, 100)); | 1580 GenerateSingleStreamCluster(0, 100, kVideoTrackNum, 100)); |
1586 ChunkDemuxer::Ranges expected; | |
1587 expected.push_back(CreateRange(0, 1, 100)); | |
1588 | 1581 |
1589 ASSERT_TRUE(AppendData(cluster_a->data(), cluster_a->size())); | 1582 ASSERT_TRUE(AppendData(cluster_a->data(), cluster_a->size())); |
1590 ASSERT_TRUE(AppendData(cluster_v->data(), cluster_v->size())); | 1583 ASSERT_TRUE(AppendData(cluster_v->data(), cluster_v->size())); |
1591 | 1584 |
| 1585 CheckExpectedRanges("{ [0,90) }"); |
| 1586 |
1592 demuxer_->EndOfStream(PIPELINE_OK); | 1587 demuxer_->EndOfStream(PIPELINE_OK); |
1593 CheckExpectedRanges(expected); | 1588 |
| 1589 CheckExpectedRanges("{ [0,100) }"); |
1594 } | 1590 } |
1595 | 1591 |
1596 TEST_F(ChunkDemuxerTest, TestDifferentStreamTimecodes) { | 1592 TEST_F(ChunkDemuxerTest, TestDifferentStreamTimecodes) { |
1597 ASSERT_TRUE(InitDemuxer(true, true, false)); | 1593 ASSERT_TRUE(InitDemuxer(true, true, false)); |
1598 | 1594 |
1599 scoped_refptr<DemuxerStream> audio = | 1595 scoped_refptr<DemuxerStream> audio = |
1600 demuxer_->GetStream(DemuxerStream::AUDIO); | 1596 demuxer_->GetStream(DemuxerStream::AUDIO); |
1601 scoped_refptr<DemuxerStream> video = | 1597 scoped_refptr<DemuxerStream> video = |
1602 demuxer_->GetStream(DemuxerStream::VIDEO); | 1598 demuxer_->GetStream(DemuxerStream::VIDEO); |
1603 | 1599 |
(...skipping 21 matching lines...) Expand all Loading... |
1625 | 1621 |
1626 TEST_F(ChunkDemuxerTest, TestCodecPrefixMatching) { | 1622 TEST_F(ChunkDemuxerTest, TestCodecPrefixMatching) { |
1627 std::vector<std::string> codecs; | 1623 std::vector<std::string> codecs; |
1628 codecs.push_back("avc1.4D4041"); | 1624 codecs.push_back("avc1.4D4041"); |
1629 codecs.push_back("mp4a.40.2"); | 1625 codecs.push_back("mp4a.40.2"); |
1630 | 1626 |
1631 EXPECT_EQ(ChunkDemuxer::kOk, | 1627 EXPECT_EQ(ChunkDemuxer::kOk, |
1632 demuxer_->AddId("source_id", "video/mp4", codecs)); | 1628 demuxer_->AddId("source_id", "video/mp4", codecs)); |
1633 } | 1629 } |
1634 | 1630 |
| 1631 TEST_F(ChunkDemuxerTest, TestEndOfStreamFailures) { |
| 1632 std::string audio_id = "audio"; |
| 1633 std::string video_id = "video"; |
| 1634 |
| 1635 ASSERT_TRUE(InitDemuxerAudioAndVideoSources(audio_id, video_id)); |
| 1636 |
| 1637 scoped_ptr<Cluster> cluster_a1( |
| 1638 GenerateSingleStreamCluster(0, 15, kAudioTrackNum, 15)); |
| 1639 scoped_ptr<Cluster> cluster_v1( |
| 1640 GenerateSingleStreamCluster(0, 5, kVideoTrackNum, 5)); |
| 1641 scoped_ptr<Cluster> cluster_v2( |
| 1642 GenerateSingleStreamCluster(5, 10, kVideoTrackNum, 5)); |
| 1643 scoped_ptr<Cluster> cluster_v3( |
| 1644 GenerateSingleStreamCluster(10, 20, kVideoTrackNum, 10)); |
| 1645 |
| 1646 ASSERT_TRUE(AppendData(audio_id, cluster_a1->data(), cluster_a1->size())); |
| 1647 ASSERT_TRUE(AppendData(video_id, cluster_v1->data(), cluster_v1->size())); |
| 1648 ASSERT_TRUE(AppendData(video_id, cluster_v3->data(), cluster_v3->size())); |
| 1649 |
| 1650 CheckExpectedRanges(audio_id, "{ [0,15) }"); |
| 1651 CheckExpectedRanges(video_id, "{ [0,5) [10,20) }"); |
| 1652 |
| 1653 // Make sure that end of stream fails because there is a gap between |
| 1654 // the current position(0) and the end of the appended data. |
| 1655 ASSERT_FALSE(demuxer_->EndOfStream(PIPELINE_OK)); |
| 1656 |
| 1657 // Seek to an time that is inside the last ranges for both streams |
| 1658 // and verify that the EndOfStream() is successful. |
| 1659 demuxer_->StartWaitingForSeek(); |
| 1660 demuxer_->Seek(base::TimeDelta::FromMilliseconds(10), |
| 1661 NewExpectedStatusCB(PIPELINE_OK)); |
| 1662 |
| 1663 ASSERT_TRUE(demuxer_->EndOfStream(PIPELINE_OK)); |
| 1664 |
| 1665 // Seek back to 0 and verify that EndOfStream() fails again. |
| 1666 demuxer_->StartWaitingForSeek(); |
| 1667 demuxer_->Seek(base::TimeDelta::FromMilliseconds(0), |
| 1668 NewExpectedStatusCB(PIPELINE_OK)); |
| 1669 |
| 1670 ASSERT_FALSE(demuxer_->EndOfStream(PIPELINE_OK)); |
| 1671 |
| 1672 // Append the missing range and verify that EndOfStream() succeeds now. |
| 1673 ASSERT_TRUE(AppendData(video_id, cluster_v2->data(), cluster_v2->size())); |
| 1674 |
| 1675 CheckExpectedRanges(audio_id, "{ [0,15) }"); |
| 1676 CheckExpectedRanges(video_id, "{ [0,20) }"); |
| 1677 |
| 1678 ASSERT_TRUE(demuxer_->EndOfStream(PIPELINE_OK)); |
| 1679 } |
| 1680 |
1635 } // namespace media | 1681 } // namespace media |
OLD | NEW |