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]
