PR #22766 opened by Zhao Zhili (quink)
URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/22766
Patch URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/22766.patch

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 <[email protected]>


>From aa37e34aa4c199999129d9d8832fe778aff0b79e Mon Sep 17 00:00:00 2001
From: Zhao Zhili <[email protected]>
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 <[email protected]>
---
 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;
 }
-- 
2.52.0

_______________________________________________
ffmpeg-devel mailing list -- [email protected]
To unsubscribe send an email to [email protected]

Reply via email to