PR #23264 opened by James Almer (jamrial) URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/23264 Patch URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/23264.patch
Fixes ticket #11183 >From 56a5e670ea53b7e8cf5cdd51fe6341cfd6675165 Mon Sep 17 00:00:00 2001 From: James Almer <[email protected]> Date: Thu, 28 May 2026 12:03:01 -0300 Subject: [PATCH 1/2] avformat/mov: add support for version 1 of chnl box Fixes ticket #11183. Signed-off-by: James Almer <[email protected]> --- libavformat/mov.c | 4 ++-- libavformat/mov_chan.c | 40 ++++++++++++++++++++++++++++++++++------ libavformat/mov_chan.h | 3 ++- 3 files changed, 38 insertions(+), 9 deletions(-) diff --git a/libavformat/mov.c b/libavformat/mov.c index d0d4910676..d8e4d1399f 100644 --- a/libavformat/mov.c +++ b/libavformat/mov.c @@ -1236,14 +1236,14 @@ static int mov_read_chnl(MOVContext *c, AVIOContext *pb, MOVAtom atom) version = avio_r8(pb); flags = avio_rb24(pb); - if (version != 0 || flags != 0) { + if (version > 1 || flags != 0) { av_log(c->fc, AV_LOG_ERROR, "Unsupported 'chnl' box with version %d, flags: %#x", version, flags); return AVERROR_INVALIDDATA; } - ret = ff_mov_read_chnl(c->fc, pb, st); + ret = ff_mov_read_chnl(c->fc, pb, st, version); if (ret < 0) return ret; diff --git a/libavformat/mov_chan.c b/libavformat/mov_chan.c index befe6ebc86..bba185742f 100644 --- a/libavformat/mov_chan.c +++ b/libavformat/mov_chan.c @@ -733,11 +733,18 @@ int ff_mov_get_channel_positions_from_layout(const AVChannelLayout *layout, return 0; } -int ff_mov_read_chnl(AVFormatContext *s, AVIOContext *pb, AVStream *st) +int ff_mov_read_chnl(AVFormatContext *s, AVIOContext *pb, AVStream *st, int version) { int stream_structure = avio_r8(pb); + int base_channel_count; + int obj_count = 0; int ret; + if (version == 1) { + stream_structure >>= 4; + base_channel_count = avio_r8(pb); + } + // stream carries channels if (stream_structure & 1) { int layout = avio_r8(pb); @@ -747,6 +754,13 @@ int ff_mov_read_chnl(AVFormatContext *s, AVIOContext *pb, AVStream *st) AVChannelLayout *ch_layout = &st->codecpar->ch_layout; int nb_channels = ch_layout->nb_channels; + if (version == 1) { + nb_channels = avio_r8(pb); + obj_count = base_channel_count - nb_channels; + if (obj_count < 0) + return AVERROR_INVALIDDATA; + } + av_channel_layout_uninit(ch_layout); ret = av_channel_layout_custom_init(ch_layout, nb_channels); if (ret < 0) @@ -776,16 +790,30 @@ int ff_mov_read_chnl(AVFormatContext *s, AVIOContext *pb, AVStream *st) if (ret < 0) return ret; } else { - uint64_t omitted_channel_map = avio_rb64(pb); - ret = mov_get_channel_layout_from_config(layout, &st->codecpar->ch_layout, omitted_channel_map); - if (ret < 0) - return ret; + uint64_t omitted_channel_map = 0; + int omitted_channel_present = 1, channel_order_definition = 0; + + if (version == 1) { + int byte = avio_r8(pb); + omitted_channel_present = byte & 1; + channel_order_definition = (byte >> 1) & 0x7; + } + + if (omitted_channel_present) + omitted_channel_map = avio_rb64(pb); + if (!channel_order_definition) { + ret = mov_get_channel_layout_from_config(layout, &st->codecpar->ch_layout, omitted_channel_map); + if (ret < 0) + return ret; + } else + av_log(s, AV_LOG_TRACE, "'chnl' with channel_order_definition %d\n", channel_order_definition); } } // stream carries objects if (stream_structure & 2) { - int obj_count = avio_r8(pb); + if (version == 0) + obj_count = avio_r8(pb); av_log(s, AV_LOG_TRACE, "'chnl' with object_count %d\n", obj_count); } diff --git a/libavformat/mov_chan.h b/libavformat/mov_chan.h index b901538279..51f24176f6 100644 --- a/libavformat/mov_chan.h +++ b/libavformat/mov_chan.h @@ -181,8 +181,9 @@ int ff_mov_get_channel_positions_from_layout(const AVChannelLayout *layout, * @param s AVFormatContext * @param pb AVIOContext * @param st The stream to set codec values for + * @param version Version of the tag * @return 0 if ok, or negative AVERROR code on failure */ -int ff_mov_read_chnl(AVFormatContext *s, AVIOContext *pb, AVStream *st); +int ff_mov_read_chnl(AVFormatContext *s, AVIOContext *pb, AVStream *st, int version); #endif /* AVFORMAT_MOV_CHAN_H */ -- 2.52.0 >From 5b07d26be26053bc9c0e964cfffb938cb4f631f6 Mon Sep 17 00:00:00 2001 From: James Almer <[email protected]> Date: Thu, 28 May 2026 12:05:29 -0300 Subject: [PATCH 2/2] avformat/mov: don't abort on unsupported or invalid chnl boxes They are optional and just define a channel layout, which may also be defined by the underlying codec. Signed-off-by: James Almer <[email protected]> --- libavformat/mov.c | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/libavformat/mov.c b/libavformat/mov.c index d8e4d1399f..581850373f 100644 --- a/libavformat/mov.c +++ b/libavformat/mov.c @@ -1236,16 +1236,14 @@ static int mov_read_chnl(MOVContext *c, AVIOContext *pb, MOVAtom atom) version = avio_r8(pb); flags = avio_rb24(pb); - if (version > 1 || flags != 0) { - av_log(c->fc, AV_LOG_ERROR, - "Unsupported 'chnl' box with version %d, flags: %#x", + if (version != 1 || flags != 0) { + av_log(c->fc, AV_LOG_WARNING, + "Unsupported 'chnl' box with version %d, flags: %#x\n", version, flags); - return AVERROR_INVALIDDATA; + return 0; } - ret = ff_mov_read_chnl(c->fc, pb, st, version); - if (ret < 0) - return ret; + ff_mov_read_chnl(c->fc, pb, st, version); if (avio_tell(pb) != end) { av_log(c->fc, AV_LOG_WARNING, "skip %" PRId64 " bytes of unknown data inside chnl\n", -- 2.52.0 _______________________________________________ ffmpeg-devel mailing list -- [email protected] To unsubscribe send an email to [email protected]
