FFmpeg
vf_dctdnoiz.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2013-2014 Clément Bœsch
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  * A simple, relatively efficient and slow DCT image denoiser.
23  *
24  * @see http://www.ipol.im/pub/art/2011/ys-dct/
25  *
26  * The DCT factorization used is based on "Fast and numerically stable
27  * algorithms for discrete cosine transforms" from Gerlind Plonkaa & Manfred
28  * Tasche (DOI: 10.1016/j.laa.2004.07.015).
29  */
30 
31 #include "libavutil/avassert.h"
32 #include "libavutil/eval.h"
33 #include "libavutil/mem.h"
34 #include "libavutil/mem_internal.h"
35 #include "libavutil/opt.h"
36 #include "internal.h"
37 #include "video.h"
38 
39 static const char *const var_names[] = { "c", NULL };
40 enum { VAR_C, VAR_VARS_NB };
41 
42 #define MAX_THREADS 8
43 
44 typedef struct DCTdnoizContext {
45  const AVClass *class;
46 
47  /* coefficient factor expression */
48  char *expr_str;
51 
53  int pr_width, pr_height; // width and height to process
54  float sigma; // used when no expression are st
55  float th; // threshold (3*sigma)
56  float *cbuf[2][3]; // two planar rgb color buffers
57  float *slices[MAX_THREADS]; // slices buffers (1 slice buffer per thread)
58  float *weights; // dct coeff are cumulated with overlapping; these values are used for averaging
59  int p_linesize; // line sizes for color and weights
60  int overlap; // number of block overlapping pixels
61  int step; // block step increment (blocksize - overlap)
62  int n; // 1<<n is the block size
63  int bsize; // block size, 1<<n
65  const float *src, int src_linesize,
66  float *dst, int dst_linesize,
67  int thread_id);
68  void (*color_decorrelation)(float **dst, int dst_linesize,
69  const uint8_t **src, int src_linesize,
70  int w, int h);
71  void (*color_correlation)(uint8_t **dst, int dst_linesize,
72  float **src, int src_linesize,
73  int w, int h);
75 
76 #define MIN_NBITS 3 /* blocksize = 1<<3 = 8 */
77 #define MAX_NBITS 4 /* blocksize = 1<<4 = 16 */
78 #define DEFAULT_NBITS 3
79 
80 #define OFFSET(x) offsetof(DCTdnoizContext, x)
81 #define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM
82 static const AVOption dctdnoiz_options[] = {
83  { "sigma", "set noise sigma constant", OFFSET(sigma), AV_OPT_TYPE_FLOAT, {.dbl=0}, 0, 999, .flags = FLAGS },
84  { "s", "set noise sigma constant", OFFSET(sigma), AV_OPT_TYPE_FLOAT, {.dbl=0}, 0, 999, .flags = FLAGS },
85  { "overlap", "set number of block overlapping pixels", OFFSET(overlap), AV_OPT_TYPE_INT, {.i64=-1}, -1, (1<<MAX_NBITS)-1, .flags = FLAGS },
86  { "expr", "set coefficient factor expression", OFFSET(expr_str), AV_OPT_TYPE_STRING, {.str=NULL}, .flags = FLAGS },
87  { "e", "set coefficient factor expression", OFFSET(expr_str), AV_OPT_TYPE_STRING, {.str=NULL}, .flags = FLAGS },
88  { "n", "set the block size, expressed in bits", OFFSET(n), AV_OPT_TYPE_INT, {.i64=DEFAULT_NBITS}, MIN_NBITS, MAX_NBITS, .flags = FLAGS },
89  { NULL }
90 };
91 
92 AVFILTER_DEFINE_CLASS(dctdnoiz);
93 
94 static void av_always_inline fdct8_1d(float *dst, const float *src,
95  int dst_stridea, int dst_strideb,
96  int src_stridea, int src_strideb)
97 {
98  int i;
99 
100  for (i = 0; i < 8; i++) {
101  const float x00 = src[0*src_stridea] + src[7*src_stridea];
102  const float x01 = src[1*src_stridea] + src[6*src_stridea];
103  const float x02 = src[2*src_stridea] + src[5*src_stridea];
104  const float x03 = src[3*src_stridea] + src[4*src_stridea];
105  const float x04 = src[0*src_stridea] - src[7*src_stridea];
106  const float x05 = src[1*src_stridea] - src[6*src_stridea];
107  const float x06 = src[2*src_stridea] - src[5*src_stridea];
108  const float x07 = src[3*src_stridea] - src[4*src_stridea];
109  const float x08 = x00 + x03;
110  const float x09 = x01 + x02;
111  const float x0a = x00 - x03;
112  const float x0b = x01 - x02;
113  const float x0c = 1.38703984532215f*x04 + 0.275899379282943f*x07;
114  const float x0d = 1.17587560241936f*x05 + 0.785694958387102f*x06;
115  const float x0e = -0.785694958387102f*x05 + 1.17587560241936f*x06;
116  const float x0f = 0.275899379282943f*x04 - 1.38703984532215f*x07;
117  const float x10 = 0.353553390593274f * (x0c - x0d);
118  const float x11 = 0.353553390593274f * (x0e - x0f);
119  dst[0*dst_stridea] = 0.353553390593274f * (x08 + x09);
120  dst[1*dst_stridea] = 0.353553390593274f * (x0c + x0d);
121  dst[2*dst_stridea] = 0.461939766255643f*x0a + 0.191341716182545f*x0b;
122  dst[3*dst_stridea] = 0.707106781186547f * (x10 - x11);
123  dst[4*dst_stridea] = 0.353553390593274f * (x08 - x09);
124  dst[5*dst_stridea] = 0.707106781186547f * (x10 + x11);
125  dst[6*dst_stridea] = 0.191341716182545f*x0a - 0.461939766255643f*x0b;
126  dst[7*dst_stridea] = 0.353553390593274f * (x0e + x0f);
127  dst += dst_strideb;
128  src += src_strideb;
129  }
130 }
131 
132 static void av_always_inline idct8_1d(float *dst, const float *src,
133  int dst_stridea, int dst_strideb,
134  int src_stridea, int src_strideb,
135  int add)
136 {
137  int i;
138 
139  for (i = 0; i < 8; i++) {
140  const float x00 = 1.4142135623731f *src[0*src_stridea];
141  const float x01 = 1.38703984532215f *src[1*src_stridea] + 0.275899379282943f*src[7*src_stridea];
142  const float x02 = 1.30656296487638f *src[2*src_stridea] + 0.541196100146197f*src[6*src_stridea];
143  const float x03 = 1.17587560241936f *src[3*src_stridea] + 0.785694958387102f*src[5*src_stridea];
144  const float x04 = 1.4142135623731f *src[4*src_stridea];
145  const float x05 = -0.785694958387102f*src[3*src_stridea] + 1.17587560241936f*src[5*src_stridea];
146  const float x06 = 0.541196100146197f*src[2*src_stridea] - 1.30656296487638f*src[6*src_stridea];
147  const float x07 = -0.275899379282943f*src[1*src_stridea] + 1.38703984532215f*src[7*src_stridea];
148  const float x09 = x00 + x04;
149  const float x0a = x01 + x03;
150  const float x0b = 1.4142135623731f*x02;
151  const float x0c = x00 - x04;
152  const float x0d = x01 - x03;
153  const float x0e = 0.353553390593274f * (x09 - x0b);
154  const float x0f = 0.353553390593274f * (x0c + x0d);
155  const float x10 = 0.353553390593274f * (x0c - x0d);
156  const float x11 = 1.4142135623731f*x06;
157  const float x12 = x05 + x07;
158  const float x13 = x05 - x07;
159  const float x14 = 0.353553390593274f * (x11 + x12);
160  const float x15 = 0.353553390593274f * (x11 - x12);
161  const float x16 = 0.5f*x13;
162  dst[0*dst_stridea] = (add ? dst[ 0*dst_stridea] : 0) + 0.25f * (x09 + x0b) + 0.353553390593274f*x0a;
163  dst[1*dst_stridea] = (add ? dst[ 1*dst_stridea] : 0) + 0.707106781186547f * (x0f + x15);
164  dst[2*dst_stridea] = (add ? dst[ 2*dst_stridea] : 0) + 0.707106781186547f * (x0f - x15);
165  dst[3*dst_stridea] = (add ? dst[ 3*dst_stridea] : 0) + 0.707106781186547f * (x0e + x16);
166  dst[4*dst_stridea] = (add ? dst[ 4*dst_stridea] : 0) + 0.707106781186547f * (x0e - x16);
167  dst[5*dst_stridea] = (add ? dst[ 5*dst_stridea] : 0) + 0.707106781186547f * (x10 - x14);
168  dst[6*dst_stridea] = (add ? dst[ 6*dst_stridea] : 0) + 0.707106781186547f * (x10 + x14);
169  dst[7*dst_stridea] = (add ? dst[ 7*dst_stridea] : 0) + 0.25f * (x09 + x0b) - 0.353553390593274f*x0a;
170  dst += dst_strideb;
171  src += src_strideb;
172  }
173 }
174 
175 
176 static void av_always_inline fdct16_1d(float *dst, const float *src,
177  int dst_stridea, int dst_strideb,
178  int src_stridea, int src_strideb)
179 {
180  int i;
181 
182  for (i = 0; i < 16; i++) {
183  const float x00 = src[ 0*src_stridea] + src[15*src_stridea];
184  const float x01 = src[ 1*src_stridea] + src[14*src_stridea];
185  const float x02 = src[ 2*src_stridea] + src[13*src_stridea];
186  const float x03 = src[ 3*src_stridea] + src[12*src_stridea];
187  const float x04 = src[ 4*src_stridea] + src[11*src_stridea];
188  const float x05 = src[ 5*src_stridea] + src[10*src_stridea];
189  const float x06 = src[ 6*src_stridea] + src[ 9*src_stridea];
190  const float x07 = src[ 7*src_stridea] + src[ 8*src_stridea];
191  const float x08 = src[ 0*src_stridea] - src[15*src_stridea];
192  const float x09 = src[ 1*src_stridea] - src[14*src_stridea];
193  const float x0a = src[ 2*src_stridea] - src[13*src_stridea];
194  const float x0b = src[ 3*src_stridea] - src[12*src_stridea];
195  const float x0c = src[ 4*src_stridea] - src[11*src_stridea];
196  const float x0d = src[ 5*src_stridea] - src[10*src_stridea];
197  const float x0e = src[ 6*src_stridea] - src[ 9*src_stridea];
198  const float x0f = src[ 7*src_stridea] - src[ 8*src_stridea];
199  const float x10 = x00 + x07;
200  const float x11 = x01 + x06;
201  const float x12 = x02 + x05;
202  const float x13 = x03 + x04;
203  const float x14 = x00 - x07;
204  const float x15 = x01 - x06;
205  const float x16 = x02 - x05;
206  const float x17 = x03 - x04;
207  const float x18 = x10 + x13;
208  const float x19 = x11 + x12;
209  const float x1a = x10 - x13;
210  const float x1b = x11 - x12;
211  const float x1c = 1.38703984532215f*x14 + 0.275899379282943f*x17;
212  const float x1d = 1.17587560241936f*x15 + 0.785694958387102f*x16;
213  const float x1e = -0.785694958387102f*x15 + 1.17587560241936f *x16;
214  const float x1f = 0.275899379282943f*x14 - 1.38703984532215f *x17;
215  const float x20 = 0.25f * (x1c - x1d);
216  const float x21 = 0.25f * (x1e - x1f);
217  const float x22 = 1.40740373752638f *x08 + 0.138617169199091f*x0f;
218  const float x23 = 1.35331800117435f *x09 + 0.410524527522357f*x0e;
219  const float x24 = 1.24722501298667f *x0a + 0.666655658477747f*x0d;
220  const float x25 = 1.09320186700176f *x0b + 0.897167586342636f*x0c;
221  const float x26 = -0.897167586342636f*x0b + 1.09320186700176f *x0c;
222  const float x27 = 0.666655658477747f*x0a - 1.24722501298667f *x0d;
223  const float x28 = -0.410524527522357f*x09 + 1.35331800117435f *x0e;
224  const float x29 = 0.138617169199091f*x08 - 1.40740373752638f *x0f;
225  const float x2a = x22 + x25;
226  const float x2b = x23 + x24;
227  const float x2c = x22 - x25;
228  const float x2d = x23 - x24;
229  const float x2e = 0.25f * (x2a - x2b);
230  const float x2f = 0.326640741219094f*x2c + 0.135299025036549f*x2d;
231  const float x30 = 0.135299025036549f*x2c - 0.326640741219094f*x2d;
232  const float x31 = x26 + x29;
233  const float x32 = x27 + x28;
234  const float x33 = x26 - x29;
235  const float x34 = x27 - x28;
236  const float x35 = 0.25f * (x31 - x32);
237  const float x36 = 0.326640741219094f*x33 + 0.135299025036549f*x34;
238  const float x37 = 0.135299025036549f*x33 - 0.326640741219094f*x34;
239  dst[ 0*dst_stridea] = 0.25f * (x18 + x19);
240  dst[ 1*dst_stridea] = 0.25f * (x2a + x2b);
241  dst[ 2*dst_stridea] = 0.25f * (x1c + x1d);
242  dst[ 3*dst_stridea] = 0.707106781186547f * (x2f - x37);
243  dst[ 4*dst_stridea] = 0.326640741219094f*x1a + 0.135299025036549f*x1b;
244  dst[ 5*dst_stridea] = 0.707106781186547f * (x2f + x37);
245  dst[ 6*dst_stridea] = 0.707106781186547f * (x20 - x21);
246  dst[ 7*dst_stridea] = 0.707106781186547f * (x2e + x35);
247  dst[ 8*dst_stridea] = 0.25f * (x18 - x19);
248  dst[ 9*dst_stridea] = 0.707106781186547f * (x2e - x35);
249  dst[10*dst_stridea] = 0.707106781186547f * (x20 + x21);
250  dst[11*dst_stridea] = 0.707106781186547f * (x30 - x36);
251  dst[12*dst_stridea] = 0.135299025036549f*x1a - 0.326640741219094f*x1b;
252  dst[13*dst_stridea] = 0.707106781186547f * (x30 + x36);
253  dst[14*dst_stridea] = 0.25f * (x1e + x1f);
254  dst[15*dst_stridea] = 0.25f * (x31 + x32);
255  dst += dst_strideb;
256  src += src_strideb;
257  }
258 }
259 
260 static void av_always_inline idct16_1d(float *dst, const float *src,
261  int dst_stridea, int dst_strideb,
262  int src_stridea, int src_strideb,
263  int add)
264 {
265  int i;
266 
267  for (i = 0; i < 16; i++) {
268  const float x00 = 1.4142135623731f *src[ 0*src_stridea];
269  const float x01 = 1.40740373752638f *src[ 1*src_stridea] + 0.138617169199091f*src[15*src_stridea];
270  const float x02 = 1.38703984532215f *src[ 2*src_stridea] + 0.275899379282943f*src[14*src_stridea];
271  const float x03 = 1.35331800117435f *src[ 3*src_stridea] + 0.410524527522357f*src[13*src_stridea];
272  const float x04 = 1.30656296487638f *src[ 4*src_stridea] + 0.541196100146197f*src[12*src_stridea];
273  const float x05 = 1.24722501298667f *src[ 5*src_stridea] + 0.666655658477747f*src[11*src_stridea];
274  const float x06 = 1.17587560241936f *src[ 6*src_stridea] + 0.785694958387102f*src[10*src_stridea];
275  const float x07 = 1.09320186700176f *src[ 7*src_stridea] + 0.897167586342636f*src[ 9*src_stridea];
276  const float x08 = 1.4142135623731f *src[ 8*src_stridea];
277  const float x09 = -0.897167586342636f*src[ 7*src_stridea] + 1.09320186700176f*src[ 9*src_stridea];
278  const float x0a = 0.785694958387102f*src[ 6*src_stridea] - 1.17587560241936f*src[10*src_stridea];
279  const float x0b = -0.666655658477747f*src[ 5*src_stridea] + 1.24722501298667f*src[11*src_stridea];
280  const float x0c = 0.541196100146197f*src[ 4*src_stridea] - 1.30656296487638f*src[12*src_stridea];
281  const float x0d = -0.410524527522357f*src[ 3*src_stridea] + 1.35331800117435f*src[13*src_stridea];
282  const float x0e = 0.275899379282943f*src[ 2*src_stridea] - 1.38703984532215f*src[14*src_stridea];
283  const float x0f = -0.138617169199091f*src[ 1*src_stridea] + 1.40740373752638f*src[15*src_stridea];
284  const float x12 = x00 + x08;
285  const float x13 = x01 + x07;
286  const float x14 = x02 + x06;
287  const float x15 = x03 + x05;
288  const float x16 = 1.4142135623731f*x04;
289  const float x17 = x00 - x08;
290  const float x18 = x01 - x07;
291  const float x19 = x02 - x06;
292  const float x1a = x03 - x05;
293  const float x1d = x12 + x16;
294  const float x1e = x13 + x15;
295  const float x1f = 1.4142135623731f*x14;
296  const float x20 = x12 - x16;
297  const float x21 = x13 - x15;
298  const float x22 = 0.25f * (x1d - x1f);
299  const float x23 = 0.25f * (x20 + x21);
300  const float x24 = 0.25f * (x20 - x21);
301  const float x25 = 1.4142135623731f*x17;
302  const float x26 = 1.30656296487638f*x18 + 0.541196100146197f*x1a;
303  const float x27 = 1.4142135623731f*x19;
304  const float x28 = -0.541196100146197f*x18 + 1.30656296487638f*x1a;
305  const float x29 = 0.176776695296637f * (x25 + x27) + 0.25f*x26;
306  const float x2a = 0.25f * (x25 - x27);
307  const float x2b = 0.176776695296637f * (x25 + x27) - 0.25f*x26;
308  const float x2c = 0.353553390593274f*x28;
309  const float x1b = 0.707106781186547f * (x2a - x2c);
310  const float x1c = 0.707106781186547f * (x2a + x2c);
311  const float x2d = 1.4142135623731f*x0c;
312  const float x2e = x0b + x0d;
313  const float x2f = x0a + x0e;
314  const float x30 = x09 + x0f;
315  const float x31 = x09 - x0f;
316  const float x32 = x0a - x0e;
317  const float x33 = x0b - x0d;
318  const float x37 = 1.4142135623731f*x2d;
319  const float x38 = 1.30656296487638f*x2e + 0.541196100146197f*x30;
320  const float x39 = 1.4142135623731f*x2f;
321  const float x3a = -0.541196100146197f*x2e + 1.30656296487638f*x30;
322  const float x3b = 0.176776695296637f * (x37 + x39) + 0.25f*x38;
323  const float x3c = 0.25f * (x37 - x39);
324  const float x3d = 0.176776695296637f * (x37 + x39) - 0.25f*x38;
325  const float x3e = 0.353553390593274f*x3a;
326  const float x34 = 0.707106781186547f * (x3c - x3e);
327  const float x35 = 0.707106781186547f * (x3c + x3e);
328  const float x3f = 1.4142135623731f*x32;
329  const float x40 = x31 + x33;
330  const float x41 = x31 - x33;
331  const float x42 = 0.25f * (x3f + x40);
332  const float x43 = 0.25f * (x3f - x40);
333  const float x44 = 0.353553390593274f*x41;
334  dst[ 0*dst_stridea] = (add ? dst[ 0*dst_stridea] : 0) + 0.176776695296637f * (x1d + x1f) + 0.25f*x1e;
335  dst[ 1*dst_stridea] = (add ? dst[ 1*dst_stridea] : 0) + 0.707106781186547f * (x29 + x3d);
336  dst[ 2*dst_stridea] = (add ? dst[ 2*dst_stridea] : 0) + 0.707106781186547f * (x29 - x3d);
337  dst[ 3*dst_stridea] = (add ? dst[ 3*dst_stridea] : 0) + 0.707106781186547f * (x23 - x43);
338  dst[ 4*dst_stridea] = (add ? dst[ 4*dst_stridea] : 0) + 0.707106781186547f * (x23 + x43);
339  dst[ 5*dst_stridea] = (add ? dst[ 5*dst_stridea] : 0) + 0.707106781186547f * (x1b - x35);
340  dst[ 6*dst_stridea] = (add ? dst[ 6*dst_stridea] : 0) + 0.707106781186547f * (x1b + x35);
341  dst[ 7*dst_stridea] = (add ? dst[ 7*dst_stridea] : 0) + 0.707106781186547f * (x22 + x44);
342  dst[ 8*dst_stridea] = (add ? dst[ 8*dst_stridea] : 0) + 0.707106781186547f * (x22 - x44);
343  dst[ 9*dst_stridea] = (add ? dst[ 9*dst_stridea] : 0) + 0.707106781186547f * (x1c + x34);
344  dst[10*dst_stridea] = (add ? dst[10*dst_stridea] : 0) + 0.707106781186547f * (x1c - x34);
345  dst[11*dst_stridea] = (add ? dst[11*dst_stridea] : 0) + 0.707106781186547f * (x24 + x42);
346  dst[12*dst_stridea] = (add ? dst[12*dst_stridea] : 0) + 0.707106781186547f * (x24 - x42);
347  dst[13*dst_stridea] = (add ? dst[13*dst_stridea] : 0) + 0.707106781186547f * (x2b - x3b);
348  dst[14*dst_stridea] = (add ? dst[14*dst_stridea] : 0) + 0.707106781186547f * (x2b + x3b);
349  dst[15*dst_stridea] = (add ? dst[15*dst_stridea] : 0) + 0.176776695296637f * (x1d + x1f) - 0.25f*x1e;
350  dst += dst_strideb;
351  src += src_strideb;
352  }
353 }
354 
355 #define DEF_FILTER_FREQ_FUNCS(bsize) \
356 static av_always_inline void filter_freq_##bsize(const float *src, int src_linesize, \
357  float *dst, int dst_linesize, \
358  AVExpr *expr, double *var_values, \
359  int sigma_th) \
360 { \
361  unsigned i; \
362  DECLARE_ALIGNED(32, float, tmp_block1)[bsize * bsize]; \
363  DECLARE_ALIGNED(32, float, tmp_block2)[bsize * bsize]; \
364  \
365  /* forward DCT */ \
366  fdct##bsize##_1d(tmp_block1, src, 1, bsize, 1, src_linesize); \
367  fdct##bsize##_1d(tmp_block2, tmp_block1, bsize, 1, bsize, 1); \
368  \
369  for (i = 0; i < bsize*bsize; i++) { \
370  float *b = &tmp_block2[i]; \
371  /* frequency filtering */ \
372  if (expr) { \
373  var_values[VAR_C] = fabsf(*b); \
374  *b *= av_expr_eval(expr, var_values, NULL); \
375  } else { \
376  if (fabsf(*b) < sigma_th) \
377  *b = 0; \
378  } \
379  } \
380  \
381  /* inverse DCT */ \
382  idct##bsize##_1d(tmp_block1, tmp_block2, 1, bsize, 1, bsize, 0); \
383  idct##bsize##_1d(dst, tmp_block1, dst_linesize, 1, bsize, 1, 1); \
384 } \
385  \
386 static void filter_freq_sigma_##bsize(DCTdnoizContext *s, \
387  const float *src, int src_linesize, \
388  float *dst, int dst_linesize, int thread_id) \
389 { \
390  filter_freq_##bsize(src, src_linesize, dst, dst_linesize, NULL, NULL, s->th); \
391 } \
392  \
393 static void filter_freq_expr_##bsize(DCTdnoizContext *s, \
394  const float *src, int src_linesize, \
395  float *dst, int dst_linesize, int thread_id) \
396 { \
397  filter_freq_##bsize(src, src_linesize, dst, dst_linesize, \
398  s->expr[thread_id], s->var_values[thread_id], 0); \
399 }
400 
403 
404 #define DCT3X3_0_0 0.5773502691896258f /* 1/sqrt(3) */
405 #define DCT3X3_0_1 0.5773502691896258f /* 1/sqrt(3) */
406 #define DCT3X3_0_2 0.5773502691896258f /* 1/sqrt(3) */
407 #define DCT3X3_1_0 0.7071067811865475f /* 1/sqrt(2) */
408 #define DCT3X3_1_2 -0.7071067811865475f /* -1/sqrt(2) */
409 #define DCT3X3_2_0 0.4082482904638631f /* 1/sqrt(6) */
410 #define DCT3X3_2_1 -0.8164965809277261f /* -2/sqrt(6) */
411 #define DCT3X3_2_2 0.4082482904638631f /* 1/sqrt(6) */
412 
413 static av_always_inline void color_decorrelation(float **dst, int dst_linesize,
414  const uint8_t **src, int src_linesize,
415  int w, int h,
416  int r, int g, int b)
417 {
418  int x, y;
419  float *dstp_r = dst[0];
420  float *dstp_g = dst[1];
421  float *dstp_b = dst[2];
422  const uint8_t *srcp = src[0];
423 
424  for (y = 0; y < h; y++) {
425  for (x = 0; x < w; x++) {
426  dstp_r[x] = srcp[r] * DCT3X3_0_0 + srcp[g] * DCT3X3_0_1 + srcp[b] * DCT3X3_0_2;
427  dstp_g[x] = srcp[r] * DCT3X3_1_0 + srcp[b] * DCT3X3_1_2;
428  dstp_b[x] = srcp[r] * DCT3X3_2_0 + srcp[g] * DCT3X3_2_1 + srcp[b] * DCT3X3_2_2;
429  srcp += 3;
430  }
431  srcp += src_linesize - w * 3;
432  dstp_r += dst_linesize;
433  dstp_g += dst_linesize;
434  dstp_b += dst_linesize;
435  }
436 }
437 
438 static av_always_inline void color_correlation(uint8_t **dst, int dst_linesize,
439  float **src, int src_linesize,
440  int w, int h,
441  int r, int g, int b)
442 {
443  int x, y;
444  const float *src_r = src[0];
445  const float *src_g = src[1];
446  const float *src_b = src[2];
447  uint8_t *dstp = dst[0];
448 
449  for (y = 0; y < h; y++) {
450  for (x = 0; x < w; x++) {
451  dstp[r] = av_clip_uint8(src_r[x] * DCT3X3_0_0 + src_g[x] * DCT3X3_1_0 + src_b[x] * DCT3X3_2_0);
452  dstp[g] = av_clip_uint8(src_r[x] * DCT3X3_0_1 + src_b[x] * DCT3X3_2_1);
453  dstp[b] = av_clip_uint8(src_r[x] * DCT3X3_0_2 + src_g[x] * DCT3X3_1_2 + src_b[x] * DCT3X3_2_2);
454  dstp += 3;
455  }
456  dstp += dst_linesize - w * 3;
457  src_r += src_linesize;
458  src_g += src_linesize;
459  src_b += src_linesize;
460  }
461 }
462 
463 #define DECLARE_COLOR_FUNCS(name, r, g, b) \
464 static void color_decorrelation_##name(float **dst, int dst_linesize, \
465  const uint8_t **src, int src_linesize, \
466  int w, int h) \
467 { \
468  color_decorrelation(dst, dst_linesize, src, src_linesize, w, h, r, g, b); \
469 } \
470  \
471 static void color_correlation_##name(uint8_t **dst, int dst_linesize, \
472  float **src, int src_linesize, \
473  int w, int h) \
474 { \
475  color_correlation(dst, dst_linesize, src, src_linesize, w, h, r, g, b); \
476 }
477 
478 DECLARE_COLOR_FUNCS(rgb, 0, 1, 2)
479 DECLARE_COLOR_FUNCS(bgr, 2, 1, 0)
480 
481 static av_always_inline void color_decorrelation_gbrp(float **dst, int dst_linesize,
482  const uint8_t **src, int src_linesize,
483  int w, int h)
484 {
485  int x, y;
486  float *dstp_r = dst[0];
487  float *dstp_g = dst[1];
488  float *dstp_b = dst[2];
489  const uint8_t *srcp_r = src[2];
490  const uint8_t *srcp_g = src[0];
491  const uint8_t *srcp_b = src[1];
492 
493  for (y = 0; y < h; y++) {
494  for (x = 0; x < w; x++) {
495  dstp_r[x] = srcp_r[x] * DCT3X3_0_0 + srcp_g[x] * DCT3X3_0_1 + srcp_b[x] * DCT3X3_0_2;
496  dstp_g[x] = srcp_r[x] * DCT3X3_1_0 + srcp_b[x] * DCT3X3_1_2;
497  dstp_b[x] = srcp_r[x] * DCT3X3_2_0 + srcp_g[x] * DCT3X3_2_1 + srcp_b[x] * DCT3X3_2_2;
498  }
499  srcp_r += src_linesize;
500  srcp_g += src_linesize;
501  srcp_b += src_linesize;
502  dstp_r += dst_linesize;
503  dstp_g += dst_linesize;
504  dstp_b += dst_linesize;
505  }
506 }
507 
508 static av_always_inline void color_correlation_gbrp(uint8_t **dst, int dst_linesize,
509  float **src, int src_linesize,
510  int w, int h)
511 {
512  int x, y;
513  const float *src_r = src[0];
514  const float *src_g = src[1];
515  const float *src_b = src[2];
516  uint8_t *dstp_r = dst[2];
517  uint8_t *dstp_g = dst[0];
518  uint8_t *dstp_b = dst[1];
519 
520  for (y = 0; y < h; y++) {
521  for (x = 0; x < w; x++) {
522  dstp_r[x] = av_clip_uint8(src_r[x] * DCT3X3_0_0 + src_g[x] * DCT3X3_1_0 + src_b[x] * DCT3X3_2_0);
523  dstp_g[x] = av_clip_uint8(src_r[x] * DCT3X3_0_1 + src_b[x] * DCT3X3_2_1);
524  dstp_b[x] = av_clip_uint8(src_r[x] * DCT3X3_0_2 + src_g[x] * DCT3X3_1_2 + src_b[x] * DCT3X3_2_2);
525  }
526  dstp_r += dst_linesize;
527  dstp_g += dst_linesize;
528  dstp_b += dst_linesize;
529  src_r += src_linesize;
530  src_g += src_linesize;
531  src_b += src_linesize;
532  }
533 }
534 
536 {
537  AVFilterContext *ctx = inlink->dst;
538  DCTdnoizContext *s = ctx->priv;
539  int i, x, y, bx, by, linesize, *iweights, max_slice_h, slice_h;
540  const int bsize = 1 << s->n;
541 
542  switch (inlink->format) {
543  case AV_PIX_FMT_BGR24:
544  s->color_decorrelation = color_decorrelation_bgr;
545  s->color_correlation = color_correlation_bgr;
546  break;
547  case AV_PIX_FMT_RGB24:
548  s->color_decorrelation = color_decorrelation_rgb;
549  s->color_correlation = color_correlation_rgb;
550  break;
551  case AV_PIX_FMT_GBRP:
552  s->color_decorrelation = color_decorrelation_gbrp;
553  s->color_correlation = color_correlation_gbrp;
554  break;
555  default:
556  av_assert0(0);
557  }
558 
559  s->pr_width = inlink->w - (inlink->w - bsize) % s->step;
560  s->pr_height = inlink->h - (inlink->h - bsize) % s->step;
561  if (s->pr_width != inlink->w)
562  av_log(ctx, AV_LOG_WARNING, "The last %d horizontal pixels won't be denoised\n",
563  inlink->w - s->pr_width);
564  if (s->pr_height != inlink->h)
565  av_log(ctx, AV_LOG_WARNING, "The last %d vertical pixels won't be denoised\n",
566  inlink->h - s->pr_height);
567 
568  max_slice_h = s->pr_height / ((s->bsize - 1) * 2);
569  if (max_slice_h == 0)
570  return AVERROR(EINVAL);
571 
572  s->nb_threads = FFMIN3(MAX_THREADS, ff_filter_get_nb_threads(ctx), max_slice_h);
573  av_log(ctx, AV_LOG_DEBUG, "threads: [max=%d hmax=%d user=%d] => %d\n",
574  MAX_THREADS, max_slice_h, ff_filter_get_nb_threads(ctx), s->nb_threads);
575 
576  s->p_linesize = linesize = FFALIGN(s->pr_width, 32);
577  for (i = 0; i < 2; i++) {
578  s->cbuf[i][0] = av_malloc_array(linesize * s->pr_height, sizeof(*s->cbuf[i][0]));
579  s->cbuf[i][1] = av_malloc_array(linesize * s->pr_height, sizeof(*s->cbuf[i][1]));
580  s->cbuf[i][2] = av_malloc_array(linesize * s->pr_height, sizeof(*s->cbuf[i][2]));
581  if (!s->cbuf[i][0] || !s->cbuf[i][1] || !s->cbuf[i][2])
582  return AVERROR(ENOMEM);
583  }
584 
585  /* eval expressions are probably not thread safe when the eval internal
586  * state can be changed (typically through load & store operations) */
587  if (s->expr_str) {
588  for (i = 0; i < s->nb_threads; i++) {
589  int ret = av_expr_parse(&s->expr[i], s->expr_str, var_names,
590  NULL, NULL, NULL, NULL, 0, ctx);
591  if (ret < 0)
592  return ret;
593  }
594  }
595 
596  /* each slice will need to (pre & re)process the top and bottom block of
597  * the previous one in in addition to its processing area. This is because
598  * each pixel is averaged by all the surrounding blocks */
599  slice_h = (int)ceilf(s->pr_height / (float)s->nb_threads) + (s->bsize - 1) * 2;
600  for (i = 0; i < s->nb_threads; i++) {
601  s->slices[i] = av_malloc_array(linesize, slice_h * sizeof(*s->slices[i]));
602  if (!s->slices[i])
603  return AVERROR(ENOMEM);
604  }
605 
606  s->weights = av_malloc(s->pr_height * linesize * sizeof(*s->weights));
607  if (!s->weights)
608  return AVERROR(ENOMEM);
609  iweights = av_calloc(s->pr_height, linesize * sizeof(*iweights));
610  if (!iweights)
611  return AVERROR(ENOMEM);
612  for (y = 0; y < s->pr_height - bsize + 1; y += s->step)
613  for (x = 0; x < s->pr_width - bsize + 1; x += s->step)
614  for (by = 0; by < bsize; by++)
615  for (bx = 0; bx < bsize; bx++)
616  iweights[(y + by)*linesize + x + bx]++;
617  for (y = 0; y < s->pr_height; y++)
618  for (x = 0; x < s->pr_width; x++)
619  s->weights[y*linesize + x] = 1. / iweights[y*linesize + x];
620  av_free(iweights);
621 
622  return 0;
623 }
624 
626 {
627  DCTdnoizContext *s = ctx->priv;
628 
629  s->bsize = 1 << s->n;
630  if (s->overlap == -1)
631  s->overlap = s->bsize - 1;
632 
633  if (s->overlap > s->bsize - 1) {
634  av_log(s, AV_LOG_ERROR, "Overlap value can not except %d "
635  "with a block size of %dx%d\n",
636  s->bsize - 1, s->bsize, s->bsize);
637  return AVERROR(EINVAL);
638  }
639 
640  if (s->expr_str) {
641  switch (s->n) {
642  case 3: s->filter_freq_func = filter_freq_expr_8; break;
643  case 4: s->filter_freq_func = filter_freq_expr_16; break;
644  default: av_assert0(0);
645  }
646  } else {
647  switch (s->n) {
648  case 3: s->filter_freq_func = filter_freq_sigma_8; break;
649  case 4: s->filter_freq_func = filter_freq_sigma_16; break;
650  default: av_assert0(0);
651  }
652  }
653 
654  s->th = s->sigma * 3.;
655  s->step = s->bsize - s->overlap;
656  return 0;
657 }
658 
659 static const enum AVPixelFormat pix_fmts[] = {
663 };
664 
665 typedef struct ThreadData {
666  float *src, *dst;
667 } ThreadData;
668 
670  void *arg, int jobnr, int nb_jobs)
671 {
672  int x, y;
673  DCTdnoizContext *s = ctx->priv;
674  const ThreadData *td = arg;
675  const int w = s->pr_width;
676  const int h = s->pr_height;
677  const int slice_start = (h * jobnr ) / nb_jobs;
678  const int slice_end = (h * (jobnr+1)) / nb_jobs;
679  const int slice_start_ctx = FFMAX(slice_start - s->bsize + 1, 0);
680  const int slice_end_ctx = FFMIN(slice_end, h - s->bsize + 1);
681  const int slice_h = slice_end_ctx - slice_start_ctx;
682  const int src_linesize = s->p_linesize;
683  const int dst_linesize = s->p_linesize;
684  const int slice_linesize = s->p_linesize;
685  float *dst;
686  const float *src = td->src + slice_start_ctx * src_linesize;
687  const float *weights = s->weights + slice_start * dst_linesize;
688  float *slice = s->slices[jobnr];
689 
690  // reset block sums
691  memset(slice, 0, (slice_h + s->bsize - 1) * dst_linesize * sizeof(*slice));
692 
693  // block dct sums
694  for (y = 0; y < slice_h; y += s->step) {
695  for (x = 0; x < w - s->bsize + 1; x += s->step)
696  s->filter_freq_func(s, src + x, src_linesize,
697  slice + x, slice_linesize,
698  jobnr);
699  src += s->step * src_linesize;
700  slice += s->step * slice_linesize;
701  }
702 
703  // average blocks
704  slice = s->slices[jobnr] + (slice_start - slice_start_ctx) * slice_linesize;
705  dst = td->dst + slice_start * dst_linesize;
706  for (y = slice_start; y < slice_end; y++) {
707  for (x = 0; x < w; x++)
708  dst[x] = slice[x] * weights[x];
709  slice += slice_linesize;
710  dst += dst_linesize;
711  weights += dst_linesize;
712  }
713 
714  return 0;
715 }
716 
718 {
719  AVFilterContext *ctx = inlink->dst;
720  DCTdnoizContext *s = ctx->priv;
721  AVFilterLink *outlink = inlink->dst->outputs[0];
722  int direct, plane;
723  AVFrame *out;
724 
725  if (av_frame_is_writable(in)) {
726  direct = 1;
727  out = in;
728  } else {
729  direct = 0;
730  out = ff_get_video_buffer(outlink, outlink->w, outlink->h);
731  if (!out) {
732  av_frame_free(&in);
733  return AVERROR(ENOMEM);
734  }
736  }
737 
738  s->color_decorrelation(s->cbuf[0], s->p_linesize,
739  (const uint8_t **)in->data, in->linesize[0],
740  s->pr_width, s->pr_height);
741  for (plane = 0; plane < 3; plane++) {
742  ThreadData td = {
743  .src = s->cbuf[0][plane],
744  .dst = s->cbuf[1][plane],
745  };
746  ff_filter_execute(ctx, filter_slice, &td, NULL, s->nb_threads);
747  }
748  s->color_correlation(out->data, out->linesize[0],
749  s->cbuf[1], s->p_linesize,
750  s->pr_width, s->pr_height);
751 
752  if (!direct) {
753  int y;
754  uint8_t *dst = out->data[0];
755  const uint8_t *src = in->data[0];
756  const int dst_linesize = out->linesize[0];
757  const int src_linesize = in->linesize[0];
758  const int hpad = (inlink->w - s->pr_width) * 3;
759  const int vpad = (inlink->h - s->pr_height);
760 
761  if (hpad) {
762  uint8_t *dstp = dst + s->pr_width * 3;
763  const uint8_t *srcp = src + s->pr_width * 3;
764 
765  for (y = 0; y < s->pr_height; y++) {
766  memcpy(dstp, srcp, hpad);
767  dstp += dst_linesize;
768  srcp += src_linesize;
769  }
770  }
771  if (vpad) {
772  uint8_t *dstp = dst + s->pr_height * dst_linesize;
773  const uint8_t *srcp = src + s->pr_height * src_linesize;
774 
775  for (y = 0; y < vpad; y++) {
776  memcpy(dstp, srcp, inlink->w * 3);
777  dstp += dst_linesize;
778  srcp += src_linesize;
779  }
780  }
781 
782  av_frame_free(&in);
783  }
784 
785  return ff_filter_frame(outlink, out);
786 }
787 
789 {
790  int i;
791  DCTdnoizContext *s = ctx->priv;
792 
793  av_freep(&s->weights);
794  for (i = 0; i < 2; i++) {
795  av_freep(&s->cbuf[i][0]);
796  av_freep(&s->cbuf[i][1]);
797  av_freep(&s->cbuf[i][2]);
798  }
799  for (i = 0; i < s->nb_threads; i++) {
800  av_freep(&s->slices[i]);
801  av_expr_free(s->expr[i]);
802  }
803 }
804 
805 static const AVFilterPad dctdnoiz_inputs[] = {
806  {
807  .name = "default",
808  .type = AVMEDIA_TYPE_VIDEO,
809  .filter_frame = filter_frame,
810  .config_props = config_input,
811  },
812 };
813 
815  .name = "dctdnoiz",
816  .description = NULL_IF_CONFIG_SMALL("Denoise frames using 2D DCT."),
817  .priv_size = sizeof(DCTdnoizContext),
818  .init = init,
819  .uninit = uninit,
823  .priv_class = &dctdnoiz_class,
825 };
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:112
DCT3X3_0_0
#define DCT3X3_0_0
Definition: vf_dctdnoiz.c:404
DCTdnoizContext
Definition: vf_dctdnoiz.c:44
AV_LOG_WARNING
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition: log.h:186
td
#define td
Definition: regdef.h:70
AVPixelFormat
AVPixelFormat
Pixel format.
Definition: pixfmt.h:71
r
const char * r
Definition: vf_curves.c:127
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
init
static av_cold int init(AVFilterContext *ctx)
Definition: vf_dctdnoiz.c:625
mem_internal.h
DCTdnoizContext::bsize
int bsize
Definition: vf_dctdnoiz.c:63
out
FILE * out
Definition: movenc.c:55
FLAGS
#define FLAGS
Definition: vf_dctdnoiz.c:81
ff_filter_frame
int ff_filter_frame(AVFilterLink *link, AVFrame *frame)
Send a frame of data to the next filter.
Definition: avfilter.c:1015
FILTER_PIXFMTS_ARRAY
#define FILTER_PIXFMTS_ARRAY(array)
Definition: internal.h:162
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
OFFSET
#define OFFSET(x)
Definition: vf_dctdnoiz.c:80
color_correlation_gbrp
static av_always_inline void color_correlation_gbrp(uint8_t **dst, int dst_linesize, float **src, int src_linesize, int w, int h)
Definition: vf_dctdnoiz.c:508
DCTdnoizContext::nb_threads
int nb_threads
Definition: vf_dctdnoiz.c:52
av_frame_free
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
Definition: frame.c:160
DEFAULT_NBITS
#define DEFAULT_NBITS
Definition: vf_dctdnoiz.c:78
AVFrame
This structure describes decoded (raw) audio or video data.
Definition: frame.h:374
w
uint8_t w
Definition: llviddspenc.c:38
AVOption
AVOption.
Definition: opt.h:346
b
#define b
Definition: input.c:41
DCTdnoizContext::step
int step
Definition: vf_dctdnoiz.c:61
AV_PIX_FMT_BGR24
@ AV_PIX_FMT_BGR24
packed RGB 8:8:8, 24bpp, BGRBGR...
Definition: pixfmt.h:76
FFMAX
#define FFMAX(a, b)
Definition: macros.h:47
AVFilter::name
const char * name
Filter name.
Definition: avfilter.h:170
video.h
DCTdnoizContext::color_correlation
void(* color_correlation)(uint8_t **dst, int dst_linesize, float **src, int src_linesize, int w, int h)
Definition: vf_dctdnoiz.c:71
ceilf
static __device__ float ceilf(float a)
Definition: cuda_runtime.h:175
AVFrame::data
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
Definition: frame.h:395
uninit
static av_cold void uninit(AVFilterContext *ctx)
Definition: vf_dctdnoiz.c:788
av_malloc
#define av_malloc(s)
Definition: tableprint_vlc.h:30
av_expr_parse
int av_expr_parse(AVExpr **expr, const char *s, const char *const *const_names, const char *const *func1_names, double(*const *funcs1)(void *, double), const char *const *func2_names, double(*const *funcs2)(void *, double, double), int log_offset, void *log_ctx)
Parse an expression.
Definition: eval.c:710
DCTdnoizContext::weights
float * weights
Definition: vf_dctdnoiz.c:58
rgb
Definition: rpzaenc.c:60
DCTdnoizContext::var_values
double var_values[MAX_THREADS][VAR_VARS_NB]
Definition: vf_dctdnoiz.c:50
config_input
static int config_input(AVFilterLink *inlink)
Definition: vf_dctdnoiz.c:535
DCTdnoizContext::filter_freq_func
void(* filter_freq_func)(struct DCTdnoizContext *s, const float *src, int src_linesize, float *dst, int dst_linesize, int thread_id)
Definition: vf_dctdnoiz.c:64
av_expr_free
void av_expr_free(AVExpr *e)
Free a parsed expression previously created with av_expr_parse().
Definition: eval.c:358
AVFilterPad
A filter pad used for either input or output.
Definition: internal.h:33
VAR_VARS_NB
@ VAR_VARS_NB
Definition: vf_dctdnoiz.c:40
avassert.h
AV_LOG_ERROR
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:180
av_cold
#define av_cold
Definition: attributes.h:90
filter_slice
static int filter_slice(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
Definition: vf_dctdnoiz.c:669
ff_video_default_filterpad
const AVFilterPad ff_video_default_filterpad[1]
An AVFilterPad array whose only entry has name "default" and is of type AVMEDIA_TYPE_VIDEO.
Definition: video.c:37
DCTdnoizContext::slices
float * slices[MAX_THREADS]
Definition: vf_dctdnoiz.c:57
VAR_C
@ VAR_C
Definition: vf_dctdnoiz.c:40
s
#define s(width, name)
Definition: cbs_vp9.c:198
filter_frame
static int filter_frame(AVFilterLink *inlink, AVFrame *in)
Definition: vf_dctdnoiz.c:717
DCT3X3_1_0
#define DCT3X3_1_0
Definition: vf_dctdnoiz.c:407
g
const char * g
Definition: vf_curves.c:128
slice_end
static int slice_end(AVCodecContext *avctx, AVFrame *pict)
Handle slice ends.
Definition: mpeg12dec.c:1730
ThreadData::src
float * src
Definition: vf_dctdnoiz.c:666
av_assert0
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Definition: avassert.h:40
AV_LOG_DEBUG
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Definition: log.h:201
DCT3X3_2_0
#define DCT3X3_2_0
Definition: vf_dctdnoiz.c:409
dctdnoiz_options
static const AVOption dctdnoiz_options[]
Definition: vf_dctdnoiz.c:82
ctx
AVFormatContext * ctx
Definition: movenc.c:49
color_decorrelation
static av_always_inline void color_decorrelation(float **dst, int dst_linesize, const uint8_t **src, int src_linesize, int w, int h, int r, int g, int b)
Definition: vf_dctdnoiz.c:413
AVExpr
Definition: eval.c:158
DCT3X3_1_2
#define DCT3X3_1_2
Definition: vf_dctdnoiz.c:408
FILTER_INPUTS
#define FILTER_INPUTS(array)
Definition: internal.h:182
arg
const char * arg
Definition: jacosubdec.c:67
ThreadData::dst
AVFrame * dst
Definition: vf_blend.c:57
AVClass
Describe the class of an AVClass context structure.
Definition: log.h:66
NULL
#define NULL
Definition: coverity.c:32
DCTdnoizContext::overlap
int overlap
Definition: vf_dctdnoiz.c:60
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:709
DCTdnoizContext::expr
AVExpr * expr[MAX_THREADS]
Definition: vf_dctdnoiz.c:49
DCTdnoizContext::sigma
float sigma
Definition: vf_dctdnoiz.c:54
MAX_THREADS
#define MAX_THREADS
Definition: vf_dctdnoiz.c:42
DCTdnoizContext::p_linesize
int p_linesize
Definition: vf_dctdnoiz.c:59
eval.h
f
f
Definition: af_crystalizer.c:121
AV_PIX_FMT_RGB24
@ AV_PIX_FMT_RGB24
packed RGB 8:8:8, 24bpp, RGBRGB...
Definition: pixfmt.h:75
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:94
var_names
static const char *const var_names[]
A simple, relatively efficient and slow DCT image denoiser.
Definition: vf_dctdnoiz.c:39
MAX_NBITS
#define MAX_NBITS
Definition: vf_dctdnoiz.c:77
av_frame_is_writable
int av_frame_is_writable(AVFrame *frame)
Check if the frame data is writable.
Definition: frame.c:645
DCTdnoizContext::color_decorrelation
void(* color_decorrelation)(float **dst, int dst_linesize, const uint8_t **src, int src_linesize, int w, int h)
Definition: vf_dctdnoiz.c:68
idct16_1d
static void av_always_inline idct16_1d(float *dst, const float *src, int dst_stridea, int dst_strideb, int src_stridea, int src_strideb, int add)
Definition: vf_dctdnoiz.c:260
DCT3X3_2_1
#define DCT3X3_2_1
Definition: vf_dctdnoiz.c:410
AVFILTER_DEFINE_CLASS
AVFILTER_DEFINE_CLASS(dctdnoiz)
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:147
AV_OPT_TYPE_FLOAT
@ AV_OPT_TYPE_FLOAT
Definition: opt.h:238
DEF_FILTER_FREQ_FUNCS
#define DEF_FILTER_FREQ_FUNCS(bsize)
Definition: vf_dctdnoiz.c:355
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:256
FFMIN3
#define FFMIN3(a, b, c)
Definition: macros.h:50
DCTdnoizContext::cbuf
float * cbuf[2][3]
Definition: vf_dctdnoiz.c:56
av_malloc_array
#define av_malloc_array(a, b)
Definition: tableprint_vlc.h:31
weights
static const int weights[]
Definition: hevc_pel.c: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:827
ThreadData
Used for passing data between threads.
Definition: dsddec.c:71
av_always_inline
#define av_always_inline
Definition: attributes.h:49
FFMIN
#define FFMIN(a, b)
Definition: macros.h:49
AVFilterPad::name
const char * name
Pad name.
Definition: internal.h:39
DCT3X3_0_1
#define DCT3X3_0_1
Definition: vf_dctdnoiz.c:405
av_calloc
void * av_calloc(size_t nmemb, size_t size)
Definition: mem.c:264
AVFilter
Filter definition.
Definition: avfilter.h:166
ff_vf_dctdnoiz
const AVFilter ff_vf_dctdnoiz
Definition: vf_dctdnoiz.c:814
pix_fmts
static enum AVPixelFormat pix_fmts[]
Definition: vf_dctdnoiz.c:659
ret
ret
Definition: filter_design.txt:187
dctdnoiz_inputs
static const AVFilterPad dctdnoiz_inputs[]
Definition: vf_dctdnoiz.c:805
color_decorrelation_gbrp
static av_always_inline void color_decorrelation_gbrp(float **dst, int dst_linesize, const uint8_t **src, int src_linesize, int w, int h)
Definition: vf_dctdnoiz.c:481
DCTdnoizContext::pr_width
int pr_width
Definition: vf_dctdnoiz.c:53
idct8_1d
static void av_always_inline idct8_1d(float *dst, const float *src, int dst_stridea, int dst_strideb, int src_stridea, int src_strideb, int add)
Definition: vf_dctdnoiz.c:132
MIN_NBITS
#define MIN_NBITS
Definition: vf_dctdnoiz.c:76
DECLARE_COLOR_FUNCS
#define DECLARE_COLOR_FUNCS(name, r, g, b)
Definition: vf_dctdnoiz.c:463
DCT3X3_2_2
#define DCT3X3_2_2
Definition: vf_dctdnoiz.c:411
AV_PIX_FMT_NONE
@ AV_PIX_FMT_NONE
Definition: pixfmt.h:72
AV_OPT_TYPE_INT
@ AV_OPT_TYPE_INT
Definition: opt.h:235
DCTdnoizContext::th
float th
Definition: vf_dctdnoiz.c:55
slice_start
static int slice_start(SliceContext *sc, VVCContext *s, VVCFrameContext *fc, const CodedBitstreamUnit *unit, const int is_first_slice)
Definition: dec.c:688
av_clip_uint8
#define av_clip_uint8
Definition: common.h:105
AVFilterContext
An instance of a filter.
Definition: avfilter.h:407
AV_PIX_FMT_GBRP
@ AV_PIX_FMT_GBRP
planar GBR 4:4:4 24bpp
Definition: pixfmt.h:165
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:117
AVMEDIA_TYPE_VIDEO
@ AVMEDIA_TYPE_VIDEO
Definition: avutil.h:201
mem.h
color_correlation
static av_always_inline void color_correlation(uint8_t **dst, int dst_linesize, float **src, int src_linesize, int w, int h, int r, int g, int b)
Definition: vf_dctdnoiz.c:438
DCTdnoizContext::n
int n
Definition: vf_dctdnoiz.c:62
DCTdnoizContext::expr_str
char * expr_str
Definition: vf_dctdnoiz.c:48
av_free
#define av_free(p)
Definition: tableprint_vlc.h:33
FFALIGN
#define FFALIGN(x, a)
Definition: macros.h:78
FILTER_OUTPUTS
#define FILTER_OUTPUTS(array)
Definition: internal.h:183
DCT3X3_0_2
#define DCT3X3_0_2
Definition: vf_dctdnoiz.c:406
av_freep
#define av_freep(p)
Definition: tableprint_vlc.h:34
src
INIT_CLIP pixel * src
Definition: h264pred_template.c:418
flags
#define flags(name, subs,...)
Definition: cbs_av1.c:474
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:419
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:27
h
h
Definition: vp9dsp_template.c:2038
AV_OPT_TYPE_STRING
@ AV_OPT_TYPE_STRING
Definition: opt.h:239
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:134
fdct8_1d
static void av_always_inline fdct8_1d(float *dst, const float *src, int dst_stridea, int dst_strideb, int src_stridea, int src_strideb)
Definition: vf_dctdnoiz.c:94
int
int
Definition: ffmpeg_filter.c:424
fdct16_1d
static void av_always_inline fdct16_1d(float *dst, const float *src, int dst_stridea, int dst_strideb, int src_stridea, int src_strideb)
Definition: vf_dctdnoiz.c:176
DCTdnoizContext::pr_height
int pr_height
Definition: vf_dctdnoiz.c:53