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