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