nx_h264_total_zeros.nx source
↩ module page · 196 lines · 7193 B
1// nx_h264_total_zeros.nx -- CAVLC total_zeros VLC (rung 4c-iii), table-driven
2// encoder + decoder. total_zeros = number of zero coefficients before the last
3// non-zero one; VLC table is indexed by TotalCoeff (1..15). Same machinery +
4// round-trip-oracle pattern as coeff_token. Filled: the TotalCoeff=1 column
5// (Table 9-7, tzVlcIndex=1). Other columns = data fill, validated by the real
6// I-frame decode (capstone oracle).
7//
8// genealogy_id: itu_t_h264_table9_7_total_zeros
9// lineage_id: vlc_symbol_table + prefix_match_decode + roundtrip_oracle
10// license_tier: ORIGINAL
11import "nx_syscalls.nx"
12import "nx_h264_bits.nx"
13import "nx_h264_bitwriter.nx"
14
15// fill the table for a given TotalCoeff into ln[]/cd[]/val[] (val = total_zeros);
16// returns entry count, or 0 if that TotalCoeff column is not yet filled.
17// FULL total_zeros (luma 4x4), TotalCoeff 1..15. Verbatim ffmpeg total_zeros_{len,bits}.
18// val[j]=j (total_zeros index). Returns column entry count (17-TotalCoeff).
19func tz_table(total_coeff: i64, ln: *i64, cd: *i64, val: *i64) -> i64 {
20 var n: i64 = 0
21 if total_coeff == 1 {
22 ln[0]=1;cd[0]=1; ln[1]=3;cd[1]=3; ln[2]=3;cd[2]=2; ln[3]=4;cd[3]=3
23 ln[4]=4;cd[4]=2; ln[5]=5;cd[5]=3; ln[6]=5;cd[6]=2; ln[7]=6;cd[7]=3
24 ln[8]=6;cd[8]=2; ln[9]=7;cd[9]=3; ln[10]=7;cd[10]=2; ln[11]=8;cd[11]=3
25 ln[12]=8;cd[12]=2; ln[13]=9;cd[13]=3; ln[14]=9;cd[14]=2; ln[15]=9;cd[15]=1
26 n=16
27 }
28 if total_coeff == 2 {
29 ln[0]=3;cd[0]=7; ln[1]=3;cd[1]=6; ln[2]=3;cd[2]=5; ln[3]=3;cd[3]=4
30 ln[4]=3;cd[4]=3; ln[5]=4;cd[5]=5; ln[6]=4;cd[6]=4; ln[7]=4;cd[7]=3
31 ln[8]=4;cd[8]=2; ln[9]=5;cd[9]=3; ln[10]=5;cd[10]=2; ln[11]=6;cd[11]=3
32 ln[12]=6;cd[12]=2; ln[13]=6;cd[13]=1; ln[14]=6;cd[14]=0
33 n=15
34 }
35 if total_coeff == 3 {
36 ln[0]=4;cd[0]=5; ln[1]=3;cd[1]=7; ln[2]=3;cd[2]=6; ln[3]=3;cd[3]=5
37 ln[4]=4;cd[4]=4; ln[5]=4;cd[5]=3; ln[6]=3;cd[6]=4; ln[7]=3;cd[7]=3
38 ln[8]=4;cd[8]=2; ln[9]=5;cd[9]=3; ln[10]=5;cd[10]=2; ln[11]=6;cd[11]=1
39 ln[12]=5;cd[12]=1; ln[13]=6;cd[13]=0
40 n=14
41 }
42 if total_coeff == 4 {
43 ln[0]=5;cd[0]=3; ln[1]=3;cd[1]=7; ln[2]=4;cd[2]=5; ln[3]=4;cd[3]=4
44 ln[4]=3;cd[4]=6; ln[5]=3;cd[5]=5; ln[6]=3;cd[6]=4; ln[7]=4;cd[7]=3
45 ln[8]=3;cd[8]=3; ln[9]=4;cd[9]=2; ln[10]=5;cd[10]=2; ln[11]=5;cd[11]=1
46 ln[12]=5;cd[12]=0
47 n=13
48 }
49 if total_coeff == 5 {
50 ln[0]=4;cd[0]=5; ln[1]=4;cd[1]=4; ln[2]=4;cd[2]=3; ln[3]=3;cd[3]=7
51 ln[4]=3;cd[4]=6; ln[5]=3;cd[5]=5; ln[6]=3;cd[6]=4; ln[7]=3;cd[7]=3
52 ln[8]=4;cd[8]=2; ln[9]=5;cd[9]=1; ln[10]=4;cd[10]=1; ln[11]=5;cd[11]=0
53 n=12
54 }
55 if total_coeff == 6 {
56 ln[0]=6;cd[0]=1; ln[1]=5;cd[1]=1; ln[2]=3;cd[2]=7; ln[3]=3;cd[3]=6
57 ln[4]=3;cd[4]=5; ln[5]=3;cd[5]=4; ln[6]=3;cd[6]=3; ln[7]=3;cd[7]=2
58 ln[8]=4;cd[8]=1; ln[9]=3;cd[9]=1; ln[10]=6;cd[10]=0
59 n=11
60 }
61 if total_coeff == 7 {
62 ln[0]=6;cd[0]=1; ln[1]=5;cd[1]=1; ln[2]=3;cd[2]=5; ln[3]=3;cd[3]=4
63 ln[4]=3;cd[4]=3; ln[5]=2;cd[5]=3; ln[6]=3;cd[6]=2; ln[7]=4;cd[7]=1
64 ln[8]=3;cd[8]=1; ln[9]=6;cd[9]=0
65 n=10
66 }
67 if total_coeff == 8 {
68 ln[0]=6;cd[0]=1; ln[1]=4;cd[1]=1; ln[2]=5;cd[2]=1; ln[3]=3;cd[3]=3
69 ln[4]=2;cd[4]=3; ln[5]=2;cd[5]=2; ln[6]=3;cd[6]=2; ln[7]=3;cd[7]=1
70 ln[8]=6;cd[8]=0
71 n=9
72 }
73 if total_coeff == 9 {
74 ln[0]=6;cd[0]=1; ln[1]=6;cd[1]=0; ln[2]=4;cd[2]=1; ln[3]=2;cd[3]=3
75 ln[4]=2;cd[4]=2; ln[5]=3;cd[5]=1; ln[6]=2;cd[6]=1; ln[7]=5;cd[7]=1
76 n=8
77 }
78 if total_coeff == 10 {
79 ln[0]=5;cd[0]=1; ln[1]=5;cd[1]=0; ln[2]=3;cd[2]=1; ln[3]=2;cd[3]=3
80 ln[4]=2;cd[4]=2; ln[5]=2;cd[5]=1; ln[6]=4;cd[6]=1
81 n=7
82 }
83 if total_coeff == 11 {
84 ln[0]=4;cd[0]=0; ln[1]=4;cd[1]=1; ln[2]=3;cd[2]=1; ln[3]=3;cd[3]=2
85 ln[4]=1;cd[4]=1; ln[5]=3;cd[5]=3
86 n=6
87 }
88 if total_coeff == 12 {
89 ln[0]=4;cd[0]=0; ln[1]=4;cd[1]=1; ln[2]=2;cd[2]=1; ln[3]=1;cd[3]=1
90 ln[4]=3;cd[4]=1
91 n=5
92 }
93 if total_coeff == 13 {
94 ln[0]=3;cd[0]=0; ln[1]=3;cd[1]=1; ln[2]=1;cd[2]=1; ln[3]=2;cd[3]=1
95 n=4
96 }
97 if total_coeff == 14 {
98 ln[0]=2;cd[0]=0; ln[1]=2;cd[1]=1; ln[2]=1;cd[2]=1
99 n=3
100 }
101 if total_coeff == 15 {
102 ln[0]=1;cd[0]=0; ln[1]=1;cd[1]=1
103 n=2
104 }
105 var z: i64 = 0
106 while z < n { val[z] = z; z = z + 1 }
107 return n
108}
109
110// Chroma DC total_zeros (2x2, maxNumCoeff=4), from ffmpeg chroma_dc_total_zeros_{len,bits}.
111func tz_table_cdc(total_coeff: i64, ln: *i64, cd: *i64, val: *i64) -> i64 {
112 if total_coeff == 1 {
113 ln[0]=1; cd[0]=1; val[0]=0
114 ln[1]=2; cd[1]=1; val[1]=1
115 ln[2]=3; cd[2]=1; val[2]=2
116 ln[3]=3; cd[3]=0; val[3]=3
117 return 4
118 }
119 if total_coeff == 2 {
120 ln[0]=1; cd[0]=1; val[0]=0
121 ln[1]=2; cd[1]=1; val[1]=1
122 ln[2]=2; cd[2]=0; val[2]=2
123 return 3
124 }
125 if total_coeff == 3 {
126 ln[0]=1; cd[0]=1; val[0]=0
127 ln[1]=1; cd[1]=0; val[1]=1
128 return 2
129 }
130 return 0
131}
132func nx_total_zeros_encode_cdc(bw: *BitWriter, total_coeff: i64, total_zeros: i64) -> i64 {
133 let ln: *i64 = sys_mmap(32 * 8) as *i64
134 let cd: *i64 = sys_mmap(32 * 8) as *i64
135 let vl: *i64 = sys_mmap(32 * 8) as *i64
136 let n: i64 = tz_table_cdc(total_coeff, ln, cd, vl)
137 var i: i64 = 0
138 while i < n {
139 if vl[i] == total_zeros { bw_write_bits(bw, cd[i], ln[i]); return 1 }
140 i = i + 1
141 }
142 return 0
143}
144func nx_total_zeros_decode_cdc(br: *BitReader, total_coeff: i64) -> i64 {
145 let ln: *i64 = sys_mmap(32 * 8) as *i64
146 let cd: *i64 = sys_mmap(32 * 8) as *i64
147 let vl: *i64 = sys_mmap(32 * 8) as *i64
148 let n: i64 = tz_table_cdc(total_coeff, ln, cd, vl)
149 if n == 0 { return 0 - 1 }
150 var acc: i64 = 0
151 var nbits: i64 = 0
152 while nbits < 8 {
153 acc = (acc << 1) | br_read_bit(br)
154 nbits = nbits + 1
155 var i: i64 = 0
156 while i < n {
157 if ln[i] == nbits { if cd[i] == acc { return vl[i] } }
158 i = i + 1
159 }
160 }
161 return 0 - 1
162}
163
164func nx_total_zeros_encode(bw: *BitWriter, total_coeff: i64, total_zeros: i64) -> i64 {
165 let ln: *i64 = sys_mmap(64 * 8) as *i64
166 let cd: *i64 = sys_mmap(64 * 8) as *i64
167 let vl: *i64 = sys_mmap(64 * 8) as *i64
168 let n: i64 = tz_table(total_coeff, ln, cd, vl)
169 var i: i64 = 0
170 while i < n {
171 if vl[i] == total_zeros { bw_write_bits(bw, cd[i], ln[i]); return 1 }
172 i = i + 1
173 }
174 return 0
175}
176
177// returns total_zeros, or -1 if no match / column unfilled
178func nx_total_zeros_decode(br: *BitReader, total_coeff: i64) -> i64 {
179 let ln: *i64 = sys_mmap(64 * 8) as *i64
180 let cd: *i64 = sys_mmap(64 * 8) as *i64
181 let vl: *i64 = sys_mmap(64 * 8) as *i64
182 let n: i64 = tz_table(total_coeff, ln, cd, vl)
183 if n == 0 { return 0 - 1 }
184 var acc: i64 = 0
185 var nbits: i64 = 0
186 while nbits < 20 {
187 acc = (acc << 1) | br_read_bit(br)
188 nbits = nbits + 1
189 var i: i64 = 0
190 while i < n {
191 if ln[i] == nbits { if cd[i] == acc { return vl[i] } }
192 i = i + 1
193 }
194 }
195 return 0 - 1
196}