nx_h264_chroma.nx source
↩ module page · 52 lines · 1932 B
1// nx_h264_chroma.nx -- chroma reconstruction kernels: 2x2 DC inverse Hadamard
2// (spec 8.5.11) + chroma QP mapping (Table 8-15).
3// H2 = [[1,1],[1,-1]]; f = H2 c H2 (c row-major 2x2 [c00,c01,c10,c11]):
4// f00=c00+c01+c10+c11 f01=c00-c01+c10-c11 f10=c00+c01-c10-c11 f11=c00-c01-c10+c11
5// chroma QP: QPc = qPi for qPi<30, else Table 8-15 map[qPi-30].
6//
7// genealogy_id: itu_t_h264_sec8_5_11_chroma_dc_hadamard + table8_15_qpc
8// lineage_id: hadamard_2x2 + chroma_qp_map
9// license_tier: ORIGINAL
10import "nx_syscalls.nx"
11import "nx_h264_idct.nx"
12
13// in-place 2x2 inverse Hadamard, c[4] = [c00,c01,c10,c11]
14func nx_h264_hadamard2x2(c: *i64) -> i64 {
15 let a: i64 = c[0]
16 let b: i64 = c[1]
17 let d: i64 = c[2]
18 let e: i64 = c[3]
19 c[0] = a + b + d + e
20 c[1] = a - b + d - e
21 c[2] = a + b - d - e
22 c[3] = a - b - d + e
23 return 0
24}
25
26// Table 8-15: qPi -> QPc
27func nx_h264_chroma_qp(qPi: i64) -> i64 {
28 if qPi < 30 { return qPi }
29 let m: *i64 = sys_mmap(32 * 8) as *i64
30 m[0]=29; m[1]=30; m[2]=31; m[3]=32; m[4]=32; m[5]=33; m[6]=34; m[7]=34; m[8]=35; m[9]=35
31 m[10]=36; m[11]=36; m[12]=37; m[13]=37; m[14]=37; m[15]=38; m[16]=38; m[17]=38; m[18]=39; m[19]=39
32 m[20]=39; m[21]=39
33 if qPi > 51 { return 39 }
34 return m[qPi - 30]
35}
36
37// Chroma DC scaling (spec 8.5.11.2): in c[4] = decoded 2x2 DC levels (raster).
38// Applies 2x2 inverse Hadamard then dcC = ((f * LS) << (qP/6)) >> 5, LS=16*normAdjust(qP%6,0,0).
39// Writes the 4 scaled DC values to out[4]. c[] is consumed (becomes f). qP = chroma QPc.
40func nx_h264_chroma_dc_scale(c: *i64, qPc: i64, out: *i64) -> i64 {
41 nx_h264_hadamard2x2(c)
42 let na: *i64 = sys_mmap(8 * 8) as *i64
43 na[0]=10; na[1]=11; na[2]=13; na[3]=14; na[4]=16; na[5]=18
44 let LS: i64 = 16 * na[qPc % 6]
45 let sh: i64 = qPc / 6
46 var i: i64 = 0
47 while i < 4 {
48 out[i] = asr((c[i] * LS) << sh, 5)
49 i = i + 1
50 }
51 return 0
52}