mirror of
https://mirror.skon.top/https://github.com/FFmpeg/FFmpeg
synced 2026-04-20 21:00:41 +08:00
avformat/mov: make items referencing items generic
Signed-off-by: James Almer <jamrial@gmail.com>
This commit is contained in:
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -9087,30 +9087,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 };
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
entries = avio_rb16(pb);
|
||||
if (entries > 1) {
|
||||
avpriv_request_sample(c->fc, "thmb in iref referencing several items");
|
||||
return AVERROR_PATCHWELCOME;
|
||||
}
|
||||
/* 'to' item ids */
|
||||
to_item_id = version ? avio_rb32(pb) : avio_rb16(pb);
|
||||
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;
|
||||
}
|
||||
|
||||
if (to_item_id != c->primary_item_id)
|
||||
return 0;
|
||||
if (!av_dynarray2_add((void **)&item->iref_list, &item->nb_iref_list,
|
||||
sizeof(*item->iref_list), (const uint8_t *)&ref))
|
||||
return AVERROR(ENOMEM);
|
||||
}
|
||||
|
||||
/* 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);
|
||||
|
||||
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;
|
||||
}
|
||||
@@ -9166,7 +9169,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;
|
||||
@@ -9185,7 +9188,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.
|
||||
@@ -9205,7 +9208,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;
|
||||
@@ -9970,6 +9973,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]);
|
||||
}
|
||||
@@ -9980,7 +9984,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;
|
||||
}
|
||||
@@ -10429,13 +10432,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) {
|
||||
@@ -10587,7 +10583,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) */
|
||||
|
||||
Reference in New Issue
Block a user