On Wed, Oct 4, 2023 at 12:40 PM Vignesh Venkatasubramanian via ffmpeg-devel <ffmpeg-devel@ffmpeg.org> wrote:
> They are similar to AVIF images (both use the HEIF container). > The only additional work needed is to parse the hvcC box and put > it in the extradata. > > With this patch applied, ffmpeg (when built with an HEVC decoder) > is able to decode the files in > https://github.com/nokiatech/heif/tree/gh-pages/content/images > > Also add a couple of fate tests with samples from > https://github.com/nokiatech/heif_conformance/tree/master/conformance_files > > Partially fixes trac ticket #6521. > > Signed-off-by: Vignesh Venkatasubramanian <vigne...@google.com> > --- > libavformat/isom.h | 2 + > libavformat/mov.c | 41 ++++++++++++++++++- > tests/fate/mov.mak | 6 +++ > .../fate/mov-heic-demux-still-image-1-item | 11 +++++ > .../mov-heic-demux-still-image-multiple-items | 11 +++++ > 5 files changed, 70 insertions(+), 1 deletion(-) > create mode 100644 tests/ref/fate/mov-heic-demux-still-image-1-item > create mode 100644 > tests/ref/fate/mov-heic-demux-still-image-multiple-items > > diff --git a/libavformat/isom.h b/libavformat/isom.h > index 3d375d7a46..b30b9da65e 100644 > --- a/libavformat/isom.h > +++ b/libavformat/isom.h > @@ -327,6 +327,8 @@ typedef struct MOVContext { > int64_t extent_offset; > } *avif_info; > int avif_info_size; > + int64_t hvcC_offset; > + int hvcC_size; > int interleaved_read; > } MOVContext; > > diff --git a/libavformat/mov.c b/libavformat/mov.c > index 294c864fbd..d3747022bd 100644 > --- a/libavformat/mov.c > +++ b/libavformat/mov.c > @@ -1218,7 +1218,8 @@ static int mov_read_ftyp(MOVContext *c, AVIOContext > *pb, MOVAtom atom) > c->isom = 1; > av_log(c->fc, AV_LOG_DEBUG, "ISO: File Type Major Brand: > %.4s\n",(char *)&type); > av_dict_set(&c->fc->metadata, "major_brand", type, 0); > - c->is_still_picture_avif = !strncmp(type, "avif", 4); > + c->is_still_picture_avif = !strncmp(type, "avif", 4) || > + !strncmp(type, "mif1", 4); > minor_ver = avio_rb32(pb); /* minor version */ > av_dict_set_int(&c->fc->metadata, "minor_version", minor_ver, 0); > > @@ -4911,6 +4912,19 @@ static int avif_add_stream(MOVContext *c, int > item_id) > st->priv_data = sc; > st->codecpar->codec_type = AVMEDIA_TYPE_VIDEO; > st->codecpar->codec_id = AV_CODEC_ID_AV1; > + if (c->hvcC_offset >= 0) { > + int ret; > + int64_t pos = avio_tell(c->fc->pb); > + st->codecpar->codec_id = AV_CODEC_ID_HEVC; > + if (avio_seek(c->fc->pb, c->hvcC_offset, SEEK_SET) != > c->hvcC_offset) { > + av_log(c->fc, AV_LOG_ERROR, "Failed to seek to hvcC data.\n"); > + return AVERROR_UNKNOWN; > + } > + ret = ff_get_extradata(c->fc, st->codecpar, c->fc->pb, > c->hvcC_size); > + if (ret < 0) > + return ret; > + avio_seek(c->fc->pb, pos, SEEK_SET); > + } > sc->ffindex = st->index; > c->trak_index = st->index; > st->avg_frame_rate.num = st->avg_frame_rate.den = 1; > @@ -4953,6 +4967,8 @@ static int avif_add_stream(MOVContext *c, int > item_id) > > static int mov_read_meta(MOVContext *c, AVIOContext *pb, MOVAtom atom) > { > + c->hvcC_offset = -1; > + c->hvcC_size = 0; > while (atom.size > 8) { > uint32_t tag; > if (avio_feof(pb)) > @@ -7827,6 +7843,28 @@ static int mov_read_iloc(MOVContext *c, AVIOContext > *pb, MOVAtom atom) > return atom.size; > } > > +static int mov_read_iprp(MOVContext *c, AVIOContext *pb, MOVAtom atom) > +{ > + int size = avio_rb32(pb); > + if (avio_rl32(pb) != MKTAG('i','p','c','o')) > + return AVERROR_INVALIDDATA; > + size -= 8; > + while (size > 0) { > + int sub_size, sub_type; > + sub_size = avio_rb32(pb); > + sub_type = avio_rl32(pb); > + sub_size -= 8; > + size -= sub_size + 8; > + if (sub_type == MKTAG('h','v','c','C')) { > + c->hvcC_offset = avio_tell(pb); > + c->hvcC_size = sub_size; > + break; > + } > + avio_skip(pb, sub_size); > + } > + return atom.size; > +} > + > static const MOVParseTableEntry mov_default_parse_table[] = { > { MKTAG('A','C','L','R'), mov_read_aclr }, > { MKTAG('A','P','R','G'), mov_read_avid }, > @@ -7934,6 +7972,7 @@ static const MOVParseTableEntry > mov_default_parse_table[] = { > { MKTAG('p','c','m','C'), mov_read_pcmc }, /* PCM configuration box */ > { MKTAG('p','i','t','m'), mov_read_pitm }, > { MKTAG('e','v','c','C'), mov_read_glbl }, > +{ MKTAG('i','p','r','p'), mov_read_iprp }, > { 0, NULL } > }; > > diff --git a/tests/fate/mov.mak b/tests/fate/mov.mak > index 6cb493ceab..a2d3cc8013 100644 > --- a/tests/fate/mov.mak > +++ b/tests/fate/mov.mak > @@ -18,6 +18,8 @@ FATE_MOV = fate-mov-3elist \ > fate-mov-neg-firstpts-discard-frames \ > fate-mov-stream-shorter-than-movie \ > fate-mov-pcm-remux \ > + fate-mov-heic-demux-still-image-1-item \ > + fate-mov-heic-demux-still-image-multiple-items \ > # FIXME: Uncomment these two lines once the test files are uploaded to > the fate > # server. > # fate-mov-avif-demux-still-image-1-item \ > @@ -152,6 +154,10 @@ fate-mov-mp4-ttml-dfxp: CMD = transcode srt > $(TARGET_SAMPLES)/sub/SubRip_capabil > # parsed. > #fate-mov-avif-demux-still-image-multiple-items: CMD = framemd5 -i > $(TARGET_SAMPLES)/avif/still_image_exif.avif -c:v copy > > +fate-mov-heic-demux-still-image-1-item: CMD = framemd5 -i > $(TARGET_SAMPLES)/heif-conformance/C002.heic -c:v copy > + > +fate-mov-heic-demux-still-image-multiple-items: CMD = framemd5 -i > $(TARGET_SAMPLES)/heif-conformance/C003.heic -c:v copy > + > # Resulting remux should have: > # 1. first audio stream with AV_DISPOSITION_HEARING_IMPAIRED > # 2. second audio stream with AV_DISPOSITION_VISUAL_IMPAIRED | > DESCRIPTIONS > diff --git a/tests/ref/fate/mov-heic-demux-still-image-1-item > b/tests/ref/fate/mov-heic-demux-still-image-1-item > new file mode 100644 > index 0000000000..c850c1ff9c > --- /dev/null > +++ b/tests/ref/fate/mov-heic-demux-still-image-1-item > @@ -0,0 +1,11 @@ > +#format: frame checksums > +#version: 2 > +#hash: MD5 > +#extradata 0, 100, > 5444bf01e03182c73ae957179d560f4d > +#tb 0: 1/1 > +#media_type 0: video > +#codec_id 0: hevc > +#dimensions 0: 1280x720 > +#sar 0: 0/1 > +#stream#, dts, pts, duration, size, hash > +0, 0, 0, 1, 111554, > 03ceabfab39afd2e2e796b9362111f32 > diff --git a/tests/ref/fate/mov-heic-demux-still-image-multiple-items > b/tests/ref/fate/mov-heic-demux-still-image-multiple-items > new file mode 100644 > index 0000000000..c850c1ff9c > --- /dev/null > +++ b/tests/ref/fate/mov-heic-demux-still-image-multiple-items > @@ -0,0 +1,11 @@ > +#format: frame checksums > +#version: 2 > +#hash: MD5 > +#extradata 0, 100, > 5444bf01e03182c73ae957179d560f4d > +#tb 0: 1/1 > +#media_type 0: video > +#codec_id 0: hevc > +#dimensions 0: 1280x720 > +#sar 0: 0/1 > +#stream#, dts, pts, duration, size, hash > +0, 0, 0, 1, 111554, > 03ceabfab39afd2e2e796b9362111f32 > -- patch lgtm. I dont have access to fate, can you send the samples to https://ffmpeg.org/fate.html#Uploading-new-samples-to-the-fate-suite? As soon as they are up, I'll merge this. Thanks -- Vittorio _______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".