Commit 8a96c851ed for ffmpeg

commit 8a96c851ed065d4b42dc30ea1e213270ed42cc6e
Author: Charly Morgand-Poyac <charly.morgand-poyac@bbright.com>
Date:   Wed Aug 19 17:16:29 2026 +0200

    lavc/hevcdec: factor local context growth and substream setup out of WPP

    Both are needed by any entry-point based decode path, not just WPP.
    No functional change.

    Signed-off-by: Charly Morgand-Poyac <charly.morgand-poyac@bbright.com>

diff --git a/libavcodec/hevc/hevcdec.c b/libavcodec/hevc/hevcdec.c
index 6f65dd5af9..2ab6b3e2c0 100644
--- a/libavcodec/hevc/hevcdec.c
+++ b/libavcodec/hevc/hevcdec.c
@@ -2949,47 +2949,40 @@ static int wpp_progress_init(HEVCContext *s, unsigned count)
     return 0;
 }

-static int hls_slice_data_wpp(HEVCContext *s, const H2645NAL *nal)
+static int alloc_local_ctxs(HEVCContext *s)
 {
-    const HEVCPPS *const pps = s->pps;
-    const HEVCSPS *const sps = pps->sps;
-    const uint8_t *data = nal->data;
-    int length          = nal->size;
-    int *ret;
-    int64_t offset;
-    int64_t startheader, cmpt = 0;
-    int j, res = 0;
+    HEVCLocalContext *tmp;

-    if (s->sh.slice_ctb_addr_rs + s->sh.num_entry_point_offsets * (int64_t)sps->ctb_width >= sps->ctb_width * (int64_t)sps->ctb_height) {
-        av_log(s->avctx, AV_LOG_ERROR, "WPP ctb addresses are wrong (%d %d %d %d)\n",
-            s->sh.slice_ctb_addr_rs, s->sh.num_entry_point_offsets,
-            sps->ctb_width, sps->ctb_height
-        );
-        return AVERROR_INVALIDDATA;
-    }
+    if (s->avctx->thread_count <= s->nb_local_ctx)
+        return 0;

-    if (s->avctx->thread_count > s->nb_local_ctx) {
-        HEVCLocalContext *tmp = av_malloc_array(s->avctx->thread_count, sizeof(*s->local_ctx));
+    tmp = av_malloc_array(s->avctx->thread_count, sizeof(*s->local_ctx));
+    if (!tmp)
+        return AVERROR(ENOMEM);

-        if (!tmp)
-            return AVERROR(ENOMEM);
+    memcpy(tmp, s->local_ctx, sizeof(*s->local_ctx) * s->nb_local_ctx);
+    av_free(s->local_ctx);
+    s->local_ctx = tmp;

-        memcpy(tmp, s->local_ctx, sizeof(*s->local_ctx) * s->nb_local_ctx);
-        av_free(s->local_ctx);
-        s->local_ctx = tmp;
+    for (unsigned i = s->nb_local_ctx; i < s->avctx->thread_count; i++) {
+        tmp = &s->local_ctx[i];

-        for (unsigned i = s->nb_local_ctx; i < s->avctx->thread_count; i++) {
-            tmp = &s->local_ctx[i];
+        memset(tmp, 0, sizeof(*tmp));

-            memset(tmp, 0, sizeof(*tmp));
+        tmp->logctx             = s->avctx;
+        tmp->parent             = s;
+        tmp->common_cabac_state = &s->cabac;
+    }

-            tmp->logctx             = s->avctx;
-            tmp->parent             = s;
-            tmp->common_cabac_state = &s->cabac;
-        }
+    s->nb_local_ctx = s->avctx->thread_count;

-        s->nb_local_ctx = s->avctx->thread_count;
-    }
+    return 0;
+}
+
+static int slice_substreams_init(HEVCContext *s, const H2645NAL *nal)
+{
+    int64_t offset, startheader, cmpt = 0;
+    int j;

     offset = s->sh.data_offset;

@@ -3015,17 +3008,43 @@ static int hls_slice_data_wpp(HEVCContext *s, const H2645NAL *nal)
     }

     offset += s->sh.entry_point_offset[s->sh.num_entry_point_offsets - 1] - cmpt;
-    if (length < offset) {
+    if (nal->size < offset) {
         av_log(s->avctx, AV_LOG_ERROR, "entry_point_offset table is corrupted\n");
         return AVERROR_INVALIDDATA;
     }
-    s->sh.size  [s->sh.num_entry_point_offsets] = length - offset;
+    s->sh.size  [s->sh.num_entry_point_offsets] = nal->size - offset;
     s->sh.offset[s->sh.num_entry_point_offsets] = offset;

     s->sh.offset[0] = s->sh.data_offset;
     s->sh.size[0]   = s->sh.offset[1] - s->sh.offset[0];

-    s->data = data;
+    s->data = nal->data;
+
+    return 0;
+}
+
+static int hls_slice_data_wpp(HEVCContext *s, const H2645NAL *nal)
+{
+    const HEVCPPS *const pps = s->pps;
+    const HEVCSPS *const sps = pps->sps;
+    int *ret;
+    int res = 0;
+
+    if (s->sh.slice_ctb_addr_rs + s->sh.num_entry_point_offsets * (int64_t)sps->ctb_width >= sps->ctb_width * (int64_t)sps->ctb_height) {
+        av_log(s->avctx, AV_LOG_ERROR, "WPP ctb addresses are wrong (%d %d %d %d)\n",
+            s->sh.slice_ctb_addr_rs, s->sh.num_entry_point_offsets,
+            sps->ctb_width, sps->ctb_height
+        );
+        return AVERROR_INVALIDDATA;
+    }
+
+    res = alloc_local_ctxs(s);
+    if (res < 0)
+        return res;
+
+    res = slice_substreams_init(s, nal);
+    if (res < 0)
+        return res;

     for (unsigned i = 1; i < s->nb_local_ctx; i++) {
         s->local_ctx[i].first_qp_group = 1;