AOMedia Video 1 (AV1) is a free video coding format developed to be the successor of VP9 by the Alliance for Open Media (AOMedia). AV1 has much better compression compared to MPEG-4 AVC (x264) and measurably better compression than VP9 and HEVC at the price of horribly slow encoding times.
HOWTO encode AV1 video
ffmpeg encoding a 1080p video as AV1 at a whopping 0.7 frames per second
|Warning: AV1 video encoding with |
There are several competing encoders available for GNU/Linux. ffmpeg with
libaom-av1 is one you likely have available on a modern GNU/Linux distribution. It is considered to be "experimental" ffmpeg requires you to use either
-strict experimental or
strict -2 or it will refuse to run.
ffmpeg can encode AV1 video in several modes. Constant quality (CQ) mode is likely the mode you want since it produces consistent quality. This mode produces constant quality even if it requires a high bitrate in scenes with a lot of movement. Constrained quality is similar except that it is possible to set upper and lower bit-rate boundaries. There is also a Average Bitrate (ABR) mode available in the
ffmpeg -h encoder=libaom-av1 will list all the available options for the
Constant Quality Encoding
ffmpeg will do constant quality encoding if you specify a quality number with
-crf. A lower number produces better quality, higher produces worse video quality at smaller file sizes. A value between 20 and 35 is advisable, values between -1 and 63 are possible. You must also specify a video bitrate of
-b:v 0 to use this mode.
ffmpeg -i inputfile.ts -c:v libaom-av1 -crf 28 -b:v 0 -strict experimental av1-encoded-video.mkv
Constrained Quality Encoding
The constrained quality mode requires you to set the same
-crf quality parameter as the constant quality encoder mode. You will also have to set a target bitrate with
-b:v. The target bitrate can be exceeded in brief periods but not by much. The only difference between the commands for constant quality encoding and constrained quality encoding is the specified
ffmpeg -i inputfile.ts -c:v libaom-av1 -crf 28 -b:v 2000k -strict experimental av1-encoded-video.mkv
Two additional bitrate limitations can be applied:
-maxrate will ensure that the actual bitrate never deviates too far from the target bitrate:
ffmpeg -i inputfile.ts -c:v libaom-av1 -crf 28 -b:v 3000k -minrate 1000k -maxrate 3500k -strict experimental av1-encoded-video.mkv
Average Bitrate (ABR) Encoding
Average bitrate encoding is not very useful for AV1 but it is possible. This mode will ensure that the encoded video is at the target bitrate at all times. No
-crf quality target should be specified to encode in this mode, a bitrate set by
-b:v is the only option necessary to use this mode:
ffmpeg -i inputfile.ts -c:v libaom-av1 -b:v 3000k strict experimental av1-encoded-video.mkv
Average bitrate encoding would make sense if live-streaming was a use-case for AV1. It is not, no unclassified computer technology is capable of real-time encoding anything larger than a stamp-sized video.
Speed Configuration For All Modes
libaom-av1 encoder has a
-cpu-used option you can safely ignore. It is described by
ffmpeg -h encoder=libaom-av1 as:
"Quality/Speed ratio modifier (from 0 to 8) (default 1)"
Lower values produce better quality at the cost of being more CPU-demanding. The default value of
1 is likely what you want; you are better off not specifying the
-cpu-used 8 will produce lower quality video faster. It could be useful for AV1 encoded live-streaming if/when computers become fast enough to be able to real-time encode 1080p video using the "faster" AV1 encoding mode.
Encoding using tiles will speed up encoding on modern multi-core computers. Encoding using tiles can be enabled by adding
-row-mt 1 and a
-tiles XxY option (
-tiles 2x2 or
-tiles 4x1 for 4 tiles). You should absolutely add
-row-mt 1 -tiles and a fitting tiles value to the encoding commands described above.
2x2 for four tiles is a good choice if you have a quad-core computer,
2x3 would utilize a six-core CPU. Using
-row-mt 1 -tiles 8x8 on a dual-core would both be pointless and slower.
HDR encoding can be done by specifying color information with
-color_primaries. What values you should use will depend on the source video. YouTube HDR uses
-colorspace bt2020nc -color_trc smpte2084 -color_primaries bt2020 so you should use that if you want to re-code YouTube HDR video for some reason (YouTube already does that for you, downloading their encode using youtube-dl is a better option).