VP9 is an open-source video codec developed by Google as a successor to VP8. It is designed for web delivery and offers compression performance close to HEVC without requiring licensing fees. The codec uses 64??64 superblocks, flexible block partitioning, and advanced prediction to reduce bitrate while maintaining visual quality.
VP9 is suitable for video-on-demand, browser playback, and adaptive streaming, though encoding speed is slower than H.264. Proper configuration with FFmpeg allows tuning for quality, bitrate, or performance depending on deployment needs.
Codec Architecture and Compression Model
VP9 is a block-based hybrid video codec using a hierarchical, tree-based partitioning system. Instead of fixed macroblock sizes like H.264 (16??16) or CTUs like HEVC (up to 64??64), VP9 encodes frames using superblocks of 64??64 pixels that are recursively partitioned into smaller blocks down to 4??4.
Each block undergoes intra-frame or inter-frame prediction, followed by a 2D DCT transform, quantization, and entropy coding using context-adaptive binary arithmetic coding (CABAC). Motion vectors in VP9 are encoded relative to reference frames, with support for up to three reference frames per inter frame.
VP9 supports variable frame refresh, alternate reference frames, and temporal scalability via frame groups, improving both compression and error resilience in streaming scenarios.
Encoding Modes and Configuration
VP9 is supported by the libvpx encoder in FFmpeg. It offers both constant quality and two-pass variable bitrate (VBR) encoding. While VP9 encoding is more computationally intensive than H.264 or VP8, it yields significantly smaller file sizes at similar quality levels.
Constant Quality Mode (CQ / CRF Equivalent)
The simplest and most used mode for VP9 in VOD workflows:
ffmpeg -i input.mp4 -c:v libvpx-vp9 -crf 32 -b:v 0 output_vp9.webmExplantation:
- -c:v libvpx-vp9: Selects the VP9 encoder.
- -crf 32: Sets the constant quality level; lower values increase quality and file size. Use 28"36 depending on target quality.
- -b:v 0: Disables target bitrate to allow CRF mode.
- output_vp9.webm: Encoded output using the WebM container.
Two-Pass Encoding for Bitrate Control
Used when targeting a specific file size or bitrate, especially in constrained bandwidth environments:
ffmpeg -i input.mp4 -c:v libvpx-vp9 -b:v 2500k -pass 1 -an -f null /dev/nullffmpeg -i input.mp4 -c:v libvpx-vp9 -b:v 2500k -pass 2 -c:a libopus output_vp9_vbr.webmExplanation:
- -pass 1: First pass analyzes content without producing output.
- -b:v 2500k: Sets average target bitrate (2.5 Mbps).
- -an -f null /dev/null: Skips audio and discards output during analysis.
- -pass 2: Second pass encodes using bitrate stats from the first pass.
- -c:a libopus: Encodes audio using Opus codec.
- Useful when targeting file size or streaming bandwidth constraints.
VP9 for Web Delivery
VP9 is widely supported across modern browsers, including Chrome, Firefox, Edge, and Opera. Safari support is limited and requires fallback to H.264 or AV1. The preferred container format for VP9 is .webm using libvpx-vp9 for video and libopus for audio.
When preparing VP9 content for web playback, using WebM avoids licensing complications while delivering high compression. For HTML5 players, the MIME type should be video/webm; codecs="vp9,opus".
Example: Web-Ready Encoding with Audio
ffmpeg -i input.mp4 -c:v libvpx-vp9 -crf 30 -b:v 0 -c:a libopus -b:a 128k output_web.webmExplanation:
- -crf 30: Sets visual quality (lower is better). Use 28"32 for good balance.
- -b:v 0: Enables constant quality encoding.
- -c:a libopus: Sets Opus as the audio codec.
- -b:a 128k: Sets audio bitrate to 128 kbps.
This produces a streaming-ready file optimized for client-side playback using JavaScript-based players or native HTML5 elements.
Performance Considerations
VP9 encoding is significantly slower than H.264 and VP8, particularly at lower CRF values or with high-resolution content. Encoding time can be reduced with faster presets, but at the cost of compression efficiency.
To adjust speed vs compression ratio:
ffmpeg -i input.mp4 -c:v libvpx-vp9 -crf 31 -b:v 0 -speed 4 output_speed4.webmExplanation:
- -speed 4: Balances encoding speed and compression efficiency. Range is 0 (slowest) to 8 (fastest).
- Higher speed values reduce CPU load but increase file size.
- Best practice: use speed=1 for archival, speed=4 for acceptable VOD, and speed=6+ for fast previews.
VP9 decoding performance is generally acceptable on modern CPUs and is hardware-accelerated on many mobile devices and smart TVs. However, older or low-end hardware may experience playback issues, especially at resolutions above 1080p.
Key Features and Limitations
- Alpha channel support: VP9 supports transparency when using the WebM container with yuva420p pixel format.
- 10-bit encoding: Available using -pix_fmt yuv420p10le, improves compression for HDR workflows but increases decoding requirements.
- No B-frames: VP9 uses alternate reference frames and compound prediction instead of traditional B-frames.
- Limited Smart Encoding Features: Unlike HEVC, VP9 lacks features like weighted prediction and tiles per second, affecting encoding scalability in cloud workflows.
Compatibility and Fallback Strategy
While VP9 is supported in Chromium-based browsers and Android devices, fallback to H.264 is required for:
- iOS Safari (does not support VP9)
- Legacy Windows devices (no VP9 hardware decoding)
- Smart TVs and embedded players lacking VP9 support
It is common to encode dual versions and serve via Media Source Extensions (MSE) or adaptive streaming manifests (HLS/DASH) with codec negotiation.

