FFmpeg
vf_vaguedenoiser.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2003 LeFunGus, lefungus@altern.org
3  *
4  * This file is part of FFmpeg
5  *
6  * FFmpeg is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * FFmpeg is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License along
17  * with FFmpeg; if not, write to the Free Software Foundation, Inc.,
18  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19  */
20 
21 #include <float.h>
22 
23 #include "libavutil/imgutils.h"
24 #include "libavutil/attributes.h"
25 #include "libavutil/common.h"
26 #include "libavutil/pixdesc.h"
27 #include "libavutil/intreadwrite.h"
28 #include "libavutil/opt.h"
29 
30 #include "avfilter.h"
31 #include "formats.h"
32 #include "internal.h"
33 #include "video.h"
34 
35 typedef struct VagueDenoiserContext {
36  const AVClass *class;
37 
38  float threshold;
39  float percent;
40  int method;
41  int type;
42  int nsteps;
43  int planes;
44 
45  int depth;
46  int bpc;
47  int peak;
48  int nb_planes;
49  int planeheight[4];
50  int planewidth[4];
51 
52  float *block;
53  float *in;
54  float *out;
55  float *tmp;
56 
57  int hlowsize[4][32];
58  int hhighsize[4][32];
59  int vlowsize[4][32];
60  int vhighsize[4][32];
61 
62  void (*thresholding)(float *block, const int width, const int height,
63  const int stride, const float threshold,
64  const float percent);
66 
67 #define OFFSET(x) offsetof(VagueDenoiserContext, x)
68 #define FLAGS AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_FILTERING_PARAM
69 static const AVOption vaguedenoiser_options[] = {
70  { "threshold", "set filtering strength", OFFSET(threshold), AV_OPT_TYPE_FLOAT, {.dbl=2.}, 0,DBL_MAX, FLAGS },
71  { "method", "set filtering method", OFFSET(method), AV_OPT_TYPE_INT, {.i64=2 }, 0, 2, FLAGS, "method" },
72  { "hard", "hard thresholding", 0, AV_OPT_TYPE_CONST, {.i64=0}, 0, 0, FLAGS, "method" },
73  { "soft", "soft thresholding", 0, AV_OPT_TYPE_CONST, {.i64=1}, 0, 0, FLAGS, "method" },
74  { "garrote", "garrote thresholding", 0, AV_OPT_TYPE_CONST, {.i64=2}, 0, 0, FLAGS, "method" },
75  { "nsteps", "set number of steps", OFFSET(nsteps), AV_OPT_TYPE_INT, {.i64=6 }, 1, 32, FLAGS },
76  { "percent", "set percent of full denoising", OFFSET(percent),AV_OPT_TYPE_FLOAT, {.dbl=85}, 0,100, FLAGS },
77  { "planes", "set planes to filter", OFFSET(planes), AV_OPT_TYPE_INT, {.i64=15 }, 0, 15, FLAGS },
78  { "type", "set threshold type", OFFSET(type), AV_OPT_TYPE_INT, {.i64=0 }, 0, 1, FLAGS, "type" },
79  { "universal", "universal (VisuShrink)", 0, AV_OPT_TYPE_CONST, {.i64=0}, 0, 0, FLAGS, "type" },
80  { "bayes", "bayes (BayesShrink)", 0, AV_OPT_TYPE_CONST, {.i64=1}, 0, 0, FLAGS, "type" },
81  { NULL }
82 };
83 
84 AVFILTER_DEFINE_CLASS(vaguedenoiser);
85 
86 #define NPAD 10
87 
88 static const float analysis_low[9] = {
89  0.037828455506995f, -0.023849465019380f, -0.110624404418423f, 0.377402855612654f,
90  0.852698679009403f, 0.377402855612654f, -0.110624404418423f, -0.023849465019380f, 0.037828455506995f
91 };
92 
93 static const float analysis_high[7] = {
94  -0.064538882628938f, 0.040689417609558f, 0.418092273222212f, -0.788485616405664f,
95  0.418092273222212f, 0.040689417609558f, -0.064538882628938f
96 };
97 
98 static const float synthesis_low[7] = {
99  -0.064538882628938f, -0.040689417609558f, 0.418092273222212f, 0.788485616405664f,
100  0.418092273222212f, -0.040689417609558f, -0.064538882628938f
101 };
102 
103 static const float synthesis_high[9] = {
104  -0.037828455506995f, -0.023849465019380f, 0.110624404418423f, 0.377402855612654f,
105  -0.852698679009403f, 0.377402855612654f, 0.110624404418423f, -0.023849465019380f, -0.037828455506995f
106 };
107 
108 static const enum AVPixelFormat pix_fmts[] = {
132 };
133 
135 {
136  VagueDenoiserContext *s = inlink->dst->priv;
138  int p, i, nsteps_width, nsteps_height, nsteps_max;
139 
140  s->depth = desc->comp[0].depth;
141  s->bpc = (s->depth + 7) / 8;
142  s->nb_planes = desc->nb_components;
143 
144  s->planeheight[1] = s->planeheight[2] = AV_CEIL_RSHIFT(inlink->h, desc->log2_chroma_h);
145  s->planeheight[0] = s->planeheight[3] = inlink->h;
146  s->planewidth[1] = s->planewidth[2] = AV_CEIL_RSHIFT(inlink->w, desc->log2_chroma_w);
147  s->planewidth[0] = s->planewidth[3] = inlink->w;
148 
149  s->block = av_malloc_array(inlink->w * inlink->h, sizeof(*s->block));
150  s->in = av_malloc_array(32 + FFMAX(inlink->w, inlink->h), sizeof(*s->in));
151  s->out = av_malloc_array(32 + FFMAX(inlink->w, inlink->h), sizeof(*s->out));
152  s->tmp = av_malloc_array(32 + FFMAX(inlink->w, inlink->h), sizeof(*s->tmp));
153 
154  if (!s->block || !s->in || !s->out || !s->tmp)
155  return AVERROR(ENOMEM);
156 
157  s->threshold *= 1 << (s->depth - 8);
158  s->peak = (1 << s->depth) - 1;
159 
160  nsteps_width = ((s->planes & 2 || s->planes & 4) && s->nb_planes > 1) ? s->planewidth[1] : s->planewidth[0];
161  nsteps_height = ((s->planes & 2 || s->planes & 4) && s->nb_planes > 1) ? s->planeheight[1] : s->planeheight[0];
162 
163  for (nsteps_max = 1; nsteps_max < 15; nsteps_max++) {
164  if (pow(2, nsteps_max) >= nsteps_width || pow(2, nsteps_max) >= nsteps_height)
165  break;
166  }
167 
168  s->nsteps = FFMIN(s->nsteps, nsteps_max - 2);
169 
170  for (p = 0; p < 4; p++) {
171  s->hlowsize[p][0] = (s->planewidth[p] + 1) >> 1;
172  s->hhighsize[p][0] = s->planewidth[p] >> 1;
173  s->vlowsize[p][0] = (s->planeheight[p] + 1) >> 1;
174  s->vhighsize[p][0] = s->planeheight[p] >> 1;
175 
176  for (i = 1; i < s->nsteps; i++) {
177  s->hlowsize[p][i] = (s->hlowsize[p][i - 1] + 1) >> 1;
178  s->hhighsize[p][i] = s->hlowsize[p][i - 1] >> 1;
179  s->vlowsize[p][i] = (s->vlowsize[p][i - 1] + 1) >> 1;
180  s->vhighsize[p][i] = s->vlowsize[p][i - 1] >> 1;
181  }
182  }
183 
184  return 0;
185 }
186 
187 static inline void copy(const float *p1, float *p2, const int length)
188 {
189  memcpy(p2, p1, length * sizeof(float));
190 }
191 
192 static inline void copyv(const float *p1, const int stride1, float *p2, const int length)
193 {
194  int i;
195 
196  for (i = 0; i < length; i++) {
197  p2[i] = *p1;
198  p1 += stride1;
199  }
200 }
201 
202 static inline void copyh(const float *p1, float *p2, const int stride2, const int length)
203 {
204  int i;
205 
206  for (i = 0; i < length; i++) {
207  *p2 = p1[i];
208  p2 += stride2;
209  }
210 }
211 
212 // Do symmetric extension of data using prescribed symmetries
213 // Original values are in output[npad] through output[npad+size-1]
214 // New values will be placed in output[0] through output[npad] and in output[npad+size] through output[2*npad+size-1] (note: end values may not be filled in)
215 // extension at left bdry is ... 3 2 1 0 | 0 1 2 3 ...
216 // same for right boundary
217 // if right_ext=1 then ... 3 2 1 0 | 1 2 3
218 static void symmetric_extension(float *output, const int size, const int left_ext, const int right_ext)
219 {
220  int first = NPAD;
221  int last = NPAD - 1 + size;
222  const int originalLast = last;
223  int i, nextend, idx;
224 
225  if (left_ext == 2)
226  output[--first] = output[NPAD];
227  if (right_ext == 2)
228  output[++last] = output[originalLast];
229 
230  // extend left end
231  nextend = first;
232  for (i = 0; i < nextend; i++)
233  output[--first] = output[NPAD + 1 + i];
234 
235  idx = NPAD + NPAD - 1 + size;
236 
237  // extend right end
238  nextend = idx - last;
239  for (i = 0; i < nextend; i++)
240  output[++last] = output[originalLast - 1 - i];
241 }
242 
243 static void transform_step(float *input, float *output, const int size, const int low_size, VagueDenoiserContext *s)
244 {
245  int i;
246 
248 
249  for (i = NPAD; i < NPAD + low_size; i++) {
250  const float a = input[2 * i - 14] * analysis_low[0];
251  const float b = input[2 * i - 13] * analysis_low[1];
252  const float c = input[2 * i - 12] * analysis_low[2];
253  const float d = input[2 * i - 11] * analysis_low[3];
254  const float e = input[2 * i - 10] * analysis_low[4];
255  const float f = input[2 * i - 9] * analysis_low[3];
256  const float g = input[2 * i - 8] * analysis_low[2];
257  const float h = input[2 * i - 7] * analysis_low[1];
258  const float k = input[2 * i - 6] * analysis_low[0];
259 
260  output[i] = a + b + c + d + e + f + g + h + k;
261  }
262 
263  for (i = NPAD; i < NPAD + low_size; i++) {
264  const float a = input[2 * i - 12] * analysis_high[0];
265  const float b = input[2 * i - 11] * analysis_high[1];
266  const float c = input[2 * i - 10] * analysis_high[2];
267  const float d = input[2 * i - 9] * analysis_high[3];
268  const float e = input[2 * i - 8] * analysis_high[2];
269  const float f = input[2 * i - 7] * analysis_high[1];
270  const float g = input[2 * i - 6] * analysis_high[0];
271 
272  output[i + low_size] = a + b + c + d + e + f + g;
273  }
274 }
275 
276 static void invert_step(const float *input, float *output, float *temp, const int size, VagueDenoiserContext *s)
277 {
278  const int low_size = (size + 1) >> 1;
279  const int high_size = size >> 1;
280  int left_ext = 1, right_ext, i;
281  int findex;
282 
283  memcpy(temp + NPAD, input + NPAD, low_size * sizeof(float));
284 
285  right_ext = (size % 2 == 0) ? 2 : 1;
286  symmetric_extension(temp, low_size, left_ext, right_ext);
287 
288  memset(output, 0, (NPAD + NPAD + size) * sizeof(float));
289  findex = (size + 2) >> 1;
290 
291  for (i = 9; i < findex + 11; i++) {
292  const float a = temp[i] * synthesis_low[0];
293  const float b = temp[i] * synthesis_low[1];
294  const float c = temp[i] * synthesis_low[2];
295  const float d = temp[i] * synthesis_low[3];
296 
297  output[2 * i - 13] += a;
298  output[2 * i - 12] += b;
299  output[2 * i - 11] += c;
300  output[2 * i - 10] += d;
301  output[2 * i - 9] += c;
302  output[2 * i - 8] += b;
303  output[2 * i - 7] += a;
304  }
305 
306  memcpy(temp + NPAD, input + NPAD + low_size, high_size * sizeof(float));
307 
308  left_ext = 2;
309  right_ext = (size % 2 == 0) ? 1 : 2;
310  symmetric_extension(temp, high_size, left_ext, right_ext);
311 
312  for (i = 8; i < findex + 11; i++) {
313  const float a = temp[i] * synthesis_high[0];
314  const float b = temp[i] * synthesis_high[1];
315  const float c = temp[i] * synthesis_high[2];
316  const float d = temp[i] * synthesis_high[3];
317  const float e = temp[i] * synthesis_high[4];
318 
319  output[2 * i - 13] += a;
320  output[2 * i - 12] += b;
321  output[2 * i - 11] += c;
322  output[2 * i - 10] += d;
323  output[2 * i - 9] += e;
324  output[2 * i - 8] += d;
325  output[2 * i - 7] += c;
326  output[2 * i - 6] += b;
327  output[2 * i - 5] += a;
328  }
329 }
330 
331 static void hard_thresholding(float *block, const int width, const int height,
332  const int stride, const float threshold,
333  const float percent)
334 {
335  const float frac = 1.f - percent * 0.01f;
336  int y, x;
337 
338  for (y = 0; y < height; y++) {
339  for (x = 0; x < width; x++) {
340  if (FFABS(block[x]) <= threshold)
341  block[x] *= frac;
342  }
343  block += stride;
344  }
345 }
346 
347 static void soft_thresholding(float *block, const int width, const int height, const int stride,
348  const float threshold, const float percent)
349 {
350  const float frac = 1.f - percent * 0.01f;
351  const float shift = threshold * 0.01f * percent;
352  int y, x;
353 
354  for (y = 0; y < height; y++) {
355  for (x = 0; x < width; x++) {
356  const float temp = FFABS(block[x]);
357  if (temp <= threshold)
358  block[x] *= frac;
359  else
360  block[x] = (block[x] < 0.f ? -1.f : (block[x] > 0.f ? 1.f : 0.f)) * (temp - shift);
361  }
362  block += stride;
363  }
364 }
365 
366 static void qian_thresholding(float *block, const int width, const int height,
367  const int stride, const float threshold,
368  const float percent)
369 {
370  const float percent01 = percent * 0.01f;
371  const float tr2 = threshold * threshold * percent01;
372  const float frac = 1.f - percent01;
373  int y, x;
374 
375  for (y = 0; y < height; y++) {
376  for (x = 0; x < width; x++) {
377  const float temp = FFABS(block[x]);
378  if (temp <= threshold) {
379  block[x] *= frac;
380  } else {
381  const float tp2 = temp * temp;
382  block[x] *= (tp2 - tr2) / tp2;
383  }
384  }
385  block += stride;
386  }
387 }
388 
389 static float bayes_threshold(float *block, const int width, const int height,
390  const int stride, const float threshold)
391 {
392  float mean = 0.f;
393 
394  for (int y = 0; y < height; y++) {
395  for (int x = 0; x < width; x++) {
396  mean += block[x] * block[x];
397  }
398  block += stride;
399  }
400 
401  mean /= width * height;
402 
403  return threshold * threshold / (FFMAX(sqrtf(mean - threshold), FLT_EPSILON));
404 }
405 
407 {
408  int p, y, x, i, j;
409 
410  for (p = 0; p < s->nb_planes; p++) {
411  const int height = s->planeheight[p];
412  const int width = s->planewidth[p];
413  const uint8_t *srcp8 = in->data[p];
414  const uint16_t *srcp16 = (const uint16_t *)in->data[p];
415  uint8_t *dstp8 = out->data[p];
416  uint16_t *dstp16 = (uint16_t *)out->data[p];
417  float *output = s->block;
418  int h_low_size0 = width;
419  int v_low_size0 = height;
420  int nsteps_transform = s->nsteps;
421  int nsteps_invert = s->nsteps;
422  const float *input = s->block;
423 
424  if (!((1 << p) & s->planes)) {
425  av_image_copy_plane(out->data[p], out->linesize[p], in->data[p], in->linesize[p],
426  s->planewidth[p] * s->bpc, s->planeheight[p]);
427  continue;
428  }
429 
430  if (s->depth <= 8) {
431  for (y = 0; y < height; y++) {
432  for (x = 0; x < width; x++)
433  output[x] = srcp8[x];
434  srcp8 += in->linesize[p];
435  output += width;
436  }
437  } else {
438  for (y = 0; y < height; y++) {
439  for (x = 0; x < width; x++)
440  output[x] = srcp16[x];
441  srcp16 += in->linesize[p] / 2;
442  output += width;
443  }
444  }
445 
446  while (nsteps_transform--) {
447  int low_size = (h_low_size0 + 1) >> 1;
448  float *input = s->block;
449  for (j = 0; j < v_low_size0; j++) {
450  copy(input, s->in + NPAD, h_low_size0);
451  transform_step(s->in, s->out, h_low_size0, low_size, s);
452  copy(s->out + NPAD, input, h_low_size0);
453  input += width;
454  }
455 
456  low_size = (v_low_size0 + 1) >> 1;
457  input = s->block;
458  for (j = 0; j < h_low_size0; j++) {
459  copyv(input, width, s->in + NPAD, v_low_size0);
460  transform_step(s->in, s->out, v_low_size0, low_size, s);
461  copyh(s->out + NPAD, input, width, v_low_size0);
462  input++;
463  }
464 
465  h_low_size0 = (h_low_size0 + 1) >> 1;
466  v_low_size0 = (v_low_size0 + 1) >> 1;
467  }
468 
469  if (s->type == 0) {
470  s->thresholding(s->block, width, height, width, s->threshold, s->percent);
471  } else {
472  for (int n = 0; n < s->nsteps; n++) {
473  float threshold;
474  float *block;
475 
476  if (n == s->nsteps - 1) {
477  threshold = bayes_threshold(s->block, s->hlowsize[p][n], s->vlowsize[p][n], width, s->threshold);
478  s->thresholding(s->block, s->hlowsize[p][n], s->vlowsize[p][n], width, threshold, s->percent);
479  }
480  block = s->block + s->hlowsize[p][n];
481  threshold = bayes_threshold(block, s->hhighsize[p][n], s->vlowsize[p][n], width, s->threshold);
482  s->thresholding(block, s->hhighsize[p][n], s->vlowsize[p][n], width, threshold, s->percent);
483  block = s->block + s->vlowsize[p][n] * width;
484  threshold = bayes_threshold(block, s->hlowsize[p][n], s->vhighsize[p][n], width, s->threshold);
485  s->thresholding(block, s->hlowsize[p][n], s->vhighsize[p][n], width, threshold, s->percent);
486  block = s->block + s->hlowsize[p][n] + s->vlowsize[p][n] * width;
487  threshold = bayes_threshold(block, s->hhighsize[p][n], s->vhighsize[p][n], width, s->threshold);
488  s->thresholding(block, s->hhighsize[p][n], s->vhighsize[p][n], width, threshold, s->percent);
489  }
490  }
491 
492  while (nsteps_invert--) {
493  const int idx = s->vlowsize[p][nsteps_invert] + s->vhighsize[p][nsteps_invert];
494  const int idx2 = s->hlowsize[p][nsteps_invert] + s->hhighsize[p][nsteps_invert];
495  float * idx3 = s->block;
496  for (i = 0; i < idx2; i++) {
497  copyv(idx3, width, s->in + NPAD, idx);
498  invert_step(s->in, s->out, s->tmp, idx, s);
499  copyh(s->out + NPAD, idx3, width, idx);
500  idx3++;
501  }
502 
503  idx3 = s->block;
504  for (i = 0; i < idx; i++) {
505  copy(idx3, s->in + NPAD, idx2);
506  invert_step(s->in, s->out, s->tmp, idx2, s);
507  copy(s->out + NPAD, idx3, idx2);
508  idx3 += width;
509  }
510  }
511 
512  if (s->depth <= 8) {
513  for (y = 0; y < height; y++) {
514  for (x = 0; x < width; x++)
515  dstp8[x] = av_clip_uint8(input[x] + 0.5f);
516  input += width;
517  dstp8 += out->linesize[p];
518  }
519  } else {
520  for (y = 0; y < height; y++) {
521  for (x = 0; x < width; x++)
522  dstp16[x] = av_clip(input[x] + 0.5f, 0, s->peak);
523  input += width;
524  dstp16 += out->linesize[p] / 2;
525  }
526  }
527  }
528 }
529 
531 {
532  AVFilterContext *ctx = inlink->dst;
533  VagueDenoiserContext *s = ctx->priv;
534  AVFilterLink *outlink = ctx->outputs[0];
535  AVFrame *out;
536  int direct = av_frame_is_writable(in);
537 
538  if (direct) {
539  out = in;
540  } else {
541  out = ff_get_video_buffer(outlink, outlink->w, outlink->h);
542  if (!out) {
543  av_frame_free(&in);
544  return AVERROR(ENOMEM);
545  }
546 
548  }
549 
550  filter(s, in, out);
551 
552  if (!direct)
553  av_frame_free(&in);
554 
555  return ff_filter_frame(outlink, out);
556 }
557 
559 {
560  VagueDenoiserContext *s = ctx->priv;
561 
562  switch (s->method) {
563  case 0:
564  s->thresholding = hard_thresholding;
565  break;
566  case 1:
567  s->thresholding = soft_thresholding;
568  break;
569  case 2:
570  s->thresholding = qian_thresholding;
571  break;
572  }
573 
574  return 0;
575 }
576 
578 {
579  VagueDenoiserContext *s = ctx->priv;
580 
581  av_freep(&s->block);
582  av_freep(&s->in);
583  av_freep(&s->out);
584  av_freep(&s->tmp);
585 }
586 
588  {
589  .name = "default",
590  .type = AVMEDIA_TYPE_VIDEO,
591  .config_props = config_input,
592  .filter_frame = filter_frame,
593  },
594 };
595 
596 
598  {
599  .name = "default",
600  .type = AVMEDIA_TYPE_VIDEO
601  },
602 };
603 
605  .name = "vaguedenoiser",
606  .description = NULL_IF_CONFIG_SMALL("Apply a Wavelet based Denoiser."),
607  .priv_size = sizeof(VagueDenoiserContext),
608  .priv_class = &vaguedenoiser_class,
609  .init = init,
610  .uninit = uninit,
615 };
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
AV_PIX_FMT_YUVA422P16
#define AV_PIX_FMT_YUVA422P16
Definition: pixfmt.h:502
AV_PIX_FMT_GBRAP16
#define AV_PIX_FMT_GBRAP16
Definition: pixfmt.h:481
AVPixelFormat
AVPixelFormat
Pixel format.
Definition: pixfmt.h:64
planes
static const struct @346 planes[]
av_clip
#define av_clip
Definition: common.h:95
transform_step
static void transform_step(float *input, float *output, const int size, const int low_size, VagueDenoiserContext *s)
Definition: vf_vaguedenoiser.c:243
filter
static void filter(VagueDenoiserContext *s, AVFrame *in, AVFrame *out)
Definition: vf_vaguedenoiser.c:406
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
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
FILTER_PIXFMTS_ARRAY
#define FILTER_PIXFMTS_ARRAY(array)
Definition: internal.h:174
copyv
static void copyv(const float *p1, const int stride1, float *p2, const int length)
Definition: vf_vaguedenoiser.c:192
OFFSET
#define OFFSET(x)
Definition: vf_vaguedenoiser.c:67
output
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 output
Definition: filter_design.txt:225
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
AV_PIX_FMT_YUVA422P9
#define AV_PIX_FMT_YUVA422P9
Definition: pixfmt.h:494
VagueDenoiserContext::in
float * in
Definition: vf_vaguedenoiser.c:53
AVFrame
This structure describes decoded (raw) audio or video data.
Definition: frame.h:330
pixdesc.h
AV_PIX_FMT_YUVA420P16
#define AV_PIX_FMT_YUVA420P16
Definition: pixfmt.h:501
vaguedenoiser_outputs
static const AVFilterPad vaguedenoiser_outputs[]
Definition: vf_vaguedenoiser.c:597
AV_PIX_FMT_YUVA420P10
#define AV_PIX_FMT_YUVA420P10
Definition: pixfmt.h:496
AVOption
AVOption.
Definition: opt.h:251
b
#define b
Definition: input.c:41
AV_PIX_FMT_YUV420P10
#define AV_PIX_FMT_YUV420P10
Definition: pixfmt.h:459
float.h
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
FFMAX
#define FFMAX(a, b)
Definition: macros.h:47
AVFilter::name
const char * name
Filter name.
Definition: avfilter.h:165
video.h
copyh
static void copyh(const float *p1, float *p2, const int stride2, const int length)
Definition: vf_vaguedenoiser.c:202
AV_PIX_FMT_YUVA422P10
#define AV_PIX_FMT_YUVA422P10
Definition: pixfmt.h:497
AV_PIX_FMT_GRAY9
#define AV_PIX_FMT_GRAY9
Definition: pixfmt.h:439
symmetric_extension
static void symmetric_extension(float *output, const int size, const int left_ext, const int right_ext)
Definition: vf_vaguedenoiser.c:218
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
VagueDenoiserContext::hhighsize
int hhighsize[4][32]
Definition: vf_vaguedenoiser.c:58
formats.h
AV_PIX_FMT_YUVA420P9
#define AV_PIX_FMT_YUVA420P9
Definition: pixfmt.h:493
AV_PIX_FMT_GBRP14
#define AV_PIX_FMT_GBRP14
Definition: pixfmt.h:477
AV_PIX_FMT_GBRAP
@ AV_PIX_FMT_GBRAP
planar GBRA 4:4:4:4 32bpp
Definition: pixfmt.h:205
analysis_high
static const float analysis_high[7]
Definition: vf_vaguedenoiser.c:93
AV_PIX_FMT_GBRP10
#define AV_PIX_FMT_GBRP10
Definition: pixfmt.h:475
AV_PIX_FMT_YUVA444P16
#define AV_PIX_FMT_YUVA444P16
Definition: pixfmt.h:503
VagueDenoiserContext::depth
int depth
Definition: vf_vaguedenoiser.c:45
VagueDenoiserContext::peak
int peak
Definition: vf_vaguedenoiser.c:47
AV_PIX_FMT_YUV422P9
#define AV_PIX_FMT_YUV422P9
Definition: pixfmt.h:457
invert_step
static void invert_step(const float *input, float *output, float *temp, const int size, VagueDenoiserContext *s)
Definition: vf_vaguedenoiser.c:276
type
it s the only field you need to keep assuming you have a context There is some magic you don t need to care about around this just let it vf type
Definition: writing_filters.txt:86
VagueDenoiserContext::nsteps
int nsteps
Definition: vf_vaguedenoiser.c:42
AV_PIX_FMT_GRAY16
#define AV_PIX_FMT_GRAY16
Definition: pixfmt.h:443
qian_thresholding
static void qian_thresholding(float *block, const int width, const int height, const int stride, const float threshold, const float percent)
Definition: vf_vaguedenoiser.c:366
AVFilterPad
A filter pad used for either input or output.
Definition: internal.h:49
VagueDenoiserContext::nb_planes
int nb_planes
Definition: vf_vaguedenoiser.c:48
AV_PIX_FMT_YUV444P10
#define AV_PIX_FMT_YUV444P10
Definition: pixfmt.h:462
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
first
trying all byte sequences megabyte in length and selecting the best looking sequence will yield cases to try But first
Definition: rate_distortion.txt:12
av_cold
#define av_cold
Definition: attributes.h:90
AV_PIX_FMT_YUV422P16
#define AV_PIX_FMT_YUV422P16
Definition: pixfmt.h:471
VagueDenoiserContext::thresholding
void(* thresholding)(float *block, const int width, const int height, const int stride, const float threshold, const float percent)
Definition: vf_vaguedenoiser.c:62
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
AV_PIX_FMT_GBRAP10
#define AV_PIX_FMT_GBRAP10
Definition: pixfmt.h:479
width
#define width
synthesis_low
static const float synthesis_low[7]
Definition: vf_vaguedenoiser.c:98
intreadwrite.h
s
#define s(width, name)
Definition: cbs_vp9.c:256
AV_PIX_FMT_GBRAP12
#define AV_PIX_FMT_GBRAP12
Definition: pixfmt.h:480
VagueDenoiserContext::percent
float percent
Definition: vf_vaguedenoiser.c:39
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
AV_PIX_FMT_YUV444P16
#define AV_PIX_FMT_YUV444P16
Definition: pixfmt.h:472
AV_CEIL_RSHIFT
#define AV_CEIL_RSHIFT(a, b)
Definition: common.h:50
g
const char * g
Definition: vf_curves.c:127
AV_PIX_FMT_YUVA444P12
#define AV_PIX_FMT_YUVA444P12
Definition: pixfmt.h:500
AV_PIX_FMT_YUV420P9
#define AV_PIX_FMT_YUV420P9
Definition: pixfmt.h:456
AV_PIX_FMT_YUV420P16
#define AV_PIX_FMT_YUV420P16
Definition: pixfmt.h:470
ctx
AVFormatContext * ctx
Definition: movenc.c:48
AV_PIX_FMT_GRAY14
#define AV_PIX_FMT_GRAY14
Definition: pixfmt.h:442
synthesis_high
static const float synthesis_high[9]
Definition: vf_vaguedenoiser.c:103
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
VagueDenoiserContext::tmp
float * tmp
Definition: vf_vaguedenoiser.c:55
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
bayes_threshold
static float bayes_threshold(float *block, const int width, const int height, const int stride, const float threshold)
Definition: vf_vaguedenoiser.c:389
FFABS
#define FFABS(a)
Absolute value, Note, INT_MIN / INT64_MIN result in undefined behavior as they are not representable ...
Definition: common.h:64
AV_PIX_FMT_GRAY10
#define AV_PIX_FMT_GRAY10
Definition: pixfmt.h:440
VagueDenoiserContext
Definition: vf_vaguedenoiser.c:35
AV_PIX_FMT_GBRP16
#define AV_PIX_FMT_GBRP16
Definition: pixfmt.h:478
AVClass
Describe the class of an AVClass context structure.
Definition: log.h:66
NULL
#define NULL
Definition: coverity.c:32
filter_frame
static int filter_frame(AVFilterLink *inlink, AVFrame *in)
Definition: vf_vaguedenoiser.c:530
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
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
hard_thresholding
static void hard_thresholding(float *block, const int width, const int height, const int stride, const float threshold, const float percent)
Definition: vf_vaguedenoiser.c:331
AV_PIX_FMT_YUV440P10
#define AV_PIX_FMT_YUV440P10
Definition: pixfmt.h:461
sqrtf
static __device__ float sqrtf(float a)
Definition: cuda_runtime.h:184
vaguedenoiser_inputs
static const AVFilterPad vaguedenoiser_inputs[]
Definition: vf_vaguedenoiser.c:587
AV_PIX_FMT_YUV422P10
#define AV_PIX_FMT_YUV422P10
Definition: pixfmt.h:460
AV_PIX_FMT_GRAY8
@ AV_PIX_FMT_GRAY8
Y , 8bpp.
Definition: pixfmt.h:74
AV_PIX_FMT_GBRP9
#define AV_PIX_FMT_GBRP9
Definition: pixfmt.h:474
VagueDenoiserContext::threshold
float threshold
Definition: vf_vaguedenoiser.c:38
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
FLAGS
#define FLAGS
Definition: vf_vaguedenoiser.c:68
VagueDenoiserContext::hlowsize
int hlowsize[4][32]
Definition: vf_vaguedenoiser.c:57
f
f
Definition: af_crystalizer.c:122
init
static av_cold int init(AVFilterContext *ctx)
Definition: vf_vaguedenoiser.c:558
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
copy
static void copy(const float *p1, float *p2, const int length)
Definition: vf_vaguedenoiser.c:187
shift
static int shift(int a, int b)
Definition: bonk.c:257
AVFILTER_DEFINE_CLASS
AVFILTER_DEFINE_CLASS(vaguedenoiser)
ff_vf_vaguedenoiser
const AVFilter ff_vf_vaguedenoiser
Definition: vf_vaguedenoiser.c:604
AV_PIX_FMT_YUV422P12
#define AV_PIX_FMT_YUV422P12
Definition: pixfmt.h:464
size
int size
Definition: twinvq_data.h:10344
VagueDenoiserContext::vlowsize
int vlowsize[4][32]
Definition: vf_vaguedenoiser.c:59
AV_PIX_FMT_YUV444P12
#define AV_PIX_FMT_YUV444P12
Definition: pixfmt.h:466
VagueDenoiserContext::block
float * block
Definition: vf_vaguedenoiser.c:52
av_frame_is_writable
int av_frame_is_writable(AVFrame *frame)
Check if the frame data is writable.
Definition: frame.c:524
uninit
static av_cold void uninit(AVFilterContext *ctx)
Definition: vf_vaguedenoiser.c:577
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
config_input
static int config_input(AVFilterLink *inlink)
Definition: vf_vaguedenoiser.c:134
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
AV_PIX_FMT_YUVA444P10
#define AV_PIX_FMT_YUVA444P10
Definition: pixfmt.h:498
attributes.h
VagueDenoiserContext::planewidth
int planewidth[4]
Definition: vf_vaguedenoiser.c:50
input
and forward the test the status of outputs and forward it to the corresponding return FFERROR_NOT_READY If the filters stores internally one or a few frame for some input
Definition: filter_design.txt:172
internal.h
VagueDenoiserContext::vhighsize
int vhighsize[4][32]
Definition: vf_vaguedenoiser.c:60
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
AV_OPT_TYPE_FLOAT
@ AV_OPT_TYPE_FLOAT
Definition: opt.h:228
VagueDenoiserContext::method
int method
Definition: vf_vaguedenoiser.c:40
VagueDenoiserContext::type
int type
Definition: vf_vaguedenoiser.c:41
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:269
av_malloc_array
#define av_malloc_array(a, b)
Definition: tableprint_vlc.h:31
AV_PIX_FMT_GBRP12
#define AV_PIX_FMT_GBRP12
Definition: pixfmt.h:476
common.h
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
AV_PIX_FMT_YUV444P9
#define AV_PIX_FMT_YUV444P9
Definition: pixfmt.h:458
vaguedenoiser_options
static const AVOption vaguedenoiser_options[]
Definition: vf_vaguedenoiser.c:69
stride
#define stride
Definition: h264pred_template.c:537
AVFilter
Filter definition.
Definition: avfilter.h:161
VagueDenoiserContext::planeheight
int planeheight[4]
Definition: vf_vaguedenoiser.c:49
analysis_low
static const float analysis_low[9]
Definition: vf_vaguedenoiser.c:88
AV_PIX_FMT_YUVA444P9
#define AV_PIX_FMT_YUVA444P9
Definition: pixfmt.h:495
left_ext
static int left_ext(int wavelet_length, int levels, uint64_t sn)
Definition: af_afwtdn.c:508
AV_PIX_FMT_YUV420P12
#define AV_PIX_FMT_YUV420P12
Definition: pixfmt.h:463
AV_PIX_FMT_YUV422P14
#define AV_PIX_FMT_YUV422P14
Definition: pixfmt.h:468
soft_thresholding
static void soft_thresholding(float *block, const int width, const int height, const int stride, const float threshold, const float percent)
Definition: vf_vaguedenoiser.c:347
NPAD
#define NPAD
Definition: vf_vaguedenoiser.c:86
AV_PIX_FMT_NONE
@ AV_PIX_FMT_NONE
Definition: pixfmt.h:65
AV_PIX_FMT_YUVA422P12
#define AV_PIX_FMT_YUVA422P12
Definition: pixfmt.h:499
AV_OPT_TYPE_INT
@ AV_OPT_TYPE_INT
Definition: opt.h:225
avfilter.h
temp
else temp
Definition: vf_mcdeint.c:248
mean
static float mean(const float *input, int size)
Definition: vf_nnedi.c:857
VagueDenoiserContext::planes
int planes
Definition: vf_vaguedenoiser.c:43
av_clip_uint8
#define av_clip_uint8
Definition: common.h:101
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_PIX_FMT_GBRP
@ AV_PIX_FMT_GBRP
planar GBR 4:4:4 24bpp
Definition: pixfmt.h:158
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
VagueDenoiserContext::out
float * out
Definition: vf_vaguedenoiser.c:54
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
av_freep
#define av_freep(p)
Definition: tableprint_vlc.h:34
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
block
The exact code depends on how similar the blocks are and how related they are to the block
Definition: filter_design.txt:207
AV_PIX_FMT_YUV440P12
#define AV_PIX_FMT_YUV440P12
Definition: pixfmt.h:465
h
h
Definition: vp9dsp_template.c:2038
AV_PIX_FMT_YUV444P14
#define AV_PIX_FMT_YUV444P14
Definition: pixfmt.h:469
AV_PIX_FMT_GRAY12
#define AV_PIX_FMT_GRAY12
Definition: pixfmt.h:441
AV_OPT_TYPE_CONST
@ AV_OPT_TYPE_CONST
Definition: opt.h:234
VagueDenoiserContext::bpc
int bpc
Definition: vf_vaguedenoiser.c:46
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
AV_PIX_FMT_YUV420P14
#define AV_PIX_FMT_YUV420P14
Definition: pixfmt.h:467
pix_fmts
static enum AVPixelFormat pix_fmts[]
Definition: vf_vaguedenoiser.c:108