nx_h264_mb_pred.nx source
↩ module page · 93 lines · 3962 B
1// nx_h264_mb_pred.nx -- I_NxN macroblock prediction layer (rung 4e, spec 7.3.5.1 +
2// 9.1.2/Table 9-4). Two parts the real I_NxN macroblock needs:
3// intra4x4 pred-mode signalling: per 4x4 block, prev_intra4x4_pred_mode_flag u(1);
4// if 0, rem_intra4x4_pred_mode u(3). (mode derivation from neighbours = recon step.)
5// coded_block_pattern: me(v) -> ue codeNum mapped via Table 9-4 (Intra column).
6//
7// The CBP map is a BIJECTION over codeNum 0..47 <-> cbp 0..47, which is a strong
8// sovereign self-check (a wrong/duplicate entry breaks bijectivity). Plus
9// encode<->decode round-trip. Intra mapping values from ITU-T Table 9-4.
10//
11// genealogy_id: itu_t_h264_sec7_3_5_1_mb_pred + table9_4_codedblockpattern_intra
12// lineage_id: intra4x4_predmode_flags + cbp_me_v_bijection
13// license_tier: ORIGINAL
14import "nx_syscalls.nx"
15import "nx_h264_bits.nx"
16import "nx_h264_bitwriter.nx"
17
18// Table 9-4 Intra (Intra_4x4/Intra_8x8): codeNum -> coded_block_pattern
19func nx_h264_cbp_intra_map(code_num: i64) -> i64 {
20 let m: *i64 = sys_mmap(48 * 8) as *i64
21 m[0]=47; m[1]=31; m[2]=15; m[3]=0; m[4]=23; m[5]=27; m[6]=29; m[7]=30
22 m[8]=7; m[9]=11; m[10]=13; m[11]=14; m[12]=39; m[13]=43; m[14]=45; m[15]=46
23 m[16]=16; m[17]=3; m[18]=5; m[19]=10; m[20]=12; m[21]=19; m[22]=21; m[23]=26
24 m[24]=28; m[25]=35; m[26]=37; m[27]=42; m[28]=44; m[29]=1; m[30]=2; m[31]=4
25 m[32]=8; m[33]=17; m[34]=18; m[35]=20; m[36]=24; m[37]=6; m[38]=9; m[39]=22
26 m[40]=25; m[41]=32; m[42]=33; m[43]=34; m[44]=36; m[45]=40; m[46]=38; m[47]=41
27 if code_num < 0 { return 0 - 1 }
28 if code_num > 47 { return 0 - 1 }
29 return m[code_num]
30}
31
32// inverse: cbp -> codeNum (linear search of the map)
33func nx_h264_cbp_intra_unmap(cbp: i64) -> i64 {
34 var i: i64 = 0
35 while i < 48 {
36 if nx_h264_cbp_intra_map(i) == cbp { return i }
37 i = i + 1
38 }
39 return 0 - 1
40}
41
42func nx_h264_decode_cbp_intra(br: *BitReader) -> i64 {
43 let cn: i64 = br_read_ue(br)
44 return nx_h264_cbp_intra_map(cn)
45}
46
47// Table 9-4 INTER (P/B): codeNum -> coded_block_pattern. VERBATIM ffmpeg golomb_to_inter_cbp[48]
48// (fetched from the reference, not memorized -- deblock-table lesson). DIFFERENT from the intra map.
49func nx_h264_cbp_inter_map(code_num: i64) -> i64 {
50 let m: *i64 = sys_mmap(48 * 8) as *i64
51 m[0]=0; m[1]=16; m[2]=1; m[3]=2; m[4]=4; m[5]=8; m[6]=32; m[7]=3
52 m[8]=5; m[9]=10; m[10]=12; m[11]=15; m[12]=47; m[13]=7; m[14]=11; m[15]=13
53 m[16]=14; m[17]=6; m[18]=9; m[19]=31; m[20]=35; m[21]=37; m[22]=42; m[23]=44
54 m[24]=33; m[25]=34; m[26]=36; m[27]=40; m[28]=39; m[29]=43; m[30]=45; m[31]=46
55 m[32]=17; m[33]=18; m[34]=20; m[35]=24; m[36]=19; m[37]=21; m[38]=26; m[39]=28
56 m[40]=23; m[41]=27; m[42]=29; m[43]=30; m[44]=22; m[45]=25; m[46]=38; m[47]=41
57 if code_num < 0 { return 0 - 1 }
58 if code_num > 47 { return 0 - 1 }
59 return m[code_num]
60}
61func nx_h264_decode_cbp_inter(br: *BitReader) -> i64 {
62 let cn: i64 = br_read_ue(br)
63 return nx_h264_cbp_inter_map(cn)
64}
65func nx_h264_encode_cbp_intra(bw: *BitWriter, cbp: i64) -> i64 {
66 let cn: i64 = nx_h264_cbp_intra_unmap(cbp)
67 bw_write_ue(bw, cn)
68 return 0
69}
70
71// parse the 16 intra4x4 pred-mode signals + chroma mode.
72// modes[0..15] = rem mode (0..7) if signalled, else -1 (use predicted); modes[16]=intra_chroma_pred_mode.
73func nx_h264_parse_inxn_predmodes(br: *BitReader, modes: *i64) -> i64 {
74 var b: i64 = 0
75 while b < 16 {
76 let prev: i64 = br_read_bit(br)
77 if prev == 1 { modes[b] = 0 - 1 }
78 if prev == 0 { modes[b] = br_read_bits(br, 3) }
79 b = b + 1
80 }
81 modes[16] = br_read_ue(br)
82 return 0
83}
84func nx_h264_encode_inxn_predmodes(bw: *BitWriter, modes: *i64) -> i64 {
85 var b: i64 = 0
86 while b < 16 {
87 if modes[b] < 0 { bw_write_bit(bw, 1) }
88 if modes[b] >= 0 { bw_write_bit(bw, 0); bw_write_bits(bw, modes[b], 3) }
89 b = b + 1
90 }
91 bw_write_ue(bw, modes[16])
92 return 0
93}