Commit Graph
24 Commits
Author SHA1 Message Date
Brandon ThomasandClaude Opus 5.5 39f60de2f4 #1457: bound slice-group map type 6 by the picture's map units (CIF FMO is 396), drop pr1441.md
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-13 01:34:27 -04:00
bfenty 1ef2960514 h264: validate PPS fields before arithmetic; conceal weighted_bipred_idc 3 (#1441) 2026-10-12 21:15:13 +00:00
jahvariandCodex fbbb57d325 WIN-02: Serialize shared codec test fixture publication
Prevent concurrent fixture producers from replacing files held open by
external decoders. Add a four-consumer Windows sharing regression.

Co-Authored-By: Codex (GPT-6) <noreply@openai.com>
2026-10-10 22:39:51 -05:00
JordyUSAandClaude Opus 5.5 3496e553e7 HW5: Linux VA-API H.264 hardware decoding (#30)
Stateless VA-API decoding with FilmCraft's own H.264 host side: the
software decoder's SPS/PPS/slice-header parsers and its DPB (now generic
over the picture type in filmcraft-h264) drive the GPU, so reference
marking, reference lists and output order are shared and the pictures are
bit-exact with the software decoder. libva is loaded at run time; no libva
or driver means software decoding as before. frame_num gaps (open-GOP
seeks) get the software decoder's stand-in frames. HybridDecoder keeps the
transparent software fallback.

Tests: hardware parity on 7 H.264 streams incl. 1080p/2160p, seeks,
flushes, forced failures, fuzzing, concurrency; front end against a
recording stand-in on every OS; ABI checks against va.h. Docs: platform
README, ADR 0001 addendum, architecture, performance (H.264 2160p CPU per
frame 417 -> 11 ms on Iris Xe), roadmap.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 08:35:57 +07:00
justjohn12345andClaude Opus 5.5 4f3e119ac2 MEM4: decode into the planes of evicted frames
With MEM1-MEM3 twelve clips on a timeline still took 5.1 GB, only 2.5 GB of
it live: each decoded picture allocated three planes, each eviction freed
them, and the system allocator kept the freed pages.

filmcraft_frame::pool keeps the planes of frames the GOP caches evict (up to
192 MiB per sample type; a frame something else still holds is left alone).
The H.264 decoder, through a plane allocator hook that keeps the crate free
of dependencies, and the VideoToolbox path take their output planes from it.

perf.stats reports decode.planePoolMB and decode.planesReused.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-05 16:57:16 -04:00
Brandon ThomasandClaude Opus 5.5 0f678aa105 h264: dequantisation wraps instead of overflowing on huge levels
Mutation fuzzing found a corrupt H.264 transport stream whose chroma DC levels overflowed
`chroma_dc_dequant_420` ("attempt to multiply with overflow" in debug builds, a decoder worker
panic). The 4x4 / 8x8 / DC dequantisers now use wrapping arithmetic, which is what release
builds always computed. Regression test `huge_levels_dequantise_without_overflow_panics`.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-04 11:56:22 -04:00
Brandon ThomasandClaude Opus 5.5 a87ba26844 h264: never crash — no unwrap/expect in the decoder, deny them
- I_PCM samples, deblocking lines, transform rows, block copies: fixed-size views through
  `get()` + `first_chunk(_mut)` instead of slice + `try_into().unwrap()`. A truncated I_PCM
  macroblock is `Error::Invalid` from the read itself.
- Decoder: a missing parameter set or a slice without a started picture is an error, not an
  `expect`; the output queue pop no longer expects.
- CAVLC table builder parses its literal codes without `from_str_radix().unwrap()`.
- `#![deny(clippy::unwrap_used, clippy::expect_used, clippy::panic, clippy::unimplemented,
  clippy::todo, clippy::unreachable)]` outside tests.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-04 11:30:55 -04:00
Brandon ThomasandClaude Opus 5.5 7e991ea95b M4.9: performance docs, h264 README and roadmap for 4K H.264 playback
Interleaved before/after bench (decode, playback incl. 1/4 and draft cases,
4K cold seeks) and decoder cycle counts in docs/performance.md; threading,
draft mode and 4K numbers in crates/h264/README.md; bench cases in
docs/testing.md.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-03 00:03:58 -04:00
Brandon ThomasandClaude Opus 5.5 849f269525 M4.9: H.264 deblocking skips edges whose alpha or beta is 0
No sample can pass the filterSamplesFlag test (8.7.2.2) at those indices.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-02 23:52:31 -04:00
Brandon ThomasandClaude Opus 5.5 aa3ad1d950 M4.9: H.264 inverse transforms reconstruct across columns at once
The column pass and the add/clip of idct4/idct8 work on whole rows so they
vectorise (same integer steps in the spec's row-then-column order; checked
against the per-column formulation on random blocks). Docs: draft decoding in
architecture.md and perf.stats fields in control-protocol.md.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-02 23:46:52 -04:00
Brandon ThomasandClaude Opus 5.5 b3a09fab64 M4.9: H.264 draft mode (no deblocking of non-reference pictures, off by default)
Decoder::set_draft: non-reference pictures skip the deblocking filter and are
flagged Picture::draft; all other pictures stay bit-exact (conformance test,
single- and frame-threaded). Conformance fixtures now also decode with 3
threads. Decoder::threads / default_threads for perf.stats.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-02 23:06:54 -04:00
Brandon ThomasandClaude Opus 5.5 a95fd5c829 M4.9: H.264 vectorised deblocking edge filters and branch-free CABAC bins
Deblocking filters all lines of an edge at once with per-lane masks (bit-exact
with the per-line filter, checked on random edges); CABAC decode_decision /
bypass select instead of branching. 4K single-thread CPU -19 %, output
identical to ffmpeg.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-02 22:54:50 -04:00
Brandon ThomasandClaude Opus 5.5 3704002f89 T2: cargo xtask fixtures pre-generates the oracle fixture matrix
Runs each crate's ignored generate_fixtures test (h264, hevc, isobmff,
matroska, prores) - the same generators the oracle tests use - and
prints made/cached/skipped per fixture plus a summary. Optional crate
filter: cargo xtask fixtures hevc prores.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-01 00:20:59 -04:00
Brandon ThomasandClaude Opus 5.5 8780d5ffa2 T1: shared ffmpeg/ffprobe discovery in filmcraft-testkit
New dev-dependency-only crate crates/testkit (L0, no FilmCraft deps):
FILMCRAFT_FFMPEG/FILMCRAFT_FFPROBE, then PATH (incl. .exe), then known
dirs; SKIPPED lines and FILMCRAFT_REQUIRE_ORACLES=1 to make skips fail;
require_ffmpeg!/require_ffprobe!/require_oracles!; fixtures_dir() under
<workspace>/target/fixtures with per-thread temp names and atomic
generation. Oracle helpers in aac, opus, h264, hevc, h264enc, isobmff,
matroska, prores and export migrated (codecs left on its local lookup).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-01 00:10:59 -04:00
Brandon ThomasandClaude Opus 5.5 a47b90e7bf M2 perf: skip internal deblocking edges of uniform-motion macroblocks
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-30 06:57:35 -04:00
Brandon ThomasandClaude Opus 5.5 3903d2909a M2 tests: Apple VideoToolbox encoded fixtures (bit-exact)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-30 06:55:44 -04:00
Brandon ThomasandClaude Opus 5.5 8da290c1bd M2 tests: POC type 1 reordering synthetic stream
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-30 06:54:54 -04:00
Brandon ThomasandClaude Opus 5.5 aa8ee4fcf6 M2 perf/docs: faster CABAC engine and residual parsing, README
- CABAC engine keeps codIOffset scaled in a 64-bit register with 32-bit
  refills instead of re-reading the bitstream on every renormalisation
- significance map collected as a position list; context increments from
  per-category tables
- fixed-size row copies for motion-compensation windows and block copies
- explicit weighted prediction (P_Skip and B_Skip bi-prediction) synthetic
  test, cross-checked with ffmpeg
- crates/h264/README.md: features, API, threading model, fixture matrix,
  performance, known gaps and the plan for High 10 / 4:2:2

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-30 06:53:55 -04:00
Brandon ThomasandClaude Opus 5.5 20f0d08311 M2 tests: synthetic I_PCM/long-term/MMCO/gap streams, avcC, robustness, stats
- hand-built CAVLC and CABAC bitstreams (test-only CABAC encoder) with I_PCM
  and P_Skip macroblocks exercising long-term references, MMCO 1-6,
  frame_num gaps and reference list modification (idc 0 and 2); expected
  output is known exactly and cross-checked with ffmpeg when available
- avcC configuration + length-prefixed samples with pts round trip
- corrupted / truncated / garbage input never panics or deadlocks
  (single- and multi-threaded)
- Decoder::stats() coverage counters and an ignored coverage report test

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-30 06:44:39 -04:00
Brandon ThomasandClaude Opus 5.5 374569e65e M2 perf: frame-threaded H.264 decoding and hot-path optimisation
- frame-level parallelism: the calling thread handles headers, POC, DPB and
  reference lists; each picture decodes as a job on a rayon pool (feature
  'threads') and publishes deblocked macroblock rows into a shared Frame;
  motion compensation and co-located lookups block per row on references
  still being decoded (safe Rust, OnceLock per MB row); outputs are handed
  out once their job has finished
- row-pipelined deblocking inside a picture (row r filtered after row r+1 is
  reconstructed), picture buffer recycling, panic/error isolation per job
- faster luma/chroma interpolation (row-wise filters, window fetch), direct
  interpolation into the picture for unweighted single-list blocks, merged
  motion compensation for uniform direct macroblocks, 8x8 direct derivation
  with direct_8x8_inference, vectorisable weighted prediction, deblocking
  with per-edge parameters and cached reference identities
- conformance tests now decode every fixture single- and multi-threaded and
  check pts/POC output order; ignored perf test (1080p High CRF20, 120 frames)

1080p: ~100 fps single-threaded, ~600 fps with 14 threads (M4 Pro, heavily
loaded machine).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-30 06:38:40 -04:00
Brandon ThomasandClaude Opus 5.5 aefe1ae08f M2.4: H.264 CABAC entropy decoding
- arithmetic decoding engine (DecodeDecision / Bypass / Terminate, 9-bit
  register semantics incl. I_PCM re-initialisation), combined state
  transition table, round-trip tested against a reference encoder model
- context initialisation for cabac_init_idc 0..2 and I slices, all 1024
  (m, n) pairs extracted from Tables 9-12..9-33 of the spec
- binarisations + ctxIdxInc derivations: mb_skip_flag, mb_type (I/P/B incl.
  intra suffixes and I_PCM), sub_mb_type, ref_idx, mvd (UEG3), prev/rem intra
  modes, intra_chroma_pred_mode, coded_block_pattern, mb_qp_delta,
  transform_size_8x8_flag, coded_block_flag (all block categories incl.
  inferred 8x8 flags), significant/last (frame, 4x4 and 8x8 tables),
  coeff_abs_level_minus1 (UEG0), end_of_slice_flag

The full fixture matrix (32 libx264 configurations: Baseline/Main/High,
CABAC+B-pyramid, weightp/weightb, direct temporal/spatial, ref=4, deblock
variants, cqm=jvt, 4 slices, open GOP, constrained intra, 8x8dct=0, QP 1/50,
720p/1080p/1918x1078 crop) decodes bit-exact against ffmpeg.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-30 06:19:54 -04:00
Brandon ThomasandClaude Opus 5.5 c6a7075de7 M2.5: H.264 deblocking loop filter
- bS derivation: intra MB edges (4) / internal (3), non-zero coefficients per
  4x4 or 8x8 transform block (2), reference picture identity + mv distance
  rules incl. bi-predicted partitions (1)
- alpha/beta/tC0 tables, luma normal and strong filters, chroma filters with
  chroma bS mapped from luma, I_PCM qP handling, per-component chroma QP
- disable_deblocking_filter_idc 0/1/2 incl. slice boundary rule, slice
  alpha/beta offsets, 8x8 transform internal edges

All CAVLC fixtures (Baseline, High CAVLC with B-frames, temporal direct,
weighted prediction, multi-slice, QP 1) are bit-exact against ffmpeg.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-30 06:14:35 -04:00
Brandon ThomasandClaude Opus 5.5 9c8de5468b M2.2/M2.3: CAVLC macroblock decoding, intra and inter prediction, DPB
- CAVLC residual parsing (coeff_token / total_zeros / run_before tables taken
  from the spec text, level decoding with escape codes), macroblock layer for
  I/P/B slices (mb_type, sub_mb_type, mb_pred, sub_mb_pred, me(v) cbp,
  mb_qp_delta), I_PCM
- intra prediction: Intra4x4 (9 modes), Intra8x8 with reference filtering,
  Intra16x16, chroma; constrained_intra_pred
- dequantisation with flat/custom scaling matrices; 4x4, 8x8, luma DC
  Hadamard and 2x2 chroma DC inverse transforms
- inter prediction: median / directional mv prediction, P_Skip, B spatial and
  temporal direct (direct_8x8_inference), B_Skip, 6-tap luma and bilinear
  chroma interpolation, explicit and implicit weighted prediction
- reference lists (init + modification), DPB with sliding window, all MMCOs,
  frame_num gaps, bumping / max_num_reorder_frames output order, IDR and
  no_output_of_prior_pics
- public Decoder/Picture API (Annex-B and avcC input, pts passes through
  reordering)

Deblocking (M2.5) follows in the next commit, so the bit-exact fixtures in
this commit are the no-deblock ones. CABAC slices return Unsupported.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-30 06:14:18 -04:00
Brandon ThomasandClaude Opus 5.5 a2ac32916b M2.1: H.264 NAL/SPS/PPS/slice header parsing
New crate filmcraft-h264 (L0, depends only on filmcraft-bitstream):
- SPS incl. VUI/HRD, scaling lists with fall-back rules A/B, frame cropping,
  high-profile chroma_format_idc / bit depth fields, DPB size from level
- PPS incl. transform_8x8_mode, scaling lists, slice groups (parse only)
- slice header: all fields incl. ref_pic_list_modification, pred_weight_table,
  dec_ref_pic_marking
- POC types 0/1/2 (incl. MMCO5 handling and frame_num gap hooks)
- default scaling / QPc / deblocking tables from the public ITU-T spec
- ffmpeg/libx264 fixture generator for tests (skips when ffmpeg is absent)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-30 06:12:38 -04:00