An open API service indexing awesome lists of open source software.

https://github.com/rafaelcaricio/av2_demo

Demo of AV2 av2codec is a from-scratch implementation of the AV2 video codec encoder in pure, safe Rust.
https://github.com/rafaelcaricio/av2_demo

av2 avm codec video

Last synced: 3 days ago
JSON representation

Demo of AV2 av2codec is a from-scratch implementation of the AV2 video codec encoder in pure, safe Rust.

Awesome Lists containing this project

README

          

# 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

- **Rust** (with `wasm32-unknown-unknown` target): `rustup target add wasm32-unknown-unknown`
- **wasm-pack**: `cargo install wasm-pack` (or see https://rustwasm.github.io/wasm-pack/installer/)
- **Emscripten SDK** (`emcc`, `emcmake`, `emmake`): https://emscripten.org/docs/getting_started/downloads.html
- **CMake** (3.16+)
- **AV2 reference source code** (the `av2/` AVM repository): https://gitlab.com/AOMediaCodec/avm

## 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)

```bash
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)

```bash
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:

```bash
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](https://github.com/gianni-rosato/gb82-image-set) by Gianni Rosato.

### 5. Serve and open

Any static HTTP server works. For example:

```bash
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 |