Version 13 (modified by slhck, 2 years ago) (diff)

note that -an can be used in first pass

FFmpeg and VP9 Encoding Guide

libvpx-vp9 is the VP9 video encoder for WebM, an open, royalty-free media file format. libvpx-vp9 can save about 20–50% bitrate compared to libx264 (the default H.264 encoder), while retaining the same visual quality.

To install FFmpeg with support for libvpx-vp9, look at the Compilation Guides and compile FFmpeg with the --enable-libvpx option. Note that for 10-bit encoding, you need to set the --enable-vp9-highbitdepth configuration option.

Note that the default audio encoder for WebM is libopus, but if it is not available libvorbis will be used instead.

VP9 offers different rate control modes, which determine the quality and file size:

  • 1-pass average bitrate
  • 2-pass average bitrate
  • Constant quality
  • Constant bitrate

Variable Bitrate (VBR)

Average Bitrate (ABR)

libvpx-vp9 offers a simple variable bitrate (VBR) mode by default. This is also sometimes called "Average Bitrate" or "Target Bitrate". In this mode, it will simply try to reach the specified bit rate on average, e.g. 2 MBit/s.

It is not usually recommended to use this mode, as the output may not be compression-efficient, or lead to quality variations. Instead, use Two-Pass or Constant Quality encoding.

ffmpeg -i input.mp4 -c:v libvpx-vp9 -b:v 2M output.webm

Choose a higher bit rate if you want better quality. Note that you shouldn't leave out the -b:v option as the default settings will produce mediocre quality output.


In order to create more efficient encodes when a particular target bitrate should be reached, you should choose two-pass encoding. For two-pass, you need to run ffmpeg twice, with almost the same settings, except for:

  • In pass 1 and 2, use the -pass 1 and -pass 2 options, 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 need to specify an output format (with -f) that matches the output format you will use in pass 2.
  • In pass 1, you can leave audio out by specifying -an.
ffmpeg -i input.mp4 -c:v libvpx-vp9 -b:v 2M -pass 1 -an -f webm /dev/null && \
ffmpeg -i input.mp4 -c:v libvpx-vp9 -b:v 2M -pass 2 -c:a libopus output.webm

Note: Windows users should use NUL instead of /dev/null and ^ instead of \.

For two-pass encoding, you can choose a higher encoding speed for the first pass (e.g., 4), and a lower one for the second pass (e.g. 1). This will speed up the entire process (for more info, scroll down to the section about controlling speed:

ffmpeg -i input.mp4 -c:v libvpx-vp9 -b:v 2M -pass 1 -speed 4 -c:a libopus -f webm /dev/null && \
ffmpeg -i input.mp4 -c:v libvpx-vp9 -b:v 2M -pass 2 -speed 1 -c:a libopus output.webm

If you want to constrain the bitrate, for example when streaming your video, use the options given in the Constrained Quality section.

Constant Quality

In addition to the "default" VBR mode, there's a constant quality (CQ) mode (like CRF in the x264 encoder) that will ensure that every frame gets the number of bits it deserves to achieve a certain (perceptual) quality level, rather than forcing the stream to have an average bit rate. This results in better overall quality. If you do not care about the 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 libvpx-vp9 -crf 30 -b:v 0 output.webm

The CRF value can be from 0–63. Lower values mean better quality. Recommended values range from 15–35, with 31 being recommended for 1080p HD video. See this guide for more info.

Constrained Quality

libvpx-vp9 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 libvpx-vp9 -crf 30 -b:v 2000k output.webm

The quality is determined by the -crf, and the bitrate limit by the -b:v where the bitrate MUST be non-zero. Note: for videos that are "easy" to encode this mode behaves exactly like the Constant Quality mode and actual bitrate may be lower than specified bitrate while for videos that are "hard" to encode the quality will be bounded by the maximum bitrate and will behave like the Variable Bitrate mode.

You can also specify a minimum and maximum bitrate instead of a quality target:

ffmpeg -i input.mp4 -c:v libvpx-vp9 -minrate 500k -b:v 2000k -maxrate 2500k output.webm

Constant Bitrate

Like most other encoders, libvpx offers a constant bitrate (CBR) encoding mode as well, which tries to encode the video in such a way that an average bitrate is reached. This doesn't mean that every frame is encoded with the same amount of bits (since it would harm quality), but the bitrate will be very constrained. You should use constant bitrate encoding if you need your video files to have a certain size, or if you're streaming the videos over a channel that only allows a certain bit rate. Generally though, using constrained quality is the recommended option in this case.

The syntax for setting a constant bit rate is:

ffmpeg -i input.mp4 -c:v libvpx-vp9 -minrate 1M -maxrate 1M -b:v 1M output.webm

Here, you can choose different values for the bitrate other than 1M, e.g. 500K, but you must set all options (i.e., minrate, maxrate and b:v) to the same value.

Lossless VP9

libvpx-vp9 has a lossless encoding mode that can be activated using -lossless 1:

ffmpeg -i input.mp4 -c:v libvpx-vp9 -lossless 1 output.webm

Controlling Speed and Quality

libvpx-vp9 has two main control knobs for speed and quality:

Deadline / Quality

-deadline can be set to realtime, good, or best. For legacy reasons, the option is also accessible with -quality in ffmpeg.

  • good is the default and recommended for most applications.
  • best is recommended if you have lots of time and want the best compression efficiency.
  • realtime is recommended for live / fast encoding.

CPU Utilization / Speed

-cpu-used sets how efficient the compression will be. For legacy reasons, the option is also accessible with -speed in ffmpeg.

When the deadline/quality parameter is good or best, values for -cpu-used can be set between 0 and 5. The default is 0. Using 1 or 2 will increase encoding speed at the expense of having some impact on quality and rate control accuracy. 4 or 5 will turn off rate distortion optimization, having even more of an impact on quality.

When the deadline/quality is set to realtime, the encoder will try to hit a particular CPU utilization target, and encoding quality will depend on CPU speed and the complexity of the clip that you are encoding. See the vpx documentation for more info. In this case, the valid values for -cpu-used are between 0 and 15, where the CPU utilization target (in per cent) is calculated as (100*(16-cpu-used)/16)%.


As of 2018, most browsers support VP9. Many recent phones and other embedded systems also support VP9. If for some reason VP9 is not supported on your target device, you may fall back to VP8 encoding, which offers higher compatibility but lower compression efficiency / quality.

If your input source is using 4:2:2 or 4:4:4 chroma subsampling, some players might not be able to handle the output that libvpx produces. Use 4:2:0 chroma subsampling in such a case:

ffmpeg -i input.mp4 -c:v libvpx-vp9 -pix_fmt yuv420p output.webm

Also see