[PR] avfilter/af_arnndn: handle partial frames at EOF (PR #24041)

AYOUB NABIL BOUBAGRAT via ffmpeg-devel <[email protected]>
Newsgroups gmane.comp.video.ffmpeg.devel
Message-ID <178610145735.59.16975379863140167486@29965ddac10e>
PR #24041 opened by AYOUB NABIL BOUBAGRAT (ayoubnabil)
URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/24041
Patch URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/24041.patch

ff_inlink_consume_samples() can return a partial frame when the input
reaches EOF. arnndn still processed FRAME_SIZE samples, reading past
the valid input and potentially turning the final frame into NaNs.
zero-pad the partial input before processing, then trim the output back
to the original sample count.

fixes #23746.


>From a6eca074cd1c7a81b2a8a5f06cdf5a9c3a56a45c Mon Sep 17 00:00:00 2001
From: Ayoub Nabil Boubagrat <[email protected]>
Date: Fri, 7 Aug 2026 13:15:30 +0200
Subject: [PATCH] avfilter/af_arnndn: handle partial frames at EOF

ff_inlink_consume_samples() can return a partial frame when the input
reaches EOF. arnndn still processed FRAME_SIZE samples, reading past
the valid input and potentially turning the final frame into NaNs.

zero-pad the partial input before processing, then trim the output back
to the original sample count.

fixes #23746.

Signed-off-by: Ayoub Nabil Boubagrat <[email protected]>
---
 libavfilter/af_arnndn.c | 32 +++++++++++++++++++++++++++++++-
 1 file changed, 31 insertions(+), 1 deletion(-)

diff --git a/libavfilter/af_arnndn.c b/libavfilter/af_arnndn.c
index 6209f1b0e0..ffad40529d 100644
--- a/libavfilter/af_arnndn.c
+++ b/libavfilter/af_arnndn.c
@@ -37,6 +37,7 @@
 #include "libavutil/mem.h"
 #include "libavutil/mem_internal.h"
 #include "libavutil/opt.h"
+#include "libavutil/samplefmt.h"
 #include "libavutil/tx.h"
 #include "avfilter.h"
 #include "audio.h"
@@ -1432,18 +1433,47 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in)
     AVFilterLink *outlink = ctx->outputs[0];
     AVFrame *out = NULL;
     ThreadData td;
+    const int nb_samples = in->nb_samples;
+    int ret;
 
     out = ff_get_audio_buffer(outlink, FRAME_SIZE);
     if (!out) {
         av_frame_free(&in);
         return AVERROR(ENOMEM);
     }
-    av_frame_copy_props(out, in);
+
+    ret = av_frame_copy_props(out, in);
+    if (ret < 0) {
+        av_frame_free(&out);
+        av_frame_free(&in);
+        return ret;
+    }
+
+    if (nb_samples < FRAME_SIZE) {
+        AVFrame *padded = ff_get_audio_buffer(outlink, FRAME_SIZE);
+
+        if (!padded) {
+            av_frame_free(&out);
+            av_frame_free(&in);
+            return AVERROR(ENOMEM);
+        }
+
+        av_samples_copy(padded->extended_data, in->extended_data,
+                        0, 0, nb_samples, in->ch_layout.nb_channels,
+                        in->format);
+        av_samples_set_silence(padded->extended_data, nb_samples,
+                               FRAME_SIZE - nb_samples,
+                               in->ch_layout.nb_channels, in->format);
+
+        av_frame_free(&in);
+        in = padded;
+    }
 
     td.in = in; td.out = out;
     ff_filter_execute(ctx, rnnoise_channels, &td, NULL,
                       FFMIN(outlink->ch_layout.nb_channels, ff_filter_get_nb_threads(ctx)));
 
+    out->nb_samples = nb_samples;
     av_frame_free(&in);
     return ff_filter_frame(outlink, out);
 }
-- 
2.52.0

_______________________________________________
ffmpeg-devel mailing list -- [email protected]
To unsubscribe send an email to [email protected]
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.