Upstream version 5.34.104.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   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(_, _))
41         .WillRepeatedly(
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());
49     rtc_decoder_ =
50         RTCVideoDecoder::Create(webrtc::kVideoCodecVP8, mock_gpu_factories_);
51   }
52
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.
59     RunUntilIdle();
60     vda_thread_.Stop();
61   }
62
63   virtual int32_t Decoded(webrtc::I420VideoFrame& decoded_image) OVERRIDE {
64     VLOG(2) << "Decoded";
65     EXPECT_EQ(vda_task_runner_, base::MessageLoopProxy::current());
66     return WEBRTC_VIDEO_CODEC_OK;
67   }
68
69   void Initialize() {
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));
75   }
76
77   void NotifyResetDone() {
78     VLOG(2) << "NotifyResetDone";
79     vda_task_runner_->PostTask(
80         FROM_HERE,
81         base::Bind(&RTCVideoDecoder::NotifyResetDone,
82                    base::Unretained(rtc_decoder_.get())));
83   }
84
85   void RunUntilIdle() {
86     VLOG(2) << "RunUntilIdle";
87     vda_task_runner_->PostTask(FROM_HERE,
88                                base::Bind(&base::WaitableEvent::Signal,
89                                           base::Unretained(&idle_waiter_)));
90     idle_waiter_.Wait();
91   }
92
93  protected:
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_;
99
100  private:
101   scoped_refptr<base::SingleThreadTaskRunner> vda_task_runner_;
102
103   base::Lock lock_;
104   base::WaitableEvent idle_waiter_;
105 };
106
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());
111 }
112
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));
117 }
118
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));
123 }
124
125 TEST_F(RTCVideoDecoderTest, DecodeReturnsErrorOnIncompleteFrame) {
126   Initialize();
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));
131 }
132
133 TEST_F(RTCVideoDecoderTest, DecodeReturnsErrorOnMissingFrames) {
134   Initialize();
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));
140 }
141
142 TEST_F(RTCVideoDecoderTest, ResetReturnsOk) {
143   Initialize();
144   EXPECT_CALL(*mock_vda_, Reset())
145       .WillOnce(Invoke(this, &RTCVideoDecoderTest::NotifyResetDone));
146   EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, rtc_decoder_->Reset());
147 }
148
149 TEST_F(RTCVideoDecoderTest, ReleaseReturnsOk) {
150   Initialize();
151   EXPECT_CALL(*mock_vda_, Reset())
152       .WillOnce(Invoke(this, &RTCVideoDecoderTest::NotifyResetDone));
153   EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, rtc_decoder_->Release());
154 }
155
156 TEST_F(RTCVideoDecoderTest, InitDecodeAfterRelease) {
157   EXPECT_CALL(*mock_vda_, Reset())
158       .WillRepeatedly(Invoke(this, &RTCVideoDecoderTest::NotifyResetDone));
159   Initialize();
160   EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, rtc_decoder_->Release());
161   Initialize();
162   EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, rtc_decoder_->Release());
163 }
164
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));
173
174   EXPECT_FALSE(rtc_decoder_->IsBufferAfterReset(0, 0));
175   EXPECT_TRUE(rtc_decoder_->IsBufferAfterReset(0, RTCVideoDecoder::ID_LAST));
176   EXPECT_FALSE(
177       rtc_decoder_->IsBufferAfterReset(0, RTCVideoDecoder::ID_HALF - 2));
178   EXPECT_TRUE(
179       rtc_decoder_->IsBufferAfterReset(0, RTCVideoDecoder::ID_HALF + 2));
180
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));
188 }
189
190 TEST_F(RTCVideoDecoderTest, IsFirstBufferAfterReset) {
191   EXPECT_TRUE(
192       rtc_decoder_->IsFirstBufferAfterReset(0, RTCVideoDecoder::ID_INVALID));
193   EXPECT_FALSE(
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));
198
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));
205
206   EXPECT_FALSE(rtc_decoder_->IsFirstBufferAfterReset(RTCVideoDecoder::ID_LAST,
207                                                      RTCVideoDecoder::ID_LAST));
208   EXPECT_TRUE(
209       rtc_decoder_->IsFirstBufferAfterReset(0, RTCVideoDecoder::ID_LAST));
210   EXPECT_FALSE(
211       rtc_decoder_->IsFirstBufferAfterReset(1, RTCVideoDecoder::ID_LAST));
212 }
213
214 }  // content