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]

Reply via email to