]>
Commit | Line | Data |
---|---|---|
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 | ]; |