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