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