Skip to content

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

Merged
lusoris merged 2 commits intomasterfrom
feat/vmaf-tune-encode-multi-codec
May 5, 2026
Merged

feat(tools): vmaf-tune encode.py — codec-agnostic dispatcher (unblocks 17 adapters)#376
lusoris merged 2 commits intomasterfrom
feat/vmaf-tune-encode-multi-codec

Conversation

@lusoris
Copy link
Copy Markdown
Owner

@lusoris lusoris commented May 3, 2026

Summary

Closes the dispatcher prerequisite called out in every adapter PR
description. Existing 13-test x264 suite stays bit-identical; new
19-test multi-codec suite (test_encode_multi_codec.py) pins the
dispatcher contract per codec.

ADR-0108 deliverables

  • Research digest: no digest needed: see Research-0070 (companion digest)
    docs/research/0054-vmaf-tune-encode-multi-codec.md.
  • Decision matrix: ADR-0297 § Alternatives considered.
  • AGENTS.md invariant note: rebase-notes entry 0228 pins the
    codec-agnostic-harness invariant (ADR-0237 follow-up).
  • Reproducer / smoke-test command: pytest tools/vmaf-tune/tests/ -q (32 passed).
  • CHANGELOG fragment: "Unreleased / lusoris fork" → "Added".
  • Rebase note:
    docs/rebase-notes.md
    entry 0228.

Test plan

  • pytest tools/vmaf-tune/tests/ -q — 32 passed (13 existing
    x264 + 19 new multi-codec).
  • ruff check tools/vmaf-tune/ — clean.
  • black --check tools/vmaf-tune/ — clean.
  • isort --check tools/vmaf-tune/ — clean.
  • pre-commit run --files <changed> — green (markdown / black /
    isort / ruff / semgrep / heredoc / conventional-commit).
  • x264 path bit-identical: composed argv on (libx264, medium, crf=23) matches Phase A verbatim.
  • Unknown-codec fallback exercised: missing adapter falls back to
    -c:v <enc> -preset <p> -crf <q> instead of raising.
  • Reviewer: confirm rebase-notes chore(release): introduce CHANGELOG + ADR-index fragment files (drop merge-conflict pain) #228 invariant matches
    ADR-0237's intent ("harness never branches on codec identity").

Hard-rules compliance

  • DO NOT break the existing x264 default path — preserved
    bit-identically; existing 13-test suite still green.
  • DO NOT remove fallback for adapters that don't ship
    ffmpeg_codec_args — fallback path explicitly retained and
    pinned by test_dispatcher_legacy_adapter_without_ffmpeg_codec_args
    • test_dispatcher_unknown_codec_falls_back_to_x264_shape.

🤖 Generated with Claude Code

@lusoris lusoris force-pushed the feat/vmaf-tune-encode-multi-codec branch from e451408 to 01eb63b Compare May 3, 2026 20:01
@lusoris lusoris marked this pull request as ready for review May 5, 2026 13:28
Copilot AI review requested due to automatic review settings May 5, 2026 13:28
…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 force-pushed the feat/vmaf-tune-encode-multi-codec branch from 01eb63b to 607c242 Compare May 5, 2026 13:29
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.

Refactors vmaf-tune’s encode.py into a codec-agnostic FFmpeg command dispatcher driven by codec adapters, expanding version parsing to be per-encoder and adding a multi-codec test suite to lock in the new contract.

Changes:

  • Turn encode.py into a dispatcher that delegates codec argv construction to adapter.ffmpeg_codec_args(...) with a legacy x264-shaped fallback.
  • Extend parse_versions(stderr, encoder=...) with a probe table covering multiple encoder families.
  • Add multi-codec dispatcher tests plus documentation/ADR/research/changelog updates for the new contract.

Reviewed changes

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

Show a summary per file
File Description
tools/vmaf-tune/src/vmaftune/encode.py Implements adapter-driven argv composition, legacy fallback, and per-encoder version probing.
tools/vmaf-tune/src/vmaftune/codec_adapters/init.py Updates the adapter Protocol to include dispatcher-consumed methods.
tools/vmaf-tune/src/vmaftune/codec_adapters/x264.py Implements ffmpeg_codec_args/extra_params for x264 to preserve bit-identical argv.
tools/vmaf-tune/tests/test_encode_multi_codec.py Adds a multi-codec test suite validating dispatcher behavior and fallbacks.
docs/usage/vmaf-tune.md Documents the codec adapter contract and dispatcher command shape.
docs/research/0070-vmaf-tune-encode-multi-codec.md Adds a research digest for the dispatcher design.
docs/rebase-notes.md Adds rebase note entry pinning the “no codec branching in harness” invariant.
docs/adr/README.md Registers the new ADR entry in the ADR index.
docs/adr/0297-vmaf-tune-encode-multi-codec.md Adds the ADR describing the dispatcher decision and consequences.
CHANGELOG.md Adds an Unreleased changelog entry for the dispatcher + tests + docs.

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

Comment on lines +1 to +6
# ADR-0294: `vmaf-tune` — codec-agnostic encode dispatcher

- **Status**: Accepted
- **Date**: 2026-05-03
- **Deciders**: Lusoris
- **Tags**: tooling, ffmpeg, codec, automation, fork-local
@@ -0,0 +1,127 @@
# Research-0054: `vmaf-tune` codec-agnostic encode dispatcher
Comment on lines 46 to +73
@@ -56,6 +60,18 @@ class CodecAdapter(Protocol):
quality_default: int
invert_quality: bool

def ffmpeg_codec_args(self, preset: str, quality: int) -> list[str]:
"""FFmpeg ``-c:v ...`` argv slice for one encode."""
...

def extra_params(self) -> tuple[str, ...]:
"""Additional non-codec argv (e.g. tile flags). May be empty."""
...

def validate(self, preset: str, quality: int) -> None:
"""Raise ``ValueError`` if ``(preset, quality)`` is unsupported."""
...
Comment on lines +162 to +164
_SVTAV1_VERSION_RE = re.compile(r"SVT-AV1.*?\sv?(\d+\.\d+(?:\.\d+)?)")
_LIBVPX_VERSION_RE = re.compile(r"libvpx-vp9.*?(\d+\.\d+\.\d+)|vpxenc\s+v(\d+\.\d+\.\d+)")
_LIBAOM_VERSION_RE = re.compile(r"libaom.*?(\d+\.\d+\.\d+)|aomenc.*?(\d+\.\d+\.\d+)")
Comment on lines +26 to +30
_HERE = Path(__file__).resolve().parent
sys.path.insert(0, str(_HERE.parent / "src"))

from vmaftune import codec_adapters as ca # noqa: E402
from vmaftune.encode import ( # noqa: E402
Comment thread docs/rebase-notes.md
### 0228 — `y4m_convert_411_422jpeg` 1-byte heap-buffer-overflow fix
### 0228 — `vmaf-tune` resolution-aware model selection (ADR-0289)
### 0282 — `vmaf-tune` AMD AMF codec adapters (ADR-0282)
### 0228 — `tools/vmaf-tune/` codec-agnostic encode dispatcher (ADR-0294)
@lusoris lusoris merged commit da5588d into master May 5, 2026
54 of 57 checks passed
@lusoris lusoris deleted the feat/vmaf-tune-encode-multi-codec branch May 5, 2026 13:55
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