| 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 131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 142 EXPECT_TRUE(buffer->end_of_stream()); | 142 EXPECT_TRUE(buffer->end_of_stream()); |
| 143 *called = true; | 143 *called = true; |
| 144 } | 144 } |
| 145 | 145 |
| 146 static void OnSeekDone_OKExpected(bool* called, PipelineStatus status) { | 146 static void OnSeekDone_OKExpected(bool* called, PipelineStatus status) { |
| 147 EXPECT_EQ(status, PIPELINE_OK); | 147 EXPECT_EQ(status, PIPELINE_OK); |
| 148 *called = true; | 148 *called = true; |
| 149 } | 149 } |
| 150 | 150 |
| 151 class ChunkDemuxerTest : public ::testing::Test { | 151 class ChunkDemuxerTest : public ::testing::Test { |
| 152 public: |
| 153 // Public method because test cases use it directly. |
| 154 MOCK_METHOD1(DemuxerInitialized, void(PipelineStatus)); |
| 155 |
| 152 protected: | 156 protected: |
| 153 enum CodecsIndex { | 157 enum CodecsIndex { |
| 154 AUDIO, | 158 AUDIO, |
| 155 VIDEO, | 159 VIDEO, |
| 156 MAX_CODECS_INDEX | 160 MAX_CODECS_INDEX |
| 157 }; | 161 }; |
| 158 | 162 |
| 159 // Default cluster to append first for simple tests. | 163 // Default cluster to append first for simple tests. |
| 160 std::unique_ptr<Cluster> kDefaultFirstCluster() { | 164 std::unique_ptr<Cluster> kDefaultFirstCluster() { |
| 161 return GenerateCluster(0, 4); | 165 return GenerateCluster(0, 4); |
| (...skipping 515 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 677 void AppendGarbage() { | 681 void AppendGarbage() { |
| 678 // Fill up an array with gibberish. | 682 // Fill up an array with gibberish. |
| 679 int garbage_cluster_size = 10; | 683 int garbage_cluster_size = 10; |
| 680 std::unique_ptr<uint8_t[]> garbage_cluster( | 684 std::unique_ptr<uint8_t[]> garbage_cluster( |
| 681 new uint8_t[garbage_cluster_size]); | 685 new uint8_t[garbage_cluster_size]); |
| 682 for (int i = 0; i < garbage_cluster_size; ++i) | 686 for (int i = 0; i < garbage_cluster_size; ++i) |
| 683 garbage_cluster[i] = i; | 687 garbage_cluster[i] = i; |
| 684 ASSERT_FALSE(AppendData(garbage_cluster.get(), garbage_cluster_size)); | 688 ASSERT_FALSE(AppendData(garbage_cluster.get(), garbage_cluster_size)); |
| 685 } | 689 } |
| 686 | 690 |
| 687 void InitDoneCalled(PipelineStatus expected_status, | |
| 688 PipelineStatus status) { | |
| 689 EXPECT_EQ(status, expected_status); | |
| 690 } | |
| 691 | |
| 692 PipelineStatusCB CreateInitDoneCB(const base::TimeDelta& expected_duration, | 691 PipelineStatusCB CreateInitDoneCB(const base::TimeDelta& expected_duration, |
| 693 PipelineStatus expected_status) { | 692 PipelineStatus expected_status) { |
| 694 if (expected_duration != kNoTimestamp) | 693 if (expected_duration != kNoTimestamp) |
| 695 EXPECT_CALL(host_, SetDuration(expected_duration)); | 694 EXPECT_CALL(host_, SetDuration(expected_duration)); |
| 696 return CreateInitDoneCB(expected_status); | 695 return CreateInitDoneCB(expected_status); |
| 697 } | 696 } |
| 698 | 697 |
| 699 PipelineStatusCB CreateInitDoneCB(PipelineStatus expected_status) { | 698 PipelineStatusCB CreateInitDoneCB(PipelineStatus expected_status) { |
| 700 return base::Bind(&ChunkDemuxerTest::InitDoneCalled, | 699 EXPECT_CALL(*this, DemuxerInitialized(expected_status)); |
| 701 base::Unretained(this), | 700 return base::Bind(&ChunkDemuxerTest::DemuxerInitialized, |
| 702 expected_status); | 701 base::Unretained(this)); |
| 703 } | 702 } |
| 704 | 703 |
| 705 enum StreamFlags { | 704 enum StreamFlags { |
| 706 HAS_AUDIO = 1 << 0, | 705 HAS_AUDIO = 1 << 0, |
| 707 HAS_VIDEO = 1 << 1, | 706 HAS_VIDEO = 1 << 1, |
| 708 HAS_TEXT = 1 << 2, | 707 HAS_TEXT = 1 << 2, |
| 709 USE_ALTERNATE_AUDIO_TRACK_ID = 1 << 3, | 708 USE_ALTERNATE_AUDIO_TRACK_ID = 1 << 3, |
| 710 USE_ALTERNATE_VIDEO_TRACK_ID = 1 << 4, | 709 USE_ALTERNATE_VIDEO_TRACK_ID = 1 << 4, |
| 711 USE_ALTERNATE_TEXT_TRACK_ID = 1 << 5, | 710 USE_ALTERNATE_TEXT_TRACK_ID = 1 << 5, |
| 712 }; | 711 }; |
| (...skipping 851 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1564 AppendMuxedCluster(MuxedStreamInfo(kAudioTrackNum, "46K 69K", 23), | 1563 AppendMuxedCluster(MuxedStreamInfo(kAudioTrackNum, "46K 69K", 23), |
| 1565 MuxedStreamInfo(kVideoTrackNum, "60 90K", 30), | 1564 MuxedStreamInfo(kVideoTrackNum, "60 90K", 30), |
| 1566 MuxedStreamInfo(kTextTrackNum, "80K 90K")); | 1565 MuxedStreamInfo(kTextTrackNum, "80K 90K")); |
| 1567 CheckExpectedRanges("{ [23,92) }"); | 1566 CheckExpectedRanges("{ [23,92) }"); |
| 1568 | 1567 |
| 1569 CheckExpectedBuffers(audio_stream, "23K 46K 69K"); | 1568 CheckExpectedBuffers(audio_stream, "23K 46K 69K"); |
| 1570 CheckExpectedBuffers(video_stream, "30K 90K"); | 1569 CheckExpectedBuffers(video_stream, "30K 90K"); |
| 1571 CheckExpectedBuffers(text_stream, "25K 40K 80K 90K"); | 1570 CheckExpectedBuffers(text_stream, "25K 40K 80K 90K"); |
| 1572 } | 1571 } |
| 1573 | 1572 |
| 1574 // Make sure that the demuxer reports an error if Shutdown() | |
| 1575 // is called before all the initialization segments are appended. | |
| 1576 TEST_F(ChunkDemuxerTest, Shutdown_BeforeAllInitSegmentsAppended) { | 1573 TEST_F(ChunkDemuxerTest, Shutdown_BeforeAllInitSegmentsAppended) { |
| 1577 EXPECT_CALL(*this, DemuxerOpened()); | 1574 EXPECT_CALL(*this, DemuxerOpened()); |
| 1578 demuxer_->Initialize( | 1575 demuxer_->Initialize(&host_, base::Bind(&ChunkDemuxerTest::DemuxerInitialized, |
| 1579 &host_, CreateInitDoneCB( | 1576 base::Unretained(this)), |
| 1580 kDefaultDuration(), DEMUXER_ERROR_COULD_NOT_OPEN), true); | 1577 true); |
| 1581 | 1578 |
| 1582 EXPECT_EQ(AddId("audio", HAS_AUDIO), ChunkDemuxer::kOk); | 1579 EXPECT_EQ(AddId("audio", HAS_AUDIO), ChunkDemuxer::kOk); |
| 1583 EXPECT_EQ(AddId("video", HAS_VIDEO), ChunkDemuxer::kOk); | 1580 EXPECT_EQ(AddId("video", HAS_VIDEO), ChunkDemuxer::kOk); |
| 1584 | 1581 |
| 1585 ExpectInitMediaLogs(HAS_AUDIO); | 1582 ExpectInitMediaLogs(HAS_AUDIO); |
| 1586 EXPECT_CALL(*this, InitSegmentReceivedMock(_)); | 1583 EXPECT_CALL(*this, InitSegmentReceivedMock(_)); |
| 1587 ASSERT_TRUE(AppendInitSegmentWithSourceId("audio", HAS_AUDIO)); | 1584 ASSERT_TRUE(AppendInitSegmentWithSourceId("audio", HAS_AUDIO)); |
| 1588 | 1585 |
| 1589 ShutdownDemuxer(); | 1586 ShutdownDemuxer(); |
| 1590 } | 1587 } |
| 1591 | 1588 |
| 1592 TEST_F(ChunkDemuxerTest, Shutdown_BeforeAllInitSegmentsAppendedText) { | 1589 TEST_F(ChunkDemuxerTest, Shutdown_BeforeAllInitSegmentsAppendedText) { |
| 1593 EXPECT_CALL(*this, DemuxerOpened()); | 1590 EXPECT_CALL(*this, DemuxerOpened()); |
| 1594 demuxer_->Initialize( | 1591 demuxer_->Initialize(&host_, base::Bind(&ChunkDemuxerTest::DemuxerInitialized, |
| 1595 &host_, CreateInitDoneCB( | 1592 base::Unretained(this)), |
| 1596 kDefaultDuration(), DEMUXER_ERROR_COULD_NOT_OPEN), true); | 1593 true); |
| 1597 | 1594 |
| 1598 EXPECT_EQ(AddId("audio", HAS_AUDIO), ChunkDemuxer::kOk); | 1595 EXPECT_EQ(AddId("audio", HAS_AUDIO), ChunkDemuxer::kOk); |
| 1599 EXPECT_EQ(AddId("video_and_text", HAS_VIDEO), ChunkDemuxer::kOk); | 1596 EXPECT_EQ(AddId("video_and_text", HAS_VIDEO), ChunkDemuxer::kOk); |
| 1600 | 1597 |
| 1601 EXPECT_CALL(host_, AddTextStream(_, _)) | 1598 EXPECT_CALL(host_, AddTextStream(_, _)) |
| 1602 .Times(Exactly(1)); | 1599 .Times(Exactly(1)); |
| 1603 | 1600 |
| 1604 ExpectInitMediaLogs(HAS_VIDEO); | 1601 ExpectInitMediaLogs(HAS_VIDEO); |
| 1605 EXPECT_CALL(*this, InitSegmentReceivedMock(_)); | 1602 EXPECT_CALL(*this, InitSegmentReceivedMock(_)); |
| 1606 ASSERT_TRUE( | 1603 ASSERT_TRUE( |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1657 | 1654 |
| 1658 ASSERT_TRUE(AppendCluster(kDefaultSecondCluster())); | 1655 ASSERT_TRUE(AppendCluster(kDefaultSecondCluster())); |
| 1659 | 1656 |
| 1660 base::RunLoop().RunUntilIdle(); | 1657 base::RunLoop().RunUntilIdle(); |
| 1661 | 1658 |
| 1662 Checkpoint(2); | 1659 Checkpoint(2); |
| 1663 } | 1660 } |
| 1664 | 1661 |
| 1665 // Test that parsing errors are handled for clusters appended after init. | 1662 // Test that parsing errors are handled for clusters appended after init. |
| 1666 TEST_F(ChunkDemuxerTest, ErrorWhileParsingClusterAfterInit) { | 1663 TEST_F(ChunkDemuxerTest, ErrorWhileParsingClusterAfterInit) { |
| 1664 InSequence s; |
| 1667 ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO)); | 1665 ASSERT_TRUE(InitDemuxer(HAS_AUDIO | HAS_VIDEO)); |
| 1668 ASSERT_TRUE(AppendCluster(kDefaultFirstCluster())); | |
| 1669 | 1666 |
| 1670 EXPECT_MEDIA_LOG(StreamParsingFailed()); | 1667 EXPECT_MEDIA_LOG(StreamParsingFailed()); |
| 1671 EXPECT_CALL(host_, OnDemuxerError(CHUNK_DEMUXER_ERROR_APPEND_FAILED)); | 1668 EXPECT_CALL(host_, OnDemuxerError(CHUNK_DEMUXER_ERROR_APPEND_FAILED)); |
| 1672 AppendGarbage(); | 1669 AppendGarbage(); |
| 1673 } | 1670 } |
| 1674 | 1671 |
| 1675 // Test the case where a Seek() is requested while the parser | 1672 // Test the case where a Seek() is requested while the parser |
| 1676 // is in the middle of cluster. This is to verify that the parser | 1673 // is in the middle of cluster. This is to verify that the parser |
| 1677 // does not reset itself on a seek. | 1674 // does not reset itself on a seek. |
| 1678 TEST_F(ChunkDemuxerTest, SeekWhileParsingCluster) { | 1675 TEST_F(ChunkDemuxerTest, SeekWhileParsingCluster) { |
| (...skipping 1424 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3103 EXPECT_EQ(DemuxerStream::kOk, status); | 3100 EXPECT_EQ(DemuxerStream::kOk, status); |
| 3104 EXPECT_EQ(kLastAudioTimestamp, last_timestamp); | 3101 EXPECT_EQ(kLastAudioTimestamp, last_timestamp); |
| 3105 | 3102 |
| 3106 ReadUntilNotOkOrEndOfStream(DemuxerStream::VIDEO, &status, &last_timestamp); | 3103 ReadUntilNotOkOrEndOfStream(DemuxerStream::VIDEO, &status, &last_timestamp); |
| 3107 EXPECT_EQ(DemuxerStream::kOk, status); | 3104 EXPECT_EQ(DemuxerStream::kOk, status); |
| 3108 EXPECT_EQ(kLastVideoTimestamp, last_timestamp); | 3105 EXPECT_EQ(kLastVideoTimestamp, last_timestamp); |
| 3109 } | 3106 } |
| 3110 | 3107 |
| 3111 TEST_F(ChunkDemuxerTest, GetBufferedRangesBeforeInitSegment) { | 3108 TEST_F(ChunkDemuxerTest, GetBufferedRangesBeforeInitSegment) { |
| 3112 EXPECT_CALL(*this, DemuxerOpened()); | 3109 EXPECT_CALL(*this, DemuxerOpened()); |
| 3113 demuxer_->Initialize(&host_, CreateInitDoneCB(PIPELINE_OK), true); | 3110 demuxer_->Initialize(&host_, base::Bind(&ChunkDemuxerTest::DemuxerInitialized, |
| 3111 base::Unretained(this)), |
| 3112 true); |
| 3114 ASSERT_EQ(AddId("audio", HAS_AUDIO), ChunkDemuxer::kOk); | 3113 ASSERT_EQ(AddId("audio", HAS_AUDIO), ChunkDemuxer::kOk); |
| 3115 ASSERT_EQ(AddId("video", HAS_VIDEO), ChunkDemuxer::kOk); | 3114 ASSERT_EQ(AddId("video", HAS_VIDEO), ChunkDemuxer::kOk); |
| 3116 | 3115 |
| 3117 CheckExpectedRanges("audio", "{ }"); | 3116 CheckExpectedRanges("audio", "{ }"); |
| 3118 CheckExpectedRanges("video", "{ }"); | 3117 CheckExpectedRanges("video", "{ }"); |
| 3119 } | 3118 } |
| 3120 | 3119 |
| 3121 // Test that Seek() completes successfully when the first cluster | 3120 // Test that Seek() completes successfully when the first cluster |
| 3122 // arrives. | 3121 // arrives. |
| 3123 TEST_F(ChunkDemuxerTest, EndOfStreamDuringSeek) { | 3122 TEST_F(ChunkDemuxerTest, EndOfStreamDuringSeek) { |
| (...skipping 1589 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4713 demuxer_->RemoveId(kId1); | 4712 demuxer_->RemoveId(kId1); |
| 4714 EXPECT_EQ(nullptr, demuxer_->GetStream(DemuxerStream::AUDIO)); | 4713 EXPECT_EQ(nullptr, demuxer_->GetStream(DemuxerStream::AUDIO)); |
| 4715 EXPECT_EQ(nullptr, demuxer_->GetStream(DemuxerStream::VIDEO)); | 4714 EXPECT_EQ(nullptr, demuxer_->GetStream(DemuxerStream::VIDEO)); |
| 4716 } | 4715 } |
| 4717 | 4716 |
| 4718 // TODO(servolk): Add a unit test with multiple audio/video tracks using the | 4717 // TODO(servolk): Add a unit test with multiple audio/video tracks using the |
| 4719 // same codec type in a single SourceBufferState, when WebM parser supports | 4718 // same codec type in a single SourceBufferState, when WebM parser supports |
| 4720 // multiple tracks. crbug.com/646900 | 4719 // multiple tracks. crbug.com/646900 |
| 4721 | 4720 |
| 4722 } // namespace media | 4721 } // namespace media |
| OLD | NEW |