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.
Showing the changes to libavformat (2 of 2 files). Show all
Unified · Split
| @@ -299,6 +299,7 @@ typedef struct HEIFGrid { · 298 unmodified lines | |||
| 299 | HEIFItem *item; | 299 | HEIFItem *item; |
| 300 | HEIFItem **tile_item_list; | 300 | HEIFItem **tile_item_list; |
| 301 | int16_t *tile_id_list; | 301 | int16_t *tile_id_list; |
| 302 | unsigned *tile_idx_list; | ||
| 302 | int nb_tiles; | 303 | int nb_tiles; |
| 303 | } HEIFGrid; | 304 | } HEIFGrid; |
| 304 | 305 | ||
| @@ -9020,8 +9020,9 @@ static int mov_read_iref_dimg(MOVContext *c, AVIOContext *pb, int version) · 9019 unmodified lines | |||
| 9020 | 9020 | ||
| 9021 | entries = avio_rb16(pb); | 9021 | entries = avio_rb16(pb); |
| 9022 | grid->tile_id_list = av_malloc_array(entries, sizeof(*grid->tile_id_list)); | 9022 | grid->tile_id_list = av_malloc_array(entries, sizeof(*grid->tile_id_list)); |
| 9023 | grid->tile_idx_list = av_calloc(entries, sizeof(*grid->tile_idx_list)); | ||
| 9023 | grid->tile_item_list = av_calloc(entries, sizeof(*grid->tile_item_list)); | 9024 | grid->tile_item_list = av_calloc(entries, sizeof(*grid->tile_item_list)); |
| 9024 | if (!grid->tile_id_list || !grid->tile_item_list) | 9025 | if (!grid->tile_id_list || !grid->tile_item_list || !grid->tile_idx_list) |
| 9025 | return AVERROR(ENOMEM); | 9026 | return AVERROR(ENOMEM); |
| 9026 | /* 'to' item ids */ | 9027 | /* 'to' item ids */ |
| 9027 | for (i = 0; i < entries; i++) | 9028 | for (i = 0; i < entries; i++) |
| @@ -9918,6 +9919,7 @@ static int mov_read_close(AVFormatContext *s) · 890 unmodified lines | |||
| 9918 | av_freep(&mov->heif_item); | 9919 | av_freep(&mov->heif_item); |
| 9919 | for (i = 0; i < mov->nb_heif_grid; i++) { | 9920 | for (i = 0; i < mov->nb_heif_grid; i++) { |
| 9920 | av_freep(&mov->heif_grid[i].tile_id_list); | 9921 | av_freep(&mov->heif_grid[i].tile_id_list); |
| 9922 | av_freep(&mov->heif_grid[i].tile_idx_list); | ||
| 9921 | av_freep(&mov->heif_grid[i].tile_item_list); | 9923 | av_freep(&mov->heif_grid[i].tile_item_list); |
| 9922 | } | 9924 | } |
| 9923 | av_freep(&mov->heif_grid); | 9925 | av_freep(&mov->heif_grid); |
| @@ -10170,7 +10172,7 @@ static int read_image_grid(AVFormatContext *s, const HEIFGrid *grid, · 246 unmodified lines | |||
| 10170 | if (i == tile_grid->nb_tiles) | 10172 | if (i == tile_grid->nb_tiles) |
| 10171 | return AVERROR_INVALIDDATA; | 10173 | return AVERROR_INVALIDDATA; |
| 10172 | 10174 | ||
| 10173 | tile_grid->offsets[i].idx = i; | 10175 | tile_grid->offsets[i].idx = grid->tile_idx_list[i]; |
| 10174 | tile_grid->offsets[i].horizontal = x; | 10176 | tile_grid->offsets[i].horizontal = x; |
| 10175 | tile_grid->offsets[i].vertical = y; | 10177 | tile_grid->offsets[i].vertical = y; |
| 10176 | 10178 | ||
| @@ -10261,7 +10263,7 @@ static int read_image_iovl(AVFormatContext *s, const HEIFGrid *grid, · 84 unmodified lines | |||
| 10261 | } | 10263 | } |
| 10262 | 10264 | ||
| 10263 | for (int i = 0; i < tile_grid->nb_tiles; i++) { | 10265 | for (int i = 0; i < tile_grid->nb_tiles; i++) { |
| 10264 | tile_grid->offsets[i].idx = grid->tile_item_list[i]->st->index; | 10266 | tile_grid->offsets[i].idx = grid->tile_idx_list[i]; |
| 10265 | tile_grid->offsets[i].horizontal = (flags & 1) ? avio_rb32(s->pb) : avio_rb16(s->pb); | 10267 | tile_grid->offsets[i].horizontal = (flags & 1) ? avio_rb32(s->pb) : avio_rb16(s->pb); |
| 10266 | tile_grid->offsets[i].vertical = (flags & 1) ? avio_rb32(s->pb) : avio_rb16(s->pb); | 10268 | tile_grid->offsets[i].vertical = (flags & 1) ? avio_rb32(s->pb) : avio_rb16(s->pb); |
| 10267 | av_log(c->fc, AV_LOG_TRACE, "iovl: stream_idx[%d] %u, " | 10269 | av_log(c->fc, AV_LOG_TRACE, "iovl: stream_idx[%d] %u, " |
| @@ -10313,10 +10315,20 @@ static int mov_parse_tiles(AVFormatContext *s) · 45 unmodified lines | |||
| 10313 | } | 10315 | } |
| 10314 | 10316 | ||
| 10315 | grid->tile_item_list[j] = item; | 10317 | grid->tile_item_list[j] = item; |
| 10318 | grid->tile_idx_list[j] = stg->nb_streams; | ||
| 10316 | 10319 | ||
| 10317 | err = avformat_stream_group_add_stream(stg, st); | 10320 | err = avformat_stream_group_add_stream(stg, st); |
| 10318 | if (err < 0 && err != AVERROR(EEXIST)) | 10321 | if (err < 0) { |
| 10319 | return err; | 10322 | int l; |
| 10323 | if (err != AVERROR(EEXIST)) | ||
| 10324 | return err; | ||
| 10325 | |||
| 10326 | for (l = 0; l < stg->nb_streams; l++) | ||
| 10327 | if (stg->streams[l]->index == st->index) | ||
| 10328 | break; | ||
| 10329 | av_assert0(l < stg->nb_streams); | ||
| 10330 | grid->tile_idx_list[j] = l; | ||
| 10331 | } | ||
| 10320 | 10332 | ||
| 10321 | if (item->item_id != mov->primary_item_id) | 10333 | if (item->item_id != mov->primary_item_id) |
| 10322 | st->disposition |= AV_DISPOSITION_DEPENDENT; | 10334 | st->disposition |= AV_DISPOSITION_DEPENDENT; |