diff --git a/libavfilter/af_afftdn.c b/libavfilter/af_afftdn.c
index fbcb0f18d5..4353db05d1 100644
--- a/libavfilter/af_afftdn.c
+++ b/libavfilter/af_afftdn.c
@@ -20,13 +20,13 @@
 
 #include <float.h>
 
-#include "libavutil/audio_fifo.h"
 #include "libavutil/avstring.h"
 #include "libavutil/channel_layout.h"
 #include "libavutil/opt.h"
 #include "libavcodec/avfft.h"
 #include "avfilter.h"
 #include "audio.h"
+#include "filters.h"
 #include "formats.h"
 
 #define C       (M_LN10 * 0.1)
@@ -98,7 +98,6 @@ typedef struct AudioFFTDeNoiseContext {
     float   last_noise_balance;
     int64_t block_count;
 
-    int64_t pts;
     int     channels;
     int     sample_noise;
     int     sample_noise_start;
@@ -135,8 +134,6 @@ typedef struct AudioFFTDeNoiseContext {
     double  vector_b[5];
     double  matrix_b[75];
     double  matrix_c[75];
-
-    AVAudioFifo *fifo;
 } AudioFFTDeNoiseContext;
 
 #define OFFSET(x) offsetof(AudioFFTDeNoiseContext, x)
@@ -616,7 +613,6 @@ static int config_input(AVFilterLink *inlink)
     if (!s->dnch)
         return AVERROR(ENOMEM);
 
-    s->pts = AV_NOPTS_VALUE;
     s->channels = inlink->channels;
     s->sample_rate = inlink->sample_rate;
     s->sample_advance = s->sample_rate / 80;
@@ -846,10 +842,6 @@ static int config_input(AVFilterLink *inlink)
     }
     s->noise_band_count = s->noise_band_edge[16];
 
-    s->fifo = av_audio_fifo_alloc(inlink->format, inlink->channels, s->fft_length);
-    if (!s->fifo)
-        return AVERROR(ENOMEM);
-
     return 0;
 }
 
@@ -1153,34 +1145,22 @@ static void get_auto_noise_levels(AudioFFTDeNoiseContext *s,
     }
 }
 
-static int filter_frame(AVFilterLink *inlink, AVFrame *frame)
+static int activate(AVFilterContext *ctx)
 {
-    AVFilterContext *ctx = inlink->dst;
+    AVFilterLink *inlink = ctx->inputs[0];
     AVFilterLink *outlink = ctx->outputs[0];
     AudioFFTDeNoiseContext *s = ctx->priv;
     AVFrame *out = NULL, *in = NULL;
     ThreadData td;
     int ret = 0;
 
-    if (s->pts == AV_NOPTS_VALUE)
-        s->pts = frame->pts;
+    FF_FILTER_FORWARD_STATUS_BACK(outlink, inlink);
 
-    ret = av_audio_fifo_write(s->fifo, (void **)frame->extended_data, frame->nb_samples);
-    av_frame_free(&frame);
+    ret = ff_inlink_peek_samples(inlink, s->window_length, &in);
     if (ret < 0)
         return ret;
 
-    while (av_audio_fifo_size(s->fifo) >= s->window_length) {
-        if (!in) {
-            in = ff_get_audio_buffer(outlink, s->window_length);
-            if (!in)
-                return AVERROR(ENOMEM);
-        }
-
-        ret = av_audio_fifo_peek(s->fifo, (void **)in->extended_data, s->window_length);
-        if (ret < 0)
-            break;
-
+    if (ret > 0) {
         if (s->track_noise) {
             for (int ch = 0; ch < inlink->channels; ch++) {
                 DeNoiseChannel *dnch = &s->dnch[ch];
@@ -1232,9 +1212,10 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *frame)
 
         out = ff_get_audio_buffer(outlink, s->sample_advance);
         if (!out) {
-            ret = AVERROR(ENOMEM);
-            break;
+            av_frame_free(&in);
+            return AVERROR(ENOMEM);
         }
+        out->pts = in->pts;
 
         for (int ch = 0; ch < inlink->channels; ch++) {
             DeNoiseChannel *dnch = &s->dnch[ch];
@@ -1262,17 +1243,16 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *frame)
             memset(src + (s->window_length - s->sample_advance), 0, s->sample_advance * sizeof(*src));
         }
 
-        av_audio_fifo_drain(s->fifo, s->sample_advance);
+        ff_inlink_skip_samples(inlink, FFMIN(ff_inlink_queued_samples(inlink), s->sample_advance));
 
-        out->pts = s->pts;
-        ret = ff_filter_frame(outlink, out);
-        if (ret < 0)
-            break;
-        s->pts += s->sample_advance;
+        av_frame_free(&in);
+        return ff_filter_frame(outlink, out);
     }
-    av_frame_free(&in);
 
-    return ret;
+    FF_FILTER_FORWARD_STATUS(inlink, outlink);
+    FF_FILTER_FORWARD_WANTED(outlink, inlink);
+
+    return FFERROR_NOT_READY;
 }
 
 static av_cold void uninit(AVFilterContext *ctx)
@@ -1308,8 +1288,6 @@ static av_cold void uninit(AVFilterContext *ctx)
         }
         av_freep(&s->dnch);
     }
-
-    av_audio_fifo_free(s->fifo);
 }
 
 static int query_formats(AVFilterContext *ctx)
@@ -1393,7 +1371,6 @@ static const AVFilterPad inputs[] = {
     {
         .name         = "default",
         .type         = AVMEDIA_TYPE_AUDIO,
-        .filter_frame = filter_frame,
         .config_props = config_input,
     },
     { NULL }
@@ -1416,6 +1393,7 @@ AVFilter ff_af_afftdn = {
     .uninit          = uninit,
     .inputs          = inputs,
     .outputs         = outputs,
+    .activate        = activate,
     .process_command = process_command,
     .flags           = AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC |
                        AVFILTER_FLAG_SLICE_THREADS,
