[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