Skip to content

feat(tune): vmafx-tune Go Stage 2 — ladder subcommand (ADR-0730)#49

Open
lusoris wants to merge 1 commit into
masterfrom
feat/vmafx-tune-go-stage2-20260528
Open

feat(tune): vmafx-tune Go Stage 2 — ladder subcommand (ADR-0730)#49
lusoris wants to merge 1 commit into
masterfrom
feat/vmafx-tune-go-stage2-20260528

Conversation

@lusoris
Copy link
Copy Markdown
Contributor

@lusoris lusoris commented May 28, 2026

Summary

  • Ports the per-title ABR bitrate-ladder generator from Python to Go as
    the Stage-2 subcommand of vmafx-tune-go.
  • New package pkg/ladder/ implements convex hull (Pareto frontier) +
    Kneedle knee selection + min-bitrate-gap filter; unit-testable without
    ffmpeg or vmaf on PATH via SamplerFn injection.
  • New subcommand vmafx-tune-go ladder wires bisect.Run as the
    production sampler; supports all hardware encoders (NVENC, QSV, AMF,
    SVT-AV1) via encoder.NewExtended.
  • JSON output (schema_version:1) is a superset of Python ladder.py
    output; Markdown output mirrors ladder.py _emit_markdown.
  • ladder removed from the stub list in root.go; stubs updated to
    "Stage 3+" messaging.

Deep-dive deliverables (ADR-0108)

  • Research digest: no digest needed: continues ADR-0705 Stage-1 playbook
  • Decision matrix: ADR-0730 ## Alternatives considered (bisect vs tune-per-shot vs report first; sequential vs concurrent; resolution scaling scope)
  • AGENTS.md invariant note: cmd/vmafx-tune/AGENTS.md invariants 7–10 (SamplerFn seam, ladder JSON schema forward-compat, Stage-2 resolution note, Stage-3 contract)
  • Reproducer: go test ./pkg/ladder/... ./pkg/bisect/... ./pkg/encoder/... ./cmd/vmafx-tune/...
  • Changelog fragment: changelog.d/added/vmafx-tune-go-stage2.md
  • Rebase notes: docs/rebase-notes.md — no upstream impact; Python ladder.py hull/knee divergence points documented

Per-surface docs (ADR-0100 / CLAUDE §12 r10)

  • docs/usage/vmafx-tune-go.md updated: ladder flags table, output
    schema example, Go-vs-Python behavioural differences table, updated
    migration roadmap (Stage 1 → Stage 5).

ffmpeg-patches impact

no rebase impact: no public C-API or header changes; pure Go addition

state.md

no state.md update needed: no bug opened, closed, or ruled not-affecting

Test plan

  • go test ./pkg/ladder/... — all unit tests pass without ffmpeg/vmaf
  • go test ./cmd/vmafx-tune/... — build + flag tests pass
  • vmafx-tune-go ladder --help — lists all flags including --max-rungs, --min-bitrate-gap
  • vmafx-tune-go ladder --reference src.mp4 --codec libx264 --targets 75,85,95 --resolutions 320x240,1280x720 --output ladder.json — emits valid JSON with schema_version:1
  • vmafx-tune-go tune-per-shot — still exits non-zero with redirect message
  • vmafx-tune-go compare --reference src.mp4 --codecs libx264 --targets 85 — compare still works

🤖 Generated with Claude Code

@lusoris lusoris marked this pull request as ready for review May 28, 2026 16:24
@lusoris lusoris enabled auto-merge (squash) May 28, 2026 16:25
@lusoris lusoris force-pushed the feat/vmafx-tune-go-stage2-20260528 branch from 24306b5 to dd8ccf5 Compare May 28, 2026 17:35
Ports the per-title ABR bitrate-ladder generator from Python to Go as
the Stage-2 subcommand of vmafx-tune-go (following Stage-1 compare).

New package pkg/ladder/:
- Build(src, encoder, Params) — samples a (resolution x VMAF-target)
  grid via an injectable SamplerFn, computes the upper convex hull
  (Pareto frontier), selects knee renditions via Kneedle perpendicular-
  distance recursion, and applies a min-bitrate-gap filter.
- Unit-testable without ffmpeg or vmaf on PATH (SamplerFn seam).

New subcommand cmd/vmafx-tune/cmd/ladder.go:
- Wires bisect.Run as the production sampler for each grid cell.
- Supports all hardware encoders (NVENC, QSV, AMF, SVT-AV1) via
  encoder.NewExtended, not just Stage-1 libx264/libx265.
- JSON output (schema_version:1) is a superset of Python ladder.py
  output; Markdown output mirrors ladder.py _emit_markdown.

Six deep-dive deliverables (ADR-0108):
(a) no digest needed: continues ADR-0705 Stage-1 playbook
(b) ADR-0730 Alternatives considered: bisect vs tune-per-shot vs report
    first; sequential vs concurrent sampling; resolution scaling scope
(c) AGENTS.md updated: Stage-2 SamplerFn seam (inv. 7-10), Stage-3
    contract
(d) Reproducer: go test ./pkg/ladder/... ./cmd/vmafx-tune/...
(e) changelog.d/added/vmafx-tune-go-stage2.md
(f) docs/rebase-notes.md entry

Per-surface docs: docs/usage/vmafx-tune-go.md updated with ladder
flags, output schema, and Go-vs-Python behavioural differences table.

Also: .markdownlint.json disables MD040/MD060 (IDE-only warnings,
not enforced by make lint or CI).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@lusoris lusoris force-pushed the feat/vmafx-tune-go-stage2-20260528 branch from dd8ccf5 to d9de1ef Compare May 28, 2026 19:34
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.

1 participant