PR #24201 opened by Kacper Michajłow (kasper93)
URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/24201
Patch URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/24201.patch


From f5a0bbafaa9d00c5a0bce641a1968318c84616f0 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Kacper=20Michaj=C5=82ow?= <[email protected]>
Date: Tue, 18 Aug 2026 15:55:51 +0200
Subject: [PATCH 1/2] avcodec/h264dec: defer execution of queued slices to the
 end of packet
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

This allows all non-VCL NAL units to be parsed and frame threading
setup to finish before the bulk of the decoding work is done.

Signed-off-by: Kacper Michajłow <[email protected]>
---
 libavcodec/h264dec.c | 20 ++++++++++++--------
 1 file changed, 12 insertions(+), 8 deletions(-)

diff --git a/libavcodec/h264dec.c b/libavcodec/h264dec.c
index b78b7989ea..1def45e0c0 100644
--- a/libavcodec/h264dec.c
+++ b/libavcodec/h264dec.c
@@ -621,7 +621,7 @@ static int decode_nal_units(H264Context *h, AVBufferRef 
*buf_ref,
 
     for (i = 0; i < h->pkt.nb_nals; i++) {
         H2645NAL *nal = &h->pkt.nals[i];
-        int max_slice_ctx, err;
+        int err;
 
         if (avctx->skip_frame >= AVDISCARD_NONREF &&
             nal->ref_idc == 0 && nal->type != H264_NAL_SEI)
@@ -649,6 +649,14 @@ static int decode_nal_units(H264Context *h, AVBufferRef 
*buf_ref,
         case H264_NAL_SLICE:
             h->has_slice = 1;
 
+            /* Execution of queued slices is deferred until the slice context
+             * queue is full or the end of the packet is reached. */
+            if (!avctx->hwaccel && h->nb_slice_ctx_queued == h->nb_slice_ctx) {
+                ret = ff_h264_execute_decode_slices(h);
+                if (ret < 0 && (h->avctx->err_recognition & AV_EF_EXPLODE))
+                    goto end;
+            }
+
             if ((err = ff_h264_queue_decode_slice(h, nal))) {
                 H264SliceContext *sl = h->slice_ctx + h->nb_slice_ctx_queued;
                 sl->ref_count[0] = sl->ref_count[1] = 0;
@@ -668,13 +676,9 @@ static int decode_nal_units(H264Context *h, AVBufferRef 
*buf_ref,
                     goto end;
             }
 
-            max_slice_ctx = avctx->hwaccel ? 1 : h->nb_slice_ctx;
-            if (h->nb_slice_ctx_queued == max_slice_ctx) {
-                if (h->avctx->hwaccel) {
-                    ret = FF_HW_CALL(avctx, decode_slice, nal->raw_data, 
nal->raw_size);
-                    h->nb_slice_ctx_queued = 0;
-                } else
-                    ret = ff_h264_execute_decode_slices(h);
+            if (avctx->hwaccel && h->nb_slice_ctx_queued) {
+                ret = FF_HW_CALL(avctx, decode_slice, nal->raw_data, 
nal->raw_size);
+                h->nb_slice_ctx_queued = 0;
                 if (ret < 0 && (h->avctx->err_recognition & AV_EF_EXPLODE))
                     goto end;
             }
-- 
2.52.0


From cd36dbe84d17c27a47b26e0ab8d3ea7ab515ab72 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Kacper=20Michaj=C5=82ow?= <[email protected]>
Date: Tue, 18 Aug 2026 16:01:30 +0200
Subject: [PATCH 2/2] avcodec/h264dec: decode late SEI before finishing frame
 threading setup
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

SEI NAL units following a slice were skipped with frame threading,
because decoding them into the SEI context after
ff_thread_finish_setup() would race with the context copy in
ff_h264_update_thread_context(). Delay the setup finish until such SEI
is decoded instead.

Fixes: https://code.ffmpeg.org/FFmpeg/FFmpeg/issues/21348
Fixes: https://github.com/mpv-player/mpv/issues/18104

Signed-off-by: Kacper Michajłow <[email protected]>
---
 libavcodec/h264dec.c | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/libavcodec/h264dec.c b/libavcodec/h264dec.c
index 1def45e0c0..4bd4ca4de3 100644
--- a/libavcodec/h264dec.c
+++ b/libavcodec/h264dec.c
@@ -519,6 +519,10 @@ static int get_last_needed_nal(H264Context *h)
         case H264_NAL_PPS:
             nals_needed = i;
             break;
+        case H264_NAL_SEI:
+            if (first_slice)
+                nals_needed = i;
+            break;
         case H264_NAL_DPA:
         case H264_NAL_IDR_SLICE:
         case H264_NAL_SLICE:
@@ -699,6 +703,13 @@ static int decode_nal_units(H264Context *h, AVBufferRef 
*buf_ref,
                 debug_green_metadata(&h->sei.green_metadata, h->avctx);
             if (ret < 0 && (h->avctx->err_recognition & AV_EF_EXPLODE))
                 goto end;
+
+            if (avctx->active_thread_type & FF_THREAD_FRAME &&
+                i >= nals_needed && !h->setup_finished &&
+                h->current_slice && h->cur_pic_ptr) {
+                ff_thread_finish_setup(avctx);
+                h->setup_finished = 1;
+            }
             break;
         case H264_NAL_SPS: {
             GetBitContext tmp_gb = nal->gb;
-- 
2.52.0

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

Reply via email to