History

avformat/mov: Support multiple thumbnails in HEIF

Prevents ffmpeg/ffprobe from erroring out when reading an HEIF that contains multiple hvcC thumbnails (e.g. from a Nikon Z6III camera). Before, move_read_iref_thmb() would always override the stored thmb_item_id in the MOVContext with each new read thumbnail, causing a stream and item_id mismatch later in mov_parse_heif_items(), resulting in the "HEIF thumbnail doesn't reference a stream" error message. To solve this, - Turn thmb_item_id into an array of IDs because multiple thumbnails can exist - Change check in mov_parse_heif_items() to compare against all stored thumbnail IDs to see if any item missing a stream is in the list of thumbnail IDs.

Eric Joyner committed 1 year ago

Commit fb163eb1 parent 25e710c2 files · +19 −8Browse files

Unified · Split

2 files
  1. libavformat/isom.h +2 −1
  2. libavformat/mov.c +17 −7
libavformat/isom.h+2−1
@@ -376,7 +376,8 @@ typedef struct MOVContext { · 375 unmodified lines
376 int nb_heif_item;376 int nb_heif_item;
377 HEIFGrid *heif_grid;377 HEIFGrid *heif_grid;
378 int nb_heif_grid;378 int nb_heif_grid;
379 int thmb_item_id;379 int* thmb_item_id;
380 int nb_thmb_item;
380 int64_t idat_offset;381 int64_t idat_offset;
381 int interleaved_read;382 int interleaved_read;
382} MOVContext;383} MOVContext;
libavformat/mov.c+17−7
@@ -8972,6 +8972,7 @@ static int mov_read_iref_dimg(MOVContext *c, AVIOContext *pb, int version) · 8971 unmodified lines
8972 8972
8973static int mov_read_iref_thmb(MOVContext *c, AVIOContext *pb, int version)8973static int mov_read_iref_thmb(MOVContext *c, AVIOContext *pb, int version)
8974{8974{
8975 int *thmb_item_id;
8975 int entries;8976 int entries;
8976 int to_item_id, from_item_id = version ? avio_rb32(pb) : avio_rb16(pb);8977 int to_item_id, from_item_id = version ? avio_rb32(pb) : avio_rb16(pb);
8977 8978
@@ -8986,10 +8987,15 @@ static int mov_read_iref_thmb(MOVContext *c, AVIOContext *pb, int version) · 8 unmodified lines
8986 if (to_item_id != c->primary_item_id)8987 if (to_item_id != c->primary_item_id)
8987 return 0;8988 return 0;
8988 8989
8989 c->thmb_item_id = from_item_id;8990 /* Put thumnbail IDs into an array */
8991 thmb_item_id = av_dynarray2_add((void **)&c->thmb_item_id, &c->nb_thmb_item,
8992 sizeof(*c->thmb_item_id),
8993 (const void *)&from_item_id);
8994 if (!thmb_item_id)
8995 return AVERROR(ENOMEM);
8990 8996
8991 av_log(c->fc, AV_LOG_TRACE, "thmb: from_item_id %d, entries %d\n",8997 av_log(c->fc, AV_LOG_TRACE, "thmb: from_item_id %d, entries %d, nb_thmb: %d\n",
8992 from_item_id, entries);8998 from_item_id, entries, c->nb_thmb_item);
8993 8999
8994 return 0;9000 return 0;
8995}9001}
@@ -9859,6 +9865,7 @@ static int mov_read_close(AVFormatContext *s) · 863 unmodified lines
9859 av_freep(&mov->heif_grid[i].tile_item_list);9865 av_freep(&mov->heif_grid[i].tile_item_list);
9860 }9866 }
9861 av_freep(&mov->heif_grid);9867 av_freep(&mov->heif_grid);
9868 av_freep(&mov->thmb_item_id);
9862 9869
9863 return 0;9870 return 0;
9864}9871}
@@ -10323,9 +10330,12 @@ static int mov_parse_heif_items(AVFormatContext *s) · 458 unmodified lines
10323 if (!item)10330 if (!item)
10324 continue;10331 continue;
10325 if (!item->st) {10332 if (!item->st) {
10326 if (item->item_id == mov->thmb_item_id) {10333 for (int j = 0; j < mov->nb_thmb_item; j++) {
10327 av_log(s, AV_LOG_ERROR, "HEIF thumbnail doesn't reference a stream\n");10334 if (item->item_id == mov->thmb_item_id[j]) {
10328 return AVERROR_INVALIDDATA;10335 av_log(s, AV_LOG_ERROR, "HEIF thumbnail ID %d doesn't reference a stream\n",
10336 item->item_id);
10337 return AVERROR_INVALIDDATA;
10338 }
10329 }10339 }
10330 continue;10340 continue;
10331 }10341 }
@@ -10476,7 +10486,7 @@ static int mov_read_header(AVFormatContext *s) · 144 unmodified lines
10476 10486
10477 mov->fc = s;10487 mov->fc = s;
10478 mov->trak_index = -1;10488 mov->trak_index = -1;
10479 mov->thmb_item_id = -1;10489 mov->thmb_item_id = NULL;
10480 mov->primary_item_id = -1;10490 mov->primary_item_id = -1;
10481 mov->cur_item_id = -1;10491 mov->cur_item_id = -1;
10482 /* .mov and .mp4 aren't streamable anyway (only progressive download if moov is before mdat) */10492 /* .mov and .mp4 aren't streamable anyway (only progressive download if moov is before mdat) */

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t