FFmpeg
h274.c
Go to the documentation of this file.
1 /*
2  * H.274 film grain synthesis
3  * Copyright (c) 2021 Niklas Haas <ffmpeg@haasn.xyz>
4  *
5  * This file is part of FFmpeg.
6  *
7  * FFmpeg is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * FFmpeg is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with FFmpeg; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20  */
21 
22 /**
23  * @file
24  * H.274 film grain synthesis.
25  * @author Niklas Haas <ffmpeg@haasn.xyz>
26  */
27 
28 #include "libavutil/avassert.h"
29 #include "libavutil/bswap.h"
30 #include "libavcodec/bswapdsp.h"
31 #include "libavutil/crc.h"
32 #include "libavutil/imgutils.h"
33 #include "libavutil/md5.h"
34 #include "libavutil/mem.h"
35 
36 #include "h274.h"
37 
38 static const int8_t Gaussian_LUT[2048+4];
39 static const uint32_t Seed_LUT[256];
40 static const int8_t R64T[64][64];
41 
42 static void prng_shift(uint32_t *state)
43 {
44  // Primitive polynomial x^31 + x^3 + 1 (modulo 2)
45  uint32_t x = *state;
46  uint8_t feedback = 1u ^ (x >> 2) ^ (x >> 30);
47  *state = (x << 1) | (feedback & 1u);
48 }
49 
50 static void init_slice_c(int8_t out[64][64], uint8_t h, uint8_t v,
51  int16_t tmp[64][64])
52 {
53  static const uint8_t deblock_factors[13] = {
54  64, 71, 77, 84, 90, 96, 103, 109, 116, 122, 128, 128, 128
55  };
56 
57  const uint8_t deblock_coeff = deblock_factors[v];
58  const uint8_t freq_h = ((h + 3) << 2) - 1;
59  const uint8_t freq_v = ((v + 3) << 2) - 1;
60  uint32_t seed = Seed_LUT[h + v * 13];
61 
62  // Initialize with random gaussian values, using the output array as a
63  // temporary buffer for these intermediate values.
64  //
65  // Note: To make the subsequent matrix multiplication cache friendlier, we
66  // store each *column* of the starting image in a *row* of `out`
67  for (int l = 0; l <= freq_v; l++) {
68  for (int k = 0; k <= freq_h; k += 4) {
69  uint16_t offset = seed % 2048;
70  out[l][k + 0] = Gaussian_LUT[offset + 0];
71  out[l][k + 1] = Gaussian_LUT[offset + 1];
72  out[l][k + 2] = Gaussian_LUT[offset + 2];
73  out[l][k + 3] = Gaussian_LUT[offset + 3];
74  prng_shift(&seed);
75  }
76  }
77 
78  out[0][0] = 0;
79 
80  // 64x64 inverse integer transform
81  for (int y = 0; y < 64; y++) {
82  for (int x = 0; x <= freq_v; x++) {
83  int32_t sum = 0;
84  for (int p = 0; p <= freq_h; p++)
85  sum += R64T[y][p] * out[x][p];
86  tmp[y][x] = (sum + 128) >> 8;
87  }
88  }
89 
90  for (int y = 0; y < 64; y++) {
91  for (int x = 0; x < 64; x++) {
92  int32_t sum = 0;
93  for (int p = 0; p <= freq_v; p++)
94  sum += tmp[x][p] * R64T[y][p]; // R64T^T = R64
95  // Renormalize and clip to [-127, 127]
96  out[y][x] = av_clip((sum + 128) >> 8, -127, 127);
97  }
98  }
99 
100  // Deblock horizontal edges by simple attenuation of values
101  for (int y = 0; y < 64; y += 8) {
102  for (int x = 0; x < 64; x++) {
103  out[y + 0][x] = (out[y + 0][x] * deblock_coeff) >> 7;
104  out[y + 7][x] = (out[y + 7][x] * deblock_coeff) >> 7;
105  }
106  }
107 }
108 
109 static void init_slice(H274FilmGrainDatabase *database, uint8_t h, uint8_t v)
110 {
111  if (database->residency[h] & (1 << v))
112  return;
113 
114  database->residency[h] |= (1 << v);
115  init_slice_c(database->db[h][v], h, v, database->slice_tmp);
116 }
117 
118 // Computes the average of an 8x8 block
119 static uint16_t avg_8x8_c(const uint8_t *in, int in_stride)
120 {
121  uint16_t avg[8] = {0}; // summing over an array vectorizes better
122 
123  for (int y = 0; y < 8; y++) {
124  for (int x = 0; x < 8; x++)
125  avg[x] += in[x];
126  in += in_stride;
127  }
128 
129  return (avg[0] + avg[1] + avg[2] + avg[3] +
130  avg[4] + avg[5] + avg[6] + avg[7]) >> 6;
131 }
132 
133 // Synthesize an 8x8 block of film grain by copying the pattern from `db`
134 static void synth_grain_8x8_c(int8_t *out, const int out_stride,
135  const int16_t scale, const uint8_t shift,
136  const int8_t *db)
137 {
138  for (int y = 0; y < 8; y++) {
139  for (int x = 0; x < 8; x++)
140  out[x] = (scale * db[x]) >> shift;
141 
142  out += out_stride;
143  db += 64;
144  }
145 }
146 
147 // Deblock vertical edges of an 8x8 block, mixing with the previous block
148 static void deblock_8x8_c(int8_t *out, const int out_stride)
149 {
150  for (int y = 0; y < 8; y++) {
151  const int8_t l1 = out[-2], l0 = out[-1];
152  const int8_t r0 = out[0], r1 = out[1];
153  out[0] = (l0 + r0 * 2 + r1) >> 2;
154  out[-1] = (r0 + l0 * 2 + l1) >> 2;
155  out += out_stride;
156  }
157 }
158 
159 // Generates a single 8x8 block of grain, optionally also applying the
160 // deblocking step (note that this implies writing to the previous block).
161 static av_always_inline void generate(int8_t *out, int out_stride,
162  const uint8_t *in, int in_stride,
163  H274FilmGrainDatabase *database,
164  const AVFilmGrainH274Params *h274,
165  int c, int invert, int deblock,
166  int y_offset, int x_offset)
167 {
168  const uint8_t shift = h274->log2_scale_factor + 6;
169  const uint16_t avg = avg_8x8_c(in, in_stride);
170  int16_t scale;
171  uint8_t h, v;
172  int8_t s = -1;
173 
174  // FIXME: This logic only generates grain with a single
175  // intensity interval. Strictly speaking, the H.274 specification allows
176  // for overlapping intensity intervals, however SMPTE RDD 5-2006 (which
177  // concerns the implementation of H.274 for H.264) forbids this as it
178  // requires a nontrivial grain synthesis process (FFT).
179  //
180  // In principle, we should detect this possibility ahead of time and warn
181  // the user that the output is unlikely to be correct, or alternatively
182  // return an AVERROR_PATCHWELCOME.
183  for (int i = 0; i < h274->num_intensity_intervals[c]; i++) {
184  if (avg >= h274->intensity_interval_lower_bound[c][i] &&
185  avg <= h274->intensity_interval_upper_bound[c][i])
186  {
187  s = i;
188  break;
189  }
190  }
191 
192  if (s < 0) {
193  // No matching intensity interval, synthesize blank film grain
194  for (int y = 0; y < 8; y++)
195  memset(out + y * out_stride, 0, sizeof(int8_t[8]));
196  return;
197  }
198 
199  h = av_clip(h274->comp_model_value[c][s][1], 2, 14) - 2;
200  v = av_clip(h274->comp_model_value[c][s][2], 2, 14) - 2;
201  init_slice(database, h, v);
202 
203  scale = h274->comp_model_value[c][s][0];
204  if (invert)
205  scale = -scale;
206 
207  synth_grain_8x8_c(out, out_stride, scale, shift,
208  &database->db[h][v][y_offset][x_offset]);
209 
210  if (deblock)
211  deblock_8x8_c(out, out_stride);
212 }
213 
214 // Saturating 8-bit sum of a+b
215 static void add_8x8_clip_c(uint8_t *out, const uint8_t *a, const int8_t *b,
216  int n)
217 {
218  for (int i = 0; i < n; i++)
219  out[i] = av_clip_uint8(a[i] + b[i]);
220 }
221 
222 int ff_h274_apply_film_grain(AVFrame *out_frame, const AVFrame *in_frame,
223  H274FilmGrainDatabase *database,
224  const AVFilmGrainParams *params)
225 {
226  AVFilmGrainH274Params h274 = params->codec.h274;
228  if (h274.model_id != 0)
229  return AVERROR_PATCHWELCOME;
230 
231  av_assert1(out_frame->format == in_frame->format);
232  if (in_frame->format != AV_PIX_FMT_YUV420P)
233  return AVERROR_PATCHWELCOME;
234 
235  for (int c = 0; c < 3; c++) {
236  static const uint8_t color_offset[3] = { 0, 85, 170 };
237  uint32_t seed = Seed_LUT[(params->seed + color_offset[c]) % 256];
238  const int width = c > 0 ? AV_CEIL_RSHIFT(out_frame->width, 1) : out_frame->width;
239  const int height = c > 0 ? AV_CEIL_RSHIFT(out_frame->height, 1) : out_frame->height;
240 
241  uint8_t * const out = out_frame->data[c];
242  const int out_stride = out_frame->linesize[c];
243  int8_t * const grain = out_frame->data[c]; // reuse output buffer for grain
244  const int grain_stride = out_stride;
245  const uint8_t * const in = in_frame->data[c];
246  const int in_stride = in_frame->linesize[c];
247 
248  if (!h274.component_model_present[c]) {
249  av_image_copy_plane(out, out_stride, in, in_stride,
250  width * sizeof(uint8_t), height);
251  continue;
252  }
253 
254  if (c > 0) {
255  // Adaptation for 4:2:0 chroma subsampling
256  for (int i = 0; i < h274.num_intensity_intervals[c]; i++) {
257  h274.comp_model_value[c][i][0] >>= 1;
258  h274.comp_model_value[c][i][1] *= 2;
259  h274.comp_model_value[c][i][2] *= 2;
260  }
261  }
262 
263  // Film grain synthesis is done in 8x8 blocks, but the PRNG state is
264  // only advanced in 16x16 blocks, so use a nested loop
265  for (int y = 0; y < height; y += 16) {
266  for (int x = 0; x < width; x += 16) {
267  uint16_t x_offset = (seed >> 16) % 52;
268  uint16_t y_offset = (seed & 0xFFFF) % 56;
269  const int invert = (seed & 0x1);
270  x_offset &= 0xFFFC;
271  y_offset &= 0xFFF8;
272  prng_shift(&seed);
273 
274  for (int yy = 0; yy < 16 && y+yy < height; yy += 8) {
275  for (int xx = 0; xx < 16 && x+xx < width; xx += 8) {
276  generate(grain + (y+yy) * grain_stride + (x+xx), grain_stride,
277  in + (y+yy) * in_stride + (x+xx), in_stride,
278  database, &h274, c, invert, (x+xx) > 0,
279  y_offset + yy, x_offset + xx);
280  }
281  }
282  }
283  }
284 
285  // Final output blend pass, done after grain synthesis is complete
286  // because deblocking depends on previous grain values
287  for (int y = 0; y < height; y++) {
288  add_8x8_clip_c(out + y * out_stride, in + y * in_stride,
289  grain + y * grain_stride, width);
290  }
291  }
292 
293  return 0;
294 }
295 
296 // These tables are all taken from the SMPTE RDD 5-2006 specification
297 static const int8_t Gaussian_LUT[2048+4] = {
298  -11, 12, 103, -11, 42, -35, 12, 59, 77, 98, -87, 3, 65, -78, 45, 56, -51, 21,
299  13, -11, -20, -19, 33, -127, 17, -6, -105, 18, 19, 71, 48, -10, -38, 42,
300  -2, 75, -67, 52, -90, 33, -47, 21, -3, -56, 49, 1, -57, -42, -1, 120, -127,
301  -108, -49, 9, 14, 127, 122, 109, 52, 127, 2, 7, 114, 19, 30, 12, 77, 112,
302  82, -61, -127, 111, -52, -29, 2, -49, -24, 58, -29, -73, 12, 112, 67, 79,
303  -3, -114, -87, -6, -5, 40, 58, -81, 49, -27, -31, -34, -105, 50, 16, -24,
304  -35, -14, -15, -127, -55, -22, -55, -127, -112, 5, -26, -72, 127, 127, -2,
305  41, 87, -65, -16, 55, 19, 91, -81, -65, -64, 35, -7, -54, 99, -7, 88, 125,
306  -26, 91, 0, 63, 60, -14, -23, 113, -33, 116, 14, 26, 51, -16, 107, -8, 53,
307  38, -34, 17, -7, 4, -91, 6, 63, 63, -15, 39, -36, 19, 55, 17, -51, 40, 33,
308  -37, 126, -39, -118, 17, -30, 0, 19, 98, 60, 101, -12, -73, -17, -52, 98,
309  3, 3, 60, 33, -3, -2, 10, -42, -106, -38, 14, 127, 16, -127, -31, -86, -39,
310  -56, 46, -41, 75, 23, -19, -22, -70, 74, -54, -2, 32, -45, 17, -92, 59,
311  -64, -67, 56, -102, -29, -87, -34, -92, 68, 5, -74, -61, 93, -43, 14, -26,
312  -38, -126, -17, 16, -127, 64, 34, 31, 93, 17, -51, -59, 71, 77, 81, 127,
313  127, 61, 33, -106, -93, 0, 0, 75, -69, 71, 127, -19, -111, 30, 23, 15, 2,
314  39, 92, 5, 42, 2, -6, 38, 15, 114, -30, -37, 50, 44, 106, 27, 119, 7, -80,
315  25, -68, -21, 92, -11, -1, 18, 41, -50, 79, -127, -43, 127, 18, 11, -21,
316  32, -52, 27, -88, -90, -39, -19, -10, 24, -118, 72, -24, -44, 2, 12, 86,
317  -107, 39, -33, -127, 47, 51, -24, -22, 46, 0, 15, -35, -69, -2, -74, 24,
318  -6, 0, 29, -3, 45, 32, -32, 117, -45, 79, -24, -17, -109, -10, -70, 88,
319  -48, 24, -91, 120, -37, 50, -127, 58, 32, -82, -10, -17, -7, 46, -127, -15,
320  89, 127, 17, 98, -39, -33, 37, 42, -40, -32, -21, 105, -19, 19, 19, -59,
321  -9, 30, 0, -127, 34, 127, -84, 75, 24, -40, -49, -127, -107, -14, 45, -75,
322  1, 30, -20, 41, -68, -40, 12, 127, -3, 5, 20, -73, -59, -127, -3, -3, -53,
323  -6, -119, 93, 120, -80, -50, 0, 20, -46, 67, 78, -12, -22, -127, 36, -41,
324  56, 119, -5, -116, -22, 68, -14, -90, 24, -82, -44, -127, 107, -25, -37,
325  40, -7, -7, -82, 5, -87, 44, -34, 9, -127, 39, 70, 49, -63, 74, -49, 109,
326  -27, -89, -47, -39, 44, 49, -4, 60, -42, 80, 9, -127, -9, -56, -49, 125,
327  -66, 47, 36, 117, 15, -11, -96, 109, 94, -17, -56, 70, 8, -14, -5, 50, 37,
328  -45, 120, -30, -76, 40, -46, 6, 3, 69, 17, -78, 1, -79, 6, 127, 43, 26,
329  127, -127, 28, -55, -26, 55, 112, 48, 107, -1, -77, -1, 53, -9, -22, -43,
330  123, 108, 127, 102, 68, 46, 5, 1, 123, -13, -55, -34, -49, 89, 65, -105,
331  -5, 94, -53, 62, 45, 30, 46, 18, -35, 15, 41, 47, -98, -24, 94, -75, 127,
332  -114, 127, -68, 1, -17, 51, -95, 47, 12, 34, -45, -75, 89, -107, -9, -58,
333  -29, -109, -24, 127, -61, -13, 77, -45, 17, 19, 83, -24, 9, 127, -66, 54,
334  4, 26, 13, 111, 43, -113, -22, 10, -24, 83, 67, -14, 75, -123, 59, 127,
335  -12, 99, -19, 64, -38, 54, 9, 7, 61, -56, 3, -57, 113, -104, -59, 3, -9,
336  -47, 74, 85, -55, -34, 12, 118, 28, 93, -72, 13, -99, -72, -20, 30, 72,
337  -94, 19, -54, 64, -12, -63, -25, 65, 72, -10, 127, 0, -127, 103, -20, -73,
338  -112, -103, -6, 28, -42, -21, -59, -29, -26, 19, -4, -51, 94, -58, -95,
339  -37, 35, 20, -69, 127, -19, -127, -22, -120, -53, 37, 74, -127, -1, -12,
340  -119, -53, -28, 38, 69, 17, 16, -114, 89, 62, 24, 37, -23, 49, -101, -32,
341  -9, -95, -53, 5, 93, -23, -49, -8, 51, 3, -75, -90, -10, -39, 127, -86,
342  -22, 20, 20, 113, 75, 52, -31, 92, -63, 7, -12, 46, 36, 101, -43, -17, -53,
343  -7, -38, -76, -31, -21, 62, 31, 62, 20, -127, 31, 64, 36, 102, -85, -10,
344  77, 80, 58, -79, -8, 35, 8, 80, -24, -9, 3, -17, 72, 127, 83, -87, 55, 18,
345  -119, -123, 36, 10, 127, 56, -55, 113, 13, 26, 32, -13, -48, 22, -13, 5,
346  58, 27, 24, 26, -11, -36, 37, -92, 78, 81, 9, 51, 14, 67, -13, 0, 32, 45,
347  -76, 32, -39, -22, -49, -127, -27, 31, -9, 36, 14, 71, 13, 57, 12, -53,
348  -86, 53, -44, -35, 2, 127, 12, -66, -44, 46, -115, 3, 10, 56, -35, 119,
349  -19, -61, 52, -59, -127, -49, -23, 4, -5, 17, -82, -6, 127, 25, 79, 67, 64,
350  -25, 14, -64, -37, -127, -28, 21, -63, 66, -53, -41, 109, -62, 15, -22, 13,
351  29, -63, 20, 27, 95, -44, -59, -116, -10, 79, -49, 22, -43, -16, 46, -47,
352  -120, -36, -29, -52, -44, 29, 127, -13, 49, -9, -127, 75, -28, -23, 88, 59,
353  11, -95, 81, -59, 58, 60, -26, 40, -92, -3, -22, -58, -45, -59, -22, -53,
354  71, -29, 66, -32, -23, 14, -17, -66, -24, -28, -62, 47, 38, 17, 16, -37,
355  -24, -11, 8, -27, -19, 59, 45, -49, -47, -4, -22, -81, 30, -67, -127, 74,
356  102, 5, -18, 98, 34, -66, 42, -52, 7, -59, 24, -58, -19, -24, -118, -73,
357  91, 15, -16, 79, -32, -79, -127, -36, 41, 77, -83, 2, 56, 22, -75, 127,
358  -16, -21, 12, 31, 56, -113, -127, 90, 55, 61, 12, 55, -14, -113, -14, 32,
359  49, -67, -17, 91, -10, 1, 21, 69, -70, 99, -19, -112, 66, -90, -10, -9,
360  -71, 127, 50, -81, -49, 24, 61, -61, -111, 7, -41, 127, 88, -66, 108, -127,
361  -6, 36, -14, 41, -50, 14, 14, 73, -101, -28, 77, 127, -8, -100, 88, 38,
362  121, 88, -125, -60, 13, -94, -115, 20, -67, -87, -94, -119, 44, -28, -30,
363  18, 5, -53, -61, 20, -43, 11, -77, -60, 13, 29, 3, 6, -72, 38, -60, -11,
364  108, -53, 41, 66, -12, -127, -127, -49, 24, 29, 46, 36, 91, 34, -33, 116,
365  -51, -34, -52, 91, 7, -83, 73, -26, -103, 24, -10, 76, 84, 5, 68, -80, -13,
366  -17, -32, -48, 20, 50, 26, 10, 63, -104, -14, 37, 127, 114, 97, 35, 1, -33,
367  -55, 127, -124, -33, 61, -7, 119, -32, -127, -53, -42, 63, 3, -5, -26, 70,
368  -58, -33, -44, -43, 34, -56, -127, 127, 25, -35, -11, 16, -81, 29, -58, 40,
369  -127, -127, 20, -47, -11, -36, -63, -52, -32, -82, 78, -76, -73, 8, 27,
370  -72, -9, -74, -85, -86, -57, 25, 78, -10, -97, 35, -65, 8, -59, 14, 1, -42,
371  32, -88, -44, 17, -3, -9, 59, 40, 12, -108, -40, 24, 34, 18, -28, 2, 51,
372  -110, -4, 100, 1, 65, 22, 0, 127, 61, 45, 25, -31, 6, 9, -7, -48, 99, 16,
373  44, -2, -40, 32, -39, -52, 10, -110, -19, 56, -127, 69, 26, 51, 92, 40, 61,
374  -52, 45, -38, 13, 85, 122, 27, 66, 45, -111, -83, -3, 31, 37, 19, -36, 58,
375  71, 39, -78, -47, 58, -78, 8, -62, -36, -14, 61, 42, -127, 71, -4, 24, -54,
376  52, -127, 67, -4, -42, 30, -63, 59, -3, -1, -18, -46, -92, -81, -96, -14,
377  -53, -10, -11, -77, 13, 1, 8, -67, -127, 127, -28, 26, -14, 18, -13, -26,
378  2, 10, -46, -32, -15, 27, -31, -59, 59, 77, -121, 28, 40, -54, -62, -31,
379  -21, -37, -32, -6, -127, -25, -60, 70, -127, 112, -127, 127, 88, -7, 116,
380  110, 53, 87, -127, 3, 16, 23, 74, -106, -51, 3, 74, -82, -112, -74, 65, 81,
381  25, 53, 127, -45, -50, -103, -41, -65, -29, 79, -67, 64, -33, -30, -8, 127,
382  0, -13, -51, 67, -14, 5, -92, 29, -35, -8, -90, -57, -3, 36, 43, 44, -31,
383  -69, -7, 36, 39, -51, 43, -81, 58, 6, 127, 12, 57, 66, 46, 59, -43, -42,
384  41, -15, -120, 24, 3, -11, 19, -13, 51, 28, 3, 55, -48, -12, -1, 2, 97,
385  -19, 29, 42, 13, 43, 78, -44, 56, -108, -43, -19, 127, 15, -11, -18, -81,
386  83, -37, 77, -109, 15, 65, -50, 43, 12, 13, 27, 28, 61, 57, 30, 26, 106,
387  -18, 56, 13, 97, 4, -8, -62, -103, 94, 108, -44, 52, 27, -47, -9, 105, -53,
388  46, 89, 103, -33, 38, -34, 55, 51, 70, -94, -35, -87, -107, -19, -31, 9,
389  -19, 79, -14, 77, 5, -19, -107, 85, 21, -45, -39, -42, 9, -29, 74, 47, -75,
390  60, -127, 120, -112, -57, -32, 41, 7, 79, 76, 66, 57, 41, -25, 31, 37, -47,
391  -36, 43, -73, -37, 63, 127, -69, -52, 90, -33, -61, 60, -55, 44, 15, 4,
392  -67, 13, -92, 64, 29, -39, -3, 83, -2, -38, -85, -86, 58, 35, -69, -61, 29,
393  -37, -95, -78, 4, 30, -4, -32, -80, -22, -9, -77, 46, 7, -93, -71, 65, 9,
394  -50, 127, -70, 26, -12, -39, -114, 63, -127, -100, 4, -32, 111, 22, -60,
395  65, -101, 26, -42, 21, -59, -27, -74, 2, -94, 6, 126, 5, 76, -88, -9, -43,
396  -101, 127, 1, 125, 92, -63, 52, 56, 4, 81, -127, 127, 80, 127, -29, 30,
397  116, -74, -17, -57, 105, 48, 45, 25, -72, 48, -38, -108, 31, -34, 4, -11,
398  41, -127, 52, -104, -43, -37, 52, 2, 47, 87, -9, 77, 27, -41, -25, 90, 86,
399  -56, 75, 10, 33, 78, 58, 127, 127, -7, -73, 49, -33, -106, -35, 38, 57, 53,
400  -17, -4, 83, 52, -108, 54, -125, 28, 23, 56, -43, -88, -17, -6, 47, 23, -9,
401  0, -13, 111, 75, 27, -52, -38, -34, 39, 30, 66, 39, 38, -64, 38, 3, 21,
402  -32, -51, -28, 54, -38, -87, 20, 52, 115, 18, -81, -70, 0, -14, -46, -46,
403  -3, 125, 16, -14, 23, -82, -84, -69, -20, -65, -127, 9, 81, -49, 61, 7,
404  -36, -45, -42, 57, -26, 47, 20, -85, 46, -13, 41, -37, -75, -60, 86, -78,
405  -127, 12, 50, 2, -3, 13, 47, 5, 19, -78, -55, -27, 65, -71, 12, -108, 20,
406  -16, 11, -31, 63, -55, 37, 75, -17, 127, -73, -33, -28, -120, 105, 68, 106,
407  -103, -106, 71, 61, 2, 23, -3, 33, -5, -15, -67, -15, -23, -54, 15, -63,
408  76, 58, -110, 1, 83, -27, 22, 75, -39, -17, -11, 64, -17, -127, -54, -66,
409  31, 96, 116, 3, -114, -7, -108, -63, 97, 9, 50, 8, 75, -28, 72, 112, -36,
410  -112, 95, -50, 23, -13, -19, 55, 21, 23, 92, 91, 22, -49, 16, -75, 23, 9,
411  -49, -97, -37, 49, -36, 36, -127, -86, 43, 127, -24, -24, 84, 83, -35, -34,
412  -12, 109, 102, -38, 51, -68, 34, 19, -22, 49, -32, 127, 40, 24, -93, -4,
413  -3, 105, 3, -58, -18, 8, 127, -18, 125, 68, 69, -62, 30, -36, 54, -57, -24,
414  17, 43, -36, -27, -57, -67, -21, -10, -49, 68, 12, 65, 4, 48, 55, 127, -75,
415  44, 89, -66, -13, -78, -82, -91, 22, 30, 33, -40, -87, -34, 96, -91, 39,
416  10, -64, -3, -12, 127, -50, -37, -56, 23, -35, -36, -54, 90, -91, 2, 50,
417  77, -6, -127, 16, 46, -5, -73, 0, -56, -18, -72, 28, 93, 60, 49, 20, 18,
418  111, -111, 32, -83, 47, 47, -10, 35, -88, 43, 57, -98, 127, -17, 0, 1, -39,
419  -127, -2, 0, 63, 93, 0, 36, -66, -61, -19, 39, -127, 58, 50, -17, 127, 88,
420  -43, -108, -51, -16, 7, -36, 68, 46, -14, 107, 40, 57, 7, 19, 8, 3, 88,
421  -90, -92, -18, -21, -24, 13, 7, -4, -78, -91, -4, 8, -35, -5, 19, 2, -111,
422  4, -66, -81, 122, -20, -34, -37, -84, 127, 68, 46, 17, 47,
423 
424  // Repeat the beginning of the array to allow wrapping reads
425  -11, 12, 103, -11,
426 };
427 
428 static const uint32_t Seed_LUT[256] = {
429  747538460, 1088979410, 1744950180, 1767011913, 1403382928,
430  521866116, 1060417601, 2110622736, 1557184770, 105289385, 585624216,
431  1827676546, 1191843873, 1018104344, 1123590530, 663361569, 2023850500,
432  76561770, 1226763489, 80325252, 1992581442, 502705249, 740409860,
433  516219202, 557974537, 1883843076, 720112066, 1640137737, 1820967556,
434  40667586, 155354121, 1820967557, 1115949072, 1631803309, 98284748,
435  287433856, 2119719977, 988742797, 1827432592, 579378475, 1017745956,
436  1309377032, 1316535465, 2074315269, 1923385360, 209722667, 1546228260,
437  168102420, 135274561, 355958469, 248291472, 2127839491, 146920100,
438  585982612, 1611702337, 696506029, 1386498192, 1258072451, 1212240548,
439  1043171860, 1217404993, 1090770605, 1386498193, 169093201, 541098240,
440  1468005469, 456510673, 1578687785, 1838217424, 2010752065, 2089828354,
441  1362717428, 970073673, 854129835, 714793201, 1266069081, 1047060864,
442  1991471829, 1098097741, 913883585, 1669598224, 1337918685, 1219264706,
443  1799741108, 1834116681, 683417731, 1120274457, 1073098457, 1648396544,
444  176642749, 31171789, 718317889, 1266977808, 1400892508, 549749008,
445  1808010512, 67112961, 1005669825, 903663673, 1771104465, 1277749632,
446  1229754427, 950632997, 1979371465, 2074373264, 305357524, 1049387408,
447  1171033360, 1686114305, 2147468765, 1941195985, 117709841, 809550080,
448  991480851, 1816248997, 1561503561, 329575568, 780651196, 1659144592,
449  1910793616, 604016641, 1665084765, 1530186961, 1870928913, 809550081,
450  2079346113, 71307521, 876663040, 1073807360, 832356664, 1573927377,
451  204073344, 2026918147, 1702476788, 2043881033, 57949587, 2001393952,
452  1197426649, 1186508931, 332056865, 950043140, 890043474, 349099312,
453  148914948, 236204097, 2022643605, 1441981517, 498130129, 1443421481,
454  924216797, 1817491777, 1913146664, 1411989632, 929068432, 495735097,
455  1684636033, 1284520017, 432816184, 1344884865, 210843729, 676364544,
456  234449232, 12112337, 1350619139, 1753272996, 2037118872, 1408560528,
457  533334916, 1043640385, 357326099, 201376421, 110375493, 541106497,
458  416159637, 242512193, 777294080, 1614872576, 1535546636, 870600145,
459  910810409, 1821440209, 1605432464, 1145147393, 951695441, 1758494976,
460  1506656568, 1557150160, 608221521, 1073840384, 217672017, 684818688,
461  1750138880, 16777217, 677990609, 953274371, 1770050213, 1359128393,
462  1797602707, 1984616737, 1865815816, 2120835200, 2051677060, 1772234061,
463  1579794881, 1652821009, 1742099468, 1887260865, 46468113, 1011925248,
464  1134107920, 881643832, 1354774993, 472508800, 1892499769, 1752793472,
465  1962502272, 687898625, 883538000, 1354355153, 1761673473, 944820481,
466  2020102353, 22020353, 961597696, 1342242816, 964808962, 1355809701,
467  17016649, 1386540177, 647682692, 1849012289, 751668241, 1557184768,
468  127374604, 1927564752, 1045744913, 1614921984, 43588881, 1016185088,
469  1544617984, 1090519041, 136122424, 215038417, 1563027841, 2026918145,
470  1688778833, 701530369, 1372639488, 1342242817, 2036945104, 953274369,
471  1750192384, 16842753, 964808960, 1359020032, 1358954497
472 };
473 
474 // Note: This is pre-transposed, i.e. stored column-major order
475 static const int8_t R64T[64][64] = {
476  {
477  32, 45, 45, 45, 45, 45, 45, 45, 44, 44, 44, 44, 43, 43, 43, 42,
478  42, 41, 41, 40, 40, 39, 39, 38, 38, 37, 36, 36, 35, 34, 34, 33,
479  32, 31, 30, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18,
480  17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 4, 3, 2, 1,
481  }, {
482  32, 45, 45, 44, 43, 42, 41, 39, 38, 36, 34, 31, 29, 26, 23, 20,
483  17, 14, 11, 8, 4, 1, -2, -6, -9, -12, -15, -18, -21, -24, -27, -30,
484  -32, -34, -36, -38, -40, -41, -43, -44, -44, -45, -45, -45, -45, -45, -44, -43,
485  -42, -40, -39, -37, -35, -33, -30, -28, -25, -22, -19, -16, -13, -10, -7, -3,
486  }, {
487  32, 45, 44, 42, 40, 37, 34, 30, 25, 20, 15, 10, 4, -1, -7, -12,
488  -17, -22, -27, -31, -35, -38, -41, -43, -44, -45, -45, -45, -43, -41, -39, -36,
489  -32, -28, -23, -18, -13, -8, -2, 3, 9, 14, 19, 24, 29, 33, 36, 39,
490  42, 44, 45, 45, 45, 44, 43, 40, 38, 34, 30, 26, 21, 16, 11, 6,
491  }, {
492  32, 45, 43, 39, 35, 30, 23, 16, 9, 1, -7, -14, -21, -28, -34, -38,
493  -42, -44, -45, -45, -43, -40, -36, -31, -25, -18, -11, -3, 4, 12, 19, 26,
494  32, 37, 41, 44, 45, 45, 44, 41, 38, 33, 27, 20, 13, 6, -2, -10,
495  -17, -24, -30, -36, -40, -43, -45, -45, -44, -42, -39, -34, -29, -22, -15, -8,
496  }, {
497  32, 44, 41, 36, 29, 20, 11, 1, -9, -18, -27, -34, -40, -44, -45, -45,
498  -42, -37, -30, -22, -13, -3, 7, 16, 25, 33, 39, 43, 45, 45, 43, 38,
499  32, 24, 15, 6, -4, -14, -23, -31, -38, -42, -45, -45, -43, -39, -34, -26,
500  -17, -8, 2, 12, 21, 30, 36, 41, 44, 45, 44, 40, 35, 28, 19, 10,
501  }, {
502  32, 44, 39, 31, 21, 10, -2, -14, -25, -34, -41, -45, -45, -42, -36, -28,
503  -17, -6, 7, 18, 29, 37, 43, 45, 44, 40, 34, 24, 13, 1, -11, -22,
504  -32, -39, -44, -45, -43, -38, -30, -20, -9, 3, 15, 26, 35, 41, 45, 45,
505  42, 36, 27, 16, 4, -8, -19, -30, -38, -43, -45, -44, -40, -33, -23, -12,
506  }, {
507  32, 43, 36, 26, 13, -1, -15, -28, -38, -44, -45, -42, -35, -24, -11, 3,
508  17, 30, 39, 44, 45, 41, 34, 22, 9, -6, -19, -31, -40, -45, -45, -40,
509  -32, -20, -7, 8, 21, 33, 41, 45, 44, 39, 30, 18, 4, -10, -23, -34,
510  -42, -45, -44, -38, -29, -16, -2, 12, 25, 36, 43, 45, 43, 37, 27, 14,
511  }, {
512  32, 42, 34, 20, 4, -12, -27, -38, -44, -45, -39, -28, -13, 3, 19, 33,
513  42, 45, 43, 34, 21, 6, -11, -26, -38, -44, -45, -39, -29, -14, 2, 18,
514  32, 41, 45, 43, 35, 22, 7, -10, -25, -37, -44, -45, -40, -30, -15, 1,
515  17, 31, 41, 45, 43, 36, 23, 8, -9, -24, -36, -44, -45, -40, -30, -16,
516  }, {
517  32, 41, 30, 14, -4, -22, -36, -44, -44, -37, -23, -6, 13, 30, 41, 45,
518  42, 31, 15, -3, -21, -36, -44, -45, -38, -24, -7, 12, 29, 40, 45, 42,
519  32, 16, -2, -20, -35, -44, -45, -38, -25, -8, 11, 28, 40, 45, 43, 33,
520  17, -1, -19, -34, -43, -45, -39, -26, -9, 10, 27, 39, 45, 43, 34, 18,
521  }, {
522  32, 40, 27, 8, -13, -31, -43, -45, -38, -22, -2, 18, 35, 44, 44, 34,
523  17, -3, -23, -38, -45, -42, -30, -12, 9, 28, 41, 45, 40, 26, 7, -14,
524  -32, -43, -45, -37, -21, -1, 19, 36, 44, 44, 34, 16, -4, -24, -39, -45,
525  -42, -30, -11, 10, 29, 41, 45, 39, 25, 6, -15, -33, -43, -45, -36, -20,
526  }, {
527  32, 39, 23, 1, -21, -38, -45, -40, -25, -3, 19, 37, 45, 41, 27, 6,
528  -17, -36, -45, -42, -29, -8, 15, 34, 44, 43, 30, 10, -13, -33, -44, -44,
529  -32, -12, 11, 31, 43, 44, 34, 14, -9, -30, -43, -45, -35, -16, 7, 28,
530  42, 45, 36, 18, -4, -26, -41, -45, -38, -20, 2, 24, 40, 45, 39, 22,
531  }, {
532  32, 38, 19, -6, -29, -43, -44, -31, -9, 16, 36, 45, 40, 22, -2, -26,
533  -42, -45, -34, -12, 13, 34, 45, 41, 25, 1, -23, -40, -45, -36, -15, 10,
534  32, 44, 43, 28, 4, -20, -39, -45, -38, -18, 7, 30, 43, 44, 30, 8,
535  -17, -37, -45, -39, -21, 3, 27, 42, 44, 33, 11, -14, -35, -45, -41, -24,
536  }, {
537  32, 37, 15, -12, -35, -45, -39, -18, 9, 33, 45, 40, 21, -6, -30, -44,
538  -42, -24, 2, 28, 43, 43, 27, 1, -25, -42, -44, -30, -4, 22, 41, 45,
539  32, 8, -19, -39, -45, -34, -11, 16, 38, 45, 36, 14, -13, -36, -45, -38,
540  -17, 10, 34, 45, 40, 20, -7, -31, -44, -41, -23, 3, 29, 44, 43, 26,
541  }, {
542  32, 36, 11, -18, -40, -45, -30, -3, 25, 43, 43, 24, -4, -31, -45, -39,
543  -17, 12, 36, 45, 35, 10, -19, -40, -44, -30, -2, 26, 43, 42, 23, -6,
544  -32, -45, -39, -16, 13, 37, 45, 34, 9, -20, -41, -44, -29, -1, 27, 44,
545  42, 22, -7, -33, -45, -38, -15, 14, 38, 45, 34, 8, -21, -41, -44, -28,
546  }, {
547  32, 34, 7, -24, -43, -41, -19, 12, 38, 45, 30, 1, -29, -45, -39, -14,
548  17, 40, 44, 26, -4, -33, -45, -36, -9, 22, 43, 42, 21, -10, -36, -45,
549  -32, -3, 27, 44, 40, 16, -15, -39, -44, -28, 2, 31, 45, 37, 11, -20,
550  -42, -43, -23, 8, 35, 45, 34, 6, -25, -44, -41, -18, 13, 38, 45, 30,
551  }, {
552  32, 33, 2, -30, -45, -36, -7, 26, 44, 38, 11, -22, -43, -40, -15, 18,
553  42, 42, 19, -14, -40, -44, -23, 10, 38, 45, 27, -6, -35, -45, -30, 1,
554  32, 45, 34, 3, -29, -45, -36, -8, 25, 44, 39, 12, -21, -43, -41, -16,
555  17, 41, 43, 20, -13, -39, -44, -24, 9, 37, 45, 28, -4, -34, -45, -31,
556  }, {
557  32, 31, -2, -34, -45, -28, 7, 37, 44, 24, -11, -39, -43, -20, 15, 41,
558  42, 16, -19, -43, -40, -12, 23, 44, 38, 8, -27, -45, -35, -3, 30, 45,
559  32, -1, -34, -45, -29, 6, 36, 45, 25, -10, -39, -44, -21, 14, 41, 42,
560  17, -18, -43, -40, -13, 22, 44, 38, 9, -26, -45, -36, -4, 30, 45, 33,
561  }, {
562  32, 30, -7, -38, -43, -18, 19, 44, 38, 6, -30, -45, -29, 8, 39, 43,
563  17, -20, -44, -37, -4, 31, 45, 28, -9, -39, -43, -16, 21, 44, 36, 3,
564  -32, -45, -27, 10, 40, 42, 15, -22, -44, -36, -2, 33, 45, 26, -11, -40,
565  -42, -14, 23, 45, 35, 1, -34, -45, -25, 12, 41, 41, 13, -24, -45, -34,
566  }, {
567  32, 28, -11, -41, -40, -8, 30, 45, 25, -14, -43, -38, -4, 33, 45, 22,
568  -17, -44, -36, -1, 35, 44, 19, -20, -44, -34, 2, 37, 43, 16, -23, -45,
569  -32, 6, 39, 42, 13, -26, -45, -30, 9, 40, 41, 10, -29, -45, -27, 12,
570  42, 39, 7, -31, -45, -24, 15, 43, 38, 3, -34, -45, -21, 18, 44, 36,
571  }, {
572  32, 26, -15, -44, -35, 3, 39, 41, 9, -31, -45, -20, 21, 45, 30, -10,
573  -42, -38, -2, 36, 43, 14, -27, -45, -25, 16, 44, 34, -4, -39, -41, -8,
574  32, 45, 19, -22, -45, -30, 11, 42, 38, 1, -36, -43, -13, 28, 45, 24,
575  -17, -44, -34, 6, 40, 40, 7, -33, -44, -18, 23, 45, 29, -12, -43, -37,
576  }, {
577  32, 24, -19, -45, -29, 14, 44, 33, -9, -42, -36, 3, 40, 39, 2, -37,
578  -42, -8, 34, 44, 13, -30, -45, -18, 25, 45, 23, -20, -45, -28, 15, 44,
579  32, -10, -43, -36, 4, 40, 39, 1, -38, -41, -7, 34, 43, 12, -30, -45,
580  -17, 26, 45, 22, -21, -45, -27, 16, 44, 31, -11, -43, -35, 6, 41, 38,
581  }, {
582  32, 22, -23, -45, -21, 24, 45, 20, -25, -45, -19, 26, 45, 18, -27, -45,
583  -17, 28, 45, 16, -29, -45, -15, 30, 44, 14, -30, -44, -13, 31, 44, 12,
584  -32, -44, -11, 33, 43, 10, -34, -43, -9, 34, 43, 8, -35, -42, -7, 36,
585  42, 6, -36, -41, -4, 37, 41, 3, -38, -40, -2, 38, 40, 1, -39, -39,
586  }, {
587  32, 20, -27, -45, -13, 33, 43, 6, -38, -39, 2, 41, 35, -10, -44, -30,
588  17, 45, 23, -24, -45, -16, 30, 44, 9, -36, -41, -1, 40, 37, -7, -43,
589  -32, 14, 45, 26, -21, -45, -19, 28, 44, 12, -34, -42, -4, 38, 39, -3,
590  -42, -34, 11, 44, 29, -18, -45, -22, 25, 45, 15, -31, -43, -8, 36, 40,
591  }, {
592  32, 18, -30, -43, -4, 39, 36, -10, -44, -26, 23, 45, 13, -34, -41, 1,
593  42, 33, -15, -45, -21, 28, 44, 8, -38, -38, 7, 44, 29, -20, -45, -16,
594  32, 42, 2, -40, -35, 12, 45, 24, -25, -45, -11, 36, 40, -3, -43, -31,
595  17, 45, 19, -30, -43, -6, 39, 37, -9, -44, -27, 22, 45, 14, -34, -41,
596  }, {
597  32, 16, -34, -40, 4, 44, 27, -24, -44, -8, 39, 36, -13, -45, -19, 31,
598  42, -1, -43, -30, 21, 45, 11, -37, -38, 10, 45, 22, -29, -43, -2, 41,
599  32, -18, -45, -14, 35, 39, -7, -44, -25, 26, 44, 6, -40, -34, 15, 45,
600  17, -33, -41, 3, 43, 28, -23, -45, -9, 38, 36, -12, -45, -20, 30, 42,
601  }, {
602  32, 14, -36, -37, 13, 45, 15, -36, -38, 12, 45, 16, -35, -38, 11, 45,
603  17, -34, -39, 10, 45, 18, -34, -39, 9, 45, 19, -33, -40, 8, 45, 20,
604  -32, -40, 7, 45, 21, -31, -41, 6, 44, 22, -30, -41, 4, 44, 23, -30,
605  -42, 3, 44, 24, -29, -42, 2, 44, 25, -28, -43, 1, 43, 26, -27, -43,
606  }, {
607  32, 12, -39, -33, 21, 44, 2, -43, -25, 30, 41, -8, -45, -16, 36, 36,
608  -17, -45, -7, 41, 29, -26, -43, 3, 44, 20, -34, -38, 13, 45, 11, -39,
609  -32, 22, 44, 1, -43, -24, 30, 40, -9, -45, -15, 37, 35, -18, -45, -6,
610  42, 28, -27, -42, 4, 45, 19, -34, -38, 14, 45, 10, -40, -31, 23, 44,
611  }, {
612  32, 10, -41, -28, 29, 40, -11, -45, -9, 41, 27, -30, -40, 12, 45, 8,
613  -42, -26, 30, 39, -13, -45, -7, 42, 25, -31, -39, 14, 45, 6, -43, -24,
614  32, 38, -15, -45, -4, 43, 23, -33, -38, 16, 45, 3, -43, -22, 34, 37,
615  -17, -45, -2, 44, 21, -34, -36, 18, 44, 1, -44, -20, 35, 36, -19, -44,
616  }, {
617  32, 8, -43, -22, 35, 34, -23, -42, 9, 45, 7, -43, -21, 36, 34, -24,
618  -42, 10, 45, 6, -43, -20, 36, 33, -25, -41, 11, 45, 4, -44, -19, 37,
619  32, -26, -41, 12, 45, 3, -44, -18, 38, 31, -27, -40, 13, 45, 2, -44,
620  -17, 38, 30, -28, -40, 14, 45, 1, -44, -16, 39, 30, -29, -39, 15, 45,
621  }, {
622  32, 6, -44, -16, 40, 26, -34, -34, 25, 40, -15, -44, 4, 45, 7, -44,
623  -17, 39, 27, -33, -35, 24, 41, -14, -44, 3, 45, 8, -43, -18, 39, 28,
624  -32, -36, 23, 41, -13, -45, 2, 45, 9, -43, -19, 38, 29, -31, -36, 22,
625  42, -12, -45, 1, 45, 10, -43, -20, 38, 30, -30, -37, 21, 42, -11, -45,
626  }, {
627  32, 3, -45, -10, 43, 16, -41, -22, 38, 28, -34, -33, 29, 37, -23, -40,
628  17, 43, -11, -45, 4, 45, 2, -45, -9, 44, 15, -41, -21, 38, 27, -34,
629  -32, 30, 36, -24, -40, 18, 43, -12, -44, 6, 45, 1, -45, -8, 44, 14,
630  -42, -20, 39, 26, -35, -31, 30, 36, -25, -39, 19, 42, -13, -44, 7, 45,
631  }, {
632  32, 1, -45, -3, 45, 6, -45, -8, 44, 10, -44, -12, 43, 14, -43, -16,
633  42, 18, -41, -20, 40, 22, -39, -24, 38, 26, -36, -28, 35, 30, -34, -31,
634  32, 33, -30, -34, 29, 36, -27, -37, 25, 38, -23, -39, 21, 40, -19, -41,
635  17, 42, -15, -43, 13, 44, -11, -44, 9, 45, -7, -45, 4, 45, -2, -45,
636  }, {
637  32, -1, -45, 3, 45, -6, -45, 8, 44, -10, -44, 12, 43, -14, -43, 16,
638  42, -18, -41, 20, 40, -22, -39, 24, 38, -26, -36, 28, 35, -30, -34, 31,
639  32, -33, -30, 34, 29, -36, -27, 37, 25, -38, -23, 39, 21, -40, -19, 41,
640  17, -42, -15, 43, 13, -44, -11, 44, 9, -45, -7, 45, 4, -45, -2, 45,
641  }, {
642  32, -3, -45, 10, 43, -16, -41, 22, 38, -28, -34, 33, 29, -37, -23, 40,
643  17, -43, -11, 45, 4, -45, 2, 45, -9, -44, 15, 41, -21, -38, 27, 34,
644  -32, -30, 36, 24, -40, -18, 43, 12, -44, -6, 45, -1, -45, 8, 44, -14,
645  -42, 20, 39, -26, -35, 31, 30, -36, -25, 39, 19, -42, -13, 44, 7, -45,
646  }, {
647  32, -6, -44, 16, 40, -26, -34, 34, 25, -40, -15, 44, 4, -45, 7, 44,
648  -17, -39, 27, 33, -35, -24, 41, 14, -44, -3, 45, -8, -43, 18, 39, -28,
649  -32, 36, 23, -41, -13, 45, 2, -45, 9, 43, -19, -38, 29, 31, -36, -22,
650  42, 12, -45, -1, 45, -10, -43, 20, 38, -30, -30, 37, 21, -42, -11, 45,
651  }, {
652  32, -8, -43, 22, 35, -34, -23, 42, 9, -45, 7, 43, -21, -36, 34, 24,
653  -42, -10, 45, -6, -43, 20, 36, -33, -25, 41, 11, -45, 4, 44, -19, -37,
654  32, 26, -41, -12, 45, -3, -44, 18, 38, -31, -27, 40, 13, -45, 2, 44,
655  -17, -38, 30, 28, -40, -14, 45, -1, -44, 16, 39, -30, -29, 39, 15, -45,
656  }, {
657  32, -10, -41, 28, 29, -40, -11, 45, -9, -41, 27, 30, -40, -12, 45, -8,
658  -42, 26, 30, -39, -13, 45, -7, -42, 25, 31, -39, -14, 45, -6, -43, 24,
659  32, -38, -15, 45, -4, -43, 23, 33, -38, -16, 45, -3, -43, 22, 34, -37,
660  -17, 45, -2, -44, 21, 34, -36, -18, 44, -1, -44, 20, 35, -36, -19, 44,
661  }, {
662  32, -12, -39, 33, 21, -44, 2, 43, -25, -30, 41, 8, -45, 16, 36, -36,
663  -17, 45, -7, -41, 29, 26, -43, -3, 44, -20, -34, 38, 13, -45, 11, 39,
664  -32, -22, 44, -1, -43, 24, 30, -40, -9, 45, -15, -37, 35, 18, -45, 6,
665  42, -28, -27, 42, 4, -45, 19, 34, -38, -14, 45, -10, -40, 31, 23, -44,
666  }, {
667  32, -14, -36, 37, 13, -45, 15, 36, -38, -12, 45, -16, -35, 38, 11, -45,
668  17, 34, -39, -10, 45, -18, -34, 39, 9, -45, 19, 33, -40, -8, 45, -20,
669  -32, 40, 7, -45, 21, 31, -41, -6, 44, -22, -30, 41, 4, -44, 23, 30,
670  -42, -3, 44, -24, -29, 42, 2, -44, 25, 28, -43, -1, 43, -26, -27, 43,
671  }, {
672  32, -16, -34, 40, 4, -44, 27, 24, -44, 8, 39, -36, -13, 45, -19, -31,
673  42, 1, -43, 30, 21, -45, 11, 37, -38, -10, 45, -22, -29, 43, -2, -41,
674  32, 18, -45, 14, 35, -39, -7, 44, -25, -26, 44, -6, -40, 34, 15, -45,
675  17, 33, -41, -3, 43, -28, -23, 45, -9, -38, 36, 12, -45, 20, 30, -42,
676  }, {
677  32, -18, -30, 43, -4, -39, 36, 10, -44, 26, 23, -45, 13, 34, -41, -1,
678  42, -33, -15, 45, -21, -28, 44, -8, -38, 38, 7, -44, 29, 20, -45, 16,
679  32, -42, 2, 40, -35, -12, 45, -24, -25, 45, -11, -36, 40, 3, -43, 31,
680  17, -45, 19, 30, -43, 6, 39, -37, -9, 44, -27, -22, 45, -14, -34, 41,
681  }, {
682  32, -20, -27, 45, -13, -33, 43, -6, -38, 39, 2, -41, 35, 10, -44, 30,
683  17, -45, 23, 24, -45, 16, 30, -44, 9, 36, -41, 1, 40, -37, -7, 43,
684  -32, -14, 45, -26, -21, 45, -19, -28, 44, -12, -34, 42, -4, -38, 39, 3,
685  -42, 34, 11, -44, 29, 18, -45, 22, 25, -45, 15, 31, -43, 8, 36, -40,
686  }, {
687  32, -22, -23, 45, -21, -24, 45, -20, -25, 45, -19, -26, 45, -18, -27, 45,
688  -17, -28, 45, -16, -29, 45, -15, -30, 44, -14, -30, 44, -13, -31, 44, -12,
689  -32, 44, -11, -33, 43, -10, -34, 43, -9, -34, 43, -8, -35, 42, -7, -36,
690  42, -6, -36, 41, -4, -37, 41, -3, -38, 40, -2, -38, 40, -1, -39, 39,
691  }, {
692  32, -24, -19, 45, -29, -14, 44, -33, -9, 42, -36, -3, 40, -39, 2, 37,
693  -42, 8, 34, -44, 13, 30, -45, 18, 25, -45, 23, 20, -45, 28, 15, -44,
694  32, 10, -43, 36, 4, -40, 39, -1, -38, 41, -7, -34, 43, -12, -30, 45,
695  -17, -26, 45, -22, -21, 45, -27, -16, 44, -31, -11, 43, -35, -6, 41, -38,
696  }, {
697  32, -26, -15, 44, -35, -3, 39, -41, 9, 31, -45, 20, 21, -45, 30, 10,
698  -42, 38, -2, -36, 43, -14, -27, 45, -25, -16, 44, -34, -4, 39, -41, 8,
699  32, -45, 19, 22, -45, 30, 11, -42, 38, -1, -36, 43, -13, -28, 45, -24,
700  -17, 44, -34, -6, 40, -40, 7, 33, -44, 18, 23, -45, 29, 12, -43, 37,
701  }, {
702  32, -28, -11, 41, -40, 8, 30, -45, 25, 14, -43, 38, -4, -33, 45, -22,
703  -17, 44, -36, 1, 35, -44, 19, 20, -44, 34, 2, -37, 43, -16, -23, 45,
704  -32, -6, 39, -42, 13, 26, -45, 30, 9, -40, 41, -10, -29, 45, -27, -12,
705  42, -39, 7, 31, -45, 24, 15, -43, 38, -3, -34, 45, -21, -18, 44, -36,
706  }, {
707  32, -30, -7, 38, -43, 18, 19, -44, 38, -6, -30, 45, -29, -8, 39, -43,
708  17, 20, -44, 37, -4, -31, 45, -28, -9, 39, -43, 16, 21, -44, 36, -3,
709  -32, 45, -27, -10, 40, -42, 15, 22, -44, 36, -2, -33, 45, -26, -11, 40,
710  -42, 14, 23, -45, 35, -1, -34, 45, -25, -12, 41, -41, 13, 24, -45, 34,
711  }, {
712  32, -31, -2, 34, -45, 28, 7, -37, 44, -24, -11, 39, -43, 20, 15, -41,
713  42, -16, -19, 43, -40, 12, 23, -44, 38, -8, -27, 45, -35, 3, 30, -45,
714  32, 1, -34, 45, -29, -6, 36, -45, 25, 10, -39, 44, -21, -14, 41, -42,
715  17, 18, -43, 40, -13, -22, 44, -38, 9, 26, -45, 36, -4, -30, 45, -33,
716  }, {
717  32, -33, 2, 30, -45, 36, -7, -26, 44, -38, 11, 22, -43, 40, -15, -18,
718  42, -42, 19, 14, -40, 44, -23, -10, 38, -45, 27, 6, -35, 45, -30, -1,
719  32, -45, 34, -3, -29, 45, -36, 8, 25, -44, 39, -12, -21, 43, -41, 16,
720  17, -41, 43, -20, -13, 39, -44, 24, 9, -37, 45, -28, -4, 34, -45, 31,
721  }, {
722  32, -34, 7, 24, -43, 41, -19, -12, 38, -45, 30, -1, -29, 45, -39, 14,
723  17, -40, 44, -26, -4, 33, -45, 36, -9, -22, 43, -42, 21, 10, -36, 45,
724  -32, 3, 27, -44, 40, -16, -15, 39, -44, 28, 2, -31, 45, -37, 11, 20,
725  -42, 43, -23, -8, 35, -45, 34, -6, -25, 44, -41, 18, 13, -38, 45, -30,
726  }, {
727  32, -36, 11, 18, -40, 45, -30, 3, 25, -43, 43, -24, -4, 31, -45, 39,
728  -17, -12, 36, -45, 35, -10, -19, 40, -44, 30, -2, -26, 43, -42, 23, 6,
729  -32, 45, -39, 16, 13, -37, 45, -34, 9, 20, -41, 44, -29, 1, 27, -44,
730  42, -22, -7, 33, -45, 38, -15, -14, 38, -45, 34, -8, -21, 41, -44, 28,
731  }, {
732  32, -37, 15, 12, -35, 45, -39, 18, 9, -33, 45, -40, 21, 6, -30, 44,
733  -42, 24, 2, -28, 43, -43, 27, -1, -25, 42, -44, 30, -4, -22, 41, -45,
734  32, -8, -19, 39, -45, 34, -11, -16, 38, -45, 36, -14, -13, 36, -45, 38,
735  -17, -10, 34, -45, 40, -20, -7, 31, -44, 41, -23, -3, 29, -44, 43, -26,
736  }, {
737  32, -38, 19, 6, -29, 43, -44, 31, -9, -16, 36, -45, 40, -22, -2, 26,
738  -42, 45, -34, 12, 13, -34, 45, -41, 25, -1, -23, 40, -45, 36, -15, -10,
739  32, -44, 43, -28, 4, 20, -39, 45, -38, 18, 7, -30, 43, -44, 30, -8,
740  -17, 37, -45, 39, -21, -3, 27, -42, 44, -33, 11, 14, -35, 45, -41, 24,
741  }, {
742  32, -39, 23, -1, -21, 38, -45, 40, -25, 3, 19, -37, 45, -41, 27, -6,
743  -17, 36, -45, 42, -29, 8, 15, -34, 44, -43, 30, -10, -13, 33, -44, 44,
744  -32, 12, 11, -31, 43, -44, 34, -14, -9, 30, -43, 45, -35, 16, 7, -28,
745  42, -45, 36, -18, -4, 26, -41, 45, -38, 20, 2, -24, 40, -45, 39, -22,
746  }, {
747  32, -40, 27, -8, -13, 31, -43, 45, -38, 22, -2, -18, 35, -44, 44, -34,
748  17, 3, -23, 38, -45, 42, -30, 12, 9, -28, 41, -45, 40, -26, 7, 14,
749  -32, 43, -45, 37, -21, 1, 19, -36, 44, -44, 34, -16, -4, 24, -39, 45,
750  -42, 30, -11, -10, 29, -41, 45, -39, 25, -6, -15, 33, -43, 45, -36, 20,
751  }, {
752  32, -41, 30, -14, -4, 22, -36, 44, -44, 37, -23, 6, 13, -30, 41, -45,
753  42, -31, 15, 3, -21, 36, -44, 45, -38, 24, -7, -12, 29, -40, 45, -42,
754  32, -16, -2, 20, -35, 44, -45, 38, -25, 8, 11, -28, 40, -45, 43, -33,
755  17, 1, -19, 34, -43, 45, -39, 26, -9, -10, 27, -39, 45, -43, 34, -18,
756  }, {
757  32, -42, 34, -20, 4, 12, -27, 38, -44, 45, -39, 28, -13, -3, 19, -33,
758  42, -45, 43, -34, 21, -6, -11, 26, -38, 44, -45, 39, -29, 14, 2, -18,
759  32, -41, 45, -43, 35, -22, 7, 10, -25, 37, -44, 45, -40, 30, -15, -1,
760  17, -31, 41, -45, 43, -36, 23, -8, -9, 24, -36, 44, -45, 40, -30, 16,
761  }, {
762  32, -43, 36, -26, 13, 1, -15, 28, -38, 44, -45, 42, -35, 24, -11, -3,
763  17, -30, 39, -44, 45, -41, 34, -22, 9, 6, -19, 31, -40, 45, -45, 40,
764  -32, 20, -7, -8, 21, -33, 41, -45, 44, -39, 30, -18, 4, 10, -23, 34,
765  -42, 45, -44, 38, -29, 16, -2, -12, 25, -36, 43, -45, 43, -37, 27, -14,
766  }, {
767  32, -44, 39, -31, 21, -10, -2, 14, -25, 34, -41, 45, -45, 42, -36, 28,
768  -17, 6, 7, -18, 29, -37, 43, -45, 44, -40, 34, -24, 13, -1, -11, 22,
769  -32, 39, -44, 45, -43, 38, -30, 20, -9, -3, 15, -26, 35, -41, 45, -45,
770  42, -36, 27, -16, 4, 8, -19, 30, -38, 43, -45, 44, -40, 33, -23, 12,
771  }, {
772  32, -44, 41, -36, 29, -20, 11, -1, -9, 18, -27, 34, -40, 44, -45, 45,
773  -42, 37, -30, 22, -13, 3, 7, -16, 25, -33, 39, -43, 45, -45, 43, -38,
774  32, -24, 15, -6, -4, 14, -23, 31, -38, 42, -45, 45, -43, 39, -34, 26,
775  -17, 8, 2, -12, 21, -30, 36, -41, 44, -45, 44, -40, 35, -28, 19, -10,
776  }, {
777  32, -45, 43, -39, 35, -30, 23, -16, 9, -1, -7, 14, -21, 28, -34, 38,
778  -42, 44, -45, 45, -43, 40, -36, 31, -25, 18, -11, 3, 4, -12, 19, -26,
779  32, -37, 41, -44, 45, -45, 44, -41, 38, -33, 27, -20, 13, -6, -2, 10,
780  -17, 24, -30, 36, -40, 43, -45, 45, -44, 42, -39, 34, -29, 22, -15, 8,
781  }, {
782  32, -45, 44, -42, 40, -37, 34, -30, 25, -20, 15, -10, 4, 1, -7, 12,
783  -17, 22, -27, 31, -35, 38, -41, 43, -44, 45, -45, 45, -43, 41, -39, 36,
784  -32, 28, -23, 18, -13, 8, -2, -3, 9, -14, 19, -24, 29, -33, 36, -39,
785  42, -44, 45, -45, 45, -44, 43, -40, 38, -34, 30, -26, 21, -16, 11, -6,
786  }, {
787  32, -45, 45, -44, 43, -42, 41, -39, 38, -36, 34, -31, 29, -26, 23, -20,
788  17, -14, 11, -8, 4, -1, -2, 6, -9, 12, -15, 18, -21, 24, -27, 30,
789  -32, 34, -36, 38, -40, 41, -43, 44, -44, 45, -45, 45, -45, 45, -44, 43,
790  -42, 40, -39, 37, -35, 33, -30, 28, -25, 22, -19, 16, -13, 10, -7, 3,
791  }, {
792  32, -45, 45, -45, 45, -45, 45, -45, 44, -44, 44, -44, 43, -43, 43, -42,
793  42, -41, 41, -40, 40, -39, 39, -38, 38, -37, 36, -36, 35, -34, 34, -33,
794  32, -31, 30, -30, 29, -28, 27, -26, 25, -24, 23, -22, 21, -20, 19, -18,
795  17, -16, 15, -14, 13, -12, 11, -10, 9, -8, 7, -6, 4, -3, 2, -1,
796  }
797 };
798 
800  int type;
801  struct AVMD5 *ctx;
802 
803 #if HAVE_BIGENDIAN
804  BswapDSPContext bdsp;
805  uint8_t *buf;
806  int buf_size;
807 #endif
808 };
809 
810 static av_always_inline void bswap16_buf_if_be(H274HashContext *s, const int ps, const uint8_t **src, const int w)
811 {
812 #if HAVE_BIGENDIAN
813  if (ps) {
814  s->bdsp.bswap16_buf((uint16_t *)s->buf,
815  (const uint16_t *)*src, w);
816  *src = s->buf;
817  }
818 #endif
819 }
820 
822  const uint8_t *_src, const int w, const int h, const int stride,
823  const int ps, const uint8_t *expected)
824 {
825 #define MD5_SIZE 16
826  struct AVMD5 *ctx = s->ctx;
827  uint8_t md5[MD5_SIZE];
828 
829  av_md5_init(ctx);
830  for (int j = 0; j < h; j++) {
831  const uint8_t *src = &_src[j * stride];
832  bswap16_buf_if_be(s, ps, &src, w);
833  av_md5_update(ctx, src, w << ps);
834  src += stride;
835  }
836  av_md5_final(ctx, md5);
837 
838  if (memcmp(md5, expected, MD5_SIZE))
839  return AVERROR_INVALIDDATA;
840 
841  return 0;
842 }
843 
844 static int verify_plane_crc(H274HashContext *s, const uint8_t *_src, const int w, const int h, const int stride,
845  const int ps, uint16_t expected)
846 {
847  uint32_t crc = 0x0F1D; // CRC-16-CCITT-AUG
849 
850  for (int j = 0; j < h; j++) {
851  const uint8_t *src = &_src[j * stride];
852  bswap16_buf_if_be(s, ps, &src, w);
853  crc = av_crc(ctx, crc, src, w << ps);
854  src += stride;
855  }
856  crc = av_bswap16(crc);
857 
858  if (crc != expected)
859  return AVERROR_INVALIDDATA;
860 
861  return 0;
862 }
863 
864 #define CAL_CHECKSUM(pixel) ((pixel) ^ xor_mask)
865 static int verify_plane_checksum(const uint8_t *src, const int w, const int h, const int stride, const int ps,
866  uint32_t expected)
867 {
868  uint32_t checksum = 0;
869  expected = av_le2ne32(expected);
870 
871  for (int y = 0; y < h; y++) {
872  for (int x = 0; x < w; x++) {
873  const int xor_mask = (x & 0xFF) ^ (y & 0xFF) ^ (x >> 8) ^ (y >> 8);
874  checksum += CAL_CHECKSUM(src[x << ps]);
875  if (ps)
876  checksum += CAL_CHECKSUM(src[(x << ps) + 1]);
877  }
878  src += stride;
879  }
880 
881  if (checksum != expected)
882  return AVERROR_INVALIDDATA;
883 
884  return 0;
885 }
886 
887 enum {
892 };
893 
895 {
896  if (*ctx) {
897  H274HashContext *c = *ctx;
898  if (c->ctx)
899  av_free(c->ctx);
900  av_freep(ctx);
901 #if HAVE_BIGENDIAN
902  av_freep(&c->buf);
903 #endif
904  }
905 }
906 
908 {
910 
911  if (type > HASH_LAST || !ctx)
912  return AVERROR(EINVAL);
913 
914  c = *ctx;
915  if (c) {
916  if (c->type != type) {
917  if (c->type == HASH_MD5SUM)
918  av_freep(&c->ctx);
919  c->type = type;
920  }
921  } else {
922  c = av_mallocz(sizeof(H274HashContext));
923  if (!c)
924  return AVERROR(ENOMEM);
925  c->type = type;
926  *ctx = c;
927  }
928 
929  if (type == HASH_MD5SUM && !c->ctx) {
930  c->ctx = av_md5_alloc();
931  if (!c->ctx)
932  return AVERROR(ENOMEM);
933  }
934 
935 #if HAVE_BIGENDIAN
936  ff_bswapdsp_init(&c->bdsp);
937 #endif
938 
939  return 0;
940 }
941 
943  const AVFrame *frame, const int coded_width, const int coded_height)
944 {
945  const AVPixFmtDescriptor *desc;
946  int err = 0;
947 
948  if (!c || !hash || !frame)
949  return AVERROR(EINVAL);
950 
951  if (c->type != hash->hash_type)
952  return AVERROR(EINVAL);
953 
954  desc = av_pix_fmt_desc_get(frame->format);
955  if (!desc)
956  return AVERROR(EINVAL);
957 
958  for (int i = 0; i < desc->nb_components; i++) {
959  const int w = i ? (coded_width >> desc->log2_chroma_w) : coded_width;
960  const int h = i ? (coded_height >> desc->log2_chroma_h) : coded_height;
961  const int ps = desc->comp[i].step - 1;
962  const uint8_t *src = frame->data[i];
963  const int stride = frame->linesize[i];
964 
965 #if HAVE_BIGENDIAN
966  if (c->type != HASH_CHECKSUM) {
967  if (ps) {
968  av_fast_malloc(&c->buf, &c->buf_size,
969  FFMAX3(frame->linesize[0], frame->linesize[1],
970  frame->linesize[2]));
971  if (!c->buf)
972  return AVERROR(ENOMEM);
973  }
974  }
975 #endif
976 
977  if (c->type == HASH_MD5SUM)
978  err = verify_plane_md5(c, src, w, h, stride, ps, hash->md5[i]);
979  else if (c->type == HASH_CRC)
980  err = verify_plane_crc(c, src, w, h, stride, ps, hash->crc[i]);
981  else if (c->type == HASH_CHECKSUM)
982  err = verify_plane_checksum(src, w, h, stride, ps, hash->checksum[i]);
983  if (err < 0)
984  goto fail;
985  }
986 
987 fail:
988  return err;
989 }
generate
static av_always_inline void generate(int8_t *out, int out_stride, const uint8_t *in, int in_stride, H274FilmGrainDatabase *database, const AVFilmGrainH274Params *h274, int c, int invert, int deblock, int y_offset, int x_offset)
Definition: h274.c:161
bswapdsp.h
av_clip
#define av_clip
Definition: common.h:100
AVERROR
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFrame structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel sample they are references to shared objects When the negotiation mechanism computes the intersection of the formats supported at each end of a all references to both lists are replaced with a reference to the intersection And when a single format is eventually chosen for a link amongst the remaining all references to the list are updated That means that if a filter requires that its input and output have the same format amongst a supported all it has to do is use a reference to the same list of formats query_formats can leave some formats unset and return AVERROR(EAGAIN) to cause the negotiation mechanism toagain later. That can be used by filters with complex requirements to use the format negotiated on one link to set the formats supported on another. Frame references ownership and permissions
H274SEIPictureHash
Definition: h274.h:69
out
FILE * out
Definition: movenc.c:55
deblock
static void deblock(const RV60Context *s, AVFrame *frame, int xpos, int ypos, int size, int dpos)
Definition: rv60dec.c:2151
H274HashContext::type
int type
Definition: h274.c:800
AVCRC
uint32_t AVCRC
Definition: crc.h:46
av_pix_fmt_desc_get
const AVPixFmtDescriptor * av_pix_fmt_desc_get(enum AVPixelFormat pix_fmt)
Definition: pixdesc.c:3447
H274HashContext
Definition: h274.c:799
AVFrame
This structure describes decoded (raw) audio or video data.
Definition: frame.h:427
AVFrame::width
int width
Definition: frame.h:499
w
uint8_t w
Definition: llviddspenc.c:38
u
#define u(width, name, range_min, range_max)
Definition: cbs_apv.c:68
ff_h274_hash_init
int ff_h274_hash_init(H274HashContext **ctx, const int type)
Definition: h274.c:907
b
#define b
Definition: input.c:42
CAL_CHECKSUM
#define CAL_CHECKSUM(pixel)
Definition: h274.c:864
init_slice_c
static void init_slice_c(int8_t out[64][64], uint8_t h, uint8_t v, int16_t tmp[64][64])
Definition: h274.c:50
hash
uint8_t hash[HASH_SIZE]
Definition: movenc.c:58
ff_h274_hash_freep
void ff_h274_hash_freep(H274HashContext **ctx)
Definition: h274.c:894
AVFilmGrainParams::seed
uint64_t seed
Seed to use for the synthesis process, if the codec allows for it.
Definition: film_grain_params.h:213
_src
uint8_t ptrdiff_t const uint8_t * _src
Definition: dsp.h:56
AVFrame::data
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
Definition: frame.h:448
av_image_copy_plane
void av_image_copy_plane(uint8_t *dst, int dst_linesize, const uint8_t *src, int src_linesize, int bytewidth, int height)
Copy image plane from src to dst.
Definition: imgutils.c:374
bswap16_buf_if_be
static av_always_inline void bswap16_buf_if_be(H274HashContext *s, const int ps, const uint8_t **src, const int w)
Definition: h274.c:810
crc.h
HASH_CHECKSUM
@ HASH_CHECKSUM
Definition: h274.c:890
fail
#define fail()
Definition: checkasm.h:200
md5
struct AVMD5 * md5
Definition: movenc.c:57
type
it s the only field you need to keep assuming you have a context There is some magic you don t need to care about around this just let it vf type
Definition: writing_filters.txt:86
AVMD5
Definition: md5.c:42
avassert.h
H274FilmGrainDatabase::slice_tmp
int16_t slice_tmp[64][64]
Definition: h274.h:40
Gaussian_LUT
static const int8_t Gaussian_LUT[2048+4]
Definition: h274.c:38
s
#define s(width, name)
Definition: cbs_vp9.c:198
AV_CEIL_RSHIFT
#define AV_CEIL_RSHIFT(a, b)
Definition: common.h:60
verify_plane_checksum
static int verify_plane_checksum(const uint8_t *src, const int w, const int h, const int stride, const int ps, uint32_t expected)
Definition: h274.c:865
ctx
AVFormatContext * ctx
Definition: movenc.c:49
AV_PIX_FMT_YUV420P
@ AV_PIX_FMT_YUV420P
planar YUV 4:2:0, 12bpp, (1 Cr & Cb sample per 2x2 Y samples)
Definition: pixfmt.h:73
AVFilmGrainH274Params::comp_model_value
int16_t comp_model_value[3][256][6]
Specifies the model values for the component for each intensity interval.
Definition: film_grain_params.h:190
AVFilmGrainH274Params::model_id
int model_id
Specifies the film grain simulation mode.
Definition: film_grain_params.h:137
H274FilmGrainDatabase::db
int8_t db[13][13][64][64]
Definition: h274.h:36
ff_bswapdsp_init
av_cold void ff_bswapdsp_init(BswapDSPContext *c)
Definition: bswapdsp.c:49
AVERROR_PATCHWELCOME
#define AVERROR_PATCHWELCOME
Not yet implemented in FFmpeg, patches welcome.
Definition: error.h:64
MD5_SIZE
#define MD5_SIZE
tmp
static uint8_t tmp[20]
Definition: aes_ctr.c:47
Seed_LUT
static const uint32_t Seed_LUT[256]
Definition: h274.c:39
HASH_CRC
@ HASH_CRC
Definition: h274.c:889
HASH_LAST
@ HASH_LAST
Definition: h274.c:891
verify_plane_crc
static int verify_plane_crc(H274HashContext *s, const uint8_t *_src, const int w, const int h, const int stride, const int ps, uint16_t expected)
Definition: h274.c:844
h274.h
init_slice
static void init_slice(H274FilmGrainDatabase *database, uint8_t h, uint8_t v)
Definition: h274.c:109
seed
static unsigned int seed
Definition: videogen.c:78
H274FilmGrainDatabase::residency
uint16_t residency[13]
Definition: h274.h:37
c
Undefined Behavior In the C some operations are like signed integer dereferencing freed accessing outside allocated Undefined Behavior must not occur in a C it is not safe even if the output of undefined operations is unused The unsafety may seem nit picking but Optimizing compilers have in fact optimized code on the assumption that no undefined Behavior occurs Optimizing code based on wrong assumptions can and has in some cases lead to effects beyond the output of computations The signed integer overflow problem in speed critical code Code which is highly optimized and works with signed integers sometimes has the problem that often the output of the computation does not c
Definition: undefined.txt:32
synth_grain_8x8_c
static void synth_grain_8x8_c(int8_t *out, const int out_stride, const int16_t scale, const uint8_t shift, const int8_t *db)
Definition: h274.c:134
H274FilmGrainDatabase
Definition: h274.h:34
height
#define height
Definition: dsp.h:89
AVFilmGrainH274Params::component_model_present
int component_model_present[3]
Indicates if the modelling of film grain for a given component is present.
Definition: film_grain_params.h:155
shift
static int shift(int a, int b)
Definition: bonk.c:261
R64T
static const int8_t R64T[64][64]
Definition: h274.c:40
AVFilmGrainParams
This structure describes how to handle film grain synthesis in video for specific codecs.
Definition: film_grain_params.h:201
avg
#define avg(a, b, c, d)
Definition: colorspacedsp_template.c:28
AVFrame::format
int format
format of the frame, -1 if unknown or unset Values correspond to enum AVPixelFormat for video frames,...
Definition: frame.h:514
a
The reader does not expect b to be semantically here and if the code is changed by maybe adding a a division or other the signedness will almost certainly be mistaken To avoid this confusion a new type was SUINT is the C unsigned type but it holds a signed int to use the same example SUINT a
Definition: undefined.txt:41
av_crc_get_table
const AVCRC * av_crc_get_table(AVCRCId crc_id)
Get an initialized standard CRC table.
Definition: crc.c:374
offset
it s the only field you need to keep assuming you have a context There is some magic you don t need to care about around this just let it vf offset
Definition: writing_filters.txt:86
avg_8x8_c
static uint16_t avg_8x8_c(const uint8_t *in, int in_stride)
Definition: h274.c:119
AVFilmGrainParams::h274
AVFilmGrainH274Params h274
Definition: film_grain_params.h:248
av_md5_init
void av_md5_init(AVMD5 *ctx)
Initialize MD5 hashing.
Definition: md5.c:143
ff_h274_apply_film_grain
int ff_h274_apply_film_grain(AVFrame *out_frame, const AVFrame *in_frame, H274FilmGrainDatabase *database, const AVFilmGrainParams *params)
Definition: h274.c:222
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:256
AV_CRC_16_CCITT
@ AV_CRC_16_CCITT
Definition: crc.h:51
AVFilmGrainH274Params
This structure describes how to handle film grain synthesis for codecs using the ITU-T H....
Definition: film_grain_params.h:132
invert
static void invert(float *h, int n)
Definition: asrc_sinc.c:186
AVFilmGrainH274Params::num_intensity_intervals
uint16_t num_intensity_intervals[3]
Specifies the number of intensity intervals for which a specific set of model values has been estimat...
Definition: film_grain_params.h:161
av_assert1
#define av_assert1(cond)
assert() equivalent, that does not lie in speed critical code.
Definition: avassert.h:57
AVFilmGrainParams::codec
union AVFilmGrainParams::@479 codec
Additional fields may be added both here and in any structure included.
av_le2ne32
#define av_le2ne32(x)
Definition: bswap.h:92
md5.h
av_always_inline
#define av_always_inline
Definition: attributes.h:49
av_mallocz
void * av_mallocz(size_t size)
Allocate a memory block with alignment suitable for all memory accesses (including vectors if availab...
Definition: mem.c:256
av_md5_final
void av_md5_final(AVMD5 *ctx, uint8_t *dst)
Finish hashing and output digest value.
Definition: md5.c:188
AVFilmGrainH274Params::intensity_interval_lower_bound
uint8_t intensity_interval_lower_bound[3][256]
Specifies the lower ounds of each intensity interval for whichthe set of model values applies for the...
Definition: film_grain_params.h:173
stride
#define stride
Definition: h264pred_template.c:536
bswap.h
frame
these buffered frames must be flushed immediately if a new input produces new the filter must not call request_frame to get more It must just process the frame or queue it The task of requesting more frames is left to the filter s request_frame method or the application If a filter has several the filter must be ready for frames arriving randomly on any input any filter with several inputs will most likely require some kind of queuing mechanism It is perfectly acceptable to have a limited queue and to drop frames when the inputs are too unbalanced request_frame For filters that do not use the this method is called when a frame is wanted on an output For a it should directly call filter_frame on the corresponding output For a if there are queued frames already one of these frames should be pushed If the filter should request a frame on one of its repeatedly until at least one frame has been pushed Return or at least make progress towards producing a frame
Definition: filter_design.txt:265
H274HashContext::ctx
struct AVMD5 * ctx
Definition: h274.c:801
AVFrame::height
int height
Definition: frame.h:499
AV_FILM_GRAIN_PARAMS_H274
@ AV_FILM_GRAIN_PARAMS_H274
The union is valid when interpreted as AVFilmGrainH274Params (codec.h274)
Definition: film_grain_params.h:35
state
static struct @521 state
av_crc
uint32_t av_crc(const AVCRC *ctx, uint32_t crc, const uint8_t *buffer, size_t length)
Calculate the CRC of a block.
Definition: crc.c:392
add_8x8_clip_c
static void add_8x8_clip_c(uint8_t *out, const uint8_t *a, const int8_t *b, int n)
Definition: h274.c:215
av_md5_alloc
struct AVMD5 * av_md5_alloc(void)
Allocate an AVMD5 context.
Definition: md5.c:50
AVFilmGrainH274Params::log2_scale_factor
int log2_scale_factor
Specifies a scale factor used in the film grain characterization equations.
Definition: film_grain_params.h:150
av_clip_uint8
#define av_clip_uint8
Definition: common.h:106
av_md5_update
void av_md5_update(AVMD5 *ctx, const uint8_t *src, size_t len)
Update hash value.
Definition: md5.c:153
ff_h274_hash_verify
int ff_h274_hash_verify(H274HashContext *c, const H274SEIPictureHash *hash, const AVFrame *frame, const int coded_width, const int coded_height)
Definition: h274.c:942
desc
const char * desc
Definition: libsvtav1.c:79
mem.h
AVPixFmtDescriptor
Descriptor that unambiguously describes how the bits of a pixel are stored in the up to 4 data planes...
Definition: pixdesc.h:69
av_free
#define av_free(p)
Definition: tableprint_vlc.h:34
scale
static void scale(int *out, const int *in, const int w, const int h, const int shift)
Definition: intra.c:273
prng_shift
static void prng_shift(uint32_t *state)
Definition: h274.c:42
av_freep
#define av_freep(p)
Definition: tableprint_vlc.h:35
av_fast_malloc
void av_fast_malloc(void *ptr, unsigned int *size, size_t min_size)
Allocate a buffer, reusing the given one if large enough.
Definition: mem.c:557
FFMAX3
#define FFMAX3(a, b, c)
Definition: macros.h:48
int32_t
int32_t
Definition: audioconvert.c:56
imgutils.h
AVFrame::linesize
int linesize[AV_NUM_DATA_POINTERS]
For video, a positive or negative value, which is typically indicating the size in bytes of each pict...
Definition: frame.h:472
deblock_8x8_c
static void deblock_8x8_c(int8_t *out, const int out_stride)
Definition: h274.c:148
AVERROR_INVALIDDATA
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition: error.h:61
BswapDSPContext
Definition: bswapdsp.h:24
h
h
Definition: vp9dsp_template.c:2070
verify_plane_md5
static int verify_plane_md5(H274HashContext *s, const uint8_t *_src, const int w, const int h, const int stride, const int ps, const uint8_t *expected)
Definition: h274.c:821
width
#define width
Definition: dsp.h:89
av_bswap16
#define av_bswap16
Definition: bswap.h:28
AVFilmGrainParams::type
enum AVFilmGrainParamsType type
Specifies the codec for which this structure is valid.
Definition: film_grain_params.h:205
src
#define src
Definition: vp8dsp.c:248
HASH_MD5SUM
@ HASH_MD5SUM
Definition: h274.c:888