You've already forked FFmpeg
mirror of
https://github.com/FFmpeg/FFmpeg.git
synced 2025-08-04 22:03:09 +02:00
avformat/mov: don't assume iloc and iinf entries for each item_id will be in the same order
Nothing forbids them to be in any order the muxer desires. Fixes demuxing heif samples generated by S1II. Tested-by: Lynne <dev@lynne.ee> Signed-off-by: James Almer <jamrial@gmail.com>
This commit is contained in:
@ -8739,7 +8739,7 @@ static int mov_read_iloc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
|
|||||||
|
|
||||||
av_log(c->fc, AV_LOG_TRACE, "iloc: item_count %d\n", item_count);
|
av_log(c->fc, AV_LOG_TRACE, "iloc: item_count %d\n", item_count);
|
||||||
for (int i = 0; i < item_count; i++) {
|
for (int i = 0; i < item_count; i++) {
|
||||||
HEIFItem *item = c->heif_item[i];
|
HEIFItem *item = NULL;
|
||||||
int item_id = (version < 2) ? avio_rb16(pb) : avio_rb32(pb);
|
int item_id = (version < 2) ? avio_rb16(pb) : avio_rb32(pb);
|
||||||
int offset_type = (version > 0) ? avio_rb16(pb) & 0xf : 0;
|
int offset_type = (version > 0) ? avio_rb16(pb) & 0xf : 0;
|
||||||
|
|
||||||
@ -8765,8 +8765,14 @@ static int mov_read_iloc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
|
|||||||
base_offset > INT64_MAX - extent_offset)
|
base_offset > INT64_MAX - extent_offset)
|
||||||
return AVERROR_INVALIDDATA;
|
return AVERROR_INVALIDDATA;
|
||||||
|
|
||||||
if (!item)
|
for (int j = 0; j < c->nb_heif_item; j++) {
|
||||||
item = c->heif_item[i] = av_mallocz(sizeof(*item));
|
item = c->heif_item[j];
|
||||||
|
if (!item)
|
||||||
|
item = c->heif_item[j] = av_mallocz(sizeof(*item));
|
||||||
|
else if (item->item_id != item_id)
|
||||||
|
continue;
|
||||||
|
break;
|
||||||
|
}
|
||||||
if (!item)
|
if (!item)
|
||||||
return AVERROR(ENOMEM);
|
return AVERROR(ENOMEM);
|
||||||
|
|
||||||
@ -8776,18 +8782,18 @@ static int mov_read_iloc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
|
|||||||
item->is_idat_relative = 1;
|
item->is_idat_relative = 1;
|
||||||
item->extent_length = extent_length;
|
item->extent_length = extent_length;
|
||||||
item->extent_offset = base_offset + extent_offset;
|
item->extent_offset = base_offset + extent_offset;
|
||||||
av_log(c->fc, AV_LOG_TRACE, "iloc: item_idx %d, offset_type %d, "
|
av_log(c->fc, AV_LOG_TRACE, "iloc: item_idx %d, item->item_id %d, offset_type %d, "
|
||||||
"extent_offset %"PRId64", extent_length %"PRId64"\n",
|
"extent_offset %"PRId64", extent_length %"PRId64"\n",
|
||||||
i, offset_type, item->extent_offset, item->extent_length);
|
i, item->item_id, offset_type, item->extent_offset, item->extent_length);
|
||||||
}
|
}
|
||||||
|
|
||||||
c->found_iloc = 1;
|
c->found_iloc = 1;
|
||||||
return atom.size;
|
return atom.size;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int mov_read_infe(MOVContext *c, AVIOContext *pb, MOVAtom atom, int idx)
|
static int mov_read_infe(MOVContext *c, AVIOContext *pb, MOVAtom atom)
|
||||||
{
|
{
|
||||||
HEIFItem *item;
|
HEIFItem *item = NULL;
|
||||||
AVBPrint item_name;
|
AVBPrint item_name;
|
||||||
int64_t size = atom.size;
|
int64_t size = atom.size;
|
||||||
uint32_t item_type;
|
uint32_t item_type;
|
||||||
@ -8827,22 +8833,27 @@ static int mov_read_infe(MOVContext *c, AVIOContext *pb, MOVAtom atom, int idx)
|
|||||||
if (size > 0)
|
if (size > 0)
|
||||||
avio_skip(pb, size);
|
avio_skip(pb, size);
|
||||||
|
|
||||||
item = c->heif_item[idx];
|
for (int i = 0; i < c->nb_heif_item; i++) {
|
||||||
if (!item)
|
item = c->heif_item[i];
|
||||||
item = c->heif_item[idx] = av_mallocz(sizeof(*item));
|
if (!item)
|
||||||
|
item = c->heif_item[i] = av_mallocz(sizeof(*item));
|
||||||
|
else if (item->item_id != item_id)
|
||||||
|
continue;
|
||||||
|
break;
|
||||||
|
}
|
||||||
if (!item)
|
if (!item)
|
||||||
return AVERROR(ENOMEM);
|
return AVERROR(ENOMEM);
|
||||||
|
|
||||||
if (ret)
|
if (ret)
|
||||||
av_bprint_finalize(&item_name, &c->heif_item[idx]->name);
|
av_bprint_finalize(&item_name, &item->name);
|
||||||
c->heif_item[idx]->item_id = item_id;
|
item->item_id = item_id;
|
||||||
c->heif_item[idx]->type = item_type;
|
item->type = item_type;
|
||||||
|
|
||||||
switch (item_type) {
|
switch (item_type) {
|
||||||
case MKTAG('a','v','0','1'):
|
case MKTAG('a','v','0','1'):
|
||||||
case MKTAG('j','p','e','g'):
|
case MKTAG('j','p','e','g'):
|
||||||
case MKTAG('h','v','c','1'):
|
case MKTAG('h','v','c','1'):
|
||||||
ret = heif_add_stream(c, c->heif_item[idx]);
|
ret = heif_add_stream(c, item);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return ret;
|
return ret;
|
||||||
break;
|
break;
|
||||||
@ -8884,7 +8895,7 @@ static int mov_read_iinf(MOVContext *c, AVIOContext *pb, MOVAtom atom)
|
|||||||
ret = AVERROR_INVALIDDATA;
|
ret = AVERROR_INVALIDDATA;
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
ret = mov_read_infe(c, pb, infe, i);
|
ret = mov_read_infe(c, pb, infe);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
goto fail;
|
goto fail;
|
||||||
if (!ret)
|
if (!ret)
|
||||||
|
Reference in New Issue
Block a user