From cd92ef77c95d3483b29089d09142bc1eb0b1df2b Mon Sep 17 00:00:00 2001 From: James Almer Date: Thu, 28 May 2026 12:03:01 -0300 Subject: [PATCH] avformat/mov: add support for version 1 of chnl box Fixes ticket #11183. Signed-off-by: James Almer --- libavformat/mov.c | 4 ++-- libavformat/mov_chan.c | 43 ++++++++++++++++++++++++++++++++++++------ libavformat/mov_chan.h | 3 ++- libavformat/version.h | 2 +- 4 files changed, 42 insertions(+), 10 deletions(-) diff --git a/libavformat/mov.c b/libavformat/mov.c index 3ab73d8747..5f8be009c4 100644 --- a/libavformat/mov.c +++ b/libavformat/mov.c @@ -1237,14 +1237,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 e45b58af24..bfe566e74e 100644 --- a/libavformat/mov_chan.c +++ b/libavformat/mov_chan.c @@ -752,11 +752,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); @@ -766,6 +773,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) @@ -795,16 +809,33 @@ 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); + + if (version == 1) + obj_count = base_channel_count - st->codecpar->ch_layout.nb_channels; } } // 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 */ diff --git a/libavformat/version.h b/libavformat/version.h index e063e12b98..bbb2fc7d87 100644 --- a/libavformat/version.h +++ b/libavformat/version.h @@ -32,7 +32,7 @@ #include "version_major.h" #define LIBAVFORMAT_VERSION_MINOR 19 -#define LIBAVFORMAT_VERSION_MICRO 100 +#define LIBAVFORMAT_VERSION_MICRO 101 #define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \ LIBAVFORMAT_VERSION_MINOR, \