nx_h264_cabac_ctxinc.nx source
↩ module page · 54 lines · 3429 B
1// nx_h264_cabac_ctxinc.nx -- H.264 CABAC I-slice ctxIdxInc DERIVATION (spec clause 9.3.3.1.1).
2// This is the table-INDEPENDENT logic layer of the CABAC decoder: pure procedures that select WHICH
3// context variable each bin uses. They need no (m,n) init values, so they are verifiable in isolation
4// (KAT gate) and are the correct next rung stacked on the already-GREEN arithmetic engine (nx_h264_cabac).
5// The (m,n) context-init VALUE tables (spec Tables 9-12..9-33) are a SEPARATE module and are DELIBERATELY
6// NOT included here -- they must be transcribed from the normative spec with per-table KATs, never guessed.
7//
8// I-slice ctxIdxOffset map (spec Table 9-11) -- documented HERE so the value tables drop into known slots:
9// mb_type (I, prefix) : ctxIdxOffset 3 (ctxIdx 3..10)
10// mb_qp_delta : ctxIdxOffset 60 (ctxIdx 60..63)
11// intra_chroma_pred_mode : ctxIdxOffset 64 (ctxIdx 64..67)
12// prev_intra4x4_pred_mode_flag: ctxIdxOffset 68 (ctxIdx 68)
13// rem_intra4x4_pred_mode : ctxIdxOffset 69 (ctxIdx 69)
14// coded_block_pattern (luma) : ctxIdxOffset 73 (ctxIdx 73..76)
15// coded_block_pattern (chroma): ctxIdxOffset 77 (ctxIdx 77..84)
16// coded_block_flag : ctxIdxOffset 85 (+ per-ctxBlockCat sub-offsets; field/8x8 extensions >459)
17// significant_coeff_flag : ctxIdxOffset 105 (frame) / 277 (field)
18// last_significant_coeff_flag: ctxIdxOffset 166 (frame) / 338 (field)
19// coeff_abs_level_minus1 : ctxIdxOffset 227
20// end_of_slice_flag : ctxIdxOffset 276 (decoded via cab_terminate, no init pair)
21// transform_size_8x8_flag : ctxIdxOffset 399 (High profile)
22// LIB (no main). license_tier: ORIGINAL genealogy_id: itu_t_h264_sec9_3_3_1_1_ctxidxinc
23import "nx_syscalls.nx"
24
25func cci_min(a: i64, b: i64) -> i64 { if a < b { return a } return b }
26
27// coded_block_flag (9.3.3.1.1.9): ctxIdxInc = condTermFlagA + 2*condTermFlagB.
28// The caller resolves each condTermFlagX (neighbour availability + its coded_block_flag) to 0/1.
29func cci_cbf(condA: i64, condB: i64) -> i64 { return condA + 2 * condB }
30
31// significant_coeff_flag / last_significant_coeff_flag for a 4x4 block, frame-coded (9.3.3.1.3):
32// ctxIdxInc = levelListIdx (the zig-zag scan position 0..14; position 15 is never signalled).
33func cci_sig4x4(scanpos: i64) -> i64 { return scanpos }
34
35// coeff_abs_level_minus1 (9.3.3.1.1.9), common path ctxBlockCat < 5 (4x4 luma/chroma/DC;
36// ctxBlockCat 5 = 8x8 uses a 4->3 clamp and is handled by the High-profile rung, flagged):
37// binIdx 0 : (numDecodAbsLevelGt1 != 0) ? 0 : Min(4, 1 + numDecodAbsLevelEq1)
38// binIdx>0 : 5 + Min(4, numDecodAbsLevelGt1)
39func cci_abslevel_bin0(numGt1: i64, numEq1: i64) -> i64 { if numGt1 != 0 { return 0 } return cci_min(4, 1 + numEq1) }
40func cci_abslevel_binN(numGt1: i64) -> i64 { return 5 + cci_min(4, numGt1) }
41
42// mb_qp_delta (9.3.3.1.1.5): binIdx0 ctxIdxInc = (prevMbQpDelta != 0) ? 1 : 0; binIdx1 = 2; binIdx>1 = 3.
43func cci_mbqpdelta(binIdx: i64, prevNonZero: i64) -> i64 {
44 if binIdx == 0 { if prevNonZero != 0 { return 1 } return 0 }
45 if binIdx == 1 { return 2 }
46 return 3
47}
48
49// intra_chroma_pred_mode (9.3.3.1.1.8): binIdx0 ctxIdxInc = condTermA + condTermB (neighbours' mode!=0);
50// binIdx>0 (the TU suffix bins) use ctxIdxInc = 3.
51func cci_chromapred(binIdx: i64, condA: i64, condB: i64) -> i64 {
52 if binIdx == 0 { return condA + condB }
53 return 3
54}