- add sources.
[platform/framework/web/crosswalk.git] / src / content / renderer / media / rtc_video_decoder_factory_tv_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/synchronization/waitable_event.h"
6 #include "base/task_runner_util.h"
7 #include "base/threading/thread.h"
8 #include "content/renderer/media/rtc_video_decoder_factory_tv.h"
9 #include "media/base/decoder_buffer.h"
10 #include "media/base/video_decoder_config.h"
11 #include "testing/gmock/include/gmock/gmock.h"
12 #include "testing/gtest/include/gtest/gtest.h"
13 #include "third_party/webrtc/modules/video_coding/codecs/interface/mock/mock_video_codec_interface.h"
14 #include "ui/gfx/rect.h"
15
16 using ::testing::_;
17 using ::testing::Return;
18
19 namespace content {
20
21 class RTCVideoDecoderFactoryTvTest : public ::testing::Test {
22  public:
23   RTCVideoDecoderFactoryTvTest()
24       : factory_(new RTCVideoDecoderFactoryTv),
25         decoder_(NULL),
26         is_demuxer_acquired_(false),
27         video_stream_(NULL),
28         size_(1280, 720),
29         input_image_(&data_, sizeof(data_), sizeof(data_)),
30         data_('a'),
31         read_event_(false, false),
32         decoder_thread_("Test decoder thread"),
33         decoder_thread_event_(false, false) {
34     memset(&codec_, 0, sizeof(codec_));
35     message_loop_proxy_ = base::MessageLoopProxy::current();
36     input_image_._frameType = webrtc::kKeyFrame;
37     input_image_._encodedWidth = size_.width();
38     input_image_._encodedHeight = size_.height();
39     input_image_._completeFrame = true;
40     decoder_thread_.Start();
41   }
42
43   virtual ~RTCVideoDecoderFactoryTvTest() {
44     if (is_demuxer_acquired_) {
45       factory_->ReleaseDemuxer();
46       is_demuxer_acquired_ = false;
47     }
48     if (decoder_) {
49       factory_->DestroyVideoDecoder(decoder_);
50       decoder_ = NULL;
51     }
52
53     decoder_thread_.Stop();
54   }
55
56   void ReadCallback(media::DemuxerStream::Status status,
57                     const scoped_refptr<media::DecoderBuffer>& decoder_buffer) {
58     switch (status) {
59       case media::DemuxerStream::kOk:
60         EXPECT_TRUE(decoder_buffer);
61         break;
62       case media::DemuxerStream::kConfigChanged:
63       case media::DemuxerStream::kAborted:
64         EXPECT_FALSE(decoder_buffer);
65         break;
66     }
67     last_decoder_buffer_ = decoder_buffer;
68     read_event_.Signal();
69   }
70
71   void ExpectEqualsAndSignal(int32_t expected, int32_t actual) {
72     EXPECT_EQ(expected, actual);
73     decoder_thread_event_.Signal();
74   }
75
76   void ExpectNotEqualsAndSignal(int32_t unexpected, int32_t actual) {
77     EXPECT_NE(unexpected, actual);
78     decoder_thread_event_.Signal();
79   }
80
81  protected:
82   base::Callback<void(int32_t)> BindExpectEquals(int32_t expected) {
83     return base::Bind(&RTCVideoDecoderFactoryTvTest::ExpectEqualsAndSignal,
84                       base::Unretained(this),
85                       expected);
86   }
87
88   base::Callback<void(int32_t)> BindExpectNotEquals(int32_t unexpected) {
89     return base::Bind(&RTCVideoDecoderFactoryTvTest::ExpectNotEqualsAndSignal,
90                       base::Unretained(this),
91                       unexpected);
92   }
93
94   base::Callback<int32_t(void)> BindInitDecode(const webrtc::VideoCodec* codec,
95                                                int32_t num_cores) {
96     return base::Bind(&webrtc::VideoDecoder::InitDecode,
97                       base::Unretained(decoder_),
98                       codec,
99                       num_cores);
100   }
101
102   base::Callback<int32_t(void)> BindDecode(
103       const webrtc::EncodedImage& input_image,
104       bool missing_frames,
105       const webrtc::RTPFragmentationHeader* fragmentation,
106       const webrtc::CodecSpecificInfo* info,
107       int64_t render_time_ms) {
108     return base::Bind(&webrtc::VideoDecoder::Decode,
109                       base::Unretained(decoder_),
110                       input_image,
111                       missing_frames,
112                       fragmentation,
113                       info,
114                       render_time_ms);
115   }
116
117   void CreateDecoderAndAcquireDemuxer() {
118     decoder_ = factory_->CreateVideoDecoder(webrtc::kVideoCodecVP8);
119     ASSERT_TRUE(decoder_);
120     ASSERT_TRUE(factory_->AcquireDemuxer());
121     is_demuxer_acquired_ = true;
122   }
123
124   void InitDecode() {
125     codec_.codecType = webrtc::kVideoCodecVP8;
126     codec_.width = size_.width();
127     codec_.height = size_.height();
128     base::PostTaskAndReplyWithResult(decoder_thread_.message_loop_proxy(),
129                                      FROM_HERE,
130                                      BindInitDecode(&codec_, 1),
131                                      BindExpectEquals(WEBRTC_VIDEO_CODEC_OK));
132     decoder_thread_event_.Wait();
133     base::PostTaskAndReplyWithResult(
134         decoder_thread_.message_loop_proxy(),
135         FROM_HERE,
136         base::Bind(&webrtc::VideoDecoder::RegisterDecodeCompleteCallback,
137                    base::Unretained(decoder_),
138                    &decode_complete_callback_),
139         BindExpectEquals(WEBRTC_VIDEO_CODEC_OK));
140     decoder_thread_event_.Wait();
141   }
142
143   void GetVideoStream() {
144     video_stream_ = factory_->GetStream(media::DemuxerStream::VIDEO);
145     ASSERT_TRUE(video_stream_);
146     EXPECT_EQ(media::kCodecVP8, video_stream_->video_decoder_config().codec());
147     EXPECT_EQ(size_, video_stream_->video_decoder_config().coded_size());
148     EXPECT_EQ(gfx::Rect(size_),
149               video_stream_->video_decoder_config().visible_rect());
150     EXPECT_EQ(size_, video_stream_->video_decoder_config().natural_size());
151   }
152
153   void PostDecodeAndWait(int32_t expected,
154                          const webrtc::EncodedImage& input_image,
155                          bool missing_frames,
156                          const webrtc::RTPFragmentationHeader* fragmentation,
157                          const webrtc::CodecSpecificInfo* info,
158                          int64_t render_time_ms) {
159     base::PostTaskAndReplyWithResult(
160         decoder_thread_.message_loop_proxy(),
161         FROM_HERE,
162         BindDecode(
163             input_image, missing_frames, fragmentation, info, render_time_ms),
164         BindExpectEquals(expected));
165     decoder_thread_event_.Wait();
166   }
167
168   RTCVideoDecoderFactoryTv* factory_;
169   webrtc::VideoDecoder* decoder_;
170   bool is_demuxer_acquired_;
171   base::MessageLoopProxy* message_loop_proxy_;
172   media::DemuxerStream* video_stream_;
173   webrtc::VideoCodec codec_;
174   gfx::Size size_;
175   webrtc::EncodedImage input_image_;
176   unsigned char data_;
177   webrtc::MockDecodedImageCallback decode_complete_callback_;
178   base::WaitableEvent read_event_;
179   base::Thread decoder_thread_;
180   base::WaitableEvent decoder_thread_event_;
181   scoped_refptr<media::DecoderBuffer> last_decoder_buffer_;
182 };
183
184 TEST_F(RTCVideoDecoderFactoryTvTest, CreateAndDestroyDecoder) {
185   // Only VP8 decoder is supported.
186   ASSERT_FALSE(factory_->CreateVideoDecoder(webrtc::kVideoCodecI420));
187   decoder_ = factory_->CreateVideoDecoder(webrtc::kVideoCodecVP8);
188   ASSERT_TRUE(decoder_);
189   // Only one decoder at a time will be created.
190   ASSERT_FALSE(factory_->CreateVideoDecoder(webrtc::kVideoCodecVP8));
191   factory_->DestroyVideoDecoder(decoder_);
192 }
193
194 TEST_F(RTCVideoDecoderFactoryTvTest, AcquireDemuxerAfterCreateDecoder) {
195   decoder_ = factory_->CreateVideoDecoder(webrtc::kVideoCodecVP8);
196   ASSERT_TRUE(decoder_);
197   ASSERT_TRUE(factory_->AcquireDemuxer());
198   is_demuxer_acquired_ = true;
199   // Demuxer can be acquired only once.
200   ASSERT_FALSE(factory_->AcquireDemuxer());
201 }
202
203 TEST_F(RTCVideoDecoderFactoryTvTest, AcquireDemuxerBeforeCreateDecoder) {
204   ASSERT_TRUE(factory_->AcquireDemuxer());
205   is_demuxer_acquired_ = true;
206   decoder_ = factory_->CreateVideoDecoder(webrtc::kVideoCodecVP8);
207   ASSERT_TRUE(decoder_);
208 }
209
210 TEST_F(RTCVideoDecoderFactoryTvTest, InitDecodeReturnsErrorOnNonVP8Codec) {
211   CreateDecoderAndAcquireDemuxer();
212   codec_.codecType = webrtc::kVideoCodecI420;
213   base::PostTaskAndReplyWithResult(decoder_thread_.message_loop_proxy(),
214                                    FROM_HERE,
215                                    BindInitDecode(&codec_, 1),
216                                    BindExpectNotEquals(WEBRTC_VIDEO_CODEC_OK));
217   decoder_thread_event_.Wait();
218 }
219
220 TEST_F(RTCVideoDecoderFactoryTvTest, InitDecodeReturnsErrorOnFeedbackMode) {
221   CreateDecoderAndAcquireDemuxer();
222   codec_.codecType = webrtc::kVideoCodecVP8;
223   codec_.codecSpecific.VP8.feedbackModeOn = true;
224   base::PostTaskAndReplyWithResult(decoder_thread_.message_loop_proxy(),
225                                    FROM_HERE,
226                                    BindInitDecode(&codec_, 1),
227                                    BindExpectNotEquals(WEBRTC_VIDEO_CODEC_OK));
228   decoder_thread_event_.Wait();
229 }
230
231 TEST_F(RTCVideoDecoderFactoryTvTest, DecodeReturnsErrorBeforeInitDecode) {
232   CreateDecoderAndAcquireDemuxer();
233   PostDecodeAndWait(
234       WEBRTC_VIDEO_CODEC_UNINITIALIZED, input_image_, false, NULL, NULL, 0);
235 }
236
237 TEST_F(RTCVideoDecoderFactoryTvTest, DecodeReturnsErrorOnDamagedBitstream) {
238   CreateDecoderAndAcquireDemuxer();
239   InitDecode();
240   input_image_._completeFrame = false;
241   PostDecodeAndWait(
242       WEBRTC_VIDEO_CODEC_ERROR, input_image_, false, NULL, NULL, 0);
243 }
244
245 TEST_F(RTCVideoDecoderFactoryTvTest, DecodeReturnsErrorOnMissingFrames) {
246   CreateDecoderAndAcquireDemuxer();
247   InitDecode();
248   PostDecodeAndWait(
249       WEBRTC_VIDEO_CODEC_ERROR, input_image_, true, NULL, NULL, 0);
250 }
251
252 TEST_F(RTCVideoDecoderFactoryTvTest, GetNonVideoStreamFails) {
253   CreateDecoderAndAcquireDemuxer();
254   InitDecode();
255   EXPECT_FALSE(factory_->GetStream(media::DemuxerStream::AUDIO));
256   EXPECT_FALSE(factory_->GetStream(media::DemuxerStream::UNKNOWN));
257 }
258
259 TEST_F(RTCVideoDecoderFactoryTvTest, GetVideoStreamSucceeds) {
260   CreateDecoderAndAcquireDemuxer();
261   InitDecode();
262   GetVideoStream();
263 }
264
265 TEST_F(RTCVideoDecoderFactoryTvTest, DecodeReturnsErrorOnNonKeyFrameAtFirst) {
266   CreateDecoderAndAcquireDemuxer();
267   InitDecode();
268   GetVideoStream();
269   input_image_._frameType = webrtc::kDeltaFrame;
270   PostDecodeAndWait(
271       WEBRTC_VIDEO_CODEC_ERROR, input_image_, false, NULL, NULL, 0);
272 }
273
274 TEST_F(RTCVideoDecoderFactoryTvTest, DecodeUpdatesVideoSizeOnKeyFrame) {
275   CreateDecoderAndAcquireDemuxer();
276   InitDecode();
277   GetVideoStream();
278   gfx::Size new_size(320, 240);
279   input_image_._encodedWidth = new_size.width();
280   input_image_._encodedHeight = new_size.height();
281   PostDecodeAndWait(WEBRTC_VIDEO_CODEC_OK, input_image_, false, NULL, NULL, 0);
282   EXPECT_EQ(new_size, video_stream_->video_decoder_config().coded_size());
283   EXPECT_EQ(gfx::Rect(new_size),
284             video_stream_->video_decoder_config().visible_rect());
285   EXPECT_EQ(new_size, video_stream_->video_decoder_config().natural_size());
286 }
287
288 TEST_F(RTCVideoDecoderFactoryTvTest, DecodeAdjustsTimestampFromZero) {
289   CreateDecoderAndAcquireDemuxer();
290   InitDecode();
291   GetVideoStream();
292   PostDecodeAndWait(
293       WEBRTC_VIDEO_CODEC_OK, input_image_, false, NULL, NULL, 10000);
294   video_stream_->Read(base::Bind(&RTCVideoDecoderFactoryTvTest::ReadCallback,
295                                  base::Unretained(this)));
296   read_event_.Wait();
297   EXPECT_EQ(base::TimeDelta::FromMilliseconds(0),
298             last_decoder_buffer_->GetTimestamp());
299   PostDecodeAndWait(
300       WEBRTC_VIDEO_CODEC_OK, input_image_, false, NULL, NULL, 10033);
301   video_stream_->Read(base::Bind(&RTCVideoDecoderFactoryTvTest::ReadCallback,
302                                  base::Unretained(this)));
303   read_event_.Wait();
304   EXPECT_EQ(base::TimeDelta::FromMilliseconds(33),
305             last_decoder_buffer_->GetTimestamp());
306 }
307
308 TEST_F(RTCVideoDecoderFactoryTvTest, DecodePassesDataCorrectly) {
309   CreateDecoderAndAcquireDemuxer();
310   InitDecode();
311   GetVideoStream();
312   video_stream_->Read(base::Bind(&RTCVideoDecoderFactoryTvTest::ReadCallback,
313                                  base::Unretained(this)));
314   PostDecodeAndWait(WEBRTC_VIDEO_CODEC_OK, input_image_, false, NULL, NULL, 0);
315   read_event_.Wait();
316   EXPECT_EQ(static_cast<int>(sizeof(data_)),
317             last_decoder_buffer_->GetDataSize());
318   EXPECT_EQ(data_, last_decoder_buffer_->GetData()[0]);
319 }
320
321 TEST_F(RTCVideoDecoderFactoryTvTest, NextReadTriggersDecodeCompleteCallback) {
322   EXPECT_CALL(decode_complete_callback_, Decoded(_))
323       .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
324
325   CreateDecoderAndAcquireDemuxer();
326   InitDecode();
327   GetVideoStream();
328   video_stream_->Read(base::Bind(&RTCVideoDecoderFactoryTvTest::ReadCallback,
329                                  base::Unretained(this)));
330   PostDecodeAndWait(WEBRTC_VIDEO_CODEC_OK, input_image_, false, NULL, NULL, 0);
331   read_event_.Wait();
332   video_stream_->Read(base::Bind(&RTCVideoDecoderFactoryTvTest::ReadCallback,
333                                  base::Unretained(this)));
334 }
335
336 TEST_F(RTCVideoDecoderFactoryTvTest, ResetReturnsOk) {
337   CreateDecoderAndAcquireDemuxer();
338   InitDecode();
339   EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, decoder_->Reset());
340 }
341
342 TEST_F(RTCVideoDecoderFactoryTvTest, ReleaseReturnsOk) {
343   CreateDecoderAndAcquireDemuxer();
344   InitDecode();
345   EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, decoder_->Release());
346 }
347
348 }  // content