| 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/file_util.h" | 10 #include "base/file_util.h" |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 59 | 59 |
| 60 | 60 |
| 61 // Fixture class to facilitate writing tests. Takes care of setting up the | 61 // Fixture class to facilitate writing tests. Takes care of setting up the |
| 62 // FFmpeg, pipeline and filter host mocks. | 62 // FFmpeg, pipeline and filter host mocks. |
| 63 class FFmpegDemuxerTest : public testing::Test { | 63 class FFmpegDemuxerTest : public testing::Test { |
| 64 protected: | 64 protected: |
| 65 FFmpegDemuxerTest() {} | 65 FFmpegDemuxerTest() {} |
| 66 | 66 |
| 67 virtual ~FFmpegDemuxerTest() { | 67 virtual ~FFmpegDemuxerTest() { |
| 68 if (demuxer_) { | 68 if (demuxer_) { |
| 69 demuxer_->Stop(base::MessageLoop::QuitWhenIdleClosure()); | 69 WaitableMessageLoopEvent event; |
| 70 message_loop_.Run(); | 70 demuxer_->Stop(event.GetClosure()); |
| 71 event.RunAndWait(); |
| 71 } | 72 } |
| 72 } | 73 } |
| 73 | 74 |
| 74 void CreateDemuxer(const std::string& name) { | 75 void CreateDemuxer(const std::string& name) { |
| 75 CHECK(!demuxer_); | 76 CHECK(!demuxer_); |
| 76 | 77 |
| 77 EXPECT_CALL(host_, SetTotalBytes(_)).Times(AnyNumber()); | 78 EXPECT_CALL(host_, SetTotalBytes(_)).Times(AnyNumber()); |
| 78 EXPECT_CALL(host_, AddBufferedByteRange(_, _)).Times(AnyNumber()); | 79 EXPECT_CALL(host_, AddBufferedByteRange(_, _)).Times(AnyNumber()); |
| 79 EXPECT_CALL(host_, AddBufferedTimeRange(_, _)).Times(AnyNumber()); | 80 EXPECT_CALL(host_, AddBufferedTimeRange(_, _)).Times(AnyNumber()); |
| 80 | 81 |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 153 scoped_ptr<FFmpegDemuxer> demuxer_; | 154 scoped_ptr<FFmpegDemuxer> demuxer_; |
| 154 StrictMock<MockDemuxerHost> host_; | 155 StrictMock<MockDemuxerHost> host_; |
| 155 base::MessageLoop message_loop_; | 156 base::MessageLoop message_loop_; |
| 156 | 157 |
| 157 AVFormatContext* format_context() { | 158 AVFormatContext* format_context() { |
| 158 return demuxer_->glue_->format_context(); | 159 return demuxer_->glue_->format_context(); |
| 159 } | 160 } |
| 160 | 161 |
| 161 void ReadUntilEndOfStream() { | 162 void ReadUntilEndOfStream() { |
| 162 // We should expect an end of stream buffer. | 163 // We should expect an end of stream buffer. |
| 163 scoped_refptr<DemuxerStream> audio = | 164 DemuxerStream* audio = demuxer_->GetStream(DemuxerStream::AUDIO); |
| 164 demuxer_->GetStream(DemuxerStream::AUDIO); | |
| 165 | 165 |
| 166 bool got_eos_buffer = false; | 166 bool got_eos_buffer = false; |
| 167 const int kMaxBuffers = 170; | 167 const int kMaxBuffers = 170; |
| 168 for (int i = 0; !got_eos_buffer && i < kMaxBuffers; i++) { | 168 for (int i = 0; !got_eos_buffer && i < kMaxBuffers; i++) { |
| 169 audio->Read(base::Bind(&EosOnReadDone, &got_eos_buffer)); | 169 audio->Read(base::Bind(&EosOnReadDone, &got_eos_buffer)); |
| 170 message_loop_.Run(); | 170 message_loop_.Run(); |
| 171 } | 171 } |
| 172 | 172 |
| 173 EXPECT_TRUE(got_eos_buffer); | 173 EXPECT_TRUE(got_eos_buffer); |
| 174 } | 174 } |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 224 WaitableMessageLoopEvent event; | 224 WaitableMessageLoopEvent event; |
| 225 demuxer_->Initialize(&host_, event.GetPipelineStatusCB()); | 225 demuxer_->Initialize(&host_, event.GetPipelineStatusCB()); |
| 226 event.RunAndWaitForStatus(DEMUXER_ERROR_NO_SUPPORTED_STREAMS); | 226 event.RunAndWaitForStatus(DEMUXER_ERROR_NO_SUPPORTED_STREAMS); |
| 227 } | 227 } |
| 228 | 228 |
| 229 TEST_F(FFmpegDemuxerTest, Initialize_Successful) { | 229 TEST_F(FFmpegDemuxerTest, Initialize_Successful) { |
| 230 CreateDemuxer("bear-320x240.webm"); | 230 CreateDemuxer("bear-320x240.webm"); |
| 231 InitializeDemuxer(); | 231 InitializeDemuxer(); |
| 232 | 232 |
| 233 // Video stream should be present. | 233 // Video stream should be present. |
| 234 scoped_refptr<DemuxerStream> stream = | 234 DemuxerStream* stream = demuxer_->GetStream(DemuxerStream::VIDEO); |
| 235 demuxer_->GetStream(DemuxerStream::VIDEO); | |
| 236 ASSERT_TRUE(stream); | 235 ASSERT_TRUE(stream); |
| 237 EXPECT_EQ(DemuxerStream::VIDEO, stream->type()); | 236 EXPECT_EQ(DemuxerStream::VIDEO, stream->type()); |
| 238 | 237 |
| 239 const VideoDecoderConfig& video_config = stream->video_decoder_config(); | 238 const VideoDecoderConfig& video_config = stream->video_decoder_config(); |
| 240 EXPECT_EQ(kCodecVP8, video_config.codec()); | 239 EXPECT_EQ(kCodecVP8, video_config.codec()); |
| 241 EXPECT_EQ(VideoFrame::YV12, video_config.format()); | 240 EXPECT_EQ(VideoFrame::YV12, video_config.format()); |
| 242 EXPECT_EQ(320, video_config.coded_size().width()); | 241 EXPECT_EQ(320, video_config.coded_size().width()); |
| 243 EXPECT_EQ(240, video_config.coded_size().height()); | 242 EXPECT_EQ(240, video_config.coded_size().height()); |
| 244 EXPECT_EQ(0, video_config.visible_rect().x()); | 243 EXPECT_EQ(0, video_config.visible_rect().x()); |
| 245 EXPECT_EQ(0, video_config.visible_rect().y()); | 244 EXPECT_EQ(0, video_config.visible_rect().y()); |
| (...skipping 28 matching lines...) Expand all Loading... |
| 274 // Stream #1: Audio (Vorbis) | 273 // Stream #1: Audio (Vorbis) |
| 275 // Stream #2: Subtitles (SRT) | 274 // Stream #2: Subtitles (SRT) |
| 276 // Stream #3: Video (Theora) | 275 // Stream #3: Video (Theora) |
| 277 // Stream #4: Audio (16-bit signed little endian PCM) | 276 // Stream #4: Audio (16-bit signed little endian PCM) |
| 278 // | 277 // |
| 279 // We should only pick the first audio/video streams we come across. | 278 // We should only pick the first audio/video streams we come across. |
| 280 CreateDemuxer("bear-320x240-multitrack.webm"); | 279 CreateDemuxer("bear-320x240-multitrack.webm"); |
| 281 InitializeDemuxer(); | 280 InitializeDemuxer(); |
| 282 | 281 |
| 283 // Video stream should be VP8. | 282 // Video stream should be VP8. |
| 284 scoped_refptr<DemuxerStream> stream = | 283 DemuxerStream* stream = demuxer_->GetStream(DemuxerStream::VIDEO); |
| 285 demuxer_->GetStream(DemuxerStream::VIDEO); | |
| 286 ASSERT_TRUE(stream); | 284 ASSERT_TRUE(stream); |
| 287 EXPECT_EQ(DemuxerStream::VIDEO, stream->type()); | 285 EXPECT_EQ(DemuxerStream::VIDEO, stream->type()); |
| 288 EXPECT_EQ(kCodecVP8, stream->video_decoder_config().codec()); | 286 EXPECT_EQ(kCodecVP8, stream->video_decoder_config().codec()); |
| 289 | 287 |
| 290 // Audio stream should be Vorbis. | 288 // Audio stream should be Vorbis. |
| 291 stream = demuxer_->GetStream(DemuxerStream::AUDIO); | 289 stream = demuxer_->GetStream(DemuxerStream::AUDIO); |
| 292 ASSERT_TRUE(stream); | 290 ASSERT_TRUE(stream); |
| 293 EXPECT_EQ(DemuxerStream::AUDIO, stream->type()); | 291 EXPECT_EQ(DemuxerStream::AUDIO, stream->type()); |
| 294 EXPECT_EQ(kCodecVorbis, stream->audio_decoder_config().codec()); | 292 EXPECT_EQ(kCodecVorbis, stream->audio_decoder_config().codec()); |
| 295 | 293 |
| (...skipping 11 matching lines...) Expand all Loading... |
| 307 CreateDemuxer("bear-320x240-av_enc-av.webm"); | 305 CreateDemuxer("bear-320x240-av_enc-av.webm"); |
| 308 InitializeDemuxer(); | 306 InitializeDemuxer(); |
| 309 } | 307 } |
| 310 | 308 |
| 311 TEST_F(FFmpegDemuxerTest, Read_Audio) { | 309 TEST_F(FFmpegDemuxerTest, Read_Audio) { |
| 312 // We test that on a successful audio packet read. | 310 // We test that on a successful audio packet read. |
| 313 CreateDemuxer("bear-320x240.webm"); | 311 CreateDemuxer("bear-320x240.webm"); |
| 314 InitializeDemuxer(); | 312 InitializeDemuxer(); |
| 315 | 313 |
| 316 // Attempt a read from the audio stream and run the message loop until done. | 314 // Attempt a read from the audio stream and run the message loop until done. |
| 317 scoped_refptr<DemuxerStream> audio = | 315 DemuxerStream* audio = demuxer_->GetStream(DemuxerStream::AUDIO); |
| 318 demuxer_->GetStream(DemuxerStream::AUDIO); | |
| 319 | 316 |
| 320 audio->Read(NewReadCB(FROM_HERE, 29, 0)); | 317 audio->Read(NewReadCB(FROM_HERE, 29, 0)); |
| 321 message_loop_.Run(); | 318 message_loop_.Run(); |
| 322 | 319 |
| 323 audio->Read(NewReadCB(FROM_HERE, 27, 3000)); | 320 audio->Read(NewReadCB(FROM_HERE, 27, 3000)); |
| 324 message_loop_.Run(); | 321 message_loop_.Run(); |
| 325 } | 322 } |
| 326 | 323 |
| 327 TEST_F(FFmpegDemuxerTest, Read_Video) { | 324 TEST_F(FFmpegDemuxerTest, Read_Video) { |
| 328 // We test that on a successful video packet read. | 325 // We test that on a successful video packet read. |
| 329 CreateDemuxer("bear-320x240.webm"); | 326 CreateDemuxer("bear-320x240.webm"); |
| 330 InitializeDemuxer(); | 327 InitializeDemuxer(); |
| 331 | 328 |
| 332 // Attempt a read from the video stream and run the message loop until done. | 329 // Attempt a read from the video stream and run the message loop until done. |
| 333 scoped_refptr<DemuxerStream> video = | 330 DemuxerStream* video = demuxer_->GetStream(DemuxerStream::VIDEO); |
| 334 demuxer_->GetStream(DemuxerStream::VIDEO); | |
| 335 | 331 |
| 336 video->Read(NewReadCB(FROM_HERE, 22084, 0)); | 332 video->Read(NewReadCB(FROM_HERE, 22084, 0)); |
| 337 message_loop_.Run(); | 333 message_loop_.Run(); |
| 338 | 334 |
| 339 video->Read(NewReadCB(FROM_HERE, 1057, 33000)); | 335 video->Read(NewReadCB(FROM_HERE, 1057, 33000)); |
| 340 message_loop_.Run(); | 336 message_loop_.Run(); |
| 341 } | 337 } |
| 342 | 338 |
| 343 TEST_F(FFmpegDemuxerTest, Read_VideoNonZeroStart) { | 339 TEST_F(FFmpegDemuxerTest, Read_VideoNonZeroStart) { |
| 344 // Test the start time is the first timestamp of the video and audio stream. | 340 // Test the start time is the first timestamp of the video and audio stream. |
| 345 CreateDemuxer("nonzero-start-time.webm"); | 341 CreateDemuxer("nonzero-start-time.webm"); |
| 346 InitializeDemuxer(); | 342 InitializeDemuxer(); |
| 347 | 343 |
| 348 // Attempt a read from the video stream and run the message loop until done. | 344 // Attempt a read from the video stream and run the message loop until done. |
| 349 scoped_refptr<DemuxerStream> video = | 345 DemuxerStream* video = demuxer_->GetStream(DemuxerStream::VIDEO); |
| 350 demuxer_->GetStream(DemuxerStream::VIDEO); | 346 DemuxerStream* audio = demuxer_->GetStream(DemuxerStream::AUDIO); |
| 351 scoped_refptr<DemuxerStream> audio = | |
| 352 demuxer_->GetStream(DemuxerStream::AUDIO); | |
| 353 | 347 |
| 354 // Check first buffer in video stream. | 348 // Check first buffer in video stream. |
| 355 video->Read(NewReadCB(FROM_HERE, 5636, 400000)); | 349 video->Read(NewReadCB(FROM_HERE, 5636, 400000)); |
| 356 message_loop_.Run(); | 350 message_loop_.Run(); |
| 357 | 351 |
| 358 // Check first buffer in audio stream. | 352 // Check first buffer in audio stream. |
| 359 audio->Read(NewReadCB(FROM_HERE, 165, 396000)); | 353 audio->Read(NewReadCB(FROM_HERE, 165, 396000)); |
| 360 message_loop_.Run(); | 354 message_loop_.Run(); |
| 361 | 355 |
| 362 // Verify that the start time is equal to the lowest timestamp (ie the audio). | 356 // Verify that the start time is equal to the lowest timestamp (ie the audio). |
| (...skipping 16 matching lines...) Expand all Loading... |
| 379 ReadUntilEndOfStream(); | 373 ReadUntilEndOfStream(); |
| 380 } | 374 } |
| 381 | 375 |
| 382 TEST_F(FFmpegDemuxerTest, Seek) { | 376 TEST_F(FFmpegDemuxerTest, Seek) { |
| 383 // We're testing that the demuxer frees all queued packets when it receives | 377 // We're testing that the demuxer frees all queued packets when it receives |
| 384 // a Seek(). | 378 // a Seek(). |
| 385 CreateDemuxer("bear-320x240.webm"); | 379 CreateDemuxer("bear-320x240.webm"); |
| 386 InitializeDemuxer(); | 380 InitializeDemuxer(); |
| 387 | 381 |
| 388 // Get our streams. | 382 // Get our streams. |
| 389 scoped_refptr<DemuxerStream> video = | 383 DemuxerStream* video = demuxer_->GetStream(DemuxerStream::VIDEO); |
| 390 demuxer_->GetStream(DemuxerStream::VIDEO); | 384 DemuxerStream* audio = demuxer_->GetStream(DemuxerStream::AUDIO); |
| 391 scoped_refptr<DemuxerStream> audio = | |
| 392 demuxer_->GetStream(DemuxerStream::AUDIO); | |
| 393 ASSERT_TRUE(video); | 385 ASSERT_TRUE(video); |
| 394 ASSERT_TRUE(audio); | 386 ASSERT_TRUE(audio); |
| 395 | 387 |
| 396 // Read a video packet and release it. | 388 // Read a video packet and release it. |
| 397 video->Read(NewReadCB(FROM_HERE, 22084, 0)); | 389 video->Read(NewReadCB(FROM_HERE, 22084, 0)); |
| 398 message_loop_.Run(); | 390 message_loop_.Run(); |
| 399 | 391 |
| 400 // Issue a simple forward seek, which should discard queued packets. | 392 // Issue a simple forward seek, which should discard queued packets. |
| 401 WaitableMessageLoopEvent event; | 393 WaitableMessageLoopEvent event; |
| 402 demuxer_->Seek(base::TimeDelta::FromMicroseconds(1000000), | 394 demuxer_->Seek(base::TimeDelta::FromMicroseconds(1000000), |
| (...skipping 10 matching lines...) Expand all Loading... |
| 413 | 405 |
| 414 // Video read #1. | 406 // Video read #1. |
| 415 video->Read(NewReadCB(FROM_HERE, 5425, 801000)); | 407 video->Read(NewReadCB(FROM_HERE, 5425, 801000)); |
| 416 message_loop_.Run(); | 408 message_loop_.Run(); |
| 417 | 409 |
| 418 // Video read #2. | 410 // Video read #2. |
| 419 video->Read(NewReadCB(FROM_HERE, 1906, 834000)); | 411 video->Read(NewReadCB(FROM_HERE, 1906, 834000)); |
| 420 message_loop_.Run(); | 412 message_loop_.Run(); |
| 421 } | 413 } |
| 422 | 414 |
| 423 // A mocked callback specialization for calling Read(). Since RunWithParams() | 415 class MockReadCB { |
| 424 // is mocked we don't need to pass in object or method pointers. | |
| 425 class MockReadCB : public base::RefCountedThreadSafe<MockReadCB> { | |
| 426 public: | 416 public: |
| 427 MockReadCB() {} | 417 MockReadCB() {} |
| 418 ~MockReadCB() {} |
| 428 | 419 |
| 429 MOCK_METHOD0(OnDelete, void()); | |
| 430 MOCK_METHOD2(Run, void(DemuxerStream::Status status, | 420 MOCK_METHOD2(Run, void(DemuxerStream::Status status, |
| 431 const scoped_refptr<DecoderBuffer>& buffer)); | 421 const scoped_refptr<DecoderBuffer>& buffer)); |
| 432 | |
| 433 protected: | |
| 434 virtual ~MockReadCB() { | |
| 435 OnDelete(); | |
| 436 } | |
| 437 | |
| 438 private: | 422 private: |
| 439 friend class base::RefCountedThreadSafe<MockReadCB>; | |
| 440 | |
| 441 DISALLOW_COPY_AND_ASSIGN(MockReadCB); | 423 DISALLOW_COPY_AND_ASSIGN(MockReadCB); |
| 442 }; | 424 }; |
| 443 | 425 |
| 444 TEST_F(FFmpegDemuxerTest, Stop) { | 426 TEST_F(FFmpegDemuxerTest, Stop) { |
| 445 // Tests that calling Read() on a stopped demuxer stream immediately deletes | 427 // Tests that calling Read() on a stopped demuxer stream immediately deletes |
| 446 // the callback. | 428 // the callback. |
| 447 CreateDemuxer("bear-320x240.webm"); | 429 CreateDemuxer("bear-320x240.webm"); |
| 448 InitializeDemuxer(); | 430 InitializeDemuxer(); |
| 449 | 431 |
| 450 // Get our stream. | 432 // Get our stream. |
| 451 scoped_refptr<DemuxerStream> audio = | 433 DemuxerStream* audio = demuxer_->GetStream(DemuxerStream::AUDIO); |
| 452 demuxer_->GetStream(DemuxerStream::AUDIO); | |
| 453 ASSERT_TRUE(audio); | 434 ASSERT_TRUE(audio); |
| 454 | 435 |
| 455 demuxer_->Stop(NewExpectedClosure()); | 436 demuxer_->Stop(NewExpectedClosure()); |
| 456 | 437 |
| 457 // Expect all calls in sequence. | 438 // Reads after being stopped are all EOS buffers. |
| 458 InSequence s; | 439 StrictMock<MockReadCB> callback; |
| 459 | 440 EXPECT_CALL(callback, Run(DemuxerStream::kOk, IsEndOfStreamBuffer())); |
| 460 // Create our mocked callback. The Callback created by base::Bind() will take | |
| 461 // ownership of this pointer. | |
| 462 StrictMock<MockReadCB>* callback = new StrictMock<MockReadCB>(); | |
| 463 | |
| 464 // The callback should be immediately deleted. We'll use a checkpoint to | |
| 465 // verify that it has indeed been deleted. | |
| 466 EXPECT_CALL(*callback, Run(DemuxerStream::kOk, IsEndOfStreamBuffer())); | |
| 467 EXPECT_CALL(*callback, OnDelete()); | |
| 468 EXPECT_CALL(*this, CheckPoint(1)); | |
| 469 | 441 |
| 470 // Attempt the read... | 442 // Attempt the read... |
| 471 audio->Read(base::Bind(&MockReadCB::Run, callback)); | 443 audio->Read(base::Bind(&MockReadCB::Run, base::Unretained(&callback))); |
| 472 | |
| 473 message_loop_.RunUntilIdle(); | 444 message_loop_.RunUntilIdle(); |
| 474 | |
| 475 // ...and verify that |callback| was deleted. | |
| 476 CheckPoint(1); | |
| 477 } | |
| 478 | |
| 479 // The streams can outlive the demuxer because the streams may still be in use | |
| 480 // by the decoder when the demuxer is destroyed. | |
| 481 // This test verifies that DemuxerStream::Read() does not use an invalid demuxer | |
| 482 // pointer (no crash occurs) and calls the callback with an EndOfStream buffer. | |
| 483 TEST_F(FFmpegDemuxerTest, StreamReadAfterStopAndDemuxerDestruction) { | |
| 484 CreateDemuxer("bear-320x240.webm"); | |
| 485 InitializeDemuxer(); | |
| 486 | |
| 487 // Get our stream. | |
| 488 scoped_refptr<DemuxerStream> audio = | |
| 489 demuxer_->GetStream(DemuxerStream::AUDIO); | |
| 490 ASSERT_TRUE(audio); | |
| 491 | |
| 492 demuxer_->Stop(base::MessageLoop::QuitWhenIdleClosure()); | |
| 493 message_loop_.Run(); | |
| 494 | |
| 495 // Expect all calls in sequence. | |
| 496 InSequence s; | |
| 497 | |
| 498 // Create our mocked callback. The Callback created by base::Bind() will take | |
| 499 // ownership of this pointer. | |
| 500 StrictMock<MockReadCB>* callback = new StrictMock<MockReadCB>(); | |
| 501 | |
| 502 // The callback should be immediately deleted. We'll use a checkpoint to | |
| 503 // verify that it has indeed been deleted. | |
| 504 EXPECT_CALL(*callback, Run(DemuxerStream::kOk, IsEndOfStreamBuffer())); | |
| 505 EXPECT_CALL(*callback, OnDelete()); | |
| 506 EXPECT_CALL(*this, CheckPoint(1)); | |
| 507 | |
| 508 // Destroy the demuxer. |audio| now has a demuxer_ pointer to invalid memory. | |
| 509 demuxer_.reset(); | |
| 510 | |
| 511 // Attempt the read... | |
| 512 audio->Read(base::Bind(&MockReadCB::Run, callback)); | |
| 513 | |
| 514 message_loop_.RunUntilIdle(); | |
| 515 | |
| 516 // ...and verify that |callback| was deleted. | |
| 517 CheckPoint(1); | |
| 518 } | 445 } |
| 519 | 446 |
| 520 TEST_F(FFmpegDemuxerTest, DisableAudioStream) { | 447 TEST_F(FFmpegDemuxerTest, DisableAudioStream) { |
| 521 // We are doing the following things here: | 448 // We are doing the following things here: |
| 522 // 1. Initialize the demuxer with audio and video stream. | 449 // 1. Initialize the demuxer with audio and video stream. |
| 523 // 2. Send a "disable audio stream" message to the demuxer. | 450 // 2. Send a "disable audio stream" message to the demuxer. |
| 524 // 3. Demuxer will free audio packets even if audio stream was initialized. | 451 // 3. Demuxer will free audio packets even if audio stream was initialized. |
| 525 CreateDemuxer("bear-320x240.webm"); | 452 CreateDemuxer("bear-320x240.webm"); |
| 526 InitializeDemuxer(); | 453 InitializeDemuxer(); |
| 527 | 454 |
| 528 // Submit a "disable audio stream" message to the demuxer. | 455 // Submit a "disable audio stream" message to the demuxer. |
| 529 demuxer_->OnAudioRendererDisabled(); | 456 demuxer_->OnAudioRendererDisabled(); |
| 530 message_loop_.RunUntilIdle(); | 457 message_loop_.RunUntilIdle(); |
| 531 | 458 |
| 532 // Get our streams. | 459 // Get our streams. |
| 533 scoped_refptr<DemuxerStream> video = | 460 DemuxerStream* video = demuxer_->GetStream(DemuxerStream::VIDEO); |
| 534 demuxer_->GetStream(DemuxerStream::VIDEO); | 461 DemuxerStream* audio = demuxer_->GetStream(DemuxerStream::AUDIO); |
| 535 scoped_refptr<DemuxerStream> audio = | |
| 536 demuxer_->GetStream(DemuxerStream::AUDIO); | |
| 537 ASSERT_TRUE(video); | 462 ASSERT_TRUE(video); |
| 538 ASSERT_TRUE(audio); | 463 ASSERT_TRUE(audio); |
| 539 | 464 |
| 540 // The audio stream should have been prematurely stopped. | 465 // The audio stream should have been prematurely stopped. |
| 541 EXPECT_FALSE(IsStreamStopped(DemuxerStream::VIDEO)); | 466 EXPECT_FALSE(IsStreamStopped(DemuxerStream::VIDEO)); |
| 542 EXPECT_TRUE(IsStreamStopped(DemuxerStream::AUDIO)); | 467 EXPECT_TRUE(IsStreamStopped(DemuxerStream::AUDIO)); |
| 543 | 468 |
| 544 // Attempt a read from the video stream: it should return valid data. | 469 // Attempt a read from the video stream: it should return valid data. |
| 545 video->Read(NewReadCB(FROM_HERE, 22084, 0)); | 470 video->Read(NewReadCB(FROM_HERE, 22084, 0)); |
| 546 message_loop_.Run(); | 471 message_loop_.Run(); |
| 547 | 472 |
| 548 // Attempt a read from the audio stream: it should immediately return end of | 473 // Attempt a read from the audio stream: it should immediately return end of |
| 549 // stream without requiring the message loop to read data. | 474 // stream without requiring the message loop to read data. |
| 550 bool got_eos_buffer = false; | 475 bool got_eos_buffer = false; |
| 551 audio->Read(base::Bind(&EosOnReadDone, &got_eos_buffer)); | 476 audio->Read(base::Bind(&EosOnReadDone, &got_eos_buffer)); |
| 552 message_loop_.RunUntilIdle(); | 477 message_loop_.RunUntilIdle(); |
| 553 EXPECT_TRUE(got_eos_buffer); | 478 EXPECT_TRUE(got_eos_buffer); |
| 554 } | 479 } |
| 555 | 480 |
| 556 // Verify that seek works properly when the WebM cues data is at the start of | 481 // Verify that seek works properly when the WebM cues data is at the start of |
| 557 // the file instead of at the end. | 482 // the file instead of at the end. |
| 558 TEST_F(FFmpegDemuxerTest, SeekWithCuesBeforeFirstCluster) { | 483 TEST_F(FFmpegDemuxerTest, SeekWithCuesBeforeFirstCluster) { |
| 559 CreateDemuxer("bear-320x240-cues-in-front.webm"); | 484 CreateDemuxer("bear-320x240-cues-in-front.webm"); |
| 560 InitializeDemuxer(); | 485 InitializeDemuxer(); |
| 561 | 486 |
| 562 // Get our streams. | 487 // Get our streams. |
| 563 scoped_refptr<DemuxerStream> video = | 488 DemuxerStream* video = demuxer_->GetStream(DemuxerStream::VIDEO); |
| 564 demuxer_->GetStream(DemuxerStream::VIDEO); | 489 DemuxerStream* audio = demuxer_->GetStream(DemuxerStream::AUDIO); |
| 565 scoped_refptr<DemuxerStream> audio = | |
| 566 demuxer_->GetStream(DemuxerStream::AUDIO); | |
| 567 ASSERT_TRUE(video); | 490 ASSERT_TRUE(video); |
| 568 ASSERT_TRUE(audio); | 491 ASSERT_TRUE(audio); |
| 569 | 492 |
| 570 // Read a video packet and release it. | 493 // Read a video packet and release it. |
| 571 video->Read(NewReadCB(FROM_HERE, 22084, 0)); | 494 video->Read(NewReadCB(FROM_HERE, 22084, 0)); |
| 572 message_loop_.Run(); | 495 message_loop_.Run(); |
| 573 | 496 |
| 574 // Issue a simple forward seek, which should discard queued packets. | 497 // Issue a simple forward seek, which should discard queued packets. |
| 575 WaitableMessageLoopEvent event; | 498 WaitableMessageLoopEvent event; |
| 576 demuxer_->Seek(base::TimeDelta::FromMicroseconds(2500000), | 499 demuxer_->Seek(base::TimeDelta::FromMicroseconds(2500000), |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 647 TEST_F(FFmpegDemuxerTest, MP4_ZeroStszEntry) { | 570 TEST_F(FFmpegDemuxerTest, MP4_ZeroStszEntry) { |
| 648 #if !defined(USE_PROPRIETARY_CODECS) | 571 #if !defined(USE_PROPRIETARY_CODECS) |
| 649 return; | 572 return; |
| 650 #endif | 573 #endif |
| 651 CreateDemuxer("bear-1280x720-zero-stsz-entry.mp4"); | 574 CreateDemuxer("bear-1280x720-zero-stsz-entry.mp4"); |
| 652 InitializeDemuxer(); | 575 InitializeDemuxer(); |
| 653 ReadUntilEndOfStream(); | 576 ReadUntilEndOfStream(); |
| 654 } | 577 } |
| 655 | 578 |
| 656 } // namespace media | 579 } // namespace media |
| OLD | NEW |