PR #25347 opened by Forgejo_Fairy URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/25347 Patch URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/25347.patch
Queued CUVID display entries retain decode-surface indices and timestamps, without copying the pixels. Fetching another packet before consuming those entries can reuse a queued surface and associate a later image with an earlier timestamp. Require the display queue to be empty before fetching more input, as proposed by hayateppp in #25210. On Linux x86-64 with an RTX 5090 and NVIDIA driver 595.84, a generated 120-frame interlaced H.264 stream decoded with bob deinterlacing produces 157 incorrect images out of 240 on master 9d106b2bb59f. With this change, all 240 match the corresponding software-decoded spatially constant source frames. Timing and sizes are unchanged. Decode-callback instrumentation confirms queued-surface reuse before the change and none afterward. Direct boundary tests reproduce the generated failure at bddb2343b6e5, while its first parent 1fd76277708c passes. The original report's unavailable inputs use default weave mode, so their exact trigger remains unconfirmed. Additional validation passed for weave, bob with drop_second_field, CUDA output followed by download, 18,000 generated progressive H.264 frames, 1,500 HEVC frames, and eight existing H.264 FATE samples. Adaptive deinterlacing completed with expected frame counts; pixel correctness of its filtering is not asserted. A complete FATE run, Windows, other GPU/driver combinations, CUARRAY zero-copy and performance were not tested. The generated-input reproducer, diagnostic patch, revision results and detailed validation are preserved on [fairy/issue25210-tooling](https://code.ffmpeg.org/Forgejo_Fairy/FFmpeg/src/branch/fairy/issue25210-tooling/tools/issue25210). The production change is limited to the queue guard and its comment. >From 9fa94cf2dddd5f99470b542506b52cb1ad11c374 Mon Sep 17 00:00:00 2001 From: hayateppp <> Date: Thu, 22 Oct 2026 09:17:32 +0000 Subject: [PATCH] avcodec/cuviddec: drain queued output before parsing more input A queued display entry holds a decode surface index, not a copy of its pixels. Parsing another packet can reuse that surface before the entry is mapped, associating a later image with the queued timestamp. The queue occupancy check does not protect individual surface lifetimes. Consume queued output before fetching another packet. In particular, this drains both deinterlaced fields before submitting further input. A generated 120-frame interlaced H.264 stream decoded with -deint bob produces 157 incorrect images out of 240 on an RTX 5090. With this guard, all 240 images match the software-decoded, spatially constant source frames, and diagnostic logging no longer observes queued surface reuse. Based on the candidate fix provided by hayateppp in issue #25210. The original report's private inputs remain untested here. Assisted-by: Fairy --- libavcodec/cuviddec.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libavcodec/cuviddec.c b/libavcodec/cuviddec.c index 14744cf0679..9bc174d2ee9 100644 --- a/libavcodec/cuviddec.c +++ b/libavcodec/cuviddec.c @@ -913,7 +913,8 @@ static int cuvid_output_frame(AVCodecContext *avctx, AVFrame *frame) return ret; } - if (!cuvid_is_buffer_full(avctx)) { + // Consume queued output before parsing can reuse its decode surfaces. + if (!av_fifo_can_read(ctx->frame_queue) && !cuvid_is_buffer_full(avctx)) { AVPacket *const pkt = ctx->pkt; ret = ff_decode_get_packet(avctx, pkt); if (ret < 0 && ret != AVERROR_EOF) -- 2.54.0 _______________________________________________ ffmpeg-devel mailing list -- [email protected] To unsubscribe send an email to [email protected]
