1 /*
2 * Copyright (c) 2018, 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 <tuple>
13 #include <utility>
14 #include <vector>
15
16 #include "gtest/gtest.h"
17
18 #include "test/register_state_check.h"
19 #include "test/acm_random.h"
20 #include "test/util.h"
21
22 #include "config/aom_config.h"
23 #include "config/aom_dsp_rtcd.h"
24
25 #include "aom/aom_integer.h"
26 #include "aom_ports/aom_timer.h"
27 #include "av1/encoder/pickrst.h"
28
29 #define MAX_WIENER_BLOCK 384
30 #define MAX_DATA_BLOCK (MAX_WIENER_BLOCK + WIENER_WIN)
31
32 // 8-bit-depth tests
33 namespace wiener_lowbd {
34
35 // C implementation of the algorithm implmented by the SIMD code.
36 // This is a little more efficient than the version in av1_compute_stats_c().
compute_stats_win_opt_c(int wiener_win,const uint8_t * dgd,const uint8_t * src,int16_t * d,int16_t * s,int h_start,int h_end,int v_start,int v_end,int dgd_stride,int src_stride,int64_t * M,int64_t * H,int use_downsampled_wiener_stats)37 static void compute_stats_win_opt_c(int wiener_win, const uint8_t *dgd,
38 const uint8_t *src, int16_t *d, int16_t *s,
39 int h_start, int h_end, int v_start,
40 int v_end, int dgd_stride, int src_stride,
41 int64_t *M, int64_t *H,
42 int use_downsampled_wiener_stats) {
43 ASSERT_TRUE(wiener_win == WIENER_WIN || wiener_win == WIENER_WIN_CHROMA);
44 (void)d;
45 (void)s;
46 int i, j, k, l, m, n;
47 const int pixel_count = (h_end - h_start) * (v_end - v_start);
48 const int wiener_win2 = wiener_win * wiener_win;
49 const int wiener_halfwin = (wiener_win >> 1);
50 uint8_t avg = find_average(dgd, h_start, h_end, v_start, v_end, dgd_stride);
51 int downsample_factor =
52 use_downsampled_wiener_stats ? WIENER_STATS_DOWNSAMPLE_FACTOR : 1;
53
54 std::vector<std::vector<int64_t> > M_int(wiener_win,
55 std::vector<int64_t>(wiener_win, 0));
56 std::vector<std::vector<int64_t> > H_int(
57 wiener_win * wiener_win, std::vector<int64_t>(wiener_win * 8, 0));
58 std::vector<std::vector<int32_t> > sumY(wiener_win,
59 std::vector<int32_t>(wiener_win, 0));
60 int32_t sumX = 0;
61 const uint8_t *dgd_win = dgd - wiener_halfwin * dgd_stride - wiener_halfwin;
62
63 // Main loop handles two pixels at a time
64 // We can assume that h_start is even, since it will always be aligned to
65 // a tile edge + some number of restoration units, and both of those will
66 // be 64-pixel aligned.
67 // However, at the edge of the image, h_end may be odd, so we need to handle
68 // that case correctly.
69 assert(h_start % 2 == 0);
70 for (i = v_start; i < v_end; i = i + downsample_factor) {
71 if (use_downsampled_wiener_stats &&
72 (v_end - i < WIENER_STATS_DOWNSAMPLE_FACTOR)) {
73 downsample_factor = v_end - i;
74 }
75 int32_t sumX_row_i32 = 0;
76 std::vector<std::vector<int32_t> > sumY_row(
77 wiener_win, std::vector<int32_t>(wiener_win, 0));
78 std::vector<std::vector<int32_t> > M_row_i32(
79 wiener_win, std::vector<int32_t>(wiener_win, 0));
80 std::vector<std::vector<int32_t> > H_row_i32(
81 wiener_win * wiener_win, std::vector<int32_t>(wiener_win * 8, 0));
82 const int h_end_even = h_end & ~1;
83 const int has_odd_pixel = h_end & 1;
84 for (j = h_start; j < h_end_even; j += 2) {
85 const uint8_t X1 = src[i * src_stride + j];
86 const uint8_t X2 = src[i * src_stride + j + 1];
87 sumX_row_i32 += X1 + X2;
88
89 const uint8_t *dgd_ij = dgd_win + i * dgd_stride + j;
90 for (k = 0; k < wiener_win; k++) {
91 for (l = 0; l < wiener_win; l++) {
92 const uint8_t *dgd_ijkl = dgd_ij + k * dgd_stride + l;
93 int32_t *H_int_temp = &H_row_i32[(l * wiener_win + k)][0];
94 const uint8_t D1 = dgd_ijkl[0];
95 const uint8_t D2 = dgd_ijkl[1];
96 sumY_row[k][l] += D1 + D2;
97 M_row_i32[l][k] += D1 * X1 + D2 * X2;
98 for (m = 0; m < wiener_win; m++) {
99 for (n = 0; n < wiener_win; n++) {
100 H_int_temp[m * 8 + n] += D1 * dgd_ij[n + dgd_stride * m] +
101 D2 * dgd_ij[n + dgd_stride * m + 1];
102 }
103 }
104 }
105 }
106 }
107 // If the width is odd, add in the final pixel
108 if (has_odd_pixel) {
109 const uint8_t X1 = src[i * src_stride + j];
110 sumX_row_i32 += X1;
111
112 const uint8_t *dgd_ij = dgd_win + i * dgd_stride + j;
113 for (k = 0; k < wiener_win; k++) {
114 for (l = 0; l < wiener_win; l++) {
115 const uint8_t *dgd_ijkl = dgd_ij + k * dgd_stride + l;
116 int32_t *H_int_temp = &H_row_i32[(l * wiener_win + k)][0];
117 const uint8_t D1 = dgd_ijkl[0];
118 sumY_row[k][l] += D1;
119 M_row_i32[l][k] += D1 * X1;
120 for (m = 0; m < wiener_win; m++) {
121 for (n = 0; n < wiener_win; n++) {
122 H_int_temp[m * 8 + n] += D1 * dgd_ij[n + dgd_stride * m];
123 }
124 }
125 }
126 }
127 }
128
129 sumX += sumX_row_i32 * downsample_factor;
130 // Scale M matrix based on the downsampling factor
131 for (k = 0; k < wiener_win; ++k) {
132 for (l = 0; l < wiener_win; ++l) {
133 sumY[k][l] += sumY_row[k][l] * downsample_factor;
134 M_int[k][l] += (int64_t)M_row_i32[k][l] * downsample_factor;
135 }
136 }
137 // Scale H matrix based on the downsampling factor
138 for (k = 0; k < wiener_win * wiener_win; ++k) {
139 for (l = 0; l < wiener_win * 8; ++l) {
140 H_int[k][l] += (int64_t)H_row_i32[k][l] * downsample_factor;
141 }
142 }
143 }
144
145 const int64_t avg_square_sum = (int64_t)avg * (int64_t)avg * pixel_count;
146 for (k = 0; k < wiener_win; k++) {
147 for (l = 0; l < wiener_win; l++) {
148 M[l * wiener_win + k] =
149 M_int[l][k] + avg_square_sum - (int64_t)avg * (sumX + sumY[k][l]);
150 for (m = 0; m < wiener_win; m++) {
151 for (n = 0; n < wiener_win; n++) {
152 H[(l * wiener_win + k) * wiener_win2 + m * wiener_win + n] =
153 H_int[(l * wiener_win + k)][n * 8 + m] + avg_square_sum -
154 (int64_t)avg * (sumY[k][l] + sumY[n][m]);
155 }
156 }
157 }
158 }
159 }
160
compute_stats_opt_c(int wiener_win,const uint8_t * dgd,const uint8_t * src,int16_t * d,int16_t * s,int h_start,int h_end,int v_start,int v_end,int dgd_stride,int src_stride,int64_t * M,int64_t * H,int use_downsampled_wiener_stats)161 static void compute_stats_opt_c(int wiener_win, const uint8_t *dgd,
162 const uint8_t *src, int16_t *d, int16_t *s,
163 int h_start, int h_end, int v_start, int v_end,
164 int dgd_stride, int src_stride, int64_t *M,
165 int64_t *H, int use_downsampled_wiener_stats) {
166 if (wiener_win == WIENER_WIN || wiener_win == WIENER_WIN_CHROMA) {
167 compute_stats_win_opt_c(wiener_win, dgd, src, d, s, h_start, h_end, v_start,
168 v_end, dgd_stride, src_stride, M, H,
169 use_downsampled_wiener_stats);
170 } else {
171 av1_compute_stats_c(wiener_win, dgd, src, d, s, h_start, h_end, v_start,
172 v_end, dgd_stride, src_stride, M, H,
173 use_downsampled_wiener_stats);
174 }
175 }
176
177 static const int kIterations = 100;
178 typedef void (*compute_stats_Func)(int wiener_win, const uint8_t *dgd,
179 const uint8_t *src, int16_t *dgd_avg,
180 int16_t *src_avg, int h_start, int h_end,
181 int v_start, int v_end, int dgd_stride,
182 int src_stride, int64_t *M, int64_t *H,
183 int use_downsampled_wiener_stats);
184
185 ////////////////////////////////////////////////////////////////////////////////
186 // 8 bit
187 ////////////////////////////////////////////////////////////////////////////////
188
189 typedef std::tuple<const compute_stats_Func> WienerTestParam;
190
191 class WienerTest : public ::testing::TestWithParam<WienerTestParam> {
192 public:
SetUp()193 void SetUp() override {
194 src_buf = (uint8_t *)aom_memalign(
195 32, MAX_DATA_BLOCK * MAX_DATA_BLOCK * sizeof(*src_buf));
196 ASSERT_NE(src_buf, nullptr);
197 dgd_buf = (uint8_t *)aom_memalign(
198 32, MAX_DATA_BLOCK * MAX_DATA_BLOCK * sizeof(*dgd_buf));
199 ASSERT_NE(dgd_buf, nullptr);
200 const int buf_size =
201 sizeof(*buf) * 6 * RESTORATION_UNITSIZE_MAX * RESTORATION_UNITSIZE_MAX;
202 buf = (int16_t *)aom_memalign(32, buf_size);
203 ASSERT_NE(buf, nullptr);
204 memset(buf, 0, buf_size);
205 target_func_ = GET_PARAM(0);
206 }
TearDown()207 void TearDown() override {
208 aom_free(src_buf);
209 aom_free(dgd_buf);
210 aom_free(buf);
211 }
212 void RunWienerTest(const int32_t wiener_win, int32_t run_times);
213 void RunWienerTest_ExtremeValues(const int32_t wiener_win);
214
215 private:
216 compute_stats_Func target_func_;
217 libaom_test::ACMRandom rng_;
218 uint8_t *src_buf;
219 uint8_t *dgd_buf;
220 int16_t *buf;
221 };
222
RunWienerTest(const int32_t wiener_win,int32_t run_times)223 void WienerTest::RunWienerTest(const int32_t wiener_win, int32_t run_times) {
224 const int32_t wiener_halfwin = wiener_win >> 1;
225 const int32_t wiener_win2 = wiener_win * wiener_win;
226 DECLARE_ALIGNED(32, int64_t, M_ref[WIENER_WIN2]);
227 DECLARE_ALIGNED(32, int64_t, H_ref[WIENER_WIN2 * WIENER_WIN2]);
228 DECLARE_ALIGNED(32, int64_t, M_test[WIENER_WIN2]);
229 DECLARE_ALIGNED(32, int64_t, H_test[WIENER_WIN2 * WIENER_WIN2]);
230 // Note(rachelbarker):
231 // The SIMD code requires `h_start` to be even, but can otherwise
232 // deal with any values of `h_end`, `v_start`, `v_end`. We cover this
233 // entire range, even though (at the time of writing) `h_start` and `v_start`
234 // will always be multiples of 64 when called from non-test code.
235 // If in future any new requirements are added, these lines will
236 // need changing.
237 int h_start = (rng_.Rand16() % (MAX_WIENER_BLOCK / 2)) & ~1;
238 int h_end = run_times != 1 ? 256 : (rng_.Rand16() % MAX_WIENER_BLOCK);
239 if (h_start > h_end) std::swap(h_start, h_end);
240 int v_start = rng_.Rand16() % (MAX_WIENER_BLOCK / 2);
241 int v_end = run_times != 1 ? 256 : (rng_.Rand16() % MAX_WIENER_BLOCK);
242 if (v_start > v_end) std::swap(v_start, v_end);
243 const int dgd_stride = h_end;
244 const int src_stride = MAX_DATA_BLOCK;
245 const int iters = run_times == 1 ? kIterations : 2;
246 const int max_value_downsample_stats = 1;
247 int16_t *dgd_avg = buf;
248 int16_t *src_avg =
249 buf + (3 * RESTORATION_UNITSIZE_MAX * RESTORATION_UNITSIZE_MAX);
250
251 for (int iter = 0; iter < iters && !HasFatalFailure(); ++iter) {
252 for (int i = 0; i < MAX_DATA_BLOCK * MAX_DATA_BLOCK; ++i) {
253 dgd_buf[i] = rng_.Rand8();
254 src_buf[i] = rng_.Rand8();
255 }
256 uint8_t *dgd = dgd_buf + wiener_halfwin * MAX_DATA_BLOCK + wiener_halfwin;
257 uint8_t *src = src_buf;
258 for (int use_downsampled_stats = 0;
259 use_downsampled_stats <= max_value_downsample_stats;
260 use_downsampled_stats++) {
261 aom_usec_timer timer;
262 aom_usec_timer_start(&timer);
263 for (int i = 0; i < run_times; ++i) {
264 av1_compute_stats_c(wiener_win, dgd, src, dgd_avg, src_avg, h_start,
265 h_end, v_start, v_end, dgd_stride, src_stride,
266 M_ref, H_ref, use_downsampled_stats);
267 }
268 aom_usec_timer_mark(&timer);
269 const double time1 = static_cast<double>(aom_usec_timer_elapsed(&timer));
270 aom_usec_timer_start(&timer);
271 for (int i = 0; i < run_times; ++i) {
272 target_func_(wiener_win, dgd, src, dgd_avg, src_avg, h_start, h_end,
273 v_start, v_end, dgd_stride, src_stride, M_test, H_test,
274 use_downsampled_stats);
275 }
276 aom_usec_timer_mark(&timer);
277 const double time2 = static_cast<double>(aom_usec_timer_elapsed(&timer));
278 if (run_times > 10) {
279 printf("win %d %3dx%-3d:%7.2f/%7.2fns", wiener_win, h_end, v_end, time1,
280 time2);
281 printf("(%3.2f)\n", time1 / time2);
282 }
283 int failed = 0;
284 for (int i = 0; i < wiener_win2; ++i) {
285 if (M_ref[i] != M_test[i]) {
286 failed = 1;
287 printf("win %d M iter %d [%4d] ref %6" PRId64 " test %6" PRId64 " \n",
288 wiener_win, iter, i, M_ref[i], M_test[i]);
289 break;
290 }
291 }
292 for (int i = 0; i < wiener_win2 * wiener_win2; ++i) {
293 if (H_ref[i] != H_test[i]) {
294 failed = 1;
295 printf("win %d H iter %d [%4d] ref %6" PRId64 " test %6" PRId64 " \n",
296 wiener_win, iter, i, H_ref[i], H_test[i]);
297 break;
298 }
299 }
300 ASSERT_EQ(failed, 0);
301 }
302 }
303 }
304
RunWienerTest_ExtremeValues(const int32_t wiener_win)305 void WienerTest::RunWienerTest_ExtremeValues(const int32_t wiener_win) {
306 const int32_t wiener_halfwin = wiener_win >> 1;
307 const int32_t wiener_win2 = wiener_win * wiener_win;
308 DECLARE_ALIGNED(32, int64_t, M_ref[WIENER_WIN2]);
309 DECLARE_ALIGNED(32, int64_t, H_ref[WIENER_WIN2 * WIENER_WIN2]);
310 DECLARE_ALIGNED(32, int64_t, M_test[WIENER_WIN2]);
311 DECLARE_ALIGNED(32, int64_t, H_test[WIENER_WIN2 * WIENER_WIN2]);
312 const int h_start = 16;
313 const int h_end = MAX_WIENER_BLOCK;
314 const int v_start = 16;
315 const int v_end = MAX_WIENER_BLOCK;
316 const int dgd_stride = h_end;
317 const int src_stride = MAX_DATA_BLOCK;
318 const int iters = 1;
319 const int max_value_downsample_stats = 1;
320 int16_t *dgd_avg = buf;
321 int16_t *src_avg =
322 buf + (3 * RESTORATION_UNITSIZE_MAX * RESTORATION_UNITSIZE_MAX);
323
324 for (int iter = 0; iter < iters && !HasFatalFailure(); ++iter) {
325 // Fill with alternating extreme values to maximize difference with
326 // the average.
327 for (int i = 0; i < MAX_DATA_BLOCK * MAX_DATA_BLOCK; ++i) {
328 dgd_buf[i] = i & 1 ? 255 : 0;
329 src_buf[i] = i & 1 ? 255 : 0;
330 }
331 uint8_t *dgd = dgd_buf + wiener_halfwin * MAX_DATA_BLOCK + wiener_halfwin;
332 uint8_t *src = src_buf;
333 for (int use_downsampled_stats = 0;
334 use_downsampled_stats <= max_value_downsample_stats;
335 use_downsampled_stats++) {
336 av1_compute_stats_c(wiener_win, dgd, src, dgd_avg, src_avg, h_start,
337 h_end, v_start, v_end, dgd_stride, src_stride, M_ref,
338 H_ref, use_downsampled_stats);
339
340 target_func_(wiener_win, dgd, src, dgd_avg, src_avg, h_start, h_end,
341 v_start, v_end, dgd_stride, src_stride, M_test, H_test,
342 use_downsampled_stats);
343
344 int failed = 0;
345 for (int i = 0; i < wiener_win2; ++i) {
346 if (M_ref[i] != M_test[i]) {
347 failed = 1;
348 printf("win %d M iter %d [%4d] ref %6" PRId64 " test %6" PRId64 " \n",
349 wiener_win, iter, i, M_ref[i], M_test[i]);
350 break;
351 }
352 }
353 for (int i = 0; i < wiener_win2 * wiener_win2; ++i) {
354 if (H_ref[i] != H_test[i]) {
355 failed = 1;
356 printf("win %d H iter %d [%4d] ref %6" PRId64 " test %6" PRId64 " \n",
357 wiener_win, iter, i, H_ref[i], H_test[i]);
358 break;
359 }
360 }
361 ASSERT_EQ(failed, 0);
362 }
363 }
364 }
365
TEST_P(WienerTest,RandomValues)366 TEST_P(WienerTest, RandomValues) {
367 RunWienerTest(WIENER_WIN, 1);
368 RunWienerTest(WIENER_WIN_CHROMA, 1);
369 }
370
TEST_P(WienerTest,ExtremeValues)371 TEST_P(WienerTest, ExtremeValues) {
372 RunWienerTest_ExtremeValues(WIENER_WIN);
373 RunWienerTest_ExtremeValues(WIENER_WIN_CHROMA);
374 }
375
TEST_P(WienerTest,DISABLED_Speed)376 TEST_P(WienerTest, DISABLED_Speed) {
377 RunWienerTest(WIENER_WIN, 200);
378 RunWienerTest(WIENER_WIN_CHROMA, 200);
379 }
380
381 INSTANTIATE_TEST_SUITE_P(C, WienerTest, ::testing::Values(compute_stats_opt_c));
382
383 #if HAVE_SSE4_1
384 INSTANTIATE_TEST_SUITE_P(SSE4_1, WienerTest,
385 ::testing::Values(av1_compute_stats_sse4_1));
386 #endif // HAVE_SSE4_1
387
388 #if HAVE_AVX2
389
390 INSTANTIATE_TEST_SUITE_P(AVX2, WienerTest,
391 ::testing::Values(av1_compute_stats_avx2));
392 #endif // HAVE_AVX2
393
394 #if HAVE_NEON
395
396 INSTANTIATE_TEST_SUITE_P(NEON, WienerTest,
397 ::testing::Values(av1_compute_stats_neon));
398 #endif // HAVE_NEON
399
400 #if HAVE_SVE
401
402 INSTANTIATE_TEST_SUITE_P(SVE, WienerTest,
403 ::testing::Values(av1_compute_stats_sve));
404 #endif // HAVE_SVE
405
406 } // namespace wiener_lowbd
407
408 #if CONFIG_AV1_HIGHBITDEPTH
409 // High bit-depth tests:
410 namespace wiener_highbd {
411
compute_stats_highbd_win_opt_c(int wiener_win,const uint8_t * dgd8,const uint8_t * src8,int h_start,int h_end,int v_start,int v_end,int dgd_stride,int src_stride,int64_t * M,int64_t * H,aom_bit_depth_t bit_depth)412 static void compute_stats_highbd_win_opt_c(int wiener_win, const uint8_t *dgd8,
413 const uint8_t *src8, int h_start,
414 int h_end, int v_start, int v_end,
415 int dgd_stride, int src_stride,
416 int64_t *M, int64_t *H,
417 aom_bit_depth_t bit_depth) {
418 ASSERT_TRUE(wiener_win == WIENER_WIN || wiener_win == WIENER_WIN_CHROMA);
419 int i, j, k, l, m, n;
420 const int pixel_count = (h_end - h_start) * (v_end - v_start);
421 const int wiener_win2 = wiener_win * wiener_win;
422 const int wiener_halfwin = (wiener_win >> 1);
423 const uint16_t *src = CONVERT_TO_SHORTPTR(src8);
424 const uint16_t *dgd = CONVERT_TO_SHORTPTR(dgd8);
425 const uint16_t avg =
426 find_average_highbd(dgd, h_start, h_end, v_start, v_end, dgd_stride);
427
428 std::vector<std::vector<int64_t> > M_int(wiener_win,
429 std::vector<int64_t>(wiener_win, 0));
430 std::vector<std::vector<int64_t> > H_int(
431 wiener_win * wiener_win, std::vector<int64_t>(wiener_win * 8, 0));
432 std::vector<std::vector<int32_t> > sumY(wiener_win,
433 std::vector<int32_t>(wiener_win, 0));
434
435 memset(M, 0, sizeof(*M) * wiener_win2);
436 memset(H, 0, sizeof(*H) * wiener_win2 * wiener_win2);
437
438 int64_t sumX = 0;
439 const uint16_t *dgd_win = dgd - wiener_halfwin * dgd_stride - wiener_halfwin;
440
441 // Main loop handles two pixels at a time
442 // We can assume that h_start is even, since it will always be aligned to
443 // a tile edge + some number of restoration units, and both of those will
444 // be 64-pixel aligned.
445 // However, at the edge of the image, h_end may be odd, so we need to handle
446 // that case correctly.
447 assert(h_start % 2 == 0);
448 for (i = v_start; i < v_end; i++) {
449 const int h_end_even = h_end & ~1;
450 const int has_odd_pixel = h_end & 1;
451 for (j = h_start; j < h_end_even; j += 2) {
452 const uint16_t X1 = src[i * src_stride + j];
453 const uint16_t X2 = src[i * src_stride + j + 1];
454 sumX += X1 + X2;
455
456 const uint16_t *dgd_ij = dgd_win + i * dgd_stride + j;
457 for (k = 0; k < wiener_win; k++) {
458 for (l = 0; l < wiener_win; l++) {
459 const uint16_t *dgd_ijkl = dgd_ij + k * dgd_stride + l;
460 int64_t *H_int_temp = &H_int[(l * wiener_win + k)][0];
461 const uint16_t D1 = dgd_ijkl[0];
462 const uint16_t D2 = dgd_ijkl[1];
463 sumY[k][l] += D1 + D2;
464 M_int[l][k] += D1 * X1 + D2 * X2;
465 for (m = 0; m < wiener_win; m++) {
466 for (n = 0; n < wiener_win; n++) {
467 H_int_temp[m * 8 + n] += D1 * dgd_ij[n + dgd_stride * m] +
468 D2 * dgd_ij[n + dgd_stride * m + 1];
469 }
470 }
471 }
472 }
473 }
474 // If the width is odd, add in the final pixel
475 if (has_odd_pixel) {
476 const uint16_t X1 = src[i * src_stride + j];
477 sumX += X1;
478
479 const uint16_t *dgd_ij = dgd_win + i * dgd_stride + j;
480 for (k = 0; k < wiener_win; k++) {
481 for (l = 0; l < wiener_win; l++) {
482 const uint16_t *dgd_ijkl = dgd_ij + k * dgd_stride + l;
483 int64_t *H_int_temp = &H_int[(l * wiener_win + k)][0];
484 const uint16_t D1 = dgd_ijkl[0];
485 sumY[k][l] += D1;
486 M_int[l][k] += D1 * X1;
487 for (m = 0; m < wiener_win; m++) {
488 for (n = 0; n < wiener_win; n++) {
489 H_int_temp[m * 8 + n] += D1 * dgd_ij[n + dgd_stride * m];
490 }
491 }
492 }
493 }
494 }
495 }
496
497 uint8_t bit_depth_divider = 1;
498 if (bit_depth == AOM_BITS_12)
499 bit_depth_divider = 16;
500 else if (bit_depth == AOM_BITS_10)
501 bit_depth_divider = 4;
502
503 const int64_t avg_square_sum = (int64_t)avg * (int64_t)avg * pixel_count;
504 for (k = 0; k < wiener_win; k++) {
505 for (l = 0; l < wiener_win; l++) {
506 M[l * wiener_win + k] =
507 (M_int[l][k] +
508 (avg_square_sum - (int64_t)avg * (sumX + sumY[k][l]))) /
509 bit_depth_divider;
510 for (m = 0; m < wiener_win; m++) {
511 for (n = 0; n < wiener_win; n++) {
512 H[(l * wiener_win + k) * wiener_win2 + m * wiener_win + n] =
513 (H_int[(l * wiener_win + k)][n * 8 + m] +
514 (avg_square_sum - (int64_t)avg * (sumY[k][l] + sumY[n][m]))) /
515 bit_depth_divider;
516 }
517 }
518 }
519 }
520 }
521
compute_stats_highbd_opt_c(int wiener_win,const uint8_t * dgd,const uint8_t * src,int16_t * d,int16_t * s,int h_start,int h_end,int v_start,int v_end,int dgd_stride,int src_stride,int64_t * M,int64_t * H,aom_bit_depth_t bit_depth)522 static void compute_stats_highbd_opt_c(int wiener_win, const uint8_t *dgd,
523 const uint8_t *src, int16_t *d,
524 int16_t *s, int h_start, int h_end,
525 int v_start, int v_end, int dgd_stride,
526 int src_stride, int64_t *M, int64_t *H,
527 aom_bit_depth_t bit_depth) {
528 if (wiener_win == WIENER_WIN || wiener_win == WIENER_WIN_CHROMA) {
529 compute_stats_highbd_win_opt_c(wiener_win, dgd, src, h_start, h_end,
530 v_start, v_end, dgd_stride, src_stride, M, H,
531 bit_depth);
532 } else {
533 av1_compute_stats_highbd_c(wiener_win, dgd, src, d, s, h_start, h_end,
534 v_start, v_end, dgd_stride, src_stride, M, H,
535 bit_depth);
536 }
537 }
538
539 static const int kIterations = 100;
540 typedef void (*compute_stats_Func)(int wiener_win, const uint8_t *dgd,
541 const uint8_t *src, int16_t *d, int16_t *s,
542 int h_start, int h_end, int v_start,
543 int v_end, int dgd_stride, int src_stride,
544 int64_t *M, int64_t *H,
545 aom_bit_depth_t bit_depth);
546
547 typedef std::tuple<const compute_stats_Func> WienerTestParam;
548
549 class WienerTestHighbd : public ::testing::TestWithParam<WienerTestParam> {
550 public:
SetUp()551 void SetUp() override {
552 src_buf = (uint16_t *)aom_memalign(
553 32, MAX_DATA_BLOCK * MAX_DATA_BLOCK * sizeof(*src_buf));
554 ASSERT_NE(src_buf, nullptr);
555 dgd_buf = (uint16_t *)aom_memalign(
556 32, MAX_DATA_BLOCK * MAX_DATA_BLOCK * sizeof(*dgd_buf));
557 ASSERT_NE(dgd_buf, nullptr);
558 const size_t buf_size =
559 sizeof(*buf) * 6 * RESTORATION_UNITSIZE_MAX * RESTORATION_UNITSIZE_MAX;
560 buf = (int16_t *)aom_memalign(32, buf_size);
561 ASSERT_NE(buf, nullptr);
562 memset(buf, 0, buf_size);
563 target_func_ = GET_PARAM(0);
564 }
TearDown()565 void TearDown() override {
566 aom_free(src_buf);
567 aom_free(dgd_buf);
568 aom_free(buf);
569 }
570 void RunWienerTest(const int32_t wiener_win, int32_t run_times,
571 aom_bit_depth_t bit_depth);
572 void RunWienerTest_ExtremeValues(const int32_t wiener_win,
573 aom_bit_depth_t bit_depth);
574
575 void RunWienerTest_Overflow32bTest(const int32_t wiener_win,
576 aom_bit_depth_t bit_depth);
577
578 private:
579 compute_stats_Func target_func_;
580 libaom_test::ACMRandom rng_;
581 uint16_t *src_buf;
582 uint16_t *dgd_buf;
583 int16_t *buf;
584 };
585
RunWienerTest(const int32_t wiener_win,int32_t run_times,aom_bit_depth_t bit_depth)586 void WienerTestHighbd::RunWienerTest(const int32_t wiener_win,
587 int32_t run_times,
588 aom_bit_depth_t bit_depth) {
589 const int32_t wiener_halfwin = wiener_win >> 1;
590 const int32_t wiener_win2 = wiener_win * wiener_win;
591 DECLARE_ALIGNED(32, int64_t, M_ref[WIENER_WIN2]);
592 DECLARE_ALIGNED(32, int64_t, H_ref[WIENER_WIN2 * WIENER_WIN2]);
593 DECLARE_ALIGNED(32, int64_t, M_test[WIENER_WIN2]);
594 DECLARE_ALIGNED(32, int64_t, H_test[WIENER_WIN2 * WIENER_WIN2]);
595 // Note(rachelbarker):
596 // The SIMD code requires `h_start` to be even, but can otherwise
597 // deal with any values of `h_end`, `v_start`, `v_end`. We cover this
598 // entire range, even though (at the time of writing) `h_start` and `v_start`
599 // will always be multiples of 64 when called from non-test code.
600 // If in future any new requirements are added, these lines will
601 // need changing.
602 int h_start = (rng_.Rand16() % (MAX_WIENER_BLOCK / 2)) & ~1;
603 int h_end = run_times != 1 ? 256 : (rng_.Rand16() % MAX_WIENER_BLOCK);
604 if (h_start > h_end) std::swap(h_start, h_end);
605 int v_start = rng_.Rand16() % (MAX_WIENER_BLOCK / 2);
606 int v_end = run_times != 1 ? 256 : (rng_.Rand16() % MAX_WIENER_BLOCK);
607 if (v_start > v_end) std::swap(v_start, v_end);
608 const int dgd_stride = h_end;
609 const int src_stride = MAX_DATA_BLOCK;
610 const int iters = run_times == 1 ? kIterations : 2;
611 int16_t *dgd_avg = buf;
612 int16_t *src_avg =
613 buf + (3 * RESTORATION_UNITSIZE_MAX * RESTORATION_UNITSIZE_MAX);
614 for (int iter = 0; iter < iters && !HasFatalFailure(); ++iter) {
615 for (int i = 0; i < MAX_DATA_BLOCK * MAX_DATA_BLOCK; ++i) {
616 dgd_buf[i] = rng_.Rand16() % (1 << bit_depth);
617 src_buf[i] = rng_.Rand16() % (1 << bit_depth);
618 }
619 const uint8_t *dgd8 = CONVERT_TO_BYTEPTR(
620 dgd_buf + wiener_halfwin * MAX_DATA_BLOCK + wiener_halfwin);
621 const uint8_t *src8 = CONVERT_TO_BYTEPTR(src_buf);
622
623 aom_usec_timer timer;
624 aom_usec_timer_start(&timer);
625 for (int i = 0; i < run_times; ++i) {
626 av1_compute_stats_highbd_c(wiener_win, dgd8, src8, dgd_avg, src_avg,
627 h_start, h_end, v_start, v_end, dgd_stride,
628 src_stride, M_ref, H_ref, bit_depth);
629 }
630 aom_usec_timer_mark(&timer);
631 const double time1 = static_cast<double>(aom_usec_timer_elapsed(&timer));
632 aom_usec_timer_start(&timer);
633 for (int i = 0; i < run_times; ++i) {
634 target_func_(wiener_win, dgd8, src8, dgd_avg, src_avg, h_start, h_end,
635 v_start, v_end, dgd_stride, src_stride, M_test, H_test,
636 bit_depth);
637 }
638 aom_usec_timer_mark(&timer);
639 const double time2 = static_cast<double>(aom_usec_timer_elapsed(&timer));
640 if (run_times > 10) {
641 printf("win %d bd %d %3dx%-3d:%7.2f/%7.2fns", wiener_win, bit_depth,
642 h_end, v_end, time1, time2);
643 printf("(%3.2f)\n", time1 / time2);
644 }
645 int failed = 0;
646 for (int i = 0; i < wiener_win2; ++i) {
647 if (M_ref[i] != M_test[i]) {
648 failed = 1;
649 printf("win %d bd %d M iter %d [%4d] ref %6" PRId64 " test %6" PRId64
650 " \n",
651 wiener_win, bit_depth, iter, i, M_ref[i], M_test[i]);
652 break;
653 }
654 }
655 for (int i = 0; i < wiener_win2 * wiener_win2; ++i) {
656 if (H_ref[i] != H_test[i]) {
657 failed = 1;
658 printf("win %d bd %d H iter %d [%4d] ref %6" PRId64 " test %6" PRId64
659 " \n",
660 wiener_win, bit_depth, iter, i, H_ref[i], H_test[i]);
661 break;
662 }
663 }
664 ASSERT_EQ(failed, 0);
665 }
666 }
667
RunWienerTest_ExtremeValues(const int32_t wiener_win,aom_bit_depth_t bit_depth)668 void WienerTestHighbd::RunWienerTest_ExtremeValues(const int32_t wiener_win,
669 aom_bit_depth_t bit_depth) {
670 const int32_t wiener_halfwin = wiener_win >> 1;
671 const int32_t wiener_win2 = wiener_win * wiener_win;
672 DECLARE_ALIGNED(32, int64_t, M_ref[WIENER_WIN2]);
673 DECLARE_ALIGNED(32, int64_t, H_ref[WIENER_WIN2 * WIENER_WIN2]);
674 DECLARE_ALIGNED(32, int64_t, M_test[WIENER_WIN2]);
675 DECLARE_ALIGNED(32, int64_t, H_test[WIENER_WIN2 * WIENER_WIN2]);
676 const int h_start = 16;
677 const int h_end = MAX_WIENER_BLOCK;
678 const int v_start = 16;
679 const int v_end = MAX_WIENER_BLOCK;
680 const int dgd_stride = h_end;
681 const int src_stride = MAX_DATA_BLOCK;
682 const int iters = 1;
683 int16_t *dgd_avg = buf;
684 int16_t *src_avg =
685 buf + (3 * RESTORATION_UNITSIZE_MAX * RESTORATION_UNITSIZE_MAX);
686 for (int iter = 0; iter < iters && !HasFatalFailure(); ++iter) {
687 // Fill with alternating extreme values to maximize difference with
688 // the average.
689 for (int i = 0; i < MAX_DATA_BLOCK * MAX_DATA_BLOCK; ++i) {
690 dgd_buf[i] = i & 1 ? ((uint16_t)1 << bit_depth) - 1 : 0;
691 src_buf[i] = i & 1 ? ((uint16_t)1 << bit_depth) - 1 : 0;
692 }
693 const uint8_t *dgd8 = CONVERT_TO_BYTEPTR(
694 dgd_buf + wiener_halfwin * MAX_DATA_BLOCK + wiener_halfwin);
695 const uint8_t *src8 = CONVERT_TO_BYTEPTR(src_buf);
696
697 av1_compute_stats_highbd_c(wiener_win, dgd8, src8, dgd_avg, src_avg,
698 h_start, h_end, v_start, v_end, dgd_stride,
699 src_stride, M_ref, H_ref, bit_depth);
700
701 target_func_(wiener_win, dgd8, src8, dgd_avg, src_avg, h_start, h_end,
702 v_start, v_end, dgd_stride, src_stride, M_test, H_test,
703 bit_depth);
704
705 int failed = 0;
706 for (int i = 0; i < wiener_win2; ++i) {
707 if (M_ref[i] != M_test[i]) {
708 failed = 1;
709 printf("win %d bd %d M iter %d [%4d] ref %6" PRId64 " test %6" PRId64
710 " \n",
711 wiener_win, bit_depth, iter, i, M_ref[i], M_test[i]);
712 break;
713 }
714 }
715 for (int i = 0; i < wiener_win2 * wiener_win2; ++i) {
716 if (H_ref[i] != H_test[i]) {
717 failed = 1;
718 printf("win %d bd %d H iter %d [%4d] ref %6" PRId64 " test %6" PRId64
719 " \n",
720 wiener_win, bit_depth, iter, i, H_ref[i], H_test[i]);
721 break;
722 }
723 }
724 ASSERT_EQ(failed, 0);
725 }
726 }
727
RunWienerTest_Overflow32bTest(const int32_t wiener_win,aom_bit_depth_t bit_depth)728 void WienerTestHighbd::RunWienerTest_Overflow32bTest(
729 const int32_t wiener_win, aom_bit_depth_t bit_depth) {
730 const int32_t wiener_halfwin = wiener_win >> 1;
731 const int32_t wiener_win2 = wiener_win * wiener_win;
732 DECLARE_ALIGNED(32, int64_t, M_ref[WIENER_WIN2]);
733 DECLARE_ALIGNED(32, int64_t, H_ref[WIENER_WIN2 * WIENER_WIN2]);
734 DECLARE_ALIGNED(32, int64_t, M_test[WIENER_WIN2]);
735 DECLARE_ALIGNED(32, int64_t, H_test[WIENER_WIN2 * WIENER_WIN2]);
736 const int h_start = 16;
737 const int h_end = MAX_WIENER_BLOCK;
738 const int v_start = 16;
739 const int v_end = MAX_WIENER_BLOCK;
740 const int dgd_stride = h_end;
741 const int src_stride = MAX_DATA_BLOCK;
742 const int iters = 1;
743 int16_t *dgd_avg = buf;
744 int16_t *src_avg =
745 buf + (3 * RESTORATION_UNITSIZE_MAX * RESTORATION_UNITSIZE_MAX);
746 for (int iter = 0; iter < iters && !HasFatalFailure(); ++iter) {
747 // Fill src and dgd such that the intermediate values for M and H will at
748 // some point overflow a signed 32-bit value.
749 for (int i = 0; i < MAX_DATA_BLOCK * MAX_DATA_BLOCK; ++i) {
750 dgd_buf[i] = ((uint16_t)1 << bit_depth) - 1;
751 src_buf[i] = 0;
752 }
753
754 memset(dgd_buf, 0, MAX_DATA_BLOCK * 30 * sizeof(dgd_buf));
755 const uint8_t *dgd8 = CONVERT_TO_BYTEPTR(
756 dgd_buf + wiener_halfwin * MAX_DATA_BLOCK + wiener_halfwin);
757 const uint8_t *src8 = CONVERT_TO_BYTEPTR(src_buf);
758
759 av1_compute_stats_highbd_c(wiener_win, dgd8, src8, dgd_avg, src_avg,
760 h_start, h_end, v_start, v_end, dgd_stride,
761 src_stride, M_ref, H_ref, bit_depth);
762
763 target_func_(wiener_win, dgd8, src8, dgd_avg, src_avg, h_start, h_end,
764 v_start, v_end, dgd_stride, src_stride, M_test, H_test,
765 bit_depth);
766
767 int failed = 0;
768 for (int i = 0; i < wiener_win2; ++i) {
769 if (M_ref[i] != M_test[i]) {
770 failed = 1;
771 printf("win %d bd %d M iter %d [%4d] ref %6" PRId64 " test %6" PRId64
772 " \n",
773 wiener_win, bit_depth, iter, i, M_ref[i], M_test[i]);
774 break;
775 }
776 }
777 for (int i = 0; i < wiener_win2 * wiener_win2; ++i) {
778 if (H_ref[i] != H_test[i]) {
779 failed = 1;
780 printf("win %d bd %d H iter %d [%4d] ref %6" PRId64 " test %6" PRId64
781 " \n",
782 wiener_win, bit_depth, iter, i, H_ref[i], H_test[i]);
783 break;
784 }
785 }
786 ASSERT_EQ(failed, 0);
787 }
788 }
789
TEST_P(WienerTestHighbd,RandomValues)790 TEST_P(WienerTestHighbd, RandomValues) {
791 RunWienerTest(WIENER_WIN, 1, AOM_BITS_8);
792 RunWienerTest(WIENER_WIN_CHROMA, 1, AOM_BITS_8);
793 RunWienerTest(WIENER_WIN, 1, AOM_BITS_10);
794 RunWienerTest(WIENER_WIN_CHROMA, 1, AOM_BITS_10);
795 RunWienerTest(WIENER_WIN, 1, AOM_BITS_12);
796 RunWienerTest(WIENER_WIN_CHROMA, 1, AOM_BITS_12);
797 }
798
TEST_P(WienerTestHighbd,ExtremeValues)799 TEST_P(WienerTestHighbd, ExtremeValues) {
800 RunWienerTest_ExtremeValues(WIENER_WIN, AOM_BITS_8);
801 RunWienerTest_ExtremeValues(WIENER_WIN_CHROMA, AOM_BITS_8);
802 RunWienerTest_ExtremeValues(WIENER_WIN, AOM_BITS_10);
803 RunWienerTest_ExtremeValues(WIENER_WIN_CHROMA, AOM_BITS_10);
804 RunWienerTest_ExtremeValues(WIENER_WIN, AOM_BITS_12);
805 RunWienerTest_ExtremeValues(WIENER_WIN_CHROMA, AOM_BITS_12);
806 }
807
TEST_P(WienerTestHighbd,Overflow32bTest)808 TEST_P(WienerTestHighbd, Overflow32bTest) {
809 RunWienerTest_Overflow32bTest(WIENER_WIN, AOM_BITS_8);
810 RunWienerTest_Overflow32bTest(WIENER_WIN_CHROMA, AOM_BITS_8);
811 RunWienerTest_Overflow32bTest(WIENER_WIN, AOM_BITS_10);
812 RunWienerTest_Overflow32bTest(WIENER_WIN_CHROMA, AOM_BITS_10);
813 RunWienerTest_Overflow32bTest(WIENER_WIN, AOM_BITS_12);
814 RunWienerTest_Overflow32bTest(WIENER_WIN_CHROMA, AOM_BITS_12);
815 }
TEST_P(WienerTestHighbd,DISABLED_Speed)816 TEST_P(WienerTestHighbd, DISABLED_Speed) {
817 RunWienerTest(WIENER_WIN, 200, AOM_BITS_8);
818 RunWienerTest(WIENER_WIN_CHROMA, 200, AOM_BITS_8);
819 RunWienerTest(WIENER_WIN, 200, AOM_BITS_10);
820 RunWienerTest(WIENER_WIN_CHROMA, 200, AOM_BITS_10);
821 RunWienerTest(WIENER_WIN, 200, AOM_BITS_12);
822 RunWienerTest(WIENER_WIN_CHROMA, 200, AOM_BITS_12);
823 }
824
825 INSTANTIATE_TEST_SUITE_P(C, WienerTestHighbd,
826 ::testing::Values(compute_stats_highbd_opt_c));
827
828 #if HAVE_SSE4_1
829 INSTANTIATE_TEST_SUITE_P(SSE4_1, WienerTestHighbd,
830 ::testing::Values(av1_compute_stats_highbd_sse4_1));
831 #endif // HAVE_SSE4_1
832
833 #if HAVE_AVX2
834 INSTANTIATE_TEST_SUITE_P(AVX2, WienerTestHighbd,
835 ::testing::Values(av1_compute_stats_highbd_avx2));
836 #endif // HAVE_AVX2
837
838 #if HAVE_NEON
839 INSTANTIATE_TEST_SUITE_P(NEON, WienerTestHighbd,
840 ::testing::Values(av1_compute_stats_highbd_neon));
841 #endif // HAVE_NEON
842
843 #if HAVE_SVE
844 INSTANTIATE_TEST_SUITE_P(SVE, WienerTestHighbd,
845 ::testing::Values(av1_compute_stats_highbd_sve));
846 #endif // HAVE_SVE
847
848 // A test that reproduces b/274668506: signed integer overflow in
849 // update_a_sep_sym().
850 TEST(SearchWienerTest, 10bitSignedIntegerOverflowInUpdateASepSym) {
851 constexpr int kWidth = 427;
852 constexpr int kHeight = 1;
853 std::vector<uint16_t> buffer(3 * kWidth * kHeight);
854 // The values in the buffer alternate between 0 and 1023.
855 uint16_t value = 0;
856 for (size_t i = 0; i < buffer.size(); ++i) {
857 buffer[i] = value;
858 value = 1023 - value;
859 }
860 unsigned char *img_data = reinterpret_cast<unsigned char *>(buffer.data());
861
862 aom_image_t img;
863 EXPECT_EQ(
864 aom_img_wrap(&img, AOM_IMG_FMT_I44416, kWidth, kHeight, 1, img_data),
865 &img);
866 img.cp = AOM_CICP_CP_UNSPECIFIED;
867 img.tc = AOM_CICP_TC_UNSPECIFIED;
868 img.mc = AOM_CICP_MC_UNSPECIFIED;
869 img.range = AOM_CR_FULL_RANGE;
870
871 aom_codec_iface_t *iface = aom_codec_av1_cx();
872 aom_codec_enc_cfg_t cfg;
873 EXPECT_EQ(aom_codec_enc_config_default(iface, &cfg, AOM_USAGE_ALL_INTRA),
874 AOM_CODEC_OK);
875 cfg.rc_end_usage = AOM_Q;
876 cfg.g_profile = 1;
877 cfg.g_bit_depth = AOM_BITS_10;
878 cfg.g_input_bit_depth = 10;
879 cfg.g_w = kWidth;
880 cfg.g_h = kHeight;
881 cfg.g_limit = 1;
882 cfg.g_lag_in_frames = 0;
883 cfg.kf_mode = AOM_KF_DISABLED;
884 cfg.kf_max_dist = 0;
885 cfg.g_threads = 61;
886 cfg.rc_min_quantizer = 2;
887 cfg.rc_max_quantizer = 20;
888 aom_codec_ctx_t enc;
889 EXPECT_EQ(aom_codec_enc_init(&enc, iface, &cfg, AOM_CODEC_USE_HIGHBITDEPTH),
890 AOM_CODEC_OK);
891 EXPECT_EQ(aom_codec_control(&enc, AOME_SET_CQ_LEVEL, 11), AOM_CODEC_OK);
892 EXPECT_EQ(aom_codec_control(&enc, AV1E_SET_ROW_MT, 1), AOM_CODEC_OK);
893 EXPECT_EQ(aom_codec_control(&enc, AV1E_SET_TILE_ROWS, 4), AOM_CODEC_OK);
894 EXPECT_EQ(aom_codec_control(&enc, AOME_SET_CPUUSED, 3), AOM_CODEC_OK);
895 EXPECT_EQ(aom_codec_control(&enc, AV1E_SET_COLOR_RANGE, AOM_CR_FULL_RANGE),
896 AOM_CODEC_OK);
897 EXPECT_EQ(aom_codec_control(&enc, AV1E_SET_SKIP_POSTPROC_FILTERING, 1),
898 AOM_CODEC_OK);
899 EXPECT_EQ(aom_codec_control(&enc, AOME_SET_TUNING, AOM_TUNE_SSIM),
900 AOM_CODEC_OK);
901
902 // Encode frame
903 EXPECT_EQ(aom_codec_encode(&enc, &img, 0, 1, 0), AOM_CODEC_OK);
904 aom_codec_iter_t iter = nullptr;
905 const aom_codec_cx_pkt_t *pkt = aom_codec_get_cx_data(&enc, &iter);
906 ASSERT_NE(pkt, nullptr);
907 EXPECT_EQ(pkt->kind, AOM_CODEC_CX_FRAME_PKT);
908 // pkt->data.frame.flags is 0x1f0011.
909 EXPECT_EQ(pkt->data.frame.flags & AOM_FRAME_IS_KEY, AOM_FRAME_IS_KEY);
910 pkt = aom_codec_get_cx_data(&enc, &iter);
911 EXPECT_EQ(pkt, nullptr);
912
913 // Flush encoder
914 EXPECT_EQ(aom_codec_encode(&enc, nullptr, 0, 1, 0), AOM_CODEC_OK);
915 iter = nullptr;
916 pkt = aom_codec_get_cx_data(&enc, &iter);
917 EXPECT_EQ(pkt, nullptr);
918
919 EXPECT_EQ(aom_codec_destroy(&enc), AOM_CODEC_OK);
920 }
921
922 // A test that reproduces b/281219978: signed integer overflow in
923 // update_b_sep_sym().
924 TEST(SearchWienerTest, 12bitSignedIntegerOverflowInUpdateBSepSym) {
925 constexpr int kWidth = 311;
926 constexpr int kHeight = 3;
927 static const uint16_t buffer[3 * kWidth * kHeight] = {
928 // Y plane:
929 0, 0, 0, 2156, 2513, 2211, 4095, 4095, 0, 2538, 0, 0, 0, 0, 4095, 0, 258,
930 941, 4095, 907, 0, 0, 2325, 2485, 2408, 4095, 1513, 0, 3644, 2080, 4095,
931 4095, 0, 2135, 0, 2461, 4095, 0, 4095, 4095, 0, 1987, 0, 3629, 0, 4095,
932 3918, 4095, 0, 4095, 4095, 4095, 0, 1065, 0, 2072, 3597, 102, 0, 534, 0, 0,
933 0, 4095, 0, 0, 4095, 0, 4095, 0, 4095, 0, 3611, 0, 1139, 4095, 0, 0, 0, 0,
934 0, 4095, 0, 0, 0, 0, 4095, 4095, 4095, 0, 0, 0, 3070, 3224, 0, 0, 4095,
935 4051, 4095, 0, 4095, 3712, 0, 1465, 4095, 1699, 4095, 4095, 0, 0, 0, 3885,
936 0, 4095, 0, 0, 4095, 1686, 4095, 4095, 4095, 4095, 1330, 0, 0, 0, 4095, 0,
937 4095, 4095, 3919, 4095, 781, 2371, 2055, 4095, 912, 3710, 0, 2045, 0, 4095,
938 4095, 4095, 1811, 0, 1298, 1115, 0, 3327, 0, 0, 4095, 0, 253, 2386, 4095,
939 1791, 3657, 1444, 0, 4095, 1918, 4095, 4095, 0, 4095, 305, 1587, 0, 4095, 0,
940 3759, 0, 0, 4095, 2387, 4095, 4095, 0, 0, 4095, 4095, 0, 1015, 4095, 0, 768,
941 2598, 1667, 130, 4095, 0, 0, 435, 4095, 3683, 4095, 0, 4095, 4095, 1888,
942 2828, 4095, 3349, 0, 4095, 4095, 4095, 4095, 0, 4095, 0, 0, 4095, 0, 2491,
943 1598, 0, 0, 383, 3712, 4095, 0, 0, 4095, 760, 4095, 4095, 4095, 2030, 4095,
944 0, 0, 3236, 0, 1040, 0, 0, 4095, 0, 0, 4095, 4095, 4095, 0, 0, 1043, 3897,
945 2446, 233, 1589, 427, 4095, 4095, 4095, 4095, 0, 1656, 3786, 4095, 0, 840,
946 4095, 4095, 1429, 4095, 0, 4095, 2734, 4095, 0, 2431, 1801, 278, 0, 4095, 0,
947 4095, 0, 0, 420, 0, 0, 746, 0, 0, 3281, 3006, 4095, 4095, 0, 0, 0, 3605,
948 4095, 4095, 0, 4095, 4095, 4095, 4095, 2660, 496, 4095, 0, 0, 0, 0, 4095, 0,
949 1317, 4095, 4095, 510, 1919, 0, 3893, 0, 4095, 4095, 4095, 4095, 4095, 2071,
950 2006, 0, 3316, 4095, 0, 0, 4095, 852, 2982, 0, 2073, 0, 2728, 1499, 4095,
951 852, 361, 3137, 4095, 4095, 1502, 1575, 0, 4095, 0, 0, 0, 0, 1585, 4095, 0,
952 4095, 0, 3188, 3244, 4095, 2958, 4095, 4095, 0, 4095, 4095, 4095, 1706,
953 2896, 4095, 1788, 730, 1146, 4095, 0, 0, 4095, 0, 0, 0, 2791, 3613, 2175,
954 2925, 0, 0, 0, 0, 0, 1279, 4095, 4095, 0, 4095, 0, 0, 2336, 0, 3462, 4095,
955 0, 4095, 1997, 2328, 2860, 0, 4095, 4095, 3241, 4095, 4095, 4095, 4095,
956 4095, 4095, 118, 0, 4095, 4095, 4095, 0, 3734, 0, 0, 0, 4095, 1952, 4095,
957 413, 4095, 1183, 4095, 0, 4095, 0, 0, 4095, 4095, 4095, 3805, 0, 1398, 0,
958 4095, 0, 0, 0, 4095, 4095, 4095, 2802, 3658, 4095, 4095, 0, 0, 0, 4095, 0,
959 897, 0, 4095, 2163, 0, 0, 0, 4095, 1440, 2487, 4095, 4095, 0, 4095, 4095,
960 4095, 2808, 0, 1999, 0, 0, 4095, 4095, 4095, 1563, 124, 2179, 754, 0, 0,
961 2407, 2798, 0, 4095, 4095, 0, 0, 1929, 0, 0, 0, 1387, 4095, 4095, 0, 0,
962 3911, 562, 4095, 0, 4095, 2639, 2673, 4095, 4095, 0, 0, 4095, 4095, 0, 4095,
963 4095, 901, 0, 321, 3961, 4095, 0, 4095, 4095, 4095, 0, 0, 0, 0, 3035, 3713,
964 3441, 0, 4095, 0, 0, 854, 1544, 3963, 1968, 4095, 0, 0, 0, 0, 2897, 4095, 0,
965 4095, 4095, 0, 235, 1011, 4095, 0, 3452, 4095, 4095, 0, 0, 4095, 4095, 4095,
966 4095, 4095, 3312, 0, 3064, 4095, 3981, 4095, 4095, 4095, 4095, 4095, 0, 791,
967 3243, 4095, 799, 0, 0, 0, 523, 2117, 3776, 0, 4095, 3311, 0, 543, 4095,
968 4095, 4095, 0, 0, 4095, 4095, 4095, 4095, 0, 0, 4095, 4095, 225, 0, 1195,
969 3070, 1210, 4095, 0, 4095, 498, 782, 0, 0, 4095, 4095, 4095, 4095, 4095,
970 1456, 4095, 3898, 1472, 4095, 4095, 0, 4095, 4026, 0, 0, 2354, 1554, 0,
971 4095, 0, 2986, 0, 1053, 1228, 0, 0, 4095, 4095, 0, 0, 4095, 0, 0, 4095, 0,
972 0, 0, 606, 0, 4095, 3563, 4095, 2016, 4095, 0, 0, 4095, 0, 4095, 4095, 4095,
973 0, 0, 0, 929, 0, 0, 4095, 0, 3069, 4095, 0, 2687, 4095, 4095, 4095, 2015,
974 4095, 4095, 4095, 0, 4095, 0, 0, 2860, 3668, 0, 0, 4095, 2523, 2104, 0, 0,
975 3063, 4095, 3674, 4095, 0, 2762, 0, 4095, 2582, 3473, 930, 0, 1012, 108, 38,
976 4095, 1148, 3568, 4036, 4095, 4095, 0, 1120, 1873, 3028, 4095, 515, 1902,
977 4095, 0, 815, 4095, 1548, 0, 1073, 3919, 4095, 2374, 0, 3126, 4095, 2268, 0,
978 0, 0, 4095, 425, 4095, 0, 0, 4095, 4095, 2710, 4095, 2067, 4095, 4095, 2201,
979 4095, 4095, 0, 4095, 4095, 2933, 0, 417, 2801, 4095, 4095, 3274, 0, 2870,
980 4095, 4095, 0, 0, 973, 0, 0, 3129, 4095, 0, 0, 0, 4095, 4095, 4095, 0, 242,
981 4095, 0, 4095, 0, 0, 0, 0, 987, 0, 2426, 4045, 2780, 0, 4095, 3762, 3361,
982 3095, 4095, 596, 1072, 4071, 4095, 4095, 0, 0, 81, 0, 1001, 1683, 4095,
983 4095, 3105, 2673, 0, 3300, 104, 4030, 0, 2615, 4095, 4095, 0, 4095, 1830,
984 3917, 4095, 4095, 4095, 0, 4095, 3637, 0, 4095, 4095, 3677, 4095, 4095, 0,
985 880, 4095, 4095, 0, 2797, 0, 0, 0, 0, 3225, 4095, 4095, 1925, 2885, 1879, 0,
986 0, 4095, 0, 0, 0, 2974, 559, 0, 0, 0, 699, 997, 1491, 423, 4012, 0, 2315,
987 4095, 0, 0, 4095, 0, 836, 4095, 0, 4095, 0, 1752, 0, 0, 0, 4095, 4095, 0, 0,
988 51, 4095, 350, 0, 2143, 2588, 0, 4095, 0, 4095, 0, 2757, 2370, 4095, 668,
989 4095, 0, 4095, 0, 3652, 3890, 0, 4095, 0, 4095, 4095, 4095, 4095, 4095,
990 // U plane:
991 4095, 4095, 1465, 0, 588, 4095, 0, 4095, 4095, 4095, 0, 2167, 4095, 4095,
992 918, 3223, 4095, 4095, 0, 696, 4095, 4095, 0, 0, 594, 4095, 2935, 0, 0, 0,
993 2036, 4095, 0, 2492, 4095, 4095, 0, 0, 0, 3883, 0, 4095, 483, 4095, 4095,
994 324, 923, 0, 3079, 0, 4095, 4095, 810, 0, 3371, 4095, 4095, 0, 4095, 2756,
995 0, 723, 0, 3338, 1084, 0, 4095, 4095, 3764, 0, 4095, 4095, 4095, 2323, 0,
996 3693, 682, 0, 0, 909, 4095, 2348, 4095, 4095, 4095, 1509, 4095, 0, 4095,
997 4095, 4095, 4095, 3977, 3652, 1580, 637, 4095, 0, 593, 4095, 1199, 1773,
998 4095, 4095, 4095, 0, 3447, 0, 0, 4095, 3873, 0, 0, 2094, 0, 1195, 0, 3892,
999 4095, 4095, 729, 4095, 0, 0, 4095, 449, 4095, 4095, 2900, 0, 4095, 0, 2114,
1000 4095, 4095, 4095, 1174, 995, 2933, 360, 0, 1970, 0, 4095, 1208, 0, 4095, 0,
1001 4095, 0, 4095, 4095, 0, 4095, 0, 0, 0, 1976, 0, 0, 921, 4095, 4095, 192,
1002 1006, 0, 0, 2725, 4095, 0, 2813, 0, 0, 2375, 4095, 1982, 0, 2725, 4095,
1003 1225, 3566, 4095, 0, 344, 863, 2747, 0, 4095, 4095, 1928, 4095, 4095, 0,
1004 3640, 0, 1744, 3191, 4095, 4095, 0, 4095, 4095, 4095, 0, 0, 748, 4095, 0,
1005 2609, 0, 0, 0, 0, 0, 3508, 4095, 4095, 2463, 0, 4095, 0, 4095, 4095, 4095,
1006 3175, 419, 2193, 0, 0, 4095, 0, 0, 4095, 4051, 2159, 4095, 4095, 2262, 379,
1007 4095, 0, 0, 3399, 4095, 4095, 4095, 3769, 2510, 4054, 3336, 730, 3968, 0, 0,
1008 3354, 0, 1822, 0, 4095, 0, 3847, 3823, 3262, 0, 0, 2936, 0, 4095, 4095,
1009 2120, 0, 3147, 0, 2838, 3480, 474, 1194, 4095, 4095, 2820, 4095, 0, 4095,
1010 1882, 4095, 1085, 0, 4095, 2234, 3371, 4095, 0, 4095, 0, 0, 0, 2586, 4095,
1011 4095, 4095, 4095, 0, 3818, 1401, 2273, 4095, 0, 4095, 0, 3907, 4095, 4095,
1012 694, 0, 4066, 4095, 0, 0, 4095, 2116, 4095, 4095, 4095, 4095, 4095, 0, 2821,
1013 29, 0, 0, 663, 1711, 652, 1271, 4095, 4095, 2401, 3726, 4095, 3453, 1803,
1014 3614, 0, 4095, 3439, 4095, 0, 4095, 0, 816, 0, 0, 4095, 4095, 2635, 0, 1918,
1015 0, 2663, 381, 0, 0, 3670, 0, 4095, 3065, 965, 4095, 4095, 4095, 2993, 4095,
1016 4095, 0, 4095, 973, 4095, 0, 4095, 4095, 0, 3071, 0, 2777, 4095, 4095, 0,
1017 3996, 4095, 1637, 0, 4095, 67, 3784, 0, 0, 4095, 2603, 579, 4095, 4095,
1018 2854, 4095, 3016, 0, 4095, 0, 0, 4095, 4095, 4095, 4095, 3998, 3023, 4095,
1019 4095, 0, 0, 0, 4095, 4095, 4095, 4095, 0, 0, 2623, 1308, 55, 4095, 0, 0,
1020 2554, 2311, 0, 4095, 4095, 4095, 1134, 2112, 0, 4095, 4095, 0, 4095, 0, 645,
1021 0, 0, 4095, 0, 909, 0, 0, 1719, 4095, 0, 3542, 0, 575, 0, 4095, 4095, 4095,
1022 3428, 1172, 481, 1521, 4095, 3199, 1265, 4095, 3518, 4017, 4095, 760, 2042,
1023 3986, 0, 4095, 42, 4095, 0, 4095, 4095, 4095, 4095, 2235, 346, 3865, 0,
1024 4095, 4095, 4095, 4095, 4095, 4095, 845, 4095, 0, 2826, 4095, 4095, 0, 0,
1025 335, 1614, 1465, 0, 4095, 4095, 0, 2771, 4095, 0, 2810, 4095, 4095, 0, 1254,
1026 4095, 2589, 4095, 4095, 2252, 0, 0, 0, 4095, 0, 73, 4095, 4095, 0, 1341, 0,
1027 0, 0, 0, 4095, 0, 0, 2645, 1985, 492, 914, 3996, 4095, 4095, 4095, 0, 2383,
1028 2556, 433, 0, 4095, 1094, 4095, 4095, 642, 4095, 1722, 0, 3460, 4095, 4095,
1029 4095, 4095, 4095, 0, 154, 4095, 92, 4095, 0, 0, 0, 4095, 0, 4095, 4095, 444,
1030 0, 2925, 0, 0, 0, 0, 1628, 0, 4095, 1731, 2418, 697, 4095, 0, 2513, 4095, 0,
1031 4095, 4095, 4095, 4095, 4095, 0, 2510, 4095, 3850, 0, 0, 4095, 2480, 4095,
1032 4095, 2661, 4095, 0, 4095, 0, 0, 4095, 4095, 847, 4095, 4095, 3257, 443, 0,
1033 67, 0, 0, 0, 4095, 0, 0, 3073, 4095, 0, 4095, 0, 4095, 0, 4095, 1224, 4095,
1034 4095, 4095, 0, 4095, 958, 0, 4095, 0, 2327, 684, 0, 0, 0, 0, 4095, 4095, 0,
1035 3693, 795, 4095, 0, 621, 1592, 2314, 4095, 0, 928, 1897, 4095, 4095, 0,
1036 4095, 0, 0, 4095, 2619, 4095, 0, 4095, 0, 0, 4095, 2485, 4095, 4095, 0, 435,
1037 4095, 1818, 4095, 4095, 0, 0, 0, 4095, 4095, 4095, 4095, 0, 1671, 4095,
1038 4095, 0, 2617, 0, 2572, 0, 0, 4095, 3471, 0, 0, 4095, 2719, 3979, 1307, 0,
1039 0, 0, 0, 1794, 642, 447, 913, 4095, 3927, 0, 2686, 0, 0, 4095, 0, 857, 0,
1040 4095, 4095, 567, 2385, 0, 0, 4095, 893, 0, 289, 0, 0, 0, 4095, 4095, 2566,
1041 0, 1913, 0, 2350, 1033, 2764, 0, 4095, 0, 4095, 0, 0, 0, 0, 4095, 3952,
1042 3969, 0, 3476, 0, 4095, 4095, 393, 0, 2613, 0, 0, 1422, 0, 3359, 491, 3263,
1043 4095, 4095, 0, 0, 4095, 697, 3601, 4095, 0, 4095, 4095, 0, 4095, 0, 0, 4095,
1044 0, 4095, 4095, 4095, 2506, 0, 0, 1403, 0, 3836, 3976, 0, 4095, 4095, 4095,
1045 2497, 4095, 4095, 4095, 4095, 0, 4095, 3317, 4095, 4095, 4095, 0, 0, 1131,
1046 0, 0, 0, 4095, 0, 0, 4095, 0, 0, 2988, 4095, 4095, 2711, 2487, 1335, 0, 0,
1047 0, 4095, 261, 4095, 86, 0, 0, 1138, 4095, 0, 0, 4095, 4095, 0, 0, 0, 334, 0,
1048 2395, 3297, 4095, 1698, 4095, 1791, 1341, 0, 3559, 0, 4095, 0, 2056, 3238,
1049 3310, 4095, 4095, 779, 2129, 2849, 4095, 2622, 1051, 0, 0, 1282, 4095, 1246,
1050 0, 0, 3696, 4095, 556, 0, 0, 3463, 2658, 3572, 4095, 3982, 4095, 4095, 0, 0,
1051 4053, 4095, 4095, 4095, 2162, 2567, 1621, 4095, 4095, 1522, 293, 4095, 0, 0,
1052 1976, 4095, 3089, 4095, 0, 0, 0, 0, 3650,
1053 // V plane:
1054 0, 1892, 4095, 1995, 0, 0, 0, 2208, 1152, 1794, 4095, 4095, 89, 3333, 4095,
1055 2478, 4095, 2505, 4095, 0, 2664, 4095, 1984, 0, 1144, 4095, 0, 4095, 0,
1056 4095, 0, 0, 0, 2404, 1727, 4095, 4095, 0, 1326, 2033, 0, 4095, 0, 4095,
1057 3022, 0, 4095, 0, 1980, 4095, 0, 2284, 4095, 0, 3422, 0, 4095, 2171, 3155,
1058 4095, 0, 4095, 0, 636, 0, 0, 4095, 3264, 3862, 0, 2164, 0, 0, 3879, 3886, 0,
1059 225, 0, 0, 4095, 0, 1956, 523, 464, 738, 0, 1545, 0, 2829, 4095, 4095, 4095,
1060 799, 4095, 358, 4095, 0, 0, 953, 0, 0, 2081, 4095, 1604, 4095, 2086, 0, 954,
1061 0, 0, 2393, 2413, 4095, 4095, 0, 3583, 4095, 4095, 2995, 4095, 0, 4095,
1062 4095, 3501, 4095, 247, 4095, 0, 0, 0, 4095, 1303, 3382, 1059, 4095, 0, 543,
1063 1276, 1801, 0, 0, 0, 2928, 0, 4095, 3931, 70, 0, 0, 3992, 4095, 1278, 1930,
1064 4095, 0, 4095, 4095, 3894, 0, 0, 0, 0, 4095, 0, 0, 0, 0, 0, 0, 4095, 4095,
1065 4095, 1098, 4095, 2059, 0, 380, 3166, 0, 4095, 2215, 0, 0, 2846, 0, 0, 2614,
1066 528, 4095, 0, 4095, 2371, 0, 4095, 0, 0, 0, 0, 4095, 3133, 4095, 4095, 0,
1067 4095, 1283, 3821, 1772, 0, 0, 4095, 4095, 4095, 890, 3475, 4095, 4095, 133,
1068 3292, 1819, 4095, 4095, 4095, 0, 0, 4095, 702, 4095, 0, 0, 0, 4095, 0, 2137,
1069 4095, 4095, 4095, 0, 0, 0, 4095, 4095, 1555, 2435, 2778, 4095, 0, 4095,
1070 3825, 0, 3736, 3054, 0, 0, 4095, 4095, 4095, 0, 0, 0, 0, 371, 4095, 4095, 0,
1071 0, 1565, 4095, 2731, 4095, 0, 756, 925, 0, 0, 0, 4095, 775, 1379, 4095,
1072 1439, 0, 0, 0, 2680, 0, 0, 4095, 1280, 4095, 0, 0, 4095, 4095, 0, 3088, 0,
1073 4095, 4095, 4095, 0, 0, 1526, 4095, 2314, 4095, 4095, 0, 4095, 288, 0, 205,
1074 4095, 4095, 4095, 0, 1247, 2014, 0, 1530, 1985, 0, 0, 4095, 3195, 0, 4095,
1075 4, 2397, 4095, 4095, 4095, 0, 4095, 4095, 4095, 0, 0, 0, 0, 0, 4031, 928,
1076 4095, 0, 0, 4095, 4095, 4095, 1966, 4095, 2299, 1215, 4095, 0, 4095, 1335,
1077 0, 4095, 1991, 4095, 0, 4095, 114, 0, 0, 0, 2123, 2639, 4095, 3323, 4095,
1078 4095, 418, 209, 0, 0, 4095, 4095, 4095, 4095, 963, 0, 0, 0, 4095, 2505, 0,
1079 3627, 0, 311, 3748, 2047, 4095, 2791, 0, 3643, 1852, 0, 0, 4095, 0, 2179, 0,
1080 4095, 2678, 0, 0, 0, 2342, 4095, 4095, 0, 0, 4095, 0, 0, 0, 0, 1076, 0, 0,
1081 4095, 0, 2370, 0, 3530, 0, 0, 0, 0, 0, 4095, 0, 0, 0, 3474, 1201, 0, 379,
1082 699, 4095, 777, 4095, 0, 4095, 4095, 0, 1213, 1762, 4095, 4095, 4095, 0,
1083 4095, 1090, 1233, 0, 4095, 0, 4095, 0, 0, 0, 2845, 3385, 2718, 0, 0, 2975,
1084 3630, 0, 4095, 4095, 4095, 4095, 3261, 243, 0, 4095, 0, 0, 3836, 4095, 4095,
1085 4095, 963, 0, 0, 2526, 0, 4095, 4000, 4095, 2069, 0, 0, 4095, 0, 4095, 1421,
1086 0, 4095, 0, 4095, 4095, 0, 4095, 0, 4095, 4095, 1537, 4095, 3201, 0, 0,
1087 4095, 2719, 4095, 0, 4095, 4095, 4095, 0, 4095, 0, 4095, 2300, 0, 2876, 0,
1088 4095, 4095, 4095, 3235, 497, 635, 0, 1480, 4095, 0, 3067, 3979, 3741, 0,
1089 3059, 1214, 4095, 4095, 2197, 0, 4095, 4095, 2734, 0, 4095, 4095, 3364,
1090 2369, 4095, 303, 4095, 0, 4095, 4095, 3472, 1733, 4095, 4095, 4095, 0, 55,
1091 0, 10, 1378, 1169, 4095, 0, 0, 688, 3613, 0, 4095, 2832, 867, 4095, 4095,
1092 3514, 4095, 0, 4095, 4095, 2458, 3506, 0, 1920, 0, 1762, 1178, 2549, 4095,
1093 3967, 4095, 0, 2975, 1282, 0, 377, 846, 3434, 97, 0, 0, 1616, 3526, 136,
1094 1888, 0, 147, 334, 4095, 0, 4095, 0, 4095, 1106, 4095, 0, 4095, 3280, 4095,
1095 4095, 0, 2849, 3528, 0, 4095, 4095, 0, 2306, 0, 3412, 0, 4095, 4095, 4095,
1096 4048, 2273, 0, 4095, 4095, 4095, 0, 4095, 3031, 4095, 4095, 4095, 0, 3382,
1097 3812, 2315, 4095, 0, 0, 0, 432, 4095, 3606, 0, 4, 2847, 4095, 0, 4095, 0, 0,
1098 2616, 4095, 4095, 0, 4095, 0, 3394, 4095, 3976, 3119, 0, 0, 0, 0, 4046,
1099 4095, 4095, 3331, 4095, 2127, 0, 4095, 0, 0, 0, 4095, 4095, 4095, 0, 4095,
1100 4095, 4095, 0, 2068, 0, 0, 3882, 2967, 0, 1745, 4095, 2112, 478, 0, 4095, 0,
1101 199, 4095, 4095, 3542, 4095, 2634, 4095, 4095, 1235, 4095, 4095, 167, 1553,
1102 0, 4095, 2649, 0, 3383, 0, 4095, 2803, 4095, 0, 4095, 0, 785, 4095, 0, 4095,
1103 1743, 4095, 0, 3945, 0, 4095, 1894, 4095, 3973, 4095, 0, 0, 4095, 0, 0,
1104 4095, 318, 4095, 4095, 4095, 0, 261, 4095, 4095, 2125, 2690, 4095, 0, 4095,
1105 3863, 1740, 4095, 0, 2899, 1509, 0, 0, 0, 2780, 4095, 1897, 2104, 4095,
1106 1708, 284, 4095, 0, 4095, 3382, 4095, 4095, 483, 0, 0, 0, 3099, 0, 4095, 0,
1107 926, 4095, 2062, 1931, 2121, 0, 4095, 0, 2485, 1535, 4095, 4095, 3662, 4095,
1108 2419, 2487, 0, 4095, 4095, 4095, 0, 0, 4095, 0, 0, 2029, 0, 3008, 2338, 0,
1109 4095, 0, 3854, 0, 4095, 0, 0, 1315, 0, 0, 0, 0, 3492, 0, 1445, 0, 11, 4095,
1110 0, 0, 873, 0, 4095, 0, 4095, 2654, 3040, 0, 0, 0, 4095, 0, 68, 4095, 0, 0,
1111 990, 0, 828, 1015, 88, 3606, 0, 2875, 4095, 0, 3117, 411, 0, 0, 2859, 0, 0,
1112 4095, 3480, 25, 4095, 4095, 4095, 0, 0, 0, 4095, 4095, 4095, 4095, 1724, 0,
1113 0, 0, 3635, 1063, 3728, 4095, 4095, 2025, 3715, 0, 0, 0, 3722, 0, 1648, 0,
1114 4095, 3579, 0, 0, 0, 4095, 4095, 0, 4095
1115 };
1116 unsigned char *img_data =
1117 reinterpret_cast<unsigned char *>(const_cast<uint16_t *>(buffer));
1118
1119 aom_image_t img;
1120 EXPECT_EQ(
1121 aom_img_wrap(&img, AOM_IMG_FMT_I44416, kWidth, kHeight, 1, img_data),
1122 &img);
1123 img.cp = AOM_CICP_CP_UNSPECIFIED;
1124 img.tc = AOM_CICP_TC_UNSPECIFIED;
1125 img.mc = AOM_CICP_MC_UNSPECIFIED;
1126 img.range = AOM_CR_FULL_RANGE;
1127
1128 aom_codec_iface_t *iface = aom_codec_av1_cx();
1129 aom_codec_enc_cfg_t cfg;
1130 EXPECT_EQ(aom_codec_enc_config_default(iface, &cfg, AOM_USAGE_ALL_INTRA),
1131 AOM_CODEC_OK);
1132 cfg.rc_end_usage = AOM_Q;
1133 cfg.g_profile = 2;
1134 cfg.g_bit_depth = AOM_BITS_12;
1135 cfg.g_input_bit_depth = 12;
1136 cfg.g_w = kWidth;
1137 cfg.g_h = kHeight;
1138 cfg.g_limit = 1;
1139 cfg.g_lag_in_frames = 0;
1140 cfg.kf_mode = AOM_KF_DISABLED;
1141 cfg.kf_max_dist = 0;
1142 cfg.g_threads = 34;
1143 cfg.rc_min_quantizer = 8;
1144 cfg.rc_max_quantizer = 20;
1145 aom_codec_ctx_t enc;
1146 EXPECT_EQ(aom_codec_enc_init(&enc, iface, &cfg, AOM_CODEC_USE_HIGHBITDEPTH),
1147 AOM_CODEC_OK);
1148 EXPECT_EQ(aom_codec_control(&enc, AOME_SET_CQ_LEVEL, 14), AOM_CODEC_OK);
1149 EXPECT_EQ(aom_codec_control(&enc, AV1E_SET_ROW_MT, 1), AOM_CODEC_OK);
1150 EXPECT_EQ(aom_codec_control(&enc, AV1E_SET_TILE_ROWS, 4), AOM_CODEC_OK);
1151 EXPECT_EQ(aom_codec_control(&enc, AV1E_SET_TILE_COLUMNS, 4), AOM_CODEC_OK);
1152 EXPECT_EQ(aom_codec_control(&enc, AOME_SET_CPUUSED, 0), AOM_CODEC_OK);
1153 EXPECT_EQ(aom_codec_control(&enc, AV1E_SET_COLOR_RANGE, AOM_CR_FULL_RANGE),
1154 AOM_CODEC_OK);
1155 EXPECT_EQ(aom_codec_control(&enc, AV1E_SET_SKIP_POSTPROC_FILTERING, 1),
1156 AOM_CODEC_OK);
1157 EXPECT_EQ(aom_codec_control(&enc, AOME_SET_TUNING, AOM_TUNE_SSIM),
1158 AOM_CODEC_OK);
1159
1160 // Encode frame
1161 EXPECT_EQ(aom_codec_encode(&enc, &img, 0, 1, 0), AOM_CODEC_OK);
1162 aom_codec_iter_t iter = nullptr;
1163 const aom_codec_cx_pkt_t *pkt = aom_codec_get_cx_data(&enc, &iter);
1164 ASSERT_NE(pkt, nullptr);
1165 EXPECT_EQ(pkt->kind, AOM_CODEC_CX_FRAME_PKT);
1166 // pkt->data.frame.flags is 0x1f0011.
1167 EXPECT_EQ(pkt->data.frame.flags & AOM_FRAME_IS_KEY, AOM_FRAME_IS_KEY);
1168 pkt = aom_codec_get_cx_data(&enc, &iter);
1169 EXPECT_EQ(pkt, nullptr);
1170
1171 // Flush encoder
1172 EXPECT_EQ(aom_codec_encode(&enc, nullptr, 0, 1, 0), AOM_CODEC_OK);
1173 iter = nullptr;
1174 pkt = aom_codec_get_cx_data(&enc, &iter);
1175 EXPECT_EQ(pkt, nullptr);
1176
1177 EXPECT_EQ(aom_codec_destroy(&enc), AOM_CODEC_OK);
1178 }
1179
1180 // A test that reproduces crbug.com/oss-fuzz/66474: signed integer overflow in
1181 // update_b_sep_sym().
1182 TEST(SearchWienerTest, 12bitSignedIntegerOverflowInUpdateBSepSym2) {
1183 constexpr int kWidth = 510;
1184 constexpr int kHeight = 3;
1185 static const uint16_t buffer[kWidth * kHeight] = {
1186 // Y plane:
1187 2136, 4095, 0, 0, 0, 4095, 4095, 0, 4095, 4095, 329, 0,
1188 4095, 0, 4095, 2587, 0, 0, 0, 4095, 0, 0, 0, 0,
1189 4095, 0, 4095, 878, 0, 4095, 0, 4095, 1474, 0, 573, 0,
1190 2401, 0, 1663, 4095, 0, 9, 3381, 0, 1084, 0, 270, 0,
1191 4095, 4095, 4095, 3992, 4095, 2047, 0, 0, 0, 4095, 41, 0,
1192 2726, 279, 0, 0, 4095, 0, 0, 1437, 0, 4095, 4095, 0,
1193 0, 0, 4095, 1683, 183, 3976, 3052, 0, 4095, 0, 0, 0,
1194 4095, 4095, 1882, 4095, 0, 4095, 83, 4095, 0, 4095, 0, 0,
1195 4095, 4095, 0, 0, 1637, 4095, 0, 4095, 0, 4095, 4095, 4095,
1196 0, 4095, 197, 4095, 563, 0, 3696, 3073, 3670, 0, 4095, 4095,
1197 0, 0, 0, 4095, 0, 0, 0, 0, 4095, 4095, 0, 0,
1198 0, 3539, 3468, 0, 2856, 3880, 0, 0, 1350, 2358, 4095, 802,
1199 4051, 0, 4095, 4095, 4095, 1677, 4095, 1135, 0, 4095, 0, 0,
1200 0, 618, 4095, 4095, 4095, 0, 2080, 4095, 0, 0, 1917, 0,
1201 0, 4095, 1937, 2835, 4095, 4095, 4095, 4095, 0, 4095, 4095, 3938,
1202 1707, 0, 0, 0, 4095, 448, 4095, 0, 1000, 2481, 3408, 0,
1203 0, 4095, 0, 3176, 0, 4095, 0, 4095, 4095, 4095, 0, 160,
1204 222, 1134, 4095, 4095, 0, 3539, 4095, 569, 3364, 0, 4095, 3687,
1205 0, 4095, 0, 0, 473, 0, 0, 4095, 298, 0, 3126, 4095,
1206 3854, 424, 0, 0, 4095, 3893, 0, 0, 175, 2774, 0, 4095,
1207 0, 2661, 950, 4095, 0, 1553, 0, 4095, 0, 4095, 4095, 2767,
1208 3630, 799, 255, 0, 4095, 0, 0, 4095, 2375, 0, 0, 0,
1209 0, 4095, 4095, 0, 0, 0, 1404, 4095, 4095, 4095, 4095, 2317,
1210 4095, 1227, 2205, 775, 0, 4095, 0, 0, 797, 1125, 736, 1773,
1211 2996, 4095, 2822, 4095, 4095, 0, 0, 0, 919, 0, 968, 3426,
1212 2702, 2613, 3647, 0, 0, 4095, 4095, 129, 4095, 0, 0, 4095,
1213 0, 0, 3632, 0, 3275, 123, 4095, 1566, 0, 0, 0, 1609,
1214 0, 1466, 4095, 577, 4095, 4095, 0, 4095, 1103, 1103, 4095, 0,
1215 1909, 0, 4095, 0, 4095, 4095, 227, 0, 4095, 2168, 4095, 374,
1216 4095, 4095, 4095, 0, 0, 0, 4095, 2066, 4095, 4095, 1475, 0,
1217 1959, 673, 4095, 0, 4095, 4095, 4095, 1142, 0, 464, 1819, 2033,
1218 4095, 0, 2212, 4095, 4095, 3961, 0, 4095, 0, 2838, 0, 4095,
1219 4095, 4095, 4095, 0, 3796, 3379, 2208, 0, 4095, 4095, 1943, 478,
1220 3573, 4095, 1763, 0, 0, 4095, 4095, 4095, 4095, 2061, 3346, 4095,
1221 0, 0, 4095, 0, 4095, 4095, 4095, 3738, 4095, 4095, 0, 4095,
1222 0, 425, 0, 0, 0, 927, 0, 0, 1814, 966, 4095, 0,
1223 0, 3185, 570, 3883, 2932, 0, 1413, 4095, 4095, 4095, 4095, 2477,
1224 2270, 4095, 2531, 4095, 1936, 3110, 99, 3936, 4095, 1315, 4095, 0,
1225 4095, 3564, 4095, 0, 0, 2797, 4095, 0, 1598, 0, 0, 3064,
1226 3526, 4095, 4095, 0, 3473, 3661, 0, 2388, 0, 4095, 639, 4095,
1227 0, 4095, 2390, 3715, 4095, 0, 0, 0, 740, 4095, 1432, 0,
1228 0, 0, 4057, 0, 0, 757, 4095, 4095, 0, 1437, 0, 0,
1229 4095, 0, 0, 0, 0, 0, 272, 4095, 4095, 4095, 2175, 4058,
1230 0, 4095, 4095, 4095, 3959, 3535, 0, 4095, 0, 0, 4095, 4095,
1231 4095, 4095, 0, 0, 4095, 4095, 4095, 3440, 3811, 0, 4095, 4095,
1232 4095, 4095, 0, 4095, 3193, 3674, 2819, 4095, 4095, 4048, 0, 0,
1233 4037, 4095, 3110, 4095, 1003, 0, 3650, 4095, 4095, 3154, 0, 1274,
1234 2192, 4095, 0, 4095, 0, 2814, 981, 370, 1407, 0, 4095, 1518,
1235 4095, 0, 0, 0, 0, 4095, 1577, 0, 4095, 0, 2607, 4095,
1236 3583, 0, 0, 4095, 1983, 1498, 4095, 4095, 2645, 4095, 4095, 3480,
1237 2587, 4095, 0, 0, 0, 0, 4095, 0, 4095, 4095, 0, 284,
1238 3973, 0, 0, 3677, 2463, 4095, 1338, 0, 4095, 0, 0, 4095,
1239 212, 2000, 4095, 4095, 0, 4095, 3780, 2039, 4095, 2453, 4095, 2050,
1240 2660, 1, 3839, 5, 1, 505, 809, 2907, 0, 0, 0, 1421,
1241 4095, 0, 0, 4095, 4095, 4095, 552, 0, 0, 4095, 3056, 0,
1242 0, 0, 0, 0, 4095, 0, 3386, 0, 0, 0, 4095, 0,
1243 0, 3404, 2702, 3534, 4095, 3562, 0, 4095, 4095, 150, 4095, 0,
1244 0, 3599, 4095, 4095, 0, 0, 0, 4095, 4095, 2093, 4095, 3753,
1245 3754, 4095, 0, 4095, 2733, 4095, 4095, 0, 0, 4095, 0, 0,
1246 0, 1496, 4095, 2366, 2936, 2494, 4095, 744, 1173, 4095, 0, 0,
1247 0, 1966, 4095, 4095, 0, 178, 3254, 4095, 4095, 995, 4095, 2083,
1248 0, 2639, 4095, 3422, 4095, 4095, 4095, 0, 842, 4095, 4095, 552,
1249 3681, 4095, 0, 1075, 2631, 554, 0, 0, 4095, 0, 0, 0,
1250 4095, 4095, 0, 0, 0, 2234, 0, 1098, 4095, 3164, 4095, 0,
1251 2748, 0, 0, 0, 4095, 4095, 4095, 1724, 891, 3496, 3964, 4095,
1252 0, 0, 1923, 4095, 4095, 4095, 3118, 0, 0, 0, 4095, 4095,
1253 0, 0, 3856, 4095, 0, 0, 4095, 4095, 2647, 0, 2089, 4095,
1254 471, 0, 4095, 0, 0, 0, 4095, 0, 1263, 2969, 289, 0,
1255 0, 4095, 289, 0, 0, 2965, 0, 0, 3280, 2279, 4091, 5,
1256 512, 1776, 4, 2046, 3994, 1, 4095, 898, 4095, 0, 0, 0,
1257 0, 4095, 0, 4095, 4095, 1930, 0, 0, 3725, 4095, 4095, 0,
1258 2593, 4095, 0, 4095, 984, 0, 4095, 2388, 0, 0, 4095, 4095,
1259 3341, 4095, 0, 2787, 0, 831, 2978, 4095, 0, 0, 0, 4095,
1260 1624, 4095, 1054, 1039, 0, 89, 3565, 0, 4095, 468, 0, 4095,
1261 4095, 0, 4095, 4095, 0, 3907, 0, 0, 0, 0, 0, 0,
1262 4095, 1898, 2178, 4095, 0, 3708, 2825, 0, 4095, 0, 4095, 4095,
1263 0, 0, 811, 1078, 0, 4095, 0, 3478, 0, 0, 1127, 0,
1264 504, 4095, 4095, 2006, 4095, 0, 2666, 1172, 4095, 4095, 4095, 4095,
1265 4095, 0, 199, 4095, 0, 2355, 2650, 2961, 0, 0, 0, 4095,
1266 4095, 0, 4095, 0, 4095, 1477, 0, 0, 1946, 0, 3352, 1988,
1267 0, 0, 2321, 4095, 0, 4095, 3367, 0, 0, 4095, 4095, 1946,
1268 0, 4034, 0, 0, 4095, 4095, 0, 0, 0, 0, 4095, 973,
1269 1734, 3966, 4095, 0, 3780, 1242, 0, 4095, 1301, 0, 1513, 4095,
1270 1079, 4095, 0, 0, 1316, 4095, 4095, 675, 2713, 2006, 4095, 4095,
1271 0, 0, 4095, 4095, 0, 3542, 4095, 0, 2365, 130, 4095, 2919,
1272 0, 4095, 3434, 0, 905, 4095, 673, 4095, 4095, 0, 3923, 293,
1273 4095, 213, 4095, 4095, 1334, 4095, 0, 3317, 0, 0, 0, 4095,
1274 4095, 4095, 2598, 2010, 0, 0, 3507, 0, 0, 0, 489, 0,
1275 0, 1782, 2681, 3303, 4095, 4095, 1955, 4095, 4095, 4095, 203, 1973,
1276 4095, 4020, 0, 4095, 1538, 0, 373, 1934, 4095, 0, 4095, 2244,
1277 4095, 1936, 4095, 640, 0, 4095, 0, 0, 0, 3653, 4095, 1966,
1278 4095, 4095, 4095, 4095, 0, 4095, 843, 0, 4095, 4095, 4095, 1646,
1279 4095, 0, 0, 4095, 4095, 4095, 2164, 0, 0, 0, 2141, 4095,
1280 0, 903, 4095, 4095, 0, 624, 4095, 792, 0, 0, 0, 0,
1281 0, 0, 0, 4095, 0, 4095, 4095, 2466, 0, 3631, 0, 4095,
1282 4095, 4095, 0, 941, 4095, 4095, 1609, 4095, 4095, 0, 0, 2398,
1283 4095, 4095, 2579, 0, 4020, 3485, 0, 0, 4095, 0, 4095, 0,
1284 3158, 2355, 0, 4095, 4095, 4095, 0, 0, 4095, 0, 0, 4095,
1285 475, 2272, 1010, 0, 0, 4095, 0, 0, 4095, 841, 4095, 4095,
1286 4095, 4095, 0, 4095, 0, 1046, 4095, 1738, 708, 4095, 0, 4095,
1287 4095, 0, 4095, 4095, 0, 4095, 4095, 0, 0, 0, 4032, 0,
1288 2679, 0, 1564, 0, 0, 0, 659, 1915, 4095, 3682, 0, 3660,
1289 4095, 723, 1383, 2499, 1353, 4095, 0, 3898, 2322, 3798, 4095, 0,
1290 444, 2277, 3729, 4095, 4095, 4095, 3054, 387, 3309, 4048, 3793, 2842,
1291 2087, 0, 3274, 2454, 518, 0, 4095, 0, 4095, 4095, 3358, 4095,
1292 2083, 2105, 0, 0, 0, 1125, 2636, 0, 0, 0, 0, 736,
1293 0, 349, 0, 4095, 2031, 4095, 992, 0, 4095, 3284, 4095, 214,
1294 3692, 4010, 402, 0, 0, 3776, 4095, 4095, 4095, 4095, 803, 2095,
1295 3864, 4095, 3323, 0, 0, 361, 1634, 0, 983, 0, 1181, 4095,
1296 1791, 4095, 367, 792, 4095, 4095, 3315, 3149, 4095, 62, 4095, 1791,
1297 3708, 2030, 4095, 1237, 0, 4095, 4095, 0, 0, 0, 0, 4095,
1298 1902, 2257, 4095, 4095, 0, 0, 2929, 4095, 0, 4095, 2356, 4095,
1299 2877, 1296, 4095, 0, 0, 0, 1310, 1968, 820, 4095, 4095, 4095,
1300 4095, 4095, 0, 0, 4095, 4095, 4095, 2897, 1787, 2218, 0, 129,
1301 4095, 4095, 0, 4095, 2331, 4095, 4095, 3192, 4095, 1744, 755, 0,
1302 1905, 0, 4095, 4095, 4095, 0, 0, 4095, 4095, 4095, 0, 0,
1303 0, 1467, 266, 1719, 4095, 729, 4095, 4095, 2647, 3543, 3388, 3326,
1304 4095, 0, 4095, 4095, 4095, 1416, 4095, 2131, 810, 0, 0, 4095,
1305 4095, 1250, 0, 0, 4095, 2722, 1493, 4095, 0, 4095, 0, 2895,
1306 0, 3847, 0, 2078, 0, 0, 0, 4095, 4095, 4095, 4095, 0,
1307 4095, 2651, 4095, 4095, 351, 2675, 4095, 0, 858, 0, 0, 0,
1308 816, 4095, 0, 4095, 0, 3842, 1990, 593, 0, 0, 3992, 4095,
1309 4095, 0, 4095, 1314, 4095, 4095, 1864, 2561, 4095, 1339, 0, 4095,
1310 2201, 4095, 0, 1403, 0, 0, 4095, 4095, 4095, 0, 0, 0,
1311 0, 0, 0, 577, 4095, 995, 2534, 827, 1431, 4095, 4095, 778,
1312 1405, 0, 0, 4095, 0, 4095, 1327, 4095, 0, 2725, 3351, 3937,
1313 741, 0, 2690, 2849, 4095, 4095, 2151, 0, 4095, 0, 4095, 4095,
1314 4095, 1342, 142, 1920, 1007, 2001
1315 };
1316 unsigned char *img_data =
1317 reinterpret_cast<unsigned char *>(const_cast<uint16_t *>(buffer));
1318
1319 aom_image_t img;
1320 EXPECT_EQ(&img, aom_img_wrap(&img, AOM_IMG_FMT_I42016, kWidth, kHeight, 1,
1321 img_data));
1322 img.cp = AOM_CICP_CP_UNSPECIFIED;
1323 img.tc = AOM_CICP_TC_UNSPECIFIED;
1324 img.mc = AOM_CICP_MC_UNSPECIFIED;
1325 img.monochrome = 1;
1326 img.csp = AOM_CSP_UNKNOWN;
1327 img.range = AOM_CR_FULL_RANGE;
1328 img.planes[1] = img.planes[2] = nullptr;
1329 img.stride[1] = img.stride[2] = 0;
1330
1331 aom_codec_iface_t *iface = aom_codec_av1_cx();
1332 aom_codec_enc_cfg_t cfg;
1333 EXPECT_EQ(AOM_CODEC_OK,
1334 aom_codec_enc_config_default(iface, &cfg, AOM_USAGE_GOOD_QUALITY));
1335 cfg.rc_end_usage = AOM_Q;
1336 cfg.g_profile = 2;
1337 cfg.g_bit_depth = AOM_BITS_12;
1338 cfg.g_input_bit_depth = 12;
1339 cfg.g_w = kWidth;
1340 cfg.g_h = kHeight;
1341 cfg.g_lag_in_frames = 0;
1342 cfg.g_threads = 53;
1343 cfg.monochrome = 1;
1344 cfg.rc_min_quantizer = 22;
1345 cfg.rc_max_quantizer = 30;
1346 aom_codec_ctx_t enc;
1347 EXPECT_EQ(AOM_CODEC_OK,
1348 aom_codec_enc_init(&enc, iface, &cfg, AOM_CODEC_USE_HIGHBITDEPTH));
1349 EXPECT_EQ(AOM_CODEC_OK, aom_codec_control(&enc, AOME_SET_CQ_LEVEL, 26));
1350 EXPECT_EQ(AOM_CODEC_OK, aom_codec_control(&enc, AV1E_SET_TILE_ROWS, 3));
1351 EXPECT_EQ(AOM_CODEC_OK, aom_codec_control(&enc, AOME_SET_CPUUSED, 6));
1352 EXPECT_EQ(AOM_CODEC_OK,
1353 aom_codec_control(&enc, AV1E_SET_COLOR_RANGE, AOM_CR_FULL_RANGE));
1354 EXPECT_EQ(AOM_CODEC_OK,
1355 aom_codec_control(&enc, AOME_SET_TUNING, AOM_TUNE_SSIM));
1356
1357 // Encode frame
1358 EXPECT_EQ(AOM_CODEC_OK, aom_codec_encode(&enc, &img, 0, 1, 0));
1359 aom_codec_iter_t iter = nullptr;
1360 const aom_codec_cx_pkt_t *pkt = aom_codec_get_cx_data(&enc, &iter);
1361 ASSERT_NE(pkt, nullptr);
1362 EXPECT_EQ(pkt->kind, AOM_CODEC_CX_FRAME_PKT);
1363 // pkt->data.frame.flags is 0x1f0011.
1364 EXPECT_EQ(pkt->data.frame.flags & AOM_FRAME_IS_KEY, AOM_FRAME_IS_KEY);
1365 pkt = aom_codec_get_cx_data(&enc, &iter);
1366 EXPECT_EQ(pkt, nullptr);
1367
1368 // Encode frame
1369 EXPECT_EQ(AOM_CODEC_OK,
1370 aom_codec_encode(&enc, &img, 0, 1, AOM_EFLAG_FORCE_KF));
1371 iter = nullptr;
1372 pkt = aom_codec_get_cx_data(&enc, &iter);
1373 ASSERT_NE(pkt, nullptr);
1374 EXPECT_EQ(pkt->kind, AOM_CODEC_CX_FRAME_PKT);
1375 // pkt->data.frame.flags is 0x1f0011.
1376 EXPECT_EQ(pkt->data.frame.flags & AOM_FRAME_IS_KEY, AOM_FRAME_IS_KEY);
1377 pkt = aom_codec_get_cx_data(&enc, &iter);
1378 EXPECT_EQ(pkt, nullptr);
1379
1380 // Encode frame
1381 EXPECT_EQ(AOM_CODEC_OK, aom_codec_encode(&enc, &img, 0, 1, 0));
1382 iter = nullptr;
1383 pkt = aom_codec_get_cx_data(&enc, &iter);
1384 ASSERT_NE(pkt, nullptr);
1385 EXPECT_EQ(pkt->kind, AOM_CODEC_CX_FRAME_PKT);
1386 pkt = aom_codec_get_cx_data(&enc, &iter);
1387 EXPECT_EQ(pkt, nullptr);
1388
1389 // Encode frame
1390 EXPECT_EQ(AOM_CODEC_OK, aom_codec_encode(&enc, &img, 0, 1, 0));
1391 iter = nullptr;
1392 pkt = aom_codec_get_cx_data(&enc, &iter);
1393 ASSERT_NE(pkt, nullptr);
1394 EXPECT_EQ(pkt->kind, AOM_CODEC_CX_FRAME_PKT);
1395 pkt = aom_codec_get_cx_data(&enc, &iter);
1396 EXPECT_EQ(pkt, nullptr);
1397
1398 // Flush encoder
1399 EXPECT_EQ(AOM_CODEC_OK, aom_codec_encode(&enc, nullptr, 0, 1, 0));
1400 iter = nullptr;
1401 pkt = aom_codec_get_cx_data(&enc, &iter);
1402 EXPECT_EQ(pkt, nullptr);
1403
1404 EXPECT_EQ(AOM_CODEC_OK, aom_codec_destroy(&enc));
1405 }
1406
1407 // A test that reproduces b/272139363: signed integer overflow in
1408 // update_b_sep_sym().
1409 TEST(SearchWienerTest, 10bitSignedIntegerOverflowInUpdateBSepSym) {
1410 constexpr int kWidth = 34;
1411 constexpr int kHeight = 3;
1412 static const uint16_t buffer[3 * kWidth * kHeight] = {
1413 // Y plane:
1414 61, 765, 674, 188, 367, 944, 153, 275, 906, 433, 154, 51, 8, 855, 186, 154,
1415 392, 0, 634, 3, 690, 1023, 1023, 1023, 1023, 1023, 1023, 8, 1, 64, 426, 0,
1416 100, 344, 944, 816, 816, 33, 1023, 1023, 1023, 1023, 295, 1023, 1023, 1023,
1417 1023, 1023, 1023, 1015, 1023, 231, 1020, 254, 439, 439, 894, 439, 150, 1019,
1418 1023, 1023, 1023, 1023, 1023, 1023, 1023, 1023, 1023, 1023, 385, 320, 575,
1419 682, 1023, 1023, 1023, 1023, 1023, 1023, 1023, 1023, 511, 699, 987, 3, 140,
1420 661, 120, 33, 143, 0, 0, 0, 3, 40, 625, 585, 16, 579, 160, 867,
1421 // U plane:
1422 739, 646, 13, 603, 7, 328, 91, 32, 488, 870, 330, 330, 330, 330, 330, 330,
1423 109, 330, 330, 330, 3, 545, 945, 249, 35, 561, 801, 32, 931, 639, 801, 91,
1424 1023, 827, 844, 948, 631, 894, 854, 601, 432, 504, 85, 1, 0, 0, 89, 89, 0,
1425 0, 0, 0, 0, 0, 432, 801, 382, 4, 0, 0, 2, 89, 89, 89, 89, 89, 89, 384, 0, 0,
1426 0, 0, 0, 0, 0, 1023, 1019, 1, 3, 691, 575, 691, 691, 691, 691, 691, 691,
1427 691, 691, 691, 691, 691, 84, 527, 4, 485, 8, 682, 698, 340, 1015, 706,
1428 // V plane:
1429 49, 10, 28, 1023, 1023, 1023, 0, 32, 32, 872, 114, 1003, 1023, 57, 477, 999,
1430 1023, 309, 309, 309, 309, 309, 309, 309, 309, 309, 309, 309, 309, 309, 309,
1431 9, 418, 418, 418, 418, 418, 418, 0, 0, 0, 1023, 4, 5, 0, 0, 1023, 0, 0, 0,
1432 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 64, 0, 155, 709, 3, 331, 807, 633, 1023,
1433 1018, 646, 886, 991, 692, 915, 294, 0, 35, 2, 0, 471, 643, 770, 346, 176,
1434 32, 329, 322, 302, 61, 765, 674, 188, 367, 944, 153, 275, 906, 433, 154
1435 };
1436 unsigned char *img_data =
1437 reinterpret_cast<unsigned char *>(const_cast<uint16_t *>(buffer));
1438
1439 aom_image_t img;
1440 EXPECT_EQ(&img, aom_img_wrap(&img, AOM_IMG_FMT_I44416, kWidth, kHeight, 1,
1441 img_data));
1442 img.cp = AOM_CICP_CP_UNSPECIFIED;
1443 img.tc = AOM_CICP_TC_UNSPECIFIED;
1444 img.mc = AOM_CICP_MC_UNSPECIFIED;
1445 img.range = AOM_CR_FULL_RANGE;
1446
1447 aom_codec_iface_t *iface = aom_codec_av1_cx();
1448 aom_codec_enc_cfg_t cfg;
1449 EXPECT_EQ(AOM_CODEC_OK,
1450 aom_codec_enc_config_default(iface, &cfg, AOM_USAGE_ALL_INTRA));
1451 cfg.rc_end_usage = AOM_Q;
1452 cfg.g_profile = 1;
1453 cfg.g_bit_depth = AOM_BITS_10;
1454 cfg.g_input_bit_depth = 10;
1455 cfg.g_w = kWidth;
1456 cfg.g_h = kHeight;
1457 cfg.g_limit = 1;
1458 cfg.g_lag_in_frames = 0;
1459 cfg.kf_mode = AOM_KF_DISABLED;
1460 cfg.kf_max_dist = 0;
1461 cfg.rc_min_quantizer = 3;
1462 cfg.rc_max_quantizer = 54;
1463 aom_codec_ctx_t enc;
1464 EXPECT_EQ(AOM_CODEC_OK,
1465 aom_codec_enc_init(&enc, iface, &cfg, AOM_CODEC_USE_HIGHBITDEPTH));
1466 EXPECT_EQ(AOM_CODEC_OK, aom_codec_control(&enc, AOME_SET_CQ_LEVEL, 28));
1467 EXPECT_EQ(AOM_CODEC_OK, aom_codec_control(&enc, AV1E_SET_TILE_COLUMNS, 3));
1468 EXPECT_EQ(AOM_CODEC_OK, aom_codec_control(&enc, AOME_SET_CPUUSED, 0));
1469 EXPECT_EQ(AOM_CODEC_OK,
1470 aom_codec_control(&enc, AV1E_SET_COLOR_RANGE, AOM_CR_FULL_RANGE));
1471 EXPECT_EQ(AOM_CODEC_OK,
1472 aom_codec_control(&enc, AV1E_SET_SKIP_POSTPROC_FILTERING, 1));
1473 EXPECT_EQ(AOM_CODEC_OK,
1474 aom_codec_control(&enc, AOME_SET_TUNING, AOM_TUNE_SSIM));
1475
1476 // Encode frame
1477 EXPECT_EQ(AOM_CODEC_OK, aom_codec_encode(&enc, &img, 0, 1, 0));
1478 aom_codec_iter_t iter = nullptr;
1479 const aom_codec_cx_pkt_t *pkt = aom_codec_get_cx_data(&enc, &iter);
1480 ASSERT_NE(pkt, nullptr);
1481 EXPECT_EQ(pkt->kind, AOM_CODEC_CX_FRAME_PKT);
1482 // pkt->data.frame.flags is 0x1f0011.
1483 EXPECT_EQ(pkt->data.frame.flags & AOM_FRAME_IS_KEY, AOM_FRAME_IS_KEY);
1484 pkt = aom_codec_get_cx_data(&enc, &iter);
1485 EXPECT_EQ(pkt, nullptr);
1486
1487 // Flush encoder
1488 EXPECT_EQ(AOM_CODEC_OK, aom_codec_encode(&enc, nullptr, 0, 1, 0));
1489 iter = nullptr;
1490 pkt = aom_codec_get_cx_data(&enc, &iter);
1491 EXPECT_EQ(pkt, nullptr);
1492
1493 EXPECT_EQ(AOM_CODEC_OK, aom_codec_destroy(&enc));
1494 }
1495
1496 // A test that reproduces b/319140742: signed integer overflow in
1497 // update_b_sep_sym().
1498 TEST(SearchWienerTest, 10bitSignedIntegerOverflowInUpdateBSepSym2) {
1499 constexpr int kWidth = 326;
1500 constexpr int kHeight = 3;
1501 static const uint16_t buffer[kWidth * kHeight] = {
1502 // Y plane:
1503 1023, 1023, 0, 1023, 1023, 0, 623, 0, 0, 1023, 1023, 0,
1504 0, 0, 0, 523, 1023, 2, 0, 0, 863, 1023, 1023, 409,
1505 7, 1023, 0, 409, 1023, 0, 579, 1023, 1023, 1023, 0, 0,
1506 1023, 1023, 446, 1023, 1023, 0, 0, 1023, 0, 0, 829, 1023,
1507 0, 1023, 939, 0, 0, 23, 1022, 990, 1023, 0, 0, 4,
1508 0, 299, 0, 0, 1023, 1023, 629, 688, 1023, 1023, 266, 1023,
1509 865, 0, 413, 0, 267, 0, 0, 69, 1023, 866, 1023, 885,
1510 0, 762, 330, 382, 0, 1023, 1023, 734, 504, 899, 119, 0,
1511 378, 1011, 0, 0, 1023, 364, 0, 1023, 1023, 462, 1023, 0,
1512 504, 1023, 1023, 0, 695, 1023, 57, 1023, 1023, 362, 0, 0,
1513 0, 0, 1023, 1023, 387, 12, 929, 1023, 0, 194, 1023, 0,
1514 1023, 505, 0, 1023, 1023, 1023, 1023, 1023, 0, 0, 676, 0,
1515 6, 683, 70, 0, 0, 1023, 226, 1023, 320, 758, 0, 0,
1516 648, 1023, 867, 550, 630, 960, 1023, 1023, 1023, 0, 0, 822,
1517 0, 0, 0, 1023, 1011, 1023, 1023, 0, 0, 15, 30, 0,
1518 1023, 1023, 0, 0, 0, 84, 954, 1023, 933, 416, 333, 323,
1519 0, 0, 1023, 355, 1023, 176, 1023, 1023, 886, 87, 1023, 0,
1520 1023, 1023, 1023, 562, 0, 1023, 1023, 354, 0, 0, 1023, 0,
1521 86, 0, 0, 1023, 0, 1023, 192, 0, 1023, 0, 1023, 0,
1522 0, 0, 735, 1023, 1023, 1023, 0, 372, 988, 131, 1023, 1023,
1523 0, 1023, 1023, 1023, 1023, 970, 1023, 1023, 248, 757, 665, 330,
1524 223, 273, 0, 274, 1023, 0, 1023, 613, 786, 1023, 792, 0,
1525 390, 282, 0, 1023, 0, 1023, 0, 1023, 1023, 1023, 614, 993,
1526 135, 737, 662, 0, 1023, 524, 970, 1023, 0, 906, 1023, 1023,
1527 959, 1023, 1023, 1023, 1023, 836, 838, 0, 0, 0, 0, 0,
1528 1023, 917, 492, 290, 1023, 1023, 817, 1023, 0, 0, 588, 410,
1529 419, 0, 1023, 1023, 178, 0, 0, 563, 775, 977, 1023, 1023,
1530 0, 1023, 0, 370, 434, 1023, 963, 587, 0, 0, 1023, 1023,
1531 1023, 1023, 1023, 1023, 619, 0, 1023, 352, 1023, 0, 0, 0,
1532 133, 557, 36, 1023, 1023, 1023, 0, 469, 1023, 1023, 0, 900,
1533 59, 841, 1023, 886, 0, 193, 126, 263, 119, 629, 0, 1023,
1534 0, 1023, 0, 0, 478, 0, 1023, 63, 1023, 0, 0, 0,
1535 0, 0, 0, 0, 1023, 888, 1023, 905, 646, 0, 0, 1023,
1536 752, 1023, 1023, 0, 1023, 0, 0, 648, 1023, 0, 0, 838,
1537 0, 321, 1023, 475, 0, 215, 867, 1023, 0, 1023, 1023, 624,
1538 417, 1023, 426, 0, 0, 960, 1020, 839, 687, 1023, 161, 1023,
1539 1023, 1023, 1023, 968, 0, 95, 430, 0, 132, 1023, 1023, 113,
1540 0, 1023, 1023, 606, 1023, 0, 0, 31, 1023, 1023, 0, 180,
1541 140, 654, 1023, 1023, 1023, 1023, 1023, 779, 1023, 0, 0, 1023,
1542 1023, 1023, 0, 1023, 0, 0, 1023, 963, 723, 536, 1023, 0,
1543 0, 0, 337, 812, 0, 0, 0, 428, 48, 0, 321, 205,
1544 0, 587, 799, 272, 5, 1023, 322, 0, 761, 0, 749, 1023,
1545 0, 0, 1023, 1023, 1023, 1023, 242, 402, 98, 0, 1023, 884,
1546 219, 1023, 0, 1023, 0, 0, 0, 106, 1023, 0, 1023, 414,
1547 1023, 0, 1023, 619, 0, 0, 973, 854, 82, 1023, 1023, 1023,
1548 0, 1023, 1023, 0, 0, 588, 433, 0, 0, 961, 0, 0,
1549 0, 917, 859, 461, 455, 68, 1023, 409, 1023, 821, 1023, 487,
1550 1023, 0, 717, 0, 613, 0, 0, 840, 932, 782, 1023, 1023,
1551 576, 1023, 0, 1023, 1023, 187, 876, 162, 0, 1023, 1023, 946,
1552 873, 0, 0, 953, 0, 537, 0, 0, 1023, 193, 807, 756,
1553 0, 0, 1023, 732, 1023, 1023, 1023, 0, 0, 1023, 1023, 1023,
1554 1023, 1023, 119, 0, 0, 90, 1023, 0, 1023, 0, 0, 0,
1555 1023, 366, 1023, 655, 0, 58, 1023, 1023, 8, 1023, 1023, 24,
1556 1023, 103, 0, 0, 1023, 919, 1023, 566, 1023, 0, 0, 480,
1557 1023, 1023, 0, 0, 807, 0, 1023, 0, 273, 412, 632, 1023,
1558 1023, 1023, 10, 633, 1023, 692, 978, 0, 0, 1023, 1023, 1023,
1559 25, 494, 215, 0, 148, 1023, 840, 118, 1023, 1023, 999, 1023,
1560 1023, 1023, 0, 0, 1023, 435, 894, 0, 1023, 1023, 168, 1023,
1561 1023, 211, 1023, 1023, 656, 1023, 0, 0, 0, 744, 238, 1023,
1562 0, 196, 907, 0, 0, 0, 838, 726, 1023, 1023, 1023, 0,
1563 0, 0, 1023, 0, 1023, 1023, 1023, 0, 1023, 0, 0, 0,
1564 323, 1023, 1023, 0, 1023, 0, 0, 925, 582, 1023, 0, 685,
1565 1023, 661, 464, 0, 0, 0, 1023, 0, 807, 0, 1023, 1023,
1566 1023, 100, 0, 1023, 302, 1023, 1023, 1023, 616, 0, 1023, 0,
1567 0, 377, 1023, 1023, 1023, 0, 1023, 555, 1023, 784, 0, 0,
1568 1023, 0, 0, 1023, 755, 0, 839, 1023, 0, 0, 0, 1023,
1569 1023, 1023, 0, 1023, 413, 0, 1023, 1023, 384, 0, 823, 797,
1570 1023, 0, 1023, 0, 0, 1023, 1023, 1023, 1023, 0, 1023, 39,
1571 0, 473, 299, 0, 0, 1023, 567, 1023, 1023, 0, 0, 1023,
1572 650, 1023, 41, 1023, 0, 1023, 0, 1023, 0, 1023, 0, 0,
1573 444, 1023, 23, 0, 503, 97, 0, 1023, 0, 890, 59, 578,
1574 0, 201, 1023, 672, 1023, 593, 1023, 599, 213, 1023, 1023, 1023,
1575 986, 1023, 335, 1023, 457, 0, 888, 1023, 1023, 97, 308, 259,
1576 813, 1023, 1023, 1023, 0, 1023, 798, 907, 105, 0, 1023, 0,
1577 1023, 1023, 0, 970, 518, 0, 635, 0, 634, 329, 1023, 430,
1578 0, 17, 1023, 1023, 1023, 0, 0, 407, 1023, 1023, 0, 1023,
1579 0, 0, 0, 0, 1023, 1023, 1023, 402, 1023, 0, 0, 101,
1580 1023, 1023, 1023, 1023, 1023, 1023, 425, 791, 1023, 1023, 961, 0,
1581 0, 1023, 474, 1023, 1023, 1023, 1023, 468, 1023, 1023, 0, 1023,
1582 215, 0, 1023, 1023, 334, 463, 286, 1023, 0, 1023, 0, 1023,
1583 270, 401, 0, 0, 1023, 0, 794, 0, 0, 0, 1023, 0,
1584 1023, 172, 317, 905, 950, 0
1585 };
1586 unsigned char *img_data =
1587 reinterpret_cast<unsigned char *>(const_cast<uint16_t *>(buffer));
1588
1589 aom_image_t img;
1590 EXPECT_EQ(&img, aom_img_wrap(&img, AOM_IMG_FMT_I42016, kWidth, kHeight, 1,
1591 img_data));
1592 img.cp = AOM_CICP_CP_UNSPECIFIED;
1593 img.tc = AOM_CICP_TC_UNSPECIFIED;
1594 img.mc = AOM_CICP_MC_UNSPECIFIED;
1595 img.monochrome = 1;
1596 img.csp = AOM_CSP_UNKNOWN;
1597 img.range = AOM_CR_FULL_RANGE;
1598 img.planes[1] = img.planes[2] = nullptr;
1599 img.stride[1] = img.stride[2] = 0;
1600
1601 aom_codec_iface_t *iface = aom_codec_av1_cx();
1602 aom_codec_enc_cfg_t cfg;
1603 EXPECT_EQ(AOM_CODEC_OK,
1604 aom_codec_enc_config_default(iface, &cfg, AOM_USAGE_GOOD_QUALITY));
1605 cfg.rc_end_usage = AOM_Q;
1606 cfg.g_profile = 0;
1607 cfg.g_bit_depth = AOM_BITS_10;
1608 cfg.g_input_bit_depth = 10;
1609 cfg.g_w = kWidth;
1610 cfg.g_h = kHeight;
1611 cfg.g_threads = 6;
1612 cfg.monochrome = 1;
1613 cfg.rc_min_quantizer = 54;
1614 cfg.rc_max_quantizer = 62;
1615 aom_codec_ctx_t enc;
1616 EXPECT_EQ(AOM_CODEC_OK,
1617 aom_codec_enc_init(&enc, iface, &cfg, AOM_CODEC_USE_HIGHBITDEPTH));
1618 EXPECT_EQ(AOM_CODEC_OK, aom_codec_control(&enc, AOME_SET_CQ_LEVEL, 58));
1619 EXPECT_EQ(AOM_CODEC_OK, aom_codec_control(&enc, AV1E_SET_TILE_ROWS, 1));
1620 EXPECT_EQ(AOM_CODEC_OK, aom_codec_control(&enc, AOME_SET_CPUUSED, 6));
1621 EXPECT_EQ(AOM_CODEC_OK,
1622 aom_codec_control(&enc, AV1E_SET_COLOR_RANGE, AOM_CR_FULL_RANGE));
1623 EXPECT_EQ(AOM_CODEC_OK,
1624 aom_codec_control(&enc, AOME_SET_TUNING, AOM_TUNE_SSIM));
1625
1626 // Encode frame
1627 EXPECT_EQ(AOM_CODEC_OK, aom_codec_encode(&enc, &img, 0, 1, 0));
1628 aom_codec_iter_t iter = nullptr;
1629 const aom_codec_cx_pkt_t *pkt = aom_codec_get_cx_data(&enc, &iter);
1630 ASSERT_EQ(pkt, nullptr);
1631
1632 // Flush encoder
1633 EXPECT_EQ(AOM_CODEC_OK, aom_codec_encode(&enc, nullptr, 0, 1, 0));
1634 iter = nullptr;
1635 pkt = aom_codec_get_cx_data(&enc, &iter);
1636 ASSERT_NE(pkt, nullptr);
1637 EXPECT_EQ(pkt->kind, AOM_CODEC_CX_FRAME_PKT);
1638 // pkt->data.frame.flags is 0x1f0011.
1639 EXPECT_EQ(pkt->data.frame.flags & AOM_FRAME_IS_KEY, AOM_FRAME_IS_KEY);
1640 pkt = aom_codec_get_cx_data(&enc, &iter);
1641 EXPECT_EQ(pkt, nullptr);
1642
1643 EXPECT_EQ(AOM_CODEC_OK, aom_codec_encode(&enc, nullptr, 0, 1, 0));
1644 iter = nullptr;
1645 pkt = aom_codec_get_cx_data(&enc, &iter);
1646 EXPECT_EQ(pkt, nullptr);
1647
1648 EXPECT_EQ(AOM_CODEC_OK, aom_codec_destroy(&enc));
1649 }
1650
1651 // A test that reproduces b/277121724: signed integer overflow in
1652 // update_b_sep_sym().
1653 TEST(SearchWienerTest, 8bitSignedIntegerOverflowInUpdateBSepSym) {
1654 constexpr int kWidth = 198;
1655 constexpr int kHeight = 3;
1656 // 8-bit YUV 4:2:2
1657 static const unsigned char buffer[2 * kWidth * kHeight] = {
1658 // Y plane:
1659 35, 225, 56, 91, 8, 142, 137, 143, 224, 49, 217, 57, 202, 163, 159, 246,
1660 232, 134, 135, 14, 76, 101, 239, 88, 186, 159, 118, 23, 114, 20, 108, 41,
1661 72, 17, 58, 242, 45, 146, 230, 14, 135, 140, 34, 61, 189, 181, 222, 71, 98,
1662 221, 5, 199, 244, 85, 229, 163, 105, 87, 144, 105, 64, 150, 36, 233, 235, 1,
1663 179, 190, 50, 222, 176, 109, 166, 18, 80, 129, 45, 9, 218, 144, 234, 10,
1664 148, 117, 37, 10, 232, 139, 206, 92, 208, 247, 128, 79, 202, 79, 212, 89,
1665 185, 152, 206, 182, 83, 105, 21, 86, 150, 84, 21, 165, 34, 251, 174, 240,
1666 172, 155, 254, 85, 98, 25, 96, 78, 230, 253, 36, 19, 247, 155, 112, 216,
1667 166, 114, 229, 118, 197, 149, 186, 194, 128, 45, 219, 26, 36, 77, 110, 45,
1668 252, 238, 183, 161, 171, 96, 232, 108, 73, 61, 243, 58, 155, 38, 91, 209,
1669 187, 206, 16, 165, 236, 145, 69, 126, 102, 10, 4, 43, 191, 106, 193, 240,
1670 132, 226, 38, 78, 7, 152, 101, 255, 254, 39, 33, 86, 35, 247, 199, 179, 239,
1671 198, 165, 58, 190, 171, 226, 94, 158, 21, 190, 151, 75, 176, 11, 53, 199,
1672 87, 91, 1, 226, 20, 117, 96, 75, 192, 101, 200, 125, 106, 233, 176, 63, 204,
1673 114, 16, 31, 222, 15, 14, 71, 2, 25, 47, 100, 174, 26, 209, 138, 138, 211,
1674 147, 164, 204, 9, 104, 135, 250, 9, 201, 88, 218, 71, 251, 61, 199, 0, 34,
1675 59, 115, 228, 161, 100, 132, 50, 4, 117, 100, 191, 126, 53, 28, 193, 42,
1676 155, 206, 79, 80, 117, 11, 3, 253, 181, 181, 138, 239, 107, 142, 216, 57,
1677 202, 126, 229, 250, 60, 62, 150, 128, 95, 32, 251, 207, 236, 208, 247, 183,
1678 59, 19, 117, 40, 106, 87, 140, 57, 109, 190, 51, 105, 226, 116, 156, 3, 35,
1679 86, 255, 138, 52, 211, 245, 76, 83, 109, 113, 77, 106, 77, 18, 56, 235, 158,
1680 24, 53, 151, 104, 152, 21, 15, 46, 163, 144, 217, 168, 154, 44, 80, 25, 11,
1681 37, 100, 235, 145, 154, 113, 0, 140, 153, 80, 64, 19, 121, 185, 144, 43,
1682 206, 16, 16, 72, 189, 175, 231, 177, 40, 177, 206, 116, 4, 82, 43, 244, 237,
1683 22, 252, 71, 194, 106, 4, 112, 0, 108, 137, 126, 80, 122, 142, 43, 205, 22,
1684 209, 217, 165, 32, 208, 100, 70, 3, 120, 159, 203, 7, 233, 152, 37, 96, 212,
1685 177, 1, 133, 218, 161, 172, 202, 192, 186, 114, 150, 121, 177, 227, 175, 64,
1686 127, 153, 113, 91, 198, 0, 111, 227, 226, 218, 71, 62, 5, 43, 128, 27, 3,
1687 82, 5, 10, 68, 153, 215, 181, 138, 246, 224, 170, 1, 241, 191, 181, 151,
1688 167, 14, 80, 45, 4, 252, 29, 66, 125, 58, 225, 253, 255, 248, 224, 40, 24,
1689 236, 46, 11, 219, 154, 134, 12, 76, 72, 97, 239, 50, 39, 85, 182, 55, 219,
1690 19, 109, 81, 119, 125, 206, 159, 239, 67, 193, 180, 132, 80, 127, 2, 169,
1691 99, 53, 47, 5, 100, 174, 151, 124, 246, 202, 93, 82, 65, 53, 214, 238, 32,
1692 218, 15, 254, 153, 95, 79, 189, 67, 233, 47, 83, 48, 125, 144, 206, 82, 69,
1693 186, 112, 134, 244, 96, 21, 143, 187, 248, 8, 224, 161, 227, 185, 236, 6,
1694 175, 237, 169, 154, 89, 143, 106, 205, 26, 47, 155, 42, 28, 162, 7, 8, 45,
1695 // U plane:
1696 55, 165, 203, 139, 152, 208, 36, 177, 61, 49, 129, 211, 140, 71, 253, 250,
1697 120, 167, 238, 67, 255, 223, 104, 32, 240, 179, 28, 41, 86, 84, 61, 243,
1698 169, 212, 201, 0, 9, 236, 89, 194, 204, 75, 228, 250, 27, 81, 137, 29, 255,
1699 131, 194, 241, 76, 133, 186, 135, 212, 197, 150, 145, 203, 96, 86, 231, 91,
1700 119, 197, 67, 226, 2, 118, 66, 181, 86, 219, 86, 132, 137, 156, 161, 221,
1701 18, 55, 170, 35, 206, 201, 193, 38, 63, 229, 29, 110, 96, 14, 135, 229, 99,
1702 106, 108, 167, 110, 50, 32, 144, 113, 48, 29, 57, 29, 20, 199, 145, 245, 9,
1703 183, 88, 174, 114, 237, 29, 40, 99, 117, 233, 6, 51, 227, 2, 28, 76, 149,
1704 190, 23, 240, 73, 113, 10, 73, 240, 105, 220, 129, 26, 144, 214, 34, 4, 24,
1705 219, 24, 156, 198, 214, 244, 143, 106, 255, 204, 93, 2, 88, 107, 211, 241,
1706 242, 86, 189, 219, 164, 132, 149, 32, 228, 219, 60, 202, 218, 189, 34, 250,
1707 160, 158, 36, 212, 212, 41, 233, 61, 92, 121, 170, 220, 192, 232, 255, 124,
1708 249, 231, 55, 196, 219, 196, 62, 238, 187, 76, 33, 138, 67, 82, 159, 169,
1709 196, 66, 196, 110, 194, 64, 35, 205, 64, 218, 12, 41, 188, 195, 244, 178,
1710 17, 80, 8, 149, 39, 110, 146, 164, 162, 215, 227, 107, 103, 47, 52, 95, 3,
1711 181, 90, 255, 80, 83, 206, 66, 153, 112, 72, 109, 235, 69, 105, 57, 75, 145,
1712 186, 16, 87, 73, 61, 98, 197, 237, 17, 32, 207, 220, 246, 188, 46, 73, 121,
1713 84, 252, 164, 111, 21, 98, 13, 170, 174, 170, 231, 77, 10, 113, 9, 217, 11,
1714 // V plane:
1715 124, 94, 69, 212, 107, 223, 228, 96, 56, 2, 158, 49, 251, 217, 143, 107,
1716 113, 17, 84, 169, 208, 43, 28, 37, 176, 54, 235, 150, 135, 135, 221, 94, 50,
1717 131, 251, 78, 38, 254, 129, 200, 207, 55, 111, 110, 144, 109, 228, 65, 70,
1718 39, 170, 5, 208, 151, 87, 86, 255, 74, 155, 153, 250, 15, 35, 33, 201, 226,
1719 117, 119, 220, 238, 133, 229, 69, 122, 160, 114, 245, 182, 13, 65, 2, 228,
1720 205, 174, 128, 248, 4, 139, 178, 227, 204, 243, 249, 253, 119, 253, 107,
1721 234, 39, 15, 173, 47, 93, 12, 222, 238, 30, 121, 124, 167, 27, 40, 215, 84,
1722 172, 130, 66, 43, 165, 55, 225, 79, 84, 153, 59, 110, 64, 176, 54, 123, 82,
1723 128, 189, 150, 52, 202, 102, 133, 199, 197, 253, 180, 221, 127, 144, 124,
1724 255, 224, 52, 149, 88, 166, 39, 38, 78, 114, 44, 242, 233, 40, 132, 142,
1725 152, 213, 112, 244, 221, 7, 52, 206, 246, 51, 182, 160, 247, 154, 183, 209,
1726 81, 70, 56, 186, 63, 182, 2, 82, 202, 178, 233, 52, 198, 241, 175, 38, 165,
1727 9, 231, 150, 114, 43, 159, 200, 42, 173, 217, 25, 233, 214, 210, 50, 43,
1728 159, 231, 102, 241, 246, 77, 76, 115, 77, 81, 114, 194, 182, 236, 0, 236,
1729 198, 197, 180, 176, 148, 48, 177, 106, 180, 150, 158, 237, 130, 242, 109,
1730 174, 247, 57, 230, 184, 64, 245, 251, 123, 169, 122, 156, 125, 123, 104,
1731 238, 1, 235, 187, 53, 67, 38, 50, 139, 123, 149, 111, 72, 80, 17, 175, 186,
1732 98, 153, 247, 97, 218, 141, 38, 0, 171, 254, 180, 81, 233, 71, 156, 48, 14,
1733 62, 210, 161, 124, 203, 92
1734 };
1735 unsigned char *img_data = const_cast<unsigned char *>(buffer);
1736
1737 aom_image_t img;
1738 EXPECT_EQ(aom_img_wrap(&img, AOM_IMG_FMT_I422, kWidth, kHeight, 1, img_data),
1739 &img);
1740 img.cp = AOM_CICP_CP_UNSPECIFIED;
1741 img.tc = AOM_CICP_TC_UNSPECIFIED;
1742 img.mc = AOM_CICP_MC_UNSPECIFIED;
1743 img.range = AOM_CR_FULL_RANGE;
1744
1745 aom_codec_iface_t *iface = aom_codec_av1_cx();
1746 aom_codec_enc_cfg_t cfg;
1747 EXPECT_EQ(aom_codec_enc_config_default(iface, &cfg, AOM_USAGE_ALL_INTRA),
1748 AOM_CODEC_OK);
1749 cfg.rc_end_usage = AOM_Q;
1750 cfg.g_profile = 2;
1751 cfg.g_bit_depth = AOM_BITS_8;
1752 cfg.g_input_bit_depth = 8;
1753 cfg.g_w = kWidth;
1754 cfg.g_h = kHeight;
1755 cfg.g_limit = 1;
1756 cfg.g_lag_in_frames = 0;
1757 cfg.kf_mode = AOM_KF_DISABLED;
1758 cfg.kf_max_dist = 0;
1759 cfg.g_threads = 43;
1760 cfg.rc_min_quantizer = 30;
1761 cfg.rc_max_quantizer = 50;
1762 aom_codec_ctx_t enc;
1763 EXPECT_EQ(aom_codec_enc_init(&enc, iface, &cfg, 0), AOM_CODEC_OK);
1764 EXPECT_EQ(aom_codec_control(&enc, AOME_SET_CQ_LEVEL, 40), AOM_CODEC_OK);
1765 EXPECT_EQ(aom_codec_control(&enc, AV1E_SET_ROW_MT, 1), AOM_CODEC_OK);
1766 EXPECT_EQ(aom_codec_control(&enc, AV1E_SET_TILE_ROWS, 4), AOM_CODEC_OK);
1767 EXPECT_EQ(aom_codec_control(&enc, AV1E_SET_TILE_COLUMNS, 1), AOM_CODEC_OK);
1768 EXPECT_EQ(aom_codec_control(&enc, AOME_SET_CPUUSED, 2), AOM_CODEC_OK);
1769 EXPECT_EQ(aom_codec_control(&enc, AV1E_SET_COLOR_RANGE, AOM_CR_FULL_RANGE),
1770 AOM_CODEC_OK);
1771 EXPECT_EQ(aom_codec_control(&enc, AV1E_SET_SKIP_POSTPROC_FILTERING, 1),
1772 AOM_CODEC_OK);
1773 EXPECT_EQ(aom_codec_control(&enc, AOME_SET_TUNING, AOM_TUNE_SSIM),
1774 AOM_CODEC_OK);
1775
1776 // Encode frame
1777 EXPECT_EQ(aom_codec_encode(&enc, &img, 0, 1, 0), AOM_CODEC_OK);
1778 aom_codec_iter_t iter = nullptr;
1779 const aom_codec_cx_pkt_t *pkt = aom_codec_get_cx_data(&enc, &iter);
1780 ASSERT_NE(pkt, nullptr);
1781 EXPECT_EQ(pkt->kind, AOM_CODEC_CX_FRAME_PKT);
1782 // pkt->data.frame.flags is 0x1f0011.
1783 EXPECT_EQ(pkt->data.frame.flags & AOM_FRAME_IS_KEY, AOM_FRAME_IS_KEY);
1784 pkt = aom_codec_get_cx_data(&enc, &iter);
1785 EXPECT_EQ(pkt, nullptr);
1786
1787 // Flush encoder
1788 EXPECT_EQ(aom_codec_encode(&enc, nullptr, 0, 1, 0), AOM_CODEC_OK);
1789 iter = nullptr;
1790 pkt = aom_codec_get_cx_data(&enc, &iter);
1791 EXPECT_EQ(pkt, nullptr);
1792
1793 EXPECT_EQ(aom_codec_destroy(&enc), AOM_CODEC_OK);
1794 }
1795
1796 // A test that reproduces crbug.com/oss-fuzz/68195: signed integer overflow in
1797 // linsolve_wiener().
1798 TEST(SearchWienerTest, 8bitSignedIntegerOverflowInLinsolveWiener) {
1799 constexpr int kWidth = 4;
1800 constexpr int kHeight = 3;
1801 constexpr unsigned char kBuffer[kWidth * kHeight] = {
1802 // Y plane:
1803 50, 167, 190, 194, 27, 29, 204, 182, 133, 239, 64, 179,
1804 };
1805 unsigned char *img_data = const_cast<unsigned char *>(kBuffer);
1806
1807 aom_image_t img;
1808 EXPECT_EQ(&img,
1809 aom_img_wrap(&img, AOM_IMG_FMT_I420, kWidth, kHeight, 1, img_data));
1810 img.cp = AOM_CICP_CP_UNSPECIFIED;
1811 img.tc = AOM_CICP_TC_UNSPECIFIED;
1812 img.mc = AOM_CICP_MC_UNSPECIFIED;
1813 img.monochrome = 1;
1814 img.csp = AOM_CSP_UNKNOWN;
1815 img.range = AOM_CR_FULL_RANGE;
1816 img.planes[1] = img.planes[2] = nullptr;
1817 img.stride[1] = img.stride[2] = 0;
1818
1819 aom_codec_iface_t *iface = aom_codec_av1_cx();
1820 aom_codec_enc_cfg_t cfg;
1821 EXPECT_EQ(AOM_CODEC_OK,
1822 aom_codec_enc_config_default(iface, &cfg, AOM_USAGE_GOOD_QUALITY));
1823 cfg.rc_end_usage = AOM_Q;
1824 cfg.g_profile = 0;
1825 cfg.g_bit_depth = AOM_BITS_8;
1826 cfg.g_input_bit_depth = 8;
1827 cfg.g_w = kWidth;
1828 cfg.g_h = kHeight;
1829 cfg.g_threads = 32;
1830 cfg.monochrome = 1;
1831 cfg.rc_min_quantizer = 50;
1832 cfg.rc_max_quantizer = 57;
1833 aom_codec_ctx_t enc;
1834 EXPECT_EQ(AOM_CODEC_OK, aom_codec_enc_init(&enc, iface, &cfg, 0));
1835 EXPECT_EQ(AOM_CODEC_OK, aom_codec_control(&enc, AOME_SET_CQ_LEVEL, 53));
1836 EXPECT_EQ(AOM_CODEC_OK, aom_codec_control(&enc, AV1E_SET_TILE_ROWS, 1));
1837 EXPECT_EQ(AOM_CODEC_OK, aom_codec_control(&enc, AV1E_SET_TILE_COLUMNS, 1));
1838 EXPECT_EQ(AOM_CODEC_OK, aom_codec_control(&enc, AOME_SET_CPUUSED, 6));
1839 EXPECT_EQ(AOM_CODEC_OK,
1840 aom_codec_control(&enc, AV1E_SET_COLOR_RANGE, AOM_CR_FULL_RANGE));
1841 EXPECT_EQ(AOM_CODEC_OK,
1842 aom_codec_control(&enc, AOME_SET_TUNING, AOM_TUNE_SSIM));
1843
1844 // Encode frame
1845 EXPECT_EQ(AOM_CODEC_OK, aom_codec_encode(&enc, &img, 0, 1, 0));
1846 aom_codec_iter_t iter = nullptr;
1847 const aom_codec_cx_pkt_t *pkt = aom_codec_get_cx_data(&enc, &iter);
1848 ASSERT_EQ(pkt, nullptr);
1849
1850 // Encode frame
1851 EXPECT_EQ(AOM_CODEC_OK, aom_codec_encode(&enc, &img, 0, 1, 0));
1852 iter = nullptr;
1853 pkt = aom_codec_get_cx_data(&enc, &iter);
1854 EXPECT_EQ(pkt, nullptr);
1855
1856 // Flush encoder
1857 EXPECT_EQ(AOM_CODEC_OK, aom_codec_encode(&enc, nullptr, 0, 1, 0));
1858 iter = nullptr;
1859 pkt = aom_codec_get_cx_data(&enc, &iter);
1860 ASSERT_NE(pkt, nullptr);
1861 EXPECT_EQ(pkt->kind, AOM_CODEC_CX_FRAME_PKT);
1862 // pkt->data.frame.flags is 0x1f0011.
1863 EXPECT_EQ(pkt->data.frame.flags & AOM_FRAME_IS_KEY, AOM_FRAME_IS_KEY);
1864 pkt = aom_codec_get_cx_data(&enc, &iter);
1865 EXPECT_EQ(pkt, nullptr);
1866
1867 // Flush encoder
1868 EXPECT_EQ(AOM_CODEC_OK, aom_codec_encode(&enc, nullptr, 0, 1, 0));
1869 iter = nullptr;
1870 pkt = aom_codec_get_cx_data(&enc, &iter);
1871 ASSERT_NE(pkt, nullptr);
1872 EXPECT_EQ(pkt->kind, AOM_CODEC_CX_FRAME_PKT);
1873 // pkt->data.frame.flags is 0x0.
1874 EXPECT_EQ(pkt->data.frame.flags & AOM_FRAME_IS_KEY, 0u);
1875 pkt = aom_codec_get_cx_data(&enc, &iter);
1876 EXPECT_EQ(pkt, nullptr);
1877
1878 // Flush encoder
1879 EXPECT_EQ(AOM_CODEC_OK, aom_codec_encode(&enc, nullptr, 0, 1, 0));
1880 iter = nullptr;
1881 pkt = aom_codec_get_cx_data(&enc, &iter);
1882 EXPECT_EQ(pkt, nullptr);
1883
1884 EXPECT_EQ(AOM_CODEC_OK, aom_codec_destroy(&enc));
1885 }
1886
1887 // A test that reproduces b/259173819: signed integer overflow in
1888 // linsolve_wiener().
1889 TEST(SearchWienerTest, 10bitSignedIntegerOverflowInLinsolveWiener) {
1890 constexpr int kWidth = 3;
1891 constexpr int kHeight = 3;
1892 static const uint16_t buffer[3 * kWidth * kHeight] = {
1893 // Y plane:
1894 81, 81, 1023, 1020, 81, 1023, 81, 128, 0,
1895 // U plane:
1896 273, 273, 273, 273, 273, 273, 273, 273, 273,
1897 // V plane:
1898 273, 273, 273, 273, 273, 273, 516, 81, 81
1899 };
1900 unsigned char *img_data =
1901 reinterpret_cast<unsigned char *>(const_cast<uint16_t *>(buffer));
1902
1903 aom_image_t img;
1904 EXPECT_EQ(
1905 aom_img_wrap(&img, AOM_IMG_FMT_I44416, kWidth, kHeight, 1, img_data),
1906 &img);
1907 img.cp = AOM_CICP_CP_UNSPECIFIED;
1908 img.tc = AOM_CICP_TC_UNSPECIFIED;
1909 img.mc = AOM_CICP_MC_UNSPECIFIED;
1910 img.range = AOM_CR_FULL_RANGE;
1911
1912 aom_codec_iface_t *iface = aom_codec_av1_cx();
1913 aom_codec_enc_cfg_t cfg;
1914 EXPECT_EQ(aom_codec_enc_config_default(iface, &cfg, AOM_USAGE_ALL_INTRA),
1915 AOM_CODEC_OK);
1916 cfg.rc_end_usage = AOM_Q;
1917 cfg.g_profile = 1;
1918 cfg.g_bit_depth = AOM_BITS_10;
1919 cfg.g_input_bit_depth = 10;
1920 cfg.g_w = kWidth;
1921 cfg.g_h = kHeight;
1922 cfg.g_limit = 1;
1923 cfg.g_lag_in_frames = 0;
1924 cfg.kf_mode = AOM_KF_DISABLED;
1925 cfg.kf_max_dist = 0;
1926 cfg.g_threads = 21;
1927 cfg.rc_min_quantizer = 16;
1928 cfg.rc_max_quantizer = 54;
1929 aom_codec_ctx_t enc;
1930 EXPECT_EQ(aom_codec_enc_init(&enc, iface, &cfg, AOM_CODEC_USE_HIGHBITDEPTH),
1931 AOM_CODEC_OK);
1932 EXPECT_EQ(aom_codec_control(&enc, AOME_SET_CQ_LEVEL, 35), AOM_CODEC_OK);
1933 EXPECT_EQ(aom_codec_control(&enc, AV1E_SET_ROW_MT, 1), AOM_CODEC_OK);
1934 EXPECT_EQ(aom_codec_control(&enc, AV1E_SET_TILE_ROWS, 2), AOM_CODEC_OK);
1935 EXPECT_EQ(aom_codec_control(&enc, AV1E_SET_TILE_COLUMNS, 5), AOM_CODEC_OK);
1936 EXPECT_EQ(aom_codec_control(&enc, AOME_SET_CPUUSED, 1), AOM_CODEC_OK);
1937 EXPECT_EQ(aom_codec_control(&enc, AV1E_SET_COLOR_RANGE, AOM_CR_FULL_RANGE),
1938 AOM_CODEC_OK);
1939 EXPECT_EQ(aom_codec_control(&enc, AV1E_SET_SKIP_POSTPROC_FILTERING, 1),
1940 AOM_CODEC_OK);
1941 EXPECT_EQ(aom_codec_control(&enc, AOME_SET_TUNING, AOM_TUNE_SSIM),
1942 AOM_CODEC_OK);
1943
1944 // Encode frame
1945 EXPECT_EQ(aom_codec_encode(&enc, &img, 0, 1, 0), AOM_CODEC_OK);
1946 aom_codec_iter_t iter = nullptr;
1947 const aom_codec_cx_pkt_t *pkt = aom_codec_get_cx_data(&enc, &iter);
1948 ASSERT_NE(pkt, nullptr);
1949 EXPECT_EQ(pkt->kind, AOM_CODEC_CX_FRAME_PKT);
1950 // pkt->data.frame.flags is 0x1f0011.
1951 EXPECT_EQ(pkt->data.frame.flags & AOM_FRAME_IS_KEY, AOM_FRAME_IS_KEY);
1952 pkt = aom_codec_get_cx_data(&enc, &iter);
1953 EXPECT_EQ(pkt, nullptr);
1954
1955 // Flush encoder
1956 EXPECT_EQ(aom_codec_encode(&enc, nullptr, 0, 1, 0), AOM_CODEC_OK);
1957 iter = nullptr;
1958 pkt = aom_codec_get_cx_data(&enc, &iter);
1959 EXPECT_EQ(pkt, nullptr);
1960
1961 EXPECT_EQ(aom_codec_destroy(&enc), AOM_CODEC_OK);
1962 }
1963
1964 // A test that reproduces b/330639949: signed integer overflow in
1965 // linsolve_wiener().
1966 TEST(SearchWienerTest, 12bitSignedIntegerOverflowInLinsolveWiener) {
1967 constexpr int kWidth = 173;
1968 constexpr int kHeight = 3;
1969 // Since the image format is YUV 4:2:0, aom_img_wrap() expects the buffer is
1970 // allocated with width and height aligned to a multiple of 2. Align the
1971 // width to a multiple of 2 so that the stride set by aom_img_wrap() is
1972 // correct. It is not necessary to align the height to a multiple of 2
1973 // because aom_codec_encode() will only read cfg.g_h rows.
1974 static constexpr uint16_t kBuffer[(kWidth + 1) * kHeight] = {
1975 // Y plane:
1976 // Row:
1977 0, 0, 369, 0, 4095, 873, 4095, 4095, 0, 571, 4023, 0, 1028, 58, 556, 0, 0,
1978 1875, 16, 1043, 4095, 0, 1671, 1990, 0, 4095, 2932, 3117, 4095, 0, 0, 0,
1979 4095, 4095, 4095, 4095, 4095, 4095, 508, 4095, 0, 0, 4095, 4095, 4095, 0,
1980 4095, 4095, 0, 197, 4095, 1475, 1127, 4095, 0, 1570, 1881, 4095, 1215, 4095,
1981 0, 0, 1918, 4095, 0, 4095, 3415, 0, 732, 122, 1087, 0, 0, 0, 0, 0, 1012,
1982 4095, 0, 4095, 4095, 0, 0, 4095, 1931, 4095, 0, 4095, 4095, 4095, 4095, 570,
1983 4095, 4095, 0, 2954, 0, 0, 0, 1925, 3802, 0, 4095, 55, 0, 4095, 760, 4095,
1984 0, 3313, 4095, 4095, 4095, 0, 218, 799, 4095, 0, 4095, 2455, 4095, 0, 0,
1985 611, 4095, 3060, 1669, 0, 0, 4095, 3589, 3903, 0, 3427, 1903, 0, 4095, 3789,
1986 4095, 4095, 107, 2064, 4095, 2764, 4095, 0, 0, 0, 3498, 0, 0, 1336, 4095,
1987 4095, 3480, 0, 545, 673, 4095, 0, 4095, 4095, 3175, 4095, 1623, 4095, 0,
1988 540, 4095, 4095, 14, 429, 0, 0,
1989 // Row:
1990 0, 4095, 4095, 0, 1703, 3003, 968, 1313, 4095, 613, 4095, 3918, 112, 4095,
1991 0, 4095, 2211, 88, 4051, 1203, 2005, 4095, 4095, 0, 2106, 0, 4095, 0, 4095,
1992 4095, 4095, 0, 3261, 0, 4095, 0, 1184, 4095, 4095, 818, 4095, 0, 4095, 1292,
1993 4095, 0, 4095, 4095, 0, 4095, 4095, 0, 0, 346, 906, 974, 4095, 4095, 4095,
1994 4095, 0, 4095, 3225, 2547, 4095, 0, 0, 2705, 2933, 4095, 0, 0, 3579, 0,
1995 4095, 4095, 4095, 1872, 4095, 298, 2961, 0, 0, 2805, 0, 0, 1210, 3773, 0,
1996 1208, 3347, 0, 4095, 0, 0, 0, 4034, 4095, 0, 0, 4095, 0, 0, 0, 3302, 0, 0,
1997 0, 0, 0, 4095, 4095, 0, 2609, 4095, 0, 1831, 4095, 0, 2463, 4095, 4095,
1998 4095, 4095, 752, 4095, 4095, 41, 1829, 2975, 227, 2505, 2719, 1059, 4071,
1999 4095, 4095, 3859, 0, 0, 0, 0, 4095, 2423, 4095, 4095, 4095, 4095, 4095,
2000 1466, 0, 0, 4095, 121, 0, 0, 4095, 0, 0, 3328, 4095, 4095, 0, 1172, 0, 2938,
2001 0, 4095, 0, 0, 0, 4095, 1821, 0,
2002 // Row:
2003 4095, 4095, 4095, 4095, 3487, 4095, 0, 0, 0, 3367, 4095, 4095, 1139, 4095,
2004 4095, 169, 1300, 1840, 4095, 3508, 4095, 618, 4095, 4095, 4095, 53, 4095,
2005 4095, 4095, 4095, 4055, 0, 0, 0, 4095, 4095, 0, 0, 0, 0, 1919, 2415, 1485,
2006 458, 4095, 4095, 3176, 4095, 0, 0, 4095, 4095, 617, 3631, 4095, 4095, 0, 0,
2007 3983, 4095, 4095, 681, 1685, 4095, 4095, 0, 1783, 25, 4095, 0, 0, 4095,
2008 4095, 0, 2075, 0, 4095, 4095, 4095, 0, 773, 3407, 0, 4095, 4095, 0, 0, 4095,
2009 4095, 4095, 4095, 4095, 0, 0, 0, 0, 4095, 0, 1804, 0, 0, 3169, 3576, 502, 0,
2010 0, 4095, 0, 4095, 0, 4095, 4095, 4095, 0, 4095, 779, 0, 4095, 0, 0, 0, 4095,
2011 0, 0, 4095, 4095, 4095, 4095, 0, 0, 4095, 4095, 2134, 4095, 4020, 2990,
2012 3949, 4095, 4095, 4095, 4095, 4095, 0, 4095, 4095, 2829, 4095, 4095, 4095,
2013 0, 197, 2328, 3745, 0, 3412, 190, 4095, 4095, 4095, 2809, 3953, 0, 4095,
2014 1502, 2514, 3866, 0, 0, 4095, 4095, 1878, 129, 4095, 0
2015 };
2016 unsigned char *img_data =
2017 reinterpret_cast<unsigned char *>(const_cast<uint16_t *>(kBuffer));
2018
2019 aom_image_t img;
2020 EXPECT_EQ(&img, aom_img_wrap(&img, AOM_IMG_FMT_I42016, kWidth, kHeight, 1,
2021 img_data));
2022 img.cp = AOM_CICP_CP_UNSPECIFIED;
2023 img.tc = AOM_CICP_TC_UNSPECIFIED;
2024 img.mc = AOM_CICP_MC_UNSPECIFIED;
2025 img.monochrome = 1;
2026 img.csp = AOM_CSP_UNKNOWN;
2027 img.range = AOM_CR_FULL_RANGE;
2028 img.planes[1] = img.planes[2] = nullptr;
2029 img.stride[1] = img.stride[2] = 0;
2030
2031 aom_codec_iface_t *iface = aom_codec_av1_cx();
2032 aom_codec_enc_cfg_t cfg;
2033 EXPECT_EQ(AOM_CODEC_OK,
2034 aom_codec_enc_config_default(iface, &cfg, AOM_USAGE_GOOD_QUALITY));
2035 cfg.rc_end_usage = AOM_Q;
2036 cfg.g_profile = 2;
2037 cfg.g_bit_depth = AOM_BITS_12;
2038 cfg.g_input_bit_depth = 12;
2039 cfg.g_w = kWidth;
2040 cfg.g_h = kHeight;
2041 cfg.g_lag_in_frames = 0;
2042 cfg.g_threads = 18;
2043 cfg.monochrome = 1;
2044 cfg.rc_min_quantizer = 0;
2045 cfg.rc_max_quantizer = 51;
2046 aom_codec_ctx_t enc;
2047 EXPECT_EQ(AOM_CODEC_OK,
2048 aom_codec_enc_init(&enc, iface, &cfg, AOM_CODEC_USE_HIGHBITDEPTH));
2049 EXPECT_EQ(AOM_CODEC_OK, aom_codec_control(&enc, AOME_SET_CQ_LEVEL, 25));
2050 EXPECT_EQ(AOM_CODEC_OK, aom_codec_control(&enc, AV1E_SET_TILE_ROWS, 4));
2051 EXPECT_EQ(AOM_CODEC_OK, aom_codec_control(&enc, AOME_SET_CPUUSED, 6));
2052 EXPECT_EQ(AOM_CODEC_OK,
2053 aom_codec_control(&enc, AV1E_SET_COLOR_RANGE, AOM_CR_FULL_RANGE));
2054 EXPECT_EQ(AOM_CODEC_OK,
2055 aom_codec_control(&enc, AOME_SET_TUNING, AOM_TUNE_SSIM));
2056
2057 // Encode frame
2058 EXPECT_EQ(aom_codec_encode(&enc, &img, 0, 1, 0), AOM_CODEC_OK);
2059 aom_codec_iter_t iter = nullptr;
2060 const aom_codec_cx_pkt_t *pkt = aom_codec_get_cx_data(&enc, &iter);
2061 ASSERT_NE(pkt, nullptr);
2062 EXPECT_EQ(pkt->kind, AOM_CODEC_CX_FRAME_PKT);
2063 // pkt->data.frame.flags is 0x1f0011.
2064 EXPECT_EQ(pkt->data.frame.flags & AOM_FRAME_IS_KEY, AOM_FRAME_IS_KEY);
2065 pkt = aom_codec_get_cx_data(&enc, &iter);
2066 EXPECT_EQ(pkt, nullptr);
2067
2068 // Encode frame
2069 EXPECT_EQ(aom_codec_encode(&enc, &img, 0, 1, 0), AOM_CODEC_OK);
2070 iter = nullptr;
2071 pkt = aom_codec_get_cx_data(&enc, &iter);
2072 ASSERT_NE(pkt, nullptr);
2073 EXPECT_EQ(pkt->kind, AOM_CODEC_CX_FRAME_PKT);
2074 // pkt->data.frame.flags is 0x20000.
2075 EXPECT_EQ(pkt->data.frame.flags & AOM_FRAME_IS_KEY, 0u);
2076 pkt = aom_codec_get_cx_data(&enc, &iter);
2077 EXPECT_EQ(pkt, nullptr);
2078
2079 // Encode frame
2080 EXPECT_EQ(aom_codec_encode(&enc, &img, 0, 1, 0), AOM_CODEC_OK);
2081 iter = nullptr;
2082 pkt = aom_codec_get_cx_data(&enc, &iter);
2083 ASSERT_NE(pkt, nullptr);
2084 EXPECT_EQ(pkt->kind, AOM_CODEC_CX_FRAME_PKT);
2085 // pkt->data.frame.flags is 0x20000.
2086 EXPECT_EQ(pkt->data.frame.flags & AOM_FRAME_IS_KEY, 0u);
2087 pkt = aom_codec_get_cx_data(&enc, &iter);
2088 EXPECT_EQ(pkt, nullptr);
2089
2090 // Encode frame
2091 EXPECT_EQ(aom_codec_encode(&enc, &img, 0, 1, 0), AOM_CODEC_OK);
2092 iter = nullptr;
2093 pkt = aom_codec_get_cx_data(&enc, &iter);
2094 ASSERT_NE(pkt, nullptr);
2095 EXPECT_EQ(pkt->kind, AOM_CODEC_CX_FRAME_PKT);
2096 // pkt->data.frame.flags is 0x20000.
2097 EXPECT_EQ(pkt->data.frame.flags & AOM_FRAME_IS_KEY, 0u);
2098 pkt = aom_codec_get_cx_data(&enc, &iter);
2099 EXPECT_EQ(pkt, nullptr);
2100
2101 // Flush encoder
2102 EXPECT_EQ(AOM_CODEC_OK, aom_codec_encode(&enc, nullptr, 0, 1, 0));
2103 iter = nullptr;
2104 pkt = aom_codec_get_cx_data(&enc, &iter);
2105 EXPECT_EQ(pkt, nullptr);
2106
2107 EXPECT_EQ(AOM_CODEC_OK, aom_codec_destroy(&enc));
2108 }
2109
2110 } // namespace wiener_highbd
2111 #endif // CONFIG_AV1_HIGHBITDEPTH
2112