Skip to content

feat(tools): vmaf-tune — libaom-av1 codec adapter#360

Merged
lusoris merged 4 commits intomasterfrom
feat/vmaf-tune-codec-adapter-libaom
May 5, 2026
Merged

feat(tools): vmaf-tune — libaom-av1 codec adapter#360
lusoris merged 4 commits intomasterfrom
feat/vmaf-tune-codec-adapter-libaom

Conversation

@lusoris
Copy link
Copy Markdown
Owner

@lusoris lusoris commented May 3, 2026

Summary

  • Adds LibaomAdapter at
    tools/vmaf-tune/src/vmaftune/codec_adapters/libaom.py — the AV1
    reference-encoder companion to the parallel SVT-AV1 and x265
    adapter PRs.
  • Populates the fourth slot of the fr_regressor_v2 six-slot codec
    one-hot (x264, x265, svtav1, libaom, ?, ?).
  • Exposes the canonical adapter contract (name, encoder, quality knob,
    range, default, invert, presets, validate) plus two libaom-specific
    helpers: cpu_used(preset) -> int and ffmpeg_codec_args(preset, crf) -> tuple[str, ...] returning the argv slice that goes after
    -c:v libaom-av1.
  • CRF range is the full libaom window [0, 63] with default 35.
    Preset vocabulary parallels x264/x265/svtav1 so a single --preset
    axis covers all four codecs.

Preset → cpu-used mapping

--preset -cpu-used
placebo 0
slowest 1
slower 2
slow 3
medium 4 (default)
fast 5
faster 6
veryfast 7
superfast 8
ultrafast 9

Sample FFmpeg invocation produced by the adapter:

ffmpeg -i ref.y4m -c:v libaom-av1 -crf 35 -cpu-used 4 -an -y out.mkv

Routing the libaom argv slice through
vmaftune.encode.build_ffmpeg_command is a follow-up alongside the
codec-pluggable encode wiring (encode.py currently hardcodes
-preset; libaom uses -cpu-used).

Six ADR-0108 deliverables

  • (1) Research digest: no digest needed: trivial adapter scaffold (option-space
    covered by Research-0044 + ADR-0237).
  • (2) Decision matrix: ADR-0279 §Alternatives considered (libaom
    skipped, cpu-used integer knob, full inline argv).
  • (3) AGENTS.md invariant note: tools/vmaf-tune/AGENTS.md adds the
    shared cross-codec preset-vocabulary invariant.
  • (4) Reproducer / smoke-test command: pytest tools/vmaf-tune/tests/ (25
    pass, mocks subprocess so no ffmpeg/libaom binary required).
  • (5) CHANGELOG fragment: Unreleased / lusoris fork §Added.
  • (6) Rebase note: ### 0279 entry; no upstream interaction.

Test plan

  • pytest tools/vmaf-tune/tests/ — 25 / 25 pass.
  • ruff check over touched Python files clean.
  • pre-commit run --files <touched> clean.
  • Reviewer: pytest tools/vmaf-tune/tests/test_codec_adapter_libaom.py
  • Reviewer: confirm from vmaftune.codec_adapters import LibaomAdapter
    works from a fresh editable install.

Refs

🤖 Generated with Claude Code

lusoris pushed a commit that referenced this pull request May 3, 2026
…s 17 adapters)

Refactors `tools/vmaf-tune/src/vmaftune/encode.py` away from the Phase A
hard-coded `libx264` `-c:v / -preset / -crf` argv. `run_encode` now
looks up the codec adapter via `codec_adapters.get_adapter(req.encoder)`
and asks it for the FFmpeg argv slice via
`adapter.ffmpeg_codec_args(preset, quality)` plus an optional
`adapter.extra_params()`. Adapters that don't yet expose
`ffmpeg_codec_args` fall back silently to the legacy x264-CRF shape so
partial in-flight adapter PRs stay drivable end-to-end.
`parse_versions(stderr, encoder=...)` selects a per-codec version probe
(libx264, libx265, libsvtav1, libvpx-vp9, libaom-av1, libvvenc, NVENC,
QSV, AMF, VideoToolbox); unknown encoders return "unknown" rather than
raising. The `EncodeRequest.crf` field is preserved unchanged for the
SCHEMA_VERSION=1 row contract; a `quality` property mirrors it for
adapter-side codec-agnostic vocabulary.

Existing 13-test x264 suite still green; new 19-test multi-codec suite
covers 9 representative codec shapes plus the unknown-codec /
missing-method fallback paths. Unblocks 17 in-flight codec adapter PRs
(#360 libaom, #362 libx265, #364 NVENC, #366 AMF, #367 QSV, #368
libvvenc, #370 libsvtav1, #373 VideoToolbox, plus follow-on waves)
which can now drive end-to-end encodes without copying or mutating the
harness.

Ships ADR-0294 + research digest 0054, vmaf-tune.md "Codec adapter
contract" section, rebase-notes #228 invariant, CHANGELOG entry.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@lusoris lusoris marked this pull request as ready for review May 5, 2026 05:51
Copilot AI review requested due to automatic review settings May 5, 2026 05:51
@lusoris lusoris force-pushed the feat/vmaf-tune-codec-adapter-libaom branch from 49f9e6a to e1e8cf7 Compare May 5, 2026 05:51
Adds LibaomAdapter under tools/vmaf-tune/src/vmaftune/codec_adapters/
as the AV1 reference-encoder companion to the parallel SVT-AV1 and
x265 adapter PRs. Populates the fourth slot of the fr_regressor_v2
six-slot codec one-hot (x264, x265, svtav1, libaom, ?, ?).

The adapter exposes the canonical contract (name, encoder, quality
knob, range, default, invert flag, presets tuple, validation) plus
two libaom-specific helpers:

  - cpu_used(preset) -> int    : preset name -> -cpu-used 0..9
  - ffmpeg_codec_args(preset, crf) -> tuple[str, ...]
                                : argv slice after `-c:v libaom-av1`

CRF range is the full libaom window [0, 63] with default 35. The
preset vocabulary parallels x264/x265/svtav1 (placebo .. ultrafast),
mapping placebo=0 (slowest) through ultrafast=9 (fastest), so the
search loop's --preset axis covers all four codecs without branching
on codec name.

Routing the libaom argv slice through vmaftune.encode is a follow-up
alongside the codec-pluggable encode wiring (encode.py currently
hardcodes -preset, libaom uses -cpu-used).

User-facing docs in docs/usage/vmaf-tune.md cover the preset
mapping and the libaom-vs-SVT-AV1 trade-off (libaom is meaningfully
slower at matched presets but tends to deliver slightly higher
quality at the same bitrate at slow presets per AOM benchmarks).

Six ADR-0108 deliverables:
  1. research digest    — none (trivial adapter scaffold)
  2. decision matrix    — ADR-0278 §Alternatives considered
  3. AGENTS.md          — preset-vocabulary invariant added
  4. smoke-test         — pytest tools/vmaf-tune/tests/ (25 pass)
  5. CHANGELOG entry    — "Unreleased / lusoris fork" §Added
  6. rebase-notes       — ### 0278 entry, no upstream interaction

Refs: ADR-0237, ADR-0278.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@lusoris lusoris force-pushed the feat/vmaf-tune-codec-adapter-libaom branch from e1e8cf7 to d24262e Compare May 5, 2026 05:52
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Note

Copilot was unable to run its full agentic suite in this review.

Adds a new LibaomAdapter for vmaf-tune so libaom-av1 appears in the codec-adapter registry alongside x264, with documentation and unit tests for its preset/CRF mapping behavior.

Changes:

  • Adds tools/vmaf-tune/src/vmaftune/codec_adapters/libaom.py implementing libaom metadata, validation, preset→cpu-used mapping, and FFmpeg argv generation.
  • Registers libaom-av1 in vmaftune.codec_adapters and updates tests to allow multiple registered codecs.
  • Documents the new adapter across usage docs, ADRs, changelog, and rebase notes.

Reviewed changes

Copilot reviewed 10 out of 10 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
tools/vmaf-tune/tests/test_corpus.py Relaxes registry test so adding codecs no longer breaks x264-focused assertions.
tools/vmaf-tune/tests/test_codec_adapter_libaom.py Adds unit tests for libaom registration, validation, mapping, and immutability.
tools/vmaf-tune/src/vmaftune/codec_adapters/libaom.py Introduces the new libaom adapter implementation.
tools/vmaf-tune/src/vmaftune/codec_adapters/__init__.py Exports and registers the new adapter in the shared codec registry.
tools/vmaf-tune/AGENTS.md Documents adapter invariants and cross-codec preset vocabulary.
docs/usage/vmaf-tune.md Adds user-facing libaom adapter documentation and trade-off notes.
docs/rebase-notes.md Records the fork-local rebase note for this adapter landing.
docs/adr/README.md Adds the ADR index entry for the libaom adapter decision.
docs/adr/0279-vmaf-tune-codec-adapter-libaom.md Adds the ADR describing the libaom adapter design and follow-ups.
CHANGELOG.md Adds a changelog entry for the new adapter.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.


_REGISTRY: dict[str, CodecAdapter] = {
"libx264": X264Adapter(),
"libaom-av1": LibaomAdapter(),
Comment on lines +38 to +51
_PRESET_CPU_USED: Mapping[str, int] = MappingProxyType(
{
"placebo": 0,
"slowest": 1,
"slower": 2,
"slow": 3,
"medium": 4,
"fast": 5,
"faster": 6,
"veryfast": 7,
"superfast": 8,
"ultrafast": 9,
}
)
Comment thread docs/rebase-notes.md
```

### 0229 — `vmaf_tiny_v3` + `vmaf_tiny_v4` dynamic-PTQ int8 sidecars (ADR-0275)
### 0278 — `vmaf-tune` libaom-av1 codec adapter (2026-05-03)
Comment thread CHANGELOG.md
[docs/research/0061-vmaf-tune-capability-audit.md](docs/research/0061-vmaf-tune-capability-audit.md);
parent ADR is
[ADR-0237](docs/adr/0237-quality-aware-encode-automation.md).
- **`vmaf-tune` codec adapter — libaom-av1 (ADR-0278).** Adds
@lusoris lusoris merged commit 996c0ef into master May 5, 2026
54 checks passed
@lusoris lusoris deleted the feat/vmaf-tune-codec-adapter-libaom branch May 5, 2026 06:40
lusoris pushed a commit that referenced this pull request May 5, 2026
…s 17 adapters)

Refactors `tools/vmaf-tune/src/vmaftune/encode.py` away from the Phase A
hard-coded `libx264` `-c:v / -preset / -crf` argv. `run_encode` now
looks up the codec adapter via `codec_adapters.get_adapter(req.encoder)`
and asks it for the FFmpeg argv slice via
`adapter.ffmpeg_codec_args(preset, quality)` plus an optional
`adapter.extra_params()`. Adapters that don't yet expose
`ffmpeg_codec_args` fall back silently to the legacy x264-CRF shape so
partial in-flight adapter PRs stay drivable end-to-end.
`parse_versions(stderr, encoder=...)` selects a per-codec version probe
(libx264, libx265, libsvtav1, libvpx-vp9, libaom-av1, libvvenc, NVENC,
QSV, AMF, VideoToolbox); unknown encoders return "unknown" rather than
raising. The `EncodeRequest.crf` field is preserved unchanged for the
SCHEMA_VERSION=1 row contract; a `quality` property mirrors it for
adapter-side codec-agnostic vocabulary.

Existing 13-test x264 suite still green; new 19-test multi-codec suite
covers 9 representative codec shapes plus the unknown-codec /
missing-method fallback paths. Unblocks 17 in-flight codec adapter PRs
(#360 libaom, #362 libx265, #364 NVENC, #366 AMF, #367 QSV, #368
libvvenc, #370 libsvtav1, #373 VideoToolbox, plus follow-on waves)
which can now drive end-to-end encodes without copying or mutating the
harness.

Ships ADR-0294 + research digest 0054, vmaf-tune.md "Codec adapter
contract" section, rebase-notes #228 invariant, CHANGELOG entry.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
lusoris added a commit that referenced this pull request May 5, 2026
…s 17 adapters) (#376)

* feat(tools): vmaf-tune encode.py — codec-agnostic dispatcher (unblocks 17 adapters)

Refactors `tools/vmaf-tune/src/vmaftune/encode.py` away from the Phase A
hard-coded `libx264` `-c:v / -preset / -crf` argv. `run_encode` now
looks up the codec adapter via `codec_adapters.get_adapter(req.encoder)`
and asks it for the FFmpeg argv slice via
`adapter.ffmpeg_codec_args(preset, quality)` plus an optional
`adapter.extra_params()`. Adapters that don't yet expose
`ffmpeg_codec_args` fall back silently to the legacy x264-CRF shape so
partial in-flight adapter PRs stay drivable end-to-end.
`parse_versions(stderr, encoder=...)` selects a per-codec version probe
(libx264, libx265, libsvtav1, libvpx-vp9, libaom-av1, libvvenc, NVENC,
QSV, AMF, VideoToolbox); unknown encoders return "unknown" rather than
raising. The `EncodeRequest.crf` field is preserved unchanged for the
SCHEMA_VERSION=1 row contract; a `quality` property mirrors it for
adapter-side codec-agnostic vocabulary.

Existing 13-test x264 suite still green; new 19-test multi-codec suite
covers 9 representative codec shapes plus the unknown-codec /
missing-method fallback paths. Unblocks 17 in-flight codec adapter PRs
(#360 libaom, #362 libx265, #364 NVENC, #366 AMF, #367 QSV, #368
libvvenc, #370 libsvtav1, #373 VideoToolbox, plus follow-on waves)
which can now drive end-to-end encodes without copying or mutating the
harness.

Ships ADR-0294 + research digest 0054, vmaf-tune.md "Codec adapter
contract" section, rebase-notes #228 invariant, CHANGELOG entry.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* chore(docs): renumber encode-multi-codec ADR 0294→0297 + research 0069→0070

---------

Co-authored-by: Lusoris <lusoris@pm.me>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants