Skip to content

feat(tools): vmaf-tune Phase E — per-title bitrate ladder (game-changer)#371

Merged
lusoris merged 2 commits intomasterfrom
feat/vmaf-tune-phase-e-bitrate-ladder
May 5, 2026
Merged

feat(tools): vmaf-tune Phase E — per-title bitrate ladder (game-changer)#371
lusoris merged 2 commits intomasterfrom
feat/vmaf-tune-phase-e-bitrate-ladder

Conversation

@lusoris
Copy link
Copy Markdown
Owner

@lusoris lusoris commented May 3, 2026

Summary

Scaffolds Phase E of vmaf-tune — the per-title bitrate-ladder generator. PR #354's capability audit ranked this Bucket #6 the single biggest game-changer for the fork ("reshapes from 'best open-source VMAF measurement' into 'only open-source per-title ladder generator with measured-PLCC proxy'"). Mirrors the Netflix per-title encoding paper: sample (resolution × target-VMAF), take the Pareto upper-convex hull on (bitrate, vmaf), pick n rungs along the hull, emit an HLS / DASH / JSON manifest.

  • New tools/vmaf-tune/src/vmaftune/ladder.pybuild_ladder (pluggable sampler), convex_hull (two-pass: Pareto filter + diminishing-returns envelope), select_knees (log-bitrate or VMAF spacing), emit_manifest (HLS / DASH / JSON), and a build_and_emit convenience.
  • New vmaf-tune ladder CLI subcommand with the canonical 5-rung 1080p/720p/480p/360p/240p default rendition set.
  • 15 new ladder tests (28 total in tools/vmaf-tune/tests/) — hull correctness on a synthetic Netflix-paper-shaped cloud, knee invariants, HLS / DASH / JSON manifest shape.

Scaffold-only. The production sampler that drives Phase B's target-VMAF bisect (PR #347) wires up in a follow-up PR. Default sampler raises NotImplementedError; tests inject a synthetic stub. Status flips Proposed → Accepted once Phase B merges and a real-corpus PLCC validation digest lands.

Test plan

  • python -m pytest tools/vmaf-tune/tests/ -v — 28 passed (13 corpus + 15 ladder).
  • python -m ruff check tools/vmaf-tune/ — clean.
  • PYTHONPATH=tools/vmaf-tune/src python -m vmaftune.cli ladder --help — argparse renders.
  • Phase B integration follow-up PR (gated on PR feat(ai): fr_regressor_v2 codec-aware scaffold (Phase B prereq) #347): swap _default_sampler for a real bisect-driven sampler; end-to-end smoke against a Netflix Public clip.
  • Real-corpus PLCC validation digest: hull-picked rungs vs. Netflix's published per-title rungs (gated on Phase B + Phase A encodes).

Six deep-dive deliverables (ADR-0108)

  • (1) Research digest: docs/research/0068-vmaf-tune-phase-e-bitrate-ladder.md (algorithm survey: Netflix per-title, Apple HLS authoring spec, JND-spaced, BO sampler).
  • (2) Decision matrix: ADR-0295 ## Alternatives considered (5 alternatives weighed: Pareto+convex / Apple fixed / geometric / JND / BO).
  • (3) AGENTS.md invariant note: tools/vmaf-tune/AGENTS.md updated with the two-pass hull invariant and the "default sampler raises by design" rule.
  • (4) Reproducer / smoke-test command: python -m pytest tools/vmaf-tune/tests/test_ladder.py -v.
  • (5) CHANGELOG fragment: top of "Unreleased / lusoris fork" Added section.
  • (6) Rebase note: docs/rebase-notes.md entry 0229 (no upstream-shared paths touched; fork-local Python tool).

References

🤖 Generated with Claude Code

@lusoris lusoris force-pushed the feat/vmaf-tune-phase-e-bitrate-ladder branch from 97e5fd3 to 1515c1c Compare May 3, 2026 19:41
@lusoris lusoris marked this pull request as ready for review May 5, 2026 11:02
Copilot AI review requested due to automatic review settings May 5, 2026 11:02
@lusoris lusoris force-pushed the feat/vmaf-tune-phase-e-bitrate-ladder branch from 1515c1c to bd0958d Compare May 5, 2026 11:03
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.

Scaffolds Phase E of vmaf-tune by adding a per-title bitrate ladder generator (Pareto + diminishing-returns “hull”, knee selection, and manifest emitters) plus a new vmaf-tune ladder CLI subcommand and accompanying documentation/tests.

Changes:

  • Added vmaftune.ladder module implementing ladder sampling API, hull computation, knee selection, and HLS/DASH/JSON emitters.
  • Added vmaf-tune ladder CLI subcommand with parsing helpers and output support.
  • Added Phase E docs/ADR/research notes and a new ladder-focused test suite.

Reviewed changes

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

Show a summary per file
File Description
tools/vmaf-tune/src/vmaftune/ladder.py New Phase E core implementation: sampling contract, hull math, rung selection, manifest emitters, convenience wrapper.
tools/vmaf-tune/src/vmaftune/cli.py Registers ladder subcommand and parses ladder-related flags.
tools/vmaf-tune/tests/test_ladder.py Adds synthetic sampler + invariants/tests for hull, knee selection, and manifest formats.
tools/vmaf-tune/AGENTS.md Documents Phase E invariants (two-pass hull, sampler behavior).
docs/usage/vmaf-tune.md Documents Phase E usage/flags and scaffold status.
docs/research/0067-vmaf-tune-phase-e-bitrate-ladder.md Adds Phase E algorithm survey write-up.
docs/rebase-notes.md Adds rebase note entry for Phase E ladder scaffold.
docs/adr/README.md Adds ADR index entry for ADR-0295.
docs/adr/0295-vmaf-tune-phase-e-bitrate-ladder.md Adds Phase E ADR describing decision/scope.
CHANGELOG.md Adds Unreleased entry describing Phase E ladder feature and tests.

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

Comment on lines +243 to +251
# Avoid duplicates if two targets snap to the same point.
while idx in seen and idx + 1 < len(hull):
idx += 1
seen.add(idx)
chosen.append(hull[idx])
chosen.sort(key=lambda p: p.bitrate_kbps)
return [_rendition_of(p) for p in chosen]


Comment on lines +326 to +335
def _emit_hls(ladder: Sequence[Rendition]) -> str:
lines: list[str] = ["#EXTM3U", "#EXT-X-VERSION:6"]
for r in ladder:
bps = int(round(r.bitrate_kbps * 1000.0))
uri = f"rendition_{r.width}x{r.height}_{int(round(r.bitrate_kbps))}k.m3u8"
lines.append(
f"#EXT-X-STREAM-INF:BANDWIDTH={bps},RESOLUTION={r.width}x{r.height},"
f'CODECS="avc1.640028"'
)
lines.append(uri)
Comment on lines +343 to +350
reps.append(
f' <Representation id="r{i}" bandwidth="{bps}" '
f'width="{r.width}" height="{r.height}" '
f'codecs="avc1.640028" mimeType="video/mp4">\n'
f" <BaseURL>rendition_{r.width}x{r.height}_"
f"{int(round(r.bitrate_kbps))}k.mp4</BaseURL>\n"
f" </Representation>"
)
Comment on lines +196 to +197
Positive = counter-clockwise turn (point ``b`` is above the line
o->a, which is what we want on the upper hull).
Comment on lines +618 to +626
manifest = build_and_emit(
src=args.src,
encoder=args.encoder,
resolutions=resolutions,
target_vmafs=target_vmafs,
quality_tiers=args.quality_tiers,
format=args.format,
spacing=args.spacing,
)
Comment on lines +365 to +366
help="source video (used to label the manifest; sampling is currently "
"Phase B / Phase A driven)",
Comment thread docs/usage/vmaf-tune.md
Comment on lines 24 to +32
[ADR-0276](../adr/0276-vmaf-tune-phase-d-per-shot.md)). Phases B
(target-VMAF bisect), C (per-title CRF predictor), E (Pareto ABR
ladder) and F (MCP tools) are not implemented yet — see ADR-0237.
This doc covers **Phase A** of the six-phase roadmap (a `libx264` grid
sweep that produces the corpus the later phases consume) and **Phase E**
(per-title bitrate-ladder generator — scaffold-only until Phase B's
target-VMAF bisect merges). Phases B (target-VMAF bisect), C (per-title
CRF predictor), D (per-shot dynamic CRF), and F (MCP tools) are not
implemented yet — see [ADR-0237](../adr/0237-quality-aware-encode-automation.md)
Comment thread CHANGELOG.md
Comment on lines +303 to +305
- **vmaf-tune Phase E — per-title bitrate-ladder generator
(ADR-0277).** Ships
[`tools/vmaf-tune/src/vmaftune/ladder.py`](tools/vmaf-tune/src/vmaftune/ladder.py)
Comment on lines +1 to +5
# Research-0054: vmaf-tune Phase E — per-title bitrate-ladder algorithm survey

- **Date**: 2026-05-03
- **Author**: Lusoris (with Claude assistance)
- **Companion**: [ADR-0295](../adr/0295-vmaf-tune-phase-e-bitrate-ladder.md)
Scaffolds the Phase E ladder generator (ADR-0277) — the highest-leverage
gap surfaced by PR #354's capability audit (Bucket #6). Mirrors the
Netflix per-title encoding paper: sample (resolution × target-VMAF),
take the Pareto upper-convex hull on (bitrate, vmaf), pick n rungs along
the hull, emit an HLS / DASH / JSON manifest.

Currently scaffold-only: the production sampler that drives Phase B's
target-VMAF bisect (PR #347) lands once that PR merges. Default sampler
raises NotImplementedError; tests inject a synthetic stub modelled on
the Netflix paper's R-D curves.

- New module tools/vmaf-tune/src/vmaftune/ladder.py — build_ladder,
  convex_hull (Pareto filter + diminishing-returns envelope),
  select_knees (log-bitrate or VMAF spacing), emit_manifest (HLS / DASH
  / JSON), and a build_and_emit convenience.
- New `vmaf-tune ladder` CLI subcommand with the canonical 5-rung
  1080p/720p/480p/360p/240p default rendition set.
- 15 new ladder tests (28 total in tools/vmaf-tune/tests/) covering hull
  correctness on a synthetic Netflix-paper-shaped cloud, knee selection
  invariants, and HLS / DASH / JSON manifest emit shape.
- ADR-0277 (Proposed; flips to Accepted once Phase B integration PR
  lands and a real-corpus PLCC validation digest reports the delta).
- Research-0054 surveys the algorithm space (Netflix per-title paper,
  Apple HLS authoring spec, JND-spaced, BO sampling).
- docs/usage/vmaf-tune.md gains a "Per-title ladder (Phase E)" section
  with the canonical invocation.
- CHANGELOG, rebase-notes (#229), AGENTS.md invariant note.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@lusoris lusoris force-pushed the feat/vmaf-tune-phase-e-bitrate-ladder branch 3 times, most recently from 181224a to 7076c54 Compare May 5, 2026 11:31
@lusoris lusoris force-pushed the feat/vmaf-tune-phase-e-bitrate-ladder branch from 7076c54 to 93e0d77 Compare May 5, 2026 11:33
@lusoris lusoris merged commit ae0f7a2 into master May 5, 2026
54 checks passed
@lusoris lusoris deleted the feat/vmaf-tune-phase-e-bitrate-ladder branch May 5, 2026 12:00
@lusoris lusoris restored the feat/vmaf-tune-phase-e-bitrate-ladder branch May 6, 2026 17:42
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