0023 — HEVC & AV1 (heavy codecs)¶
Status: NATIVE ENCODE IMPLEMENTED (2026-07-05) — the WASM deferrals below stand (no-threads/
no-asm/size make HEVC & AV1 encode impractical in .wasm), but the 0028
native driver inverts every blocker: threads + SIMD are exactly what x265 and SVT-AV1 want. So
HEVC encode (libx265, GPL/full-gpl only) and AV1 encode (libsvtav1, both variants) now ship in the
native full profile (0022) — built by ffmpeg-wasi build/deps.sh (cmake) + build/libav.sh,
published + signed as ffmpeg-wasi-driver-linux-amd64-full-<variant>, selectable via
native.NewFromRelease(…, WithReleaseProfile(ProfileFull)). Verified end-to-end (HEVC→mp4, AV1→mkv
over the afero/IPC bridge). D-0023-B/D flip to done for native (the wasm verdicts are unchanged;
HW-accel remains a follow-up. AV1 decode via libdav1d is now DONE on BOTH runtimes (2026-07-05):
native (threaded) and — after the dav1d-WASM spike proved a single-threaded, atomics-free dav1d builds
and decodes on wazero — the WASM module too (intermediate, both variants); see D-0023-C and
0030 for the single-threaded trade-off. Originally one of the 0013–0023 batch mapping the
0012 roadmap; the §7 "HEVC / AV1" Tier-3 row.
Date: 2026-06-30 (native encode implemented 2026-07-05)
Parent: 0012 §7 (the dispatch row), §4A/§4B (the AV1/HEVC
entries), §2 (the envelope), §3 (the licensing lens), §5 (Tier 3); 0007
§5 (D-FW-C, the LGPL/GPL split)
Owns: R-PARITY-HEAVY-CODECS
1. Why¶
HEVC and AV1 are the next-generation video codecs a "does it do X?" consumer eventually asks for —
better compression than H.264/VP9, and increasingly the delivery target for 4K/HDR. But they are
the worst fit for our envelope (0012 §2): the encoders are computationally enormous, lean
hardest on threads and asm — both of which we forbid — and they drag the largest external libs into
the .wasm. HEVC additionally carries an active patent pool (unlike the sunsetting AVC one,
licensing.md). So this spec is deliberately a deferral with conditions, not a build plan: it
records the per-codec recommendation (do / defer) and the gates (a real consumer need · acceptable
size · a measured 0008 perf number) each must clear to graduate.
2. Scope¶
Four distinct codec directions, each judged separately — decode and encode do not share a verdict:
- HEVC/H.265 decode — already shipped (the
hevcnative decoder is in thebuild/libav.shallowlist today). In scope only to record it as done and note no lib is needed. - HEVC/H.265 encode —
libx265(GPL) → full variant only; large; slow single-threaded; HEVC patent-pool exposure. - AV1 decode —
libdav1d(BSD) → LGPL default variant; the practical decoder (the native FFmpeg AV1 decoder is too slow). Royalty-free. - AV1 encode —
libaom/SVT-AV1/rav1e→ heavy, slow, and of uncertain cross-compile feasibility; likely impractical in this envelope pending measurement.
Out of scope (other specs own these): LGPL encoders Opus/MP3/VP8-9/WebP → 0018;
the native codec batch → 0016; the lean/full size bucketing →
0022; perf measurement methodology → 0008. No new job-spec
vocabulary — these are video_codec string values (libx265, libaom-av1, libsvtav1) plus the
existing av1/hevc decoder names; the 0007 §4 contract is unchanged.
3. Approach / design¶
The build mechanics are the established cross-compile pattern from ffmpeg-wasi build/deps.sh
(zlib/x264/openh264) + build/libav.sh: a build_<lib> function emits a static wasm32-wasi
archive into $PREFIX; libav.sh adds --enable-lib<x> + the explicit --enable-encoder=/
--enable-decoder= (under --disable-everything). The GPL gate already exists — libx265 joins
libx264 behind [ "$VARIANT" = gpl ] && GPL_FLAGS="--enable-gpl …". Each lib must build with
--disable-asm-equivalents and no threads, mirroring how x264 took --host=x86-gnu --disable-asm
(the portable C path) and openh264 took ARCH=generic USE_ASM=No + a single-thread shim.
- libx265 (HEVC encode) — cmake-based; needs a wasi toolchain file, asm off (
ENABLE_ASSEMBLY=OFF), threads off, CLI off, 8-bit. The cmake build is more involved than x264's autoconf but tractable. - libdav1d (AV1 decode) — meson/ninja build; needs a meson cross file for wasm32-wasi, asm
off (
enable_asm=false). dav1d is designed with a clean C fallback, so the no-asm path is first-class — the lowest-risk new lib here. - AV1 encode — feasibility is itself the open question (§6):
libaom(cmake, very large, very slow),SVT-AV1(cmake, architected around a thread pool — single-thread strips its whole point),rav1e(Rust — conflicts with the C-only wasi-sdk/clang toolchain, D-FW-E; out).
No design beyond "wire the lib the same way the existing ones are wired." The hard part is not plumbing — it is whether the result is usable (§5).
4. Build & job-spec impact¶
build/deps.sh: newbuild_x265(gpl branch only, besidebuild_x264); newbuild_dav1d(both variants, beside zlib/openh264 — it is LGPL-clean); AV1-encode functions not added until a verdict flips (§6). Each carries the patent/licence caveat comment x264/openh264 carry.build/libav.sh:--enable-libx265 --enable-encoder=libx265intoGPL_FLAGS;--enable-libdav1d --enable-decoder=libdav1dinto the defaultENABLEset; AV1 encoder enables deferred.hevcdecode is already enabled — no change.- job-spec / afmpeg: none.
video_codec: "libx265"(full variant),"libdav1d"/decode-sideav1, and (if ever)"libaom-av1"/"libsvtav1"are plain codec-name strings the driver passes to libav. Capability is variant- and build-gated, surfaced through the codec/filter matrix doc (0012 §6), not new vocabulary.
5. Licensing, PATENTS & size impact (central)¶
This is the section that justifies Tier 3. Three independent axes:
- Copyright licence.
libx265is GPL-2.0-or-later → it can only enter the full/GPL variant (0007 §5, the--enable-gplgate), never the LGPL default.libdav1dis BSD andlibaom/SVT-AV1are BSD/permissive → AV1 is LGPL-clean and rides the default variant, exactly like the dav1d entry in 0012 §3. - Patents. HEVC has an active, fragmented patent landscape — multiple pools (Via LA,
Access Advance, plus unaffiliated holders) with no sunset in sight, unlike the AVC pool that
expires 2027-11-29 (licensing.md). We mirror the openh264/AVC posture for
libx265: self-compiled from source → outside any binary patent grant; ship on a deliberate, bounded basis — low expected distribution volume, comply-on-demand (pull promptly from the full variant if any HEVC rights-holder asks), and state plainly that GPL is a copyright licence that conveys no patent rights. The caveat is harder than AVC's (active pools, no expiry) — so HEVC encode is the most licence-exposed thing in the catalogue and should ship only on real demand. AV1 is royalty-free by design (AOMedia's patent commitment) → no patent caveat; this is the decisive advantage that makes AV1 decode the recommended graduation. - Size. These are the largest libs in the survey.
libx265andlibaomeach add roughly a megaclass of static code;libdav1dis more modest but still sizeable. Against--enable-smallthis directly threatens the lean build (0022) — so any graduation lands in full (or a dedicated heavy bucket), never lean. Exact numbers are a 0022/0008 measurement input.
6. Decisions & open questions¶
- D-0023-A — HEVC decode: KEEP (done). Native, already enabled, no lib, both variants. Recorded as shipped; nothing to build.
- D-0023-B — HEVC encode (
libx265): DEFER to full variant, gate on demand. GPL + active patent pools + size + single-thread slowness make it the highest-cost encoder. Promote only when a real consumer needs HEVC output and accepts the full-variant + patent posture. Build path (cmake, asm/threads off) is feasible — the blocker is should we, not can we. - D-0023-C — AV1 decode (
libdav1d): RECOMMEND for the default variant. The strongest case in this spec: BSD (LGPL-clean), royalty-free, the correct decoder, lowest-risk no-asm build (clean C fallback). The one Tier-3 item that plausibly graduates first — gated only on size budget (0022) and a decode-throughput sanity check (0008). - D-0023-D — AV1 encode: DEFER as experimental, pending a 0008 measurement. Likely
impractical single-threaded:
SVT-AV1is thread-architected (loses its purpose at 1 thread),libaomis famously slow even threaded,rav1eis Rust (toolchain conflict, D-FW-E). Verdict flips only if a 0008 spike shows a tolerable single-threadlibaom/SVT-AV1encode at low preset on representative clips. - Open — cross-compile feasibility per encoder. dav1d (meson) and x265 (cmake) are expected to build; AV1-encode buildability is unverified — cmake/meson cross files for wasm32-wasi, asm fully disablable, no thread-spawn assumptions. Each is a spike before any promotion.
- Open — does "AV1 decode, no AV1 encode" satisfy consumers? Decode-only is the common need (play/transcode-from AV1); confirm before investing in encode.
7. Requirements¶
- R-PARITY-HEAVY-CODECS (this spec owns it): the heavy-codec gap is documented and gated — each of the four directions has an explicit do/defer verdict, a licence/patent posture, and the conditions (consumer need · size budget 0022 · measured perf 0008) for graduation. No code ships from this spec; it is the decision record the build specs cite when a verdict flips.
8. Test surface¶
When (if) a codec graduates, it needs the standard 0012 §6 treatment: a licence-clean fixture (a short AV1/HEVC clip — the synthetic in-memory WAV/PNG fixtures cannot cover these), a round-trip integration test over the real driver (decode AV1 → frames; full-variant HEVC encode → mux → probe), and a perf assertion is the gating test, not a pass/fail correctness one — the 0008 harness records single-thread frames/sec so the defer/promote line is data-backed. Until graduation: no tests; the codec names are simply absent from the build allowlist.
9. Dependencies & sequencing¶
- Depends on 0022 (lean/full matrix) — these libs must land in full/heavy, never lean; the bucketing decision precedes any enable.
- Depends on 0008 (perf) — the encode verdicts (D-0023-B, D-0023-D) are unresolvable without a single-thread measurement; 0008 is the gate.
- Independent of 0016/0017/0018 — no shared libs; this is purely the heavy/gated tail.
- Sequencing: last of the parity batch. Likely order if pursued: AV1 decode (dav1d, D-0023-C) first and standalone → HEVC encode (D-0023-B) on demand → AV1 encode (D-0023-D) only after a positive 0008 spike, if ever.
10. Definition of done (this scoping spec)¶
The four heavy-codec directions are catalogued with per-direction verdicts (D-0023-A keep, D-0023-B/D defer, D-0023-C recommend), the GPL+HEVC-patent posture is stated by mirroring the openh264/AVC model, the size threat to the lean build is flagged, and the graduation gates (0022 size · 0008 perf · consumer demand) plus the open cross-compile-feasibility questions are recorded. Implementation is explicitly out of scope — this spec exists so the build specs have a defensible answer to "why isn't HEVC/AV1 in the box yet?"