[FFmpeg-cvslog] avformat/iamf_parse: add checks to parameter definition durations
James Almer
git at videolan.org
Fri Feb 28 21:28:19 EET 2025
ffmpeg | branch: release/7.0 | James Almer <jamrial at gmail.com> | Wed Dec 11 23:27:00 2024 -0300| [5a8055a58ac7db8bd8837b44ab8e5c02adfb623c] | committer: James Almer
avformat/iamf_parse: add checks to parameter definition durations
Section 3.6.1 of the IAMF spec states "When constant_subblock_duration is equal to 0, the summation of all
subblock_duration in this parameter block SHALL be equal to duration.".
Signed-off-by: James Almer <jamrial at gmail.com>
(cherry picked from commit d38fc25519cf12a9212dadcba1258fc176ffbade)
> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=5a8055a58ac7db8bd8837b44ab8e5c02adfb623c
---
libavformat/iamf_parse.c | 14 ++++++++++++--
libavformat/iamf_reader.c | 15 +++++++++++++--
2 files changed, 25 insertions(+), 4 deletions(-)
diff --git a/libavformat/iamf_parse.c b/libavformat/iamf_parse.c
index 5f2ad9fb5b..8d952cf203 100644
--- a/libavformat/iamf_parse.c
+++ b/libavformat/iamf_parse.c
@@ -498,6 +498,7 @@ static int param_parse(void *s, IAMFContext *c, AVIOContext *pb,
AVIAMFParamDefinition *param;
unsigned int parameter_id, parameter_rate, mode;
unsigned int duration = 0, constant_subblock_duration = 0, nb_subblocks = 0;
+ unsigned int total_duration = 0;
size_t param_size;
parameter_id = ffio_read_leb(pb);
@@ -518,8 +519,10 @@ static int param_parse(void *s, IAMFContext *c, AVIOContext *pb,
constant_subblock_duration = ffio_read_leb(pb);
if (constant_subblock_duration == 0)
nb_subblocks = ffio_read_leb(pb);
- else
+ else {
nb_subblocks = duration / constant_subblock_duration;
+ total_duration = duration;
+ }
}
param = av_iamf_param_definition_alloc(type, nb_subblocks, ¶m_size);
@@ -530,8 +533,10 @@ static int param_parse(void *s, IAMFContext *c, AVIOContext *pb,
void *subblock = av_iamf_param_definition_get_subblock(param, i);
unsigned int subblock_duration = constant_subblock_duration;
- if (constant_subblock_duration == 0)
+ if (constant_subblock_duration == 0) {
subblock_duration = ffio_read_leb(pb);
+ total_duration += subblock_duration;
+ }
switch (type) {
case AV_IAMF_PARAMETER_DEFINITION_MIX_GAIN: {
@@ -559,6 +564,11 @@ static int param_parse(void *s, IAMFContext *c, AVIOContext *pb,
}
}
+ if (!mode && !constant_subblock_duration && total_duration != duration) {
+ av_log(s, AV_LOG_ERROR, "Invalid subblock durations in parameter_id %u\n", parameter_id);
+ return AVERROR_INVALIDDATA;
+ }
+
param->parameter_id = parameter_id;
param->parameter_rate = parameter_rate;
param->duration = duration;
diff --git a/libavformat/iamf_reader.c b/libavformat/iamf_reader.c
index fa825cf287..b43ed76df4 100644
--- a/libavformat/iamf_reader.c
+++ b/libavformat/iamf_reader.c
@@ -108,6 +108,7 @@ static int parameter_block_obu(AVFormatContext *s, IAMFDemuxContext *c,
AVIOContext *pb;
uint8_t *buf;
unsigned int duration, constant_subblock_duration;
+ unsigned int total_duration = 0;
unsigned int nb_subblocks;
unsigned int parameter_id;
size_t out_param_size;
@@ -146,8 +147,10 @@ static int parameter_block_obu(AVFormatContext *s, IAMFDemuxContext *c,
constant_subblock_duration = ffio_read_leb(pb);
if (constant_subblock_duration == 0)
nb_subblocks = ffio_read_leb(pb);
- else
+ else {
nb_subblocks = duration / constant_subblock_duration;
+ total_duration = duration;
+ }
} else {
duration = param->duration;
constant_subblock_duration = param->constant_subblock_duration;
@@ -171,8 +174,10 @@ static int parameter_block_obu(AVFormatContext *s, IAMFDemuxContext *c,
void *subblock = av_iamf_param_definition_get_subblock(out_param, i);
unsigned int subblock_duration = constant_subblock_duration;
- if (!param_definition->mode && !constant_subblock_duration)
+ if (!param_definition->mode && !constant_subblock_duration) {
subblock_duration = ffio_read_leb(pb);
+ total_duration += subblock_duration;
+ }
switch (param->type) {
case AV_IAMF_PARAMETER_DEFINITION_MIX_GAIN: {
@@ -234,6 +239,12 @@ static int parameter_block_obu(AVFormatContext *s, IAMFDemuxContext *c,
av_log(s, level, "Underread in parameter_block_obu. %d bytes left at the end\n", len);
}
+ if (!param_definition->mode && !constant_subblock_duration && total_duration != duration) {
+ av_log(s, AV_LOG_ERROR, "Invalid duration in parameter block\n");
+ ret = AVERROR_INVALIDDATA;
+ goto fail;
+ }
+
switch (param->type) {
case AV_IAMF_PARAMETER_DEFINITION_MIX_GAIN:
av_free(c->mix);
More information about the ffmpeg-cvslog
mailing list