[FFmpeg-devel] [PATCH 3/3] avformat/movenc: Add support for AVIF muxing

Andreas Rheinhardt andreas.rheinhardt at outlook.com
Thu Apr 14 00:01:26 EEST 2022


Vignesh Venkatasubramanian:
> Add an AVIF muxer by re-using the existing the mov/mp4 muxer.
> 
> AVIF Specification: https://aomediacodec.github.io/av1-avif
> 
> Sample usage for still image:
> ffmpeg -i image.png -c:v libaom-av1 -avif-image 1 image.avif
> 
> Sample usage for animated AVIF image:
> ffmpeg -i video.mp4 animated.avif
> 
> We can re-use any of the AV1 encoding options that will make
> sense for image encoding (like bitrate, tiles, encoding speed,
> etc).
> 
> The files generated by this muxer has been verified to be valid
> AVIF files by the following:
> 1) Displays on Chrome (both still and animated images).
> 2) Displays on Firefox (only still images, firefox does not support
>    animated AVIF yet).
> 3) Verified to be valid by Compliance Warden:
>    https://github.com/gpac/ComplianceWarden
> 
> Fixes the encoder/muxer part of Trac Ticket #7621
> 
> Signed-off-by: Vignesh Venkatasubramanian <vigneshv at google.com>
> ---
>  configure                |   1 +
>  libavformat/allformats.c |   1 +
>  libavformat/movenc.c     | 337 ++++++++++++++++++++++++++++++++++++---
>  libavformat/movenc.h     |   5 +
>  4 files changed, 319 insertions(+), 25 deletions(-)
> 
> +static int avif_write_trailer(AVFormatContext *s)
> +{
> +    AVIOContext *pb = s->pb;
> +    MOVMuxContext *mov = s->priv_data;
> +    int64_t pos_backup, mdat_pos;
> +    uint8_t *buf;
> +    int buf_size, moov_size;
> +
> +    if (mov->moov_written) return 0;

Can it happen that moov_written is true? What happens if it is? (I
presume the file to be invalid.)

> +
> +    mov->is_animated_avif = s->streams[0]->nb_frames > 1;
> +    mov_write_identification(pb, s);
> +    mov_write_meta_tag(pb, mov, s);
> +
> +    moov_size = get_moov_size(s);
> +    mov->tracks[0].data_offset = avio_tell(pb) + moov_size + 8;
> +
> +    if (mov->is_animated_avif) {
> +        int ret;
> +        if ((ret = mov_write_moov_tag(pb, mov, s)) < 0)
> +            return ret;
> +    }
> +
> +    buf_size = avio_get_dyn_buf(mov->mdat_buf, &buf);
> +    avio_wb32(pb, buf_size + 8);
> +    ffio_wfourcc(pb, "mdat");
> +    mdat_pos = avio_tell(pb);
> +
> +    if (mdat_pos != (uint32_t)mdat_pos) {
> +        av_log(s, AV_LOG_ERROR, "mdat offset does not fit in 32 bits\n");
> +        return AVERROR_INVALIDDATA;
> +    }
> +
> +    avio_write(pb, buf, buf_size);
> +
> +    // write extent offset.
> +    pos_backup = avio_tell(pb);
> +    avio_seek(pb, mov->avif_extent_pos, SEEK_SET);
> +    avio_wb32(pb, mdat_pos); /* rewrite offset */
> +    avio_seek(pb, pos_backup, SEEK_SET);
> +
> +    return 0;
> +}
> +

- Andreas


More information about the ffmpeg-devel mailing list