1 use nihav_core::codecs::*;
2 use nihav_core::io::bitreader::*;
3 use nihav_codec_support::codecs::{MV, ZIGZAG};
4 use nihav_codec_support::codecs::blockdsp::edge_emu;
5 use super::vpcommon::*;
8 const VERSION_VP60: u8 = 6;
9 //const VERSION_VP61: u8 = 7;
10 const VERSION_VP62: u8 = 8;
12 const VP6_SIMPLE_PROFILE: u8 = 0;
13 const VP6_ADVANCED_PROFILE: u8 = 3;
35 impl VP56Parser for VP6BR {
36 fn parse_header(&mut self, bc: &mut BoolCoder) -> DecoderResult<VP56Header> {
37 let mut hdr = VP56Header::default();
38 // horrible hack to match VP6 header parsing
40 let mut br = BitReader::new(src, BitReaderMode::BE);
42 hdr.is_intra = !br.read_bool()?;
43 hdr.is_golden = hdr.is_intra;
44 hdr.quant = br.read(6)? as u8;
45 hdr.multistream = br.read_bool()?;
47 hdr.version = br.read(5)? as u8;
48 validate!((hdr.version >= VERSION_VP60) && (hdr.version <= VERSION_VP62));
49 hdr.profile = br.read(2)? as u8;
50 validate!((hdr.profile == VP6_SIMPLE_PROFILE) || (hdr.profile == VP6_ADVANCED_PROFILE));
51 hdr.interlaced = br.read_bool()?;
53 hdr.version = self.vpversion;
54 hdr.profile = self.profile;
55 hdr.interlaced = self.interlaced;
57 if hdr.multistream || (hdr.profile == VP6_SIMPLE_PROFILE) {
58 hdr.offset = br.read(16)? as u16;
59 validate!(hdr.offset > if hdr.is_intra { 6 } else { 2 });
61 let bytes = br.tell() >> 3;
66 hdr.mb_h = bc.read_bits(8) as u8;
67 hdr.mb_w = bc.read_bits(8) as u8;
68 hdr.disp_h = bc.read_bits(8) as u8;
69 hdr.disp_w = bc.read_bits(8) as u8;
70 validate!((hdr.mb_h > 0) && (hdr.mb_w > 0) && (hdr.disp_w > 0) && (hdr.disp_h > 0));
71 validate!((hdr.disp_w <= hdr.mb_w) && (hdr.disp_h <= hdr.mb_h));
72 hdr.scale = bc.read_bits(2) as u8;
74 hdr.is_golden = bc.read_bool();
75 if hdr.profile == VP6_ADVANCED_PROFILE {
76 self.loop_mode = bc.read_bool() as u8;
77 if self.loop_mode != 0 {
78 self.loop_mode += bc.read_bool() as u8;
79 validate!(self.loop_mode <= 1);
81 if hdr.version == VERSION_VP62 {
82 self.do_pm = bc.read_bool();
87 if (hdr.profile == VP6_ADVANCED_PROFILE) && (hdr.is_intra || self.do_pm) {
88 self.autosel_pm = bc.read_bool();
90 self.var_thresh = bc.read_bits(5) as u16;
91 if hdr.version != VERSION_VP62 {
92 self.var_thresh <<= 5;
94 self.mv_thresh = bc.read_bits(3) as u8;
96 self.bicubic = bc.read_bool();
98 if hdr.version == VERSION_VP62 {
99 self.filter_alpha = bc.read_bits(4) as usize;
101 self.filter_alpha = 16;
105 hdr.use_huffman = bc.read_bool();
107 self.vpversion = hdr.version;
108 self.profile = hdr.profile;
109 self.interlaced = hdr.interlaced;
112 fn decode_mv(&self, bc: &mut BoolCoder, model: &VP56MVModel) -> i16 {
113 const LONG_VECTOR_ORDER: [usize; 7] = [ 0, 1, 2, 7, 6, 5, 4 ];
115 let val = if !bc.read_prob(model.nz_prob) { // short vector
116 vp_tree!(bc, model.tree_probs[0],
117 vp_tree!(bc, model.tree_probs[1],
118 vp_tree!(bc, model.tree_probs[2], 0, 1),
119 vp_tree!(bc, model.tree_probs[3], 2, 3)),
120 vp_tree!(bc, model.tree_probs[4],
121 vp_tree!(bc, model.tree_probs[5], 4, 5),
122 vp_tree!(bc, model.tree_probs[6], 6, 7)))
125 for ord in LONG_VECTOR_ORDER.iter() {
126 raw |= (bc.read_prob(model.raw_probs[*ord]) as i16) << *ord;
128 if (raw & 0xF0) != 0 {
129 raw |= (bc.read_prob(model.raw_probs[3]) as i16) << 3;
135 if (val != 0) && bc.read_prob(model.sign_prob) {
141 fn reset_models(&self, models: &mut VP56Models) {
142 const NZ_PROBS: [u8; 2] = [ 162, 164 ];
143 const RAW_PROBS: [[u8; 8]; 2] = [
144 [ 247, 210, 135, 68, 138, 220, 239, 246 ],
145 [ 244, 184, 201, 44, 173, 221, 239, 253 ]
147 const TREE_PROBS: [[u8; 7]; 2] = [
148 [ 225, 146, 172, 147, 214, 39, 156 ],
149 [ 204, 170, 119, 235, 140, 230, 228 ]
151 const ZERO_RUN_PROBS: [[u8; 14]; 2] = [
152 [ 198, 197, 196, 146, 198, 204, 169, 142, 130, 136, 149, 149, 191, 249 ],
153 [ 135, 201, 181, 154, 98, 117, 132, 126, 146, 169, 184, 240, 246, 254 ]
156 for (i, mdl) in models.mv_models.iter_mut().enumerate() {
157 mdl.nz_prob = NZ_PROBS[i];
159 mdl.raw_probs.copy_from_slice(&RAW_PROBS[i]);
160 mdl.tree_probs.copy_from_slice(&TREE_PROBS[i]);
162 models.vp6models.zero_run_probs.copy_from_slice(&ZERO_RUN_PROBS);
163 reset_scan(&mut models.vp6models, self.interlaced);
165 fn decode_mv_models(&self, bc: &mut BoolCoder, models: &mut [VP56MVModel; 2]) -> DecoderResult<()> {
166 const HAS_NZ_PROB: [u8; 2] = [ 237, 231 ];
167 const HAS_SIGN_PROB: [u8; 2] = [ 246, 243 ];
168 const HAS_TREE_PROB: [[u8; 7]; 2] = [
169 [ 253, 253, 254, 254, 254, 254, 254 ],
170 [ 245, 253, 254, 254, 254, 254, 254 ]
172 const HAS_RAW_PROB: [[u8; 8]; 2] = [
173 [ 254, 254, 254, 254, 254, 250, 250, 252 ],
174 [ 254, 254, 254, 254, 254, 251, 251, 254 ]
178 if bc.read_prob(HAS_NZ_PROB[comp]) {
179 models[comp].nz_prob = bc.read_probability();
181 if bc.read_prob(HAS_SIGN_PROB[comp]) {
182 models[comp].sign_prob = bc.read_probability();
186 for (i, prob) in HAS_TREE_PROB[comp].iter().enumerate() {
187 if bc.read_prob(*prob) {
188 models[comp].tree_probs[i] = bc.read_probability();
193 for (i, prob) in HAS_RAW_PROB[comp].iter().enumerate() {
194 if bc.read_prob(*prob) {
195 models[comp].raw_probs[i] = bc.read_probability();
201 fn decode_coeff_models(&self, bc: &mut BoolCoder, models: &mut VP56Models, is_intra: bool) -> DecoderResult<()> {
202 const COEF_PROBS: [[u8; 11]; 2] = [
203 [ 146, 255, 181, 207, 232, 243, 238, 251, 244, 250, 249 ],
204 [ 179, 255, 214, 240, 250, 255, 244, 255, 255, 255, 255 ]
206 const SCAN_UPD_PROBS: [u8; 64] = [
207 0, 132, 132, 159, 153, 151, 161, 170,
208 164, 162, 136, 110, 103, 114, 129, 118,
209 124, 125, 132, 136, 114, 110, 142, 135,
210 134, 123, 143, 126, 153, 183, 166, 161,
211 171, 180, 179, 164, 203, 218, 225, 217,
212 215, 206, 203, 217, 229, 241, 248, 243,
213 253, 255, 253, 255, 255, 255, 255, 255,
214 255, 255, 255, 255, 255, 255, 255, 255
216 const ZERO_RUN_PROBS: [[u8; 14]; 2] = [
217 [ 219, 246, 238, 249, 232, 239, 249, 255, 248, 253, 239, 244, 241, 248 ],
218 [ 198, 232, 251, 253, 219, 241, 253, 255, 248, 249, 244, 238, 251, 255 ]
221 let mut def_prob = [128u8; 11];
224 if bc.read_prob(COEF_PROBS[plane][i]) {
225 def_prob[i] = bc.read_probability();
226 models.coeff_models[plane].dc_value_probs[i] = def_prob[i];
228 models.coeff_models[plane].dc_value_probs[i] = def_prob[i];
235 if bc.read_prob(SCAN_UPD_PROBS[i]) {
236 models.vp6models.scan_order[i] = bc.read_bits(4) as usize;
239 update_scan(&mut models.vp6models);
241 reset_scan(&mut models.vp6models, self.interlaced);
246 if bc.read_prob(ZERO_RUN_PROBS[comp][i]) {
247 models.vp6models.zero_run_probs[comp][i] = bc.read_probability();
256 if bc.read_prob(VP6_AC_PROBS[ctype][plane][group][i]) {
257 def_prob[i] = bc.read_probability();
258 models.coeff_models[plane].ac_val_probs[ctype][group][i] = def_prob[i];
260 models.coeff_models[plane].ac_val_probs[ctype][group][i] = def_prob[i];
267 let mdl = &mut models.coeff_models[plane];
270 mdl.dc_token_probs[0][i][k] = rescale_prob(mdl.dc_value_probs[k], &VP6_DC_WEIGHTS[k][i], 255);
276 fn decode_block(&self, bc: &mut BoolCoder, coeffs: &mut [i16; 64], model: &VP56CoeffModel, vp6model: &VP6Models, fstate: &mut FrameState) -> DecoderResult<()> {
277 let left_ctx = fstate.coeff_cat[fstate.ctx_idx][0] as usize;
278 let top_ctx = fstate.top_ctx as usize;
279 let dc_mode = top_ctx + left_ctx;
280 let token = decode_token_bc(bc, &model.dc_token_probs[0][dc_mode], model.dc_value_probs[5], true, true);
281 let val = expand_token_bc(bc, &model.dc_value_probs, token, 6);
283 fstate.last_idx[fstate.ctx_idx] = 0;
286 let mut last_val = val;
288 let ac_band = VP6_IDX_TO_AC_BAND[idx];
289 let ac_mode = last_val.abs().min(2) as usize;
290 let has_nnz = (idx == 1) || (last_val != 0);
291 let token = decode_token_bc(bc, &model.ac_val_probs[ac_mode][ac_band], model.ac_val_probs[ac_mode][ac_band][5], false, has_nnz);
292 if token == 42 { break; }
293 let val = expand_token_bc(bc, &model.ac_val_probs[ac_mode][ac_band], token, 6);
294 coeffs[vp6model.zigzag[idx]] = val.wrapping_mul(fstate.ac_quant);
298 idx += decode_zero_run_bc(bc, &vp6model.zero_run_probs[if idx >= 7 { 1 } else { 0 }]);
299 validate!(idx <= 64);
302 fstate.coeff_cat[fstate.ctx_idx][0] = if coeffs[0] != 0 { 1 } else { 0 };
303 fstate.top_ctx = fstate.coeff_cat[fstate.ctx_idx][0];
304 fstate.last_idx[fstate.ctx_idx] = idx;
307 fn decode_block_huff(&self, br: &mut BitReader, coeffs: &mut [i16; 64], vp6model: &VP6Models, model: &VP6HuffModels, fstate: &mut FrameState) -> DecoderResult<()> {
308 let plane = if (fstate.plane == 0) || (fstate.plane == 3) { 0 } else { 1 };
311 if fstate.dc_zero_run[plane] == 0 {
312 let (val, eob) = decode_token_huff(br, &model.dc_token_tree[plane])?;
319 fstate.dc_zero_run[plane] = decode_eob_run_huff(br)?;
323 fstate.dc_zero_run[plane] -= 1;
326 if fstate.ac_zero_run[plane] > 0 {
327 fstate.ac_zero_run[plane] -= 1;
328 fstate.last_idx[fstate.ctx_idx] = 0;
334 let ac_band = VP6_IDX_TO_AC_BAND[idx].min(3);
335 let ac_mode = last_val.abs().min(2) as usize;
336 let (val, eob) = decode_token_huff(br, &model.ac_token_tree[plane][ac_mode][ac_band])?;
339 fstate.ac_zero_run[plane] = decode_eob_run_huff(br)?;
343 coeffs[vp6model.zigzag[idx]] = val.wrapping_mul(fstate.ac_quant);
347 idx += decode_zero_run_huff(br, &model.zero_run_tree[if idx >= 7 { 1 } else { 0 }])?;
348 validate!(idx <= 64);
352 fstate.last_idx[fstate.ctx_idx] = idx;
356 fn mc_block(&self, dst: &mut NASimpleVideoFrame<u8>, mut mc_buf: NAVideoBufferRef<u8>, src: NAVideoBufferRef<u8>, plane: usize, x: usize, y: usize, mv: MV, loop_str: i16) {
357 let is_luma = (plane != 1) && (plane != 2);
358 let (sx, sy, mx, my, msx, msy) = if is_luma {
359 (mv.x >> 2, mv.y >> 2, (mv.x & 3) << 1, (mv.y & 3) << 1, mv.x / 4, mv.y / 4)
361 (mv.x >> 3, mv.y >> 3, mv.x & 7, mv.y & 7, mv.x / 8, mv.y / 8)
363 let tmp_blk = mc_buf.get_data_mut().unwrap();
364 get_block(tmp_blk, 16, src.clone(), plane, x, y, sx, sy);
366 let foff = (8 - (sx & 7)) as usize;
368 vp31_loop_filter(tmp_blk, off, 1, 16, 12, loop_str);
371 let foff = (8 - (sy & 7)) as usize;
372 let off = (2 + foff) * 16;
373 vp31_loop_filter(tmp_blk, off, 16, 1, 12, loop_str);
375 let copy_mode = (mx == 0) && (my == 0);
376 let mut bicubic = !copy_mode && is_luma && self.bicubic;
377 if is_luma && !copy_mode && (self.profile == VP6_ADVANCED_PROFILE) {
378 if !self.autosel_pm {
381 let mv_limit = 1 << (self.mv_thresh + 1);
382 if (mv.x.abs() <= mv_limit) && (mv.y.abs() <= mv_limit) {
383 let mut var_off = 16 * 2 + 2;
384 if mv.x < 0 { var_off += 1; }
385 if mv.y < 0 { var_off += 16; }
386 let var = calc_variance(&tmp_blk[var_off..], 16);
387 if var >= self.var_thresh {
393 let dstride = dst.stride[plane];
394 let dbuf = &mut dst.data[dst.offset[plane] + x + y * dstride..];
396 let src = &tmp_blk[2 * 16 + 2..];
397 for (dline, sline) in dbuf.chunks_mut(dst.stride[plane]).zip(src.chunks(16)).take(8) {
398 for i in 0..8 { dline[i] = sline[i]; }
401 let coeff_h = &VP6_BICUBIC_COEFFS[self.filter_alpha][mx as usize];
402 let coeff_v = &VP6_BICUBIC_COEFFS[self.filter_alpha][my as usize];
403 mc_bicubic(dbuf, dstride, tmp_blk, 16 * 2 + 2, 16, coeff_h, coeff_v);
405 mc_bilinear(dbuf, dstride, tmp_blk, 16 * 2 + 2, 16, mx as u16, my as u16);
410 fn update_scan(model: &mut VP6Models) {
414 if model.scan_order[i] == band {
421 model.zigzag[i] = ZIGZAG[model.scan[i]];
425 fn reset_scan(model: &mut VP6Models, interlaced: bool) {
426 const VP6_DEFAULT_SCAN_ORDER: [usize; 64] = [
427 0, 0, 1, 1, 1, 2, 2, 2,
428 2, 2, 2, 3, 3, 4, 4, 4,
429 5, 5, 5, 5, 6, 6, 7, 7,
430 7, 7, 7, 8, 8, 9, 9, 9,
431 9, 9, 9, 10, 10, 11, 11, 11,
432 11, 11, 11, 12, 12, 12, 12, 12,
433 12, 13, 13, 13, 13, 13, 14, 14,
434 14, 14, 15, 15, 15, 15, 15, 15
436 const VP6_INTERLACED_SCAN_ORDER: [usize; 64] = [
437 0, 1, 0, 1, 1, 2, 5, 3,
438 2, 2, 2, 2, 4, 7, 8, 10,
439 9, 7, 5, 4, 2, 3, 5, 6,
440 8, 9, 11, 12, 13, 12, 11, 10,
441 9, 7, 5, 4, 6, 7, 9, 11,
442 12, 12, 13, 13, 14, 12, 11, 9,
443 7, 9, 11, 12, 14, 14, 14, 15,
444 13, 11, 13, 15, 15, 15, 15, 15
448 model.scan_order.copy_from_slice(&VP6_DEFAULT_SCAN_ORDER);
450 model.scan_order.copy_from_slice(&VP6_INTERLACED_SCAN_ORDER);
452 for i in 0..64 { model.scan[i] = i; }
453 model.zigzag.copy_from_slice(&ZIGZAG);
456 fn decode_token_bc(bc: &mut BoolCoder, probs: &[u8], prob34: u8, is_dc: bool, has_nnz: bool) -> u8 {
457 if has_nnz && !bc.read_prob(probs[0]) {
458 if is_dc || bc.read_prob(probs[1]) {
464 vp_tree!(bc, probs[2],
466 vp_tree!(bc, probs[3],
467 vp_tree!(bc, probs[4],
469 vp_tree!(bc, prob34, 3, 4)),
474 fn decode_zero_run_bc(bc: &mut BoolCoder, probs: &[u8; 14]) -> usize {
475 let val = vp_tree!(bc, probs[0],
476 vp_tree!(bc, probs[1],
477 vp_tree!(bc, probs[2], 0, 1),
478 vp_tree!(bc, probs[3], 2, 3)),
479 vp_tree!(bc, probs[4],
480 vp_tree!(bc, probs[5],
481 vp_tree!(bc, probs[6], 4, 5),
482 vp_tree!(bc, probs[7], 6, 7)),
489 nval += (bc.read_prob(probs[i + 8]) as usize) << i;
495 fn decode_token_huff(br: &mut BitReader, huff: &VP6Huff) -> DecoderResult<(i16, bool)> {
496 const COEF_ADD_BITS: [u8; 6] = [ 1, 2, 3, 4, 5, 11 ];
497 let tok = br.read_huff(huff)?;
501 if !br.read_bool()? {
502 Ok((tok as i16, false))
504 Ok((-(tok as i16), false))
507 5 | 6 | 7 | 8 | 9 | 10 => {
508 let base = (tok - 5) as usize;
509 let add_bits = br.read(COEF_ADD_BITS[base])? as i16;
510 let val = VP56_COEF_BASE[base] + add_bits;
511 if !br.read_bool()? {
521 fn decode_eob_run_huff(br: &mut BitReader) -> DecoderResult<usize> {
522 let val = br.read(2)?;
527 let val = br.read(2)?;
528 Ok((val as usize) + 2)
532 Ok((br.read(6)? as usize) + 10)
534 Ok((br.read(2)? as usize) + 6)
540 fn decode_zero_run_huff(br: &mut BitReader, huff: &VP6Huff) -> DecoderResult<usize> {
541 let val = br.read_huff(huff)?;
545 Ok((br.read(6)? as usize) + 8)
550 fn get_block(dst: &mut [u8], dstride: usize, src: NAVideoBufferRef<u8>, comp: usize,
551 dx: usize, dy: usize, mv_x: i16, mv_y: i16)
553 let (w, h) = src.get_dimensions(comp);
554 let sx = (dx as isize) + (mv_x as isize);
555 let sy = (dy as isize) + (mv_y as isize);
557 if (sx - 2 < 0) || (sx + 8 + 2 > (w as isize)) ||
558 (sy - 2 < 0) || (sy + 8 + 2 > (h as isize)) {
559 edge_emu(&src, sx - 2, sy - 2, 8 + 2 + 2, 8 + 2 + 2,
560 dst, dstride, comp, 0);
562 let sstride = src.get_stride(comp);
563 let soff = src.get_offset(comp);
564 let sdta = src.get_data();
565 let sbuf: &[u8] = sdta.as_slice();
566 let saddr = soff + ((sx - 2) as usize) + ((sy - 2) as usize) * sstride;
567 let src = &sbuf[saddr..];
568 for (dline, sline) in dst.chunks_mut(dstride).zip(src.chunks(sstride)).take(12) {
576 fn calc_variance(src: &[u8], stride: usize) -> u16 {
579 for line in src.chunks(stride * 2).take(4) {
580 for el in line.iter().take(8).step_by(2) {
581 let pix = *el as u32;
586 ((ssum * 16 - sum * sum) >> 8) as u16
589 macro_rules! mc_filter {
590 (bilinear; $a: expr, $b: expr, $c: expr) => {
591 ((($a as u16) * (8 - $c) + ($b as u16) * $c + 4) >> 3) as u8
593 (bicubic; $src: expr, $off: expr, $step: expr, $coeffs: expr) => {
594 ((($src[$off - $step] as i32) * ($coeffs[0] as i32) +
595 ($src[$off] as i32) * ($coeffs[1] as i32) +
596 ($src[$off + $step] as i32) * ($coeffs[2] as i32) +
597 ($src[$off + $step * 2] as i32) * ($coeffs[3] as i32) + 64) >> 7).min(255).max(0) as u8
601 //#[allow(snake_case)]
602 fn mc_bilinear(dst: &mut [u8], dstride: usize, src: &[u8], mut soff: usize, sstride: usize, mx: u16, my: u16) {
604 for dline in dst.chunks_mut(dstride).take(8) {
606 dline[i] = mc_filter!(bilinear; src[soff + i], src[soff + i + 1], mx);
611 for dline in dst.chunks_mut(dstride).take(8) {
613 dline[i] = mc_filter!(bilinear; src[soff + i], src[soff + i + sstride], my);
618 let mut tmp = [0u8; 8];
620 tmp[i] = mc_filter!(bilinear; src[soff + i], src[soff + i + 1], mx);
623 for dline in dst.chunks_mut(dstride).take(8) {
625 let cur = mc_filter!(bilinear; src[soff + i], src[soff + i + 1], mx);
626 dline[i] = mc_filter!(bilinear; tmp[i], cur, my);
634 fn mc_bicubic(dst: &mut [u8], dstride: usize, src: &[u8], mut soff: usize, sstride: usize, coeffs_w: &[i16; 4], coeffs_h: &[i16; 4]) {
635 if coeffs_h[1] == 128 {
636 for dline in dst.chunks_mut(dstride).take(8) {
638 dline[i] = mc_filter!(bicubic; src, soff + i, 1, coeffs_w);
642 } else if coeffs_w[1] == 128 { // horizontal-only interpolation
643 for dline in dst.chunks_mut(dstride).take(8) {
645 dline[i] = mc_filter!(bicubic; src, soff + i, sstride, coeffs_h);
650 let mut buf = [0u8; 16 * 11];
652 for dline in buf.chunks_mut(16) {
654 dline[i] = mc_filter!(bicubic; src, soff + i, 1, coeffs_w);
659 for dline in dst.chunks_mut(dstride).take(8) {
661 dline[i] = mc_filter!(bicubic; buf, soff + i, 16, coeffs_h);
670 info: NACodecInfoRef,
676 fn new(has_alpha: bool) -> Self {
678 dec: VP56Decoder::new(6, has_alpha, true),
679 info: NACodecInfoRef::default(),
686 impl NADecoder for VP6Decoder {
687 fn init(&mut self, supp: &mut NADecoderSupport, info: NACodecInfoRef) -> DecoderResult<()> {
688 if let NACodecTypeInfo::Video(vinfo) = info.get_properties() {
689 let fmt = if !self.has_alpha {
694 let myvinfo = NAVideoInfo::new(vinfo.get_width(), vinfo.get_height(), false, fmt);
695 let myinfo = NACodecTypeInfo::Video(myvinfo.clone());
696 self.info = NACodecInfo::new_ref(info.get_name(), myinfo, info.get_extradata()).into_ref();
697 self.dec.init(supp, myvinfo)?;
700 Err(DecoderError::InvalidData)
703 fn decode(&mut self, supp: &mut NADecoderSupport, pkt: &NAPacket) -> DecoderResult<NAFrameRef> {
704 let src = pkt.get_buffer();
706 let (bufinfo, ftype) = self.dec.decode_frame(supp, src.as_slice(), &mut self.br)?;
708 let mut frm = NAFrame::new_from_pkt(pkt, self.info.clone(), bufinfo);
709 frm.set_keyframe(ftype == FrameType::I);
710 frm.set_frame_type(ftype);
713 fn flush(&mut self) {
718 pub fn get_decoder_vp6() -> Box<NADecoder + Send> {
719 Box::new(VP6Decoder::new(false))
722 pub fn get_decoder_vp6_alpha() -> Box<NADecoder + Send> {
723 Box::new(VP6Decoder::new(true))
728 use nihav_core::codecs::RegisteredDecoders;
729 use nihav_core::demuxers::RegisteredDemuxers;
730 use nihav_codec_support::test::dec_video::*;
731 use crate::duck_register_all_codecs;
732 use nihav_commonfmt::generic_register_all_demuxers;
736 let mut dmx_reg = RegisteredDemuxers::new();
737 generic_register_all_demuxers(&mut dmx_reg);
738 let mut dec_reg = RegisteredDecoders::new();
739 duck_register_all_codecs(&mut dec_reg);
741 test_decoding("avi", "vp6", "assets/Duck/selection_720x576_300kBit_vp60i.avi", Some(16),
743 ExpectedTestResult::MD5([0x042c3e96, 0x8a9b26a2, 0x4dcbaf66, 0x1b788d03]));
747 let mut dmx_reg = RegisteredDemuxers::new();
748 generic_register_all_demuxers(&mut dmx_reg);
749 let mut dec_reg = RegisteredDecoders::new();
750 duck_register_all_codecs(&mut dec_reg);
752 test_decoding("avi", "vp6", "assets/Duck/vp6_crash.avi", Some(4),
753 &dmx_reg, &dec_reg, ExpectedTestResult::MD5Frames(vec![
754 [0xdcd70fa0, 0x0d075ce2, 0xc9e65077, 0xb003a92e],
755 [0x334abf96, 0x3a004c7a, 0x5781cd5c, 0x25c3ae5c],
756 [0x6164b851, 0x528cd8de, 0xecab7328, 0x4b49708a],
757 [0x11b048ac, 0xedb3e471, 0xd04e9399, 0x64e623e3],
758 [0x182871b1, 0x2146893a, 0x2912210e, 0x6dd592e8]]));
760 // todo find good sample for vp6a test
763 const VP6_AC_PROBS: [[[[u8; 11]; 6]; 2]; 3] = [
766 [ 227, 246, 230, 247, 244, 255, 255, 255, 255, 255, 255 ],
767 [ 255, 255, 209, 231, 231, 249, 249, 253, 255, 255, 255 ],
768 [ 255, 255, 225, 242, 241, 251, 253, 255, 255, 255, 255 ],
769 [ 255, 255, 241, 253, 252, 255, 255, 255, 255, 255, 255 ],
770 [ 255, 255, 248, 255, 255, 255, 255, 255, 255, 255, 255 ],
771 [ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 ]
773 [ 240, 255, 248, 255, 255, 255, 255, 255, 255, 255, 255 ],
774 [ 255, 255, 240, 253, 255, 255, 255, 255, 255, 255, 255 ],
775 [ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 ],
776 [ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 ],
777 [ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 ],
778 [ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 ]
782 [ 206, 203, 227, 239, 247, 255, 253, 255, 255, 255, 255 ],
783 [ 207, 199, 220, 236, 243, 252, 252, 255, 255, 255, 255 ],
784 [ 212, 219, 230, 243, 244, 253, 252, 255, 255, 255, 255 ],
785 [ 236, 237, 247, 252, 253, 255, 255, 255, 255, 255, 255 ],
786 [ 240, 240, 248, 255, 255, 255, 255, 255, 255, 255, 255 ],
787 [ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 ]
789 [ 230, 233, 249, 255, 255, 255, 255, 255, 255, 255, 255 ],
790 [ 238, 238, 250, 255, 255, 255, 255, 255, 255, 255, 255 ],
791 [ 248, 251, 255, 255, 255, 255, 255, 255, 255, 255, 255 ],
792 [ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 ],
793 [ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 ],
794 [ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 ]
798 [ 225, 239, 227, 231, 244, 253, 243, 255, 255, 253, 255 ],
799 [ 232, 234, 224, 228, 242, 249, 242, 252, 251, 251, 255 ],
800 [ 235, 249, 238, 240, 251, 255, 249, 255, 253, 253, 255 ],
801 [ 249, 253, 251, 250, 255, 255, 255, 255, 255, 255, 255 ],
802 [ 251, 250, 249, 255, 255, 255, 255, 255, 255, 255, 255 ],
803 [ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 ]
805 [ 243, 244, 250, 250, 255, 255, 255, 255, 255, 255, 255 ],
806 [ 249, 248, 250, 253, 255, 255, 255, 255, 255, 255, 255 ],
807 [ 253, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 ],
808 [ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 ],
809 [ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 ],
810 [ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 ]
815 const VP6_DC_WEIGHTS: [[[i16; 2]; 3]; 5] = [
816 [ [ 122, 133 ], [ 133, 51 ], [ 142, -16 ] ],
817 [ [ 0, 1 ], [ 0, 1 ], [ 0, 1 ] ],
818 [ [ 78, 171 ], [ 169, 71 ], [ 221, -30 ] ],
819 [ [ 139, 117 ], [ 214, 44 ], [ 246, -3 ] ],
820 [ [ 168, 79 ], [ 210, 38 ], [ 203, 17 ] ]
823 const VP6_IDX_TO_AC_BAND: [usize; 64] = [
824 0, 0, 1, 1, 1, 2, 2, 2,
825 2, 2, 2, 3, 3, 3, 3, 3,
826 3, 3, 3, 3, 3, 3, 4, 4,
827 4, 4, 4, 4, 4, 4, 4, 4,
828 4, 4, 4, 4, 4, 5, 5, 5,
829 5, 5, 5, 5, 5, 5, 5, 5,
830 5, 5, 5, 5, 5, 5, 5, 5,
831 5, 5, 5, 5, 5, 5, 5, 5
834 const VP6_BICUBIC_COEFFS: [[[i16; 4]; 8]; 17] = [
892 [ -10, 111, 30, -3 ],
896 [ -3, 30, 111, -10 ],
901 [ -11, 112, 31, -4 ],
903 [ -10, 74, 74, -10 ],
905 [ -4, 31, 112, -11 ],
910 [ -12, 112, 32, -4 ],
912 [ -10, 74, 74, -10 ],
914 [ -4, 32, 112, -12 ],
919 [ -13, 112, 33, -4 ],
921 [ -11, 75, 75, -11 ],
923 [ -4, 33, 112, -13 ],
928 [ -14, 113, 34, -5 ],
930 [ -12, 76, 76, -12 ],
932 [ -5, 34, 112, -13 ],
936 [ -10, 124, 15, -1 ],
937 [ -14, 113, 34, -5 ],
939 [ -13, 77, 77, -13 ],
941 [ -5, 34, 113, -14 ],
945 [ -10, 123, 16, -1 ],
946 [ -15, 113, 35, -5 ],
947 [ -16, 98, 56, -10 ],
948 [ -14, 78, 78, -14 ],
949 [ -10, 56, 98, -16 ],
950 [ -5, 35, 113, -15 ],
954 [ -11, 124, 17, -2 ],
955 [ -16, 113, 36, -5 ],
956 [ -17, 98, 57, -10 ],
957 [ -14, 78, 78, -14 ],
958 [ -10, 57, 98, -17 ],
959 [ -5, 36, 113, -16 ],
963 [ -12, 125, 17, -2 ],
964 [ -17, 114, 37, -6 ],
965 [ -18, 99, 58, -11 ],
966 [ -15, 79, 79, -15 ],
967 [ -11, 58, 99, -18 ],
968 [ -6, 37, 114, -17 ],
972 [ -12, 124, 18, -2 ],
973 [ -18, 114, 38, -6 ],
974 [ -19, 99, 59, -11 ],
975 [ -16, 80, 80, -16 ],
976 [ -11, 59, 99, -19 ],
977 [ -6, 38, 114, -18 ],