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