nx_h264_cavlc_enc.nx source
↩ module page · 42 lines · 1894 B
1// nx_h264_cavlc_enc.nx -- CAVLC level ENCODER (inverse of nx_h264_cavlc_level's
2// read_level). Exists so the decoder can be gated SOVEREIGNLY: encode known
3// levels -> decode -> must recover exactly (the round-trip oracle, no ffmpeg).
4//
5// level -> levelCode: level>0 -> (level<<1)-2 (even) ; level<=0 -> (-level<<1)-1 (odd)
6// levelCode -> (prefix, suffix) given suffixLength (non-escape, prefix<15):
7// suffixLength==0: prefix = levelCode, no suffix
8// suffixLength>0 : prefix = levelCode >> suffixLength, suffix = low suffixLength bits
9// emit: <prefix zeros><1><suffix bits>
10// Escape (prefix>=15) is NOT emitted here -- callers keep magnitudes in range
11// (flagged); matches the decoder's common path.
12//
13// genealogy_id: itu_t_h264_sec9_2_2_cavlc_level_inverse
14// lineage_id: level_to_levelcode + prefix_suffix_emit
15// license_tier: ORIGINAL
16import "nx_syscalls.nx"
17import "nx_h264_bitwriter.nx"
18
19// encode a level, subtracting code_offset from levelCode first (inverse of
20// nx_cavlc_read_level_off). returns the prefix used (<15 = non-escape).
21func nx_cavlc_encode_level_off(bw: *BitWriter, level: i64, suffix_length: i64, code_offset: i64) -> i64 {
22 var lc: i64 = 0
23 if level > 0 { lc = (level << 1) - 2 }
24 if level <= 0 { lc = ((0 - level) << 1) - 1 }
25 lc = lc - code_offset
26 var prefix: i64 = lc
27 var suffix: i64 = 0
28 if suffix_length > 0 {
29 prefix = lc >> suffix_length
30 suffix = lc & ((1 << suffix_length) - 1)
31 }
32 var i: i64 = 0
33 while i < prefix { bw_write_bit(bw, 0); i = i + 1 }
34 bw_write_bit(bw, 1)
35 if suffix_length > 0 { bw_write_bits(bw, suffix, suffix_length) }
36 return prefix
37}
38
39// returns the prefix used (caller can assert <15 = non-escape)
40func nx_cavlc_encode_level(bw: *BitWriter, level: i64, suffix_length: i64) -> i64 {
41 return nx_cavlc_encode_level_off(bw, level, suffix_length, 0)
42}