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 <algorithm> | 5 #include <algorithm> |
6 #include <deque> | 6 #include <deque> |
7 #include <string> | 7 #include <string> |
8 | 8 |
9 #include "base/bind.h" | 9 #include "base/bind.h" |
10 #include "base/files/file_path.h" | 10 #include "base/files/file_path.h" |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
76 CHECK(!demuxer_); | 76 CHECK(!demuxer_); |
77 | 77 |
78 EXPECT_CALL(host_, SetTotalBytes(_)).Times(AnyNumber()); | 78 EXPECT_CALL(host_, SetTotalBytes(_)).Times(AnyNumber()); |
79 EXPECT_CALL(host_, AddBufferedByteRange(_, _)).Times(AnyNumber()); | 79 EXPECT_CALL(host_, AddBufferedByteRange(_, _)).Times(AnyNumber()); |
80 EXPECT_CALL(host_, AddBufferedTimeRange(_, _)).Times(AnyNumber()); | 80 EXPECT_CALL(host_, AddBufferedTimeRange(_, _)).Times(AnyNumber()); |
81 | 81 |
82 CreateDataSource(name); | 82 CreateDataSource(name); |
83 | 83 |
84 Demuxer::NeedKeyCB need_key_cb = | 84 Demuxer::NeedKeyCB need_key_cb = |
85 base::Bind(&FFmpegDemuxerTest::NeedKeyCB, base::Unretained(this)); | 85 base::Bind(&FFmpegDemuxerTest::NeedKeyCB, base::Unretained(this)); |
| 86 |
86 demuxer_.reset(new FFmpegDemuxer(message_loop_.message_loop_proxy(), | 87 demuxer_.reset(new FFmpegDemuxer(message_loop_.message_loop_proxy(), |
87 data_source_.get(), | 88 data_source_.get(), |
88 need_key_cb, | 89 need_key_cb, |
89 new MediaLog())); | 90 new MediaLog())); |
90 } | 91 } |
91 | 92 |
92 MOCK_METHOD1(CheckPoint, void(int v)); | 93 MOCK_METHOD1(CheckPoint, void(int v)); |
93 | 94 |
94 void InitializeDemuxer() { | 95 void InitializeDemuxerText(bool enable_text) { |
95 EXPECT_CALL(host_, SetDuration(_)); | 96 EXPECT_CALL(host_, SetDuration(_)); |
96 WaitableMessageLoopEvent event; | 97 WaitableMessageLoopEvent event; |
97 demuxer_->Initialize(&host_, event.GetPipelineStatusCB()); | 98 demuxer_->Initialize(&host_, event.GetPipelineStatusCB(), enable_text); |
98 event.RunAndWaitForStatus(PIPELINE_OK); | 99 event.RunAndWaitForStatus(PIPELINE_OK); |
99 } | 100 } |
100 | 101 |
| 102 void InitializeDemuxer() { |
| 103 InitializeDemuxerText(false); |
| 104 } |
| 105 |
101 MOCK_METHOD2(OnReadDoneCalled, void(int, int64)); | 106 MOCK_METHOD2(OnReadDoneCalled, void(int, int64)); |
102 | 107 |
103 // Verifies that |buffer| has a specific |size| and |timestamp|. | 108 // Verifies that |buffer| has a specific |size| and |timestamp|. |
104 // |location| simply indicates where the call to this function was made. | 109 // |location| simply indicates where the call to this function was made. |
105 // This makes it easier to track down where test failures occur. | 110 // This makes it easier to track down where test failures occur. |
106 void OnReadDone(const tracked_objects::Location& location, | 111 void OnReadDone(const tracked_objects::Location& location, |
107 int size, int64 timestampInMicroseconds, | 112 int size, int64 timestampInMicroseconds, |
108 DemuxerStream::Status status, | 113 DemuxerStream::Status status, |
109 const scoped_refptr<DecoderBuffer>& buffer) { | 114 const scoped_refptr<DecoderBuffer>& buffer) { |
110 std::string location_str; | 115 std::string location_str; |
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
192 EXPECT_TRUE(data_source_->Initialize(file_path)); | 197 EXPECT_TRUE(data_source_->Initialize(file_path)); |
193 } | 198 } |
194 | 199 |
195 DISALLOW_COPY_AND_ASSIGN(FFmpegDemuxerTest); | 200 DISALLOW_COPY_AND_ASSIGN(FFmpegDemuxerTest); |
196 }; | 201 }; |
197 | 202 |
198 TEST_F(FFmpegDemuxerTest, Initialize_OpenFails) { | 203 TEST_F(FFmpegDemuxerTest, Initialize_OpenFails) { |
199 // Simulate avformat_open_input() failing. | 204 // Simulate avformat_open_input() failing. |
200 CreateDemuxer("ten_byte_file"); | 205 CreateDemuxer("ten_byte_file"); |
201 WaitableMessageLoopEvent event; | 206 WaitableMessageLoopEvent event; |
202 demuxer_->Initialize(&host_, event.GetPipelineStatusCB()); | 207 demuxer_->Initialize(&host_, event.GetPipelineStatusCB(), true); |
203 event.RunAndWaitForStatus(DEMUXER_ERROR_COULD_NOT_OPEN); | 208 event.RunAndWaitForStatus(DEMUXER_ERROR_COULD_NOT_OPEN); |
204 } | 209 } |
205 | 210 |
206 // TODO(acolwell): Uncomment this test when we discover a file that passes | 211 // TODO(acolwell): Uncomment this test when we discover a file that passes |
207 // avformat_open_input(), but has avformat_find_stream_info() fail. | 212 // avformat_open_input(), but has avformat_find_stream_info() fail. |
208 // | 213 // |
209 //TEST_F(FFmpegDemuxerTest, Initialize_ParseFails) { | 214 //TEST_F(FFmpegDemuxerTest, Initialize_ParseFails) { |
210 // ("find_stream_info_fail.webm"); | 215 // ("find_stream_info_fail.webm"); |
211 // demuxer_->Initialize( | 216 // demuxer_->Initialize( |
212 // &host_, NewExpectedStatusCB(DEMUXER_ERROR_COULD_NOT_PARSE)); | 217 // &host_, NewExpectedStatusCB(DEMUXER_ERROR_COULD_NOT_PARSE)); |
213 // message_loop_.RunUntilIdle(); | 218 // message_loop_.RunUntilIdle(); |
214 //} | 219 //} |
215 | 220 |
216 TEST_F(FFmpegDemuxerTest, Initialize_NoStreams) { | 221 TEST_F(FFmpegDemuxerTest, Initialize_NoStreams) { |
217 // Open a file with no streams whatsoever. | 222 // Open a file with no streams whatsoever. |
218 CreateDemuxer("no_streams.webm"); | 223 CreateDemuxer("no_streams.webm"); |
219 WaitableMessageLoopEvent event; | 224 WaitableMessageLoopEvent event; |
220 demuxer_->Initialize(&host_, event.GetPipelineStatusCB()); | 225 demuxer_->Initialize(&host_, event.GetPipelineStatusCB(), true); |
221 event.RunAndWaitForStatus(DEMUXER_ERROR_NO_SUPPORTED_STREAMS); | 226 event.RunAndWaitForStatus(DEMUXER_ERROR_NO_SUPPORTED_STREAMS); |
222 } | 227 } |
223 | 228 |
224 TEST_F(FFmpegDemuxerTest, Initialize_NoAudioVideo) { | 229 TEST_F(FFmpegDemuxerTest, Initialize_NoAudioVideo) { |
225 // Open a file containing streams but none of which are audio/video streams. | 230 // Open a file containing streams but none of which are audio/video streams. |
226 CreateDemuxer("no_audio_video.webm"); | 231 CreateDemuxer("no_audio_video.webm"); |
227 WaitableMessageLoopEvent event; | 232 WaitableMessageLoopEvent event; |
228 demuxer_->Initialize(&host_, event.GetPipelineStatusCB()); | 233 demuxer_->Initialize(&host_, event.GetPipelineStatusCB(), true); |
229 event.RunAndWaitForStatus(DEMUXER_ERROR_NO_SUPPORTED_STREAMS); | 234 event.RunAndWaitForStatus(DEMUXER_ERROR_NO_SUPPORTED_STREAMS); |
230 } | 235 } |
231 | 236 |
232 TEST_F(FFmpegDemuxerTest, Initialize_Successful) { | 237 TEST_F(FFmpegDemuxerTest, Initialize_Successful) { |
233 CreateDemuxer("bear-320x240.webm"); | 238 CreateDemuxer("bear-320x240.webm"); |
234 InitializeDemuxer(); | 239 InitializeDemuxer(); |
235 | 240 |
236 // Video stream should be present. | 241 // Video stream should be present. |
237 DemuxerStream* stream = demuxer_->GetStream(DemuxerStream::VIDEO); | 242 DemuxerStream* stream = demuxer_->GetStream(DemuxerStream::VIDEO); |
238 ASSERT_TRUE(stream); | 243 ASSERT_TRUE(stream); |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
291 // Audio stream should be Vorbis. | 296 // Audio stream should be Vorbis. |
292 stream = demuxer_->GetStream(DemuxerStream::AUDIO); | 297 stream = demuxer_->GetStream(DemuxerStream::AUDIO); |
293 ASSERT_TRUE(stream); | 298 ASSERT_TRUE(stream); |
294 EXPECT_EQ(DemuxerStream::AUDIO, stream->type()); | 299 EXPECT_EQ(DemuxerStream::AUDIO, stream->type()); |
295 EXPECT_EQ(kCodecVorbis, stream->audio_decoder_config().codec()); | 300 EXPECT_EQ(kCodecVorbis, stream->audio_decoder_config().codec()); |
296 | 301 |
297 // Unknown stream should never be present. | 302 // Unknown stream should never be present. |
298 EXPECT_FALSE(demuxer_->GetStream(DemuxerStream::UNKNOWN)); | 303 EXPECT_FALSE(demuxer_->GetStream(DemuxerStream::UNKNOWN)); |
299 } | 304 } |
300 | 305 |
| 306 TEST_F(FFmpegDemuxerTest, Initialize_MultitrackText) { |
| 307 // Open a file containing the following streams: |
| 308 // Stream #0: Video (VP8) |
| 309 // Stream #1: Audio (Vorbis) |
| 310 // Stream #2: Text (WebVTT) |
| 311 |
| 312 CreateDemuxer("bear-vp8-webvtt.webm"); |
| 313 DemuxerStream* text_stream = NULL; |
| 314 EXPECT_CALL(host_, AddTextStream(_, _)) |
| 315 .WillOnce(SaveArg<0>(&text_stream)); |
| 316 InitializeDemuxerText(true); |
| 317 ASSERT_TRUE(text_stream); |
| 318 EXPECT_EQ(DemuxerStream::TEXT, text_stream->type()); |
| 319 |
| 320 // Video stream should be VP8. |
| 321 DemuxerStream* stream = demuxer_->GetStream(DemuxerStream::VIDEO); |
| 322 ASSERT_TRUE(stream); |
| 323 EXPECT_EQ(DemuxerStream::VIDEO, stream->type()); |
| 324 EXPECT_EQ(kCodecVP8, stream->video_decoder_config().codec()); |
| 325 |
| 326 // Audio stream should be Vorbis. |
| 327 stream = demuxer_->GetStream(DemuxerStream::AUDIO); |
| 328 ASSERT_TRUE(stream); |
| 329 EXPECT_EQ(DemuxerStream::AUDIO, stream->type()); |
| 330 EXPECT_EQ(kCodecVorbis, stream->audio_decoder_config().codec()); |
| 331 |
| 332 // Unknown stream should never be present. |
| 333 EXPECT_FALSE(demuxer_->GetStream(DemuxerStream::UNKNOWN)); |
| 334 } |
| 335 |
301 TEST_F(FFmpegDemuxerTest, Initialize_Encrypted) { | 336 TEST_F(FFmpegDemuxerTest, Initialize_Encrypted) { |
302 EXPECT_CALL(*this, NeedKeyCBMock(kWebMEncryptInitDataType, NotNull(), | 337 EXPECT_CALL(*this, NeedKeyCBMock(kWebMEncryptInitDataType, NotNull(), |
303 DecryptConfig::kDecryptionKeySize)) | 338 DecryptConfig::kDecryptionKeySize)) |
304 .Times(Exactly(2)); | 339 .Times(Exactly(2)); |
305 | 340 |
306 CreateDemuxer("bear-320x240-av_enc-av.webm"); | 341 CreateDemuxer("bear-320x240-av_enc-av.webm"); |
307 InitializeDemuxer(); | 342 InitializeDemuxer(); |
308 } | 343 } |
309 | 344 |
310 TEST_F(FFmpegDemuxerTest, Read_Audio) { | 345 TEST_F(FFmpegDemuxerTest, Read_Audio) { |
(...skipping 19 matching lines...) Expand all Loading... |
330 // Attempt a read from the video stream and run the message loop until done. | 365 // Attempt a read from the video stream and run the message loop until done. |
331 DemuxerStream* video = demuxer_->GetStream(DemuxerStream::VIDEO); | 366 DemuxerStream* video = demuxer_->GetStream(DemuxerStream::VIDEO); |
332 | 367 |
333 video->Read(NewReadCB(FROM_HERE, 22084, 0)); | 368 video->Read(NewReadCB(FROM_HERE, 22084, 0)); |
334 message_loop_.Run(); | 369 message_loop_.Run(); |
335 | 370 |
336 video->Read(NewReadCB(FROM_HERE, 1057, 33000)); | 371 video->Read(NewReadCB(FROM_HERE, 1057, 33000)); |
337 message_loop_.Run(); | 372 message_loop_.Run(); |
338 } | 373 } |
339 | 374 |
| 375 TEST_F(FFmpegDemuxerTest, Read_Text) { |
| 376 // We test that on a successful text packet read. |
| 377 CreateDemuxer("bear-vp8-webvtt.webm"); |
| 378 DemuxerStream* text_stream = NULL; |
| 379 EXPECT_CALL(host_, AddTextStream(_, _)) |
| 380 .WillOnce(SaveArg<0>(&text_stream)); |
| 381 InitializeDemuxerText(true); |
| 382 ASSERT_TRUE(text_stream); |
| 383 EXPECT_EQ(DemuxerStream::TEXT, text_stream->type()); |
| 384 |
| 385 text_stream->Read(NewReadCB(FROM_HERE, 31, 0)); |
| 386 message_loop_.Run(); |
| 387 |
| 388 text_stream->Read(NewReadCB(FROM_HERE, 19, 500000)); |
| 389 message_loop_.Run(); |
| 390 } |
| 391 |
340 TEST_F(FFmpegDemuxerTest, Read_VideoNonZeroStart) { | 392 TEST_F(FFmpegDemuxerTest, Read_VideoNonZeroStart) { |
341 // Test the start time is the first timestamp of the video and audio stream. | 393 // Test the start time is the first timestamp of the video and audio stream. |
342 CreateDemuxer("nonzero-start-time.webm"); | 394 CreateDemuxer("nonzero-start-time.webm"); |
343 InitializeDemuxer(); | 395 InitializeDemuxer(); |
344 | 396 |
345 // Attempt a read from the video stream and run the message loop until done. | 397 // Attempt a read from the video stream and run the message loop until done. |
346 DemuxerStream* video = demuxer_->GetStream(DemuxerStream::VIDEO); | 398 DemuxerStream* video = demuxer_->GetStream(DemuxerStream::VIDEO); |
347 DemuxerStream* audio = demuxer_->GetStream(DemuxerStream::AUDIO); | 399 DemuxerStream* audio = demuxer_->GetStream(DemuxerStream::AUDIO); |
348 | 400 |
349 // Check first buffer in video stream. | 401 // Check first buffer in video stream. |
350 video->Read(NewReadCB(FROM_HERE, 5636, 400000)); | 402 video->Read(NewReadCB(FROM_HERE, 5636, 400000)); |
351 message_loop_.Run(); | 403 message_loop_.Run(); |
352 | 404 |
353 // Check first buffer in audio stream. | 405 // Check first buffer in audio stream. |
354 audio->Read(NewReadCB(FROM_HERE, 165, 396000)); | 406 audio->Read(NewReadCB(FROM_HERE, 165, 396000)); |
355 message_loop_.Run(); | 407 message_loop_.Run(); |
356 | 408 |
357 // Verify that the start time is equal to the lowest timestamp (ie the audio). | 409 // Verify that the start time is equal to the lowest timestamp (ie the audio). |
358 EXPECT_EQ(demuxer_->GetStartTime().InMicroseconds(), 396000); | 410 EXPECT_EQ(demuxer_->GetStartTime().InMicroseconds(), 396000); |
359 } | 411 } |
360 | 412 |
361 TEST_F(FFmpegDemuxerTest, Read_EndOfStream) { | 413 TEST_F(FFmpegDemuxerTest, Read_EndOfStream) { |
362 // Verify that end of stream buffers are created. | 414 // Verify that end of stream buffers are created. |
363 CreateDemuxer("bear-320x240.webm"); | 415 CreateDemuxer("bear-320x240.webm"); |
364 InitializeDemuxer(); | 416 InitializeDemuxer(); |
365 ReadUntilEndOfStream(); | 417 ReadUntilEndOfStream(); |
366 } | 418 } |
367 | 419 |
| 420 TEST_F(FFmpegDemuxerTest, Read_EndOfStreamText) { |
| 421 // Verify that end of stream buffers are created. |
| 422 CreateDemuxer("bear-vp8-webvtt.webm"); |
| 423 DemuxerStream* text_stream = NULL; |
| 424 EXPECT_CALL(host_, AddTextStream(_, _)) |
| 425 .WillOnce(SaveArg<0>(&text_stream)); |
| 426 InitializeDemuxerText(true); |
| 427 ASSERT_TRUE(text_stream); |
| 428 EXPECT_EQ(DemuxerStream::TEXT, text_stream->type()); |
| 429 |
| 430 bool got_eos_buffer = false; |
| 431 const int kMaxBuffers = 10; |
| 432 for (int i = 0; !got_eos_buffer && i < kMaxBuffers; i++) { |
| 433 text_stream->Read(base::Bind(&EosOnReadDone, &got_eos_buffer)); |
| 434 message_loop_.Run(); |
| 435 } |
| 436 |
| 437 EXPECT_TRUE(got_eos_buffer); |
| 438 } |
| 439 |
368 TEST_F(FFmpegDemuxerTest, Read_EndOfStream_NoDuration) { | 440 TEST_F(FFmpegDemuxerTest, Read_EndOfStream_NoDuration) { |
369 // Verify that end of stream buffers are created. | 441 // Verify that end of stream buffers are created. |
370 CreateDemuxer("bear-320x240.webm"); | 442 CreateDemuxer("bear-320x240.webm"); |
371 InitializeDemuxer(); | 443 InitializeDemuxer(); |
372 set_duration_known(false); | 444 set_duration_known(false); |
373 EXPECT_CALL(host_, SetDuration(_)); | 445 EXPECT_CALL(host_, SetDuration(_)); |
374 ReadUntilEndOfStream(); | 446 ReadUntilEndOfStream(); |
375 } | 447 } |
376 | 448 |
377 TEST_F(FFmpegDemuxerTest, Seek) { | 449 TEST_F(FFmpegDemuxerTest, Seek) { |
(...skipping 28 matching lines...) Expand all Loading... |
406 | 478 |
407 // Video read #1. | 479 // Video read #1. |
408 video->Read(NewReadCB(FROM_HERE, 5425, 801000)); | 480 video->Read(NewReadCB(FROM_HERE, 5425, 801000)); |
409 message_loop_.Run(); | 481 message_loop_.Run(); |
410 | 482 |
411 // Video read #2. | 483 // Video read #2. |
412 video->Read(NewReadCB(FROM_HERE, 1906, 834000)); | 484 video->Read(NewReadCB(FROM_HERE, 1906, 834000)); |
413 message_loop_.Run(); | 485 message_loop_.Run(); |
414 } | 486 } |
415 | 487 |
| 488 TEST_F(FFmpegDemuxerTest, SeekText) { |
| 489 // We're testing that the demuxer frees all queued packets when it receives |
| 490 // a Seek(). |
| 491 CreateDemuxer("bear-vp8-webvtt.webm"); |
| 492 DemuxerStream* text_stream = NULL; |
| 493 EXPECT_CALL(host_, AddTextStream(_, _)) |
| 494 .WillOnce(SaveArg<0>(&text_stream)); |
| 495 InitializeDemuxerText(true); |
| 496 ASSERT_TRUE(text_stream); |
| 497 EXPECT_EQ(DemuxerStream::TEXT, text_stream->type()); |
| 498 |
| 499 // Get our streams. |
| 500 DemuxerStream* video = demuxer_->GetStream(DemuxerStream::VIDEO); |
| 501 DemuxerStream* audio = demuxer_->GetStream(DemuxerStream::AUDIO); |
| 502 ASSERT_TRUE(video); |
| 503 ASSERT_TRUE(audio); |
| 504 |
| 505 // Read a text packet and release it. |
| 506 text_stream->Read(NewReadCB(FROM_HERE, 31, 0)); |
| 507 message_loop_.Run(); |
| 508 |
| 509 // Issue a simple forward seek, which should discard queued packets. |
| 510 WaitableMessageLoopEvent event; |
| 511 demuxer_->Seek(base::TimeDelta::FromMicroseconds(1000000), |
| 512 event.GetPipelineStatusCB()); |
| 513 event.RunAndWaitForStatus(PIPELINE_OK); |
| 514 |
| 515 // Audio read #1. |
| 516 audio->Read(NewReadCB(FROM_HERE, 145, 803000)); |
| 517 message_loop_.Run(); |
| 518 |
| 519 // Audio read #2. |
| 520 audio->Read(NewReadCB(FROM_HERE, 148, 826000)); |
| 521 message_loop_.Run(); |
| 522 |
| 523 // Video read #1. |
| 524 video->Read(NewReadCB(FROM_HERE, 5425, 801000)); |
| 525 message_loop_.Run(); |
| 526 |
| 527 // Video read #2. |
| 528 video->Read(NewReadCB(FROM_HERE, 1906, 834000)); |
| 529 message_loop_.Run(); |
| 530 |
| 531 // Text read #1. |
| 532 text_stream->Read(NewReadCB(FROM_HERE, 19, 500000)); |
| 533 message_loop_.Run(); |
| 534 |
| 535 // Text read #2. |
| 536 text_stream->Read(NewReadCB(FROM_HERE, 19, 1000000)); |
| 537 message_loop_.Run(); |
| 538 } |
| 539 |
416 class MockReadCB { | 540 class MockReadCB { |
417 public: | 541 public: |
418 MockReadCB() {} | 542 MockReadCB() {} |
419 ~MockReadCB() {} | 543 ~MockReadCB() {} |
420 | 544 |
421 MOCK_METHOD2(Run, void(DemuxerStream::Status status, | 545 MOCK_METHOD2(Run, void(DemuxerStream::Status status, |
422 const scoped_refptr<DecoderBuffer>& buffer)); | 546 const scoped_refptr<DecoderBuffer>& buffer)); |
423 private: | 547 private: |
424 DISALLOW_COPY_AND_ASSIGN(MockReadCB); | 548 DISALLOW_COPY_AND_ASSIGN(MockReadCB); |
425 }; | 549 }; |
(...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
576 TEST_F(FFmpegDemuxerTest, MP4_ZeroStszEntry) { | 700 TEST_F(FFmpegDemuxerTest, MP4_ZeroStszEntry) { |
577 #if !defined(USE_PROPRIETARY_CODECS) | 701 #if !defined(USE_PROPRIETARY_CODECS) |
578 return; | 702 return; |
579 #endif | 703 #endif |
580 CreateDemuxer("bear-1280x720-zero-stsz-entry.mp4"); | 704 CreateDemuxer("bear-1280x720-zero-stsz-entry.mp4"); |
581 InitializeDemuxer(); | 705 InitializeDemuxer(); |
582 ReadUntilEndOfStream(); | 706 ReadUntilEndOfStream(); |
583 } | 707 } |
584 | 708 |
585 } // namespace media | 709 } // namespace media |
OLD | NEW |