]> git.sesse.net Git - ffmpeg/blobdiff - libavfilter/af_adeclick.c
avfilter: Constify all AVFilters
[ffmpeg] / libavfilter / af_adeclick.c
index 50eef7492181f2bfe62ea78fbf742a665dddf416..798838f522cb5f0f90b376bf6fef5cd39c956bb7 100644 (file)
@@ -63,6 +63,7 @@ typedef struct AudioDeclickContext {
     int hop_size;
     int overlap_skip;
 
+    AVFrame *enabled;
     AVFrame *in;
     AVFrame *out;
     AVFrame *buffer;
@@ -77,6 +78,7 @@ typedef struct AudioDeclickContext {
     int samples_left;
     int eof;
 
+    AVAudioFifo *efifo;
     AVAudioFifo *fifo;
     double *window_func_lut;
 
@@ -90,13 +92,21 @@ typedef struct AudioDeclickContext {
 #define AF AV_OPT_FLAG_AUDIO_PARAM|AV_OPT_FLAG_FILTERING_PARAM
 
 static const AVOption adeclick_options[] = {
+    { "window", "set window size",     OFFSET(w),         AV_OPT_TYPE_DOUBLE, {.dbl=55}, 10,  100, AF },
     { "w", "set window size",          OFFSET(w),         AV_OPT_TYPE_DOUBLE, {.dbl=55}, 10,  100, AF },
+    { "overlap", "set window overlap", OFFSET(overlap),   AV_OPT_TYPE_DOUBLE, {.dbl=75}, 50,   95, AF },
     { "o", "set window overlap",       OFFSET(overlap),   AV_OPT_TYPE_DOUBLE, {.dbl=75}, 50,   95, AF },
+    { "arorder", "set autoregression order", OFFSET(ar),  AV_OPT_TYPE_DOUBLE, {.dbl=2},   0,   25, AF },
     { "a", "set autoregression order", OFFSET(ar),        AV_OPT_TYPE_DOUBLE, {.dbl=2},   0,   25, AF },
+    { "threshold", "set threshold",    OFFSET(threshold), AV_OPT_TYPE_DOUBLE, {.dbl=2},   1,  100, AF },
     { "t", "set threshold",            OFFSET(threshold), AV_OPT_TYPE_DOUBLE, {.dbl=2},   1,  100, AF },
+    { "burst", "set burst fusion",     OFFSET(burst),     AV_OPT_TYPE_DOUBLE, {.dbl=2},   0,   10, AF },
     { "b", "set burst fusion",         OFFSET(burst),     AV_OPT_TYPE_DOUBLE, {.dbl=2},   0,   10, AF },
+    { "method", "set overlap method",  OFFSET(method),    AV_OPT_TYPE_INT,    {.i64=0},   0,    1, AF, "m" },
     { "m", "set overlap method",       OFFSET(method),    AV_OPT_TYPE_INT,    {.i64=0},   0,    1, AF, "m" },
+    { "add", "overlap-add",            0,                 AV_OPT_TYPE_CONST,  {.i64=0},   0,    0, AF, "m" },
     { "a", "overlap-add",              0,                 AV_OPT_TYPE_CONST,  {.i64=0},   0,    0, AF, "m" },
+    { "save", "overlap-save",          0,                 AV_OPT_TYPE_CONST,  {.i64=1},   0,    0, AF, "m" },
     { "s", "overlap-save",             0,                 AV_OPT_TYPE_CONST,  {.i64=1},   0,    0, AF, "m" },
     { NULL }
 };
@@ -159,13 +169,17 @@ static int config_input(AVFilterLink *inlink)
     av_frame_free(&s->out);
     av_frame_free(&s->buffer);
     av_frame_free(&s->is);
+    s->enabled = ff_get_audio_buffer(inlink, s->window_size);
     s->in = ff_get_audio_buffer(inlink, s->window_size);
     s->out = ff_get_audio_buffer(inlink, s->window_size);
     s->buffer = ff_get_audio_buffer(inlink, s->window_size * 2);
     s->is = ff_get_audio_buffer(inlink, s->window_size);
-    if (!s->in || !s->out || !s->buffer || !s->is)
+    if (!s->in || !s->out || !s->buffer || !s->is || !s->enabled)
         return AVERROR(ENOMEM);
 
+    s->efifo = av_audio_fifo_alloc(inlink->format, 1, s->window_size);
+    if (!s->efifo)
+        return AVERROR(ENOMEM);
     s->fifo = av_audio_fifo_alloc(inlink->format, inlink->channels, s->window_size);
     if (!s->fifo)
         return AVERROR(ENOMEM);
@@ -513,14 +527,20 @@ static int filter_channel(AVFilterContext *ctx, void *arg, int ch, int nb_jobs)
         nb_errors = s->detector(s, c, sigmae, c->detection, c->acoefficients,
                                 c->click, index, src, dst);
         if (nb_errors > 0) {
+            double *enabled = (double *)s->enabled->extended_data[0];
+
             ret = interpolation(c, src, s->ar_order, c->acoefficients, index,
                                 nb_errors, c->auxiliary, interpolated);
             if (ret < 0)
                 return ret;
 
+            av_audio_fifo_peek(s->efifo, (void**)s->enabled->extended_data, s->window_size);
+
             for (j = 0; j < nb_errors; j++) {
-                dst[index[j]] = interpolated[j];
-                is[index[j]] = 1;
+                if (enabled[index[j]]) {
+                    dst[index[j]] = interpolated[j];
+                    is[index[j]] = 1;
+                }
             }
         }
     } else {
@@ -580,19 +600,20 @@ static int filter_frame(AVFilterLink *inlink)
     }
 
     av_audio_fifo_drain(s->fifo, s->hop_size);
+    av_audio_fifo_drain(s->efifo, s->hop_size);
 
     if (s->samples_left > 0)
         out->nb_samples = FFMIN(s->hop_size, s->samples_left);
 
     out->pts = s->pts;
-    s->pts += s->hop_size;
+    s->pts += av_rescale_q(s->hop_size, (AVRational){1, outlink->sample_rate}, outlink->time_base);
 
     s->detected_errors += detected_errors;
     s->nb_samples += out->nb_samples * inlink->channels;
 
     ret = ff_filter_frame(outlink, out);
     if (ret < 0)
-        goto fail;
+        return ret;
 
     if (s->samples_left > 0) {
         s->samples_left -= s->hop_size;
@@ -621,11 +642,17 @@ static int activate(AVFilterContext *ctx)
     if (ret < 0)
         return ret;
     if (ret > 0) {
+        double *e = (double *)s->enabled->extended_data[0];
+
         if (s->pts == AV_NOPTS_VALUE)
             s->pts = in->pts;
 
         ret = av_audio_fifo_write(s->fifo, (void **)in->extended_data,
                                   in->nb_samples);
+        for (int i = 0; i < in->nb_samples; i++)
+            e[i] = !ctx->is_disabled;
+
+        av_audio_fifo_write(s->efifo, (void**)s->enabled->extended_data, in->nb_samples);
         av_frame_free(&in);
         if (ret < 0)
             return ret;
@@ -684,7 +711,9 @@ static av_cold void uninit(AVFilterContext *ctx)
            s->nb_samples, 100. * s->detected_errors / s->nb_samples);
 
     av_audio_fifo_free(s->fifo);
+    av_audio_fifo_free(s->efifo);
     av_freep(&s->window_func_lut);
+    av_frame_free(&s->enabled);
     av_frame_free(&s->in);
     av_frame_free(&s->out);
     av_frame_free(&s->buffer);
@@ -733,7 +762,7 @@ static const AVFilterPad outputs[] = {
     { NULL }
 };
 
-AVFilter ff_af_adeclick = {
+const AVFilter ff_af_adeclick = {
     .name          = "adeclick",
     .description   = NULL_IF_CONFIG_SMALL("Remove impulsive noise from input audio."),
     .query_formats = query_formats,
@@ -744,24 +773,32 @@ AVFilter ff_af_adeclick = {
     .uninit        = uninit,
     .inputs        = inputs,
     .outputs       = outputs,
-    .flags         = AVFILTER_FLAG_SLICE_THREADS,
+    .flags         = AVFILTER_FLAG_SLICE_THREADS | AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL,
 };
 
 static const AVOption adeclip_options[] = {
-    { "w", "set window size",          OFFSET(w),              AV_OPT_TYPE_DOUBLE, {.dbl=55},     10,  100, AF },
-    { "o", "set window overlap",       OFFSET(overlap),        AV_OPT_TYPE_DOUBLE, {.dbl=75},     50,   95, AF },
-    { "a", "set autoregression order", OFFSET(ar),             AV_OPT_TYPE_DOUBLE, {.dbl=8},       0,   25, AF },
-    { "t", "set threshold",            OFFSET(threshold),      AV_OPT_TYPE_DOUBLE, {.dbl=10},      1,  100, AF },
-    { "n", "set histogram size",       OFFSET(nb_hbins),       AV_OPT_TYPE_INT,    {.i64=1000},  100, 9999, AF },
-    { "m", "set overlap method",       OFFSET(method),         AV_OPT_TYPE_INT,    {.i64=0},       0,    1, AF, "m" },
-    { "a", "overlap-add",              0,                      AV_OPT_TYPE_CONST,  {.i64=0},       0,    0, AF, "m" },
-    { "s", "overlap-save",             0,                      AV_OPT_TYPE_CONST,  {.i64=1},       0,    0, AF, "m" },
+    { "window", "set window size",     OFFSET(w),         AV_OPT_TYPE_DOUBLE, {.dbl=55},     10,  100, AF },
+    { "w", "set window size",          OFFSET(w),         AV_OPT_TYPE_DOUBLE, {.dbl=55},     10,  100, AF },
+    { "overlap", "set window overlap", OFFSET(overlap),   AV_OPT_TYPE_DOUBLE, {.dbl=75},     50,   95, AF },
+    { "o", "set window overlap",       OFFSET(overlap),   AV_OPT_TYPE_DOUBLE, {.dbl=75},     50,   95, AF },
+    { "arorder", "set autoregression order", OFFSET(ar),  AV_OPT_TYPE_DOUBLE, {.dbl=8},       0,   25, AF },
+    { "a", "set autoregression order", OFFSET(ar),        AV_OPT_TYPE_DOUBLE, {.dbl=8},       0,   25, AF },
+    { "threshold", "set threshold",    OFFSET(threshold), AV_OPT_TYPE_DOUBLE, {.dbl=10},      1,  100, AF },
+    { "t", "set threshold",            OFFSET(threshold), AV_OPT_TYPE_DOUBLE, {.dbl=10},      1,  100, AF },
+    { "hsize", "set histogram size",   OFFSET(nb_hbins),  AV_OPT_TYPE_INT,    {.i64=1000},  100, 9999, AF },
+    { "n", "set histogram size",       OFFSET(nb_hbins),  AV_OPT_TYPE_INT,    {.i64=1000},  100, 9999, AF },
+    { "method", "set overlap method",  OFFSET(method),    AV_OPT_TYPE_INT,    {.i64=0},       0,    1, AF, "m" },
+    { "m", "set overlap method",       OFFSET(method),    AV_OPT_TYPE_INT,    {.i64=0},       0,    1, AF, "m" },
+    { "add", "overlap-add",            0,                 AV_OPT_TYPE_CONST,  {.i64=0},       0,    0, AF, "m" },
+    { "a", "overlap-add",              0,                 AV_OPT_TYPE_CONST,  {.i64=0},       0,    0, AF, "m" },
+    { "save", "overlap-save",          0,                 AV_OPT_TYPE_CONST,  {.i64=1},       0,    0, AF, "m" },
+    { "s", "overlap-save",             0,                 AV_OPT_TYPE_CONST,  {.i64=1},       0,    0, AF, "m" },
     { NULL }
 };
 
 AVFILTER_DEFINE_CLASS(adeclip);
 
-AVFilter ff_af_adeclip = {
+const AVFilter ff_af_adeclip = {
     .name          = "adeclip",
     .description   = NULL_IF_CONFIG_SMALL("Remove clipping from input audio."),
     .query_formats = query_formats,
@@ -772,5 +809,5 @@ AVFilter ff_af_adeclip = {
     .uninit        = uninit,
     .inputs        = inputs,
     .outputs       = outputs,
-    .flags         = AVFILTER_FLAG_SLICE_THREADS,
+    .flags         = AVFILTER_FLAG_SLICE_THREADS | AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL,
 };