FFmpeg  4.4.8
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 "filters.h"
30 #include "formats.h"
31 #include "internal.h"
32 #include "removegrain.h"
33 #include "video.h"
34 
35 #define OFFSET(x) offsetof(RemoveGrainContext, x)
36 #define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM
37 
38 static const AVOption removegrain_options[] = {
39  { "m0", "set mode for 1st plane", OFFSET(mode[0]), AV_OPT_TYPE_INT, {.i64=0}, 0, 24, FLAGS },
40  { "m1", "set mode for 2nd plane", OFFSET(mode[1]), AV_OPT_TYPE_INT, {.i64=0}, 0, 24, FLAGS },
41  { "m2", "set mode for 3rd plane", OFFSET(mode[2]), AV_OPT_TYPE_INT, {.i64=0}, 0, 24, FLAGS },
42  { "m3", "set mode for 4th plane", OFFSET(mode[3]), AV_OPT_TYPE_INT, {.i64=0}, 0, 24, FLAGS },
43  {NULL}
44 };
45 
46 AVFILTER_DEFINE_CLASS(removegrain);
47 
49 {
50  static const enum AVPixelFormat pix_fmts[] = {
59  };
60 
62  if (!fmts_list)
63  return AVERROR(ENOMEM);
64  return ff_set_common_formats(ctx, fmts_list);
65 }
66 
67 #define REMOVE_GRAIN_SORT_AXIS \
68  const int ma1 = FFMAX(a1, a8); \
69  const int mi1 = FFMIN(a1, a8); \
70  const int ma2 = FFMAX(a2, a7); \
71  const int mi2 = FFMIN(a2, a7); \
72  const int ma3 = FFMAX(a3, a6); \
73  const int mi3 = FFMIN(a3, a6); \
74  const int ma4 = FFMAX(a4, a5); \
75  const int mi4 = FFMIN(a4, a5);
76 
77 static int mode01(int c, int a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8)
78 {
79  const int mi = FFMIN(FFMIN(FFMIN(a1, a2), FFMIN(a3, a4)), FFMIN(FFMIN(a5, a6), FFMIN(a7, a8)));
80  const int ma = FFMAX(FFMAX(FFMAX(a1, a2), FFMAX(a3, a4)), FFMAX(FFMAX(a5, a6), FFMAX(a7, a8)));
81 
82  return av_clip(c, mi, ma);
83 }
84 
85 static int cmp_int(const void *p1, const void *p2)
86 {
87  int left = *(const int *)p1;
88  int right = *(const int *)p2;
89  return FFDIFFSIGN(left, right);
90 }
91 
92 static int mode02(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[2 - 1 ], a[7 - 1]);
99 }
100 
101 static int mode03(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[3 - 1 ], a[6 - 1]);
108 }
109 
110 static int mode04(int c, int a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8)
111 {
112  int a[8] = { a1, a2, a3, a4, a5, a6, a7, a8 };
113 
114  AV_QSORT(a, 8, int, cmp_int);
115 
116  return av_clip(c, a[4 - 1 ], a[5 - 1]);
117 }
118 
119 static int mode05(int c, int a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8)
120 {
122 
123  const int c1 = FFABS(c - av_clip(c, mi1, ma1));
124  const int c2 = FFABS(c - av_clip(c, mi2, ma2));
125  const int c3 = FFABS(c - av_clip(c, mi3, ma3));
126  const int c4 = FFABS(c - av_clip(c, mi4, ma4));
127 
128  const int mindiff = FFMIN(FFMIN(c1, c2), FFMIN(c3, c4));
129 
130  /* When adding SIMD notice the return order here: 4, 2, 3, 1. */
131  if (mindiff == c4) {
132  return av_clip(c, mi4, ma4);
133  } else if (mindiff == c2) {
134  return av_clip(c, mi2, ma2);
135  } else if (mindiff == c3) {
136  return av_clip(c, mi3, ma3);
137  }
138 
139  return av_clip(c, mi1, ma1);
140 }
141 
142 static int mode06(int c, int a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8)
143 {
145 
146  const int d1 = ma1 - mi1;
147  const int d2 = ma2 - mi2;
148  const int d3 = ma3 - mi3;
149  const int d4 = ma4 - mi4;
150 
151  const int cli1 = av_clip(c, mi1, ma1);
152  const int cli2 = av_clip(c, mi2, ma2);
153  const int cli3 = av_clip(c, mi3, ma3);
154  const int cli4 = av_clip(c, mi4, ma4);
155 
156  const int c1 = av_clip_uint16((FFABS(c - cli1) << 1) + d1);
157  const int c2 = av_clip_uint16((FFABS(c - cli2) << 1) + d2);
158  const int c3 = av_clip_uint16((FFABS(c - cli3) << 1) + d3);
159  const int c4 = av_clip_uint16((FFABS(c - cli4) << 1) + d4);
160 
161  const int mindiff = FFMIN(FFMIN(c1, c2), FFMIN(c3, c4));
162 
163  if (mindiff == c4) {
164  return cli4;
165  } else if (mindiff == c2) {
166  return cli2;
167  } else if (mindiff == c3) {
168  return cli3;
169  }
170 
171  return cli1;
172 }
173 
174 static int mode07(int c, int a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8)
175 {
177 
178  const int d1 = ma1 - mi1;
179  const int d2 = ma2 - mi2;
180  const int d3 = ma3 - mi3;
181  const int d4 = ma4 - mi4;
182 
183  const int cli1 = av_clip(c, mi1, ma1);
184  const int cli2 = av_clip(c, mi2, ma2);
185  const int cli3 = av_clip(c, mi3, ma3);
186  const int cli4 = av_clip(c, mi4, ma4);
187 
188  const int c1 = FFABS(c - cli1) + d1;
189  const int c2 = FFABS(c - cli2) + d2;
190  const int c3 = FFABS(c - cli3) + d3;
191  const int c4 = FFABS(c - cli4) + d4;
192 
193  const int mindiff = FFMIN(FFMIN(c1, c2), FFMIN(c3, c4));
194 
195  if (mindiff == c4) {
196  return cli4;
197  } else if (mindiff == c2) {
198  return cli2;
199  } else if (mindiff == c3) {
200  return cli3;
201  }
202 
203  return cli1;
204 }
205 
206 static int mode08(int c, int a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8)
207 {
209 
210  const int d1 = ma1 - mi1;
211  const int d2 = ma2 - mi2;
212  const int d3 = ma3 - mi3;
213  const int d4 = ma4 - mi4;
214 
215  const int cli1 = av_clip(c, mi1, ma1);
216  const int cli2 = av_clip(c, mi2, ma2);
217  const int cli3 = av_clip(c, mi3, ma3);
218  const int cli4 = av_clip(c, mi4, ma4);
219 
220  const int c1 = av_clip_uint16(FFABS(c - cli1) + (d1 << 1));
221  const int c2 = av_clip_uint16(FFABS(c - cli2) + (d2 << 1));
222  const int c3 = av_clip_uint16(FFABS(c - cli3) + (d3 << 1));
223  const int c4 = av_clip_uint16(FFABS(c - cli4) + (d4 << 1));
224 
225  const int mindiff = FFMIN(FFMIN(c1, c2), FFMIN(c3, c4));
226 
227  if (mindiff == c4) {
228  return cli4;
229  } else if (mindiff == c2) {
230  return cli2;
231  } else if (mindiff == c3) {
232  return cli3;
233  }
234 
235  return cli1;
236 }
237 
238 static int mode09(int c, int a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8)
239 {
241 
242  const int d1 = ma1 - mi1;
243  const int d2 = ma2 - mi2;
244  const int d3 = ma3 - mi3;
245  const int d4 = ma4 - mi4;
246 
247  const int mindiff = FFMIN(FFMIN(d1, d2), FFMIN(d3, d4));
248 
249  if (mindiff == d4) {
250  return av_clip(c, mi4, ma4);
251  } else if (mindiff == d2) {
252  return av_clip(c, mi2, ma2);
253  } else if (mindiff == d3) {
254  return av_clip(c, mi3, ma3);
255  }
256 
257  return av_clip(c, mi1, ma1);
258 }
259 
260 static int mode10(int c, int a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8)
261 {
262  const int d1 = FFABS(c - a1);
263  const int d2 = FFABS(c - a2);
264  const int d3 = FFABS(c - a3);
265  const int d4 = FFABS(c - a4);
266  const int d5 = FFABS(c - a5);
267  const int d6 = FFABS(c - a6);
268  const int d7 = FFABS(c - a7);
269  const int d8 = FFABS(c - a8);
270 
271  const int mindiff = FFMIN(FFMIN(FFMIN(d1, d2), FFMIN(d3, d4)),
272  FFMIN(FFMIN(d5, d6), FFMIN(d7, d8)));
273 
274  if (mindiff == d7) return a7;
275  if (mindiff == d8) return a8;
276  if (mindiff == d6) return a6;
277  if (mindiff == d2) return a2;
278  if (mindiff == d3) return a3;
279  if (mindiff == d1) return a1;
280  if (mindiff == d5) return a5;
281 
282  return a4;
283 }
284 
285 static int mode1112(int c, int a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8)
286 {
287  const int sum = 4 * c + 2 * (a2 + a4 + a5 + a7) + a1 + a3 + a6 + a8;
288  const int val = (sum + 8) >> 4;
289 
290  return val;
291 }
292 
293 static int mode1314(int c, int a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8)
294 {
295  const int d1 = FFABS(a1 - a8);
296  const int d2 = FFABS(a2 - a7);
297  const int d3 = FFABS(a3 - a6);
298 
299  const int mindiff = FFMIN(FFMIN(d1, d2), d3);
300 
301  if (mindiff == d2) {
302  return (a2 + a7 + 1) >> 1;
303  }
304  if (mindiff == d3) {
305  return (a3 + a6 + 1) >> 1;
306  }
307 
308  return (a1 + a8 + 1) >> 1;
309 }
310 
311 static int mode1516(int c, int a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8)
312 {
313  const int d1 = FFABS(a1 - a8);
314  const int d2 = FFABS(a2 - a7);
315  const int d3 = FFABS(a3 - a6);
316 
317  const int mindiff = FFMIN(FFMIN(d1, d2), d3);
318  const int average = (2 * (a2 + a7) + a1 + a3 + a6 + a8 + 4) >> 3;
319 
320  if (mindiff == d2) {
321  return av_clip(average, FFMIN(a2, a7), FFMAX(a2, a7));
322  }
323  if (mindiff == d3) {
324  return av_clip(average, FFMIN(a3, a6), FFMAX(a3, a6));
325  }
326 
327  return av_clip(average, FFMIN(a1, a8), FFMAX(a1, a8));
328 }
329 
330 static int mode17(int c, int a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8)
331 {
333 
334  const int l = FFMAX(FFMAX(mi1, mi2), FFMAX(mi3, mi4));
335  const int u = FFMIN(FFMIN(ma1, ma2), FFMIN(ma3, ma4));
336 
337  return av_clip(c, FFMIN(l, u), FFMAX(l, u));
338 }
339 
340 static int mode18(int c, int a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8)
341 {
342  const int d1 = FFMAX(FFABS(c - a1), FFABS(c - a8));
343  const int d2 = FFMAX(FFABS(c - a2), FFABS(c - a7));
344  const int d3 = FFMAX(FFABS(c - a3), FFABS(c - a6));
345  const int d4 = FFMAX(FFABS(c - a4), FFABS(c - a5));
346 
347  const int mindiff = FFMIN(FFMIN(d1, d2), FFMIN(d3, d4));
348 
349  if (mindiff == d4) {
350  return av_clip(c, FFMIN(a4, a5), FFMAX(a4, a5));
351  }
352  if (mindiff == d2) {
353  return av_clip(c, FFMIN(a2, a7), FFMAX(a2, a7));
354  }
355  if (mindiff == d3) {
356  return av_clip(c, FFMIN(a3, a6), FFMAX(a3, a6));
357  }
358 
359  return av_clip(c, FFMIN(a1, a8), FFMAX(a1, a8));
360 }
361 
362 static int mode19(int c, int a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8)
363 {
364  const int sum = a1 + a2 + a3 + a4 + a5 + a6 + a7 + a8;
365  const int val = (sum + 4) >> 3;
366 
367  return val;
368 }
369 
370 static int mode20(int c, int a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8)
371 {
372  const int sum = a1 + a2 + a3 + a4 + c + a5 + a6 + a7 + a8;
373  const int val = (sum + 4) / 9;
374 
375  return val;
376 }
377 
378 static int mode21(int c, int a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8)
379 {
380  const int l1l = (a1 + a8) >> 1;
381  const int l2l = (a2 + a7) >> 1;
382  const int l3l = (a3 + a6) >> 1;
383  const int l4l = (a4 + a5) >> 1;
384 
385  const int l1h = (a1 + a8 + 1) >> 1;
386  const int l2h = (a2 + a7 + 1) >> 1;
387  const int l3h = (a3 + a6 + 1) >> 1;
388  const int l4h = (a4 + a5 + 1) >> 1;
389 
390  const int mi = FFMIN(FFMIN(l1l, l2l), FFMIN(l3l, l4l));
391  const int ma = FFMAX(FFMAX(l1h, l2h), FFMAX(l3h, l4h));
392 
393  return av_clip(c, mi, ma);
394 }
395 
396 static int mode22(int c, int a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8)
397 {
398  const int l1 = (a1 + a8 + 1) >> 1;
399  const int l2 = (a2 + a7 + 1) >> 1;
400  const int l3 = (a3 + a6 + 1) >> 1;
401  const int l4 = (a4 + a5 + 1) >> 1;
402 
403  const int mi = FFMIN(FFMIN(l1, l2), FFMIN(l3, l4));
404  const int ma = FFMAX(FFMAX(l1, l2), FFMAX(l3, l4));
405 
406  return av_clip(c, mi, ma);
407 }
408 
409 static int mode23(int c, int a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8)
410 {
412 
413  const int linediff1 = ma1 - mi1;
414  const int linediff2 = ma2 - mi2;
415  const int linediff3 = ma3 - mi3;
416  const int linediff4 = ma4 - mi4;
417 
418  const int u1 = FFMIN(c - ma1, linediff1);
419  const int u2 = FFMIN(c - ma2, linediff2);
420  const int u3 = FFMIN(c - ma3, linediff3);
421  const int u4 = FFMIN(c - ma4, linediff4);
422  const int u = FFMAX(FFMAX(FFMAX(u1, u2), FFMAX(u3, u4)), 0);
423 
424  const int d1 = FFMIN(mi1 - c, linediff1);
425  const int d2 = FFMIN(mi2 - c, linediff2);
426  const int d3 = FFMIN(mi3 - c, linediff3);
427  const int d4 = FFMIN(mi4 - c, linediff4);
428  const int d = FFMAX(FFMAX(FFMAX(d1, d2), FFMAX(d3, d4)), 0);
429 
430  return c - u + d; // This probably will never overflow.
431 }
432 
433 static int mode24(int c, int a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8)
434 {
436 
437  const int linediff1 = ma1 - mi1;
438  const int linediff2 = ma2 - mi2;
439  const int linediff3 = ma3 - mi3;
440  const int linediff4 = ma4 - mi4;
441 
442  const int tu1 = c - ma1;
443  const int tu2 = c - ma2;
444  const int tu3 = c - ma3;
445  const int tu4 = c - ma4;
446 
447  const int u1 = FFMIN(tu1, linediff1 - tu1);
448  const int u2 = FFMIN(tu2, linediff2 - tu2);
449  const int u3 = FFMIN(tu3, linediff3 - tu3);
450  const int u4 = FFMIN(tu4, linediff4 - tu4);
451  const int u = FFMAX(FFMAX(FFMAX(u1, u2), FFMAX(u3, u4)), 0);
452 
453  const int td1 = mi1 - c;
454  const int td2 = mi2 - c;
455  const int td3 = mi3 - c;
456  const int td4 = mi4 - c;
457 
458  const int d1 = FFMIN(td1, linediff1 - td1);
459  const int d2 = FFMIN(td2, linediff2 - td2);
460  const int d3 = FFMIN(td3, linediff3 - td3);
461  const int d4 = FFMIN(td4, linediff4 - td4);
462  const int d = FFMAX(FFMAX(FFMAX(d1, d2), FFMAX(d3, d4)), 0);
463 
464  return c - u + d; // This probably will never overflow.
465 }
466 
467 static int config_input(AVFilterLink *inlink)
468 {
469  RemoveGrainContext *s = inlink->dst->priv;
471  int i;
472 
473  s->nb_planes = av_pix_fmt_count_planes(inlink->format);
474 
475  s->planeheight[1] = s->planeheight[2] = AV_CEIL_RSHIFT(inlink->h, desc->log2_chroma_h);
476  s->planeheight[0] = s->planeheight[3] = inlink->h;
477  s->planewidth[1] = s->planewidth[2] = AV_CEIL_RSHIFT(inlink->w, desc->log2_chroma_w);
478  s->planewidth[0] = s->planewidth[3] = inlink->w;
479 
480  for (i = 0; i < s->nb_planes; i++) {
481  switch (s->mode[i]) {
482  case 1: s->rg[i] = mode01; break;
483  case 2: s->rg[i] = mode02; break;
484  case 3: s->rg[i] = mode03; break;
485  case 4: s->rg[i] = mode04; break;
486  case 5: s->rg[i] = mode05; break;
487  case 6: s->rg[i] = mode06; break;
488  case 7: s->rg[i] = mode07; break;
489  case 8: s->rg[i] = mode08; break;
490  case 9: s->rg[i] = mode09; break;
491  case 10: s->rg[i] = mode10; break;
492  case 11: s->rg[i] = mode1112; break;
493  case 12: s->rg[i] = mode1112; break;
494  case 13: s->skip_odd = 1;
495  s->rg[i] = mode1314; break;
496  case 14: s->skip_even = 1;
497  s->rg[i] = mode1314; break;
498  case 15: s->skip_odd = 1;
499  s->rg[i] = mode1516; break;
500  case 16: s->skip_even = 1;
501  s->rg[i] = mode1516; break;
502  case 17: s->rg[i] = mode17; break;
503  case 18: s->rg[i] = mode18; break;
504  case 19: s->rg[i] = mode19; break;
505  case 20: s->rg[i] = mode20; break;
506  case 21: s->rg[i] = mode21; break;
507  case 22: s->rg[i] = mode22; break;
508  case 23: s->rg[i] = mode23; break;
509  case 24: s->rg[i] = mode24; break;
510  }
511  }
512 
513  if (ARCH_X86)
515 
516  return 0;
517 }
518 
519 typedef struct ThreadData {
520  AVFrame *in, *out;
521  int plane;
522 } ThreadData;
523 
524 static int filter_slice(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
525 {
526  RemoveGrainContext *s = ctx->priv;
527  ThreadData *td = arg;
528  AVFrame *in = td->in;
529  AVFrame *out = td->out;
530  const int i = td->plane;
531  const int height = s->planeheight[i];
532  const int om = in->linesize[i] - 1;
533  const int o0 = in->linesize[i] ;
534  const int op = in->linesize[i] + 1;
535  int start = ff_slice_pos(height, jobnr, nb_jobs);
536  int end = ff_slice_pos(height, jobnr + 1, nb_jobs);
537  int x, y;
538 
539  start = FFMAX(1, start);
540  end = FFMIN(height-1, end);
541  for (y = start; y < end; y++) {
542  uint8_t *dst = out->data[i];
543  uint8_t *src = in->data[i];
544 
545  src = in->data[i] + y * in->linesize[i];
546  dst = out->data[i] + y * out->linesize[i];
547 
548  if (s->skip_even && !(y & 1)) {
549  memcpy(dst, src, s->planewidth[i]);
550  continue;
551  }
552  if (s->skip_odd && y & 1) {
553  memcpy(dst, src, s->planewidth[i]);
554  continue;
555  }
556 
557  *dst++ = *src++;
558 
559  if (s->fl[i]) {
560  int w_asm = (s->planewidth[i] - 2) & ~15;
561 
562  s->fl[i](dst, src, in->linesize[i], w_asm);
563 
564  x = 1 + w_asm;
565  dst += w_asm;
566  src += w_asm;
567  } else
568  x = 1;
569 
570  for (; x < s->planewidth[i] - 1; x++) {
571  const int a1 = src[-op];
572  const int a2 = src[-o0];
573  const int a3 = src[-om];
574  const int a4 = src[-1 ];
575  const int c = src[ 0 ];
576  const int a5 = src[ 1 ];
577  const int a6 = src[ om];
578  const int a7 = src[ o0];
579  const int a8 = src[ op];
580 
581  const int res = s->rg[i](c, a1, a2, a3, a4, a5, a6, a7, a8);
582 
583  *dst = res;
584  dst++, src++;
585  }
586  dst[0] = src[0];
587  }
588 
589  return 0;
590 }
591 
592 static int filter_frame(AVFilterLink *inlink, AVFrame *in)
593 {
594  AVFilterContext *ctx = inlink->dst;
595  AVFilterLink *outlink = ctx->outputs[0];
596  RemoveGrainContext *s = ctx->priv;
597  ThreadData td;
598  AVFrame *out;
599  int i;
600 
601  out = ff_get_video_buffer(outlink, outlink->w, outlink->h);
602  if (!out) {
603  av_frame_free(&in);
604  return AVERROR(ENOMEM);
605  }
607 
608  for (i = 0; i < s->nb_planes; i++) {
609  uint8_t *dst = out->data[i];
610  uint8_t *src = in->data[i];
611 
612  if (s->mode[i] == 0) {
613  av_image_copy_plane(dst, out->linesize[i],
614  src, in->linesize[i],
615  s->planewidth[i], s->planeheight[i]);
616  continue;
617  }
618 
619  memcpy(dst, src, s->planewidth[i]);
620 
621  td.in = in; td.out = out; td.plane = i;
622  ctx->internal->execute(ctx, filter_slice, &td, NULL,
623  FFMIN(s->planeheight[i], ff_filter_get_nb_threads(ctx)));
624 
625  src = in->data[i] + (s->planeheight[i] - 1) * in->linesize[i];
626  dst = out->data[i] + (s->planeheight[i] - 1) * out->linesize[i];
627  memcpy(dst, src, s->planewidth[i]);
628  }
629 
630  av_frame_free(&in);
631  return ff_filter_frame(outlink, out);
632 }
633 
634 static const AVFilterPad removegrain_inputs[] = {
635  {
636  .name = "default",
637  .type = AVMEDIA_TYPE_VIDEO,
638  .filter_frame = filter_frame,
639  .config_props = config_input,
640  },
641  { NULL }
642 };
643 
645  {
646  .name = "default",
647  .type = AVMEDIA_TYPE_VIDEO,
648  },
649  { NULL }
650 };
651 
653  .name = "removegrain",
654  .description = NULL_IF_CONFIG_SMALL("Remove grain."),
655  .priv_size = sizeof(RemoveGrainContext),
659  .priv_class = &removegrain_class,
661 };
static double val(void *priv, double ch)
Definition: aeval.c:76
static const AVFilterPad inputs[]
Definition: af_acontrast.c:193
static const AVFilterPad outputs[]
Definition: af_acontrast.c:203
uint8_t pi<< 24) CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_U8, uint8_t,(*(const uint8_t *) pi - 0x80) *(1.0f/(1<< 7))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_U8, uint8_t,(*(const uint8_t *) pi - 0x80) *(1.0/(1<< 7))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_S16, int16_t,(*(const int16_t *) pi >> 8)+0x80) CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_S16, int16_t, *(const int16_t *) pi *(1.0f/(1<< 15))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_S16, int16_t, *(const int16_t *) pi *(1.0/(1<< 15))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_S32, int32_t,(*(const int32_t *) pi >> 24)+0x80) CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_S32, int32_t, *(const int32_t *) pi *(1.0f/(1U<< 31))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_S32, int32_t, *(const int32_t *) pi *(1.0/(1U<< 31))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_FLT, float, av_clip_uint8(lrintf(*(const float *) pi *(1<< 7))+0x80)) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_FLT, float, av_clip_int16(lrintf(*(const float *) pi *(1<< 15)))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_FLT, float, av_clipl_int32(llrintf(*(const float *) pi *(1U<< 31)))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_DBL, double, av_clip_uint8(lrint(*(const double *) pi *(1<< 7))+0x80)) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_DBL, double, av_clip_int16(lrint(*(const double *) pi *(1<< 15)))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_DBL, double, av_clipl_int32(llrint(*(const double *) pi *(1U<< 31)))) #define SET_CONV_FUNC_GROUP(ofmt, ifmt) static void set_generic_function(AudioConvert *ac) { } void ff_audio_convert_free(AudioConvert **ac) { if(! *ac) return;ff_dither_free(&(*ac) ->dc);av_freep(ac);} AudioConvert *ff_audio_convert_alloc(AVAudioResampleContext *avr, enum AVSampleFormat out_fmt, enum AVSampleFormat in_fmt, int channels, int sample_rate, int apply_map) { AudioConvert *ac;int in_planar, out_planar;ac=av_mallocz(sizeof(*ac));if(!ac) return NULL;ac->avr=avr;ac->out_fmt=out_fmt;ac->in_fmt=in_fmt;ac->channels=channels;ac->apply_map=apply_map;if(avr->dither_method !=AV_RESAMPLE_DITHER_NONE &&av_get_packed_sample_fmt(out_fmt)==AV_SAMPLE_FMT_S16 &&av_get_bytes_per_sample(in_fmt) > 2) { ac->dc=ff_dither_alloc(avr, out_fmt, in_fmt, channels, sample_rate, apply_map);if(!ac->dc) { av_free(ac);return NULL;} return ac;} in_planar=ff_sample_fmt_is_planar(in_fmt, channels);out_planar=ff_sample_fmt_is_planar(out_fmt, channels);if(in_planar==out_planar) { ac->func_type=CONV_FUNC_TYPE_FLAT;ac->planes=in_planar ? ac->channels :1;} else if(in_planar) ac->func_type=CONV_FUNC_TYPE_INTERLEAVE;else ac->func_type=CONV_FUNC_TYPE_DEINTERLEAVE;set_generic_function(ac);if(ARCH_AARCH64) ff_audio_convert_init_aarch64(ac);if(ARCH_ARM) ff_audio_convert_init_arm(ac);if(ARCH_X86) ff_audio_convert_init_x86(ac);return ac;} int ff_audio_convert(AudioConvert *ac, AudioData *out, AudioData *in) { int use_generic=1;int len=in->nb_samples;int p;if(ac->dc) { av_log(ac->avr, AV_LOG_TRACE, "%d samples - audio_convert: %s to %s (dithered)\n", len, av_get_sample_fmt_name(ac->in_fmt), av_get_sample_fmt_name(ac->out_fmt));return ff_convert_dither(ac-> in
uint8_t
int ff_filter_frame(AVFilterLink *link, AVFrame *frame)
Send a frame of data to the next filter.
Definition: avfilter.c:1096
int ff_filter_get_nb_threads(AVFilterContext *ctx)
Get number of threads for current filter instance.
Definition: avfilter.c:802
Main libavfilter public API header.
#define flags(name, subs,...)
Definition: cbs_av1.c:572
#define u(width, name, range_min, range_max)
Definition: cbs_h2645.c:264
#define s(width, name)
Definition: cbs_vp9.c:257
#define FFMIN(a, b)
Definition: common.h:105
#define AV_CEIL_RSHIFT(a, b)
Definition: common.h:58
#define av_clip
Definition: common.h:122
#define FFMAX(a, b)
Definition: common.h:103
#define av_clip_uint16
Definition: common.h:134
#define FFABS(a)
Absolute value, Note, INT_MIN / INT64_MIN result in undefined behavior as they are not representable ...
Definition: common.h:72
#define FFDIFFSIGN(x, y)
Comparator.
Definition: common.h:101
#define ARCH_X86
Definition: config.h:39
#define NULL
Definition: coverity.c:32
mode
Use these values in ebur128_init (or'ed).
Definition: ebur128.h:83
static int ff_slice_pos(int total, int jobnr, int nb_jobs)
Compute the boundary index for a slice when work of size total is split into nb_jobs slices.
Definition: filters.h:271
int ff_set_common_formats(AVFilterContext *ctx, AVFilterFormats *formats)
A helper for query_formats() which sets all links to the same list of formats.
Definition: formats.c:587
AVFilterFormats * ff_make_format_list(const int *fmts)
Create a list of supported formats.
Definition: formats.c:286
@ AV_OPT_TYPE_INT
Definition: opt.h:225
#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:126
#define AVFILTER_FLAG_SLICE_THREADS
The filter supports multithreading by splitting frames into multiple parts and processing them concur...
Definition: avfilter.h:117
#define AVERROR(e)
Definition: error.h:43
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
Definition: frame.c:203
int av_frame_copy_props(AVFrame *dst, const AVFrame *src)
Copy only "metadata" fields from src to dst.
Definition: frame.c:658
@ AVMEDIA_TYPE_VIDEO
Definition: avutil.h:201
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:373
misc image utilities
int i
Definition: input.c:407
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:75
const char * arg
Definition: jacosubdec.c:66
common internal API header
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification.
Definition: internal.h:117
static enum AVPixelFormat pix_fmts[]
Definition: libkvazaar.c:309
const char * desc
Definition: libsvtav1.c:79
static const uint64_t c2
Definition: murmur3.c:52
static const uint64_t c1
Definition: murmur3.c:51
AVOptions.
int av_pix_fmt_count_planes(enum AVPixelFormat pix_fmt)
Definition: pixdesc.c:2613
const AVPixFmtDescriptor * av_pix_fmt_desc_get(enum AVPixelFormat pix_fmt)
Definition: pixdesc.c:2573
AVPixelFormat
Pixel format.
Definition: pixfmt.h:64
@ AV_PIX_FMT_NONE
Definition: pixfmt.h:65
@ AV_PIX_FMT_YUV420P
planar YUV 4:2:0, 12bpp, (1 Cr & Cb sample per 2x2 Y samples)
Definition: pixfmt.h:66
@ AV_PIX_FMT_YUV440P
planar YUV 4:4:0 (1 Cr & Cb sample per 1x2 Y samples)
Definition: pixfmt.h:99
@ AV_PIX_FMT_YUV422P
planar YUV 4:2:2, 16bpp, (1 Cr & Cb sample per 2x1 Y samples)
Definition: pixfmt.h:70
@ AV_PIX_FMT_GRAY8
Y , 8bpp.
Definition: pixfmt.h:74
@ AV_PIX_FMT_YUVA420P
planar YUV 4:2:0, 20bpp, (1 Cr & Cb sample per 2x2 Y & A samples)
Definition: pixfmt.h:101
@ 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
@ AV_PIX_FMT_YUV410P
planar YUV 4:1:0, 9bpp, (1 Cr & Cb sample per 4x4 Y samples)
Definition: pixfmt.h:72
@ AV_PIX_FMT_YUV411P
planar YUV 4:1:1, 12bpp, (1 Cr & Cb sample per 4x1 Y samples)
Definition: pixfmt.h:73
@ AV_PIX_FMT_YUV444P
planar YUV 4:4:4, 24bpp, (1 Cr & Cb sample per 1x1 Y samples)
Definition: pixfmt.h:71
@ AV_PIX_FMT_YUVA444P
planar YUV 4:4:4 32bpp, (1 Cr & Cb sample per 1x1 Y & A samples)
Definition: pixfmt.h:177
@ 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:258
@ AV_PIX_FMT_GBRAP
planar GBRA 4:4:4:4 32bpp
Definition: pixfmt.h:215
@ 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
@ AV_PIX_FMT_YUVA422P
planar YUV 4:2:2 24bpp, (1 Cr & Cb sample per 2x1 Y & A samples)
Definition: pixfmt.h:176
@ AV_PIX_FMT_GBRP
planar GBR 4:4:4 24bpp
Definition: pixfmt.h:168
@ 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
@ 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
#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
#define a4
Definition: regdef.h:50
#define a3
Definition: regdef.h:49
#define a5
Definition: regdef.h:51
#define a2
Definition: regdef.h:48
#define td
Definition: regdef.h:70
#define a1
Definition: regdef.h:47
void ff_removegrain_init_x86(RemoveGrainContext *rg)
An instance of a filter.
Definition: avfilter.h:341
void * priv
private data for use by the filter
Definition: avfilter.h:356
A list of supported formats for one end of a filter link.
Definition: formats.h:65
A filter pad used for either input or output.
Definition: internal.h:54
const char * name
Pad name.
Definition: internal.h:60
Filter definition.
Definition: avfilter.h:145
const char * name
Filter name.
Definition: avfilter.h:149
AVFormatInternal * internal
An opaque field for libavformat internal usage.
Definition: avformat.h:1699
This structure describes decoded (raw) audio or video data.
Definition: frame.h:318
AVOption.
Definition: opt.h:248
Descriptor that unambiguously describes how the bits of a pixel are stored in the up to 4 data planes...
Definition: pixdesc.h:81
Used for passing data between threads.
Definition: dsddec.c:67
AVFrame * out
Definition: af_adeclick.c:502
AVFrame * in
Definition: af_adenorm.c:223
int plane
Definition: vf_blend.c:59
#define src
Definition: vp8dsp.c:255
FILE * out
Definition: movenc.c:54
AVFormatContext * ctx
Definition: movenc.c:48
#define height
#define ma
#define mi
static int mode03(int c, int a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8)
static int mode20(int c, int a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8)
static int mode22(int c, int a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8)
static int mode1314(int c, int a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8)
static int filter_slice(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
static int mode19(int c, int a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8)
static int mode01(int c, int a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8)
static int mode08(int c, int a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8)
static int mode18(int c, int a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8)
static int mode1112(int c, int a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8)
static int mode24(int c, int a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8)
static const AVFilterPad removegrain_outputs[]
static int mode1516(int c, int a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8)
static const AVFilterPad removegrain_inputs[]
static int query_formats(AVFilterContext *ctx)
static int config_input(AVFilterLink *inlink)
static int mode02(int c, int a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8)
static int mode10(int c, int a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8)
#define FLAGS
AVFilter ff_vf_removegrain
static int mode09(int c, int a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8)
static int mode04(int c, int a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8)
static int filter_frame(AVFilterLink *inlink, AVFrame *in)
static int mode05(int c, int a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8)
AVFILTER_DEFINE_CLASS(removegrain)
static int mode06(int c, int a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8)
#define REMOVE_GRAIN_SORT_AXIS
static int mode23(int c, int a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8)
static int mode07(int c, int a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8)
static int cmp_int(const void *p1, const void *p2)
#define OFFSET(x)
static int mode17(int c, int a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8)
static const AVOption removegrain_options[]
static int mode21(int c, int a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8)
AVFrame * ff_get_video_buffer(AVFilterLink *link, int w, int h)
Request a picture buffer with a specific set of permissions.
Definition: video.c:104
static double c[64]