Skip to content



Repository files navigation

Measuring Video Codec Performance

This is not an official Google product.

Example graph of SSIM-Y over multiple bitrates Example graph of per-frame SSIM-Y inside a single clip

This project contains a couple of scripts that can be used to generate quality metrics and graphs for different video codecs, encoders and settings.

Quality metrics can be generated for .y4m as well as .yuv raw I420 video files. .yuv files require the special format clip.WIDTH_HEIGHT.yuv:FPS since width, height and fps metadata are not available in this containerless format.

A set of industry-standard clips that can be used are available at Video Test Media, aka. "derf's collection".


To build pinned versions of dependencies, comparison tools and libvpx run:

$ ./

This requires git and build dependencies for libvpx that are not listed here. See build instructions for libvpx for build dependencies.

To use .y4m files as input (instead of .yuv), mediainfo and ffmpeg are both required (to extract metadata and convert to .yuv). They can either be built and installed from source or likely by running (or similar depending on distribution):

$ sudo apt-get install ffmpeg mediainfo


After building dependencies with ./ libvpx encoders are available. Additional encoders have to be fetched and built by using their corresponding setup scripts.

libvpx-rt:vp8 and libvpx-rt:vp9 use libvpx encoders with settings as close as possible to settings used by Chromium's WebRTC implementation.

TODO(pbos): Add reasonable non-realtime settings for --good and --best settings as libvpx-good and libvpx-best encoders for comparison with aom-good.


To build pinned versions of libyami, VA-API and required utils run:

$ ./

Using libyami encoders (yami:vp8, yami:vp9) requires VA-API hardware encoding support that's at least available on newer Intel chipsets. Hardware encoding support can be probed for with vainfo.


To build pinned versions of aomedia utils run:

$ ./

This permits encoding and evaluating quality for the AV1 video codec by running the encoder pair aom-good:av1. This runs a runs aomenc with --good configured as a 2-pass non-realtime encoding. This is significantly slower than realtime targets but provides better quality.

There's currently no realtime target for AV1 encoding as the codec isn't considered realtime ready at the point of writing. When it is, aom-rt should be added and runs could then be reasonably compared to other realtime encoders and codecs.


To build pinned versions of OpenH264, run:

$ ./

OpenH264 is a single-pass encoder used in WebRTC both in Chrome and Firefox. This adds the openh264:h264 which runs h264enc with settings that are intended to be close to WebRTC's implementation.


To build dav1d, run:

$ ./

dav1d is a very fast av1 decoder developed by VideoLAN.


To build rav1e, run:

$ ./

rav1e is a AV1 Encoder which is intended to cover all use-cases where libaom is very slow, it is written in rust. Gives near real-time encoding in higher speed-levels. To use rav1e use rav1e-default:rav1e

Generating Data

To generate graph data (after building and installing dependencies), see:

$ ./ --help

Example usage:

$ ./ --out=libvpx-rt.txt --encoders=libvpx-rt:vp8,libvpx-rt:vp9 clip1.320_240.yuv:30 clip2.320_180.yuv:30 clip3.y4m

This will generate libvpx-rt.txt with an array of Python dictionaries with metrics used later to build graphs. This part takes a long time (may take hours or even days depending on clips, encoders and configurations) as multiple clips are encoded using various settings. Make sure to back up this file after running or risk running the whole thing all over again.

To preserve encoded files, supply the --encoded-file-dir argument.


Graph data can be optionally supplemented with VMAF metrics. To build a pinned version of VMAF, run:

$ ./

This requires several additional dependencies that are not listed here. See build instructions for VMAF for build dependencies.

To enable the creation of VMAF metrics, supply the --enable-vmaf argument to

System Binaries

To use system versions of binaries (either installed or otherwise available in your PATH variable), supply --use-system-path to This will fall back to locally-compiled binaries (but warn) if the encoder commands are not available in PATH.

Dumping Encoder Commands

For debugging and reproducing (if you're working on encoders) it can be useful to know which encoder command produced a certain data point.

To dump the commands used to generate data instead of running them, supply --dump-commands to

Generating Graphs

To generate graphs from existing graph data run:

$ --out-dir OUT_DIR graph_file.txt [graph_file.txt ...]

This will generate several graph image files under OUT_DIR from data files generated using, where each clip and temporal/spatial configuration are grouped together to generate graphs comparing different encoders and layer performances for separate SSIM, AvgPSNR and GlbPSNR metrics. Multiple encoders and codecs are placed in the same graphs to enable a comparison between them.

The script also generates graphs for encode time used. For speed tests it's recommended to use a SSD or similar, along with a single worker instance to minimize the impact that competing processes and disk/network drive performance has on time spent encoding.

The scripts make heavy use of temporary filespace. Every worker instance uses disk space roughly equal to a few copies of the original raw video file that is usually huge to begin with. To solve or mitigate issues where disk space runs out during graph-data generation, either reduce the amount of workers used with --workers or use another temporary directory (with more space available) by changing the TMPDIR environment variable.

Adding or Updating Encoder Implementations

Adding support for additional encoders are encouraged. This requires adding an entry under which handles the new encoder, optionally including support for spatial/temporal configurations.

Any improvements upstream to encoder implementations have to be pulled in by updating pinned revision hashes in corresponding setup/build scripts.


Compare (Real-Time) Video Codec Performance







No releases published


No packages published


  • Python 82.7%
  • Shell 17.3%