| 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 |