Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(244)

Side by Side Diff: content/renderer/media/rtc_video_decoder_factory_tv_unittest.cc

Issue 14247018: Implement WebRTC in Chrome for TV (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: fix bugs Created 7 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright (c) 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_vid eo_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
83 base::Callback<void(int32_t)> BindExpectEquals(int32_t expected) {
84 return base::Bind(&RTCVideoDecoderFactoryTvTest::ExpectEqualsAndSignal,
85 base::Unretained(this),
86 expected);
87 }
88
89 base::Callback<void(int32_t)> BindExpectNotEquals(int32_t unexpected) {
90 return base::Bind(&RTCVideoDecoderFactoryTvTest::ExpectNotEqualsAndSignal,
91 base::Unretained(this),
92 unexpected);
93 }
94
95 base::Callback<int32_t(void)> BindInitDecode(const webrtc::VideoCodec* codec,
96 int32_t num_cores) {
97 return base::Bind(&webrtc::VideoDecoder::InitDecode,
98 base::Unretained(decoder_),
99 codec,
100 num_cores);
101 }
102
103 base::Callback<int32_t(void)> BindDecode(
104 const webrtc::EncodedImage& input_image,
105 bool missing_frames,
106 const webrtc::RTPFragmentationHeader* fragmentation,
107 const webrtc::CodecSpecificInfo* info = NULL,
108 int64_t render_time_ms = -1) {
109 return base::Bind(&webrtc::VideoDecoder::Decode,
110 base::Unretained(decoder_),
111 input_image,
112 missing_frames,
113 fragmentation,
114 info,
115 render_time_ms);
116 }
117
118 void CreateDecoderAndAcquireDemuxer() {
119 decoder_ = factory_->CreateVideoDecoder(webrtc::kVideoCodecVP8);
120 ASSERT_TRUE(decoder_);
121 ASSERT_TRUE(factory_->AcquireDemuxer());
122 is_demuxer_acquired_ = true;
123 }
124
125 void InitDecode() {
126 codec_.codecType = webrtc::kVideoCodecVP8;
127 codec_.width = size_.width();
128 codec_.height = size_.height();
129 base::PostTaskAndReplyWithResult(decoder_thread_.message_loop_proxy(),
130 FROM_HERE,
131 BindInitDecode(&codec_, 1),
132 BindExpectEquals(WEBRTC_VIDEO_CODEC_OK));
133 decoder_thread_event_.Wait();
134 base::PostTaskAndReplyWithResult(
135 decoder_thread_.message_loop_proxy(),
136 FROM_HERE,
137 base::Bind(&webrtc::VideoDecoder::RegisterDecodeCompleteCallback,
138 base::Unretained(decoder_),
139 &decode_complete_callback_),
140 BindExpectEquals(WEBRTC_VIDEO_CODEC_OK));
141 decoder_thread_event_.Wait();
142 }
143
144 void GetVideoStream() {
145 video_stream_ = factory_->GetStream(media::DemuxerStream::VIDEO);
146 ASSERT_TRUE(video_stream_);
147 EXPECT_EQ(media::kCodecVP8, video_stream_->video_decoder_config().codec());
148 EXPECT_EQ(size_, video_stream_->video_decoder_config().coded_size());
149 EXPECT_EQ(gfx::Rect(size_),
150 video_stream_->video_decoder_config().visible_rect());
151 EXPECT_EQ(size_, video_stream_->video_decoder_config().natural_size());
152 }
153
154 void PostDecodeAndWait(int32_t expected,
155 const webrtc::EncodedImage& input_image,
156 bool missing_frames,
157 const webrtc::RTPFragmentationHeader* fragmentation,
158 const webrtc::CodecSpecificInfo* info = NULL,
159 int64_t render_time_ms = -1) {
160 base::PostTaskAndReplyWithResult(
161 decoder_thread_.message_loop_proxy(),
162 FROM_HERE,
163 BindDecode(
164 input_image, missing_frames, fragmentation, info, render_time_ms),
165 BindExpectEquals(expected));
166 decoder_thread_event_.Wait();
167 }
168
169 RTCVideoDecoderFactoryTv* factory_;
170 webrtc::VideoDecoder* decoder_;
171 bool is_demuxer_acquired_;
172 base::MessageLoopProxy* message_loop_proxy_;
173 media::DemuxerStream* video_stream_;
174 webrtc::VideoCodec codec_;
175 gfx::Size size_;
176 webrtc::EncodedImage input_image_;
177 unsigned char data_;
178 webrtc::MockDecodedImageCallback decode_complete_callback_;
179 base::WaitableEvent read_event_;
180 base::Thread decoder_thread_;
181 base::WaitableEvent decoder_thread_event_;
182 scoped_refptr<media::DecoderBuffer> last_decoder_buffer_;
183 };
184
185 TEST_F(RTCVideoDecoderFactoryTvTest, CreateAndDestroyDecoder) {
186 // Only VP8 decoder is supported.
187 ASSERT_FALSE(factory_->CreateVideoDecoder(webrtc::kVideoCodecI420));
188 decoder_ = factory_->CreateVideoDecoder(webrtc::kVideoCodecVP8);
189 ASSERT_TRUE(decoder_);
190 // Only one decoder at a time will be created.
191 ASSERT_FALSE(factory_->CreateVideoDecoder(webrtc::kVideoCodecVP8));
192 factory_->DestroyVideoDecoder(decoder_);
193 }
194
195 TEST_F(RTCVideoDecoderFactoryTvTest, AcquireDemuxerAfterCreateDecoder) {
196 decoder_ = factory_->CreateVideoDecoder(webrtc::kVideoCodecVP8);
197 ASSERT_TRUE(decoder_);
198 ASSERT_TRUE(factory_->AcquireDemuxer());
199 is_demuxer_acquired_ = true;
200 // Demuxer can be acquired only once.
201 ASSERT_FALSE(factory_->AcquireDemuxer());
202 }
203
204 TEST_F(RTCVideoDecoderFactoryTvTest, AcquireDemuxerBeforeCreateDecoder) {
205 ASSERT_TRUE(factory_->AcquireDemuxer());
206 is_demuxer_acquired_ = true;
207 decoder_ = factory_->CreateVideoDecoder(webrtc::kVideoCodecVP8);
208 ASSERT_TRUE(decoder_);
209 }
210
211 TEST_F(RTCVideoDecoderFactoryTvTest, InitDecodeReturnsErrorOnNonVP8Codec) {
212 CreateDecoderAndAcquireDemuxer();
213 codec_.codecType = webrtc::kVideoCodecI420;
214 base::PostTaskAndReplyWithResult(decoder_thread_.message_loop_proxy(),
215 FROM_HERE,
216 BindInitDecode(&codec_, 1),
217 BindExpectNotEquals(WEBRTC_VIDEO_CODEC_OK));
218 decoder_thread_event_.Wait();
219 }
220
221 TEST_F(RTCVideoDecoderFactoryTvTest, InitDecodeReturnsErrorOnFeedbackMode) {
222 CreateDecoderAndAcquireDemuxer();
223 codec_.codecType = webrtc::kVideoCodecVP8;
224 codec_.codecSpecific.VP8.feedbackModeOn = true;
225 base::PostTaskAndReplyWithResult(decoder_thread_.message_loop_proxy(),
226 FROM_HERE,
227 BindInitDecode(&codec_, 1),
228 BindExpectNotEquals(WEBRTC_VIDEO_CODEC_OK));
229 decoder_thread_event_.Wait();
230 }
231
232 TEST_F(RTCVideoDecoderFactoryTvTest, DecodeReturnsErrorBeforeInitDecode) {
233 CreateDecoderAndAcquireDemuxer();
234 PostDecodeAndWait(
235 WEBRTC_VIDEO_CODEC_UNINITIALIZED, input_image_, false, NULL, NULL, 0);
236 }
237
238 TEST_F(RTCVideoDecoderFactoryTvTest, DecodeReturnsErrorOnDamagedBitstream) {
239 CreateDecoderAndAcquireDemuxer();
240 InitDecode();
241 input_image_._completeFrame = false;
242 PostDecodeAndWait(
243 WEBRTC_VIDEO_CODEC_ERROR, input_image_, false, NULL, NULL, 0);
244 }
245
246 TEST_F(RTCVideoDecoderFactoryTvTest, DecodeReturnsErrorOnMissingFrames) {
247 CreateDecoderAndAcquireDemuxer();
248 InitDecode();
249 PostDecodeAndWait(
250 WEBRTC_VIDEO_CODEC_ERROR, input_image_, true, NULL, NULL, 0);
251 }
252
253 TEST_F(RTCVideoDecoderFactoryTvTest, GetNonVideoStreamFails) {
254 CreateDecoderAndAcquireDemuxer();
255 InitDecode();
256 EXPECT_FALSE(factory_->GetStream(media::DemuxerStream::AUDIO));
257 EXPECT_FALSE(factory_->GetStream(media::DemuxerStream::UNKNOWN));
258 }
259
260 TEST_F(RTCVideoDecoderFactoryTvTest, GetVideoStreamSucceeds) {
261 CreateDecoderAndAcquireDemuxer();
262 InitDecode();
263 GetVideoStream();
264 }
265
266 TEST_F(RTCVideoDecoderFactoryTvTest, DecodeReturnsErrorOnNonKeyFrameAtFirst) {
267 CreateDecoderAndAcquireDemuxer();
268 InitDecode();
269 GetVideoStream();
270 input_image_._frameType = webrtc::kDeltaFrame;
271 PostDecodeAndWait(
272 WEBRTC_VIDEO_CODEC_ERROR, input_image_, false, NULL, NULL, 0);
273 }
274
275 TEST_F(RTCVideoDecoderFactoryTvTest, DecodeUpdatesVideoSizeOnKeyFrame) {
276 CreateDecoderAndAcquireDemuxer();
277 InitDecode();
278 GetVideoStream();
279 gfx::Size new_size(320, 240);
280 input_image_._encodedWidth = new_size.width();
281 input_image_._encodedHeight = new_size.height();
282 PostDecodeAndWait(WEBRTC_VIDEO_CODEC_OK, input_image_, false, NULL, NULL, 0);
283 EXPECT_EQ(new_size, video_stream_->video_decoder_config().coded_size());
284 EXPECT_EQ(gfx::Rect(new_size),
285 video_stream_->video_decoder_config().visible_rect());
286 EXPECT_EQ(new_size, video_stream_->video_decoder_config().natural_size());
287 }
288
289 TEST_F(RTCVideoDecoderFactoryTvTest, DecodeAdjustsTimestampFromZero) {
290 CreateDecoderAndAcquireDemuxer();
291 InitDecode();
292 GetVideoStream();
293 PostDecodeAndWait(
294 WEBRTC_VIDEO_CODEC_OK, input_image_, false, NULL, NULL, 10000);
295 video_stream_->Read(base::Bind(&RTCVideoDecoderFactoryTvTest::ReadCallback,
296 base::Unretained(this)));
297 read_event_.Wait();
298 EXPECT_EQ(base::TimeDelta::FromMilliseconds(0),
299 last_decoder_buffer_->GetTimestamp());
300 PostDecodeAndWait(
301 WEBRTC_VIDEO_CODEC_OK, input_image_, false, NULL, NULL, 10033);
302 video_stream_->Read(base::Bind(&RTCVideoDecoderFactoryTvTest::ReadCallback,
303 base::Unretained(this)));
304 read_event_.Wait();
305 EXPECT_EQ(base::TimeDelta::FromMilliseconds(33),
306 last_decoder_buffer_->GetTimestamp());
307 }
308
309 TEST_F(RTCVideoDecoderFactoryTvTest, DecodePassesDataCorrectly) {
310 CreateDecoderAndAcquireDemuxer();
311 InitDecode();
312 GetVideoStream();
313 video_stream_->Read(base::Bind(&RTCVideoDecoderFactoryTvTest::ReadCallback,
314 base::Unretained(this)));
315 PostDecodeAndWait(WEBRTC_VIDEO_CODEC_OK, input_image_, false, NULL, NULL, 0);
316 read_event_.Wait();
317 EXPECT_EQ(static_cast<int>(sizeof(data_)),
318 last_decoder_buffer_->GetDataSize());
319 EXPECT_EQ(data_, last_decoder_buffer_->GetData()[0]);
320 }
321
322 TEST_F(RTCVideoDecoderFactoryTvTest, NextReadTriggersDecodeCompleteCallback) {
323 EXPECT_CALL(decode_complete_callback_, Decoded(_))
324 .WillOnce(Return(WEBRTC_VIDEO_CODEC_OK));
325
326 CreateDecoderAndAcquireDemuxer();
327 InitDecode();
328 GetVideoStream();
329 video_stream_->Read(base::Bind(&RTCVideoDecoderFactoryTvTest::ReadCallback,
330 base::Unretained(this)));
331 PostDecodeAndWait(WEBRTC_VIDEO_CODEC_OK, input_image_, false, NULL, NULL, 0);
332 read_event_.Wait();
333 video_stream_->Read(base::Bind(&RTCVideoDecoderFactoryTvTest::ReadCallback,
334 base::Unretained(this)));
335 }
336
337 TEST_F(RTCVideoDecoderFactoryTvTest, ResetReturnsOk) {
338 CreateDecoderAndAcquireDemuxer();
339 InitDecode();
340 EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, decoder_->Reset());
341 }
342
343 TEST_F(RTCVideoDecoderFactoryTvTest, ReleaseReturnsOk) {
344 CreateDecoderAndAcquireDemuxer();
345 InitDecode();
346 EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK, decoder_->Release());
347 }
348
349 } // content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698