xref: /aosp_15_r20/external/libaom/test/wiener_test.cc (revision 77c1e3ccc04c968bd2bc212e87364f250e820521)
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