Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / content / renderer / media / rtc_video_decoder_unittest.cc
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.
4
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"
14
15 using ::testing::_;
16 using ::testing::Invoke;
17 using ::testing::Return;
18 using ::testing::SaveArg;
19 using ::testing::WithArgs;
20
21 namespace content {
22
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_));
32   }
33
34   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);
48   }
49
50   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();
58   }
59
60   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;
64   }
65
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_);
71   }
72
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));
78   }
79
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())));
86   }
87
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();
94   }
95
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_;
102
103  private:
104   scoped_refptr<base::SingleThreadTaskRunner> vda_task_runner_;
105
106   base::Lock lock_;
107   base::WaitableEvent idle_waiter_;
108 };
109
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());
115 }
116
117 TEST_F(RTCVideoDecoderTest, CreateAndInitSucceedsForH264Codec) {
118   CreateDecoder(webrtc::kVideoCodecH264);
119   EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, rtc_decoder_->InitDecode(&codec_, 1));
120 }
121
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));
126 }
127
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));
133 }
134
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));
142 }
143
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));
152 }
153
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());
160 }
161
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());
168 }
169
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());
178 }
179
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));
189
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));
196
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));
204 }
205
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));
215
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));
222
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));
229 }
230
231 }  // content