Commit 00c61945c2 for ffmpeg

commit 00c61945c245a1c4b4ce485ea2146284935bcd20
Author: Frank Plowman <post@frankplowman.com>
Date:   Sat Oct 10 10:08:06 2026 +0100

    lavc/vvc: Use 1D array for explicit slice heights in PPS

    The spec defines pps_exp_slice_height_in_ctus_minus1 as a 2D array but
    it is sparse, with at most VVC_MAX_SLICES present elements. This commit
    replaces it with a 1D array, similar to what was already done in
    libavcodec/vaapi_vvc.c. This reduces the size of H266RawPPS from ~1.9MiB
    to ~26KiB.

    Fixes: 529105369/clusterfuzz-testcase-minimized-ffmpeg_BSF_VVC_METADATA_fuzzer-5351121246552064
    Signed-off-by: Frank Plowman <post@frankplowman.com>

diff --git a/libavcodec/cbs_h266.h b/libavcodec/cbs_h266.h
index 8f7ce5f5b6..4833048479 100644
--- a/libavcodec/cbs_h266.h
+++ b/libavcodec/cbs_h266.h
@@ -538,7 +538,7 @@ typedef struct H266RawPPS {
     uint16_t pps_slice_width_in_tiles_minus1[VVC_MAX_SLICES];
     uint16_t pps_slice_height_in_tiles_minus1[VVC_MAX_SLICES];
     uint16_t pps_num_exp_slices_in_tile[VVC_MAX_SLICES];
-    uint16_t pps_exp_slice_height_in_ctus_minus1[VVC_MAX_SLICES][VVC_MAX_TILE_ROWS];
+    uint16_t pps_exp_slice_height_in_ctus_minus1[VVC_MAX_SLICES];
     int16_t  pps_tile_idx_delta_val[VVC_MAX_SLICES];

     uint8_t  pps_loop_filter_across_slices_enabled_flag;
diff --git a/libavcodec/cbs_h266_syntax_template.c b/libavcodec/cbs_h266_syntax_template.c
index f15d70cb8d..e11799c2e5 100644
--- a/libavcodec/cbs_h266_syntax_template.c
+++ b/libavcodec/cbs_h266_syntax_template.c
@@ -2024,12 +2024,13 @@ static int FUNC(pps) (CodedBitstreamContext *ctx, RWContext *rw,

                         for (j = 0; j < current->pps_num_exp_slices_in_tile[i];
                              j++) {
-                            ues(pps_exp_slice_height_in_ctus_minus1[i][j], 0,
+                            xue(pps_exp_slice_height_in_ctus_minus1[i][j],
+                                current->pps_exp_slice_height_in_ctus_minus1[i + j], 0,
                                 remaining_height_in_ctbs_y - (current->pps_num_exp_slices_in_tile[i] - j), 2,
                                 i, j);
                             slice_height_in_ctus =
                                 current->
-                                pps_exp_slice_height_in_ctus_minus1[i][j] + 1;
+                                pps_exp_slice_height_in_ctus_minus1[i + j] + 1;

                             current->slice_height_in_ctus[i + j] =
                                 slice_height_in_ctus;
@@ -2041,7 +2042,7 @@ static int FUNC(pps) (CodedBitstreamContext *ctx, RWContext *rw,
                         }
                         uniform_slice_height = 1 +
                             (j == 0 ? current->row_height_val[tile_y] - 1:
-                            current->pps_exp_slice_height_in_ctus_minus1[i][j-1]);
+                            current->pps_exp_slice_height_in_ctus_minus1[i + j - 1]);

                         num_uniform_slices = (remaining_height_in_ctbs_y + uniform_slice_height - 1)
                                            / uniform_slice_height;
diff --git a/libavcodec/vaapi_vvc.c b/libavcodec/vaapi_vvc.c
index 908db7bfab..f5ee07ee87 100644
--- a/libavcodec/vaapi_vvc.c
+++ b/libavcodec/vaapi_vvc.c
@@ -425,7 +425,7 @@ static int vaapi_vvc_start_frame(AVCodecContext          *avctx,
     if (!pps->pps_no_pic_partition_flag && pps->pps_rect_slice_flag && !pps->pps_single_slice_per_subpic_flag) {
         for (i = 0; i <= pps->pps_num_slices_in_pic_minus1; i++) {
             for (j = 0; j < pps->pps_num_exp_slices_in_tile[i]; j++) {
-                exp_slice_height_in_ctus[i + j] = pps->pps_exp_slice_height_in_ctus_minus1[i][j] + 1;
+                exp_slice_height_in_ctus[i + j] = pps->pps_exp_slice_height_in_ctus_minus1[i + j] + 1;
             }
         }
         for (i = 0; i <= pps->pps_num_slices_in_pic_minus1; i++) {