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


>From 5a98a863bc8523ebac93baca409d1d52628811cc Mon Sep 17 00:00:00 2001
From: Zhao Zhili <[email protected]>
Date: Tue, 15 Sep 2026 17:20:50 +0800
Subject: [PATCH 1/3] avcodec/videotoolboxenc: free the buffer node when a
 frame is dropped

The output callback returns without freeing the node it received as
sourceFrameCtx when VideoToolbox completes a frame with no sample buffer,
leaking it once per dropped frame.
---
 libavcodec/videotoolboxenc.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/libavcodec/videotoolboxenc.c b/libavcodec/videotoolboxenc.c
index 536565a252..ac4b01e6c6 100644
--- a/libavcodec/videotoolboxenc.c
+++ b/libavcodec/videotoolboxenc.c
@@ -762,6 +762,7 @@ static void vtenc_output_callback(
     }
 
     if (!sample_buffer) {
+        vtenc_free_buf_node(info);
         return;
     }
 
-- 
2.52.0


>From 539d9f039e9db608c2cbb13a5af2fbd3cb5d3ee0 Mon Sep 17 00:00:00 2001
From: Zhao Zhili <[email protected]>
Date: Tue, 15 Sep 2026 17:38:55 +0800
Subject: [PATCH 2/3] avcodec/videotoolboxenc: fail when no frame is encoded
 for extradata

VideoToolbox reports a dropped frame as success with no sample buffer,
which is why vtenc_output_callback() checks for it (see 6966548c1bd,
reported to happen often on iOS 11). If the single frame sent to
populate extradata is dropped, nothing is queued, vtenc_q_pop()
returns success with a NULL buffer, and the unconditional CFRelease()
releases NULL. Fail where the missing buffer is detected.
---
 libavcodec/videotoolboxenc.c | 9 +++++++--
 1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/libavcodec/videotoolboxenc.c b/libavcodec/videotoolboxenc.c
index ac4b01e6c6..d946682e4e 100644
--- a/libavcodec/videotoolboxenc.c
+++ b/libavcodec/videotoolboxenc.c
@@ -2681,10 +2681,15 @@ static int vtenc_populate_extradata(AVCodecContext   
*avctx,
         goto pe_cleanup;
     }
 
+    if (!buf) {
+        // VideoToolbox reports a dropped frame as success with no buffer.
+        av_log(avctx, AV_LOG_ERROR, "Extradata frame dropped, no param 
sets\n");
+        status = AVERROR_EXTERNAL;
+        goto pe_cleanup;
+    }
+
     CFRelease(buf);
 
-
-
 pe_cleanup:
     CVPixelBufferRelease(pix_buf);
 
-- 
2.52.0


>From 9ea65f7fa9b98715a2688b957d6f22b43bb5a636 Mon Sep 17 00:00:00 2001
From: Zhao Zhili <[email protected]>
Date: Tue, 15 Sep 2026 18:14:17 +0800
Subject: [PATCH 3/3] avcodec/videotoolboxenc: free the extradata buffer node
 on error paths

node is set to NULL at the point ownership passes to VideoToolbox, so a
node that is still set at the end of vtenc_populate_extradata() is one
this function owns and must release.
---
 libavcodec/videotoolboxenc.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/libavcodec/videotoolboxenc.c b/libavcodec/videotoolboxenc.c
index d946682e4e..c2e1405b6c 100644
--- a/libavcodec/videotoolboxenc.c
+++ b/libavcodec/videotoolboxenc.c
@@ -2703,8 +2703,8 @@ pe_cleanup:
     vtctx->frame_ct_out = 0;
 
     av_assert0(status != 0 || (avctx->extradata && avctx->extradata_size > 0));
-    if (!status)
-        vtenc_free_buf_node(node);
+    // NULL once ownership passed to VideoToolbox, so a set node must be freed.
+    vtenc_free_buf_node(node);
 
     return status;
 }
-- 
2.52.0

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

Reply via email to