libaom AV1 Encoding Guide
libaom-av1 is the AOMedia video encoder for AV1, an open source & royalty-free video codec.
libaom-av1 can save about 30% bitrate compared to VP9 and H.265 / HEVC, and about 50% over H.264, while retaining the same visual quality.
To install FFmpeg with support for
libaom-av1, look at the Compilation Guides and compile FFmpeg with the
libaom offers the following rate-control modes which determine the quality and file size obtained:
- Constant quality
- Constrained quality
- 2-pass average bitrate
- 1-pass average bitrate
For a list of options, run
ffmpeg -h encoder=libaom-av1 or check FFmpeg's online documentation.
libaom-av1 has a constant quality (CQ) mode (like CRF in x264 and x265) which will ensure that every frame gets the number of bits it deserves to achieve a certain (perceptual) quality level, rather than encoding each frame to meet a bit rate target. This results in better overall quality. If you do not need to achieve a fixed target file size, this should be your method of choice.
To trigger this mode, you must use a combination of -crf and -b:v 0. -b:v MUST be 0.
ffmpeg -i input.mp4 -c:v libaom-av1 -crf 30 -b:v 0 av1_test.mkv
The CRF value can be from 0–63. Lower values mean better quality and greater file size. 0 means lossless.
libaom-av1 also has a constrained quality (CQ) mode that will ensure that a constant (perceptual) quality is reached while keeping the bitrate below a specified upper bound or within a certain bound. This method is useful for bulk encoding videos in a generally consistent fashion.
ffmpeg -i input.mp4 -c:v libaom-av1 -crf 30 -b:v 2000k output.mkv
The quality is determined by the
-crf, and the bitrate limit by the
-b:v where the bitrate MUST be non-zero.
You can also specify a minimum and maximum bitrate instead of a quality target:
ffmpeg -i input.mp4 -c:v libaom-av1 -minrate 500k -b:v 2000k -maxrate 2500k output.mp4
In order to create more efficient encodes when a particular target bitrate should be reached, you should choose two-pass encoding. Two-pass encoding is also beneficial for encoding efficiency when constant quality is used without a target bitrate. For two-pass, you need to run
ffmpeg twice, with almost the same settings, except for:
- In pass 1 and 2, use the
-pass 2options, respectively.
- In pass 1, output to a null file descriptor, not an actual file. (This will generate a logfile that FFmpeg needs for the second pass.)
- In pass 1, you can leave audio out by specifying
ffmpeg -i input.mp4 -c:v libaom-av1 -b:v 2M -pass 1 -an -f null /dev/null && \ ffmpeg -i input.mp4 -c:v libaom-av1 -b:v 2M -pass 2 -c:a libopus output.mkv
Average Bitrate (ABR)
libaom-av1 also offers a simple "Average Bitrate" or "Target Bitrate" mode. In this mode, it will simply try to reach the specified bit rate on average, e.g. 2 MBit/s.
ffmpeg -i input.mp4 -c:v libaom-av1 -b:v 2M output.mkv
Use this option only if file size and encoding time are more important factors than quality alone. Otherwise, use one of the other rate control methods described above.
Controlling Speed / Quality
-cpu-used sets how efficient the compression will be. Default is 1. Lower values mean slower encoding with better quality, and vice-versa.
-row-mt 1 enables row-based multi-threading which maximizes CPU usage. To enable fast decoding performance, also add tiles (i.e.
-tiles 4x1 or
-tiles 2x2 for 4 tiles). Enabling
row-mt is only faster when the CPU has more threads than the number of encoded tiles.
By default, libaom's maximum keyframe interval is 9999 frames. This can lead to slow seeking, especially with content that has few or infrequent scene changes.
-g option can be used to set the maximum keyframe interval. Anything up to 10 seconds is considered reasonable for most content, so for 30 frames per second content one would use
-g 300, for 60 fps content
-g 600, etc.
To set a fixed keyframe interval, set both
-keyint_min to the same value. Note that currently
-keyint_min is ignored unless it's the same as
-g, so the minimum keyframe interval can't be set on its own.
For intra-only output, use
HDR and high bit depth
When encoding in HDR it's necessary to pass through color information;
-color_primaries. For example, Youtube HDR uses
-colorspace bt2020nc -color_trc smpte2084 -color_primaries bt2020
AV1 includes 10-bit support in its Main profile. Thus content can be encoded in 10-bit without having to worry about incompatible hardware decoders.
To utilize 10-bit in the Main profile, use
-pix_fmt yuv420p10le. For 10-bit with 4:4:4 chroma subsampling (requires the High profile), use
-pix_fmt yuv444p10le. 12-bit is also supported, but requires the Professional profile. See
ffmpeg -help encoder=libaom-av1 for the supported pixel formats.
-crf 0 for lossless encoding. Because of a bug present in FFmpeg versions prior to 4.4, the first frame will not be losslessly preserved (the issue was fixed on March 21, 2021). As a workaround on pre-4.4 versions one may use
-aom-params lossless=1 for lossless output.
The range of options are similar to that of libaom (aomenc). It is supposed to be faster than libaom while having comparable quality.
Rav1e claims to be the fastest software AV1 encoder, but that really depends on the setting.
More info about AV1 can be found here: