1 /*
2 * Copyright (c) 2016, Alliance for Open Media. All rights reserved
3 *
4 * This source code is subject to the terms of the BSD 2 Clause License and
5 * the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
6 * was not distributed with this source code in the LICENSE file, you can
7 * obtain it at www.aomedia.org/license/software. If the Alliance for Open
8 * Media Patent License 1.0 was not distributed with this source code in the
9 * PATENTS file, you can obtain it at www.aomedia.org/license/patent.
10 */
11
12 #include "third_party/googletest/src/googletest/include/gtest/gtest.h"
13 #include "test/codec_factory.h"
14 #include "test/encode_test_driver.h"
15 #include "test/i420_video_source.h"
16 #include "test/util.h"
17
18 namespace {
19
20 const int kMaxErrorFrames = 12;
21 const int kMaxInvisibleErrorFrames = 12;
22 const int kMaxDroppableFrames = 12;
23 const int kMaxErrorResilientFrames = 12;
24 const int kMaxNoMFMVFrames = 12;
25 const int kMaxPrimRefNoneFrames = 12;
26 const int kMaxSFrames = 12;
27 const int kCpuUsed = 1;
28
29 class ErrorResilienceTestLarge
30 : public ::libaom_test::CodecTestWith2Params<libaom_test::TestMode, int>,
31 public ::libaom_test::EncoderTest {
32 protected:
ErrorResilienceTestLarge()33 ErrorResilienceTestLarge()
34 : EncoderTest(GET_PARAM(0)), psnr_(0.0), nframes_(0), mismatch_psnr_(0.0),
35 mismatch_nframes_(0), encoding_mode_(GET_PARAM(1)), allow_mismatch_(0),
36 enable_altref_(GET_PARAM(2)) {
37 Reset();
38 }
39
~ErrorResilienceTestLarge()40 virtual ~ErrorResilienceTestLarge() {}
41
Reset()42 void Reset() {
43 error_nframes_ = 0;
44 invisible_error_nframes_ = 0;
45 droppable_nframes_ = 0;
46 error_resilient_nframes_ = 0;
47 nomfmv_nframes_ = 0;
48 prim_ref_none_nframes_ = 0;
49 s_nframes_ = 0;
50 }
51
SetupEncoder(int bitrate,int lag)52 void SetupEncoder(int bitrate, int lag) {
53 const aom_rational timebase = { 33333333, 1000000000 };
54 cfg_.g_timebase = timebase;
55 cfg_.rc_target_bitrate = bitrate;
56 cfg_.kf_mode = AOM_KF_DISABLED;
57 cfg_.g_lag_in_frames = lag;
58 init_flags_ = AOM_CODEC_USE_PSNR;
59 }
60
SetUp()61 virtual void SetUp() {
62 InitializeConfig();
63 SetMode(encoding_mode_);
64 }
65
BeginPassHook(unsigned int)66 virtual void BeginPassHook(unsigned int /*pass*/) {
67 psnr_ = 0.0;
68 nframes_ = 0;
69 decoded_nframes_ = 0;
70 mismatch_psnr_ = 0.0;
71 mismatch_nframes_ = 0;
72 }
73
PSNRPktHook(const aom_codec_cx_pkt_t * pkt)74 virtual void PSNRPktHook(const aom_codec_cx_pkt_t *pkt) {
75 psnr_ += pkt->data.psnr.psnr[0];
76 nframes_++;
77 }
78
PreEncodeFrameHook(libaom_test::VideoSource * video,libaom_test::Encoder * encoder)79 virtual void PreEncodeFrameHook(libaom_test::VideoSource *video,
80 libaom_test::Encoder *encoder) {
81 if (video->frame() == 0) {
82 encoder->Control(AOME_SET_CPUUSED, kCpuUsed);
83 encoder->Control(AOME_SET_ENABLEAUTOALTREF, enable_altref_);
84 }
85 frame_flags_ &=
86 ~(AOM_EFLAG_NO_UPD_LAST | AOM_EFLAG_NO_UPD_GF | AOM_EFLAG_NO_UPD_ARF |
87 AOM_EFLAG_NO_REF_FRAME_MVS | AOM_EFLAG_ERROR_RESILIENT |
88 AOM_EFLAG_SET_S_FRAME | AOM_EFLAG_SET_PRIMARY_REF_NONE);
89 if (droppable_nframes_ > 0 &&
90 (cfg_.g_pass == AOM_RC_LAST_PASS || cfg_.g_pass == AOM_RC_ONE_PASS)) {
91 for (unsigned int i = 0; i < droppable_nframes_; ++i) {
92 if (droppable_frames_[i] == video->frame()) {
93 std::cout << " Encoding droppable frame: "
94 << droppable_frames_[i] << "\n";
95 frame_flags_ |= (AOM_EFLAG_NO_UPD_LAST | AOM_EFLAG_NO_UPD_GF |
96 AOM_EFLAG_NO_UPD_ARF);
97 break;
98 }
99 }
100 }
101
102 if (error_resilient_nframes_ > 0 &&
103 (cfg_.g_pass == AOM_RC_LAST_PASS || cfg_.g_pass == AOM_RC_ONE_PASS)) {
104 for (unsigned int i = 0; i < error_resilient_nframes_; ++i) {
105 if (error_resilient_frames_[i] == video->frame()) {
106 std::cout << " Encoding error_resilient frame: "
107 << error_resilient_frames_[i] << "\n";
108 frame_flags_ |= AOM_EFLAG_ERROR_RESILIENT;
109 break;
110 }
111 }
112 }
113
114 if (nomfmv_nframes_ > 0 &&
115 (cfg_.g_pass == AOM_RC_LAST_PASS || cfg_.g_pass == AOM_RC_ONE_PASS)) {
116 for (unsigned int i = 0; i < nomfmv_nframes_; ++i) {
117 if (nomfmv_frames_[i] == video->frame()) {
118 std::cout << " Encoding no mfmv frame: "
119 << nomfmv_frames_[i] << "\n";
120 frame_flags_ |= AOM_EFLAG_NO_REF_FRAME_MVS;
121 break;
122 }
123 }
124 }
125
126 if (prim_ref_none_nframes_ > 0 &&
127 (cfg_.g_pass == AOM_RC_LAST_PASS || cfg_.g_pass == AOM_RC_ONE_PASS)) {
128 for (unsigned int i = 0; i < prim_ref_none_nframes_; ++i) {
129 if (prim_ref_none_frames_[i] == video->frame()) {
130 std::cout << " Encoding no PRIMARY_REF_NONE frame: "
131 << prim_ref_none_frames_[i] << "\n";
132 frame_flags_ |= AOM_EFLAG_SET_PRIMARY_REF_NONE;
133 break;
134 }
135 }
136 }
137
138 encoder->Control(AV1E_SET_S_FRAME_MODE, 0);
139 if (s_nframes_ > 0 &&
140 (cfg_.g_pass == AOM_RC_LAST_PASS || cfg_.g_pass == AOM_RC_ONE_PASS)) {
141 for (unsigned int i = 0; i < s_nframes_; ++i) {
142 if (s_frames_[i] == video->frame()) {
143 std::cout << " Encoding S frame: " << s_frames_[i]
144 << "\n";
145 frame_flags_ |= AOM_EFLAG_SET_S_FRAME;
146 break;
147 }
148 }
149 }
150 }
151
FramePktHook(const aom_codec_cx_pkt_t * pkt)152 virtual void FramePktHook(const aom_codec_cx_pkt_t *pkt) {
153 // Check that the encode frame flags are correctly reflected
154 // in the output frame flags.
155 const int encode_flags = pkt->data.frame.flags >> 16;
156 if ((encode_flags & (AOM_EFLAG_NO_UPD_LAST | AOM_EFLAG_NO_UPD_GF |
157 AOM_EFLAG_NO_UPD_ARF)) ==
158 (AOM_EFLAG_NO_UPD_LAST | AOM_EFLAG_NO_UPD_GF | AOM_EFLAG_NO_UPD_ARF)) {
159 ASSERT_EQ(pkt->data.frame.flags & AOM_FRAME_IS_DROPPABLE,
160 static_cast<aom_codec_frame_flags_t>(AOM_FRAME_IS_DROPPABLE));
161 }
162 if (encode_flags & AOM_EFLAG_SET_S_FRAME) {
163 ASSERT_EQ(pkt->data.frame.flags & AOM_FRAME_IS_SWITCH,
164 static_cast<aom_codec_frame_flags_t>(AOM_FRAME_IS_SWITCH));
165 }
166 if (encode_flags & AOM_EFLAG_ERROR_RESILIENT) {
167 ASSERT_EQ(
168 pkt->data.frame.flags & AOM_FRAME_IS_ERROR_RESILIENT,
169 static_cast<aom_codec_frame_flags_t>(AOM_FRAME_IS_ERROR_RESILIENT));
170 }
171 }
172
GetAveragePsnr() const173 double GetAveragePsnr() const {
174 if (nframes_) return psnr_ / nframes_;
175 return 0.0;
176 }
177
GetAverageMismatchPsnr() const178 double GetAverageMismatchPsnr() const {
179 if (mismatch_nframes_) return mismatch_psnr_ / mismatch_nframes_;
180 return 0.0;
181 }
182
DoDecode() const183 virtual bool DoDecode() const {
184 if (error_nframes_ > 0 &&
185 (cfg_.g_pass == AOM_RC_LAST_PASS || cfg_.g_pass == AOM_RC_ONE_PASS)) {
186 for (unsigned int i = 0; i < error_nframes_; ++i) {
187 if (error_frames_[i] == nframes_ - 1) {
188 std::cout << " Skipping decoding frame: "
189 << error_frames_[i] << "\n";
190 return 0;
191 }
192 }
193 }
194 return 1;
195 }
196
DoDecodeInvisible() const197 virtual bool DoDecodeInvisible() const {
198 if (invisible_error_nframes_ > 0 &&
199 (cfg_.g_pass == AOM_RC_LAST_PASS || cfg_.g_pass == AOM_RC_ONE_PASS)) {
200 for (unsigned int i = 0; i < invisible_error_nframes_; ++i) {
201 if (invisible_error_frames_[i] == nframes_ - 1) {
202 std::cout << " Skipping decoding all invisible frames in "
203 "frame pkt: "
204 << invisible_error_frames_[i] << "\n";
205 return 0;
206 }
207 }
208 }
209 return 1;
210 }
211
MismatchHook(const aom_image_t * img1,const aom_image_t * img2)212 virtual void MismatchHook(const aom_image_t *img1, const aom_image_t *img2) {
213 if (allow_mismatch_) {
214 double mismatch_psnr = compute_psnr(img1, img2);
215 mismatch_psnr_ += mismatch_psnr;
216 ++mismatch_nframes_;
217 // std::cout << "Mismatch frame psnr: " << mismatch_psnr << "\n";
218 } else {
219 ::libaom_test::EncoderTest::MismatchHook(img1, img2);
220 }
221 }
222
DecompressedFrameHook(const aom_image_t & img,aom_codec_pts_t pts)223 virtual void DecompressedFrameHook(const aom_image_t &img,
224 aom_codec_pts_t pts) {
225 (void)img;
226 (void)pts;
227 ++decoded_nframes_;
228 }
229
SetErrorFrames(int num,unsigned int * list)230 void SetErrorFrames(int num, unsigned int *list) {
231 if (num > kMaxErrorFrames)
232 num = kMaxErrorFrames;
233 else if (num < 0)
234 num = 0;
235 error_nframes_ = num;
236 for (unsigned int i = 0; i < error_nframes_; ++i)
237 error_frames_[i] = list[i];
238 }
239
SetInvisibleErrorFrames(int num,unsigned int * list)240 void SetInvisibleErrorFrames(int num, unsigned int *list) {
241 if (num > kMaxInvisibleErrorFrames)
242 num = kMaxInvisibleErrorFrames;
243 else if (num < 0)
244 num = 0;
245 invisible_error_nframes_ = num;
246 for (unsigned int i = 0; i < invisible_error_nframes_; ++i)
247 invisible_error_frames_[i] = list[i];
248 }
249
SetDroppableFrames(int num,unsigned int * list)250 void SetDroppableFrames(int num, unsigned int *list) {
251 if (num > kMaxDroppableFrames)
252 num = kMaxDroppableFrames;
253 else if (num < 0)
254 num = 0;
255 droppable_nframes_ = num;
256 for (unsigned int i = 0; i < droppable_nframes_; ++i)
257 droppable_frames_[i] = list[i];
258 }
259
SetErrorResilientFrames(int num,unsigned int * list)260 void SetErrorResilientFrames(int num, unsigned int *list) {
261 if (num > kMaxErrorResilientFrames)
262 num = kMaxErrorResilientFrames;
263 else if (num < 0)
264 num = 0;
265 error_resilient_nframes_ = num;
266 for (unsigned int i = 0; i < error_resilient_nframes_; ++i)
267 error_resilient_frames_[i] = list[i];
268 }
269
SetNoMFMVFrames(int num,unsigned int * list)270 void SetNoMFMVFrames(int num, unsigned int *list) {
271 if (num > kMaxNoMFMVFrames)
272 num = kMaxNoMFMVFrames;
273 else if (num < 0)
274 num = 0;
275 nomfmv_nframes_ = num;
276 for (unsigned int i = 0; i < nomfmv_nframes_; ++i)
277 nomfmv_frames_[i] = list[i];
278 }
279
SetPrimaryRefNoneFrames(int num,unsigned int * list)280 void SetPrimaryRefNoneFrames(int num, unsigned int *list) {
281 if (num > kMaxPrimRefNoneFrames)
282 num = kMaxPrimRefNoneFrames;
283 else if (num < 0)
284 num = 0;
285 prim_ref_none_nframes_ = num;
286 for (unsigned int i = 0; i < prim_ref_none_nframes_; ++i)
287 prim_ref_none_frames_[i] = list[i];
288 }
289
SetSFrames(int num,unsigned int * list)290 void SetSFrames(int num, unsigned int *list) {
291 if (num > kMaxSFrames)
292 num = kMaxSFrames;
293 else if (num < 0)
294 num = 0;
295 s_nframes_ = num;
296 for (unsigned int i = 0; i < s_nframes_; ++i) s_frames_[i] = list[i];
297 }
298
GetMismatchFrames()299 unsigned int GetMismatchFrames() { return mismatch_nframes_; }
GetEncodedFrames()300 unsigned int GetEncodedFrames() { return nframes_; }
GetDecodedFrames()301 unsigned int GetDecodedFrames() { return decoded_nframes_; }
302
SetAllowMismatch(int allow)303 void SetAllowMismatch(int allow) { allow_mismatch_ = allow; }
304
305 private:
306 double psnr_;
307 unsigned int nframes_;
308 unsigned int decoded_nframes_;
309 unsigned int error_nframes_;
310 unsigned int invisible_error_nframes_;
311 unsigned int droppable_nframes_;
312 unsigned int error_resilient_nframes_;
313 unsigned int nomfmv_nframes_;
314 unsigned int prim_ref_none_nframes_;
315 unsigned int s_nframes_;
316 double mismatch_psnr_;
317 unsigned int mismatch_nframes_;
318 unsigned int error_frames_[kMaxErrorFrames];
319 unsigned int invisible_error_frames_[kMaxInvisibleErrorFrames];
320 unsigned int droppable_frames_[kMaxDroppableFrames];
321 unsigned int error_resilient_frames_[kMaxErrorResilientFrames];
322 unsigned int nomfmv_frames_[kMaxNoMFMVFrames];
323 unsigned int prim_ref_none_frames_[kMaxPrimRefNoneFrames];
324 unsigned int s_frames_[kMaxSFrames];
325 libaom_test::TestMode encoding_mode_;
326 int allow_mismatch_;
327 int enable_altref_;
328 };
329
TEST_P(ErrorResilienceTestLarge,OnVersusOff)330 TEST_P(ErrorResilienceTestLarge, OnVersusOff) {
331 SetupEncoder(2000, 10);
332 libaom_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
333 cfg_.g_timebase.den, cfg_.g_timebase.num,
334 0, 12);
335
336 // Global error resilient mode OFF.
337 cfg_.g_error_resilient = 0;
338 ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
339 const double psnr_resilience_off = GetAveragePsnr();
340 EXPECT_GT(psnr_resilience_off, 25.0);
341
342 Reset();
343 // Error resilient mode ON for certain frames
344 unsigned int num_error_resilient_frames = 5;
345 unsigned int error_resilient_frame_list[] = { 3, 5, 6, 9, 11 };
346 SetErrorResilientFrames(num_error_resilient_frames,
347 error_resilient_frame_list);
348 ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
349 const double psnr_resilience_on = GetAveragePsnr();
350 EXPECT_GT(psnr_resilience_on, 25.0);
351
352 // Test that turning on error resilient mode hurts by 10% at most.
353 if (psnr_resilience_off > 0.0) {
354 const double psnr_ratio = psnr_resilience_on / psnr_resilience_off;
355 EXPECT_GE(psnr_ratio, 0.9);
356 EXPECT_LE(psnr_ratio, 1.1);
357 }
358 }
359
360 // Check for successful decoding and no encoder/decoder mismatch
361 // if we lose (i.e., drop before decoding) a set of droppable
362 // frames (i.e., frames that don't update any reference buffers).
TEST_P(ErrorResilienceTestLarge,DropFramesWithoutRecovery)363 TEST_P(ErrorResilienceTestLarge, DropFramesWithoutRecovery) {
364 SetupEncoder(500, 10);
365 libaom_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
366 cfg_.g_timebase.den, cfg_.g_timebase.num,
367 0, 20);
368
369 // Set an arbitrary set of error frames same as droppable frames.
370 unsigned int num_droppable_frames = 3;
371 unsigned int droppable_frame_list[] = { 5, 11, 13 };
372 SetDroppableFrames(num_droppable_frames, droppable_frame_list);
373 SetErrorFrames(num_droppable_frames, droppable_frame_list);
374 ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
375 // Test that no mismatches have been found
376 std::cout << " Encoded frames: " << GetEncodedFrames() << "\n";
377 std::cout << " Decoded frames: " << GetDecodedFrames() << "\n";
378 std::cout << " Mismatch frames: " << GetMismatchFrames() << "\n";
379 EXPECT_EQ(GetEncodedFrames() - GetDecodedFrames(), num_droppable_frames);
380 }
381
382 // Check for ParseAbility property of an error-resilient frame.
383 // Encode a frame in error-resilient mode (E-frame), and disallow all
384 // subsequent frames from using MFMV. If frames are dropped before the
385 // E frame, all frames starting from the E frame should be parse-able.
TEST_P(ErrorResilienceTestLarge,ParseAbilityTest)386 TEST_P(ErrorResilienceTestLarge, ParseAbilityTest) {
387 SetupEncoder(500, 10);
388
389 libaom_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
390 cfg_.g_timebase.den, cfg_.g_timebase.num,
391 0, 15);
392
393 SetAllowMismatch(1);
394
395 // Note that an E-frame cannot be forced on a frame that is a
396 // show_existing_frame, or a frame that comes directly after an invisible
397 // frame. Currently, this will cause an assertion failure.
398 // Set an arbitrary error resilient (E) frame
399 unsigned int num_error_resilient_frames = 1;
400 unsigned int error_resilient_frame_list[] = { 8 };
401 SetErrorResilientFrames(num_error_resilient_frames,
402 error_resilient_frame_list);
403 // Ensure that any invisible frames before the E frame are dropped
404 SetInvisibleErrorFrames(num_error_resilient_frames,
405 error_resilient_frame_list);
406 // Set all frames after the error resilient frame to not allow MFMV
407 unsigned int num_post_error_resilient_frames = 6;
408 unsigned int post_error_resilient_frame_list[] = { 9, 10, 11, 12, 13, 14 };
409 SetNoMFMVFrames(num_post_error_resilient_frames,
410 post_error_resilient_frame_list);
411
412 // Set a few frames before the E frame that are lost (not decoded)
413 unsigned int num_error_frames = 5;
414 unsigned int error_frame_list[] = { 3, 4, 5, 6, 7 };
415 SetErrorFrames(num_error_frames, error_frame_list);
416
417 ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
418 std::cout << " Encoded frames: " << GetEncodedFrames() << "\n";
419 std::cout << " Decoded frames: " << GetDecodedFrames() << "\n";
420 std::cout << " Mismatch frames: " << GetMismatchFrames() << "\n";
421 EXPECT_EQ(GetEncodedFrames() - GetDecodedFrames(), num_error_frames);
422 // All frames following the E-frame and the E-frame are expected to have
423 // mismatches, but still be parse-able.
424 EXPECT_LE(GetMismatchFrames(), num_post_error_resilient_frames + 1);
425 }
426
427 // Check for ParseAbility property of an S frame.
428 // Encode an S-frame. If frames are dropped before the S-frame, all frames
429 // starting from the S frame should be parse-able.
TEST_P(ErrorResilienceTestLarge,SFrameTest)430 TEST_P(ErrorResilienceTestLarge, SFrameTest) {
431 SetupEncoder(500, 10);
432
433 libaom_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
434 cfg_.g_timebase.den, cfg_.g_timebase.num,
435 0, 15);
436
437 SetAllowMismatch(1);
438
439 // Note that an S-frame cannot be forced on a frame that is a
440 // show_existing_frame. This issue still needs to be addressed.
441 // Set an arbitrary S-frame
442 unsigned int num_s_frames = 1;
443 unsigned int s_frame_list[] = { 6 };
444 SetSFrames(num_s_frames, s_frame_list);
445 // Ensure that any invisible frames before the S frame are dropped
446 SetInvisibleErrorFrames(num_s_frames, s_frame_list);
447
448 // Set a few frames before the S frame that are lost (not decoded)
449 unsigned int num_error_frames = 4;
450 unsigned int error_frame_list[] = { 2, 3, 4, 5 };
451 SetErrorFrames(num_error_frames, error_frame_list);
452
453 ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
454 std::cout << " Encoded frames: " << GetEncodedFrames() << "\n";
455 std::cout << " Decoded frames: " << GetDecodedFrames() << "\n";
456 std::cout << " Mismatch frames: " << GetMismatchFrames() << "\n";
457 EXPECT_EQ(GetEncodedFrames() - GetDecodedFrames(), num_error_frames);
458 // All frames following the S-frame and the S-frame are expected to have
459 // mismatches, but still be parse-able.
460 EXPECT_LE(GetMismatchFrames(), GetEncodedFrames() - s_frame_list[0]);
461 }
462
463 AV1_INSTANTIATE_TEST_SUITE(ErrorResilienceTestLarge, NONREALTIME_TEST_MODES,
464 ::testing::Values(0, 1));
465
466 // This class is used to check the presence of SFrame.
467 class SFramePresenceTestLarge
468 : public ::libaom_test::CodecTestWith3Params<libaom_test::TestMode,
469 aom_rc_mode, int>,
470 public ::libaom_test::EncoderTest {
471 protected:
SFramePresenceTestLarge()472 SFramePresenceTestLarge()
473 : EncoderTest(GET_PARAM(0)), encoding_mode_(GET_PARAM(1)),
474 rc_end_usage_(GET_PARAM(2)), enable_altref_(GET_PARAM(3)) {
475 is_sframe_present_ = 0;
476 is_sframe_position_violated_ = 0;
477 }
~SFramePresenceTestLarge()478 virtual ~SFramePresenceTestLarge() {}
479
SetUp()480 virtual void SetUp() {
481 InitializeConfig();
482 SetMode(encoding_mode_);
483 const aom_rational timebase = { 1, 30 };
484 cfg_.g_timebase = timebase;
485 cfg_.rc_end_usage = rc_end_usage_;
486 cfg_.g_threads = 1;
487 cfg_.kf_min_dist = 0;
488 cfg_.kf_max_dist = 60;
489 cfg_.g_lag_in_frames = 35;
490 cfg_.sframe_dist = 5;
491 if (enable_altref_) cfg_.sframe_mode = 2;
492 }
493
DoDecode() const494 virtual bool DoDecode() const { return 1; }
495
PreEncodeFrameHook(::libaom_test::VideoSource * video,::libaom_test::Encoder * encoder)496 virtual void PreEncodeFrameHook(::libaom_test::VideoSource *video,
497 ::libaom_test::Encoder *encoder) {
498 if (video->frame() == 0) {
499 encoder->Control(AOME_SET_CPUUSED, 5);
500 encoder->Control(AOME_SET_ENABLEAUTOALTREF, enable_altref_);
501 }
502 }
503
HandleDecodeResult(const aom_codec_err_t res_dec,libaom_test::Decoder * decoder)504 virtual bool HandleDecodeResult(const aom_codec_err_t res_dec,
505 libaom_test::Decoder *decoder) {
506 EXPECT_EQ(AOM_CODEC_OK, res_dec) << decoder->DecodeError();
507 if (AOM_CODEC_OK == res_dec) {
508 aom_codec_ctx_t *ctx_dec = decoder->GetDecoder();
509 AOM_CODEC_CONTROL_TYPECHECKED(ctx_dec, AOMD_GET_S_FRAME_INFO,
510 &sframe_info);
511 if (sframe_info.is_s_frame) {
512 is_sframe_present_ = 1;
513 if (enable_altref_ && is_sframe_position_violated_ == 0 &&
514 sframe_info.is_s_frame_at_altref == 0)
515 is_sframe_position_violated_ = 1;
516 }
517 }
518 return AOM_CODEC_OK == res_dec;
519 }
520
521 ::libaom_test::TestMode encoding_mode_;
522 aom_rc_mode rc_end_usage_;
523 int is_sframe_present_;
524 int is_sframe_position_violated_;
525 int enable_altref_;
526 aom_s_frame_info sframe_info;
527 };
528
529 // TODO(http://crbug.com/aomedia/2831): Disable the S frame unit test for frame
530 // scheduling re-design.
TEST_P(SFramePresenceTestLarge,DISABLED_SFramePresenceTest)531 TEST_P(SFramePresenceTestLarge, DISABLED_SFramePresenceTest) {
532 libaom_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
533 cfg_.g_timebase.den, cfg_.g_timebase.num,
534 0, 100);
535 ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
536 ASSERT_EQ(is_sframe_present_, 1);
537 if (enable_altref_) {
538 ASSERT_EQ(is_sframe_position_violated_, 0);
539 }
540 }
541
542 /* TODO(anyone): Currently SFramePresenceTest fails when enable_altref_ = 1.
543 * Hence this configuration is not added. Add this configuration after the
544 * bug is fixed.
545 */
546 AV1_INSTANTIATE_TEST_SUITE(SFramePresenceTestLarge,
547 ::testing::Values(::libaom_test::kOnePassGood,
548 ::libaom_test::kTwoPassGood),
549 ::testing::Values(AOM_Q, AOM_VBR, AOM_CBR, AOM_CQ),
550 ::testing::Values(0));
551 } // namespace
552