Follows PR #26 (Intra_4x4 luma) with the same promotion pattern for
the rest of the intra prediction primitive set:
Intra_16x16 luma (4 modes, PR #13) — V/H/DC/Plane
Intra_8x8 chroma (4 modes, PR #14) — DC/H/V/Plane (4:2:0)
Intra_8x8 luma (9 modes, PRs #21 + #22) — High profile,
with 1-2-1 pre-filter
3 file moves via `git mv`, ~17 function renames stripping the `_ref`
suffix. Test binaries rewired to link daedalus_core instead of
compiling the (now moved) ref files directly. No code change — pure
plumbing for substitution-arc consumers.
26 intra prediction modes total now in the public API after this PR.
Verified on hertz:
test_intra_pred_16x16: 5/5 PASS
test_intra_pred_chroma8x8: 5/5 PASS
test_intra_pred_8x8_luma: 11/11 PASS
All via public symbols (test binaries linked against daedalus_core).
Unblocks marfrit-packages substitution arc patch 0014 — wires
H264PredContext.pred4x4[], pred16x16[], pred8x8[], pred8x8l[]
through daedalus alongside the existing IDCT / deblock / qpel / DC
Hadamard substitutions.
After 0014 lands, the libavcodec.so built by marfrit-packages will
have EVERY hot-path pixel-math kernel of an H.264 8-bit 4:2:0
decode routing through daedalus — the substitution arc is feature-
complete for the campaign target (Pi 5 Firefox YouTube playback).
Second piece of the intra-prediction primitive set after PR #12
(Intra_4x4 luma 9 modes). Covers the Intra_16x16 luma MB type
per H.264 §8.3.2: 4 modes (Vertical, Horizontal, DC, Plane).
Scope:
- tests/h264_intra_pred_16x16_ref.c — 4 spec-derived modes.
Same FFmpeg-style interface as the 4x4 sibling:
void daedalus_h264_pred_16x16_<name>_ref(uint8_t *dst, ptrdiff_t stride);
Assumes all neighbours valid (interior-MB case).
The Plane mode is the algorithmically heaviest of the four —
spec §8.3.2.4 has two slope sums (H, V) over the asymmetric
top/left contexts, a clipped quadratic evaluation per cell,
and a top-left-corner participant at i=7 / j=7. Implementation
follows the spec straightforwardly with `clip_u8` on the final
saturating cast.
- tests/test_intra_pred_16x16.c — 5 test cases:
* V, H, DC: standard contexts (gradient top / gradient left /
small uniform pair).
* Plane (uniform): all neighbours = 100 → H = V = 0 →
output = (16*200 + 16) >> 5 = 100. Verifies the
orientation-free portion of the formula.
* Plane (gradient): top + left both 0..15, spec-derived
corner expectations pred[0][0] = 1 and pred[15][15] = 31.
The arithmetic chain (H = V = 400 → b = c = 31, a = 480)
is fully hand-traced in the test comment so the expected
values are auditable.
- CMakeLists.txt — new test_intra_pred_16x16 binary; pure-CPU
library, no daedalus_core dependency (same separation as the
4x4 ref).
Verified on hertz:
$ ./build/test_intra_pred_16x16
Vertical (mode 0) PASS
Horizontal (mode 1) PASS
DC (mode 2) PASS
Plane (mode 3, uniform) PASS
Plane (mode 3, gradient) PASS (corners 1, 31)
ALL Intra_16x16 mode references PASS
Plane mode being right first try is meaningful — H/V sums, b/c
slope shifts, and the a-baseline arithmetic have many sign / index
error opportunities. The asymmetric gradient test would have caught
any of them; it didn't.
What this does NOT cover (still in the intra-pred backlog):
- Intra_8x8 chroma (4 modes per H.264 §8.3.3).
- Intra_8x8 luma (High profile, 9 modes per §8.3.2.1 + the 1-2-1
smoothing pre-filter — distinct algorithm from Intra_4x4).
- Neighbour-availability fallback for boundary MBs.
- Dispatch wrappers (same architectural question as before — wait
for decoder Stage 2a strategy decision).