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 "media/filters/chunk_demuxer.h" | 5 #include "media/filters/chunk_demuxer.h" |
6 | 6 |
7 #include <stddef.h> | 7 #include <stddef.h> |
8 #include <stdint.h> | 8 #include <stdint.h> |
9 #include <algorithm> | 9 #include <algorithm> |
10 #include <utility> | 10 #include <utility> |
(...skipping 245 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
256 // have timestamps consistent with the end times of the blocks | 256 // have timestamps consistent with the end times of the blocks |
257 // in kDefaultFirstCluster() so that these two clusters represent | 257 // in kDefaultFirstCluster() so that these two clusters represent |
258 // a continuous region. | 258 // a continuous region. |
259 scoped_ptr<Cluster> kDefaultSecondCluster() { | 259 scoped_ptr<Cluster> kDefaultSecondCluster() { |
260 return GenerateCluster(46, 66, 5); | 260 return GenerateCluster(46, 66, 5); |
261 } | 261 } |
262 | 262 |
263 ChunkDemuxerTest() | 263 ChunkDemuxerTest() |
264 : media_log_(new StrictMock<MockMediaLog>()), | 264 : media_log_(new StrictMock<MockMediaLog>()), |
265 append_window_end_for_next_append_(kInfiniteDuration()) { | 265 append_window_end_for_next_append_(kInfiniteDuration()) { |
266 init_segment_received_cb_ = | 266 init_segment_received_cb_ = base::Bind( |
267 base::Bind(&ChunkDemuxerTest::InitSegmentReceived, | 267 &ChunkDemuxerTest::InitSegmentReceivedWrapper, base::Unretained(this)); |
268 base::Unretained(this)); | |
269 CreateNewDemuxer(); | 268 CreateNewDemuxer(); |
270 } | 269 } |
271 | 270 |
272 void CreateNewDemuxer() { | 271 void CreateNewDemuxer() { |
273 base::Closure open_cb = | 272 base::Closure open_cb = |
274 base::Bind(&ChunkDemuxerTest::DemuxerOpened, base::Unretained(this)); | 273 base::Bind(&ChunkDemuxerTest::DemuxerOpened, base::Unretained(this)); |
275 Demuxer::EncryptedMediaInitDataCB encrypted_media_init_data_cb = base::Bind( | 274 Demuxer::EncryptedMediaInitDataCB encrypted_media_init_data_cb = base::Bind( |
276 &ChunkDemuxerTest::OnEncryptedMediaInitData, base::Unretained(this)); | 275 &ChunkDemuxerTest::OnEncryptedMediaInitData, base::Unretained(this)); |
277 demuxer_.reset(new ChunkDemuxer(open_cb, encrypted_media_init_data_cb, | 276 demuxer_.reset(new ChunkDemuxer(open_cb, encrypted_media_init_data_cb, |
278 media_log_, true)); | 277 media_log_, true)); |
(...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
444 | 443 |
445 if (has_video) { | 444 if (has_video) { |
446 codecs.push_back("vp8"); | 445 codecs.push_back("vp8"); |
447 type = "video/webm"; | 446 type = "video/webm"; |
448 } | 447 } |
449 | 448 |
450 if (!has_audio && !has_video) { | 449 if (!has_audio && !has_video) { |
451 return AddId(kSourceId, HAS_AUDIO | HAS_VIDEO); | 450 return AddId(kSourceId, HAS_AUDIO | HAS_VIDEO); |
452 } | 451 } |
453 | 452 |
454 return demuxer_->AddId(source_id, type, codecs); | 453 ChunkDemuxer::Status status = demuxer_->AddId(source_id, type, codecs); |
| 454 if (status == ChunkDemuxer::kOk) |
| 455 demuxer_->SetTracksWatcher( |
| 456 source_id, base::Bind(&ChunkDemuxerTest::InitSegmentReceivedWrapper, |
| 457 base::Unretained(this))); |
| 458 return status; |
455 } | 459 } |
456 | 460 |
457 #if BUILDFLAG(ENABLE_MSE_MPEG2TS_STREAM_PARSER) | 461 #if BUILDFLAG(ENABLE_MSE_MPEG2TS_STREAM_PARSER) |
458 ChunkDemuxer::Status AddIdForMp2tSource(const std::string& source_id) { | 462 ChunkDemuxer::Status AddIdForMp2tSource(const std::string& source_id) { |
459 std::vector<std::string> codecs; | 463 std::vector<std::string> codecs; |
460 std::string type = "video/mp2t"; | 464 std::string type = "video/mp2t"; |
461 codecs.push_back("mp4a.40.2"); | 465 codecs.push_back("mp4a.40.2"); |
462 codecs.push_back("avc1.640028"); | 466 codecs.push_back("avc1.640028"); |
463 return demuxer_->AddId(source_id, type, codecs); | 467 ChunkDemuxer::Status status = demuxer_->AddId(source_id, type, codecs); |
| 468 if (status == ChunkDemuxer::kOk) |
| 469 demuxer_->SetTracksWatcher( |
| 470 source_id, base::Bind(&ChunkDemuxerTest::InitSegmentReceivedWrapper, |
| 471 base::Unretained(this))); |
| 472 return status; |
464 } | 473 } |
465 #endif | 474 #endif |
466 | 475 |
467 void AppendData(const uint8_t* data, size_t length) { | 476 void AppendData(const uint8_t* data, size_t length) { |
468 AppendData(kSourceId, data, length); | 477 AppendData(kSourceId, data, length); |
469 } | 478 } |
470 | 479 |
471 void AppendCluster(const std::string& source_id, | 480 void AppendCluster(const std::string& source_id, |
472 scoped_ptr<Cluster> cluster) { | 481 scoped_ptr<Cluster> cluster) { |
473 AppendData(source_id, cluster->data(), cluster->size()); | 482 AppendData(source_id, cluster->data(), cluster->size()); |
(...skipping 234 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
708 | 717 |
709 void AppendMuxedCluster(const std::vector<MuxedStreamInfo> msi) { | 718 void AppendMuxedCluster(const std::vector<MuxedStreamInfo> msi) { |
710 AppendCluster(kSourceId, GenerateMuxedCluster(msi)); | 719 AppendCluster(kSourceId, GenerateMuxedCluster(msi)); |
711 } | 720 } |
712 | 721 |
713 void AppendData(const std::string& source_id, | 722 void AppendData(const std::string& source_id, |
714 const uint8_t* data, | 723 const uint8_t* data, |
715 size_t length) { | 724 size_t length) { |
716 EXPECT_CALL(host_, OnBufferedTimeRangesChanged(_)).Times(AnyNumber()); | 725 EXPECT_CALL(host_, OnBufferedTimeRangesChanged(_)).Times(AnyNumber()); |
717 | 726 |
718 demuxer_->AppendData(source_id, data, length, | 727 demuxer_->AppendData( |
719 append_window_start_for_next_append_, | 728 source_id, data, length, append_window_start_for_next_append_, |
720 append_window_end_for_next_append_, | 729 append_window_end_for_next_append_, ×tamp_offset_map_[source_id]); |
721 ×tamp_offset_map_[source_id], | |
722 init_segment_received_cb_); | |
723 } | 730 } |
724 | 731 |
725 void AppendDataInPieces(const uint8_t* data, size_t length) { | 732 void AppendDataInPieces(const uint8_t* data, size_t length) { |
726 AppendDataInPieces(data, length, 7); | 733 AppendDataInPieces(data, length, 7); |
727 } | 734 } |
728 | 735 |
729 void AppendDataInPieces(const uint8_t* data, | 736 void AppendDataInPieces(const uint8_t* data, |
730 size_t length, | 737 size_t length, |
731 size_t piece_size) { | 738 size_t piece_size) { |
732 const uint8_t* start = data; | 739 const uint8_t* start = data; |
(...skipping 606 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1339 } | 1346 } |
1340 | 1347 |
1341 return true; | 1348 return true; |
1342 } | 1349 } |
1343 | 1350 |
1344 MOCK_METHOD0(DemuxerOpened, void()); | 1351 MOCK_METHOD0(DemuxerOpened, void()); |
1345 MOCK_METHOD2(OnEncryptedMediaInitData, | 1352 MOCK_METHOD2(OnEncryptedMediaInitData, |
1346 void(EmeInitDataType init_data_type, | 1353 void(EmeInitDataType init_data_type, |
1347 const std::vector<uint8_t>& init_data)); | 1354 const std::vector<uint8_t>& init_data)); |
1348 | 1355 |
1349 MOCK_METHOD1(InitSegmentReceived, void(const MediaTracks&)); | 1356 MOCK_METHOD1(InitSegmentReceived, void(scoped_ptr<MediaTracks>&)); |
1350 | 1357 |
1351 void Seek(base::TimeDelta seek_time) { | 1358 void Seek(base::TimeDelta seek_time) { |
1352 demuxer_->StartWaitingForSeek(seek_time); | 1359 demuxer_->StartWaitingForSeek(seek_time); |
1353 demuxer_->Seek(seek_time, NewExpectedStatusCB(PIPELINE_OK)); | 1360 demuxer_->Seek(seek_time, NewExpectedStatusCB(PIPELINE_OK)); |
1354 message_loop_.RunUntilIdle(); | 1361 message_loop_.RunUntilIdle(); |
1355 } | 1362 } |
1356 | 1363 |
1357 void MarkEndOfStream(PipelineStatus status) { | 1364 void MarkEndOfStream(PipelineStatus status) { |
1358 demuxer_->MarkEndOfStream(status); | 1365 demuxer_->MarkEndOfStream(status); |
1359 message_loop_.RunUntilIdle(); | 1366 message_loop_.RunUntilIdle(); |
1360 } | 1367 } |
1361 | 1368 |
1362 bool SetTimestampOffset(const std::string& id, | 1369 bool SetTimestampOffset(const std::string& id, |
1363 base::TimeDelta timestamp_offset) { | 1370 base::TimeDelta timestamp_offset) { |
1364 if (demuxer_->IsParsingMediaSegment(id)) | 1371 if (demuxer_->IsParsingMediaSegment(id)) |
1365 return false; | 1372 return false; |
1366 | 1373 |
1367 timestamp_offset_map_[id] = timestamp_offset; | 1374 timestamp_offset_map_[id] = timestamp_offset; |
1368 return true; | 1375 return true; |
1369 } | 1376 } |
1370 | 1377 |
1371 base::MessageLoop message_loop_; | 1378 base::MessageLoop message_loop_; |
1372 MockDemuxerHost host_; | 1379 MockDemuxerHost host_; |
1373 | 1380 |
1374 scoped_refptr<StrictMock<MockMediaLog>> media_log_; | 1381 scoped_refptr<StrictMock<MockMediaLog>> media_log_; |
1375 | 1382 |
1376 scoped_ptr<ChunkDemuxer> demuxer_; | 1383 scoped_ptr<ChunkDemuxer> demuxer_; |
1377 MediaSourceState::InitSegmentReceivedCB init_segment_received_cb_; | 1384 Demuxer::MediaTracksUpdatedCB init_segment_received_cb_; |
1378 | 1385 |
1379 base::TimeDelta append_window_start_for_next_append_; | 1386 base::TimeDelta append_window_start_for_next_append_; |
1380 base::TimeDelta append_window_end_for_next_append_; | 1387 base::TimeDelta append_window_end_for_next_append_; |
1381 | 1388 |
1382 // Map of source id to timestamp offset to use for the next AppendData() | 1389 // Map of source id to timestamp offset to use for the next AppendData() |
1383 // operation for that source id. | 1390 // operation for that source id. |
1384 std::map<std::string, base::TimeDelta> timestamp_offset_map_; | 1391 std::map<std::string, base::TimeDelta> timestamp_offset_map_; |
1385 | 1392 |
| 1393 public: |
| 1394 // A workaround for gtest mocks not allowing moving scoped_ptrs. |
| 1395 void InitSegmentReceivedWrapper(scoped_ptr<MediaTracks> tracks) { |
| 1396 InitSegmentReceived(tracks); |
| 1397 } |
| 1398 |
1386 private: | 1399 private: |
1387 DISALLOW_COPY_AND_ASSIGN(ChunkDemuxerTest); | 1400 DISALLOW_COPY_AND_ASSIGN(ChunkDemuxerTest); |
1388 }; | 1401 }; |
1389 | 1402 |
1390 TEST_F(ChunkDemuxerTest, Init) { | 1403 TEST_F(ChunkDemuxerTest, Init) { |
1391 InSequence s; | 1404 InSequence s; |
1392 | 1405 |
1393 // Test no streams, audio-only, video-only, and audio & video scenarios. | 1406 // Test no streams, audio-only, video-only, and audio & video scenarios. |
1394 // Audio and video streams can be encrypted or not encrypted. | 1407 // Audio and video streams can be encrypted or not encrypted. |
1395 for (int i = 0; i < 16; i++) { | 1408 for (int i = 0; i < 16; i++) { |
(...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1545 | 1558 |
1546 scoped_ptr<uint8_t[]> info_tracks; | 1559 scoped_ptr<uint8_t[]> info_tracks; |
1547 int info_tracks_size = 0; | 1560 int info_tracks_size = 0; |
1548 CreateInitSegmentWithAlternateTextTrackNum(HAS_TEXT | HAS_AUDIO | HAS_VIDEO, | 1561 CreateInitSegmentWithAlternateTextTrackNum(HAS_TEXT | HAS_AUDIO | HAS_VIDEO, |
1549 false, false, | 1562 false, false, |
1550 &info_tracks, &info_tracks_size); | 1563 &info_tracks, &info_tracks_size); |
1551 EXPECT_CALL(*this, InitSegmentReceived(_)); | 1564 EXPECT_CALL(*this, InitSegmentReceived(_)); |
1552 demuxer_->AppendData(kSourceId, info_tracks.get(), info_tracks_size, | 1565 demuxer_->AppendData(kSourceId, info_tracks.get(), info_tracks_size, |
1553 append_window_start_for_next_append_, | 1566 append_window_start_for_next_append_, |
1554 append_window_end_for_next_append_, | 1567 append_window_end_for_next_append_, |
1555 ×tamp_offset_map_[kSourceId], | 1568 ×tamp_offset_map_[kSourceId]); |
1556 init_segment_received_cb_); | |
1557 | 1569 |
1558 AppendMuxedCluster( | 1570 AppendMuxedCluster( |
1559 MuxedStreamInfo(kAudioTrackNum, "46K 69K", 23), | 1571 MuxedStreamInfo(kAudioTrackNum, "46K 69K", 23), |
1560 MuxedStreamInfo(kVideoTrackNum, "60K", | 1572 MuxedStreamInfo(kVideoTrackNum, "60K", |
1561 WebMClusterParser::kDefaultVideoBufferDurationInMs), | 1573 WebMClusterParser::kDefaultVideoBufferDurationInMs), |
1562 MuxedStreamInfo(kAlternateTextTrackNum, "45K")); | 1574 MuxedStreamInfo(kAlternateTextTrackNum, "45K")); |
1563 | 1575 |
1564 CheckExpectedRanges("{ [0,92) }"); | 1576 CheckExpectedRanges("{ [0,92) }"); |
1565 CheckExpectedBuffers(audio_stream, "0K 23K 46K 69K"); | 1577 CheckExpectedBuffers(audio_stream, "0K 23K 46K 69K"); |
1566 CheckExpectedBuffers(video_stream, "0K 30 60K"); | 1578 CheckExpectedBuffers(video_stream, "0K 30 60K"); |
(...skipping 172 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1739 | 1751 |
1740 // Test the case where AppendData() is called before Init(). | 1752 // Test the case where AppendData() is called before Init(). |
1741 TEST_F(ChunkDemuxerTest, AppendDataBeforeInit) { | 1753 TEST_F(ChunkDemuxerTest, AppendDataBeforeInit) { |
1742 scoped_ptr<uint8_t[]> info_tracks; | 1754 scoped_ptr<uint8_t[]> info_tracks; |
1743 int info_tracks_size = 0; | 1755 int info_tracks_size = 0; |
1744 CreateInitSegment(HAS_AUDIO | HAS_VIDEO, | 1756 CreateInitSegment(HAS_AUDIO | HAS_VIDEO, |
1745 false, false, &info_tracks, &info_tracks_size); | 1757 false, false, &info_tracks, &info_tracks_size); |
1746 demuxer_->AppendData(kSourceId, info_tracks.get(), info_tracks_size, | 1758 demuxer_->AppendData(kSourceId, info_tracks.get(), info_tracks_size, |
1747 append_window_start_for_next_append_, | 1759 append_window_start_for_next_append_, |
1748 append_window_end_for_next_append_, | 1760 append_window_end_for_next_append_, |
1749 ×tamp_offset_map_[kSourceId], | 1761 ×tamp_offset_map_[kSourceId]); |
1750 init_segment_received_cb_); | |
1751 } | 1762 } |
1752 | 1763 |
1753 // Make sure Read() callbacks are dispatched with the proper data. | 1764 // Make sure Read() callbacks are dispatched with the proper data. |
1754 TEST_F(ChunkDemuxerTest, Read) { | 1765 TEST_F(ChunkDemuxerTest, Read) { |
1755 ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO)); | 1766 ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO)); |
1756 | 1767 |
1757 AppendCluster(kDefaultFirstCluster()); | 1768 AppendCluster(kDefaultFirstCluster()); |
1758 | 1769 |
1759 bool audio_read_done = false; | 1770 bool audio_read_done = false; |
1760 bool video_read_done = false; | 1771 bool video_read_done = false; |
(...skipping 18 matching lines...) Expand all Loading... |
1779 // overlaps with the previously appended cluster. | 1790 // overlaps with the previously appended cluster. |
1780 EXPECT_MEDIA_LOG(SkippingSpliceAlreadySpliced(0)); | 1791 EXPECT_MEDIA_LOG(SkippingSpliceAlreadySpliced(0)); |
1781 AppendCluster(GenerateCluster(5, 4)); | 1792 AppendCluster(GenerateCluster(5, 4)); |
1782 | 1793 |
1783 // Verify that AppendData() can still accept more data. | 1794 // Verify that AppendData() can still accept more data. |
1784 scoped_ptr<Cluster> cluster_c(GenerateCluster(45, 2)); | 1795 scoped_ptr<Cluster> cluster_c(GenerateCluster(45, 2)); |
1785 EXPECT_MEDIA_LOG(GeneratedSplice(6000, 45000)); | 1796 EXPECT_MEDIA_LOG(GeneratedSplice(6000, 45000)); |
1786 demuxer_->AppendData(kSourceId, cluster_c->data(), cluster_c->size(), | 1797 demuxer_->AppendData(kSourceId, cluster_c->data(), cluster_c->size(), |
1787 append_window_start_for_next_append_, | 1798 append_window_start_for_next_append_, |
1788 append_window_end_for_next_append_, | 1799 append_window_end_for_next_append_, |
1789 ×tamp_offset_map_[kSourceId], | 1800 ×tamp_offset_map_[kSourceId]); |
1790 init_segment_received_cb_); | |
1791 } | 1801 } |
1792 | 1802 |
1793 TEST_F(ChunkDemuxerTest, NonMonotonicButAboveClusterTimecode) { | 1803 TEST_F(ChunkDemuxerTest, NonMonotonicButAboveClusterTimecode) { |
1794 ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO)); | 1804 ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO)); |
1795 AppendCluster(kDefaultFirstCluster()); | 1805 AppendCluster(kDefaultFirstCluster()); |
1796 | 1806 |
1797 ClusterBuilder cb; | 1807 ClusterBuilder cb; |
1798 | 1808 |
1799 // Test the case where block timecodes are not monotonically | 1809 // Test the case where block timecodes are not monotonically |
1800 // increasing but stay above the cluster timecode. | 1810 // increasing but stay above the cluster timecode. |
1801 cb.SetClusterTimecode(5); | 1811 cb.SetClusterTimecode(5); |
1802 AddSimpleBlock(&cb, kAudioTrackNum, 5); | 1812 AddSimpleBlock(&cb, kAudioTrackNum, 5); |
1803 AddSimpleBlock(&cb, kVideoTrackNum, 10); | 1813 AddSimpleBlock(&cb, kVideoTrackNum, 10); |
1804 AddSimpleBlock(&cb, kAudioTrackNum, 7); | 1814 AddSimpleBlock(&cb, kAudioTrackNum, 7); |
1805 AddSimpleBlock(&cb, kVideoTrackNum, 15); | 1815 AddSimpleBlock(&cb, kVideoTrackNum, 15); |
1806 | 1816 |
1807 EXPECT_MEDIA_LOG(WebMOutOfOrderTimecode()); | 1817 EXPECT_MEDIA_LOG(WebMOutOfOrderTimecode()); |
1808 EXPECT_MEDIA_LOG(StreamParsingFailed()); | 1818 EXPECT_MEDIA_LOG(StreamParsingFailed()); |
1809 EXPECT_CALL(host_, OnDemuxerError(PIPELINE_ERROR_DECODE)); | 1819 EXPECT_CALL(host_, OnDemuxerError(PIPELINE_ERROR_DECODE)); |
1810 AppendCluster(cb.Finish()); | 1820 AppendCluster(cb.Finish()); |
1811 | 1821 |
1812 // Verify that AppendData() ignores data after the error. | 1822 // Verify that AppendData() ignores data after the error. |
1813 scoped_ptr<Cluster> cluster_b(GenerateCluster(20, 2)); | 1823 scoped_ptr<Cluster> cluster_b(GenerateCluster(20, 2)); |
1814 demuxer_->AppendData(kSourceId, cluster_b->data(), cluster_b->size(), | 1824 demuxer_->AppendData(kSourceId, cluster_b->data(), cluster_b->size(), |
1815 append_window_start_for_next_append_, | 1825 append_window_start_for_next_append_, |
1816 append_window_end_for_next_append_, | 1826 append_window_end_for_next_append_, |
1817 ×tamp_offset_map_[kSourceId], | 1827 ×tamp_offset_map_[kSourceId]); |
1818 init_segment_received_cb_); | |
1819 } | 1828 } |
1820 | 1829 |
1821 TEST_F(ChunkDemuxerTest, BackwardsAndBeforeClusterTimecode) { | 1830 TEST_F(ChunkDemuxerTest, BackwardsAndBeforeClusterTimecode) { |
1822 ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO)); | 1831 ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO)); |
1823 AppendCluster(kDefaultFirstCluster()); | 1832 AppendCluster(kDefaultFirstCluster()); |
1824 | 1833 |
1825 ClusterBuilder cb; | 1834 ClusterBuilder cb; |
1826 | 1835 |
1827 // Test timecodes going backwards and including values less than the cluster | 1836 // Test timecodes going backwards and including values less than the cluster |
1828 // timecode. | 1837 // timecode. |
1829 cb.SetClusterTimecode(5); | 1838 cb.SetClusterTimecode(5); |
1830 AddSimpleBlock(&cb, kAudioTrackNum, 5); | 1839 AddSimpleBlock(&cb, kAudioTrackNum, 5); |
1831 AddSimpleBlock(&cb, kVideoTrackNum, 5); | 1840 AddSimpleBlock(&cb, kVideoTrackNum, 5); |
1832 AddSimpleBlock(&cb, kAudioTrackNum, 3); | 1841 AddSimpleBlock(&cb, kAudioTrackNum, 3); |
1833 AddSimpleBlock(&cb, kVideoTrackNum, 3); | 1842 AddSimpleBlock(&cb, kVideoTrackNum, 3); |
1834 | 1843 |
1835 EXPECT_MEDIA_LOG(WebMNegativeTimecodeOffset("-2")); | 1844 EXPECT_MEDIA_LOG(WebMNegativeTimecodeOffset("-2")); |
1836 EXPECT_MEDIA_LOG(StreamParsingFailed()); | 1845 EXPECT_MEDIA_LOG(StreamParsingFailed()); |
1837 EXPECT_CALL(host_, OnDemuxerError(PIPELINE_ERROR_DECODE)); | 1846 EXPECT_CALL(host_, OnDemuxerError(PIPELINE_ERROR_DECODE)); |
1838 AppendCluster(cb.Finish()); | 1847 AppendCluster(cb.Finish()); |
1839 | 1848 |
1840 // Verify that AppendData() ignores data after the error. | 1849 // Verify that AppendData() ignores data after the error. |
1841 scoped_ptr<Cluster> cluster_b(GenerateCluster(6, 2)); | 1850 scoped_ptr<Cluster> cluster_b(GenerateCluster(6, 2)); |
1842 demuxer_->AppendData(kSourceId, cluster_b->data(), cluster_b->size(), | 1851 demuxer_->AppendData(kSourceId, cluster_b->data(), cluster_b->size(), |
1843 append_window_start_for_next_append_, | 1852 append_window_start_for_next_append_, |
1844 append_window_end_for_next_append_, | 1853 append_window_end_for_next_append_, |
1845 ×tamp_offset_map_[kSourceId], | 1854 ×tamp_offset_map_[kSourceId]); |
1846 init_segment_received_cb_); | |
1847 } | 1855 } |
1848 | 1856 |
1849 | 1857 |
1850 TEST_F(ChunkDemuxerTest, PerStreamMonotonicallyIncreasingTimestamps) { | 1858 TEST_F(ChunkDemuxerTest, PerStreamMonotonicallyIncreasingTimestamps) { |
1851 ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO)); | 1859 ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO)); |
1852 AppendCluster(kDefaultFirstCluster()); | 1860 AppendCluster(kDefaultFirstCluster()); |
1853 | 1861 |
1854 ClusterBuilder cb; | 1862 ClusterBuilder cb; |
1855 | 1863 |
1856 // Test monotonic increasing timestamps on a per stream | 1864 // Test monotonic increasing timestamps on a per stream |
(...skipping 468 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2325 TEST_F(ChunkDemuxerTest, ParseErrorDuringInit) { | 2333 TEST_F(ChunkDemuxerTest, ParseErrorDuringInit) { |
2326 EXPECT_CALL(*this, DemuxerOpened()); | 2334 EXPECT_CALL(*this, DemuxerOpened()); |
2327 demuxer_->Initialize( | 2335 demuxer_->Initialize( |
2328 &host_, CreateInitDoneCB( | 2336 &host_, CreateInitDoneCB( |
2329 kNoTimestamp(), PIPELINE_ERROR_DECODE), true); | 2337 kNoTimestamp(), PIPELINE_ERROR_DECODE), true); |
2330 | 2338 |
2331 ASSERT_EQ(AddId(), ChunkDemuxer::kOk); | 2339 ASSERT_EQ(AddId(), ChunkDemuxer::kOk); |
2332 | 2340 |
2333 EXPECT_MEDIA_LOG(StreamParsingFailed()); | 2341 EXPECT_MEDIA_LOG(StreamParsingFailed()); |
2334 uint8_t tmp = 0; | 2342 uint8_t tmp = 0; |
2335 demuxer_->AppendData(kSourceId, &tmp, 1, | 2343 demuxer_->AppendData(kSourceId, &tmp, 1, append_window_start_for_next_append_, |
2336 append_window_start_for_next_append_, | |
2337 append_window_end_for_next_append_, | 2344 append_window_end_for_next_append_, |
2338 ×tamp_offset_map_[kSourceId], | 2345 ×tamp_offset_map_[kSourceId]); |
2339 init_segment_received_cb_); | |
2340 } | 2346 } |
2341 | 2347 |
2342 TEST_F(ChunkDemuxerTest, AVHeadersWithAudioOnlyType) { | 2348 TEST_F(ChunkDemuxerTest, AVHeadersWithAudioOnlyType) { |
2343 EXPECT_CALL(*this, DemuxerOpened()); | 2349 EXPECT_CALL(*this, DemuxerOpened()); |
2344 demuxer_->Initialize( | 2350 demuxer_->Initialize( |
2345 &host_, CreateInitDoneCB(kNoTimestamp(), | 2351 &host_, CreateInitDoneCB(kNoTimestamp(), |
2346 PIPELINE_ERROR_DECODE), true); | 2352 PIPELINE_ERROR_DECODE), true); |
2347 | 2353 |
2348 std::vector<std::string> codecs(1); | 2354 std::vector<std::string> codecs(1); |
2349 codecs[0] = "vorbis"; | 2355 codecs[0] = "vorbis"; |
2350 ASSERT_EQ(demuxer_->AddId(kSourceId, "audio/webm", codecs), | 2356 ASSERT_EQ(demuxer_->AddId(kSourceId, "audio/webm", codecs), |
2351 ChunkDemuxer::kOk); | 2357 ChunkDemuxer::kOk); |
| 2358 demuxer_->SetTracksWatcher( |
| 2359 kSourceId, base::Bind(&ChunkDemuxerTest::InitSegmentReceivedWrapper, |
| 2360 base::Unretained(this))); |
2352 | 2361 |
2353 // Video track is unexpected per mimetype. | 2362 // Video track is unexpected per mimetype. |
2354 EXPECT_MEDIA_LOG(InitSegmentMismatchesMimeType("a video", true)); | 2363 EXPECT_MEDIA_LOG(InitSegmentMismatchesMimeType("a video", true)); |
2355 EXPECT_MEDIA_LOG(StreamParsingFailed()); | 2364 EXPECT_MEDIA_LOG(StreamParsingFailed()); |
2356 AppendInitSegment(HAS_AUDIO | HAS_VIDEO); | 2365 AppendInitSegment(HAS_AUDIO | HAS_VIDEO); |
2357 } | 2366 } |
2358 | 2367 |
2359 TEST_F(ChunkDemuxerTest, AVHeadersWithVideoOnlyType) { | 2368 TEST_F(ChunkDemuxerTest, AVHeadersWithVideoOnlyType) { |
2360 EXPECT_CALL(*this, DemuxerOpened()); | 2369 EXPECT_CALL(*this, DemuxerOpened()); |
2361 demuxer_->Initialize( | 2370 demuxer_->Initialize( |
2362 &host_, CreateInitDoneCB(kNoTimestamp(), | 2371 &host_, CreateInitDoneCB(kNoTimestamp(), |
2363 PIPELINE_ERROR_DECODE), true); | 2372 PIPELINE_ERROR_DECODE), true); |
2364 | 2373 |
2365 std::vector<std::string> codecs(1); | 2374 std::vector<std::string> codecs(1); |
2366 codecs[0] = "vp8"; | 2375 codecs[0] = "vp8"; |
2367 ASSERT_EQ(demuxer_->AddId(kSourceId, "video/webm", codecs), | 2376 ASSERT_EQ(demuxer_->AddId(kSourceId, "video/webm", codecs), |
2368 ChunkDemuxer::kOk); | 2377 ChunkDemuxer::kOk); |
| 2378 demuxer_->SetTracksWatcher( |
| 2379 kSourceId, base::Bind(&ChunkDemuxerTest::InitSegmentReceivedWrapper, |
| 2380 base::Unretained(this))); |
2369 | 2381 |
2370 // Audio track is unexpected per mimetype. | 2382 // Audio track is unexpected per mimetype. |
2371 EXPECT_MEDIA_LOG(InitSegmentMismatchesMimeType("an audio", true)); | 2383 EXPECT_MEDIA_LOG(InitSegmentMismatchesMimeType("an audio", true)); |
2372 EXPECT_MEDIA_LOG(StreamParsingFailed()); | 2384 EXPECT_MEDIA_LOG(StreamParsingFailed()); |
2373 AppendInitSegment(HAS_AUDIO | HAS_VIDEO); | 2385 AppendInitSegment(HAS_AUDIO | HAS_VIDEO); |
2374 } | 2386 } |
2375 | 2387 |
2376 TEST_F(ChunkDemuxerTest, AudioOnlyHeaderWithAVType) { | 2388 TEST_F(ChunkDemuxerTest, AudioOnlyHeaderWithAVType) { |
2377 EXPECT_CALL(*this, DemuxerOpened()); | 2389 EXPECT_CALL(*this, DemuxerOpened()); |
2378 demuxer_->Initialize( | 2390 demuxer_->Initialize( |
2379 &host_, CreateInitDoneCB(kNoTimestamp(), PIPELINE_ERROR_DECODE), true); | 2391 &host_, CreateInitDoneCB(kNoTimestamp(), PIPELINE_ERROR_DECODE), true); |
2380 | 2392 |
2381 std::vector<std::string> codecs(2); | 2393 std::vector<std::string> codecs(2); |
2382 codecs[0] = "vorbis"; | 2394 codecs[0] = "vorbis"; |
2383 codecs[1] = "vp8"; | 2395 codecs[1] = "vp8"; |
2384 ASSERT_EQ(demuxer_->AddId(kSourceId, "video/webm", codecs), | 2396 ASSERT_EQ(demuxer_->AddId(kSourceId, "video/webm", codecs), |
2385 ChunkDemuxer::kOk); | 2397 ChunkDemuxer::kOk); |
| 2398 demuxer_->SetTracksWatcher( |
| 2399 kSourceId, base::Bind(&ChunkDemuxerTest::InitSegmentReceivedWrapper, |
| 2400 base::Unretained(this))); |
2386 | 2401 |
2387 // Video track is also expected per mimetype. | 2402 // Video track is also expected per mimetype. |
2388 EXPECT_MEDIA_LOG(InitSegmentMismatchesMimeType("a video", false)); | 2403 EXPECT_MEDIA_LOG(InitSegmentMismatchesMimeType("a video", false)); |
2389 EXPECT_MEDIA_LOG(StreamParsingFailed()); | 2404 EXPECT_MEDIA_LOG(StreamParsingFailed()); |
2390 AppendInitSegment(HAS_AUDIO); | 2405 AppendInitSegment(HAS_AUDIO); |
2391 } | 2406 } |
2392 | 2407 |
2393 TEST_F(ChunkDemuxerTest, VideoOnlyHeaderWithAVType) { | 2408 TEST_F(ChunkDemuxerTest, VideoOnlyHeaderWithAVType) { |
2394 EXPECT_CALL(*this, DemuxerOpened()); | 2409 EXPECT_CALL(*this, DemuxerOpened()); |
2395 demuxer_->Initialize( | 2410 demuxer_->Initialize( |
2396 &host_, CreateInitDoneCB(kNoTimestamp(), PIPELINE_ERROR_DECODE), true); | 2411 &host_, CreateInitDoneCB(kNoTimestamp(), PIPELINE_ERROR_DECODE), true); |
2397 | 2412 |
2398 std::vector<std::string> codecs(2); | 2413 std::vector<std::string> codecs(2); |
2399 codecs[0] = "vorbis"; | 2414 codecs[0] = "vorbis"; |
2400 codecs[1] = "vp8"; | 2415 codecs[1] = "vp8"; |
2401 ASSERT_EQ(demuxer_->AddId(kSourceId, "video/webm", codecs), | 2416 ASSERT_EQ(demuxer_->AddId(kSourceId, "video/webm", codecs), |
2402 ChunkDemuxer::kOk); | 2417 ChunkDemuxer::kOk); |
| 2418 demuxer_->SetTracksWatcher( |
| 2419 kSourceId, base::Bind(&ChunkDemuxerTest::InitSegmentReceivedWrapper, |
| 2420 base::Unretained(this))); |
2403 | 2421 |
2404 // Audio track is also expected per mimetype. | 2422 // Audio track is also expected per mimetype. |
2405 EXPECT_MEDIA_LOG(InitSegmentMismatchesMimeType("an audio", false)); | 2423 EXPECT_MEDIA_LOG(InitSegmentMismatchesMimeType("an audio", false)); |
2406 EXPECT_MEDIA_LOG(StreamParsingFailed()); | 2424 EXPECT_MEDIA_LOG(StreamParsingFailed()); |
2407 AppendInitSegment(HAS_VIDEO); | 2425 AppendInitSegment(HAS_VIDEO); |
2408 } | 2426 } |
2409 | 2427 |
2410 TEST_F(ChunkDemuxerTest, MultipleHeaders) { | 2428 TEST_F(ChunkDemuxerTest, MultipleHeaders) { |
2411 ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO)); | 2429 ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO)); |
2412 | 2430 |
(...skipping 2195 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4608 cluster->size() - video_start); | 4626 cluster->size() - video_start); |
4609 | 4627 |
4610 CheckExpectedRanges(DemuxerStream::AUDIO, "{ [30,90) }"); | 4628 CheckExpectedRanges(DemuxerStream::AUDIO, "{ [30,90) }"); |
4611 CheckExpectedRanges(DemuxerStream::VIDEO, "{ [0,91) }"); | 4629 CheckExpectedRanges(DemuxerStream::VIDEO, "{ [0,91) }"); |
4612 CheckExpectedRanges("{ [30,90) }"); | 4630 CheckExpectedRanges("{ [30,90) }"); |
4613 CheckExpectedBuffers(audio_stream, "30K 40K 50K 60K 70K 80K"); | 4631 CheckExpectedBuffers(audio_stream, "30K 40K 50K 60K 70K 80K"); |
4614 CheckExpectedBuffers(video_stream, "71K 81"); | 4632 CheckExpectedBuffers(video_stream, "71K 81"); |
4615 } | 4633 } |
4616 | 4634 |
4617 } // namespace media | 4635 } // namespace media |
OLD | NEW |