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 <algorithm> | 5 #include <algorithm> |
6 | 6 |
7 #include "base/bind.h" | 7 #include "base/bind.h" |
8 #include "base/message_loop/message_loop.h" | 8 #include "base/message_loop/message_loop.h" |
9 #include "base/strings/string_number_conversions.h" | 9 #include "base/strings/string_number_conversions.h" |
10 #include "base/strings/string_split.h" | 10 #include "base/strings/string_split.h" |
(...skipping 379 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
390 block_duration = kTextBlockDuration; | 390 block_duration = kTextBlockDuration; |
391 break; | 391 break; |
392 } | 392 } |
393 ASSERT_NE(block_duration, 0); | 393 ASSERT_NE(block_duration, 0); |
394 int end_timecode = timecode + block_count * block_duration; | 394 int end_timecode = timecode + block_count * block_duration; |
395 AppendCluster(source_id, | 395 AppendCluster(source_id, |
396 GenerateSingleStreamCluster( | 396 GenerateSingleStreamCluster( |
397 timecode, end_timecode, track_number, block_duration)); | 397 timecode, end_timecode, track_number, block_duration)); |
398 } | 398 } |
399 | 399 |
400 // |cluster_description| - A space delimited string of buffer info that | 400 struct BlockInfo { |
401 // is used to construct a cluster. Each buffer info is a timestamp in | 401 BlockInfo() |
402 // milliseconds and optionally followed by a 'K' to indicate that a buffer | 402 : track_number(0), |
403 // should be marked as a keyframe. For example "0K 30 60" should constuct | 403 timestamp_in_ms(0), |
404 // a cluster with 3 blocks: a keyframe with timestamp 0 and 2 non-keyframes | 404 flags(0), |
405 // at 30ms and 60ms. | 405 duration(0) { |
406 void AppendSingleStreamCluster(const std::string& source_id, int track_number, | 406 } |
407 const std::string& cluster_description) { | 407 |
| 408 BlockInfo(int tn, int ts, int f, int d) |
| 409 : track_number(tn), |
| 410 timestamp_in_ms(ts), |
| 411 flags(f), |
| 412 duration(d) { |
| 413 } |
| 414 |
| 415 int track_number; |
| 416 int timestamp_in_ms; |
| 417 int flags; |
| 418 int duration; |
| 419 |
| 420 bool operator< (const BlockInfo& rhs) const { |
| 421 return timestamp_in_ms < rhs.timestamp_in_ms; |
| 422 } |
| 423 }; |
| 424 |
| 425 // |track_number| - The track number to place in |
| 426 // |block_descriptions| - A space delimited string of block info that |
| 427 // is used to populate |blocks|. Each block info has a timestamp in |
| 428 // milliseconds and optionally followed by a 'K' to indicate that a block |
| 429 // should be marked as a keyframe. For example "0K 30 60" should populate |
| 430 // |blocks| with 3 BlockInfo objects: a keyframe with timestamp 0 and 2 |
| 431 // non-keyframes at 30ms and 60ms. |
| 432 void ParseBlockDescriptions(int track_number, |
| 433 const std::string block_descriptions, |
| 434 std::vector<BlockInfo>* blocks) { |
408 std::vector<std::string> timestamps; | 435 std::vector<std::string> timestamps; |
409 base::SplitString(cluster_description, ' ', ×tamps); | 436 base::SplitString(block_descriptions, ' ', ×tamps); |
410 | 437 |
411 ClusterBuilder cb; | |
412 std::vector<uint8> data(10); | |
413 for (size_t i = 0; i < timestamps.size(); ++i) { | 438 for (size_t i = 0; i < timestamps.size(); ++i) { |
414 std::string timestamp_str = timestamps[i]; | 439 std::string timestamp_str = timestamps[i]; |
415 int block_flags = 0; | 440 BlockInfo block_info; |
| 441 block_info.track_number = track_number; |
| 442 block_info.flags = 0; |
| 443 block_info.duration = 0; |
| 444 |
416 if (EndsWith(timestamp_str, "K", true)) { | 445 if (EndsWith(timestamp_str, "K", true)) { |
417 block_flags = kWebMFlagKeyframe; | 446 block_info.flags = kWebMFlagKeyframe; |
418 // Remove the "K" off of the token. | 447 // Remove the "K" off of the token. |
419 timestamp_str = timestamp_str.substr(0, timestamps[i].length() - 1); | 448 timestamp_str = timestamp_str.substr(0, timestamps[i].length() - 1); |
420 } | 449 } |
421 int timestamp_in_ms; | 450 CHECK(base::StringToInt(timestamp_str, &block_info.timestamp_in_ms)); |
422 CHECK(base::StringToInt(timestamp_str, ×tamp_in_ms)); | |
423 | |
424 if (i == 0) | |
425 cb.SetClusterTimecode(timestamp_in_ms); | |
426 | 451 |
427 if (track_number == kTextTrackNum || | 452 if (track_number == kTextTrackNum || |
428 track_number == kAlternateTextTrackNum) { | 453 track_number == kAlternateTextTrackNum) { |
429 cb.AddBlockGroup(track_number, timestamp_in_ms, kTextBlockDuration, | 454 block_info.duration = kTextBlockDuration; |
430 block_flags, &data[0], data.size()); | 455 ASSERT_EQ(kWebMFlagKeyframe, block_info.flags) |
| 456 << "Text block with timestamp " << block_info.timestamp_in_ms |
| 457 << " was not marked as a keyframe." |
| 458 << " All text blocks must be keyframes"; |
| 459 } |
| 460 |
| 461 blocks->push_back(block_info); |
| 462 } |
| 463 } |
| 464 |
| 465 scoped_ptr<Cluster> GenerateCluster(const std::vector<BlockInfo>& blocks, |
| 466 bool unknown_size) { |
| 467 DCHECK_GT(blocks.size(), 0u); |
| 468 ClusterBuilder cb; |
| 469 |
| 470 std::vector<uint8> data(10); |
| 471 for (size_t i = 0; i < blocks.size(); ++i) { |
| 472 if (i == 0) |
| 473 cb.SetClusterTimecode(blocks[i].timestamp_in_ms); |
| 474 |
| 475 if (blocks[i].duration) { |
| 476 if (blocks[i].track_number == kVideoTrackNum) { |
| 477 AddVideoBlockGroup(&cb, |
| 478 blocks[i].track_number, blocks[i].timestamp_in_ms, |
| 479 blocks[i].duration, blocks[i].flags); |
| 480 } else { |
| 481 cb.AddBlockGroup(blocks[i].track_number, blocks[i].timestamp_in_ms, |
| 482 blocks[i].duration, blocks[i].flags, |
| 483 &data[0], data.size()); |
| 484 } |
431 } else { | 485 } else { |
432 cb.AddSimpleBlock(track_number, timestamp_in_ms, block_flags, | 486 cb.AddSimpleBlock(blocks[i].track_number, blocks[i].timestamp_in_ms, |
| 487 blocks[i].flags, |
433 &data[0], data.size()); | 488 &data[0], data.size()); |
434 } | 489 } |
435 } | 490 } |
436 AppendCluster(source_id, cb.Finish()); | 491 |
| 492 return unknown_size ? cb.FinishWithUnknownSize() : cb.Finish(); |
| 493 } |
| 494 |
| 495 scoped_ptr<Cluster> GenerateCluster( |
| 496 std::priority_queue<BlockInfo> block_queue, |
| 497 bool unknown_size) { |
| 498 std::vector<BlockInfo> blocks(block_queue.size()); |
| 499 for (size_t i = block_queue.size() - 1; !block_queue.empty(); --i) { |
| 500 blocks[i] = block_queue.top(); |
| 501 block_queue.pop(); |
| 502 } |
| 503 |
| 504 return GenerateCluster(blocks, unknown_size); |
| 505 } |
| 506 |
| 507 // |block_descriptions| - The block descriptions used to construct the |
| 508 // cluster. See the documentation for ParseBlockDescriptions() for details on |
| 509 // the string format. |
| 510 void AppendSingleStreamCluster(const std::string& source_id, int track_number, |
| 511 const std::string& block_descriptions) { |
| 512 std::vector<BlockInfo> blocks; |
| 513 ParseBlockDescriptions(track_number, block_descriptions, &blocks); |
| 514 AppendCluster(source_id, GenerateCluster(blocks, false)); |
437 } | 515 } |
438 | 516 |
439 struct MuxedStreamInfo { | 517 struct MuxedStreamInfo { |
440 MuxedStreamInfo() | 518 MuxedStreamInfo() |
441 : track_number(0), | 519 : track_number(0), |
442 cluster_description("") | 520 block_descriptions("") |
443 {} | 521 {} |
444 | 522 |
445 MuxedStreamInfo(int track_num, const char* cluster_desc) | 523 MuxedStreamInfo(int track_num, const char* block_desc) |
446 : track_number(track_num), | 524 : track_number(track_num), |
447 cluster_description(cluster_desc) { | 525 block_descriptions(block_desc) { |
448 } | 526 } |
449 | 527 |
450 int track_number; | 528 int track_number; |
451 // The cluster description passed to AppendSingleStreamCluster(). | 529 // The block description passed to ParseBlockDescriptions(). |
452 // See the documentation for that method for details on the string format. | 530 // See the documentation for that method for details on the string format. |
453 const char* cluster_description; | 531 const char* block_descriptions; |
454 }; | 532 }; |
455 | 533 |
456 void AppendMuxedCluster(const MuxedStreamInfo& msi_1, | 534 void AppendMuxedCluster(const MuxedStreamInfo& msi_1, |
457 const MuxedStreamInfo& msi_2) { | 535 const MuxedStreamInfo& msi_2) { |
458 std::vector<MuxedStreamInfo> msi(2); | 536 std::vector<MuxedStreamInfo> msi(2); |
459 msi[0] = msi_1; | 537 msi[0] = msi_1; |
460 msi[1] = msi_2; | 538 msi[1] = msi_2; |
461 AppendMuxedCluster(msi); | 539 AppendMuxedCluster(msi); |
462 } | 540 } |
463 | 541 |
464 void AppendMuxedCluster(const MuxedStreamInfo& msi_1, | 542 void AppendMuxedCluster(const MuxedStreamInfo& msi_1, |
465 const MuxedStreamInfo& msi_2, | 543 const MuxedStreamInfo& msi_2, |
466 const MuxedStreamInfo& msi_3) { | 544 const MuxedStreamInfo& msi_3) { |
467 std::vector<MuxedStreamInfo> msi(3); | 545 std::vector<MuxedStreamInfo> msi(3); |
468 msi[0] = msi_1; | 546 msi[0] = msi_1; |
469 msi[1] = msi_2; | 547 msi[1] = msi_2; |
470 msi[2] = msi_3; | 548 msi[2] = msi_3; |
471 AppendMuxedCluster(msi); | 549 AppendMuxedCluster(msi); |
472 } | 550 } |
473 | 551 |
474 void AppendMuxedCluster(const std::vector<MuxedStreamInfo> msi) { | 552 void AppendMuxedCluster(const std::vector<MuxedStreamInfo> msi) { |
| 553 std::priority_queue<BlockInfo> block_queue; |
475 for (size_t i = 0; i < msi.size(); ++i) { | 554 for (size_t i = 0; i < msi.size(); ++i) { |
476 AppendSingleStreamCluster(kSourceId, | 555 std::vector<BlockInfo> track_blocks; |
477 msi[i].track_number, | 556 ParseBlockDescriptions(msi[i].track_number, msi[i].block_descriptions, |
478 msi[i].cluster_description); | 557 &track_blocks); |
| 558 |
| 559 for (size_t j = 0; j < track_blocks.size(); ++j) |
| 560 block_queue.push(track_blocks[j]); |
479 } | 561 } |
| 562 |
| 563 AppendCluster(kSourceId, GenerateCluster(block_queue, false)); |
480 } | 564 } |
481 | 565 |
482 void AppendData(const std::string& source_id, | 566 void AppendData(const std::string& source_id, |
483 const uint8* data, size_t length) { | 567 const uint8* data, size_t length) { |
484 EXPECT_CALL(host_, AddBufferedTimeRange(_, _)).Times(AnyNumber()); | 568 EXPECT_CALL(host_, AddBufferedTimeRange(_, _)).Times(AnyNumber()); |
485 | 569 |
486 demuxer_->AppendData(source_id, data, length, | 570 demuxer_->AppendData(source_id, data, length, |
487 append_window_start_for_next_append_, | 571 append_window_start_for_next_append_, |
488 append_window_end_for_next_append_, | 572 append_window_end_for_next_append_, |
489 ×tamp_offset_map_[source_id]); | 573 ×tamp_offset_map_[source_id]); |
(...skipping 224 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
714 int block_count) { | 798 int block_count) { |
715 return GenerateCluster(first_audio_timecode, first_video_timecode, | 799 return GenerateCluster(first_audio_timecode, first_video_timecode, |
716 block_count, false); | 800 block_count, false); |
717 } | 801 } |
718 scoped_ptr<Cluster> GenerateCluster(int first_audio_timecode, | 802 scoped_ptr<Cluster> GenerateCluster(int first_audio_timecode, |
719 int first_video_timecode, | 803 int first_video_timecode, |
720 int block_count, | 804 int block_count, |
721 bool unknown_size) { | 805 bool unknown_size) { |
722 CHECK_GT(block_count, 0); | 806 CHECK_GT(block_count, 0); |
723 | 807 |
724 int size = 10; | 808 std::priority_queue<BlockInfo> block_queue; |
725 scoped_ptr<uint8[]> data(new uint8[size]); | |
726 | |
727 ClusterBuilder cb; | |
728 cb.SetClusterTimecode(std::min(first_audio_timecode, first_video_timecode)); | |
729 | 809 |
730 if (block_count == 1) { | 810 if (block_count == 1) { |
731 cb.AddBlockGroup(kAudioTrackNum, first_audio_timecode, | 811 block_queue.push(BlockInfo(kAudioTrackNum, |
732 kAudioBlockDuration, kWebMFlagKeyframe, | 812 first_audio_timecode, |
733 data.get(), size); | 813 kWebMFlagKeyframe, |
734 return cb.Finish(); | 814 kAudioBlockDuration)); |
| 815 return GenerateCluster(block_queue, unknown_size); |
735 } | 816 } |
736 | 817 |
737 int audio_timecode = first_audio_timecode; | 818 int audio_timecode = first_audio_timecode; |
738 int video_timecode = first_video_timecode; | 819 int video_timecode = first_video_timecode; |
739 | 820 |
740 // Create simple blocks for everything except the last 2 blocks. | 821 // Create simple blocks for everything except the last 2 blocks. |
741 // The first video frame must be a keyframe. | 822 // The first video frame must be a keyframe. |
742 uint8 video_flag = kWebMFlagKeyframe; | 823 uint8 video_flag = kWebMFlagKeyframe; |
743 for (int i = 0; i < block_count - 2; i++) { | 824 for (int i = 0; i < block_count - 2; i++) { |
744 if (audio_timecode <= video_timecode) { | 825 if (audio_timecode <= video_timecode) { |
745 cb.AddSimpleBlock(kAudioTrackNum, audio_timecode, kWebMFlagKeyframe, | 826 block_queue.push(BlockInfo(kAudioTrackNum, |
746 data.get(), size); | 827 audio_timecode, |
| 828 kWebMFlagKeyframe, |
| 829 0)); |
747 audio_timecode += kAudioBlockDuration; | 830 audio_timecode += kAudioBlockDuration; |
748 continue; | 831 continue; |
749 } | 832 } |
750 | 833 |
751 cb.AddSimpleBlock(kVideoTrackNum, video_timecode, video_flag, data.get(), | 834 block_queue.push(BlockInfo(kVideoTrackNum, |
752 size); | 835 video_timecode, |
| 836 video_flag, |
| 837 0)); |
753 video_timecode += kVideoBlockDuration; | 838 video_timecode += kVideoBlockDuration; |
754 video_flag = 0; | 839 video_flag = 0; |
755 } | 840 } |
756 | 841 |
757 // Make the last 2 blocks BlockGroups so that they don't get delayed by the | 842 // Make the last 2 blocks BlockGroups so that they don't get delayed by the |
758 // block duration calculation logic. | 843 // block duration calculation logic. |
759 if (audio_timecode <= video_timecode) { | 844 block_queue.push(BlockInfo(kAudioTrackNum, |
760 cb.AddBlockGroup(kAudioTrackNum, audio_timecode, kAudioBlockDuration, | 845 audio_timecode, |
761 kWebMFlagKeyframe, data.get(), size); | 846 kWebMFlagKeyframe, |
762 AddVideoBlockGroup(&cb, kVideoTrackNum, video_timecode, | 847 kAudioBlockDuration)); |
763 kVideoBlockDuration, video_flag); | 848 block_queue.push(BlockInfo(kVideoTrackNum, |
764 } else { | 849 video_timecode, |
765 AddVideoBlockGroup(&cb, kVideoTrackNum, video_timecode, | 850 video_flag, |
766 kVideoBlockDuration, video_flag); | 851 kVideoBlockDuration)); |
767 cb.AddBlockGroup(kAudioTrackNum, audio_timecode, kAudioBlockDuration, | |
768 kWebMFlagKeyframe, data.get(), size); | |
769 } | |
770 | 852 |
771 return unknown_size ? cb.FinishWithUnknownSize() : cb.Finish(); | 853 return GenerateCluster(block_queue, unknown_size); |
772 } | 854 } |
773 | 855 |
774 scoped_ptr<Cluster> GenerateSingleStreamCluster(int timecode, | 856 scoped_ptr<Cluster> GenerateSingleStreamCluster(int timecode, |
775 int end_timecode, | 857 int end_timecode, |
776 int track_number, | 858 int track_number, |
777 int block_duration) { | 859 int block_duration) { |
778 CHECK_GT(end_timecode, timecode); | 860 CHECK_GT(end_timecode, timecode); |
779 | 861 |
780 std::vector<uint8> data(kBlockSize); | 862 std::vector<uint8> data(kBlockSize); |
781 | 863 |
(...skipping 501 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1283 .WillOnce(SaveArg<0>(&text_stream)); | 1365 .WillOnce(SaveArg<0>(&text_stream)); |
1284 ASSERT_TRUE(InitDemuxerWithEncryptionInfo( | 1366 ASSERT_TRUE(InitDemuxerWithEncryptionInfo( |
1285 HAS_TEXT | HAS_AUDIO | HAS_VIDEO, false, false)); | 1367 HAS_TEXT | HAS_AUDIO | HAS_VIDEO, false, false)); |
1286 DemuxerStream* audio_stream = demuxer_->GetStream(DemuxerStream::AUDIO); | 1368 DemuxerStream* audio_stream = demuxer_->GetStream(DemuxerStream::AUDIO); |
1287 DemuxerStream* video_stream = demuxer_->GetStream(DemuxerStream::VIDEO); | 1369 DemuxerStream* video_stream = demuxer_->GetStream(DemuxerStream::VIDEO); |
1288 ASSERT_TRUE(audio_stream && video_stream && text_stream); | 1370 ASSERT_TRUE(audio_stream && video_stream && text_stream); |
1289 | 1371 |
1290 AppendMuxedCluster( | 1372 AppendMuxedCluster( |
1291 MuxedStreamInfo(kAudioTrackNum, "0 23K"), | 1373 MuxedStreamInfo(kAudioTrackNum, "0 23K"), |
1292 MuxedStreamInfo(kVideoTrackNum, "0 30K"), | 1374 MuxedStreamInfo(kVideoTrackNum, "0 30K"), |
1293 MuxedStreamInfo(kTextTrackNum, "0 40K")); | 1375 MuxedStreamInfo(kTextTrackNum, "25K 40K")); |
1294 CheckExpectedRanges(kSourceId, "{ [30,46) }"); | 1376 CheckExpectedRanges(kSourceId, "{ [23,46) }"); |
1295 | 1377 |
1296 AppendInitSegment(HAS_TEXT | HAS_AUDIO | HAS_VIDEO); | 1378 AppendInitSegment(HAS_TEXT | HAS_AUDIO | HAS_VIDEO); |
1297 AppendMuxedCluster( | 1379 AppendMuxedCluster( |
1298 MuxedStreamInfo(kAudioTrackNum, "46 69K"), | 1380 MuxedStreamInfo(kAudioTrackNum, "46 69K"), |
1299 MuxedStreamInfo(kVideoTrackNum, "60 90K"), | 1381 MuxedStreamInfo(kVideoTrackNum, "60 90K"), |
1300 MuxedStreamInfo(kTextTrackNum, "80 90K")); | 1382 MuxedStreamInfo(kTextTrackNum, "80K 90K")); |
1301 CheckExpectedRanges(kSourceId, "{ [30,92) }"); | 1383 CheckExpectedRanges(kSourceId, "{ [23,92) }"); |
1302 | 1384 |
1303 CheckExpectedBuffers(audio_stream, "23 69"); | 1385 CheckExpectedBuffers(audio_stream, "23 69"); |
1304 CheckExpectedBuffers(video_stream, "30 90"); | 1386 CheckExpectedBuffers(video_stream, "30 90"); |
1305 | 1387 CheckExpectedBuffers(text_stream, "25 40 80 90"); |
1306 // WebM parser marks all text buffers as keyframes. | |
1307 CheckExpectedBuffers(text_stream, "0 40 80 90"); | |
1308 } | 1388 } |
1309 | 1389 |
1310 // Make sure that the demuxer reports an error if Shutdown() | 1390 // Make sure that the demuxer reports an error if Shutdown() |
1311 // is called before all the initialization segments are appended. | 1391 // is called before all the initialization segments are appended. |
1312 TEST_F(ChunkDemuxerTest, Shutdown_BeforeAllInitSegmentsAppended) { | 1392 TEST_F(ChunkDemuxerTest, Shutdown_BeforeAllInitSegmentsAppended) { |
1313 EXPECT_CALL(*this, DemuxerOpened()); | 1393 EXPECT_CALL(*this, DemuxerOpened()); |
1314 demuxer_->Initialize( | 1394 demuxer_->Initialize( |
1315 &host_, CreateInitDoneCB( | 1395 &host_, CreateInitDoneCB( |
1316 kDefaultDuration(), DEMUXER_ERROR_COULD_NOT_OPEN), true); | 1396 kDefaultDuration(), DEMUXER_ERROR_COULD_NOT_OPEN), true); |
1317 | 1397 |
(...skipping 1143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2461 // Verify that the range extends to the end of the video data. | 2541 // Verify that the range extends to the end of the video data. |
2462 CheckExpectedRanges("{ [0,66) }"); | 2542 CheckExpectedRanges("{ [0,66) }"); |
2463 | 2543 |
2464 // Verify that the range reverts to the intersection when end of stream | 2544 // Verify that the range reverts to the intersection when end of stream |
2465 // has been cancelled. | 2545 // has been cancelled. |
2466 demuxer_->UnmarkEndOfStream(); | 2546 demuxer_->UnmarkEndOfStream(); |
2467 CheckExpectedRanges("{ [0,46) }"); | 2547 CheckExpectedRanges("{ [0,46) }"); |
2468 | 2548 |
2469 // Append and remove data so that the 2 streams' end ranges do not overlap. | 2549 // Append and remove data so that the 2 streams' end ranges do not overlap. |
2470 | 2550 |
2471 EXPECT_CALL(host_, SetDuration(base::TimeDelta::FromMilliseconds(246))); | |
2472 EXPECT_CALL(host_, SetDuration(base::TimeDelta::FromMilliseconds(398))); | 2551 EXPECT_CALL(host_, SetDuration(base::TimeDelta::FromMilliseconds(398))); |
2473 AppendMuxedCluster( | 2552 AppendMuxedCluster( |
2474 MuxedStreamInfo(kAudioTrackNum, "200K 223K"), | 2553 MuxedStreamInfo(kAudioTrackNum, "200K 223K"), |
2475 MuxedStreamInfo(kVideoTrackNum, "200K 233 266 299 332K 365")); | 2554 MuxedStreamInfo(kVideoTrackNum, "200K 233 266 299 332K 365")); |
2476 | 2555 |
2477 // At this point, the per-stream ranges are as follows: | 2556 // At this point, the per-stream ranges are as follows: |
2478 // Audio: [0,46) [200,246) | 2557 // Audio: [0,46) [200,246) |
2479 // Video: [0,66) [200,398) | 2558 // Video: [0,66) [200,398) |
2480 CheckExpectedRanges("{ [0,46) [200,246) }"); | 2559 CheckExpectedRanges("{ [0,46) [200,246) }"); |
2481 | 2560 |
(...skipping 864 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3346 // Append a cluster that starts before and ends after the append | 3425 // Append a cluster that starts before and ends after the append |
3347 // window. | 3426 // window. |
3348 AppendMuxedCluster( | 3427 AppendMuxedCluster( |
3349 MuxedStreamInfo(kVideoTrackNum, | 3428 MuxedStreamInfo(kVideoTrackNum, |
3350 "0K 30 60 90 120K 150 180 210 240K 270 300 330K"), | 3429 "0K 30 60 90 120K 150 180 210 240K 270 300 330K"), |
3351 MuxedStreamInfo(kTextTrackNum, "0K 100K 200K 300K" )); | 3430 MuxedStreamInfo(kTextTrackNum, "0K 100K 200K 300K" )); |
3352 | 3431 |
3353 // Verify that text cues that start outside the window are not included | 3432 // Verify that text cues that start outside the window are not included |
3354 // in the buffer. Also verify that cues that extend beyond the | 3433 // in the buffer. Also verify that cues that extend beyond the |
3355 // window are not included. | 3434 // window are not included. |
3356 CheckExpectedRanges(kSourceId, "{ [120,270) }"); | 3435 CheckExpectedRanges(kSourceId, "{ [100,270) }"); |
3357 CheckExpectedBuffers(video_stream, "120 150 180 210 240"); | 3436 CheckExpectedBuffers(video_stream, "120 150 180 210 240"); |
3358 CheckExpectedBuffers(text_stream, "100"); | 3437 CheckExpectedBuffers(text_stream, "100"); |
3359 | 3438 |
3360 // Extend the append window to [20,650). | 3439 // Extend the append window to [20,650). |
3361 append_window_end_for_next_append_ = base::TimeDelta::FromMilliseconds(650); | 3440 append_window_end_for_next_append_ = base::TimeDelta::FromMilliseconds(650); |
3362 | 3441 |
3363 // Append more data and verify that a new range is created. | 3442 // Append more data and verify that a new range is created. |
3364 AppendMuxedCluster( | 3443 AppendMuxedCluster( |
3365 MuxedStreamInfo(kVideoTrackNum, | 3444 MuxedStreamInfo(kVideoTrackNum, |
3366 "360 390 420K 450 480 510 540K 570 600 630K"), | 3445 "360 390 420K 450 480 510 540K 570 600 630K"), |
3367 MuxedStreamInfo(kTextTrackNum, "400K 500K 600K 700K" )); | 3446 MuxedStreamInfo(kTextTrackNum, "400K 500K 600K 700K" )); |
3368 CheckExpectedRanges(kSourceId, "{ [120,270) [420,630) }"); | 3447 CheckExpectedRanges(kSourceId, "{ [100,270) [400,630) }"); |
3369 | 3448 |
3370 // Seek to the new range and verify that the expected buffers are returned. | 3449 // Seek to the new range and verify that the expected buffers are returned. |
3371 Seek(base::TimeDelta::FromMilliseconds(420)); | 3450 Seek(base::TimeDelta::FromMilliseconds(420)); |
3372 CheckExpectedBuffers(video_stream, "420 450 480 510 540 570 600"); | 3451 CheckExpectedBuffers(video_stream, "420 450 480 510 540 570 600"); |
3373 CheckExpectedBuffers(text_stream, "400 500"); | 3452 CheckExpectedBuffers(text_stream, "400 500"); |
3374 } | 3453 } |
3375 | 3454 |
3376 TEST_F(ChunkDemuxerTest, StartWaitingForSeekAfterParseError) { | 3455 TEST_F(ChunkDemuxerTest, StartWaitingForSeekAfterParseError) { |
3377 ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO)); | 3456 ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO)); |
3378 EXPECT_CALL(host_, OnDemuxerError(PIPELINE_ERROR_DECODE)); | 3457 EXPECT_CALL(host_, OnDemuxerError(PIPELINE_ERROR_DECODE)); |
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3491 // Append text cues that start after the seek point and verify that | 3570 // Append text cues that start after the seek point and verify that |
3492 // they are returned by Read() calls. | 3571 // they are returned by Read() calls. |
3493 AppendMuxedCluster( | 3572 AppendMuxedCluster( |
3494 MuxedStreamInfo(kAudioTrackNum, "220K 240K 260K 280K"), | 3573 MuxedStreamInfo(kAudioTrackNum, "220K 240K 260K 280K"), |
3495 MuxedStreamInfo(kVideoTrackNum, "240K 270 300 330"), | 3574 MuxedStreamInfo(kVideoTrackNum, "240K 270 300 330"), |
3496 MuxedStreamInfo(kTextTrackNum, "225K 275K 325K")); | 3575 MuxedStreamInfo(kTextTrackNum, "225K 275K 325K")); |
3497 | 3576 |
3498 message_loop_.RunUntilIdle(); | 3577 message_loop_.RunUntilIdle(); |
3499 EXPECT_TRUE(text_read_done); | 3578 EXPECT_TRUE(text_read_done); |
3500 | 3579 |
3501 // NOTE: we start at 175 here because the buffer at 125 was returned | 3580 // NOTE: we start at 275 here because the buffer at 225 was returned |
3502 // to the pending read initiated above. | 3581 // to the pending read initiated above. |
3503 CheckExpectedBuffers(text_stream, "275 325"); | 3582 CheckExpectedBuffers(text_stream, "275 325"); |
3504 | 3583 |
3505 // Verify that audio & video streams continue to return expected values. | 3584 // Verify that audio & video streams continue to return expected values. |
3506 CheckExpectedBuffers(audio_stream, "160 180"); | 3585 CheckExpectedBuffers(audio_stream, "160 180"); |
3507 CheckExpectedBuffers(video_stream, "180 210"); | 3586 CheckExpectedBuffers(video_stream, "180 210"); |
3508 } | 3587 } |
3509 | 3588 |
3510 TEST_F(ChunkDemuxerTest, ClusterWithUnknownSize) { | 3589 TEST_F(ChunkDemuxerTest, ClusterWithUnknownSize) { |
3511 ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO)); | 3590 ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO)); |
(...skipping 23 matching lines...) Expand all Loading... |
3535 TEST_F(ChunkDemuxerTest, CuesBetweenClusters) { | 3614 TEST_F(ChunkDemuxerTest, CuesBetweenClusters) { |
3536 ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO)); | 3615 ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO)); |
3537 | 3616 |
3538 AppendCluster(GenerateCluster(0, 0, 4)); | 3617 AppendCluster(GenerateCluster(0, 0, 4)); |
3539 AppendData(kCuesHeader, sizeof(kCuesHeader)); | 3618 AppendData(kCuesHeader, sizeof(kCuesHeader)); |
3540 AppendCluster(GenerateCluster(46, 66, 5)); | 3619 AppendCluster(GenerateCluster(46, 66, 5)); |
3541 CheckExpectedRanges(kSourceId, "{ [0,115) }"); | 3620 CheckExpectedRanges(kSourceId, "{ [0,115) }"); |
3542 } | 3621 } |
3543 | 3622 |
3544 } // namespace media | 3623 } // namespace media |
OLD | NEW |