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..0a29291e56719548865e401ef22319c05b3cde7e |
--- /dev/null |
+++ b/content/renderer/media/rtc_video_decoder_unittest.cc |
@@ -0,0 +1,153 @@ |
+// 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/synchronization/waitable_event.h" |
+#include "base/threading/thread.h" |
+#include "content/renderer/media/rtc_video_decoder.h" |
+#include "media/base/gmock_callback_support.h" |
+#include "media/filters/gpu_video_decoder.h" |
+#include "media/filters/mock_gpu_video_decoder_factories.h" |
+#include "media/video/mock_video_decode_accelerator.h" |
+#include "testing/gtest/include/gtest/gtest.h" |
+ |
+using ::testing::_; |
+using ::testing::Invoke; |
+using ::testing::Return; |
+using ::testing::SaveArg; |
+using ::testing::WithArgs; |
+ |
+namespace content { |
+ |
+class RTCVideoDecoderTest : public ::testing::Test, |
+ webrtc::DecodedImageCallback { |
+ public: |
+ RTCVideoDecoderTest() |
+ : mock_gpu_factories_(new media::MockGpuVideoDecoderFactories), |
+ vda_thread_("vda_thread"), |
+ idle_waiter_(false, false) { |
+ memset(&codec_, 0, sizeof(codec_)); |
+ } |
+ |
+ virtual void SetUp() OVERRIDE { |
+ ASSERT_TRUE(vda_thread_.Start()); |
+ vda_loop_proxy_ = vda_thread_.message_loop_proxy(); |
+ mock_vda_ = new media::MockVideoDecodeAccelerator; |
+ EXPECT_CALL(*mock_gpu_factories_, GetMessageLoop()) |
+ .WillRepeatedly(Return(vda_loop_proxy_)); |
+ EXPECT_CALL(*mock_gpu_factories_, |
+ CreateVideoDecodeAccelerator(media::VP8PROFILE_MAIN, _)) |
+ .WillOnce(Return(mock_vda_)); |
+ EXPECT_CALL(*mock_vda_, Destroy()); |
+ rtc_decoder_ = RTCVideoDecoder::Create(mock_gpu_factories_); |
+ } |
+ |
+ virtual void TearDown() OVERRIDE { |
+ VLOG(2) << "TearDown"; |
+ if (vda_thread_.IsRunning()) { |
+ RunUntilIdle(); // Wait until all callbascks complete. |
+ vda_loop_proxy_->DeleteSoon(FROM_HERE, rtc_decoder_.release()); |
+ // Make sure the decoder is released before stopping the thread. |
+ RunUntilIdle(); |
+ vda_thread_.Stop(); |
+ } else { |
+ rtc_decoder_.reset(); |
+ } |
+ } |
+ |
+ virtual int32_t Decoded(webrtc::I420VideoFrame& decoded_image) OVERRIDE { |
+ VLOG(2) << "Decoded"; |
+ EXPECT_EQ(vda_loop_proxy_, base::MessageLoopProxy::current()); |
+ return WEBRTC_VIDEO_CODEC_OK; |
+ } |
+ |
+ void Initialize() { |
+ VLOG(2) << "Initialize"; |
+ codec_.codecType = webrtc::kVideoCodecVP8; |
+ EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, rtc_decoder_->InitDecode(&codec_, 1)); |
+ EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, |
+ rtc_decoder_->RegisterDecodeCompleteCallback(this)); |
+ } |
+ |
+ void NotifyResetDone() { |
+ VLOG(2) << "NotifyResetDone"; |
+ vda_loop_proxy_->PostTask(FROM_HERE, |
+ base::Bind(&RTCVideoDecoder::NotifyResetDone, |
+ base::Unretained(rtc_decoder_.get()))); |
+ } |
+ |
+ void RunUntilIdle() { |
+ VLOG(2) << "RunUntilIdle"; |
+ vda_loop_proxy_->PostTask( |
+ FROM_HERE, |
+ base::Bind(&RTCVideoDecoderTest::NotifyIdle, base::Unretained(this))); |
Ami GONE FROM CHROMIUM
2013/06/19 18:28:58
This is equal to
base::Bind(&WaitableEvent::Signa
wuchengli
2013/06/20 07:27:04
Done.
|
+ idle_waiter_.Wait(); |
+ } |
+ |
+ void NotifyIdle() { idle_waiter_.Signal(); } |
+ |
+ protected: |
+ scoped_refptr<media::MockGpuVideoDecoderFactories> mock_gpu_factories_; |
+ media::MockVideoDecodeAccelerator* mock_vda_; |
+ scoped_ptr<RTCVideoDecoder> rtc_decoder_; |
+ webrtc::VideoCodec codec_; |
+ base::Thread vda_thread_; |
+ |
+ private: |
+ scoped_refptr<base::MessageLoopProxy> vda_loop_proxy_; |
+ |
+ base::Lock lock_; |
+ base::WaitableEvent idle_waiter_; |
+}; |
+ |
+TEST_F(RTCVideoDecoderTest, InitDecodeReturnsErrorOnFeedbackMode) { |
+ codec_.codecType = webrtc::kVideoCodecVP8; |
+ codec_.codecSpecific.VP8.feedbackModeOn = true; |
+ EXPECT_EQ(WEBRTC_VIDEO_CODEC_ERROR, rtc_decoder_->InitDecode(&codec_, 1)); |
+} |
+ |
+TEST_F(RTCVideoDecoderTest, DecodeReturnsErrorWithoutInitDecode) { |
+ webrtc::EncodedImage input_image; |
+ EXPECT_EQ(WEBRTC_VIDEO_CODEC_UNINITIALIZED, |
+ rtc_decoder_->Decode(input_image, false, NULL, NULL, 0)); |
+} |
+ |
+TEST_F(RTCVideoDecoderTest, DecodeReturnsErrorOnIncompleteFrame) { |
+ Initialize(); |
+ webrtc::EncodedImage input_image; |
+ input_image._completeFrame = false; |
+ EXPECT_EQ(WEBRTC_VIDEO_CODEC_ERROR, |
+ rtc_decoder_->Decode(input_image, false, NULL, NULL, 0)); |
+} |
+ |
+TEST_F(RTCVideoDecoderTest, DecodeReturnsErrorOnMissingFrames) { |
+ Initialize(); |
+ webrtc::EncodedImage input_image; |
+ input_image._completeFrame = true; |
+ bool missingFrames = true; |
+ EXPECT_EQ(WEBRTC_VIDEO_CODEC_ERROR, |
+ rtc_decoder_->Decode(input_image, missingFrames, NULL, NULL, 0)); |
+} |
+ |
+TEST_F(RTCVideoDecoderTest, ResetReturnsOk) { |
+ Initialize(); |
+ EXPECT_CALL(*mock_vda_, Reset()) |
+ .WillOnce(Invoke(this, &RTCVideoDecoderTest::NotifyResetDone)); |
+ EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, rtc_decoder_->Reset()); |
+} |
+ |
+TEST_F(RTCVideoDecoderTest, ReleaseReturnsOk) { |
+ Initialize(); |
+ EXPECT_CALL(*mock_vda_, Reset()) |
+ .WillOnce(Invoke(this, &RTCVideoDecoderTest::NotifyResetDone)); |
+ EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, rtc_decoder_->Release()); |
+} |
+ |
+TEST_F(RTCVideoDecoderTest, VdaThreadStops) { |
+ EXPECT_CALL(*mock_gpu_factories_, Abort()); |
+ vda_thread_.Stop(); |
+} |
+ |
+} // content |