@@ -44,6 +44,7 @@ typedef struct ATADenoiseContext {
44
44
const AVClass * class ;
45
45
46
46
float fthra [4 ], fthrb [4 ];
47
+ float sigma [4 ];
47
48
int thra [4 ], thrb [4 ];
48
49
int algorithm ;
49
50
@@ -55,7 +56,8 @@ typedef struct ATADenoiseContext {
55
56
struct FFBufQueue q ;
56
57
void * data [4 ][SIZE ];
57
58
int linesize [4 ][SIZE ];
58
- int size , mid ;
59
+ float weights [4 ][SIZE ];
60
+ int size , mid , radius ;
59
61
int available ;
60
62
61
63
int (* filter_slice )(AVFilterContext * ctx , void * arg , int jobnr , int nb_jobs );
@@ -79,6 +81,9 @@ static const AVOption atadenoise_options[] = {
79
81
{ "a" , "set variant of algorithm" , OFFSET (algorithm ),AV_OPT_TYPE_INT , {.i64 = PARALLEL }, 0 , NB_ATAA - 1 , FLAGS , "a" },
80
82
{ "p" , "parallel" , 0 , AV_OPT_TYPE_CONST , {.i64 = PARALLEL }, 0 , 0 , FLAGS , "a" },
81
83
{ "s" , "serial" , 0 , AV_OPT_TYPE_CONST , {.i64 = SERIAL }, 0 , 0 , FLAGS , "a" },
84
+ { "0s" , "set sigma for 1st plane" , OFFSET (sigma [0 ]), AV_OPT_TYPE_FLOAT , {.dbl = INT16_MAX }, 0 , INT16_MAX , FLAGS },
85
+ { "1s" , "set sigma for 2nd plane" , OFFSET (sigma [1 ]), AV_OPT_TYPE_FLOAT , {.dbl = INT16_MAX }, 0 , INT16_MAX , FLAGS },
86
+ { "2s" , "set sigma for 3rd plane" , OFFSET (sigma [2 ]), AV_OPT_TYPE_FLOAT , {.dbl = INT16_MAX }, 0 , INT16_MAX , FLAGS },
82
87
{ NULL }
83
88
};
84
89
@@ -129,7 +134,8 @@ static av_cold int init(AVFilterContext *ctx)
129
134
av_log (ctx , AV_LOG_WARNING , "size %d is invalid. Must be an odd value, setting it to %d.\n" , s -> size , s -> size |1 );
130
135
s -> size |= 1 ;
131
136
}
132
- s -> mid = s -> size / 2 + 1 ;
137
+ s -> radius = s -> size / 2 ;
138
+ s -> mid = s -> radius + 1 ;
133
139
134
140
return 0 ;
135
141
}
@@ -138,11 +144,114 @@ typedef struct ThreadData {
138
144
AVFrame * in , * out ;
139
145
} ThreadData ;
140
146
147
+ #define WFILTER_ROW (type , name ) \
148
+ static void fweight_row##name(const uint8_t *ssrc, uint8_t *ddst, \
149
+ const uint8_t *ssrcf[SIZE], \
150
+ int w, int mid, int size, \
151
+ int thra, int thrb, const float *weights) \
152
+ { \
153
+ const type *src = (const type *)ssrc; \
154
+ const type **srcf = (const type **)ssrcf; \
155
+ type *dst = (type *)ddst; \
156
+ \
157
+ for (int x = 0; x < w; x++) { \
158
+ const int srcx = src[x]; \
159
+ unsigned lsumdiff = 0, rsumdiff = 0; \
160
+ unsigned ldiff, rdiff; \
161
+ float sum = srcx; \
162
+ float wsum = 1.f; \
163
+ int l = 0, r = 0; \
164
+ int srcjx, srcix; \
165
+ \
166
+ for (int j = mid - 1, i = mid + 1; j >= 0 && i < size; j--, i++) { \
167
+ srcjx = srcf[j][x]; \
168
+ \
169
+ ldiff = FFABS(srcx - srcjx); \
170
+ lsumdiff += ldiff; \
171
+ if (ldiff > thra || \
172
+ lsumdiff > thrb) \
173
+ break; \
174
+ l++; \
175
+ sum += srcjx * weights[j]; \
176
+ wsum += weights[j]; \
177
+ \
178
+ srcix = srcf[i][x]; \
179
+ \
180
+ rdiff = FFABS(srcx - srcix); \
181
+ rsumdiff += rdiff; \
182
+ if (rdiff > thra || \
183
+ rsumdiff > thrb) \
184
+ break; \
185
+ r++; \
186
+ sum += srcix * weights[i]; \
187
+ wsum += weights[i]; \
188
+ } \
189
+ \
190
+ dst[x] = lrintf(sum / wsum); \
191
+ } \
192
+ }
193
+
194
+ WFILTER_ROW (uint8_t , 8 )
195
+ WFILTER_ROW (uint16_t , 16 )
196
+
197
+ #define WFILTER_ROW_SERIAL (type , name ) \
198
+ static void fweight_row##name##_serial(const uint8_t *ssrc, uint8_t *ddst, \
199
+ const uint8_t *ssrcf[SIZE], \
200
+ int w, int mid, int size, \
201
+ int thra, int thrb, \
202
+ const float *weights) \
203
+ { \
204
+ const type *src = (const type *)ssrc; \
205
+ const type **srcf = (const type **)ssrcf; \
206
+ type *dst = (type *)ddst; \
207
+ \
208
+ for (int x = 0; x < w; x++) { \
209
+ const int srcx = src[x]; \
210
+ unsigned lsumdiff = 0, rsumdiff = 0; \
211
+ unsigned ldiff, rdiff; \
212
+ float sum = srcx; \
213
+ float wsum = 1.f; \
214
+ int l = 0, r = 0; \
215
+ int srcjx, srcix; \
216
+ \
217
+ for (int j = mid - 1; j >= 0; j--) { \
218
+ srcjx = srcf[j][x]; \
219
+ \
220
+ ldiff = FFABS(srcx - srcjx); \
221
+ lsumdiff += ldiff; \
222
+ if (ldiff > thra || \
223
+ lsumdiff > thrb) \
224
+ break; \
225
+ l++; \
226
+ sum += srcjx * weights[j]; \
227
+ wsum += weights[j]; \
228
+ } \
229
+ \
230
+ for (int i = mid + 1; i < size; i++) { \
231
+ srcix = srcf[i][x]; \
232
+ \
233
+ rdiff = FFABS(srcx - srcix); \
234
+ rsumdiff += rdiff; \
235
+ if (rdiff > thra || \
236
+ rsumdiff > thrb) \
237
+ break; \
238
+ r++; \
239
+ sum += srcix * weights[i]; \
240
+ wsum += weights[i]; \
241
+ } \
242
+ \
243
+ dst[x] = lrintf(sum / wsum); \
244
+ } \
245
+ }
246
+
247
+ WFILTER_ROW_SERIAL (uint8_t , 8 )
248
+ WFILTER_ROW_SERIAL (uint16_t , 16 )
249
+
141
250
#define FILTER_ROW (type , name ) \
142
251
static void filter_row##name(const uint8_t *ssrc, uint8_t *ddst, \
143
252
const uint8_t *ssrcf[SIZE], \
144
253
int w, int mid, int size, \
145
- int thra, int thrb) \
254
+ int thra, int thrb, const float *weights) \
146
255
{ \
147
256
const type *src = (const type *)ssrc; \
148
257
const type **srcf = (const type **)ssrcf; \
@@ -189,7 +298,8 @@ FILTER_ROW(uint16_t, 16)
189
298
static void filter_row##name##_serial(const uint8_t *ssrc, uint8_t *ddst, \
190
299
const uint8_t *ssrcf[SIZE], \
191
300
int w, int mid, int size, \
192
- int thra, int thrb) \
301
+ int thra, int thrb, \
302
+ const float *weights) \
193
303
{ \
194
304
const type *src = (const type *)ssrc; \
195
305
const type **srcf = (const type **)ssrcf; \
@@ -245,6 +355,7 @@ static int filter_slice(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
245
355
int p , y , i ;
246
356
247
357
for (p = 0 ; p < s -> nb_planes ; p ++ ) {
358
+ const float * weights = s -> weights [p ];
248
359
const int h = s -> planeheight [p ];
249
360
const int w = s -> planewidth [p ];
250
361
const int slice_start = (h * jobnr ) / nb_jobs ;
@@ -267,7 +378,7 @@ static int filter_slice(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
267
378
srcf [i ] = data [i ] + slice_start * linesize [i ];
268
379
269
380
for (y = slice_start ; y < slice_end ; y ++ ) {
270
- s -> dsp .filter_row (src , dst , srcf , w , mid , size , thra , thrb );
381
+ s -> dsp .filter_row [ p ] (src , dst , srcf , w , mid , size , thra , thrb , weights );
271
382
272
383
dst += out -> linesize [p ];
273
384
src += in -> linesize [p ];
@@ -296,10 +407,17 @@ static int config_input(AVFilterLink *inlink)
296
407
297
408
depth = desc -> comp [0 ].depth ;
298
409
s -> filter_slice = filter_slice ;
299
- if (depth == 8 )
300
- s -> dsp .filter_row = s -> algorithm == PARALLEL ? filter_row8 : filter_row8_serial ;
301
- else
302
- s -> dsp .filter_row = s -> algorithm == PARALLEL ? filter_row16 : filter_row16_serial ;
410
+
411
+ for (int p = 0 ; p < s -> nb_planes ; p ++ ) {
412
+ if (depth == 8 && s -> sigma [p ] == INT16_MAX )
413
+ s -> dsp .filter_row [p ] = s -> algorithm == PARALLEL ? filter_row8 : filter_row8_serial ;
414
+ else if (s -> sigma [p ] == INT16_MAX )
415
+ s -> dsp .filter_row [p ] = s -> algorithm == PARALLEL ? filter_row16 : filter_row16_serial ;
416
+ else if (depth == 8 && s -> sigma [p ] < INT16_MAX )
417
+ s -> dsp .filter_row [p ] = s -> algorithm == PARALLEL ? fweight_row8 : fweight_row8_serial ;
418
+ else if (s -> sigma [p ] < INT16_MAX )
419
+ s -> dsp .filter_row [p ] = s -> algorithm == PARALLEL ? fweight_row16 : fweight_row16_serial ;
420
+ }
303
421
304
422
s -> thra [0 ] = s -> fthra [0 ] * (1 << depth ) - 1 ;
305
423
s -> thra [1 ] = s -> fthra [1 ] * (1 << depth ) - 1 ;
@@ -308,8 +426,18 @@ static int config_input(AVFilterLink *inlink)
308
426
s -> thrb [1 ] = s -> fthrb [1 ] * (1 << depth ) - 1 ;
309
427
s -> thrb [2 ] = s -> fthrb [2 ] * (1 << depth ) - 1 ;
310
428
429
+ for (int p = 0 ; p < s -> nb_planes ; p ++ ) {
430
+ float sigma = s -> radius * s -> sigma [p ];
431
+
432
+ s -> weights [p ][s -> mid ] = 1.f ;
433
+ for (int n = 1 ; n <= s -> radius ; n ++ ) {
434
+ s -> weights [p ][s -> radius + n ] =
435
+ s -> weights [p ][s -> radius - n ] = expf (-0.5 * (n + 1 ) * (n + 1 ) / (sigma * sigma ));
436
+ }
437
+ }
438
+
311
439
if (ARCH_X86 )
312
- ff_atadenoise_init_x86 (& s -> dsp , depth , s -> algorithm );
440
+ ff_atadenoise_init_x86 (& s -> dsp , depth , s -> algorithm , s -> sigma );
313
441
314
442
return 0 ;
315
443
}
0 commit comments