aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJames Almer <jamrial@gmail.com>2025-01-01 13:31:25 -0300
committerJames Almer <jamrial@gmail.com>2025-01-05 00:31:58 -0300
commitbf0786d9bde6fc16239ebcf68c85fffd34f9d874 (patch)
tree24c94048b8aa1795b0fb82ad0cf103cbe454974c
parentcd174c7c7c5849727f45b7d7d263810ddf9b9cba (diff)
downloadffmpeg-bf0786d9bde6fc16239ebcf68c85fffd34f9d874.tar.gz
avformat/mov: fix setting tile grid stream offsets when a stream is referenced more than once
The amount of tiles does not necessarely need to match the amount of streams referenced in the grid, as there could be duplicates. Don't silently ignore EEXIST return codes from avformat_stream_group_add_stream() and instead store the index of the duplicate stream. Signed-off-by: James Almer <jamrial@gmail.com>
-rw-r--r--libavformat/isom.h1
-rw-r--r--libavformat/mov.c22
2 files changed, 18 insertions, 5 deletions
diff --git a/libavformat/isom.h b/libavformat/isom.h
index f18b15bbff..767babf749 100644
--- a/libavformat/isom.h
+++ b/libavformat/isom.h
@@ -299,6 +299,7 @@ typedef struct HEIFGrid {
HEIFItem *item;
HEIFItem **tile_item_list;
int16_t *tile_id_list;
+ unsigned *tile_idx_list;
int nb_tiles;
} HEIFGrid;
diff --git a/libavformat/mov.c b/libavformat/mov.c
index 93e1cebe65..a881acf99d 100644
--- a/libavformat/mov.c
+++ b/libavformat/mov.c
@@ -9020,8 +9020,9 @@ static int mov_read_iref_dimg(MOVContext *c, AVIOContext *pb, int version)
entries = avio_rb16(pb);
grid->tile_id_list = av_malloc_array(entries, sizeof(*grid->tile_id_list));
+ grid->tile_idx_list = av_calloc(entries, sizeof(*grid->tile_idx_list));
grid->tile_item_list = av_calloc(entries, sizeof(*grid->tile_item_list));
- if (!grid->tile_id_list || !grid->tile_item_list)
+ if (!grid->tile_id_list || !grid->tile_item_list || !grid->tile_idx_list)
return AVERROR(ENOMEM);
/* 'to' item ids */
for (i = 0; i < entries; i++)
@@ -9918,6 +9919,7 @@ static int mov_read_close(AVFormatContext *s)
av_freep(&mov->heif_item);
for (i = 0; i < mov->nb_heif_grid; i++) {
av_freep(&mov->heif_grid[i].tile_id_list);
+ av_freep(&mov->heif_grid[i].tile_idx_list);
av_freep(&mov->heif_grid[i].tile_item_list);
}
av_freep(&mov->heif_grid);
@@ -10170,7 +10172,7 @@ static int read_image_grid(AVFormatContext *s, const HEIFGrid *grid,
if (i == tile_grid->nb_tiles)
return AVERROR_INVALIDDATA;
- tile_grid->offsets[i].idx = i;
+ tile_grid->offsets[i].idx = grid->tile_idx_list[i];
tile_grid->offsets[i].horizontal = x;
tile_grid->offsets[i].vertical = y;
@@ -10261,7 +10263,7 @@ static int read_image_iovl(AVFormatContext *s, const HEIFGrid *grid,
}
for (int i = 0; i < tile_grid->nb_tiles; i++) {
- tile_grid->offsets[i].idx = grid->tile_item_list[i]->st->index;
+ tile_grid->offsets[i].idx = grid->tile_idx_list[i];
tile_grid->offsets[i].horizontal = (flags & 1) ? avio_rb32(s->pb) : avio_rb16(s->pb);
tile_grid->offsets[i].vertical = (flags & 1) ? avio_rb32(s->pb) : avio_rb16(s->pb);
av_log(c->fc, AV_LOG_TRACE, "iovl: stream_idx[%d] %u, "
@@ -10313,10 +10315,20 @@ static int mov_parse_tiles(AVFormatContext *s)
}
grid->tile_item_list[j] = item;
+ grid->tile_idx_list[j] = stg->nb_streams;
err = avformat_stream_group_add_stream(stg, st);
- if (err < 0 && err != AVERROR(EEXIST))
- return err;
+ if (err < 0) {
+ int l;
+ if (err != AVERROR(EEXIST))
+ return err;
+
+ for (l = 0; l < stg->nb_streams; l++)
+ if (stg->streams[l]->index == st->index)
+ break;
+ av_assert0(l < stg->nb_streams);
+ grid->tile_idx_list[j] = l;
+ }
if (item->item_id != mov->primary_item_id)
st->disposition |= AV_DISPOSITION_DEPENDENT;