FFmpeg
vf_nlmeans.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2016 Clément Bœsch <u pkh me>
3  *
4  * This file is part of FFmpeg.
5  *
6  * FFmpeg is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (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 GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with FFmpeg; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19  */
20 
21 /**
22  * @todo
23  * - better automatic defaults? see "Parameters" @ http://www.ipol.im/pub/art/2011/bcm_nlm/
24  * - temporal support (probably doesn't need any displacement according to
25  * "Denoising image sequences does not require motion estimation")
26  * - Bayer pixel format support for at least raw photos? (DNG support would be
27  * handy here)
28  * - FATE test (probably needs visual threshold test mechanism due to the use
29  * of floats)
30  */
31 
32 #include "libavutil/avassert.h"
33 #include "libavutil/opt.h"
34 #include "libavutil/pixdesc.h"
35 #include "avfilter.h"
36 #include "formats.h"
37 #include "internal.h"
38 #include "vf_nlmeans.h"
39 #include "video.h"
40 
41 struct weighted_avg {
42  float total_weight;
43  float sum;
44 };
45 
46 typedef struct NLMeansContext {
47  const AVClass *class;
48  int nb_planes;
50  double pdiff_scale; // invert of the filtering parameter (sigma*10) squared
51  double sigma; // denoising strength
52  int patch_size, patch_hsize; // patch size and half size
53  int patch_size_uv, patch_hsize_uv; // patch size and half size for chroma planes
54  int research_size, research_hsize; // research size and half size
55  int research_size_uv, research_hsize_uv; // research size and half size for chroma planes
56  uint32_t *ii_orig; // integral image
57  uint32_t *ii; // integral image starting after the 0-line and 0-column
58  int ii_w, ii_h; // width and height of the integral image
59  ptrdiff_t ii_lz_32; // linesize in 32-bit units of the integral image
60  struct weighted_avg *wa; // weighted average of every pixel
61  ptrdiff_t wa_linesize; // linesize for wa in struct size unit
62  float *weight_lut; // lookup table mapping (scaled) patch differences to their associated weights
63  uint32_t max_meaningful_diff; // maximum difference considered (if the patch difference is too high we ignore the pixel)
66 
67 #define OFFSET(x) offsetof(NLMeansContext, x)
68 #define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM
69 static const AVOption nlmeans_options[] = {
70  { "s", "denoising strength", OFFSET(sigma), AV_OPT_TYPE_DOUBLE, { .dbl = 1.0 }, 1.0, 30.0, FLAGS },
71  { "p", "patch size", OFFSET(patch_size), AV_OPT_TYPE_INT, { .i64 = 3*2+1 }, 0, 99, FLAGS },
72  { "pc", "patch size for chroma planes", OFFSET(patch_size_uv), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 99, FLAGS },
73  { "r", "research window", OFFSET(research_size), AV_OPT_TYPE_INT, { .i64 = 7*2+1 }, 0, 99, FLAGS },
74  { "rc", "research window for chroma planes", OFFSET(research_size_uv), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 99, FLAGS },
75  { NULL }
76 };
77 
78 AVFILTER_DEFINE_CLASS(nlmeans);
79 
81 {
82  static const enum AVPixelFormat pix_fmts[] = {
91  };
92 
94 }
95 
96 /**
97  * Compute squared difference of the safe area (the zone where s1 and s2
98  * overlap). It is likely the largest integral zone, so it is interesting to do
99  * as little checks as possible; contrary to the unsafe version of this
100  * function, we do not need any clipping here.
101  *
102  * The line above dst and the column to its left are always readable.
103  */
104 static void compute_safe_ssd_integral_image_c(uint32_t *dst, ptrdiff_t dst_linesize_32,
105  const uint8_t *s1, ptrdiff_t linesize1,
106  const uint8_t *s2, ptrdiff_t linesize2,
107  int w, int h)
108 {
109  int x, y;
110  const uint32_t *dst_top = dst - dst_linesize_32;
111 
112  /* SIMD-friendly assumptions allowed here */
113  av_assert2(!(w & 0xf) && w >= 16 && h >= 1);
114 
115  for (y = 0; y < h; y++) {
116  for (x = 0; x < w; x += 4) {
117  const int d0 = s1[x ] - s2[x ];
118  const int d1 = s1[x + 1] - s2[x + 1];
119  const int d2 = s1[x + 2] - s2[x + 2];
120  const int d3 = s1[x + 3] - s2[x + 3];
121 
122  dst[x ] = dst_top[x ] - dst_top[x - 1] + d0*d0;
123  dst[x + 1] = dst_top[x + 1] - dst_top[x ] + d1*d1;
124  dst[x + 2] = dst_top[x + 2] - dst_top[x + 1] + d2*d2;
125  dst[x + 3] = dst_top[x + 3] - dst_top[x + 2] + d3*d3;
126 
127  dst[x ] += dst[x - 1];
128  dst[x + 1] += dst[x ];
129  dst[x + 2] += dst[x + 1];
130  dst[x + 3] += dst[x + 2];
131  }
132  s1 += linesize1;
133  s2 += linesize2;
134  dst += dst_linesize_32;
135  dst_top += dst_linesize_32;
136  }
137 }
138 
139 /**
140  * Compute squared difference of an unsafe area (the zone nor s1 nor s2 could
141  * be readable).
142  *
143  * On the other hand, the line above dst and the column to its left are always
144  * readable.
145  *
146  * There is little point in having this function SIMDified as it is likely too
147  * complex and only handle small portions of the image.
148  *
149  * @param dst integral image
150  * @param dst_linesize_32 integral image linesize (in 32-bit integers unit)
151  * @param startx integral starting x position
152  * @param starty integral starting y position
153  * @param src source plane buffer
154  * @param linesize source plane linesize
155  * @param offx source offsetting in x
156  * @param offy source offsetting in y
157  * @paran r absolute maximum source offsetting
158  * @param sw source width
159  * @param sh source height
160  * @param w width to compute
161  * @param h height to compute
162  */
163 static inline void compute_unsafe_ssd_integral_image(uint32_t *dst, ptrdiff_t dst_linesize_32,
164  int startx, int starty,
165  const uint8_t *src, ptrdiff_t linesize,
166  int offx, int offy, int r, int sw, int sh,
167  int w, int h)
168 {
169  int x, y;
170 
171  for (y = starty; y < starty + h; y++) {
172  uint32_t acc = dst[y*dst_linesize_32 + startx - 1] - dst[(y-1)*dst_linesize_32 + startx - 1];
173  const int s1y = av_clip(y - r, 0, sh - 1);
174  const int s2y = av_clip(y - (r + offy), 0, sh - 1);
175 
176  for (x = startx; x < startx + w; x++) {
177  const int s1x = av_clip(x - r, 0, sw - 1);
178  const int s2x = av_clip(x - (r + offx), 0, sw - 1);
179  const uint8_t v1 = src[s1y*linesize + s1x];
180  const uint8_t v2 = src[s2y*linesize + s2x];
181  const int d = v1 - v2;
182  acc += d * d;
183  dst[y*dst_linesize_32 + x] = dst[(y-1)*dst_linesize_32 + x] + acc;
184  }
185  }
186 }
187 
188 /*
189  * Compute the sum of squared difference integral image
190  * http://www.ipol.im/pub/art/2014/57/
191  * Integral Images for Block Matching - Gabriele Facciolo, Nicolas Limare, Enric Meinhardt-Llopis
192  *
193  * @param ii integral image of dimension (w+e*2) x (h+e*2) with
194  * an additional zeroed top line and column already
195  * "applied" to the pointer value
196  * @param ii_linesize_32 integral image linesize (in 32-bit integers unit)
197  * @param src source plane buffer
198  * @param linesize source plane linesize
199  * @param offx x-offsetting ranging in [-e;e]
200  * @param offy y-offsetting ranging in [-e;e]
201  * @param w source width
202  * @param h source height
203  * @param e research padding edge
204  */
206  uint32_t *ii, ptrdiff_t ii_linesize_32,
207  const uint8_t *src, ptrdiff_t linesize, int offx, int offy,
208  int e, int w, int h)
209 {
210  // ii has a surrounding padding of thickness "e"
211  const int ii_w = w + e*2;
212  const int ii_h = h + e*2;
213 
214  // we center the first source
215  const int s1x = e;
216  const int s1y = e;
217 
218  // 2nd source is the frame with offsetting
219  const int s2x = e + offx;
220  const int s2y = e + offy;
221 
222  // get the dimension of the overlapping rectangle where it is always safe
223  // to compare the 2 sources pixels
224  const int startx_safe = FFMAX(s1x, s2x);
225  const int starty_safe = FFMAX(s1y, s2y);
226  const int u_endx_safe = FFMIN(s1x + w, s2x + w); // unaligned
227  const int endy_safe = FFMIN(s1y + h, s2y + h);
228 
229  // deduce the safe area width and height
230  const int safe_pw = (u_endx_safe - startx_safe) & ~0xf;
231  const int safe_ph = endy_safe - starty_safe;
232 
233  // adjusted end x position of the safe area after width of the safe area gets aligned
234  const int endx_safe = startx_safe + safe_pw;
235 
236  // top part where only one of s1 and s2 is still readable, or none at all
237  compute_unsafe_ssd_integral_image(ii, ii_linesize_32,
238  0, 0,
239  src, linesize,
240  offx, offy, e, w, h,
241  ii_w, starty_safe);
242 
243  // fill the left column integral required to compute the central
244  // overlapping one
245  compute_unsafe_ssd_integral_image(ii, ii_linesize_32,
246  0, starty_safe,
247  src, linesize,
248  offx, offy, e, w, h,
249  startx_safe, safe_ph);
250 
251  // main and safe part of the integral
252  av_assert1(startx_safe - s1x >= 0); av_assert1(startx_safe - s1x < w);
253  av_assert1(starty_safe - s1y >= 0); av_assert1(starty_safe - s1y < h);
254  av_assert1(startx_safe - s2x >= 0); av_assert1(startx_safe - s2x < w);
255  av_assert1(starty_safe - s2y >= 0); av_assert1(starty_safe - s2y < h);
256  if (safe_pw && safe_ph)
257  dsp->compute_safe_ssd_integral_image(ii + starty_safe*ii_linesize_32 + startx_safe, ii_linesize_32,
258  src + (starty_safe - s1y) * linesize + (startx_safe - s1x), linesize,
259  src + (starty_safe - s2y) * linesize + (startx_safe - s2x), linesize,
260  safe_pw, safe_ph);
261 
262  // right part of the integral
263  compute_unsafe_ssd_integral_image(ii, ii_linesize_32,
264  endx_safe, starty_safe,
265  src, linesize,
266  offx, offy, e, w, h,
267  ii_w - endx_safe, safe_ph);
268 
269  // bottom part where only one of s1 and s2 is still readable, or none at all
270  compute_unsafe_ssd_integral_image(ii, ii_linesize_32,
271  0, endy_safe,
272  src, linesize,
273  offx, offy, e, w, h,
274  ii_w, ii_h - endy_safe);
275 }
276 
278 {
279  AVFilterContext *ctx = inlink->dst;
280  NLMeansContext *s = ctx->priv;
282  const int e = FFMAX(s->research_hsize, s->research_hsize_uv)
283  + FFMAX(s->patch_hsize, s->patch_hsize_uv);
284 
285  s->chroma_w = AV_CEIL_RSHIFT(inlink->w, desc->log2_chroma_w);
286  s->chroma_h = AV_CEIL_RSHIFT(inlink->h, desc->log2_chroma_h);
287  s->nb_planes = av_pix_fmt_count_planes(inlink->format);
288 
289  /* Allocate the integral image with extra edges of thickness "e"
290  *
291  * +_+-------------------------------+
292  * |0|0000000000000000000000000000000|
293  * +-x-------------------------------+
294  * |0|\ ^ |
295  * |0| ii | e |
296  * |0| v |
297  * |0| +-----------------------+ |
298  * |0| | | |
299  * |0|<->| | |
300  * |0| e | | |
301  * |0| | | |
302  * |0| +-----------------------+ |
303  * |0| |
304  * |0| |
305  * |0| |
306  * +-+-------------------------------+
307  */
308  s->ii_w = inlink->w + e*2;
309  s->ii_h = inlink->h + e*2;
310 
311  // align to 4 the linesize, "+1" is for the space of the left 0-column
312  s->ii_lz_32 = FFALIGN(s->ii_w + 1, 4);
313 
314  // "+1" is for the space of the top 0-line
315  s->ii_orig = av_calloc(s->ii_h + 1, s->ii_lz_32 * sizeof(*s->ii_orig));
316  if (!s->ii_orig)
317  return AVERROR(ENOMEM);
318 
319  // skip top 0-line and left 0-column
320  s->ii = s->ii_orig + s->ii_lz_32 + 1;
321 
322  // allocate weighted average for every pixel
323  s->wa_linesize = inlink->w;
324  s->wa = av_malloc_array(s->wa_linesize, inlink->h * sizeof(*s->wa));
325  if (!s->wa)
326  return AVERROR(ENOMEM);
327 
328  return 0;
329 }
330 
331 struct thread_data {
332  const uint8_t *src;
333  ptrdiff_t src_linesize;
335  int endx, endy;
336  const uint32_t *ii_start;
337  int p;
338 };
339 
340 static int nlmeans_slice(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
341 {
342  int x, y;
343  NLMeansContext *s = ctx->priv;
344  const struct thread_data *td = arg;
345  const ptrdiff_t src_linesize = td->src_linesize;
346  const int process_h = td->endy - td->starty;
347  const int slice_start = (process_h * jobnr ) / nb_jobs;
348  const int slice_end = (process_h * (jobnr+1)) / nb_jobs;
349  const int starty = td->starty + slice_start;
350  const int endy = td->starty + slice_end;
351  const int p = td->p;
352  const uint32_t *ii = td->ii_start + (starty - p - 1) * s->ii_lz_32 - p - 1;
353  const int dist_b = 2*p + 1;
354  const int dist_d = dist_b * s->ii_lz_32;
355  const int dist_e = dist_d + dist_b;
356 
357  for (y = starty; y < endy; y++) {
358  const uint8_t *src = td->src + y*src_linesize;
359  struct weighted_avg *wa = s->wa + y*s->wa_linesize;
360  for (x = td->startx; x < td->endx; x++) {
361  /*
362  * M is a discrete map where every entry contains the sum of all the entries
363  * in the rectangle from the top-left origin of M to its coordinate. In the
364  * following schema, "i" contains the sum of the whole map:
365  *
366  * M = +----------+-----------------+----+
367  * | | | |
368  * | | | |
369  * | a| b| c|
370  * +----------+-----------------+----+
371  * | | | |
372  * | | | |
373  * | | X | |
374  * | | | |
375  * | d| e| f|
376  * +----------+-----------------+----+
377  * | | | |
378  * | g| h| i|
379  * +----------+-----------------+----+
380  *
381  * The sum of the X box can be calculated with:
382  * X = e-d-b+a
383  *
384  * See https://en.wikipedia.org/wiki/Summed_area_table
385  *
386  * The compute*_ssd functions compute the integral image M where every entry
387  * contains the sum of the squared difference of every corresponding pixels of
388  * two input planes of the same size as M.
389  */
390  const uint32_t a = ii[x];
391  const uint32_t b = ii[x + dist_b];
392  const uint32_t d = ii[x + dist_d];
393  const uint32_t e = ii[x + dist_e];
394  const uint32_t patch_diff_sq = e - d - b + a;
395 
396  if (patch_diff_sq < s->max_meaningful_diff) {
397  const float weight = s->weight_lut[patch_diff_sq]; // exp(-patch_diff_sq * s->pdiff_scale)
398  wa[x].total_weight += weight;
399  wa[x].sum += weight * src[x];
400  }
401  }
402  ii += s->ii_lz_32;
403  }
404  return 0;
405 }
406 
407 static void weight_averages(uint8_t *dst, ptrdiff_t dst_linesize,
408  const uint8_t *src, ptrdiff_t src_linesize,
409  struct weighted_avg *wa, ptrdiff_t wa_linesize,
410  int w, int h)
411 {
412  int x, y;
413 
414  for (y = 0; y < h; y++) {
415  for (x = 0; x < w; x++) {
416  // Also weight the centered pixel
417  wa[x].total_weight += 1.f;
418  wa[x].sum += 1.f * src[x];
419  dst[x] = av_clip_uint8(wa[x].sum / wa[x].total_weight + 0.5f);
420  }
421  dst += dst_linesize;
422  src += src_linesize;
423  wa += wa_linesize;
424  }
425 }
426 
427 static int nlmeans_plane(AVFilterContext *ctx, int w, int h, int p, int r,
428  uint8_t *dst, ptrdiff_t dst_linesize,
429  const uint8_t *src, ptrdiff_t src_linesize)
430 {
431  int offx, offy;
432  NLMeansContext *s = ctx->priv;
433  /* patches center points cover the whole research window so the patches
434  * themselves overflow the research window */
435  const int e = r + p;
436  /* focus an integral pointer on the centered image (s1) */
437  const uint32_t *centered_ii = s->ii + e*s->ii_lz_32 + e;
438 
439  memset(s->wa, 0, s->wa_linesize * h * sizeof(*s->wa));
440 
441  for (offy = -r; offy <= r; offy++) {
442  for (offx = -r; offx <= r; offx++) {
443  if (offx || offy) {
444  struct thread_data td = {
445  .src = src + offy*src_linesize + offx,
446  .src_linesize = src_linesize,
447  .startx = FFMAX(0, -offx),
448  .starty = FFMAX(0, -offy),
449  .endx = FFMIN(w, w - offx),
450  .endy = FFMIN(h, h - offy),
451  .ii_start = centered_ii + offy*s->ii_lz_32 + offx,
452  .p = p,
453  };
454 
455  compute_ssd_integral_image(&s->dsp, s->ii, s->ii_lz_32,
456  src, src_linesize,
457  offx, offy, e, w, h);
459  FFMIN(td.endy - td.starty, ff_filter_get_nb_threads(ctx)));
460  }
461  }
462  }
463 
464  weight_averages(dst, dst_linesize, src, src_linesize,
465  s->wa, s->wa_linesize, w, h);
466 
467  return 0;
468 }
469 
471 {
472  int i;
473  AVFilterContext *ctx = inlink->dst;
474  NLMeansContext *s = ctx->priv;
475  AVFilterLink *outlink = ctx->outputs[0];
476 
477  AVFrame *out = ff_get_video_buffer(outlink, outlink->w, outlink->h);
478  if (!out) {
479  av_frame_free(&in);
480  return AVERROR(ENOMEM);
481  }
483 
484  for (i = 0; i < s->nb_planes; i++) {
485  const int w = i ? s->chroma_w : inlink->w;
486  const int h = i ? s->chroma_h : inlink->h;
487  const int p = i ? s->patch_hsize_uv : s->patch_hsize;
488  const int r = i ? s->research_hsize_uv : s->research_hsize;
489  nlmeans_plane(ctx, w, h, p, r,
490  out->data[i], out->linesize[i],
491  in->data[i], in->linesize[i]);
492  }
493 
494  av_frame_free(&in);
495  return ff_filter_frame(outlink, out);
496 }
497 
498 #define CHECK_ODD_FIELD(field, name) do { \
499  if (!(s->field & 1)) { \
500  s->field |= 1; \
501  av_log(ctx, AV_LOG_WARNING, name " size must be odd, " \
502  "setting it to %d\n", s->field); \
503  } \
504 } while (0)
505 
507 {
509 
510  if (ARCH_AARCH64)
512 }
513 
515 {
516  int i;
517  NLMeansContext *s = ctx->priv;
518  const double h = s->sigma * 10.;
519 
520  s->pdiff_scale = 1. / (h * h);
521  s->max_meaningful_diff = log(255.) / s->pdiff_scale;
522  s->weight_lut = av_calloc(s->max_meaningful_diff, sizeof(*s->weight_lut));
523  if (!s->weight_lut)
524  return AVERROR(ENOMEM);
525  for (i = 0; i < s->max_meaningful_diff; i++)
526  s->weight_lut[i] = exp(-i * s->pdiff_scale);
527 
528  CHECK_ODD_FIELD(research_size, "Luma research window");
529  CHECK_ODD_FIELD(patch_size, "Luma patch");
530 
531  if (!s->research_size_uv) s->research_size_uv = s->research_size;
532  if (!s->patch_size_uv) s->patch_size_uv = s->patch_size;
533 
534  CHECK_ODD_FIELD(research_size_uv, "Chroma research window");
535  CHECK_ODD_FIELD(patch_size_uv, "Chroma patch");
536 
537  s->research_hsize = s->research_size / 2;
538  s->research_hsize_uv = s->research_size_uv / 2;
539  s->patch_hsize = s->patch_size / 2;
540  s->patch_hsize_uv = s->patch_size_uv / 2;
541 
542  av_log(ctx, AV_LOG_INFO, "Research window: %dx%d / %dx%d, patch size: %dx%d / %dx%d\n",
543  s->research_size, s->research_size, s->research_size_uv, s->research_size_uv,
544  s->patch_size, s->patch_size, s->patch_size_uv, s->patch_size_uv);
545 
546  ff_nlmeans_init(&s->dsp);
547 
548  return 0;
549 }
550 
552 {
553  NLMeansContext *s = ctx->priv;
554  av_freep(&s->weight_lut);
555  av_freep(&s->ii_orig);
556  av_freep(&s->wa);
557 }
558 
559 static const AVFilterPad nlmeans_inputs[] = {
560  {
561  .name = "default",
562  .type = AVMEDIA_TYPE_VIDEO,
563  .config_props = config_input,
564  .filter_frame = filter_frame,
565  },
566 };
567 
568 static const AVFilterPad nlmeans_outputs[] = {
569  {
570  .name = "default",
571  .type = AVMEDIA_TYPE_VIDEO,
572  },
573 };
574 
576  .name = "nlmeans",
577  .description = NULL_IF_CONFIG_SMALL("Non-local means denoiser."),
578  .priv_size = sizeof(NLMeansContext),
579  .init = init,
580  .uninit = uninit,
584  .priv_class = &nlmeans_class,
586 };
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:98
td
#define td
Definition: regdef.h:70
AVPixelFormat
AVPixelFormat
Pixel format.
Definition: pixfmt.h:64
av_clip
#define av_clip
Definition: common.h:96
NLMeansContext::weight_lut
float * weight_lut
Definition: vf_nlmeans.c:62
r
const char * r
Definition: vf_curves.c:116
acc
int acc
Definition: yuv2rgb.c:554
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
thread_data::src_linesize
ptrdiff_t src_linesize
Definition: vf_nlmeans.c:333
ff_filter_frame
int ff_filter_frame(AVFilterLink *link, AVFrame *frame)
Send a frame of data to the next filter.
Definition: avfilter.c:1019
av_pix_fmt_desc_get
const AVPixFmtDescriptor * av_pix_fmt_desc_get(enum AVPixelFormat pix_fmt)
Definition: pixdesc.c:2564
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:112
AVFrame
This structure describes decoded (raw) audio or video data.
Definition: frame.h:303
pixdesc.h
w
uint8_t w
Definition: llviddspenc.c:38
NLMeansContext::max_meaningful_diff
uint32_t max_meaningful_diff
Definition: vf_nlmeans.c:63
AVOption
AVOption.
Definition: opt.h:247
b
#define b
Definition: input.c:40
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:153
compute_safe_ssd_integral_image_c
static void compute_safe_ssd_integral_image_c(uint32_t *dst, ptrdiff_t dst_linesize_32, const uint8_t *s1, ptrdiff_t linesize1, const uint8_t *s2, ptrdiff_t linesize2, int w, int h)
Compute squared difference of the safe area (the zone where s1 and s2 overlap).
Definition: vf_nlmeans.c:104
video.h
CHECK_ODD_FIELD
#define CHECK_ODD_FIELD(field, name)
Definition: vf_nlmeans.c:498
AVFrame::data
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
Definition: frame.h:317
formats.h
NLMeansContext::wa
struct weighted_avg * wa
Definition: vf_nlmeans.c:60
query_formats
static int query_formats(AVFilterContext *ctx)
Definition: vf_nlmeans.c:80
NLMeansContext::ii_w
int ii_w
Definition: vf_nlmeans.c:58
av_pix_fmt_count_planes
int av_pix_fmt_count_planes(enum AVPixelFormat pix_fmt)
Definition: pixdesc.c:2604
NLMeansDSPContext
Definition: vf_nlmeans.h:25
NLMeansContext::nb_planes
int nb_planes
Definition: vf_nlmeans.c:48
nlmeans_outputs
static const AVFilterPad nlmeans_outputs[]
Definition: vf_nlmeans.c:568
compute_ssd_integral_image
static void compute_ssd_integral_image(const NLMeansDSPContext *dsp, uint32_t *ii, ptrdiff_t ii_linesize_32, const uint8_t *src, ptrdiff_t linesize, int offx, int offy, int e, int w, int h)
Definition: vf_nlmeans.c:205
nlmeans_inputs
static const AVFilterPad nlmeans_inputs[]
Definition: vf_nlmeans.c:559
NLMeansDSPContext::compute_safe_ssd_integral_image
void(* compute_safe_ssd_integral_image)(uint32_t *dst, ptrdiff_t dst_linesize_32, const uint8_t *s1, ptrdiff_t linesize1, const uint8_t *s2, ptrdiff_t linesize2, int w, int h)
Definition: vf_nlmeans.h:26
NLMeansContext::wa_linesize
ptrdiff_t wa_linesize
Definition: vf_nlmeans.c:61
weight_averages
static void weight_averages(uint8_t *dst, ptrdiff_t dst_linesize, const uint8_t *src, ptrdiff_t src_linesize, struct weighted_avg *wa, ptrdiff_t wa_linesize, int w, int h)
Definition: vf_nlmeans.c:407
AVFilterPad
A filter pad used for either input or output.
Definition: internal.h:50
thread_data::starty
int starty
Definition: vf_nlmeans.c:334
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:248
avassert.h
compute_unsafe_ssd_integral_image
static void compute_unsafe_ssd_integral_image(uint32_t *dst, ptrdiff_t dst_linesize_32, int startx, int starty, const uint8_t *src, ptrdiff_t linesize, int offx, int offy, int r, int sw, int sh, int w, int h)
Compute squared difference of an unsafe area (the zone nor s1 nor s2 could be readable).
Definition: vf_nlmeans.c:163
av_cold
#define av_cold
Definition: attributes.h:90
NLMeansContext::dsp
NLMeansDSPContext dsp
Definition: vf_nlmeans.c:64
thread_data
Definition: vf_lut.c:337
NLMeansContext::research_hsize_uv
int research_hsize_uv
Definition: vf_nlmeans.c:55
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
NLMeansContext::chroma_h
int chroma_h
Definition: vf_nlmeans.c:49
s
#define s(width, name)
Definition: cbs_vp9.c:257
NLMeansContext::research_hsize
int research_hsize
Definition: vf_nlmeans.c:54
AV_CEIL_RSHIFT
#define AV_CEIL_RSHIFT(a, b)
Definition: common.h:51
AV_OPT_TYPE_DOUBLE
@ AV_OPT_TYPE_DOUBLE
Definition: opt.h:226
s1
#define s1
Definition: regdef.h:38
slice_end
static int slice_end(AVCodecContext *avctx, AVFrame *pict)
Handle slice ends.
Definition: mpeg12dec.c:2041
ff_set_common_formats_from_list
int ff_set_common_formats_from_list(AVFilterContext *ctx, const int *fmts)
Equivalent to ff_set_common_formats(ctx, ff_make_format_list(fmts))
Definition: formats.c:698
pix_fmts
static enum AVPixelFormat pix_fmts[]
Definition: libkvazaar.c:290
ctx
AVFormatContext * ctx
Definition: movenc.c:48
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
f
#define f(width, name)
Definition: cbs_vp9.c:255
thread_data::src
const uint8_t * src
Definition: vf_nlmeans.c:332
FILTER_INPUTS
#define FILTER_INPUTS(array)
Definition: internal.h:152
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
thread_data::endx
int endx
Definition: vf_nlmeans.c:335
AVClass
Describe the class of an AVClass context structure.
Definition: log.h:66
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:537
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
ff_vf_nlmeans
const AVFilter ff_vf_nlmeans
Definition: vf_nlmeans.c:575
src
#define src
Definition: vp8dsp.c:255
thread_data::startx
int startx
Definition: vf_nlmeans.c:334
NLMeansContext
Definition: vf_nlmeans.c:46
NLMeansContext::ii_lz_32
ptrdiff_t ii_lz_32
Definition: vf_nlmeans.c:59
AV_PIX_FMT_GRAY8
@ AV_PIX_FMT_GRAY8
Y , 8bpp.
Definition: pixfmt.h:74
FLAGS
#define FLAGS
Definition: vf_nlmeans.c:68
exp
int8_t exp
Definition: eval.c:72
weight
static int weight(int i, int blen, int offset)
Definition: diracdec.c:1561
for
for(j=16;j >0;--j)
Definition: h264pred_template.c:469
s2
#define s2
Definition: regdef.h:39
uninit
static av_cold void uninit(AVFilterContext *ctx)
Definition: vf_nlmeans.c:551
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:117
vf_nlmeans.h
nlmeans_slice
static int nlmeans_slice(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
Definition: vf_nlmeans.c:340
NLMeansContext::pdiff_scale
double pdiff_scale
Definition: vf_nlmeans.c:50
weighted_avg::sum
float sum
Definition: vf_nlmeans.c:43
NLMeansContext::ii_orig
uint32_t * ii_orig
Definition: vf_nlmeans.c:56
config_input
static int config_input(AVFilterLink *inlink)
Definition: vf_nlmeans.c:277
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
thread_data::endy
int endy
Definition: vf_nlmeans.c:335
AV_LOG_INFO
#define AV_LOG_INFO
Standard information.
Definition: log.h:191
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:130
NLMeansContext::ii_h
int ii_h
Definition: vf_nlmeans.c:58
av_assert2
#define av_assert2(cond)
assert() equivalent, that does lie in speed critical code.
Definition: avassert.h:64
NLMeansContext::patch_size
int patch_size
Definition: vf_nlmeans.c:52
NLMeansContext::ii
uint32_t * ii
Definition: vf_nlmeans.c:57
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:271
av_malloc_array
#define av_malloc_array(a, b)
Definition: tableprint_vlc.h:32
ff_filter_get_nb_threads
int ff_filter_get_nb_threads(AVFilterContext *ctx)
Get number of threads for current filter instance.
Definition: avfilter.c:804
av_assert1
#define av_assert1(cond)
assert() equivalent, that does not lie in speed critical code.
Definition: avassert.h:53
xf
#define xf(width, name, var, range_min, range_max, subs,...)
Definition: cbs_av1.c:664
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:56
av_calloc
void * av_calloc(size_t nmemb, size_t size)
Definition: mem.c:271
NLMeansContext::chroma_w
int chroma_w
Definition: vf_nlmeans.c:49
AVFilter
Filter definition.
Definition: avfilter.h:149
NLMeansContext::sigma
double sigma
Definition: vf_nlmeans.c:51
init
static av_cold int init(AVFilterContext *ctx)
Definition: vf_nlmeans.c:514
weighted_avg::total_weight
float total_weight
Definition: vf_nlmeans.c:42
AV_PIX_FMT_NONE
@ AV_PIX_FMT_NONE
Definition: pixfmt.h:65
AV_OPT_TYPE_INT
@ AV_OPT_TYPE_INT
Definition: opt.h:224
avfilter.h
NLMeansContext::patch_hsize
int patch_hsize
Definition: vf_nlmeans.c:52
NLMeansContext::research_size
int research_size
Definition: vf_nlmeans.c:54
NLMeansContext::patch_hsize_uv
int patch_hsize_uv
Definition: vf_nlmeans.c:53
av_clip_uint8
#define av_clip_uint8
Definition: common.h:102
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:346
AV_PIX_FMT_GBRP
@ AV_PIX_FMT_GBRP
planar GBR 4:4:4 24bpp
Definition: pixfmt.h:158
AVFILTER_DEFINE_CLASS
AVFILTER_DEFINE_CLASS(nlmeans)
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:121
desc
const char * desc
Definition: libsvtav1.c:79
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
NLMeansContext::research_size_uv
int research_size_uv
Definition: vf_nlmeans.c:55
filter_frame
static int filter_frame(AVFilterLink *inlink, AVFrame *in)
Definition: vf_nlmeans.c:470
AVPixFmtDescriptor
Descriptor that unambiguously describes how the bits of a pixel are stored in the up to 4 data planes...
Definition: pixdesc.h:69
nlmeans_plane
static int nlmeans_plane(AVFilterContext *ctx, int w, int h, int p, int r, uint8_t *dst, ptrdiff_t dst_linesize, const uint8_t *src, ptrdiff_t src_linesize)
Definition: vf_nlmeans.c:427
FFALIGN
#define FFALIGN(x, a)
Definition: macros.h:78
ff_nlmeans_init
void ff_nlmeans_init(NLMeansDSPContext *dsp)
Definition: vf_nlmeans.c:506
FILTER_OUTPUTS
#define FILTER_OUTPUTS(array)
Definition: internal.h:153
av_freep
#define av_freep(p)
Definition: tableprint_vlc.h:35
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
thread_data::in
AVFrame * in
Definition: vf_lut.c:338
d
d
Definition: ffmpeg_filter.c:156
ff_nlmeans_init_aarch64
av_cold void ff_nlmeans_init_aarch64(NLMeansDSPContext *dsp)
Definition: vf_nlmeans_init.c:28
nlmeans_options
static const AVOption nlmeans_options[]
Definition: vf_nlmeans.c:69
AVFrame::linesize
int linesize[AV_NUM_DATA_POINTERS]
For video, size in bytes of each picture line.
Definition: frame.h:334
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
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:28
h
h
Definition: vp9dsp_template.c:2038
OFFSET
#define OFFSET(x)
Definition: vf_nlmeans.c:67
weighted_avg
Definition: vf_nlmeans.c:41
thread_data::p
int p
Definition: vf_nlmeans.c:337
thread_data::ii_start
const uint32_t * ii_start
Definition: vf_nlmeans.c:336
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:143
NLMeansContext::patch_size_uv
int patch_size_uv
Definition: vf_nlmeans.c:53