]> git.nihav.org Git - nihav.git/blame - nihav-duck/src/codecs/vp56.rs
avimux: do not record palette change chunks in OpenDML index
[nihav.git] / nihav-duck / src / codecs / vp56.rs
CommitLineData
3584b223
KS
1use nihav_core::codecs::*;
2use nihav_core::io::bitreader::*;
b4d5b851 3use nihav_codec_support::codecs::{MV, ZERO_MV};
3584b223
KS
4use super::vpcommon::*;
5
6pub const TOKEN_LARGE: u8 = 5;
7pub const TOKEN_EOB: u8 = 42;
8
9#[derive(Clone,Copy,Debug,Default)]
3584b223
KS
10pub 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)]
28pub 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)]
36pub struct VP56MBTypeModel {
37 pub probs: [u8; 10],
38}
39
40#[derive(Clone,Copy,Default)]
41pub struct VP56CoeffModel {
42 pub dc_token_probs: [[[u8; 5]; 6]; 6],
43 pub dc_value_probs: [u8; 11],
3584b223
KS
44 pub ac_type_probs: [[[[u8; 5]; 6]; 3]; 3],
45 pub ac_val_probs: [[[u8; 11]; 6]; 3],
46}
47
48pub struct VP6Models {
49 pub scan_order: [usize; 64],
50 pub scan: [usize; 64],
51 pub zigzag: [usize; 64],
52 pub zero_run_probs: [[u8; 14]; 2],
53}
54
55const MAX_HUFF_ELEMS: usize = 12;
56#[derive(Clone,Copy,Default)]
57pub struct VP6Huff {
58 pub codes: [u16; MAX_HUFF_ELEMS],
59 pub bits: [u8; MAX_HUFF_ELEMS],
60}
61
62#[derive(Clone,Copy,Default)]
63struct Node {
64 weight: u16,
65 sym: i8,
66 ch0: usize,
67 ch1: usize,
68}
69
70fn prob2weight(a: u8, b: u8) -> u8 {
47933c6d 71 let w = ((u16::from(a) * u16::from(b)) >> 8) as u8;
3584b223
KS
72 if w == 0 {
73 1
74 } else {
75 w
76 }
77}
78
20b5a55f 79#[allow(clippy::identity_op)]
3584b223
KS
80impl 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() {
47933c6d 134 let weight = u16::from(*w);
3584b223 135 let mut pos = nlen;
20b5a55f
KS
136 for (i, node) in nodes[..nlen].iter().enumerate() {
137 if node.weight > weight {
3584b223
KS
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
186pub trait ReadHuff {
187 fn read_huff(&mut self, huff: &VP6Huff) -> DecoderResult<u8>;
188}
189
190impl<'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() {
47933c6d
KS
194 if (peekval >> (16 - *bit)) == u32::from(*code) {
195 self.skip(u32::from(*bit))?;
3584b223
KS
196 return Ok(i as u8);
197 }
198 }
199 Err(DecoderError::InvalidData)
200 }
201}
202
203#[derive(Clone,Copy,Default)]
204pub 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
210impl 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
221pub 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
230impl 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
243pub 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
254enum CoeffReader<'a> {
255 None,
256 Bool(BoolCoder<'a>),
257 Huff(BitReader<'a>),
258}
259
260#[derive(Clone,Copy,Default)]
261struct MBInfo {
262 mb_type: VPMBType,
263 mv: MV,
264}
265
266pub 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
280impl 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
13078a1f
KS
298#[derive(Default)]
299pub 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
313const INVALID_REF: u8 = 42;
314
315impl 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
3584b223
KS
344pub 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,
6d48a381 354 amodels: VP56Models,
3584b223
KS
355 coeffs: [[i16; 64]; 6],
356 last_mbt: VPMBType,
357
358 loop_thr: i16,
359 ilace_prob: u8,
360 ilace_mb: bool,
361
362 mb_info: Vec<MBInfo>,
363 fstate: FrameState,
13078a1f 364 dc_pred: VP56DCPred,
3584b223
KS
365 last_dc: [[i16; 4]; 3],
366 top_ctx: [Vec<u8>; 4],
367
368 mc_buf: NAVideoBufferRef<u8>,
369}
370
371fn rescale_mb_mode_prob(prob: u32, total: u32) -> u8 {
372 (255 * prob / (1 + total)) as u8
373}
374
375fn map_mb_type(mbtype: VPMBType) -> usize {
376 match mbtype {
377 VPMBType::InterNoMV => 0,
378 VPMBType::Intra => 1,
379 VPMBType::InterMV => 2,
380 VPMBType::InterNearest => 3,
381 VPMBType::InterNear => 4,
382 VPMBType::GoldenNoMV => 5,
383 VPMBType::GoldenMV => 6,
384 VPMBType::InterFourMV => 7,
385 VPMBType::GoldenNearest => 8,
386 VPMBType::GoldenNear => 9,
387 }
388}
389
3584b223 390pub fn expand_token_bc(bc: &mut BoolCoder, val_probs: &[u8; 11], token: u8, version: u8) -> i16 {
3584b223
KS
391 let mut sign = false;
392 let level;
393 if token < TOKEN_LARGE {
394 if token != 0 {
395 sign = bc.read_bool();
396 }
47933c6d 397 level = i16::from(token);
3584b223
KS
398 } else {
399 let cat: usize = vp_tree!(bc, val_probs[6],
400 vp_tree!(bc, val_probs[7], 0, 1),
401 vp_tree!(bc, val_probs[8],
402 vp_tree!(bc, val_probs[9], 2, 3),
403 vp_tree!(bc, val_probs[10], 4, 5)));
404 if version == 5 {
405 sign = bc.read_bool();
406 }
407 let mut add = 0i16;
3f67638d 408 let add_probs = &VP56_COEF_ADD_PROBS[cat];
3584b223
KS
409 for prob in add_probs.iter() {
410 if *prob == 128 { break; }
411 add = (add << 1) | (bc.read_prob(*prob) as i16);
412 }
413 if version != 5 {
414 sign = bc.read_bool();
415 }
416 level = VP56_COEF_BASE[cat] + add;
417 }
418 if !sign {
419 level
420 } else {
421 -level
422 }
423}
424
425impl VP56Decoder {
426 pub fn new(version: u8, has_alpha: bool, flip: bool) -> Self {
93bbc2b0 427 let vt = alloc_video_buffer(NAVideoInfo::new(24, 24, false, VP_YUVA420_FORMAT), 4).unwrap();
3584b223
KS
428 let mc_buf = vt.get_vbuf().unwrap();
429 Self {
430 version, has_alpha, flip,
431 shuf: VPShuffler::new(),
432 width: 0,
433 height: 0,
434 mb_w: 0,
435 mb_h: 0,
436 models: VP56Models::new(),
6d48a381 437 amodels: VP56Models::new(),
3584b223
KS
438 coeffs: [[0; 64]; 6],
439 last_mbt: VPMBType::InterNoMV,
440
441 loop_thr: 0,
442 ilace_prob: 0,
443 ilace_mb: false,
444
445 mb_info: Vec::new(),
446 fstate: FrameState::new(),
13078a1f 447 dc_pred: VP56DCPred::new(),
3584b223
KS
448 last_dc: [[0; 4]; 3],
449 top_ctx: [Vec::new(), Vec::new(), Vec::new(), Vec::new()],
450
451 mc_buf,
452 }
453 }
454 fn set_dimensions(&mut self, width: usize, height: usize) {
455 self.width = width;
456 self.height = height;
457 self.mb_w = (self.width + 15) >> 4;
458 self.mb_h = (self.height + 15) >> 4;
459 self.mb_info.resize(self.mb_w * self.mb_h, MBInfo::default());
3584b223
KS
460 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]];
461 }
462 pub fn init(&mut self, supp: &mut NADecoderSupport, vinfo: NAVideoInfo) -> DecoderResult<()> {
8dd7f679 463 supp.pool_u8.set_dec_bufs(3 + if vinfo.get_format().has_alpha() { 1 } else { 0 });
3584b223
KS
464 supp.pool_u8.prealloc_video(NAVideoInfo::new(vinfo.get_width(), vinfo.get_height(), false, vinfo.get_format()), 4)?;
465 self.set_dimensions(vinfo.get_width(), vinfo.get_height());
13078a1f 466 self.dc_pred.resize(self.mb_w);
3584b223
KS
467 Ok(())
468 }
f9be4e75
KS
469 pub fn flush(&mut self) {
470 self.shuf.clear();
471 }
20b5a55f 472 #[allow(clippy::collapsible_else_if)]
3584b223
KS
473 pub fn decode_frame(&mut self, supp: &mut NADecoderSupport, src: &[u8], br: &mut dyn VP56Parser) -> DecoderResult<(NABufferType, FrameType)> {
474 let aoffset;
475 let mut bc;
476 if self.has_alpha {
477 validate!(src.len() >= 7);
478 aoffset = ((src[0] as usize) << 16) | ((src[1] as usize) << 8) | (src[2] as usize);
479 validate!((aoffset > 0) && (aoffset < src.len() - 3));
480 bc = BoolCoder::new(&src[3..])?;
481 } else {
482 validate!(src.len() >= 4);
483 aoffset = src.len();
484 bc = BoolCoder::new(src)?;
485 }
486 let hdr = br.parse_header(&mut bc)?;
487 validate!((hdr.offset as usize) < aoffset); //XXX: take alpha 3 byte offset into account?
488
92d9fb69 489 if hdr.mb_w != 0 && (usize::from(hdr.mb_w) != self.mb_w || usize::from(hdr.mb_h) != self.mb_h) {
3584b223
KS
490 self.set_dimensions((hdr.mb_w as usize) * 16, (hdr.mb_h as usize) * 16);
491 }
93bbc2b0
KS
492 let fmt = if !self.has_alpha {
493 YUV420_FORMAT
494 } else {
495 VP_YUVA420_FORMAT
496 };
497 let vinfo = NAVideoInfo::new(self.width, self.height, self.flip, fmt);
3584b223
KS
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();
6e24ec0b
KS
517 } else {
518 if !self.shuf.has_refs() {
519 return Err(DecoderError::MissingReference);
520 }
3584b223
KS
521 }
522
6d48a381
KS
523 let psrc = &src[if self.has_alpha { 3 } else { 0 }..aoffset];
524 self.decode_planes(br, &mut dframe, &mut bc, &hdr, psrc, false)?;
525
526 if self.has_alpha {
527 let asrc = &src[aoffset + 3..];
528 let mut bc = BoolCoder::new(asrc)?;
529 let ahdr = br.parse_header(&mut bc)?;
530 validate!(ahdr.mb_w == hdr.mb_w && ahdr.mb_h == hdr.mb_h);
531 std::mem::swap(&mut self.models, &mut self.amodels);
532 let ret = self.decode_planes(br, &mut dframe, &mut bc, &ahdr, asrc, true);
533 std::mem::swap(&mut self.models, &mut self.amodels);
e6aaad5c 534 ret?;
8dd7f679
KS
535 match (hdr.is_golden, ahdr.is_golden) {
536 (true, true) => { self.shuf.add_golden_frame(buf.clone()); },
537 (true, false) => {
538 let cur_golden = self.shuf.get_golden().unwrap();
539 let off = cur_golden.get_offset(3);
540 let stride = cur_golden.get_stride(3);
541 let mut new_golden = supp.pool_u8.get_copy(&buf).unwrap();
542 let dst = new_golden.get_data_mut().unwrap();
543 let src = cur_golden.get_data();
544 dst[off..][..stride * self.mb_h * 16].copy_from_slice(&src[off..][..stride * self.mb_h * 16]);
545 self.shuf.add_golden_frame(new_golden);
546 },
547 (false, true) => {
548 let cur_golden = self.shuf.get_golden().unwrap();
549 let off = cur_golden.get_offset(3);
550 let stride = cur_golden.get_stride(3);
551 let mut new_golden = supp.pool_u8.get_copy(&cur_golden).unwrap();
552 let dst = new_golden.get_data_mut().unwrap();
553 let src = buf.get_data();
554 dst[off..][..stride * self.mb_h * 16].copy_from_slice(&src[off..][..stride * self.mb_h * 16]);
555 self.shuf.add_golden_frame(new_golden);
556 },
557 _ => {},
558 };
6d48a381
KS
559 }
560
8dd7f679 561 if hdr.is_golden && !self.has_alpha {
6d48a381
KS
562 self.shuf.add_golden_frame(buf.clone());
563 }
564 self.shuf.add_frame(buf.clone());
565
566 Ok((NABufferType::Video(buf), if hdr.is_intra { FrameType::I } else { FrameType::P }))
567 }
568 fn decode_planes(&mut self, br: &mut dyn VP56Parser, dframe: &mut NASimpleVideoFrame<u8>, bc: &mut BoolCoder, hdr: &VP56Header, src: &[u8], alpha: bool) -> DecoderResult<()> {
3584b223
KS
569 let mut cr;
570 if hdr.multistream {
6d48a381 571 let off = hdr.offset as usize;
3584b223
KS
572 if !hdr.use_huffman {
573 let bc2 = BoolCoder::new(&src[off..])?;
574 cr = CoeffReader::Bool(bc2);
575 } else {
6d48a381 576 let br = BitReader::new(&src[off..], BitReaderMode::BE);
3584b223
KS
577 cr = CoeffReader::Huff(br);
578 }
579 } else {
580 cr = CoeffReader::None;
581 }
582
583 if hdr.is_intra {
584 br.reset_models(&mut self.models);
585 self.reset_mbtype_models();
586 } else {
6d48a381
KS
587 self.decode_mode_prob_models(bc)?;
588 br.decode_mv_models(bc, &mut self.models.mv_models)?;
3584b223 589 }
6d48a381 590 br.decode_coeff_models(bc, &mut self.models, hdr.is_intra)?;
3584b223
KS
591 if hdr.use_huffman {
592 for i in 0..2 {
593 self.models.vp6huff.dc_token_tree[i].build_codes(&self.models.coeff_models[i].dc_value_probs);
594 }
595 for i in 0..2 {
596 for mode in 0..3 {
597 for band in 0..6 {
598 self.models.vp6huff.ac_token_tree[i][mode][band].build_codes(&self.models.coeff_models[i].ac_val_probs[mode][band]);
599 }
600 }
601 }
602 for i in 0..2 {
603 self.models.vp6huff.zero_run_tree[i].build_codes_zero_run(&self.models.vp6models.zero_run_probs[i]);
604 }
605 }
606
607 if hdr.interlaced {
608 self.ilace_prob = bc.read_bits(8) as u8;
609 }
610
611 self.fstate = FrameState::new();
612 self.fstate.dc_quant = VP56_DC_QUANTS[hdr.quant as usize] * 4;
613 self.fstate.ac_quant = VP56_AC_QUANTS[hdr.quant as usize] * 4;
47933c6d 614 self.loop_thr = i16::from(VP56_FILTER_LIMITS[hdr.quant as usize]);
3584b223
KS
615
616 self.last_mbt = VPMBType::InterNoMV;
3584b223
KS
617 for vec in self.top_ctx.iter_mut() {
618 for el in vec.iter_mut() {
619 *el = 0;
620 }
621 }
622 self.last_dc = [[0; 4]; 3];
623 self.last_dc[0][1] = 0x80;
624 self.last_dc[0][2] = 0x80;
13078a1f 625 self.dc_pred.reset();
3584b223
KS
626
627 self.ilace_mb = false;
628 for mb_y in 0..self.mb_h {
629 self.fstate.mb_y = mb_y;
630 self.fstate.coeff_cat = [[0; 64]; 4];
631 self.fstate.last_idx = [24; 4];
632 for mb_x in 0..self.mb_w {
633 self.fstate.mb_x = mb_x;
6f263099 634 self.decode_mb(dframe, bc, &mut cr, br, hdr, alpha)?;
13078a1f 635 self.dc_pred.next_mb();
3584b223 636 }
13078a1f 637 self.dc_pred.update_row();
3584b223 638 }
6d48a381 639 Ok(())
3584b223
KS
640 }
641 fn reset_mbtype_models(&mut self) {
642 const DEFAULT_XMITTED_PROBS: [[u8; 20]; 3] = [
643 [ 42, 69, 2, 1, 7, 1, 42, 44, 22, 6, 3, 1, 2, 0, 5, 1, 1, 0, 0, 0 ],
644 [ 8, 229, 1, 1, 8, 0, 0, 0, 0, 0, 2, 1, 1, 0, 0, 0, 1, 1, 0, 0 ],
645 [ 35, 122, 1, 1, 6, 1, 34, 46, 0, 0, 2, 1, 1, 0, 1, 0, 1, 1, 0, 0 ]
646 ];
647 self.models.prob_xmitted.copy_from_slice(&DEFAULT_XMITTED_PROBS);
648 }
649 fn decode_mode_prob_models(&mut self, bc: &mut BoolCoder) -> DecoderResult<()> {
20b5a55f 650 for (prob_xmitted, vq_modes) in self.models.prob_xmitted.iter_mut().zip(VP56_MODE_VQ.iter()) {
3584b223
KS
651 if bc.read_prob(174) {
652 let idx = bc.read_bits(4) as usize;
20b5a55f
KS
653 for (i, &vq_mode) in vq_modes[idx].iter().enumerate() {
654 prob_xmitted[i ^ 1] = vq_mode;
3584b223
KS
655 }
656 }
657 if bc.read_prob(254) {
658 for set in 0..20 {
659 if bc.read_prob(205) {
660 let sign = bc.read_bool();
661 let diff = vp_tree!(bc, 171,
662 vp_tree!(bc, 83, 2, 1),
663 vp_tree!(bc, 199,
664 vp_tree!(bc, 140,
665 vp_tree!(bc, 125,
666 vp_tree!(bc, 104, 6, 5),
667 4
668 ),
669 3
670 ),
671 bc.read_bits(7)
672 )) * 4;
673 validate!(diff < 256);
674 let diff = diff as u8;
675 if !sign {
20b5a55f
KS
676 validate!(prob_xmitted[set ^ 1] <= 255 - diff);
677 prob_xmitted[set ^ 1] += diff;
3584b223 678 } else {
20b5a55f
KS
679 validate!(prob_xmitted[set ^ 1] >= diff);
680 prob_xmitted[set ^ 1] -= diff;
3584b223
KS
681 }
682 }
683 }
684 }
685 }
20b5a55f
KS
686 for (prob_xmitted, mbtype_models) in self.models.prob_xmitted.iter()
687 .zip(self.models.mbtype_models.iter_mut()) {
688 for (mode, mdl) in mbtype_models.iter_mut().enumerate() {
3584b223
KS
689 let mut cnt = [0u32; 10];
690 let mut total = 0;
691 for i in 0..10 {
692 if i == mode { continue; }
47933c6d 693 cnt[i] = 100 * u32::from(prob_xmitted[i * 2]);
3584b223
KS
694 total += cnt[i];
695 }
47933c6d
KS
696 let sum = u32::from(prob_xmitted[mode * 2]) + u32::from(prob_xmitted[mode * 2 + 1]);
697 mdl.probs[9] = 255 - rescale_mb_mode_prob(u32::from(prob_xmitted[mode * 2 + 1]), sum);
3584b223 698
e6aaad5c
KS
699 let inter_mv0_weight = cnt[0] + cnt[2];
700 let inter_mv1_weight = cnt[3] + cnt[4];
701 let gold_mv0_weight = cnt[5] + cnt[6];
702 let gold_mv1_weight = cnt[8] + cnt[9];
703 let mix_weight = cnt[1] + cnt[7];
3584b223
KS
704 mdl.probs[0] = 1 + rescale_mb_mode_prob(inter_mv0_weight + inter_mv1_weight, total);
705 mdl.probs[1] = 1 + rescale_mb_mode_prob(inter_mv0_weight, inter_mv0_weight + inter_mv1_weight);
706 mdl.probs[2] = 1 + rescale_mb_mode_prob(mix_weight, mix_weight + gold_mv0_weight + gold_mv1_weight);
e6aaad5c
KS
707 mdl.probs[3] = 1 + rescale_mb_mode_prob(cnt[0], inter_mv0_weight);
708 mdl.probs[4] = 1 + rescale_mb_mode_prob(cnt[3], inter_mv1_weight);
3584b223
KS
709 mdl.probs[5] = 1 + rescale_mb_mode_prob(cnt[1], mix_weight);
710 mdl.probs[6] = 1 + rescale_mb_mode_prob(gold_mv0_weight, gold_mv0_weight + gold_mv1_weight);
711 mdl.probs[7] = 1 + rescale_mb_mode_prob(cnt[5], gold_mv0_weight);
712 mdl.probs[8] = 1 + rescale_mb_mode_prob(cnt[8], gold_mv1_weight);
713 }
714 }
715 Ok(())
716 }
717 fn find_mv_pred(&self, ref_id: u8) -> (usize, MV, MV, MV) {
718 const CAND_POS: [(i8, i8); 12] = [
719 (-1, 0), ( 0, -1),
720 (-1, -1), (-1, 1),
721 (-2, 0), ( 0, -2),
722 (-1, -2), (-2, -1),
723 (-2, 1), (-1, 2),
724 (-2, -2), (-2, 2)
725 ];
726
727 let mut nearest_mv = ZERO_MV;
728 let mut near_mv = ZERO_MV;
729 let mut pred_mv = ZERO_MV;
730 let mut num_mv: usize = 0;
731
732 for (i, (yoff, xoff)) in CAND_POS.iter().enumerate() {
733 let cx = (self.fstate.mb_x as isize) + (*xoff as isize);
734 let cy = (self.fstate.mb_y as isize) + (*yoff as isize);
735 if (cx < 0) || (cy < 0) {
736 continue;
737 }
738 let cx = cx as usize;
739 let cy = cy as usize;
740 if (cx >= self.mb_w) || (cy >= self.mb_h) {
741 continue;
742 }
743 let mb_pos = cx + cy * self.mb_w;
744 let mv = self.mb_info[mb_pos].mv;
745 if (self.mb_info[mb_pos].mb_type.get_ref_id() != ref_id) || (mv == ZERO_MV) {
746 continue;
747 }
748 if num_mv == 0 {
749 nearest_mv = mv;
750 num_mv += 1;
751 if (self.version > 5) && (i < 2) {
752 pred_mv = mv;
753 }
754 } else if mv != nearest_mv {
755 near_mv = mv;
756 num_mv += 1;
757 break;
758 }
759 }
760
761 (num_mv, nearest_mv, near_mv, pred_mv)
762 }
763 fn decode_mv(&self, bc: &mut BoolCoder, br: &mut dyn VP56Parser) -> MV {
764 let x = br.decode_mv(bc, &self.models.mv_models[0]);
765 let y = br.decode_mv(bc, &self.models.mv_models[1]);
766 MV{ x, y }
767 }
768 fn decode_mb_type(&mut self, bc: &mut BoolCoder, ctx: usize) -> DecoderResult<VPMBType> {
769 let probs = &self.models.mbtype_models[ctx][map_mb_type(self.last_mbt)].probs;
770 if !bc.read_prob(probs[9]) {
771 self.last_mbt = vp_tree!(
772 bc, probs[0],
773 vp_tree!(bc, probs[1],
774 vp_tree!(bc, probs[3], VPMBType::InterNoMV, VPMBType::InterMV),
775 vp_tree!(bc, probs[4], VPMBType::InterNearest, VPMBType::InterNear)
776 ),
777 vp_tree!(bc, probs[2],
778 vp_tree!(bc, probs[5], VPMBType::Intra, VPMBType::InterFourMV),
779 vp_tree!(bc, probs[6],
780 vp_tree!(bc, probs[7], VPMBType::GoldenNoMV, VPMBType::GoldenMV),
dd72b2d4 781 vp_tree!(bc, probs[8], VPMBType::GoldenNearest, VPMBType::GoldenNear)
3584b223
KS
782 )
783 )
784 );
785 }
786 Ok(self.last_mbt)
787 }
b7c882c1 788 #[allow(clippy::cognitive_complexity)]
20b5a55f 789 #[allow(clippy::collapsible_else_if)]
3584b223
KS
790 fn decode_mb(&mut self, frm: &mut NASimpleVideoFrame<u8>, bc: &mut BoolCoder, cr: &mut CoeffReader, br: &mut dyn VP56Parser, hdr: &VP56Header, alpha: bool) -> DecoderResult<()> {
791 const FOURMV_SUB_TYPE: [VPMBType; 4] = [ VPMBType::InterNoMV, VPMBType::InterMV, VPMBType::InterNearest, VPMBType::InterNear ];
792
793 let mb_x = self.fstate.mb_x;
794 let mb_y = self.fstate.mb_y;
795 self.coeffs = [[0; 64]; 6];
796 let mb_pos = mb_x + mb_y * self.mb_w;
797 let mut four_mv = [ZERO_MV; 4];
798 let mut four_mbt = [VPMBType::Intra; 4];
799
800 if hdr.interlaced {
801 let iprob = self.ilace_prob;
802 let prob = if mb_x == 0 {
803 iprob
804 } else if !self.ilace_mb {
47933c6d 805 iprob + (((256 - u16::from(iprob)) >> 1) as u8)
3584b223
KS
806 } else {
807 iprob - (iprob >> 1)
808 };
809 self.ilace_mb = bc.read_prob(prob);
810 }
811
812 let (num_mv, nearest_mv, near_mv, pred_mv) = if hdr.is_intra {
813 (0, ZERO_MV, ZERO_MV, ZERO_MV)
814 } else { self.find_mv_pred(VP_REF_INTER) };
815 let mb_type = if hdr.is_intra {
816 VPMBType::Intra
817 } else {
818 self.decode_mb_type(bc, (num_mv + 1) % 3)?
819 };
820 self.mb_info[mb_pos].mb_type = mb_type;
821 if mb_type.get_ref_id() != VP_REF_GOLDEN {
822 match mb_type {
823 VPMBType::Intra |
824 VPMBType::InterNoMV => {
825 self.mb_info[mb_pos].mv = ZERO_MV;
826 },
827 VPMBType::InterMV => {
828 let diff_mv = self.decode_mv(bc, br);
829 self.mb_info[mb_pos].mv = pred_mv + diff_mv;
830 },
831 VPMBType::InterNearest => {
832 self.mb_info[mb_pos].mv = nearest_mv;
833 },
834 VPMBType::InterNear => {
835 self.mb_info[mb_pos].mv = near_mv;
836 },
837 VPMBType::InterFourMV => {
20b5a55f
KS
838 for mbt in four_mbt.iter_mut() {
839 *mbt = FOURMV_SUB_TYPE[bc.read_bits(2) as usize];
3584b223 840 }
20b5a55f
KS
841 for (&mbt, mv) in four_mbt.iter().zip(four_mv.iter_mut()) {
842 match mbt {
3584b223
KS
843 VPMBType::InterNoMV => {},
844 VPMBType::InterMV => {
845 let diff_mv = self.decode_mv(bc, br);
20b5a55f 846 *mv = pred_mv + diff_mv;
3584b223
KS
847 },
848 VPMBType::InterNearest => {
20b5a55f 849 *mv = nearest_mv;
3584b223
KS
850 },
851 VPMBType::InterNear => {
20b5a55f 852 *mv = near_mv;
3584b223
KS
853 },
854 _ => unreachable!(),
855 };
856 }
857 self.mb_info[mb_pos].mv = four_mv[3];
858 },
859 _ => unreachable!(),
860 };
861 } else {
862 let (_num_mv, nearest_mv, near_mv, pred_mv) = self.find_mv_pred(VP_REF_GOLDEN);
863 match mb_type {
864 VPMBType::GoldenNoMV => {
865 self.mb_info[mb_pos].mv = ZERO_MV;
866 },
867 VPMBType::GoldenMV => {
868 let diff_mv = self.decode_mv(bc, br);
869 self.mb_info[mb_pos].mv = pred_mv + diff_mv;
870 },
871 VPMBType::GoldenNearest => {
872 self.mb_info[mb_pos].mv = nearest_mv;
873 },
874 VPMBType::GoldenNear => {
875 self.mb_info[mb_pos].mv = near_mv;
876 },
877 _ => unreachable!(),
878 };
879 }
880 if !mb_type.is_intra() && (mb_type != VPMBType::InterFourMV) {
881 self.do_mc(br, frm, mb_type, self.mb_info[mb_pos].mv, alpha);
882 } else if mb_type == VPMBType::InterFourMV {
883 self.do_fourmv(br, frm, &four_mv, alpha);
884 }
885
886 for blk_no in 0..4 {
887 self.fstate.plane = if !alpha { 0 } else { 3 };
888 self.fstate.ctx_idx = blk_no >> 1;
889 self.fstate.top_ctx = self.top_ctx[self.fstate.plane][mb_x * 2 + (blk_no & 1)];
890 match cr {
891 CoeffReader::None => {
892 br.decode_block(bc, &mut self.coeffs[blk_no], &self.models.coeff_models[0], &self.models.vp6models, &mut self.fstate)?;
893 },
894 CoeffReader::Bool(ref mut bcc) => {
895 br.decode_block(bcc, &mut self.coeffs[blk_no], &self.models.coeff_models[0], &self.models.vp6models, &mut self.fstate)?;
896 },
897 CoeffReader::Huff(ref mut brc) => {
898 br.decode_block_huff(brc, &mut self.coeffs[blk_no], &self.models.vp6models, &self.models.vp6huff, &mut self.fstate)?;
899 },
900 };
901 self.top_ctx[self.fstate.plane][mb_x * 2 + (blk_no & 1)] = self.fstate.top_ctx;
902 self.predict_dc(mb_type, mb_pos, blk_no, alpha);
903
904 let bx = mb_x * 2 + (blk_no & 1);
905 let by = mb_y * 2 + (blk_no >> 1);
906 let has_ac = self.fstate.last_idx[self.fstate.ctx_idx] > 0;
907 if mb_type.is_intra() {
908 if !self.ilace_mb {
909 if has_ac {
910 vp_put_block(&mut self.coeffs[blk_no], bx, by, self.fstate.plane, frm);
911 } else {
912 vp_put_block_dc(&mut self.coeffs[blk_no], bx, by, self.fstate.plane, frm);
913 }
914 } else {
915 vp_put_block_ilace(&mut self.coeffs[blk_no], bx, by, self.fstate.plane, frm);
916 }
917 } else {
918 if !self.ilace_mb {
919 if has_ac {
920 vp_add_block(&mut self.coeffs[blk_no], bx, by, self.fstate.plane, frm);
921 } else {
922 vp_add_block_dc(&mut self.coeffs[blk_no], bx, by, self.fstate.plane, frm);
923 }
924 } else {
925 vp_add_block_ilace(&mut self.coeffs[blk_no], bx, by, self.fstate.plane, frm);
926 }
927 }
928 }
6d48a381
KS
929 for blk_no in 4..6 {
930 self.fstate.plane = blk_no - 3;
931 self.fstate.ctx_idx = blk_no - 2;
932 self.fstate.top_ctx = self.top_ctx[self.fstate.plane][mb_x];
933 match cr {
934 CoeffReader::None => {
935 br.decode_block(bc, &mut self.coeffs[blk_no], &self.models.coeff_models[1], &self.models.vp6models, &mut self.fstate)?;
936 },
937 CoeffReader::Bool(ref mut bcc) => {
938 br.decode_block(bcc, &mut self.coeffs[blk_no], &self.models.coeff_models[1], &self.models.vp6models, &mut self.fstate)?;
939 },
940 CoeffReader::Huff(ref mut brc) => {
941 br.decode_block_huff(brc, &mut self.coeffs[blk_no], &self.models.vp6models, &self.models.vp6huff, &mut self.fstate)?;
942 },
943 };
944 self.top_ctx[self.fstate.plane][mb_x] = self.fstate.top_ctx;
945 self.predict_dc(mb_type, mb_pos, blk_no, alpha);
946 if !alpha {
3584b223
KS
947 let has_ac = self.fstate.last_idx[self.fstate.ctx_idx] > 0;
948 if mb_type.is_intra() {
949 if has_ac {
950 vp_put_block(&mut self.coeffs[blk_no], mb_x, mb_y, self.fstate.plane, frm);
951 } else {
952 vp_put_block_dc(&mut self.coeffs[blk_no], mb_x, mb_y, self.fstate.plane, frm);
953 }
954 } else {
955 if has_ac {
956 vp_add_block(&mut self.coeffs[blk_no], mb_x, mb_y, self.fstate.plane, frm);
957 } else {
958 vp_add_block_dc(&mut self.coeffs[blk_no], mb_x, mb_y, self.fstate.plane, frm);
959 }
960 }
961 }
962 }
963 Ok(())
964 }
20b5a55f 965 #[allow(clippy::identity_op)]
3584b223
KS
966 fn do_mc(&mut self, br: &dyn VP56Parser, frm: &mut NASimpleVideoFrame<u8>, mb_type: VPMBType, mv: MV, alpha: bool) {
967 let x = self.fstate.mb_x * 16;
968 let y = self.fstate.mb_y * 16;
969 let plane = if !alpha { 0 } else { 3 };
970 let src = if mb_type.get_ref_id() == VP_REF_INTER {
971 self.shuf.get_last().unwrap()
972 } else {
973 self.shuf.get_golden().unwrap()
974 };
975
976 br.mc_block(frm, self.mc_buf.clone(), src.clone(), plane, x + 0, y + 0, mv, self.loop_thr);
977 br.mc_block(frm, self.mc_buf.clone(), src.clone(), plane, x + 8, y + 0, mv, self.loop_thr);
978 br.mc_block(frm, self.mc_buf.clone(), src.clone(), plane, x + 0, y + 8, mv, self.loop_thr);
979 br.mc_block(frm, self.mc_buf.clone(), src.clone(), plane, x + 8, y + 8, mv, self.loop_thr);
980 if !alpha {
981 let x = self.fstate.mb_x * 8;
982 let y = self.fstate.mb_y * 8;
983 br.mc_block(frm, self.mc_buf.clone(), src.clone(), 1, x, y, mv, self.loop_thr);
b7c882c1 984 br.mc_block(frm, self.mc_buf.clone(), src, 2, x, y, mv, self.loop_thr);
3584b223
KS
985 }
986 }
987 fn do_fourmv(&mut self, br: &dyn VP56Parser, frm: &mut NASimpleVideoFrame<u8>, mvs: &[MV; 4], alpha: bool) {
988 let x = self.fstate.mb_x * 16;
989 let y = self.fstate.mb_y * 16;
990 let plane = if !alpha { 0 } else { 3 };
991 let src = self.shuf.get_last().unwrap();
20b5a55f 992 for (blk_no, &mv) in mvs.iter().enumerate() {
3584b223
KS
993 br.mc_block(frm, self.mc_buf.clone(), src.clone(),
994 plane, x + (blk_no & 1) * 8, y + (blk_no & 2) * 4,
20b5a55f 995 mv, self.loop_thr);
3584b223
KS
996 }
997 if !alpha {
998 let x = self.fstate.mb_x * 8;
999 let y = self.fstate.mb_y * 8;
1000 let sum = mvs[0] + mvs[1] + mvs[2] + mvs[3];
1001 let mv = MV { x: sum.x / 4, y: sum.y / 4 };
1002 br.mc_block(frm, self.mc_buf.clone(), src.clone(), 1, x, y, mv, self.loop_thr);
b7c882c1 1003 br.mc_block(frm, self.mc_buf.clone(), src, 2, x, y, mv, self.loop_thr);
3584b223
KS
1004 }
1005 }
13078a1f 1006 fn predict_dc(&mut self, mb_type: VPMBType, _mb_pos: usize, blk_no: usize, _alpha: bool) {
3584b223 1007 let is_luma = blk_no < 4;
13078a1f
KS
1008 let (plane, dcs) = match blk_no {
1009 4 => (1, &mut self.dc_pred.dc_u),
1010 5 => (2, &mut self.dc_pred.dc_v),
1011 _ => (0, &mut self.dc_pred.dc_y),
3584b223 1012 };
13078a1f
KS
1013 let (dc_ref, dc_idx) = if is_luma {
1014 (&mut self.dc_pred.ref_y, self.dc_pred.y_idx + (blk_no & 1))
3584b223 1015 } else {
13078a1f 1016 (&mut self.dc_pred.ref_c, self.dc_pred.c_idx)
3584b223
KS
1017 };
1018 let ref_id = mb_type.get_ref_id();
3584b223
KS
1019 let mut dc_pred = 0;
1020 let mut count = 0;
13078a1f
KS
1021 let has_left_blk = is_luma && ((blk_no & 1) == 1);
1022 if has_left_blk || self.dc_pred.ref_left == ref_id {
1023 dc_pred += match blk_no {
1024 0 | 1 => self.dc_pred.ldc_y[0],
1025 2 | 3 => self.dc_pred.ldc_y[1],
1026 4 => self.dc_pred.ldc_u,
1027 _ => self.dc_pred.ldc_v,
1028 };
3584b223
KS
1029 count += 1;
1030 }
13078a1f
KS
1031 if dc_ref[dc_idx] == ref_id {
1032 dc_pred += dcs[dc_idx];
3584b223
KS
1033 count += 1;
1034 }
1035 if self.version == 5 {
13078a1f
KS
1036 if (count < 2) && (dc_ref[dc_idx - 1] == ref_id) {
1037 dc_pred += dcs[dc_idx - 1];
3584b223
KS
1038 count += 1;
1039 }
13078a1f
KS
1040 if (count < 2) && (dc_ref[dc_idx + 1] == ref_id) {
1041 dc_pred += dcs[dc_idx + 1];
3584b223
KS
1042 count += 1;
1043 }
1044 }
1045 if count == 0 {
1046 dc_pred = self.last_dc[ref_id as usize][plane];
1047 } else if count == 2 {
1048 dc_pred /= 2;
1049 }
1050 self.coeffs[blk_no][0] += dc_pred;
13078a1f
KS
1051
1052 let dc = self.coeffs[blk_no][0];
1053 if blk_no != 4 { // update top block reference only for the second chroma component
1054 dc_ref[dc_idx] = ref_id;
1055 }
1056 match blk_no {
1057 0 | 1 => {
1058 self.dc_pred.ldc_y[0] = dc;
1059 },
1060 2 | 3 => {
1061 self.dc_pred.ldc_y[1] = dc;
1062 },
1063 4 => {
1064 self.dc_pred.ldc_u = dc;
1065 },
1066 _ => {
1067 self.dc_pred.ldc_v = dc;
1068 self.dc_pred.ref_left = ref_id;
1069 },
1070 };
1071 dcs[dc_idx] = dc;
1072
1073 self.last_dc[ref_id as usize][plane] = dc;
3584b223
KS
1074 self.coeffs[blk_no][0] = self.coeffs[blk_no][0].wrapping_mul(self.fstate.dc_quant);
1075 }
1076}
1077
1078const VP56_DC_QUANTS: [i16; 64] = [
1079 47, 47, 47, 47, 45, 43, 43, 43,
1080 43, 43, 42, 41, 41, 40, 40, 40,
1081 40, 35, 35, 35, 35, 33, 33, 33,
1082 33, 32, 32, 32, 27, 27, 26, 26,
1083 25, 25, 24, 24, 23, 23, 19, 19,
1084 19, 19, 18, 18, 17, 16, 16, 16,
1085 16, 16, 15, 11, 11, 11, 10, 10,
1086 9, 8, 7, 5, 3, 3, 2, 2
1087];
1088const VP56_AC_QUANTS: [i16; 64] = [
1089 94, 92, 90, 88, 86, 82, 78, 74,
1090 70, 66, 62, 58, 54, 53, 52, 51,
1091 50, 49, 48, 47, 46, 45, 44, 43,
1092 42, 40, 39, 37, 36, 35, 34, 33,
1093 32, 31, 30, 29, 28, 27, 26, 25,
1094 24, 23, 22, 21, 20, 19, 18, 17,
1095 16, 15, 14, 13, 12, 11, 10, 9,
1096 8, 7, 6, 5, 4, 3, 2, 1
1097];
1098
1099const VP56_FILTER_LIMITS: [u8; 64] = [
1100 14, 14, 13, 13, 12, 12, 10, 10,
1101 10, 10, 8, 8, 8, 8, 8, 8,
1102 8, 8, 8, 8, 8, 8, 8, 8,
1103 8, 8, 8, 8, 8, 8, 8, 8,
1104 8, 8, 8, 8, 7, 7, 7, 7,
1105 7, 7, 6, 6, 6, 6, 6, 6,
1106 5, 5, 5, 5, 4, 4, 4, 4,
1107 4, 4, 4, 3, 3, 3, 3, 2
1108];
1109
1110const VP56_MODE_VQ: [[[u8; 20]; 16]; 3] = [
1111 [
1112 [ 9, 15, 32, 25, 7, 19, 9, 21, 1, 12, 14, 12, 3, 18, 14, 23, 3, 10, 0, 4 ],
1113 [ 48, 39, 1, 2, 11, 27, 29, 44, 7, 27, 1, 4, 0, 3, 1, 6, 1, 2, 0, 0 ],
1114 [ 21, 32, 1, 2, 4, 10, 32, 43, 6, 23, 2, 3, 1, 19, 1, 6, 12, 21, 0, 7 ],
1115 [ 69, 83, 0, 0, 0, 2, 10, 29, 3, 12, 0, 1, 0, 3, 0, 3, 2, 2, 0, 0 ],
1116 [ 11, 20, 1, 4, 18, 36, 43, 48, 13, 35, 0, 2, 0, 5, 3, 12, 1, 2, 0, 0 ],
1117 [ 70, 44, 0, 1, 2, 10, 37, 46, 8, 26, 0, 2, 0, 2, 0, 2, 0, 1, 0, 0 ],
1118 [ 8, 15, 0, 1, 8, 21, 74, 53, 22, 42, 0, 1, 0, 2, 0, 3, 1, 2, 0, 0 ],
1119 [ 141, 42, 0, 0, 1, 4, 11, 24, 1, 11, 0, 1, 0, 1, 0, 2, 0, 0, 0, 0 ],
1120 [ 8, 19, 4, 10, 24, 45, 21, 37, 9, 29, 0, 3, 1, 7, 11, 25, 0, 2, 0, 1 ],
1121 [ 46, 42, 0, 1, 2, 10, 54, 51, 10, 30, 0, 2, 0, 2, 0, 1, 0, 1, 0, 0 ],
1122 [ 28, 32, 0, 0, 3, 10, 75, 51, 14, 33, 0, 1, 0, 2, 0, 1, 1, 2, 0, 0 ],
1123 [ 100, 46, 0, 1, 3, 9, 21, 37, 5, 20, 0, 1, 0, 2, 1, 2, 0, 1, 0, 0 ],
1124 [ 27, 29, 0, 1, 9, 25, 53, 51, 12, 34, 0, 1, 0, 3, 1, 5, 0, 2, 0, 0 ],
1125 [ 80, 38, 0, 0, 1, 4, 69, 33, 5, 16, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0 ],
1126 [ 16, 20, 0, 0, 2, 8, 104, 49, 15, 33, 0, 1, 0, 1, 0, 1, 1, 1, 0, 0 ],
1127 [ 194, 16, 0, 0, 1, 1, 1, 9, 1, 3, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0 ],
1128 ], [
1129 [ 41, 22, 1, 0, 1, 31, 0, 0, 0, 0, 0, 1, 1, 7, 0, 1, 98, 25, 4, 10 ],
1130 [ 123, 37, 6, 4, 1, 27, 0, 0, 0, 0, 5, 8, 1, 7, 0, 1, 12, 10, 0, 2 ],
1131 [ 26, 14, 14, 12, 0, 24, 0, 0, 0, 0, 55, 17, 1, 9, 0, 36, 5, 7, 1, 3 ],
1132 [ 209, 5, 0, 0, 0, 27, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0 ],
1133 [ 2, 5, 4, 5, 0, 121, 0, 0, 0, 0, 0, 3, 2, 4, 1, 4, 2, 2, 0, 1 ],
1134 [ 175, 5, 0, 1, 0, 48, 0, 0, 0, 0, 0, 2, 0, 1, 0, 2, 0, 1, 0, 0 ],
1135 [ 83, 5, 2, 3, 0, 102, 0, 0, 0, 0, 1, 3, 0, 2, 0, 1, 0, 0, 0, 0 ],
1136 [ 233, 6, 0, 0, 0, 8, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0 ],
1137 [ 34, 16, 112, 21, 1, 28, 0, 0, 0, 0, 6, 8, 1, 7, 0, 3, 2, 5, 0, 2 ],
1138 [ 159, 35, 2, 2, 0, 25, 0, 0, 0, 0, 3, 6, 0, 5, 0, 1, 4, 4, 0, 1 ],
1139 [ 75, 39, 5, 7, 2, 48, 0, 0, 0, 0, 3, 11, 2, 16, 1, 4, 7, 10, 0, 2 ],
1140 [ 212, 21, 0, 1, 0, 9, 0, 0, 0, 0, 1, 2, 0, 2, 0, 0, 2, 2, 0, 0 ],
1141 [ 4, 2, 0, 0, 0, 172, 0, 0, 0, 0, 0, 1, 0, 2, 0, 0, 2, 0, 0, 0 ],
1142 [ 187, 22, 1, 1, 0, 17, 0, 0, 0, 0, 3, 6, 0, 4, 0, 1, 4, 4, 0, 1 ],
1143 [ 133, 6, 1, 2, 1, 70, 0, 0, 0, 0, 0, 2, 0, 4, 0, 3, 1, 1, 0, 0 ],
1144 [ 251, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ],
1145 ], [
1146 [ 2, 3, 2, 3, 0, 2, 0, 2, 0, 0, 11, 4, 1, 4, 0, 2, 3, 2, 0, 4 ],
1147 [ 49, 46, 3, 4, 7, 31, 42, 41, 0, 0, 2, 6, 1, 7, 1, 4, 2, 4, 0, 1 ],
1148 [ 26, 25, 1, 1, 2, 10, 67, 39, 0, 0, 1, 1, 0, 14, 0, 2, 31, 26, 1, 6 ],
1149 [ 103, 46, 1, 2, 2, 10, 33, 42, 0, 0, 1, 4, 0, 3, 0, 1, 1, 3, 0, 0 ],
1150 [ 14, 31, 9, 13, 14, 54, 22, 29, 0, 0, 2, 6, 4, 18, 6, 13, 1, 5, 0, 1 ],
1151 [ 85, 39, 0, 0, 1, 9, 69, 40, 0, 0, 0, 1, 0, 3, 0, 1, 2, 3, 0, 0 ],
1152 [ 31, 28, 0, 0, 3, 14, 130, 34, 0, 0, 0, 1, 0, 3, 0, 1, 3, 3, 0, 1 ],
1153 [ 171, 25, 0, 0, 1, 5, 25, 21, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0 ],
1154 [ 17, 21, 68, 29, 6, 15, 13, 22, 0, 0, 6, 12, 3, 14, 4, 10, 1, 7, 0, 3 ],
1155 [ 51, 39, 0, 1, 2, 12, 91, 44, 0, 0, 0, 2, 0, 3, 0, 1, 2, 3, 0, 1 ],
1156 [ 81, 25, 0, 0, 2, 9, 106, 26, 0, 0, 0, 1, 0, 1, 0, 1, 1, 1, 0, 0 ],
1157 [ 140, 37, 0, 1, 1, 8, 24, 33, 0, 0, 1, 2, 0, 2, 0, 1, 1, 2, 0, 0 ],
1158 [ 14, 23, 1, 3, 11, 53, 90, 31, 0, 0, 0, 3, 1, 5, 2, 6, 1, 2, 0, 0 ],
1159 [ 123, 29, 0, 0, 1, 7, 57, 30, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0 ],
1160 [ 13, 14, 0, 0, 4, 20, 175, 20, 0, 0, 0, 1, 0, 1, 0, 1, 1, 1, 0, 0 ],
1161 [ 202, 23, 0, 0, 1, 3, 2, 9, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0 ],
1162 ]
1163];
1164