PR #25304 opened by Marti2203 URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/25304 Patch URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/25304.patch
`mov_update_iamf_streams()` looks up the stream group of each IAMF audio element by comparing only the group id, and keeps the last match. Mix presentation groups are created after the audio element groups and get the `mix_presentation_id` as their id, so when a mix presentation id equals an audio element id, the mix presentation group is picked instead. Its entries are the streams of all audio elements, so the same stream gets its index entries copied twice and `av_assert0(!out_sti->index_entries)` aborts ffprobe and ffmpeg. The file can be written by FFmpeg's own mp4 muxer: two audio elements with ids 1 and 2 and a mix presentation with id 1. ``` ffmpeg -f lavfi -i sine=d=1 -f lavfi -i sine=f=880:d=1 \ -stream_group "type=iamf_audio_element:id=1:st=0,layer=ch_layout=mono" \ -stream_group "type=iamf_audio_element:id=2:st=1,layer=ch_layout=mono" \ -stream_group "type=iamf_mix_presentation:id=1:stg=0:stg=1,submix=parameter_id=100:parameter_rate=48000:default_mix_gain=0.0|element=stg=0:parameter_id=101:parameter_rate=48000:headphones_rendering_mode=stereo|element=stg=1:parameter_id=102:parameter_rate=48000:headphones_rendering_mode=stereo|layout=sound_system=stereo" \ -map 0 -map 1 -streamid 0:0 -streamid 1:1 -c:a flac -t 1 mix1.mp4 ffprobe mix1.mp4 Assertion !out_sti->index_entries failed at libavformat/mov.c:5543 Aborted (core dumped) ``` With mix presentation id 3 the same file probes fine. The lookup of the audio elements of a submix in `mov_read_iacb()` already checks for `AV_STREAM_GROUP_PARAMS_IAMF_AUDIO_ELEMENT` and breaks on the first match; the patch does the same here. With it, the file above probes and decodes with `-map 0 -f null -`, and the groups and stream durations are the same as for the id 3 file. The second commit adds `fate-mov-mp4-iamf-stereo-id-collision`, which muxes two audio elements and a mix presentation with colliding ids from `asynth-44100-2.wav` and demuxes/probes the result, so no samples are needed. It aborts with exit code 134 on master and passes with the fix. `fate-iamf` (including its sample tests) and `fate-mov` pass, apart from 33 mov tests whose samples (heif, avif, cenc, ...) I did not have locally. Open PR #24256 changes the ids of other mov stream groups to sequential values, but leaves the IAMF ones alone, so it does not cover this case. This issue was found by an LLM-Enhanced Static Analysis Engine and verified manually. 🤖 Generated with [Claude Code](https://claude.com/claude-code) From 4acb7b826f1120527020c41d6cabd2acf1a69cde Mon Sep 17 00:00:00 2001 From: Martin Mirchev <[email protected]> Date: Wed, 21 Oct 2026 19:01:04 +0800 Subject: [PATCH 1/2] avformat/mov: check the stream group type when updating IAMF streams The lookup of the stream group for each IAMF audio element compared only the group id and kept the last match. Mix presentation groups are created after the audio element groups and use the mix_presentation_id as their id, so if a mix_presentation_id equals an audio_element_id the mix presentation group was picked instead. Its entries are the streams of every audio element, so the same output stream got its index entries filled twice and the av_assert0(!out_sti->index_entries) aborted. Such files are written by FFmpeg's own mp4 muxer, e.g. with two audio elements with ids 1 and 2 and a mix presentation with id 1. Check the group type and stop at the first match, as is already done when looking up the audio elements of a mix presentation submix. Signed-off-by: Martin Mirchev <[email protected]> --- libavformat/mov.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/libavformat/mov.c b/libavformat/mov.c index 910df844dce..aef265b5315 100644 --- a/libavformat/mov.c +++ b/libavformat/mov.c @@ -5520,8 +5520,11 @@ static int mov_update_iamf_streams(MOVContext *c, const AVStream *st) const AVStreamGroup *stg = NULL; for (int j = 0; j < c->fc->nb_stream_groups; j++) - if (c->fc->stream_groups[j]->id == iamf->audio_elements[i]->audio_element_id) + if (c->fc->stream_groups[j]->type == AV_STREAM_GROUP_PARAMS_IAMF_AUDIO_ELEMENT && + c->fc->stream_groups[j]->id == iamf->audio_elements[i]->audio_element_id) { stg = c->fc->stream_groups[j]; + break; + } av_assert0(stg); for (int j = 0; j < stg->nb_entries; j++) { -- 2.54.0 From 61a04e802d4ab938006899e9a6c9d3086968198c Mon Sep 17 00:00:00 2001 From: Martin Mirchev <[email protected]> Date: Wed, 21 Oct 2026 19:01:48 +0800 Subject: [PATCH 2/2] tests/fate/mov: add a test for IAMF stream group id collisions Mux two IAMF audio elements with ids 1 and 2 and a mix presentation with id 1 into mp4, then demux and probe the result. Without the previous commit the mov demuxer aborts on an assertion when reading this file. Signed-off-by: Martin Mirchev <[email protected]> --- tests/fate/mov.mak | 11 +++ .../ref/fate/mov-mp4-iamf-stereo-id-collision | 84 +++++++++++++++++++ tests/streamgroups/audio_element-stereo-2 | 2 + .../streamgroups/mix_presentation-stereo-id-1 | 2 + 4 files changed, 99 insertions(+) create mode 100644 tests/ref/fate/mov-mp4-iamf-stereo-id-collision create mode 100644 tests/streamgroups/audio_element-stereo-2 create mode 100644 tests/streamgroups/mix_presentation-stereo-id-1 diff --git a/tests/fate/mov.mak b/tests/fate/mov.mak index 3550e1d7b81..0ef4c2c4d5e 100644 --- a/tests/fate/mov.mak +++ b/tests/fate/mov.mak @@ -483,6 +483,17 @@ fate-mov-mp4-iamf-stereo: CMD = transcode wav $(SRC) mp4 " \ -streamid 0:0 -c:a flac -t 1" "-c:a copy -map 0" \ "-show_entries stream_group=index,id,nb_streams,type:stream_group_components:stream_group_disposition:stream_group_tags:stream_group_stream=index,id:stream_group_stream_disposition" +# Two audio elements and a mix presentation whose id equals the id of the first audio element. +FATE_MOV_FFMPEG_FFPROBE-$(call TRANSCODE, FLAC, MP4 MOV, WAV_DEMUXER PCM_S16LE_DECODER) += fate-mov-mp4-iamf-stereo-id-collision +fate-mov-mp4-iamf-stereo-id-collision: tests/data/asynth-44100-2.wav tests/data/streamgroups/audio_element-stereo tests/data/streamgroups/audio_element-stereo-2 tests/data/streamgroups/mix_presentation-stereo-id-1 +fate-mov-mp4-iamf-stereo-id-collision: SRC = $(TARGET_PATH)/tests/data/asynth-44100-2.wav +fate-mov-mp4-iamf-stereo-id-collision: CMD = transcode wav $(SRC) mp4 " \ + -/stream_group $(TARGET_PATH)/tests/data/streamgroups/audio_element-stereo \ + -/stream_group $(TARGET_PATH)/tests/data/streamgroups/audio_element-stereo-2 \ + -/stream_group $(TARGET_PATH)/tests/data/streamgroups/mix_presentation-stereo-id-1 \ + -map 0:a -map 0:a -streamid 0:0 -streamid 1:1 -c:a flac -t 1" "-c:a copy -map 0" \ + "-show_entries stream_group=index,id,nb_streams,type:stream_group_stream=index,id:stream=index,id,duration_ts" + FATE_MOV_FFMPEG_FFPROBE-$(call TRANSCODE, FLAC, MP4 MOV, WAV_DEMUXER PCM_S16LE_DECODER ARESAMPLE_FILTER) += fate-mov-mp4-iamf-5_1_4 fate-mov-mp4-iamf-5_1_4: tests/data/asynth-44100-10.wav tests/data/filtergraphs/iamf_5_1_4 tests/data/streamgroups/audio_element-5_1_4 tests/data/streamgroups/mix_presentation-5_1_4 fate-mov-mp4-iamf-5_1_4: SRC = $(TARGET_PATH)/tests/data/asynth-44100-10.wav diff --git a/tests/ref/fate/mov-mp4-iamf-stereo-id-collision b/tests/ref/fate/mov-mp4-iamf-stereo-id-collision new file mode 100644 index 00000000000..c3a6d51cc5c --- /dev/null +++ b/tests/ref/fate/mov-mp4-iamf-stereo-id-collision @@ -0,0 +1,84 @@ +0587a41960832c1797fe25162b953a4c *tests/data/fate/mov-mp4-iamf-stereo-id-collision.mp4 +29293 tests/data/fate/mov-mp4-iamf-stereo-id-collision.mp4 +#extradata 0: 34, 0xa77c0cd6 +#extradata 1: 34, 0xa77c0cd6 +#tb 0: 1/44100 +#media_type 0: audio +#codec_id 0: flac +#sample_rate 0: 44100 +#channel_layout_name 0: stereo +#tb 1: 1/44100 +#media_type 1: audio +#codec_id 1: flac +#sample_rate 1: 44100 +#channel_layout_name 1: stereo +0, 0, 0, 4096, 1323, 0xb9bc0f9a +1, 0, 0, 4096, 1323, 0xb9bc0f9a +0, 4096, 4096, 4096, 1254, 0xf7e910bc +1, 4096, 4096, 4096, 1254, 0xf7e910bc +0, 8192, 8192, 4096, 1320, 0xe4fe09c9 +1, 8192, 8192, 4096, 1320, 0xe4fe09c9 +0, 12288, 12288, 4096, 1280, 0x22e9127e +1, 12288, 12288, 4096, 1280, 0x22e9127e +0, 16384, 16384, 4096, 1331, 0x8bc61bbf +1, 16384, 16384, 4096, 1331, 0x8bc61bbf +0, 20480, 20480, 4096, 1267, 0x2c4708fa +1, 20480, 20480, 4096, 1267, 0x2c4708fa +0, 24576, 24576, 4096, 1282, 0x0438152d +1, 24576, 24576, 4096, 1282, 0x0438152d +0, 28672, 28672, 4096, 1313, 0x2e79ffa2 +1, 28672, 28672, 4096, 1313, 0x2e79ffa2 +0, 32768, 32768, 4096, 1323, 0xb9f70fce +1, 32768, 32768, 4096, 1323, 0xb9f70fce +0, 36864, 36864, 4096, 1254, 0xf6f01051 +1, 36864, 36864, 4096, 1254, 0xf6f01051 +0, 40960, 40960, 4096, 1235, 0xcf181f77, S=1, Skip Samples, 10, 0x047700bf +1, 40960, 40960, 4096, 1235, 0xcf181f77, S=1, Skip Samples, 10, 0x047700bf +[STREAM_GROUP] +index=0 +id=0x1 +nb_streams=1 +type=IAMF Audio Element +[STREAM] +index=0 +id=0x0 +duration_ts=44100 +[/STREAM] +[/STREAM_GROUP] +[STREAM_GROUP] +index=1 +id=0x2 +nb_streams=1 +type=IAMF Audio Element +[STREAM] +index=1 +id=0x1 +duration_ts=44100 +[/STREAM] +[/STREAM_GROUP] +[STREAM_GROUP] +index=2 +id=0x1 +nb_streams=2 +type=IAMF Mix Presentation +[STREAM] +index=0 +id=0x0 +duration_ts=44100 +[/STREAM] +[STREAM] +index=1 +id=0x1 +duration_ts=44100 +[/STREAM] +[/STREAM_GROUP] +[STREAM] +index=0 +id=0x0 +duration_ts=44100 +[/STREAM] +[STREAM] +index=1 +id=0x1 +duration_ts=44100 +[/STREAM] diff --git a/tests/streamgroups/audio_element-stereo-2 b/tests/streamgroups/audio_element-stereo-2 new file mode 100644 index 00000000000..c935ebf99c5 --- /dev/null +++ b/tests/streamgroups/audio_element-stereo-2 @@ -0,0 +1,2 @@ +type=iamf_audio_element:id=2:st=1, +layer=ch_layout=stereo, diff --git a/tests/streamgroups/mix_presentation-stereo-id-1 b/tests/streamgroups/mix_presentation-stereo-id-1 new file mode 100644 index 00000000000..93333a87169 --- /dev/null +++ b/tests/streamgroups/mix_presentation-stereo-id-1 @@ -0,0 +1,2 @@ +type=iamf_mix_presentation:id=1:stg=0:stg=1, +submix=parameter_id=100:parameter_rate=48000:default_mix_gain=1.0|element=stg=0:parameter_id=101:parameter_rate=48000:headphones_rendering_mode=stereo|element=stg=1:parameter_id=102:parameter_rate=48000:headphones_rendering_mode=stereo|layout=sound_system=stereo, -- 2.54.0 _______________________________________________ ffmpeg-devel mailing list -- [email protected] To unsubscribe send an email to [email protected]
