avformat/mov: split off heif item initialization to its own function

Signed-off-by: James Almer <jamrial@gmail.com>
(cherry picked from commit d5eb0e7fb3)
This commit is contained in:
James Almer 2024-10-05 10:32:14 -03:00
parent 779b0fe015
commit 23697c3f02
1 changed files with 55 additions and 43 deletions

View File

@ -10072,6 +10072,58 @@ static int mov_parse_tiles(AVFormatContext *s)
return 0;
}
static int mov_parse_heif_items(AVFormatContext *s)
{
MOVContext *mov = s->priv_data;
int err;
for (int i = 0; i < mov->nb_heif_item; i++) {
HEIFItem *item = &mov->heif_item[i];
MOVStreamContext *sc;
AVStream *st;
int64_t offset = 0;
if (!item->st) {
if (item->item_id == mov->thmb_item_id) {
av_log(s, AV_LOG_ERROR, "HEIF thumbnail doesn't reference a stream\n");
return AVERROR_INVALIDDATA;
}
continue;
}
if (item->is_idat_relative) {
if (!mov->idat_offset) {
av_log(s, AV_LOG_ERROR, "Missing idat box for item %d\n", item->item_id);
return AVERROR_INVALIDDATA;
}
offset = mov->idat_offset;
}
st = item->st;
sc = st->priv_data;
st->codecpar->width = item->width;
st->codecpar->height = item->height;
if (sc->sample_count != 1 || sc->chunk_count != 1)
return AVERROR_INVALIDDATA;
sc->sample_sizes[0] = item->extent_length;
sc->chunk_offsets[0] = item->extent_offset + offset;
if (item->item_id == mov->primary_item_id)
st->disposition |= AV_DISPOSITION_DEFAULT;
mov_build_index(mov, st);
}
if (mov->nb_heif_grid) {
err = mov_parse_tiles(s);
if (err < 0)
return err;
}
return 0;
}
static AVStream *mov_find_reference_track(AVFormatContext *s, AVStream *st,
int first_index)
{
@ -10129,49 +10181,9 @@ static int mov_read_header(AVFormatContext *s)
av_log(mov->fc, AV_LOG_TRACE, "on_parse_exit_offset=%"PRId64"\n", avio_tell(pb));
if (mov->found_iloc && mov->found_iinf) {
for (i = 0; i < mov->nb_heif_item; i++) {
HEIFItem *item = &mov->heif_item[i];
MOVStreamContext *sc;
AVStream *st;
int64_t offset = 0;
if (!item->st) {
if (item->item_id == mov->thmb_item_id) {
av_log(s, AV_LOG_ERROR, "HEIF thumbnail doesn't reference a stream\n");
return AVERROR_INVALIDDATA;
}
continue;
}
if (item->is_idat_relative) {
if (!mov->idat_offset) {
av_log(s, AV_LOG_ERROR, "Missing idat box for item %d\n", item->item_id);
return AVERROR_INVALIDDATA;
}
offset = mov->idat_offset;
}
st = item->st;
sc = st->priv_data;
st->codecpar->width = item->width;
st->codecpar->height = item->height;
if (sc->sample_count != 1 || sc->chunk_count != 1)
return AVERROR_INVALIDDATA;
sc->sample_sizes[0] = item->extent_length;
sc->chunk_offsets[0] = item->extent_offset + offset;
if (item->item_id == mov->primary_item_id)
st->disposition |= AV_DISPOSITION_DEFAULT;
mov_build_index(mov, st);
}
if (mov->nb_heif_grid) {
err = mov_parse_tiles(s);
if (err < 0)
return err;
}
err = mov_parse_heif_items(s);
if (err < 0)
return err;
}
// prevent iloc and iinf boxes from being parsed while reading packets.
// this is needed because an iinf box may have been parsed but ignored