1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
6 #include "base/message_loop/message_loop.h"
7 #include "base/synchronization/waitable_event.h"
8 #include "base/threading/thread.h"
9 #include "content/renderer/media/rtc_video_decoder.h"
10 #include "media/base/gmock_callback_support.h"
11 #include "media/filters/mock_gpu_video_accelerator_factories.h"
12 #include "media/video/mock_video_decode_accelerator.h"
13 #include "testing/gtest/include/gtest/gtest.h"
16 using ::testing::Invoke;
17 using ::testing::Return;
18 using ::testing::SaveArg;
19 using ::testing::WithArgs;
23 // TODO(wuchengli): add MockSharedMemroy so more functions can be tested.
24 class RTCVideoDecoderTest : public ::testing::Test,
25 webrtc::DecodedImageCallback {
28 : mock_gpu_factories_(new media::MockGpuVideoAcceleratorFactories),
29 vda_thread_("vda_thread"),
30 idle_waiter_(false, false) {
31 memset(&codec_, 0, sizeof(codec_));
34 virtual void SetUp() OVERRIDE {
35 ASSERT_TRUE(vda_thread_.Start());
36 vda_task_runner_ = vda_thread_.message_loop_proxy();
37 mock_vda_ = new media::MockVideoDecodeAccelerator;
38 EXPECT_CALL(*mock_gpu_factories_, GetTaskRunner())
39 .WillRepeatedly(Return(vda_task_runner_));
40 EXPECT_CALL(*mock_gpu_factories_, DoCreateVideoDecodeAccelerator(_, _))
42 Return(static_cast<media::VideoDecodeAccelerator*>(NULL)));
43 EXPECT_CALL(*mock_gpu_factories_,
44 DoCreateVideoDecodeAccelerator(media::VP8PROFILE_MAIN, _))
45 .WillRepeatedly(Return(mock_vda_));
46 EXPECT_CALL(*mock_gpu_factories_, CreateSharedMemory(_))
47 .WillRepeatedly(Return(static_cast<base::SharedMemory*>(NULL)));
48 EXPECT_CALL(*mock_vda_, Destroy());
50 RTCVideoDecoder::Create(webrtc::kVideoCodecVP8, mock_gpu_factories_);
53 virtual void TearDown() OVERRIDE {
54 VLOG(2) << "TearDown";
55 EXPECT_TRUE(vda_thread_.IsRunning());
56 RunUntilIdle(); // Wait until all callbascks complete.
57 vda_task_runner_->DeleteSoon(FROM_HERE, rtc_decoder_.release());
58 // Make sure the decoder is released before stopping the thread.
63 virtual int32_t Decoded(webrtc::I420VideoFrame& decoded_image) OVERRIDE {
65 EXPECT_EQ(vda_task_runner_, base::MessageLoopProxy::current());
66 return WEBRTC_VIDEO_CODEC_OK;
70 VLOG(2) << "Initialize";
71 codec_.codecType = webrtc::kVideoCodecVP8;
72 EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, rtc_decoder_->InitDecode(&codec_, 1));
73 EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
74 rtc_decoder_->RegisterDecodeCompleteCallback(this));
77 void NotifyResetDone() {
78 VLOG(2) << "NotifyResetDone";
79 vda_task_runner_->PostTask(
81 base::Bind(&RTCVideoDecoder::NotifyResetDone,
82 base::Unretained(rtc_decoder_.get())));
86 VLOG(2) << "RunUntilIdle";
87 vda_task_runner_->PostTask(FROM_HERE,
88 base::Bind(&base::WaitableEvent::Signal,
89 base::Unretained(&idle_waiter_)));
94 scoped_refptr<media::MockGpuVideoAcceleratorFactories> mock_gpu_factories_;
95 media::MockVideoDecodeAccelerator* mock_vda_;
96 scoped_ptr<RTCVideoDecoder> rtc_decoder_;
97 webrtc::VideoCodec codec_;
98 base::Thread vda_thread_;
101 scoped_refptr<base::SingleThreadTaskRunner> vda_task_runner_;
104 base::WaitableEvent idle_waiter_;
107 TEST_F(RTCVideoDecoderTest, CreateReturnsNullOnUnsupportedCodec) {
108 scoped_ptr<RTCVideoDecoder> null_rtc_decoder(
109 RTCVideoDecoder::Create(webrtc::kVideoCodecI420, mock_gpu_factories_));
110 EXPECT_EQ(NULL, null_rtc_decoder.get());
113 TEST_F(RTCVideoDecoderTest, InitDecodeReturnsErrorOnFeedbackMode) {
114 codec_.codecType = webrtc::kVideoCodecVP8;
115 codec_.codecSpecific.VP8.feedbackModeOn = true;
116 EXPECT_EQ(WEBRTC_VIDEO_CODEC_ERROR, rtc_decoder_->InitDecode(&codec_, 1));
119 TEST_F(RTCVideoDecoderTest, DecodeReturnsErrorWithoutInitDecode) {
120 webrtc::EncodedImage input_image;
121 EXPECT_EQ(WEBRTC_VIDEO_CODEC_UNINITIALIZED,
122 rtc_decoder_->Decode(input_image, false, NULL, NULL, 0));
125 TEST_F(RTCVideoDecoderTest, DecodeReturnsErrorOnIncompleteFrame) {
127 webrtc::EncodedImage input_image;
128 input_image._completeFrame = false;
129 EXPECT_EQ(WEBRTC_VIDEO_CODEC_ERROR,
130 rtc_decoder_->Decode(input_image, false, NULL, NULL, 0));
133 TEST_F(RTCVideoDecoderTest, DecodeReturnsErrorOnMissingFrames) {
135 webrtc::EncodedImage input_image;
136 input_image._completeFrame = true;
137 bool missingFrames = true;
138 EXPECT_EQ(WEBRTC_VIDEO_CODEC_ERROR,
139 rtc_decoder_->Decode(input_image, missingFrames, NULL, NULL, 0));
142 TEST_F(RTCVideoDecoderTest, ResetReturnsOk) {
144 EXPECT_CALL(*mock_vda_, Reset())
145 .WillOnce(Invoke(this, &RTCVideoDecoderTest::NotifyResetDone));
146 EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, rtc_decoder_->Reset());
149 TEST_F(RTCVideoDecoderTest, ReleaseReturnsOk) {
151 EXPECT_CALL(*mock_vda_, Reset())
152 .WillOnce(Invoke(this, &RTCVideoDecoderTest::NotifyResetDone));
153 EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, rtc_decoder_->Release());
156 TEST_F(RTCVideoDecoderTest, InitDecodeAfterRelease) {
157 EXPECT_CALL(*mock_vda_, Reset())
158 .WillRepeatedly(Invoke(this, &RTCVideoDecoderTest::NotifyResetDone));
160 EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, rtc_decoder_->Release());
162 EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, rtc_decoder_->Release());
165 TEST_F(RTCVideoDecoderTest, IsBufferAfterReset) {
166 EXPECT_TRUE(rtc_decoder_->IsBufferAfterReset(0, RTCVideoDecoder::ID_INVALID));
167 EXPECT_TRUE(rtc_decoder_->IsBufferAfterReset(RTCVideoDecoder::ID_LAST,
168 RTCVideoDecoder::ID_INVALID));
169 EXPECT_FALSE(rtc_decoder_->IsBufferAfterReset(RTCVideoDecoder::ID_HALF - 2,
170 RTCVideoDecoder::ID_HALF + 2));
171 EXPECT_TRUE(rtc_decoder_->IsBufferAfterReset(RTCVideoDecoder::ID_HALF + 2,
172 RTCVideoDecoder::ID_HALF - 2));
174 EXPECT_FALSE(rtc_decoder_->IsBufferAfterReset(0, 0));
175 EXPECT_TRUE(rtc_decoder_->IsBufferAfterReset(0, RTCVideoDecoder::ID_LAST));
177 rtc_decoder_->IsBufferAfterReset(0, RTCVideoDecoder::ID_HALF - 2));
179 rtc_decoder_->IsBufferAfterReset(0, RTCVideoDecoder::ID_HALF + 2));
181 EXPECT_FALSE(rtc_decoder_->IsBufferAfterReset(RTCVideoDecoder::ID_LAST, 0));
182 EXPECT_FALSE(rtc_decoder_->IsBufferAfterReset(RTCVideoDecoder::ID_LAST,
183 RTCVideoDecoder::ID_HALF - 2));
184 EXPECT_TRUE(rtc_decoder_->IsBufferAfterReset(RTCVideoDecoder::ID_LAST,
185 RTCVideoDecoder::ID_HALF + 2));
186 EXPECT_FALSE(rtc_decoder_->IsBufferAfterReset(RTCVideoDecoder::ID_LAST,
187 RTCVideoDecoder::ID_LAST));
190 TEST_F(RTCVideoDecoderTest, IsFirstBufferAfterReset) {
192 rtc_decoder_->IsFirstBufferAfterReset(0, RTCVideoDecoder::ID_INVALID));
194 rtc_decoder_->IsFirstBufferAfterReset(1, RTCVideoDecoder::ID_INVALID));
195 EXPECT_FALSE(rtc_decoder_->IsFirstBufferAfterReset(0, 0));
196 EXPECT_TRUE(rtc_decoder_->IsFirstBufferAfterReset(1, 0));
197 EXPECT_FALSE(rtc_decoder_->IsFirstBufferAfterReset(2, 0));
199 EXPECT_FALSE(rtc_decoder_->IsFirstBufferAfterReset(RTCVideoDecoder::ID_HALF,
200 RTCVideoDecoder::ID_HALF));
201 EXPECT_TRUE(rtc_decoder_->IsFirstBufferAfterReset(
202 RTCVideoDecoder::ID_HALF + 1, RTCVideoDecoder::ID_HALF));
203 EXPECT_FALSE(rtc_decoder_->IsFirstBufferAfterReset(
204 RTCVideoDecoder::ID_HALF + 2, RTCVideoDecoder::ID_HALF));
206 EXPECT_FALSE(rtc_decoder_->IsFirstBufferAfterReset(RTCVideoDecoder::ID_LAST,
207 RTCVideoDecoder::ID_LAST));
209 rtc_decoder_->IsFirstBufferAfterReset(0, RTCVideoDecoder::ID_LAST));
211 rtc_decoder_->IsFirstBufferAfterReset(1, RTCVideoDecoder::ID_LAST));