FFmpeg
filter_template.c
Go to the documentation of this file.
1 /*
2  * VVC filters DSP
3  *
4  * Copyright (C) 2022 Nuo Mi
5  *
6  * This file is part of FFmpeg.
7  *
8  * FFmpeg is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Lesser General Public
10  * License as published by the Free Software Foundation; either
11  * version 2.1 of the License, or (at your option) any later version.
12  *
13  * FFmpeg is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16  * Lesser General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with FFmpeg; if not, write to the Free Software
20  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21  */
22 
24 
25 static void FUNC(lmcs_filter_luma)(uint8_t *_dst, ptrdiff_t dst_stride, const int width, const int height, const void *_lut)
26 {
27  const pixel *lut = _lut;
28  pixel *dst = (pixel*)_dst;
29  dst_stride /= sizeof(pixel);
30 
31  for (int y = 0; y < height; y++) {
32  for (int x = 0; x < width; x++)
33  dst[x] = lut[dst[x]];
34  dst += dst_stride;
35  }
36 }
37 
38 static av_always_inline int16_t FUNC(alf_clip)(pixel curr, pixel v0, pixel v1, int16_t clip)
39 {
40  return av_clip(v0 - curr, -clip, clip) + av_clip(v1 - curr, -clip, clip);
41 }
42 
43 static void FUNC(alf_filter_luma)(uint8_t *_dst, ptrdiff_t dst_stride, const uint8_t *_src, ptrdiff_t src_stride,
44  const int width, const int height, const int16_t *filter, const int16_t *clip, const int vb_pos)
45 {
46  const pixel *src = (pixel *)_src;
47  const int shift = 7;
48  const int offset = 1 << ( shift - 1 );
49  const int vb_above = vb_pos - 4;
50  const int vb_below = vb_pos + 3;
51 
52  dst_stride /= sizeof(pixel);
53  src_stride /= sizeof(pixel);
54 
55  for (int y = 0; y < height; y += ALF_BLOCK_SIZE) {
56  for (int x = 0; x < width; x += ALF_BLOCK_SIZE) {
57  const pixel *s0 = src + y * src_stride + x;
58  const pixel *s1 = s0 + src_stride;
59  const pixel *s2 = s0 - src_stride;
60  const pixel *s3 = s1 + src_stride;
61  const pixel *s4 = s2 - src_stride;
62  const pixel *s5 = s3 + src_stride;
63  const pixel *s6 = s4 - src_stride;
64 
65  for (int i = 0; i < ALF_BLOCK_SIZE; i++) {
66  pixel *dst = (pixel *)_dst + (y + i) * dst_stride + x;
67 
68  const pixel *p0 = s0 + i * src_stride;
69  const pixel *p1 = s1 + i * src_stride;
70  const pixel *p2 = s2 + i * src_stride;
71  const pixel *p3 = s3 + i * src_stride;
72  const pixel *p4 = s4 + i * src_stride;
73  const pixel *p5 = s5 + i * src_stride;
74  const pixel *p6 = s6 + i * src_stride;
75 
76  const int is_near_vb_above = (y + i < vb_pos) && (y + i >= vb_pos - 1);
77  const int is_near_vb_below = (y + i >= vb_pos) && (y + i <= vb_pos);
78  const int is_near_vb = is_near_vb_above || is_near_vb_below;
79 
80  if ((y + i < vb_pos) && ((y + i) >= vb_above)) {
81  p1 = (y + i == vb_pos - 1) ? p0 : p1;
82  p3 = (y + i >= vb_pos - 2) ? p1 : p3;
83  p5 = (y + i >= vb_pos - 3) ? p3 : p5;
84 
85  p2 = (y + i == vb_pos - 1) ? p0 : p2;
86  p4 = (y + i >= vb_pos - 2) ? p2 : p4;
87  p6 = (y + i >= vb_pos - 3) ? p4 : p6;
88  } else if ((y + i >= vb_pos) && ((y + i) <= vb_below)) {
89  p2 = (y + i == vb_pos ) ? p0 : p2;
90  p4 = (y + i <= vb_pos + 1) ? p2 : p4;
91  p6 = (y + i <= vb_pos + 2) ? p4 : p6;
92 
93  p1 = (y + i == vb_pos ) ? p0 : p1;
94  p3 = (y + i <= vb_pos + 1) ? p1 : p3;
95  p5 = (y + i <= vb_pos + 2) ? p3 : p5;
96  }
97 
98  for (int j = 0; j < ALF_BLOCK_SIZE; j++) {
99  int sum = 0;
100  const pixel curr = *p0;
101 
102  sum += filter[0] * FUNC(alf_clip)(curr, p5[+0], p6[+0], clip[0]);
103  sum += filter[1] * FUNC(alf_clip)(curr, p3[+1], p4[-1], clip[1]);
104  sum += filter[2] * FUNC(alf_clip)(curr, p3[+0], p4[+0], clip[2]);
105  sum += filter[3] * FUNC(alf_clip)(curr, p3[-1], p4[+1], clip[3]);
106  sum += filter[4] * FUNC(alf_clip)(curr, p1[+2], p2[-2], clip[4]);
107  sum += filter[5] * FUNC(alf_clip)(curr, p1[+1], p2[-1], clip[5]);
108  sum += filter[6] * FUNC(alf_clip)(curr, p1[+0], p2[+0], clip[6]);
109  sum += filter[7] * FUNC(alf_clip)(curr, p1[-1], p2[+1], clip[7]);
110  sum += filter[8] * FUNC(alf_clip)(curr, p1[-2], p2[+2], clip[8]);
111  sum += filter[9] * FUNC(alf_clip)(curr, p0[+3], p0[-3], clip[9]);
112  sum += filter[10] * FUNC(alf_clip)(curr, p0[+2], p0[-2], clip[10]);
113  sum += filter[11] * FUNC(alf_clip)(curr, p0[+1], p0[-1], clip[11]);
114 
115  if (!is_near_vb)
116  sum = (sum + offset) >> shift;
117  else
118  sum = (sum + (1 << ((shift + 3) - 1))) >> (shift + 3);
119  sum += curr;
120  dst[j] = CLIP(sum);
121 
122  p0++;
123  p1++;
124  p2++;
125  p3++;
126  p4++;
127  p5++;
128  p6++;
129  }
130  }
133  }
134  }
135 }
136 
137 static void FUNC(alf_filter_chroma)(uint8_t* _dst, ptrdiff_t dst_stride, const uint8_t* _src, ptrdiff_t src_stride,
138  const int width, const int height, const int16_t* filter, const int16_t* clip, const int vb_pos)
139 {
140  const pixel *src = (pixel *)_src;
141  const int shift = 7;
142  const int offset = 1 << ( shift - 1 );
143  const int vb_above = vb_pos - 2;
144  const int vb_below = vb_pos + 1;
145 
146  dst_stride /= sizeof(pixel);
147  src_stride /= sizeof(pixel);
148 
149  for (int y = 0; y < height; y += ALF_BLOCK_SIZE) {
150  for (int x = 0; x < width; x += ALF_BLOCK_SIZE) {
151  const pixel *s0 = src + y * src_stride + x;
152  const pixel *s1 = s0 + src_stride;
153  const pixel *s2 = s0 - src_stride;
154  const pixel *s3 = s1 + src_stride;
155  const pixel *s4 = s2 - src_stride;
156  const pixel *s5 = s3 + src_stride;
157  const pixel *s6 = s4 - src_stride;
158 
159  for (int i = 0; i < ALF_BLOCK_SIZE; i++) {
160  pixel *dst = (pixel *)_dst + (y + i) * dst_stride + x;
161 
162  const pixel *p0 = s0 + i * src_stride;
163  const pixel *p1 = s1 + i * src_stride;
164  const pixel *p2 = s2 + i * src_stride;
165  const pixel *p3 = s3 + i * src_stride;
166  const pixel *p4 = s4 + i * src_stride;
167  const pixel *p5 = s5 + i * src_stride;
168  const pixel *p6 = s6 + i * src_stride;
169 
170  const int is_near_vb_above = (y + i < vb_pos) && (y + i >= vb_pos - 1);
171  const int is_near_vb_below = (y + i >= vb_pos) && (y + i <= vb_pos);
172  const int is_near_vb = is_near_vb_above || is_near_vb_below;
173 
174  if ((y + i < vb_pos) && ((y + i) >= vb_above)) {
175  p1 = (y + i == vb_pos - 1) ? p0 : p1;
176  p3 = (y + i >= vb_pos - 2) ? p1 : p3;
177  p5 = (y + i >= vb_pos - 3) ? p3 : p5;
178 
179  p2 = (y + i == vb_pos - 1) ? p0 : p2;
180  p4 = (y + i >= vb_pos - 2) ? p2 : p4;
181  p6 = (y + i >= vb_pos - 3) ? p4 : p6;
182  } else if ((y + i >= vb_pos) && ((y + i) <= vb_below)) {
183  p2 = (y + i == vb_pos ) ? p0 : p2;
184  p4 = (y + i <= vb_pos + 1) ? p2 : p4;
185  p6 = (y + i <= vb_pos + 2) ? p4 : p6;
186 
187  p1 = (y + i == vb_pos ) ? p0 : p1;
188  p3 = (y + i <= vb_pos + 1) ? p1 : p3;
189  p5 = (y + i <= vb_pos + 2) ? p3 : p5;
190  }
191 
192  for (int j = 0; j < ALF_BLOCK_SIZE; j++) {
193  int sum = 0;
194  const pixel curr = *p0;
195 
196  sum += filter[0] * FUNC(alf_clip)(curr, p3[+0], p4[+0], clip[0]);
197  sum += filter[1] * FUNC(alf_clip)(curr, p1[+1], p2[-1], clip[1]);
198  sum += filter[2] * FUNC(alf_clip)(curr, p1[+0], p2[+0], clip[2]);
199  sum += filter[3] * FUNC(alf_clip)(curr, p1[-1], p2[+1], clip[3]);
200  sum += filter[4] * FUNC(alf_clip)(curr, p0[+2], p0[-2], clip[4]);
201  sum += filter[5] * FUNC(alf_clip)(curr, p0[+1], p0[-1], clip[5]);
202 
203  if (!is_near_vb)
204  sum = (sum + offset) >> shift;
205  else
206  sum = (sum + (1 << ((shift + 3) - 1))) >> (shift + 3);
207  sum += curr;
208  dst[j] = CLIP(sum);
209 
210  p0++;
211  p1++;
212  p2++;
213  p3++;
214  p4++;
215  p5++;
216  p6++;
217  }
218  }
219  }
220  }
221 }
222 
223 static void FUNC(alf_filter_cc)(uint8_t *_dst, ptrdiff_t dst_stride, const uint8_t *_luma, const ptrdiff_t luma_stride,
224  const int width, const int height, const int hs, const int vs, const int16_t *filter, const int vb_pos)
225 {
226  const ptrdiff_t stride = luma_stride / sizeof(pixel);
227 
228  dst_stride /= sizeof(pixel);
229 
230  for (int y = 0; y < height; y++) {
231  for (int x = 0; x < width; x++) {
232  int sum = 0;
233  pixel *dst = (pixel *)_dst + y * dst_stride + x;
234  const pixel *src = (pixel *)_luma + (y << vs) * stride + (x << hs);
235 
236  const pixel *s0 = src - stride;
237  const pixel *s1 = src;
238  const pixel *s2 = src + stride;
239  const pixel *s3 = src + 2 * stride;
240 
241  const int pos = y << vs;
242  if (!vs && (pos == vb_pos || pos == vb_pos + 1))
243  continue;
244 
245  if (pos == (vb_pos - 2) || pos == (vb_pos + 1))
246  s3 = s2;
247  else if (pos == (vb_pos - 1) || pos == vb_pos)
248  s3 = s2 = s0 = s1;
249 
250 
251  sum += filter[0] * (*s0 - *src);
252  sum += filter[1] * (*(s1 - 1) - *src);
253  sum += filter[2] * (*(s1 + 1) - *src);
254  sum += filter[3] * (*(s2 - 1) - *src);
255  sum += filter[4] * (*s2 - *src);
256  sum += filter[5] * (*(s2 + 1) - *src);
257  sum += filter[6] * (*s3 - *src);
258  sum = av_clip((sum + 64) >> 7, -(1 << (BIT_DEPTH - 1)), (1 << (BIT_DEPTH - 1)) - 1);
259  sum += *dst;
260  *dst = av_clip_pixel(sum);
261  }
262  }
263 }
264 
265 #define ALF_DIR_VERT 0
266 #define ALF_DIR_HORZ 1
267 #define ALF_DIR_DIGA0 2
268 #define ALF_DIR_DIGA1 3
269 
270 static void FUNC(alf_get_idx)(int *class_idx, int *transpose_idx, const int *sum, const int ac)
271 {
272  static const int arg_var[] = {0, 1, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 4 };
273 
274  int hv0, hv1, dir_hv, d0, d1, dir_d, hvd1, hvd0, sum_hv, dir1;
275 
276  dir_hv = sum[ALF_DIR_VERT] <= sum[ALF_DIR_HORZ];
277  hv1 = FFMAX(sum[ALF_DIR_VERT], sum[ALF_DIR_HORZ]);
278  hv0 = FFMIN(sum[ALF_DIR_VERT], sum[ALF_DIR_HORZ]);
279 
280  dir_d = sum[ALF_DIR_DIGA0] <= sum[ALF_DIR_DIGA1];
281  d1 = FFMAX(sum[ALF_DIR_DIGA0], sum[ALF_DIR_DIGA1]);
282  d0 = FFMIN(sum[ALF_DIR_DIGA0], sum[ALF_DIR_DIGA1]);
283 
284  //promote to avoid overflow
285  dir1 = (uint64_t)d1 * hv0 <= (uint64_t)hv1 * d0;
286  hvd1 = dir1 ? hv1 : d1;
287  hvd0 = dir1 ? hv0 : d0;
288 
289  sum_hv = sum[ALF_DIR_HORZ] + sum[ALF_DIR_VERT];
290  *class_idx = arg_var[av_clip_uintp2(sum_hv * ac >> (BIT_DEPTH - 1), 4)];
291  if (hvd1 * 2 > 9 * hvd0)
292  *class_idx += ((dir1 << 1) + 2) * 5;
293  else if (hvd1 > 2 * hvd0)
294  *class_idx += ((dir1 << 1) + 1) * 5;
295 
296  *transpose_idx = dir_d * 2 + dir_hv;
297 }
298 
299 static void FUNC(alf_classify)(int *class_idx, int *transpose_idx,
300  const uint8_t *_src, const ptrdiff_t _src_stride, const int width, const int height,
301  const int vb_pos, int *gradient_tmp)
302 {
303  int *grad;
304 
305  const int h = height + ALF_GRADIENT_BORDER * 2;
306  const int w = width + ALF_GRADIENT_BORDER * 2;
308  const int gstride = (w / ALF_GRADIENT_STEP) * ALF_NUM_DIR;
309 
310  const pixel *src = (const pixel *)_src;
311  const ptrdiff_t src_stride = _src_stride / sizeof(pixel);
312  src -= (ALF_GRADIENT_BORDER + 1) * src_stride + ALF_GRADIENT_BORDER;
313 
314  grad = gradient_tmp;
315  for (int y = 0; y < h; y += ALF_GRADIENT_STEP) {
316  const pixel *s0 = src + y * src_stride;
317  const pixel *s1 = s0 + src_stride;
318  const pixel *s2 = s1 + src_stride;
319  const pixel *s3 = s2 + src_stride;
320 
321  if (y == vb_pos) //above
322  s3 = s2;
323  else if (y == vb_pos + ALF_GRADIENT_BORDER)
324  s0 = s1;
325 
326  for (int x = 0; x < w; x += ALF_GRADIENT_STEP) {
327  //two points a time
328  const pixel *a0 = s0 + x;
329  const pixel *p0 = s1 + x;
330  const pixel *b0 = s2 + x;
331  const int val0 = (*p0) << 1;
332 
333  const pixel *a1 = s1 + x + 1;
334  const pixel *p1 = s2 + x + 1;
335  const pixel *b1 = s3 + x + 1;
336  const int val1 = (*p1) << 1;
337 
338  grad[ALF_DIR_VERT] = FFABS(val0 - *a0 - *b0) + FFABS(val1 - *a1 - *b1);
339  grad[ALF_DIR_HORZ] = FFABS(val0 - *(p0 - 1) - *(p0 + 1)) + FFABS(val1 - *(p1 - 1) - *(p1 + 1));
340  grad[ALF_DIR_DIGA0] = FFABS(val0 - *(a0 - 1) - *(b0 + 1)) + FFABS(val1 - *(a1 - 1) - *(b1 + 1));
341  grad[ALF_DIR_DIGA1] = FFABS(val0 - *(a0 + 1) - *(b0 - 1)) + FFABS(val1 - *(a1 + 1) - *(b1 - 1));
342  grad += ALF_NUM_DIR;
343  }
344  }
345 
346  for (int y = 0; y < height ; y += ALF_BLOCK_SIZE ) {
347  int start = 0;
349  int ac = 2;
350  if (y + ALF_BLOCK_SIZE == vb_pos) {
352  ac = 3;
353  } else if (y == vb_pos) {
355  ac = 3;
356  }
357  for (int x = 0; x < width; x += ALF_BLOCK_SIZE) {
358  const int xg = x / ALF_GRADIENT_STEP;
359  const int yg = y / ALF_GRADIENT_STEP;
360  int sum[ALF_NUM_DIR] = { 0 };
361 
362  grad = gradient_tmp + (yg + start) * gstride + xg * ALF_NUM_DIR;
363  //todo: optimize this loop
364  for (int i = start; i < end; i++) {
365  for (int j = 0; j < size; j++) {
366  sum[ALF_DIR_VERT] += grad[ALF_DIR_VERT];
367  sum[ALF_DIR_HORZ] += grad[ALF_DIR_HORZ];
368  sum[ALF_DIR_DIGA0] += grad[ALF_DIR_DIGA0];
369  sum[ALF_DIR_DIGA1] += grad[ALF_DIR_DIGA1];
370  grad += ALF_NUM_DIR;
371  }
372  grad += gstride - size * ALF_NUM_DIR;
373  }
374  FUNC(alf_get_idx)(class_idx, transpose_idx, sum, ac);
375 
376  class_idx++;
377  transpose_idx++;
378  }
379  }
380 
381 }
382 
383 static void FUNC(alf_recon_coeff_and_clip)(int16_t *coeff, int16_t *clip,
384  const int *class_idx, const int *transpose_idx, const int size,
385  const int16_t *coeff_set, const uint8_t *clip_idx_set, const uint8_t *class_to_filt)
386 {
387  const static int index[][ALF_NUM_COEFF_LUMA] = {
388  { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 },
389  { 9, 4, 10, 8, 1, 5, 11, 7, 3, 0, 2, 6 },
390  { 0, 3, 2, 1, 8, 7, 6, 5, 4, 9, 10, 11 },
391  { 9, 8, 10, 4, 3, 7, 11, 5, 1, 0, 2, 6 },
392  };
393 
394  const int16_t clip_set[] = {
395  1 << BIT_DEPTH, 1 << (BIT_DEPTH - 3), 1 << (BIT_DEPTH - 5), 1 << (BIT_DEPTH - 7)
396  };
397 
398  for (int i = 0; i < size; i++) {
399  const int16_t *src_coeff = coeff_set + class_to_filt[class_idx[i]] * ALF_NUM_COEFF_LUMA;
400  const uint8_t *clip_idx = clip_idx_set + class_idx[i] * ALF_NUM_COEFF_LUMA;
401 
402  for (int j = 0; j < ALF_NUM_COEFF_LUMA; j++) {
403  const int idx = index[transpose_idx[i]][j];
404  *coeff++ = src_coeff[idx];
405  *clip++ = clip_set[clip_idx[idx]];
406  }
407  }
408 }
409 
410 #undef ALF_DIR_HORZ
411 #undef ALF_DIR_VERT
412 #undef ALF_DIR_DIGA0
413 #undef ALF_DIR_DIGA1
414 
415 // line zero
416 #define P7 pix[-8 * xstride]
417 #define P6 pix[-7 * xstride]
418 #define P5 pix[-6 * xstride]
419 #define P4 pix[-5 * xstride]
420 #define P3 pix[-4 * xstride]
421 #define P2 pix[-3 * xstride]
422 #define P1 pix[-2 * xstride]
423 #define P0 pix[-1 * xstride]
424 #define Q0 pix[0 * xstride]
425 #define Q1 pix[1 * xstride]
426 #define Q2 pix[2 * xstride]
427 #define Q3 pix[3 * xstride]
428 #define Q4 pix[4 * xstride]
429 #define Q5 pix[5 * xstride]
430 #define Q6 pix[6 * xstride]
431 #define Q7 pix[7 * xstride]
432 #define P(x) pix[(-(x)-1) * xstride]
433 #define Q(x) pix[(x) * xstride]
434 
435 // line three. used only for deblocking decision
436 #define TP7 pix[-8 * xstride + 3 * ystride]
437 #define TP6 pix[-7 * xstride + 3 * ystride]
438 #define TP5 pix[-6 * xstride + 3 * ystride]
439 #define TP4 pix[-5 * xstride + 3 * ystride]
440 #define TP3 pix[-4 * xstride + 3 * ystride]
441 #define TP2 pix[-3 * xstride + 3 * ystride]
442 #define TP1 pix[-2 * xstride + 3 * ystride]
443 #define TP0 pix[-1 * xstride + 3 * ystride]
444 #define TQ0 pix[0 * xstride + 3 * ystride]
445 #define TQ1 pix[1 * xstride + 3 * ystride]
446 #define TQ2 pix[2 * xstride + 3 * ystride]
447 #define TQ3 pix[3 * xstride + 3 * ystride]
448 #define TQ4 pix[4 * xstride + 3 * ystride]
449 #define TQ5 pix[5 * xstride + 3 * ystride]
450 #define TQ6 pix[6 * xstride + 3 * ystride]
451 #define TQ7 pix[7 * xstride + 3 * ystride]
452 #define TP(x) pix[(-(x)-1) * xstride + 3 * ystride]
453 #define TQ(x) pix[(x) * xstride + 3 * ystride]
454 
455 #define FP3 pix[-4 * xstride + 1 * ystride]
456 #define FP2 pix[-3 * xstride + 1 * ystride]
457 #define FP1 pix[-2 * xstride + 1 * ystride]
458 #define FP0 pix[-1 * xstride + 1 * ystride]
459 #define FQ0 pix[0 * xstride + 1 * ystride]
460 #define FQ1 pix[1 * xstride + 1 * ystride]
461 #define FQ2 pix[2 * xstride + 1 * ystride]
462 #define FQ3 pix[3 * xstride + 1 * ystride]
463 
465 
466 static void FUNC(loop_filter_luma_large)(pixel *pix, const ptrdiff_t xstride, const ptrdiff_t ystride, const int32_t tc,
467  const uint8_t no_p, const uint8_t no_q, const uint8_t max_len_p, const uint8_t max_len_q)
468 {
469  for (int d = 0; d < 4; d++) {
470  const int p6 = P6;
471  const int p5 = P5;
472  const int p4 = P4;
473  const int p3 = P3;
474  const int p2 = P2;
475  const int p1 = P1;
476  const int p0 = P0;
477  const int q0 = Q0;
478  const int q1 = Q1;
479  const int q2 = Q2;
480  const int q3 = Q3;
481  const int q4 = Q4;
482  const int q5 = Q5;
483  const int q6 = Q6;
484  int m;
485  if (max_len_p == 5 && max_len_q == 5)
486  m = (p4 + p3 + 2 * (p2 + p1 + p0 + q0 + q1 + q2) + q3 + q4 + 8) >> 4;
487  else if (max_len_p == max_len_q)
488  m = (p6 + p5 + p4 + p3 + p2 + p1 + 2 * (p0 + q0) + q1 + q2 + q3 + q4 + q5 + q6 + 8) >> 4;
489  else if (max_len_p + max_len_q == 12)
490  m = (p5 + p4 + p3 + p2 + 2 * (p1 + p0 + q0 + q1) + q2 + q3 + q4 + q5 + 8) >> 4;
491  else if (max_len_p + max_len_q == 8)
492  m = (p3 + p2 + p1 + p0 + q0 + q1 + q2 + q3 + 4) >> 3;
493  else if (max_len_q == 7)
494  m = (2 * (p2 + p1 + p0 + q0) + p0 + p1 + q1 + q2 + q3 + q4 + q5 + q6 + 8) >> 4;
495  else
496  m = (p6 + p5 + p4 + p3 + p2 + p1 + 2 * (q2 + q1 + q0 + p0) + q0 + q1 + 8) >> 4;
497  if (!no_p) {
498  const int refp = (P(max_len_p) + P(max_len_p - 1) + 1) >> 1;
499  if (max_len_p == 3) {
500  P0 = p0 + av_clip(((m * 53 + refp * 11 + 32) >> 6) - p0, -(tc * 6 >> 1), (tc * 6 >> 1));
501  P1 = p1 + av_clip(((m * 32 + refp * 32 + 32) >> 6) - p1, -(tc * 4 >> 1), (tc * 4 >> 1));
502  P2 = p2 + av_clip(((m * 11 + refp * 53 + 32) >> 6) - p2, -(tc * 2 >> 1), (tc * 2 >> 1));
503  } else if (max_len_p == 5) {
504  P0 = p0 + av_clip(((m * 58 + refp * 6 + 32) >> 6) - p0, -(tc * 6 >> 1), (tc * 6 >> 1));
505  P1 = p1 + av_clip(((m * 45 + refp * 19 + 32) >> 6) - p1, -(tc * 5 >> 1), (tc * 5 >> 1));
506  P2 = p2 + av_clip(((m * 32 + refp * 32 + 32) >> 6) - p2, -(tc * 4 >> 1), (tc * 4 >> 1));
507  P3 = p3 + av_clip(((m * 19 + refp * 45 + 32) >> 6) - p3, -(tc * 3 >> 1), (tc * 3 >> 1));
508  P4 = p4 + av_clip(((m * 6 + refp * 58 + 32) >> 6) - p4, -(tc * 2 >> 1), (tc * 2 >> 1));
509  } else {
510  P0 = p0 + av_clip(((m * 59 + refp * 5 + 32) >> 6) - p0, -(tc * 6 >> 1), (tc * 6 >> 1));
511  P1 = p1 + av_clip(((m * 50 + refp * 14 + 32) >> 6) - p1, -(tc * 5 >> 1), (tc * 5 >> 1));
512  P2 = p2 + av_clip(((m * 41 + refp * 23 + 32) >> 6) - p2, -(tc * 4 >> 1), (tc * 4 >> 1));
513  P3 = p3 + av_clip(((m * 32 + refp * 32 + 32) >> 6) - p3, -(tc * 3 >> 1), (tc * 3 >> 1));
514  P4 = p4 + av_clip(((m * 23 + refp * 41 + 32) >> 6) - p4, -(tc * 2 >> 1), (tc * 2 >> 1));
515  P5 = p5 + av_clip(((m * 14 + refp * 50 + 32) >> 6) - p5, -(tc * 1 >> 1), (tc * 1 >> 1));
516  P6 = p6 + av_clip(((m * 5 + refp * 59 + 32) >> 6) - p6, -(tc * 1 >> 1), (tc * 1 >> 1));
517  }
518  }
519  if (!no_q) {
520  const int refq = (Q(max_len_q) + Q(max_len_q - 1) + 1) >> 1;
521  if (max_len_q == 3) {
522  Q0 = q0 + av_clip(((m * 53 + refq * 11 + 32) >> 6) - q0, -(tc * 6 >> 1), (tc * 6 >> 1));
523  Q1 = q1 + av_clip(((m * 32 + refq * 32 + 32) >> 6) - q1, -(tc * 4 >> 1), (tc * 4 >> 1));
524  Q2 = q2 + av_clip(((m * 11 + refq * 53 + 32) >> 6) - q2, -(tc * 2 >> 1), (tc * 2 >> 1));
525  } else if (max_len_q == 5) {
526  Q0 = q0 + av_clip(((m * 58 + refq * 6 + 32) >> 6) - q0, -(tc * 6 >> 1), (tc * 6 >> 1));
527  Q1 = q1 + av_clip(((m * 45 + refq * 19 + 32) >> 6) - q1, -(tc * 5 >> 1), (tc * 5 >> 1));
528  Q2 = q2 + av_clip(((m * 32 + refq * 32 + 32) >> 6) - q2, -(tc * 4 >> 1), (tc * 4 >> 1));
529  Q3 = q3 + av_clip(((m * 19 + refq * 45 + 32) >> 6) - q3, -(tc * 3 >> 1), (tc * 3 >> 1));
530  Q4 = q4 + av_clip(((m * 6 + refq * 58 + 32) >> 6) - q4, -(tc * 2 >> 1), (tc * 2 >> 1));
531  } else {
532  Q0 = q0 + av_clip(((m * 59 + refq * 5 + 32) >> 6) - q0, -(tc * 6 >> 1), (tc * 6 >> 1));
533  Q1 = q1 + av_clip(((m * 50 + refq * 14 + 32) >> 6) - q1, -(tc * 5 >> 1), (tc * 5 >> 1));
534  Q2 = q2 + av_clip(((m * 41 + refq * 23 + 32) >> 6) - q2, -(tc * 4 >> 1), (tc * 4 >> 1));
535  Q3 = q3 + av_clip(((m * 32 + refq * 32 + 32) >> 6) - q3, -(tc * 3 >> 1), (tc * 3 >> 1));
536  Q4 = q4 + av_clip(((m * 23 + refq * 41 + 32) >> 6) - q4, -(tc * 2 >> 1), (tc * 2 >> 1));
537  Q5 = q5 + av_clip(((m * 14 + refq * 50 + 32) >> 6) - q5, -(tc * 1 >> 1), (tc * 1 >> 1));
538  Q6 = q6 + av_clip(((m * 5 + refq * 59 + 32) >> 6) - q6, -(tc * 1 >> 1), (tc * 1 >> 1));
539  }
540 
541  }
542  pix += ystride;
543  }
544 }
545 
546 static void FUNC(vvc_loop_filter_luma)(uint8_t* _pix, ptrdiff_t _xstride, ptrdiff_t _ystride,
547  const int32_t *_beta, const int32_t *_tc, const uint8_t *_no_p, const uint8_t *_no_q,
548  const uint8_t *_max_len_p, const uint8_t *_max_len_q, const int hor_ctu_edge)
549 {
550  const ptrdiff_t xstride = _xstride / sizeof(pixel);
551  const ptrdiff_t ystride = _ystride / sizeof(pixel);
552 
553  for (int i = 0; i < 2; i++) {
554 #if BIT_DEPTH < 10
555  const int tc = (_tc[i] + (1 << (9 - BIT_DEPTH))) >> (10 - BIT_DEPTH);
556 #else
557  const int tc = _tc[i] << (BIT_DEPTH - 10);
558 #endif
559  if (tc) {
560  pixel* pix = (pixel*)_pix + i * 4 * ystride;
561  const int dp0 = abs(P2 - 2 * P1 + P0);
562  const int dq0 = abs(Q2 - 2 * Q1 + Q0);
563  const int dp3 = abs(TP2 - 2 * TP1 + TP0);
564  const int dq3 = abs(TQ2 - 2 * TQ1 + TQ0);
565  const int d0 = dp0 + dq0;
566  const int d3 = dp3 + dq3;
567  const int tc25 = ((tc * 5 + 1) >> 1);
568 
569  const int no_p = _no_p[i];
570  const int no_q = _no_q[i];
571 
572  int max_len_p = _max_len_p[i];
573  int max_len_q = _max_len_q[i];
574 
575  const int large_p = (max_len_p > 3 && !hor_ctu_edge);
576  const int large_q = max_len_q > 3;
577 
578  const int beta = _beta[i] << BIT_DEPTH - 8;
579  const int beta_3 = beta >> 3;
580  const int beta_2 = beta >> 2;
581 
582  if (large_p || large_q) {
583  const int dp0l = large_p ? ((dp0 + abs(P5 - 2 * P4 + P3) + 1) >> 1) : dp0;
584  const int dq0l = large_q ? ((dq0 + abs(Q5 - 2 * Q4 + Q3) + 1) >> 1) : dq0;
585  const int dp3l = large_p ? ((dp3 + abs(TP5 - 2 * TP4 + TP3) + 1) >> 1) : dp3;
586  const int dq3l = large_q ? ((dq3 + abs(TQ5 - 2 * TQ4 + TQ3) + 1) >> 1) : dq3;
587  const int d0l = dp0l + dq0l;
588  const int d3l = dp3l + dq3l;
589  const int beta53 = beta * 3 >> 5;
590  const int beta_4 = beta >> 4;
591  max_len_p = large_p ? max_len_p : 3;
592  max_len_q = large_q ? max_len_q : 3;
593 
594  if (d0l + d3l < beta) {
595  const int sp0l = abs(P3 - P0) + (max_len_p == 7 ? abs(P7 - P6 - P5 + P4) : 0);
596  const int sq0l = abs(Q0 - Q3) + (max_len_q == 7 ? abs(Q4 - Q5 - Q6 + Q7) : 0);
597  const int sp3l = abs(TP3 - TP0) + (max_len_p == 7 ? abs(TP7 - TP6 - TP5 + TP4) : 0);
598  const int sq3l = abs(TQ0 - TQ3) + (max_len_q == 7 ? abs(TQ4 - TQ5 - TQ6 + TQ7) : 0);
599  const int sp0 = large_p ? ((sp0l + abs(P3 - P(max_len_p)) + 1) >> 1) : sp0l;
600  const int sp3 = large_p ? ((sp3l + abs(TP3 - TP(max_len_p)) + 1) >> 1) : sp3l;
601  const int sq0 = large_q ? ((sq0l + abs(Q3 - Q(max_len_q)) + 1) >> 1) : sq0l;
602  const int sq3 = large_q ? ((sq3l + abs(TQ3 - TQ(max_len_q)) + 1) >> 1) : sq3l;
603  if (sp0 + sq0 < beta53 && abs(P0 - Q0) < tc25 &&
604  sp3 + sq3 < beta53 && abs(TP0 - TQ0) < tc25 &&
605  (d0l << 1) < beta_4 && (d3l << 1) < beta_4) {
606  FUNC(loop_filter_luma_large)(pix, xstride, ystride, tc, no_p, no_q, max_len_p, max_len_q);
607  continue;
608  }
609  }
610  }
611  if (d0 + d3 < beta) {
612  if (max_len_p > 2 && max_len_q > 2 &&
613  abs(P3 - P0) + abs(Q3 - Q0) < beta_3 && abs(P0 - Q0) < tc25 &&
614  abs(TP3 - TP0) + abs(TQ3 - TQ0) < beta_3 && abs(TP0 - TQ0) < tc25 &&
615  (d0 << 1) < beta_2 && (d3 << 1) < beta_2) {
616  FUNC(loop_filter_luma_strong)(pix, xstride, ystride, tc, tc << 1, tc * 3, no_p, no_q);
617  } else {
618  int nd_p = 1;
619  int nd_q = 1;
620  if (max_len_p > 1 && max_len_q > 1) {
621  if (dp0 + dp3 < ((beta + (beta >> 1)) >> 3))
622  nd_p = 2;
623  if (dq0 + dq3 < ((beta + (beta >> 1)) >> 3))
624  nd_q = 2;
625  }
626  FUNC(loop_filter_luma_weak)(pix, xstride, ystride, tc, beta, no_p, no_q, nd_p, nd_q);
627  }
628  }
629  }
630  }
631 }
632 
633 static void FUNC(loop_filter_chroma_strong)(pixel *pix, const ptrdiff_t xstride, const ptrdiff_t ystride,
634  const int size, const int32_t tc, const uint8_t no_p, const uint8_t no_q)
635 {
636  for (int d = 0; d < size; d++) {
637  const int p3 = P3;
638  const int p2 = P2;
639  const int p1 = P1;
640  const int p0 = P0;
641  const int q0 = Q0;
642  const int q1 = Q1;
643  const int q2 = Q2;
644  const int q3 = Q3;
645  if (!no_p) {
646  P0 = av_clip((p3 + p2 + p1 + 2 * p0 + q0 + q1 + q2 + 4) >> 3, p0 - tc, p0 + tc);
647  P1 = av_clip((2 * p3 + p2 + 2 * p1 + p0 + q0 + q1 + 4) >> 3, p1 - tc, p1 + tc);
648  P2 = av_clip((3 * p3 + 2 * p2 + p1 + p0 + q0 + 4) >> 3, p2 - tc, p2 + tc );
649  }
650  if (!no_q) {
651  Q0 = av_clip((p2 + p1 + p0 + 2 * q0 + q1 + q2 + q3 + 4) >> 3, q0 - tc, q0 + tc);
652  Q1 = av_clip((p1 + p0 + q0 + 2 * q1 + q2 + 2 * q3 + 4) >> 3, q1 - tc, q1 + tc);
653  Q2 = av_clip((p0 + q0 + q1 + 2 * q2 + 3 * q3 + 4) >> 3, q2 - tc, q2 + tc);
654  }
655  pix += ystride;
656  }
657 }
658 
659 static void FUNC(loop_filter_chroma_strong_one_side)(pixel *pix, const ptrdiff_t xstride, const ptrdiff_t ystride,
660  const int size, const int32_t tc, const uint8_t no_p, const uint8_t no_q)
661 {
662  for (int d = 0; d < size; d++) {
663  const int p1 = P1;
664  const int p0 = P0;
665  const int q0 = Q0;
666  const int q1 = Q1;
667  const int q2 = Q2;
668  const int q3 = Q3;
669  if (!no_p) {
670  P0 = av_clip((3 * p1 + 2 * p0 + q0 + q1 + q2 + 4) >> 3, p0 - tc, p0 + tc);
671  }
672  if (!no_q) {
673  Q0 = av_clip((2 * p1 + p0 + 2 * q0 + q1 + q2 + q3 + 4) >> 3, q0 - tc, q0 + tc);
674  Q1 = av_clip((p1 + p0 + q0 + 2 * q1 + q2 + 2 * q3 + 4) >> 3, q1 - tc, q1 + tc);
675  Q2 = av_clip((p0 + q0 + q1 + 2 * q2 + 3 * q3 + 4) >> 3, q2 - tc, q2 + tc);
676  }
677  pix += ystride;
678  }
679 }
680 
681 static void FUNC(vvc_loop_filter_chroma)(uint8_t *_pix, const ptrdiff_t _xstride, const ptrdiff_t _ystride,
682  const int32_t *_beta, const int32_t *_tc, const uint8_t *_no_p, const uint8_t *_no_q,
683  const uint8_t *_max_len_p, const uint8_t *_max_len_q, const int shift)
684 {
685  const ptrdiff_t xstride = _xstride / sizeof(pixel);
686  const ptrdiff_t ystride = _ystride / sizeof(pixel);
687  const int size = shift ? 2 : 4;
688  const int end = 8 / size; // 8 samples a loop
689 
690  for (int i = 0; i < end; i++) {
691 #if BIT_DEPTH < 10
692  const int tc = (_tc[i] + (1 << (9 - BIT_DEPTH))) >> (10 - BIT_DEPTH);
693 #else
694  const int tc = _tc[i] << (BIT_DEPTH - 10);
695 #endif
696  if (tc) {
697  pixel *pix = (pixel *)_pix + i * size * ystride;
698  const uint8_t no_p = _no_p[i];
699  const uint8_t no_q = _no_q[i];
700 
701  const int beta = _beta[i] << (BIT_DEPTH - 8);
702  const int beta_3 = beta >> 3;
703  const int beta_2 = beta >> 2;
704 
705  const int tc25 = ((tc * 5 + 1) >> 1);
706 
707  uint8_t max_len_p = _max_len_p[i];
708  uint8_t max_len_q = _max_len_q[i];
709 
710  if (!max_len_p || !max_len_q)
711  continue;
712 
713  if (max_len_q == 3){
714  const int p1n = shift ? FP1 : TP1;
715  const int p2n = max_len_p == 1 ? p1n : (shift ? FP2 : TP2);
716  const int p0n = shift ? FP0 : TP0;
717  const int q0n = shift ? FQ0 : TQ0;
718  const int q1n = shift ? FQ1 : TQ1;
719  const int q2n = shift ? FQ2 : TQ2;
720  const int p3 = max_len_p == 1 ? P1 : P3;
721  const int p2 = max_len_p == 1 ? P1 : P2;
722  const int p1 = P1;
723  const int p0 = P0;
724  const int dp0 = abs(p2 - 2 * p1 + p0);
725  const int dq0 = abs(Q2 - 2 * Q1 + Q0);
726 
727  const int dp1 = abs(p2n - 2 * p1n + p0n);
728  const int dq1 = abs(q2n - 2 * q1n + q0n);
729  const int d0 = dp0 + dq0;
730  const int d1 = dp1 + dq1;
731 
732  if (d0 + d1 < beta) {
733  const int p3n = max_len_p == 1 ? p1n : (shift ? FP3 : TP3);
734  const int q3n = shift ? FQ3 : TQ3;
735  const int dsam0 = (d0 << 1) < beta_2 && (abs(p3 - p0) + abs(Q0 - Q3) < beta_3) &&
736  abs(p0 - Q0) < tc25;
737  const int dsam1 = (d1 << 1) < beta_2 && (abs(p3n - p0n) + abs(q0n - q3n) < beta_3) &&
738  abs(p0n - q0n) < tc25;
739  if (!dsam0 || !dsam1)
740  max_len_p = max_len_q = 1;
741  } else {
742  max_len_p = max_len_q = 1;
743  }
744  }
745 
746  if (max_len_p == 3 && max_len_q == 3)
747  FUNC(loop_filter_chroma_strong)(pix, xstride, ystride, size, tc, no_p, no_q);
748  else if (max_len_q == 3)
749  FUNC(loop_filter_chroma_strong_one_side)(pix, xstride, ystride, size, tc, no_p, no_q);
750  else
751  FUNC(loop_filter_chroma_weak)(pix, xstride, ystride, size, tc, no_p, no_q);
752  }
753  }
754 }
755 
756 static void FUNC(vvc_h_loop_filter_chroma)(uint8_t *pix, ptrdiff_t stride,
757  const int32_t *beta, const int32_t *tc, const uint8_t *no_p, const uint8_t *no_q,
758  const uint8_t *max_len_p, const uint8_t *max_len_q, int shift)
759 {
760  FUNC(vvc_loop_filter_chroma)(pix, stride, sizeof(pixel), beta, tc,
761  no_p, no_q, max_len_p, max_len_q, shift);
762 }
763 
764 static void FUNC(vvc_v_loop_filter_chroma)(uint8_t *pix, ptrdiff_t stride,
765  const int32_t *beta, const int32_t *tc, const uint8_t *no_p, const uint8_t *no_q,
766  const uint8_t *max_len_p, const uint8_t *max_len_q, int shift)
767 {
768  FUNC(vvc_loop_filter_chroma)(pix, sizeof(pixel), stride, beta, tc,
769  no_p, no_q, max_len_p, max_len_q, shift);
770 }
771 
772 static void FUNC(vvc_h_loop_filter_luma)(uint8_t *pix, ptrdiff_t stride,
773  const int32_t *beta, const int32_t *tc, const uint8_t *no_p, const uint8_t *no_q,
774  const uint8_t *max_len_p, const uint8_t *max_len_q, const int hor_ctu_edge)
775 {
776  FUNC(vvc_loop_filter_luma)(pix, stride, sizeof(pixel), beta, tc,
777  no_p, no_q, max_len_p, max_len_q, hor_ctu_edge);
778 }
779 
780 static void FUNC(vvc_v_loop_filter_luma)(uint8_t *pix, ptrdiff_t stride,
781  const int32_t *beta, const int32_t *tc, const uint8_t *no_p, const uint8_t *no_q,
782  const uint8_t *max_len_p, const uint8_t *max_len_q, const int hor_ctu_edge)
783 {
784  FUNC(vvc_loop_filter_luma)(pix, sizeof(pixel), stride, beta, tc,
785  no_p, no_q, max_len_p, max_len_q, hor_ctu_edge);
786 }
787 
788 static int FUNC(vvc_loop_ladf_level)(const uint8_t *_pix, const ptrdiff_t _xstride, const ptrdiff_t _ystride)
789 {
790  const pixel *pix = (pixel *)_pix;
791  const ptrdiff_t xstride = _xstride / sizeof(pixel);
792  const ptrdiff_t ystride = _ystride / sizeof(pixel);
793  return (P0 + TP0 + Q0 + TQ0) >> 2;
794 }
795 
796 static int FUNC(vvc_h_loop_ladf_level)(const uint8_t *pix, ptrdiff_t stride)
797 {
798  return FUNC(vvc_loop_ladf_level)(pix, stride, sizeof(pixel));
799 }
800 
801 static int FUNC(vvc_v_loop_ladf_level)(const uint8_t *pix, ptrdiff_t stride)
802 {
803  return FUNC(vvc_loop_ladf_level)(pix, sizeof(pixel), stride);
804 }
805 
806 #undef P7
807 #undef P6
808 #undef P5
809 #undef P4
810 #undef P3
811 #undef P2
812 #undef P1
813 #undef P0
814 #undef Q0
815 #undef Q1
816 #undef Q2
817 #undef Q3
818 #undef Q4
819 #undef Q5
820 #undef Q6
821 #undef Q7
822 
823 #undef TP7
824 #undef TP6
825 #undef TP5
826 #undef TP4
827 #undef TP3
828 #undef TP2
829 #undef TP1
830 #undef TP0
831 #undef TQ0
832 #undef TQ1
833 #undef TQ2
834 #undef TQ3
835 #undef TQ4
836 #undef TQ5
837 #undef TQ6
838 #undef TQ7
839 
840 static void FUNC(ff_vvc_lmcs_dsp_init)(VVCLMCSDSPContext *const lmcs)
841 {
842  lmcs->filter = FUNC(lmcs_filter_luma);
843 }
844 
845 static void FUNC(ff_vvc_lf_dsp_init)(VVCLFDSPContext *const lf)
846 {
847  lf->ladf_level[0] = FUNC(vvc_h_loop_ladf_level);
848  lf->ladf_level[1] = FUNC(vvc_v_loop_ladf_level);
849  lf->filter_luma[0] = FUNC(vvc_h_loop_filter_luma);
850  lf->filter_luma[1] = FUNC(vvc_v_loop_filter_luma);
851  lf->filter_chroma[0] = FUNC(vvc_h_loop_filter_chroma);
852  lf->filter_chroma[1] = FUNC(vvc_v_loop_filter_chroma);
853 }
854 
855 static void FUNC(ff_vvc_sao_dsp_init)(VVCSAODSPContext *const sao)
856 {
857  for (int i = 0; i < FF_ARRAY_ELEMS(sao->band_filter); i++)
858  sao->band_filter[i] = FUNC(sao_band_filter);
859  for (int i = 0; i < FF_ARRAY_ELEMS(sao->edge_filter); i++)
860  sao->edge_filter[i] = FUNC(sao_edge_filter);
861  sao->edge_restore[0] = FUNC(sao_edge_restore_0);
862  sao->edge_restore[1] = FUNC(sao_edge_restore_1);
863 }
864 
865 static void FUNC(ff_vvc_alf_dsp_init)(VVCALFDSPContext *const alf)
866 {
867  alf->filter[LUMA] = FUNC(alf_filter_luma);
868  alf->filter[CHROMA] = FUNC(alf_filter_chroma);
869  alf->filter_cc = FUNC(alf_filter_cc);
870  alf->classify = FUNC(alf_classify);
871  alf->recon_coeff_and_clip = FUNC(alf_recon_coeff_and_clip);
872 }
q1
static const uint8_t q1[256]
Definition: twofish.c:100
s5
#define s5
Definition: regdef.h:42
av_clip
#define av_clip
Definition: common.h:99
TP0
#define TP0
Definition: filter_template.c:443
BIT_DEPTH
#define BIT_DEPTH
Definition: aom_film_grain.c:61
FP1
#define FP1
Definition: filter_template.c:457
loop_filter_chroma_strong
static void FUNC() loop_filter_chroma_strong(pixel *pix, const ptrdiff_t xstride, const ptrdiff_t ystride, const int size, const int32_t tc, const uint8_t no_p, const uint8_t no_q)
Definition: filter_template.c:633
av_clip_uintp2
#define av_clip_uintp2
Definition: common.h:123
alf_get_idx
static void FUNC() alf_get_idx(int *class_idx, int *transpose_idx, const int *sum, const int ac)
Definition: filter_template.c:270
w
uint8_t w
Definition: llviddspenc.c:38
FQ0
#define FQ0
Definition: filter_template.c:459
TQ6
#define TQ6
Definition: filter_template.c:450
ALF_DIR_VERT
#define ALF_DIR_VERT
Definition: filter_template.c:265
Q5
#define Q5
Definition: filter_template.c:429
filter
filter_frame For filters that do not use the this method is called when a frame is pushed to the filter s input It can be called at any time except in a reentrant way If the input frame is enough to produce then the filter should push the output frames on the output link immediately As an exception to the previous rule if the input frame is enough to produce several output frames then the filter needs output only at least one per link The additional frames can be left buffered in the filter
Definition: filter_design.txt:228
FFMAX
#define FFMAX(a, b)
Definition: macros.h:47
TQ1
#define TQ1
Definition: filter_template.c:445
vvc_loop_filter_chroma
static void FUNC() vvc_loop_filter_chroma(uint8_t *_pix, const ptrdiff_t _xstride, const ptrdiff_t _ystride, const int32_t *_beta, const int32_t *_tc, const uint8_t *_no_p, const uint8_t *_no_q, const uint8_t *_max_len_p, const uint8_t *_max_len_q, const int shift)
Definition: filter_template.c:681
sao_edge_restore_1
static void FUNC() sao_edge_restore_1(uint8_t *_dst, const uint8_t *_src, ptrdiff_t stride_dst, ptrdiff_t stride_src, const SAOParams *sao, const int *borders, int _width, int _height, int c_idx, const uint8_t *vert_edge, const uint8_t *horiz_edge, const uint8_t *diag_edge)
Definition: h2656_sao_template.c:131
loop_filter_luma_strong
static void FUNC() loop_filter_luma_strong(pixel *pix, const ptrdiff_t xstride, const ptrdiff_t ystride, const int32_t tc, const int32_t tc2, const int tc3, const uint8_t no_p, const uint8_t no_q)
Definition: h2656_deblock_template.c:25
ff_vvc_lmcs_dsp_init
static void FUNC() ff_vvc_lmcs_dsp_init(VVCLMCSDSPContext *const lmcs)
Definition: filter_template.c:840
Q1
#define Q1
Definition: filter_template.c:425
sao_edge_restore_0
static void FUNC() sao_edge_restore_0(uint8_t *_dst, const uint8_t *_src, ptrdiff_t stride_dst, ptrdiff_t stride_src, const SAOParams *sao, const int *borders, int _width, int _height, int c_idx, const uint8_t *vert_edge, const uint8_t *horiz_edge, const uint8_t *diag_edge)
Definition: h2656_sao_template.c:81
FP3
#define FP3
Definition: filter_template.c:455
Q3
#define Q3
Definition: filter_template.c:427
s3
#define s3
Definition: regdef.h:40
b1
static double b1(void *priv, double x, double y)
Definition: vf_xfade.c:2035
TP5
#define TP5
Definition: filter_template.c:438
v0
#define v0
Definition: regdef.h:26
P
#define P(x)
Definition: filter_template.c:432
vvc_v_loop_filter_chroma
static void FUNC() vvc_v_loop_filter_chroma(uint8_t *pix, ptrdiff_t stride, const int32_t *beta, const int32_t *tc, const uint8_t *no_p, const uint8_t *no_q, const uint8_t *max_len_p, const uint8_t *max_len_q, int shift)
Definition: filter_template.c:764
P1
#define P1
Definition: filter_template.c:422
ALF_GRADIENT_BORDER
#define ALF_GRADIENT_BORDER
Definition: ctu.h:83
a1
#define a1
Definition: regdef.h:47
ALF_DIR_HORZ
#define ALF_DIR_HORZ
Definition: filter_template.c:266
TQ3
#define TQ3
Definition: filter_template.c:447
vvc_v_loop_ladf_level
static int FUNC() vvc_v_loop_ladf_level(const uint8_t *pix, ptrdiff_t stride)
Definition: filter_template.c:801
FF_ARRAY_ELEMS
#define FF_ARRAY_ELEMS(a)
Definition: sinewin_tablegen.c:29
alf_filter_cc
static void FUNC() alf_filter_cc(uint8_t *_dst, ptrdiff_t dst_stride, const uint8_t *_luma, const ptrdiff_t luma_stride, const int width, const int height, const int hs, const int vs, const int16_t *filter, const int vb_pos)
Definition: filter_template.c:223
clip
clip
Definition: af_crystalizer.c:121
width
#define width
sao_band_filter
static void FUNC() sao_band_filter(uint8_t *_dst, const uint8_t *_src, ptrdiff_t stride_dst, ptrdiff_t stride_src, const int16_t *sao_offset_val, int sao_left_class, int width, int height)
Definition: h2656_sao_template.c:24
ALF_DIR_DIGA1
#define ALF_DIR_DIGA1
Definition: filter_template.c:268
loop_filter_luma_large
static void FUNC() loop_filter_luma_large(pixel *pix, const ptrdiff_t xstride, const ptrdiff_t ystride, const int32_t tc, const uint8_t no_p, const uint8_t no_q, const uint8_t max_len_p, const uint8_t max_len_q)
Definition: filter_template.c:466
Q4
#define Q4
Definition: filter_template.c:428
s1
#define s1
Definition: regdef.h:38
VVCALFDSPContext
Definition: dsp.h:159
TP2
#define TP2
Definition: filter_template.c:441
vvc_h_loop_filter_luma
static void FUNC() vvc_h_loop_filter_luma(uint8_t *pix, ptrdiff_t stride, const int32_t *beta, const int32_t *tc, const uint8_t *no_p, const uint8_t *no_q, const uint8_t *max_len_p, const uint8_t *max_len_q, const int hor_ctu_edge)
Definition: filter_template.c:772
loop_filter_chroma_weak
static void FUNC() loop_filter_chroma_weak(pixel *pix, const ptrdiff_t xstride, const ptrdiff_t ystride, const int size, const int32_t tc, const uint8_t no_p, const uint8_t no_q)
Definition: h2656_deblock_template.c:83
q0
static const uint8_t q0[256]
Definition: twofish.c:81
FFABS
#define FFABS(a)
Absolute value, Note, INT_MIN / INT64_MIN result in undefined behavior as they are not representable ...
Definition: common.h:73
TQ5
#define TQ5
Definition: filter_template.c:449
ALF_DIR_DIGA0
#define ALF_DIR_DIGA0
Definition: filter_template.c:267
pixel
uint8_t pixel
Definition: tiny_ssim.c:41
Q6
#define Q6
Definition: filter_template.c:430
s6
#define s6
Definition: regdef.h:43
P0
#define P0
Definition: filter_template.c:423
h2656_deblock_template.c
ff_vvc_alf_dsp_init
static void FUNC() ff_vvc_alf_dsp_init(VVCALFDSPContext *const alf)
Definition: filter_template.c:865
TQ2
#define TQ2
Definition: filter_template.c:446
FQ1
#define FQ1
Definition: filter_template.c:460
ALF_NUM_COEFF_LUMA
#define ALF_NUM_COEFF_LUMA
Definition: ps.h:161
ALF_NUM_DIR
#define ALF_NUM_DIR
Definition: ctu.h:85
abs
#define abs(x)
Definition: cuda_runtime.h:35
VVCSAODSPContext
Definition: dsp.h:148
Q0
#define Q0
Definition: filter_template.c:424
index
int index
Definition: gxfenc.c:90
alf_classify
static void FUNC() alf_classify(int *class_idx, int *transpose_idx, const uint8_t *_src, const ptrdiff_t _src_stride, const int width, const int height, const int vb_pos, int *gradient_tmp)
Definition: filter_template.c:299
s2
#define s2
Definition: regdef.h:39
Q2
#define Q2
Definition: filter_template.c:426
shift
static int shift(int a, int b)
Definition: bonk.c:261
P6
#define P6
Definition: filter_template.c:417
VVCLMCSDSPContext
Definition: dsp.h:134
size
int size
Definition: twinvq_data.h:10344
vvc_h_loop_ladf_level
static int FUNC() vvc_h_loop_ladf_level(const uint8_t *pix, ptrdiff_t stride)
Definition: filter_template.c:796
ALF_BLOCK_SIZE
#define ALF_BLOCK_SIZE
Definition: ctu.h:74
TP4
#define TP4
Definition: filter_template.c:439
FQ3
#define FQ3
Definition: filter_template.c:462
TQ0
#define TQ0
Definition: filter_template.c:444
TP1
#define TP1
Definition: filter_template.c:442
height
#define height
TQ
#define TQ(x)
Definition: filter_template.c:453
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
alf_filter_luma
static void FUNC() alf_filter_luma(uint8_t *_dst, ptrdiff_t dst_stride, const uint8_t *_src, ptrdiff_t src_stride, const int width, const int height, const int16_t *filter, const int16_t *clip, const int vb_pos)
Definition: filter_template.c:43
TP3
#define TP3
Definition: filter_template.c:440
a0
#define a0
Definition: regdef.h:46
TP
#define TP(x)
Definition: filter_template.c:452
alf_filter_chroma
static void FUNC() alf_filter_chroma(uint8_t *_dst, ptrdiff_t dst_stride, const uint8_t *_src, ptrdiff_t src_stride, const int width, const int height, const int16_t *filter, const int16_t *clip, const int vb_pos)
Definition: filter_template.c:137
ff_vvc_lf_dsp_init
static void FUNC() ff_vvc_lf_dsp_init(VVCLFDSPContext *const lf)
Definition: filter_template.c:845
P3
#define P3
Definition: filter_template.c:420
vvc_h_loop_filter_chroma
static void FUNC() vvc_h_loop_filter_chroma(uint8_t *pix, ptrdiff_t stride, const int32_t *beta, const int32_t *tc, const uint8_t *no_p, const uint8_t *no_q, const uint8_t *max_len_p, const uint8_t *max_len_q, int shift)
Definition: filter_template.c:756
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:256
vvc_loop_filter_luma
static void FUNC() vvc_loop_filter_luma(uint8_t *_pix, ptrdiff_t _xstride, ptrdiff_t _ystride, const int32_t *_beta, const int32_t *_tc, const uint8_t *_no_p, const uint8_t *_no_q, const uint8_t *_max_len_p, const uint8_t *_max_len_q, const int hor_ctu_edge)
Definition: filter_template.c:546
FP0
#define FP0
Definition: filter_template.c:458
av_always_inline
#define av_always_inline
Definition: attributes.h:49
P2
#define P2
Definition: filter_template.c:421
FFMIN
#define FFMIN(a, b)
Definition: macros.h:49
alf_clip
static av_always_inline int16_t FUNC() alf_clip(pixel curr, pixel v0, pixel v1, int16_t clip)
Definition: filter_template.c:38
s4
#define s4
Definition: regdef.h:41
ff_vvc_sao_dsp_init
static void FUNC() ff_vvc_sao_dsp_init(VVCSAODSPContext *const sao)
Definition: filter_template.c:855
TQ7
#define TQ7
Definition: filter_template.c:451
stride
#define stride
Definition: h264pred_template.c:537
sao_edge_filter
static void FUNC() sao_edge_filter(uint8_t *_dst, const uint8_t *_src, ptrdiff_t stride_dst, const int16_t *sao_offset_val, int eo, int width, int height)
Definition: h2656_sao_template.c:50
CHROMA
@ CHROMA
Definition: vf_waveform.c:49
av_clip_pixel
#define av_clip_pixel(a)
Definition: bit_depth_template.c:98
pos
unsigned int pos
Definition: spdifenc.c:414
loop_filter_chroma_strong_one_side
static void FUNC() loop_filter_chroma_strong_one_side(pixel *pix, const ptrdiff_t xstride, const ptrdiff_t ystride, const int size, const int32_t tc, const uint8_t no_p, const uint8_t no_q)
Definition: filter_template.c:659
FQ2
#define FQ2
Definition: filter_template.c:461
FUNC
#define FUNC(a)
Definition: bit_depth_template.c:104
TQ4
#define TQ4
Definition: filter_template.c:448
loop_filter_luma_weak
static void FUNC() loop_filter_luma_weak(pixel *pix, const ptrdiff_t xstride, const ptrdiff_t ystride, const int32_t tc, const int32_t beta, const uint8_t no_p, const uint8_t no_q, const int nd_p, const int nd_q)
Definition: h2656_deblock_template.c:52
P7
#define P7
Definition: filter_template.c:416
tc
#define tc
Definition: regdef.h:69
ALF_GRADIENT_STEP
#define ALF_GRADIENT_STEP
Definition: ctu.h:82
Q7
#define Q7
Definition: filter_template.c:431
CLIP
@ CLIP
Definition: qdrw.c:37
s0
#define s0
Definition: regdef.h:37
VVCLFDSPContext
Definition: dsp.h:138
P4
#define P4
Definition: filter_template.c:419
src
INIT_CLIP pixel * src
Definition: h264pred_template.c:418
P5
#define P5
Definition: filter_template.c:418
d
d
Definition: ffmpeg_filter.c:424
int32_t
int32_t
Definition: audioconvert.c:56
Q
#define Q(x)
Definition: filter_template.c:433
TP6
#define TP6
Definition: filter_template.c:437
coeff
static const double coeff[2][5]
Definition: vf_owdenoise.c:80
alf_recon_coeff_and_clip
static void FUNC() alf_recon_coeff_and_clip(int16_t *coeff, int16_t *clip, const int *class_idx, const int *transpose_idx, const int size, const int16_t *coeff_set, const uint8_t *clip_idx_set, const uint8_t *class_to_filt)
Definition: filter_template.c:383
FP2
#define FP2
Definition: filter_template.c:456
b0
static double b0(void *priv, double x, double y)
Definition: vf_xfade.c:2034
h
h
Definition: vp9dsp_template.c:2038
vvc_v_loop_filter_luma
static void FUNC() vvc_v_loop_filter_luma(uint8_t *pix, ptrdiff_t stride, const int32_t *beta, const int32_t *tc, const uint8_t *no_p, const uint8_t *no_q, const uint8_t *max_len_p, const uint8_t *max_len_q, const int hor_ctu_edge)
Definition: filter_template.c:780
LUMA
#define LUMA
Definition: hevc_filter.c:31
TP7
#define TP7
Definition: filter_template.c:436
vvc_loop_ladf_level
static int FUNC() vvc_loop_ladf_level(const uint8_t *_pix, const ptrdiff_t _xstride, const ptrdiff_t _ystride)
Definition: filter_template.c:788
h2656_sao_template.c
lmcs_filter_luma
static void FUNC() lmcs_filter_luma(uint8_t *_dst, ptrdiff_t dst_stride, const int width, const int height, const void *_lut)
Definition: filter_template.c:25