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]
