code wiki / (root) / nx_h264_chroma.nx

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}