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
376376 int nb_heif_item;
377377 HEIFGrid *heif_grid;
378378 int nb_heif_grid;
379− int thmb_item_id;
379+ int* thmb_item_id;
380+ int nb_thmb_item;
380381 int64_t idat_offset;
381382 int interleaved_read;
382383 } 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
89728972
89738973 static int mov_read_iref_thmb(MOVContext *c, AVIOContext *pb, int version)
89748974 {
8975+ int *thmb_item_id;
89758976 int entries;
89768977 int to_item_id, from_item_id = version ? avio_rb32(pb) : avio_rb16(pb);
89778978
@@ -8986,10 +8987,15 @@ static int mov_read_iref_thmb(MOVContext *c, AVIOContext *pb, int version) · 8 unmodified lines
89868987 if (to_item_id != c->primary_item_id)
89878988 return 0;
89888989
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);
89908996
8991− av_log(c->fc, AV_LOG_TRACE, "thmb: from_item_id %d, entries %d\n",
8992− from_item_id, entries);
8997+ av_log(c->fc, AV_LOG_TRACE, "thmb: from_item_id %d, entries %d, nb_thmb: %d\n",
8998+ from_item_id, entries, c->nb_thmb_item);
89938999
89949000 return 0;
89959001 }
@@ -9859,6 +9865,7 @@ static int mov_read_close(AVFormatContext *s) · 863 unmodified lines
98599865 av_freep(&mov->heif_grid[i].tile_item_list);
98609866 }
98619867 av_freep(&mov->heif_grid);
9868+ av_freep(&mov->thmb_item_id);
98629869
98639870 return 0;
98649871 }
@@ -10323,9 +10330,12 @@ static int mov_parse_heif_items(AVFormatContext *s) · 458 unmodified lines
1032310330 if (!item)
1032410331 continue;
1032510332 if (!item->st) {
10326− if (item->item_id == mov->thmb_item_id) {
10327− av_log(s, AV_LOG_ERROR, "HEIF thumbnail doesn't reference a stream\n");
10328− return AVERROR_INVALIDDATA;
10333+ for (int j = 0; j < mov->nb_thmb_item; j++) {
10334+ if (item->item_id == mov->thmb_item_id[j]) {
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+ }
1032910339 }
1033010340 continue;
1033110341 }
@@ -10476,7 +10486,7 @@ static int mov_read_header(AVFormatContext *s) · 144 unmodified lines
1047610486
1047710487 mov->fc = s;
1047810488 mov->trak_index = -1;
10479− mov->thmb_item_id = -1;
10489+ mov->thmb_item_id = NULL;
1048010490 mov->primary_item_id = -1;
1048110491 mov->cur_item_id = -1;
1048210492 /* .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