code wiki / (root) / nx_h264_cavlc_level.nx

nx_h264_cavlc_level.nx source

↩ module page · 67 lines · 3003 B

1// nx_h264_cavlc_level.nx -- CAVLC level decoding (rung 4c-i, spec 9.2.2.1). 2// The algorithmic heart of CAVLC residual reading: for each non-trailing-ones 3// coefficient, read level_prefix (leading zeros) + level_suffix, form levelCode, 4// map to a signed level, and adapt suffixLength. Pure algorithm (no VLC tables) 5// -> exactly gateable. The coeff_token / total_zeros / run_before VLC tables are 6// the following sub-rungs. 7// 8// level_prefix = number of leading 0 bits before the first 1 9// levelSuffixSize = suffixLength; =4 if prefix==14 && suffixLength==0; 10// = prefix-3 if prefix>=15 11// levelCode = (min(prefix,15) << suffixLength) + level_suffix 12// (+15 if prefix>=15 && suffixLength==0; + (1<<(prefix-3))-4096 if prefix>=16) 13// level = (levelCode+2)>>1 if even ; -((levelCode+1)>>1) if odd 14// suffixLength: 0->1 first; ++ if |level| > (3<<(suffixLength-1)) and <6 15// 16// genealogy_id: itu_t_h264_sec9_2_2_cavlc_level 17// lineage_id: level_prefix_suffix + levelcode_signed_map + suffixlength_adapt 18// license_tier: ORIGINAL 19import "nx_syscalls.nx" 20import "nx_h264_bits.nx" 21 22// levelCode -> signed level (both shifts on non-negative values) 23func nx_cavlc_levelcode_to_level(level_code: i64) -> i64 { 24 if (level_code & 1) == 0 { return (level_code + 2) >> 1 } 25 return 0 - ((level_code + 1) >> 1) 26} 27 28// read one level given suffixLength, adding code_offset to levelCode before the 29// signed mapping (the residual decoder passes +2 for the first non-trailing-one 30// level when TrailingOnes<3; spec 9.2.2). 31func nx_cavlc_read_level_off(br: *BitReader, suffix_length: i64, code_offset: i64) -> i64 { 32 var prefix: i64 = 0 33 var seen: i64 = 0 34 while seen == 0 { 35 if br.byte_pos >= br.len { return 0 } 36 let b: i64 = br_read_bit(br) 37 if b == 1 { seen = 1 } 38 if b == 0 { prefix = prefix + 1 } 39 } 40 var suffix_size: i64 = suffix_length 41 if prefix == 14 { if suffix_length == 0 { suffix_size = 4 } } 42 if prefix >= 15 { suffix_size = prefix - 3 } 43 var suffix: i64 = 0 44 if suffix_size > 0 { suffix = br_read_bits(br, suffix_size) } 45 var mp: i64 = prefix 46 if mp > 15 { mp = 15 } 47 var level_code: i64 = (mp << suffix_length) + suffix 48 if prefix >= 15 { if suffix_length == 0 { level_code = level_code + 15 } } 49 if prefix >= 16 { level_code = level_code + ((1 << (prefix - 3)) - 4096) } 50 level_code = level_code + code_offset 51 return nx_cavlc_levelcode_to_level(level_code) 52} 53 54// read one level from the bitstream given current suffixLength (no offset) 55func nx_cavlc_read_level(br: *BitReader, suffix_length: i64) -> i64 { 56 return nx_cavlc_read_level_off(br, suffix_length, 0) 57} 58 59// adapt suffixLength after decoding a level 60func nx_cavlc_update_suffix(suffix_length: i64, level: i64) -> i64 { 61 var sl: i64 = suffix_length 62 if sl == 0 { sl = 1 } 63 var al: i64 = level 64 if al < 0 { al = 0 - al } 65 if al > (3 << (sl - 1)) { if sl < 6 { sl = sl + 1 } } 66 return sl 67}