add flush() to decoder interface
[nihav.git] / nihav-duck / src / codecs / vp56.rs
1 use nihav_core::codecs::*;
2 use nihav_core::data::GenericCache;
3 use nihav_core::io::bitreader::*;
4 use super::vpcommon::*;
5
6 pub const TOKEN_LARGE: u8 = 5;
7 pub const TOKEN_EOB: u8 = 42;
8
9 #[derive(Clone,Copy,Debug,Default)]
10 #[allow(dead_code)]
11 pub struct VP56Header {
12 pub is_intra: bool,
13 pub is_golden: bool,
14 pub quant: u8,
15 pub multistream: bool,
16 pub use_huffman: bool,
17 pub version: u8,
18 pub profile: u8,
19 pub interlaced: bool,
20 pub offset: u16,
21 pub mb_w: u8,
22 pub mb_h: u8,
23 pub disp_w: u8,
24 pub disp_h: u8,
25 pub scale: u8,
26 }
27
28 #[derive(Clone,Copy,Default)]
29 pub struct VP56MVModel {
30 pub nz_prob: u8,
31 pub sign_prob: u8,
32 pub raw_probs: [u8; 8],
33 pub tree_probs: [u8; 7],
34 }
35
36 #[derive(Clone,Copy,Default)]
37 pub struct VP56MBTypeModel {
38 pub probs: [u8; 10],
39 }
40
41 #[derive(Clone,Copy,Default)]
42 pub struct VP56CoeffModel {
43 pub dc_token_probs: [[[u8; 5]; 6]; 6],
44 pub dc_value_probs: [u8; 11],
45 pub ac_ctype_probs: [[[[u8; 5]; 5]; 6]; 3],
46 pub ac_type_probs: [[[[u8; 5]; 6]; 3]; 3],
47 pub ac_val_probs: [[[u8; 11]; 6]; 3],
48 }
49
50 pub struct VP6Models {
51 pub scan_order: [usize; 64],
52 pub scan: [usize; 64],
53 pub zigzag: [usize; 64],
54 pub zero_run_probs: [[u8; 14]; 2],
55 }
56
57 const MAX_HUFF_ELEMS: usize = 12;
58 #[derive(Clone,Copy,Default)]
59 pub struct VP6Huff {
60 pub codes: [u16; MAX_HUFF_ELEMS],
61 pub bits: [u8; MAX_HUFF_ELEMS],
62 }
63
64 #[derive(Clone,Copy,Default)]
65 struct Node {
66 weight: u16,
67 sym: i8,
68 ch0: usize,
69 ch1: usize,
70 }
71
72 fn prob2weight(a: u8, b: u8) -> u8 {
73 let w = (((a as u16) * (b as u16)) >> 8) as u8;
74 if w == 0 {
75 1
76 } else {
77 w
78 }
79 }
80
81 impl VP6Huff {
82 fn build_codes(&mut self, probs: &[u8; 11]) {
83 let mut weights = [0u8; 12];
84
85 weights[11] = prob2weight( probs[0], probs[ 1]);
86 weights[ 0] = prob2weight( probs[0], !probs[ 1]);
87 weights[ 1] = prob2weight(!probs[0], probs[ 2]);
88 let lvroot = prob2weight(!probs[0], !probs[ 2]);
89 let tworoot = prob2weight( lvroot, probs[ 3]);
90 let hlroot = prob2weight( lvroot, !probs[ 3]);
91 weights[ 2] = prob2weight( tworoot, probs[ 4]);
92 let root34 = prob2weight( tworoot, !probs[ 4]);
93 weights[ 3] = prob2weight( root34, probs[ 5]);
94 weights[ 4] = prob2weight( root34, !probs[ 5]);
95 let c1root = prob2weight( hlroot, probs[ 6]);
96 let c34root = prob2weight( hlroot, !probs[ 6]);
97 weights[ 5] = prob2weight( c1root, probs[ 7]);
98 weights[ 6] = prob2weight( c1root, !probs[ 7]);
99 let c3root = prob2weight( c34root, probs[ 8]);
100 let c4root = prob2weight( c34root, !probs[ 8]);
101 weights[ 7] = prob2weight( c3root, probs[ 9]);
102 weights[ 8] = prob2weight( c3root, !probs[ 9]);
103 weights[ 9] = prob2weight( c4root, probs[10]);
104 weights[10] = prob2weight( c4root, !probs[10]);
105
106 self.build(&weights);
107 }
108 fn build_codes_zero_run(&mut self, probs: &[u8; 14]) {
109 let mut weights = [0u8; 9];
110
111 let root = prob2weight( probs[0], probs[1]);
112 weights[0] = prob2weight( root, probs[2]);
113 weights[1] = prob2weight( root, !probs[2]);
114
115 let root = prob2weight( probs[0], !probs[1]);
116 weights[2] = prob2weight( root, probs[3]);
117 weights[3] = prob2weight( root, !probs[3]);
118
119 let root = prob2weight(!probs[0], probs[4]);
120 weights[8] = prob2weight(!probs[0], !probs[4]);
121 let root1 = prob2weight( root, probs[5]);
122 let root2 = prob2weight( root, !probs[5]);
123 weights[4] = prob2weight( root1, probs[6]);
124 weights[5] = prob2weight( root1, !probs[6]);
125 weights[6] = prob2weight( root2, probs[7]);
126 weights[7] = prob2weight( root2, !probs[7]);
127
128 self.build(&weights);
129 }
130 fn build(&mut self, weights: &[u8]) {
131 let mut nodes = [Node::default(); MAX_HUFF_ELEMS * 2];
132 let mut nlen = 0;
133
134 for w in weights.iter().rev() {
135 let weight = *w as u16;
136 let mut pos = nlen;
137 for i in 0..nlen {
138 if nodes[i].weight > weight {
139 pos = i;
140 break;
141 }
142 }
143 for j in (pos..nlen).rev() {
144 nodes[j + 1] = nodes[j];
145 }
146 nodes[pos].weight = weight;
147 nodes[pos].sym = (weights.len() - nlen - 1) as i8;
148 nlen += 1;
149 }
150
151 let mut low = 0;
152 for _ in 0..nlen-1 {
153 let nnode = Node {
154 weight: nodes[low + 0].weight + nodes[low + 1].weight,
155 sym: -1,
156 ch0: low + 0,
157 ch1: low + 1,
158 };
159 low += 2;
160 let mut pos = low;
161 while (pos < nlen) && (nodes[pos].weight < nnode.weight) {
162 pos += 1;
163 }
164 for j in (pos..nlen).rev() {
165 nodes[j + 1] = nodes[j];
166 }
167 nodes[pos] = nnode;
168 nlen += 1;
169 }
170 self.get_codes(&nodes, nlen - 1, 0, 0);
171 for i in nlen..self.codes.len() {
172 self.codes[i] = self.codes[0];
173 self.bits[i] = self.bits[0];
174 }
175 }
176 fn get_codes(&mut self, nodes: &[Node], pos: usize, code: u16, len: u8) {
177 if nodes[pos].sym >= 0 {
178 self.codes[nodes[pos].sym as usize] = code;
179 self.bits [nodes[pos].sym as usize] = len;
180 } else {
181 self.get_codes(nodes, nodes[pos].ch0, (code << 1) | 0, len + 1);
182 self.get_codes(nodes, nodes[pos].ch1, (code << 1) | 1, len + 1);
183 }
184 }
185 }
186
187 pub trait ReadHuff {
188 fn read_huff(&mut self, huff: &VP6Huff) -> DecoderResult<u8>;
189 }
190
191 impl<'a> ReadHuff for BitReader<'a> {
192 fn read_huff(&mut self, huff: &VP6Huff) -> DecoderResult<u8> {
193 let peekval = self.peek(16);
194 for (i, (code, bit)) in huff.codes.iter().zip(huff.bits.iter()).enumerate() {
195 if (peekval >> (16 - *bit)) == (*code as u32) {
196 self.skip(*bit as u32)?;
197 return Ok(i as u8);
198 }
199 }
200 Err(DecoderError::InvalidData)
201 }
202 }
203
204 #[derive(Clone,Copy,Default)]
205 pub struct VP6HuffModels {
206 pub dc_token_tree: [VP6Huff; 2],
207 pub ac_token_tree: [[[VP6Huff; 6]; 3]; 2],
208 pub zero_run_tree: [VP6Huff; 2],
209 }
210
211 impl VP6Models {
212 fn new() -> Self {
213 Self {
214 scan_order: [0; 64],
215 scan: [0; 64],
216 zigzag: [0; 64],
217 zero_run_probs: [[0; 14]; 2],
218 }
219 }
220 }
221
222 pub struct VP56Models {
223 pub mv_models: [VP56MVModel; 2],
224 pub mbtype_models: [[VP56MBTypeModel; 10]; 3],
225 pub coeff_models: [VP56CoeffModel; 2],
226 pub prob_xmitted: [[u8; 20]; 3],
227 pub vp6models: VP6Models,
228 pub vp6huff: VP6HuffModels,
229 }
230
231 impl VP56Models {
232 fn new() -> Self {
233 Self {
234 mv_models: [VP56MVModel::default(); 2],
235 mbtype_models: [[VP56MBTypeModel::default(); 10]; 3],
236 coeff_models: [VP56CoeffModel::default(); 2],
237 prob_xmitted: [[0; 20]; 3],
238 vp6models: VP6Models::new(),
239 vp6huff: VP6HuffModels::default(),
240 }
241 }
242 }
243
244 pub trait VP56Parser {
245 fn parse_header(&mut self, bc: &mut BoolCoder) -> DecoderResult<VP56Header>;
246 fn reset_models(&self, models: &mut VP56Models);
247 fn decode_mv(&self, bc: &mut BoolCoder, model: &VP56MVModel) -> i16;
248 fn decode_mv_models(&self, bc: &mut BoolCoder, models: &mut [VP56MVModel; 2]) -> DecoderResult<()>;
249 fn decode_coeff_models(&self, bc: &mut BoolCoder, models: &mut VP56Models, is_intra: bool) -> DecoderResult<()>;
250 fn decode_block(&self, bc: &mut BoolCoder, coeffs: &mut [i16; 64], model: &VP56CoeffModel, vp6model: &VP6Models, fstate: &mut FrameState) -> DecoderResult<()>;
251 fn decode_block_huff(&self, br: &mut BitReader, coeffs: &mut [i16; 64], vp6model: &VP6Models, model: &VP6HuffModels, fstate: &mut FrameState) -> DecoderResult<()>;
252 fn mc_block(&self, dst: &mut NASimpleVideoFrame<u8>, mc_buf: NAVideoBufferRef<u8>, src: NAVideoBufferRef<u8>, plane: usize, x: usize, y: usize, mv: MV, loop_thr: i16);
253 }
254
255 enum CoeffReader<'a> {
256 None,
257 Bool(BoolCoder<'a>),
258 Huff(BitReader<'a>),
259 }
260
261 #[derive(Clone,Copy,Default)]
262 struct MBInfo {
263 mb_type: VPMBType,
264 mv: MV,
265 }
266
267 pub struct FrameState {
268 pub mb_x: usize,
269 pub mb_y: usize,
270 pub plane: usize,
271 pub coeff_cat: [[u8; 64]; 4],
272 pub last_idx: [usize; 4],
273 pub top_ctx: u8,
274 pub ctx_idx: usize,
275 pub dc_quant: i16,
276 pub ac_quant: i16,
277 pub dc_zero_run: [usize; 2],
278 pub ac_zero_run: [usize; 2],
279 }
280
281 impl FrameState {
282 fn new() -> Self {
283 Self {
284 mb_x: 0,
285 mb_y: 0,
286 plane: 0,
287 coeff_cat: [[0; 64]; 4],
288 last_idx: [0; 4],
289 top_ctx: 0,
290 ctx_idx: 0,
291 dc_quant: 0,
292 ac_quant: 0,
293 dc_zero_run: [0; 2],
294 ac_zero_run: [0; 2],
295 }
296 }
297 }
298
299 pub struct VP56Decoder {
300 version: u8,
301 has_alpha: bool,
302 flip: bool,
303 shuf: VPShuffler,
304 width: usize,
305 height: usize,
306 mb_w: usize,
307 mb_h: usize,
308 models: VP56Models,
309 coeffs: [[i16; 64]; 6],
310 last_mbt: VPMBType,
311
312 loop_thr: i16,
313 ilace_prob: u8,
314 ilace_mb: bool,
315
316 mb_info: Vec<MBInfo>,
317 fstate: FrameState,
318 dc_y: GenericCache<i16>,
319 dc_u: GenericCache<i16>,
320 dc_v: GenericCache<i16>,
321 dc_a: GenericCache<i16>,
322 last_dc: [[i16; 4]; 3],
323 top_ctx: [Vec<u8>; 4],
324
325 mc_buf: NAVideoBufferRef<u8>,
326 }
327
328 fn rescale_mb_mode_prob(prob: u32, total: u32) -> u8 {
329 (255 * prob / (1 + total)) as u8
330 }
331
332 fn map_mb_type(mbtype: VPMBType) -> usize {
333 match mbtype {
334 VPMBType::InterNoMV => 0,
335 VPMBType::Intra => 1,
336 VPMBType::InterMV => 2,
337 VPMBType::InterNearest => 3,
338 VPMBType::InterNear => 4,
339 VPMBType::GoldenNoMV => 5,
340 VPMBType::GoldenMV => 6,
341 VPMBType::InterFourMV => 7,
342 VPMBType::GoldenNearest => 8,
343 VPMBType::GoldenNear => 9,
344 }
345 }
346
347 pub fn expand_token_bc(bc: &mut BoolCoder, val_probs: &[u8; 11], token: u8, version: u8) -> i16 {
348 let mut sign = false;
349 let level;
350 if token < TOKEN_LARGE {
351 if token != 0 {
352 sign = bc.read_bool();
353 }
354 level = token as i16;
355 } else {
356 let cat: usize = vp_tree!(bc, val_probs[6],
357 vp_tree!(bc, val_probs[7], 0, 1),
358 vp_tree!(bc, val_probs[8],
359 vp_tree!(bc, val_probs[9], 2, 3),
360 vp_tree!(bc, val_probs[10], 4, 5)));
361 if version == 5 {
362 sign = bc.read_bool();
363 }
364 let mut add = 0i16;
365 let add_probs = &VP56_COEF_ADD_PROBS[cat];
366 for prob in add_probs.iter() {
367 if *prob == 128 { break; }
368 add = (add << 1) | (bc.read_prob(*prob) as i16);
369 }
370 if version != 5 {
371 sign = bc.read_bool();
372 }
373 level = VP56_COEF_BASE[cat] + add;
374 }
375 if !sign {
376 level
377 } else {
378 -level
379 }
380 }
381
382 impl VP56Decoder {
383 pub fn new(version: u8, has_alpha: bool, flip: bool) -> Self {
384 let vt = alloc_video_buffer(NAVideoInfo::new(24, 24, false, YUV420_FORMAT), 4).unwrap();
385 let mc_buf = vt.get_vbuf().unwrap();
386 Self {
387 version, has_alpha, flip,
388 shuf: VPShuffler::new(),
389 width: 0,
390 height: 0,
391 mb_w: 0,
392 mb_h: 0,
393 models: VP56Models::new(),
394 coeffs: [[0; 64]; 6],
395 last_mbt: VPMBType::InterNoMV,
396
397 loop_thr: 0,
398 ilace_prob: 0,
399 ilace_mb: false,
400
401 mb_info: Vec::new(),
402 fstate: FrameState::new(),
403 dc_y: GenericCache::new(0, 0, 0),
404 dc_u: GenericCache::new(0, 0, 0),
405 dc_v: GenericCache::new(0, 0, 0),
406 dc_a: GenericCache::new(0, 0, 0),
407 last_dc: [[0; 4]; 3],
408 top_ctx: [Vec::new(), Vec::new(), Vec::new(), Vec::new()],
409
410 mc_buf,
411 }
412 }
413 fn set_dimensions(&mut self, width: usize, height: usize) {
414 self.width = width;
415 self.height = height;
416 self.mb_w = (self.width + 15) >> 4;
417 self.mb_h = (self.height + 15) >> 4;
418 self.mb_info.resize(self.mb_w * self.mb_h, MBInfo::default());
419 self.dc_y = GenericCache::new(2, 1 + self.mb_w * 2, 0);
420 self.dc_u = GenericCache::new(1, 1 + self.mb_w, 0);
421 self.dc_v = GenericCache::new(1, 1 + self.mb_w, 0);
422 self.dc_a = GenericCache::new(2, 1 + self.mb_w * 2, 0);
423 self.top_ctx = [vec![0; self.mb_w * 2], vec![0; self.mb_w], vec![0; self.mb_w], vec![0; self.mb_w * 2]];
424 }
425 pub fn init(&mut self, supp: &mut NADecoderSupport, vinfo: NAVideoInfo) -> DecoderResult<()> {
426 supp.pool_u8.set_dec_bufs(3);
427 supp.pool_u8.prealloc_video(NAVideoInfo::new(vinfo.get_width(), vinfo.get_height(), false, vinfo.get_format()), 4)?;
428 self.set_dimensions(vinfo.get_width(), vinfo.get_height());
429 Ok(())
430 }
431 pub fn flush(&mut self) {
432 self.shuf.clear();
433 }
434 pub fn decode_frame(&mut self, supp: &mut NADecoderSupport, src: &[u8], br: &mut dyn VP56Parser) -> DecoderResult<(NABufferType, FrameType)> {
435 let aoffset;
436 let mut bc;
437 if self.has_alpha {
438 validate!(src.len() >= 7);
439 aoffset = ((src[0] as usize) << 16) | ((src[1] as usize) << 8) | (src[2] as usize);
440 validate!((aoffset > 0) && (aoffset < src.len() - 3));
441 bc = BoolCoder::new(&src[3..])?;
442 } else {
443 validate!(src.len() >= 4);
444 aoffset = src.len();
445 bc = BoolCoder::new(src)?;
446 }
447 let hdr = br.parse_header(&mut bc)?;
448 validate!((hdr.offset as usize) < aoffset); //XXX: take alpha 3 byte offset into account?
449
450 if hdr.mb_w != 0 {
451 self.set_dimensions((hdr.mb_w as usize) * 16, (hdr.mb_h as usize) * 16);
452 }
453 let vinfo = NAVideoInfo::new(self.width, self.height, self.flip, YUV420_FORMAT);
454 let ret = supp.pool_u8.get_free();
455 if ret.is_none() {
456 return Err(DecoderError::AllocError);
457 }
458 let mut buf = ret.unwrap();
459 if buf.get_info() != vinfo {
460 self.shuf.clear();
461 supp.pool_u8.reset();
462 supp.pool_u8.prealloc_video(vinfo, 4)?;
463 let ret = supp.pool_u8.get_free();
464 if ret.is_none() {
465 return Err(DecoderError::AllocError);
466 }
467 buf = ret.unwrap();
468 }
469 let mut dframe = NASimpleVideoFrame::from_video_buf(&mut buf).unwrap();
470
471 if hdr.is_intra {
472 self.shuf.clear();
473 }
474
475 let mut cr;
476 if hdr.multistream {
477 let off = (if self.has_alpha { 3 } else { 0 }) + (hdr.offset as usize);
478 if !hdr.use_huffman {
479 let bc2 = BoolCoder::new(&src[off..])?;
480 cr = CoeffReader::Bool(bc2);
481 } else {
482 let br = BitReader::new(&src[off..], aoffset - off, BitReaderMode::BE);
483 cr = CoeffReader::Huff(br);
484 }
485 } else {
486 cr = CoeffReader::None;
487 }
488
489 if hdr.is_intra {
490 br.reset_models(&mut self.models);
491 self.reset_mbtype_models();
492 } else {
493 self.decode_mode_prob_models(&mut bc)?;
494 br.decode_mv_models(&mut bc, &mut self.models.mv_models)?;
495 }
496 br.decode_coeff_models(&mut bc, &mut self.models, hdr.is_intra)?;
497 if hdr.use_huffman {
498 for i in 0..2 {
499 self.models.vp6huff.dc_token_tree[i].build_codes(&self.models.coeff_models[i].dc_value_probs);
500 }
501 for i in 0..2 {
502 for mode in 0..3 {
503 for band in 0..6 {
504 self.models.vp6huff.ac_token_tree[i][mode][band].build_codes(&self.models.coeff_models[i].ac_val_probs[mode][band]);
505 }
506 }
507 }
508 for i in 0..2 {
509 self.models.vp6huff.zero_run_tree[i].build_codes_zero_run(&self.models.vp6models.zero_run_probs[i]);
510 }
511 }
512
513 if hdr.interlaced {
514 self.ilace_prob = bc.read_bits(8) as u8;
515 }
516
517 self.fstate = FrameState::new();
518 self.fstate.dc_quant = VP56_DC_QUANTS[hdr.quant as usize] * 4;
519 self.fstate.ac_quant = VP56_AC_QUANTS[hdr.quant as usize] * 4;
520 self.loop_thr = VP56_FILTER_LIMITS[hdr.quant as usize] as i16;
521
522 self.last_mbt = VPMBType::InterNoMV;
523 self.dc_y.reset();
524 self.dc_u.reset();
525 self.dc_v.reset();
526 self.dc_a.reset();
527 for vec in self.top_ctx.iter_mut() {
528 for el in vec.iter_mut() {
529 *el = 0;
530 }
531 }
532 self.last_dc = [[0; 4]; 3];
533 self.last_dc[0][1] = 0x80;
534 self.last_dc[0][2] = 0x80;
535
536 self.ilace_mb = false;
537 for mb_y in 0..self.mb_h {
538 self.fstate.mb_y = mb_y;
539 self.fstate.coeff_cat = [[0; 64]; 4];
540 self.fstate.last_idx = [24; 4];
541 for mb_x in 0..self.mb_w {
542 self.fstate.mb_x = mb_x;
543 self.decode_mb(&mut dframe, &mut bc, &mut cr, br, &hdr, false)?;
544 }
545 self.dc_y.update_row();
546 self.dc_u.update_row();
547 self.dc_v.update_row();
548 self.dc_a.update_row();
549 }
550
551 if self.has_alpha {
552 let asrc = &src[aoffset + 3..];
553 let mut bc = BoolCoder::new(asrc)?;
554 let ahdr = br.parse_header(&mut bc)?;
555 validate!(ahdr.mb_w == hdr.mb_w && ahdr.mb_h == hdr.mb_h);
556 }
557
558 if hdr.is_golden {
559 self.shuf.add_golden_frame(buf.clone());
560 }
561 self.shuf.add_frame(buf.clone());
562
563 Ok((NABufferType::Video(buf), if hdr.is_intra { FrameType::I } else { FrameType::P }))
564 }
565 fn reset_mbtype_models(&mut self) {
566 const DEFAULT_XMITTED_PROBS: [[u8; 20]; 3] = [
567 [ 42, 69, 2, 1, 7, 1, 42, 44, 22, 6, 3, 1, 2, 0, 5, 1, 1, 0, 0, 0 ],
568 [ 8, 229, 1, 1, 8, 0, 0, 0, 0, 0, 2, 1, 1, 0, 0, 0, 1, 1, 0, 0 ],
569 [ 35, 122, 1, 1, 6, 1, 34, 46, 0, 0, 2, 1, 1, 0, 1, 0, 1, 1, 0, 0 ]
570 ];
571 self.models.prob_xmitted.copy_from_slice(&DEFAULT_XMITTED_PROBS);
572 }
573 fn decode_mode_prob_models(&mut self, bc: &mut BoolCoder) -> DecoderResult<()> {
574 for ctx in 0..3 {
575 if bc.read_prob(174) {
576 let idx = bc.read_bits(4) as usize;
577 for i in 0..20 {
578 self.models.prob_xmitted[ctx][i ^ 1] = VP56_MODE_VQ[ctx][idx][i];
579 }
580 }
581 if bc.read_prob(254) {
582 for set in 0..20 {
583 if bc.read_prob(205) {
584 let sign = bc.read_bool();
585 let diff = vp_tree!(bc, 171,
586 vp_tree!(bc, 83, 2, 1),
587 vp_tree!(bc, 199,
588 vp_tree!(bc, 140,
589 vp_tree!(bc, 125,
590 vp_tree!(bc, 104, 6, 5),
591 4
592 ),
593 3
594 ),
595 bc.read_bits(7)
596 )) * 4;
597 validate!(diff < 256);
598 let diff = diff as u8;
599 if !sign {
600 validate!(self.models.prob_xmitted[ctx][set ^ 1] <= 255 - diff);
601 self.models.prob_xmitted[ctx][set ^ 1] += diff;
602 } else {
603 validate!(self.models.prob_xmitted[ctx][set ^ 1] >= diff);
604 self.models.prob_xmitted[ctx][set ^ 1] -= diff;
605 }
606 }
607 }
608 }
609 }
610 for ctx in 0..3 {
611 let prob_xmitted = &self.models.prob_xmitted[ctx];
612 for mode in 0..10 {
613 let mdl = &mut self.models.mbtype_models[ctx][mode];
614 let mut cnt = [0u32; 10];
615 let mut total = 0;
616 for i in 0..10 {
617 if i == mode { continue; }
618 cnt[i] = 100 * (prob_xmitted[i * 2] as u32);
619 total += cnt[i];
620 }
621 let sum = (prob_xmitted[mode * 2] as u32) + (prob_xmitted[mode * 2 + 1] as u32);
622 mdl.probs[9] = 255 - rescale_mb_mode_prob(prob_xmitted[mode * 2 + 1] as u32, sum);
623
624 let inter_mv0_weight = (cnt[0] as u32) + (cnt[2] as u32);
625 let inter_mv1_weight = (cnt[3] as u32) + (cnt[4] as u32);
626 let gold_mv0_weight = (cnt[5] as u32) + (cnt[6] as u32);
627 let gold_mv1_weight = (cnt[8] as u32) + (cnt[9] as u32);
628 let mix_weight = (cnt[1] as u32) + (cnt[7] as u32);
629 mdl.probs[0] = 1 + rescale_mb_mode_prob(inter_mv0_weight + inter_mv1_weight, total);
630 mdl.probs[1] = 1 + rescale_mb_mode_prob(inter_mv0_weight, inter_mv0_weight + inter_mv1_weight);
631 mdl.probs[2] = 1 + rescale_mb_mode_prob(mix_weight, mix_weight + gold_mv0_weight + gold_mv1_weight);
632 mdl.probs[3] = 1 + rescale_mb_mode_prob(cnt[0] as u32, inter_mv0_weight);
633 mdl.probs[4] = 1 + rescale_mb_mode_prob(cnt[3] as u32, inter_mv1_weight);
634 mdl.probs[5] = 1 + rescale_mb_mode_prob(cnt[1], mix_weight);
635 mdl.probs[6] = 1 + rescale_mb_mode_prob(gold_mv0_weight, gold_mv0_weight + gold_mv1_weight);
636 mdl.probs[7] = 1 + rescale_mb_mode_prob(cnt[5], gold_mv0_weight);
637 mdl.probs[8] = 1 + rescale_mb_mode_prob(cnt[8], gold_mv1_weight);
638 }
639 }
640 Ok(())
641 }
642 fn find_mv_pred(&self, ref_id: u8) -> (usize, MV, MV, MV) {
643 const CAND_POS: [(i8, i8); 12] = [
644 (-1, 0), ( 0, -1),
645 (-1, -1), (-1, 1),
646 (-2, 0), ( 0, -2),
647 (-1, -2), (-2, -1),
648 (-2, 1), (-1, 2),
649 (-2, -2), (-2, 2)
650 ];
651
652 let mut nearest_mv = ZERO_MV;
653 let mut near_mv = ZERO_MV;
654 let mut pred_mv = ZERO_MV;
655 let mut num_mv: usize = 0;
656
657 for (i, (yoff, xoff)) in CAND_POS.iter().enumerate() {
658 let cx = (self.fstate.mb_x as isize) + (*xoff as isize);
659 let cy = (self.fstate.mb_y as isize) + (*yoff as isize);
660 if (cx < 0) || (cy < 0) {
661 continue;
662 }
663 let cx = cx as usize;
664 let cy = cy as usize;
665 if (cx >= self.mb_w) || (cy >= self.mb_h) {
666 continue;
667 }
668 let mb_pos = cx + cy * self.mb_w;
669 let mv = self.mb_info[mb_pos].mv;
670 if (self.mb_info[mb_pos].mb_type.get_ref_id() != ref_id) || (mv == ZERO_MV) {
671 continue;
672 }
673 if num_mv == 0 {
674 nearest_mv = mv;
675 num_mv += 1;
676 if (self.version > 5) && (i < 2) {
677 pred_mv = mv;
678 }
679 } else if mv != nearest_mv {
680 near_mv = mv;
681 num_mv += 1;
682 break;
683 }
684 }
685
686 (num_mv, nearest_mv, near_mv, pred_mv)
687 }
688 fn decode_mv(&self, bc: &mut BoolCoder, br: &mut dyn VP56Parser) -> MV {
689 let x = br.decode_mv(bc, &self.models.mv_models[0]);
690 let y = br.decode_mv(bc, &self.models.mv_models[1]);
691 MV{ x, y }
692 }
693 fn decode_mb_type(&mut self, bc: &mut BoolCoder, ctx: usize) -> DecoderResult<VPMBType> {
694 let probs = &self.models.mbtype_models[ctx][map_mb_type(self.last_mbt)].probs;
695 if !bc.read_prob(probs[9]) {
696 self.last_mbt = vp_tree!(
697 bc, probs[0],
698 vp_tree!(bc, probs[1],
699 vp_tree!(bc, probs[3], VPMBType::InterNoMV, VPMBType::InterMV),
700 vp_tree!(bc, probs[4], VPMBType::InterNearest, VPMBType::InterNear)
701 ),
702 vp_tree!(bc, probs[2],
703 vp_tree!(bc, probs[5], VPMBType::Intra, VPMBType::InterFourMV),
704 vp_tree!(bc, probs[6],
705 vp_tree!(bc, probs[7], VPMBType::GoldenNoMV, VPMBType::GoldenMV),
706 vp_tree!(bc, probs[8], VPMBType::InterNearest, VPMBType::InterNear)
707 )
708 )
709 );
710 }
711 Ok(self.last_mbt)
712 }
713 fn decode_mb(&mut self, frm: &mut NASimpleVideoFrame<u8>, bc: &mut BoolCoder, cr: &mut CoeffReader, br: &mut dyn VP56Parser, hdr: &VP56Header, alpha: bool) -> DecoderResult<()> {
714 const FOURMV_SUB_TYPE: [VPMBType; 4] = [ VPMBType::InterNoMV, VPMBType::InterMV, VPMBType::InterNearest, VPMBType::InterNear ];
715
716 let mb_x = self.fstate.mb_x;
717 let mb_y = self.fstate.mb_y;
718 self.coeffs = [[0; 64]; 6];
719 let mb_pos = mb_x + mb_y * self.mb_w;
720 let mut four_mv = [ZERO_MV; 4];
721 let mut four_mbt = [VPMBType::Intra; 4];
722
723 if hdr.interlaced {
724 let iprob = self.ilace_prob;
725 let prob = if mb_x == 0 {
726 iprob
727 } else if !self.ilace_mb {
728 iprob + (((256 - (iprob as u16)) >> 1) as u8)
729 } else {
730 iprob - (iprob >> 1)
731 };
732 self.ilace_mb = bc.read_prob(prob);
733 }
734
735 let (num_mv, nearest_mv, near_mv, pred_mv) = if hdr.is_intra {
736 (0, ZERO_MV, ZERO_MV, ZERO_MV)
737 } else { self.find_mv_pred(VP_REF_INTER) };
738 let mb_type = if hdr.is_intra {
739 VPMBType::Intra
740 } else {
741 self.decode_mb_type(bc, (num_mv + 1) % 3)?
742 };
743 self.mb_info[mb_pos].mb_type = mb_type;
744 if mb_type.get_ref_id() != VP_REF_GOLDEN {
745 match mb_type {
746 VPMBType::Intra |
747 VPMBType::InterNoMV => {
748 self.mb_info[mb_pos].mv = ZERO_MV;
749 },
750 VPMBType::InterMV => {
751 let diff_mv = self.decode_mv(bc, br);
752 self.mb_info[mb_pos].mv = pred_mv + diff_mv;
753 },
754 VPMBType::InterNearest => {
755 self.mb_info[mb_pos].mv = nearest_mv;
756 },
757 VPMBType::InterNear => {
758 self.mb_info[mb_pos].mv = near_mv;
759 },
760 VPMBType::InterFourMV => {
761 for i in 0..4 {
762 four_mbt[i] = FOURMV_SUB_TYPE[bc.read_bits(2) as usize];
763 }
764 for i in 0..4 {
765 match four_mbt[i] {
766 VPMBType::InterNoMV => {},
767 VPMBType::InterMV => {
768 let diff_mv = self.decode_mv(bc, br);
769 four_mv[i] = pred_mv + diff_mv;
770 },
771 VPMBType::InterNearest => {
772 four_mv[i] = nearest_mv;
773 },
774 VPMBType::InterNear => {
775 four_mv[i] = near_mv;
776 },
777 _ => unreachable!(),
778 };
779 }
780 self.mb_info[mb_pos].mv = four_mv[3];
781 },
782 _ => unreachable!(),
783 };
784 } else {
785 let (_num_mv, nearest_mv, near_mv, pred_mv) = self.find_mv_pred(VP_REF_GOLDEN);
786 match mb_type {
787 VPMBType::GoldenNoMV => {
788 self.mb_info[mb_pos].mv = ZERO_MV;
789 },
790 VPMBType::GoldenMV => {
791 let diff_mv = self.decode_mv(bc, br);
792 self.mb_info[mb_pos].mv = pred_mv + diff_mv;
793 },
794 VPMBType::GoldenNearest => {
795 self.mb_info[mb_pos].mv = nearest_mv;
796 },
797 VPMBType::GoldenNear => {
798 self.mb_info[mb_pos].mv = near_mv;
799 },
800 _ => unreachable!(),
801 };
802 }
803 if !mb_type.is_intra() && (mb_type != VPMBType::InterFourMV) {
804 self.do_mc(br, frm, mb_type, self.mb_info[mb_pos].mv, alpha);
805 } else if mb_type == VPMBType::InterFourMV {
806 self.do_fourmv(br, frm, &four_mv, alpha);
807 }
808
809 for blk_no in 0..4 {
810 self.fstate.plane = if !alpha { 0 } else { 3 };
811 self.fstate.ctx_idx = blk_no >> 1;
812 self.fstate.top_ctx = self.top_ctx[self.fstate.plane][mb_x * 2 + (blk_no & 1)];
813 match cr {
814 CoeffReader::None => {
815 br.decode_block(bc, &mut self.coeffs[blk_no], &self.models.coeff_models[0], &self.models.vp6models, &mut self.fstate)?;
816 },
817 CoeffReader::Bool(ref mut bcc) => {
818 br.decode_block(bcc, &mut self.coeffs[blk_no], &self.models.coeff_models[0], &self.models.vp6models, &mut self.fstate)?;
819 },
820 CoeffReader::Huff(ref mut brc) => {
821 br.decode_block_huff(brc, &mut self.coeffs[blk_no], &self.models.vp6models, &self.models.vp6huff, &mut self.fstate)?;
822 },
823 };
824 self.top_ctx[self.fstate.plane][mb_x * 2 + (blk_no & 1)] = self.fstate.top_ctx;
825 self.predict_dc(mb_type, mb_pos, blk_no, alpha);
826
827 let bx = mb_x * 2 + (blk_no & 1);
828 let by = mb_y * 2 + (blk_no >> 1);
829 let has_ac = self.fstate.last_idx[self.fstate.ctx_idx] > 0;
830 if mb_type.is_intra() {
831 if !self.ilace_mb {
832 if has_ac {
833 vp_put_block(&mut self.coeffs[blk_no], bx, by, self.fstate.plane, frm);
834 } else {
835 vp_put_block_dc(&mut self.coeffs[blk_no], bx, by, self.fstate.plane, frm);
836 }
837 } else {
838 vp_put_block_ilace(&mut self.coeffs[blk_no], bx, by, self.fstate.plane, frm);
839 }
840 } else {
841 if !self.ilace_mb {
842 if has_ac {
843 vp_add_block(&mut self.coeffs[blk_no], bx, by, self.fstate.plane, frm);
844 } else {
845 vp_add_block_dc(&mut self.coeffs[blk_no], bx, by, self.fstate.plane, frm);
846 }
847 } else {
848 vp_add_block_ilace(&mut self.coeffs[blk_no], bx, by, self.fstate.plane, frm);
849 }
850 }
851 }
852 if !alpha {
853 for blk_no in 4..6 {
854 self.fstate.plane = blk_no - 3;
855 self.fstate.ctx_idx = blk_no - 2;
856 self.fstate.top_ctx = self.top_ctx[self.fstate.plane][mb_x];
857 match cr {
858 CoeffReader::None => {
859 br.decode_block(bc, &mut self.coeffs[blk_no], &self.models.coeff_models[1], &self.models.vp6models, &mut self.fstate)?;
860 },
861 CoeffReader::Bool(ref mut bcc) => {
862 br.decode_block(bcc, &mut self.coeffs[blk_no], &self.models.coeff_models[1], &self.models.vp6models, &mut self.fstate)?;
863 },
864 CoeffReader::Huff(ref mut brc) => {
865 br.decode_block_huff(brc, &mut self.coeffs[blk_no], &self.models.vp6models, &self.models.vp6huff, &mut self.fstate)?;
866 },
867 };
868 self.top_ctx[self.fstate.plane][mb_x] = self.fstate.top_ctx;
869 self.predict_dc(mb_type, mb_pos, blk_no, alpha);
870
871 let has_ac = self.fstate.last_idx[self.fstate.ctx_idx] > 0;
872 if mb_type.is_intra() {
873 if has_ac {
874 vp_put_block(&mut self.coeffs[blk_no], mb_x, mb_y, self.fstate.plane, frm);
875 } else {
876 vp_put_block_dc(&mut self.coeffs[blk_no], mb_x, mb_y, self.fstate.plane, frm);
877 }
878 } else {
879 if has_ac {
880 vp_add_block(&mut self.coeffs[blk_no], mb_x, mb_y, self.fstate.plane, frm);
881 } else {
882 vp_add_block_dc(&mut self.coeffs[blk_no], mb_x, mb_y, self.fstate.plane, frm);
883 }
884 }
885 }
886 }
887 Ok(())
888 }
889 fn do_mc(&mut self, br: &dyn VP56Parser, frm: &mut NASimpleVideoFrame<u8>, mb_type: VPMBType, mv: MV, alpha: bool) {
890 let x = self.fstate.mb_x * 16;
891 let y = self.fstate.mb_y * 16;
892 let plane = if !alpha { 0 } else { 3 };
893 let src = if mb_type.get_ref_id() == VP_REF_INTER {
894 self.shuf.get_last().unwrap()
895 } else {
896 self.shuf.get_golden().unwrap()
897 };
898
899 br.mc_block(frm, self.mc_buf.clone(), src.clone(), plane, x + 0, y + 0, mv, self.loop_thr);
900 br.mc_block(frm, self.mc_buf.clone(), src.clone(), plane, x + 8, y + 0, mv, self.loop_thr);
901 br.mc_block(frm, self.mc_buf.clone(), src.clone(), plane, x + 0, y + 8, mv, self.loop_thr);
902 br.mc_block(frm, self.mc_buf.clone(), src.clone(), plane, x + 8, y + 8, mv, self.loop_thr);
903 if !alpha {
904 let x = self.fstate.mb_x * 8;
905 let y = self.fstate.mb_y * 8;
906 br.mc_block(frm, self.mc_buf.clone(), src.clone(), 1, x, y, mv, self.loop_thr);
907 br.mc_block(frm, self.mc_buf.clone(), src.clone(), 2, x, y, mv, self.loop_thr);
908 }
909 }
910 fn do_fourmv(&mut self, br: &dyn VP56Parser, frm: &mut NASimpleVideoFrame<u8>, mvs: &[MV; 4], alpha: bool) {
911 let x = self.fstate.mb_x * 16;
912 let y = self.fstate.mb_y * 16;
913 let plane = if !alpha { 0 } else { 3 };
914 let src = self.shuf.get_last().unwrap();
915 for blk_no in 0..4 {
916 br.mc_block(frm, self.mc_buf.clone(), src.clone(),
917 plane, x + (blk_no & 1) * 8, y + (blk_no & 2) * 4,
918 mvs[blk_no], self.loop_thr);
919 }
920 if !alpha {
921 let x = self.fstate.mb_x * 8;
922 let y = self.fstate.mb_y * 8;
923 let sum = mvs[0] + mvs[1] + mvs[2] + mvs[3];
924 let mv = MV { x: sum.x / 4, y: sum.y / 4 };
925 br.mc_block(frm, self.mc_buf.clone(), src.clone(), 1, x, y, mv, self.loop_thr);
926 br.mc_block(frm, self.mc_buf.clone(), src.clone(), 2, x, y, mv, self.loop_thr);
927 }
928 }
929 fn predict_dc(&mut self, mb_type: VPMBType, mb_pos: usize, blk_no: usize, alpha: bool) {
930 let mb_x = self.fstate.mb_x;
931 let is_luma = blk_no < 4;
932 let (plane, dcs) = if alpha { (0, &mut self.dc_a) } else {
933 match blk_no {
934 4 => (1, &mut self.dc_u),
935 5 => (2, &mut self.dc_v),
936 _ => (0, &mut self.dc_y),
937 }
938 };
939 let dc_pos = if is_luma {
940 dcs.xpos + mb_x * 2 + (blk_no & 1) + (blk_no >> 1) * dcs.stride
941 } else {
942 dcs.xpos + mb_x
943 };
944 let ref_id = mb_type.get_ref_id();
945 let has_left_blk = is_luma && ((blk_no & 1) != 0);
946 let has_top_blk = is_luma && ((blk_no & 2) != 0);
947 let mut dc_pred = 0;
948 let mut count = 0;
949 if has_left_blk || ((mb_x > 0) && (self.mb_info[mb_pos - 1].mb_type.get_ref_id() == ref_id)) {
950 dc_pred += dcs.data[dc_pos - 1];
951 count += 1;
952 }
953 if has_top_blk || ((mb_pos >= self.mb_w) && (self.mb_info[mb_pos - self.mb_w].mb_type.get_ref_id() == ref_id)) {
954 dc_pred += dcs.data[dc_pos - dcs.stride];
955 count += 1;
956 }
957 if self.version == 5 {
958 if (count < 2) && has_left_blk {
959 dc_pred += dc_pred;
960 count += 1;
961 }
962 if (count < 2) && !has_left_blk && has_top_blk && (mb_x > 0) && (self.mb_info[mb_pos - 1].mb_type.get_ref_id() == ref_id) {
963 dc_pred += dc_pred;
964 count += 1;
965 }
966 if (count < 2) && mb_pos == 0 && !is_luma {
967 count += 1;
968 }
969 if (count < 2) && !has_left_blk && !has_top_blk && is_luma && (mb_x > 0) && (self.mb_info[mb_pos - 1].mb_type.get_ref_id() == ref_id) {
970 dc_pred += dcs.data[dc_pos + dcs.stride - 1];
971 count += 1;
972 }
973 if (count < 2) && blk_no == 2 {
974 dc_pred += dcs.data[dc_pos - dcs.stride + 1];
975 count += 1;
976 }
977 if (count < 2) && !has_left_blk && (mb_pos >= self.mb_w) && (self.mb_info[mb_pos - self.mb_w].mb_type.get_ref_id() == ref_id) {
978 dc_pred += dcs.data[dc_pos - dcs.stride + 1];
979 count += 1;
980 }
981 if (count < 2) && has_left_blk && (mb_pos > self.mb_w) && (mb_x < self.mb_w - 1) && (self.mb_info[mb_pos - self.mb_w + 1].mb_type.get_ref_id() == ref_id) {
982 dc_pred += dcs.data[dc_pos - dcs.stride + 1];
983 count += 1;
984 }
985 }
986 if count == 0 {
987 dc_pred = self.last_dc[ref_id as usize][plane];
988 } else if count == 2 {
989 dc_pred /= 2;
990 }
991 self.coeffs[blk_no][0] += dc_pred;
992 self.last_dc[ref_id as usize][plane] = self.coeffs[blk_no][0];
993 dcs.data[dc_pos] = self.coeffs[blk_no][0];
994 self.coeffs[blk_no][0] = self.coeffs[blk_no][0].wrapping_mul(self.fstate.dc_quant);
995 }
996 }
997
998 const VP56_DC_QUANTS: [i16; 64] = [
999 47, 47, 47, 47, 45, 43, 43, 43,
1000 43, 43, 42, 41, 41, 40, 40, 40,
1001 40, 35, 35, 35, 35, 33, 33, 33,
1002 33, 32, 32, 32, 27, 27, 26, 26,
1003 25, 25, 24, 24, 23, 23, 19, 19,
1004 19, 19, 18, 18, 17, 16, 16, 16,
1005 16, 16, 15, 11, 11, 11, 10, 10,
1006 9, 8, 7, 5, 3, 3, 2, 2
1007 ];
1008 const VP56_AC_QUANTS: [i16; 64] = [
1009 94, 92, 90, 88, 86, 82, 78, 74,
1010 70, 66, 62, 58, 54, 53, 52, 51,
1011 50, 49, 48, 47, 46, 45, 44, 43,
1012 42, 40, 39, 37, 36, 35, 34, 33,
1013 32, 31, 30, 29, 28, 27, 26, 25,
1014 24, 23, 22, 21, 20, 19, 18, 17,
1015 16, 15, 14, 13, 12, 11, 10, 9,
1016 8, 7, 6, 5, 4, 3, 2, 1
1017 ];
1018
1019 const VP56_FILTER_LIMITS: [u8; 64] = [
1020 14, 14, 13, 13, 12, 12, 10, 10,
1021 10, 10, 8, 8, 8, 8, 8, 8,
1022 8, 8, 8, 8, 8, 8, 8, 8,
1023 8, 8, 8, 8, 8, 8, 8, 8,
1024 8, 8, 8, 8, 7, 7, 7, 7,
1025 7, 7, 6, 6, 6, 6, 6, 6,
1026 5, 5, 5, 5, 4, 4, 4, 4,
1027 4, 4, 4, 3, 3, 3, 3, 2
1028 ];
1029
1030 const VP56_MODE_VQ: [[[u8; 20]; 16]; 3] = [
1031 [
1032 [ 9, 15, 32, 25, 7, 19, 9, 21, 1, 12, 14, 12, 3, 18, 14, 23, 3, 10, 0, 4 ],
1033 [ 48, 39, 1, 2, 11, 27, 29, 44, 7, 27, 1, 4, 0, 3, 1, 6, 1, 2, 0, 0 ],
1034 [ 21, 32, 1, 2, 4, 10, 32, 43, 6, 23, 2, 3, 1, 19, 1, 6, 12, 21, 0, 7 ],
1035 [ 69, 83, 0, 0, 0, 2, 10, 29, 3, 12, 0, 1, 0, 3, 0, 3, 2, 2, 0, 0 ],
1036 [ 11, 20, 1, 4, 18, 36, 43, 48, 13, 35, 0, 2, 0, 5, 3, 12, 1, 2, 0, 0 ],
1037 [ 70, 44, 0, 1, 2, 10, 37, 46, 8, 26, 0, 2, 0, 2, 0, 2, 0, 1, 0, 0 ],
1038 [ 8, 15, 0, 1, 8, 21, 74, 53, 22, 42, 0, 1, 0, 2, 0, 3, 1, 2, 0, 0 ],
1039 [ 141, 42, 0, 0, 1, 4, 11, 24, 1, 11, 0, 1, 0, 1, 0, 2, 0, 0, 0, 0 ],
1040 [ 8, 19, 4, 10, 24, 45, 21, 37, 9, 29, 0, 3, 1, 7, 11, 25, 0, 2, 0, 1 ],
1041 [ 46, 42, 0, 1, 2, 10, 54, 51, 10, 30, 0, 2, 0, 2, 0, 1, 0, 1, 0, 0 ],
1042 [ 28, 32, 0, 0, 3, 10, 75, 51, 14, 33, 0, 1, 0, 2, 0, 1, 1, 2, 0, 0 ],
1043 [ 100, 46, 0, 1, 3, 9, 21, 37, 5, 20, 0, 1, 0, 2, 1, 2, 0, 1, 0, 0 ],
1044 [ 27, 29, 0, 1, 9, 25, 53, 51, 12, 34, 0, 1, 0, 3, 1, 5, 0, 2, 0, 0 ],
1045 [ 80, 38, 0, 0, 1, 4, 69, 33, 5, 16, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0 ],
1046 [ 16, 20, 0, 0, 2, 8, 104, 49, 15, 33, 0, 1, 0, 1, 0, 1, 1, 1, 0, 0 ],
1047 [ 194, 16, 0, 0, 1, 1, 1, 9, 1, 3, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0 ],
1048 ], [
1049 [ 41, 22, 1, 0, 1, 31, 0, 0, 0, 0, 0, 1, 1, 7, 0, 1, 98, 25, 4, 10 ],
1050 [ 123, 37, 6, 4, 1, 27, 0, 0, 0, 0, 5, 8, 1, 7, 0, 1, 12, 10, 0, 2 ],
1051 [ 26, 14, 14, 12, 0, 24, 0, 0, 0, 0, 55, 17, 1, 9, 0, 36, 5, 7, 1, 3 ],
1052 [ 209, 5, 0, 0, 0, 27, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0 ],
1053 [ 2, 5, 4, 5, 0, 121, 0, 0, 0, 0, 0, 3, 2, 4, 1, 4, 2, 2, 0, 1 ],
1054 [ 175, 5, 0, 1, 0, 48, 0, 0, 0, 0, 0, 2, 0, 1, 0, 2, 0, 1, 0, 0 ],
1055 [ 83, 5, 2, 3, 0, 102, 0, 0, 0, 0, 1, 3, 0, 2, 0, 1, 0, 0, 0, 0 ],
1056 [ 233, 6, 0, 0, 0, 8, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0 ],
1057 [ 34, 16, 112, 21, 1, 28, 0, 0, 0, 0, 6, 8, 1, 7, 0, 3, 2, 5, 0, 2 ],
1058 [ 159, 35, 2, 2, 0, 25, 0, 0, 0, 0, 3, 6, 0, 5, 0, 1, 4, 4, 0, 1 ],
1059 [ 75, 39, 5, 7, 2, 48, 0, 0, 0, 0, 3, 11, 2, 16, 1, 4, 7, 10, 0, 2 ],
1060 [ 212, 21, 0, 1, 0, 9, 0, 0, 0, 0, 1, 2, 0, 2, 0, 0, 2, 2, 0, 0 ],
1061 [ 4, 2, 0, 0, 0, 172, 0, 0, 0, 0, 0, 1, 0, 2, 0, 0, 2, 0, 0, 0 ],
1062 [ 187, 22, 1, 1, 0, 17, 0, 0, 0, 0, 3, 6, 0, 4, 0, 1, 4, 4, 0, 1 ],
1063 [ 133, 6, 1, 2, 1, 70, 0, 0, 0, 0, 0, 2, 0, 4, 0, 3, 1, 1, 0, 0 ],
1064 [ 251, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ],
1065 ], [
1066 [ 2, 3, 2, 3, 0, 2, 0, 2, 0, 0, 11, 4, 1, 4, 0, 2, 3, 2, 0, 4 ],
1067 [ 49, 46, 3, 4, 7, 31, 42, 41, 0, 0, 2, 6, 1, 7, 1, 4, 2, 4, 0, 1 ],
1068 [ 26, 25, 1, 1, 2, 10, 67, 39, 0, 0, 1, 1, 0, 14, 0, 2, 31, 26, 1, 6 ],
1069 [ 103, 46, 1, 2, 2, 10, 33, 42, 0, 0, 1, 4, 0, 3, 0, 1, 1, 3, 0, 0 ],
1070 [ 14, 31, 9, 13, 14, 54, 22, 29, 0, 0, 2, 6, 4, 18, 6, 13, 1, 5, 0, 1 ],
1071 [ 85, 39, 0, 0, 1, 9, 69, 40, 0, 0, 0, 1, 0, 3, 0, 1, 2, 3, 0, 0 ],
1072 [ 31, 28, 0, 0, 3, 14, 130, 34, 0, 0, 0, 1, 0, 3, 0, 1, 3, 3, 0, 1 ],
1073 [ 171, 25, 0, 0, 1, 5, 25, 21, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0 ],
1074 [ 17, 21, 68, 29, 6, 15, 13, 22, 0, 0, 6, 12, 3, 14, 4, 10, 1, 7, 0, 3 ],
1075 [ 51, 39, 0, 1, 2, 12, 91, 44, 0, 0, 0, 2, 0, 3, 0, 1, 2, 3, 0, 1 ],
1076 [ 81, 25, 0, 0, 2, 9, 106, 26, 0, 0, 0, 1, 0, 1, 0, 1, 1, 1, 0, 0 ],
1077 [ 140, 37, 0, 1, 1, 8, 24, 33, 0, 0, 1, 2, 0, 2, 0, 1, 1, 2, 0, 0 ],
1078 [ 14, 23, 1, 3, 11, 53, 90, 31, 0, 0, 0, 3, 1, 5, 2, 6, 1, 2, 0, 0 ],
1079 [ 123, 29, 0, 0, 1, 7, 57, 30, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0 ],
1080 [ 13, 14, 0, 0, 4, 20, 175, 20, 0, 0, 0, 1, 0, 1, 0, 1, 1, 1, 0, 0 ],
1081 [ 202, 23, 0, 0, 1, 3, 2, 9, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0 ],
1082 ]
1083 ];
1084