Research-1101: Vendoring the Pelorus interop ABI into vmafx¶
- Status: Closed (ADR-1113 Accepted)
- Workstream: Pelorus <-> vmafx bidirectional integration, workstream A (vmafx: vendor ABI)
- Last updated: 2026-06-14
- Related ADR: ADR-1113
- Source plan:
.workingdir2/rc/pelorus/PLAN.md(gitignored planning artifact; this digest is the tracked summary of its verified findings).
Question¶
vmafx needs the Pelorus data-plane interop ABI (a versioned per-frame side-data blob + its pack/parse pair) in-tree to compile a reader and run a conformance test. The ABI is owned by Pelorus (single source of truth, Pelorus ADR-0103). How should vmafx obtain it without (a) coupling its build to Pelorus's Vulkan/shader toolchain, (b) allowing the two repos' parsers to diverge silently, or (c) tripping the fork's touched-file lint rule on code it must not edit?
Options weighed¶
| Option | Verdict |
|---|---|
| Pinned read-only vendor + sync guard | Chosen. Zero build coupling; drift is mechanically detected; the shared conformance fixture proves byte-compat. |
| git submodule of pelorus | Rejected — drags in Pelorus's full build (Vulkan/shader deps vmafx rejects); poor UX in CI / release tarballs / worktrees. |
| meson subproject (wrap) | Rejected — couples to Pelorus's meson graph + option matrix; configure-time fetch is a release-pipeline liability for a flat, dependency-free ABI. |
| Hand-reimplement the parser | Rejected — two diverging implementations of a frozen wire format guarantee an eventual interop bug; defeats single-source-of-truth. |
The vendoring posture matches the fork's existing treatment of vendored code (core/src/svm.cpp, pdjson.c): copy verbatim, exclude from the strict lint profile, fix defects upstream. The only local edits are a DO NOT EDIT banner and a pelorus/<x>.h → libvmaf/pelorus/<x>.h include rewrite so the headers resolve under core/include/.
Verified findings (guess + check)¶
-
The conformance fixture needs more than
interop.c. Hypothesis: vendor onlyinterop.c+ 3 headers per the plan's A1. Check: the pelorusinterop_test.clinkspel_deband_params_default/validate(deband_params.c) andpelorus_version_string(version.c) and exercises thedeband_paramsvector (A3 requires keeping all 7 vectors). Conclusion: vendordeband_params.c+version.calongsideinterop.cso the fixture stays byte-identical and links. All three are CPU-only, dependency-free, BSD+Patent — the same vendoring posture applies. -
The local pelorus checkout had advanced past the pin. Hypothesis: diff the vendored mirror against the working tree at
/home/kilian/dev/vmafx/pelorus. Check:git -C … rev-parse HEADreturnedff63ebe, not the pinned835e097; the working tree had been reformatted (wider column limit) AND refactored (pel_blob_packsplit intovalidate_pack_sections+write_pack_headerhelpers). Conclusion: the drift guard must read the pinned commit's git tree object (git show 835e097:libpelorus/…), not the working tree, so it stays pin-accurate regardless of where the checkout'sHEADsits. With this fix the guard reports no drift against835e097. -
A dir-local
Checks: '-*'is the wrong lint-exclusion mechanism. Hypothesis: drop a.clang-tidywithChecks: '-*'in each vendored dir (clang-tidy uses the nearest config). Check:make lint-cand the CI clang-tidy job pass all changed files in a single invocation; aChecks: '-*'file makes clang-tidy abort the whole run withError: no checks enabled. Conclusion: use the repo's established idiom —grep -vpath exclusion in the Makefilelint-cglob and the CI workflow's exclusion filter (same placecore/src/svm.cppand the GPU TUs are excluded), plus a cppcheck suppression and theauto-format-on-edit.shhook skip. clang-format 22 was independently confirmed to reflow the vendored files (different version than pelorus's), so the format exclusion is load- bearing for byte-identity.
Outcome¶
Vendored 6 files (3 headers + 3 sources) + the conformance fixture; registered the sources in core/src/meson.build and the fixture in core/test/meson.build (fast suite). Conformance fixture passes 7/7; the sync guard reports no drift against 835e097; the vendored library objects compile clean under -pedantic. See ADR-1113 for the decision and docs/api/pelorus-interop.md for the consumer-facing reference.