1. Andrew's Corner »
  2. FFmpeg: Some explorations...

FFmpeg: Exploring AV1 Encoding...

The official announcement of the new AV1 video codec came at the end of 2015 with support added to FFmpeg for encoding with 'libaom' (as it was then known in FFmpeg) at the beginning of 2018. My own involvement came about when I was not only intrigued by the appearance of yet another video codec that promised so much but when I first compiled the aom reference encoder and decoder and then finally created and maintained build scripts for libaom in 2018 on SBo. (For those who are not of the cognoscenti this is a central repository for build scripts under Slackware Linux).

This page does not aim to be the definitive word for AV1 encoding with FFmpeg, such a page already exists here. Rather it represents a diary of my own exploration of this promising new codec and there will be mistakes and fumbles here for sure! If you see things described on this page that you believe could be done better please use the link at the base of this page to suggest improvements and better techniques. But for now lets get transcoding...

Transcoding...

Some preparation is always required when transcoding with a video codec that is still under heavy development. It is strongly advised to compile FFmpeg from its git repository as well as building aom from git. I have also used the following lossless media files for my transcoding and if you wish to follow for a while in my steps you could do worse than to download these as well:

Trailer:
wget https://media.xiph.org/video/derf/y4m/sintel_trailer_2k_1080p24.y4m
wget https://media.xiph.org/sintel/sintel_trailer-audio.flac

Full movie:
wget https://media.xiph.org/sintel/sintel-1280.y4m
wget https://media.xiph.org/sintel/sintel-master-st.wav

These are all lossless files with the trailer files being relatively petite but the 1280p full movie file weighing in at 21G. Mind you there is also a 4K lossless file in there that is a monster 53G download. This one I will probably use when encoding with the reference encoder picks up anything at all that resembles speed!

Single pass encode...

I see that many have derided the single pass encode for the AV1 reference encoder but I confess that I cannot see what all of the fuss is about as the output video in this case is fine. Overwhelming issue is the speed of the encoder: it has a truly glacial slowness. Fortunately the Sintel trailer is only 52 seconds long so a reasonable CPU should be able to get the job done in an acceptable time.

ffmpeg -i sintel_trailer_2k_1080p24.y4m -i sintel_trailer-audio.flac \
       -metadata title="Sintel Trailer 1080p: AV1 Conversion" \
       -metadata description="FFmpeg & libaom version 1.0.0.r1966.g96c7a019f" \
       -metadata date="$(date +'%B %d %Y')" \
       -c:v libaom-av1 -crf 30 -b:v 0 -strict experimental \
       -row-mt 1 -tiles 4x2 -threads 16 -cpu-used 4 \
       -c:a libfdk_aac -b:a 128k \
       1pass_sintel_trailer_av1_$(date +'%d%m%Y').mkv

There are a few points to make here and some of these points are notes to myself to revisit at a later stage:

So I have left myself a little homework which I will undertake in a month or so when hopefully libaom-av1 and FFmpeg have matured in their relationship. And when aom has become a little faster!

Two pass encode...

The 2 pass encode is supposed to produce a better results than a single pass, crf encode although I confess that my old eyes could not see such a great difference with this source material. You can see that I have used the same multithreaded row based multithreading with an 8 tile selection. Worked well enough for the single pass and also well enough for the 2 pass encode.

ffmpeg -y -i sintel_trailer_2k_1080p24.y4m \
       -c:v libaom-av1 -strict experimental -b:v 3M  \
       -row-mt 1 -tiles 4x2 -threads 16 -cpu-used 8 \
       -pass 1 -f webm /dev/null && \
ffmpeg -i sintel_trailer_2k_1080p24.y4m -i sintel_trailer-audio.flac \
       -metadata title="Sintel Trailer 1080p: 2 Pass AV1 Conversion" \
       -metadata description="FFmpeg & libaom version 1.0.0.r1966.g96c7a019f" \
       -metadata date="$(date +'%B %d %Y')" \
       -c:v libaom-av1 -strict experimental -b:v 3M  \
       -row-mt 1 -tiles 4x2 -threads 16 -cpu-used 4 \
       -c:a libopus -b:a 96k \
       -pass 2 \
       2pass_sintel_trailer_av1_$(date +'%d%m%Y').webm

There are a few points to make here and some of these points are notes to myself to revisit at a later stage:

When I revisit this page in a month or so I am hoping that multithreading has improved significantly and if this is the case I will have a decent shot at encoding the 4k lossless, full film that I have seen parked on the Xiph website. Should be a lot of fun! And of course when rav1e matures a little and gets added to FFmpeg I will be back here with bells on!

And in conclusion...

This page represents my own initial exploration of FFmpeg and libaom-av1. If I have perhaps made your own usage of both a little easier let me know by using the email link below. Also let me know of any errors on this page or indeed if there are better ways to accomplish the various tasks I have outlined here. And above all "Have fun!".