semi-working VP5/6 decoder
[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 pub struct GenericCache<T: Copy> {
299 pub height: usize,
300 pub stride: usize,
301 pub xpos: usize,
302 pub data: Vec<T>,
303 pub default: T,
304 }
305
306 impl<T:Copy> GenericCache<T> {
307 fn new(height: usize, stride: usize, default: T) -> Self {
308 let mut ret = Self {
309 stride,
310 height,
311 xpos: 0,
312 data: Vec::with_capacity((height + 1) * stride),
313 default,
314 };
315 ret.reset();
316 ret
317 }
318 fn full_size(&self) -> usize { self.stride * (self.height + 1) }
319 fn reset(&mut self) {
320 self.data.truncate(0);
321 let size = self.full_size();
322 self.data.resize(size, self.default);
323 self.xpos = self.stride + 1;
324 }
325 fn update_row(&mut self) {
326 for i in 0..self.stride {
327 self.data[i] = self.data[self.height * self.stride + i];
328 }
329 self.data.truncate(self.stride);
330 let size = self.full_size();
331 self.data.resize(size, self.default);
332 self.xpos = self.stride + 1;
333 }
334 }
335
336 pub struct VP56Decoder {
337 version: u8,
338 has_alpha: bool,
339 flip: bool,
340 shuf: VPShuffler,
341 width: usize,
342 height: usize,
343 mb_w: usize,
344 mb_h: usize,
345 models: VP56Models,
346 coeffs: [[i16; 64]; 6],
347 last_mbt: VPMBType,
348
349 loop_thr: i16,
350 ilace_prob: u8,
351 ilace_mb: bool,
352
353 mb_info: Vec<MBInfo>,
354 fstate: FrameState,
355 dc_y: GenericCache<i16>,
356 dc_u: GenericCache<i16>,
357 dc_v: GenericCache<i16>,
358 dc_a: GenericCache<i16>,
359 last_dc: [[i16; 4]; 3],
360 top_ctx: [Vec<u8>; 4],
361
362 mc_buf: NAVideoBufferRef<u8>,
363 }
364
365 fn rescale_mb_mode_prob(prob: u32, total: u32) -> u8 {
366 (255 * prob / (1 + total)) as u8
367 }
368
369 fn map_mb_type(mbtype: VPMBType) -> usize {
370 match mbtype {
371 VPMBType::InterNoMV => 0,
372 VPMBType::Intra => 1,
373 VPMBType::InterMV => 2,
374 VPMBType::InterNearest => 3,
375 VPMBType::InterNear => 4,
376 VPMBType::GoldenNoMV => 5,
377 VPMBType::GoldenMV => 6,
378 VPMBType::InterFourMV => 7,
379 VPMBType::GoldenNearest => 8,
380 VPMBType::GoldenNear => 9,
381 }
382 }
383
384 pub const VP56_COEF_BASE: [i16; 6] = [ 5, 7, 11, 19, 35, 67 ];
385 pub fn expand_token_bc(bc: &mut BoolCoder, val_probs: &[u8; 11], token: u8, version: u8) -> i16 {
386 const COEF_ADD_PROBS: [[u8; 12]; 6] = [
387 [ 159, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ],
388 [ 165, 145, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0 ],
389 [ 173, 148, 140, 128, 0, 0, 0, 0, 0, 0, 0, 0 ],
390 [ 176, 155, 140, 135, 128, 0, 0, 0, 0, 0, 0, 0 ],
391 [ 180, 157, 141, 134, 130, 128, 0, 0, 0, 0, 0, 0 ],
392 [ 254, 254, 243, 230, 196, 177, 153, 140, 133, 130, 129, 128 ],
393 ];
394
395 let mut sign = false;
396 let level;
397 if token < TOKEN_LARGE {
398 if token != 0 {
399 sign = bc.read_bool();
400 }
401 level = token as i16;
402 } else {
403 let cat: usize = vp_tree!(bc, val_probs[6],
404 vp_tree!(bc, val_probs[7], 0, 1),
405 vp_tree!(bc, val_probs[8],
406 vp_tree!(bc, val_probs[9], 2, 3),
407 vp_tree!(bc, val_probs[10], 4, 5)));
408 if version == 5 {
409 sign = bc.read_bool();
410 }
411 let mut add = 0i16;
412 let add_probs = &COEF_ADD_PROBS[cat];
413 for prob in add_probs.iter() {
414 if *prob == 128 { break; }
415 add = (add << 1) | (bc.read_prob(*prob) as i16);
416 }
417 if version != 5 {
418 sign = bc.read_bool();
419 }
420 level = VP56_COEF_BASE[cat] + add;
421 }
422 if !sign {
423 level
424 } else {
425 -level
426 }
427 }
428
429 impl VP56Decoder {
430 pub fn new(version: u8, has_alpha: bool, flip: bool) -> Self {
431 let vt = alloc_video_buffer(NAVideoInfo::new(24, 24, false, YUV420_FORMAT), 4).unwrap();
432 let mc_buf = vt.get_vbuf().unwrap();
433 Self {
434 version, has_alpha, flip,
435 shuf: VPShuffler::new(),
436 width: 0,
437 height: 0,
438 mb_w: 0,
439 mb_h: 0,
440 models: VP56Models::new(),
441 coeffs: [[0; 64]; 6],
442 last_mbt: VPMBType::InterNoMV,
443
444 loop_thr: 0,
445 ilace_prob: 0,
446 ilace_mb: false,
447
448 mb_info: Vec::new(),
449 fstate: FrameState::new(),
450 dc_y: GenericCache::new(0, 0, 0),
451 dc_u: GenericCache::new(0, 0, 0),
452 dc_v: GenericCache::new(0, 0, 0),
453 dc_a: GenericCache::new(0, 0, 0),
454 last_dc: [[0; 4]; 3],
455 top_ctx: [Vec::new(), Vec::new(), Vec::new(), Vec::new()],
456
457 mc_buf,
458 }
459 }
460 fn set_dimensions(&mut self, width: usize, height: usize) {
461 self.width = width;
462 self.height = height;
463 self.mb_w = (self.width + 15) >> 4;
464 self.mb_h = (self.height + 15) >> 4;
465 self.mb_info.resize(self.mb_w * self.mb_h, MBInfo::default());
466 self.dc_y = GenericCache::new(2, 1 + self.mb_w * 2, 0);
467 self.dc_u = GenericCache::new(1, 1 + self.mb_w, 0);
468 self.dc_v = GenericCache::new(1, 1 + self.mb_w, 0);
469 self.dc_a = GenericCache::new(2, 1 + self.mb_w * 2, 0);
470 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]];
471 }
472 pub fn init(&mut self, supp: &mut NADecoderSupport, vinfo: NAVideoInfo) -> DecoderResult<()> {
473 supp.pool_u8.set_dec_bufs(3);
474 supp.pool_u8.prealloc_video(NAVideoInfo::new(vinfo.get_width(), vinfo.get_height(), false, vinfo.get_format()), 4)?;
475 self.set_dimensions(vinfo.get_width(), vinfo.get_height());
476 Ok(())
477 }
478 pub fn decode_frame(&mut self, supp: &mut NADecoderSupport, src: &[u8], br: &mut dyn VP56Parser) -> DecoderResult<(NABufferType, FrameType)> {
479 let aoffset;
480 let mut bc;
481 if self.has_alpha {
482 validate!(src.len() >= 7);
483 aoffset = ((src[0] as usize) << 16) | ((src[1] as usize) << 8) | (src[2] as usize);
484 validate!((aoffset > 0) && (aoffset < src.len() - 3));
485 bc = BoolCoder::new(&src[3..])?;
486 } else {
487 validate!(src.len() >= 4);
488 aoffset = src.len();
489 bc = BoolCoder::new(src)?;
490 }
491 let hdr = br.parse_header(&mut bc)?;
492 validate!((hdr.offset as usize) < aoffset); //XXX: take alpha 3 byte offset into account?
493
494 if hdr.mb_w != 0 {
495 self.set_dimensions((hdr.mb_w as usize) * 16, (hdr.mb_h as usize) * 16);
496 }
497 let vinfo = NAVideoInfo::new(self.width, self.height, self.flip, YUV420_FORMAT);
498 let ret = supp.pool_u8.get_free();
499 if ret.is_none() {
500 return Err(DecoderError::AllocError);
501 }
502 let mut buf = ret.unwrap();
503 if buf.get_info() != vinfo {
504 self.shuf.clear();
505 supp.pool_u8.reset();
506 supp.pool_u8.prealloc_video(vinfo, 4)?;
507 let ret = supp.pool_u8.get_free();
508 if ret.is_none() {
509 return Err(DecoderError::AllocError);
510 }
511 buf = ret.unwrap();
512 }
513 let mut dframe = NASimpleVideoFrame::from_video_buf(&mut buf).unwrap();
514
515 if hdr.is_intra {
516 self.shuf.clear();
517 }
518
519 let mut cr;
520 if hdr.multistream {
521 let off = (if self.has_alpha { 3 } else { 0 }) + (hdr.offset as usize);
522 if !hdr.use_huffman {
523 let bc2 = BoolCoder::new(&src[off..])?;
524 cr = CoeffReader::Bool(bc2);
525 } else {
526 let br = BitReader::new(&src[off..], aoffset - off, BitReaderMode::BE);
527 cr = CoeffReader::Huff(br);
528 }
529 } else {
530 cr = CoeffReader::None;
531 }
532
533 if hdr.is_intra {
534 br.reset_models(&mut self.models);
535 self.reset_mbtype_models();
536 } else {
537 self.decode_mode_prob_models(&mut bc)?;
538 br.decode_mv_models(&mut bc, &mut self.models.mv_models)?;
539 }
540 br.decode_coeff_models(&mut bc, &mut self.models, hdr.is_intra)?;
541 if hdr.use_huffman {
542 for i in 0..2 {
543 self.models.vp6huff.dc_token_tree[i].build_codes(&self.models.coeff_models[i].dc_value_probs);
544 }
545 for i in 0..2 {
546 for mode in 0..3 {
547 for band in 0..6 {
548 self.models.vp6huff.ac_token_tree[i][mode][band].build_codes(&self.models.coeff_models[i].ac_val_probs[mode][band]);
549 }
550 }
551 }
552 for i in 0..2 {
553 self.models.vp6huff.zero_run_tree[i].build_codes_zero_run(&self.models.vp6models.zero_run_probs[i]);
554 }
555 }
556
557 if hdr.interlaced {
558 self.ilace_prob = bc.read_bits(8) as u8;
559 }
560
561 self.fstate = FrameState::new();
562 self.fstate.dc_quant = VP56_DC_QUANTS[hdr.quant as usize] * 4;
563 self.fstate.ac_quant = VP56_AC_QUANTS[hdr.quant as usize] * 4;
564 self.loop_thr = VP56_FILTER_LIMITS[hdr.quant as usize] as i16;
565
566 self.last_mbt = VPMBType::InterNoMV;
567 self.dc_y.reset();
568 self.dc_u.reset();
569 self.dc_v.reset();
570 self.dc_a.reset();
571 for vec in self.top_ctx.iter_mut() {
572 for el in vec.iter_mut() {
573 *el = 0;
574 }
575 }
576 self.last_dc = [[0; 4]; 3];
577 self.last_dc[0][1] = 0x80;
578 self.last_dc[0][2] = 0x80;
579
580 self.ilace_mb = false;
581 for mb_y in 0..self.mb_h {
582 self.fstate.mb_y = mb_y;
583 self.fstate.coeff_cat = [[0; 64]; 4];
584 self.fstate.last_idx = [24; 4];
585 for mb_x in 0..self.mb_w {
586 self.fstate.mb_x = mb_x;
587 self.decode_mb(&mut dframe, &mut bc, &mut cr, br, &hdr, false)?;
588 }
589 self.dc_y.update_row();
590 self.dc_u.update_row();
591 self.dc_v.update_row();
592 self.dc_a.update_row();
593 }
594
595 if self.has_alpha {
596 let asrc = &src[aoffset + 3..];
597 let mut bc = BoolCoder::new(asrc)?;
598 let ahdr = br.parse_header(&mut bc)?;
599 validate!(ahdr.mb_w == hdr.mb_w && ahdr.mb_h == hdr.mb_h);
600 }
601
602 if hdr.is_golden {
603 self.shuf.add_golden_frame(buf.clone());
604 }
605 self.shuf.add_frame(buf.clone());
606
607 Ok((NABufferType::Video(buf), if hdr.is_intra { FrameType::I } else { FrameType::P }))
608 }
609 fn reset_mbtype_models(&mut self) {
610 const DEFAULT_XMITTED_PROBS: [[u8; 20]; 3] = [
611 [ 42, 69, 2, 1, 7, 1, 42, 44, 22, 6, 3, 1, 2, 0, 5, 1, 1, 0, 0, 0 ],
612 [ 8, 229, 1, 1, 8, 0, 0, 0, 0, 0, 2, 1, 1, 0, 0, 0, 1, 1, 0, 0 ],
613 [ 35, 122, 1, 1, 6, 1, 34, 46, 0, 0, 2, 1, 1, 0, 1, 0, 1, 1, 0, 0 ]
614 ];
615 self.models.prob_xmitted.copy_from_slice(&DEFAULT_XMITTED_PROBS);
616 }
617 fn decode_mode_prob_models(&mut self, bc: &mut BoolCoder) -> DecoderResult<()> {
618 for ctx in 0..3 {
619 if bc.read_prob(174) {
620 let idx = bc.read_bits(4) as usize;
621 for i in 0..20 {
622 self.models.prob_xmitted[ctx][i ^ 1] = VP56_MODE_VQ[ctx][idx][i];
623 }
624 }
625 if bc.read_prob(254) {
626 for set in 0..20 {
627 if bc.read_prob(205) {
628 let sign = bc.read_bool();
629 let diff = vp_tree!(bc, 171,
630 vp_tree!(bc, 83, 2, 1),
631 vp_tree!(bc, 199,
632 vp_tree!(bc, 140,
633 vp_tree!(bc, 125,
634 vp_tree!(bc, 104, 6, 5),
635 4
636 ),
637 3
638 ),
639 bc.read_bits(7)
640 )) * 4;
641 validate!(diff < 256);
642 let diff = diff as u8;
643 if !sign {
644 validate!(self.models.prob_xmitted[ctx][set ^ 1] <= 255 - diff);
645 self.models.prob_xmitted[ctx][set ^ 1] += diff;
646 } else {
647 validate!(self.models.prob_xmitted[ctx][set ^ 1] >= diff);
648 self.models.prob_xmitted[ctx][set ^ 1] -= diff;
649 }
650 }
651 }
652 }
653 }
654 for ctx in 0..3 {
655 let prob_xmitted = &self.models.prob_xmitted[ctx];
656 for mode in 0..10 {
657 let mdl = &mut self.models.mbtype_models[ctx][mode];
658 let mut cnt = [0u32; 10];
659 let mut total = 0;
660 for i in 0..10 {
661 if i == mode { continue; }
662 cnt[i] = 100 * (prob_xmitted[i * 2] as u32);
663 total += cnt[i];
664 }
665 let sum = (prob_xmitted[mode * 2] as u32) + (prob_xmitted[mode * 2 + 1] as u32);
666 mdl.probs[9] = 255 - rescale_mb_mode_prob(prob_xmitted[mode * 2 + 1] as u32, sum);
667
668 let inter_mv0_weight = (cnt[0] as u32) + (cnt[2] as u32);
669 let inter_mv1_weight = (cnt[3] as u32) + (cnt[4] as u32);
670 let gold_mv0_weight = (cnt[5] as u32) + (cnt[6] as u32);
671 let gold_mv1_weight = (cnt[8] as u32) + (cnt[9] as u32);
672 let mix_weight = (cnt[1] as u32) + (cnt[7] as u32);
673 mdl.probs[0] = 1 + rescale_mb_mode_prob(inter_mv0_weight + inter_mv1_weight, total);
674 mdl.probs[1] = 1 + rescale_mb_mode_prob(inter_mv0_weight, inter_mv0_weight + inter_mv1_weight);
675 mdl.probs[2] = 1 + rescale_mb_mode_prob(mix_weight, mix_weight + gold_mv0_weight + gold_mv1_weight);
676 mdl.probs[3] = 1 + rescale_mb_mode_prob(cnt[0] as u32, inter_mv0_weight);
677 mdl.probs[4] = 1 + rescale_mb_mode_prob(cnt[3] as u32, inter_mv1_weight);
678 mdl.probs[5] = 1 + rescale_mb_mode_prob(cnt[1], mix_weight);
679 mdl.probs[6] = 1 + rescale_mb_mode_prob(gold_mv0_weight, gold_mv0_weight + gold_mv1_weight);
680 mdl.probs[7] = 1 + rescale_mb_mode_prob(cnt[5], gold_mv0_weight);
681 mdl.probs[8] = 1 + rescale_mb_mode_prob(cnt[8], gold_mv1_weight);
682 }
683 }
684 Ok(())
685 }
686 fn find_mv_pred(&self, ref_id: u8) -> (usize, MV, MV, MV) {
687 const CAND_POS: [(i8, i8); 12] = [
688 (-1, 0), ( 0, -1),
689 (-1, -1), (-1, 1),
690 (-2, 0), ( 0, -2),
691 (-1, -2), (-2, -1),
692 (-2, 1), (-1, 2),
693 (-2, -2), (-2, 2)
694 ];
695
696 let mut nearest_mv = ZERO_MV;
697 let mut near_mv = ZERO_MV;
698 let mut pred_mv = ZERO_MV;
699 let mut num_mv: usize = 0;
700
701 for (i, (yoff, xoff)) in CAND_POS.iter().enumerate() {
702 let cx = (self.fstate.mb_x as isize) + (*xoff as isize);
703 let cy = (self.fstate.mb_y as isize) + (*yoff as isize);
704 if (cx < 0) || (cy < 0) {
705 continue;
706 }
707 let cx = cx as usize;
708 let cy = cy as usize;
709 if (cx >= self.mb_w) || (cy >= self.mb_h) {
710 continue;
711 }
712 let mb_pos = cx + cy * self.mb_w;
713 let mv = self.mb_info[mb_pos].mv;
714 if (self.mb_info[mb_pos].mb_type.get_ref_id() != ref_id) || (mv == ZERO_MV) {
715 continue;
716 }
717 if num_mv == 0 {
718 nearest_mv = mv;
719 num_mv += 1;
720 if (self.version > 5) && (i < 2) {
721 pred_mv = mv;
722 }
723 } else if mv != nearest_mv {
724 near_mv = mv;
725 num_mv += 1;
726 break;
727 }
728 }
729
730 (num_mv, nearest_mv, near_mv, pred_mv)
731 }
732 fn decode_mv(&self, bc: &mut BoolCoder, br: &mut dyn VP56Parser) -> MV {
733 let x = br.decode_mv(bc, &self.models.mv_models[0]);
734 let y = br.decode_mv(bc, &self.models.mv_models[1]);
735 MV{ x, y }
736 }
737 fn decode_mb_type(&mut self, bc: &mut BoolCoder, ctx: usize) -> DecoderResult<VPMBType> {
738 let probs = &self.models.mbtype_models[ctx][map_mb_type(self.last_mbt)].probs;
739 if !bc.read_prob(probs[9]) {
740 self.last_mbt = vp_tree!(
741 bc, probs[0],
742 vp_tree!(bc, probs[1],
743 vp_tree!(bc, probs[3], VPMBType::InterNoMV, VPMBType::InterMV),
744 vp_tree!(bc, probs[4], VPMBType::InterNearest, VPMBType::InterNear)
745 ),
746 vp_tree!(bc, probs[2],
747 vp_tree!(bc, probs[5], VPMBType::Intra, VPMBType::InterFourMV),
748 vp_tree!(bc, probs[6],
749 vp_tree!(bc, probs[7], VPMBType::GoldenNoMV, VPMBType::GoldenMV),
750 vp_tree!(bc, probs[8], VPMBType::InterNearest, VPMBType::InterNear)
751 )
752 )
753 );
754 }
755 Ok(self.last_mbt)
756 }
757 fn decode_mb(&mut self, frm: &mut NASimpleVideoFrame<u8>, bc: &mut BoolCoder, cr: &mut CoeffReader, br: &mut dyn VP56Parser, hdr: &VP56Header, alpha: bool) -> DecoderResult<()> {
758 const FOURMV_SUB_TYPE: [VPMBType; 4] = [ VPMBType::InterNoMV, VPMBType::InterMV, VPMBType::InterNearest, VPMBType::InterNear ];
759
760 let mb_x = self.fstate.mb_x;
761 let mb_y = self.fstate.mb_y;
762 self.coeffs = [[0; 64]; 6];
763 let mb_pos = mb_x + mb_y * self.mb_w;
764 let mut four_mv = [ZERO_MV; 4];
765 let mut four_mbt = [VPMBType::Intra; 4];
766
767 if hdr.interlaced {
768 let iprob = self.ilace_prob;
769 let prob = if mb_x == 0 {
770 iprob
771 } else if !self.ilace_mb {
772 iprob + (((256 - (iprob as u16)) >> 1) as u8)
773 } else {
774 iprob - (iprob >> 1)
775 };
776 self.ilace_mb = bc.read_prob(prob);
777 }
778
779 let (num_mv, nearest_mv, near_mv, pred_mv) = if hdr.is_intra {
780 (0, ZERO_MV, ZERO_MV, ZERO_MV)
781 } else { self.find_mv_pred(VP_REF_INTER) };
782 let mb_type = if hdr.is_intra {
783 VPMBType::Intra
784 } else {
785 self.decode_mb_type(bc, (num_mv + 1) % 3)?
786 };
787 self.mb_info[mb_pos].mb_type = mb_type;
788 if mb_type.get_ref_id() != VP_REF_GOLDEN {
789 match mb_type {
790 VPMBType::Intra |
791 VPMBType::InterNoMV => {
792 self.mb_info[mb_pos].mv = ZERO_MV;
793 },
794 VPMBType::InterMV => {
795 let diff_mv = self.decode_mv(bc, br);
796 self.mb_info[mb_pos].mv = pred_mv + diff_mv;
797 },
798 VPMBType::InterNearest => {
799 self.mb_info[mb_pos].mv = nearest_mv;
800 },
801 VPMBType::InterNear => {
802 self.mb_info[mb_pos].mv = near_mv;
803 },
804 VPMBType::InterFourMV => {
805 for i in 0..4 {
806 four_mbt[i] = FOURMV_SUB_TYPE[bc.read_bits(2) as usize];
807 }
808 for i in 0..4 {
809 match four_mbt[i] {
810 VPMBType::InterNoMV => {},
811 VPMBType::InterMV => {
812 let diff_mv = self.decode_mv(bc, br);
813 four_mv[i] = pred_mv + diff_mv;
814 },
815 VPMBType::InterNearest => {
816 four_mv[i] = nearest_mv;
817 },
818 VPMBType::InterNear => {
819 four_mv[i] = near_mv;
820 },
821 _ => unreachable!(),
822 };
823 }
824 self.mb_info[mb_pos].mv = four_mv[3];
825 },
826 _ => unreachable!(),
827 };
828 } else {
829 let (_num_mv, nearest_mv, near_mv, pred_mv) = self.find_mv_pred(VP_REF_GOLDEN);
830 match mb_type {
831 VPMBType::GoldenNoMV => {
832 self.mb_info[mb_pos].mv = ZERO_MV;
833 },
834 VPMBType::GoldenMV => {
835 let diff_mv = self.decode_mv(bc, br);
836 self.mb_info[mb_pos].mv = pred_mv + diff_mv;
837 },
838 VPMBType::GoldenNearest => {
839 self.mb_info[mb_pos].mv = nearest_mv;
840 },
841 VPMBType::GoldenNear => {
842 self.mb_info[mb_pos].mv = near_mv;
843 },
844 _ => unreachable!(),
845 };
846 }
847 if !mb_type.is_intra() && (mb_type != VPMBType::InterFourMV) {
848 self.do_mc(br, frm, mb_type, self.mb_info[mb_pos].mv, alpha);
849 } else if mb_type == VPMBType::InterFourMV {
850 self.do_fourmv(br, frm, &four_mv, alpha);
851 }
852
853 for blk_no in 0..4 {
854 self.fstate.plane = if !alpha { 0 } else { 3 };
855 self.fstate.ctx_idx = blk_no >> 1;
856 self.fstate.top_ctx = self.top_ctx[self.fstate.plane][mb_x * 2 + (blk_no & 1)];
857 match cr {
858 CoeffReader::None => {
859 br.decode_block(bc, &mut self.coeffs[blk_no], &self.models.coeff_models[0], &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[0], &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 * 2 + (blk_no & 1)] = self.fstate.top_ctx;
869 self.predict_dc(mb_type, mb_pos, blk_no, alpha);
870
871 let bx = mb_x * 2 + (blk_no & 1);
872 let by = mb_y * 2 + (blk_no >> 1);
873 let has_ac = self.fstate.last_idx[self.fstate.ctx_idx] > 0;
874 if mb_type.is_intra() {
875 if !self.ilace_mb {
876 if has_ac {
877 vp_put_block(&mut self.coeffs[blk_no], bx, by, self.fstate.plane, frm);
878 } else {
879 vp_put_block_dc(&mut self.coeffs[blk_no], bx, by, self.fstate.plane, frm);
880 }
881 } else {
882 vp_put_block_ilace(&mut self.coeffs[blk_no], bx, by, self.fstate.plane, frm);
883 }
884 } else {
885 if !self.ilace_mb {
886 if has_ac {
887 vp_add_block(&mut self.coeffs[blk_no], bx, by, self.fstate.plane, frm);
888 } else {
889 vp_add_block_dc(&mut self.coeffs[blk_no], bx, by, self.fstate.plane, frm);
890 }
891 } else {
892 vp_add_block_ilace(&mut self.coeffs[blk_no], bx, by, self.fstate.plane, frm);
893 }
894 }
895 }
896 if !alpha {
897 for blk_no in 4..6 {
898 self.fstate.plane = blk_no - 3;
899 self.fstate.ctx_idx = blk_no - 2;
900 self.fstate.top_ctx = self.top_ctx[self.fstate.plane][mb_x];
901 match cr {
902 CoeffReader::None => {
903 br.decode_block(bc, &mut self.coeffs[blk_no], &self.models.coeff_models[1], &self.models.vp6models, &mut self.fstate)?;
904 },
905 CoeffReader::Bool(ref mut bcc) => {
906 br.decode_block(bcc, &mut self.coeffs[blk_no], &self.models.coeff_models[1], &self.models.vp6models, &mut self.fstate)?;
907 },
908 CoeffReader::Huff(ref mut brc) => {
909 br.decode_block_huff(brc, &mut self.coeffs[blk_no], &self.models.vp6models, &self.models.vp6huff, &mut self.fstate)?;
910 },
911 };
912 self.top_ctx[self.fstate.plane][mb_x] = self.fstate.top_ctx;
913 self.predict_dc(mb_type, mb_pos, blk_no, alpha);
914
915 let has_ac = self.fstate.last_idx[self.fstate.ctx_idx] > 0;
916 if mb_type.is_intra() {
917 if has_ac {
918 vp_put_block(&mut self.coeffs[blk_no], mb_x, mb_y, self.fstate.plane, frm);
919 } else {
920 vp_put_block_dc(&mut self.coeffs[blk_no], mb_x, mb_y, self.fstate.plane, frm);
921 }
922 } else {
923 if has_ac {
924 vp_add_block(&mut self.coeffs[blk_no], mb_x, mb_y, self.fstate.plane, frm);
925 } else {
926 vp_add_block_dc(&mut self.coeffs[blk_no], mb_x, mb_y, self.fstate.plane, frm);
927 }
928 }
929 }
930 }
931 Ok(())
932 }
933 fn do_mc(&mut self, br: &dyn VP56Parser, frm: &mut NASimpleVideoFrame<u8>, mb_type: VPMBType, mv: MV, alpha: bool) {
934 let x = self.fstate.mb_x * 16;
935 let y = self.fstate.mb_y * 16;
936 let plane = if !alpha { 0 } else { 3 };
937 let src = if mb_type.get_ref_id() == VP_REF_INTER {
938 self.shuf.get_last().unwrap()
939 } else {
940 self.shuf.get_golden().unwrap()
941 };
942
943 br.mc_block(frm, self.mc_buf.clone(), src.clone(), plane, x + 0, y + 0, mv, self.loop_thr);
944 br.mc_block(frm, self.mc_buf.clone(), src.clone(), plane, x + 8, y + 0, mv, self.loop_thr);
945 br.mc_block(frm, self.mc_buf.clone(), src.clone(), plane, x + 0, y + 8, mv, self.loop_thr);
946 br.mc_block(frm, self.mc_buf.clone(), src.clone(), plane, x + 8, y + 8, mv, self.loop_thr);
947 if !alpha {
948 let x = self.fstate.mb_x * 8;
949 let y = self.fstate.mb_y * 8;
950 br.mc_block(frm, self.mc_buf.clone(), src.clone(), 1, x, y, mv, self.loop_thr);
951 br.mc_block(frm, self.mc_buf.clone(), src.clone(), 2, x, y, mv, self.loop_thr);
952 }
953 }
954 fn do_fourmv(&mut self, br: &dyn VP56Parser, frm: &mut NASimpleVideoFrame<u8>, mvs: &[MV; 4], alpha: bool) {
955 let x = self.fstate.mb_x * 16;
956 let y = self.fstate.mb_y * 16;
957 let plane = if !alpha { 0 } else { 3 };
958 let src = self.shuf.get_last().unwrap();
959 for blk_no in 0..4 {
960 br.mc_block(frm, self.mc_buf.clone(), src.clone(),
961 plane, x + (blk_no & 1) * 8, y + (blk_no & 2) * 4,
962 mvs[blk_no], self.loop_thr);
963 }
964 if !alpha {
965 let x = self.fstate.mb_x * 8;
966 let y = self.fstate.mb_y * 8;
967 let sum = mvs[0] + mvs[1] + mvs[2] + mvs[3];
968 let mv = MV { x: sum.x / 4, y: sum.y / 4 };
969 br.mc_block(frm, self.mc_buf.clone(), src.clone(), 1, x, y, mv, self.loop_thr);
970 br.mc_block(frm, self.mc_buf.clone(), src.clone(), 2, x, y, mv, self.loop_thr);
971 }
972 }
973 fn predict_dc(&mut self, mb_type: VPMBType, mb_pos: usize, blk_no: usize, alpha: bool) {
974 let mb_x = self.fstate.mb_x;
975 let is_luma = blk_no < 4;
976 let (plane, dcs) = if alpha { (0, &mut self.dc_a) } else {
977 match blk_no {
978 4 => (1, &mut self.dc_u),
979 5 => (2, &mut self.dc_v),
980 _ => (0, &mut self.dc_y),
981 }
982 };
983 let dc_pos = if is_luma {
984 dcs.xpos + mb_x * 2 + (blk_no & 1) + (blk_no >> 1) * dcs.stride
985 } else {
986 dcs.xpos + mb_x
987 };
988 let ref_id = mb_type.get_ref_id();
989 let has_left_blk = is_luma && ((blk_no & 1) != 0);
990 let has_top_blk = is_luma && ((blk_no & 2) != 0);
991 let mut dc_pred = 0;
992 let mut count = 0;
993 if has_left_blk || ((mb_x > 0) && (self.mb_info[mb_pos - 1].mb_type.get_ref_id() == ref_id)) {
994 dc_pred += dcs.data[dc_pos - 1];
995 count += 1;
996 }
997 if has_top_blk || ((mb_pos >= self.mb_w) && (self.mb_info[mb_pos - self.mb_w].mb_type.get_ref_id() == ref_id)) {
998 dc_pred += dcs.data[dc_pos - dcs.stride];
999 count += 1;
1000 }
1001 if self.version == 5 {
1002 if (count < 2) && has_left_blk {
1003 dc_pred += dc_pred;
1004 count += 1;
1005 }
1006 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) {
1007 dc_pred += dc_pred;
1008 count += 1;
1009 }
1010 if (count < 2) && mb_pos == 0 && !is_luma {
1011 count += 1;
1012 }
1013 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) {
1014 dc_pred += dcs.data[dc_pos + dcs.stride - 1];
1015 count += 1;
1016 }
1017 if (count < 2) && blk_no == 2 {
1018 dc_pred += dcs.data[dc_pos - dcs.stride + 1];
1019 count += 1;
1020 }
1021 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) {
1022 dc_pred += dcs.data[dc_pos - dcs.stride + 1];
1023 count += 1;
1024 }
1025 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) {
1026 dc_pred += dcs.data[dc_pos - dcs.stride + 1];
1027 count += 1;
1028 }
1029 }
1030 if count == 0 {
1031 dc_pred = self.last_dc[ref_id as usize][plane];
1032 } else if count == 2 {
1033 dc_pred /= 2;
1034 }
1035 self.coeffs[blk_no][0] += dc_pred;
1036 self.last_dc[ref_id as usize][plane] = self.coeffs[blk_no][0];
1037 dcs.data[dc_pos] = self.coeffs[blk_no][0];
1038 self.coeffs[blk_no][0] = self.coeffs[blk_no][0].wrapping_mul(self.fstate.dc_quant);
1039 }
1040 }
1041
1042 const VP56_DC_QUANTS: [i16; 64] = [
1043 47, 47, 47, 47, 45, 43, 43, 43,
1044 43, 43, 42, 41, 41, 40, 40, 40,
1045 40, 35, 35, 35, 35, 33, 33, 33,
1046 33, 32, 32, 32, 27, 27, 26, 26,
1047 25, 25, 24, 24, 23, 23, 19, 19,
1048 19, 19, 18, 18, 17, 16, 16, 16,
1049 16, 16, 15, 11, 11, 11, 10, 10,
1050 9, 8, 7, 5, 3, 3, 2, 2
1051 ];
1052 const VP56_AC_QUANTS: [i16; 64] = [
1053 94, 92, 90, 88, 86, 82, 78, 74,
1054 70, 66, 62, 58, 54, 53, 52, 51,
1055 50, 49, 48, 47, 46, 45, 44, 43,
1056 42, 40, 39, 37, 36, 35, 34, 33,
1057 32, 31, 30, 29, 28, 27, 26, 25,
1058 24, 23, 22, 21, 20, 19, 18, 17,
1059 16, 15, 14, 13, 12, 11, 10, 9,
1060 8, 7, 6, 5, 4, 3, 2, 1
1061 ];
1062
1063 const VP56_FILTER_LIMITS: [u8; 64] = [
1064 14, 14, 13, 13, 12, 12, 10, 10,
1065 10, 10, 8, 8, 8, 8, 8, 8,
1066 8, 8, 8, 8, 8, 8, 8, 8,
1067 8, 8, 8, 8, 8, 8, 8, 8,
1068 8, 8, 8, 8, 7, 7, 7, 7,
1069 7, 7, 6, 6, 6, 6, 6, 6,
1070 5, 5, 5, 5, 4, 4, 4, 4,
1071 4, 4, 4, 3, 3, 3, 3, 2
1072 ];
1073
1074 const VP56_MODE_VQ: [[[u8; 20]; 16]; 3] = [
1075 [
1076 [ 9, 15, 32, 25, 7, 19, 9, 21, 1, 12, 14, 12, 3, 18, 14, 23, 3, 10, 0, 4 ],
1077 [ 48, 39, 1, 2, 11, 27, 29, 44, 7, 27, 1, 4, 0, 3, 1, 6, 1, 2, 0, 0 ],
1078 [ 21, 32, 1, 2, 4, 10, 32, 43, 6, 23, 2, 3, 1, 19, 1, 6, 12, 21, 0, 7 ],
1079 [ 69, 83, 0, 0, 0, 2, 10, 29, 3, 12, 0, 1, 0, 3, 0, 3, 2, 2, 0, 0 ],
1080 [ 11, 20, 1, 4, 18, 36, 43, 48, 13, 35, 0, 2, 0, 5, 3, 12, 1, 2, 0, 0 ],
1081 [ 70, 44, 0, 1, 2, 10, 37, 46, 8, 26, 0, 2, 0, 2, 0, 2, 0, 1, 0, 0 ],
1082 [ 8, 15, 0, 1, 8, 21, 74, 53, 22, 42, 0, 1, 0, 2, 0, 3, 1, 2, 0, 0 ],
1083 [ 141, 42, 0, 0, 1, 4, 11, 24, 1, 11, 0, 1, 0, 1, 0, 2, 0, 0, 0, 0 ],
1084 [ 8, 19, 4, 10, 24, 45, 21, 37, 9, 29, 0, 3, 1, 7, 11, 25, 0, 2, 0, 1 ],
1085 [ 46, 42, 0, 1, 2, 10, 54, 51, 10, 30, 0, 2, 0, 2, 0, 1, 0, 1, 0, 0 ],
1086 [ 28, 32, 0, 0, 3, 10, 75, 51, 14, 33, 0, 1, 0, 2, 0, 1, 1, 2, 0, 0 ],
1087 [ 100, 46, 0, 1, 3, 9, 21, 37, 5, 20, 0, 1, 0, 2, 1, 2, 0, 1, 0, 0 ],
1088 [ 27, 29, 0, 1, 9, 25, 53, 51, 12, 34, 0, 1, 0, 3, 1, 5, 0, 2, 0, 0 ],
1089 [ 80, 38, 0, 0, 1, 4, 69, 33, 5, 16, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0 ],
1090 [ 16, 20, 0, 0, 2, 8, 104, 49, 15, 33, 0, 1, 0, 1, 0, 1, 1, 1, 0, 0 ],
1091 [ 194, 16, 0, 0, 1, 1, 1, 9, 1, 3, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0 ],
1092 ], [
1093 [ 41, 22, 1, 0, 1, 31, 0, 0, 0, 0, 0, 1, 1, 7, 0, 1, 98, 25, 4, 10 ],
1094 [ 123, 37, 6, 4, 1, 27, 0, 0, 0, 0, 5, 8, 1, 7, 0, 1, 12, 10, 0, 2 ],
1095 [ 26, 14, 14, 12, 0, 24, 0, 0, 0, 0, 55, 17, 1, 9, 0, 36, 5, 7, 1, 3 ],
1096 [ 209, 5, 0, 0, 0, 27, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0 ],
1097 [ 2, 5, 4, 5, 0, 121, 0, 0, 0, 0, 0, 3, 2, 4, 1, 4, 2, 2, 0, 1 ],
1098 [ 175, 5, 0, 1, 0, 48, 0, 0, 0, 0, 0, 2, 0, 1, 0, 2, 0, 1, 0, 0 ],
1099 [ 83, 5, 2, 3, 0, 102, 0, 0, 0, 0, 1, 3, 0, 2, 0, 1, 0, 0, 0, 0 ],
1100 [ 233, 6, 0, 0, 0, 8, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0 ],
1101 [ 34, 16, 112, 21, 1, 28, 0, 0, 0, 0, 6, 8, 1, 7, 0, 3, 2, 5, 0, 2 ],
1102 [ 159, 35, 2, 2, 0, 25, 0, 0, 0, 0, 3, 6, 0, 5, 0, 1, 4, 4, 0, 1 ],
1103 [ 75, 39, 5, 7, 2, 48, 0, 0, 0, 0, 3, 11, 2, 16, 1, 4, 7, 10, 0, 2 ],
1104 [ 212, 21, 0, 1, 0, 9, 0, 0, 0, 0, 1, 2, 0, 2, 0, 0, 2, 2, 0, 0 ],
1105 [ 4, 2, 0, 0, 0, 172, 0, 0, 0, 0, 0, 1, 0, 2, 0, 0, 2, 0, 0, 0 ],
1106 [ 187, 22, 1, 1, 0, 17, 0, 0, 0, 0, 3, 6, 0, 4, 0, 1, 4, 4, 0, 1 ],
1107 [ 133, 6, 1, 2, 1, 70, 0, 0, 0, 0, 0, 2, 0, 4, 0, 3, 1, 1, 0, 0 ],
1108 [ 251, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ],
1109 ], [
1110 [ 2, 3, 2, 3, 0, 2, 0, 2, 0, 0, 11, 4, 1, 4, 0, 2, 3, 2, 0, 4 ],
1111 [ 49, 46, 3, 4, 7, 31, 42, 41, 0, 0, 2, 6, 1, 7, 1, 4, 2, 4, 0, 1 ],
1112 [ 26, 25, 1, 1, 2, 10, 67, 39, 0, 0, 1, 1, 0, 14, 0, 2, 31, 26, 1, 6 ],
1113 [ 103, 46, 1, 2, 2, 10, 33, 42, 0, 0, 1, 4, 0, 3, 0, 1, 1, 3, 0, 0 ],
1114 [ 14, 31, 9, 13, 14, 54, 22, 29, 0, 0, 2, 6, 4, 18, 6, 13, 1, 5, 0, 1 ],
1115 [ 85, 39, 0, 0, 1, 9, 69, 40, 0, 0, 0, 1, 0, 3, 0, 1, 2, 3, 0, 0 ],
1116 [ 31, 28, 0, 0, 3, 14, 130, 34, 0, 0, 0, 1, 0, 3, 0, 1, 3, 3, 0, 1 ],
1117 [ 171, 25, 0, 0, 1, 5, 25, 21, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0 ],
1118 [ 17, 21, 68, 29, 6, 15, 13, 22, 0, 0, 6, 12, 3, 14, 4, 10, 1, 7, 0, 3 ],
1119 [ 51, 39, 0, 1, 2, 12, 91, 44, 0, 0, 0, 2, 0, 3, 0, 1, 2, 3, 0, 1 ],
1120 [ 81, 25, 0, 0, 2, 9, 106, 26, 0, 0, 0, 1, 0, 1, 0, 1, 1, 1, 0, 0 ],
1121 [ 140, 37, 0, 1, 1, 8, 24, 33, 0, 0, 1, 2, 0, 2, 0, 1, 1, 2, 0, 0 ],
1122 [ 14, 23, 1, 3, 11, 53, 90, 31, 0, 0, 0, 3, 1, 5, 2, 6, 1, 2, 0, 0 ],
1123 [ 123, 29, 0, 0, 1, 7, 57, 30, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0 ],
1124 [ 13, 14, 0, 0, 4, 20, 175, 20, 0, 0, 0, 1, 0, 1, 0, 1, 1, 1, 0, 0 ],
1125 [ 202, 23, 0, 0, 1, 3, 2, 9, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0 ],
1126 ]
1127 ];
1128