OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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/path_service.h" | 8 #include "base/path_service.h" |
9 #include "base/threading/thread.h" | 9 #include "base/threading/thread.h" |
10 #include "media/base/filters.h" | 10 #include "media/base/filters.h" |
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
119 // when streaming video). Uses this data source to initialize a demuxer, then | 119 // when streaming video). Uses this data source to initialize a demuxer, then |
120 // returns true if the bitrate is valid, false otherwise. | 120 // returns true if the bitrate is valid, false otherwise. |
121 bool VideoHasValidBitrate( | 121 bool VideoHasValidBitrate( |
122 const std::string& file_name, bool disable_file_size) { | 122 const std::string& file_name, bool disable_file_size) { |
123 scoped_refptr<FileDataSource> data_source = | 123 scoped_refptr<FileDataSource> data_source = |
124 CreateDataSource(file_name, disable_file_size); | 124 CreateDataSource(file_name, disable_file_size); |
125 InitializeDemuxer(data_source); | 125 InitializeDemuxer(data_source); |
126 return demuxer_->GetBitrate() > 0; | 126 return demuxer_->GetBitrate() > 0; |
127 } | 127 } |
128 | 128 |
| 129 bool IsStreamStopped(DemuxerStream::Type type) { |
| 130 DemuxerStream* stream = demuxer_->GetStream(type); |
| 131 CHECK(stream); |
| 132 return static_cast<FFmpegDemuxerStream*>(stream)->stopped_; |
| 133 } |
| 134 |
129 // Fixture members. | 135 // Fixture members. |
130 scoped_refptr<FFmpegDemuxer> demuxer_; | 136 scoped_refptr<FFmpegDemuxer> demuxer_; |
131 StrictMock<MockFilterHost> host_; | 137 StrictMock<MockFilterHost> host_; |
132 MessageLoop message_loop_; | 138 MessageLoop message_loop_; |
133 | 139 |
134 int64 current_read_position_; | 140 int64 current_read_position_; |
135 | 141 |
136 private: | 142 private: |
137 DISALLOW_COPY_AND_ASSIGN(FFmpegDemuxerTest); | 143 DISALLOW_COPY_AND_ASSIGN(FFmpegDemuxerTest); |
138 }; | 144 }; |
(...skipping 11 matching lines...) Expand all Loading... |
150 // av_open_input_file(), but has av_find_stream_info() fail. | 156 // av_open_input_file(), but has av_find_stream_info() fail. |
151 // | 157 // |
152 //TEST_F(FFmpegDemuxerTest, Initialize_ParseFails) { | 158 //TEST_F(FFmpegDemuxerTest, Initialize_ParseFails) { |
153 // demuxer_->Initialize( | 159 // demuxer_->Initialize( |
154 // CreateDataSource("find_stream_info_fail.webm"), | 160 // CreateDataSource("find_stream_info_fail.webm"), |
155 // NewExpectedStatusCB(DEMUXER_ERROR_COULD_NOT_PARSE)); | 161 // NewExpectedStatusCB(DEMUXER_ERROR_COULD_NOT_PARSE)); |
156 // message_loop_.RunAllPending(); | 162 // message_loop_.RunAllPending(); |
157 //} | 163 //} |
158 | 164 |
159 TEST_F(FFmpegDemuxerTest, Initialize_NoStreams) { | 165 TEST_F(FFmpegDemuxerTest, Initialize_NoStreams) { |
160 // Open a file with no parseable streams. | 166 // Open a file with no streams whatsoever. |
161 EXPECT_CALL(host_, SetCurrentReadPosition(_)); | 167 EXPECT_CALL(host_, SetCurrentReadPosition(_)); |
162 demuxer_->Initialize( | 168 demuxer_->Initialize( |
163 CreateDataSource("no_streams.webm"), | 169 CreateDataSource("no_streams.webm"), |
164 NewExpectedStatusCB(DEMUXER_ERROR_NO_SUPPORTED_STREAMS)); | 170 NewExpectedStatusCB(DEMUXER_ERROR_NO_SUPPORTED_STREAMS)); |
165 message_loop_.RunAllPending(); | 171 message_loop_.RunAllPending(); |
166 } | 172 } |
167 | 173 |
168 // TODO(acolwell): Find a subtitle only file so we can uncomment this test. | 174 TEST_F(FFmpegDemuxerTest, Initialize_NoAudioVideo) { |
169 // | 175 // Open a file containing streams but none of which are audio/video streams. |
170 //TEST_F(FFmpegDemuxerTest, Initialize_DataStreamOnly) { | 176 demuxer_->Initialize( |
171 // demuxer_->Initialize( | 177 CreateDataSource("no_audio_video.webm"), |
172 // CreateDataSource("subtitles_only.mp4"),, | 178 NewExpectedStatusCB(DEMUXER_ERROR_NO_SUPPORTED_STREAMS)); |
173 // NewExpectedStatusCB(DEMUXER_ERROR_NO_SUPPORTED_STREAMS)); | 179 message_loop_.RunAllPending(); |
174 // message_loop_.RunAllPending(); | 180 } |
175 //} | |
176 | 181 |
177 TEST_F(FFmpegDemuxerTest, Initialize_Successful) { | 182 TEST_F(FFmpegDemuxerTest, Initialize_Successful) { |
178 InitializeDemuxer(CreateDataSource("bear-320x240.webm")); | 183 InitializeDemuxer(CreateDataSource("bear-320x240.webm")); |
179 | 184 |
180 // Video stream should be present. | 185 // Video stream should be present. |
181 scoped_refptr<DemuxerStream> stream = | 186 scoped_refptr<DemuxerStream> stream = |
182 demuxer_->GetStream(DemuxerStream::VIDEO); | 187 demuxer_->GetStream(DemuxerStream::VIDEO); |
183 ASSERT_TRUE(stream); | 188 ASSERT_TRUE(stream); |
184 EXPECT_EQ(DemuxerStream::VIDEO, stream->type()); | 189 EXPECT_EQ(DemuxerStream::VIDEO, stream->type()); |
185 | 190 |
(...skipping 18 matching lines...) Expand all Loading... |
204 ASSERT_TRUE(stream); | 209 ASSERT_TRUE(stream); |
205 EXPECT_EQ(DemuxerStream::AUDIO, stream->type()); | 210 EXPECT_EQ(DemuxerStream::AUDIO, stream->type()); |
206 | 211 |
207 const AudioDecoderConfig& audio_config = stream->audio_decoder_config(); | 212 const AudioDecoderConfig& audio_config = stream->audio_decoder_config(); |
208 EXPECT_EQ(kCodecVorbis, audio_config.codec()); | 213 EXPECT_EQ(kCodecVorbis, audio_config.codec()); |
209 EXPECT_EQ(16, audio_config.bits_per_channel()); | 214 EXPECT_EQ(16, audio_config.bits_per_channel()); |
210 EXPECT_EQ(CHANNEL_LAYOUT_STEREO, audio_config.channel_layout()); | 215 EXPECT_EQ(CHANNEL_LAYOUT_STEREO, audio_config.channel_layout()); |
211 EXPECT_EQ(44100, audio_config.samples_per_second()); | 216 EXPECT_EQ(44100, audio_config.samples_per_second()); |
212 EXPECT_TRUE(audio_config.extra_data()); | 217 EXPECT_TRUE(audio_config.extra_data()); |
213 EXPECT_GT(audio_config.extra_data_size(), 0u); | 218 EXPECT_GT(audio_config.extra_data_size(), 0u); |
| 219 |
| 220 // Unknown stream should never be present. |
| 221 EXPECT_FALSE(demuxer_->GetStream(DemuxerStream::UNKNOWN)); |
| 222 } |
| 223 |
| 224 TEST_F(FFmpegDemuxerTest, Initialize_Multitrack) { |
| 225 // Open a file containing the following streams: |
| 226 // Stream #0: Video (VP8) |
| 227 // Stream #1: Audio (Vorbis) |
| 228 // Stream #2: Subtitles (SRT) |
| 229 // Stream #3: Video (Theora) |
| 230 // Stream #4: Audio (16-bit signed little endian PCM) |
| 231 // |
| 232 // We should only pick the first audio/video streams we come across. |
| 233 InitializeDemuxer(CreateDataSource("bear-320x240-multitrack.webm")); |
| 234 |
| 235 // Video stream should be VP8. |
| 236 scoped_refptr<DemuxerStream> stream = |
| 237 demuxer_->GetStream(DemuxerStream::VIDEO); |
| 238 ASSERT_TRUE(stream); |
| 239 EXPECT_EQ(DemuxerStream::VIDEO, stream->type()); |
| 240 EXPECT_EQ(kCodecVP8, stream->video_decoder_config().codec()); |
| 241 |
| 242 // Audio stream should be Vorbis. |
| 243 stream = demuxer_->GetStream(DemuxerStream::AUDIO); |
| 244 ASSERT_TRUE(stream); |
| 245 EXPECT_EQ(DemuxerStream::AUDIO, stream->type()); |
| 246 EXPECT_EQ(kCodecVorbis, stream->audio_decoder_config().codec()); |
| 247 |
| 248 // Unknown stream should never be present. |
| 249 EXPECT_FALSE(demuxer_->GetStream(DemuxerStream::UNKNOWN)); |
214 } | 250 } |
215 | 251 |
216 TEST_F(FFmpegDemuxerTest, Read_Audio) { | 252 TEST_F(FFmpegDemuxerTest, Read_Audio) { |
217 // We test that on a successful audio packet read. | 253 // We test that on a successful audio packet read. |
218 InitializeDemuxer(CreateDataSource("bear-320x240.webm")); | 254 InitializeDemuxer(CreateDataSource("bear-320x240.webm")); |
219 | 255 |
220 // Attempt a read from the audio stream and run the message loop until done. | 256 // Attempt a read from the audio stream and run the message loop until done. |
221 scoped_refptr<DemuxerStream> audio = | 257 scoped_refptr<DemuxerStream> audio = |
222 demuxer_->GetStream(DemuxerStream::AUDIO); | 258 demuxer_->GetStream(DemuxerStream::AUDIO); |
223 scoped_refptr<DemuxerStreamReader> reader(new DemuxerStreamReader()); | 259 scoped_refptr<DemuxerStreamReader> reader(new DemuxerStreamReader()); |
(...skipping 260 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
484 message_loop_.RunAllPending(); | 520 message_loop_.RunAllPending(); |
485 | 521 |
486 // Get our streams. | 522 // Get our streams. |
487 scoped_refptr<DemuxerStream> video = | 523 scoped_refptr<DemuxerStream> video = |
488 demuxer_->GetStream(DemuxerStream::VIDEO); | 524 demuxer_->GetStream(DemuxerStream::VIDEO); |
489 scoped_refptr<DemuxerStream> audio = | 525 scoped_refptr<DemuxerStream> audio = |
490 demuxer_->GetStream(DemuxerStream::AUDIO); | 526 demuxer_->GetStream(DemuxerStream::AUDIO); |
491 ASSERT_TRUE(video); | 527 ASSERT_TRUE(video); |
492 ASSERT_TRUE(audio); | 528 ASSERT_TRUE(audio); |
493 | 529 |
494 // Attempt a read from the video stream and run the message loop until done. | 530 // The audio stream should have been prematurely stopped. |
| 531 EXPECT_FALSE(IsStreamStopped(DemuxerStream::VIDEO)); |
| 532 EXPECT_TRUE(IsStreamStopped(DemuxerStream::AUDIO)); |
| 533 |
| 534 // Attempt a read from the video stream: it should return valid data. |
495 scoped_refptr<DemuxerStreamReader> reader(new DemuxerStreamReader()); | 535 scoped_refptr<DemuxerStreamReader> reader(new DemuxerStreamReader()); |
496 reader->Read(video); | 536 reader->Read(video); |
497 message_loop_.RunAllPending(); | 537 message_loop_.RunAllPending(); |
498 EXPECT_TRUE(reader->called()); | 538 ASSERT_TRUE(reader->called()); |
499 ValidateBuffer(FROM_HERE, reader->buffer(), 22084, 0); | 539 ValidateBuffer(FROM_HERE, reader->buffer(), 22084, 0); |
500 | 540 |
| 541 // Attempt a read from the audio stream: it should immediately return end of |
| 542 // stream without requiring the message loop to read data. |
501 reader->Reset(); | 543 reader->Reset(); |
502 reader->Read(audio); | 544 reader->Read(audio); |
503 message_loop_.RunAllPending(); | 545 ASSERT_TRUE(reader->called()); |
504 EXPECT_TRUE(reader->called()); | |
505 EXPECT_TRUE(reader->buffer()->IsEndOfStream()); | 546 EXPECT_TRUE(reader->buffer()->IsEndOfStream()); |
506 } | 547 } |
507 | 548 |
508 class MockFFmpegDemuxer : public FFmpegDemuxer { | 549 class MockFFmpegDemuxer : public FFmpegDemuxer { |
509 public: | 550 public: |
510 explicit MockFFmpegDemuxer(MessageLoop* message_loop) | 551 explicit MockFFmpegDemuxer(MessageLoop* message_loop) |
511 : FFmpegDemuxer(message_loop, true) { | 552 : FFmpegDemuxer(message_loop, true) { |
512 } | 553 } |
513 virtual ~MockFFmpegDemuxer() {} | 554 virtual ~MockFFmpegDemuxer() {} |
514 | 555 |
(...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
696 message_loop_.RunAllPending(); | 737 message_loop_.RunAllPending(); |
697 EXPECT_TRUE(reader->called()); | 738 EXPECT_TRUE(reader->called()); |
698 ValidateBuffer(FROM_HERE, reader->buffer(), 1740, 2436000); | 739 ValidateBuffer(FROM_HERE, reader->buffer(), 1740, 2436000); |
699 | 740 |
700 // Manually release the last reference to the buffer and verify it was freed. | 741 // Manually release the last reference to the buffer and verify it was freed. |
701 reader->Reset(); | 742 reader->Reset(); |
702 message_loop_.RunAllPending(); | 743 message_loop_.RunAllPending(); |
703 } | 744 } |
704 | 745 |
705 } // namespace media | 746 } // namespace media |
OLD | NEW |