]>
Commit | Line | Data |
---|---|---|
696e4e20 KS |
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 | ||
b7c882c1 | 109 | #[allow(clippy::cognitive_complexity)] |
696e4e20 KS |
110 | pub 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(); | |
133 | sstate.get_cur_blk4(x + y * 4).ipred = (pred_mode as u8).into(); | |
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(); | |
157 | sstate.get_cur_blk4(blk4).ipred = (pred_mode as u8).into(); | |
158 | sstate.get_cur_blk4(blk4 + 1).ipred = (pred_mode as u8).into(); | |
159 | sstate.get_cur_blk4(blk4 + 4).ipred = (pred_mode as u8).into(); | |
160 | sstate.get_cur_blk4(blk4 + 5).ipred = (pred_mode as u8).into(); | |
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 | ||
249 | fn 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 | ||
270 | fn 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 | ||
281 | fn 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 | ||
358 | fn 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 | ||
362 | fn 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 | ||
366 | fn 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 | ||
370 | fn 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 | ||
379 | pub 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 | ||
471 | pub 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 | ||
479 | fn map_idx(idx: usize) -> u8 { idx as u8 } | |
480 | ||
481 | macro_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 | ||
488 | impl 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 | ||
553 | const 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 | ]; | |
592 | const 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 | ||
611 | const CHROMA_DC_COEFF_TOKEN_BITS: [u8; 14] = [ | |
612 | 1, 7, 1, 4, 6, 1, 3, 3, 2, 5, 2, 3, 2, 0 | |
613 | ]; | |
614 | const CHROMA_DC_COEFF_TOKEN_LENS: [u8; 14] = [ | |
615 | 2, 6, 1, 6, 6, 3, 6, 7, 7, 6, 6, 8, 8, 7 | |
616 | ]; | |
617 | ||
618 | const 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 | ]; | |
635 | const 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 | ||
653 | const CHROMA_DC_TOTAL_ZERO_BITS: [[u8; 4]; 3] = [ | |
654 | [ 1, 1, 1, 0 ], [ 1, 1, 0, 0 ], [ 1, 0, 0, 0 ] | |
655 | ]; | |
656 | const CHROMA_DC_TOTAL_ZERO_LENS: [[u8; 4]; 3] = [ | |
657 | [ 1, 2, 3, 3 ], [ 1, 2, 2, 0 ], [ 1, 1, 0, 0 ] | |
658 | ]; | |
659 | ||
660 | const 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 | ]; | |
669 | const 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 | ]; |