duck/avc: improve decoder a bit
[nihav.git] / nihav-duck / src / codecs / vp56.rs
CommitLineData
3584b223 1use nihav_core::codecs::*;
1fdbd53e 2use nihav_core::data::GenericCache;
3584b223
KS
3use nihav_core::io::bitreader::*;
4use super::vpcommon::*;
5
6pub const TOKEN_LARGE: u8 = 5;
7pub const TOKEN_EOB: u8 = 42;
8
9#[derive(Clone,Copy,Debug,Default)]
10#[allow(dead_code)]
11pub 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)]
29pub 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)]
37pub struct VP56MBTypeModel {
38 pub probs: [u8; 10],
39}
40
41#[derive(Clone,Copy,Default)]
42pub 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
50pub 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
57const MAX_HUFF_ELEMS: usize = 12;
58#[derive(Clone,Copy,Default)]
59pub struct VP6Huff {
60 pub codes: [u16; MAX_HUFF_ELEMS],
61 pub bits: [u8; MAX_HUFF_ELEMS],
62}
63
64#[derive(Clone,Copy,Default)]
65struct Node {
66 weight: u16,
67 sym: i8,
68 ch0: usize,
69 ch1: usize,
70}
71
72fn 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
81impl 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
187pub trait ReadHuff {
188 fn read_huff(&mut self, huff: &VP6Huff) -> DecoderResult<u8>;
189}
190
191impl<'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)]
205pub 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
211impl 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
222pub 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
231impl 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
244pub 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
255enum CoeffReader<'a> {
256 None,
257 Bool(BoolCoder<'a>),
258 Huff(BitReader<'a>),
259}
260
261#[derive(Clone,Copy,Default)]
262struct MBInfo {
263 mb_type: VPMBType,
264 mv: MV,
265}
266
267pub 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
281impl 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
3584b223
KS
299pub 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
328fn rescale_mb_mode_prob(prob: u32, total: u32) -> u8 {
329 (255 * prob / (1 + total)) as u8
330}
331
332fn 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
3584b223 347pub fn expand_token_bc(bc: &mut BoolCoder, val_probs: &[u8; 11], token: u8, version: u8) -> i16 {
3584b223
KS
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;
3f67638d 365 let add_probs = &VP56_COEF_ADD_PROBS[cat];
3584b223
KS
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
382impl 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 decode_frame(&mut self, supp: &mut NADecoderSupport, src: &[u8], br: &mut dyn VP56Parser) -> DecoderResult<(NABufferType, FrameType)> {
432 let aoffset;
433 let mut bc;
434 if self.has_alpha {
435 validate!(src.len() >= 7);
436 aoffset = ((src[0] as usize) << 16) | ((src[1] as usize) << 8) | (src[2] as usize);
437 validate!((aoffset > 0) && (aoffset < src.len() - 3));
438 bc = BoolCoder::new(&src[3..])?;
439 } else {
440 validate!(src.len() >= 4);
441 aoffset = src.len();
442 bc = BoolCoder::new(src)?;
443 }
444 let hdr = br.parse_header(&mut bc)?;
445 validate!((hdr.offset as usize) < aoffset); //XXX: take alpha 3 byte offset into account?
446
447 if hdr.mb_w != 0 {
448 self.set_dimensions((hdr.mb_w as usize) * 16, (hdr.mb_h as usize) * 16);
449 }
450 let vinfo = NAVideoInfo::new(self.width, self.height, self.flip, YUV420_FORMAT);
451 let ret = supp.pool_u8.get_free();
452 if ret.is_none() {
453 return Err(DecoderError::AllocError);
454 }
455 let mut buf = ret.unwrap();
456 if buf.get_info() != vinfo {
457 self.shuf.clear();
458 supp.pool_u8.reset();
459 supp.pool_u8.prealloc_video(vinfo, 4)?;
460 let ret = supp.pool_u8.get_free();
461 if ret.is_none() {
462 return Err(DecoderError::AllocError);
463 }
464 buf = ret.unwrap();
465 }
466 let mut dframe = NASimpleVideoFrame::from_video_buf(&mut buf).unwrap();
467
468 if hdr.is_intra {
469 self.shuf.clear();
470 }
471
472 let mut cr;
473 if hdr.multistream {
474 let off = (if self.has_alpha { 3 } else { 0 }) + (hdr.offset as usize);
475 if !hdr.use_huffman {
476 let bc2 = BoolCoder::new(&src[off..])?;
477 cr = CoeffReader::Bool(bc2);
478 } else {
479 let br = BitReader::new(&src[off..], aoffset - off, BitReaderMode::BE);
480 cr = CoeffReader::Huff(br);
481 }
482 } else {
483 cr = CoeffReader::None;
484 }
485
486 if hdr.is_intra {
487 br.reset_models(&mut self.models);
488 self.reset_mbtype_models();
489 } else {
490 self.decode_mode_prob_models(&mut bc)?;
491 br.decode_mv_models(&mut bc, &mut self.models.mv_models)?;
492 }
493 br.decode_coeff_models(&mut bc, &mut self.models, hdr.is_intra)?;
494 if hdr.use_huffman {
495 for i in 0..2 {
496 self.models.vp6huff.dc_token_tree[i].build_codes(&self.models.coeff_models[i].dc_value_probs);
497 }
498 for i in 0..2 {
499 for mode in 0..3 {
500 for band in 0..6 {
501 self.models.vp6huff.ac_token_tree[i][mode][band].build_codes(&self.models.coeff_models[i].ac_val_probs[mode][band]);
502 }
503 }
504 }
505 for i in 0..2 {
506 self.models.vp6huff.zero_run_tree[i].build_codes_zero_run(&self.models.vp6models.zero_run_probs[i]);
507 }
508 }
509
510 if hdr.interlaced {
511 self.ilace_prob = bc.read_bits(8) as u8;
512 }
513
514 self.fstate = FrameState::new();
515 self.fstate.dc_quant = VP56_DC_QUANTS[hdr.quant as usize] * 4;
516 self.fstate.ac_quant = VP56_AC_QUANTS[hdr.quant as usize] * 4;
517 self.loop_thr = VP56_FILTER_LIMITS[hdr.quant as usize] as i16;
518
519 self.last_mbt = VPMBType::InterNoMV;
520 self.dc_y.reset();
521 self.dc_u.reset();
522 self.dc_v.reset();
523 self.dc_a.reset();
524 for vec in self.top_ctx.iter_mut() {
525 for el in vec.iter_mut() {
526 *el = 0;
527 }
528 }
529 self.last_dc = [[0; 4]; 3];
530 self.last_dc[0][1] = 0x80;
531 self.last_dc[0][2] = 0x80;
532
533 self.ilace_mb = false;
534 for mb_y in 0..self.mb_h {
535 self.fstate.mb_y = mb_y;
536 self.fstate.coeff_cat = [[0; 64]; 4];
537 self.fstate.last_idx = [24; 4];
538 for mb_x in 0..self.mb_w {
539 self.fstate.mb_x = mb_x;
540 self.decode_mb(&mut dframe, &mut bc, &mut cr, br, &hdr, false)?;
541 }
542 self.dc_y.update_row();
543 self.dc_u.update_row();
544 self.dc_v.update_row();
545 self.dc_a.update_row();
546 }
547
548 if self.has_alpha {
549 let asrc = &src[aoffset + 3..];
550 let mut bc = BoolCoder::new(asrc)?;
551 let ahdr = br.parse_header(&mut bc)?;
552 validate!(ahdr.mb_w == hdr.mb_w && ahdr.mb_h == hdr.mb_h);
553 }
554
555 if hdr.is_golden {
556 self.shuf.add_golden_frame(buf.clone());
557 }
558 self.shuf.add_frame(buf.clone());
559
560 Ok((NABufferType::Video(buf), if hdr.is_intra { FrameType::I } else { FrameType::P }))
561 }
562 fn reset_mbtype_models(&mut self) {
563 const DEFAULT_XMITTED_PROBS: [[u8; 20]; 3] = [
564 [ 42, 69, 2, 1, 7, 1, 42, 44, 22, 6, 3, 1, 2, 0, 5, 1, 1, 0, 0, 0 ],
565 [ 8, 229, 1, 1, 8, 0, 0, 0, 0, 0, 2, 1, 1, 0, 0, 0, 1, 1, 0, 0 ],
566 [ 35, 122, 1, 1, 6, 1, 34, 46, 0, 0, 2, 1, 1, 0, 1, 0, 1, 1, 0, 0 ]
567 ];
568 self.models.prob_xmitted.copy_from_slice(&DEFAULT_XMITTED_PROBS);
569 }
570 fn decode_mode_prob_models(&mut self, bc: &mut BoolCoder) -> DecoderResult<()> {
571 for ctx in 0..3 {
572 if bc.read_prob(174) {
573 let idx = bc.read_bits(4) as usize;
574 for i in 0..20 {
575 self.models.prob_xmitted[ctx][i ^ 1] = VP56_MODE_VQ[ctx][idx][i];
576 }
577 }
578 if bc.read_prob(254) {
579 for set in 0..20 {
580 if bc.read_prob(205) {
581 let sign = bc.read_bool();
582 let diff = vp_tree!(bc, 171,
583 vp_tree!(bc, 83, 2, 1),
584 vp_tree!(bc, 199,
585 vp_tree!(bc, 140,
586 vp_tree!(bc, 125,
587 vp_tree!(bc, 104, 6, 5),
588 4
589 ),
590 3
591 ),
592 bc.read_bits(7)
593 )) * 4;
594 validate!(diff < 256);
595 let diff = diff as u8;
596 if !sign {
597 validate!(self.models.prob_xmitted[ctx][set ^ 1] <= 255 - diff);
598 self.models.prob_xmitted[ctx][set ^ 1] += diff;
599 } else {
600 validate!(self.models.prob_xmitted[ctx][set ^ 1] >= diff);
601 self.models.prob_xmitted[ctx][set ^ 1] -= diff;
602 }
603 }
604 }
605 }
606 }
607 for ctx in 0..3 {
608 let prob_xmitted = &self.models.prob_xmitted[ctx];
609 for mode in 0..10 {
610 let mdl = &mut self.models.mbtype_models[ctx][mode];
611 let mut cnt = [0u32; 10];
612 let mut total = 0;
613 for i in 0..10 {
614 if i == mode { continue; }
615 cnt[i] = 100 * (prob_xmitted[i * 2] as u32);
616 total += cnt[i];
617 }
618 let sum = (prob_xmitted[mode * 2] as u32) + (prob_xmitted[mode * 2 + 1] as u32);
619 mdl.probs[9] = 255 - rescale_mb_mode_prob(prob_xmitted[mode * 2 + 1] as u32, sum);
620
621 let inter_mv0_weight = (cnt[0] as u32) + (cnt[2] as u32);
622 let inter_mv1_weight = (cnt[3] as u32) + (cnt[4] as u32);
623 let gold_mv0_weight = (cnt[5] as u32) + (cnt[6] as u32);
624 let gold_mv1_weight = (cnt[8] as u32) + (cnt[9] as u32);
625 let mix_weight = (cnt[1] as u32) + (cnt[7] as u32);
626 mdl.probs[0] = 1 + rescale_mb_mode_prob(inter_mv0_weight + inter_mv1_weight, total);
627 mdl.probs[1] = 1 + rescale_mb_mode_prob(inter_mv0_weight, inter_mv0_weight + inter_mv1_weight);
628 mdl.probs[2] = 1 + rescale_mb_mode_prob(mix_weight, mix_weight + gold_mv0_weight + gold_mv1_weight);
629 mdl.probs[3] = 1 + rescale_mb_mode_prob(cnt[0] as u32, inter_mv0_weight);
630 mdl.probs[4] = 1 + rescale_mb_mode_prob(cnt[3] as u32, inter_mv1_weight);
631 mdl.probs[5] = 1 + rescale_mb_mode_prob(cnt[1], mix_weight);
632 mdl.probs[6] = 1 + rescale_mb_mode_prob(gold_mv0_weight, gold_mv0_weight + gold_mv1_weight);
633 mdl.probs[7] = 1 + rescale_mb_mode_prob(cnt[5], gold_mv0_weight);
634 mdl.probs[8] = 1 + rescale_mb_mode_prob(cnt[8], gold_mv1_weight);
635 }
636 }
637 Ok(())
638 }
639 fn find_mv_pred(&self, ref_id: u8) -> (usize, MV, MV, MV) {
640 const CAND_POS: [(i8, i8); 12] = [
641 (-1, 0), ( 0, -1),
642 (-1, -1), (-1, 1),
643 (-2, 0), ( 0, -2),
644 (-1, -2), (-2, -1),
645 (-2, 1), (-1, 2),
646 (-2, -2), (-2, 2)
647 ];
648
649 let mut nearest_mv = ZERO_MV;
650 let mut near_mv = ZERO_MV;
651 let mut pred_mv = ZERO_MV;
652 let mut num_mv: usize = 0;
653
654 for (i, (yoff, xoff)) in CAND_POS.iter().enumerate() {
655 let cx = (self.fstate.mb_x as isize) + (*xoff as isize);
656 let cy = (self.fstate.mb_y as isize) + (*yoff as isize);
657 if (cx < 0) || (cy < 0) {
658 continue;
659 }
660 let cx = cx as usize;
661 let cy = cy as usize;
662 if (cx >= self.mb_w) || (cy >= self.mb_h) {
663 continue;
664 }
665 let mb_pos = cx + cy * self.mb_w;
666 let mv = self.mb_info[mb_pos].mv;
667 if (self.mb_info[mb_pos].mb_type.get_ref_id() != ref_id) || (mv == ZERO_MV) {
668 continue;
669 }
670 if num_mv == 0 {
671 nearest_mv = mv;
672 num_mv += 1;
673 if (self.version > 5) && (i < 2) {
674 pred_mv = mv;
675 }
676 } else if mv != nearest_mv {
677 near_mv = mv;
678 num_mv += 1;
679 break;
680 }
681 }
682
683 (num_mv, nearest_mv, near_mv, pred_mv)
684 }
685 fn decode_mv(&self, bc: &mut BoolCoder, br: &mut dyn VP56Parser) -> MV {
686 let x = br.decode_mv(bc, &self.models.mv_models[0]);
687 let y = br.decode_mv(bc, &self.models.mv_models[1]);
688 MV{ x, y }
689 }
690 fn decode_mb_type(&mut self, bc: &mut BoolCoder, ctx: usize) -> DecoderResult<VPMBType> {
691 let probs = &self.models.mbtype_models[ctx][map_mb_type(self.last_mbt)].probs;
692 if !bc.read_prob(probs[9]) {
693 self.last_mbt = vp_tree!(
694 bc, probs[0],
695 vp_tree!(bc, probs[1],
696 vp_tree!(bc, probs[3], VPMBType::InterNoMV, VPMBType::InterMV),
697 vp_tree!(bc, probs[4], VPMBType::InterNearest, VPMBType::InterNear)
698 ),
699 vp_tree!(bc, probs[2],
700 vp_tree!(bc, probs[5], VPMBType::Intra, VPMBType::InterFourMV),
701 vp_tree!(bc, probs[6],
702 vp_tree!(bc, probs[7], VPMBType::GoldenNoMV, VPMBType::GoldenMV),
703 vp_tree!(bc, probs[8], VPMBType::InterNearest, VPMBType::InterNear)
704 )
705 )
706 );
707 }
708 Ok(self.last_mbt)
709 }
710 fn decode_mb(&mut self, frm: &mut NASimpleVideoFrame<u8>, bc: &mut BoolCoder, cr: &mut CoeffReader, br: &mut dyn VP56Parser, hdr: &VP56Header, alpha: bool) -> DecoderResult<()> {
711 const FOURMV_SUB_TYPE: [VPMBType; 4] = [ VPMBType::InterNoMV, VPMBType::InterMV, VPMBType::InterNearest, VPMBType::InterNear ];
712
713 let mb_x = self.fstate.mb_x;
714 let mb_y = self.fstate.mb_y;
715 self.coeffs = [[0; 64]; 6];
716 let mb_pos = mb_x + mb_y * self.mb_w;
717 let mut four_mv = [ZERO_MV; 4];
718 let mut four_mbt = [VPMBType::Intra; 4];
719
720 if hdr.interlaced {
721 let iprob = self.ilace_prob;
722 let prob = if mb_x == 0 {
723 iprob
724 } else if !self.ilace_mb {
725 iprob + (((256 - (iprob as u16)) >> 1) as u8)
726 } else {
727 iprob - (iprob >> 1)
728 };
729 self.ilace_mb = bc.read_prob(prob);
730 }
731
732 let (num_mv, nearest_mv, near_mv, pred_mv) = if hdr.is_intra {
733 (0, ZERO_MV, ZERO_MV, ZERO_MV)
734 } else { self.find_mv_pred(VP_REF_INTER) };
735 let mb_type = if hdr.is_intra {
736 VPMBType::Intra
737 } else {
738 self.decode_mb_type(bc, (num_mv + 1) % 3)?
739 };
740 self.mb_info[mb_pos].mb_type = mb_type;
741 if mb_type.get_ref_id() != VP_REF_GOLDEN {
742 match mb_type {
743 VPMBType::Intra |
744 VPMBType::InterNoMV => {
745 self.mb_info[mb_pos].mv = ZERO_MV;
746 },
747 VPMBType::InterMV => {
748 let diff_mv = self.decode_mv(bc, br);
749 self.mb_info[mb_pos].mv = pred_mv + diff_mv;
750 },
751 VPMBType::InterNearest => {
752 self.mb_info[mb_pos].mv = nearest_mv;
753 },
754 VPMBType::InterNear => {
755 self.mb_info[mb_pos].mv = near_mv;
756 },
757 VPMBType::InterFourMV => {
758 for i in 0..4 {
759 four_mbt[i] = FOURMV_SUB_TYPE[bc.read_bits(2) as usize];
760 }
761 for i in 0..4 {
762 match four_mbt[i] {
763 VPMBType::InterNoMV => {},
764 VPMBType::InterMV => {
765 let diff_mv = self.decode_mv(bc, br);
766 four_mv[i] = pred_mv + diff_mv;
767 },
768 VPMBType::InterNearest => {
769 four_mv[i] = nearest_mv;
770 },
771 VPMBType::InterNear => {
772 four_mv[i] = near_mv;
773 },
774 _ => unreachable!(),
775 };
776 }
777 self.mb_info[mb_pos].mv = four_mv[3];
778 },
779 _ => unreachable!(),
780 };
781 } else {
782 let (_num_mv, nearest_mv, near_mv, pred_mv) = self.find_mv_pred(VP_REF_GOLDEN);
783 match mb_type {
784 VPMBType::GoldenNoMV => {
785 self.mb_info[mb_pos].mv = ZERO_MV;
786 },
787 VPMBType::GoldenMV => {
788 let diff_mv = self.decode_mv(bc, br);
789 self.mb_info[mb_pos].mv = pred_mv + diff_mv;
790 },
791 VPMBType::GoldenNearest => {
792 self.mb_info[mb_pos].mv = nearest_mv;
793 },
794 VPMBType::GoldenNear => {
795 self.mb_info[mb_pos].mv = near_mv;
796 },
797 _ => unreachable!(),
798 };
799 }
800 if !mb_type.is_intra() && (mb_type != VPMBType::InterFourMV) {
801 self.do_mc(br, frm, mb_type, self.mb_info[mb_pos].mv, alpha);
802 } else if mb_type == VPMBType::InterFourMV {
803 self.do_fourmv(br, frm, &four_mv, alpha);
804 }
805
806 for blk_no in 0..4 {
807 self.fstate.plane = if !alpha { 0 } else { 3 };
808 self.fstate.ctx_idx = blk_no >> 1;
809 self.fstate.top_ctx = self.top_ctx[self.fstate.plane][mb_x * 2 + (blk_no & 1)];
810 match cr {
811 CoeffReader::None => {
812 br.decode_block(bc, &mut self.coeffs[blk_no], &self.models.coeff_models[0], &self.models.vp6models, &mut self.fstate)?;
813 },
814 CoeffReader::Bool(ref mut bcc) => {
815 br.decode_block(bcc, &mut self.coeffs[blk_no], &self.models.coeff_models[0], &self.models.vp6models, &mut self.fstate)?;
816 },
817 CoeffReader::Huff(ref mut brc) => {
818 br.decode_block_huff(brc, &mut self.coeffs[blk_no], &self.models.vp6models, &self.models.vp6huff, &mut self.fstate)?;
819 },
820 };
821 self.top_ctx[self.fstate.plane][mb_x * 2 + (blk_no & 1)] = self.fstate.top_ctx;
822 self.predict_dc(mb_type, mb_pos, blk_no, alpha);
823
824 let bx = mb_x * 2 + (blk_no & 1);
825 let by = mb_y * 2 + (blk_no >> 1);
826 let has_ac = self.fstate.last_idx[self.fstate.ctx_idx] > 0;
827 if mb_type.is_intra() {
828 if !self.ilace_mb {
829 if has_ac {
830 vp_put_block(&mut self.coeffs[blk_no], bx, by, self.fstate.plane, frm);
831 } else {
832 vp_put_block_dc(&mut self.coeffs[blk_no], bx, by, self.fstate.plane, frm);
833 }
834 } else {
835 vp_put_block_ilace(&mut self.coeffs[blk_no], bx, by, self.fstate.plane, frm);
836 }
837 } else {
838 if !self.ilace_mb {
839 if has_ac {
840 vp_add_block(&mut self.coeffs[blk_no], bx, by, self.fstate.plane, frm);
841 } else {
842 vp_add_block_dc(&mut self.coeffs[blk_no], bx, by, self.fstate.plane, frm);
843 }
844 } else {
845 vp_add_block_ilace(&mut self.coeffs[blk_no], bx, by, self.fstate.plane, frm);
846 }
847 }
848 }
849 if !alpha {
850 for blk_no in 4..6 {
851 self.fstate.plane = blk_no - 3;
852 self.fstate.ctx_idx = blk_no - 2;
853 self.fstate.top_ctx = self.top_ctx[self.fstate.plane][mb_x];
854 match cr {
855 CoeffReader::None => {
856 br.decode_block(bc, &mut self.coeffs[blk_no], &self.models.coeff_models[1], &self.models.vp6models, &mut self.fstate)?;
857 },
858 CoeffReader::Bool(ref mut bcc) => {
859 br.decode_block(bcc, &mut self.coeffs[blk_no], &self.models.coeff_models[1], &self.models.vp6models, &mut self.fstate)?;
860 },
861 CoeffReader::Huff(ref mut brc) => {
862 br.decode_block_huff(brc, &mut self.coeffs[blk_no], &self.models.vp6models, &self.models.vp6huff, &mut self.fstate)?;
863 },
864 };
865 self.top_ctx[self.fstate.plane][mb_x] = self.fstate.top_ctx;
866 self.predict_dc(mb_type, mb_pos, blk_no, alpha);
867
868 let has_ac = self.fstate.last_idx[self.fstate.ctx_idx] > 0;
869 if mb_type.is_intra() {
870 if has_ac {
871 vp_put_block(&mut self.coeffs[blk_no], mb_x, mb_y, self.fstate.plane, frm);
872 } else {
873 vp_put_block_dc(&mut self.coeffs[blk_no], mb_x, mb_y, self.fstate.plane, frm);
874 }
875 } else {
876 if has_ac {
877 vp_add_block(&mut self.coeffs[blk_no], mb_x, mb_y, self.fstate.plane, frm);
878 } else {
879 vp_add_block_dc(&mut self.coeffs[blk_no], mb_x, mb_y, self.fstate.plane, frm);
880 }
881 }
882 }
883 }
884 Ok(())
885 }
886 fn do_mc(&mut self, br: &dyn VP56Parser, frm: &mut NASimpleVideoFrame<u8>, mb_type: VPMBType, mv: MV, alpha: bool) {
887 let x = self.fstate.mb_x * 16;
888 let y = self.fstate.mb_y * 16;
889 let plane = if !alpha { 0 } else { 3 };
890 let src = if mb_type.get_ref_id() == VP_REF_INTER {
891 self.shuf.get_last().unwrap()
892 } else {
893 self.shuf.get_golden().unwrap()
894 };
895
896 br.mc_block(frm, self.mc_buf.clone(), src.clone(), plane, x + 0, y + 0, mv, self.loop_thr);
897 br.mc_block(frm, self.mc_buf.clone(), src.clone(), plane, x + 8, y + 0, mv, self.loop_thr);
898 br.mc_block(frm, self.mc_buf.clone(), src.clone(), plane, x + 0, y + 8, mv, self.loop_thr);
899 br.mc_block(frm, self.mc_buf.clone(), src.clone(), plane, x + 8, y + 8, mv, self.loop_thr);
900 if !alpha {
901 let x = self.fstate.mb_x * 8;
902 let y = self.fstate.mb_y * 8;
903 br.mc_block(frm, self.mc_buf.clone(), src.clone(), 1, x, y, mv, self.loop_thr);
904 br.mc_block(frm, self.mc_buf.clone(), src.clone(), 2, x, y, mv, self.loop_thr);
905 }
906 }
907 fn do_fourmv(&mut self, br: &dyn VP56Parser, frm: &mut NASimpleVideoFrame<u8>, mvs: &[MV; 4], alpha: bool) {
908 let x = self.fstate.mb_x * 16;
909 let y = self.fstate.mb_y * 16;
910 let plane = if !alpha { 0 } else { 3 };
911 let src = self.shuf.get_last().unwrap();
912 for blk_no in 0..4 {
913 br.mc_block(frm, self.mc_buf.clone(), src.clone(),
914 plane, x + (blk_no & 1) * 8, y + (blk_no & 2) * 4,
915 mvs[blk_no], self.loop_thr);
916 }
917 if !alpha {
918 let x = self.fstate.mb_x * 8;
919 let y = self.fstate.mb_y * 8;
920 let sum = mvs[0] + mvs[1] + mvs[2] + mvs[3];
921 let mv = MV { x: sum.x / 4, y: sum.y / 4 };
922 br.mc_block(frm, self.mc_buf.clone(), src.clone(), 1, x, y, mv, self.loop_thr);
923 br.mc_block(frm, self.mc_buf.clone(), src.clone(), 2, x, y, mv, self.loop_thr);
924 }
925 }
926 fn predict_dc(&mut self, mb_type: VPMBType, mb_pos: usize, blk_no: usize, alpha: bool) {
927 let mb_x = self.fstate.mb_x;
928 let is_luma = blk_no < 4;
929 let (plane, dcs) = if alpha { (0, &mut self.dc_a) } else {
930 match blk_no {
931 4 => (1, &mut self.dc_u),
932 5 => (2, &mut self.dc_v),
933 _ => (0, &mut self.dc_y),
934 }
935 };
936 let dc_pos = if is_luma {
937 dcs.xpos + mb_x * 2 + (blk_no & 1) + (blk_no >> 1) * dcs.stride
938 } else {
939 dcs.xpos + mb_x
940 };
941 let ref_id = mb_type.get_ref_id();
942 let has_left_blk = is_luma && ((blk_no & 1) != 0);
943 let has_top_blk = is_luma && ((blk_no & 2) != 0);
944 let mut dc_pred = 0;
945 let mut count = 0;
946 if has_left_blk || ((mb_x > 0) && (self.mb_info[mb_pos - 1].mb_type.get_ref_id() == ref_id)) {
947 dc_pred += dcs.data[dc_pos - 1];
948 count += 1;
949 }
950 if has_top_blk || ((mb_pos >= self.mb_w) && (self.mb_info[mb_pos - self.mb_w].mb_type.get_ref_id() == ref_id)) {
951 dc_pred += dcs.data[dc_pos - dcs.stride];
952 count += 1;
953 }
954 if self.version == 5 {
955 if (count < 2) && has_left_blk {
956 dc_pred += dc_pred;
957 count += 1;
958 }
959 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) {
960 dc_pred += dc_pred;
961 count += 1;
962 }
963 if (count < 2) && mb_pos == 0 && !is_luma {
964 count += 1;
965 }
966 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) {
967 dc_pred += dcs.data[dc_pos + dcs.stride - 1];
968 count += 1;
969 }
970 if (count < 2) && blk_no == 2 {
971 dc_pred += dcs.data[dc_pos - dcs.stride + 1];
972 count += 1;
973 }
974 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) {
975 dc_pred += dcs.data[dc_pos - dcs.stride + 1];
976 count += 1;
977 }
978 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) {
979 dc_pred += dcs.data[dc_pos - dcs.stride + 1];
980 count += 1;
981 }
982 }
983 if count == 0 {
984 dc_pred = self.last_dc[ref_id as usize][plane];
985 } else if count == 2 {
986 dc_pred /= 2;
987 }
988 self.coeffs[blk_no][0] += dc_pred;
989 self.last_dc[ref_id as usize][plane] = self.coeffs[blk_no][0];
990 dcs.data[dc_pos] = self.coeffs[blk_no][0];
991 self.coeffs[blk_no][0] = self.coeffs[blk_no][0].wrapping_mul(self.fstate.dc_quant);
992 }
993}
994
995const VP56_DC_QUANTS: [i16; 64] = [
996 47, 47, 47, 47, 45, 43, 43, 43,
997 43, 43, 42, 41, 41, 40, 40, 40,
998 40, 35, 35, 35, 35, 33, 33, 33,
999 33, 32, 32, 32, 27, 27, 26, 26,
1000 25, 25, 24, 24, 23, 23, 19, 19,
1001 19, 19, 18, 18, 17, 16, 16, 16,
1002 16, 16, 15, 11, 11, 11, 10, 10,
1003 9, 8, 7, 5, 3, 3, 2, 2
1004];
1005const VP56_AC_QUANTS: [i16; 64] = [
1006 94, 92, 90, 88, 86, 82, 78, 74,
1007 70, 66, 62, 58, 54, 53, 52, 51,
1008 50, 49, 48, 47, 46, 45, 44, 43,
1009 42, 40, 39, 37, 36, 35, 34, 33,
1010 32, 31, 30, 29, 28, 27, 26, 25,
1011 24, 23, 22, 21, 20, 19, 18, 17,
1012 16, 15, 14, 13, 12, 11, 10, 9,
1013 8, 7, 6, 5, 4, 3, 2, 1
1014];
1015
1016const VP56_FILTER_LIMITS: [u8; 64] = [
1017 14, 14, 13, 13, 12, 12, 10, 10,
1018 10, 10, 8, 8, 8, 8, 8, 8,
1019 8, 8, 8, 8, 8, 8, 8, 8,
1020 8, 8, 8, 8, 8, 8, 8, 8,
1021 8, 8, 8, 8, 7, 7, 7, 7,
1022 7, 7, 6, 6, 6, 6, 6, 6,
1023 5, 5, 5, 5, 4, 4, 4, 4,
1024 4, 4, 4, 3, 3, 3, 3, 2
1025];
1026
1027const VP56_MODE_VQ: [[[u8; 20]; 16]; 3] = [
1028 [
1029 [ 9, 15, 32, 25, 7, 19, 9, 21, 1, 12, 14, 12, 3, 18, 14, 23, 3, 10, 0, 4 ],
1030 [ 48, 39, 1, 2, 11, 27, 29, 44, 7, 27, 1, 4, 0, 3, 1, 6, 1, 2, 0, 0 ],
1031 [ 21, 32, 1, 2, 4, 10, 32, 43, 6, 23, 2, 3, 1, 19, 1, 6, 12, 21, 0, 7 ],
1032 [ 69, 83, 0, 0, 0, 2, 10, 29, 3, 12, 0, 1, 0, 3, 0, 3, 2, 2, 0, 0 ],
1033 [ 11, 20, 1, 4, 18, 36, 43, 48, 13, 35, 0, 2, 0, 5, 3, 12, 1, 2, 0, 0 ],
1034 [ 70, 44, 0, 1, 2, 10, 37, 46, 8, 26, 0, 2, 0, 2, 0, 2, 0, 1, 0, 0 ],
1035 [ 8, 15, 0, 1, 8, 21, 74, 53, 22, 42, 0, 1, 0, 2, 0, 3, 1, 2, 0, 0 ],
1036 [ 141, 42, 0, 0, 1, 4, 11, 24, 1, 11, 0, 1, 0, 1, 0, 2, 0, 0, 0, 0 ],
1037 [ 8, 19, 4, 10, 24, 45, 21, 37, 9, 29, 0, 3, 1, 7, 11, 25, 0, 2, 0, 1 ],
1038 [ 46, 42, 0, 1, 2, 10, 54, 51, 10, 30, 0, 2, 0, 2, 0, 1, 0, 1, 0, 0 ],
1039 [ 28, 32, 0, 0, 3, 10, 75, 51, 14, 33, 0, 1, 0, 2, 0, 1, 1, 2, 0, 0 ],
1040 [ 100, 46, 0, 1, 3, 9, 21, 37, 5, 20, 0, 1, 0, 2, 1, 2, 0, 1, 0, 0 ],
1041 [ 27, 29, 0, 1, 9, 25, 53, 51, 12, 34, 0, 1, 0, 3, 1, 5, 0, 2, 0, 0 ],
1042 [ 80, 38, 0, 0, 1, 4, 69, 33, 5, 16, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0 ],
1043 [ 16, 20, 0, 0, 2, 8, 104, 49, 15, 33, 0, 1, 0, 1, 0, 1, 1, 1, 0, 0 ],
1044 [ 194, 16, 0, 0, 1, 1, 1, 9, 1, 3, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0 ],
1045 ], [
1046 [ 41, 22, 1, 0, 1, 31, 0, 0, 0, 0, 0, 1, 1, 7, 0, 1, 98, 25, 4, 10 ],
1047 [ 123, 37, 6, 4, 1, 27, 0, 0, 0, 0, 5, 8, 1, 7, 0, 1, 12, 10, 0, 2 ],
1048 [ 26, 14, 14, 12, 0, 24, 0, 0, 0, 0, 55, 17, 1, 9, 0, 36, 5, 7, 1, 3 ],
1049 [ 209, 5, 0, 0, 0, 27, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0 ],
1050 [ 2, 5, 4, 5, 0, 121, 0, 0, 0, 0, 0, 3, 2, 4, 1, 4, 2, 2, 0, 1 ],
1051 [ 175, 5, 0, 1, 0, 48, 0, 0, 0, 0, 0, 2, 0, 1, 0, 2, 0, 1, 0, 0 ],
1052 [ 83, 5, 2, 3, 0, 102, 0, 0, 0, 0, 1, 3, 0, 2, 0, 1, 0, 0, 0, 0 ],
1053 [ 233, 6, 0, 0, 0, 8, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0 ],
1054 [ 34, 16, 112, 21, 1, 28, 0, 0, 0, 0, 6, 8, 1, 7, 0, 3, 2, 5, 0, 2 ],
1055 [ 159, 35, 2, 2, 0, 25, 0, 0, 0, 0, 3, 6, 0, 5, 0, 1, 4, 4, 0, 1 ],
1056 [ 75, 39, 5, 7, 2, 48, 0, 0, 0, 0, 3, 11, 2, 16, 1, 4, 7, 10, 0, 2 ],
1057 [ 212, 21, 0, 1, 0, 9, 0, 0, 0, 0, 1, 2, 0, 2, 0, 0, 2, 2, 0, 0 ],
1058 [ 4, 2, 0, 0, 0, 172, 0, 0, 0, 0, 0, 1, 0, 2, 0, 0, 2, 0, 0, 0 ],
1059 [ 187, 22, 1, 1, 0, 17, 0, 0, 0, 0, 3, 6, 0, 4, 0, 1, 4, 4, 0, 1 ],
1060 [ 133, 6, 1, 2, 1, 70, 0, 0, 0, 0, 0, 2, 0, 4, 0, 3, 1, 1, 0, 0 ],
1061 [ 251, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ],
1062 ], [
1063 [ 2, 3, 2, 3, 0, 2, 0, 2, 0, 0, 11, 4, 1, 4, 0, 2, 3, 2, 0, 4 ],
1064 [ 49, 46, 3, 4, 7, 31, 42, 41, 0, 0, 2, 6, 1, 7, 1, 4, 2, 4, 0, 1 ],
1065 [ 26, 25, 1, 1, 2, 10, 67, 39, 0, 0, 1, 1, 0, 14, 0, 2, 31, 26, 1, 6 ],
1066 [ 103, 46, 1, 2, 2, 10, 33, 42, 0, 0, 1, 4, 0, 3, 0, 1, 1, 3, 0, 0 ],
1067 [ 14, 31, 9, 13, 14, 54, 22, 29, 0, 0, 2, 6, 4, 18, 6, 13, 1, 5, 0, 1 ],
1068 [ 85, 39, 0, 0, 1, 9, 69, 40, 0, 0, 0, 1, 0, 3, 0, 1, 2, 3, 0, 0 ],
1069 [ 31, 28, 0, 0, 3, 14, 130, 34, 0, 0, 0, 1, 0, 3, 0, 1, 3, 3, 0, 1 ],
1070 [ 171, 25, 0, 0, 1, 5, 25, 21, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0 ],
1071 [ 17, 21, 68, 29, 6, 15, 13, 22, 0, 0, 6, 12, 3, 14, 4, 10, 1, 7, 0, 3 ],
1072 [ 51, 39, 0, 1, 2, 12, 91, 44, 0, 0, 0, 2, 0, 3, 0, 1, 2, 3, 0, 1 ],
1073 [ 81, 25, 0, 0, 2, 9, 106, 26, 0, 0, 0, 1, 0, 1, 0, 1, 1, 1, 0, 0 ],
1074 [ 140, 37, 0, 1, 1, 8, 24, 33, 0, 0, 1, 2, 0, 2, 0, 1, 1, 2, 0, 0 ],
1075 [ 14, 23, 1, 3, 11, 53, 90, 31, 0, 0, 0, 3, 1, 5, 2, 6, 1, 2, 0, 0 ],
1076 [ 123, 29, 0, 0, 1, 7, 57, 30, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0 ],
1077 [ 13, 14, 0, 0, 4, 20, 175, 20, 0, 0, 0, 1, 0, 1, 0, 1, 1, 1, 0, 0 ],
1078 [ 202, 23, 0, 0, 1, 3, 2, 9, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0 ],
1079 ]
1080];
1081