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