This is an automated email from the git hooks/post-receive script.

Git pushed a commit to branch release/8.0
in repository ffmpeg.

commit 5acd4d17cc272f22de08785491a2e8e14c85cd73
Author:     James Almer <[email protected]>
AuthorDate: Wed Aug 20 17:07:50 2025 -0300
Commit:     James Almer <[email protected]>
CommitDate: Thu Mar 5 23:07:58 2026 -0300

    avformat/mov: make items referencing items generic
    
    Signed-off-by: James Almer <[email protected]>
    (cherry picked from commit 74e430202d933284fc38b591d4b3a12464e8aec6)
---
 libavformat/isom.h |  9 ++++++--
 libavformat/mov.c  | 67 +++++++++++++++++++++++++-----------------------------
 2 files changed, 38 insertions(+), 38 deletions(-)

diff --git a/libavformat/isom.h b/libavformat/isom.h
index 94c9c65989..55bc2827b4 100644
--- a/libavformat/isom.h
+++ b/libavformat/isom.h
@@ -286,8 +286,15 @@ typedef struct MOVStreamContext {
     int iamf_stream_offset;
 } MOVStreamContext;
 
+typedef struct HEIFItemRef {
+    uint32_t type;
+    int item_id;
+} HEIFItemRef;
+
 typedef struct HEIFItem {
     AVStream *st;
+    HEIFItemRef *iref_list;
+    int nb_iref_list;
     char *name;
     int item_id;
     int64_t extent_length;
@@ -376,8 +383,6 @@ typedef struct MOVContext {
     int nb_heif_item;
     HEIFGrid *heif_grid;
     int nb_heif_grid;
-    int* thmb_item_id;
-    int nb_thmb_item;
     int64_t idat_offset;
     int interleaved_read;
 } MOVContext;
diff --git a/libavformat/mov.c b/libavformat/mov.c
index 49498eda77..dc082b3500 100644
--- a/libavformat/mov.c
+++ b/libavformat/mov.c
@@ -188,14 +188,14 @@ static int mov_read_mac_string(MOVContext *c, AVIOContext 
*pb, int len,
 }
 
 /**
- * Get the current item in the parsing process.
+ * Get the requested item.
  */
-static HEIFItem *heif_cur_item(MOVContext *c)
+static HEIFItem *get_heif_item(MOVContext *c, unsigned id)
 {
     HEIFItem *item = NULL;
 
     for (int i = 0; i < c->nb_heif_item; i++) {
-        if (!c->heif_item[i] || c->heif_item[i]->item_id != c->cur_item_id)
+        if (!c->heif_item[i] || c->heif_item[i]->item_id != id)
             continue;
 
         item = c->heif_item[i];
@@ -220,7 +220,7 @@ static AVStream *get_curr_st(MOVContext *c)
     if (c->cur_item_id == -1)
         return c->fc->streams[c->fc->nb_streams-1];
 
-    item = heif_cur_item(c);
+    item = get_heif_item(c, c->cur_item_id);
     if (item)
         st = item->st;
 
@@ -1245,7 +1245,7 @@ static int mov_read_clap(MOVContext *c, AVIOContext *pb, 
MOVAtom atom)
     AVRational pc_x, pc_y;
     uint64_t top, bottom, left, right;
 
-    item = heif_cur_item(c);
+    item = get_heif_item(c, c->cur_item_id);
     st = get_curr_st(c);
     if (!st)
         return 0;
@@ -2078,7 +2078,7 @@ static int mov_read_colr(MOVContext *c, AVIOContext *pb, 
MOVAtom atom)
 
     st = get_curr_st(c);
     if (!st) {
-        item = heif_cur_item(c);
+        item = get_heif_item(c, c->cur_item_id);
         if (!item)
             return 0;
     }
@@ -9095,30 +9095,33 @@ static int mov_read_iref_dimg(MOVContext *c, 
AVIOContext *pb, int version)
 
 static int mov_read_iref_thmb(MOVContext *c, AVIOContext *pb, int version)
 {
-    int *thmb_item_id;
+    HEIFItem *from_item = NULL;
     int entries;
-    int to_item_id, from_item_id = version ? avio_rb32(pb) : avio_rb16(pb);
+    int from_item_id = version ? avio_rb32(pb) : avio_rb16(pb);
+    const HEIFItemRef ref = { MKTAG('t','h','m','b'), from_item_id };
 
-    entries = avio_rb16(pb);
-    if (entries > 1) {
-        avpriv_request_sample(c->fc, "thmb in iref referencing several items");
-        return AVERROR_PATCHWELCOME;
+    from_item = get_heif_item(c, from_item_id);
+    if (!from_item) {
+        av_log(c->fc, AV_LOG_ERROR, "Missing stream referenced by thmb 
item\n");
+        return AVERROR_INVALIDDATA;
     }
-    /* 'to' item ids */
-    to_item_id = version ? avio_rb32(pb) : avio_rb16(pb);
 
-    if (to_item_id != c->primary_item_id)
-        return 0;
+    entries = avio_rb16(pb);
+    /* 'to' item ids */
+    for (int i = 0; i < entries; i++) {
+        HEIFItem *item = get_heif_item(c, version ? avio_rb32(pb) : 
avio_rb16(pb));
+        if (!item) {
+            av_log(c->fc, AV_LOG_WARNING, "Missing stream referenced by thmb 
item\n");
+            continue;
+        }
 
-    /* Put thumnbail IDs into an array */
-    thmb_item_id = av_dynarray2_add((void **)&c->thmb_item_id, 
&c->nb_thmb_item,
-                                    sizeof(*c->thmb_item_id),
-                                    (const void *)&from_item_id);
-    if (!thmb_item_id)
-        return AVERROR(ENOMEM);
+        if (!av_dynarray2_add((void **)&item->iref_list, &item->nb_iref_list,
+                              sizeof(*item->iref_list), (const uint8_t *)&ref))
+            return AVERROR(ENOMEM);
+    }
 
-    av_log(c->fc, AV_LOG_TRACE, "thmb: from_item_id %d, entries %d, nb_thmb: 
%d\n",
-           from_item_id, entries, c->nb_thmb_item);
+    av_log(c->fc, AV_LOG_TRACE, "thmb: from_item_id %d, entries %d\n",
+           from_item_id, entries);
 
     return 0;
 }
@@ -9174,7 +9177,7 @@ static int mov_read_ispe(MOVContext *c, AVIOContext *pb, 
MOVAtom atom)
     av_log(c->fc, AV_LOG_TRACE, "ispe: item_id %d, width %u, height %u\n",
            c->cur_item_id, width, height);
 
-    item = heif_cur_item(c);
+    item = get_heif_item(c, c->cur_item_id);
     if (item) {
         item->width  = width;
         item->height = height;
@@ -9193,7 +9196,7 @@ static int mov_read_irot(MOVContext *c, AVIOContext *pb, 
MOVAtom atom)
     av_log(c->fc, AV_LOG_TRACE, "irot: item_id %d, angle %u\n",
            c->cur_item_id, angle);
 
-    item = heif_cur_item(c);
+    item = get_heif_item(c, c->cur_item_id);
     if (item) {
         // angle * 90 specifies the angle (in anti-clockwise direction)
         // in units of degrees.
@@ -9213,7 +9216,7 @@ static int mov_read_imir(MOVContext *c, AVIOContext *pb, 
MOVAtom atom)
     av_log(c->fc, AV_LOG_TRACE, "imir: item_id %d, axis %u\n",
            c->cur_item_id, axis);
 
-    item = heif_cur_item(c);
+    item = get_heif_item(c, c->cur_item_id);
     if (item) {
         item->hflip =  axis;
         item->vflip = !axis;
@@ -9978,6 +9981,7 @@ static int mov_read_close(AVFormatContext *s)
         if (!mov->heif_item[i])
             continue;
         av_freep(&mov->heif_item[i]->name);
+        av_freep(&mov->heif_item[i]->iref_list);
         av_freep(&mov->heif_item[i]->icc_profile);
         av_freep(&mov->heif_item[i]);
     }
@@ -9988,7 +9992,6 @@ static int mov_read_close(AVFormatContext *s)
         av_freep(&mov->heif_grid[i].tile_item_list);
     }
     av_freep(&mov->heif_grid);
-    av_freep(&mov->thmb_item_id);
 
     return 0;
 }
@@ -10453,13 +10456,6 @@ static int mov_parse_heif_items(AVFormatContext *s)
         if (!item)
             continue;
         if (!item->st) {
-            for (int j = 0; j < mov->nb_thmb_item; j++) {
-                if (item->item_id == mov->thmb_item_id[j]) {
-                    av_log(s, AV_LOG_ERROR, "HEIF thumbnail ID %d doesn't 
reference a stream\n",
-                           item->item_id);
-                    return AVERROR_INVALIDDATA;
-                }
-            }
             continue;
         }
         if (item->is_idat_relative) {
@@ -10625,7 +10621,6 @@ static int mov_read_header(AVFormatContext *s)
 
     mov->fc = s;
     mov->trak_index = -1;
-    mov->thmb_item_id = NULL;
     mov->primary_item_id = -1;
     mov->cur_item_id = -1;
     /* .mov and .mp4 aren't streamable anyway (only progressive download if 
moov is before mdat) */

_______________________________________________
ffmpeg-cvslog mailing list -- [email protected]
To unsubscribe send an email to [email protected]

Reply via email to