Imported from VMAFx/vmafx (
pkg/codecadapter/AGENTS.md). Install upstream withnpx skills add VMAFx/vmafx --skill codecadapter. Copyright stays with the author.
AGENTS.md — the vmafx-tune ML-driven port
Go port of predictor-, saliency- and search-driven half of vmaf-tune:
recommend, predict, recommend-saliency, prefilter. Note covers
pkg/codecadapter + eight sibling packages — invariants below span
them.
| Package | Ports |
|---|---|
pkg/codecadapter |
vmaftune/codec_adapters/ |
pkg/ffencode |
vmaftune/encode.py |
pkg/scorecli |
vmaftune/score.py |
pkg/pershot |
vmaftune/per_shot.py (detection half) |
pkg/predictor |
vmaftune/predictor.py, predictor_features.py, predictor_validate.py |
pkg/conformal |
vmaftune/conformal.py (split-conformal half) |
pkg/uncertainty |
vmaftune/uncertainty.py |
pkg/recommend |
vmaftune/recommend.py |
pkg/saliency |
vmaftune/saliency.py |
pkg/prefilter |
vmaftune/prefilter.py, filter_adapters/pelorus_deband.py |
pkg/corpusrow |
the recommend-scoped part of vmaftune/corpus.py |
pkg/pyjson |
Python json.dumps / jsonio.dumps_strict output compatibility (ADR-1137) |
Rebase-sensitive invariants
-
Python is oracle, tests hold it.
pkg/codecadapter/golden_python_test.goandpkg/saliency/golden_python_test.goare machine-generated dumps of Python implementations run on fixed inputs;pkg/corpusrow'spythonSchemaV3KeysisCORPUS_ROW_KEYSverbatim. When Python adapter, kernel or row key changes, regenerate those tables in same change — do not edit Go side to make failing golden test pass. -
Adapter.FFmpegCodecArgsexcludesExtraParams;ResolveCodecArgsincludes them (codecadapter.go). Split mirrors Python'sffmpeg_codec_args/extra_paramslayering, whichencode._resolve_codec_argscomposes. Folding extras intoFFmpegCodecArgswould double libvpx-vp9's-row-mt 1once encode driver appends them again. libvpx's-b:v 0is NOT extra param: it is part of codec argv proper (qualityTail) — Python emits it fromffmpeg_codec_args. -
AMF trio's argv is deliberately de-duplicated. Python's
extra_params(preset, qp)onh264_amf/hevc_amf/av1_amfreturns same tokensffmpeg_codec_argsalready produced, so Python emits-quality … -rc cqp -qp_i … -qp_p …twice per AMF encode. Go port emits each token once; since ADR-1137 that holds for every encode driver (pkg/ffencode,pkg/corpus,pkg/encodeprofile,pkg/tune/executor) — all build argv through this registry.TestCodecArgsMatchPythonAtDefaultQualitypins exception precisely: Python fixture'sextramust equal codec-args tail, so change in what Python duplicates still caught. If future change makes duplication load-bearing (not today — FFmpeg takes last occurrence), deviation has to be revisited, not silently inherited. -
recommend's CRF window is 10–50, not adapter's quality range (cmd/vmafx-tune/cmd/recommend.go). Python CLI never overridescoarse_to_fine_search'scrf_min/crf_maxdefaults, so pinning Go side to adapter range would make two binaries visit different cells, produce non-comparable corpora. Change both sides together. -
Corpus JSONL carries bare
NaN/Infinitytokens. Unmeasured feature aggregate is NaN by design (ADR-0366); Python'sjson.dumpswrites bare token.pkg/corpusrowwrites them viapkg/pyjson;pkg/recommend.SanitizeNonFiniteTokensreads them back. Do NOT "fix" writer to emitnull: Python reader would then getNonewherefloat(None)raises, instead of NaN that propagates. Sanitiser is string-literal aware on purpose — source path containing textNaNmust survive. -
pkg/pyjsonis single implementation of Python-output compatibility (ADR-1137). Exists becauseencoding/jsondiverges in four places: cannot marshal NaN at all, renders93.0as93, HTML-escapes<,>and&, emits non-ASCII raw where Python escapes to\uXXXX. Every payload ML-driven subcommands emit goes through it. Do not reach forencoding/jsonfor user-facing payload. -
predictor.FeatureVector's fourteen-element order is pinned by model card (predictor.go).predictor_train.pyproduces models against that exact layout; reordering it silently corrupts every learned prediction rather than failing. Lives in one function for that reason. -
Analytical curve must stay monotone in CRF (
predictor.go).PickCRFbinary-searches curve — only sound becausePredictAnalyticalis non-increasing across every codec's whole quality range.TestPredictAnalytical_isMonotonesweeps all fourteen codecs to hold that; if coefficient set ever breaks it, fix coefficients, not test. -
NaN interval bounds must reach
uncertainty.Classifyintact (recommend.go,rowInterval). Row with novmaf_intervalblock gets NaN bounds, classify as MIDDLE, defer to point estimate. Substituting zero-width(point, point, point)interval would classify as TIGHT, short-circuit search on "lower bound" that is only point estimate.TestPickTargetVMAFWithUncertainty_zeroWidthIsNotTightis guard. -
Exit code 2 is load-bearing. Python CLI uses it for requested-but-unavailable feature (no Pelorus filter, no ROI dispatch for encoder, bad CRF range) and for
predict'sfall_backverdict; scripts branch on it.cmd/vmafx-tune/cmd/root.gohonours an error'sExitCode()for that reason. Returning plain error from those paths silently downgrades them to exit 1. -
Saliency inference is absent for specific reason, recorded in code.
cmd/vmafx-tune/cmd/saliencysession.go'sErrSaliencyInferenceUnavailabledocuments why (vmafx-ort-runnerbridge passes tensors through argv, cannot carry 3×H×W) and what would unblock it.TestSaliencySession_reportsWhyInferenceIsUnavailablefails moment implementation lands, forcing doc comment, CLI help anddocs/usage/vmafx-tune-go.mdto be updated together. -
TPE sampler is native; trajectory is NOT Optuna's.
pkg/prefilter/tpe.goimplements published construction rather than depending on Go Optuna port that would pull gorm plus MySQL, Postgres and cgo-SQLite drivers into one-shot CLI. Per-seed reproducibility and emitted schema are contractual; trial-by-trial sequence is not — no test should assert on it. Contract tests assert convergence against uniform baseline instead. -
Pelorus knob table is frozen two-repo contract (ADR-0110,
pkg/prefilter/knobs.go). Renaming, retyping or re-ranging knob is coordinated Pelorus + vmafx change.TestKnobTable_isTheFrozenContractpins all ten. Out-of-contract options (sample,blur,planes,meta) excluded on purpose, must stay rejected.