What is VP9 Constant Rate Factor

This article explains the Constant Rate Factor (CRF) mode—also known as Constant Quality—in the libvpx-vp9 video encoder. It covers how this rate control mode works, why it is highly efficient for video compression, and the specific commands required to enable it during encoding.

Understanding Constant Rate Factor (CRF) in VP9

Constant Rate Factor (CRF) is an encoding mode that targets a consistent level of visual quality throughout an entire video. Instead of allocating a fixed number of bits per second (as in Constant Bitrate, or CBR), CRF adjusts the bitrate dynamically.

When a video scene is complex—featuring fast motion, high detail, or rapid camera transitions—the encoder automatically increases the bitrate to prevent compression artifacts. Conversely, during simple scenes with static backgrounds or low motion, the encoder lowers the bitrate. This ensures that visual quality remains uniform and no bits are wasted on scenes that do not require them.

How libvpx-vp9 Handles CRF

Unlike other encoders like x264 or x265, the VP9 encoder (libvpx-vp9) requires a specific combination of parameters to enable true CRF.

In libvpx-vp9, you must set the target bitrate parameter (-b:v) to zero. If you do not set the bitrate to zero, the encoder will operate in “Constrained Quality” (CQ) mode instead of pure CRF. In CQ mode, the encoder tries to meet the quality target but caps the maximum bitrate based on the value specified in -b:v.

The VP9 CRF Scale

The CRF scale for VP9 ranges from 0 to 63: * 0 represents lossless compression (maximum file size, perfect quality). * 63 represents the lowest quality (minimum file size). * 15 to 35 is the recommended range for most web and archival purposes. * 31 is widely considered the default sweet spot for 1080p video, balancing excellent visual quality with highly efficient file sizes. For 4K video, a lower CRF value (around 15 to 24) is recommended due to the higher pixel density.

How to Use CRF in FFmpeg

To encode a video using pure CRF with the libvpx-vp9 encoder in FFmpeg, use the following command structure:

ffmpeg -i input.mp4 -c:v libvpx-vp9 -crf 30 -b:v 0 -c:a libopus output.webm

In this command: * -c:v libvpx-vp9 selects the VP9 video encoder. * -crf 30 sets the desired quality level to 30. * -b:v 0 is mandatory to force the encoder into pure CRF mode. * -c:a libopus encodes the audio using the highly compatible Opus codec.