h264: Intra_8x8 chroma prediction — 4-mode C reference + spec gates

Third intra-prediction primitive after PR #12 (Intra_4x4 luma) and
PR #13 (Intra_16x16 luma).  Covers Intra_8x8 chroma per H.264 §8.3.3:
4 modes used for BOTH Cb and Cr planes at 4:2:0.

Mode quirks worth flagging in code review:

  - Mode 0 DC is asymmetric per quadrant.  The 8x8 chroma block
    splits into four 4x4 quadrants with different DC formulas:
      (0,0) top-left  : (sum_top[0..3] + sum_left[0..3] + 4) >> 3
      (0,1) top-right : (sum_top[4..7]                  + 2) >> 2
      (1,0) bot-left  : (sum_left[4..7]                 + 2) >> 2
      (1,1) bot-right : (sum_top[4..7] + sum_left[4..7] + 4) >> 3
    The top-right quadrant deliberately IGNORES the top-left half
    even though it's available — that's per spec §8.3.3.2.

  - Mode 3 Plane uses slope coefficient 34 (not 5 like Intra_16x16
    luma).  Centre is (x-3, y-3) instead of (x-7, y-7).  Sums span
    4 differences instead of 8.  Easy to copy-paste-bug from the
    luma Plane if you don't notice the constants change.

Test highlights:

  - DC quadrants: distinct expected values per quadrant (16, 16,
    40, 28 from asymmetric top/left halves) — any quadrant mix-up
    would surface immediately.  Hand-derived from the formulas
    in the test comment.
  - Plane uniform: all-100 context → all-100 output (a = 3200,
    H = V = 0, (3200+16) >> 5 = 100 exactly).
  - Plane gradient: top + left = 0..7, hand-derives pred[0][0] = 1
    and pred[7][7] = 15 via the full arithmetic chain (H = V = 56,
    b = c = 30, a = 224).  Same hand-traced spec-walkthrough as
    the Intra_16x16 Plane gradient test.

Verified on hertz:

  $ ./build/test_intra_pred_chroma8x8
    Horizontal (mode 1)            PASS
    Vertical (mode 2)              PASS
    DC quadrants (mode 0)          PASS
    Plane uniform (mode 3)         PASS
    Plane gradient (mode 3)        PASS (corners 1, 15)

  ALL Intra_8x8 chroma mode references PASS

All 5 tests PASS first try.  The DC quadrant correctness is meaningful
(4 different formulas in one kernel) and the Plane gradient corners
validate the slope=34 + centre=(x-3,y-3) constants vs the luma
equivalents.

Combined coverage after this PR:
  - Intra_4x4 luma:   9 modes ✓ (PR #12, all 9 PASS)
  - Intra_16x16 luma: 4 modes ✓ (PR #13, all 5 tests PASS)
  - Intra_8x8 chroma: 4 modes ✓ (this PR, all 5 tests PASS)
  - Intra_8x8 luma (High profile): 9 modes + smoothing — pending.

Remaining backlog: Intra_8x8 luma (High profile, 9 modes + 1-2-1
smoothing pre-filter — distinct algorithm from Intra_4x4 because of
the pre-filter), neighbour-availability fallback, dispatch wrappers.
This commit is contained in:
2026-05-25 00:42:49 +02:00
parent dff610e13d
commit d7100459f2
3 changed files with 302 additions and 0 deletions
+9
View File
@@ -548,6 +548,15 @@ add_executable(test_intra_pred_16x16
)
target_compile_options(test_intra_pred_16x16 PRIVATE -O2)
# H.264 Intra_8x8 chroma prediction (4 modes: DC, H, V, Plane) —
# reference + tests. DC is per-quadrant (asymmetric); Plane uses
# slope coefficient 34 instead of luma's 5.
add_executable(test_intra_pred_chroma8x8
tests/test_intra_pred_chroma8x8.c
tests/h264_intra_pred_chroma8x8_ref.c
)
target_compile_options(test_intra_pred_chroma8x8 PRIVATE -O2)
add_executable(bench_pool_overhead tests/bench_pool_overhead.c)
target_link_libraries(bench_pool_overhead PRIVATE daedalus_core)
target_compile_options(bench_pool_overhead PRIVATE -O2)