Configure CRF in libvpx-vp9 FFmpeg

This article explains how to configure the Constant Rate Factor (CRF) for the VP9 video encoder (libvpx-vp9) using FFmpeg. You will learn the specific command-line syntax required for true CRF encoding, the recommended quality ranges for different use cases, and how to optimize your encoding speed.

The Core CRF Command

Unlike other encoders (such as x264 or x265), the libvpx-vp9 encoder requires you to explicitly set the video bitrate to zero (-b:v 0) to enable true CRF mode. If you omit this argument, FFmpeg will default to a constrained bitrate mode instead.

Here is the basic command template for VP9 CRF encoding:

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

Understanding VP9 CRF Values

The CRF scale for VP9 ranges from 0 to 63:

  • 0 (Lossless): Produces the highest possible quality but results in extremely large file sizes.
  • 63 (Lowest Quality): Produces the smallest file size with heavy compression artifacts.
  • Recommended Range (15 to 35):
    • 15–25: Excellent quality for high-definition 1080p or 4K video sourcing.
    • 31: The default value, which offers a great balance between file size and visual quality for web playback.
    • 32–35: Ideal for lower-resolution videos or when bandwidth savings are the top priority.

Optimizing Encoding Speed

VP9 encoding can be resource-intensive and slow. To speed up the process without significantly impacting quality, you should use the -row-mt 1 (row-based multi-threading) and -cpu-used options.

The -cpu-used flag accepts values from 0 to 5. Lower numbers result in slower, higher-quality encodes, while higher numbers result in faster, slightly lower-quality encodes. A value of 1 or 2 is recommended for standard encoding.

Here is an optimized command incorporating these settings alongside Opus audio (the standard pair for WebM files):

ffmpeg -i input.mp4 -c:v libvpx-vp9 -crf 30 -b:v 0 -row-mt 1 -cpu-used 2 -c:a libopus output.webm