Index: media/filters/ffmpeg_demuxer_unittest.cc |
diff --git a/media/filters/ffmpeg_demuxer_unittest.cc b/media/filters/ffmpeg_demuxer_unittest.cc |
index 0622e017477be5cdd143a339d31ea0d1e91cbcd2..9e0e831ff56a20afe7492a6a26753e4f57e8a43f 100644 |
--- a/media/filters/ffmpeg_demuxer_unittest.cc |
+++ b/media/filters/ffmpeg_demuxer_unittest.cc |
@@ -31,6 +31,11 @@ using ::testing::_; |
namespace media { |
+MATCHER(IsEndOfStreamBuffer, |
+ std::string(negation ? "isn't" : "is") + " end of stream") { |
+ return arg->IsEndOfStream(); |
scherkus (not reviewing)
2011/10/15 00:17:22
indent by 2
ddorwin
2011/10/15 01:19:47
Done.
|
+} |
+ |
// Fixture class to facilitate writing tests. Takes care of setting up the |
// FFmpeg, pipeline and filter host mocks. |
class FFmpegDemuxerTest : public testing::Test { |
@@ -51,8 +56,9 @@ class FFmpegDemuxerTest : public testing::Test { |
} |
virtual ~FFmpegDemuxerTest() { |
- // Call Stop() to shut down internal threads. |
- demuxer_->Stop(NewExpectedClosure()); |
+ if (demuxer_) |
+ // Call Stop() to shut down internal threads. |
+ demuxer_->Stop(NewExpectedClosure()); |
// Finish up any remaining tasks. |
message_loop_.RunAllPending(); |
@@ -376,8 +382,8 @@ class MockReadCallback : public base::RefCountedThreadSafe<MockReadCallback> { |
}; |
TEST_F(FFmpegDemuxerTest, Stop) { |
- // Tests that calling Read() on a stopped demuxer immediately deletes the |
- // callback. |
+ // Tests that calling Read() on a stopped demuxer stream immediately deletes |
+ // the callback. |
InitializeDemuxer(CreateDataSource("bear-320x240.webm")); |
// Get our stream. |
@@ -396,6 +402,7 @@ TEST_F(FFmpegDemuxerTest, Stop) { |
// The callback should be immediately deleted. We'll use a checkpoint to |
// verify that it has indeed been deleted. |
+ EXPECT_CALL(*callback, Run(NotNull())); |
EXPECT_CALL(*callback, OnDelete()); |
EXPECT_CALL(*this, CheckPoint(1)); |
@@ -408,6 +415,47 @@ TEST_F(FFmpegDemuxerTest, Stop) { |
CheckPoint(1); |
} |
+// The streams can outlive the demuxer because the streams may still be in use |
+// by the decoder when the demuxer is destroyed. |
+TEST_F(FFmpegDemuxerTest, StreamReadAfterStopAndDemuxerDestruction) { |
+ InitializeDemuxer(CreateDataSource("bear-320x240.webm")); |
+ |
+ // Get our stream. |
+ scoped_refptr<DemuxerStream> audio = |
+ demuxer_->GetStream(DemuxerStream::AUDIO); |
+ ASSERT_TRUE(audio); |
+ |
+ demuxer_->Stop(NewExpectedClosure()); |
+ |
+ // Finish up any remaining tasks. |
+ message_loop_.RunAllPending(); |
+ |
+ // Expect all calls in sequence. |
+ InSequence s; |
+ |
+ // Create our mocked callback. The Callback created by base::Bind() will take |
+ // ownership of this pointer. |
+ StrictMock<MockReadCallback>* callback = new StrictMock<MockReadCallback>(); |
+ |
+ // The callback should be immediately deleted. We'll use a checkpoint to |
+ // verify that it has indeed been deleted. |
+ EXPECT_CALL(*callback, Run(IsEndOfStreamBuffer())); |
+ EXPECT_CALL(*callback, OnDelete()); |
+ EXPECT_CALL(*this, CheckPoint(1)); |
+ |
+ // Release the reference to the demuxer. This should also destroy it. |
+ demuxer_ = NULL; |
+ // video_stream now has a demuxer_ pointer to invalid memory. |
scherkus (not reviewing)
2011/10/15 00:17:22
do you mean |audio| instead of video_stream?
ddorwin
2011/10/15 01:19:47
Done.
|
+ |
+ // Attempt the read... |
+ audio->Read(base::Bind(&MockReadCallback::Run, callback)); |
+ |
+ message_loop_.RunAllPending(); |
+ |
+ // ...and verify that |callback| was deleted. |
+ CheckPoint(1); |
+} |
+ |
TEST_F(FFmpegDemuxerTest, DisableAudioStream) { |
// We are doing the following things here: |
// 1. Initialize the demuxer with audio and video stream. |