code wiki / (root) / nx_h264_mb_pred.nx

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}