avformat/mov: add support for version 1 of chnl box

Fixes ticket #11183.

Signed-off-by: James Almer <jamrial@gmail.com>
This commit is contained in:
James Almer
2026-06-01 09:53:54 -03:00
parent bf608f16fd
commit cd92ef77c9
4 changed files with 42 additions and 10 deletions
+2 -2
View File
@@ -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;
+37 -6
View File
@@ -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);
}
+2 -1
View File
@@ -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 */
+1 -1
View File
@@ -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, \