FFmpeg coverage


Directory: ../../../ffmpeg/
File: src/libavfilter/af_adeclick.c
Date: 2024-04-18 10:05:09
Exec Total Coverage
Lines: 0 403 0.0%
Functions: 0 15 0.0%
Branches: 0 260 0.0%

Line Branch Exec Source
1 /*
2 * Copyright (c) 2018 Paul B Mahol
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 #include "libavutil/audio_fifo.h"
22 #include "libavutil/mem.h"
23 #include "libavutil/opt.h"
24 #include "libavutil/tx.h"
25 #include "avfilter.h"
26 #include "audio.h"
27 #include "filters.h"
28 #include "internal.h"
29
30 typedef struct DeclickChannel {
31 double *auxiliary;
32 double *detection;
33 double *acoefficients;
34 double *acorrelation;
35 double *tmp;
36 double *interpolated;
37 double *matrix;
38 int matrix_size;
39 double *vector;
40 int vector_size;
41 double *y;
42 int y_size;
43 uint8_t *click;
44 int *index;
45 unsigned *histogram;
46 int histogram_size;
47 } DeclickChannel;
48
49 typedef struct AudioDeclickContext {
50 const AVClass *class;
51
52 double w;
53 double overlap;
54 double threshold;
55 double ar;
56 double burst;
57 int method;
58 int nb_hbins;
59
60 int is_declip;
61 int ar_order;
62 int nb_burst_samples;
63 int window_size;
64 int hop_size;
65 int overlap_skip;
66
67 AVFrame *enabled;
68 AVFrame *in;
69 AVFrame *out;
70 AVFrame *buffer;
71 AVFrame *is;
72
73 DeclickChannel *chan;
74
75 int64_t pts;
76 int nb_channels;
77 uint64_t nb_samples;
78 uint64_t detected_errors;
79 int samples_left;
80 int eof;
81
82 AVAudioFifo *efifo;
83 AVAudioFifo *fifo;
84 double *window_func_lut;
85
86 int (*detector)(struct AudioDeclickContext *s, DeclickChannel *c,
87 double sigmae, double *detection,
88 double *acoefficients, uint8_t *click, int *index,
89 const double *src, double *dst);
90 } AudioDeclickContext;
91
92 #define OFFSET(x) offsetof(AudioDeclickContext, x)
93 #define AF AV_OPT_FLAG_AUDIO_PARAM|AV_OPT_FLAG_FILTERING_PARAM
94
95 static const AVOption adeclick_options[] = {
96 { "window", "set window size", OFFSET(w), AV_OPT_TYPE_DOUBLE, {.dbl=55}, 10, 100, AF },
97 { "w", "set window size", OFFSET(w), AV_OPT_TYPE_DOUBLE, {.dbl=55}, 10, 100, AF },
98 { "overlap", "set window overlap", OFFSET(overlap), AV_OPT_TYPE_DOUBLE, {.dbl=75}, 50, 95, AF },
99 { "o", "set window overlap", OFFSET(overlap), AV_OPT_TYPE_DOUBLE, {.dbl=75}, 50, 95, AF },
100 { "arorder", "set autoregression order", OFFSET(ar), AV_OPT_TYPE_DOUBLE, {.dbl=2}, 0, 25, AF },
101 { "a", "set autoregression order", OFFSET(ar), AV_OPT_TYPE_DOUBLE, {.dbl=2}, 0, 25, AF },
102 { "threshold", "set threshold", OFFSET(threshold), AV_OPT_TYPE_DOUBLE, {.dbl=2}, 1, 100, AF },
103 { "t", "set threshold", OFFSET(threshold), AV_OPT_TYPE_DOUBLE, {.dbl=2}, 1, 100, AF },
104 { "burst", "set burst fusion", OFFSET(burst), AV_OPT_TYPE_DOUBLE, {.dbl=2}, 0, 10, AF },
105 { "b", "set burst fusion", OFFSET(burst), AV_OPT_TYPE_DOUBLE, {.dbl=2}, 0, 10, AF },
106 { "method", "set overlap method", OFFSET(method), AV_OPT_TYPE_INT, {.i64=0}, 0, 1, AF, .unit = "m" },
107 { "m", "set overlap method", OFFSET(method), AV_OPT_TYPE_INT, {.i64=0}, 0, 1, AF, .unit = "m" },
108 { "add", "overlap-add", 0, AV_OPT_TYPE_CONST, {.i64=0}, 0, 0, AF, .unit = "m" },
109 { "a", "overlap-add", 0, AV_OPT_TYPE_CONST, {.i64=0}, 0, 0, AF, .unit = "m" },
110 { "save", "overlap-save", 0, AV_OPT_TYPE_CONST, {.i64=1}, 0, 0, AF, .unit = "m" },
111 { "s", "overlap-save", 0, AV_OPT_TYPE_CONST, {.i64=1}, 0, 0, AF, .unit = "m" },
112 { NULL }
113 };
114
115 AVFILTER_DEFINE_CLASS(adeclick);
116
117 static int config_input(AVFilterLink *inlink)
118 {
119 AVFilterContext *ctx = inlink->dst;
120 AudioDeclickContext *s = ctx->priv;
121 int i;
122
123 s->pts = AV_NOPTS_VALUE;
124 s->window_size = FFMAX(100, inlink->sample_rate * s->w / 1000.);
125 s->ar_order = FFMAX(s->window_size * s->ar / 100., 1);
126 s->nb_burst_samples = s->window_size * s->burst / 1000.;
127 s->hop_size = FFMAX(1, s->window_size * (1. - (s->overlap / 100.)));
128
129 s->window_func_lut = av_calloc(s->window_size, sizeof(*s->window_func_lut));
130 if (!s->window_func_lut)
131 return AVERROR(ENOMEM);
132
133 {
134 double *tx_in[2], *tx_out[2];
135 AVTXContext *tx, *itx;
136 av_tx_fn tx_fn, itx_fn;
137 int ret, tx_size;
138 double scale;
139
140 tx_size = 1 << (32 - ff_clz(s->window_size));
141
142 scale = 1.0;
143 ret = av_tx_init(&tx, &tx_fn, AV_TX_DOUBLE_RDFT, 0, tx_size, &scale, 0);
144 if (ret < 0)
145 return ret;
146
147 scale = 1.0 / tx_size;
148 ret = av_tx_init(&itx, &itx_fn, AV_TX_DOUBLE_RDFT, 1, tx_size, &scale, 0);
149 if (ret < 0)
150 return ret;
151
152 tx_in[0] = av_calloc(tx_size + 2, sizeof(*tx_in[0]));
153 tx_in[1] = av_calloc(tx_size + 2, sizeof(*tx_in[1]));
154 tx_out[0] = av_calloc(tx_size + 2, sizeof(*tx_out[0]));
155 tx_out[1] = av_calloc(tx_size + 2, sizeof(*tx_out[1]));
156 if (!tx_in[0] || !tx_in[1] || !tx_out[0] || !tx_out[1])
157 return AVERROR(ENOMEM);
158
159 for (int n = 0; n < s->window_size - s->hop_size; n++)
160 tx_in[0][n] = 1.0;
161
162 for (int n = 0; n < s->hop_size; n++)
163 tx_in[1][n] = 1.0;
164
165 tx_fn(tx, tx_out[0], tx_in[0], sizeof(double));
166 tx_fn(tx, tx_out[1], tx_in[1], sizeof(double));
167
168 for (int n = 0; n <= tx_size/2; n++) {
169 double re0 = tx_out[0][2*n];
170 double im0 = tx_out[0][2*n+1];
171 double re1 = tx_out[1][2*n];
172 double im1 = tx_out[1][2*n+1];
173
174 tx_in[0][2*n] = re0 * re1 - im0 * im1;
175 tx_in[0][2*n+1] = re0 * im1 + re1 * im0;
176 }
177
178 itx_fn(itx, tx_out[0], tx_in[0], sizeof(AVComplexDouble));
179
180 scale = 1.0 / (s->window_size - s->hop_size);
181 for (int n = 0; n < s->window_size; n++)
182 s->window_func_lut[n] = tx_out[0][n] * scale;
183
184 av_tx_uninit(&tx);
185 av_tx_uninit(&itx);
186
187 av_freep(&tx_in[0]);
188 av_freep(&tx_in[1]);
189 av_freep(&tx_out[0]);
190 av_freep(&tx_out[1]);
191 }
192
193 av_frame_free(&s->in);
194 av_frame_free(&s->out);
195 av_frame_free(&s->buffer);
196 av_frame_free(&s->is);
197 s->enabled = ff_get_audio_buffer(inlink, s->window_size);
198 s->in = ff_get_audio_buffer(inlink, s->window_size);
199 s->out = ff_get_audio_buffer(inlink, s->window_size);
200 s->buffer = ff_get_audio_buffer(inlink, s->window_size * 2);
201 s->is = ff_get_audio_buffer(inlink, s->window_size);
202 if (!s->in || !s->out || !s->buffer || !s->is || !s->enabled)
203 return AVERROR(ENOMEM);
204
205 s->efifo = av_audio_fifo_alloc(inlink->format, 1, s->window_size);
206 if (!s->efifo)
207 return AVERROR(ENOMEM);
208 s->fifo = av_audio_fifo_alloc(inlink->format, inlink->ch_layout.nb_channels, s->window_size);
209 if (!s->fifo)
210 return AVERROR(ENOMEM);
211 s->overlap_skip = s->method ? (s->window_size - s->hop_size) / 2 : 0;
212 if (s->overlap_skip > 0) {
213 av_audio_fifo_write(s->fifo, (void **)s->in->extended_data,
214 s->overlap_skip);
215 }
216
217 s->nb_channels = inlink->ch_layout.nb_channels;
218 s->chan = av_calloc(inlink->ch_layout.nb_channels, sizeof(*s->chan));
219 if (!s->chan)
220 return AVERROR(ENOMEM);
221
222 for (i = 0; i < inlink->ch_layout.nb_channels; i++) {
223 DeclickChannel *c = &s->chan[i];
224
225 c->detection = av_calloc(s->window_size, sizeof(*c->detection));
226 c->auxiliary = av_calloc(s->ar_order + 1, sizeof(*c->auxiliary));
227 c->acoefficients = av_calloc(s->ar_order + 1, sizeof(*c->acoefficients));
228 c->acorrelation = av_calloc(s->ar_order + 1, sizeof(*c->acorrelation));
229 c->tmp = av_calloc(s->ar_order, sizeof(*c->tmp));
230 c->click = av_calloc(s->window_size, sizeof(*c->click));
231 c->index = av_calloc(s->window_size, sizeof(*c->index));
232 c->interpolated = av_calloc(s->window_size, sizeof(*c->interpolated));
233 if (!c->auxiliary || !c->acoefficients || !c->detection || !c->click ||
234 !c->index || !c->interpolated || !c->acorrelation || !c->tmp)
235 return AVERROR(ENOMEM);
236 }
237
238 return 0;
239 }
240
241 static void autocorrelation(const double *input, int order, int size,
242 double *output, double scale)
243 {
244 int i, j;
245
246 for (i = 0; i <= order; i++) {
247 double value = 0.;
248
249 for (j = i; j < size; j++)
250 value += input[j] * input[j - i];
251
252 output[i] = value * scale;
253 }
254 }
255
256 static double autoregression(const double *samples, int ar_order,
257 int nb_samples, double *k, double *r, double *a)
258 {
259 double alpha;
260 int i, j;
261
262 memset(a, 0, ar_order * sizeof(*a));
263
264 autocorrelation(samples, ar_order, nb_samples, r, 1. / nb_samples);
265
266 /* Levinson-Durbin algorithm */
267 k[0] = a[0] = -r[1] / r[0];
268 alpha = r[0] * (1. - k[0] * k[0]);
269 for (i = 1; i < ar_order; i++) {
270 double epsilon = 0.;
271
272 for (j = 0; j < i; j++)
273 epsilon += a[j] * r[i - j];
274 epsilon += r[i + 1];
275
276 k[i] = -epsilon / alpha;
277 alpha *= (1. - k[i] * k[i]);
278 for (j = i - 1; j >= 0; j--)
279 k[j] = a[j] + k[i] * a[i - j - 1];
280 for (j = 0; j <= i; j++)
281 a[j] = k[j];
282 }
283
284 k[0] = 1.;
285 for (i = 1; i <= ar_order; i++)
286 k[i] = a[i - 1];
287
288 return sqrt(alpha);
289 }
290
291 static int isfinite_array(double *samples, int nb_samples)
292 {
293 int i;
294
295 for (i = 0; i < nb_samples; i++)
296 if (!isfinite(samples[i]))
297 return 0;
298
299 return 1;
300 }
301
302 static int find_index(int *index, int value, int size)
303 {
304 int i, start, end;
305
306 if ((value < index[0]) || (value > index[size - 1]))
307 return 1;
308
309 i = start = 0;
310 end = size - 1;
311
312 while (start <= end) {
313 i = (end + start) / 2;
314 if (index[i] == value)
315 return 0;
316 if (value < index[i])
317 end = i - 1;
318 if (value > index[i])
319 start = i + 1;
320 }
321
322 return 1;
323 }
324
325 static int factorization(double *matrix, int n)
326 {
327 int i, j, k;
328
329 for (i = 0; i < n; i++) {
330 const int in = i * n;
331 double value;
332
333 value = matrix[in + i];
334 for (j = 0; j < i; j++)
335 value -= matrix[j * n + j] * matrix[in + j] * matrix[in + j];
336
337 if (value == 0.) {
338 return -1;
339 }
340
341 matrix[in + i] = value;
342 for (j = i + 1; j < n; j++) {
343 const int jn = j * n;
344 double x;
345
346 x = matrix[jn + i];
347 for (k = 0; k < i; k++)
348 x -= matrix[k * n + k] * matrix[in + k] * matrix[jn + k];
349 matrix[jn + i] = x / matrix[in + i];
350 }
351 }
352
353 return 0;
354 }
355
356 static int do_interpolation(DeclickChannel *c, double *matrix,
357 double *vector, int n, double *out)
358 {
359 int i, j, ret;
360 double *y;
361
362 ret = factorization(matrix, n);
363 if (ret < 0)
364 return ret;
365
366 av_fast_malloc(&c->y, &c->y_size, n * sizeof(*c->y));
367 y = c->y;
368 if (!y)
369 return AVERROR(ENOMEM);
370
371 for (i = 0; i < n; i++) {
372 const int in = i * n;
373 double value;
374
375 value = vector[i];
376 for (j = 0; j < i; j++)
377 value -= matrix[in + j] * y[j];
378 y[i] = value;
379 }
380
381 for (i = n - 1; i >= 0; i--) {
382 out[i] = y[i] / matrix[i * n + i];
383 for (j = i + 1; j < n; j++)
384 out[i] -= matrix[j * n + i] * out[j];
385 }
386
387 return 0;
388 }
389
390 static int interpolation(DeclickChannel *c, const double *src, int ar_order,
391 double *acoefficients, int *index, int nb_errors,
392 double *auxiliary, double *interpolated)
393 {
394 double *vector, *matrix;
395 int i, j;
396
397 av_fast_malloc(&c->matrix, &c->matrix_size, nb_errors * nb_errors * sizeof(*c->matrix));
398 matrix = c->matrix;
399 if (!matrix)
400 return AVERROR(ENOMEM);
401
402 av_fast_malloc(&c->vector, &c->vector_size, nb_errors * sizeof(*c->vector));
403 vector = c->vector;
404 if (!vector)
405 return AVERROR(ENOMEM);
406
407 autocorrelation(acoefficients, ar_order, ar_order + 1, auxiliary, 1.);
408
409 for (i = 0; i < nb_errors; i++) {
410 const int im = i * nb_errors;
411
412 for (j = i; j < nb_errors; j++) {
413 if (abs(index[j] - index[i]) <= ar_order) {
414 matrix[j * nb_errors + i] = matrix[im + j] = auxiliary[abs(index[j] - index[i])];
415 } else {
416 matrix[j * nb_errors + i] = matrix[im + j] = 0;
417 }
418 }
419 }
420
421 for (i = 0; i < nb_errors; i++) {
422 double value = 0.;
423
424 for (j = -ar_order; j <= ar_order; j++)
425 if (find_index(index, index[i] - j, nb_errors))
426 value -= src[index[i] - j] * auxiliary[abs(j)];
427
428 vector[i] = value;
429 }
430
431 return do_interpolation(c, matrix, vector, nb_errors, interpolated);
432 }
433
434 static int detect_clips(AudioDeclickContext *s, DeclickChannel *c,
435 double unused0,
436 double *unused1, double *unused2,
437 uint8_t *clip, int *index,
438 const double *src, double *dst)
439 {
440 const double threshold = s->threshold;
441 double max_amplitude = 0;
442 unsigned *histogram;
443 int i, nb_clips = 0;
444
445 av_fast_malloc(&c->histogram, &c->histogram_size, s->nb_hbins * sizeof(*c->histogram));
446 if (!c->histogram)
447 return AVERROR(ENOMEM);
448 histogram = c->histogram;
449 memset(histogram, 0, sizeof(*histogram) * s->nb_hbins);
450
451 for (i = 0; i < s->window_size; i++) {
452 const unsigned index = fmin(fabs(src[i]), 1) * (s->nb_hbins - 1);
453
454 histogram[index]++;
455 dst[i] = src[i];
456 clip[i] = 0;
457 }
458
459 for (i = s->nb_hbins - 1; i > 1; i--) {
460 if (histogram[i]) {
461 if (histogram[i] / (double)FFMAX(histogram[i - 1], 1) > threshold) {
462 max_amplitude = i / (double)s->nb_hbins;
463 }
464 break;
465 }
466 }
467
468 if (max_amplitude > 0.) {
469 for (i = 0; i < s->window_size; i++) {
470 clip[i] = fabs(src[i]) >= max_amplitude;
471 }
472 }
473
474 memset(clip, 0, s->ar_order * sizeof(*clip));
475 memset(clip + (s->window_size - s->ar_order), 0, s->ar_order * sizeof(*clip));
476
477 for (i = s->ar_order; i < s->window_size - s->ar_order; i++)
478 if (clip[i])
479 index[nb_clips++] = i;
480
481 return nb_clips;
482 }
483
484 static int detect_clicks(AudioDeclickContext *s, DeclickChannel *c,
485 double sigmae,
486 double *detection, double *acoefficients,
487 uint8_t *click, int *index,
488 const double *src, double *dst)
489 {
490 const double threshold = s->threshold;
491 int i, j, nb_clicks = 0, prev = -1;
492
493 memset(detection, 0, s->window_size * sizeof(*detection));
494
495 for (i = s->ar_order; i < s->window_size; i++) {
496 for (j = 0; j <= s->ar_order; j++) {
497 detection[i] += acoefficients[j] * src[i - j];
498 }
499 }
500
501 for (i = 0; i < s->window_size; i++) {
502 click[i] = fabs(detection[i]) > sigmae * threshold;
503 dst[i] = src[i];
504 }
505
506 for (i = 0; i < s->window_size; i++) {
507 if (!click[i])
508 continue;
509
510 if (prev >= 0 && (i > prev + 1) && (i <= s->nb_burst_samples + prev))
511 for (j = prev + 1; j < i; j++)
512 click[j] = 1;
513 prev = i;
514 }
515
516 memset(click, 0, s->ar_order * sizeof(*click));
517 memset(click + (s->window_size - s->ar_order), 0, s->ar_order * sizeof(*click));
518
519 for (i = s->ar_order; i < s->window_size - s->ar_order; i++)
520 if (click[i])
521 index[nb_clicks++] = i;
522
523 return nb_clicks;
524 }
525
526 typedef struct ThreadData {
527 AVFrame *out;
528 } ThreadData;
529
530 static int filter_channel(AVFilterContext *ctx, void *arg, int ch, int nb_jobs)
531 {
532 AudioDeclickContext *s = ctx->priv;
533 ThreadData *td = arg;
534 AVFrame *out = td->out;
535 const double *src = (const double *)s->in->extended_data[ch];
536 double *is = (double *)s->is->extended_data[ch];
537 double *dst = (double *)s->out->extended_data[ch];
538 double *ptr = (double *)out->extended_data[ch];
539 double *buf = (double *)s->buffer->extended_data[ch];
540 const double *w = s->window_func_lut;
541 DeclickChannel *c = &s->chan[ch];
542 double sigmae;
543 int j, ret;
544
545 sigmae = autoregression(src, s->ar_order, s->window_size, c->acoefficients, c->acorrelation, c->tmp);
546
547 if (isfinite_array(c->acoefficients, s->ar_order + 1)) {
548 double *interpolated = c->interpolated;
549 int *index = c->index;
550 int nb_errors;
551
552 nb_errors = s->detector(s, c, sigmae, c->detection, c->acoefficients,
553 c->click, index, src, dst);
554 if (nb_errors > 0) {
555 double *enabled = (double *)s->enabled->extended_data[0];
556
557 ret = interpolation(c, src, s->ar_order, c->acoefficients, index,
558 nb_errors, c->auxiliary, interpolated);
559 if (ret < 0)
560 return ret;
561
562 av_audio_fifo_peek(s->efifo, (void**)s->enabled->extended_data, s->window_size);
563
564 for (j = 0; j < nb_errors; j++) {
565 if (enabled[index[j]]) {
566 dst[index[j]] = interpolated[j];
567 is[index[j]] = 1;
568 }
569 }
570 }
571 } else {
572 memcpy(dst, src, s->window_size * sizeof(*dst));
573 }
574
575 if (s->method == 0) {
576 for (j = 0; j < s->window_size; j++)
577 buf[j] += dst[j] * w[j];
578 } else {
579 const int skip = s->overlap_skip;
580
581 for (j = 0; j < s->hop_size; j++)
582 buf[j] = dst[skip + j];
583 }
584 for (j = 0; j < s->hop_size; j++)
585 ptr[j] = buf[j];
586
587 memmove(buf, buf + s->hop_size, (s->window_size * 2 - s->hop_size) * sizeof(*buf));
588 memmove(is, is + s->hop_size, (s->window_size - s->hop_size) * sizeof(*is));
589 memset(buf + s->window_size * 2 - s->hop_size, 0, s->hop_size * sizeof(*buf));
590 memset(is + s->window_size - s->hop_size, 0, s->hop_size * sizeof(*is));
591
592 return 0;
593 }
594
595 static int filter_frame(AVFilterLink *inlink)
596 {
597 AVFilterContext *ctx = inlink->dst;
598 AVFilterLink *outlink = ctx->outputs[0];
599 AudioDeclickContext *s = ctx->priv;
600 AVFrame *out = NULL;
601 int ret = 0, j, ch, detected_errors = 0;
602 ThreadData td;
603
604 out = ff_get_audio_buffer(outlink, s->hop_size);
605 if (!out)
606 return AVERROR(ENOMEM);
607
608 ret = av_audio_fifo_peek(s->fifo, (void **)s->in->extended_data,
609 s->window_size);
610 if (ret < 0)
611 goto fail;
612
613 td.out = out;
614 ret = ff_filter_execute(ctx, filter_channel, &td, NULL, inlink->ch_layout.nb_channels);
615 if (ret < 0)
616 goto fail;
617
618 for (ch = 0; ch < s->in->ch_layout.nb_channels; ch++) {
619 double *is = (double *)s->is->extended_data[ch];
620
621 for (j = 0; j < s->hop_size; j++) {
622 if (is[j])
623 detected_errors++;
624 }
625 }
626
627 av_audio_fifo_drain(s->fifo, s->hop_size);
628 av_audio_fifo_drain(s->efifo, s->hop_size);
629
630 if (s->samples_left > 0)
631 out->nb_samples = FFMIN(s->hop_size, s->samples_left);
632
633 out->pts = s->pts;
634 s->pts += av_rescale_q(s->hop_size, (AVRational){1, outlink->sample_rate}, outlink->time_base);
635
636 s->detected_errors += detected_errors;
637 s->nb_samples += out->nb_samples * inlink->ch_layout.nb_channels;
638
639 ret = ff_filter_frame(outlink, out);
640 if (ret < 0)
641 return ret;
642
643 if (s->samples_left > 0) {
644 s->samples_left -= s->hop_size;
645 if (s->samples_left <= 0)
646 av_audio_fifo_drain(s->fifo, av_audio_fifo_size(s->fifo));
647 }
648
649 fail:
650 if (ret < 0)
651 av_frame_free(&out);
652 return ret;
653 }
654
655 static int activate(AVFilterContext *ctx)
656 {
657 AVFilterLink *inlink = ctx->inputs[0];
658 AVFilterLink *outlink = ctx->outputs[0];
659 AudioDeclickContext *s = ctx->priv;
660 AVFrame *in;
661 int ret, status;
662 int64_t pts;
663
664 FF_FILTER_FORWARD_STATUS_BACK(outlink, inlink);
665
666 ret = ff_inlink_consume_samples(inlink, s->window_size, s->window_size, &in);
667 if (ret < 0)
668 return ret;
669 if (ret > 0) {
670 double *e = (double *)s->enabled->extended_data[0];
671
672 if (s->pts == AV_NOPTS_VALUE)
673 s->pts = in->pts;
674
675 ret = av_audio_fifo_write(s->fifo, (void **)in->extended_data,
676 in->nb_samples);
677 for (int i = 0; i < in->nb_samples; i++)
678 e[i] = !ctx->is_disabled;
679
680 av_audio_fifo_write(s->efifo, (void**)s->enabled->extended_data, in->nb_samples);
681 av_frame_free(&in);
682 if (ret < 0)
683 return ret;
684 }
685
686 if (av_audio_fifo_size(s->fifo) >= s->window_size ||
687 s->samples_left > 0)
688 return filter_frame(inlink);
689
690 if (av_audio_fifo_size(s->fifo) >= s->window_size) {
691 ff_filter_set_ready(ctx, 100);
692 return 0;
693 }
694
695 if (!s->eof && ff_inlink_acknowledge_status(inlink, &status, &pts)) {
696 if (status == AVERROR_EOF) {
697 s->eof = 1;
698 s->samples_left = av_audio_fifo_size(s->fifo) - s->overlap_skip;
699 ff_filter_set_ready(ctx, 100);
700 return 0;
701 }
702 }
703
704 if (s->eof && s->samples_left <= 0) {
705 ff_outlink_set_status(outlink, AVERROR_EOF, s->pts);
706 return 0;
707 }
708
709 if (!s->eof)
710 FF_FILTER_FORWARD_WANTED(outlink, inlink);
711
712 return FFERROR_NOT_READY;
713 }
714
715 static av_cold int init(AVFilterContext *ctx)
716 {
717 AudioDeclickContext *s = ctx->priv;
718
719 s->is_declip = !strcmp(ctx->filter->name, "adeclip");
720 if (s->is_declip) {
721 s->detector = detect_clips;
722 } else {
723 s->detector = detect_clicks;
724 }
725
726 return 0;
727 }
728
729 static av_cold void uninit(AVFilterContext *ctx)
730 {
731 AudioDeclickContext *s = ctx->priv;
732 int i;
733
734 if (s->nb_samples > 0)
735 av_log(ctx, AV_LOG_INFO, "Detected %s in %"PRId64" of %"PRId64" samples (%g%%).\n",
736 s->is_declip ? "clips" : "clicks", s->detected_errors,
737 s->nb_samples, 100. * s->detected_errors / s->nb_samples);
738
739 av_audio_fifo_free(s->fifo);
740 av_audio_fifo_free(s->efifo);
741 av_freep(&s->window_func_lut);
742 av_frame_free(&s->enabled);
743 av_frame_free(&s->in);
744 av_frame_free(&s->out);
745 av_frame_free(&s->buffer);
746 av_frame_free(&s->is);
747
748 if (s->chan) {
749 for (i = 0; i < s->nb_channels; i++) {
750 DeclickChannel *c = &s->chan[i];
751
752 av_freep(&c->detection);
753 av_freep(&c->auxiliary);
754 av_freep(&c->acoefficients);
755 av_freep(&c->acorrelation);
756 av_freep(&c->tmp);
757 av_freep(&c->click);
758 av_freep(&c->index);
759 av_freep(&c->interpolated);
760 av_freep(&c->matrix);
761 c->matrix_size = 0;
762 av_freep(&c->histogram);
763 c->histogram_size = 0;
764 av_freep(&c->vector);
765 c->vector_size = 0;
766 av_freep(&c->y);
767 c->y_size = 0;
768 }
769 }
770 av_freep(&s->chan);
771 s->nb_channels = 0;
772 }
773
774 static const AVFilterPad inputs[] = {
775 {
776 .name = "default",
777 .type = AVMEDIA_TYPE_AUDIO,
778 .config_props = config_input,
779 },
780 };
781
782 const AVFilter ff_af_adeclick = {
783 .name = "adeclick",
784 .description = NULL_IF_CONFIG_SMALL("Remove impulsive noise from input audio."),
785 .priv_size = sizeof(AudioDeclickContext),
786 .priv_class = &adeclick_class,
787 .init = init,
788 .activate = activate,
789 .uninit = uninit,
790 FILTER_INPUTS(inputs),
791 FILTER_OUTPUTS(ff_audio_default_filterpad),
792 FILTER_SINGLE_SAMPLEFMT(AV_SAMPLE_FMT_DBLP),
793 .flags = AVFILTER_FLAG_SLICE_THREADS | AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL,
794 };
795
796 static const AVOption adeclip_options[] = {
797 { "window", "set window size", OFFSET(w), AV_OPT_TYPE_DOUBLE, {.dbl=55}, 10, 100, AF },
798 { "w", "set window size", OFFSET(w), AV_OPT_TYPE_DOUBLE, {.dbl=55}, 10, 100, AF },
799 { "overlap", "set window overlap", OFFSET(overlap), AV_OPT_TYPE_DOUBLE, {.dbl=75}, 50, 95, AF },
800 { "o", "set window overlap", OFFSET(overlap), AV_OPT_TYPE_DOUBLE, {.dbl=75}, 50, 95, AF },
801 { "arorder", "set autoregression order", OFFSET(ar), AV_OPT_TYPE_DOUBLE, {.dbl=8}, 0, 25, AF },
802 { "a", "set autoregression order", OFFSET(ar), AV_OPT_TYPE_DOUBLE, {.dbl=8}, 0, 25, AF },
803 { "threshold", "set threshold", OFFSET(threshold), AV_OPT_TYPE_DOUBLE, {.dbl=10}, 1, 100, AF },
804 { "t", "set threshold", OFFSET(threshold), AV_OPT_TYPE_DOUBLE, {.dbl=10}, 1, 100, AF },
805 { "hsize", "set histogram size", OFFSET(nb_hbins), AV_OPT_TYPE_INT, {.i64=1000}, 100, 9999, AF },
806 { "n", "set histogram size", OFFSET(nb_hbins), AV_OPT_TYPE_INT, {.i64=1000}, 100, 9999, AF },
807 { "method", "set overlap method", OFFSET(method), AV_OPT_TYPE_INT, {.i64=0}, 0, 1, AF, .unit = "m" },
808 { "m", "set overlap method", OFFSET(method), AV_OPT_TYPE_INT, {.i64=0}, 0, 1, AF, .unit = "m" },
809 { "add", "overlap-add", 0, AV_OPT_TYPE_CONST, {.i64=0}, 0, 0, AF, .unit = "m" },
810 { "a", "overlap-add", 0, AV_OPT_TYPE_CONST, {.i64=0}, 0, 0, AF, .unit = "m" },
811 { "save", "overlap-save", 0, AV_OPT_TYPE_CONST, {.i64=1}, 0, 0, AF, .unit = "m" },
812 { "s", "overlap-save", 0, AV_OPT_TYPE_CONST, {.i64=1}, 0, 0, AF, .unit = "m" },
813 { NULL }
814 };
815
816 AVFILTER_DEFINE_CLASS(adeclip);
817
818 const AVFilter ff_af_adeclip = {
819 .name = "adeclip",
820 .description = NULL_IF_CONFIG_SMALL("Remove clipping from input audio."),
821 .priv_size = sizeof(AudioDeclickContext),
822 .priv_class = &adeclip_class,
823 .init = init,
824 .activate = activate,
825 .uninit = uninit,
826 FILTER_INPUTS(inputs),
827 FILTER_OUTPUTS(ff_audio_default_filterpad),
828 FILTER_SINGLE_SAMPLEFMT(AV_SAMPLE_FMT_DBLP),
829 .flags = AVFILTER_FLAG_SLICE_THREADS | AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL,
830 };
831