diff --git a/libavfilter/af_aderivative.c b/libavfilter/af_aderivative.c
index 6b3e4dd0e4..559223d5ee 100644
--- a/libavfilter/af_aderivative.c
+++ b/libavfilter/af_aderivative.c
@@ -22,8 +22,8 @@
 
 typedef struct ADerivativeContext {
     const AVClass *class;
-    AVFrame *prev;
-    void (*filter)(void **dst, void **prv, const void **src,
+    void *prev;
+    void (*filter)(void **dst, void *prv, const void **src,
                    int nb_samples, int channels);
 } ADerivativeContext;
 
@@ -63,22 +63,24 @@ static int query_formats(AVFilterContext *ctx)
 }
 
 #define DERIVATIVE(name, type)                                          \
-static void aderivative_## name ##p(void **d, void **p, const void **s, \
+static void aderivative_## name ##p(void **d, void *p0, const void **s, \
                                     int nb_samples, int channels)       \
 {                                                                       \
+    type *const p = p0;                                                 \
     int n, c;                                                           \
                                                                         \
     for (c = 0; c < channels; c++) {                                    \
         const type *src = s[c];                                         \
         type *dst = d[c];                                               \
-        type *prv = p[c];                                               \
+        type  prv = p[c];                                               \
                                                                         \
         for (n = 0; n < nb_samples; n++) {                              \
             const type current = src[n];                                \
                                                                         \
-            dst[n] = current - prv[0];                                  \
-            prv[0] = current;                                           \
+            dst[n] = current - prv;                                     \
+            prv    = current;                                           \
         }                                                               \
+        p[c] = prv;                                                     \
     }                                                                   \
 }
 
@@ -88,22 +90,24 @@ DERIVATIVE(s16, int16_t)
 DERIVATIVE(s32, int32_t)
 
 #define INTEGRAL(name, type)                                          \
-static void aintegral_## name ##p(void **d, void **p, const void **s, \
+static void aintegral_## name ##p(void **d, void *p0, const void **s, \
                                   int nb_samples, int channels)       \
 {                                                                     \
+    type *const p = p0;                                               \
     int n, c;                                                         \
                                                                       \
     for (c = 0; c < channels; c++) {                                  \
         const type *src = s[c];                                       \
         type *dst = d[c];                                             \
-        type *prv = p[c];                                             \
+        type  prv = p[c];                                             \
                                                                       \
         for (n = 0; n < nb_samples; n++) {                            \
             const type current = src[n];                              \
                                                                       \
-            dst[n] = current + prv[0];                                \
-            prv[0] = dst[n];                                          \
+            dst[n] = current + prv;                                   \
+            prv    = dst[n];                                          \
         }                                                             \
+        p[c] = prv;                                                   \
     }                                                                 \
 }
 
@@ -122,6 +126,10 @@ static int config_input(AVFilterLink *inlink)
     case AV_SAMPLE_FMT_S16P: s->filter = aderivative_s16p; break;
     }
 
+    s->prev = av_calloc(inlink->channels, av_get_bytes_per_sample(inlink->format));
+    if (!s->prev)
+        return AVERROR(ENOMEM);
+
     if (strcmp(ctx->filter->name, "aintegral"))
         return 0;
 
@@ -146,15 +154,7 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in)
     }
     av_frame_copy_props(out, in);
 
-    if (!s->prev) {
-        s->prev = ff_get_audio_buffer(inlink, 1);
-        if (!s->prev) {
-            av_frame_free(&in);
-            return AVERROR(ENOMEM);
-        }
-    }
-
-    s->filter((void **)out->extended_data, (void **)s->prev->extended_data, (const void **)in->extended_data,
+    s->filter((void **)out->extended_data, s->prev, (const void **)in->extended_data,
               in->nb_samples, in->channels);
 
     av_frame_free(&in);
@@ -165,7 +165,7 @@ static av_cold void uninit(AVFilterContext *ctx)
 {
     ADerivativeContext *s = ctx->priv;
 
-    av_frame_free(&s->prev);
+    av_freep(&s->prev);
 }
 
 static const AVFilterPad aderivative_inputs[] = {
