Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(127)

Unified Diff: media/filters/fake_video_decoder_unittest.cc

Issue 15085011: Add FakeVideoDecoder. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 7 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: media/filters/fake_video_decoder_unittest.cc
diff --git a/media/filters/fake_video_decoder_unittest.cc b/media/filters/fake_video_decoder_unittest.cc
new file mode 100644
index 0000000000000000000000000000000000000000..91a6c77c9a0be76fed866266ae4675663d2eee6a
--- /dev/null
+++ b/media/filters/fake_video_decoder_unittest.cc
@@ -0,0 +1,434 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "base/basictypes.h"
+#include "base/bind.h"
+#include "base/message_loop.h"
+#include "media/base/decoder_buffer.h"
+#include "media/base/mock_filters.h"
+#include "media/base/test_helpers.h"
+#include "media/base/video_frame.h"
+#include "media/filters/fake_demuxer_stream.h"
+#include "media/filters/fake_video_decoder.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace media {
+
+static const int kDecodingDelay = 9;
+static const int kNumConfigs = 3;
+static const int kNumBuffersInOneConfig = 9;
+static const int kNumInputBuffers = kNumConfigs * kNumBuffersInOneConfig;
+
+class FakeVideoDecoderTest : public testing::Test {
+ public:
+ FakeVideoDecoderTest()
+ : decoder_(new FakeVideoDecoder(kDecodingDelay)),
+ demuxer_stream_(
+ new FakeDemuxerStream(kNumConfigs, kNumBuffersInOneConfig, false)),
+ num_decoded_frames_(0),
+ is_read_pending_(false),
+ is_reset_pending_(false),
+ is_stop_pending_(false) {}
+
+ virtual ~FakeVideoDecoderTest() {
+ StopAndExpect(OK);
+ }
+
+ void Initialize() {
+ decoder_->Initialize(demuxer_stream_.get(),
+ NewExpectedStatusCB(PIPELINE_OK),
+ base::Bind(&MockStatisticsCB::OnStatistics,
+ base::Unretained(&statistics_cb_)));
+ message_loop_.RunUntilIdle();
+ }
+
+ // Callback for VideoDecoder::Read().
+ void FrameReady(VideoDecoder::Status status,
+ const scoped_refptr<VideoFrame>& frame) {
+ DCHECK(is_read_pending_);
+ ASSERT_EQ(VideoDecoder::kOk, status);
+
+ is_read_pending_ = false;
+ frame_read_ = frame;
+
+ if (frame && !frame->IsEndOfStream())
+ num_decoded_frames_++;
+ }
+
+ enum CallbackResult {
+ PENDING,
+ OK,
+ ABROTED,
+ EOS
+ };
+
+ void ExpectReadResult(CallbackResult result) {
+ switch (result) {
+ case PENDING:
+ EXPECT_TRUE(is_read_pending_);
+ ASSERT_FALSE(frame_read_);
+ break;
+ case OK:
+ EXPECT_FALSE(is_read_pending_);
+ ASSERT_TRUE(frame_read_);
+ EXPECT_FALSE(frame_read_->IsEndOfStream());
+ break;
+ case ABROTED:
+ EXPECT_FALSE(is_read_pending_);
+ EXPECT_FALSE(frame_read_);
+ break;
+ case EOS:
+ EXPECT_FALSE(is_read_pending_);
+ ASSERT_TRUE(frame_read_);
+ EXPECT_TRUE(frame_read_->IsEndOfStream());
+ break;
+ }
+ }
+
+ void ReadOneFrame() {
+ frame_read_ = NULL;
+ is_read_pending_ = true;
+ decoder_->Read(
+ base::Bind(&FakeVideoDecoderTest::FrameReady, base::Unretained(this)));
+ message_loop_.RunUntilIdle();
+ }
+
+ void ReadUntilEOS() {
+ do {
+ ReadOneFrame();
+ } while (frame_read_ && !frame_read_->IsEndOfStream());
+ }
+
+ void EnterPendingReadState() {
+ decoder_->HoldNextRead();
+ ReadOneFrame();
+ ExpectReadResult(PENDING);
+ }
+
+ void SatisfyRead() {
+ decoder_->SatisfyRead();
+ message_loop_.RunUntilIdle();
+ ExpectReadResult(OK);
+ }
+
+ // Callback for VideoDecoder::Reset().
+ void OnDecoderReset() {
+ DCHECK(is_reset_pending_);
+ is_reset_pending_ = false;
+ }
+
+ void ExpectResetResult(CallbackResult result) {
+ switch (result) {
+ case PENDING:
+ EXPECT_TRUE(is_reset_pending_);
+ break;
+ case OK:
+ EXPECT_FALSE(is_reset_pending_);
+ break;
+ default:
+ NOTREACHED();
+ }
+ }
+
+ void ResetAndExpect(CallbackResult result) {
+ is_reset_pending_ = true;
+ decoder_->Reset(base::Bind(&FakeVideoDecoderTest::OnDecoderReset,
+ base::Unretained(this)));
+ message_loop_.RunUntilIdle();
+ ExpectResetResult(result);
+ }
+
+ void EnterPendingResetState() {
+ decoder_->HoldNextReset();
+ ResetAndExpect(PENDING);
+ }
+
+ void SatisfyReset() {
+ decoder_->SatisfyReset();
+ message_loop_.RunUntilIdle();
+ ExpectResetResult(OK);
+ }
+
+ // Callback for VideoDecoder::Stop().
+ void OnDecoderStopped() {
+ DCHECK(is_stop_pending_);
+ is_stop_pending_ = false;
+ }
+
+ void ExpectStopResult(CallbackResult result) {
+ switch (result) {
+ case PENDING:
+ EXPECT_TRUE(is_stop_pending_);
+ break;
+ case OK:
+ EXPECT_FALSE(is_stop_pending_);
+ break;
+ default:
+ NOTREACHED();
+ }
+ }
+
+ void StopAndExpect(CallbackResult result) {
+ is_stop_pending_ = true;
+ decoder_->Stop(base::Bind(&FakeVideoDecoderTest::OnDecoderStopped,
+ base::Unretained(this)));
+ message_loop_.RunUntilIdle();
+ ExpectStopResult(result);
+ }
+
+ void EnterPendingStopState() {
+ decoder_->HoldNextStop();
+ StopAndExpect(PENDING);
+ }
+
+ void SatisfyStop() {
+ decoder_->SatisfyStop();
+ message_loop_.RunUntilIdle();
+ ExpectStopResult(OK);
+ }
+
+ // Callback for DemuxerStream::Read so that we can skip frames to trigger a
+ // config change.
+ void BufferReady(bool* config_changed,
+ DemuxerStream::Status status,
+ const scoped_refptr<DecoderBuffer>& buffer) {
+ if (status == DemuxerStream::kConfigChanged)
+ *config_changed = true;
+ }
+
+ void ChangeConfig() {
+ bool config_changed = false;
+ while (!config_changed) {
+ demuxer_stream_->Read(base::Bind(&FakeVideoDecoderTest::BufferReady,
+ base::Unretained(this),
+ &config_changed));
+ message_loop_.RunUntilIdle();
+ }
+ }
+
+ void EnterPendingDemuxerReadState() {
+ demuxer_stream_->HoldNextRead();
+ ReadOneFrame();
+ }
+
+ void SatisfyDemuxerRead() {
+ demuxer_stream_->SatisfyRead();
+ message_loop_.RunUntilIdle();
+ }
+
+ void AbortDemuxerRead() {
+ demuxer_stream_->Reset();
+ message_loop_.RunUntilIdle();
+ }
+
+ base::MessageLoop message_loop_;
+ scoped_ptr<FakeVideoDecoder> decoder_;
+ scoped_ptr<FakeDemuxerStream> demuxer_stream_;
+ MockStatisticsCB statistics_cb_;
+ int num_decoded_frames_;
+
+ // Callback result/status.
+ scoped_refptr<VideoFrame> frame_read_;
+ bool is_read_pending_;
+ bool is_reset_pending_;
+ bool is_stop_pending_;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(FakeVideoDecoderTest);
+};
+
+TEST_F(FakeVideoDecoderTest, Initialize) {
+ Initialize();
+}
+
+TEST_F(FakeVideoDecoderTest, Read_AllFrames) {
+ Initialize();
+ ReadUntilEOS();
+ EXPECT_EQ(kNumInputBuffers, num_decoded_frames_);
+}
+
+TEST_F(FakeVideoDecoderTest, Read_AbortedDemuxerRead) {
+ Initialize();
+ demuxer_stream_->HoldNextRead();
+ ReadOneFrame();
+ AbortDemuxerRead();
+ ExpectReadResult(ABROTED);
+}
+
+TEST_F(FakeVideoDecoderTest, Read_DecodingDelay) {
+ Initialize();
+
+ while (demuxer_stream_->num_buffers_returned() < kNumInputBuffers) {
+ ReadOneFrame();
+ EXPECT_EQ(demuxer_stream_->num_buffers_returned(),
+ num_decoded_frames_ + kDecodingDelay);
+ }
+}
+
+TEST_F(FakeVideoDecoderTest, Read_ZeroDelay) {
+ decoder_.reset(new FakeVideoDecoder(0));
+ Initialize();
+
+ while (demuxer_stream_->num_buffers_returned() < kNumInputBuffers) {
+ ReadOneFrame();
+ EXPECT_EQ(demuxer_stream_->num_buffers_returned(), num_decoded_frames_);
+ }
+}
+
+TEST_F(FakeVideoDecoderTest, Read_Pending) {
+ Initialize();
+ EnterPendingReadState();
+ SatisfyRead();
+}
+
+TEST_F(FakeVideoDecoderTest, Reinitialize) {
+ Initialize();
+ VideoDecoderConfig old_config = demuxer_stream_->video_decoder_config();
+ ChangeConfig();
+ VideoDecoderConfig new_config = demuxer_stream_->video_decoder_config();
+ EXPECT_FALSE(new_config.Matches(old_config));
+ Initialize();
+}
+
+// Reinitializing the decoder during the middle of the decoding process can
+// cause dropped frames.
+TEST_F(FakeVideoDecoderTest, Reinitialize_FrameDropped) {
+ Initialize();
+ ReadOneFrame();
+ Initialize();
+ ReadUntilEOS();
+ EXPECT_LT(num_decoded_frames_, kNumInputBuffers);
+}
+
+TEST_F(FakeVideoDecoderTest, Reset) {
+ Initialize();
+ ReadOneFrame();
+ ResetAndExpect(OK);
+}
+
+TEST_F(FakeVideoDecoderTest, Reset_DuringPendingDemuxerRead) {
+ Initialize();
+ EnterPendingDemuxerReadState();
+ ResetAndExpect(PENDING);
+ SatisfyDemuxerRead();
+ ExpectReadResult(ABROTED);
+}
+
+TEST_F(FakeVideoDecoderTest, Reset_DuringPendingDemuxerRead_Aborted) {
+ Initialize();
+ EnterPendingDemuxerReadState();
+ ResetAndExpect(PENDING);
+ AbortDemuxerRead();
+ ExpectReadResult(ABROTED);
+}
+
+TEST_F(FakeVideoDecoderTest, Reset_DuringPendingRead) {
+ Initialize();
+ EnterPendingReadState();
+ ResetAndExpect(PENDING);
+ SatisfyRead();
+}
+
+TEST_F(FakeVideoDecoderTest, Reset_Pending) {
+ Initialize();
+ EnterPendingResetState();
+ SatisfyReset();
+}
+
+TEST_F(FakeVideoDecoderTest, Reset_PendingDuringPendingRead) {
+ Initialize();
+ EnterPendingReadState();
+ EnterPendingResetState();
+ SatisfyRead();
+ SatisfyReset();
+}
+
+TEST_F(FakeVideoDecoderTest, Stop) {
+ Initialize();
+ ReadOneFrame();
+ ExpectReadResult(OK);
+ StopAndExpect(OK);
+}
+
+TEST_F(FakeVideoDecoderTest, Stop_DuringPendingDemuxerRead) {
+ Initialize();
+ EnterPendingDemuxerReadState();
+ StopAndExpect(PENDING);
+ SatisfyDemuxerRead();
+ ExpectReadResult(ABROTED);
+}
+
+TEST_F(FakeVideoDecoderTest, Stop_DuringPendingDemuxerRead_Aborted) {
+ Initialize();
+ EnterPendingDemuxerReadState();
+ ResetAndExpect(PENDING);
+ StopAndExpect(PENDING);
+ SatisfyDemuxerRead();
+ ExpectReadResult(ABROTED);
+ ExpectResetResult(OK);
+ ExpectStopResult(OK);
+}
+
+TEST_F(FakeVideoDecoderTest, Stop_DuringPendingRead) {
+ Initialize();
+ EnterPendingReadState();
+ StopAndExpect(PENDING);
+ SatisfyRead();
+ ExpectStopResult(OK);
+}
+
+TEST_F(FakeVideoDecoderTest, Stop_DuringPendingReset) {
+ Initialize();
+ EnterPendingResetState();
+ StopAndExpect(PENDING);
+ SatisfyReset();
+ ExpectStopResult(OK);
+}
+
+TEST_F(FakeVideoDecoderTest, Stop_DuringPendingReadAndPendingReset) {
+ Initialize();
+ EnterPendingReadState();
+ EnterPendingResetState();
+ StopAndExpect(PENDING);
+ SatisfyRead();
+ SatisfyReset();
+ ExpectStopResult(OK);
+}
+
+TEST_F(FakeVideoDecoderTest, Stop_Pending) {
+ Initialize();
+ decoder_->HoldNextStop();
+ StopAndExpect(PENDING);
+ decoder_->SatisfyStop();
+ message_loop_.RunUntilIdle();
+ ExpectStopResult(OK);
+}
+
+TEST_F(FakeVideoDecoderTest, Stop_PendingDuringPendingRead) {
+ Initialize();
+ EnterPendingReadState();
+ EnterPendingStopState();
+ SatisfyRead();
+ SatisfyStop();
+}
+
+TEST_F(FakeVideoDecoderTest, Stop_PendingDuringPendingReset) {
+ Initialize();
+ EnterPendingResetState();
+ EnterPendingStopState();
+ SatisfyReset();
+ SatisfyStop();
+}
+
+TEST_F(FakeVideoDecoderTest, Stop_PendingDuringPendingReadAndPendingReset) {
+ Initialize();
+ EnterPendingReadState();
+ EnterPendingResetState();
+ EnterPendingStopState();
+ SatisfyRead();
+ SatisfyReset();
+ SatisfyStop();
+}
+
+} // namespace media

Powered by Google App Engine
This is Rietveld 408576698