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;