Chromium Code Reviews| 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 13 matching lines...) Expand all Loading... | |
| 24 using ::testing::NotNull; | 24 using ::testing::NotNull; |
| 25 using ::testing::Return; | 25 using ::testing::Return; |
| 26 using ::testing::SaveArg; | 26 using ::testing::SaveArg; |
| 27 using ::testing::SetArgPointee; | 27 using ::testing::SetArgPointee; |
| 28 using ::testing::StrictMock; | 28 using ::testing::StrictMock; |
| 29 using ::testing::WithArgs; | 29 using ::testing::WithArgs; |
| 30 using ::testing::_; | 30 using ::testing::_; |
| 31 | 31 |
| 32 namespace media { | 32 namespace media { |
| 33 | 33 |
| 34 MATCHER(IsEndOfStreamBuffer, | |
| 35 std::string(negation ? "isn't" : "is") + " end of stream") { | |
| 36 return arg->IsEndOfStream(); | |
| 37 } | |
| 38 | |
| 34 // Fixture class to facilitate writing tests. Takes care of setting up the | 39 // Fixture class to facilitate writing tests. Takes care of setting up the |
| 35 // FFmpeg, pipeline and filter host mocks. | 40 // FFmpeg, pipeline and filter host mocks. |
| 36 class FFmpegDemuxerTest : public testing::Test { | 41 class FFmpegDemuxerTest : public testing::Test { |
| 37 protected: | 42 protected: |
| 38 | 43 |
| 39 FFmpegDemuxerTest() { | 44 FFmpegDemuxerTest() { |
| 40 // Create an FFmpegDemuxer. | 45 // Create an FFmpegDemuxer. |
| 41 demuxer_ = new FFmpegDemuxer(&message_loop_); | 46 demuxer_ = new FFmpegDemuxer(&message_loop_); |
| 42 demuxer_->disable_first_seek_hack_for_testing(); | 47 demuxer_->disable_first_seek_hack_for_testing(); |
| 43 | 48 |
| 44 // Inject a filter host and message loop and prepare a data source. | 49 // Inject a filter host and message loop and prepare a data source. |
| 45 demuxer_->set_host(&host_); | 50 demuxer_->set_host(&host_); |
| 46 | 51 |
| 47 EXPECT_CALL(host_, SetTotalBytes(_)).Times(AnyNumber()); | 52 EXPECT_CALL(host_, SetTotalBytes(_)).Times(AnyNumber()); |
| 48 EXPECT_CALL(host_, SetBufferedBytes(_)).Times(AnyNumber()); | 53 EXPECT_CALL(host_, SetBufferedBytes(_)).Times(AnyNumber()); |
| 49 EXPECT_CALL(host_, SetCurrentReadPosition(_)) | 54 EXPECT_CALL(host_, SetCurrentReadPosition(_)) |
| 50 .WillRepeatedly(SaveArg<0>(¤t_read_position_)); | 55 .WillRepeatedly(SaveArg<0>(¤t_read_position_)); |
| 51 } | 56 } |
| 52 | 57 |
| 53 virtual ~FFmpegDemuxerTest() { | 58 virtual ~FFmpegDemuxerTest() { |
| 54 // Call Stop() to shut down internal threads. | 59 if (demuxer_) |
|
scherkus (not reviewing)
2011/10/15 01:32:14
could you add {} around here
ddorwin
2011/10/15 01:38:16
Done.
| |
| 55 demuxer_->Stop(NewExpectedClosure()); | 60 // Call Stop() to shut down internal threads. |
| 61 demuxer_->Stop(NewExpectedClosure()); | |
| 56 | 62 |
| 57 // Finish up any remaining tasks. | 63 // Finish up any remaining tasks. |
| 58 message_loop_.RunAllPending(); | 64 message_loop_.RunAllPending(); |
| 59 // Release the reference to the demuxer. | 65 // Release the reference to the demuxer. |
| 60 demuxer_ = NULL; | 66 demuxer_ = NULL; |
| 61 } | 67 } |
| 62 | 68 |
| 63 scoped_refptr<FileDataSource> CreateDataSource(const std::string& name) { | 69 scoped_refptr<FileDataSource> CreateDataSource(const std::string& name) { |
| 64 return CreateDataSource(name, false); | 70 return CreateDataSource(name, false); |
| 65 } | 71 } |
| (...skipping 303 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 369 } | 375 } |
| 370 | 376 |
| 371 MOCK_METHOD0(OnDelete, void()); | 377 MOCK_METHOD0(OnDelete, void()); |
| 372 MOCK_METHOD1(Run, void(Buffer* buffer)); | 378 MOCK_METHOD1(Run, void(Buffer* buffer)); |
| 373 | 379 |
| 374 private: | 380 private: |
| 375 DISALLOW_COPY_AND_ASSIGN(MockReadCallback); | 381 DISALLOW_COPY_AND_ASSIGN(MockReadCallback); |
| 376 }; | 382 }; |
| 377 | 383 |
| 378 TEST_F(FFmpegDemuxerTest, Stop) { | 384 TEST_F(FFmpegDemuxerTest, Stop) { |
| 379 // Tests that calling Read() on a stopped demuxer immediately deletes the | 385 // Tests that calling Read() on a stopped demuxer stream immediately deletes |
| 380 // callback. | 386 // the callback. |
| 381 InitializeDemuxer(CreateDataSource("bear-320x240.webm")); | 387 InitializeDemuxer(CreateDataSource("bear-320x240.webm")); |
| 382 | 388 |
| 383 // Get our stream. | 389 // Get our stream. |
| 384 scoped_refptr<DemuxerStream> audio = | 390 scoped_refptr<DemuxerStream> audio = |
| 385 demuxer_->GetStream(DemuxerStream::AUDIO); | 391 demuxer_->GetStream(DemuxerStream::AUDIO); |
| 386 ASSERT_TRUE(audio); | 392 ASSERT_TRUE(audio); |
| 387 | 393 |
| 388 demuxer_->Stop(NewExpectedClosure()); | 394 demuxer_->Stop(NewExpectedClosure()); |
| 389 | 395 |
| 390 // Expect all calls in sequence. | 396 // Expect all calls in sequence. |
| 391 InSequence s; | 397 InSequence s; |
| 392 | 398 |
| 393 // Create our mocked callback. The Callback created by base::Bind() will take | 399 // Create our mocked callback. The Callback created by base::Bind() will take |
| 394 // ownership of this pointer. | 400 // ownership of this pointer. |
| 395 StrictMock<MockReadCallback>* callback = new StrictMock<MockReadCallback>(); | 401 StrictMock<MockReadCallback>* callback = new StrictMock<MockReadCallback>(); |
| 396 | 402 |
| 397 // The callback should be immediately deleted. We'll use a checkpoint to | 403 // The callback should be immediately deleted. We'll use a checkpoint to |
| 398 // verify that it has indeed been deleted. | 404 // verify that it has indeed been deleted. |
| 405 EXPECT_CALL(*callback, Run(NotNull())); | |
| 399 EXPECT_CALL(*callback, OnDelete()); | 406 EXPECT_CALL(*callback, OnDelete()); |
| 400 EXPECT_CALL(*this, CheckPoint(1)); | 407 EXPECT_CALL(*this, CheckPoint(1)); |
| 401 | 408 |
| 402 // Attempt the read... | 409 // Attempt the read... |
| 403 audio->Read(base::Bind(&MockReadCallback::Run, callback)); | 410 audio->Read(base::Bind(&MockReadCallback::Run, callback)); |
| 404 | 411 |
| 405 message_loop_.RunAllPending(); | 412 message_loop_.RunAllPending(); |
| 406 | 413 |
| 407 // ...and verify that |callback| was deleted. | 414 // ...and verify that |callback| was deleted. |
| 408 CheckPoint(1); | 415 CheckPoint(1); |
| 409 } | 416 } |
| 410 | 417 |
| 418 // The streams can outlive the demuxer because the streams may still be in use | |
| 419 // by the decoder when the demuxer is destroyed. | |
| 420 // This test verifies that DemuxerStream::Read() does not use an invalid demuxer | |
| 421 // pointer (no crash occurs) and calls the callback with an EndOfStream buffer. | |
| 422 TEST_F(FFmpegDemuxerTest, StreamReadAfterStopAndDemuxerDestruction) { | |
| 423 InitializeDemuxer(CreateDataSource("bear-320x240.webm")); | |
| 424 | |
| 425 // Get our stream. | |
| 426 scoped_refptr<DemuxerStream> audio = | |
| 427 demuxer_->GetStream(DemuxerStream::AUDIO); | |
| 428 ASSERT_TRUE(audio); | |
| 429 | |
| 430 demuxer_->Stop(NewExpectedClosure()); | |
| 431 | |
| 432 // Finish up any remaining tasks. | |
| 433 message_loop_.RunAllPending(); | |
| 434 | |
| 435 // Expect all calls in sequence. | |
| 436 InSequence s; | |
| 437 | |
| 438 // Create our mocked callback. The Callback created by base::Bind() will take | |
| 439 // ownership of this pointer. | |
| 440 StrictMock<MockReadCallback>* callback = new StrictMock<MockReadCallback>(); | |
| 441 | |
| 442 // The callback should be immediately deleted. We'll use a checkpoint to | |
| 443 // verify that it has indeed been deleted. | |
| 444 EXPECT_CALL(*callback, Run(IsEndOfStreamBuffer())); | |
| 445 EXPECT_CALL(*callback, OnDelete()); | |
| 446 EXPECT_CALL(*this, CheckPoint(1)); | |
| 447 | |
| 448 // Release the reference to the demuxer. This should also destroy it. | |
| 449 demuxer_ = NULL; | |
| 450 // |audio| now has a demuxer_ pointer to invalid memory. | |
| 451 | |
| 452 // Attempt the read... | |
| 453 audio->Read(base::Bind(&MockReadCallback::Run, callback)); | |
| 454 | |
| 455 message_loop_.RunAllPending(); | |
| 456 | |
| 457 // ...and verify that |callback| was deleted. | |
| 458 CheckPoint(1); | |
| 459 } | |
| 460 | |
| 411 TEST_F(FFmpegDemuxerTest, DisableAudioStream) { | 461 TEST_F(FFmpegDemuxerTest, DisableAudioStream) { |
| 412 // We are doing the following things here: | 462 // We are doing the following things here: |
| 413 // 1. Initialize the demuxer with audio and video stream. | 463 // 1. Initialize the demuxer with audio and video stream. |
| 414 // 2. Send a "disable audio stream" message to the demuxer. | 464 // 2. Send a "disable audio stream" message to the demuxer. |
| 415 // 3. Demuxer will free audio packets even if audio stream was initialized. | 465 // 3. Demuxer will free audio packets even if audio stream was initialized. |
| 416 InitializeDemuxer(CreateDataSource("bear-320x240.webm")); | 466 InitializeDemuxer(CreateDataSource("bear-320x240.webm")); |
| 417 | 467 |
| 418 // Submit a "disable audio stream" message to the demuxer. | 468 // Submit a "disable audio stream" message to the demuxer. |
| 419 demuxer_->OnAudioRendererDisabled(); | 469 demuxer_->OnAudioRendererDisabled(); |
| 420 message_loop_.RunAllPending(); | 470 message_loop_.RunAllPending(); |
| (...skipping 211 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 632 message_loop_.RunAllPending(); | 682 message_loop_.RunAllPending(); |
| 633 EXPECT_TRUE(reader->called()); | 683 EXPECT_TRUE(reader->called()); |
| 634 ValidateBuffer(FROM_HERE, reader->buffer(), 1740, 2436000); | 684 ValidateBuffer(FROM_HERE, reader->buffer(), 1740, 2436000); |
| 635 | 685 |
| 636 // Manually release the last reference to the buffer and verify it was freed. | 686 // Manually release the last reference to the buffer and verify it was freed. |
| 637 reader->Reset(); | 687 reader->Reset(); |
| 638 message_loop_.RunAllPending(); | 688 message_loop_.RunAllPending(); |
| 639 } | 689 } |
| 640 | 690 |
| 641 } // namespace media | 691 } // namespace media |
| OLD | NEW |