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 <deque> | 5 #include <deque> |
6 | 6 |
7 #include "base/file_path.h" | 7 #include "base/file_path.h" |
| 8 #include "base/file_util.h" |
8 #include "base/path_service.h" | 9 #include "base/path_service.h" |
9 #include "base/threading/thread.h" | 10 #include "base/threading/thread.h" |
10 #include "media/base/filters.h" | 11 #include "media/base/filters.h" |
11 #include "media/base/mock_callback.h" | 12 #include "media/base/mock_callback.h" |
12 #include "media/base/mock_demuxer_host.h" | 13 #include "media/base/mock_demuxer_host.h" |
13 #include "media/base/mock_filters.h" | 14 #include "media/base/mock_filters.h" |
14 #include "media/base/mock_reader.h" | 15 #include "media/base/mock_reader.h" |
15 #include "media/ffmpeg/ffmpeg_common.h" | 16 #include "media/ffmpeg/ffmpeg_common.h" |
16 #include "media/filters/ffmpeg_demuxer.h" | 17 #include "media/filters/ffmpeg_demuxer.h" |
17 #include "media/filters/file_data_source.h" | 18 #include "media/filters/file_data_source.h" |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
65 EXPECT_CALL(host_, SetTotalBytes(_)).Times(AnyNumber()); | 66 EXPECT_CALL(host_, SetTotalBytes(_)).Times(AnyNumber()); |
66 EXPECT_CALL(host_, SetBufferedBytes(_)).Times(AnyNumber()); | 67 EXPECT_CALL(host_, SetBufferedBytes(_)).Times(AnyNumber()); |
67 EXPECT_CALL(host_, SetCurrentReadPosition(_)) | 68 EXPECT_CALL(host_, SetCurrentReadPosition(_)) |
68 .WillRepeatedly(SaveArg<0>(¤t_read_position_)); | 69 .WillRepeatedly(SaveArg<0>(¤t_read_position_)); |
69 | 70 |
70 CreateDataSource(name, disable_file_size); | 71 CreateDataSource(name, disable_file_size); |
71 | 72 |
72 // Create an FFmpegDemuxer with local data source. | 73 // Create an FFmpegDemuxer with local data source. |
73 demuxer_ = new FFmpegDemuxer(&message_loop_, data_source_, true); | 74 demuxer_ = new FFmpegDemuxer(&message_loop_, data_source_, true); |
74 demuxer_->disable_first_seek_hack_for_testing(); | 75 demuxer_->disable_first_seek_hack_for_testing(); |
75 | |
76 // Inject a filter host and message loop and prepare a data source. | |
77 demuxer_->set_host(&host_); | |
78 } | 76 } |
79 | 77 |
80 MOCK_METHOD1(CheckPoint, void(int v)); | 78 MOCK_METHOD1(CheckPoint, void(int v)); |
81 | 79 |
82 void InitializeDemuxer() { | 80 void InitializeDemuxer() { |
83 EXPECT_CALL(host_, SetDuration(_)); | 81 EXPECT_CALL(host_, SetDuration(_)); |
84 demuxer_->Initialize(NewExpectedStatusCB(PIPELINE_OK)); | 82 demuxer_->Initialize(&host_, NewExpectedStatusCB(PIPELINE_OK)); |
85 message_loop_.RunAllPending(); | 83 message_loop_.RunAllPending(); |
86 } | 84 } |
87 | 85 |
88 // Verifies that |buffer| has a specific |size| and |timestamp|. | 86 // Verifies that |buffer| has a specific |size| and |timestamp|. |
89 // |location| simply indicates where the call to this function was made. | 87 // |location| simply indicates where the call to this function was made. |
90 // This makes it easier to track down where test failures occur. | 88 // This makes it easier to track down where test failures occur. |
91 void ValidateBuffer(const tracked_objects::Location& location, | 89 void ValidateBuffer(const tracked_objects::Location& location, |
92 const scoped_refptr<Buffer>& buffer, | 90 const scoped_refptr<Buffer>& buffer, |
93 int size, int64 timestampInMicroseconds) { | 91 int size, int64 timestampInMicroseconds) { |
94 std::string location_str; | 92 std::string location_str; |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
142 EXPECT_EQ(PIPELINE_OK, data_source_->Initialize(file_path.MaybeAsASCII())); | 140 EXPECT_EQ(PIPELINE_OK, data_source_->Initialize(file_path.MaybeAsASCII())); |
143 } | 141 } |
144 | 142 |
145 DISALLOW_COPY_AND_ASSIGN(FFmpegDemuxerTest); | 143 DISALLOW_COPY_AND_ASSIGN(FFmpegDemuxerTest); |
146 }; | 144 }; |
147 | 145 |
148 TEST_F(FFmpegDemuxerTest, Initialize_OpenFails) { | 146 TEST_F(FFmpegDemuxerTest, Initialize_OpenFails) { |
149 // Simulate avformat_open_input() failing. | 147 // Simulate avformat_open_input() failing. |
150 CreateDemuxer("ten_byte_file"), | 148 CreateDemuxer("ten_byte_file"), |
151 EXPECT_CALL(host_, SetCurrentReadPosition(_)); | 149 EXPECT_CALL(host_, SetCurrentReadPosition(_)); |
152 demuxer_->Initialize(NewExpectedStatusCB(DEMUXER_ERROR_COULD_NOT_OPEN)); | 150 demuxer_->Initialize( |
| 151 &host_, NewExpectedStatusCB(DEMUXER_ERROR_COULD_NOT_OPEN)); |
153 | 152 |
154 message_loop_.RunAllPending(); | 153 message_loop_.RunAllPending(); |
155 } | 154 } |
156 | 155 |
157 // TODO(acolwell): Uncomment this test when we discover a file that passes | 156 // TODO(acolwell): Uncomment this test when we discover a file that passes |
158 // avformat_open_input(), but has avformat_find_stream_info() fail. | 157 // avformat_open_input(), but has avformat_find_stream_info() fail. |
159 // | 158 // |
160 //TEST_F(FFmpegDemuxerTest, Initialize_ParseFails) { | 159 //TEST_F(FFmpegDemuxerTest, Initialize_ParseFails) { |
161 // CreateDemuxer("find_stream_info_fail.webm"); | 160 // CreateDemuxer("find_stream_info_fail.webm"); |
162 // demuxer_->Initialize( | 161 // demuxer_->Initialize( |
163 // NewExpectedStatusCB(DEMUXER_ERROR_COULD_NOT_PARSE)); | 162 // &host_, NewExpectedStatusCB(DEMUXER_ERROR_COULD_NOT_PARSE)); |
164 // message_loop_.RunAllPending(); | 163 // message_loop_.RunAllPending(); |
165 //} | 164 //} |
166 | 165 |
167 TEST_F(FFmpegDemuxerTest, Initialize_NoStreams) { | 166 TEST_F(FFmpegDemuxerTest, Initialize_NoStreams) { |
168 // Open a file with no streams whatsoever. | 167 // Open a file with no streams whatsoever. |
169 CreateDemuxer("no_streams.webm"); | 168 CreateDemuxer("no_streams.webm"); |
170 EXPECT_CALL(host_, SetCurrentReadPosition(_)); | 169 EXPECT_CALL(host_, SetCurrentReadPosition(_)); |
171 demuxer_->Initialize( | 170 demuxer_->Initialize( |
172 NewExpectedStatusCB(DEMUXER_ERROR_NO_SUPPORTED_STREAMS)); | 171 &host_, NewExpectedStatusCB(DEMUXER_ERROR_NO_SUPPORTED_STREAMS)); |
173 message_loop_.RunAllPending(); | 172 message_loop_.RunAllPending(); |
174 } | 173 } |
175 | 174 |
176 TEST_F(FFmpegDemuxerTest, Initialize_NoAudioVideo) { | 175 TEST_F(FFmpegDemuxerTest, Initialize_NoAudioVideo) { |
177 // Open a file containing streams but none of which are audio/video streams. | 176 // Open a file containing streams but none of which are audio/video streams. |
178 CreateDemuxer("no_audio_video.webm"); | 177 CreateDemuxer("no_audio_video.webm"); |
179 demuxer_->Initialize( | 178 demuxer_->Initialize( |
180 NewExpectedStatusCB(DEMUXER_ERROR_NO_SUPPORTED_STREAMS)); | 179 &host_, NewExpectedStatusCB(DEMUXER_ERROR_NO_SUPPORTED_STREAMS)); |
181 message_loop_.RunAllPending(); | 180 message_loop_.RunAllPending(); |
182 } | 181 } |
183 | 182 |
184 TEST_F(FFmpegDemuxerTest, Initialize_Successful) { | 183 TEST_F(FFmpegDemuxerTest, Initialize_Successful) { |
185 CreateDemuxer("bear-320x240.webm"); | 184 CreateDemuxer("bear-320x240.webm"); |
186 InitializeDemuxer(); | 185 InitializeDemuxer(); |
187 | 186 |
188 // Video stream should be present. | 187 // Video stream should be present. |
189 scoped_refptr<DemuxerStream> stream = | 188 scoped_refptr<DemuxerStream> stream = |
190 demuxer_->GetStream(DemuxerStream::VIDEO); | 189 demuxer_->GetStream(DemuxerStream::VIDEO); |
(...skipping 360 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
551 ValidateBuffer(FROM_HERE, reader->buffer(), 22084, 0); | 550 ValidateBuffer(FROM_HERE, reader->buffer(), 22084, 0); |
552 | 551 |
553 // Attempt a read from the audio stream: it should immediately return end of | 552 // Attempt a read from the audio stream: it should immediately return end of |
554 // stream without requiring the message loop to read data. | 553 // stream without requiring the message loop to read data. |
555 reader->Reset(); | 554 reader->Reset(); |
556 reader->Read(audio); | 555 reader->Read(audio); |
557 ASSERT_TRUE(reader->called()); | 556 ASSERT_TRUE(reader->called()); |
558 EXPECT_TRUE(reader->buffer()->IsEndOfStream()); | 557 EXPECT_TRUE(reader->buffer()->IsEndOfStream()); |
559 } | 558 } |
560 | 559 |
561 class MockFFmpegDemuxer : public FFmpegDemuxer { | 560 TEST_F(FFmpegDemuxerTest, ProtocolRead) { |
562 public: | 561 CreateDemuxer("bear-320x240.webm"); |
563 MockFFmpegDemuxer(MessageLoop* message_loop, | 562 InitializeDemuxer(); |
564 const scoped_refptr<DataSource>& data_source) | |
565 : FFmpegDemuxer(message_loop, data_source, true) { | |
566 } | |
567 virtual ~MockFFmpegDemuxer() {} | |
568 | 563 |
569 MOCK_METHOD0(WaitForRead, int()); | 564 // Set read head to zero as Initialize() will have parsed a bit of the file. |
570 MOCK_METHOD1(SignalReadCompleted, void(int size)); | 565 int64 position = 0; |
| 566 EXPECT_TRUE(demuxer_->SetPosition(0)); |
| 567 EXPECT_TRUE(demuxer_->GetPosition(&position)); |
| 568 EXPECT_EQ(0, position); |
571 | 569 |
572 private: | 570 // Read 32 bytes from offset zero and verify position. |
573 DISALLOW_COPY_AND_ASSIGN(MockFFmpegDemuxer); | 571 uint8 buffer[32]; |
574 }; | 572 EXPECT_EQ(32u, demuxer_->Read(32, buffer)); |
| 573 EXPECT_EQ(32, current_read_position_); |
| 574 EXPECT_TRUE(demuxer_->GetPosition(&position)); |
| 575 EXPECT_EQ(32, position); |
575 | 576 |
576 // A gmock helper method to execute the callback and deletes it. | 577 // Read an additional 32 bytes and verify position. |
577 void RunCallback(int size, const DataSource::ReadCB& callback) { | 578 EXPECT_EQ(32u, demuxer_->Read(32, buffer)); |
578 DCHECK(!callback.is_null()); | 579 EXPECT_EQ(64, current_read_position_); |
579 callback.Run(size); | 580 EXPECT_TRUE(demuxer_->GetPosition(&position)); |
580 } | 581 EXPECT_EQ(64, position); |
581 | 582 |
582 TEST_F(FFmpegDemuxerTest, ProtocolRead) { | 583 // Seek to end and read until EOF. |
583 scoped_refptr<StrictMock<MockDataSource> > data_source = | 584 int64 size = 0; |
584 new StrictMock<MockDataSource>(); | 585 EXPECT_TRUE(demuxer_->GetSize(&size)); |
| 586 EXPECT_TRUE(demuxer_->SetPosition(size - 48)); |
| 587 EXPECT_EQ(32u, demuxer_->Read(32, buffer)); |
| 588 EXPECT_EQ(size - 16, current_read_position_); |
| 589 EXPECT_TRUE(demuxer_->GetPosition(&position)); |
| 590 EXPECT_EQ(size - 16, position); |
585 | 591 |
586 EXPECT_CALL(*data_source, Stop(_)) | 592 EXPECT_EQ(16u, demuxer_->Read(32, buffer)); |
587 .WillRepeatedly(Invoke(&RunStopFilterCallback)); | 593 EXPECT_EQ(size, current_read_position_); |
| 594 EXPECT_TRUE(demuxer_->GetPosition(&position)); |
| 595 EXPECT_EQ(size, position); |
588 | 596 |
589 // Creates a demuxer. | 597 EXPECT_EQ(0u, demuxer_->Read(32, buffer)); |
590 scoped_refptr<MockFFmpegDemuxer> demuxer( | 598 EXPECT_EQ(size, current_read_position_); |
591 new MockFFmpegDemuxer(&message_loop_, data_source)); | 599 EXPECT_TRUE(demuxer_->GetPosition(&position)); |
592 demuxer->set_host(&host_); | 600 EXPECT_EQ(size, position); |
593 | 601 |
594 uint8 kBuffer[1]; | 602 demuxer_->Stop(NewExpectedClosure()); |
595 InSequence s; | |
596 // Actions taken in the first read. | |
597 EXPECT_CALL(*data_source, GetSize(_)) | |
598 .WillOnce(DoAll(SetArgPointee<0>(1024), Return(true))); | |
599 EXPECT_CALL(*data_source, Read(0, 512, kBuffer, _)) | |
600 .WillOnce(WithArgs<1, 3>(Invoke(&RunCallback))); | |
601 EXPECT_CALL(*demuxer, SignalReadCompleted(512)); | |
602 EXPECT_CALL(*demuxer, WaitForRead()) | |
603 .WillOnce(Return(512)); | |
604 EXPECT_CALL(host_, SetCurrentReadPosition(512)); | |
605 | |
606 // Second read. | |
607 EXPECT_CALL(*data_source, GetSize(_)) | |
608 .WillOnce(DoAll(SetArgPointee<0>(1024), Return(true))); | |
609 EXPECT_CALL(*data_source, Read(512, 512, kBuffer, _)) | |
610 .WillOnce(WithArgs<1, 3>(Invoke(&RunCallback))); | |
611 EXPECT_CALL(*demuxer, SignalReadCompleted(512)); | |
612 EXPECT_CALL(*demuxer, WaitForRead()) | |
613 .WillOnce(Return(512)); | |
614 EXPECT_CALL(host_, SetCurrentReadPosition(1024)); | |
615 | |
616 // Third read will fail because it exceeds the file size. | |
617 EXPECT_CALL(*data_source, GetSize(_)) | |
618 .WillOnce(DoAll(SetArgPointee<0>(1024), Return(true))); | |
619 | |
620 // First read. | |
621 EXPECT_EQ(512u, demuxer->Read(512, kBuffer)); | |
622 int64 position; | |
623 EXPECT_TRUE(demuxer->GetPosition(&position)); | |
624 EXPECT_EQ(512, position); | |
625 | |
626 // Second read. | |
627 EXPECT_EQ(512u, demuxer->Read(512, kBuffer)); | |
628 EXPECT_TRUE(demuxer->GetPosition(&position)); | |
629 EXPECT_EQ(1024, position); | |
630 | |
631 // Third read will get an end-of-file error, which is represented as zero. | |
632 EXPECT_EQ(0u, demuxer->Read(512, kBuffer)); | |
633 | |
634 // This read complete signal is generated when demuxer is stopped. | |
635 EXPECT_CALL(*demuxer, SignalReadCompleted(DataSource::kReadError)); | |
636 demuxer->Stop(NewExpectedClosure()); | |
637 message_loop_.RunAllPending(); | 603 message_loop_.RunAllPending(); |
638 } | 604 } |
639 | 605 |
640 TEST_F(FFmpegDemuxerTest, GetBitrate_SetInContainer) { | 606 TEST_F(FFmpegDemuxerTest, GetBitrate_SetInContainer) { |
641 EXPECT_TRUE(VideoHasValidBitrate("bear.ogv", false)); | 607 EXPECT_TRUE(VideoHasValidBitrate("bear.ogv", false)); |
642 } | 608 } |
643 | 609 |
644 TEST_F(FFmpegDemuxerTest, GetBitrate_UnsetInContainer_KnownSize) { | 610 TEST_F(FFmpegDemuxerTest, GetBitrate_UnsetInContainer_KnownSize) { |
645 EXPECT_TRUE(VideoHasValidBitrate("bear-320x240.webm", false)); | 611 EXPECT_TRUE(VideoHasValidBitrate("bear-320x240.webm", false)); |
646 } | 612 } |
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
749 message_loop_.RunAllPending(); | 715 message_loop_.RunAllPending(); |
750 EXPECT_TRUE(reader->called()); | 716 EXPECT_TRUE(reader->called()); |
751 ValidateBuffer(FROM_HERE, reader->buffer(), 1740, 2436000); | 717 ValidateBuffer(FROM_HERE, reader->buffer(), 1740, 2436000); |
752 | 718 |
753 // Manually release the last reference to the buffer and verify it was freed. | 719 // Manually release the last reference to the buffer and verify it was freed. |
754 reader->Reset(); | 720 reader->Reset(); |
755 message_loop_.RunAllPending(); | 721 message_loop_.RunAllPending(); |
756 } | 722 } |
757 | 723 |
758 } // namespace media | 724 } // namespace media |
OLD | NEW |