Research-0074: vmaf-tune Apple VideoToolbox codec adapters¶
- Date: 2026-05-05
- Status: Implementation digest (companion to ADR-0283).
- Tags: tooling, ffmpeg, codec, hardware-encoder, apple, fork-local
- Companion ADR: ADR-0283
Question¶
Add Apple VideoToolbox H.264 + HEVC adapters to tools/vmaf-tune/ following the same one-file-per-codec contract NVENC / AMF / QSV already use. Goal: macOS-host coverage for the harness so corpus runs on Apple Silicon are first-class.
Findings¶
- Encoder names. FFmpeg exposes two VideoToolbox-backed encoders:
h264_videotoolboxandhevc_videotoolbox. AV1 is not yet surfaced (noav1_videotoolboxas of FFmpeg 8.1 / 2026-Q1) — Apple Silicon does not include an AV1 hardware encoder block. - Quality knob. Both encoders take
-q:v <int>on the[0, 100]scale where higher is better quality. This inverts the x264 / x265 / NVENC convention (crflower = better) — the adapter'sinvert_quality=Falseflag tells the harness to leave the value alone. Default is60(matches FFmpeg's documented sweet spot for Apple-Silicon HEVC encoding). - Preset axis. VideoToolbox exposes only a binary
-realtime {0,1}flag. The harness's nine-name preset taxonomy (ultrafast…veryslow) collapses onto that boolean per the table in_videotoolbox_common.py:ultrafast/superfast/veryfast/faster/fast→realtime=1;medium/slow/slower/veryslow→realtime=0. The mapping is intentionally lossy — VT cannot expose a finer dial. - Subprocess seam. The smoke test mocks
subprocess.runso Linux CI stays green without a macOS runner. End-to-end run is left to a macOS contributor with VideoToolbox available locally. - Codec-aware regressor coupling. Originally proposed alongside a 16-slot codec one-hot vocab expansion. After
fr_regressor_v2shipped to production with the 13-slot vocab v2 schema (ADR-0291 / PR #397), the schema-expansion side requires a fresh production retrain to clear the 0.95 LOSO PLCC ship gate (ADR-0235); that work is split out into a follow-up PR. The VT adapters land independently because the registry-add doesn't change any numeric output.
Implementation note¶
Three new files:
tools/vmaf-tune/src/vmaftune/codec_adapters/h264_videotoolbox.pytools/vmaf-tune/src/vmaftune/codec_adapters/hevc_videotoolbox.pytools/vmaf-tune/src/vmaftune/codec_adapters/_videotoolbox_common.py
Plus a registry entry in codec_adapters/__init__.py and the smoke suite at tests/test_codec_adapter_videotoolbox.py (9 cases).
Decision¶
Land the two adapters now along the same one-file-per-codec contract NVENC / AMF / QSV use. Defer the codec-vocab schema-expansion + the fr_regressor_v2_hw retrain to a follow-up PR.