FFmpeg
vf_removegrain.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2012 Laurent de Soras
3  * Copyright (c) 2013 Fredrik Mellbin
4  * Copyright (c) 2015 Paul B Mahol
5  * Copyright (c) 2015 James Darnley
6  *
7  * This file is part of FFmpeg.
8  *
9  * FFmpeg is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU Lesser General Public
11  * License as published by the Free Software Foundation; either
12  * version 2.1 of the License, or (at your option) any later version.
13  *
14  * FFmpeg is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17  * Lesser General Public License for more details.
18  *
19  * You should have received a copy of the GNU Lesser General Public
20  * License along with FFmpeg; if not, write to the Free Software
21  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22  */
23 
24 #include "libavutil/imgutils.h"
25 #include "libavutil/opt.h"
26 #include "libavutil/pixdesc.h"
27 #include "libavutil/qsort.h"
28 #include "avfilter.h"
29 #include "formats.h"
30 #include "internal.h"
31 #include "removegrain.h"
32 #include "video.h"
33 
34 #define OFFSET(x) offsetof(RemoveGrainContext, x)
35 #define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM
36 
37 static const AVOption removegrain_options[] = {
38  { "m0", "set mode for 1st plane", OFFSET(mode[0]), AV_OPT_TYPE_INT, {.i64=0}, 0, 24, FLAGS },
39  { "m1", "set mode for 2nd plane", OFFSET(mode[1]), AV_OPT_TYPE_INT, {.i64=0}, 0, 24, FLAGS },
40  { "m2", "set mode for 3rd plane", OFFSET(mode[2]), AV_OPT_TYPE_INT, {.i64=0}, 0, 24, FLAGS },
41  { "m3", "set mode for 4th plane", OFFSET(mode[3]), AV_OPT_TYPE_INT, {.i64=0}, 0, 24, FLAGS },
42  {NULL}
43 };
44 
45 AVFILTER_DEFINE_CLASS(removegrain);
46 
47 static const enum AVPixelFormat pix_fmts[] = {
56 };
57 
58 #define REMOVE_GRAIN_SORT_AXIS \
59  const int ma1 = FFMAX(a1, a8); \
60  const int mi1 = FFMIN(a1, a8); \
61  const int ma2 = FFMAX(a2, a7); \
62  const int mi2 = FFMIN(a2, a7); \
63  const int ma3 = FFMAX(a3, a6); \
64  const int mi3 = FFMIN(a3, a6); \
65  const int ma4 = FFMAX(a4, a5); \
66  const int mi4 = FFMIN(a4, a5);
67 
68 static int mode01(int c, int a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8)
69 {
70  const int mi = FFMIN(FFMIN(FFMIN(a1, a2), FFMIN(a3, a4)), FFMIN(FFMIN(a5, a6), FFMIN(a7, a8)));
71  const int ma = FFMAX(FFMAX(FFMAX(a1, a2), FFMAX(a3, a4)), FFMAX(FFMAX(a5, a6), FFMAX(a7, a8)));
72 
73  return av_clip(c, mi, ma);
74 }
75 
76 static int cmp_int(const void *p1, const void *p2)
77 {
78  int left = *(const int *)p1;
79  int right = *(const int *)p2;
80  return FFDIFFSIGN(left, right);
81 }
82 
83 static int mode02(int c, int a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8)
84 {
85  int a[8] = { a1, a2, a3, a4, a5, a6, a7, a8 };
86 
87  AV_QSORT(a, 8, int, cmp_int);
88 
89  return av_clip(c, a[2 - 1 ], a[7 - 1]);
90 }
91 
92 static int mode03(int c, int a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8)
93 {
94  int a[8] = { a1, a2, a3, a4, a5, a6, a7, a8 };
95 
96  AV_QSORT(a, 8, int, cmp_int);
97 
98  return av_clip(c, a[3 - 1 ], a[6 - 1]);
99 }
100 
101 static int mode04(int c, int a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8)
102 {
103  int a[8] = { a1, a2, a3, a4, a5, a6, a7, a8 };
104 
105  AV_QSORT(a, 8, int, cmp_int);
106 
107  return av_clip(c, a[4 - 1 ], a[5 - 1]);
108 }
109 
110 static int mode05(int c, int a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8)
111 {
113 
114  const int c1 = FFABS(c - av_clip(c, mi1, ma1));
115  const int c2 = FFABS(c - av_clip(c, mi2, ma2));
116  const int c3 = FFABS(c - av_clip(c, mi3, ma3));
117  const int c4 = FFABS(c - av_clip(c, mi4, ma4));
118 
119  const int mindiff = FFMIN(FFMIN(c1, c2), FFMIN(c3, c4));
120 
121  /* When adding SIMD notice the return order here: 4, 2, 3, 1. */
122  if (mindiff == c4) {
123  return av_clip(c, mi4, ma4);
124  } else if (mindiff == c2) {
125  return av_clip(c, mi2, ma2);
126  } else if (mindiff == c3) {
127  return av_clip(c, mi3, ma3);
128  }
129 
130  return av_clip(c, mi1, ma1);
131 }
132 
133 static int mode06(int c, int a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8)
134 {
136 
137  const int d1 = ma1 - mi1;
138  const int d2 = ma2 - mi2;
139  const int d3 = ma3 - mi3;
140  const int d4 = ma4 - mi4;
141 
142  const int cli1 = av_clip(c, mi1, ma1);
143  const int cli2 = av_clip(c, mi2, ma2);
144  const int cli3 = av_clip(c, mi3, ma3);
145  const int cli4 = av_clip(c, mi4, ma4);
146 
147  const int c1 = av_clip_uint16((FFABS(c - cli1) << 1) + d1);
148  const int c2 = av_clip_uint16((FFABS(c - cli2) << 1) + d2);
149  const int c3 = av_clip_uint16((FFABS(c - cli3) << 1) + d3);
150  const int c4 = av_clip_uint16((FFABS(c - cli4) << 1) + d4);
151 
152  const int mindiff = FFMIN(FFMIN(c1, c2), FFMIN(c3, c4));
153 
154  if (mindiff == c4) {
155  return cli4;
156  } else if (mindiff == c2) {
157  return cli2;
158  } else if (mindiff == c3) {
159  return cli3;
160  }
161 
162  return cli1;
163 }
164 
165 static int mode07(int c, int a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8)
166 {
168 
169  const int d1 = ma1 - mi1;
170  const int d2 = ma2 - mi2;
171  const int d3 = ma3 - mi3;
172  const int d4 = ma4 - mi4;
173 
174  const int cli1 = av_clip(c, mi1, ma1);
175  const int cli2 = av_clip(c, mi2, ma2);
176  const int cli3 = av_clip(c, mi3, ma3);
177  const int cli4 = av_clip(c, mi4, ma4);
178 
179  const int c1 = FFABS(c - cli1) + d1;
180  const int c2 = FFABS(c - cli2) + d2;
181  const int c3 = FFABS(c - cli3) + d3;
182  const int c4 = FFABS(c - cli4) + d4;
183 
184  const int mindiff = FFMIN(FFMIN(c1, c2), FFMIN(c3, c4));
185 
186  if (mindiff == c4) {
187  return cli4;
188  } else if (mindiff == c2) {
189  return cli2;
190  } else if (mindiff == c3) {
191  return cli3;
192  }
193 
194  return cli1;
195 }
196 
197 static int mode08(int c, int a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8)
198 {
200 
201  const int d1 = ma1 - mi1;
202  const int d2 = ma2 - mi2;
203  const int d3 = ma3 - mi3;
204  const int d4 = ma4 - mi4;
205 
206  const int cli1 = av_clip(c, mi1, ma1);
207  const int cli2 = av_clip(c, mi2, ma2);
208  const int cli3 = av_clip(c, mi3, ma3);
209  const int cli4 = av_clip(c, mi4, ma4);
210 
211  const int c1 = av_clip_uint16(FFABS(c - cli1) + (d1 << 1));
212  const int c2 = av_clip_uint16(FFABS(c - cli2) + (d2 << 1));
213  const int c3 = av_clip_uint16(FFABS(c - cli3) + (d3 << 1));
214  const int c4 = av_clip_uint16(FFABS(c - cli4) + (d4 << 1));
215 
216  const int mindiff = FFMIN(FFMIN(c1, c2), FFMIN(c3, c4));
217 
218  if (mindiff == c4) {
219  return cli4;
220  } else if (mindiff == c2) {
221  return cli2;
222  } else if (mindiff == c3) {
223  return cli3;
224  }
225 
226  return cli1;
227 }
228 
229 static int mode09(int c, int a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8)
230 {
232 
233  const int d1 = ma1 - mi1;
234  const int d2 = ma2 - mi2;
235  const int d3 = ma3 - mi3;
236  const int d4 = ma4 - mi4;
237 
238  const int mindiff = FFMIN(FFMIN(d1, d2), FFMIN(d3, d4));
239 
240  if (mindiff == d4) {
241  return av_clip(c, mi4, ma4);
242  } else if (mindiff == d2) {
243  return av_clip(c, mi2, ma2);
244  } else if (mindiff == d3) {
245  return av_clip(c, mi3, ma3);
246  }
247 
248  return av_clip(c, mi1, ma1);
249 }
250 
251 static int mode10(int c, int a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8)
252 {
253  const int d1 = FFABS(c - a1);
254  const int d2 = FFABS(c - a2);
255  const int d3 = FFABS(c - a3);
256  const int d4 = FFABS(c - a4);
257  const int d5 = FFABS(c - a5);
258  const int d6 = FFABS(c - a6);
259  const int d7 = FFABS(c - a7);
260  const int d8 = FFABS(c - a8);
261 
262  const int mindiff = FFMIN(FFMIN(FFMIN(d1, d2), FFMIN(d3, d4)),
263  FFMIN(FFMIN(d5, d6), FFMIN(d7, d8)));
264 
265  if (mindiff == d7) return a7;
266  if (mindiff == d8) return a8;
267  if (mindiff == d6) return a6;
268  if (mindiff == d2) return a2;
269  if (mindiff == d3) return a3;
270  if (mindiff == d1) return a1;
271  if (mindiff == d5) return a5;
272 
273  return a4;
274 }
275 
276 static int mode1112(int c, int a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8)
277 {
278  const int sum = 4 * c + 2 * (a2 + a4 + a5 + a7) + a1 + a3 + a6 + a8;
279  const int val = (sum + 8) >> 4;
280 
281  return val;
282 }
283 
284 static int mode1314(int c, int a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8)
285 {
286  const int d1 = FFABS(a1 - a8);
287  const int d2 = FFABS(a2 - a7);
288  const int d3 = FFABS(a3 - a6);
289 
290  const int mindiff = FFMIN(FFMIN(d1, d2), d3);
291 
292  if (mindiff == d2) {
293  return (a2 + a7 + 1) >> 1;
294  }
295  if (mindiff == d3) {
296  return (a3 + a6 + 1) >> 1;
297  }
298 
299  return (a1 + a8 + 1) >> 1;
300 }
301 
302 static int mode1516(int c, int a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8)
303 {
304  const int d1 = FFABS(a1 - a8);
305  const int d2 = FFABS(a2 - a7);
306  const int d3 = FFABS(a3 - a6);
307 
308  const int mindiff = FFMIN(FFMIN(d1, d2), d3);
309  const int average = (2 * (a2 + a7) + a1 + a3 + a6 + a8 + 4) >> 3;
310 
311  if (mindiff == d2) {
312  return av_clip(average, FFMIN(a2, a7), FFMAX(a2, a7));
313  }
314  if (mindiff == d3) {
315  return av_clip(average, FFMIN(a3, a6), FFMAX(a3, a6));
316  }
317 
318  return av_clip(average, FFMIN(a1, a8), FFMAX(a1, a8));
319 }
320 
321 static int mode17(int c, int a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8)
322 {
324 
325  const int l = FFMAX(FFMAX(mi1, mi2), FFMAX(mi3, mi4));
326  const int u = FFMIN(FFMIN(ma1, ma2), FFMIN(ma3, ma4));
327 
328  return av_clip(c, FFMIN(l, u), FFMAX(l, u));
329 }
330 
331 static int mode18(int c, int a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8)
332 {
333  const int d1 = FFMAX(FFABS(c - a1), FFABS(c - a8));
334  const int d2 = FFMAX(FFABS(c - a2), FFABS(c - a7));
335  const int d3 = FFMAX(FFABS(c - a3), FFABS(c - a6));
336  const int d4 = FFMAX(FFABS(c - a4), FFABS(c - a5));
337 
338  const int mindiff = FFMIN(FFMIN(d1, d2), FFMIN(d3, d4));
339 
340  if (mindiff == d4) {
341  return av_clip(c, FFMIN(a4, a5), FFMAX(a4, a5));
342  }
343  if (mindiff == d2) {
344  return av_clip(c, FFMIN(a2, a7), FFMAX(a2, a7));
345  }
346  if (mindiff == d3) {
347  return av_clip(c, FFMIN(a3, a6), FFMAX(a3, a6));
348  }
349 
350  return av_clip(c, FFMIN(a1, a8), FFMAX(a1, a8));
351 }
352 
353 static int mode19(int c, int a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8)
354 {
355  const int sum = a1 + a2 + a3 + a4 + a5 + a6 + a7 + a8;
356  const int val = (sum + 4) >> 3;
357 
358  return val;
359 }
360 
361 static int mode20(int c, int a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8)
362 {
363  const int sum = a1 + a2 + a3 + a4 + c + a5 + a6 + a7 + a8;
364  const int val = (sum + 4) / 9;
365 
366  return val;
367 }
368 
369 static int mode21(int c, int a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8)
370 {
371  const int l1l = (a1 + a8) >> 1;
372  const int l2l = (a2 + a7) >> 1;
373  const int l3l = (a3 + a6) >> 1;
374  const int l4l = (a4 + a5) >> 1;
375 
376  const int l1h = (a1 + a8 + 1) >> 1;
377  const int l2h = (a2 + a7 + 1) >> 1;
378  const int l3h = (a3 + a6 + 1) >> 1;
379  const int l4h = (a4 + a5 + 1) >> 1;
380 
381  const int mi = FFMIN(FFMIN(l1l, l2l), FFMIN(l3l, l4l));
382  const int ma = FFMAX(FFMAX(l1h, l2h), FFMAX(l3h, l4h));
383 
384  return av_clip(c, mi, ma);
385 }
386 
387 static int mode22(int c, int a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8)
388 {
389  const int l1 = (a1 + a8 + 1) >> 1;
390  const int l2 = (a2 + a7 + 1) >> 1;
391  const int l3 = (a3 + a6 + 1) >> 1;
392  const int l4 = (a4 + a5 + 1) >> 1;
393 
394  const int mi = FFMIN(FFMIN(l1, l2), FFMIN(l3, l4));
395  const int ma = FFMAX(FFMAX(l1, l2), FFMAX(l3, l4));
396 
397  return av_clip(c, mi, ma);
398 }
399 
400 static int mode23(int c, int a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8)
401 {
403 
404  const int linediff1 = ma1 - mi1;
405  const int linediff2 = ma2 - mi2;
406  const int linediff3 = ma3 - mi3;
407  const int linediff4 = ma4 - mi4;
408 
409  const int u1 = FFMIN(c - ma1, linediff1);
410  const int u2 = FFMIN(c - ma2, linediff2);
411  const int u3 = FFMIN(c - ma3, linediff3);
412  const int u4 = FFMIN(c - ma4, linediff4);
413  const int u = FFMAX(FFMAX(FFMAX(u1, u2), FFMAX(u3, u4)), 0);
414 
415  const int d1 = FFMIN(mi1 - c, linediff1);
416  const int d2 = FFMIN(mi2 - c, linediff2);
417  const int d3 = FFMIN(mi3 - c, linediff3);
418  const int d4 = FFMIN(mi4 - c, linediff4);
419  const int d = FFMAX(FFMAX(FFMAX(d1, d2), FFMAX(d3, d4)), 0);
420 
421  return c - u + d; // This probably will never overflow.
422 }
423 
424 static int mode24(int c, int a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8)
425 {
427 
428  const int linediff1 = ma1 - mi1;
429  const int linediff2 = ma2 - mi2;
430  const int linediff3 = ma3 - mi3;
431  const int linediff4 = ma4 - mi4;
432 
433  const int tu1 = c - ma1;
434  const int tu2 = c - ma2;
435  const int tu3 = c - ma3;
436  const int tu4 = c - ma4;
437 
438  const int u1 = FFMIN(tu1, linediff1 - tu1);
439  const int u2 = FFMIN(tu2, linediff2 - tu2);
440  const int u3 = FFMIN(tu3, linediff3 - tu3);
441  const int u4 = FFMIN(tu4, linediff4 - tu4);
442  const int u = FFMAX(FFMAX(FFMAX(u1, u2), FFMAX(u3, u4)), 0);
443 
444  const int td1 = mi1 - c;
445  const int td2 = mi2 - c;
446  const int td3 = mi3 - c;
447  const int td4 = mi4 - c;
448 
449  const int d1 = FFMIN(td1, linediff1 - td1);
450  const int d2 = FFMIN(td2, linediff2 - td2);
451  const int d3 = FFMIN(td3, linediff3 - td3);
452  const int d4 = FFMIN(td4, linediff4 - td4);
453  const int d = FFMAX(FFMAX(FFMAX(d1, d2), FFMAX(d3, d4)), 0);
454 
455  return c - u + d; // This probably will never overflow.
456 }
457 
459 {
460  RemoveGrainContext *s = inlink->dst->priv;
462  int i;
463 
464  s->nb_planes = av_pix_fmt_count_planes(inlink->format);
465 
466  s->planeheight[1] = s->planeheight[2] = AV_CEIL_RSHIFT(inlink->h, desc->log2_chroma_h);
467  s->planeheight[0] = s->planeheight[3] = inlink->h;
468  s->planewidth[1] = s->planewidth[2] = AV_CEIL_RSHIFT(inlink->w, desc->log2_chroma_w);
469  s->planewidth[0] = s->planewidth[3] = inlink->w;
470 
471  for (i = 0; i < s->nb_planes; i++) {
472  switch (s->mode[i]) {
473  case 1: s->rg[i] = mode01; break;
474  case 2: s->rg[i] = mode02; break;
475  case 3: s->rg[i] = mode03; break;
476  case 4: s->rg[i] = mode04; break;
477  case 5: s->rg[i] = mode05; break;
478  case 6: s->rg[i] = mode06; break;
479  case 7: s->rg[i] = mode07; break;
480  case 8: s->rg[i] = mode08; break;
481  case 9: s->rg[i] = mode09; break;
482  case 10: s->rg[i] = mode10; break;
483  case 11: s->rg[i] = mode1112; break;
484  case 12: s->rg[i] = mode1112; break;
485  case 13: s->skip_odd = 1;
486  s->rg[i] = mode1314; break;
487  case 14: s->skip_even = 1;
488  s->rg[i] = mode1314; break;
489  case 15: s->skip_odd = 1;
490  s->rg[i] = mode1516; break;
491  case 16: s->skip_even = 1;
492  s->rg[i] = mode1516; break;
493  case 17: s->rg[i] = mode17; break;
494  case 18: s->rg[i] = mode18; break;
495  case 19: s->rg[i] = mode19; break;
496  case 20: s->rg[i] = mode20; break;
497  case 21: s->rg[i] = mode21; break;
498  case 22: s->rg[i] = mode22; break;
499  case 23: s->rg[i] = mode23; break;
500  case 24: s->rg[i] = mode24; break;
501  }
502  }
503 
504 #if ARCH_X86
506 #endif
507 
508  return 0;
509 }
510 
511 typedef struct ThreadData {
512  AVFrame *in, *out;
513  int plane;
514 } ThreadData;
515 
516 static int filter_slice(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
517 {
518  RemoveGrainContext *s = ctx->priv;
519  ThreadData *td = arg;
520  AVFrame *in = td->in;
521  AVFrame *out = td->out;
522  const int i = td->plane;
523  const int height = s->planeheight[i];
524  const int om = in->linesize[i] - 1;
525  const int o0 = in->linesize[i] ;
526  const int op = in->linesize[i] + 1;
527  int start = (height * jobnr ) / nb_jobs;
528  int end = (height * (jobnr+1)) / nb_jobs;
529  int x, y;
530 
531  start = FFMAX(1, start);
532  end = FFMIN(height-1, end);
533  for (y = start; y < end; y++) {
534  uint8_t *dst = out->data[i];
535  uint8_t *src = in->data[i];
536 
537  src = in->data[i] + y * in->linesize[i];
538  dst = out->data[i] + y * out->linesize[i];
539 
540  if (s->skip_even && !(y & 1)) {
541  memcpy(dst, src, s->planewidth[i]);
542  continue;
543  }
544  if (s->skip_odd && y & 1) {
545  memcpy(dst, src, s->planewidth[i]);
546  continue;
547  }
548 
549  *dst++ = *src++;
550 
551  if (s->fl[i]) {
552  int w_asm = (s->planewidth[i] - 2) & ~15;
553 
554  s->fl[i](dst, src, in->linesize[i], w_asm);
555 
556  x = 1 + w_asm;
557  dst += w_asm;
558  src += w_asm;
559  } else
560  x = 1;
561 
562  for (; x < s->planewidth[i] - 1; x++) {
563  const int a1 = src[-op];
564  const int a2 = src[-o0];
565  const int a3 = src[-om];
566  const int a4 = src[-1 ];
567  const int c = src[ 0 ];
568  const int a5 = src[ 1 ];
569  const int a6 = src[ om];
570  const int a7 = src[ o0];
571  const int a8 = src[ op];
572 
573  const int res = s->rg[i](c, a1, a2, a3, a4, a5, a6, a7, a8);
574 
575  *dst = res;
576  dst++, src++;
577  }
578  dst[0] = src[0];
579  }
580 
581  return 0;
582 }
583 
585 {
586  AVFilterContext *ctx = inlink->dst;
587  AVFilterLink *outlink = ctx->outputs[0];
588  RemoveGrainContext *s = ctx->priv;
589  ThreadData td;
590  AVFrame *out;
591  int i;
592 
593  out = ff_get_video_buffer(outlink, outlink->w, outlink->h);
594  if (!out) {
595  av_frame_free(&in);
596  return AVERROR(ENOMEM);
597  }
599 
600  for (i = 0; i < s->nb_planes; i++) {
601  uint8_t *dst = out->data[i];
602  uint8_t *src = in->data[i];
603 
604  if (s->mode[i] == 0) {
605  av_image_copy_plane(dst, out->linesize[i],
606  src, in->linesize[i],
607  s->planewidth[i], s->planeheight[i]);
608  continue;
609  }
610 
611  memcpy(dst, src, s->planewidth[i]);
612 
613  td.in = in; td.out = out; td.plane = i;
615  FFMIN(s->planeheight[i], ff_filter_get_nb_threads(ctx)));
616 
617  src = in->data[i] + (s->planeheight[i] - 1) * in->linesize[i];
618  dst = out->data[i] + (s->planeheight[i] - 1) * out->linesize[i];
619  memcpy(dst, src, s->planewidth[i]);
620  }
621 
622  av_frame_free(&in);
623  return ff_filter_frame(outlink, out);
624 }
625 
626 static const AVFilterPad removegrain_inputs[] = {
627  {
628  .name = "default",
629  .type = AVMEDIA_TYPE_VIDEO,
630  .filter_frame = filter_frame,
631  .config_props = config_input,
632  },
633 };
634 
636  {
637  .name = "default",
638  .type = AVMEDIA_TYPE_VIDEO,
639  },
640 };
641 
643  .name = "removegrain",
644  .description = NULL_IF_CONFIG_SMALL("Remove grain."),
645  .priv_size = sizeof(RemoveGrainContext),
649  .priv_class = &removegrain_class,
651 };
ff_get_video_buffer
AVFrame * ff_get_video_buffer(AVFilterLink *link, int w, int h)
Request a picture buffer with a specific set of permissions.
Definition: video.c:101
td
#define td
Definition: regdef.h:70
AVPixelFormat
AVPixelFormat
Pixel format.
Definition: pixfmt.h:64
pix_fmts
static enum AVPixelFormat pix_fmts[]
Definition: vf_removegrain.c:47
av_clip
#define av_clip
Definition: common.h:95
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
opt.h
out
FILE * out
Definition: movenc.c:54
u
#define u(width, name, range_min, range_max)
Definition: cbs_h2645.c:262
ff_filter_frame
int ff_filter_frame(AVFilterLink *link, AVFrame *frame)
Send a frame of data to the next filter.
Definition: avfilter.c:969
av_pix_fmt_desc_get
const AVPixFmtDescriptor * av_pix_fmt_desc_get(enum AVPixelFormat pix_fmt)
Definition: pixdesc.c:2888
mode19
static int mode19(int c, int a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8)
Definition: vf_removegrain.c:353
FILTER_PIXFMTS_ARRAY
#define FILTER_PIXFMTS_ARRAY(array)
Definition: internal.h:174
inlink
The exact code depends on how similar the blocks are and how related they are to the and needs to apply these operations to the correct inlink or outlink if there are several Macros are available to factor that when no extra processing is inlink
Definition: filter_design.txt:212
av_frame_free
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
Definition: frame.c:99
AVFrame
This structure describes decoded (raw) audio or video data.
Definition: frame.h:330
pixdesc.h
mode05
static int mode05(int c, int a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8)
Definition: vf_removegrain.c:110
ff_removegrain_init_x86
void ff_removegrain_init_x86(RemoveGrainContext *rg)
Definition: vf_removegrain_init.c:50
AVOption
AVOption.
Definition: opt.h:251
AV_PIX_FMT_YUV440P
@ AV_PIX_FMT_YUV440P
planar YUV 4:4:0 (1 Cr & Cb sample per 1x2 Y samples)
Definition: pixfmt.h:99
mode20
static int mode20(int c, int a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8)
Definition: vf_removegrain.c:361
FFMAX
#define FFMAX(a, b)
Definition: macros.h:47
AVFilter::name
const char * name
Filter name.
Definition: avfilter.h:165
mode06
static int mode06(int c, int a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8)
Definition: vf_removegrain.c:133
c1
static const uint64_t c1
Definition: murmur3.c:51
mode18
static int mode18(int c, int a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8)
Definition: vf_removegrain.c:331
ThreadData::out
AVFrame * out
Definition: af_adeclick.c:473
video.h
ThreadData::in
AVFrame * in
Definition: af_adecorrelate.c:154
AVFrame::data
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
Definition: frame.h:351
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
formats.h
mode08
static int mode08(int c, int a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8)
Definition: vf_removegrain.c:197
av_pix_fmt_count_planes
int av_pix_fmt_count_planes(enum AVPixelFormat pix_fmt)
Definition: pixdesc.c:2928
AVFILTER_DEFINE_CLASS
AVFILTER_DEFINE_CLASS(removegrain)
AV_PIX_FMT_GBRAP
@ AV_PIX_FMT_GBRAP
planar GBRA 4:4:4:4 32bpp
Definition: pixfmt.h:205
mode22
static int mode22(int c, int a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8)
Definition: vf_removegrain.c:387
val
static double val(void *priv, double ch)
Definition: aeval.c:77
mode23
static int mode23(int c, int a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8)
Definition: vf_removegrain.c:400
AVFilterPad
A filter pad used for either input or output.
Definition: internal.h:49
FFDIFFSIGN
#define FFDIFFSIGN(x, y)
Comparator.
Definition: macros.h:45
mode21
static int mode21(int c, int a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8)
Definition: vf_removegrain.c:369
a1
#define a1
Definition: regdef.h:47
AV_PIX_FMT_YUVJ411P
@ AV_PIX_FMT_YUVJ411P
planar YUV 4:1:1, 12bpp, (1 Cr & Cb sample per 4x1 Y samples) full scale (JPEG), deprecated in favor ...
Definition: pixfmt.h:276
filter_frame
static int filter_frame(AVFilterLink *inlink, AVFrame *in)
Definition: vf_removegrain.c:584
AV_PIX_FMT_YUVJ422P
@ AV_PIX_FMT_YUVJ422P
planar YUV 4:2:2, 16bpp, full scale (JPEG), deprecated in favor of AV_PIX_FMT_YUV422P and setting col...
Definition: pixfmt.h:79
ThreadData::plane
int plane
Definition: vf_blend.c:58
s
#define s(width, name)
Definition: cbs_vp9.c:256
removegrain_inputs
static const AVFilterPad removegrain_inputs[]
Definition: vf_removegrain.c:626
AV_PIX_FMT_YUVA420P
@ AV_PIX_FMT_YUVA420P
planar YUV 4:2:0, 20bpp, (1 Cr & Cb sample per 2x2 Y & A samples)
Definition: pixfmt.h:101
RemoveGrainContext
Definition: removegrain.h:27
AV_CEIL_RSHIFT
#define AV_CEIL_RSHIFT(a, b)
Definition: common.h:50
mi
#define mi
Definition: vf_colormatrix.c:108
mode04
static int mode04(int c, int a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8)
Definition: vf_removegrain.c:101
op
static int op(uint8_t **dst, const uint8_t *dst_end, GetByteContext *gb, int pixel, int count, int *x, int width, int linesize)
Perform decode operation.
Definition: anm.c:76
ctx
AVFormatContext * ctx
Definition: movenc.c:48
mode07
static int mode07(int c, int a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8)
Definition: vf_removegrain.c:165
a4
#define a4
Definition: regdef.h:50
mode1516
static int mode1516(int c, int a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8)
Definition: vf_removegrain.c:302
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:66
FILTER_INPUTS
#define FILTER_INPUTS(array)
Definition: internal.h:194
AV_PIX_FMT_YUVJ444P
@ AV_PIX_FMT_YUVJ444P
planar YUV 4:4:4, 24bpp, full scale (JPEG), deprecated in favor of AV_PIX_FMT_YUV444P and setting col...
Definition: pixfmt.h:80
arg
const char * arg
Definition: jacosubdec.c:67
FFABS
#define FFABS(a)
Absolute value, Note, INT_MIN / INT64_MIN result in undefined behavior as they are not representable ...
Definition: common.h:64
NULL
#define NULL
Definition: coverity.c:32
av_frame_copy_props
int av_frame_copy_props(AVFrame *dst, const AVFrame *src)
Copy only "metadata" fields from src to dst.
Definition: frame.c:594
OFFSET
#define OFFSET(x)
Definition: vf_removegrain.c:34
AV_PIX_FMT_YUVJ420P
@ AV_PIX_FMT_YUVJ420P
planar YUV 4:2:0, 12bpp, full scale (JPEG), deprecated in favor of AV_PIX_FMT_YUV420P and setting col...
Definition: pixfmt.h:78
cmp_int
static int cmp_int(const void *p1, const void *p2)
Definition: vf_removegrain.c:76
AV_PIX_FMT_GRAY8
@ AV_PIX_FMT_GRAY8
Y , 8bpp.
Definition: pixfmt.h:74
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
qsort.h
NULL_IF_CONFIG_SMALL
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification.
Definition: internal.h:115
REMOVE_GRAIN_SORT_AXIS
#define REMOVE_GRAIN_SORT_AXIS
Definition: vf_removegrain.c:58
removegrain.h
removegrain_options
static const AVOption removegrain_options[]
Definition: vf_removegrain.c:37
height
#define height
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_PIX_FMT_YUVA444P
@ AV_PIX_FMT_YUVA444P
planar YUV 4:4:4 32bpp, (1 Cr & Cb sample per 1x1 Y & A samples)
Definition: pixfmt.h:167
ff_vf_removegrain
const AVFilter ff_vf_removegrain
Definition: vf_removegrain.c:642
filter_slice
static int filter_slice(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
Definition: vf_removegrain.c:516
mode01
static int mode01(int c, int a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8)
Definition: vf_removegrain.c:68
FLAGS
#define FLAGS
Definition: vf_removegrain.c:35
internal.h
AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC
#define AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC
Some filters support a generic "enable" expression option that can be used to enable or disable a fil...
Definition: avfilter.h:142
mode24
static int mode24(int c, int a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8)
Definition: vf_removegrain.c:424
config_input
static int config_input(AVFilterLink *inlink)
Definition: vf_removegrain.c:458
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:269
AV_QSORT
#define AV_QSORT(p, num, type, cmp)
Quicksort This sort is fast, and fully inplace but not stable and it is possible to construct input t...
Definition: qsort.h:33
a2
#define a2
Definition: regdef.h:48
ff_filter_get_nb_threads
int ff_filter_get_nb_threads(AVFilterContext *ctx)
Get number of threads for current filter instance.
Definition: avfilter.c:777
ThreadData
Used for passing data between threads.
Definition: dsddec.c:69
FFMIN
#define FFMIN(a, b)
Definition: macros.h:49
AV_PIX_FMT_YUVJ440P
@ AV_PIX_FMT_YUVJ440P
planar YUV 4:4:0 full scale (JPEG), deprecated in favor of AV_PIX_FMT_YUV440P and setting color_range
Definition: pixfmt.h:100
AVFilterPad::name
const char * name
Pad name.
Definition: internal.h:55
mode02
static int mode02(int c, int a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8)
Definition: vf_removegrain.c:83
AVFilter
Filter definition.
Definition: avfilter.h:161
left
Tag MUST be and< 10hcoeff half pel interpolation filter coefficients, hcoeff[0] are the 2 middle coefficients[1] are the next outer ones and so on, resulting in a filter like:...eff[2], hcoeff[1], hcoeff[0], hcoeff[0], hcoeff[1], hcoeff[2] ... the sign of the coefficients is not explicitly stored but alternates after each coeff and coeff[0] is positive, so ...,+,-,+,-,+,+,-,+,-,+,... hcoeff[0] is not explicitly stored but found by subtracting the sum of all stored coefficients with signs from 32 hcoeff[0]=32 - hcoeff[1] - hcoeff[2] - ... a good choice for hcoeff and htaps is htaps=6 hcoeff={40,-10, 2} an alternative which requires more computations at both encoder and decoder side and may or may not be better is htaps=8 hcoeff={42,-14, 6,-2}ref_frames minimum of the number of available reference frames and max_ref_frames for example the first frame after a key frame always has ref_frames=1spatial_decomposition_type wavelet type 0 is a 9/7 symmetric compact integer wavelet 1 is a 5/3 symmetric compact integer wavelet others are reserved stored as delta from last, last is reset to 0 if always_reset||keyframeqlog quality(logarithmic quantizer scale) stored as delta from last, last is reset to 0 if always_reset||keyframemv_scale stored as delta from last, last is reset to 0 if always_reset||keyframe FIXME check that everything works fine if this changes between framesqbias dequantization bias stored as delta from last, last is reset to 0 if always_reset||keyframeblock_max_depth maximum depth of the block tree stored as delta from last, last is reset to 0 if always_reset||keyframequant_table quantization tableHighlevel bitstream structure:==============================--------------------------------------------|Header|--------------------------------------------|------------------------------------|||Block0||||split?||||yes no||||......... intra?||||:Block01 :yes no||||:Block02 :....... ..........||||:Block03 ::y DC ::ref index:||||:Block04 ::cb DC ::motion x :||||......... :cr DC ::motion y :||||....... ..........|||------------------------------------||------------------------------------|||Block1|||...|--------------------------------------------|------------ ------------ ------------|||Y subbands||Cb subbands||Cr subbands||||--- ---||--- ---||--- ---|||||LL0||HL0||||LL0||HL0||||LL0||HL0|||||--- ---||--- ---||--- ---||||--- ---||--- ---||--- ---|||||LH0||HH0||||LH0||HH0||||LH0||HH0|||||--- ---||--- ---||--- ---||||--- ---||--- ---||--- ---|||||HL1||LH1||||HL1||LH1||||HL1||LH1|||||--- ---||--- ---||--- ---||||--- ---||--- ---||--- ---|||||HH1||HL2||||HH1||HL2||||HH1||HL2|||||...||...||...|||------------ ------------ ------------|--------------------------------------------Decoding process:=================------------|||Subbands|------------||||------------|Intra DC||||LL0 subband prediction ------------|\ Dequantization ------------------- \||Reference frames|\ IDWT|------- -------|Motion \|||Frame 0||Frame 1||Compensation . OBMC v -------|------- -------|--------------. \------> Frame n output Frame Frame<----------------------------------/|...|------------------- Range Coder:============Binary Range Coder:------------------- The implemented range coder is an adapted version based upon "Range encoding: an algorithm for removing redundancy from a digitised message." by G. N. N. Martin. The symbols encoded by the Snow range coder are bits(0|1). The associated probabilities are not fix but change depending on the symbol mix seen so far. bit seen|new state ---------+----------------------------------------------- 0|256 - state_transition_table[256 - old_state];1|state_transition_table[old_state];state_transition_table={ 0, 0, 0, 0, 0, 0, 0, 0, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 190, 191, 192, 194, 194, 195, 196, 197, 198, 199, 200, 201, 202, 202, 204, 205, 206, 207, 208, 209, 209, 210, 211, 212, 213, 215, 215, 216, 217, 218, 219, 220, 220, 222, 223, 224, 225, 226, 227, 227, 229, 229, 230, 231, 232, 234, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 248, 0, 0, 0, 0, 0, 0, 0};FIXME Range Coding of integers:------------------------- FIXME Neighboring Blocks:===================left and top are set to the respective blocks unless they are outside of the image in which case they are set to the Null block top-left is set to the top left block unless it is outside of the image in which case it is set to the left block if this block has no larger parent block or it is at the left side of its parent block and the top right block is not outside of the image then the top right block is used for top-right else the top-left block is used Null block y, cb, cr are 128 level, ref, mx and my are 0 Motion Vector Prediction:=========================1. the motion vectors of all the neighboring blocks are scaled to compensate for the difference of reference frames scaled_mv=(mv *(256 *(current_reference+1)/(mv.reference+1))+128)> the median of the scaled left
Definition: snow.txt:386
removegrain_outputs
static const AVFilterPad removegrain_outputs[]
Definition: vf_removegrain.c:635
c2
static const uint64_t c2
Definition: murmur3.c:52
a5
#define a5
Definition: regdef.h:51
mode1112
static int mode1112(int c, int a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8)
Definition: vf_removegrain.c:276
mode1314
static int mode1314(int c, int a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8)
Definition: vf_removegrain.c:284
mode
mode
Definition: ebur128.h:83
AV_PIX_FMT_NONE
@ AV_PIX_FMT_NONE
Definition: pixfmt.h:65
AV_OPT_TYPE_INT
@ AV_OPT_TYPE_INT
Definition: opt.h:225
avfilter.h
mode03
static int mode03(int c, int a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8)
Definition: vf_removegrain.c:92
AV_PIX_FMT_YUV444P
@ AV_PIX_FMT_YUV444P
planar YUV 4:4:4, 24bpp, (1 Cr & Cb sample per 1x1 Y samples)
Definition: pixfmt.h:71
AVFilterContext
An instance of a filter.
Definition: avfilter.h:392
av_clip_uint16
#define av_clip_uint16
Definition: common.h:107
mode09
static int mode09(int c, int a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8)
Definition: vf_removegrain.c:229
AV_PIX_FMT_GBRP
@ AV_PIX_FMT_GBRP
planar GBR 4:4:4 24bpp
Definition: pixfmt.h:158
AVFILTER_FLAG_SLICE_THREADS
#define AVFILTER_FLAG_SLICE_THREADS
The filter supports multithreading by splitting frames into multiple parts and processing them concur...
Definition: avfilter.h:117
desc
const char * desc
Definition: libsvtav1.c:83
AVMEDIA_TYPE_VIDEO
@ AVMEDIA_TYPE_VIDEO
Definition: avutil.h:201
AV_PIX_FMT_YUV422P
@ AV_PIX_FMT_YUV422P
planar YUV 4:2:2, 16bpp, (1 Cr & Cb sample per 2x1 Y samples)
Definition: pixfmt.h:70
mode17
static int mode17(int c, int a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8)
Definition: vf_removegrain.c:321
AVPixFmtDescriptor
Descriptor that unambiguously describes how the bits of a pixel are stored in the up to 4 data planes...
Definition: pixdesc.h:69
FILTER_OUTPUTS
#define FILTER_OUTPUTS(array)
Definition: internal.h:195
src
INIT_CLIP pixel * src
Definition: h264pred_template.c:418
AV_PIX_FMT_YUV411P
@ AV_PIX_FMT_YUV411P
planar YUV 4:1:1, 12bpp, (1 Cr & Cb sample per 4x1 Y samples)
Definition: pixfmt.h:73
d
d
Definition: ffmpeg_filter.c:156
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:375
AV_PIX_FMT_YUV410P
@ AV_PIX_FMT_YUV410P
planar YUV 4:1:0, 9bpp, (1 Cr & Cb sample per 4x4 Y samples)
Definition: pixfmt.h:72
ma
#define ma
Definition: vf_colormatrix.c:100
ff_filter_execute
static av_always_inline int ff_filter_execute(AVFilterContext *ctx, avfilter_action_func *func, void *arg, int *ret, int nb_jobs)
Definition: internal.h:146
a3
#define a3
Definition: regdef.h:49
AV_PIX_FMT_YUVA422P
@ AV_PIX_FMT_YUVA422P
planar YUV 4:2:2 24bpp, (1 Cr & Cb sample per 2x1 Y & A samples)
Definition: pixfmt.h:166
mode10
static int mode10(int c, int a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8)
Definition: vf_removegrain.c:251