From e717604a29992e5ae429a0683f28b9cedd09e6eb Mon Sep 17 00:00:00 2001 From: Zhao Zhili Date: Tue, 7 Apr 2026 15:37:08 +0800 Subject: [PATCH] avfilter/mpdecimate: fix kept-frame forwarding and error handling When duplicate frames are forced to be kept, forward the input frame without cloning instead of creating an unnecessary extra reference. This removes the leak path introduced when clone allocation fails. For frames that become the new reference, keep using a clone for forwarding. Signed-off-by: Zhao Zhili --- libavfilter/vf_mpdecimate.c | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/libavfilter/vf_mpdecimate.c b/libavfilter/vf_mpdecimate.c index 010c90b243..00bc6699c3 100644 --- a/libavfilter/vf_mpdecimate.c +++ b/libavfilter/vf_mpdecimate.c @@ -212,6 +212,7 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *cur) { DecimateContext *decimate = inlink->dst->priv; AVFilterLink *outlink = inlink->dst->outputs[0]; + AVFrame *out = NULL; int ret; DecimateResult result = decimate->ref ? decimate_frame(inlink->dst, cur, decimate->ref) : DECIMATE_KEEP_UPDATE; @@ -222,16 +223,18 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *cur) break; case DECIMATE_KEEP_NO_UPDATE: decimate->drop_count = FFMIN(-1, decimate->drop_count-1); - if ((ret = ff_filter_frame(outlink, av_frame_clone(cur))) < 0) - return ret; + out = cur; break; case DECIMATE_KEEP_UPDATE: + out = av_frame_clone(cur); + if (!out) { + av_frame_free(&cur); + return AVERROR(ENOMEM); + } av_frame_free(&decimate->ref); decimate->ref = cur; decimate->drop_count = FFMIN(-1, decimate->drop_count-1); decimate->keep_count = 0; - if ((ret = ff_filter_frame(outlink, av_frame_clone(cur))) < 0) - return ret; break; } @@ -242,8 +245,14 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *cur) decimate->drop_count, decimate->keep_count); - if (result != DECIMATE_KEEP_UPDATE) + if (result == DECIMATE_DROP) { av_frame_free(&cur); + return 0; + } + + ret = ff_filter_frame(outlink, out); + if (ret < 0) + return ret; return 0; }