xref: /aosp_15_r20/external/libgav1/src/film_grain_test.cc (revision 095378508e87ed692bf8dfeb34008b65b3735891)
1 // Copyright 2021 The libgav1 Authors
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //      http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #include "src/dsp/film_grain.h"
16 
17 #include <algorithm>
18 #include <cassert>
19 #include <cstddef>
20 #include <cstdint>
21 #include <cstdio>
22 #include <cstring>
23 #include <memory>
24 #include <new>
25 #include <string>
26 #include <tuple>
27 #include <type_traits>
28 
29 #include "absl/strings/match.h"
30 #include "absl/strings/str_format.h"
31 #include "absl/time/clock.h"
32 #include "absl/time/time.h"
33 #include "gtest/gtest.h"
34 #include "src/dsp/common.h"
35 #include "src/dsp/dsp.h"
36 #include "src/dsp/film_grain_common.h"
37 #include "src/film_grain.h"
38 #include "src/utils/array_2d.h"
39 #include "src/utils/common.h"
40 #include "src/utils/constants.h"
41 #include "src/utils/cpu.h"
42 #include "src/utils/memory.h"
43 #include "src/utils/threadpool.h"
44 #include "src/utils/types.h"
45 #include "tests/block_utils.h"
46 #include "tests/third_party/libvpx/acm_random.h"
47 #include "tests/utils.h"
48 
49 namespace libgav1 {
50 namespace dsp {
51 namespace film_grain {
52 namespace {
53 
54 constexpr int kNumSpeedTests = 50;
55 constexpr int kNumFilmGrainTestParams = 10;
56 constexpr size_t kLumaBlockSize = kLumaWidth * kLumaHeight;
57 constexpr size_t kChromaBlockSize = kMaxChromaWidth * kMaxChromaHeight;
58 // Dimensions for unit tests concerning applying grain to the whole frame.
59 constexpr size_t kNumTestStripes = 64;
60 constexpr int kNoiseStripeHeight = 34;
61 constexpr size_t kFrameWidth = 1921;
62 constexpr size_t kFrameHeight = (kNumTestStripes - 1) * 32 + 1;
63 
64 /*
65   The film grain parameters for 10 frames were generated with the following
66   command line:
67   aomenc --end-usage=q --cq-level=20 --cpu-used=8 -w 1920 -h 1080 \
68     --denoise-noise-level=50 --ivf breaking_bad_21m23s_10frames.1920_1080.yuv \
69     -o breaking_bad_21m23s_10frames.1920_1080.noise50.ivf
70 */
71 constexpr FilmGrainParams kFilmGrainParams[10] = {
72     {/*apply_grain=*/true,
73      /*update_grain=*/true,
74      /*chroma_scaling_from_luma=*/false,
75      /*overlap_flag=*/true,
76      /*clip_to_restricted_range=*/false,
77      /*num_y_points=*/7,
78      /*num_u_points=*/8,
79      /*num_v_points=*/8,
80      /*point_y_value=*/{0, 13, 27, 40, 54, 121, 255, 0, 0, 0, 0, 0, 0, 0},
81      /*point_y_scaling=*/{71, 71, 91, 99, 98, 100, 100, 0, 0, 0, 0, 0, 0, 0},
82      /*point_u_value=*/{0, 13, 27, 40, 54, 67, 94, 255, 0, 0},
83      /*point_u_scaling=*/{37, 37, 43, 48, 48, 50, 51, 51, 0, 0},
84      /*point_v_value=*/{0, 13, 27, 40, 54, 67, 107, 255, 0, 0},
85      /*point_v_scaling=*/{48, 48, 43, 33, 32, 33, 34, 34, 0, 0},
86      /*chroma_scaling=*/11,
87      /*auto_regression_coeff_lag=*/3,
88      /*auto_regression_coeff_y=*/{2,   -2,  -2,  10,  3, -2, 1,   -4,
89                                   5,   -1,  -25, -13, 3, -1, 0,   7,
90                                   -20, 103, 26,  -2,  1, 14, -49, 117},
91      /*auto_regression_coeff_u=*/{-2,  1,  -3, 4,   -4, 0,  3,   5,  -5,
92                                   -17, 17, 0,  -10, -5, -3, -30, 14, 70,
93                                   29,  9,  -2, -10, 50, 71, -11},
94      /*auto_regression_coeff_v=*/{3,   -2, -7, 6,   -7, -8, 3,   1,  -12,
95                                   -15, 28, 5,  -11, -2, -7, -27, 32, 62,
96                                   31,  18, -2, -6,  61, 43, 2},
97      /*auto_regression_shift=*/8,
98      /*grain_seed=*/7391,
99      /*reference_index=*/0,
100      /*grain_scale_shift=*/0,
101      /*u_multiplier=*/0,
102      /*u_luma_multiplier=*/64,
103      /*u_offset=*/0,
104      /*v_multiplier=*/0,
105      /*v_luma_multiplier=*/64,
106      /*v_offset=*/0},
107     {/*apply_grain=*/true,
108      /*update_grain=*/true,
109      /*chroma_scaling_from_luma=*/false,
110      /*overlap_flag=*/true,
111      /*clip_to_restricted_range=*/false,
112      /*num_y_points=*/8,
113      /*num_u_points=*/7,
114      /*num_v_points=*/8,
115      /*point_y_value=*/{0, 13, 27, 40, 54, 94, 134, 255, 0, 0, 0, 0, 0, 0},
116      /*point_y_scaling=*/{72, 72, 91, 99, 97, 100, 102, 102, 0, 0, 0, 0, 0, 0},
117      /*point_u_value=*/{0, 13, 40, 54, 67, 134, 255, 0, 0, 0},
118      /*point_u_scaling=*/{38, 38, 50, 49, 51, 53, 53, 0, 0, 0},
119      /*point_v_value=*/{0, 13, 27, 40, 54, 67, 121, 255, 0, 0},
120      /*point_v_scaling=*/{50, 50, 45, 34, 33, 35, 37, 37, 0, 0},
121      /*chroma_scaling=*/11,
122      /*auto_regression_coeff_lag=*/3,
123      /*auto_regression_coeff_y=*/{2,   -2,  -2,  10,  3,  -1, 1,   -3,
124                                   3,   1,   -27, -12, 2,  -1, 1,   7,
125                                   -17, 100, 27,  0,   -1, 13, -50, 116},
126      /*auto_regression_coeff_u=*/{-3,  1,  -2, 3,   -3, -1, 2,   5,  -3,
127                                   -16, 16, -2, -10, -2, -1, -31, 14, 70,
128                                   29,  9,  -1, -10, 47, 70, -11},
129      /*auto_regression_coeff_v=*/{1,   0,  -5, 5,   -6, -6, 2,   1,  -10,
130                                   -14, 26, 4,  -10, -3, -5, -26, 29, 63,
131                                   31,  17, -1, -6,  55, 47, 2},
132      /*auto_regression_shift=*/8,
133      /*grain_seed=*/10772,
134      /*reference_index=*/0,
135      /*grain_scale_shift=*/0,
136      /*u_multiplier=*/0,
137      /*u_luma_multiplier=*/64,
138      /*u_offset=*/0,
139      /*v_multiplier=*/0,
140      /*v_luma_multiplier=*/64,
141      /*v_offset=*/0},
142     {/*apply_grain=*/true,
143      /*update_grain=*/true,
144      /*chroma_scaling_from_luma=*/false,
145      /*overlap_flag=*/true,
146      /*clip_to_restricted_range=*/false,
147      /*num_y_points=*/8,
148      /*num_u_points=*/7,
149      /*num_v_points=*/8,
150      /*point_y_value=*/{0, 13, 27, 40, 54, 94, 134, 255, 0, 0, 0, 0, 0, 0},
151      /*point_y_scaling=*/{71, 71, 91, 99, 98, 101, 103, 103, 0, 0, 0, 0, 0, 0},
152      /*point_u_value=*/{0, 13, 40, 54, 81, 107, 255, 0, 0, 0},
153      /*point_u_scaling=*/{37, 37, 49, 48, 51, 52, 52, 0, 0, 0},
154      /*point_v_value=*/{0, 13, 27, 40, 54, 67, 121, 255, 0, 0},
155      /*point_v_scaling=*/{49, 49, 44, 34, 32, 34, 36, 36, 0, 0},
156      /*chroma_scaling=*/11,
157      /*auto_regression_coeff_lag=*/3,
158      /*auto_regression_coeff_y=*/{1,   -2,  -2,  10,  3, -1, 1,   -4,
159                                   4,   1,   -26, -12, 2, -1, 1,   7,
160                                   -18, 101, 26,  -1,  0, 13, -49, 116},
161      /*auto_regression_coeff_u=*/{-3,  1,  -3, 4,   -3, -1, 2,   5,  -4,
162                                   -16, 17, -2, -10, -3, -2, -31, 15, 70,
163                                   28,  9,  -1, -10, 48, 70, -11},
164      /*auto_regression_coeff_v=*/{1,   -1, -6, 5,   -6, -7, 2,   2,  -11,
165                                   -14, 27, 5,  -11, -3, -6, -26, 30, 62,
166                                   30,  18, -2, -6,  58, 45, 2},
167      /*auto_regression_shift=*/8,
168      /*grain_seed=*/14153,
169      /*reference_index=*/0,
170      /*grain_scale_shift=*/0,
171      /*u_multiplier=*/0,
172      /*u_luma_multiplier=*/64,
173      /*u_offset=*/0,
174      /*v_multiplier=*/0,
175      /*v_luma_multiplier=*/64,
176      /*v_offset=*/0},
177     {/*apply_grain=*/true,
178      /*update_grain=*/true,
179      /*chroma_scaling_from_luma=*/false,
180      /*overlap_flag=*/true,
181      /*clip_to_restricted_range=*/false,
182      /*num_y_points=*/7,
183      /*num_u_points=*/5,
184      /*num_v_points=*/7,
185      /*point_y_value=*/{0, 13, 27, 40, 54, 121, 255, 0, 0, 0, 0, 0, 0, 0},
186      /*point_y_scaling=*/{71, 71, 90, 99, 98, 100, 100, 0, 0, 0, 0, 0, 0, 0},
187      /*point_u_value=*/{0, 13, 40, 107, 255, 0, 0, 0, 0, 0},
188      /*point_u_scaling=*/{37, 37, 48, 51, 51, 0, 0, 0, 0, 0},
189      /*point_v_value=*/{0, 13, 27, 40, 54, 94, 255, 0, 0, 0},
190      /*point_v_scaling=*/{49, 49, 43, 33, 32, 34, 34, 0, 0, 0},
191      /*chroma_scaling=*/11,
192      /*auto_regression_coeff_lag=*/3,
193      /*auto_regression_coeff_y=*/{2,   -2,  -2,  10,  3, -1, 1,   -4,
194                                   6,   0,   -26, -13, 3, -1, 1,   6,
195                                   -20, 103, 26,  -2,  1, 13, -48, 117},
196      /*auto_regression_coeff_u=*/{-3,  1,  -2, 4,   -4, -1, 2,   5,  -5,
197                                   -16, 18, -1, -10, -3, -2, -30, 16, 69,
198                                   28,  9,  -2, -10, 50, 68, -11},
199      /*auto_regression_coeff_v=*/{2,   -1, -6, 5,   -6, -7, 2,   2,  -11,
200                                   -15, 29, 4,  -10, -3, -6, -26, 30, 62,
201                                   31,  18, -3, -6,  59, 45, 3},
202      /*auto_regression_shift=*/8,
203      /*grain_seed=*/17534,
204      /*reference_index=*/0,
205      /*grain_scale_shift=*/0,
206      /*u_multiplier=*/0,
207      /*u_luma_multiplier=*/64,
208      /*u_offset=*/0,
209      /*v_multiplier=*/0,
210      /*v_luma_multiplier=*/64,
211      /*v_offset=*/0},
212     {/*apply_grain=*/true,
213      /*update_grain=*/true,
214      /*chroma_scaling_from_luma=*/false,
215      /*overlap_flag=*/true,
216      /*clip_to_restricted_range=*/false,
217      /*num_y_points=*/8,
218      /*num_u_points=*/7,
219      /*num_v_points=*/7,
220      /*point_y_value=*/{0, 13, 27, 40, 54, 94, 134, 255, 0, 0, 0, 0, 0, 0},
221      /*point_y_scaling=*/{71, 71, 91, 99, 98, 101, 103, 103, 0, 0, 0, 0, 0, 0},
222      /*point_u_value=*/{0, 13, 40, 54, 81, 107, 255, 0, 0, 0},
223      /*point_u_scaling=*/{37, 37, 49, 49, 52, 53, 53, 0, 0, 0},
224      /*point_v_value=*/{0, 13, 27, 40, 54, 94, 255, 0, 0, 0},
225      /*point_v_scaling=*/{50, 50, 44, 34, 33, 36, 37, 0, 0, 0},
226      /*chroma_scaling=*/11,
227      /*auto_regression_coeff_lag=*/3,
228      /*auto_regression_coeff_y=*/{2,   -2,  -2,  10,  3, -1, 1,   -4,
229                                   3,   1,   -26, -12, 2, -1, 1,   7,
230                                   -17, 101, 26,  0,   0, 13, -50, 116},
231      /*auto_regression_coeff_u=*/{-2,  1,  -2, 3,   -3, -1, 2,   5,  -4,
232                                   -16, 16, -2, -10, -3, -1, -31, 14, 70,
233                                   28,  9,  -1, -10, 48, 70, -11},
234      /*auto_regression_coeff_v=*/{1,   0,  -5, 5,   -6, -6, 2,   2,  -10,
235                                   -14, 26, 4,  -10, -3, -5, -26, 29, 63,
236                                   30,  17, -1, -6,  56, 47, 3},
237      /*auto_regression_shift=*/8,
238      /*grain_seed=*/20915,
239      /*reference_index=*/0,
240      /*grain_scale_shift=*/0,
241      /*u_multiplier=*/0,
242      /*u_luma_multiplier=*/64,
243      /*u_offset=*/0,
244      /*v_multiplier=*/0,
245      /*v_luma_multiplier=*/64,
246      /*v_offset=*/0},
247     {/*apply_grain=*/true,
248      /*update_grain=*/true,
249      /*chroma_scaling_from_luma=*/false,
250      /*overlap_flag=*/true,
251      /*clip_to_restricted_range=*/false,
252      /*num_y_points=*/7,
253      /*num_u_points=*/7,
254      /*num_v_points=*/7,
255      /*point_y_value=*/{0, 13, 27, 40, 54, 134, 255, 0, 0, 0, 0, 0, 0, 0},
256      /*point_y_scaling=*/{72, 72, 91, 99, 97, 101, 101, 0, 0, 0, 0, 0, 0, 0},
257      /*point_u_value=*/{0, 13, 40, 54, 67, 107, 255, 0, 0, 0},
258      /*point_u_scaling=*/{38, 38, 51, 50, 52, 53, 54, 0, 0, 0},
259      /*point_v_value=*/{0, 13, 27, 40, 54, 94, 255, 0, 0, 0},
260      /*point_v_scaling=*/{51, 51, 45, 35, 33, 36, 36, 0, 0, 0},
261      /*chroma_scaling=*/11,
262      /*auto_regression_coeff_lag=*/3,
263      /*auto_regression_coeff_y=*/{2,   -2,  -2,  9,   3,  -1, 1,   -3,
264                                   2,   2,   -27, -12, 2,  0,  1,   7,
265                                   -16, 100, 27,  0,   -1, 13, -51, 116},
266      /*auto_regression_coeff_u=*/{-3,  1,  -2, 3,   -3, -1, 1,   4,  -2,
267                                   -17, 14, -3, -10, -2, 0,  -31, 14, 71,
268                                   29,  8,  -2, -10, 45, 71, -11},
269      /*auto_regression_coeff_v=*/{0,   -1, -5, 4,   -6, -5, 2,   1,  -9,
270                                   -14, 24, 3,  -10, -3, -4, -25, 29, 63,
271                                   31,  16, -1, -7,  54, 48, 2},
272      /*auto_regression_shift=*/8,
273      /*grain_seed=*/24296,
274      /*reference_index=*/0,
275      /*grain_scale_shift=*/0,
276      /*u_multiplier=*/0,
277      /*u_luma_multiplier=*/64,
278      /*u_offset=*/0,
279      /*v_multiplier=*/0,
280      /*v_luma_multiplier=*/64,
281      /*v_offset=*/0},
282     {/*apply_grain=*/true,
283      /*update_grain=*/true,
284      /*chroma_scaling_from_luma=*/false,
285      /*overlap_flag=*/true,
286      /*clip_to_restricted_range=*/false,
287      /*num_y_points=*/7,
288      /*num_u_points=*/7,
289      /*num_v_points=*/8,
290      /*point_y_value=*/{0, 13, 27, 40, 54, 134, 255, 0, 0, 0, 0, 0, 0, 0},
291      /*point_y_scaling=*/{72, 72, 91, 99, 97, 101, 101, 0, 0, 0, 0, 0, 0, 0},
292      /*point_u_value=*/{0, 13, 40, 54, 67, 134, 255, 0, 0, 0},
293      /*point_u_scaling=*/{38, 38, 50, 50, 51, 53, 53, 0, 0, 0},
294      /*point_v_value=*/{0, 13, 27, 40, 54, 67, 121, 255, 0, 0},
295      /*point_v_scaling=*/{50, 50, 45, 34, 33, 35, 36, 36, 0, 0},
296      /*chroma_scaling=*/11,
297      /*auto_regression_coeff_lag=*/3,
298      /*auto_regression_coeff_y=*/{2,   -2,  -2,  10,  3,  -1, 1,   -3,
299                                   3,   2,   -27, -12, 2,  0,  1,   7,
300                                   -17, 100, 27,  0,   -1, 13, -51, 116},
301      /*auto_regression_coeff_u=*/{-3,  1,  -2, 3,   -3, -1, 1,   5,  -3,
302                                   -16, 15, -2, -10, -2, -1, -31, 14, 70,
303                                   29,  8,  -1, -10, 46, 71, -11},
304      /*auto_regression_coeff_v=*/{1,   0,  -5, 5,   -6, -5, 2,   1,  -9,
305                                   -14, 25, 4,  -10, -3, -5, -25, 29, 63,
306                                   31,  17, -1, -7,  55, 47, 2},
307      /*auto_regression_shift=*/8,
308      /*grain_seed=*/27677,
309      /*reference_index=*/0,
310      /*grain_scale_shift=*/0,
311      /*u_multiplier=*/0,
312      /*u_luma_multiplier=*/64,
313      /*u_offset=*/0,
314      /*v_multiplier=*/0,
315      /*v_luma_multiplier=*/64,
316      /*v_offset=*/0},
317     {/*apply_grain=*/true,
318      /*update_grain=*/true,
319      /*chroma_scaling_from_luma=*/false,
320      /*overlap_flag=*/true,
321      /*clip_to_restricted_range=*/false,
322      /*num_y_points=*/7,
323      /*num_u_points=*/7,
324      /*num_v_points=*/8,
325      /*point_y_value=*/{0, 13, 27, 40, 54, 121, 255, 0, 0, 0, 0, 0, 0, 0},
326      /*point_y_scaling=*/{72, 72, 92, 99, 97, 101, 101, 0, 0, 0, 0, 0, 0, 0},
327      /*point_u_value=*/{0, 13, 40, 54, 67, 174, 255, 0, 0, 0},
328      /*point_u_scaling=*/{38, 38, 51, 50, 52, 54, 54, 0, 0, 0},
329      /*point_v_value=*/{0, 13, 27, 40, 54, 67, 121, 255, 0, 0},
330      /*point_v_scaling=*/{51, 51, 46, 35, 33, 35, 37, 37, 0, 0},
331      /*chroma_scaling=*/11,
332      /*auto_regression_coeff_lag=*/3,
333      /*auto_regression_coeff_y=*/{1,   -1, -2,  9,   3,  -1, 1,   -3,
334                                   2,   2,  -28, -12, 2,  0,  1,   8,
335                                   -16, 99, 27,  0,   -1, 13, -51, 116},
336      /*auto_regression_coeff_u=*/{-3,  1,  -2, 3,   -3, -1, 2,   4,  -2,
337                                   -16, 14, -3, -10, -2, 0,  -31, 13, 71,
338                                   29,  8,  -2, -11, 44, 72, -11},
339      /*auto_regression_coeff_v=*/{0,   -1, -5, 4,   -6, -4, 2,   1,  -9,
340                                   -13, 23, 3,  -10, -3, -4, -25, 28, 63,
341                                   32,  16, -1, -7,  54, 49, 2},
342      /*auto_regression_shift=*/8,
343      /*grain_seed=*/31058,
344      /*reference_index=*/0,
345      /*grain_scale_shift=*/0,
346      /*u_multiplier=*/0,
347      /*u_luma_multiplier=*/64,
348      /*u_offset=*/0,
349      /*v_multiplier=*/0,
350      /*v_luma_multiplier=*/64,
351      /*v_offset=*/0},
352     {/*apply_grain=*/true,
353      /*update_grain=*/true,
354      /*chroma_scaling_from_luma=*/false,
355      /*overlap_flag=*/true,
356      /*clip_to_restricted_range=*/false,
357      /*num_y_points=*/7,
358      /*num_u_points=*/7,
359      /*num_v_points=*/9,
360      /*point_y_value=*/{0, 13, 27, 40, 54, 121, 255, 0, 0, 0, 0, 0, 0, 0},
361      /*point_y_scaling=*/{72, 72, 92, 99, 98, 100, 98, 0, 0, 0, 0, 0, 0, 0},
362      /*point_u_value=*/{0, 13, 40, 54, 67, 228, 255, 0, 0, 0},
363      /*point_u_scaling=*/{38, 38, 51, 51, 52, 54, 54, 0, 0, 0},
364      /*point_v_value=*/{0, 13, 27, 40, 54, 67, 121, 201, 255, 0},
365      /*point_v_scaling=*/{51, 51, 46, 35, 34, 35, 37, 37, 37, 0},
366      /*chroma_scaling=*/11,
367      /*auto_regression_coeff_lag=*/3,
368      /*auto_regression_coeff_y=*/{1,   -1, -2,  9,   3,  -1, 1,   -3,
369                                   2,   2,  -28, -12, 2,  0,  1,   8,
370                                   -16, 99, 27,  0,   -1, 13, -52, 116},
371      /*auto_regression_coeff_u=*/{-3,  1,  -2, 3,   -3, -1, 1,   4,  -2,
372                                   -16, 13, -3, -10, -2, 0,  -31, 13, 71,
373                                   29,  8,  -2, -11, 44, 72, -11},
374      /*auto_regression_coeff_v=*/{0,   -1, -5, 4,   -6, -4, 2,   2,  -8,
375                                   -13, 23, 3,  -10, -3, -4, -25, 28, 63,
376                                   32,  16, -1, -7,  54, 49, 2},
377      /*auto_regression_shift=*/8,
378      /*grain_seed=*/34439,
379      /*reference_index=*/0,
380      /*grain_scale_shift=*/0,
381      /*u_multiplier=*/0,
382      /*u_luma_multiplier=*/64,
383      /*u_offset=*/0,
384      /*v_multiplier=*/0,
385      /*v_luma_multiplier=*/64,
386      /*v_offset=*/0},
387     {/*apply_grain=*/true,
388      /*update_grain=*/true,
389      /*chroma_scaling_from_luma=*/false,
390      /*overlap_flag=*/true,
391      /*clip_to_restricted_range=*/false,
392      /*num_y_points=*/7,
393      /*num_u_points=*/7,
394      /*num_v_points=*/9,
395      /*point_y_value=*/{0, 13, 27, 40, 54, 121, 255, 0, 0, 0, 0, 0, 0, 0},
396      /*point_y_scaling=*/{72, 72, 92, 99, 98, 99, 95, 0, 0, 0, 0, 0, 0, 0},
397      /*point_u_value=*/{0, 13, 40, 54, 67, 228, 255, 0, 0, 0},
398      /*point_u_scaling=*/{39, 39, 51, 51, 52, 54, 54, 0, 0, 0},
399      /*point_v_value=*/{0, 13, 27, 40, 54, 67, 121, 201, 255, 0},
400      /*point_v_scaling=*/{51, 51, 46, 35, 34, 35, 36, 35, 35, 0},
401      /*chroma_scaling=*/11,
402      /*auto_regression_coeff_lag=*/3,
403      /*auto_regression_coeff_y=*/{1,   -1, -2,  9,   3,  -1, 1,   -3,
404                                   2,   2,  -28, -11, 2,  0,  1,   8,
405                                   -16, 99, 27,  0,   -1, 13, -52, 116},
406      /*auto_regression_coeff_u=*/{-3,  1,  -2, 3,   -3, -1, 1,   4,  -2,
407                                   -16, 13, -3, -10, -2, 0,  -30, 13, 71,
408                                   29,  8,  -2, -10, 43, 72, -11},
409      /*auto_regression_coeff_v=*/{0,   -1, -5, 3,   -6, -4, 2,   2,  -8,
410                                   -13, 23, 3,  -10, -3, -4, -25, 28, 64,
411                                   32,  16, -1, -7,  53, 49, 2},
412      /*auto_regression_shift=*/8,
413      /*grain_seed=*/37820,
414      /*reference_index=*/0,
415      /*grain_scale_shift=*/0,
416      /*u_multiplier=*/0,
417      /*u_luma_multiplier=*/64,
418      /*u_offset=*/0,
419      /*v_multiplier=*/0,
420      /*v_luma_multiplier=*/64,
421      /*v_offset=*/0}};
422 
GetTestDigestLuma(int bitdepth,int param_index)423 const char* GetTestDigestLuma(int bitdepth, int param_index) {
424   static const char* const kTestDigestsLuma8bpp[10] = {
425       "80da8e849110a10c0a73f9dec0d9a2fb", "54352f02aeda541e17a4c2d208897e2b",
426       "2ad9021124c82aca3e7c9517d00d1236", "f6c5f64513925b09ceba31e92511f8a1",
427       "46c6006578c68c3c8619f7a389c7de45", "fcddbd27545254dc50f1c333c8b7e313",
428       "c6d4dc181bf7f2f93ae099b836685151", "2949ef836748271195914fef9acf4e46",
429       "524e79bb87ed550e123d00a61df94381", "182222470d7b7a80017521d0261e4474",
430   };
431   static const char* const kTestDigestsLuma10bpp[10] = {
432       "27a49a2131fb6d4dd4b8c34da1b7642e", "4ea9134f6831dd398545c85b2a68e31f",
433       "4e12232a18a2b06e958d7ab6b953faad", "0ede12864ddaced2d8062ffa4225ce24",
434       "5fee492c4a430b2417a64aa4920b69e9", "39af842a3f9370d796e8ef047c0c42a8",
435       "0efbad5f9dc07391ad243232b8df1787", "2bd41882cd82960019aa2b87d5fb1fbc",
436       "1c66629c0c4e7b6f9b0a7a6944fbad50", "2c633a50ead62f8e844a409545f46244",
437   };
438   static const char* const kTestDigestsLuma12bpp[10] = {
439       "1dc9b38a93454a85eb924f25346ae369", "5f9d311ee5384a5a902f8e2d1297319e",
440       "cf1a35878720564c7a741f91eef66565", "47a0608fe0f6f7ccae42a5ca05783cbf",
441       "dbc28da0178e3c18a036c3f2203c300f", "04911d2074e3252119ee2d80426b8c01",
442       "df19ab8103c40b726c842ccf7772208b", "39276967eb16710d98f82068c3eeba41",
443       "b83100f18abb2062d9c9969f07182b86", "b39a69515491329698cf66f6d4fa371f",
444   };
445 
446   switch (bitdepth) {
447     case 8:
448       return kTestDigestsLuma8bpp[param_index];
449     case 10:
450       return kTestDigestsLuma10bpp[param_index];
451     case 12:
452       return kTestDigestsLuma12bpp[param_index];
453     default:
454       assert(bitdepth == 8 || bitdepth == 10 || bitdepth == 12);
455       return nullptr;
456   }
457 }
458 
GetTestDigestChromaU(int bitdepth,int param_index)459 const char* GetTestDigestChromaU(int bitdepth, int param_index) {
460   static const char* const kTestDigestsChromaU8bpp[10] = {
461       "e56b7bbe9f39bf987770b18aeca59514", "d0b3fd3cf2901dae31b73f20c510d83e",
462       "800c01d58d9fb72136d21ec2bb07899a", "4cd0badba679e8edbcd60a931fce49a1",
463       "cabec236cc17f91f3f08d8cde867aa72", "380a2205cf2d40c6a27152585f61a3b0",
464       "3813526234dc7f90f80f6684772c729a", "97a43a73066d88f9cbd915d56fc9c196",
465       "5b70b27a43dd63b03e23aecd3a935071", "d5cc98685582ffd47a41a97d2e377ac8",
466   };
467   static const char* const kTestDigestsChromaU10bpp[10] = {
468       "9a6d0369ba86317598e65913276dae6d", "2512bdc4c88f21f8185b040b7752d1db",
469       "1e86b779ce6555fcf5bd0ade2af67e73", "5ad463a354ffce522c52b616fb122024",
470       "290d53c22c2143b0882acb887da3fdf1", "54622407d865371d7e70bbf29fdda626",
471       "be306c6a94c55dbd9ef514f0ad4a0011", "904602329b0dec352b3b177b0a2554d2",
472       "58afc9497d968c67fdf2c0cf23b33aa3", "74fee7be6f62724bf901fdd04a733b46",
473   };
474   static const char* const kTestDigestsChromaU12bpp[10] = {
475       "846d608050fe7c19d6cabe2d53cb7821", "2caf4665a26aad50f68497e4b1326417",
476       "ce40f0f8f8c207c7c985464c812fea33", "820de51d07a21da5c00833bab546f1fa",
477       "5e7bedd8933cd274af03babb4dbb94dd", "d137cf584eabea86387460a6d3f62bfe",
478       "f206e0c6ed35b3ab35c6ff37e151e963", "55d87981b7044df225b3b5935185449b",
479       "6a655c8bf4df6af0e80ae6d004a73a25", "6234ae36076cc77161af6e6e3c04449a",
480   };
481 
482   switch (bitdepth) {
483     case 8:
484       return kTestDigestsChromaU8bpp[param_index];
485     case 10:
486       return kTestDigestsChromaU10bpp[param_index];
487     case 12:
488       return kTestDigestsChromaU12bpp[param_index];
489     default:
490       assert(bitdepth == 8 || bitdepth == 10 || bitdepth == 12);
491       return nullptr;
492   }
493 }
494 
GetTestDigestChromaV(int bitdepth,int param_index)495 const char* GetTestDigestChromaV(int bitdepth, int param_index) {
496   static const char* const kTestDigestsChromaV8bpp[10] = {
497       "7205ed6c07ed27b7b52d871e0559b8fa", "fad033b1482dba0ed2d450b461fa310e",
498       "6bb39798ec6a0f7bda0b0fcb0a555734", "08c19856e10123ae520ccfc63e2fbe7b",
499       "a7695a6b69fba740a50310dfa6cf1c00", "ac2eac2d13fc5b21c4f2995d5abe14b9",
500       "be35cb30062db628a9e1304fca8b75dc", "f5bfc7a910c76bcd5b32c40772170879",
501       "aca07b37d63f978d76df5cd75d0cea5e", "107c7c56d4ec21f346a1a02206301b0d",
502   };
503   static const char* const kTestDigestsChromaV10bpp[10] = {
504       "910724a77710996c90e272f1c1e9ff8e", "d293f861580770a89f1e266931a012ad",
505       "9e4f0c85fb533e51238586f9c3e68b6e", "a5ff4478d9eeb2168262c2e955e17a4f",
506       "fba6b1e8f28e4e90c836d41f28a0c154", "50b9a93f9a1f3845e6903bff9270a3e6",
507       "7b1624c3543badf5fadaee4d1e602e6b", "3be074e4ca0eec5770748b15661aaadd",
508       "639197401032f272d6c30666a2d08f43", "28075dd34246bf9d5e6197b1944f646a",
509   };
510   static const char* const kTestDigestsChromaV12bpp[10] = {
511       "4957ec919c20707d594fa5c2138c2550", "3f07c65bfb42c81768b1f5ad9611d1ce",
512       "665d9547171c99faba95ac81a35c9a0c", "1b5d032e0cefdb4041ad51796de8a45e",
513       "18fa974579a4f1ff8cd7df664fc339d5", "2ffaa4f143495ff73c06a580a97b6321",
514       "4fd1f562bc47a68dbfaf7c566c7c4da6", "4d37c80c9caf110c1d3d20bd1a1875b3",
515       "8ea29759640962613166dc5154837d14", "5ca4c10f42d0906c72ebee90fae6ce7d",
516   };
517 
518   switch (bitdepth) {
519     case 8:
520       return kTestDigestsChromaV8bpp[param_index];
521     case 10:
522       return kTestDigestsChromaV10bpp[param_index];
523     case 12:
524       return kTestDigestsChromaV12bpp[param_index];
525     default:
526       assert(bitdepth == 8 || bitdepth == 10 || bitdepth == 12);
527       return nullptr;
528   }
529 }
530 
GetARTestDigestLuma(int bitdepth,int coeff_lag,int param_index)531 const char* GetARTestDigestLuma(int bitdepth, int coeff_lag, int param_index) {
532   static const char* const kTestDigestsLuma8bpp[3][kNumFilmGrainTestParams] = {
533       {"a835127918f93478b45f1ba4d20d81bd", "a835127918f93478b45f1ba4d20d81bd",
534        "e5db4da626e214bb17bcc7ecffa76303", "a835127918f93478b45f1ba4d20d81bd",
535        "a835127918f93478b45f1ba4d20d81bd", "e5db4da626e214bb17bcc7ecffa76303",
536        "a835127918f93478b45f1ba4d20d81bd", "1da62b7233de502123a18546b6c97da2",
537        "1da62b7233de502123a18546b6c97da2", "1da62b7233de502123a18546b6c97da2"},
538       {"11464b880de3ecd6e6189c5c4e7f9b28", "dfe411762e283b5f49bece02ec200951",
539        "5c534d92afdf0a5b53dbe4fe7271929c", "2e1a68a18aca96c31320ba7ceab59be9",
540        "584c0323e6b276cb9acb1a294d462d58", "9571eb8f1cbaa96ea3bf64a820a8d9f0",
541        "305285ff0df87aba3c59e3fc0818697d", "0066d35c8818cf20230114dcd3765a4d",
542        "0066d35c8818cf20230114dcd3765a4d", "16d61b046084ef2636eedc5a737cb6f6"},
543       {"0c9e2cf1b6c3cad0f7668026e8ea0516", "7d094855292d0eded9e0d1b5bab1990b",
544        "fbf28860a5f1285dcc6725a45256a86a", "dccb906904160ccabbd2c9a7797a4bf9",
545        "46f645e17f08a3260b1ae70284e5c5b8", "124fdc90bed11a7320a0cbdee8b94400",
546        "8d2978651dddeaef6282191fa146f0a0", "28b4d5aa33f05b3fb7f9323a11936bdc",
547        "6a8ea684f6736a069e3612d1af6391a8", "2781ea40a63704dbfeb3a1ac5db6f2fc"},
548   };
549 
550   static const char* const kTestDigestsLuma10bpp[3][kNumFilmGrainTestParams] = {
551       {"5e6bc8444ece2d38420f51d82238d812", "5e6bc8444ece2d38420f51d82238d812",
552        "2bfaec768794af33d60a9771f971f68d", "5e6bc8444ece2d38420f51d82238d812",
553        "5e6bc8444ece2d38420f51d82238d812", "c880807a368c4e82c23bea6f035ad23f",
554        "5e6bc8444ece2d38420f51d82238d812", "c576667da5286183ec3aab9a76f53a2e",
555        "c576667da5286183ec3aab9a76f53a2e", "c576667da5286183ec3aab9a76f53a2e"},
556       {"095c2dd4d4d52aff9696df9bfdb70062", "983d14afa497060792d472a449a380c7",
557        "c5fdc0f7c594b2b36132cec6f45a79bd", "acff232ac5597c1712213150552281d1",
558        "4dd7341923b1d260092853553b6b6246", "0ca8afd71a4f564ea1ce69c4af14e9ab",
559        "9bc7565e5359d09194fcee28e4bf7b94", "6fea7805458b9d149f238a30e2dc3f13",
560        "6fea7805458b9d149f238a30e2dc3f13", "681dff5fc7a7244ba4e4a582ca7ecb14"},
561       {"cb99352c9c6300e7e825188bb4adaee0", "7e40674de0209bd72f8e9c6e39ee6f7c",
562        "3e475572f6b4ecbb2730fd16751ad7ed", "e6e4c63abc9cb112d9d1f23886cd1415",
563        "1a1c953b175c105c604902877e2bab18", "380a53072530223d4ee622e014ee4bdb",
564        "6137394ea1172fb7ea0cbac237ff1703", "85ab0c813e46f97cb9f42542f44c01ad",
565        "68c8ac462f0e28cb35402c538bee32f1", "0038502ffa4760c8feb6f9abd4de7250"},
566   };
567 
568   static const char* const kTestDigestsLuma12bpp[3][kNumFilmGrainTestParams] = {
569       {"d618bbb0e337969c91b1805f39561520", "d618bbb0e337969c91b1805f39561520",
570        "678f6e911591daf9eca4e305dabdb2b3", "d618bbb0e337969c91b1805f39561520",
571        "d618bbb0e337969c91b1805f39561520", "3b26f49612fd587c7360790d40adb5de",
572        "d618bbb0e337969c91b1805f39561520", "33f77d3ff50cfc64c6bc9a896b567377",
573        "33f77d3ff50cfc64c6bc9a896b567377", "33f77d3ff50cfc64c6bc9a896b567377"},
574       {"362fd67050fb7abaf57c43a92d993423", "e014ae0eb9e697281015c38905cc46ef",
575        "82b867e57151dc08afba31eccf5ccf69", "a94ba736cdce7bfa0b550285f59e47a9",
576        "3f1b0b7dd3b10e322254d35e4e185b7c", "7929708e5f017d58c53513cb79b35fda",
577        "6d26d31a091cbe642a7070933bd7de5a", "dc29ac40a994c0a760bfbad0bfc15b3a",
578        "dc29ac40a994c0a760bfbad0bfc15b3a", "399b919db5190a5311ce8d166580827b"},
579       {"6116d1f569f5b568eca4dc1fbf255086", "7e9cf31ea74e8ea99ffd12094ce6cd05",
580        "bb982c4c39e82a333d744defd16f4388", "7c6e584b082dc6b97ed0d967def3993f",
581        "fb234695353058f03c8e128f2f8de130", "9218c6ca67bf6a9237f98aa1ce7acdfd",
582        "d1fb834bbb388ed066c5cbc1c79b5bdf", "d6f630daedc08216fcea12012e7408b5",
583        "dd7fe49299e6f113a98debc7411c8db8", "8b89e45a5101a28c24209ae119eafeb8"},
584   };
585 
586   switch (bitdepth) {
587     case 8:
588       return kTestDigestsLuma8bpp[coeff_lag - 1][param_index];
589     case 10:
590       return kTestDigestsLuma10bpp[coeff_lag - 1][param_index];
591     case 12:
592       return kTestDigestsLuma12bpp[coeff_lag - 1][param_index];
593     default:
594       assert(bitdepth == 8 || bitdepth == 10 || bitdepth == 12);
595       return nullptr;
596   }
597 }
598 
GetARTestDigestChromaU(int bitdepth,int coeff_lag,int subsampling_x,int subsampling_y)599 const char* GetARTestDigestChromaU(int bitdepth, int coeff_lag,
600                                    int subsampling_x, int subsampling_y) {
601   static const char* const kTestDigestsChromaU8bpp[12] = {
602       "11ced66de0eaf55c1ff9bad18d7b8ed7", "0c3b77345dd4ab0915ef53693ab93ce4",
603       "b0645044ba080b3ceb8f299e269377d6", "50590ad5d895f0b4bc6694d878e9cd32",
604       "85e1bf3741100135062f5b4abfe7639b", "76955b70dde61ca5c7d079c501b90906",
605       "3f0995e1397fd9efd9fc46b67f7796b3", "0a0d6c3e4e1649eb101395bc97943a07",
606       "1878855ed8db600ccae1d39abac52ec6", "13ab2b28320ed3ac2b820f08fdfd424d",
607       "f3e95544a86ead5387e3dc4e043fd0f0", "ff8f5d2d97a6689e16a7e4f482f69f0b",
608   };
609 
610   static const char* const kTestDigestsChromaU10bpp[12] = {
611       "707f2aa5aa7e77bc6e83ab08287d748d", "0bcf40c7fead9ac3a5d71b4cc1e21549",
612       "0c1df27053e5da7cf1276a122a8f4e8b", "782962f7425eb38923a4f87e7ab319d9",
613       "b4a709ae5967afef55530b9ea8ef0062", "70a971a0b9bf06212d510b396f0f9095",
614       "d033b89d6e31f8b13c83d94c840b7d54", "40bbe804bf3f90cee667d3b275e3c964",
615       "90bb2b9d518b945adcfd1b1807f7d170", "4bc34aa157fe5ad4270c611afa75e878",
616       "e2688d7286cd43fe0a3ea734d2ad0f77", "853193c4981bd882912171061327bdf2",
617   };
618 
619   static const char* const kTestDigestsChromaU12bpp[12] = {
620       "04c23b01d01c0e3f3247f3741581b383", "9f8ea1d66e44f6fe93d765ce56b2b0f3",
621       "5dda44b128d6c244963f1e8e17cc1d22", "9dd0a79dd2f772310a95762d445bface",
622       "0dbd40d930e4873d72ea72b9e3d62440", "d7d83c207c6b435a164206d5f457931f",
623       "e8d04f6e63ed63838adff965275a1ff1", "fc09a903e941fcff8bad67a84f705775",
624       "9cd706606a2aa40d0957547756f7abd9", "258b37e7b8f48db77dac7ea24073fe69",
625       "80149b8bb05308da09c1383d8b79d3da", "e993f3bffae53204a1942feb1af42074",
626   };
627 
628   assert(!(subsampling_x == 0 && subsampling_y == 1));
629   const int base_index = 3 * coeff_lag + subsampling_x + subsampling_y;
630   switch (bitdepth) {
631     case 8:
632       return kTestDigestsChromaU8bpp[base_index];
633     case 10:
634       return kTestDigestsChromaU10bpp[base_index];
635     case 12:
636       return kTestDigestsChromaU12bpp[base_index];
637     default:
638       assert(bitdepth == 8 || bitdepth == 10 || bitdepth == 12);
639       return nullptr;
640   }
641 }
642 
GetARTestDigestChromaV(int bitdepth,int coeff_lag,int subsampling_x,int subsampling_y)643 const char* GetARTestDigestChromaV(int bitdepth, int coeff_lag,
644                                    int subsampling_x, int subsampling_y) {
645   static const char* const kTestDigestsChromaV8bpp[12] = {
646       "5c2179f3d93be0a0da75d2bb90347c2f", "79b883847d7eaa7890e1d633b8e34353",
647       "90ade818e55808e8cf58c11debb5ddd1", "1d0f2a14bc4df2b2a1abaf8137029f92",
648       "ac753a57ade140dccb50c14f941ae1fc", "d24ab497558f6896f08dc17bcc3c50c1",
649       "3d74436c63920022a95c85b234db4e33", "061c2d53ed84c830f454e395c362cb16",
650       "05d24869d7fb952e332457a114c8b9b7", "fcee31b87a2ada8028c2a975e094856a",
651       "c019e2c475737abcf9c2b2a52845c646", "9cd994baa7021f8bdf1d1c468c1c8e9c",
652   };
653 
654   static const char* const kTestDigestsChromaV10bpp[12] = {
655       "bc9e44454a05cac8571c15af5b720e79", "f0374436698d94e879c03331b1f30df4",
656       "4580dd009abd6eeed59485057c55f63e", "7d1f7aecd45302bb461f4467f2770f72",
657       "1f0d003fce6c5fedc147c6112813f43b", "4771a45c2c1a04c375400619d5536035",
658       "df9cf619a78907c0f6e58bc13d7d5546", "dd3715ce65d905f30070a36977c818e0",
659       "32de5800f76e34c128a1d89146b4010b", "db9d7c70c3f69feb68fae04398efc773",
660       "d3d0912e3fdb956fef416a010bd7b4c2", "a2fca8abd9fd38d2eef3c4495d9eff78",
661   };
662 
663   static const char* const kTestDigestsChromaV12bpp[12] = {
664       "0d1890335f4464167de22353678ca9c6", "9e6830aba73139407196f1c811f910bc",
665       "6018f2fb76bd648bef0262471cfeba5c", "78e1ae1b790d709cdb8997621cf0fde3",
666       "5b44ae281d7f9db2f17aa3c24b4741dd", "f931d16991669cb16721de87da9b8067",
667       "5580f2aed349d9cabdafb9fc25a57b1c", "86918cd78bf95e6d4405dd050f5890b8",
668       "13c8b314eeebe35fa60b703d94e1b2c1", "13c6fb75cab3f42e0d4ca31e4d068b0e",
669       "bb9ca0bd6f8cd67e44c8ac2803abf5a5", "0da4ea711ffe557bb66577392b6f148b",
670   };
671 
672   assert(!(subsampling_x == 0 && subsampling_y == 1));
673   const int base_index = 3 * coeff_lag + subsampling_x + subsampling_y;
674   switch (bitdepth) {
675     case 8:
676       return kTestDigestsChromaV8bpp[base_index];
677     case 10:
678       return kTestDigestsChromaV10bpp[base_index];
679     case 12:
680       return kTestDigestsChromaV12bpp[base_index];
681     default:
682       assert(bitdepth == 8 || bitdepth == 10 || bitdepth == 12);
683       return nullptr;
684   }
685 }
686 
GetGrainGenerationTestDigestLuma(int bitdepth,int param_index)687 const char* GetGrainGenerationTestDigestLuma(int bitdepth, int param_index) {
688   static const char* const kTestDigestsLuma8bpp[kNumFilmGrainTestParams] = {
689       "c48babd99e5cfcbaa13d8b6e0c12e644", "da4b971d2de19b709e2bc98d2e50caf3",
690       "96c72faac19a79c138afeea8b8ae8c7a", "90a2b9c8304a44d14e83ca51bfd2fe8a",
691       "72bd3aa85c17850acb430afb4183bf1a", "a0acf76349b9efbc9181fc31153d9ef6",
692       "6da74dd631a4ec8b9372c0bbec22e246", "6e11fa230f0e5fbb13084255c22cabf9",
693       "be1d257b762f9880d81680e9325932a2", "37e302075af8130b371de4430e8a22cf",
694   };
695 
696   static const char* const kTestDigestsLuma10bpp[kNumFilmGrainTestParams] = {
697       "0a40fd2f261095a6154584a531328142", "9d0c8173a94a0514c769e94b6f254030",
698       "7894e959fdd5545895412e1512c9352d", "6802cad2748cf6db7f66f53807ee46ab",
699       "ea24e962b98351c3d929a8ae41e320e2", "b333dc944274a3a094073889ca6e11d6",
700       "7211d7ac0ff7d11b5ef1538c0d98f43d", "ef9f9cbc101a07da7bfa62637130e331",
701       "85a122e32648fde84b883a1f98947c60", "dee656e3791138285bc5b71e3491a177",
702   };
703 
704   static const char* const kTestDigestsLuma12bpp[kNumFilmGrainTestParams] = {
705       "ae359794b5340d073d597117046886ac", "4d4ad3908b4fb0f248a0086537dd6b1e",
706       "672a97e15180cbeeaf76d763992c9f23", "739124d10d16e00a158e833ea92107bc",
707       "4c38c738ff7ffc50adaa4474584d3aae", "ca05ba7e51000a7d10e5cbb2101bbd86",
708       "e207022b916bf03a76ac8742af29853d", "7454bf1859149237ff74f1161156c857",
709       "10fc2a16e663bbc305255b0883cfcd45", "4228abff6899bb33839b579288ab29fe",
710   };
711 
712   switch (bitdepth) {
713     case 8:
714       return kTestDigestsLuma8bpp[param_index];
715     case 10:
716       return kTestDigestsLuma10bpp[param_index];
717     case 12:
718       return kTestDigestsLuma12bpp[param_index];
719     default:
720       assert(bitdepth == 8 || bitdepth == 10 || bitdepth == 12);
721       return nullptr;
722   }
723 }
724 
GetConstructStripesTestDigest(int bitdepth,int overlap_flag,int subsampling_x,int subsampling_y)725 const char* GetConstructStripesTestDigest(int bitdepth, int overlap_flag,
726                                           int subsampling_x,
727                                           int subsampling_y) {
728   static const char* const kTestDigests8bpp[6] = {
729       "cd14aaa6fc1728290fa75772730a2155", "13ad4551feadccc3a3a9bd5e25878d2a",
730       "ed6ad9532c96ef0d79ff3228c89a429f", "82f307a7f5fc3308c3ebe268b5169e70",
731       "aed793d525b85349a8c2eb6d40e93969", "311c3deb727621a7d4f18e8defb65de7",
732   };
733 
734   static const char* const kTestDigests10bpp[6] = {
735       "4fe2fa1e428737de3595be3a097d0203", "80568c3c3b53bdbbd03b820179092dcd",
736       "bc7b73099961a0739c36e027d6d09ea1", "e5331364e5146a6327fd94e1467f59a3",
737       "125bf18b7787e8f0792ea12f9210de0d", "21cf98cbce17eca77dc150cc9be0e0a0",
738   };
739 
740   static const char* const kTestDigests12bpp[6] = {
741       "57f8e17078b6e8935252e918a2562636", "556a7b294a99bf1163b7166b4f68357e",
742       "249bee5572cd7d1cc07182c97adc4ba7", "9bf43ae1998c2a5b2e5f4d8236b58747",
743       "477c08fa26499936e5bb03bde097633e", "fe64b7166ff87ea0711ae4f519cadd59",
744   };
745 
746   const int base_index = 3 * overlap_flag + subsampling_x + subsampling_y;
747   switch (bitdepth) {
748     case 8:
749       return kTestDigests8bpp[base_index];
750     case 10:
751       return kTestDigests10bpp[base_index];
752     case 12:
753       return kTestDigests12bpp[base_index];
754     default:
755       assert(bitdepth == 8 || bitdepth == 10 || bitdepth == 12);
756       return nullptr;
757   }
758 }
759 
GetConstructImageTestDigest(int bitdepth,int overlap_flag,int subsampling_x,int subsampling_y)760 const char* GetConstructImageTestDigest(int bitdepth, int overlap_flag,
761                                         int subsampling_x, int subsampling_y) {
762   static const char* const kTestDigests8bpp[6] = {
763       "17030fc692e685557a3717f9334af7e8", "d16ea46147183cd7bc36bcfc2f936a5b",
764       "68152958540dbec885f71e3bcd7aa088", "bb43b420f05a122eb4780aca06055ab1",
765       "87567b04fbdf64f391258c0742de266b", "ce87d556048b3de32570faf6729f4010",
766   };
767 
768   static const char* const kTestDigests10bpp[6] = {
769       "5b31b29a5e22126a9bf8cd6a01645777", "2bb94a25164117f2ab18dae18e2c6577",
770       "27e57a4ed6f0c9fe0a763a03f44805e8", "481642ab0b07437b76b169aa4eb82123",
771       "656a9ef056b04565bec9ca7e0873c408", "a70fff81ab28d02d99dd4f142699ba39",
772   };
773 
774   static const char* const kTestDigests12bpp[6] = {
775       "146f7ceadaf77e7a3c41e191a58c1d3c", "de18526db39630936733e687cdca189e",
776       "165c96ff63bf3136505ab1d239f7ceae", "a102636662547f84e5f6fb6c3e4ef959",
777       "4cb073fcc783c158a95c0b1ce0d27e9f", "3a734c71d4325a7da53e2a6e00f81647",
778   };
779 
780   const int base_index = 3 * overlap_flag + subsampling_x + subsampling_y;
781   switch (bitdepth) {
782     case 8:
783       return kTestDigests8bpp[base_index];
784     case 10:
785       return kTestDigests10bpp[base_index];
786     case 12:
787       return kTestDigests12bpp[base_index];
788     default:
789       assert(bitdepth == 8 || bitdepth == 10 || bitdepth == 12);
790       return nullptr;
791   }
792 }
793 
GetScalingInitTestDigest(int param_index,int bitdepth)794 const char* GetScalingInitTestDigest(int param_index, int bitdepth) {
795   static const char* const kTestDigests8bpp[kNumFilmGrainTestParams] = {
796       "315202ca3bf9c46eac8605e89baffd2a", "640f6408702b07ab7e832e7326cce56f",
797       "f75ee83e3912a3f25949e852d67326cf", "211223f5d6a4b42a8e3c662f921b71c0",
798       "f75ee83e3912a3f25949e852d67326cf", "e7a1de8c5a2cac2145c586ecf1f9051c",
799       "e7a1de8c5a2cac2145c586ecf1f9051c", "276fe5e3b30b2db2a9ff798eb6cb8e00",
800       "ac67f1c3aff2f50ed4b1975bde67ffe3", "8db6145a60d506cc94f07cef8b27c681",
801   };
802 
803   static const char* const kTestDigests10bpp[kNumFilmGrainTestParams] = {
804       "c50be59c62b634ff45ddfbe5b978adfc", "7626286109a2a1eaf0a26f6b2bbab9aa",
805       "f2302988140c47a0724fc55ff523b6ec", "5318e33d8a59a526347ffa6a72ba6ebd",
806       "f2302988140c47a0724fc55ff523b6ec", "f435b5fe98e9d8b6c61fa6f457601c2c",
807       "f435b5fe98e9d8b6c61fa6f457601c2c", "ff07a2944dbe094d01e199098764941c",
808       "11b3e256c74cee2b5679f7457793869a", "89fab5c1db09e242d0494d1c696a774a",
809   };
810 
811   static const char* const kTestDigests12bpp[kNumFilmGrainTestParams] = {
812       "1554df49a863a851d146213e09d311a4", "84808c3ed3b5495a62c9d2dd9a08cb26",
813       "bb31f083a3bd9ef26587478b8752f280", "34fdfe61d6871e4882e38062a0725c5c",
814       "bb31f083a3bd9ef26587478b8752f280", "e7b8c3e4508ceabe89b78f10a9e160b8",
815       "e7b8c3e4508ceabe89b78f10a9e160b8", "a0ccc9e3d0f0c9d1f08f1249264d92f5",
816       "7992a96883c8a9a35d6ca8961bc4515b", "de906ce2c0fceed6f168215447b21b16",
817   };
818 
819   switch (bitdepth) {
820     case 8:
821       return kTestDigests8bpp[param_index];
822     case 10:
823       return kTestDigests10bpp[param_index];
824     case 12:
825       return kTestDigests12bpp[param_index];
826     default:
827       assert(bitdepth == 8 || bitdepth == 10 || bitdepth == 12);
828       return nullptr;
829   }
830 }
831 
GetBlendLumaTestDigest(int bitdepth)832 const char* GetBlendLumaTestDigest(int bitdepth) {
833   static const char* const kTestDigests[] = {
834       "de35b16c702690b1d311cdd0973835d7",
835       "60e9f24dcaaa0207a8db5ab5f3c66608",
836       "8e7d44b620bb7768459074be6bfbca7b",
837   };
838 
839   assert(bitdepth == 8 || bitdepth == 10 || bitdepth == 12);
840   return kTestDigests[(bitdepth - 8) / 2];
841 }
842 
GetBlendChromaUTestDigest(int bitdepth,int chroma_scaling_from_luma,int subsampling_x,int subsampling_y)843 const char* GetBlendChromaUTestDigest(int bitdepth,
844                                       int chroma_scaling_from_luma,
845                                       int subsampling_x, int subsampling_y) {
846   static const char* const kTestDigests8bpp[6] = {
847       "36ca194734d45e75079baba1f3ec9e9e", "182b388061f59fd3e24ef4581c536e67",
848       "2e7843b4c624f03316c3cbe1cc835859", "39e6d9606915da6a41168fbb006b55e4",
849       "3f44a4e252d4823544ac66a900dc7983", "1860f0831841f262d66b23f6a6b5833b",
850   };
851 
852   static const char* const kTestDigests10bpp[6] = {
853       "2054665564f55750c9588b505eb01ac0", "4d8b0e248f8a6bfc72516aa164e76b0b",
854       "7e549800a4f9fff6833bb7738e272baf", "8de6f30dcda99a37b359fd815e62d2f7",
855       "9b7958a2278a16bce2b7bc31fdd811f5", "c5c3c8cccf6a2b4e40b4a412a5bf4f08",
856   };
857 
858   static const char* const kTestDigests12bpp[6] = {
859       "8fad0cc641da35e0d2d8f178c7ce8394", "793eb9d2e6b4ea2e3bb08e7068236155",
860       "9156bd85ab9493d8867a174f920bb1e6", "6834319b4c88e3e0c96b6f8d7efd08dd",
861       "c40e492790d3803a734efbc6feca46e2", "d884c3b1e2c21d98844ca7639e0599a5",
862   };
863 
864   const int base_index =
865       3 * chroma_scaling_from_luma + subsampling_x + subsampling_y;
866   switch (bitdepth) {
867     case 8:
868       return kTestDigests8bpp[base_index];
869     case 10:
870       return kTestDigests10bpp[base_index];
871     case 12:
872       return kTestDigests12bpp[base_index];
873     default:
874       assert(bitdepth == 8 || bitdepth == 10 || bitdepth == 12);
875       return nullptr;
876   }
877 }
878 
GetBlendChromaVTestDigest(int bitdepth,int chroma_scaling_from_luma,int subsampling_x,int subsampling_y)879 const char* GetBlendChromaVTestDigest(int bitdepth,
880                                       int chroma_scaling_from_luma,
881                                       int subsampling_x, int subsampling_y) {
882   static const char* const kTestDigests8bpp[6] = {
883       "9a353e4f86d7ebaa980f7f6cfc0995ad", "17589b4039ed49ba16f32db9fae724b7",
884       "76ae8bed48a173b548993b6e1824ff67", "c1458ac9bdfbf0b4d6a175343b17b27b",
885       "fa76d1c8e48957537f26af6a5b54ec14", "313fe3c34568b7f9c5ecb09d419d4ba4",
886   };
887 
888   static const char* const kTestDigests10bpp[6] = {
889       "8ab5a8e03f07547260033d6a0b689e3c", "275ede58d311e2f5fd76f222f45a64fc",
890       "ce13916e0f7b02087fd0356534d32770", "165bfc8cda0266936a67fa4ec9b215cb",
891       "ed4382caa936acf1158ff8049d18ffac", "942bdd1344c9182dd7572099fb9372db",
892   };
893 
894   static const char* const kTestDigests12bpp[6] = {
895       "70704a1e171a3a70d40b7d0037a75fbc", "62549e2afbf36a1ed405a6574d39c542",
896       "e93889927ab77c6e0767ff071d980c02", "a0c1f6ed78874137710fee7418d80959",
897       "f6283e36a25cb867e30bdf0bfdb2124b", "741c2d48898835b9d9e3bd0b6ac6269a",
898   };
899 
900   const int base_index =
901       3 * chroma_scaling_from_luma + subsampling_x + subsampling_y;
902   switch (bitdepth) {
903     case 8:
904       return kTestDigests8bpp[base_index];
905     case 10:
906       return kTestDigests10bpp[base_index];
907     case 12:
908       return kTestDigests12bpp[base_index];
909     default:
910       assert(bitdepth == 8 || bitdepth == 10 || bitdepth == 12);
911       return nullptr;
912   }
913 }
914 
915 // GetFilmGrainRandomNumber() is only invoked with |bits| equal to 11 or 8. Test
916 // both values of |bits|.
TEST(FilmGrainTest,GetFilmGrainRandomNumber)917 TEST(FilmGrainTest, GetFilmGrainRandomNumber) {
918   uint16_t seed = 51968;
919   const struct {
920     int rand;
921     uint16_t seed;
922   } kExpected11[5] = {
923       {812, 25984}, {406, 12992}, {1227, 39264}, {1637, 52400}, {818, 26200},
924   };
925   for (int i = 0; i < 5; ++i) {
926     int rand = GetFilmGrainRandomNumber(11, &seed);
927     EXPECT_EQ(rand, kExpected11[i].rand) << "i = " << i;
928     EXPECT_EQ(seed, kExpected11[i].seed) << "i = " << i;
929   }
930   const struct {
931     int rand;
932     uint16_t seed;
933   } kExpected8[5] = {
934       {179, 45868}, {89, 22934}, {44, 11467}, {150, 38501}, {75, 19250},
935   };
936   for (int i = 0; i < 5; ++i) {
937     int rand = GetFilmGrainRandomNumber(8, &seed);
938     EXPECT_EQ(rand, kExpected8[i].rand) << "i = " << i;
939     EXPECT_EQ(seed, kExpected8[i].seed) << "i = " << i;
940   }
941 }
942 
943 // In FilmGrainParams, if num_u_points and num_v_points are both 0 and
944 // chroma_scaling_from_luma is false, GenerateChromaGrains() should set both
945 // the u_grain and v_grain arrays to all zeros.
TEST(FilmGrainTest,GenerateZeroChromaGrains)946 TEST(FilmGrainTest, GenerateZeroChromaGrains) {
947   FilmGrainParams film_grain_params = {};
948   film_grain_params.apply_grain = true;
949   film_grain_params.update_grain = true;
950   film_grain_params.chroma_scaling = 8;
951   film_grain_params.auto_regression_shift = 6;
952   film_grain_params.grain_seed = 51968;
953 
954   int8_t u_grain[73 * 82];
955   int8_t v_grain[73 * 82];
956   const int chroma_width = 44;
957   const int chroma_height = 38;
958 
959   // Initialize u_grain and v_grain with arbitrary nonzero values.
960   memset(u_grain, 1, sizeof(u_grain));
961   memset(v_grain, 2, sizeof(v_grain));
962   for (int y = 0; y < chroma_height; ++y) {
963     for (int x = 0; x < chroma_width; ++x) {
964       EXPECT_NE(u_grain[y * chroma_width + x], 0);
965       EXPECT_NE(v_grain[y * chroma_width + x], 0);
966     }
967   }
968 
969   FilmGrain<8>::GenerateChromaGrains(film_grain_params, chroma_width,
970                                      chroma_height, u_grain, v_grain);
971 
972   for (int y = 0; y < chroma_height; ++y) {
973     for (int x = 0; x < chroma_width; ++x) {
974       EXPECT_EQ(u_grain[y * chroma_width + x], 0);
975       EXPECT_EQ(v_grain[y * chroma_width + x], 0);
976     }
977   }
978 }
979 
980 // First parameter is coefficient lag. Second parameter is the index into
981 // |kFilmGrainParams|.
982 template <int bitdepth>
983 class AutoRegressionTestLuma
984     : public testing::TestWithParam<std::tuple<int, int>> {
985  public:
986   static_assert(bitdepth >= kBitdepth8 && bitdepth <= LIBGAV1_MAX_BITDEPTH, "");
987   using GrainType =
988       typename std::conditional<bitdepth == 8, int8_t, int16_t>::type;
989 
AutoRegressionTestLuma()990   AutoRegressionTestLuma() {
991     FilmGrainInit_C();
992     const dsp::Dsp* const dsp = dsp::GetDspTable(bitdepth);
993     const int index = std::get<0>(GetParam()) - 1;
994     base_luma_auto_regression_func_ =
995         dsp->film_grain.luma_auto_regression[index];
996 
997     const testing::TestInfo* const test_info =
998         testing::UnitTest::GetInstance()->current_test_info();
999     const char* const test_case = test_info->test_suite_name();
1000     if (absl::StartsWith(test_case, "C/")) {
1001       base_luma_auto_regression_func_ = nullptr;
1002     } else if (absl::StartsWith(test_case, "NEON/")) {
1003 #if LIBGAV1_ENABLE_NEON
1004       FilmGrainInit_NEON();
1005 #endif
1006     }
1007     luma_auto_regression_func_ = dsp->film_grain.luma_auto_regression[index];
1008   }
1009 
1010  protected:
1011   // |compare| determines whether to compare the output blocks from the SIMD
1012   // implementation, if used, and the C implementation.
1013   // |saturate| determines whether to set the inputs to maximum values. This is
1014   // intended primarily as a way to simplify differences in output when
1015   // debugging.
1016   void TestAutoRegressiveFilterLuma(int coeff_lag, int param_index,
1017                                     int num_runs, bool saturate, bool compare);
1018   LumaAutoRegressionFunc luma_auto_regression_func_;
1019   LumaAutoRegressionFunc base_luma_auto_regression_func_;
1020   GrainType luma_block_buffer_[kLumaBlockSize];
1021   GrainType base_luma_block_buffer_[kLumaBlockSize];
1022 };
1023 
1024 // First parameter is coefficient lag. Second parameter is the index into
1025 // |kFilmGrainParams|.
1026 template <int bitdepth>
TestAutoRegressiveFilterLuma(int coeff_lag,int param_index,int num_runs,bool saturate,bool compare)1027 void AutoRegressionTestLuma<bitdepth>::TestAutoRegressiveFilterLuma(
1028     int coeff_lag, int param_index, int num_runs, bool saturate, bool compare) {
1029   if (luma_auto_regression_func_ == nullptr) return;
1030   // Compare is only needed for NEON tests to compare with C output.
1031   if (base_luma_auto_regression_func_ == nullptr && compare) return;
1032   FilmGrainParams params = kFilmGrainParams[param_index];
1033   params.auto_regression_coeff_lag = coeff_lag;
1034   const int grain_max = GetGrainMax<bitdepth>();
1035   for (int y = 0; y < kLumaHeight; ++y) {
1036     for (int x = 0; x < kLumaWidth; ++x) {
1037       if (saturate) {
1038         luma_block_buffer_[y * kLumaWidth + x] = grain_max;
1039       } else {
1040         luma_block_buffer_[y * kLumaWidth + x] =
1041             std::min(x - (kLumaWidth >> 1), y - (kLumaHeight >> 1)) *
1042             (1 << (bitdepth - 8));
1043       }
1044     }
1045   }
1046 
1047   if (saturate) {
1048     memset(params.auto_regression_coeff_y, 127,
1049            sizeof(params.auto_regression_coeff_y));
1050   }
1051   if (compare) {
1052     memcpy(base_luma_block_buffer_, luma_block_buffer_,
1053            sizeof(luma_block_buffer_));
1054   }
1055 
1056   const absl::Time start = absl::Now();
1057   for (int i = 0; i < num_runs; ++i) {
1058     luma_auto_regression_func_(params, luma_block_buffer_);
1059   }
1060   const absl::Duration elapsed_time = absl::Now() - start;
1061   if (num_runs > 1) {
1062     printf("AutoRegressionLuma lag=%d, param_index=%d: %d us\n", coeff_lag,
1063            param_index,
1064            static_cast<int>(absl::ToInt64Microseconds(elapsed_time)));
1065     return;
1066   }
1067   if (compare) {
1068     base_luma_auto_regression_func_(params, base_luma_block_buffer_);
1069     EXPECT_TRUE(test_utils::CompareBlocks(
1070         luma_block_buffer_, base_luma_block_buffer_, kLumaWidth, kLumaHeight,
1071         kLumaWidth, kLumaWidth, false));
1072   } else {
1073     test_utils::CheckMd5Digest(
1074         "FilmGrain",
1075         absl::StrFormat("AutoRegressionLuma lag=%d, param_index=%d", coeff_lag,
1076                         param_index)
1077             .c_str(),
1078         GetARTestDigestLuma(bitdepth, coeff_lag, param_index),
1079         luma_block_buffer_, sizeof(luma_block_buffer_), elapsed_time);
1080   }
1081 }
1082 
1083 using AutoRegressionTestLuma8bpp = AutoRegressionTestLuma<8>;
1084 
TEST_P(AutoRegressionTestLuma8bpp,AutoRegressiveFilterLuma)1085 TEST_P(AutoRegressionTestLuma8bpp, AutoRegressiveFilterLuma) {
1086   TestAutoRegressiveFilterLuma(std::get<0>(GetParam()), std::get<1>(GetParam()),
1087                                1, /*saturate=*/false,
1088                                /*compare=*/false);
1089 }
1090 
TEST_P(AutoRegressionTestLuma8bpp,AutoRegressiveFilterLumaSaturated)1091 TEST_P(AutoRegressionTestLuma8bpp, AutoRegressiveFilterLumaSaturated) {
1092   TestAutoRegressiveFilterLuma(std::get<0>(GetParam()), std::get<1>(GetParam()),
1093                                1, /*saturate=*/true,
1094                                /*compare=*/true);
1095 }
1096 
TEST_P(AutoRegressionTestLuma8bpp,DISABLED_Speed)1097 TEST_P(AutoRegressionTestLuma8bpp, DISABLED_Speed) {
1098   TestAutoRegressiveFilterLuma(std::get<0>(GetParam()), std::get<1>(GetParam()),
1099                                1e5,
1100                                /*saturate=*/false, /*compare=*/false);
1101 }
1102 
1103 #if LIBGAV1_MAX_BITDEPTH >= 10
1104 using AutoRegressionTestLuma10bpp = AutoRegressionTestLuma<10>;
1105 
TEST_P(AutoRegressionTestLuma10bpp,AutoRegressiveFilterLuma)1106 TEST_P(AutoRegressionTestLuma10bpp, AutoRegressiveFilterLuma) {
1107   TestAutoRegressiveFilterLuma(std::get<0>(GetParam()), std::get<1>(GetParam()),
1108                                1, /*saturate=*/false,
1109                                /*compare=*/false);
1110 }
1111 
TEST_P(AutoRegressionTestLuma10bpp,AutoRegressiveFilterLumaSaturated)1112 TEST_P(AutoRegressionTestLuma10bpp, AutoRegressiveFilterLumaSaturated) {
1113   TestAutoRegressiveFilterLuma(std::get<0>(GetParam()), std::get<1>(GetParam()),
1114                                1, /*saturate=*/true,
1115                                /*compare=*/true);
1116 }
1117 
TEST_P(AutoRegressionTestLuma10bpp,DISABLED_Speed)1118 TEST_P(AutoRegressionTestLuma10bpp, DISABLED_Speed) {
1119   TestAutoRegressiveFilterLuma(std::get<0>(GetParam()), std::get<1>(GetParam()),
1120                                1e5,
1121                                /*saturate=*/false, /*compare=*/false);
1122 }
1123 #endif  // LIBGAV1_MAX_BITDEPTH >= 10
1124 
1125 #if LIBGAV1_MAX_BITDEPTH == 12
1126 using AutoRegressionTestLuma12bpp = AutoRegressionTestLuma<12>;
1127 
TEST_P(AutoRegressionTestLuma12bpp,AutoRegressiveFilterLuma)1128 TEST_P(AutoRegressionTestLuma12bpp, AutoRegressiveFilterLuma) {
1129   TestAutoRegressiveFilterLuma(std::get<0>(GetParam()), std::get<1>(GetParam()),
1130                                1, /*saturate=*/false,
1131                                /*compare=*/false);
1132 }
1133 
TEST_P(AutoRegressionTestLuma12bpp,AutoRegressiveFilterLumaSaturated)1134 TEST_P(AutoRegressionTestLuma12bpp, AutoRegressiveFilterLumaSaturated) {
1135   TestAutoRegressiveFilterLuma(std::get<0>(GetParam()), std::get<1>(GetParam()),
1136                                1, /*saturate=*/true,
1137                                /*compare=*/true);
1138 }
1139 
TEST_P(AutoRegressionTestLuma12bpp,DISABLED_Speed)1140 TEST_P(AutoRegressionTestLuma12bpp, DISABLED_Speed) {
1141   TestAutoRegressiveFilterLuma(std::get<0>(GetParam()), std::get<1>(GetParam()),
1142                                1e5,
1143                                /*saturate=*/false, /*compare=*/false);
1144 }
1145 #endif  // LIBGAV1_MAX_BITDEPTH == 12
1146 
1147 INSTANTIATE_TEST_SUITE_P(
1148     C, AutoRegressionTestLuma8bpp,
1149     testing::Combine(testing::Range(1, 4) /* coeff_lag */,
1150                      testing::Range(0, 10) /* param_index */));
1151 #if LIBGAV1_ENABLE_NEON
1152 INSTANTIATE_TEST_SUITE_P(
1153     NEON, AutoRegressionTestLuma8bpp,
1154     testing::Combine(testing::Range(1, 4) /* coeff_lag */,
1155                      testing::Range(0, 10) /* param_index */));
1156 #endif
1157 
1158 #if LIBGAV1_MAX_BITDEPTH >= 10
1159 INSTANTIATE_TEST_SUITE_P(
1160     C, AutoRegressionTestLuma10bpp,
1161     testing::Combine(testing::Range(1, 4) /* coeff_lag */,
1162                      testing::Range(0, 10) /* param_index */));
1163 #if LIBGAV1_ENABLE_NEON
1164 INSTANTIATE_TEST_SUITE_P(
1165     NEON, AutoRegressionTestLuma10bpp,
1166     testing::Combine(testing::Range(1, 4) /* coeff_lag */,
1167                      testing::Range(0, 10) /* param_index */));
1168 #endif
1169 #endif  // LIBGAV1_MAX_BITDEPTH >= 10
1170 
1171 #if LIBGAV1_MAX_BITDEPTH == 12
1172 INSTANTIATE_TEST_SUITE_P(
1173     C, AutoRegressionTestLuma12bpp,
1174     testing::Combine(testing::Range(1, 4) /* coeff_lag */,
1175                      testing::Range(0, 10) /* param_index */));
1176 #endif  // LIBGAV1_MAX_BITDEPTH == 12
1177 
1178 struct AutoRegressionChromaTestParam {
AutoRegressionChromaTestParamlibgav1::dsp::film_grain::__anoncc33db1e0111::AutoRegressionChromaTestParam1179   explicit AutoRegressionChromaTestParam(const std::tuple<int, int>& in)
1180       : coeff_lag(std::get<0>(in)) {
1181     switch (std::get<1>(in)) {
1182       case 0:
1183         subsampling_x = 0;
1184         subsampling_y = 0;
1185         break;
1186       case 1:
1187         subsampling_x = 1;
1188         subsampling_y = 0;
1189         break;
1190       default:
1191         assert(std::get<1>(in) == 2);
1192         subsampling_x = 1;
1193         subsampling_y = 1;
1194     }
1195   }
1196   const int coeff_lag;
1197   int subsampling_x;
1198   int subsampling_y;
1199 };
1200 
1201 template <int bitdepth>
1202 class AutoRegressionTestChroma
1203     : public testing::TestWithParam<std::tuple<int, int>> {
1204  public:
1205   static_assert(bitdepth >= kBitdepth8 && bitdepth <= LIBGAV1_MAX_BITDEPTH, "");
1206   using GrainType =
1207       typename std::conditional<bitdepth == 8, int8_t, int16_t>::type;
1208 
AutoRegressionTestChroma()1209   AutoRegressionTestChroma() {
1210     AutoRegressionChromaTestParam test_param(GetParam());
1211     FilmGrainInit_C();
1212     const dsp::Dsp* const dsp = dsp::GetDspTable(bitdepth);
1213     // This test suite does not cover num_y_points == 0. This should be covered
1214     // in the test of the full synthesis process.
1215     base_chroma_auto_regression_func_ =
1216         dsp->film_grain.chroma_auto_regression[1][test_param.coeff_lag];
1217 
1218     const testing::TestInfo* const test_info =
1219         testing::UnitTest::GetInstance()->current_test_info();
1220     const char* const test_case = test_info->test_suite_name();
1221     if (absl::StartsWith(test_case, "C/")) {
1222       base_chroma_auto_regression_func_ = nullptr;
1223     } else if (absl::StartsWith(test_case, "NEON/")) {
1224 #if LIBGAV1_ENABLE_NEON
1225       FilmGrainInit_NEON();
1226 #endif
1227     }
1228     chroma_auto_regression_func_ =
1229         dsp->film_grain.chroma_auto_regression[1][test_param.coeff_lag];
1230   }
1231 
1232   ~AutoRegressionTestChroma() override = default;
1233 
1234  protected:
1235   // |compare| determines whether to compare the output blocks from the SIMD
1236   // implementation, if used, and the C implementation.
1237   // |saturate| determines whether to set the inputs to maximum values. This is
1238   // intended primarily as a way to simplify differences in output when
1239   // debugging.
1240   void TestAutoRegressiveFilterChroma(int coeff_lag, int subsampling_x,
1241                                       int subsampling_y, int num_runs,
1242                                       bool saturate, bool compare);
1243   ChromaAutoRegressionFunc chroma_auto_regression_func_;
1244   ChromaAutoRegressionFunc base_chroma_auto_regression_func_;
1245   GrainType luma_block_buffer_[kLumaBlockSize];
1246   GrainType u_block_buffer_[kChromaBlockSize];
1247   GrainType v_block_buffer_[kChromaBlockSize];
1248   GrainType base_u_block_buffer_[kChromaBlockSize];
1249   GrainType base_v_block_buffer_[kChromaBlockSize];
1250 };
1251 
1252 template <int bitdepth>
TestAutoRegressiveFilterChroma(int coeff_lag,int subsampling_x,int subsampling_y,int num_runs,bool saturate,bool compare)1253 void AutoRegressionTestChroma<bitdepth>::TestAutoRegressiveFilterChroma(
1254     int coeff_lag, int subsampling_x, int subsampling_y, int num_runs,
1255     bool saturate, bool compare) {
1256   if (chroma_auto_regression_func_ == nullptr) return;
1257   // Compare is only needed for NEON tests to compare with C output.
1258   if (base_chroma_auto_regression_func_ == nullptr && compare) return;
1259 
1260   // This function relies on the first set of sampled params for basics. The
1261   // test param generators are used for coverage.
1262   FilmGrainParams params = kFilmGrainParams[0];
1263   params.auto_regression_coeff_lag = coeff_lag;
1264   const int grain_max = GetGrainMax<bitdepth>();
1265   const int grain_min = GetGrainMin<bitdepth>();
1266   const int chroma_width =
1267       (subsampling_x != 0) ? kMinChromaWidth : kMaxChromaWidth;
1268   const int chroma_height =
1269       (subsampling_y != 0) ? kMinChromaHeight : kMaxChromaHeight;
1270   if (saturate) {
1271     memset(params.auto_regression_coeff_u, 127,
1272            sizeof(params.auto_regression_coeff_u));
1273     memset(params.auto_regression_coeff_v, 127,
1274            sizeof(params.auto_regression_coeff_v));
1275     for (int y = 0; y < kLumaHeight; ++y) {
1276       for (int x = 0; x < kLumaWidth; ++x) {
1277         // This loop relies on the fact that kMaxChromaWidth == kLumaWidth.
1278         luma_block_buffer_[y * kLumaWidth + x] = grain_max;
1279         u_block_buffer_[y * kLumaWidth + x] = grain_max;
1280         v_block_buffer_[y * kLumaWidth + x] = grain_max;
1281       }
1282     }
1283   } else {
1284     libvpx_test::ACMRandom rnd(libvpx_test::ACMRandom::DeterministicSeed());
1285     // Allow any valid grain values.
1286     const int random_range = grain_max - grain_min + 1;
1287     for (int y = 0; y < kLumaHeight; ++y) {
1288       for (int x = 0; x < kLumaWidth; ++x) {
1289         // This loop relies on the fact that kMaxChromaWidth == kLumaWidth.
1290         const int random_y = rnd(random_range);
1291         luma_block_buffer_[y * kLumaWidth + x] = random_y + grain_min;
1292         const int random_u = rnd(random_range);
1293         u_block_buffer_[y * kLumaWidth + x] = random_u + grain_min;
1294         const int random_v = rnd(random_range);
1295         v_block_buffer_[y * kLumaWidth + x] = random_v + grain_min;
1296       }
1297     }
1298   }
1299   if (compare) {
1300     memcpy(base_u_block_buffer_, u_block_buffer_, sizeof(u_block_buffer_));
1301     memcpy(base_v_block_buffer_, v_block_buffer_, sizeof(v_block_buffer_));
1302   }
1303 
1304   const absl::Time start = absl::Now();
1305   for (int i = 0; i < num_runs; ++i) {
1306     chroma_auto_regression_func_(params, luma_block_buffer_, subsampling_x,
1307                                  subsampling_y, u_block_buffer_,
1308                                  v_block_buffer_);
1309   }
1310   const absl::Duration elapsed_time = absl::Now() - start;
1311   if (num_runs > 1) {
1312     printf("AutoRegressionChroma lag=%d, sub_x=%d, sub_y=%d: %d us\n",
1313            coeff_lag, subsampling_x, subsampling_y,
1314            static_cast<int>(absl::ToInt64Microseconds(elapsed_time)));
1315     return;
1316   }
1317   if (compare) {
1318     base_chroma_auto_regression_func_(params, luma_block_buffer_, subsampling_x,
1319                                       subsampling_y, base_u_block_buffer_,
1320                                       base_v_block_buffer_);
1321     EXPECT_TRUE(test_utils::CompareBlocks(u_block_buffer_, base_u_block_buffer_,
1322                                           chroma_width, chroma_height,
1323                                           chroma_width, chroma_width, false));
1324     EXPECT_TRUE(test_utils::CompareBlocks(v_block_buffer_, base_v_block_buffer_,
1325                                           chroma_width, chroma_height,
1326                                           chroma_width, chroma_width, false));
1327   } else {
1328     test_utils::CheckMd5Digest(
1329         "FilmGrain",
1330         absl::StrFormat("AutoRegressionChromaU lag=%d, sub_x=%d, sub_y=%d",
1331                         coeff_lag, subsampling_x, subsampling_y)
1332             .c_str(),
1333         GetARTestDigestChromaU(bitdepth, coeff_lag, subsampling_x,
1334                                subsampling_y),
1335         u_block_buffer_, sizeof(u_block_buffer_), elapsed_time);
1336     test_utils::CheckMd5Digest(
1337         "FilmGrain",
1338         absl::StrFormat("AutoRegressionChromaV lag=%d, sub_x=%d, sub_y=%d",
1339                         coeff_lag, subsampling_x, subsampling_y)
1340             .c_str(),
1341         GetARTestDigestChromaV(bitdepth, coeff_lag, subsampling_x,
1342                                subsampling_y),
1343         v_block_buffer_, sizeof(v_block_buffer_), elapsed_time);
1344   }
1345 }
1346 
1347 using AutoRegressionTestChroma8bpp = AutoRegressionTestChroma<8>;
1348 
TEST_P(AutoRegressionTestChroma8bpp,AutoRegressiveFilterChroma)1349 TEST_P(AutoRegressionTestChroma8bpp, AutoRegressiveFilterChroma) {
1350   AutoRegressionChromaTestParam test_param(GetParam());
1351   TestAutoRegressiveFilterChroma(test_param.coeff_lag, test_param.subsampling_x,
1352                                  test_param.subsampling_y, 1,
1353                                  /*saturate=*/false,
1354                                  /*compare=*/false);
1355 }
1356 
TEST_P(AutoRegressionTestChroma8bpp,AutoRegressiveFilterChromaSaturated)1357 TEST_P(AutoRegressionTestChroma8bpp, AutoRegressiveFilterChromaSaturated) {
1358   AutoRegressionChromaTestParam test_param(GetParam());
1359   TestAutoRegressiveFilterChroma(test_param.coeff_lag, test_param.subsampling_x,
1360                                  test_param.subsampling_y, 1, /*saturate=*/true,
1361                                  /*compare=*/true);
1362 }
1363 
TEST_P(AutoRegressionTestChroma8bpp,DISABLED_Speed)1364 TEST_P(AutoRegressionTestChroma8bpp, DISABLED_Speed) {
1365   AutoRegressionChromaTestParam test_param(GetParam());
1366   TestAutoRegressiveFilterChroma(
1367       test_param.coeff_lag, test_param.subsampling_x, test_param.subsampling_y,
1368       // Subsampling cuts each dimension of the chroma blocks in half, so run
1369       // twice as many times to compensate.
1370       1e5 * (1 << (test_param.subsampling_y + test_param.subsampling_x)),
1371       /*saturate=*/false, /*compare=*/false);
1372 }
1373 
1374 #if LIBGAV1_MAX_BITDEPTH >= 10
1375 using AutoRegressionTestChroma10bpp = AutoRegressionTestChroma<10>;
1376 
TEST_P(AutoRegressionTestChroma10bpp,AutoRegressiveFilterChroma)1377 TEST_P(AutoRegressionTestChroma10bpp, AutoRegressiveFilterChroma) {
1378   AutoRegressionChromaTestParam test_param(GetParam());
1379   TestAutoRegressiveFilterChroma(test_param.coeff_lag, test_param.subsampling_x,
1380                                  test_param.subsampling_y, 1,
1381                                  /*saturate=*/false,
1382                                  /*compare=*/false);
1383 }
1384 
TEST_P(AutoRegressionTestChroma10bpp,AutoRegressiveFilterChromaSaturated)1385 TEST_P(AutoRegressionTestChroma10bpp, AutoRegressiveFilterChromaSaturated) {
1386   AutoRegressionChromaTestParam test_param(GetParam());
1387   TestAutoRegressiveFilterChroma(test_param.coeff_lag, test_param.subsampling_x,
1388                                  test_param.subsampling_y, 1, /*saturate=*/true,
1389                                  /*compare=*/true);
1390 }
1391 
TEST_P(AutoRegressionTestChroma10bpp,DISABLED_Speed)1392 TEST_P(AutoRegressionTestChroma10bpp, DISABLED_Speed) {
1393   AutoRegressionChromaTestParam test_param(GetParam());
1394   TestAutoRegressiveFilterChroma(
1395       test_param.coeff_lag, test_param.subsampling_x, test_param.subsampling_y,
1396       // Subsampling cuts each dimension of the chroma blocks in half, so run
1397       // twice as many times to compensate.
1398       1e5 * (1 << (test_param.subsampling_y + test_param.subsampling_x)),
1399       /*saturate=*/false, /*compare=*/false);
1400 }
1401 #endif  // LIBGAV1_MAX_BITDEPTH >= 10
1402 
1403 #if LIBGAV1_MAX_BITDEPTH == 12
1404 using AutoRegressionTestChroma12bpp = AutoRegressionTestChroma<12>;
1405 
TEST_P(AutoRegressionTestChroma12bpp,AutoRegressiveFilterChroma)1406 TEST_P(AutoRegressionTestChroma12bpp, AutoRegressiveFilterChroma) {
1407   AutoRegressionChromaTestParam test_param(GetParam());
1408   TestAutoRegressiveFilterChroma(test_param.coeff_lag, test_param.subsampling_x,
1409                                  test_param.subsampling_y, 1,
1410                                  /*saturate=*/false,
1411                                  /*compare=*/false);
1412 }
1413 
TEST_P(AutoRegressionTestChroma12bpp,AutoRegressiveFilterChromaSaturated)1414 TEST_P(AutoRegressionTestChroma12bpp, AutoRegressiveFilterChromaSaturated) {
1415   AutoRegressionChromaTestParam test_param(GetParam());
1416   TestAutoRegressiveFilterChroma(test_param.coeff_lag, test_param.subsampling_x,
1417                                  test_param.subsampling_y, 1, /*saturate=*/true,
1418                                  /*compare=*/true);
1419 }
1420 
TEST_P(AutoRegressionTestChroma12bpp,DISABLED_Speed)1421 TEST_P(AutoRegressionTestChroma12bpp, DISABLED_Speed) {
1422   AutoRegressionChromaTestParam test_param(GetParam());
1423   TestAutoRegressiveFilterChroma(
1424       test_param.coeff_lag, test_param.subsampling_x, test_param.subsampling_y,
1425       // Subsampling cuts each dimension of the chroma blocks in half, so run
1426       // twice as many times to compensate.
1427       1e5 * (1 << (test_param.subsampling_y + test_param.subsampling_x)),
1428       /*saturate=*/false, /*compare=*/false);
1429 }
1430 #endif  // LIBGAV1_MAX_BITDEPTH == 12
1431 
1432 INSTANTIATE_TEST_SUITE_P(C, AutoRegressionTestChroma8bpp,
1433                          testing::Combine(testing::Range(0, 4) /* coeff_lag */,
1434                                           testing::Range(0,
1435                                                          3) /* subsampling */));
1436 
1437 #if LIBGAV1_MAX_BITDEPTH >= 10
1438 INSTANTIATE_TEST_SUITE_P(C, AutoRegressionTestChroma10bpp,
1439                          testing::Combine(testing::Range(0, 4) /* coeff_lag */,
1440                                           testing::Range(0,
1441                                                          3) /* subsampling */));
1442 #endif  // LIBGAV1_MAX_BITDEPTH >= 10
1443 
1444 #if LIBGAV1_MAX_BITDEPTH == 12
1445 INSTANTIATE_TEST_SUITE_P(C, AutoRegressionTestChroma12bpp,
1446                          testing::Combine(testing::Range(0, 4) /* coeff_lag */,
1447                                           testing::Range(0,
1448                                                          3) /* subsampling */));
1449 #endif  // LIBGAV1_MAX_BITDEPTH == 12
1450 
1451 #if LIBGAV1_ENABLE_NEON
1452 INSTANTIATE_TEST_SUITE_P(NEON, AutoRegressionTestChroma8bpp,
1453                          testing::Combine(testing::Range(0, 4) /* coeff_lag */,
1454                                           testing::Range(0,
1455                                                          3) /* subsampling */));
1456 
1457 #if LIBGAV1_MAX_BITDEPTH >= 10
1458 INSTANTIATE_TEST_SUITE_P(NEON, AutoRegressionTestChroma10bpp,
1459                          testing::Combine(testing::Range(0, 4) /* coeff_lag */,
1460                                           testing::Range(0,
1461                                                          3) /* subsampling */));
1462 #endif  // LIBGAV1_MAX_BITDEPTH >= 10
1463 #endif  // LIBGAV1_ENABLE_NEON
1464 
1465 template <int bitdepth>
1466 class GrainGenerationTest : public testing::TestWithParam<int> {
1467  protected:
1468   static_assert(bitdepth >= kBitdepth8 && bitdepth <= LIBGAV1_MAX_BITDEPTH, "");
1469   using GrainType =
1470       typename std::conditional<bitdepth == 8, int8_t, int16_t>::type;
1471 
1472   void TestGenerateGrainLuma(int param_index, int num_runs);
1473 
1474   GrainType luma_block_buffer_[kLumaBlockSize];
1475 };
1476 
1477 template <int bitdepth>
TestGenerateGrainLuma(int param_index,int num_runs)1478 void GrainGenerationTest<bitdepth>::TestGenerateGrainLuma(int param_index,
1479                                                           int num_runs) {
1480   FilmGrainParams params = kFilmGrainParams[param_index];
1481 
1482   const absl::Time start = absl::Now();
1483   for (int i = 0; i < num_runs; ++i) {
1484     FilmGrain<bitdepth>::GenerateLumaGrain(params, luma_block_buffer_);
1485   }
1486   const absl::Duration elapsed_time = absl::Now() - start;
1487   if (num_runs == 1) {
1488     test_utils::CheckMd5Digest(
1489         "FilmGrain",
1490         absl::StrFormat("GenerateGrainLuma param_index=%d", param_index)
1491             .c_str(),
1492         GetGrainGenerationTestDigestLuma(bitdepth, param_index),
1493         luma_block_buffer_, sizeof(luma_block_buffer_), elapsed_time);
1494   } else {
1495     printf("GenerateGrainLuma param_index=%d: %d us\n", param_index,
1496            static_cast<int>(absl::ToInt64Microseconds(elapsed_time)));
1497   }
1498 }
1499 
1500 using GrainGenerationTest8bpp = GrainGenerationTest<8>;
1501 
TEST_P(GrainGenerationTest8bpp,GenerateGrainLuma)1502 TEST_P(GrainGenerationTest8bpp, GenerateGrainLuma) {
1503   TestGenerateGrainLuma(GetParam(), 1);
1504 }
1505 
TEST_P(GrainGenerationTest8bpp,DISABLED_LumaSpeed)1506 TEST_P(GrainGenerationTest8bpp, DISABLED_LumaSpeed) {
1507   TestGenerateGrainLuma(GetParam(), 1e5);
1508 }
1509 
1510 #if LIBGAV1_MAX_BITDEPTH >= 10
1511 using GrainGenerationTest10bpp = GrainGenerationTest<10>;
1512 
TEST_P(GrainGenerationTest10bpp,GenerateGrainLuma)1513 TEST_P(GrainGenerationTest10bpp, GenerateGrainLuma) {
1514   TestGenerateGrainLuma(GetParam(), 1);
1515 }
1516 
TEST_P(GrainGenerationTest10bpp,DISABLED_LumaSpeed)1517 TEST_P(GrainGenerationTest10bpp, DISABLED_LumaSpeed) {
1518   TestGenerateGrainLuma(GetParam(), 1e5);
1519 }
1520 #endif  // LIBGAV1_MAX_BITDEPTH >= 10
1521 
1522 #if LIBGAV1_MAX_BITDEPTH == 12
1523 using GrainGenerationTest12bpp = GrainGenerationTest<12>;
1524 
TEST_P(GrainGenerationTest12bpp,GenerateGrainLuma)1525 TEST_P(GrainGenerationTest12bpp, GenerateGrainLuma) {
1526   TestGenerateGrainLuma(GetParam(), 1);
1527 }
1528 
TEST_P(GrainGenerationTest12bpp,DISABLED_LumaSpeed)1529 TEST_P(GrainGenerationTest12bpp, DISABLED_LumaSpeed) {
1530   TestGenerateGrainLuma(GetParam(), 1e5);
1531 }
1532 #endif  // LIBGAV1_MAX_BITDEPTH == 12
1533 
1534 INSTANTIATE_TEST_SUITE_P(C, GrainGenerationTest8bpp,
1535                          testing::Range(0, 10) /* param_index */);
1536 
1537 #if LIBGAV1_MAX_BITDEPTH >= 10
1538 INSTANTIATE_TEST_SUITE_P(C, GrainGenerationTest10bpp,
1539                          testing::Range(0, 10) /* param_index */);
1540 #endif  // LIBGAV1_MAX_BITDEPTH >= 10
1541 #if LIBGAV1_MAX_BITDEPTH == 12
1542 INSTANTIATE_TEST_SUITE_P(C, GrainGenerationTest12bpp,
1543                          testing::Range(0, 10) /* param_index */);
1544 #endif  // LIBGAV1_MAX_BITDEPTH == 12
1545 
1546 // This param type is used for both ConstructStripesTest and
1547 // ConstructImageTest.
1548 struct ConstructNoiseTestParam {
ConstructNoiseTestParamlibgav1::dsp::film_grain::__anoncc33db1e0111::ConstructNoiseTestParam1549   explicit ConstructNoiseTestParam(const std::tuple<int, int>& in)
1550       : overlap_flag(std::get<0>(in)) {
1551     switch (std::get<1>(in)) {
1552       case 0:
1553         subsampling_x = 0;
1554         subsampling_y = 0;
1555         break;
1556       case 1:
1557         subsampling_x = 1;
1558         subsampling_y = 0;
1559         break;
1560       default:
1561         assert(std::get<1>(in) == 2);
1562         subsampling_x = 1;
1563         subsampling_y = 1;
1564     }
1565   }
1566   const int overlap_flag;
1567   int subsampling_x;
1568   int subsampling_y;
1569 };
1570 
1571 template <int bitdepth>
1572 class ConstructStripesTest
1573     : public testing::TestWithParam<std::tuple<int, int>> {
1574  public:
1575   static_assert(bitdepth >= kBitdepth8 && bitdepth <= LIBGAV1_MAX_BITDEPTH, "");
1576   using GrainType =
1577       typename std::conditional<bitdepth == 8, int8_t, int16_t>::type;
1578 
ConstructStripesTest()1579   ConstructStripesTest() {
1580     FilmGrainInit_C();
1581     const dsp::Dsp* const dsp = dsp::GetDspTable(bitdepth);
1582     base_construct_noise_stripes_func_ =
1583         dsp->film_grain.construct_noise_stripes[std::get<0>(GetParam())];
1584 
1585     const testing::TestInfo* const test_info =
1586         testing::UnitTest::GetInstance()->current_test_info();
1587     const char* const test_case = test_info->test_suite_name();
1588     if (absl::StartsWith(test_case, "C/")) {
1589       base_construct_noise_stripes_func_ = nullptr;
1590     } else if (absl::StartsWith(test_case, "NEON/")) {
1591 #if LIBGAV1_ENABLE_NEON
1592       FilmGrainInit_NEON();
1593 #endif
1594     }
1595     construct_noise_stripes_func_ =
1596         dsp->film_grain.construct_noise_stripes[std::get<0>(GetParam())];
1597   }
1598 
1599   ~ConstructStripesTest() override = default;
1600 
1601  protected:
1602   // |compare| determines whether to compare the output blocks from the SIMD
1603   // implementation, if used, and the C implementation.
1604   // |saturate| determines whether to set the inputs to maximum values. This is
1605   // intended primarily as a way to simplify differences in output when
1606   // debugging.
1607   void TestConstructNoiseStripes(int overlap_flag, int subsampling_x,
1608                                  int subsampling_y, int num_runs, bool saturate,
1609                                  bool compare);
1610   ConstructNoiseStripesFunc construct_noise_stripes_func_;
1611   ConstructNoiseStripesFunc base_construct_noise_stripes_func_;
1612   GrainType grain_buffer_[kLumaBlockSize];
1613   Array2DView<GrainType> noise_stripes_;
1614   // Owns the memory that noise_stripes_ points to.
1615   std::unique_ptr<GrainType[]> stripe_buffer_;
1616   Array2DView<GrainType> base_noise_stripes_;
1617   // Owns the memory that base_stripe_buffer_ points to.
1618   std::unique_ptr<GrainType[]> base_stripe_buffer_;
1619 };
1620 
1621 template <int bitdepth>
TestConstructNoiseStripes(int overlap_flag,int subsampling_x,int subsampling_y,int num_runs,bool saturate,bool compare)1622 void ConstructStripesTest<bitdepth>::TestConstructNoiseStripes(
1623     int overlap_flag, int subsampling_x, int subsampling_y, int num_runs,
1624     bool saturate, bool compare) {
1625   if (construct_noise_stripes_func_ == nullptr) return;
1626   // Compare is only needed for NEON tests to compare with C output.
1627   if (base_construct_noise_stripes_func_ == nullptr && compare) return;
1628 
1629   const int stripe_width = ((kFrameWidth + subsampling_x) >> subsampling_x);
1630   const int stripe_height = kNoiseStripeHeight;
1631   const int stripe_size = stripe_height * stripe_width;
1632   const int stripe_buffer_size = stripe_size * kNumTestStripes;
1633   if (compare) {
1634     base_stripe_buffer_.reset(new (
1635         std::nothrow) GrainType[stripe_buffer_size + kNoiseStripePadding]());
1636     ASSERT_NE(base_stripe_buffer_, nullptr);
1637     base_noise_stripes_.Reset(kNumTestStripes, stripe_size,
1638                               base_stripe_buffer_.get());
1639   }
1640   stripe_buffer_.reset(
1641       new (std::nothrow) GrainType[stripe_buffer_size + kNoiseStripePadding]());
1642   ASSERT_NE(stripe_buffer_, nullptr);
1643   noise_stripes_.Reset(kNumTestStripes, stripe_size, stripe_buffer_.get());
1644 
1645   const int grain_max = GetGrainMax<bitdepth>();
1646   const int grain_min = GetGrainMin<bitdepth>();
1647   if (saturate) {
1648     for (int y = 0; y < kLumaHeight; ++y) {
1649       for (int x = 0; x < kLumaWidth; ++x) {
1650         grain_buffer_[y * kLumaWidth + x] = grain_max;
1651       }
1652     }
1653   } else {
1654     libvpx_test::ACMRandom rnd(libvpx_test::ACMRandom::DeterministicSeed());
1655     // Allow any valid grain values.
1656     const int random_range = grain_max - grain_min + 1;
1657     for (int y = 0; y < kLumaHeight; ++y) {
1658       for (int x = 0; x < kLumaWidth; ++x) {
1659         grain_buffer_[y * kLumaWidth + x] = grain_min + rnd(random_range);
1660       }
1661     }
1662   }
1663 
1664   const absl::Time start = absl::Now();
1665   for (int i = 0; i < num_runs; ++i) {
1666     construct_noise_stripes_func_(grain_buffer_, 68, kFrameWidth, kFrameHeight,
1667                                   subsampling_x, subsampling_y,
1668                                   &noise_stripes_);
1669   }
1670   const absl::Duration elapsed_time = absl::Now() - start;
1671   if (num_runs > 1) {
1672     printf(
1673         "ConstructNoiseStripes Speed Test for overlap=%d, sub_x=%d, "
1674         "sub_y=%d: %d us\n",
1675         overlap_flag, subsampling_x, subsampling_y,
1676         static_cast<int>(absl::ToInt64Microseconds(elapsed_time)));
1677     return;
1678   }
1679   if (compare) {
1680     base_construct_noise_stripes_func_(grain_buffer_, 68, kFrameWidth,
1681                                        kFrameHeight, subsampling_x,
1682                                        subsampling_y, &base_noise_stripes_);
1683 
1684     constexpr int kCompareWidth = 64;
1685     for (int stripe = 0; stripe < kNumTestStripes;) {
1686       EXPECT_TRUE(test_utils::CompareBlocks(
1687           noise_stripes_[stripe], base_noise_stripes_[stripe], kCompareWidth,
1688           stripe_height, stripe_width, stripe_width, /*check_padding=*/false,
1689           /*print_diff=*/false));
1690     }
1691   } else {
1692     test_utils::CheckMd5Digest(
1693         "FilmGrain",
1694         absl::StrFormat("ConstructNoiseStripes overlap=%d, sub_x=%d, sub_y=%d",
1695                         overlap_flag, subsampling_x, subsampling_y)
1696             .c_str(),
1697         GetConstructStripesTestDigest(bitdepth, overlap_flag, subsampling_x,
1698                                       subsampling_y),
1699         noise_stripes_[0], stripe_buffer_size, elapsed_time);
1700   }
1701 }
1702 
1703 using ConstructStripesTest8bpp = ConstructStripesTest<8>;
1704 
TEST_P(ConstructStripesTest8bpp,RandomValues)1705 TEST_P(ConstructStripesTest8bpp, RandomValues) {
1706   ConstructNoiseTestParam test_params(GetParam());
1707   TestConstructNoiseStripes(test_params.overlap_flag, test_params.subsampling_x,
1708                             test_params.subsampling_y, /*num_runs=*/1,
1709                             /*saturate=*/false, /*compare=*/false);
1710 }
1711 
TEST_P(ConstructStripesTest8bpp,SaturatedValues)1712 TEST_P(ConstructStripesTest8bpp, SaturatedValues) {
1713   ConstructNoiseTestParam test_params(GetParam());
1714   TestConstructNoiseStripes(test_params.overlap_flag, test_params.subsampling_x,
1715                             test_params.subsampling_y, /*num_runs=*/1,
1716                             /*saturate=*/true, /*compare=*/true);
1717 }
TEST_P(ConstructStripesTest8bpp,DISABLED_Speed)1718 TEST_P(ConstructStripesTest8bpp, DISABLED_Speed) {
1719   ConstructNoiseTestParam test_params(GetParam());
1720   TestConstructNoiseStripes(test_params.overlap_flag, test_params.subsampling_x,
1721                             test_params.subsampling_y, /*num_runs=*/500,
1722                             /*saturate=*/false, /*compare=*/false);
1723 }
1724 
1725 #if LIBGAV1_MAX_BITDEPTH >= 10
1726 using ConstructStripesTest10bpp = ConstructStripesTest<10>;
1727 
TEST_P(ConstructStripesTest10bpp,RandomValues)1728 TEST_P(ConstructStripesTest10bpp, RandomValues) {
1729   ConstructNoiseTestParam test_params(GetParam());
1730   TestConstructNoiseStripes(test_params.overlap_flag, test_params.subsampling_x,
1731                             test_params.subsampling_y, /*num_runs=*/1,
1732                             /*saturate=*/false, /*compare=*/false);
1733 }
TEST_P(ConstructStripesTest10bpp,SaturatedValues)1734 TEST_P(ConstructStripesTest10bpp, SaturatedValues) {
1735   ConstructNoiseTestParam test_params(GetParam());
1736   TestConstructNoiseStripes(test_params.overlap_flag, test_params.subsampling_x,
1737                             test_params.subsampling_y, /*num_runs=*/1,
1738                             /*saturate=*/true, /*compare=*/true);
1739 }
1740 
TEST_P(ConstructStripesTest10bpp,DISABLED_Speed)1741 TEST_P(ConstructStripesTest10bpp, DISABLED_Speed) {
1742   ConstructNoiseTestParam test_params(GetParam());
1743   TestConstructNoiseStripes(test_params.overlap_flag, test_params.subsampling_x,
1744                             test_params.subsampling_y, /*num_runs=*/500,
1745                             /*saturate=*/false, /*compare=*/false);
1746 }
1747 #endif  // LIBGAV1_MAX_BITDEPTH >= 10
1748 
1749 #if LIBGAV1_MAX_BITDEPTH == 12
1750 using ConstructStripesTest12bpp = ConstructStripesTest<12>;
1751 
TEST_P(ConstructStripesTest12bpp,RandomValues)1752 TEST_P(ConstructStripesTest12bpp, RandomValues) {
1753   ConstructNoiseTestParam test_params(GetParam());
1754   TestConstructNoiseStripes(test_params.overlap_flag, test_params.subsampling_x,
1755                             test_params.subsampling_y, /*num_runs=*/1,
1756                             /*saturate=*/false, /*compare=*/false);
1757 }
TEST_P(ConstructStripesTest12bpp,SaturatedValues)1758 TEST_P(ConstructStripesTest12bpp, SaturatedValues) {
1759   ConstructNoiseTestParam test_params(GetParam());
1760   TestConstructNoiseStripes(test_params.overlap_flag, test_params.subsampling_x,
1761                             test_params.subsampling_y, /*num_runs=*/1,
1762                             /*saturate=*/true, /*compare=*/true);
1763 }
1764 
TEST_P(ConstructStripesTest12bpp,DISABLED_Speed)1765 TEST_P(ConstructStripesTest12bpp, DISABLED_Speed) {
1766   ConstructNoiseTestParam test_params(GetParam());
1767   TestConstructNoiseStripes(test_params.overlap_flag, test_params.subsampling_x,
1768                             test_params.subsampling_y, /*num_runs=*/500,
1769                             /*saturate=*/false, /*compare=*/false);
1770 }
1771 #endif  // LIBGAV1_MAX_BITDEPTH == 12
1772 
1773 INSTANTIATE_TEST_SUITE_P(C, ConstructStripesTest8bpp,
1774                          testing::Combine(testing::Range(0, 2),
1775                                           testing::Range(0, 3)));
1776 
1777 #if LIBGAV1_MAX_BITDEPTH >= 10
1778 INSTANTIATE_TEST_SUITE_P(C, ConstructStripesTest10bpp,
1779                          testing::Combine(testing::Range(0, 2),
1780                                           testing::Range(0, 3)));
1781 #endif  // LIBGAV1_MAX_BITDEPTH >= 10
1782 
1783 #if LIBGAV1_MAX_BITDEPTH == 12
1784 INSTANTIATE_TEST_SUITE_P(C, ConstructStripesTest12bpp,
1785                          testing::Combine(testing::Range(0, 2),
1786                                           testing::Range(0, 3)));
1787 #endif  // LIBGAV1_MAX_BITDEPTH == 12
1788 
1789 template <int bitdepth>
1790 class ConstructImageTest : public testing::TestWithParam<std::tuple<int, int>> {
1791  public:
1792   static_assert(bitdepth >= kBitdepth8 && bitdepth <= LIBGAV1_MAX_BITDEPTH, "");
1793   using GrainType =
1794       typename std::conditional<bitdepth == 8, int8_t, int16_t>::type;
1795 
ConstructImageTest()1796   ConstructImageTest() {
1797     FilmGrainInit_C();
1798     const dsp::Dsp* const dsp = dsp::GetDspTable(bitdepth);
1799     base_construct_noise_image_overlap_func_ =
1800         dsp->film_grain.construct_noise_image_overlap;
1801 
1802     const testing::TestInfo* const test_info =
1803         testing::UnitTest::GetInstance()->current_test_info();
1804     const char* const test_case = test_info->test_suite_name();
1805     if (absl::StartsWith(test_case, "C/")) {
1806       base_construct_noise_image_overlap_func_ = nullptr;
1807     } else if (absl::StartsWith(test_case, "NEON/")) {
1808 #if LIBGAV1_ENABLE_NEON
1809       FilmGrainInit_NEON();
1810 #endif
1811     }
1812     construct_noise_image_overlap_func_ =
1813         dsp->film_grain.construct_noise_image_overlap;
1814   }
1815 
1816   ~ConstructImageTest() override = default;
1817 
1818  protected:
1819   // |compare| determines whether to compare the output blocks from the SIMD
1820   // implementation, if used, and the C implementation.
1821   // |saturate| determines whether to set the inputs to maximum values. This is
1822   // intended primarily as a way to simplify differences in output when
1823   // debugging.
1824   void TestConstructNoiseImage(int overlap_flag, int subsampling_x,
1825                                int subsampling_y, int num_runs, bool saturate,
1826                                bool compare);
1827   ConstructNoiseImageOverlapFunc construct_noise_image_overlap_func_;
1828   ConstructNoiseImageOverlapFunc base_construct_noise_image_overlap_func_;
1829   Array2DView<GrainType> noise_stripes_;
1830   // Owns the memory that noise_stripes_ points to.
1831   std::unique_ptr<GrainType[]> stripe_buffer_;
1832   Array2D<GrainType> noise_image_;
1833   Array2D<GrainType> base_noise_image_;
1834 };
1835 
1836 template <int bitdepth>
TestConstructNoiseImage(int overlap_flag,int subsampling_x,int subsampling_y,int num_runs,bool saturate,bool compare)1837 void ConstructImageTest<bitdepth>::TestConstructNoiseImage(
1838     int overlap_flag, int subsampling_x, int subsampling_y, int num_runs,
1839     bool saturate, bool compare) {
1840   if (construct_noise_image_overlap_func_ == nullptr) return;
1841   // Compare is only needed for NEON tests to compare with C output.
1842   if (base_construct_noise_image_overlap_func_ == nullptr && compare) return;
1843 
1844   const int image_width = ((kFrameWidth + subsampling_x) >> subsampling_x);
1845   const int image_height = ((kFrameHeight + subsampling_y) >> subsampling_y);
1846   const int stripe_height =
1847       ((kNoiseStripeHeight + subsampling_y) >> subsampling_y);
1848   const int image_stride = image_width + kNoiseImagePadding;
1849   const int stripe_size = stripe_height * image_width;
1850   if (compare) {
1851     ASSERT_TRUE(base_noise_image_.Reset(image_height, image_stride,
1852                                         /*zero_initialize=*/false));
1853   }
1854   ASSERT_TRUE(noise_image_.Reset(image_height, image_stride,
1855                                  /*zero_initialize=*/false));
1856   // Stride between stripe rows is |image_width|. Padding is only at the
1857   // end of the final row of the final stripe to protect from overreads.
1858   stripe_buffer_.reset(
1859       new (std::nothrow)
1860           GrainType[kNumTestStripes * stripe_size + kNoiseStripePadding]);
1861   ASSERT_NE(stripe_buffer_, nullptr);
1862   noise_stripes_.Reset(kNumTestStripes, stripe_size, stripe_buffer_.get());
1863 
1864   const int grain_max = GetGrainMax<bitdepth>();
1865   const int grain_min = GetGrainMin<bitdepth>();
1866   if (saturate) {
1867     for (int i = 0; i < stripe_size; ++i) {
1868       noise_stripes_[0][i] = grain_max;
1869     }
1870     for (int stripe = 1; stripe < kNumTestStripes; ++stripe) {
1871       memcpy(noise_stripes_[stripe], noise_stripes_[0],
1872              stripe_size * sizeof(noise_stripes_[0][0]));
1873     }
1874   } else {
1875     libvpx_test::ACMRandom rnd(libvpx_test::ACMRandom::DeterministicSeed());
1876     // Allow any valid grain values.
1877     const int random_range = grain_max - grain_min + 1;
1878     for (int stripe = 0; stripe < kNumTestStripes; ++stripe) {
1879       // Assign all allocated memory for this stripe.
1880       for (int i = 0; i < stripe_height; ++i) {
1881         for (int x = 0; x < image_width; ++x) {
1882           noise_stripes_[stripe][i * image_width + x] =
1883               grain_min + rnd(random_range);
1884         }
1885       }
1886     }
1887   }
1888 
1889   const absl::Time start = absl::Now();
1890   for (int i = 0; i < num_runs; ++i) {
1891     FilmGrain<bitdepth>::ConstructNoiseImage(
1892         &noise_stripes_, kFrameWidth, kFrameHeight, subsampling_x,
1893         subsampling_y, overlap_flag << (1 - subsampling_y), &noise_image_);
1894     if (overlap_flag == 1) {
1895       construct_noise_image_overlap_func_(&noise_stripes_, kFrameWidth,
1896                                           kFrameHeight, subsampling_x,
1897                                           subsampling_y, &noise_image_);
1898     }
1899   }
1900 
1901   const absl::Duration elapsed_time = absl::Now() - start;
1902   if (num_runs > 1) {
1903     printf(
1904         "ConstructNoiseImage Speed Test for overlap=%d, sub_x=%d, "
1905         "sub_y=%d: %d us\n",
1906         overlap_flag, subsampling_x, subsampling_y,
1907         static_cast<int>(absl::ToInt64Microseconds(elapsed_time)));
1908     return;
1909   }
1910   if (compare) {
1911     FilmGrain<bitdepth>::ConstructNoiseImage(
1912         &noise_stripes_, kFrameWidth, kFrameHeight, subsampling_x,
1913         subsampling_y, overlap_flag << (1 - subsampling_y), &base_noise_image_);
1914     if (overlap_flag == 1) {
1915       base_construct_noise_image_overlap_func_(
1916           &noise_stripes_, kFrameWidth, kFrameHeight, subsampling_x,
1917           subsampling_y, &base_noise_image_);
1918     }
1919     constexpr int kCompareWidth = 72;
1920     constexpr int kCompareHeight = 72;
1921     EXPECT_TRUE(test_utils::CompareBlocks(
1922         noise_image_[0], base_noise_image_[0], kCompareWidth, kCompareHeight,
1923         image_stride, image_stride, /*check_padding=*/false,
1924         /*print_diff=*/false));
1925   } else {
1926     printf("BD%d \"%s\",\n", bitdepth,
1927            test_utils::GetMd5Sum(noise_image_[0], image_width, image_height,
1928                                  image_stride)
1929                .c_str());
1930     test_utils::CheckMd5Digest(
1931         "FilmGrain",
1932         absl::StrFormat("ConstructNoiseImage overlap=%d, sub_x=%d, sub_y=%d",
1933                         overlap_flag, subsampling_x, subsampling_y)
1934             .c_str(),
1935         GetConstructImageTestDigest(bitdepth, overlap_flag, subsampling_x,
1936                                     subsampling_y),
1937         noise_image_[0], image_width, image_height, image_stride, elapsed_time);
1938   }
1939 }
1940 
1941 using ConstructImageTest8bpp = ConstructImageTest<8>;
1942 
TEST_P(ConstructImageTest8bpp,RandomValues)1943 TEST_P(ConstructImageTest8bpp, RandomValues) {
1944   ConstructNoiseTestParam test_params(GetParam());
1945   TestConstructNoiseImage(test_params.overlap_flag, test_params.subsampling_x,
1946                           test_params.subsampling_y, /*num_runs=*/1,
1947                           /*saturate=*/false, /*compare=*/false);
1948 }
1949 
TEST_P(ConstructImageTest8bpp,SaturatedValues)1950 TEST_P(ConstructImageTest8bpp, SaturatedValues) {
1951   ConstructNoiseTestParam test_params(GetParam());
1952   TestConstructNoiseImage(test_params.overlap_flag, test_params.subsampling_x,
1953                           test_params.subsampling_y, /*num_runs=*/1,
1954                           /*saturate=*/true, /*compare=*/true);
1955 }
1956 
TEST_P(ConstructImageTest8bpp,DISABLED_Speed)1957 TEST_P(ConstructImageTest8bpp, DISABLED_Speed) {
1958   ConstructNoiseTestParam test_params(GetParam());
1959   TestConstructNoiseImage(test_params.overlap_flag, test_params.subsampling_x,
1960                           test_params.subsampling_y, /*num_runs=*/500,
1961                           /*saturate=*/false, /*compare=*/false);
1962 }
1963 
1964 #if LIBGAV1_MAX_BITDEPTH >= 10
1965 using ConstructImageTest10bpp = ConstructImageTest<10>;
1966 
TEST_P(ConstructImageTest10bpp,RandomValues)1967 TEST_P(ConstructImageTest10bpp, RandomValues) {
1968   ConstructNoiseTestParam test_params(GetParam());
1969   TestConstructNoiseImage(test_params.overlap_flag, test_params.subsampling_x,
1970                           test_params.subsampling_y, /*num_runs=*/1,
1971                           /*saturate=*/false, /*compare=*/false);
1972 }
1973 
TEST_P(ConstructImageTest10bpp,SaturatedValues)1974 TEST_P(ConstructImageTest10bpp, SaturatedValues) {
1975   ConstructNoiseTestParam test_params(GetParam());
1976   TestConstructNoiseImage(test_params.overlap_flag, test_params.subsampling_x,
1977                           test_params.subsampling_y, /*num_runs=*/1,
1978                           /*saturate=*/true, /*compare=*/true);
1979 }
1980 
TEST_P(ConstructImageTest10bpp,DISABLED_Speed)1981 TEST_P(ConstructImageTest10bpp, DISABLED_Speed) {
1982   ConstructNoiseTestParam test_params(GetParam());
1983   TestConstructNoiseImage(test_params.overlap_flag, test_params.subsampling_x,
1984                           test_params.subsampling_y, /*num_runs=*/500,
1985                           /*saturate=*/false, /*compare=*/false);
1986 }
1987 #endif  // LIBGAV1_MAX_BITDEPTH >= 10
1988 
1989 #if LIBGAV1_MAX_BITDEPTH == 12
1990 using ConstructImageTest12bpp = ConstructImageTest<12>;
1991 
TEST_P(ConstructImageTest12bpp,RandomValues)1992 TEST_P(ConstructImageTest12bpp, RandomValues) {
1993   ConstructNoiseTestParam test_params(GetParam());
1994   TestConstructNoiseImage(test_params.overlap_flag, test_params.subsampling_x,
1995                           test_params.subsampling_y, /*num_runs=*/1,
1996                           /*saturate=*/false, /*compare=*/false);
1997 }
1998 
TEST_P(ConstructImageTest12bpp,SaturatedValues)1999 TEST_P(ConstructImageTest12bpp, SaturatedValues) {
2000   ConstructNoiseTestParam test_params(GetParam());
2001   TestConstructNoiseImage(test_params.overlap_flag, test_params.subsampling_x,
2002                           test_params.subsampling_y, /*num_runs=*/1,
2003                           /*saturate=*/true, /*compare=*/true);
2004 }
2005 
TEST_P(ConstructImageTest12bpp,DISABLED_Speed)2006 TEST_P(ConstructImageTest12bpp, DISABLED_Speed) {
2007   ConstructNoiseTestParam test_params(GetParam());
2008   TestConstructNoiseImage(test_params.overlap_flag, test_params.subsampling_x,
2009                           test_params.subsampling_y, /*num_runs=*/500,
2010                           /*saturate=*/false, /*compare=*/false);
2011 }
2012 #endif  // LIBGAV1_MAX_BITDEPTH == 12
2013 
2014 INSTANTIATE_TEST_SUITE_P(C, ConstructImageTest8bpp,
2015                          testing::Combine(testing::Range(0, 2),
2016                                           testing::Range(0, 3)));
2017 
2018 #if LIBGAV1_ENABLE_NEON
2019 INSTANTIATE_TEST_SUITE_P(NEON, ConstructImageTest8bpp,
2020                          testing::Combine(testing::Range(0, 2),
2021                                           testing::Range(0, 3)));
2022 #endif  // LIBGAV1_ENABLE_NEON
2023 
2024 #if LIBGAV1_MAX_BITDEPTH >= 10
2025 INSTANTIATE_TEST_SUITE_P(C, ConstructImageTest10bpp,
2026                          testing::Combine(testing::Range(0, 2),
2027                                           testing::Range(0, 3)));
2028 #endif  // LIBGAV1_MAX_BITDEPTH >= 10
2029 
2030 #if LIBGAV1_MAX_BITDEPTH == 12
2031 INSTANTIATE_TEST_SUITE_P(C, ConstructImageTest12bpp,
2032                          testing::Combine(testing::Range(0, 2),
2033                                           testing::Range(0, 3)));
2034 #endif  // LIBGAV1_MAX_BITDEPTH == 12
2035 
2036 template <int bitdepth>
2037 class ScalingLookupTableTest : public testing::TestWithParam<int> {
2038  public:
2039   static_assert(bitdepth >= kBitdepth8 && bitdepth <= LIBGAV1_MAX_BITDEPTH, "");
ScalingLookupTableTest()2040   ScalingLookupTableTest() {
2041     test_utils::ResetDspTable(bitdepth);
2042     FilmGrainInit_C();
2043     const dsp::Dsp* const dsp = dsp::GetDspTable(bitdepth);
2044 
2045     const testing::TestInfo* const test_info =
2046         testing::UnitTest::GetInstance()->current_test_info();
2047     const char* const test_case = test_info->test_suite_name();
2048     if (absl::StartsWith(test_case, "NEON/")) {
2049 #if LIBGAV1_ENABLE_NEON
2050       FilmGrainInit_NEON();
2051 #endif
2052     }
2053     initialize_func_ = dsp->film_grain.initialize_scaling_lut;
2054   }
2055   ~ScalingLookupTableTest() override = default;
2056 
2057  protected:
2058   void TestSpeed(int num_runs);
2059   void ZeroPoints();
2060 
2061  private:
2062   static constexpr int kScalingLutBufferLength =
2063       (kScalingLookupTableSize + kScalingLookupTablePadding) << (bitdepth - 8);
2064   dsp::InitializeScalingLutFunc initialize_func_;
2065   int16_t scaling_lut_[kScalingLutBufferLength];
2066 };
2067 
2068 template <int bitdepth>
TestSpeed(int num_runs)2069 void ScalingLookupTableTest<bitdepth>::TestSpeed(int num_runs) {
2070   if (initialize_func_ == nullptr) return;
2071   const int param_index = GetParam();
2072   const FilmGrainParams& params = kFilmGrainParams[param_index];
2073   const absl::Time start = absl::Now();
2074   Memset(scaling_lut_, 0, kScalingLutBufferLength);
2075   for (int i = 0; i < num_runs; ++i) {
2076     initialize_func_(params.num_y_points, params.point_y_value,
2077                      params.point_y_scaling, scaling_lut_,
2078                      kScalingLutBufferLength);
2079   }
2080   const absl::Duration elapsed_time = absl::Now() - start;
2081   if (num_runs > 1) {
2082     printf("InitializeScalingLut: %d us\n",
2083            static_cast<int>(absl::ToInt64Microseconds(elapsed_time)));
2084     return;
2085   }
2086   test_utils::CheckMd5Digest(
2087       "FilmGrain",
2088       absl::StrFormat("InitializeScalingLut for param set: %d", param_index)
2089           .c_str(),
2090       GetScalingInitTestDigest(param_index, bitdepth), scaling_lut_,
2091       (sizeof(scaling_lut_[0]) * kScalingLookupTableSize) << (bitdepth - 8),
2092       elapsed_time);
2093 }
2094 
2095 template <int bitdepth>
ZeroPoints()2096 void ScalingLookupTableTest<bitdepth>::ZeroPoints() {
2097   if (initialize_func_ == nullptr) return;
2098   const int param_index = GetParam();
2099   const FilmGrainParams& params = kFilmGrainParams[param_index];
2100   initialize_func_(0, params.point_y_value, params.point_y_scaling,
2101                    scaling_lut_, kScalingLookupTableSize);
2102   for (int i = 0; i < kScalingLookupTableSize; ++i) {
2103     ASSERT_EQ(scaling_lut_[i], 0);
2104   }
2105 }
2106 
2107 using ScalingLookupTableTest8bpp = ScalingLookupTableTest<8>;
2108 
TEST_P(ScalingLookupTableTest8bpp,ZeroPoints)2109 TEST_P(ScalingLookupTableTest8bpp, ZeroPoints) { ZeroPoints(); }
2110 
TEST_P(ScalingLookupTableTest8bpp,Correctness)2111 TEST_P(ScalingLookupTableTest8bpp, Correctness) { TestSpeed(/*num_runs=*/1); }
2112 
TEST_P(ScalingLookupTableTest8bpp,DISABLED_Speed)2113 TEST_P(ScalingLookupTableTest8bpp, DISABLED_Speed) {
2114   TestSpeed(/*num_runs=*/1e5);
2115 }
2116 
2117 #if LIBGAV1_MAX_BITDEPTH >= 10
2118 using ScalingLookupTableTest10bpp = ScalingLookupTableTest<10>;
2119 
TEST_P(ScalingLookupTableTest10bpp,ZeroPoints)2120 TEST_P(ScalingLookupTableTest10bpp, ZeroPoints) { ZeroPoints(); }
2121 
TEST_P(ScalingLookupTableTest10bpp,Correctness)2122 TEST_P(ScalingLookupTableTest10bpp, Correctness) { TestSpeed(/*num_runs=*/1); }
2123 
TEST_P(ScalingLookupTableTest10bpp,DISABLED_Speed)2124 TEST_P(ScalingLookupTableTest10bpp, DISABLED_Speed) {
2125   TestSpeed(/*num_runs=*/1e5);
2126 }
2127 #endif  // LIBGAV1_MAX_BITDEPTH >= 10
2128 
2129 #if LIBGAV1_MAX_BITDEPTH == 12
2130 using ScalingLookupTableTest12bpp = ScalingLookupTableTest<12>;
2131 
TEST_P(ScalingLookupTableTest12bpp,ZeroPoints)2132 TEST_P(ScalingLookupTableTest12bpp, ZeroPoints) { ZeroPoints(); }
2133 
TEST_P(ScalingLookupTableTest12bpp,Correctness)2134 TEST_P(ScalingLookupTableTest12bpp, Correctness) { TestSpeed(/*num_runs=*/1); }
2135 
TEST_P(ScalingLookupTableTest12bpp,DISABLED_Speed)2136 TEST_P(ScalingLookupTableTest12bpp, DISABLED_Speed) {
2137   TestSpeed(/*num_runs=*/1e5);
2138 }
2139 #endif  // LIBGAV1_MAX_BITDEPTH == 12
2140 
2141 INSTANTIATE_TEST_SUITE_P(C, ScalingLookupTableTest8bpp,
2142                          testing::Range(0, kNumFilmGrainTestParams));
2143 
2144 #if LIBGAV1_ENABLE_NEON
2145 INSTANTIATE_TEST_SUITE_P(NEON, ScalingLookupTableTest8bpp,
2146                          testing::Range(0, kNumFilmGrainTestParams));
2147 #endif
2148 
2149 #if LIBGAV1_MAX_BITDEPTH >= 10
2150 INSTANTIATE_TEST_SUITE_P(C, ScalingLookupTableTest10bpp,
2151                          testing::Range(0, kNumFilmGrainTestParams));
2152 
2153 #if LIBGAV1_ENABLE_NEON
2154 INSTANTIATE_TEST_SUITE_P(NEON, ScalingLookupTableTest10bpp,
2155                          testing::Range(0, kNumFilmGrainTestParams));
2156 #endif
2157 #endif  // LIBGAV1_MAX_BITDEPTH >= 10
2158 
2159 #if LIBGAV1_MAX_BITDEPTH == 12
2160 INSTANTIATE_TEST_SUITE_P(C, ScalingLookupTableTest12bpp,
2161                          testing::Range(0, kNumFilmGrainTestParams));
2162 #endif  // LIBGAV1_MAX_BITDEPTH == 12
2163 
2164 struct BlendNoiseTestParam {
BlendNoiseTestParamlibgav1::dsp::film_grain::__anoncc33db1e0111::BlendNoiseTestParam2165   explicit BlendNoiseTestParam(const std::tuple<int, int>& in)
2166       : chroma_scaling_from_luma(std::get<0>(in)) {
2167     switch (std::get<1>(in)) {
2168       case 0:
2169         subsampling_x = 0;
2170         subsampling_y = 0;
2171         break;
2172       case 1:
2173         subsampling_x = 1;
2174         subsampling_y = 0;
2175         break;
2176       default:
2177         assert(std::get<1>(in) == 2);
2178         subsampling_x = 1;
2179         subsampling_y = 1;
2180     }
2181   }
2182   const int chroma_scaling_from_luma;
2183   int subsampling_x;
2184   int subsampling_y;
2185 };
2186 
2187 template <int bitdepth, typename Pixel>
2188 class BlendNoiseTest : public testing::TestWithParam<std::tuple<int, int>> {
2189  public:
2190   static_assert(bitdepth >= kBitdepth8 && bitdepth <= LIBGAV1_MAX_BITDEPTH, "");
2191   using GrainType =
2192       typename std::conditional<bitdepth == 8, int8_t, int16_t>::type;
2193   ~BlendNoiseTest() override = default;
2194 
2195  protected:
SetUp()2196   void SetUp() override {
2197     test_utils::ResetDspTable(bitdepth);
2198     FilmGrainInit_C();
2199     const dsp::Dsp* const dsp = dsp::GetDspTable(bitdepth);
2200 
2201     const testing::TestInfo* const test_info =
2202         testing::UnitTest::GetInstance()->current_test_info();
2203     const char* const test_case = test_info->test_suite_name();
2204     if (absl::StartsWith(test_case, "NEON/")) {
2205 #if LIBGAV1_ENABLE_NEON
2206       FilmGrainInit_NEON();
2207 #endif
2208     } else if (absl::StartsWith(test_case, "SSE41/")) {
2209       if ((GetCpuInfo() & kSSE4_1) == 0) GTEST_SKIP() << "No SSE4.1 support!";
2210       FilmGrainInit_SSE4_1();
2211     }
2212     const BlendNoiseTestParam test_param(GetParam());
2213     chroma_scaling_from_luma_ = test_param.chroma_scaling_from_luma;
2214     blend_luma_func_ = dsp->film_grain.blend_noise_luma;
2215     blend_chroma_func_ =
2216         dsp->film_grain.blend_noise_chroma[chroma_scaling_from_luma_];
2217     subsampling_x_ = test_param.subsampling_x;
2218     subsampling_y_ = test_param.subsampling_y;
2219 
2220     uv_width_ = (width_ + subsampling_x_) >> subsampling_x_;
2221     uv_height_ = (height_ + subsampling_y_) >> subsampling_y_;
2222     uv_stride_ = uv_width_ * sizeof(Pixel);
2223     y_stride_ = width_ * sizeof(Pixel);
2224     const size_t buffer_size =
2225         sizeof(Pixel) * (width_ * height_ + 2 * uv_width_ * uv_height_ +
2226                          3 * kBorderPixelsFilmGrain);
2227     source_buffer_.reset(new (std::nothrow) uint8_t[buffer_size]);
2228     memset(source_buffer_.get(), 0, sizeof(source_buffer_[0]) * buffer_size);
2229     dest_buffer_.reset(new (std::nothrow) uint8_t[buffer_size]);
2230     memset(dest_buffer_.get(), 0, sizeof(dest_buffer_[0]) * buffer_size);
2231     source_plane_y_ = source_buffer_.get();
2232     source_plane_u_ =
2233         source_plane_y_ + y_stride_ * height_ + kBorderPixelsFilmGrain;
2234     source_plane_v_ =
2235         source_plane_u_ + uv_stride_ * uv_height_ + kBorderPixelsFilmGrain;
2236     dest_plane_y_ = dest_buffer_.get();
2237     dest_plane_u_ =
2238         dest_plane_y_ + y_stride_ * height_ + kBorderPixelsFilmGrain;
2239     dest_plane_v_ =
2240         dest_plane_u_ + uv_stride_ * uv_height_ + kBorderPixelsFilmGrain;
2241   }
2242 
2243   void TestSpeed(int num_runs);
2244 
2245  private:
2246   static constexpr int kScalingLutBufferLength =
2247       (kScalingLookupTableSize + kScalingLookupTablePadding) << 2;
2248 
2249   void ConvertScalingLut10bpp(int16_t* scaling_lut_10bpp,
2250                               const int16_t* src_scaling_lut);
2251   dsp::BlendNoiseWithImageLumaFunc blend_luma_func_;
2252   dsp::BlendNoiseWithImageChromaFunc blend_chroma_func_;
2253 
2254   const int width_ = 1921;
2255   const int height_ = 1081;
2256   int chroma_scaling_from_luma_ = 0;
2257   int subsampling_x_ = 0;
2258   int subsampling_y_ = 0;
2259   int uv_width_ = 0;
2260   int uv_height_ = 0;
2261   int uv_stride_ = 0;
2262   int y_stride_ = 0;
2263   // This holds the data that |source_plane_y_|, |source_plane_u_|, and
2264   // |source_plane_v_| point to.
2265   std::unique_ptr<uint8_t[]> source_buffer_;
2266   // This holds the data that |dest_plane_y_|, |dest_plane_u_|, and
2267   // |dest_plane_v_| point to.
2268   std::unique_ptr<uint8_t[]> dest_buffer_;
2269   uint8_t* source_plane_y_ = nullptr;
2270   uint8_t* source_plane_u_ = nullptr;
2271   uint8_t* source_plane_v_ = nullptr;
2272   uint8_t* dest_plane_y_ = nullptr;
2273   uint8_t* dest_plane_u_ = nullptr;
2274   uint8_t* dest_plane_v_ = nullptr;
2275   Array2D<GrainType> noise_image_[kMaxPlanes];
2276   int16_t scaling_lut_10bpp_y_[kScalingLutBufferLength];
2277   int16_t scaling_lut_10bpp_u_[kScalingLutBufferLength];
2278   int16_t scaling_lut_10bpp_v_[kScalingLutBufferLength];
2279 };
2280 
2281 template <int bitdepth, typename Pixel>
ConvertScalingLut10bpp(int16_t * scaling_lut_10bpp,const int16_t * src_scaling_lut)2282 void BlendNoiseTest<bitdepth, Pixel>::ConvertScalingLut10bpp(
2283     int16_t* scaling_lut_10bpp, const int16_t* src_scaling_lut) {
2284   for (int i = 0; i < kScalingLookupTableSize - 1; ++i) {
2285     const int x_base = i << 2;
2286     const int start = src_scaling_lut[i];
2287     const int end_index = std::min(i + 1, kScalingLookupTableSize - 1);
2288     const int end = src_scaling_lut[end_index];
2289     const int delta = end - start;
2290     scaling_lut_10bpp[x_base] = start;
2291     scaling_lut_10bpp[x_base + 1] = start + RightShiftWithRounding(delta, 2);
2292     scaling_lut_10bpp[x_base + 2] =
2293         start + RightShiftWithRounding(2 * delta, 2);
2294     scaling_lut_10bpp[x_base + 3] =
2295         start + RightShiftWithRounding(3 * delta, 2);
2296   }
2297 }
2298 
2299 template <int bitdepth, typename Pixel>
TestSpeed(const int num_runs)2300 void BlendNoiseTest<bitdepth, Pixel>::TestSpeed(const int num_runs) {
2301   if (blend_chroma_func_ == nullptr || blend_luma_func_ == nullptr) return;
2302   // Allow optimized code to read into the border without generating MSan
2303   // warnings. This matches the behavior in FilmGrain::AllocateNoiseImage().
2304   constexpr bool zero_initialize = LIBGAV1_MSAN == 1;
2305   ASSERT_TRUE(noise_image_[kPlaneY].Reset(height_, width_ + kNoiseImagePadding,
2306                                           zero_initialize));
2307   ASSERT_TRUE(noise_image_[kPlaneU].Reset(
2308       uv_height_, uv_width_ + kNoiseImagePadding, zero_initialize));
2309   ASSERT_TRUE(noise_image_[kPlaneV].Reset(
2310       uv_height_, uv_width_ + kNoiseImagePadding, zero_initialize));
2311   libvpx_test::ACMRandom rnd(libvpx_test::ACMRandom::DeterministicSeed());
2312   // Allow any valid grain values.
2313   const int grain_max = GetGrainMax<bitdepth>();
2314   const int grain_min = GetGrainMin<bitdepth>();
2315   const int random_range = grain_max - grain_min + 1;
2316   auto* src_y = reinterpret_cast<Pixel*>(source_plane_y_);
2317   auto* src_u = reinterpret_cast<Pixel*>(source_plane_u_);
2318   auto* src_v = reinterpret_cast<Pixel*>(source_plane_v_);
2319   for (int y = 0; y < height_; ++y) {
2320     for (int x = 0; x < width_; ++x) {
2321       const int random_source_y = rnd(random_range);
2322       // Populating the luma source ensures the lookup table is tested. Chroma
2323       // planes are given identical values. Giving them different values would
2324       // artificially differentiate the outputs. It's important that the test
2325       // expect that different outputs are caused by the different scaling
2326       // lookup tables, rather than by different inputs.
2327       const int uv_y_pos = y >> subsampling_y_;
2328       const int uv_x_pos = x >> subsampling_x_;
2329       src_y[y * width_ + x] = random_source_y;
2330       src_u[uv_y_pos * uv_width_ + uv_x_pos] = random_source_y;
2331       src_v[uv_y_pos * uv_width_ + uv_x_pos] = random_source_y;
2332       const int random_y = rnd(random_range);
2333       noise_image_[kPlaneY][y][x] = random_y + grain_min;
2334       const int random_u = rnd(random_range);
2335       noise_image_[kPlaneU][uv_y_pos][uv_x_pos] = random_u + grain_min;
2336       const int random_v = rnd(random_range);
2337       noise_image_[kPlaneV][uv_y_pos][uv_x_pos] = random_v + grain_min;
2338     }
2339   }
2340   static constexpr int16_t kTestScalingLutY[kScalingLookupTableSize] = {
2341       72,  72,  72,  72,  72,  72,  72,  72,  72,  72,  72,  72,  72,  72,  73,
2342       75,  76,  77,  79,  80,  81,  83,  84,  86,  87,  88,  90,  91,  92,  92,
2343       93,  93,  94,  95,  95,  96,  97,  97,  98,  98,  99,  99,  99,  99,  98,
2344       98,  98,  98,  98,  98,  98,  97,  97,  97,  97,  97,  97,  97,  97,  97,
2345       97,  98,  98,  98,  98,  98,  98,  98,  98,  98,  98,  98,  98,  98,  98,
2346       99,  99,  99,  99,  99,  99,  99,  99,  99,  99,  99,  99,  99,  100, 100,
2347       100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100,
2348       101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101,
2349       101, 101, 101, 101, 101, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102,
2350       102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102,
2351       102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102,
2352       102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102,
2353       102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102,
2354       102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102,
2355       102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102,
2356       102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102,
2357       102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102,
2358       102, 102,
2359   };
2360   static constexpr int16_t kTestScalingLutU[kScalingLookupTableSize] = {
2361       30,  42,  53,  65,  74,  74,  74,  74,  74,  74,  74,  74,  74,  74,  74,
2362       75,  76,  78,  79,  81,  82,  83,  85,  86,  88,  89,  91,  92,  93,  93,
2363       94,  94,  95,  95,  96,  96,  97,  97,  98,  98,  99,  99,  99,  99,  99,
2364       99,  99,  99,  98,  98,  98,  98,  98,  98,  98,  98,  98,  98,  98,  98,
2365       98,  98,  98,  98,  98,  98,  98,  98,  98,  98,  98,  98,  98,  98,  98,
2366       98,  98,  98,  98,  98,  98,  98,  98,  98,  98,  98,  98,  98,  99,  99,
2367       99,  99,  99,  99,  99,  99,  99,  99,  99,  99,  99,  99,  99,  99,  99,
2368       99,  99,  99,  99,  99,  99,  99,  99,  99,  99,  99,  99,  99,  99,  99,
2369       99,  99,  99,  99,  99,  99,  100, 100, 100, 100, 100, 100, 100, 100, 100,
2370       100, 100, 100, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 120,
2371       110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, 110,
2372       98,  98,  98,  98,  98,  98,  98,  97,  97,  97,  97,  97,  97,  97,  97,
2373       97,  97,  97,  97,  97,  97,  97,  97,  97,  97,  97,  97,  97,  97,  97,
2374       97,  97,  97,  97,  97,  97,  97,  97,  97,  97,  96,  96,  96,  96,  96,
2375       96,  96,  96,  96,  96,  96,  96,  96,  96,  96,  96,  96,  96,  96,  96,
2376       96,  96,  96,  96,  96,  96,  96,  96,  96,  96,  96,  96,  96,  96,  95,
2377       95,  95,  95,  95,  95,  95,  95,  95,  95,  95,  95,  95,  95,  95,  95,
2378       95,  95,
2379   };
2380   static constexpr int16_t kTestScalingLutV[kScalingLookupTableSize] = {
2381       73,  73,  73,  73,  73,  73,  73,  73,  73,  73,  73,  73,  74,  74,  74,
2382       75,  75,  78,  79,  81,  82,  83,  85,  86,  88,  89,  91,  92,  93,  93,
2383       94,  94,  95,  95,  96,  96,  97,  97,  98,  98,  99,  99,  99,  99,  98,
2384       98,  98,  98,  98,  98,  98,  97,  97,  97,  97,  97,  97,  97,  97,  97,
2385       97,  97,  97,  98,  98,  98,  98,  98,  98,  98,  98,  98,  98,  98,  98,
2386       98,  98,  98,  98,  98,  99,  99,  99,  99,  99,  99,  99,  99,  99,  99,
2387       99,  99,  99,  99,  99,  99,  100, 100, 100, 100, 100, 100, 100, 100, 100,
2388       100, 100, 100, 100, 100, 100, 100, 100, 101, 101, 101, 101, 101, 101, 101,
2389       101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101,
2390       101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101,
2391       101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101,
2392       101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101,
2393       101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101,
2394       101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101,
2395       150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150,
2396       180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180, 180,
2397       200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200, 200,
2398       255, 255,
2399   };
2400 
2401   if (bitdepth == 10) {
2402     for (int i = 0; i < kScalingLutBufferLength; ++i) {
2403       ConvertScalingLut10bpp(scaling_lut_10bpp_y_, kTestScalingLutY);
2404       ConvertScalingLut10bpp(scaling_lut_10bpp_u_, kTestScalingLutU);
2405       ConvertScalingLut10bpp(scaling_lut_10bpp_v_, kTestScalingLutV);
2406     }
2407   }
2408   const FilmGrainParams& params = kFilmGrainParams[0];
2409   const int min_value = 16 << (bitdepth - 8);
2410   const int max_value = 235 << (bitdepth - 8);
2411   const absl::Time start = absl::Now();
2412   for (int i = 0; i < num_runs; ++i) {
2413     if (chroma_scaling_from_luma_) {
2414       blend_chroma_func_(
2415           kPlaneU, params, noise_image_, min_value, max_value, width_, height_,
2416           /*start_height=*/0, subsampling_x_, subsampling_y_,
2417           (bitdepth == 10) ? scaling_lut_10bpp_y_ : kTestScalingLutY,
2418           source_plane_y_, y_stride_, source_plane_u_, uv_stride_,
2419           dest_plane_u_, uv_stride_);
2420       blend_chroma_func_(
2421           kPlaneV, params, noise_image_, min_value, max_value, width_, height_,
2422           /*start_height=*/0, subsampling_x_, subsampling_y_,
2423           (bitdepth == 10) ? scaling_lut_10bpp_y_ : kTestScalingLutY,
2424           source_plane_y_, y_stride_, source_plane_v_, uv_stride_,
2425           dest_plane_v_, uv_stride_);
2426     } else {
2427       blend_chroma_func_(
2428           kPlaneU, params, noise_image_, min_value, max_value, width_, height_,
2429           /*start_height=*/0, subsampling_x_, subsampling_y_,
2430           (bitdepth == 10) ? scaling_lut_10bpp_u_ : kTestScalingLutU,
2431           source_plane_y_, y_stride_, source_plane_u_, uv_stride_,
2432           dest_plane_u_, uv_stride_);
2433       blend_chroma_func_(
2434           kPlaneV, params, noise_image_, min_value, max_value, width_, height_,
2435           /*start_height=*/0, subsampling_x_, subsampling_y_,
2436           (bitdepth == 10) ? scaling_lut_10bpp_v_ : kTestScalingLutV,
2437           source_plane_y_, y_stride_, source_plane_v_, uv_stride_,
2438           dest_plane_v_, uv_stride_);
2439     }
2440     blend_luma_func_(noise_image_, min_value, max_value, params.chroma_scaling,
2441                      width_, height_, /*start_height=*/0,
2442                      (bitdepth == 10) ? scaling_lut_10bpp_y_ : kTestScalingLutY,
2443                      source_plane_y_, y_stride_, dest_plane_y_, y_stride_);
2444   }
2445   const absl::Duration elapsed_time = absl::Now() - start;
2446   const char* digest_luma = GetBlendLumaTestDigest(bitdepth);
2447   printf("YBD%d \"%s\",\n", bitdepth,
2448          test_utils::GetMd5Sum(dest_plane_y_, y_stride_ * height_).c_str());
2449   printf("UBD%d \"%s\",\n", bitdepth,
2450          test_utils::GetMd5Sum(dest_plane_u_, uv_stride_ * uv_height_).c_str());
2451   printf("VBD%d \"%s\",\n", bitdepth,
2452          test_utils::GetMd5Sum(dest_plane_v_, uv_stride_ * uv_height_).c_str());
2453   test_utils::CheckMd5Digest(
2454       "BlendNoiseWithImage",
2455       absl::StrFormat("Luma cfl=%d, sub_x=%d, sub_y=%d",
2456                       chroma_scaling_from_luma_, subsampling_x_, subsampling_y_)
2457           .c_str(),
2458       digest_luma, dest_plane_y_, y_stride_ * height_, elapsed_time);
2459   const char* digest_chroma_u = GetBlendChromaUTestDigest(
2460       bitdepth, chroma_scaling_from_luma_, subsampling_x_, subsampling_y_);
2461   test_utils::CheckMd5Digest(
2462       "BlendNoiseWithImage",
2463       absl::StrFormat("ChromaU cfl=%d, sub_x=%d, sub_y=%d",
2464                       chroma_scaling_from_luma_, subsampling_x_, subsampling_y_)
2465           .c_str(),
2466       digest_chroma_u, dest_plane_u_, uv_stride_ * uv_height_, elapsed_time);
2467   const char* digest_chroma_v = GetBlendChromaVTestDigest(
2468       bitdepth, chroma_scaling_from_luma_, subsampling_x_, subsampling_y_);
2469   test_utils::CheckMd5Digest(
2470       "BlendNoiseWithImage",
2471       absl::StrFormat("ChromaV cfl=%d, sub_x=%d, sub_y=%d",
2472                       chroma_scaling_from_luma_, subsampling_x_, subsampling_y_)
2473           .c_str(),
2474       digest_chroma_v, dest_plane_v_, uv_stride_ * uv_height_, elapsed_time);
2475 }
2476 
2477 using BlendNoiseTest8bpp = BlendNoiseTest<8, uint8_t>;
2478 
TEST_P(BlendNoiseTest8bpp,MatchesOriginalOutput)2479 TEST_P(BlendNoiseTest8bpp, MatchesOriginalOutput) { TestSpeed(1); }
2480 
TEST_P(BlendNoiseTest8bpp,DISABLED_Speed)2481 TEST_P(BlendNoiseTest8bpp, DISABLED_Speed) { TestSpeed(kNumSpeedTests); }
2482 
2483 INSTANTIATE_TEST_SUITE_P(C, BlendNoiseTest8bpp,
2484                          testing::Combine(testing::Range(0, 2),
2485                                           testing::Range(0, 3)));
2486 #if LIBGAV1_ENABLE_SSE4_1
2487 INSTANTIATE_TEST_SUITE_P(SSE41, BlendNoiseTest8bpp,
2488                          testing::Combine(testing::Range(0, 2),
2489                                           testing::Range(0, 3)));
2490 #endif
2491 
2492 #if LIBGAV1_ENABLE_NEON
2493 INSTANTIATE_TEST_SUITE_P(NEON, BlendNoiseTest8bpp,
2494                          testing::Combine(testing::Range(0, 2),
2495                                           testing::Range(0, 3)));
2496 #endif
2497 
2498 #if LIBGAV1_MAX_BITDEPTH >= 10
2499 using BlendNoiseTest10bpp = BlendNoiseTest<10, uint16_t>;
2500 
TEST_P(BlendNoiseTest10bpp,MatchesOriginalOutput)2501 TEST_P(BlendNoiseTest10bpp, MatchesOriginalOutput) { TestSpeed(1); }
2502 
TEST_P(BlendNoiseTest10bpp,DISABLED_Speed)2503 TEST_P(BlendNoiseTest10bpp, DISABLED_Speed) { TestSpeed(kNumSpeedTests); }
2504 
2505 INSTANTIATE_TEST_SUITE_P(C, BlendNoiseTest10bpp,
2506                          testing::Combine(testing::Range(0, 2),
2507                                           testing::Range(0, 3)));
2508 #if LIBGAV1_ENABLE_SSE4_1
2509 INSTANTIATE_TEST_SUITE_P(SSE41, BlendNoiseTest10bpp,
2510                          testing::Combine(testing::Range(0, 2),
2511                                           testing::Range(0, 3)));
2512 #endif
2513 
2514 #if LIBGAV1_ENABLE_NEON
2515 INSTANTIATE_TEST_SUITE_P(NEON, BlendNoiseTest10bpp,
2516                          testing::Combine(testing::Range(0, 2),
2517                                           testing::Range(0, 3)));
2518 #endif
2519 #endif  // LIBGAV1_MAX_BITDEPTH >= 10
2520 
2521 #if LIBGAV1_MAX_BITDEPTH == 12
2522 using BlendNoiseTest12bpp = BlendNoiseTest<12, uint16_t>;
2523 
TEST_P(BlendNoiseTest12bpp,MatchesOriginalOutput)2524 TEST_P(BlendNoiseTest12bpp, MatchesOriginalOutput) { TestSpeed(1); }
2525 
TEST_P(BlendNoiseTest12bpp,DISABLED_Speed)2526 TEST_P(BlendNoiseTest12bpp, DISABLED_Speed) { TestSpeed(kNumSpeedTests); }
2527 
2528 INSTANTIATE_TEST_SUITE_P(C, BlendNoiseTest12bpp,
2529                          testing::Combine(testing::Range(0, 2),
2530                                           testing::Range(0, 3)));
2531 #endif  // LIBGAV1_MAX_BITDEPTH == 12
2532 
2533 template <int bitdepth, typename Pixel>
2534 class FilmGrainSpeedTest : public testing::TestWithParam<int> {
2535  public:
2536   static_assert(bitdepth >= kBitdepth8 && bitdepth <= LIBGAV1_MAX_BITDEPTH, "");
2537   ~FilmGrainSpeedTest() override = default;
2538 
2539  protected:
SetUp()2540   void SetUp() override {
2541     test_utils::ResetDspTable(bitdepth);
2542     FilmGrainInit_C();
2543 
2544     const testing::TestInfo* const test_info =
2545         testing::UnitTest::GetInstance()->current_test_info();
2546     const char* const test_case = test_info->test_suite_name();
2547     if (absl::StartsWith(test_case, "NEON/")) {
2548 #if LIBGAV1_ENABLE_NEON
2549       FilmGrainInit_NEON();
2550 #endif
2551     } else if (absl::StartsWith(test_case, "SSE41/")) {
2552       if ((GetCpuInfo() & kSSE4_1) == 0) GTEST_SKIP() << "No SSE4.1 support!";
2553       FilmGrainInit_SSE4_1();
2554     }
2555     uv_width_ = (width_ + subsampling_x_) >> subsampling_x_;
2556     uv_height_ = (height_ + subsampling_y_) >> subsampling_y_;
2557     uv_stride_ = uv_width_ * sizeof(Pixel);
2558     y_stride_ = width_ * sizeof(Pixel);
2559     const size_t buffer_size =
2560         sizeof(Pixel) * (width_ * height_ + 2 * uv_width_ * uv_height_);
2561     source_buffer_.reset(new (std::nothrow) uint8_t[buffer_size]);
2562     memset(source_buffer_.get(), 0, sizeof(source_buffer_[0]) * buffer_size);
2563     dest_buffer_.reset(new (std::nothrow) uint8_t[buffer_size]);
2564     memset(dest_buffer_.get(), 0, sizeof(dest_buffer_[0]) * buffer_size);
2565     source_plane_y_ = source_buffer_.get();
2566     source_plane_u_ = source_plane_y_ + y_stride_ * height_;
2567     source_plane_v_ = source_plane_u_ + uv_stride_ * uv_height_;
2568     dest_plane_y_ = dest_buffer_.get();
2569     dest_plane_u_ = dest_plane_y_ + y_stride_ * height_;
2570     dest_plane_v_ = dest_plane_u_ + uv_stride_ * uv_height_;
2571     const int num_threads = GetParam();
2572     thread_pool_ = ThreadPool::Create(num_threads);
2573   }
2574 
2575   void TestSpeed(int num_runs);
2576 
2577  private:
2578   const int width_ = 1920;
2579   const int height_ = 1080;
2580   const int subsampling_x_ = 1;
2581   const int subsampling_y_ = 1;
2582   int uv_width_ = 0;
2583   int uv_height_ = 0;
2584   int uv_stride_ = 0;
2585   int y_stride_ = 0;
2586   std::unique_ptr<uint8_t[]> source_buffer_;
2587   std::unique_ptr<uint8_t[]> dest_buffer_;
2588   const uint8_t* source_plane_y_ = nullptr;
2589   const uint8_t* source_plane_u_ = nullptr;
2590   const uint8_t* source_plane_v_ = nullptr;
2591   uint8_t* dest_plane_y_ = nullptr;
2592   uint8_t* dest_plane_u_ = nullptr;
2593   uint8_t* dest_plane_v_ = nullptr;
2594   std::unique_ptr<ThreadPool> thread_pool_;
2595 };
2596 
2597 // Each run of the speed test adds film grain noise to 10 dummy frames. The
2598 // film grain parameters for the 10 frames were generated with aomenc.
2599 template <int bitdepth, typename Pixel>
TestSpeed(const int num_runs)2600 void FilmGrainSpeedTest<bitdepth, Pixel>::TestSpeed(const int num_runs) {
2601   const dsp::Dsp* dsp = GetDspTable(bitdepth);
2602   if (dsp->film_grain.blend_noise_chroma[0] == nullptr ||
2603       dsp->film_grain.blend_noise_luma == nullptr) {
2604     return;
2605   }
2606   for (int k = 0; k < kNumFilmGrainTestParams; ++k) {
2607     const FilmGrainParams& params = kFilmGrainParams[k];
2608     const absl::Time start = absl::Now();
2609     for (int i = 0; i < num_runs; ++i) {
2610       FilmGrain<bitdepth> film_grain(params, /*is_monochrome=*/false,
2611                                      /*color_matrix_is_identity=*/false,
2612                                      subsampling_x_, subsampling_y_, width_,
2613                                      height_, thread_pool_.get());
2614       EXPECT_TRUE(film_grain.AddNoise(
2615           source_plane_y_, y_stride_, source_plane_u_, source_plane_v_,
2616           uv_stride_, dest_plane_y_, y_stride_, dest_plane_u_, dest_plane_v_,
2617           uv_stride_));
2618     }
2619     const absl::Duration elapsed_time = absl::Now() - start;
2620     const char* digest_luma = GetTestDigestLuma(bitdepth, k);
2621     test_utils::CheckMd5Digest(
2622         "FilmGrainSynthesisLuma",
2623         absl::StrFormat("kFilmGrainParams[%d]", k).c_str(), digest_luma,
2624         dest_plane_y_, y_stride_ * height_, elapsed_time);
2625     const char* digest_chroma_u = GetTestDigestChromaU(bitdepth, k);
2626     test_utils::CheckMd5Digest(
2627         "FilmGrainSynthesisChromaU",
2628         absl::StrFormat("kFilmGrainParams[%d]", k).c_str(), digest_chroma_u,
2629         dest_plane_u_, uv_stride_ * uv_height_, elapsed_time);
2630     const char* digest_chroma_v = GetTestDigestChromaV(bitdepth, k);
2631     test_utils::CheckMd5Digest(
2632         "FilmGrainSynthesisChromaV",
2633         absl::StrFormat("kFilmGrainParams[%d]", k).c_str(), digest_chroma_v,
2634         dest_plane_v_, uv_stride_ * uv_height_, elapsed_time);
2635   }
2636 }
2637 
2638 using FilmGrainSpeedTest8bpp = FilmGrainSpeedTest<8, uint8_t>;
2639 
TEST_P(FilmGrainSpeedTest8bpp,MatchesOriginalOutput)2640 TEST_P(FilmGrainSpeedTest8bpp, MatchesOriginalOutput) { TestSpeed(1); }
2641 
TEST_P(FilmGrainSpeedTest8bpp,DISABLED_Speed)2642 TEST_P(FilmGrainSpeedTest8bpp, DISABLED_Speed) { TestSpeed(kNumSpeedTests); }
2643 
2644 INSTANTIATE_TEST_SUITE_P(C, FilmGrainSpeedTest8bpp, testing::Values(0, 3, 8));
2645 
2646 #if LIBGAV1_ENABLE_SSE4_1
2647 INSTANTIATE_TEST_SUITE_P(SSE41, FilmGrainSpeedTest8bpp,
2648                          testing::Values(0, 3, 8));
2649 #endif
2650 
2651 #if LIBGAV1_ENABLE_NEON
2652 INSTANTIATE_TEST_SUITE_P(NEON, FilmGrainSpeedTest8bpp,
2653                          testing::Values(0, 3, 8));
2654 #endif
2655 
2656 #if LIBGAV1_MAX_BITDEPTH >= 10
2657 using FilmGrainSpeedTest10bpp = FilmGrainSpeedTest<10, uint16_t>;
2658 
TEST_P(FilmGrainSpeedTest10bpp,MatchesOriginalOutput)2659 TEST_P(FilmGrainSpeedTest10bpp, MatchesOriginalOutput) { TestSpeed(1); }
2660 
TEST_P(FilmGrainSpeedTest10bpp,DISABLED_Speed)2661 TEST_P(FilmGrainSpeedTest10bpp, DISABLED_Speed) { TestSpeed(kNumSpeedTests); }
2662 
2663 INSTANTIATE_TEST_SUITE_P(C, FilmGrainSpeedTest10bpp, testing::Values(0, 3, 8));
2664 
2665 #if LIBGAV1_ENABLE_SSE4_1
2666 INSTANTIATE_TEST_SUITE_P(SSE41, FilmGrainSpeedTest10bpp,
2667                          testing::Values(0, 3, 8));
2668 #endif
2669 
2670 #if LIBGAV1_ENABLE_NEON
2671 INSTANTIATE_TEST_SUITE_P(NEON, FilmGrainSpeedTest10bpp,
2672                          testing::Values(0, 3, 8));
2673 #endif
2674 
2675 #endif  // LIBGAV1_MAX_BITDEPTH >= 10
2676 
2677 #if LIBGAV1_MAX_BITDEPTH == 12
2678 using FilmGrainSpeedTest12bpp = FilmGrainSpeedTest<12, uint16_t>;
2679 
TEST_P(FilmGrainSpeedTest12bpp,MatchesOriginalOutput)2680 TEST_P(FilmGrainSpeedTest12bpp, MatchesOriginalOutput) { TestSpeed(1); }
2681 
TEST_P(FilmGrainSpeedTest12bpp,DISABLED_Speed)2682 TEST_P(FilmGrainSpeedTest12bpp, DISABLED_Speed) { TestSpeed(kNumSpeedTests); }
2683 
2684 INSTANTIATE_TEST_SUITE_P(C, FilmGrainSpeedTest12bpp, testing::Values(0, 3, 8));
2685 #endif  // LIBGAV1_MAX_BITDEPTH == 12
2686 
2687 }  // namespace
2688 }  // namespace film_grain
2689 }  // namespace dsp
2690 }  // namespace libgav1
2691