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  if (!fmts_list)
95  return AVERROR(ENOMEM);
96  return ff_set_common_formats(ctx, fmts_list);
97 }
98 
99 /**
100  * Compute squared difference of the safe area (the zone where s1 and s2
101  * overlap). It is likely the largest integral zone, so it is interesting to do
102  * as little checks as possible; contrary to the unsafe version of this
103  * function, we do not need any clipping here.
104  *
105  * The line above dst and the column to its left are always readable.
106  */
107 static void compute_safe_ssd_integral_image_c(uint32_t *dst, ptrdiff_t dst_linesize_32,
108  const uint8_t *s1, ptrdiff_t linesize1,
109  const uint8_t *s2, ptrdiff_t linesize2,
110  int w, int h)
111 {
112  int x, y;
113  const uint32_t *dst_top = dst - dst_linesize_32;
114 
115  /* SIMD-friendly assumptions allowed here */
116  av_assert2(!(w & 0xf) && w >= 16 && h >= 1);
117 
118  for (y = 0; y < h; y++) {
119  for (x = 0; x < w; x += 4) {
120  const int d0 = s1[x ] - s2[x ];
121  const int d1 = s1[x + 1] - s2[x + 1];
122  const int d2 = s1[x + 2] - s2[x + 2];
123  const int d3 = s1[x + 3] - s2[x + 3];
124 
125  dst[x ] = dst_top[x ] - dst_top[x - 1] + d0*d0;
126  dst[x + 1] = dst_top[x + 1] - dst_top[x ] + d1*d1;
127  dst[x + 2] = dst_top[x + 2] - dst_top[x + 1] + d2*d2;
128  dst[x + 3] = dst_top[x + 3] - dst_top[x + 2] + d3*d3;
129 
130  dst[x ] += dst[x - 1];
131  dst[x + 1] += dst[x ];
132  dst[x + 2] += dst[x + 1];
133  dst[x + 3] += dst[x + 2];
134  }
135  s1 += linesize1;
136  s2 += linesize2;
137  dst += dst_linesize_32;
138  dst_top += dst_linesize_32;
139  }
140 }
141 
142 /**
143  * Compute squared difference of an unsafe area (the zone nor s1 nor s2 could
144  * be readable).
145  *
146  * On the other hand, the line above dst and the column to its left are always
147  * readable.
148  *
149  * There is little point in having this function SIMDified as it is likely too
150  * complex and only handle small portions of the image.
151  *
152  * @param dst integral image
153  * @param dst_linesize_32 integral image linesize (in 32-bit integers unit)
154  * @param startx integral starting x position
155  * @param starty integral starting y position
156  * @param src source plane buffer
157  * @param linesize source plane linesize
158  * @param offx source offsetting in x
159  * @param offy source offsetting in y
160  * @paran r absolute maximum source offsetting
161  * @param sw source width
162  * @param sh source height
163  * @param w width to compute
164  * @param h height to compute
165  */
166 static inline void compute_unsafe_ssd_integral_image(uint32_t *dst, ptrdiff_t dst_linesize_32,
167  int startx, int starty,
168  const uint8_t *src, ptrdiff_t linesize,
169  int offx, int offy, int r, int sw, int sh,
170  int w, int h)
171 {
172  int x, y;
173 
174  for (y = starty; y < starty + h; y++) {
175  uint32_t acc = dst[y*dst_linesize_32 + startx - 1] - dst[(y-1)*dst_linesize_32 + startx - 1];
176  const int s1y = av_clip(y - r, 0, sh - 1);
177  const int s2y = av_clip(y - (r + offy), 0, sh - 1);
178 
179  for (x = startx; x < startx + w; x++) {
180  const int s1x = av_clip(x - r, 0, sw - 1);
181  const int s2x = av_clip(x - (r + offx), 0, sw - 1);
182  const uint8_t v1 = src[s1y*linesize + s1x];
183  const uint8_t v2 = src[s2y*linesize + s2x];
184  const int d = v1 - v2;
185  acc += d * d;
186  dst[y*dst_linesize_32 + x] = dst[(y-1)*dst_linesize_32 + x] + acc;
187  }
188  }
189 }
190 
191 /*
192  * Compute the sum of squared difference integral image
193  * http://www.ipol.im/pub/art/2014/57/
194  * Integral Images for Block Matching - Gabriele Facciolo, Nicolas Limare, Enric Meinhardt-Llopis
195  *
196  * @param ii integral image of dimension (w+e*2) x (h+e*2) with
197  * an additional zeroed top line and column already
198  * "applied" to the pointer value
199  * @param ii_linesize_32 integral image linesize (in 32-bit integers unit)
200  * @param src source plane buffer
201  * @param linesize source plane linesize
202  * @param offx x-offsetting ranging in [-e;e]
203  * @param offy y-offsetting ranging in [-e;e]
204  * @param w source width
205  * @param h source height
206  * @param e research padding edge
207  */
209  uint32_t *ii, ptrdiff_t ii_linesize_32,
210  const uint8_t *src, ptrdiff_t linesize, int offx, int offy,
211  int e, int w, int h)
212 {
213  // ii has a surrounding padding of thickness "e"
214  const int ii_w = w + e*2;
215  const int ii_h = h + e*2;
216 
217  // we center the first source
218  const int s1x = e;
219  const int s1y = e;
220 
221  // 2nd source is the frame with offsetting
222  const int s2x = e + offx;
223  const int s2y = e + offy;
224 
225  // get the dimension of the overlapping rectangle where it is always safe
226  // to compare the 2 sources pixels
227  const int startx_safe = FFMAX(s1x, s2x);
228  const int starty_safe = FFMAX(s1y, s2y);
229  const int u_endx_safe = FFMIN(s1x + w, s2x + w); // unaligned
230  const int endy_safe = FFMIN(s1y + h, s2y + h);
231 
232  // deduce the safe area width and height
233  const int safe_pw = (u_endx_safe - startx_safe) & ~0xf;
234  const int safe_ph = endy_safe - starty_safe;
235 
236  // adjusted end x position of the safe area after width of the safe area gets aligned
237  const int endx_safe = startx_safe + safe_pw;
238 
239  // top part where only one of s1 and s2 is still readable, or none at all
240  compute_unsafe_ssd_integral_image(ii, ii_linesize_32,
241  0, 0,
242  src, linesize,
243  offx, offy, e, w, h,
244  ii_w, starty_safe);
245 
246  // fill the left column integral required to compute the central
247  // overlapping one
248  compute_unsafe_ssd_integral_image(ii, ii_linesize_32,
249  0, starty_safe,
250  src, linesize,
251  offx, offy, e, w, h,
252  startx_safe, safe_ph);
253 
254  // main and safe part of the integral
255  av_assert1(startx_safe - s1x >= 0); av_assert1(startx_safe - s1x < w);
256  av_assert1(starty_safe - s1y >= 0); av_assert1(starty_safe - s1y < h);
257  av_assert1(startx_safe - s2x >= 0); av_assert1(startx_safe - s2x < w);
258  av_assert1(starty_safe - s2y >= 0); av_assert1(starty_safe - s2y < h);
259  if (safe_pw && safe_ph)
260  dsp->compute_safe_ssd_integral_image(ii + starty_safe*ii_linesize_32 + startx_safe, ii_linesize_32,
261  src + (starty_safe - s1y) * linesize + (startx_safe - s1x), linesize,
262  src + (starty_safe - s2y) * linesize + (startx_safe - s2x), linesize,
263  safe_pw, safe_ph);
264 
265  // right part of the integral
266  compute_unsafe_ssd_integral_image(ii, ii_linesize_32,
267  endx_safe, starty_safe,
268  src, linesize,
269  offx, offy, e, w, h,
270  ii_w - endx_safe, safe_ph);
271 
272  // bottom part where only one of s1 and s2 is still readable, or none at all
273  compute_unsafe_ssd_integral_image(ii, ii_linesize_32,
274  0, endy_safe,
275  src, linesize,
276  offx, offy, e, w, h,
277  ii_w, ii_h - endy_safe);
278 }
279 
281 {
282  AVFilterContext *ctx = inlink->dst;
283  NLMeansContext *s = ctx->priv;
285  const int e = FFMAX(s->research_hsize, s->research_hsize_uv)
286  + FFMAX(s->patch_hsize, s->patch_hsize_uv);
287 
288  s->chroma_w = AV_CEIL_RSHIFT(inlink->w, desc->log2_chroma_w);
289  s->chroma_h = AV_CEIL_RSHIFT(inlink->h, desc->log2_chroma_h);
290  s->nb_planes = av_pix_fmt_count_planes(inlink->format);
291 
292  /* Allocate the integral image with extra edges of thickness "e"
293  *
294  * +_+-------------------------------+
295  * |0|0000000000000000000000000000000|
296  * +-x-------------------------------+
297  * |0|\ ^ |
298  * |0| ii | e |
299  * |0| v |
300  * |0| +-----------------------+ |
301  * |0| | | |
302  * |0|<->| | |
303  * |0| e | | |
304  * |0| | | |
305  * |0| +-----------------------+ |
306  * |0| |
307  * |0| |
308  * |0| |
309  * +-+-------------------------------+
310  */
311  s->ii_w = inlink->w + e*2;
312  s->ii_h = inlink->h + e*2;
313 
314  // align to 4 the linesize, "+1" is for the space of the left 0-column
315  s->ii_lz_32 = FFALIGN(s->ii_w + 1, 4);
316 
317  // "+1" is for the space of the top 0-line
318  s->ii_orig = av_mallocz_array(s->ii_h + 1, s->ii_lz_32 * sizeof(*s->ii_orig));
319  if (!s->ii_orig)
320  return AVERROR(ENOMEM);
321 
322  // skip top 0-line and left 0-column
323  s->ii = s->ii_orig + s->ii_lz_32 + 1;
324 
325  // allocate weighted average for every pixel
326  s->wa_linesize = inlink->w;
327  s->wa = av_malloc_array(s->wa_linesize, inlink->h * sizeof(*s->wa));
328  if (!s->wa)
329  return AVERROR(ENOMEM);
330 
331  return 0;
332 }
333 
334 struct thread_data {
335  const uint8_t *src;
336  ptrdiff_t src_linesize;
338  int endx, endy;
339  const uint32_t *ii_start;
340  int p;
341 };
342 
343 static int nlmeans_slice(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
344 {
345  int x, y;
346  NLMeansContext *s = ctx->priv;
347  const struct thread_data *td = arg;
348  const ptrdiff_t src_linesize = td->src_linesize;
349  const int process_h = td->endy - td->starty;
350  const int slice_start = (process_h * jobnr ) / nb_jobs;
351  const int slice_end = (process_h * (jobnr+1)) / nb_jobs;
352  const int starty = td->starty + slice_start;
353  const int endy = td->starty + slice_end;
354  const int p = td->p;
355  const uint32_t *ii = td->ii_start + (starty - p - 1) * s->ii_lz_32 - p - 1;
356  const int dist_b = 2*p + 1;
357  const int dist_d = dist_b * s->ii_lz_32;
358  const int dist_e = dist_d + dist_b;
359 
360  for (y = starty; y < endy; y++) {
361  const uint8_t *src = td->src + y*src_linesize;
362  struct weighted_avg *wa = s->wa + y*s->wa_linesize;
363  for (x = td->startx; x < td->endx; x++) {
364  /*
365  * M is a discrete map where every entry contains the sum of all the entries
366  * in the rectangle from the top-left origin of M to its coordinate. In the
367  * following schema, "i" contains the sum of the whole map:
368  *
369  * M = +----------+-----------------+----+
370  * | | | |
371  * | | | |
372  * | a| b| c|
373  * +----------+-----------------+----+
374  * | | | |
375  * | | | |
376  * | | X | |
377  * | | | |
378  * | d| e| f|
379  * +----------+-----------------+----+
380  * | | | |
381  * | g| h| i|
382  * +----------+-----------------+----+
383  *
384  * The sum of the X box can be calculated with:
385  * X = e-d-b+a
386  *
387  * See https://en.wikipedia.org/wiki/Summed_area_table
388  *
389  * The compute*_ssd functions compute the integral image M where every entry
390  * contains the sum of the squared difference of every corresponding pixels of
391  * two input planes of the same size as M.
392  */
393  const uint32_t a = ii[x];
394  const uint32_t b = ii[x + dist_b];
395  const uint32_t d = ii[x + dist_d];
396  const uint32_t e = ii[x + dist_e];
397  const uint32_t patch_diff_sq = e - d - b + a;
398 
399  if (patch_diff_sq < s->max_meaningful_diff) {
400  const float weight = s->weight_lut[patch_diff_sq]; // exp(-patch_diff_sq * s->pdiff_scale)
401  wa[x].total_weight += weight;
402  wa[x].sum += weight * src[x];
403  }
404  }
405  ii += s->ii_lz_32;
406  }
407  return 0;
408 }
409 
410 static void weight_averages(uint8_t *dst, ptrdiff_t dst_linesize,
411  const uint8_t *src, ptrdiff_t src_linesize,
412  struct weighted_avg *wa, ptrdiff_t wa_linesize,
413  int w, int h)
414 {
415  int x, y;
416 
417  for (y = 0; y < h; y++) {
418  for (x = 0; x < w; x++) {
419  // Also weight the centered pixel
420  wa[x].total_weight += 1.f;
421  wa[x].sum += 1.f * src[x];
422  dst[x] = av_clip_uint8(wa[x].sum / wa[x].total_weight);
423  }
424  dst += dst_linesize;
425  src += src_linesize;
426  wa += wa_linesize;
427  }
428 }
429 
430 static int nlmeans_plane(AVFilterContext *ctx, int w, int h, int p, int r,
431  uint8_t *dst, ptrdiff_t dst_linesize,
432  const uint8_t *src, ptrdiff_t src_linesize)
433 {
434  int offx, offy;
435  NLMeansContext *s = ctx->priv;
436  /* patches center points cover the whole research window so the patches
437  * themselves overflow the research window */
438  const int e = r + p;
439  /* focus an integral pointer on the centered image (s1) */
440  const uint32_t *centered_ii = s->ii + e*s->ii_lz_32 + e;
441 
442  memset(s->wa, 0, s->wa_linesize * h * sizeof(*s->wa));
443 
444  for (offy = -r; offy <= r; offy++) {
445  for (offx = -r; offx <= r; offx++) {
446  if (offx || offy) {
447  struct thread_data td = {
448  .src = src + offy*src_linesize + offx,
449  .src_linesize = src_linesize,
450  .startx = FFMAX(0, -offx),
451  .starty = FFMAX(0, -offy),
452  .endx = FFMIN(w, w - offx),
453  .endy = FFMIN(h, h - offy),
454  .ii_start = centered_ii + offy*s->ii_lz_32 + offx,
455  .p = p,
456  };
457 
458  compute_ssd_integral_image(&s->dsp, s->ii, s->ii_lz_32,
459  src, src_linesize,
460  offx, offy, e, w, h);
461  ctx->internal->execute(ctx, nlmeans_slice, &td, NULL,
462  FFMIN(td.endy - td.starty, ff_filter_get_nb_threads(ctx)));
463  }
464  }
465  }
466 
468  s->wa, s->wa_linesize, w, h);
469 
470  return 0;
471 }
472 
474 {
475  int i;
476  AVFilterContext *ctx = inlink->dst;
477  NLMeansContext *s = ctx->priv;
478  AVFilterLink *outlink = ctx->outputs[0];
479 
480  AVFrame *out = ff_get_video_buffer(outlink, outlink->w, outlink->h);
481  if (!out) {
482  av_frame_free(&in);
483  return AVERROR(ENOMEM);
484  }
486 
487  for (i = 0; i < s->nb_planes; i++) {
488  const int w = i ? s->chroma_w : inlink->w;
489  const int h = i ? s->chroma_h : inlink->h;
490  const int p = i ? s->patch_hsize_uv : s->patch_hsize;
491  const int r = i ? s->research_hsize_uv : s->research_hsize;
492  nlmeans_plane(ctx, w, h, p, r,
493  out->data[i], out->linesize[i],
494  in->data[i], in->linesize[i]);
495  }
496 
497  av_frame_free(&in);
498  return ff_filter_frame(outlink, out);
499 }
500 
501 #define CHECK_ODD_FIELD(field, name) do { \
502  if (!(s->field & 1)) { \
503  s->field |= 1; \
504  av_log(ctx, AV_LOG_WARNING, name " size must be odd, " \
505  "setting it to %d\n", s->field); \
506  } \
507 } while (0)
508 
510 {
512 
513  if (ARCH_AARCH64)
515 }
516 
518 {
519  int i;
520  NLMeansContext *s = ctx->priv;
521  const double h = s->sigma * 10.;
522 
523  s->pdiff_scale = 1. / (h * h);
524  s->max_meaningful_diff = log(255.) / s->pdiff_scale;
525  s->weight_lut = av_calloc(s->max_meaningful_diff, sizeof(*s->weight_lut));
526  if (!s->weight_lut)
527  return AVERROR(ENOMEM);
528  for (i = 0; i < s->max_meaningful_diff; i++)
529  s->weight_lut[i] = exp(-i * s->pdiff_scale);
530 
531  CHECK_ODD_FIELD(research_size, "Luma research window");
532  CHECK_ODD_FIELD(patch_size, "Luma patch");
533 
534  if (!s->research_size_uv) s->research_size_uv = s->research_size;
535  if (!s->patch_size_uv) s->patch_size_uv = s->patch_size;
536 
537  CHECK_ODD_FIELD(research_size_uv, "Chroma research window");
538  CHECK_ODD_FIELD(patch_size_uv, "Chroma patch");
539 
540  s->research_hsize = s->research_size / 2;
541  s->research_hsize_uv = s->research_size_uv / 2;
542  s->patch_hsize = s->patch_size / 2;
543  s->patch_hsize_uv = s->patch_size_uv / 2;
544 
545  av_log(ctx, AV_LOG_INFO, "Research window: %dx%d / %dx%d, patch size: %dx%d / %dx%d\n",
546  s->research_size, s->research_size, s->research_size_uv, s->research_size_uv,
547  s->patch_size, s->patch_size, s->patch_size_uv, s->patch_size_uv);
548 
549  ff_nlmeans_init(&s->dsp);
550 
551  return 0;
552 }
553 
555 {
556  NLMeansContext *s = ctx->priv;
557  av_freep(&s->weight_lut);
558  av_freep(&s->ii_orig);
559  av_freep(&s->wa);
560 }
561 
562 static const AVFilterPad nlmeans_inputs[] = {
563  {
564  .name = "default",
565  .type = AVMEDIA_TYPE_VIDEO,
566  .config_props = config_input,
567  .filter_frame = filter_frame,
568  },
569  { NULL }
570 };
571 
572 static const AVFilterPad nlmeans_outputs[] = {
573  {
574  .name = "default",
575  .type = AVMEDIA_TYPE_VIDEO,
576  },
577  { NULL }
578 };
579 
581  .name = "nlmeans",
582  .description = NULL_IF_CONFIG_SMALL("Non-local means denoiser."),
583  .priv_size = sizeof(NLMeansContext),
584  .init = init,
585  .uninit = uninit,
589  .priv_class = &nlmeans_class,
591 };
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:99
td
#define td
Definition: regdef.h:70
AVPixelFormat
AVPixelFormat
Pixel format.
Definition: pixfmt.h:64
NLMeansContext::weight_lut
float * weight_lut
Definition: vf_nlmeans.c:62
r
const char * r
Definition: vf_curves.c:114
acc
int acc
Definition: yuv2rgb.c:555
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_make_format_list
AVFilterFormats * ff_make_format_list(const int *fmts)
Create a list of supported formats.
Definition: formats.c:283
out
FILE * out
Definition: movenc.c:54
thread_data::src_linesize
ptrdiff_t src_linesize
Definition: vf_nlmeans.c:336
ff_filter_frame
int ff_filter_frame(AVFilterLink *link, AVFrame *frame)
Send a frame of data to the next filter.
Definition: avfilter.c:1080
av_pix_fmt_desc_get
const AVPixFmtDescriptor * av_pix_fmt_desc_get(enum AVPixelFormat pix_fmt)
Definition: pixdesc.c:2522
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:202
AVFrame
This structure describes decoded (raw) audio or video data.
Definition: frame.h:295
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:246
b
#define b
Definition: input.c:41
av_mallocz_array
void * av_mallocz_array(size_t nmemb, size_t size)
Definition: mem.c:191
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
AVFilter::name
const char * name
Filter name.
Definition: avfilter.h:148
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:107
video.h
AVFormatContext::internal
AVFormatInternal * internal
An opaque field for libavformat internal usage.
Definition: avformat.h:1795
CHECK_ODD_FIELD
#define CHECK_ODD_FIELD(field, name)
Definition: vf_nlmeans.c:501
AVFilterFormats
A list of supported formats for one end of a filter link.
Definition: formats.h:64
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:2562
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:572
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:208
nlmeans_inputs
static const AVFilterPad nlmeans_inputs[]
Definition: vf_nlmeans.c:562
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
src
#define src
Definition: vp8dsp.c:254
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:410
AVFilterPad
A filter pad used for either input or output.
Definition: internal.h:54
thread_data::starty
int starty
Definition: vf_nlmeans.c:337
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:258
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:166
av_cold
#define av_cold
Definition: attributes.h:84
ff_set_common_formats
int ff_set_common_formats(AVFilterContext *ctx, AVFilterFormats *formats)
A helper for query_formats() which sets all links to the same list of formats.
Definition: formats.c:568
NLMeansContext::dsp
NLMeansDSPContext dsp
Definition: vf_nlmeans.c:64
thread_data
Definition: vf_colorlevels.c:108
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
thread_data::src_linesize
int src_linesize
Definition: vf_colorlevels.c:112
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:58
AV_OPT_TYPE_DOUBLE
@ AV_OPT_TYPE_DOUBLE
Definition: opt.h:225
s1
#define s1
Definition: regdef.h:38
slice_end
static int slice_end(AVCodecContext *avctx, AVFrame *pict)
Handle slice ends.
Definition: mpeg12dec.c:2026
outputs
static const AVFilterPad outputs[]
Definition: af_acontrast.c:203
pix_fmts
static enum AVPixelFormat pix_fmts[]
Definition: libkvazaar.c:275
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
thread_data::src
const uint8_t * src
Definition: vf_nlmeans.c:335
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:66
thread_data::endx
int endx
Definition: vf_nlmeans.c:338
AVClass
Describe the class of an AVClass context structure.
Definition: log.h:67
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:654
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
thread_data::dst_linesize
int dst_linesize
Definition: vf_colorlevels.c:111
thread_data::startx
int startx
Definition: vf_nlmeans.c:337
NLMeansContext
Definition: vf_nlmeans.c:46
NLMeansContext::ii_lz_32
ptrdiff_t ii_lz_32
Definition: vf_nlmeans.c:59
inputs
these buffered frames must be flushed immediately if a new input produces new the filter must not call request_frame to get more It must just process the frame or queue it The task of requesting more frames is left to the filter s request_frame method or the application If a filter has several inputs
Definition: filter_design.txt:243
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:1564
for
for(j=16;j >0;--j)
Definition: h264pred_template.c:469
s2
#define s2
Definition: regdef.h:39
desc
const char * desc
Definition: nvenc.c:68
uninit
static av_cold void uninit(AVFilterContext *ctx)
Definition: vf_nlmeans.c:554
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:188
ff_vf_nlmeans
AVFilter ff_vf_nlmeans
Definition: vf_nlmeans.c:580
vf_nlmeans.h
FFMAX
#define FFMAX(a, b)
Definition: common.h:94
nlmeans_slice
static int nlmeans_slice(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
Definition: vf_nlmeans.c:343
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:280
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
FFMIN
#define FFMIN(a, b)
Definition: common.h:96
thread_data::endy
int endy
Definition: vf_nlmeans.c:338
AV_LOG_INFO
#define AV_LOG_INFO
Standard information.
Definition: log.h:187
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:125
NLMeansContext::ii_h
int ii_h
Definition: vf_nlmeans.c:58
in
uint8_t pi<< 24) CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_U8, uint8_t,(*(const uint8_t *) pi - 0x80) *(1.0f/(1<< 7))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_U8, uint8_t,(*(const uint8_t *) pi - 0x80) *(1.0/(1<< 7))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_S16, int16_t,(*(const int16_t *) pi >> 8)+0x80) CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_S16, int16_t, *(const int16_t *) pi *(1.0f/(1<< 15))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_S16, int16_t, *(const int16_t *) pi *(1.0/(1<< 15))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_S32, int32_t,(*(const int32_t *) pi >> 24)+0x80) CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_S32, int32_t, *(const int32_t *) pi *(1.0f/(1U<< 31))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_S32, int32_t, *(const int32_t *) pi *(1.0/(1U<< 31))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_FLT, float, av_clip_uint8(lrintf(*(const float *) pi *(1<< 7))+0x80)) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_FLT, float, av_clip_int16(lrintf(*(const float *) pi *(1<< 15)))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_FLT, float, av_clipl_int32(llrintf(*(const float *) pi *(1U<< 31)))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_DBL, double, av_clip_uint8(lrint(*(const double *) pi *(1<< 7))+0x80)) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_DBL, double, av_clip_int16(lrint(*(const double *) pi *(1<< 15)))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_DBL, double, av_clipl_int32(llrint(*(const double *) pi *(1U<< 31)))) #define SET_CONV_FUNC_GROUP(ofmt, ifmt) static void set_generic_function(AudioConvert *ac) { } void ff_audio_convert_free(AudioConvert **ac) { if(! *ac) return;ff_dither_free(&(*ac) ->dc);av_freep(ac);} AudioConvert *ff_audio_convert_alloc(AVAudioResampleContext *avr, enum AVSampleFormat out_fmt, enum AVSampleFormat in_fmt, int channels, int sample_rate, int apply_map) { AudioConvert *ac;int in_planar, out_planar;ac=av_mallocz(sizeof(*ac));if(!ac) return NULL;ac->avr=avr;ac->out_fmt=out_fmt;ac->in_fmt=in_fmt;ac->channels=channels;ac->apply_map=apply_map;if(avr->dither_method !=AV_RESAMPLE_DITHER_NONE &&av_get_packed_sample_fmt(out_fmt)==AV_SAMPLE_FMT_S16 &&av_get_bytes_per_sample(in_fmt) > 2) { ac->dc=ff_dither_alloc(avr, out_fmt, in_fmt, channels, sample_rate, apply_map);if(!ac->dc) { av_free(ac);return NULL;} return ac;} in_planar=ff_sample_fmt_is_planar(in_fmt, channels);out_planar=ff_sample_fmt_is_planar(out_fmt, channels);if(in_planar==out_planar) { ac->func_type=CONV_FUNC_TYPE_FLAT;ac->planes=in_planar ? ac->channels :1;} else if(in_planar) ac->func_type=CONV_FUNC_TYPE_INTERLEAVE;else ac->func_type=CONV_FUNC_TYPE_DEINTERLEAVE;set_generic_function(ac);if(ARCH_AARCH64) ff_audio_convert_init_aarch64(ac);if(ARCH_ARM) ff_audio_convert_init_arm(ac);if(ARCH_X86) ff_audio_convert_init_x86(ac);return ac;} int ff_audio_convert(AudioConvert *ac, AudioData *out, AudioData *in) { int use_generic=1;int len=in->nb_samples;int p;if(ac->dc) { av_log(ac->avr, AV_LOG_TRACE, "%d samples - audio_convert: %s to %s (dithered)\n", len, av_get_sample_fmt_name(ac->in_fmt), av_get_sample_fmt_name(ac->out_fmt));return ff_convert_dither(ac-> in
Definition: audio_convert.c:326
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:259
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:802
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:668
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
uint8_t
uint8_t
Definition: audio_convert.c:194
AVFilterPad::name
const char * name
Pad name.
Definition: internal.h:60
NLMeansContext::chroma_w
int chroma_w
Definition: vf_nlmeans.c:49
AVFilter
Filter definition.
Definition: avfilter.h:144
NLMeansContext::sigma
double sigma
Definition: vf_nlmeans.c:51
init
static av_cold int init(AVFilterContext *ctx)
Definition: vf_nlmeans.c:517
weighted_avg::total_weight
float total_weight
Definition: vf_nlmeans.c:42
av_calloc
void * av_calloc(size_t nmemb, size_t size)
Non-inlined equivalent of av_mallocz_array().
Definition: mem.c:244
AV_PIX_FMT_NONE
@ AV_PIX_FMT_NONE
Definition: pixfmt.h:65
AV_OPT_TYPE_INT
@ AV_OPT_TYPE_INT
Definition: opt.h:223
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_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:338
AV_PIX_FMT_GBRP
@ AV_PIX_FMT_GBRP
planar GBR 4:4:4 24bpp
Definition: pixfmt.h:168
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:116
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:473
AVPixFmtDescriptor
Descriptor that unambiguously describes how the bits of a pixel are stored in the up to 4 data planes...
Definition: pixdesc.h:81
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:430
FFALIGN
#define FFALIGN(x, a)
Definition: macros.h:48
ff_nlmeans_init
void ff_nlmeans_init(NLMeansDSPContext *dsp)
Definition: vf_nlmeans.c:509
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
ff_nlmeans_init_aarch64
av_cold void ff_nlmeans_init_aarch64(NLMeansDSPContext *dsp)
Definition: vf_nlmeans_init.c:27
nlmeans_options
static const AVOption nlmeans_options[]
Definition: vf_nlmeans.c:69
flags
#define flags(name, subs,...)
Definition: cbs_av1.c:565
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:340
thread_data::ii_start
const uint32_t * ii_start
Definition: vf_nlmeans.c:339
NLMeansContext::patch_size_uv
int patch_size_uv
Definition: vf_nlmeans.c:53