1 use nihav_core::codecs::*;
2 use nihav_core::io::bitreader::*;
3 use nihav_core::codecs::blockdsp::edge_emu;
4 use super::vpcommon::*;
7 const VERSION_VP60: u8 = 6;
8 //const VERSION_VP61: u8 = 7;
9 const VERSION_VP62: u8 = 8;
11 const VP6_SIMPLE_PROFILE: u8 = 0;
12 const VP6_ADVANCED_PROFILE: u8 = 3;
34 impl VP56Parser for VP6BR {
35 fn parse_header(&mut self, bc: &mut BoolCoder) -> DecoderResult<VP56Header> {
36 let mut hdr = VP56Header::default();
37 // horrible hack to match VP6 header parsing
39 let mut br = BitReader::new(src, src.len(), BitReaderMode::BE);
41 hdr.is_intra = !br.read_bool()?;
42 hdr.is_golden = hdr.is_intra;
43 hdr.quant = br.read(6)? as u8;
44 hdr.multistream = br.read_bool()?;
46 hdr.version = br.read(5)? as u8;
47 validate!((hdr.version >= VERSION_VP60) && (hdr.version <= VERSION_VP62));
48 hdr.profile = br.read(2)? as u8;
49 validate!((hdr.profile == VP6_SIMPLE_PROFILE) || (hdr.profile == VP6_ADVANCED_PROFILE));
50 hdr.interlaced = br.read_bool()?;
52 hdr.version = self.vpversion;
53 hdr.profile = self.profile;
54 hdr.interlaced = self.interlaced;
56 if hdr.multistream || (hdr.profile == VP6_SIMPLE_PROFILE) {
57 hdr.offset = br.read(16)? as u16;
58 validate!(hdr.offset > if hdr.is_intra { 6 } else { 2 });
60 let bytes = br.tell() >> 3;
65 hdr.mb_h = bc.read_bits(8) as u8;
66 hdr.mb_w = bc.read_bits(8) as u8;
67 hdr.disp_h = bc.read_bits(8) as u8;
68 hdr.disp_w = bc.read_bits(8) as u8;
69 validate!((hdr.mb_h > 0) && (hdr.mb_w > 0) && (hdr.disp_w > 0) && (hdr.disp_h > 0));
70 validate!((hdr.disp_w <= hdr.mb_w) && (hdr.disp_h <= hdr.mb_h));
71 hdr.scale = bc.read_bits(2) as u8;
73 hdr.is_golden = bc.read_bool();
74 if hdr.profile == VP6_ADVANCED_PROFILE {
75 self.loop_mode = bc.read_bool() as u8;
76 if self.loop_mode != 0 {
77 self.loop_mode += bc.read_bool() as u8;
78 validate!(self.loop_mode <= 1);
80 if hdr.version == VERSION_VP62 {
81 self.do_pm = bc.read_bool();
86 if (hdr.profile == VP6_ADVANCED_PROFILE) && (hdr.is_intra || self.do_pm) {
87 self.autosel_pm = bc.read_bool();
89 self.var_thresh = bc.read_bits(5) as u16;
90 if hdr.version != VERSION_VP62 {
91 self.var_thresh <<= 5;
93 self.mv_thresh = bc.read_bits(3) as u8;
95 self.bicubic = bc.read_bool();
97 if hdr.version == VERSION_VP62 {
98 self.filter_alpha = bc.read_bits(4) as usize;
100 self.filter_alpha = 16;
104 hdr.use_huffman = bc.read_bool();
106 self.vpversion = hdr.version;
107 self.profile = hdr.profile;
108 self.interlaced = hdr.interlaced;
111 fn decode_mv(&self, bc: &mut BoolCoder, model: &VP56MVModel) -> i16 {
112 const LONG_VECTOR_ORDER: [usize; 7] = [ 0, 1, 2, 7, 6, 5, 4 ];
114 let val = if !bc.read_prob(model.nz_prob) { // short vector
115 vp_tree!(bc, model.tree_probs[0],
116 vp_tree!(bc, model.tree_probs[1],
117 vp_tree!(bc, model.tree_probs[2], 0, 1),
118 vp_tree!(bc, model.tree_probs[3], 2, 3)),
119 vp_tree!(bc, model.tree_probs[4],
120 vp_tree!(bc, model.tree_probs[5], 4, 5),
121 vp_tree!(bc, model.tree_probs[6], 6, 7)))
124 for ord in LONG_VECTOR_ORDER.iter() {
125 raw |= (bc.read_prob(model.raw_probs[*ord]) as i16) << *ord;
127 if (raw & 0xF0) != 0 {
128 raw |= (bc.read_prob(model.raw_probs[3]) as i16) << 3;
134 if (val != 0) && bc.read_prob(model.sign_prob) {
140 fn reset_models(&self, models: &mut VP56Models) {
141 const NZ_PROBS: [u8; 2] = [ 162, 164 ];
142 const RAW_PROBS: [[u8; 8]; 2] = [
143 [ 247, 210, 135, 68, 138, 220, 239, 246 ],
144 [ 244, 184, 201, 44, 173, 221, 239, 253 ]
146 const TREE_PROBS: [[u8; 7]; 2] = [
147 [ 225, 146, 172, 147, 214, 39, 156 ],
148 [ 204, 170, 119, 235, 140, 230, 228 ]
150 const ZERO_RUN_PROBS: [[u8; 14]; 2] = [
151 [ 198, 197, 196, 146, 198, 204, 169, 142, 130, 136, 149, 149, 191, 249 ],
152 [ 135, 201, 181, 154, 98, 117, 132, 126, 146, 169, 184, 240, 246, 254 ]
155 for (i, mdl) in models.mv_models.iter_mut().enumerate() {
156 mdl.nz_prob = NZ_PROBS[i];
158 mdl.raw_probs.copy_from_slice(&RAW_PROBS[i]);
159 mdl.tree_probs.copy_from_slice(&TREE_PROBS[i]);
161 models.vp6models.zero_run_probs.copy_from_slice(&ZERO_RUN_PROBS);
162 reset_scan(&mut models.vp6models, self.interlaced);
164 fn decode_mv_models(&self, bc: &mut BoolCoder, models: &mut [VP56MVModel; 2]) -> DecoderResult<()> {
165 const HAS_NZ_PROB: [u8; 2] = [ 237, 231 ];
166 const HAS_SIGN_PROB: [u8; 2] = [ 246, 243 ];
167 const HAS_TREE_PROB: [[u8; 7]; 2] = [
168 [ 253, 253, 254, 254, 254, 254, 254 ],
169 [ 245, 253, 254, 254, 254, 254, 254 ]
171 const HAS_RAW_PROB: [[u8; 8]; 2] = [
172 [ 254, 254, 254, 254, 254, 250, 250, 252 ],
173 [ 254, 254, 254, 254, 254, 251, 251, 254 ]
177 if bc.read_prob(HAS_NZ_PROB[comp]) {
178 models[comp].nz_prob = bc.read_probability();
180 if bc.read_prob(HAS_SIGN_PROB[comp]) {
181 models[comp].sign_prob = bc.read_probability();
185 for (i, prob) in HAS_TREE_PROB[comp].iter().enumerate() {
186 if bc.read_prob(*prob) {
187 models[comp].tree_probs[i] = bc.read_probability();
192 for (i, prob) in HAS_RAW_PROB[comp].iter().enumerate() {
193 if bc.read_prob(*prob) {
194 models[comp].raw_probs[i] = bc.read_probability();
200 fn decode_coeff_models(&self, bc: &mut BoolCoder, models: &mut VP56Models, is_intra: bool) -> DecoderResult<()> {
201 const COEF_PROBS: [[u8; 11]; 2] = [
202 [ 146, 255, 181, 207, 232, 243, 238, 251, 244, 250, 249 ],
203 [ 179, 255, 214, 240, 250, 255, 244, 255, 255, 255, 255 ]
205 const SCAN_UPD_PROBS: [u8; 64] = [
206 0, 132, 132, 159, 153, 151, 161, 170,
207 164, 162, 136, 110, 103, 114, 129, 118,
208 124, 125, 132, 136, 114, 110, 142, 135,
209 134, 123, 143, 126, 153, 183, 166, 161,
210 171, 180, 179, 164, 203, 218, 225, 217,
211 215, 206, 203, 217, 229, 241, 248, 243,
212 253, 255, 253, 255, 255, 255, 255, 255,
213 255, 255, 255, 255, 255, 255, 255, 255
215 const ZERO_RUN_PROBS: [[u8; 14]; 2] = [
216 [ 219, 246, 238, 249, 232, 239, 249, 255, 248, 253, 239, 244, 241, 248 ],
217 [ 198, 232, 251, 253, 219, 241, 253, 255, 248, 249, 244, 238, 251, 255 ]
220 let mut def_prob = [128u8; 11];
223 if bc.read_prob(COEF_PROBS[plane][i]) {
224 def_prob[i] = bc.read_probability();
225 models.coeff_models[plane].dc_value_probs[i] = def_prob[i];
227 models.coeff_models[plane].dc_value_probs[i] = def_prob[i];
234 if bc.read_prob(SCAN_UPD_PROBS[i]) {
235 models.vp6models.scan_order[i] = bc.read_bits(4) as usize;
238 update_scan(&mut models.vp6models);
240 reset_scan(&mut models.vp6models, self.interlaced);
245 if bc.read_prob(ZERO_RUN_PROBS[comp][i]) {
246 models.vp6models.zero_run_probs[comp][i] = bc.read_probability();
255 if bc.read_prob(VP6_AC_PROBS[ctype][plane][group][i]) {
256 def_prob[i] = bc.read_probability();
257 models.coeff_models[plane].ac_val_probs[ctype][group][i] = def_prob[i];
259 models.coeff_models[plane].ac_val_probs[ctype][group][i] = def_prob[i];
266 let mdl = &mut models.coeff_models[plane];
269 mdl.dc_token_probs[0][i][k] = rescale_prob(mdl.dc_value_probs[k], &VP6_DC_WEIGHTS[k][i], 255);
275 fn decode_block(&self, bc: &mut BoolCoder, coeffs: &mut [i16; 64], model: &VP56CoeffModel, vp6model: &VP6Models, fstate: &mut FrameState) -> DecoderResult<()> {
276 let left_ctx = fstate.coeff_cat[fstate.ctx_idx][0] as usize;
277 let top_ctx = fstate.top_ctx as usize;
278 let dc_mode = top_ctx + left_ctx;
279 let token = decode_token_bc(bc, &model.dc_token_probs[0][dc_mode], model.dc_value_probs[5], true, true);
280 let val = expand_token_bc(bc, &model.dc_value_probs, token, 6);
282 fstate.last_idx[fstate.ctx_idx] = 0;
285 let mut last_val = val;
287 let ac_band = VP6_IDX_TO_AC_BAND[idx];
288 let ac_mode = last_val.abs().min(2) as usize;
289 let has_nnz = (idx == 1) || (last_val != 0);
290 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);
291 if token == 42 { break; }
292 let val = expand_token_bc(bc, &model.ac_val_probs[ac_mode][ac_band], token, 6);
293 coeffs[vp6model.zigzag[idx]] = val.wrapping_mul(fstate.ac_quant);
297 idx += decode_zero_run_bc(bc, &vp6model.zero_run_probs[if idx >= 7 { 1 } else { 0 }]);
298 validate!(idx <= 64);
301 fstate.coeff_cat[fstate.ctx_idx][0] = if coeffs[0] != 0 { 1 } else { 0 };
302 fstate.top_ctx = fstate.coeff_cat[fstate.ctx_idx][0];
303 fstate.last_idx[fstate.ctx_idx] = idx;
306 fn decode_block_huff(&self, br: &mut BitReader, coeffs: &mut [i16; 64], vp6model: &VP6Models, model: &VP6HuffModels, fstate: &mut FrameState) -> DecoderResult<()> {
307 let plane = if (fstate.plane == 0) || (fstate.plane == 3) { 0 } else { 1 };
310 if fstate.dc_zero_run[plane] == 0 {
311 let (val, eob) = decode_token_huff(br, &model.dc_token_tree[plane])?;
318 fstate.dc_zero_run[plane] = decode_eob_run_huff(br)?;
322 fstate.dc_zero_run[plane] -= 1;
325 if fstate.ac_zero_run[plane] > 0 {
326 fstate.ac_zero_run[plane] -= 1;
327 fstate.last_idx[fstate.ctx_idx] = 0;
333 let ac_band = VP6_IDX_TO_AC_BAND[idx].min(3);
334 let ac_mode = last_val.abs().min(2) as usize;
335 let (val, eob) = decode_token_huff(br, &model.ac_token_tree[plane][ac_mode][ac_band])?;
338 fstate.ac_zero_run[plane] = decode_eob_run_huff(br)?;
342 coeffs[vp6model.zigzag[idx]] = val.wrapping_mul(fstate.ac_quant);
346 idx += decode_zero_run_huff(br, &model.zero_run_tree[if idx >= 7 { 1 } else { 0 }])?;
347 validate!(idx <= 64);
351 fstate.last_idx[fstate.ctx_idx] = idx;
355 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) {
356 let is_luma = (plane != 1) && (plane != 2);
357 let (sx, sy, mx, my, msx, msy) = if is_luma {
358 (mv.x >> 2, mv.y >> 2, (mv.x & 3) << 1, (mv.y & 3) << 1, mv.x / 4, mv.y / 4)
360 (mv.x >> 3, mv.y >> 3, mv.x & 7, mv.y & 7, mv.x / 8, mv.y / 8)
362 let tmp_blk = mc_buf.get_data_mut().unwrap();
363 get_block(tmp_blk, 16, src.clone(), plane, x, y, sx, sy);
365 let foff = (8 - (sx & 7)) as usize;
367 vp31_loop_filter(tmp_blk, off, 1, 16, 12, loop_str);
370 let foff = (8 - (sy & 7)) as usize;
371 let off = (2 + foff) * 16;
372 vp31_loop_filter(tmp_blk, off, 16, 1, 12, loop_str);
374 let copy_mode = (mx == 0) && (my == 0);
375 let mut bicubic = !copy_mode && is_luma && self.bicubic;
376 if is_luma && !copy_mode && (self.profile == VP6_ADVANCED_PROFILE) {
377 if !self.autosel_pm {
380 let mv_limit = 1 << (self.mv_thresh + 1);
381 if (mv.x.abs() <= mv_limit) && (mv.y.abs() <= mv_limit) {
382 let mut var_off = 16 * 2 + 2;
383 if mv.x < 0 { var_off += 1; }
384 if mv.y < 0 { var_off += 16; }
385 let var = calc_variance(&tmp_blk[var_off..], 16);
386 if var >= self.var_thresh {
392 let dstride = dst.stride[plane];
393 let dbuf = &mut dst.data[dst.offset[plane] + x + y * dstride..];
395 let src = &tmp_blk[2 * 16 + 2..];
396 for (dline, sline) in dbuf.chunks_mut(dst.stride[plane]).zip(src.chunks(16)).take(8) {
397 for i in 0..8 { dline[i] = sline[i]; }
400 let coeff_h = &VP6_BICUBIC_COEFFS[self.filter_alpha][mx as usize];
401 let coeff_v = &VP6_BICUBIC_COEFFS[self.filter_alpha][my as usize];
402 mc_bicubic(dbuf, dstride, tmp_blk, 16 * 2 + 2, 16, coeff_h, coeff_v);
404 mc_bilinear(dbuf, dstride, tmp_blk, 16 * 2 + 2, 16, mx as u16, my as u16);
409 fn update_scan(model: &mut VP6Models) {
413 if model.scan_order[i] == band {
420 model.zigzag[i] = ZIGZAG[model.scan[i]];
424 fn reset_scan(model: &mut VP6Models, interlaced: bool) {
425 const VP6_DEFAULT_SCAN_ORDER: [usize; 64] = [
426 0, 0, 1, 1, 1, 2, 2, 2,
427 2, 2, 2, 3, 3, 4, 4, 4,
428 5, 5, 5, 5, 6, 6, 7, 7,
429 7, 7, 7, 8, 8, 9, 9, 9,
430 9, 9, 9, 10, 10, 11, 11, 11,
431 11, 11, 11, 12, 12, 12, 12, 12,
432 12, 13, 13, 13, 13, 13, 14, 14,
433 14, 14, 15, 15, 15, 15, 15, 15
435 const VP6_INTERLACED_SCAN_ORDER: [usize; 64] = [
436 0, 1, 0, 1, 1, 2, 5, 3,
437 2, 2, 2, 2, 4, 7, 8, 10,
438 9, 7, 5, 4, 2, 3, 5, 6,
439 8, 9, 11, 12, 13, 12, 11, 10,
440 9, 7, 5, 4, 6, 7, 9, 11,
441 12, 12, 13, 13, 14, 12, 11, 9,
442 7, 9, 11, 12, 14, 14, 14, 15,
443 13, 11, 13, 15, 15, 15, 15, 15
447 model.scan_order.copy_from_slice(&VP6_DEFAULT_SCAN_ORDER);
449 model.scan_order.copy_from_slice(&VP6_INTERLACED_SCAN_ORDER);
451 for i in 0..64 { model.scan[i] = i; }
452 model.zigzag.copy_from_slice(&ZIGZAG);
455 fn decode_token_bc(bc: &mut BoolCoder, probs: &[u8], prob34: u8, is_dc: bool, has_nnz: bool) -> u8 {
456 if has_nnz && !bc.read_prob(probs[0]) {
457 if is_dc || bc.read_prob(probs[1]) {
463 vp_tree!(bc, probs[2],
465 vp_tree!(bc, probs[3],
466 vp_tree!(bc, probs[4],
468 vp_tree!(bc, prob34, 3, 4)),
473 fn decode_zero_run_bc(bc: &mut BoolCoder, probs: &[u8; 14]) -> usize {
474 let val = vp_tree!(bc, probs[0],
475 vp_tree!(bc, probs[1],
476 vp_tree!(bc, probs[2], 0, 1),
477 vp_tree!(bc, probs[3], 2, 3)),
478 vp_tree!(bc, probs[4],
479 vp_tree!(bc, probs[5],
480 vp_tree!(bc, probs[6], 4, 5),
481 vp_tree!(bc, probs[7], 6, 7)),
488 nval += (bc.read_prob(probs[i + 8]) as usize) << i;
494 fn decode_token_huff(br: &mut BitReader, huff: &VP6Huff) -> DecoderResult<(i16, bool)> {
495 const COEF_ADD_BITS: [u8; 6] = [ 1, 2, 3, 4, 5, 11 ];
496 let tok = br.read_huff(huff)?;
500 if !br.read_bool()? {
501 Ok((tok as i16, false))
503 Ok((-(tok as i16), false))
506 5 | 6 | 7 | 8 | 9 | 10 => {
507 let base = (tok - 5) as usize;
508 let add_bits = br.read(COEF_ADD_BITS[base])? as i16;
509 let val = VP56_COEF_BASE[base] + add_bits;
510 if !br.read_bool()? {
520 fn decode_eob_run_huff(br: &mut BitReader) -> DecoderResult<usize> {
521 let val = br.read(2)?;
526 let val = br.read(2)?;
527 Ok((val as usize) + 2)
531 Ok((br.read(6)? as usize) + 10)
533 Ok((br.read(2)? as usize) + 6)
539 fn decode_zero_run_huff(br: &mut BitReader, huff: &VP6Huff) -> DecoderResult<usize> {
540 let val = br.read_huff(huff)?;
544 Ok((br.read(6)? as usize) + 8)
549 fn get_block(dst: &mut [u8], dstride: usize, src: NAVideoBufferRef<u8>, comp: usize,
550 dx: usize, dy: usize, mv_x: i16, mv_y: i16)
552 let (w, h) = src.get_dimensions(comp);
553 let sx = (dx as isize) + (mv_x as isize);
554 let sy = (dy as isize) + (mv_y as isize);
556 if (sx - 2 < 0) || (sx + 8 + 2 > (w as isize)) ||
557 (sy - 2 < 0) || (sy + 8 + 2 > (h as isize)) {
558 edge_emu(&src, sx - 2, sy - 2, 8 + 2 + 2, 8 + 2 + 2,
561 let sstride = src.get_stride(comp);
562 let soff = src.get_offset(comp);
563 let sdta = src.get_data();
564 let sbuf: &[u8] = sdta.as_slice();
565 let saddr = soff + ((sx - 2) as usize) + ((sy - 2) as usize) * sstride;
566 let src = &sbuf[saddr..];
567 for (dline, sline) in dst.chunks_mut(dstride).zip(src.chunks(sstride)).take(12) {
575 fn calc_variance(src: &[u8], stride: usize) -> u16 {
578 for line in src.chunks(stride * 2).take(4) {
579 for el in line.iter().take(8).step_by(2) {
580 let pix = *el as u32;
585 ((ssum * 16 - sum * sum) >> 8) as u16
588 macro_rules! mc_filter {
589 (bilinear; $a: expr, $b: expr, $c: expr) => {
590 ((($a as u16) * (8 - $c) + ($b as u16) * $c + 4) >> 3) as u8
592 (bicubic; $src: expr, $off: expr, $step: expr, $coeffs: expr) => {
593 ((($src[$off - $step] as i32) * ($coeffs[0] as i32) +
594 ($src[$off] as i32) * ($coeffs[1] as i32) +
595 ($src[$off + $step] as i32) * ($coeffs[2] as i32) +
596 ($src[$off + $step * 2] as i32) * ($coeffs[3] as i32) + 64) >> 7).min(255).max(0) as u8
600 //#[allow(snake_case)]
601 fn mc_bilinear(dst: &mut [u8], dstride: usize, src: &[u8], mut soff: usize, sstride: usize, mx: u16, my: u16) {
603 for dline in dst.chunks_mut(dstride).take(8) {
605 dline[i] = mc_filter!(bilinear; src[soff + i], src[soff + i + 1], mx);
610 for dline in dst.chunks_mut(dstride).take(8) {
612 dline[i] = mc_filter!(bilinear; src[soff + i], src[soff + i + sstride], my);
617 let mut tmp = [0u8; 8];
619 tmp[i] = mc_filter!(bilinear; src[soff + i], src[soff + i + 1], mx);
622 for dline in dst.chunks_mut(dstride).take(8) {
624 let cur = mc_filter!(bilinear; src[soff + i], src[soff + i + 1], mx);
625 dline[i] = mc_filter!(bilinear; tmp[i], cur, my);
633 fn mc_bicubic(dst: &mut [u8], dstride: usize, src: &[u8], mut soff: usize, sstride: usize, coeffs_w: &[i16; 4], coeffs_h: &[i16; 4]) {
634 if coeffs_h[1] == 128 {
635 for dline in dst.chunks_mut(dstride).take(8) {
637 dline[i] = mc_filter!(bicubic; src, soff + i, 1, coeffs_w);
641 } else if coeffs_w[1] == 128 { // horizontal-only interpolation
642 for dline in dst.chunks_mut(dstride).take(8) {
644 dline[i] = mc_filter!(bicubic; src, soff + i, sstride, coeffs_h);
649 let mut buf = [0u8; 16 * 11];
651 for dline in buf.chunks_mut(16) {
653 dline[i] = mc_filter!(bicubic; src, soff + i, 1, coeffs_w);
658 for dline in dst.chunks_mut(dstride).take(8) {
660 dline[i] = mc_filter!(bicubic; buf, soff + i, 16, coeffs_h);
669 info: NACodecInfoRef,
675 fn new(has_alpha: bool) -> Self {
677 dec: VP56Decoder::new(6, has_alpha, true),
678 info: NACodecInfoRef::default(),
685 impl NADecoder for VP6Decoder {
686 fn init(&mut self, supp: &mut NADecoderSupport, info: NACodecInfoRef) -> DecoderResult<()> {
687 if let NACodecTypeInfo::Video(vinfo) = info.get_properties() {
688 let fmt = if !self.has_alpha {
693 let myvinfo = NAVideoInfo::new(vinfo.get_width(), vinfo.get_height(), false, fmt);
694 let myinfo = NACodecTypeInfo::Video(myvinfo.clone());
695 self.info = NACodecInfo::new_ref(info.get_name(), myinfo, info.get_extradata()).into_ref();
696 self.dec.init(supp, myvinfo)?;
699 Err(DecoderError::InvalidData)
702 fn decode(&mut self, supp: &mut NADecoderSupport, pkt: &NAPacket) -> DecoderResult<NAFrameRef> {
703 let src = pkt.get_buffer();
705 let (bufinfo, ftype) = self.dec.decode_frame(supp, src.as_slice(), &mut self.br)?;
707 let mut frm = NAFrame::new_from_pkt(pkt, self.info.clone(), bufinfo);
708 frm.set_keyframe(ftype == FrameType::I);
709 frm.set_frame_type(ftype);
712 fn flush(&mut self) {
717 pub fn get_decoder_vp6() -> Box<NADecoder + Send> {
718 Box::new(VP6Decoder::new(false))
721 pub fn get_decoder_vp6_alpha() -> Box<NADecoder + Send> {
722 Box::new(VP6Decoder::new(true))
727 use nihav_core::codecs::RegisteredDecoders;
728 use nihav_core::demuxers::RegisteredDemuxers;
729 use nihav_core::test::dec_video::*;
730 use crate::codecs::duck_register_all_codecs;
731 use nihav_commonfmt::demuxers::generic_register_all_demuxers;
735 let mut dmx_reg = RegisteredDemuxers::new();
736 generic_register_all_demuxers(&mut dmx_reg);
737 let mut dec_reg = RegisteredDecoders::new();
738 duck_register_all_codecs(&mut dec_reg);
740 test_decoding("avi", "vp6", "assets/Duck/selection_720x576_300kBit_vp60i.avi", Some(16),
742 ExpectedTestResult::MD5([0x042c3e96, 0x8a9b26a2, 0x4dcbaf66, 0x1b788d03]));
746 let mut dmx_reg = RegisteredDemuxers::new();
747 generic_register_all_demuxers(&mut dmx_reg);
748 let mut dec_reg = RegisteredDecoders::new();
749 duck_register_all_codecs(&mut dec_reg);
751 test_decoding("avi", "vp6", "assets/Duck/vp6_crash.avi", Some(4),
752 &dmx_reg, &dec_reg, ExpectedTestResult::MD5Frames(vec![
753 [0xdcd70fa0, 0x0d075ce2, 0xc9e65077, 0xb003a92e],
754 [0x334abf96, 0x3a004c7a, 0x5781cd5c, 0x25c3ae5c],
755 [0x6164b851, 0x528cd8de, 0xecab7328, 0x4b49708a],
756 [0x11b048ac, 0xedb3e471, 0xd04e9399, 0x64e623e3],
757 [0x182871b1, 0x2146893a, 0x2912210e, 0x6dd592e8]]));
759 // todo find good sample for vp6a test
762 const VP6_AC_PROBS: [[[[u8; 11]; 6]; 2]; 3] = [
765 [ 227, 246, 230, 247, 244, 255, 255, 255, 255, 255, 255 ],
766 [ 255, 255, 209, 231, 231, 249, 249, 253, 255, 255, 255 ],
767 [ 255, 255, 225, 242, 241, 251, 253, 255, 255, 255, 255 ],
768 [ 255, 255, 241, 253, 252, 255, 255, 255, 255, 255, 255 ],
769 [ 255, 255, 248, 255, 255, 255, 255, 255, 255, 255, 255 ],
770 [ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 ]
772 [ 240, 255, 248, 255, 255, 255, 255, 255, 255, 255, 255 ],
773 [ 255, 255, 240, 253, 255, 255, 255, 255, 255, 255, 255 ],
774 [ 255, 255, 255, 255, 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 ]
781 [ 206, 203, 227, 239, 247, 255, 253, 255, 255, 255, 255 ],
782 [ 207, 199, 220, 236, 243, 252, 252, 255, 255, 255, 255 ],
783 [ 212, 219, 230, 243, 244, 253, 252, 255, 255, 255, 255 ],
784 [ 236, 237, 247, 252, 253, 255, 255, 255, 255, 255, 255 ],
785 [ 240, 240, 248, 255, 255, 255, 255, 255, 255, 255, 255 ],
786 [ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 ]
788 [ 230, 233, 249, 255, 255, 255, 255, 255, 255, 255, 255 ],
789 [ 238, 238, 250, 255, 255, 255, 255, 255, 255, 255, 255 ],
790 [ 248, 251, 255, 255, 255, 255, 255, 255, 255, 255, 255 ],
791 [ 255, 255, 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 ]
797 [ 225, 239, 227, 231, 244, 253, 243, 255, 255, 253, 255 ],
798 [ 232, 234, 224, 228, 242, 249, 242, 252, 251, 251, 255 ],
799 [ 235, 249, 238, 240, 251, 255, 249, 255, 253, 253, 255 ],
800 [ 249, 253, 251, 250, 255, 255, 255, 255, 255, 255, 255 ],
801 [ 251, 250, 249, 255, 255, 255, 255, 255, 255, 255, 255 ],
802 [ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 ]
804 [ 243, 244, 250, 250, 255, 255, 255, 255, 255, 255, 255 ],
805 [ 249, 248, 250, 253, 255, 255, 255, 255, 255, 255, 255 ],
806 [ 253, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 ],
807 [ 255, 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 ]
814 const VP6_DC_WEIGHTS: [[[i16; 2]; 3]; 5] = [
815 [ [ 122, 133 ], [ 133, 51 ], [ 142, -16 ] ],
816 [ [ 0, 1 ], [ 0, 1 ], [ 0, 1 ] ],
817 [ [ 78, 171 ], [ 169, 71 ], [ 221, -30 ] ],
818 [ [ 139, 117 ], [ 214, 44 ], [ 246, -3 ] ],
819 [ [ 168, 79 ], [ 210, 38 ], [ 203, 17 ] ]
822 const VP6_IDX_TO_AC_BAND: [usize; 64] = [
823 0, 0, 1, 1, 1, 2, 2, 2,
824 2, 2, 2, 3, 3, 3, 3, 3,
825 3, 3, 3, 3, 3, 3, 4, 4,
826 4, 4, 4, 4, 4, 4, 4, 4,
827 4, 4, 4, 4, 4, 5, 5, 5,
828 5, 5, 5, 5, 5, 5, 5, 5,
829 5, 5, 5, 5, 5, 5, 5, 5,
830 5, 5, 5, 5, 5, 5, 5, 5
833 const VP6_BICUBIC_COEFFS: [[[i16; 4]; 8]; 17] = [
891 [ -10, 111, 30, -3 ],
895 [ -3, 30, 111, -10 ],
900 [ -11, 112, 31, -4 ],
902 [ -10, 74, 74, -10 ],
904 [ -4, 31, 112, -11 ],
909 [ -12, 112, 32, -4 ],
911 [ -10, 74, 74, -10 ],
913 [ -4, 32, 112, -12 ],
918 [ -13, 112, 33, -4 ],
920 [ -11, 75, 75, -11 ],
922 [ -4, 33, 112, -13 ],
927 [ -14, 113, 34, -5 ],
929 [ -12, 76, 76, -12 ],
931 [ -5, 34, 112, -13 ],
935 [ -10, 124, 15, -1 ],
936 [ -14, 113, 34, -5 ],
938 [ -13, 77, 77, -13 ],
940 [ -5, 34, 113, -14 ],
944 [ -10, 123, 16, -1 ],
945 [ -15, 113, 35, -5 ],
946 [ -16, 98, 56, -10 ],
947 [ -14, 78, 78, -14 ],
948 [ -10, 56, 98, -16 ],
949 [ -5, 35, 113, -15 ],
953 [ -11, 124, 17, -2 ],
954 [ -16, 113, 36, -5 ],
955 [ -17, 98, 57, -10 ],
956 [ -14, 78, 78, -14 ],
957 [ -10, 57, 98, -17 ],
958 [ -5, 36, 113, -16 ],
962 [ -12, 125, 17, -2 ],
963 [ -17, 114, 37, -6 ],
964 [ -18, 99, 58, -11 ],
965 [ -15, 79, 79, -15 ],
966 [ -11, 58, 99, -18 ],
967 [ -6, 37, 114, -17 ],
971 [ -12, 124, 18, -2 ],
972 [ -18, 114, 38, -6 ],
973 [ -19, 99, 59, -11 ],
974 [ -16, 80, 80, -16 ],
975 [ -11, 59, 99, -19 ],
976 [ -6, 38, 114, -18 ],