Commit 0747459f0c for ffmpeg

commit 0747459f0c6f228566f5cb11ceed56b977208582
Author: Michael Niedermayer <michael@niedermayer.cc>
Date:   Tue Oct 20 03:22:01 2026 +0200

    avcodec/bsf/lcevc_metadata: write the VUI into the NAL unit holding the global config

    Fixes: u1TxsBfg36kp/testcase/two_b.mp4 / gen_au.py gen_mp4.py
    Fixes: u1TxsBfg36kp
    Fixes: AISLE-2026-0150-00084
    Fixes: assertion failure
    Assertion failure Replicated through UnModified FFmpeg

    Found-by: Joshua Rogers (AISLE)

    The report suggested returning the NAL unit together with the found
    block and inserting into its list, and replacing the assertion by a
    runtime check.

    Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>

diff --git a/libavcodec/bsf/lcevc_metadata.c b/libavcodec/bsf/lcevc_metadata.c
index 4ca4cd6b3d..ac9f459d4a 100644
--- a/libavcodec/bsf/lcevc_metadata.c
+++ b/libavcodec/bsf/lcevc_metadata.c
@@ -51,11 +51,12 @@ static int lcevc_metadata_handle_vui(AVBSFContext *bsf,
     LCEVCRawProcessBlock *block = NULL;
     LCEVCRawAdditionalInfo *ai = &ctx->ai;
     LCEVCRawVUI *vui = &ai->vui;
+    CodedBitstreamUnit *unit;
     int position, err;

     position = ff_cbs_lcevc_find_process_block(ctx->common.output, au,
                                                LCEVC_PAYLOAD_TYPE_GLOBAL_CONFIG,
-                                               &block);
+                                               &unit, &block);
     if (position < 0)
         return 0;

@@ -100,7 +101,7 @@ static int lcevc_metadata_handle_vui(AVBSFContext *bsf,
         vui->chroma_sample_loc_type_bottom_field = ctx->chroma_sample_loc_type;
     }

-    err = ff_cbs_lcevc_add_process_block(ctx->common.output, au, position + 1,
+    err = ff_cbs_lcevc_add_process_block(ctx->common.output, unit, position + 1,
                                          LCEVC_PAYLOAD_TYPE_ADDITIONAL_INFO,
                                          ai, NULL);
     if (err < 0)
diff --git a/libavcodec/cbs_lcevc.c b/libavcodec/cbs_lcevc.c
index 52337cad25..0beae6f6f1 100644
--- a/libavcodec/cbs_lcevc.c
+++ b/libavcodec/cbs_lcevc.c
@@ -608,14 +608,13 @@ static int cbs_lcevc_get_process_block_list(CodedBitstreamContext *ctx,
 }

 int ff_cbs_lcevc_add_process_block(CodedBitstreamContext *ctx,
-                                   CodedBitstreamFragment *au,
+                                   CodedBitstreamUnit *unit,
                                    int position,
                                    uint32_t     payload_type,
                                    void        *payload_data,
                                    void        *payload_ref)
 {
     const LCEVCProcessBlockTypeDescriptor *desc;
-    CodedBitstreamUnit *unit = NULL;
     LCEVCRawProcessBlockList *list;
     LCEVCRawProcessBlock *block;
     int err;
@@ -624,16 +623,6 @@ int ff_cbs_lcevc_add_process_block(CodedBitstreamContext *ctx,
     if (!desc)
         return AVERROR(EINVAL);

-    for (int i = 0; i < au->nb_units; i++) {
-        if (au->units[i].type == LCEVC_NON_IDR_NUT ||
-            au->units[i].type == LCEVC_IDR_NUT) {
-            unit = &au->units[i];
-            break;
-        }
-    }
-    if (!unit)
-        return AVERROR(EINVAL);
-
     // Find the block list inside the codec-dependent unit.
     err = cbs_lcevc_get_process_block_list(ctx, unit, &list);
     if (err < 0)
@@ -662,6 +651,7 @@ int ff_cbs_lcevc_add_process_block(CodedBitstreamContext *ctx,
 int ff_cbs_lcevc_find_process_block(CodedBitstreamContext *ctx,
                                     CodedBitstreamFragment *au,
                                     uint32_t payload_type,
+                                    CodedBitstreamUnit **block_unit,
                                     LCEVCRawProcessBlock **iter)
 {
     int err, found;
@@ -684,6 +674,8 @@ int ff_cbs_lcevc_find_process_block(CodedBitstreamContext *ctx,
             if (block->payload_type == payload_type) {
                 if (!*iter || found) {
                     *iter = block;
+                    if (block_unit)
+                        *block_unit = unit;
                     return j;
                 }
                 if (block == *iter)
diff --git a/libavcodec/cbs_lcevc.h b/libavcodec/cbs_lcevc.h
index 0dde83a299..2f7793f48f 100644
--- a/libavcodec/cbs_lcevc.h
+++ b/libavcodec/cbs_lcevc.h
@@ -272,16 +272,15 @@ int ff_cbs_lcevc_list_add(LCEVCRawProcessBlockList *list, int position);
 void ff_cbs_lcevc_free_process_block_list(LCEVCRawProcessBlockList *list);

 /**
- * Add a process block to an access unit.
- *
- * An existing NAL unit of type IDR or NON_IDR are required.
+ * Add a process block to a NAL unit of type IDR or NON_IDR, at the given
+ * position of its block list or at the end if position is -1.
  *
  * If set, payload_ref must be a RefStruct reference backing payload_data.
  * This function creates a new reference to payload_ref in this case.
  * If payload_ref is NULL, the new message will not be reference counted.
  */
 int ff_cbs_lcevc_add_process_block(CodedBitstreamContext *ctx,
-                                   CodedBitstreamFragment *au,
+                                   CodedBitstreamUnit *unit,
                                    int position,
                                    uint32_t     payload_type,
                                    void        *payload_data,
@@ -290,12 +289,14 @@ int ff_cbs_lcevc_add_process_block(CodedBitstreamContext *ctx,
 /**
  * Iterate over blocks with the given payload type in an access unit.
  *
- * Set block to NULL in the first call. Returns 0 while more blocks
- * are available, AVERROR(ENOENT) when all blocks have been found.
+ * Set block to NULL in the first call. Returns the position of the block in
+ * the block list of its NAL unit, which is stored in block_unit if that is
+ * not NULL, or AVERROR(ENOENT) when all blocks have been found.
  */
 int ff_cbs_lcevc_find_process_block(CodedBitstreamContext *ctx,
                                     CodedBitstreamFragment *au,
                                     uint32_t payload_type,
+                                    CodedBitstreamUnit **block_unit,
                                     LCEVCRawProcessBlock **block);

 /**
diff --git a/libavcodec/lcevcdec.c b/libavcodec/lcevcdec.c
index 066866a75e..e3d28c7a18 100644
--- a/libavcodec/lcevcdec.c
+++ b/libavcodec/lcevcdec.c
@@ -529,7 +529,7 @@ int ff_lcevc_parse_frame(FFLCEVCContext *lcevc, const AVFrame *frame,
     }

     ret = ff_cbs_lcevc_find_process_block(lcevc->cbc, lcevc->frag,
-                                          LCEVC_PAYLOAD_TYPE_GLOBAL_CONFIG, &block);
+                                          LCEVC_PAYLOAD_TYPE_GLOBAL_CONFIG, NULL, &block);
     if (ret < 0) {
         ret = 0;
         goto end;