On 2/22/2022 3:40 PM, Vignesh Venkatasubramanian wrote:
Add an AVIF muxer by re-using the existing the mov/mp4 muxer.

AVIF Specifiation: 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) Verfied 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 <vigne...@google.com>
---
  configure                |   1 +
  libavformat/allformats.c |   1 +
  libavformat/movenc.c     | 300 +++++++++++++++++++++++++++++++++++----
  libavformat/movenc.h     |   5 +
  4 files changed, 283 insertions(+), 24 deletions(-)

diff --git a/configure b/configure
index 1535dc3c5b..87b380fe3a 100755
--- a/configure
+++ b/configure
@@ -3393,6 +3393,7 @@ asf_stream_muxer_select="asf_muxer"
  av1_demuxer_select="av1_frame_merge_bsf av1_parser"
  avi_demuxer_select="riffdec exif"
  avi_muxer_select="riffenc"
+avif_muxer_select="mov_muxer"
  caf_demuxer_select="iso_media"
  caf_muxer_select="iso_media"
  dash_muxer_select="mp4_muxer"
diff --git a/libavformat/allformats.c b/libavformat/allformats.c
index d066a7745b..400c17afbd 100644
--- a/libavformat/allformats.c
+++ b/libavformat/allformats.c
@@ -81,6 +81,7 @@ extern const AVOutputFormat ff_au_muxer;
  extern const AVInputFormat  ff_av1_demuxer;
  extern const AVInputFormat  ff_avi_demuxer;
  extern const AVOutputFormat ff_avi_muxer;
+extern const AVOutputFormat ff_avif_muxer;
  extern const AVInputFormat  ff_avisynth_demuxer;
  extern const AVOutputFormat ff_avm2_muxer;
  extern const AVInputFormat  ff_avr_demuxer;
diff --git a/libavformat/movenc.c b/libavformat/movenc.c
index 1a746a67fd..05537d1e78 100644
--- a/libavformat/movenc.c
+++ b/libavformat/movenc.c
@@ -1303,7 +1303,7 @@ static int mov_write_av1c_tag(AVIOContext *pb, MOVTrack 
*track)
avio_wb32(pb, 0);
      ffio_wfourcc(pb, "av1C");
-    ff_isom_write_av1c(pb, track->vos_data, track->vos_len, 1);
+    ff_isom_write_av1c(pb, track->vos_data, track->vos_len, track->mode != 
MODE_AVIF);
      return update_size(pb, pos);
  }
@@ -2004,12 +2004,13 @@ static int mov_write_colr_tag(AVIOContext *pb, MOVTrack *track, int prefer_icc)
          }
      }
- /* We should only ever be called by MOV or MP4. */
-    av_assert0(track->mode == MODE_MOV || track->mode == MODE_MP4);
+    /* We should only ever be called for MOV, MP4 and AVIF. */
+    av_assert0(track->mode == MODE_MOV || track->mode == MODE_MP4 ||
+               track->mode == MODE_AVIF);
avio_wb32(pb, 0); /* size */
      ffio_wfourcc(pb, "colr");
-    if (track->mode == MODE_MP4)
+    if (track->mode == MODE_MP4 || track->mode == MODE_AVIF)
          ffio_wfourcc(pb, "nclx");
      else
          ffio_wfourcc(pb, "nclc");
@@ -2019,7 +2020,7 @@ static int mov_write_colr_tag(AVIOContext *pb, MOVTrack 
*track, int prefer_icc)
      avio_wb16(pb, track->par->color_primaries);
      avio_wb16(pb, track->par->color_trc);
      avio_wb16(pb, track->par->color_space);
-    if (track->mode == MODE_MP4) {
+    if (track->mode == MODE_MP4 || track->mode == MODE_AVIF) {
          int full_range = track->par->color_range == AVCOL_RANGE_JPEG;
          avio_w8(pb, full_range << 7);
      }
@@ -2103,6 +2104,8 @@ static void find_compressor(char * compressor_name, int 
len, MOVTrack *track)
          av_strlcatf(compressor_name, len, " %d%c", track->par->height, 
interlaced ? 'i' : 'p');
av_strlcatf(compressor_name, len, "%d", rate * (interlaced + 1));
+    } else if (track->par->codec_id == AV_CODEC_ID_AV1 && track->mode == 
MODE_AVIF) {
+        av_strlcatf(compressor_name, len, "libaom Encoder");
libaom is not the only AV1 encoder supported by libavcodec, a libavformat user could even not use a libavcodec based encoder to begin with, and then there's also the codec copy scenario where no encoder is used at all.

This should probably use the same path as MODE_MOV above if there's a key "encoder" in track->st->metadata, and write it.
_______________________________________________
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".

Reply via email to