fix clippy warnings
[nihav.git] / nihav-itu / src / codecs / h264 / cavlc.rs
CommitLineData
696e4e20
KS
1use nihav_core::codecs::{DecoderResult, DecoderError};
2use nihav_core::io::bitreader::*;
3use nihav_core::io::codebook::*;
4use nihav_core::io::intcode::*;
5use super::*;
6use super::dsp::{CHROMA_DC_SCAN, ZIGZAG, ZIGZAG1};
7use super::slice::SliceHeader;
8
9fn map_i_type(idx: usize) -> MBType {
10 if idx == 0 {
11 MBType::Intra4x4
12 } else if idx == 25 {
13 MBType::PCM
14 } else {
15 let imode = ((idx - 1) & 3) as u8;
16 let cbpc = ((idx - 1) / 4) as u8;
17 let (cbpy, cbpc) = if cbpc >= 3 { (0xF, cbpc - 3) } else { (0x0, cbpc) };
18 MBType::Intra16x16(imode, cbpy, cbpc)
19 }
20}
21
22const NUM_I_TYPES: usize = 26;
23
24const P_TYPES: [MBType; 5] = [
25 MBType::P16x16, MBType::P16x8, MBType::P8x16, MBType::P8x8, MBType::P8x8Ref0
26];
27
28const B_TYPES: [MBType; 23] = [
29 MBType::Direct,
30 MBType::B16x16(BMode::L0),
31 MBType::B16x16(BMode::L1),
32 MBType::B16x16(BMode::Bi),
33 MBType::B16x8(BMode::L0, BMode::L0),
34 MBType::B8x16(BMode::L0, BMode::L0),
35 MBType::B16x8(BMode::L1, BMode::L1),
36 MBType::B8x16(BMode::L1, BMode::L1),
37 MBType::B16x8(BMode::L0, BMode::L1),
38 MBType::B8x16(BMode::L0, BMode::L1),
39 MBType::B16x8(BMode::L1, BMode::L0),
40 MBType::B8x16(BMode::L1, BMode::L0),
41 MBType::B16x8(BMode::L0, BMode::Bi),
42 MBType::B8x16(BMode::L0, BMode::Bi),
43 MBType::B16x8(BMode::L1, BMode::Bi),
44 MBType::B8x16(BMode::L1, BMode::Bi),
45 MBType::B16x8(BMode::Bi, BMode::L0),
46 MBType::B8x16(BMode::Bi, BMode::L0),
47 MBType::B16x8(BMode::Bi, BMode::L1),
48 MBType::B8x16(BMode::Bi, BMode::L1),
49 MBType::B16x8(BMode::Bi, BMode::Bi),
50 MBType::B8x16(BMode::Bi, BMode::Bi),
51 MBType::B8x8,
52];
53
54pub fn decode_mb_type_cavlc(br: &mut BitReader, slice_hdr: &SliceHeader) -> DecoderResult<MBType> {
55 let mb_type_id = br.read_ue()? as usize;
56 match slice_hdr.slice_type {
57 SliceType::I => {
58 validate!(mb_type_id < NUM_I_TYPES);
59 Ok(map_i_type(mb_type_id))
60 },
61 SliceType::SI => {
62 validate!(mb_type_id < NUM_I_TYPES + 1);
63 if mb_type_id == 0 {
64 Ok(MBType::Intra4x4) // special SI one
65 } else {
66 Ok(map_i_type(mb_type_id - 1))
67 }
68 },
69 SliceType::P | SliceType::SP => {
70 validate!(mb_type_id < NUM_I_TYPES + P_TYPES.len());
71 if mb_type_id < P_TYPES.len() {
72 Ok(P_TYPES[mb_type_id])
73 } else {
74 Ok(map_i_type(mb_type_id - P_TYPES.len()))
75 }
76 },
77 SliceType::B => {
78 validate!(mb_type_id < NUM_I_TYPES + B_TYPES.len());
79 if mb_type_id < B_TYPES.len() {
80 Ok(B_TYPES[mb_type_id])
81 } else {
82 Ok(map_i_type(mb_type_id - B_TYPES.len()))
83 }
84 },
85 }
86}
87
88fn read_refs(br: &mut BitReader, dst: &mut [PicRef], num_refs: usize) -> DecoderResult<()> {
89 if num_refs > 1 {
90 for pic_ref in dst.iter_mut() {
91 *pic_ref = PicRef::new(br.read_te(num_refs as u32 - 1)? as u8);
92 }
93 } else {
94 for pic_ref in dst.iter_mut() {
95 *pic_ref = ZERO_REF;
96 }
97 }
98 Ok(())
99}
100
101fn read_mvs(br: &mut BitReader, mvs: &mut [MV]) -> DecoderResult<()> {
102 for mv in mvs.iter_mut() {
103 mv.x = br.read_se()? as i16;
104 mv.y = br.read_se()? as i16;
105 }
106 Ok(())
107}
108
b7c882c1 109#[allow(clippy::cognitive_complexity)]
696e4e20
KS
110pub fn decode_mb_pred_cavlc(br: &mut BitReader, slice_hdr: &SliceHeader, mb_type: MBType, sstate: &mut SliceState, mb_info: &mut CurrentMBInfo) -> DecoderResult<()> {
111 mb_info.mb_type = mb_type;
112 let num_l0 = slice_hdr.num_ref_idx_l0_active;
113 let num_l1 = slice_hdr.num_ref_idx_l1_active;
114 match mb_type {
115 MBType::Intra4x4 => {
116 for &(x, y) in I4X4_SCAN.iter() {
117 let x = x as usize;
118 let y = y as usize;
119 let top_pred = sstate.get_top_blk4(x + y * 4).ipred;
120 let left_pred = sstate.get_left_blk4(x + y * 4).ipred;
121
122 let top_idx = top_pred.into_pred_idx();
123 let left_idx = left_pred.into_pred_idx();
124 let pred_mode = top_idx.min(left_idx);
125 let mut pred_mode = if pred_mode != -1 { pred_mode as u8 } else { 2 };
126 if !br.read_bool()? {
127 let new_mode = br.read(3)? as u8;
128 pred_mode = if new_mode >= pred_mode {
129 new_mode + 1
130 } else { new_mode };
131 }
132 mb_info.ipred[x + y * 4] = pred_mode.into();
e6aaad5c 133 sstate.get_cur_blk4(x + y * 4).ipred = pred_mode.into();
696e4e20
KS
134 }
135 mb_info.chroma_ipred = br.read_ue_lim(3)? as u8;
136 },
137 MBType::Intra8x8 => {
138 for part in 0..4 {
139 let blk4 = (part & 1) * 2 + (part & 2) * 4;
140 let top_pred = sstate.get_top_blk4(blk4).ipred;
141 let left_pred = sstate.get_left_blk4(blk4).ipred;
142
143 let top_idx = top_pred.into_pred_idx();
144 let left_idx = left_pred.into_pred_idx();
145 let pred_mode = top_idx.min(left_idx);
146 let mut pred_mode = if pred_mode != -1 { pred_mode as u8 } else { 2 };
147 if !br.read_bool()? {
148 let new_mode = br.read(3)? as u8;
149 pred_mode = if new_mode >= pred_mode {
150 new_mode + 1
151 } else { new_mode };
152 }
153 mb_info.ipred[blk4] = pred_mode.into();
154 mb_info.ipred[blk4 + 1] = pred_mode.into();
155 mb_info.ipred[blk4 + 4] = pred_mode.into();
156 mb_info.ipred[blk4 + 5] = pred_mode.into();
e6aaad5c
KS
157 sstate.get_cur_blk4(blk4).ipred = pred_mode.into();
158 sstate.get_cur_blk4(blk4 + 1).ipred = pred_mode.into();
159 sstate.get_cur_blk4(blk4 + 4).ipred = pred_mode.into();
160 sstate.get_cur_blk4(blk4 + 5).ipred = pred_mode.into();
696e4e20
KS
161 }
162 mb_info.chroma_ipred = br.read_ue_lim(3)? as u8;
163 },
164 MBType::Intra16x16(_ipred, _, _) => {
165 sstate.fill_ipred(IntraPredMode::DC);
166 mb_info.chroma_ipred = br.read_ue_lim(3)? as u8;
167 },
168 MBType::P16x16 | MBType::P16x8 | MBType::P8x16 => {
169 let nparts = mb_type.num_parts();
170 read_refs(br, &mut mb_info.ref_l0[..nparts], num_l0)?;
171 read_mvs(br, &mut mb_info.mv_l0[..nparts])?;
172 },
173 MBType::B16x16(mode) => {
174 if mode != BMode::L1 {
175 read_refs(br, &mut mb_info.ref_l0[..1], num_l0)?;
176 }
177 if mode != BMode::L0 {
178 read_refs(br, &mut mb_info.ref_l1[..1], num_l1)?;
179 }
180 if mode != BMode::L1 {
181 read_mvs(br, &mut mb_info.mv_l0[..1])?;
182 }
183 if mode != BMode::L0 {
184 read_mvs(br, &mut mb_info.mv_l1[..1])?;
185 }
186 },
187 MBType::B16x8(mode0, mode1) | MBType::B8x16(mode0, mode1) => {
188 if num_l0 > 1 {
189 if mode0 != BMode::L1 {
190 read_refs(br, &mut mb_info.ref_l0[0..1], num_l0)?;
191 }
192 if mode1 != BMode::L1 {
193 read_refs(br, &mut mb_info.ref_l0[1..2], num_l0)?;
194 }
195 }
196 if num_l1 > 1 {
197 if mode0 != BMode::L0 {
198 read_refs(br, &mut mb_info.ref_l1[0..1], num_l1)?;
199 }
200 if mode1 != BMode::L0 {
201 read_refs(br, &mut mb_info.ref_l1[1..2], num_l1)?;
202 }
203 }
204 if mode0 != BMode::L1 {
205 read_mvs(br, &mut mb_info.mv_l0[0..1])?;
206 }
207 if mode1 != BMode::L1 {
208 read_mvs(br, &mut mb_info.mv_l0[1..2])?;
209 }
210 if mode0 != BMode::L0 {
211 read_mvs(br, &mut mb_info.mv_l1[0..1])?;
212 }
213 if mode1 != BMode::L0 {
214 read_mvs(br, &mut mb_info.mv_l1[1..2])?;
215 }
216 },
217 MBType::P8x8 | MBType::P8x8Ref0 | MBType::B8x8 => {
218 for sub_mb in mb_info.sub_mb_type.iter_mut() {
219 *sub_mb = decode_sub_mb_type(br, mb_type != MBType::B8x8)?;
220 }
221 for (part, &sub_mb) in mb_info.sub_mb_type.iter().enumerate() {
222 if num_l0 > 1 && mb_type != MBType::P8x8Ref0 && sub_mb != SubMBType::Direct8x8 && !sub_mb.is_l1() {
223 read_refs(br, &mut mb_info.ref_l0[part..][..1], num_l0)?;
224 }
225 }
226 for (part, &sub_mb) in mb_info.sub_mb_type.iter().enumerate() {
227 if num_l1 > 1 && sub_mb != SubMBType::Direct8x8 && !sub_mb.is_l0() {
228 read_refs(br, &mut mb_info.ref_l1[part..][..1], num_l1)?;
229 }
230 }
231 for (part, &sub_mb) in mb_info.sub_mb_type.iter().enumerate() {
232 if sub_mb != SubMBType::Direct8x8 && !sub_mb.is_l1() {
233 let num_subparts = sub_mb.num_parts();
234 read_mvs(br, &mut mb_info.mv_l0[part * 4..][..num_subparts])?;
235 }
236 }
237 for (part, &sub_mb) in mb_info.sub_mb_type.iter().enumerate() {
238 if sub_mb != SubMBType::Direct8x8 && !sub_mb.is_l0() {
239 let num_subparts = sub_mb.num_parts();
240 read_mvs(br, &mut mb_info.mv_l1[part * 4..][..num_subparts])?;
241 }
242 }
243 },
244 _ => {},
245 };
246 Ok(())
247}
248
249fn decode_sub_mb_type(br: &mut BitReader, is_p: bool) -> DecoderResult<SubMBType> {
250 const SUB_MB_P_TYPES: [SubMBType; 4] = [
251 SubMBType::P8x8, SubMBType::P8x4, SubMBType::P4x8, SubMBType::P4x4
252 ];
253 const SUB_MB_B_TYPES: [SubMBType; 13] = [
254 SubMBType::Direct8x8,
255 SubMBType::B8x8(BMode::L0), SubMBType::B8x8(BMode::L1), SubMBType::B8x8(BMode::Bi),
256 SubMBType::B8x4(BMode::L0), SubMBType::B4x8(BMode::L0),
257 SubMBType::B8x4(BMode::L1), SubMBType::B4x8(BMode::L1),
258 SubMBType::B8x4(BMode::Bi), SubMBType::B4x8(BMode::Bi),
259 SubMBType::B4x4(BMode::L0), SubMBType::B4x4(BMode::L1), SubMBType::B4x4(BMode::Bi),
260 ];
261 if is_p {
262 let idx = br.read_ue_lim(SUB_MB_P_TYPES.len() as u32 - 1)? as usize;
263 Ok(SUB_MB_P_TYPES[idx])
264 } else {
265 let idx = br.read_ue_lim(SUB_MB_B_TYPES.len() as u32 - 1)? as usize;
266 Ok(SUB_MB_B_TYPES[idx])
267 }
268}
269
270fn map_coeff_token(val: u8) -> (usize, usize) {
271 const TRAILING_ONES: [u8; 6] = [ 0, 0, 1, 0, 1, 2 ];
272 const TOTAL_COEFF: [u8; 6] = [0, 1, 1, 2, 2, 2];
273
274 if val < 6 {
275 (TRAILING_ONES[val as usize] as usize, TOTAL_COEFF[val as usize] as usize)
276 } else {
277 (((val - 6) & 3) as usize, ((val + 6) >> 2) as usize)
278 }
279}
280
281fn decode_coeffs(br: &mut BitReader, coeffs: &mut [i16], scan: &[usize], cb: &Codebook<u8>, tables: &CAVLCTables) -> DecoderResult<u8> {
282 let coeff_token = br.read_cb(cb)?;
283 let (trail_ones, total_coeff) = map_coeff_token(coeff_token);
284 let mut level = [0i16; 16];
285 let mut run = [0u8; 16];
286 if total_coeff > 0 {
287 let mut suffix_length = (total_coeff > 10 && trail_ones < 3) as u8;
288 for i in 0..total_coeff {
289 if i < trail_ones {
290 if !br.read_bool()? {
291 level[i] = 1;
292 } else {
293 level[i] = -1;
294 }
295 } else {
296 let level_prefix = br.read_code(UintCodeType::UnaryZeroes)?;
297 validate!(level_prefix <= 19);
298 let mut level_code = level_prefix.min(15) << suffix_length;
299 if suffix_length > 0 || level_prefix >= 14 {
300 let level_suffix_size = if level_prefix == 14 && suffix_length == 0 {
301 4
302 } else if level_prefix >= 15 {
303 (level_prefix - 3) as u8
304 } else {
305 suffix_length
306 };
307 let level_suffix = br.read(level_suffix_size)?;
308 level_code += level_suffix;
309 }
310 if level_prefix >= 15 && suffix_length == 0 {
311 level_code += 15;
312 }
313 if level_prefix >= 16 {
314 level_code += (1 << (level_prefix - 3)) - 4096;
315 }
316 if i == trail_ones && trail_ones < 3 {
317 level_code += 2;
318 }
319 level[i] = if (level_code & 1) == 0 {
320 (level_code as i32 + 2) >> 1
321 } else {
322 -((level_code as i32 + 1) >> 1)
323 } as i16;
324 if suffix_length == 0 {
325 suffix_length = 1;
326 }
327 if level[i].abs() > (3 << (suffix_length - 1)) && suffix_length < 6 {
328 suffix_length += 1;
329 }
330 }
331 }
332 let mut zeros_left = if total_coeff < coeffs.len() {
333 let cb = if coeffs.len() > 4 {
334 &tables.total_zeros_cb[total_coeff - 1]
335 } else {
336 &tables.cdc_total_zeros_cb[total_coeff - 1]
337 };
338 br.read_cb(cb)?
339 } else { 0 };
340 for i in 0..total_coeff - 1 {
341 if zeros_left > 0 {
342 let run_before = br.read_cb(&tables.run_before_cb[(zeros_left - 1).min(6) as usize])?;
343 run[i] = run_before;
344 zeros_left -= run_before;
345 }
346 }
347 run[total_coeff - 1] = zeros_left;
348 let mut idx = 0;
349 for i in (0..total_coeff).rev() {
350 idx += run[i] as usize;
351 coeffs[scan[idx]] = level[i];
352 idx += 1;
353 }
354 }
355 Ok(total_coeff as u8)
356}
357
358fn decode_block(br: &mut BitReader, coeffs: &mut [i16; 16], cb: &Codebook<u8>, tables: &CAVLCTables) -> DecoderResult<u8> {
359 decode_coeffs(br, coeffs, &ZIGZAG, cb, tables)
360}
361
362fn decode_block_ac(br: &mut BitReader, coeffs: &mut [i16; 16], cb: &Codebook<u8>, tables: &CAVLCTables) -> DecoderResult<u8> {
363 decode_coeffs(br, &mut coeffs[1..], &ZIGZAG1, cb, tables)
364}
365
366fn decode_chroma_dc(br: &mut BitReader, coeffs: &mut [i16; 4], cb: &Codebook<u8>, tables: &CAVLCTables) -> DecoderResult<u8> {
367 decode_coeffs(br, coeffs, &CHROMA_DC_SCAN, cb, tables)
368}
369
370fn get_cb_idx(nc: u8) -> usize {
371 match nc {
372 0 | 1 => 0,
373 2 | 3 => 1,
374 4..=7 => 2,
375 _ => 3,
376 }
377}
378
379pub fn decode_residual_cavlc(br: &mut BitReader, sstate: &mut SliceState, mb_info: &mut CurrentMBInfo, tables: &CAVLCTables) -> DecoderResult<()> {
380 if mb_info.mb_type.is_intra16x16() {
381 let mut top_nc = sstate.get_top_blk4(0).ncoded;
382 let mut left_nc = sstate.get_left_blk4(0).ncoded;
383 if !sstate.has_left {
384 left_nc = top_nc;
385 } else if !sstate.has_top {
386 top_nc = left_nc;
387 }
388 let cb_idx = get_cb_idx((left_nc + top_nc + 1) >> 1);
389
390 let nc = decode_block(br, &mut mb_info.coeffs[24], &tables.coeff_token_cb[cb_idx], tables)?;
391 mb_info.coded[24] = nc != 0;
392 }
393 for blk8 in 0..4 {
394 if (mb_info.cbpy & (1 << blk8)) != 0 {
395 for blk4 in 0..4 {
396 let bx = (blk8 & 1) * 2 + (blk4 & 1);
397 let by = ((blk8 & 2) * 2 + (blk4 & 2)) >> 1;
398 let blk_no = bx + by * 4;
399
400 let mut top_nc = sstate.get_top_blk4(blk_no).ncoded;
401 let mut left_nc = sstate.get_left_blk4(blk_no).ncoded;
402 if bx == 0 && !sstate.has_left {
403 left_nc = top_nc;
404 } else if by == 0 && !sstate.has_top {
405 top_nc = left_nc;
406 }
407 let cb_idx = get_cb_idx((left_nc + top_nc + 1) >> 1);
408
409 let nc = if mb_info.mb_type.is_intra16x16() {
410 decode_block_ac(br, &mut mb_info.coeffs[blk_no], &tables.coeff_token_cb[cb_idx], tables)?
411 } else {
412 decode_block(br, &mut mb_info.coeffs[blk_no], &tables.coeff_token_cb[cb_idx], tables)?
413 };
414 sstate.get_cur_blk4(blk_no).ncoded = nc;
415 mb_info.coded[blk_no] = nc != 0;
416 }
417 }
418 }
419 if mb_info.transform_size_8x8 {
420 for y in 0..2 {
421 for x in 0..2 {
422 let b0 = &mb_info.coeffs[x + y * 8];
423 let b1 = &mb_info.coeffs[x + 1 + y * 8];
424 let b2 = &mb_info.coeffs[x + 4 + y * 8];
425 let b3 = &mb_info.coeffs[x + 5 + y * 8];
426 let dst = &mut mb_info.coeffs8x8[x + y * 2].coeffs;
427 for (dst, (s0, s1)) in dst.chunks_mut(8).zip(b0.chunks(4).zip(b1.chunks(4))) {
428 let (d0, d1) = dst.split_at_mut(4);
429 d0.copy_from_slice(s0);
430 d1.copy_from_slice(s1);
431 }
432 for (dst, (s0, s1)) in dst.chunks_mut(8).skip(4).zip(b2.chunks(4).zip(b3.chunks(4))) {
433 let (d0, d1) = dst.split_at_mut(4);
434 d0.copy_from_slice(s0);
435 d1.copy_from_slice(s1);
436 }
437 }
438 }
439 }
440 for chroma in 0..2 {
441 if (mb_info.cbpc & 3) != 0 {
442 decode_chroma_dc(br, &mut mb_info.chroma_dc[chroma], &tables.cdc_coeff_token_cb, tables)?;
443 }
444 }
445 for chroma in 0..2 {
446 if (mb_info.cbpc & 2) != 0 {
447 for blk4 in 0..4 {
448 let blk_no = 16 + chroma * 4 + blk4;
449 let bx = blk4 & 1;
450 let by = blk4 >> 1;
451
452 let mut top_nc = sstate.get_top_blk8(blk4).ncoded_c[chroma];
453 let mut left_nc = sstate.get_left_blk8(blk4).ncoded_c[chroma];
454 if bx == 0 && !sstate.has_left {
455 left_nc = top_nc;
456 } else if by == 0 && !sstate.has_top {
457 top_nc = left_nc;
458 }
459 let cb_idx = get_cb_idx((left_nc + top_nc + 1) >> 1);
460
461 let nc = decode_block_ac(br, &mut mb_info.coeffs[blk_no], &tables.coeff_token_cb[cb_idx], tables)?;
462 sstate.get_cur_blk8(blk4).ncoded_c[chroma] = nc;
463 mb_info.coded[blk_no] = nc != 0;
464 }
465 }
466 }
467
468 Ok(())
469}
470
471pub struct CAVLCTables {
472 coeff_token_cb: [Codebook<u8>; 4],
473 cdc_coeff_token_cb: Codebook<u8>,
474 total_zeros_cb: [Codebook<u8>; 15],
475 cdc_total_zeros_cb: [Codebook<u8>; 3],
476 run_before_cb: [Codebook<u8>; 7],
477}
478
479fn map_idx(idx: usize) -> u8 { idx as u8 }
480
481macro_rules! create_cb {
482 ($bits: expr, $lens: expr) => {{
483 let mut reader = TableCodebookDescReader::new($bits, $lens, map_idx);
484 Codebook::new(&mut reader, CodebookMode::MSB).unwrap()
485 }}
486}
487
488impl CAVLCTables {
489 pub fn new() -> Self {
490 /*let mut reader = TableCodebookDescReader::new(&COEFF_TOKEN_BITS[0], &COEFF_TOKEN_LENS[0], map_idx);
491 let coef_tok_cb0 = Codebook::new(&mut reader, CodebookMode::MSB).unwrap();
492 let mut reader = TableCodebookDescReader::new(&COEFF_TOKEN_BITS[1], &COEFF_TOKEN_LENS[1], map_idx);
493 let coef_tok_cb1 = Codebook::new(&mut reader, CodebookMode::MSB).unwrap();
494 let mut reader = TableCodebookDescReader::new(&COEFF_TOKEN_BITS[2], &COEFF_TOKEN_LENS[2], map_idx);
495 let coef_tok_cb2 = Codebook::new(&mut reader, CodebookMode::MSB).unwrap();
496 let mut reader = TableCodebookDescReader::new(&COEFF_TOKEN_BITS[3], &COEFF_TOKEN_LENS[3], map_idx);
497 let coef_tok_cb3 = Codebook::new(&mut reader, CodebookMode::MSB).unwrap();
498
499 let mut reader = TableCodebookDescReader::new(&CHROMA_DC_COEFF_TOKEN_BITS, &CHROMA_DC_COEFF_TOKEN_LENS, map_idx);
500 let cdc_coeff_token_cb = Codebook::new(&mut reader, CodebookMode::MSB).unwrap();*/
501
502 let coef_tok_cb0 = create_cb!(&COEFF_TOKEN_BITS[0], &COEFF_TOKEN_LENS[0]);
503 let coef_tok_cb1 = create_cb!(&COEFF_TOKEN_BITS[1], &COEFF_TOKEN_LENS[1]);
504 let coef_tok_cb2 = create_cb!(&COEFF_TOKEN_BITS[2], &COEFF_TOKEN_LENS[2]);
505 let coef_tok_cb3 = create_cb!(&COEFF_TOKEN_BITS[3], &COEFF_TOKEN_LENS[3]);
506
507 let cdc_coeff_token_cb = create_cb!(&CHROMA_DC_COEFF_TOKEN_BITS, &CHROMA_DC_COEFF_TOKEN_LENS);
508
509 let total_zeros0 = create_cb!(&TOTAL_ZERO_BITS[ 0], &TOTAL_ZERO_LENS[ 0]);
510 let total_zeros1 = create_cb!(&TOTAL_ZERO_BITS[ 1], &TOTAL_ZERO_LENS[ 1]);
511 let total_zeros2 = create_cb!(&TOTAL_ZERO_BITS[ 2], &TOTAL_ZERO_LENS[ 2]);
512 let total_zeros3 = create_cb!(&TOTAL_ZERO_BITS[ 3], &TOTAL_ZERO_LENS[ 3]);
513 let total_zeros4 = create_cb!(&TOTAL_ZERO_BITS[ 4], &TOTAL_ZERO_LENS[ 4]);
514 let total_zeros5 = create_cb!(&TOTAL_ZERO_BITS[ 5], &TOTAL_ZERO_LENS[ 5]);
515 let total_zeros6 = create_cb!(&TOTAL_ZERO_BITS[ 6], &TOTAL_ZERO_LENS[ 6]);
516 let total_zeros7 = create_cb!(&TOTAL_ZERO_BITS[ 7], &TOTAL_ZERO_LENS[ 7]);
517 let total_zeros8 = create_cb!(&TOTAL_ZERO_BITS[ 8], &TOTAL_ZERO_LENS[ 8]);
518 let total_zeros9 = create_cb!(&TOTAL_ZERO_BITS[ 9], &TOTAL_ZERO_LENS[ 9]);
519 let total_zeros10 = create_cb!(&TOTAL_ZERO_BITS[10], &TOTAL_ZERO_LENS[10]);
520 let total_zeros11 = create_cb!(&TOTAL_ZERO_BITS[11], &TOTAL_ZERO_LENS[11]);
521 let total_zeros12 = create_cb!(&TOTAL_ZERO_BITS[12], &TOTAL_ZERO_LENS[12]);
522 let total_zeros13 = create_cb!(&TOTAL_ZERO_BITS[13], &TOTAL_ZERO_LENS[13]);
523 let total_zeros14 = create_cb!(&TOTAL_ZERO_BITS[14], &TOTAL_ZERO_LENS[14]);
524
525 let cdc_total_zeros_cb0 = create_cb!(&CHROMA_DC_TOTAL_ZERO_BITS[0], &CHROMA_DC_TOTAL_ZERO_LENS[0]);
526 let cdc_total_zeros_cb1 = create_cb!(&CHROMA_DC_TOTAL_ZERO_BITS[1], &CHROMA_DC_TOTAL_ZERO_LENS[1]);
527 let cdc_total_zeros_cb2 = create_cb!(&CHROMA_DC_TOTAL_ZERO_BITS[2], &CHROMA_DC_TOTAL_ZERO_LENS[2]);
528
529 let run_before_cb0 = create_cb!(&RUN_BEFORE_BITS[0], &RUN_BEFORE_LENS[0]);
530 let run_before_cb1 = create_cb!(&RUN_BEFORE_BITS[1], &RUN_BEFORE_LENS[1]);
531 let run_before_cb2 = create_cb!(&RUN_BEFORE_BITS[2], &RUN_BEFORE_LENS[2]);
532 let run_before_cb3 = create_cb!(&RUN_BEFORE_BITS[3], &RUN_BEFORE_LENS[3]);
533 let run_before_cb4 = create_cb!(&RUN_BEFORE_BITS[4], &RUN_BEFORE_LENS[4]);
534 let run_before_cb5 = create_cb!(&RUN_BEFORE_BITS[5], &RUN_BEFORE_LENS[5]);
535 let run_before_cb6 = create_cb!(&RUN_BEFORE_BITS[6], &RUN_BEFORE_LENS[6]);
536
537 Self {
538 coeff_token_cb: [coef_tok_cb0, coef_tok_cb1, coef_tok_cb2, coef_tok_cb3],
539 cdc_coeff_token_cb,
540 total_zeros_cb: [total_zeros0, total_zeros1, total_zeros2,
541 total_zeros3, total_zeros4, total_zeros5,
542 total_zeros6, total_zeros7, total_zeros8,
543 total_zeros9, total_zeros10, total_zeros11,
544 total_zeros12, total_zeros13, total_zeros14 ],
545 cdc_total_zeros_cb: [cdc_total_zeros_cb0, cdc_total_zeros_cb1, cdc_total_zeros_cb2],
546 run_before_cb: [ run_before_cb0, run_before_cb1, run_before_cb2,
547 run_before_cb3, run_before_cb4, run_before_cb5,
548 run_before_cb6 ],
549 }
550 }
551}
552
553const COEFF_TOKEN_BITS: [[u16; 62]; 4] = [
554 [
555 0x01, 0x05, 0x01, 0x07, 0x04, 0x01, 0x07, 0x06,
556 0x05, 0x03, 0x07, 0x06, 0x05, 0x03, 0x07, 0x06,
557 0x05, 0x04, 0x0F, 0x06, 0x05, 0x04, 0x0B, 0x0E,
558 0x05, 0x04, 0x08, 0x0A, 0x0D, 0x04, 0x0F, 0x0E,
559 0x09, 0x04, 0x0B, 0x0A, 0x0D, 0x0C, 0x0F, 0x0E,
560 0x09, 0x0C, 0x0B, 0x0A, 0x0D, 0x08, 0x0F, 0x01,
561 0x09, 0x0C, 0x0B, 0x0E, 0x0D, 0x08, 0x07, 0x0A,
562 0x09, 0x0C, 0x04, 0x06, 0x05, 0x08
563 ], [
564 0x03, 0x0B, 0x02, 0x07, 0x07, 0x03, 0x07, 0x0A,
565 0x09, 0x05, 0x07, 0x06, 0x05, 0x04, 0x04, 0x06,
566 0x05, 0x06, 0x07, 0x06, 0x05, 0x08, 0x0F, 0x06,
567 0x05, 0x04, 0x0B, 0x0E, 0x0D, 0x04, 0x0F, 0x0A,
568 0x09, 0x04, 0x0B, 0x0E, 0x0D, 0x0C, 0x08, 0x0A,
569 0x09, 0x08, 0x0F, 0x0E, 0x0D, 0x0C, 0x0B, 0x0A,
570 0x09, 0x0C, 0x07, 0x0B, 0x06, 0x08, 0x09, 0x08,
571 0x0A, 0x01, 0x07, 0x06, 0x05, 0x04
572 ], [
573 0x0F, 0x0F, 0x0E, 0x0B, 0x0F, 0x0D, 0x08, 0x0C,
574 0x0E, 0x0C, 0x0F, 0x0A, 0x0B, 0x0B, 0x0B, 0x08,
575 0x09, 0x0A, 0x09, 0x0E, 0x0D, 0x09, 0x08, 0x0A,
576 0x09, 0x08, 0x0F, 0x0E, 0x0D, 0x0D, 0x0B, 0x0E,
577 0x0A, 0x0C, 0x0F, 0x0A, 0x0D, 0x0C, 0x0B, 0x0E,
578 0x09, 0x0C, 0x08, 0x0A, 0x0D, 0x08, 0x0D, 0x07,
579 0x09, 0x0C, 0x09, 0x0C, 0x0B, 0x0A, 0x05, 0x08,
580 0x07, 0x06, 0x01, 0x04, 0x03, 0x02
581 ], [
582 0x03, 0x00, 0x01, 0x04, 0x05, 0x06, 0x08, 0x09,
583 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11,
584 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19,
585 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21,
586 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29,
587 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30, 0x31,
588 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
589 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F
590 ]
591];
592const COEFF_TOKEN_LENS: [[u8; 62]; 4] = [
593 [
594 1, 6, 2, 8, 6, 3, 9, 8, 7, 5, 10, 9, 8, 6, 11, 10,
595 9, 7, 13, 11, 10, 8, 13, 13, 11, 9, 13, 13, 13, 10, 14, 14,
596 13, 11, 14, 14, 14, 13, 15, 15, 14, 14, 15, 15, 15, 14, 16, 15,
597 15, 15, 16, 16, 16, 15, 16, 16, 16, 16, 16, 16, 16, 16
598 ], [
599 2, 6, 2, 6, 5, 3, 7, 6, 6, 4, 8, 6, 6, 4, 8, 7,
600 7, 5, 9, 8, 8, 6, 11, 9, 9, 6, 11, 11, 11, 7, 12, 11,
601 11, 9, 12, 12, 12, 11, 12, 12, 12, 11, 13, 13, 13, 12, 13, 13,
602 13, 13, 13, 14, 13, 13, 14, 14, 14, 13, 14, 14, 14, 14
603 ], [
604 4, 6, 4, 6, 5, 4, 6, 5, 5, 4, 7, 5, 5, 4, 7, 5,
605 5, 4, 7, 6, 6, 4, 7, 6, 6, 4, 8, 7, 7, 5, 8, 8,
606 7, 6, 9, 8, 8, 7, 9, 9, 8, 8, 9, 9, 9, 8, 10, 9,
607 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10
608 ], [ 6; 62 ]
609];
610
611const CHROMA_DC_COEFF_TOKEN_BITS: [u8; 14] = [
612 1, 7, 1, 4, 6, 1, 3, 3, 2, 5, 2, 3, 2, 0
613];
614const CHROMA_DC_COEFF_TOKEN_LENS: [u8; 14] = [
615 2, 6, 1, 6, 6, 3, 6, 7, 7, 6, 6, 8, 8, 7
616];
617
618const TOTAL_ZERO_BITS: [[u8; 16]; 15] = [
619 [ 1, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 1 ],
620 [ 7, 6, 5, 4, 3, 5, 4, 3, 2, 3, 2, 3, 2, 1, 0, 0 ],
621 [ 5, 7, 6, 5, 4, 3, 4, 3, 2, 3, 2, 1, 1, 0, 0, 0 ],
622 [ 3, 7, 5, 4, 6, 5, 4, 3, 3, 2, 2, 1, 0, 0, 0, 0 ],
623 [ 5, 4, 3, 7, 6, 5, 4, 3, 2, 1, 1, 0, 0, 0, 0, 0 ],
624 [ 1, 1, 7, 6, 5, 4, 3, 2, 1, 1, 0, 0, 0, 0, 0, 0 ],
625 [ 1, 1, 5, 4, 3, 3, 2, 1, 1, 0, 0, 0, 0, 0, 0, 0 ],
626 [ 1, 1, 1, 3, 3, 2, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0 ],
627 [ 1, 0, 1, 3, 2, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0 ],
628 [ 1, 0, 1, 3, 2, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0 ],
629 [ 0, 1, 1, 2, 1, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ],
630 [ 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ],
631 [ 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ],
632 [ 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ],
633 [ 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ]
634];
635const TOTAL_ZERO_LENS: [[u8; 16]; 15] = [
636 [ 1, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 9 ],
637 [ 3, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 6, 6, 6, 6, 0 ],
638 [ 4, 3, 3, 3, 4, 4, 3, 3, 4, 5, 5, 6, 5, 6, 0, 0 ],
639 [ 5, 3, 4, 4, 3, 3, 3, 4, 3, 4, 5, 5, 5, 0, 0, 0 ],
640 [ 4, 4, 4, 3, 3, 3, 3, 3, 4, 5, 4, 5, 0, 0, 0, 0 ],
641 [ 6, 5, 3, 3, 3, 3, 3, 3, 4, 3, 6, 0, 0, 0, 0, 0 ],
642 [ 6, 5, 3, 3, 3, 2, 3, 4, 3, 6, 0, 0, 0, 0, 0, 0 ],
643 [ 6, 4, 5, 3, 2, 2, 3, 3, 6, 0, 0, 0, 0, 0, 0, 0 ],
644 [ 6, 6, 4, 2, 2, 3, 2, 5, 0, 0, 0, 0, 0, 0, 0, 0 ],
645 [ 5, 5, 3, 2, 2, 2, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0 ],
646 [ 4, 4, 3, 3, 1, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ],
647 [ 4, 4, 2, 1, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ],
648 [ 3, 3, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ],
649 [ 2, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ],
650 [ 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ]
651];
652
653const CHROMA_DC_TOTAL_ZERO_BITS: [[u8; 4]; 3] = [
654 [ 1, 1, 1, 0 ], [ 1, 1, 0, 0 ], [ 1, 0, 0, 0 ]
655];
656const CHROMA_DC_TOTAL_ZERO_LENS: [[u8; 4]; 3] = [
657 [ 1, 2, 3, 3 ], [ 1, 2, 2, 0 ], [ 1, 1, 0, 0 ]
658];
659
660const RUN_BEFORE_BITS: [[u8; 15]; 7] = [
661 [ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ],
662 [ 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ],
663 [ 3, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ],
664 [ 3, 2, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ],
665 [ 3, 2, 3, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ],
666 [ 3, 0, 1, 3, 2, 5, 4, 0, 0, 0, 0, 0, 0, 0, 0 ],
667 [ 7, 6, 5, 4, 3, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1 ]
668];
669const RUN_BEFORE_LENS: [[u8; 15]; 7] = [
670 [ 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ],
671 [ 1, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ],
672 [ 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ],
673 [ 2, 2, 2, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ],
674 [ 2, 2, 3, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0 ],
675 [ 2, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0 ],
676 [ 3, 3, 3, 3, 3, 3, 3, 4, 5, 6, 7, 8, 9, 10, 11 ]
677];