av2codec — AV2 Video Codec Written in Rust

av2codec is a from-scratch implementation of the AV2 video codec encoder in pure, safe Rust — zero unsafe code, zero C dependencies. This demo showcases the encoder running in the browser via WebAssembly.

To prove spec compliance, the encoded bitstream is decoded by the official AVM reference decoder (also compiled to WASM). Both encoding and decoding happen entirely in the browser — select a sample image or upload your own, adjust the quantization settings, and see the results instantly.

Architecture

Browser
  |
  |-- av2codec encoder (Rust -> WASM, ~154 KB)
  |     RGB image -> YUV 4:2:0 -> AV2 bitstream
  |
  |-- AVM reference decoder (C -> WASM, ~1.7 MB)
  |     AV2 bitstream -> YUV 4:2:0 -> RGB -> Canvas
  |
  |-- index.html
        UI controls, sample images, canvas rendering

Features

  • Select from 9 sample images or upload your own (max 2 MB, max 1024px)
  • Choose 8-bit or 10-bit quantization
  • Adjustable quantization index (QIndex 1-255)
  • Side-by-side original vs. encoded/decoded comparison
  • Encode/decode timing and compression statistics

Prerequisites

Directory Layout

av2codec_demo/
  Cargo.toml              # Rust crate (encoder WASM bindings)
  src/lib.rs              # Encoder: RGB->YUV + av2codec encode, exposed via wasm-bindgen
  decoder_wasm/
    avmdec_wasm.c          # Thin C wrapper around AVM reference decoder API
    build.sh               # Emscripten build script for the reference decoder
  web/
    index.html             # Demo page (single-file HTML + JS)
    samples/               # Sample PNG images
    pkg/                   # [generated] Rust encoder WASM output (wasm-pack)
    avmdec.js              # [generated] Emscripten JS glue for reference decoder
    avmdec.wasm            # [generated] Reference decoder WASM binary

Building

1. Clone dependencies

Ensure the following sibling directories exist relative to this project:

parent/
  av2/          # AVM reference codec source (git clone from gitlab.com/AOMediaCodec/avm)
  wav2c/        # av2codec encoder (Rust library)
  av2codec_demo/  # This project

2. Build the encoder (Rust -> WASM)

cd av2codec_demo
wasm-pack build --target web --out-dir web/pkg --release

This compiles the av2codec encoder to WebAssembly and outputs the JS bindings + .wasm file into web/pkg/.

3. Build the reference decoder (C -> WASM)

cd decoder_wasm
bash build.sh

This does two things:

  1. Cross-compiles the AVM reference decoder library (libavm.a) using Emscripten with decoder-only configuration (no encoder, no threads, no SIMD, no tests)
  2. Compiles avmdec_wasm.c (our thin wrapper) and links it with libavm.a to produce web/avmdec.js + web/avmdec.wasm

The AV2 source location defaults to ../av2/ relative to this project. Override it with the AV2_SRC environment variable:

AV2_SRC=/path/to/av2 bash build.sh

The libavm.a build is cached in decoder_wasm/build/. Delete that directory to force a full rebuild.

4. Add sample images

Copy sample PNG images into web/samples/. The demo expects these files:

flowers.png  city.png  dog.png  sunset.png  waves.png
bulb.png  house.png  night.png  guitar.png

The sample images are from the GB82 Image Set by Gianni Rosato.

5. Serve and open

Any static HTTP server works. For example:

cd web
python3 -m http.server 8080

Then open http://localhost:8080 in a browser.

How It Works

  1. The user selects or uploads an image
  2. The image is drawn to a canvas and its RGBA pixel data is extracted
  3. Encoding (Rust WASM): RGBA pixels are converted to YUV 4:2:0 and encoded into an AV2 bitstream using av2codec::Encoder
  4. Decoding (C WASM): The bitstream is passed to the AVM reference decoder (avmdec), which decodes it back to YUV and converts to RGBA
  5. The decoded RGBA data is rendered on a second canvas for side-by-side comparison
  6. Statistics (encode/decode time, bitstream size, compression ratio) are displayed

Rebuilding After Changes

What changed Rebuild command
Rust encoder code (src/lib.rs) wasm-pack build --target web --out-dir web/pkg --release
C decoder wrapper (decoder_wasm/avmdec_wasm.c) cd decoder_wasm && bash build.sh
AVM reference source (../av2/) rm -rf decoder_wasm/build && cd decoder_wasm && bash build.sh
HTML/JS (web/index.html) Just reload the browser
S
Description
Demo of AV2 av2codec is a from-scratch implementation of the AV2 video codec encoder in pure, safe Rust.
Readme 4 MiB
Languages
HTML 74.4%
Rust 9.7%
C 9.5%
Shell 6.4%