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