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}