Index: content/renderer/media/rtc_video_decoder_unittest.cc |
diff --git a/content/renderer/media/rtc_video_decoder_unittest.cc b/content/renderer/media/rtc_video_decoder_unittest.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..eefcb5ffeb97f79b43b24c7c2a9c1bd5a70f8db5 |
--- /dev/null |
+++ b/content/renderer/media/rtc_video_decoder_unittest.cc |
@@ -0,0 +1,200 @@ |
+// 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/bind.h" |
+#include "base/message_loop.h" |
+#include "base/threading/platform_thread.h" |
+#include "content/renderer/media/rtc_video_decoder.h" |
+#include "media/base/gmock_callback_support.h" |
+#include "media/base/mock_filters.h" |
+#include "testing/gtest/include/gtest/gtest.h" |
+ |
+using ::testing::_; |
+ |
+namespace content { |
+ |
+class RTCVideoDecoderTest |
+ : public ::testing::Test, |
+ public base::PlatformThread::Delegate, |
+ webrtc::DecodedImageCallback { |
+ public: |
+ RTCVideoDecoderTest() |
+ : decoder_(new media::MockVideoDecoder()), |
+ loop_idle_waiter_(false, false), |
+ num_delivered_frames_(0), |
+ num_delivered_encoded_image_(0), |
+ loop_ready_waiter_(false, false), |
+ thread_(base::kNullThreadHandle), |
+ is_tearing_down_(false) { |
+ memset(&codec_, 0, sizeof(codec_)); |
+ } |
+ |
+ virtual void SetUp() OVERRIDE { |
+ CHECK(base::PlatformThread::Create(0, this, &thread_)); |
+ loop_ready_waiter_.Wait(); |
+ bridge_.reset(new RTCVideoDecoder(decoder_, loop_proxy_)); |
Ami GONE FROM CHROMIUM
2013/05/14 22:57:24
|bridge_| is now a strange name for the variable c
wuchengli
2013/05/15 15:30:46
Changed |bridge_| to |rtc_decoder_| and changed |d
|
+ } |
+ |
+ virtual void TearDown() OVERRIDE { |
+ if (thread_ != base::kNullThreadHandle) { |
+ { |
+ base::AutoLock auto_lock(lock_); |
+ is_tearing_down_ = true; |
+ } |
+ base::PlatformThread::Join(thread_); |
+ } |
+ } |
+ |
+ virtual void ThreadMain() OVERRIDE { |
+ MessageLoop message_loop; |
+ loop_proxy_ = message_loop.message_loop_proxy(); |
+ loop_ready_waiter_.Signal(); |
+ LOG(INFO) << "ThreadMain()"; |
+ while (true) { |
+ message_loop.RunUntilIdle(); |
+ loop_idle_waiter_.Signal(); |
+ loop_idle_waiter_.Reset(); |
+ base::AutoLock auto_lock(lock_); |
+ if (is_tearing_down_) { |
+ break; |
+ } |
+ } |
+ } |
+ |
+ virtual int32_t Decoded(webrtc::I420VideoFrame& decoded_image) |
+ OVERRIDE { |
+ num_delivered_frames_++; |
Ami GONE FROM CHROMIUM
2013/05/14 22:57:24
nit: prefer pre-{de,in}crement to post-, where the
wuchengli
2013/05/15 15:30:46
All done.
|
+ return WEBRTC_VIDEO_CODEC_OK; |
+ } |
+ |
+ void Initialize() { |
+ EXPECT_CALL(*decoder_, Initialize(_, _, _)) |
+ .WillOnce(media::RunCallback<1>(media::PIPELINE_OK)); |
+ EXPECT_CALL(*decoder_, Read(_)) |
+ .WillRepeatedly( |
+ Invoke(this, &RTCVideoDecoderTest::FrameRequested)); |
+ EXPECT_CALL(*decoder_, Stop(_)) |
+ .WillRepeatedly(media::RunClosure<0>()); |
+ EXPECT_CALL(*decoder_, Reset(_)) |
+ .WillRepeatedly(media::RunClosure<0>()); |
+ |
+ codec_.codecType = webrtc::kVideoCodecVP8; |
+ EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, bridge_->InitDecode(&codec_, 1)); |
+ EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, |
+ bridge_->RegisterDecodeCompleteCallback(this)); |
+ } |
+ |
+ void FrameRequested(const media::VideoDecoder::ReadCB& read_cb) { |
+ DCHECK_EQ(loop_proxy_, base::MessageLoopProxy::current()); |
+ EXPECT_TRUE(read_cb_.is_null()); |
+ read_cb_ = read_cb; |
+ SimulateDecoding(); |
+ } |
+ |
+ void SimulateDecoding() { |
+ CHECK(!read_cb_.is_null()); |
+ base::AutoLock auto_lock(lock_); |
+ if (num_delivered_encoded_image_ <= 0) { |
+ return; |
+ } |
+ num_delivered_encoded_image_--; |
+ |
+ loop_proxy_->PostTask( |
+ FROM_HERE, |
+ base::Bind(read_cb_, media::VideoDecoder::kOk, |
+ media::VideoFrame::CreateEmptyFrame())); |
+ read_cb_.Reset(); |
+ } |
+ |
+protected: |
+ media::MockVideoDecoder* decoder_; |
+ scoped_ptr<RTCVideoDecoder> bridge_; |
+ webrtc::VideoCodec codec_; |
+ base::WaitableEvent loop_idle_waiter_; |
+ int num_delivered_frames_; |
+ int num_delivered_encoded_image_; |
+ |
+ private: |
+ scoped_refptr<base::MessageLoopProxy> loop_proxy_; |
+ base::WaitableEvent loop_ready_waiter_; |
+ base::PlatformThreadHandle thread_; |
+ |
+ base::Lock lock_; |
+ bool is_tearing_down_; |
+ media::VideoDecoder::ReadCB read_cb_; |
+}; |
+ |
+TEST_F(RTCVideoDecoderTest, InitDecodeReturnsErrorOnNonVP8Codec) { |
+ codec_.codecType = webrtc::kVideoCodecI420; |
+ EXPECT_NE(WEBRTC_VIDEO_CODEC_OK, bridge_->InitDecode(&codec_, 1)); |
+} |
+ |
+TEST_F(RTCVideoDecoderTest, InitDecodeReturnsErrorOnFeedbackMode) { |
+ codec_.codecType = webrtc::kVideoCodecVP8; |
+ codec_.codecSpecific.VP8.feedbackModeOn = true; |
+ EXPECT_NE(WEBRTC_VIDEO_CODEC_OK, bridge_->InitDecode(&codec_, 1)); |
+} |
+ |
+TEST_F(RTCVideoDecoderTest, InitDecodeReturnsErrorOnDecoderInitFailure) { |
+ EXPECT_CALL(*decoder_, Initialize(_, _, _)) |
+ .WillOnce(media::RunCallback<1>(media::DECODER_ERROR_NOT_SUPPORTED)); |
+ |
+ codec_.codecType = webrtc::kVideoCodecVP8; |
+ EXPECT_NE(WEBRTC_VIDEO_CODEC_OK, bridge_->InitDecode(&codec_, 1)); |
+} |
+ |
+TEST_F(RTCVideoDecoderTest, InitDecodeReturnsOkOnSuccessfulDecoderInit) { |
+ Initialize(); |
+} |
+ |
+TEST_F(RTCVideoDecoderTest, DecodeReturnsErrorBeforeInitDecode) { |
+ webrtc::EncodedImage input_image; |
+ EXPECT_EQ(WEBRTC_VIDEO_CODEC_UNINITIALIZED, |
+ bridge_->Decode(input_image, false, NULL, NULL, 0)); |
+} |
+ |
+TEST_F(RTCVideoDecoderTest, DecodeReturnsErrorOnDamagedBitstream) { |
+ Initialize(); |
+ webrtc::EncodedImage input_image; |
+ input_image._completeFrame = false; |
+ EXPECT_EQ(WEBRTC_VIDEO_CODEC_ERROR, |
+ bridge_->Decode(input_image, false, NULL, NULL, 0)); |
+} |
+ |
+TEST_F(RTCVideoDecoderTest, DecodeReturnsErrorOnMissingFrames) { |
+ Initialize(); |
+ webrtc::EncodedImage input_image; |
+ input_image._completeFrame = true; |
+ EXPECT_EQ(WEBRTC_VIDEO_CODEC_ERROR, |
+ bridge_->Decode(input_image, true, NULL, NULL, 0)); |
+} |
+ |
+TEST_F(RTCVideoDecoderTest, DecodeReturnsOkAndGetsDecodedFrame) { |
+ Initialize(); |
+ webrtc::EncodedImage input_image; |
+ input_image._completeFrame = true; |
+ unsigned char data = 123; |
+ input_image._buffer = &data; |
+ input_image._length = sizeof(data); |
+ EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, |
+ bridge_->Decode(input_image, false, NULL, NULL, 0)); |
+ num_delivered_encoded_image_++; //XXX : lock? |
+ loop_idle_waiter_.Wait(); |
+ SimulateDecoding(); |
+ loop_idle_waiter_.Wait(); |
+ // Check output. |
+ EXPECT_EQ(1, num_delivered_frames_); //XXX: lock? |
Ami GONE FROM CHROMIUM
2013/05/14 22:57:24
If all you need is sequencing (not mutual exclusio
wuchengli
2013/05/15 15:30:46
Yes. It's only sequencing. The comments were remov
|
+} |
+ |
+TEST_F(RTCVideoDecoderTest, ResetReturnsOk) { |
+ Initialize(); |
+ EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, bridge_->Reset()); |
+} |
+ |
+TEST_F(RTCVideoDecoderTest, ReleaseReturnsOk) { |
+ Initialize(); |
+ EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, bridge_->Release()); |
+} |
+ |
+} // content |