Updating trunk VERSION from 2139.0 to 2140.0
[chromium-blink-merge.git] / content / renderer / media / rtc_video_decoder_unittest.cc
blobc0603441605f9a958b76e40cbd186cf550745190
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.
5 #include "base/bind.h"
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"
15 using ::testing::_;
16 using ::testing::Invoke;
17 using ::testing::Return;
18 using ::testing::SaveArg;
19 using ::testing::WithArgs;
21 namespace content {
23 // TODO(wuchengli): add MockSharedMemroy so more functions can be tested.
24 class RTCVideoDecoderTest : public ::testing::Test,
25 webrtc::DecodedImageCallback {
26 public:
27 RTCVideoDecoderTest()
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_.get(), GetTaskRunner())
39 .WillRepeatedly(Return(vda_task_runner_));
40 EXPECT_CALL(*mock_gpu_factories_.get(), DoCreateVideoDecodeAccelerator())
41 .WillRepeatedly(Return(mock_vda_));
42 EXPECT_CALL(*mock_gpu_factories_.get(), CreateSharedMemory(_))
43 .WillRepeatedly(Return(static_cast<base::SharedMemory*>(NULL)));
44 EXPECT_CALL(*mock_vda_, Initialize(_, _))
45 .Times(1)
46 .WillRepeatedly(Return(true));
47 EXPECT_CALL(*mock_vda_, Destroy()).Times(1);
50 virtual void TearDown() OVERRIDE {
51 VLOG(2) << "TearDown";
52 EXPECT_TRUE(vda_thread_.IsRunning());
53 RunUntilIdle(); // Wait until all callbascks complete.
54 vda_task_runner_->DeleteSoon(FROM_HERE, rtc_decoder_.release());
55 // Make sure the decoder is released before stopping the thread.
56 RunUntilIdle();
57 vda_thread_.Stop();
60 virtual int32_t Decoded(webrtc::I420VideoFrame& decoded_image) OVERRIDE {
61 VLOG(2) << "Decoded";
62 EXPECT_EQ(vda_task_runner_, base::MessageLoopProxy::current());
63 return WEBRTC_VIDEO_CODEC_OK;
66 void CreateDecoder(webrtc::VideoCodecType codec_type) {
67 VLOG(2) << "CreateDecoder";
68 codec_.codecType = codec_type;
69 rtc_decoder_ =
70 RTCVideoDecoder::Create(codec_type, mock_gpu_factories_);
73 void Initialize() {
74 VLOG(2) << "Initialize";
75 EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, rtc_decoder_->InitDecode(&codec_, 1));
76 EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
77 rtc_decoder_->RegisterDecodeCompleteCallback(this));
80 void NotifyResetDone() {
81 VLOG(2) << "NotifyResetDone";
82 vda_task_runner_->PostTask(
83 FROM_HERE,
84 base::Bind(&RTCVideoDecoder::NotifyResetDone,
85 base::Unretained(rtc_decoder_.get())));
88 void RunUntilIdle() {
89 VLOG(2) << "RunUntilIdle";
90 vda_task_runner_->PostTask(FROM_HERE,
91 base::Bind(&base::WaitableEvent::Signal,
92 base::Unretained(&idle_waiter_)));
93 idle_waiter_.Wait();
96 protected:
97 scoped_refptr<media::MockGpuVideoAcceleratorFactories> mock_gpu_factories_;
98 media::MockVideoDecodeAccelerator* mock_vda_;
99 scoped_ptr<RTCVideoDecoder> rtc_decoder_;
100 webrtc::VideoCodec codec_;
101 base::Thread vda_thread_;
103 private:
104 scoped_refptr<base::SingleThreadTaskRunner> vda_task_runner_;
106 base::Lock lock_;
107 base::WaitableEvent idle_waiter_;
110 TEST_F(RTCVideoDecoderTest, CreateReturnsNullOnUnsupportedCodec) {
111 CreateDecoder(webrtc::kVideoCodecVP8);
112 scoped_ptr<RTCVideoDecoder> null_rtc_decoder(
113 RTCVideoDecoder::Create(webrtc::kVideoCodecI420, mock_gpu_factories_));
114 EXPECT_EQ(NULL, null_rtc_decoder.get());
117 TEST_F(RTCVideoDecoderTest, CreateAndInitSucceedsForH264Codec) {
118 CreateDecoder(webrtc::kVideoCodecH264);
119 EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, rtc_decoder_->InitDecode(&codec_, 1));
122 TEST_F(RTCVideoDecoderTest, InitDecodeReturnsErrorOnFeedbackMode) {
123 CreateDecoder(webrtc::kVideoCodecVP8);
124 codec_.codecSpecific.VP8.feedbackModeOn = true;
125 EXPECT_EQ(WEBRTC_VIDEO_CODEC_ERROR, rtc_decoder_->InitDecode(&codec_, 1));
128 TEST_F(RTCVideoDecoderTest, DecodeReturnsErrorWithoutInitDecode) {
129 CreateDecoder(webrtc::kVideoCodecVP8);
130 webrtc::EncodedImage input_image;
131 EXPECT_EQ(WEBRTC_VIDEO_CODEC_UNINITIALIZED,
132 rtc_decoder_->Decode(input_image, false, NULL, NULL, 0));
135 TEST_F(RTCVideoDecoderTest, DecodeReturnsErrorOnIncompleteFrame) {
136 CreateDecoder(webrtc::kVideoCodecVP8);
137 Initialize();
138 webrtc::EncodedImage input_image;
139 input_image._completeFrame = false;
140 EXPECT_EQ(WEBRTC_VIDEO_CODEC_ERROR,
141 rtc_decoder_->Decode(input_image, false, NULL, NULL, 0));
144 TEST_F(RTCVideoDecoderTest, DecodeReturnsErrorOnMissingFrames) {
145 CreateDecoder(webrtc::kVideoCodecVP8);
146 Initialize();
147 webrtc::EncodedImage input_image;
148 input_image._completeFrame = true;
149 bool missingFrames = true;
150 EXPECT_EQ(WEBRTC_VIDEO_CODEC_ERROR,
151 rtc_decoder_->Decode(input_image, missingFrames, NULL, NULL, 0));
154 TEST_F(RTCVideoDecoderTest, ResetReturnsOk) {
155 CreateDecoder(webrtc::kVideoCodecVP8);
156 Initialize();
157 EXPECT_CALL(*mock_vda_, Reset())
158 .WillOnce(Invoke(this, &RTCVideoDecoderTest::NotifyResetDone));
159 EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, rtc_decoder_->Reset());
162 TEST_F(RTCVideoDecoderTest, ReleaseReturnsOk) {
163 CreateDecoder(webrtc::kVideoCodecVP8);
164 Initialize();
165 EXPECT_CALL(*mock_vda_, Reset())
166 .WillOnce(Invoke(this, &RTCVideoDecoderTest::NotifyResetDone));
167 EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, rtc_decoder_->Release());
170 TEST_F(RTCVideoDecoderTest, InitDecodeAfterRelease) {
171 CreateDecoder(webrtc::kVideoCodecVP8);
172 EXPECT_CALL(*mock_vda_, Reset())
173 .WillRepeatedly(Invoke(this, &RTCVideoDecoderTest::NotifyResetDone));
174 Initialize();
175 EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, rtc_decoder_->Release());
176 Initialize();
177 EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, rtc_decoder_->Release());
180 TEST_F(RTCVideoDecoderTest, IsBufferAfterReset) {
181 CreateDecoder(webrtc::kVideoCodecVP8);
182 EXPECT_TRUE(rtc_decoder_->IsBufferAfterReset(0, RTCVideoDecoder::ID_INVALID));
183 EXPECT_TRUE(rtc_decoder_->IsBufferAfterReset(RTCVideoDecoder::ID_LAST,
184 RTCVideoDecoder::ID_INVALID));
185 EXPECT_FALSE(rtc_decoder_->IsBufferAfterReset(RTCVideoDecoder::ID_HALF - 2,
186 RTCVideoDecoder::ID_HALF + 2));
187 EXPECT_TRUE(rtc_decoder_->IsBufferAfterReset(RTCVideoDecoder::ID_HALF + 2,
188 RTCVideoDecoder::ID_HALF - 2));
190 EXPECT_FALSE(rtc_decoder_->IsBufferAfterReset(0, 0));
191 EXPECT_TRUE(rtc_decoder_->IsBufferAfterReset(0, RTCVideoDecoder::ID_LAST));
192 EXPECT_FALSE(
193 rtc_decoder_->IsBufferAfterReset(0, RTCVideoDecoder::ID_HALF - 2));
194 EXPECT_TRUE(
195 rtc_decoder_->IsBufferAfterReset(0, RTCVideoDecoder::ID_HALF + 2));
197 EXPECT_FALSE(rtc_decoder_->IsBufferAfterReset(RTCVideoDecoder::ID_LAST, 0));
198 EXPECT_FALSE(rtc_decoder_->IsBufferAfterReset(RTCVideoDecoder::ID_LAST,
199 RTCVideoDecoder::ID_HALF - 2));
200 EXPECT_TRUE(rtc_decoder_->IsBufferAfterReset(RTCVideoDecoder::ID_LAST,
201 RTCVideoDecoder::ID_HALF + 2));
202 EXPECT_FALSE(rtc_decoder_->IsBufferAfterReset(RTCVideoDecoder::ID_LAST,
203 RTCVideoDecoder::ID_LAST));
206 TEST_F(RTCVideoDecoderTest, IsFirstBufferAfterReset) {
207 CreateDecoder(webrtc::kVideoCodecVP8);
208 EXPECT_TRUE(
209 rtc_decoder_->IsFirstBufferAfterReset(0, RTCVideoDecoder::ID_INVALID));
210 EXPECT_FALSE(
211 rtc_decoder_->IsFirstBufferAfterReset(1, RTCVideoDecoder::ID_INVALID));
212 EXPECT_FALSE(rtc_decoder_->IsFirstBufferAfterReset(0, 0));
213 EXPECT_TRUE(rtc_decoder_->IsFirstBufferAfterReset(1, 0));
214 EXPECT_FALSE(rtc_decoder_->IsFirstBufferAfterReset(2, 0));
216 EXPECT_FALSE(rtc_decoder_->IsFirstBufferAfterReset(RTCVideoDecoder::ID_HALF,
217 RTCVideoDecoder::ID_HALF));
218 EXPECT_TRUE(rtc_decoder_->IsFirstBufferAfterReset(
219 RTCVideoDecoder::ID_HALF + 1, RTCVideoDecoder::ID_HALF));
220 EXPECT_FALSE(rtc_decoder_->IsFirstBufferAfterReset(
221 RTCVideoDecoder::ID_HALF + 2, RTCVideoDecoder::ID_HALF));
223 EXPECT_FALSE(rtc_decoder_->IsFirstBufferAfterReset(RTCVideoDecoder::ID_LAST,
224 RTCVideoDecoder::ID_LAST));
225 EXPECT_TRUE(
226 rtc_decoder_->IsFirstBufferAfterReset(0, RTCVideoDecoder::ID_LAST));
227 EXPECT_FALSE(
228 rtc_decoder_->IsFirstBufferAfterReset(1, RTCVideoDecoder::ID_LAST));
231 } // content