blob: 8209a21cc18b8c9dc39c36d9c787b14df46b2244 [file] [log] [blame]
Adrian Grangecc017ca2012-10-02 12:16:27 -07001/*
Yaowu Xu2ab7ff02016-09-02 12:04:54 -07002 * Copyright (c) 2016, Alliance for Open Media. All rights reserved
Frank Galligan38536f62013-12-12 08:36:34 -08003 *
Yaowu Xu2ab7ff02016-09-02 12:04:54 -07004 * 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.
Johann123e8a62017-12-28 14:40:49 -080010 */
Deb Mukherjee01cafaa2013-01-15 06:43:35 -080011
Tom Finegan7a07ece2017-02-07 17:14:05 -080012#include "third_party/googletest/src/googletest/include/gtest/gtest.h"
John Koleszar706cafe2013-01-18 11:51:12 -080013#include "test/codec_factory.h"
Adrian Grangecc017ca2012-10-02 12:16:27 -070014#include "test/encode_test_driver.h"
15#include "test/i420_video_source.h"
John Koleszar706cafe2013-01-18 11:51:12 -080016#include "test/util.h"
Adrian Grangecc017ca2012-10-02 12:16:27 -070017
18namespace {
19
Marco Paniconif61b9622014-02-24 18:14:50 -080020const int kMaxErrorFrames = 12;
sarahparker48065fc2018-04-06 17:12:54 -070021const int kMaxInvisibleErrorFrames = 12;
Marco Paniconif61b9622014-02-24 18:14:50 -080022const int kMaxDroppableFrames = 12;
Debargha Mukherjee9dec0c52018-03-25 09:09:36 -070023const int kMaxErrorResilientFrames = 12;
Debargha Mukherjee93b047e2018-03-29 11:27:42 -070024const int kMaxNoMFMVFrames = 12;
Sarah Parker50b6d6e2018-04-11 19:21:54 -070025const int kMaxPrimRefNoneFrames = 12;
Debargha Mukherjeee09b3912018-03-29 20:01:35 -070026const int kMaxSFrames = 12;
Debargha Mukherjee776b6412018-03-23 17:25:06 -070027const int kCpuUsed = 1;
Deb Mukherjee01cafaa2013-01-15 06:43:35 -080028
clang-format3a826f12016-08-11 17:46:05 -070029class ErrorResilienceTestLarge
Sebastien Alaiwan4322bc12017-06-05 10:18:28 +020030 : public ::libaom_test::CodecTestWithParam<libaom_test::TestMode>,
31 public ::libaom_test::EncoderTest {
Adrian Grangecc017ca2012-10-02 12:16:27 -070032 protected:
Jim Bankoskia0b5ed62014-03-12 08:13:16 -070033 ErrorResilienceTestLarge()
clang-format3a826f12016-08-11 17:46:05 -070034 : EncoderTest(GET_PARAM(0)), psnr_(0.0), nframes_(0), mismatch_psnr_(0.0),
Debargha Mukherjee5729d172018-03-29 12:31:21 -070035 mismatch_nframes_(0), encoding_mode_(GET_PARAM(1)), allow_mismatch_(0) {
Deb Mukherjee01cafaa2013-01-15 06:43:35 -080036 Reset();
37 }
John Koleszar706cafe2013-01-18 11:51:12 -080038
Jim Bankoskia0b5ed62014-03-12 08:13:16 -070039 virtual ~ErrorResilienceTestLarge() {}
Adrian Grangecc017ca2012-10-02 12:16:27 -070040
Deb Mukherjee01cafaa2013-01-15 06:43:35 -080041 void Reset() {
42 error_nframes_ = 0;
sarahparker48065fc2018-04-06 17:12:54 -070043 invisible_error_nframes_ = 0;
Deb Mukherjee01cafaa2013-01-15 06:43:35 -080044 droppable_nframes_ = 0;
Debargha Mukherjee9dec0c52018-03-25 09:09:36 -070045 error_resilient_nframes_ = 0;
Debargha Mukherjee93b047e2018-03-29 11:27:42 -070046 nomfmv_nframes_ = 0;
Sarah Parker50b6d6e2018-04-11 19:21:54 -070047 prim_ref_none_nframes_ = 0;
Debargha Mukherjeee09b3912018-03-29 20:01:35 -070048 s_nframes_ = 0;
49 }
50
51 void SetupEncoder(int bitrate, int lag) {
52 const aom_rational timebase = { 33333333, 1000000000 };
53 cfg_.g_timebase = timebase;
54 cfg_.rc_target_bitrate = bitrate;
55 cfg_.kf_mode = AOM_KF_DISABLED;
56 cfg_.g_lag_in_frames = lag;
57 init_flags_ = AOM_CODEC_USE_PSNR;
Deb Mukherjee01cafaa2013-01-15 06:43:35 -080058 }
59
Adrian Grangecc017ca2012-10-02 12:16:27 -070060 virtual void SetUp() {
61 InitializeConfig();
62 SetMode(encoding_mode_);
63 }
64
65 virtual void BeginPassHook(unsigned int /*pass*/) {
66 psnr_ = 0.0;
67 nframes_ = 0;
Debargha Mukherjee776b6412018-03-23 17:25:06 -070068 decoded_nframes_ = 0;
Deb Mukherjee01cafaa2013-01-15 06:43:35 -080069 mismatch_psnr_ = 0.0;
70 mismatch_nframes_ = 0;
Adrian Grangecc017ca2012-10-02 12:16:27 -070071 }
72
Yaowu Xuf883b422016-08-30 14:01:10 -070073 virtual void PSNRPktHook(const aom_codec_cx_pkt_t *pkt) {
Adrian Grangecc017ca2012-10-02 12:16:27 -070074 psnr_ += pkt->data.psnr.psnr[0];
75 nframes_++;
76 }
77
Debargha Mukherjee776b6412018-03-23 17:25:06 -070078 virtual void PreEncodeFrameHook(libaom_test::VideoSource *video,
79 libaom_test::Encoder *encoder) {
80 if (video->frame() == 0) encoder->Control(AOME_SET_CPUUSED, kCpuUsed);
Sarah Parker50b6d6e2018-04-11 19:21:54 -070081 frame_flags_ &=
82 ~(AOM_EFLAG_NO_UPD_LAST | AOM_EFLAG_NO_UPD_GF | AOM_EFLAG_NO_UPD_ARF |
83 AOM_EFLAG_NO_REF_FRAME_MVS | AOM_EFLAG_ERROR_RESILIENT |
84 AOM_EFLAG_SET_S_FRAME | AOM_EFLAG_SET_PRIMARY_REF_NONE);
James Zerncc73e1f2016-08-08 15:09:30 -070085 if (droppable_nframes_ > 0 &&
Yaowu Xuf883b422016-08-30 14:01:10 -070086 (cfg_.g_pass == AOM_RC_LAST_PASS || cfg_.g_pass == AOM_RC_ONE_PASS)) {
Deb Mukherjee01cafaa2013-01-15 06:43:35 -080087 for (unsigned int i = 0; i < droppable_nframes_; ++i) {
Deb Mukherjee0d8723f2013-08-19 14:16:26 -070088 if (droppable_frames_[i] == video->frame()) {
Debargha Mukherjee776b6412018-03-23 17:25:06 -070089 std::cout << " Encoding droppable frame: "
90 << droppable_frames_[i] << "\n";
Yaowu Xuf883b422016-08-30 14:01:10 -070091 frame_flags_ |= (AOM_EFLAG_NO_UPD_LAST | AOM_EFLAG_NO_UPD_GF |
92 AOM_EFLAG_NO_UPD_ARF);
Debargha Mukherjee9dec0c52018-03-25 09:09:36 -070093 break;
94 }
95 }
96 }
Debargha Mukherjeee09b3912018-03-29 20:01:35 -070097
Debargha Mukherjee9dec0c52018-03-25 09:09:36 -070098 if (error_resilient_nframes_ > 0 &&
99 (cfg_.g_pass == AOM_RC_LAST_PASS || cfg_.g_pass == AOM_RC_ONE_PASS)) {
100 for (unsigned int i = 0; i < error_resilient_nframes_; ++i) {
101 if (error_resilient_frames_[i] == video->frame()) {
102 std::cout << " Encoding error_resilient frame: "
103 << error_resilient_frames_[i] << "\n";
sarahparker27d686a2018-03-30 17:43:44 -0700104 frame_flags_ |= AOM_EFLAG_ERROR_RESILIENT;
Debargha Mukherjee9dec0c52018-03-25 09:09:36 -0700105 break;
Deb Mukherjee01cafaa2013-01-15 06:43:35 -0800106 }
107 }
108 }
Debargha Mukherjeee09b3912018-03-29 20:01:35 -0700109
Debargha Mukherjee93b047e2018-03-29 11:27:42 -0700110 if (nomfmv_nframes_ > 0 &&
111 (cfg_.g_pass == AOM_RC_LAST_PASS || cfg_.g_pass == AOM_RC_ONE_PASS)) {
112 for (unsigned int i = 0; i < nomfmv_nframes_; ++i) {
113 if (nomfmv_frames_[i] == video->frame()) {
114 std::cout << " Encoding no mfmv frame: "
115 << nomfmv_frames_[i] << "\n";
sarahparker21dbca42018-03-30 17:43:44 -0700116 frame_flags_ |= AOM_EFLAG_NO_REF_FRAME_MVS;
Debargha Mukherjee93b047e2018-03-29 11:27:42 -0700117 break;
118 }
119 }
120 }
Debargha Mukherjeee09b3912018-03-29 20:01:35 -0700121
Sarah Parker50b6d6e2018-04-11 19:21:54 -0700122 if (prim_ref_none_nframes_ > 0 &&
123 (cfg_.g_pass == AOM_RC_LAST_PASS || cfg_.g_pass == AOM_RC_ONE_PASS)) {
124 for (unsigned int i = 0; i < prim_ref_none_nframes_; ++i) {
125 if (prim_ref_none_frames_[i] == video->frame()) {
126 std::cout << " Encoding no PRIMARY_REF_NONE frame: "
127 << prim_ref_none_frames_[i] << "\n";
128 frame_flags_ |= AOM_EFLAG_SET_PRIMARY_REF_NONE;
129 break;
130 }
131 }
132 }
133
Debargha Mukherjeee09b3912018-03-29 20:01:35 -0700134 encoder->Control(AV1E_SET_S_FRAME_MODE, 0);
135 if (s_nframes_ > 0 &&
136 (cfg_.g_pass == AOM_RC_LAST_PASS || cfg_.g_pass == AOM_RC_ONE_PASS)) {
137 for (unsigned int i = 0; i < s_nframes_; ++i) {
138 if (s_frames_[i] == video->frame()) {
139 std::cout << " Encoding S frame: " << s_frames_[i]
140 << "\n";
sarahparker9806fed2018-03-30 17:43:44 -0700141 frame_flags_ |= AOM_EFLAG_SET_S_FRAME;
Debargha Mukherjeee09b3912018-03-29 20:01:35 -0700142 break;
143 }
144 }
145 }
Deb Mukherjee01cafaa2013-01-15 06:43:35 -0800146 }
147
Adrian Grangecc017ca2012-10-02 12:16:27 -0700148 double GetAveragePsnr() const {
clang-format3a826f12016-08-11 17:46:05 -0700149 if (nframes_) return psnr_ / nframes_;
Adrian Grangecc017ca2012-10-02 12:16:27 -0700150 return 0.0;
151 }
152
Deb Mukherjee01cafaa2013-01-15 06:43:35 -0800153 double GetAverageMismatchPsnr() const {
clang-format3a826f12016-08-11 17:46:05 -0700154 if (mismatch_nframes_) return mismatch_psnr_ / mismatch_nframes_;
Deb Mukherjee01cafaa2013-01-15 06:43:35 -0800155 return 0.0;
156 }
157
158 virtual bool DoDecode() const {
159 if (error_nframes_ > 0 &&
Yaowu Xuf883b422016-08-30 14:01:10 -0700160 (cfg_.g_pass == AOM_RC_LAST_PASS || cfg_.g_pass == AOM_RC_ONE_PASS)) {
Deb Mukherjee01cafaa2013-01-15 06:43:35 -0800161 for (unsigned int i = 0; i < error_nframes_; ++i) {
162 if (error_frames_[i] == nframes_ - 1) {
163 std::cout << " Skipping decoding frame: "
164 << error_frames_[i] << "\n";
165 return 0;
166 }
167 }
168 }
169 return 1;
170 }
171
sarahparker48065fc2018-04-06 17:12:54 -0700172 virtual bool DoDecodeInvisible() const {
173 if (invisible_error_nframes_ > 0 &&
174 (cfg_.g_pass == AOM_RC_LAST_PASS || cfg_.g_pass == AOM_RC_ONE_PASS)) {
175 for (unsigned int i = 0; i < invisible_error_nframes_; ++i) {
176 if (invisible_error_frames_[i] == nframes_ - 1) {
177 std::cout << " Skipping decoding all invisible frames in "
178 "frame pkt: "
179 << invisible_error_frames_[i] << "\n";
180 return 0;
181 }
182 }
183 }
184 return 1;
185 }
186
Yaowu Xuf883b422016-08-30 14:01:10 -0700187 virtual void MismatchHook(const aom_image_t *img1, const aom_image_t *img2) {
Debargha Mukherjee5729d172018-03-29 12:31:21 -0700188 if (allow_mismatch_) {
189 double mismatch_psnr = compute_psnr(img1, img2);
190 mismatch_psnr_ += mismatch_psnr;
191 ++mismatch_nframes_;
192 // std::cout << "Mismatch frame psnr: " << mismatch_psnr << "\n";
193 } else {
194 ::libaom_test::EncoderTest::MismatchHook(img1, img2);
195 }
Deb Mukherjee01cafaa2013-01-15 06:43:35 -0800196 }
197
Debargha Mukherjee776b6412018-03-23 17:25:06 -0700198 virtual void DecompressedFrameHook(const aom_image_t &img,
199 aom_codec_pts_t pts) {
200 (void)img;
201 (void)pts;
202 ++decoded_nframes_;
203 }
204
Deb Mukherjee01cafaa2013-01-15 06:43:35 -0800205 void SetErrorFrames(int num, unsigned int *list) {
206 if (num > kMaxErrorFrames)
207 num = kMaxErrorFrames;
208 else if (num < 0)
209 num = 0;
210 error_nframes_ = num;
211 for (unsigned int i = 0; i < error_nframes_; ++i)
212 error_frames_[i] = list[i];
213 }
214
sarahparker48065fc2018-04-06 17:12:54 -0700215 void SetInvisibleErrorFrames(int num, unsigned int *list) {
216 if (num > kMaxInvisibleErrorFrames)
217 num = kMaxInvisibleErrorFrames;
218 else if (num < 0)
219 num = 0;
220 invisible_error_nframes_ = num;
221 for (unsigned int i = 0; i < invisible_error_nframes_; ++i)
222 invisible_error_frames_[i] = list[i];
223 }
224
Deb Mukherjee01cafaa2013-01-15 06:43:35 -0800225 void SetDroppableFrames(int num, unsigned int *list) {
226 if (num > kMaxDroppableFrames)
227 num = kMaxDroppableFrames;
228 else if (num < 0)
229 num = 0;
230 droppable_nframes_ = num;
231 for (unsigned int i = 0; i < droppable_nframes_; ++i)
232 droppable_frames_[i] = list[i];
233 }
234
Debargha Mukherjee9dec0c52018-03-25 09:09:36 -0700235 void SetErrorResilientFrames(int num, unsigned int *list) {
236 if (num > kMaxErrorResilientFrames)
237 num = kMaxErrorResilientFrames;
238 else if (num < 0)
239 num = 0;
240 error_resilient_nframes_ = num;
241 for (unsigned int i = 0; i < error_resilient_nframes_; ++i)
242 error_resilient_frames_[i] = list[i];
243 }
244
Debargha Mukherjee93b047e2018-03-29 11:27:42 -0700245 void SetNoMFMVFrames(int num, unsigned int *list) {
246 if (num > kMaxNoMFMVFrames)
247 num = kMaxNoMFMVFrames;
248 else if (num < 0)
249 num = 0;
250 nomfmv_nframes_ = num;
251 for (unsigned int i = 0; i < nomfmv_nframes_; ++i)
252 nomfmv_frames_[i] = list[i];
253 }
254
Sarah Parker50b6d6e2018-04-11 19:21:54 -0700255 void SetPrimaryRefNoneFrames(int num, unsigned int *list) {
256 if (num > kMaxPrimRefNoneFrames)
257 num = kMaxPrimRefNoneFrames;
258 else if (num < 0)
259 num = 0;
260 prim_ref_none_nframes_ = num;
261 for (unsigned int i = 0; i < prim_ref_none_nframes_; ++i)
262 prim_ref_none_frames_[i] = list[i];
263 }
264
Debargha Mukherjeee09b3912018-03-29 20:01:35 -0700265 void SetSFrames(int num, unsigned int *list) {
266 if (num > kMaxSFrames)
267 num = kMaxSFrames;
268 else if (num < 0)
269 num = 0;
270 s_nframes_ = num;
271 for (unsigned int i = 0; i < s_nframes_; ++i) s_frames_[i] = list[i];
272 }
273
clang-format3a826f12016-08-11 17:46:05 -0700274 unsigned int GetMismatchFrames() { return mismatch_nframes_; }
Debargha Mukherjee776b6412018-03-23 17:25:06 -0700275 unsigned int GetEncodedFrames() { return nframes_; }
276 unsigned int GetDecodedFrames() { return decoded_nframes_; }
Deb Mukherjee01cafaa2013-01-15 06:43:35 -0800277
Debargha Mukherjee5729d172018-03-29 12:31:21 -0700278 void SetAllowMismatch(int allow) { allow_mismatch_ = allow; }
Marco2c6d9c52015-01-11 15:26:44 -0800279
Adrian Grangecc017ca2012-10-02 12:16:27 -0700280 private:
281 double psnr_;
282 unsigned int nframes_;
Debargha Mukherjee776b6412018-03-23 17:25:06 -0700283 unsigned int decoded_nframes_;
Deb Mukherjee01cafaa2013-01-15 06:43:35 -0800284 unsigned int error_nframes_;
sarahparker48065fc2018-04-06 17:12:54 -0700285 unsigned int invisible_error_nframes_;
Deb Mukherjee01cafaa2013-01-15 06:43:35 -0800286 unsigned int droppable_nframes_;
Debargha Mukherjee9dec0c52018-03-25 09:09:36 -0700287 unsigned int error_resilient_nframes_;
Debargha Mukherjee93b047e2018-03-29 11:27:42 -0700288 unsigned int nomfmv_nframes_;
Sarah Parker50b6d6e2018-04-11 19:21:54 -0700289 unsigned int prim_ref_none_nframes_;
Debargha Mukherjeee09b3912018-03-29 20:01:35 -0700290 unsigned int s_nframes_;
Deb Mukherjee01cafaa2013-01-15 06:43:35 -0800291 double mismatch_psnr_;
292 unsigned int mismatch_nframes_;
293 unsigned int error_frames_[kMaxErrorFrames];
sarahparker48065fc2018-04-06 17:12:54 -0700294 unsigned int invisible_error_frames_[kMaxInvisibleErrorFrames];
Deb Mukherjee01cafaa2013-01-15 06:43:35 -0800295 unsigned int droppable_frames_[kMaxDroppableFrames];
Debargha Mukherjee9dec0c52018-03-25 09:09:36 -0700296 unsigned int error_resilient_frames_[kMaxErrorResilientFrames];
Debargha Mukherjee93b047e2018-03-29 11:27:42 -0700297 unsigned int nomfmv_frames_[kMaxNoMFMVFrames];
Sarah Parker50b6d6e2018-04-11 19:21:54 -0700298 unsigned int prim_ref_none_frames_[kMaxPrimRefNoneFrames];
Debargha Mukherjeee09b3912018-03-29 20:01:35 -0700299 unsigned int s_frames_[kMaxSFrames];
Yaowu Xuc27fc142016-08-22 16:08:15 -0700300 libaom_test::TestMode encoding_mode_;
Debargha Mukherjee5729d172018-03-29 12:31:21 -0700301 int allow_mismatch_;
Adrian Grangecc017ca2012-10-02 12:16:27 -0700302};
303
Jim Bankoskia0b5ed62014-03-12 08:13:16 -0700304TEST_P(ErrorResilienceTestLarge, OnVersusOff) {
Debargha Mukherjeee09b3912018-03-29 20:01:35 -0700305 SetupEncoder(2000, 10);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700306 libaom_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
Debargha Mukherjeee09b3912018-03-29 20:01:35 -0700307 cfg_.g_timebase.den, cfg_.g_timebase.num,
308 0, 12);
Adrian Grangecc017ca2012-10-02 12:16:27 -0700309
Debargha Mukherjee9dec0c52018-03-25 09:09:36 -0700310 // Global error resilient mode OFF.
Adrian Grangecc017ca2012-10-02 12:16:27 -0700311 cfg_.g_error_resilient = 0;
312 ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
313 const double psnr_resilience_off = GetAveragePsnr();
314 EXPECT_GT(psnr_resilience_off, 25.0);
315
Debargha Mukherjee9dec0c52018-03-25 09:09:36 -0700316 Reset();
317 // Error resilient mode ON for certain frames
318 unsigned int num_error_resilient_frames = 5;
319 unsigned int error_resilient_frame_list[] = { 3, 5, 6, 9, 11 };
320 SetErrorResilientFrames(num_error_resilient_frames,
321 error_resilient_frame_list);
Adrian Grangecc017ca2012-10-02 12:16:27 -0700322 ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
323 const double psnr_resilience_on = GetAveragePsnr();
324 EXPECT_GT(psnr_resilience_on, 25.0);
325
326 // Test that turning on error resilient mode hurts by 10% at most.
327 if (psnr_resilience_off > 0.0) {
328 const double psnr_ratio = psnr_resilience_on / psnr_resilience_off;
329 EXPECT_GE(psnr_ratio, 0.9);
330 EXPECT_LE(psnr_ratio, 1.1);
331 }
332}
333
Marco Paniconif61b9622014-02-24 18:14:50 -0800334// Check for successful decoding and no encoder/decoder mismatch
335// if we lose (i.e., drop before decoding) a set of droppable
336// frames (i.e., frames that don't update any reference buffers).
Jim Bankoskia0b5ed62014-03-12 08:13:16 -0700337TEST_P(ErrorResilienceTestLarge, DropFramesWithoutRecovery) {
Debargha Mukherjeee09b3912018-03-29 20:01:35 -0700338 SetupEncoder(500, 10);
Yaowu Xuc27fc142016-08-22 16:08:15 -0700339 libaom_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
Debargha Mukherjeee09b3912018-03-29 20:01:35 -0700340 cfg_.g_timebase.den, cfg_.g_timebase.num,
341 0, 20);
Deb Mukherjee01cafaa2013-01-15 06:43:35 -0800342
Marco Paniconif61b9622014-02-24 18:14:50 -0800343 // Set an arbitrary set of error frames same as droppable frames.
Debargha Mukherjee776b6412018-03-23 17:25:06 -0700344 unsigned int num_droppable_frames = 3;
345 unsigned int droppable_frame_list[] = { 5, 10, 13 };
Deb Mukherjee01cafaa2013-01-15 06:43:35 -0800346 SetDroppableFrames(num_droppable_frames, droppable_frame_list);
347 SetErrorFrames(num_droppable_frames, droppable_frame_list);
348 ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
349 // Test that no mismatches have been found
Debargha Mukherjee776b6412018-03-23 17:25:06 -0700350 std::cout << " Encoded frames: " << GetEncodedFrames() << "\n";
351 std::cout << " Decoded frames: " << GetDecodedFrames() << "\n";
clang-format3a826f12016-08-11 17:46:05 -0700352 std::cout << " Mismatch frames: " << GetMismatchFrames() << "\n";
Debargha Mukherjee776b6412018-03-23 17:25:06 -0700353 EXPECT_EQ(GetEncodedFrames() - GetDecodedFrames(), num_droppable_frames);
Debargha Mukherjee5729d172018-03-29 12:31:21 -0700354}
355
356// Check for ParseAbility property of an error-resilient frame.
357// Encode a frame in error-resilient mode (E-frame), and disallow all
358// subsequent frames from using MFMV. If frames are dropped before the
359// E frame, all frames starting from the E frame should be parse-able.
360TEST_P(ErrorResilienceTestLarge, ParseAbilityTest) {
sarahparker27d686a2018-03-30 17:43:44 -0700361 SetupEncoder(500, 10);
Debargha Mukherjee5729d172018-03-29 12:31:21 -0700362
363 libaom_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
Debargha Mukherjeee09b3912018-03-29 20:01:35 -0700364 cfg_.g_timebase.den, cfg_.g_timebase.num,
365 0, 15);
Debargha Mukherjee5729d172018-03-29 12:31:21 -0700366
367 SetAllowMismatch(1);
368
sarahparkerd0001252018-04-05 18:44:47 -0700369 // Note that an E-frame cannot be forced on a frame that is a
370 // show_existing_frame, or a frame that comes directly after an invisible
371 // frame. Currently, this will cause an assertion failure.
Debargha Mukherjee5729d172018-03-29 12:31:21 -0700372 // Set an arbitrary error resilient (E) frame
373 unsigned int num_error_resilient_frames = 1;
sarahparkerd0001252018-04-05 18:44:47 -0700374 unsigned int error_resilient_frame_list[] = { 8 };
Debargha Mukherjee5729d172018-03-29 12:31:21 -0700375 SetErrorResilientFrames(num_error_resilient_frames,
376 error_resilient_frame_list);
Sarah Parker52100eb2018-04-11 15:11:15 -0700377 // Ensure that any invisible frames before the E frame are dropped
378 SetInvisibleErrorFrames(num_error_resilient_frames,
379 error_resilient_frame_list);
Sarah Parker50b6d6e2018-04-11 19:21:54 -0700380 // Set all frames after the error resilient frame to not allow MFMV and to
381 // use PRIMARY_REF_NONE for their primary_ref_frame.
382 unsigned int num_post_error_resilient_frames = 6;
383 unsigned int post_error_resilient_frame_list[] = { 9, 10, 11, 12, 13, 14 };
384 SetNoMFMVFrames(num_post_error_resilient_frames,
385 post_error_resilient_frame_list);
Sarah Parker5b1914d2018-04-13 16:05:52 -0700386 // SetPrimaryRefNoneFrames(num_post_error_resilient_frames,
387 // post_error_resilient_frame_list);
Debargha Mukherjee5729d172018-03-29 12:31:21 -0700388
389 // Set a few frames before the E frame that are lost (not decoded)
sarahparkerd0001252018-04-05 18:44:47 -0700390 unsigned int num_error_frames = 5;
391 unsigned int error_frame_list[] = { 3, 4, 5, 6, 7 };
Debargha Mukherjee5729d172018-03-29 12:31:21 -0700392 SetErrorFrames(num_error_frames, error_frame_list);
393
394 ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
395 std::cout << " Encoded frames: " << GetEncodedFrames() << "\n";
396 std::cout << " Decoded frames: " << GetDecodedFrames() << "\n";
397 std::cout << " Mismatch frames: " << GetMismatchFrames() << "\n";
398 EXPECT_EQ(GetEncodedFrames() - GetDecodedFrames(), num_error_frames);
399 // All frames following the E-frame and the E-frame are expected to have
400 // mismatches, but still be parse-able.
Sarah Parker50b6d6e2018-04-11 19:21:54 -0700401 EXPECT_LE(GetMismatchFrames(), num_post_error_resilient_frames + 1);
Deb Mukherjee01cafaa2013-01-15 06:43:35 -0800402}
403
Debargha Mukherjee1c7eec82018-03-29 20:02:44 -0700404// Check for ParseAbility property of an S frame.
405// Encode an S-frame. If frames are dropped before the S-frame, all frames
406// starting from the S frame should be parse-able.
407TEST_P(ErrorResilienceTestLarge, SFrameTest) {
sarahparkerd0001252018-04-05 18:44:47 -0700408 SetupEncoder(500, 10);
Debargha Mukherjee1c7eec82018-03-29 20:02:44 -0700409
410 libaom_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
411 cfg_.g_timebase.den, cfg_.g_timebase.num,
412 0, 15);
413
414 SetAllowMismatch(1);
415
sarahparkerd0001252018-04-05 18:44:47 -0700416 // Note that an S-frame cannot be forced on a frame that is a
sarahparker48065fc2018-04-06 17:12:54 -0700417 // show_existing_frame. This issue still needs to be addressed.
Debargha Mukherjee1c7eec82018-03-29 20:02:44 -0700418 // Set an arbitrary S-frame
419 unsigned int num_s_frames = 1;
sarahparker48065fc2018-04-06 17:12:54 -0700420 unsigned int s_frame_list[] = { 7 };
Debargha Mukherjee1c7eec82018-03-29 20:02:44 -0700421 SetSFrames(num_s_frames, s_frame_list);
sarahparker48065fc2018-04-06 17:12:54 -0700422 // Ensure that any invisible frames before the S frame are dropped
423 SetInvisibleErrorFrames(num_s_frames, s_frame_list);
Debargha Mukherjee1c7eec82018-03-29 20:02:44 -0700424
425 // Set a few frames before the S frame that are lost (not decoded)
sarahparker48065fc2018-04-06 17:12:54 -0700426 unsigned int num_error_frames = 4;
427 unsigned int error_frame_list[] = { 3, 4, 5, 6 };
Debargha Mukherjee1c7eec82018-03-29 20:02:44 -0700428 SetErrorFrames(num_error_frames, error_frame_list);
429
430 ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
431 std::cout << " Encoded frames: " << GetEncodedFrames() << "\n";
432 std::cout << " Decoded frames: " << GetDecodedFrames() << "\n";
433 std::cout << " Mismatch frames: " << GetMismatchFrames() << "\n";
434 EXPECT_EQ(GetEncodedFrames() - GetDecodedFrames(), num_error_frames);
435 // All frames following the S-frame and the S-frame are expected to have
436 // mismatches, but still be parse-able.
sarahparker9806fed2018-03-30 17:43:44 -0700437 EXPECT_LE(GetMismatchFrames(), GetEncodedFrames() - s_frame_list[0]);
Debargha Mukherjee1c7eec82018-03-29 20:02:44 -0700438}
439
Debargha Mukherjee776b6412018-03-23 17:25:06 -0700440AV1_INSTANTIATE_TEST_CASE(ErrorResilienceTestLarge, NONREALTIME_TEST_MODES);
Adrian Grangecc017ca2012-10-02 12:16:27 -0700441} // namespace