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