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;
55 if hdr.multistream || (hdr.profile == VP6_SIMPLE_PROFILE) {
56 hdr.offset = br.read(16)? as u16;
57 validate!(hdr.offset > if hdr.is_intra { 6 } else { 2 });
59 let bytes = br.tell() >> 3;
64 hdr.mb_h = bc.read_bits(8) as u8;
65 hdr.mb_w = bc.read_bits(8) as u8;
66 hdr.disp_h = bc.read_bits(8) as u8;
67 hdr.disp_w = bc.read_bits(8) as u8;
68 validate!((hdr.mb_h > 0) && (hdr.mb_w > 0) && (hdr.disp_w > 0) && (hdr.disp_h > 0));
69 validate!((hdr.disp_w <= hdr.mb_w) && (hdr.disp_h <= hdr.mb_h));
70 hdr.scale = bc.read_bits(2) as u8;
72 hdr.is_golden = bc.read_bool();
73 if hdr.profile == VP6_ADVANCED_PROFILE {
74 self.loop_mode = bc.read_bool() as u8;
75 if self.loop_mode != 0 {
76 self.loop_mode += bc.read_bool() as u8;
77 validate!(self.loop_mode <= 1);
79 if hdr.version == VERSION_VP62 {
80 self.do_pm = bc.read_bool();
85 if (hdr.profile == VP6_ADVANCED_PROFILE) && (hdr.is_intra || self.do_pm) {
86 self.autosel_pm = bc.read_bool();
88 self.var_thresh = bc.read_bits(5) as u16;
89 if hdr.version != VERSION_VP62 {
90 self.var_thresh <<= 5;
92 self.mv_thresh = bc.read_bits(3) as u8;
94 self.bicubic = bc.read_bool();
96 if hdr.version == VERSION_VP62 {
97 self.filter_alpha = bc.read_bits(4) as usize;
99 self.filter_alpha = 16;
103 hdr.use_huffman = bc.read_bool();
105 self.vpversion = hdr.version;
106 self.profile = hdr.profile;
107 self.interlaced = hdr.interlaced;
110 fn decode_mv(&self, bc: &mut BoolCoder, model: &VP56MVModel) -> i16 {
111 const LONG_VECTOR_ORDER: [usize; 7] = [ 0, 1, 2, 7, 6, 5, 4 ];
113 let val = if !bc.read_prob(model.nz_prob) { // short vector
114 vp_tree!(bc, model.tree_probs[0],
115 vp_tree!(bc, model.tree_probs[1],
116 vp_tree!(bc, model.tree_probs[2], 0, 1),
117 vp_tree!(bc, model.tree_probs[3], 2, 3)),
118 vp_tree!(bc, model.tree_probs[4],
119 vp_tree!(bc, model.tree_probs[5], 4, 5),
120 vp_tree!(bc, model.tree_probs[6], 6, 7)))
123 for ord in LONG_VECTOR_ORDER.iter() {
124 raw |= (bc.read_prob(model.raw_probs[*ord]) as i16) << *ord;
126 if (raw & 0xF0) != 0 {
127 raw |= (bc.read_prob(model.raw_probs[3]) as i16) << 3;
133 if (val != 0) && bc.read_prob(model.sign_prob) {
139 fn reset_models(&self, models: &mut VP56Models) {
140 const NZ_PROBS: [u8; 2] = [ 162, 164 ];
141 const RAW_PROBS: [[u8; 8]; 2] = [
142 [ 247, 210, 135, 68, 138, 220, 239, 246 ],
143 [ 244, 184, 201, 44, 173, 221, 239, 253 ]
145 const TREE_PROBS: [[u8; 7]; 2] = [
146 [ 225, 146, 172, 147, 214, 39, 156 ],
147 [ 204, 170, 119, 235, 140, 230, 228 ]
149 const ZERO_RUN_PROBS: [[u8; 14]; 2] = [
150 [ 198, 197, 196, 146, 198, 204, 169, 142, 130, 136, 149, 149, 191, 249 ],
151 [ 135, 201, 181, 154, 98, 117, 132, 126, 146, 169, 184, 240, 246, 254 ]
154 for (i, mdl) in models.mv_models.iter_mut().enumerate() {
155 mdl.nz_prob = NZ_PROBS[i];
157 mdl.raw_probs.copy_from_slice(&RAW_PROBS[i]);
158 mdl.tree_probs.copy_from_slice(&TREE_PROBS[i]);
160 models.vp6models.zero_run_probs.copy_from_slice(&ZERO_RUN_PROBS);
161 reset_scan(&mut models.vp6models, self.interlaced);
163 fn decode_mv_models(&self, bc: &mut BoolCoder, models: &mut [VP56MVModel; 2]) -> DecoderResult<()> {
164 const HAS_NZ_PROB: [u8; 2] = [ 237, 231 ];
165 const HAS_SIGN_PROB: [u8; 2] = [ 246, 243 ];
166 const HAS_TREE_PROB: [[u8; 7]; 2] = [
167 [ 253, 253, 254, 254, 254, 254, 254 ],
168 [ 245, 253, 254, 254, 254, 254, 254 ]
170 const HAS_RAW_PROB: [[u8; 8]; 2] = [
171 [ 254, 254, 254, 254, 254, 250, 250, 252 ],
172 [ 254, 254, 254, 254, 254, 251, 251, 254 ]
176 if bc.read_prob(HAS_NZ_PROB[comp]) {
177 models[comp].nz_prob = bc.read_probability();
179 if bc.read_prob(HAS_SIGN_PROB[comp]) {
180 models[comp].sign_prob = bc.read_probability();
184 for (i, prob) in HAS_TREE_PROB[comp].iter().enumerate() {
185 if bc.read_prob(*prob) {
186 models[comp].tree_probs[i] = bc.read_probability();
191 for (i, prob) in HAS_RAW_PROB[comp].iter().enumerate() {
192 if bc.read_prob(*prob) {
193 models[comp].raw_probs[i] = bc.read_probability();
199 fn decode_coeff_models(&self, bc: &mut BoolCoder, models: &mut VP56Models, is_intra: bool) -> DecoderResult<()> {
200 const COEF_PROBS: [[u8; 11]; 2] = [
201 [ 146, 255, 181, 207, 232, 243, 238, 251, 244, 250, 249 ],
202 [ 179, 255, 214, 240, 250, 255, 244, 255, 255, 255, 255 ]
204 const SCAN_UPD_PROBS: [u8; 64] = [
205 0, 132, 132, 159, 153, 151, 161, 170,
206 164, 162, 136, 110, 103, 114, 129, 118,
207 124, 125, 132, 136, 114, 110, 142, 135,
208 134, 123, 143, 126, 153, 183, 166, 161,
209 171, 180, 179, 164, 203, 218, 225, 217,
210 215, 206, 203, 217, 229, 241, 248, 243,
211 253, 255, 253, 255, 255, 255, 255, 255,
212 255, 255, 255, 255, 255, 255, 255, 255
214 const ZERO_RUN_PROBS: [[u8; 14]; 2] = [
215 [ 219, 246, 238, 249, 232, 239, 249, 255, 248, 253, 239, 244, 241, 248 ],
216 [ 198, 232, 251, 253, 219, 241, 253, 255, 248, 249, 244, 238, 251, 255 ]
219 let mut def_prob = [128u8; 11];
222 if bc.read_prob(COEF_PROBS[plane][i]) {
223 def_prob[i] = bc.read_probability();
224 models.coeff_models[plane].dc_value_probs[i] = def_prob[i];
226 models.coeff_models[plane].dc_value_probs[i] = def_prob[i];
233 if bc.read_prob(SCAN_UPD_PROBS[i]) {
234 models.vp6models.scan_order[i] = bc.read_bits(4) as usize;
237 update_scan(&mut models.vp6models);
239 reset_scan(&mut models.vp6models, self.interlaced);
244 if bc.read_prob(ZERO_RUN_PROBS[comp][i]) {
245 models.vp6models.zero_run_probs[comp][i] = bc.read_probability();
254 if bc.read_prob(VP6_AC_PROBS[ctype][plane][group][i]) {
255 def_prob[i] = bc.read_probability();
256 models.coeff_models[plane].ac_val_probs[ctype][group][i] = def_prob[i];
258 models.coeff_models[plane].ac_val_probs[ctype][group][i] = def_prob[i];
265 let mdl = &mut models.coeff_models[plane];
268 mdl.dc_token_probs[0][i][k] = rescale_prob(mdl.dc_value_probs[k], &VP6_DC_WEIGHTS[k][i], 255);
274 fn decode_block(&self, bc: &mut BoolCoder, coeffs: &mut [i16; 64], model: &VP56CoeffModel, vp6model: &VP6Models, fstate: &mut FrameState) -> DecoderResult<()> {
275 let left_ctx = fstate.coeff_cat[fstate.ctx_idx][0] as usize;
276 let top_ctx = fstate.top_ctx as usize;
277 let dc_mode = top_ctx + left_ctx;
278 let token = decode_token_bc(bc, &model.dc_token_probs[0][dc_mode], model.dc_value_probs[5], true, true);
279 let val = expand_token_bc(bc, &model.dc_value_probs, token, 6);
281 fstate.last_idx[fstate.ctx_idx] = 0;
284 let mut last_val = val;
286 let ac_band = VP6_IDX_TO_AC_BAND[idx];
287 let ac_mode = last_val.abs().min(2) as usize;
288 let has_nnz = (idx == 1) || (last_val != 0);
289 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);
290 if token == 42 { break; }
291 let val = expand_token_bc(bc, &model.ac_val_probs[ac_mode][ac_band], token, 6);
292 coeffs[vp6model.zigzag[idx]] = val.wrapping_mul(fstate.ac_quant);
296 idx += decode_zero_run_bc(bc, &vp6model.zero_run_probs[if idx >= 7 { 1 } else { 0 }]);
297 validate!(idx <= 64);
300 fstate.coeff_cat[fstate.ctx_idx][0] = if coeffs[0] != 0 { 1 } else { 0 };
301 fstate.top_ctx = fstate.coeff_cat[fstate.ctx_idx][0];
302 fstate.last_idx[fstate.ctx_idx] = idx;
305 fn decode_block_huff(&self, br: &mut BitReader, coeffs: &mut [i16; 64], vp6model: &VP6Models, model: &VP6HuffModels, fstate: &mut FrameState) -> DecoderResult<()> {
306 let plane = if (fstate.plane == 0) || (fstate.plane == 3) { 0 } else { 1 };
309 if fstate.dc_zero_run[plane] == 0 {
310 let (val, eob) = decode_token_huff(br, &model.dc_token_tree[plane])?;
317 fstate.dc_zero_run[plane] = decode_eob_run_huff(br)?;
321 fstate.dc_zero_run[plane] -= 1;
324 if fstate.ac_zero_run[plane] > 0 {
325 fstate.ac_zero_run[plane] -= 1;
326 fstate.last_idx[fstate.ctx_idx] = 0;
332 let ac_band = VP6_IDX_TO_AC_BAND[idx].min(3);
333 let ac_mode = last_val.abs().min(2) as usize;
334 let (val, eob) = decode_token_huff(br, &model.ac_token_tree[plane][ac_mode][ac_band])?;
337 fstate.ac_zero_run[plane] = decode_eob_run_huff(br)?;
341 coeffs[vp6model.zigzag[idx]] = val.wrapping_mul(fstate.ac_quant);
345 idx += decode_zero_run_huff(br, &model.zero_run_tree[if idx >= 7 { 1 } else { 0 }])?;
346 validate!(idx <= 64);
350 fstate.last_idx[fstate.ctx_idx] = idx;
354 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) {
355 let is_luma = (plane != 1) && (plane != 2);
356 let (sx, sy, mx, my) = if is_luma {
357 (mv.x / 4, mv.y / 4, mv.x & 3, mv.y & 3)
359 (mv.x / 8, mv.y / 8, mv.x & 7, mv.y & 7)
361 let tmp_blk = mc_buf.get_data_mut().unwrap();
362 get_block(tmp_blk, 16, src.clone(), plane, x, y, sx, sy);
364 let mut bicubic = self.bicubic;
365 if is_luma && (self.profile == VP6_ADVANCED_PROFILE) {
366 if !self.autosel_pm {
369 let mv_limit = 1 << (self.mv_thresh + 1);
370 if (mv.x.abs() <= mv_limit) && (mv.y.abs() <= mv_limit) {
371 let var = calc_variance(&tmp_blk[16 * 2 + 2..], 16);
372 if var > self.var_thresh {
378 let dstride = dst.stride[plane];
379 let dbuf = &mut dst.data[dst.offset[plane] + x + y * dstride..];
380 if mx == 0 && my == 0 {
381 let src = &tmp_blk[2 * 16 + 2..];
382 for (dline, sline) in dbuf.chunks_mut(dst.stride[plane]).zip(src.chunks(16)).take(8) {
383 for i in 0..8 { dline[i] = sline[i]; }
385 } else if is_luma && bicubic {
386 let coeff_h = &VP6_BICUBIC_COEFFS[self.filter_alpha][mx as usize];
387 let coeff_v = &VP6_BICUBIC_COEFFS[self.filter_alpha][my as usize];
388 mc_bicubic(dbuf, dstride, tmp_blk, 16 * 2 + 2, 16, coeff_h, coeff_v);
390 mc_bilinear(dbuf, dstride, tmp_blk, 16 * 2 + 2, 16, mx as u16, my as u16);
395 fn update_scan(model: &mut VP6Models) {
399 if model.scan_order[i] == band {
406 model.zigzag[i] = ZIGZAG[model.scan[i]];
410 fn reset_scan(model: &mut VP6Models, interlaced: bool) {
411 const VP6_DEFAULT_SCAN_ORDER: [usize; 64] = [
412 0, 0, 1, 1, 1, 2, 2, 2,
413 2, 2, 2, 3, 3, 4, 4, 4,
414 5, 5, 5, 5, 6, 6, 7, 7,
415 7, 7, 7, 8, 8, 9, 9, 9,
416 9, 9, 9, 10, 10, 11, 11, 11,
417 11, 11, 11, 12, 12, 12, 12, 12,
418 12, 13, 13, 13, 13, 13, 14, 14,
419 14, 14, 15, 15, 15, 15, 15, 15
421 const VP6_INTERLACED_SCAN_ORDER: [usize; 64] = [
422 0, 1, 0, 1, 1, 2, 5, 3,
423 2, 2, 2, 2, 4, 7, 8, 10,
424 9, 7, 5, 4, 2, 3, 5, 6,
425 8, 9, 11, 12, 13, 12, 11, 10,
426 9, 7, 5, 4, 6, 7, 9, 11,
427 12, 12, 13, 13, 14, 12, 11, 9,
428 7, 9, 11, 12, 14, 14, 14, 15,
429 13, 11, 13, 15, 15, 15, 15, 15
433 model.scan_order.copy_from_slice(&VP6_DEFAULT_SCAN_ORDER);
435 model.scan_order.copy_from_slice(&VP6_INTERLACED_SCAN_ORDER);
437 for i in 0..64 { model.scan[i] = i; }
438 model.zigzag.copy_from_slice(&ZIGZAG);
441 fn decode_token_bc(bc: &mut BoolCoder, probs: &[u8], prob34: u8, is_dc: bool, has_nnz: bool) -> u8 {
442 if has_nnz && !bc.read_prob(probs[0]) {
443 if is_dc || bc.read_prob(probs[1]) {
449 vp_tree!(bc, probs[2],
451 vp_tree!(bc, probs[3],
452 vp_tree!(bc, probs[4],
454 vp_tree!(bc, prob34, 3, 4)),
459 fn decode_zero_run_bc(bc: &mut BoolCoder, probs: &[u8; 14]) -> usize {
460 let val = vp_tree!(bc, probs[0],
461 vp_tree!(bc, probs[1],
462 vp_tree!(bc, probs[2], 0, 1),
463 vp_tree!(bc, probs[3], 2, 3)),
464 vp_tree!(bc, probs[4],
465 vp_tree!(bc, probs[5],
466 vp_tree!(bc, probs[6], 4, 5),
467 vp_tree!(bc, probs[7], 6, 7)),
474 nval += (bc.read_prob(probs[i + 8]) as usize) << i;
480 fn decode_token_huff(br: &mut BitReader, huff: &VP6Huff) -> DecoderResult<(i16, bool)> {
481 const COEF_ADD_BITS: [u8; 6] = [ 1, 2, 3, 4, 5, 11 ];
482 let tok = br.read_huff(huff)?;
486 if !br.read_bool()? {
487 Ok((tok as i16, false))
489 Ok((-(tok as i16), false))
492 5 | 6 | 7 | 8 | 9 | 10 => {
493 let base = (tok - 5) as usize;
494 let add_bits = br.read(COEF_ADD_BITS[base])? as i16;
495 let val = VP56_COEF_BASE[base] + add_bits;
496 if !br.read_bool()? {
506 fn decode_eob_run_huff(br: &mut BitReader) -> DecoderResult<usize> {
507 let val = br.read(2)?;
512 let val = br.read(2)?;
513 Ok((val as usize) + 2)
517 Ok((br.read(6)? as usize) + 10)
519 Ok((br.read(2)? as usize) + 6)
525 fn decode_zero_run_huff(br: &mut BitReader, huff: &VP6Huff) -> DecoderResult<usize> {
526 let val = br.read_huff(huff)?;
530 Ok((br.read(6)? as usize) + 8)
535 fn get_block(dst: &mut [u8], dstride: usize, src: NAVideoBufferRef<u8>, comp: usize,
536 dx: usize, dy: usize, mv_x: i16, mv_y: i16)
538 let (w, h) = src.get_dimensions(comp);
539 let sx = (dx as isize) + (mv_x as isize);
540 let sy = (dy as isize) + (mv_y as isize);
542 if (sx - 2 < 0) || (sx + 8 + 2 > (w as isize)) ||
543 (sy - 2 < 0) || (sy + 8 + 2 > (h as isize)) {
544 edge_emu(&src, sx - 2, sy - 2, 8 + 2 + 2, 8 + 2 + 2,
547 let sstride = src.get_stride(comp);
548 let soff = src.get_offset(comp);
549 let sdta = src.get_data();
550 let sbuf: &[u8] = sdta.as_slice();
551 let saddr = soff + ((sx - 2) as usize) + ((sy - 2) as usize) * sstride;
552 let src = &sbuf[saddr..];
553 for (dline, sline) in dst.chunks_mut(dstride).zip(src.chunks(sstride)).take(12) {
561 fn calc_variance(src: &[u8], stride: usize) -> u16 {
564 for line in src.chunks(stride * 2).take(8) {
565 for el in line.iter().take(8).step_by(2) {
566 let pix = *el as u32;
571 ((ssum * 16 - sum * sum) >> 8) as u16
574 macro_rules! mc_filter {
575 (bilinear; $a: expr, $b: expr, $c: expr) => {
576 ((($a as u16) * (8 - $c) + ($b as u16) * $c + 3) >> 3) as u8
578 (bicubic; $src: expr, $off: expr, $step: expr, $coeffs: expr) => {
579 ((($src[$off - $step] as i32) * ($coeffs[0] as i32) +
580 ($src[$off] as i32) * ($coeffs[1] as i32) +
581 ($src[$off + $step] as i32) * ($coeffs[2] as i32) +
582 ($src[$off + $step * 2] as i32) * ($coeffs[3] as i32) + 64) >> 7).min(255).max(0) as u8
586 //#[allow(snake_case)]
587 fn mc_bilinear(dst: &mut [u8], dstride: usize, src: &[u8], mut soff: usize, sstride: usize, mx: u16, my: u16) {
589 for dline in dst.chunks_mut(dstride).take(8) {
591 dline[i] = mc_filter!(bilinear; src[soff + i], src[soff + i + 1], mx);
596 for dline in dst.chunks_mut(dstride).take(8) {
598 dline[i] = mc_filter!(bilinear; src[soff + i], src[soff + i + sstride], my);
603 let mut tmp = [0u8; 8];
605 tmp[i] = mc_filter!(bilinear; src[soff + i], src[soff + i + 1], mx);
608 for dline in dst.chunks_mut(dstride).take(8) {
610 let cur = mc_filter!(bilinear; src[soff + i], src[soff + i + 1], mx);
611 dline[i] = mc_filter!(bilinear; tmp[i], cur, my);
619 fn mc_bicubic(dst: &mut [u8], dstride: usize, src: &[u8], mut soff: usize, sstride: usize, coeffs_w: &[i16; 4], coeffs_h: &[i16; 4]) {
620 if coeffs_h[1] == 128 {
621 for dline in dst.chunks_mut(dstride).take(8) {
623 dline[i] = mc_filter!(bicubic; src, soff + i, 1, coeffs_w);
627 } else if coeffs_w[1] == 128 { // horizontal-only interpolation
628 for dline in dst.chunks_mut(dstride).take(8) {
630 dline[i] = mc_filter!(bicubic; src, soff + i, sstride, coeffs_h);
635 let mut buf = [0u8; 16 * 11];
637 for dline in buf.chunks_mut(16) {
639 dline[i] = mc_filter!(bicubic; src, soff + i, 1, coeffs_w);
644 for dline in dst.chunks_mut(dstride).take(8) {
646 dline[i] = mc_filter!(bicubic; buf, soff + i, 16, coeffs_h);
655 info: NACodecInfoRef,
661 fn new(has_alpha: bool) -> Self {
663 dec: VP56Decoder::new(6, has_alpha, true),
664 info: NACodecInfoRef::default(),
671 impl NADecoder for VP6Decoder {
672 fn init(&mut self, supp: &mut NADecoderSupport, info: NACodecInfoRef) -> DecoderResult<()> {
673 if let NACodecTypeInfo::Video(vinfo) = info.get_properties() {
674 let fmt = if !self.has_alpha {
677 NAPixelFormaton::new(ColorModel::YUV(YUVSubmodel::YUVJ),
678 Some(NAPixelChromaton::new(0, 0, false, 8, 0, 0, 1)),
679 Some(NAPixelChromaton::new(1, 1, false, 8, 0, 1, 1)),
680 Some(NAPixelChromaton::new(1, 1, false, 8, 0, 2, 1)),
681 Some(NAPixelChromaton::new(0, 0, false, 8, 0, 3, 1)),
685 let myvinfo = NAVideoInfo::new(vinfo.get_width(), vinfo.get_height(), false, fmt);
686 let myinfo = NACodecTypeInfo::Video(myvinfo.clone());
687 self.info = NACodecInfo::new_ref(info.get_name(), myinfo, info.get_extradata()).into_ref();
688 self.dec.init(supp, myvinfo)?;
691 Err(DecoderError::InvalidData)
694 fn decode(&mut self, supp: &mut NADecoderSupport, pkt: &NAPacket) -> DecoderResult<NAFrameRef> {
695 let src = pkt.get_buffer();
697 let (bufinfo, ftype) = self.dec.decode_frame(supp, src.as_slice(), &mut self.br)?;
699 let mut frm = NAFrame::new_from_pkt(pkt, self.info.clone(), bufinfo);
700 frm.set_keyframe(ftype == FrameType::I);
701 frm.set_frame_type(ftype);
704 fn flush(&mut self) {
709 pub fn get_decoder_vp6() -> Box<NADecoder + Send> {
710 Box::new(VP6Decoder::new(false))
713 pub fn get_decoder_vp6_alpha() -> Box<NADecoder + Send> {
714 Box::new(VP6Decoder::new(true))
719 use nihav_core::codecs::RegisteredDecoders;
720 use nihav_core::demuxers::RegisteredDemuxers;
721 use nihav_core::test::dec_video::*;
722 use crate::codecs::duck_register_all_codecs;
723 use nihav_commonfmt::demuxers::generic_register_all_demuxers;
727 let mut dmx_reg = RegisteredDemuxers::new();
728 generic_register_all_demuxers(&mut dmx_reg);
729 let mut dec_reg = RegisteredDecoders::new();
730 duck_register_all_codecs(&mut dec_reg);
732 //let file = "assets/Duck/predator2_vp60.avi";
733 //let file = "assets/Duck/predator2_vp61.avi";
734 //let file = "assets/Duck/vp6_crash.avi";
735 let file = "assets/Duck/vp6_interlaced.avi";
736 //let file = "assets/Duck/vp6_vid.avi";
737 //let file = "assets/Duck/selection_720x576_300kBit_vp60i.avi";
738 //let file = "assets/Duck/selection_720x576_300kBit_flipped_vp60i.avi";
739 test_file_decoding("avi", file, Some(17), true, false, None/*Some("vp6")*/, &dmx_reg, &dec_reg);
744 const VP6_AC_PROBS: [[[[u8; 11]; 6]; 2]; 3] = [
747 [ 227, 246, 230, 247, 244, 255, 255, 255, 255, 255, 255 ],
748 [ 255, 255, 209, 231, 231, 249, 249, 253, 255, 255, 255 ],
749 [ 255, 255, 225, 242, 241, 251, 253, 255, 255, 255, 255 ],
750 [ 255, 255, 241, 253, 252, 255, 255, 255, 255, 255, 255 ],
751 [ 255, 255, 248, 255, 255, 255, 255, 255, 255, 255, 255 ],
752 [ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 ]
754 [ 240, 255, 248, 255, 255, 255, 255, 255, 255, 255, 255 ],
755 [ 255, 255, 240, 253, 255, 255, 255, 255, 255, 255, 255 ],
756 [ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 ],
757 [ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 ],
758 [ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 ],
759 [ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 ]
763 [ 206, 203, 227, 239, 247, 255, 253, 255, 255, 255, 255 ],
764 [ 207, 199, 220, 236, 243, 252, 252, 255, 255, 255, 255 ],
765 [ 212, 219, 230, 243, 244, 253, 252, 255, 255, 255, 255 ],
766 [ 236, 237, 247, 252, 253, 255, 255, 255, 255, 255, 255 ],
767 [ 240, 240, 248, 255, 255, 255, 255, 255, 255, 255, 255 ],
768 [ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 ]
770 [ 230, 233, 249, 255, 255, 255, 255, 255, 255, 255, 255 ],
771 [ 238, 238, 250, 255, 255, 255, 255, 255, 255, 255, 255 ],
772 [ 248, 251, 255, 255, 255, 255, 255, 255, 255, 255, 255 ],
773 [ 255, 255, 255, 255, 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 ]
779 [ 225, 239, 227, 231, 244, 253, 243, 255, 255, 253, 255 ],
780 [ 232, 234, 224, 228, 242, 249, 242, 252, 251, 251, 255 ],
781 [ 235, 249, 238, 240, 251, 255, 249, 255, 253, 253, 255 ],
782 [ 249, 253, 251, 250, 255, 255, 255, 255, 255, 255, 255 ],
783 [ 251, 250, 249, 255, 255, 255, 255, 255, 255, 255, 255 ],
784 [ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 ]
786 [ 243, 244, 250, 250, 255, 255, 255, 255, 255, 255, 255 ],
787 [ 249, 248, 250, 253, 255, 255, 255, 255, 255, 255, 255 ],
788 [ 253, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 ],
789 [ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 ],
790 [ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 ],
791 [ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 ]
796 const VP6_DC_WEIGHTS: [[[i16; 2]; 3]; 5] = [
797 [ [ 122, 133 ], [ 133, 51 ], [ 142, -16 ] ],
798 [ [ 0, 1 ], [ 0, 1 ], [ 0, 1 ] ],
799 [ [ 78, 171 ], [ 169, 71 ], [ 221, -30 ] ],
800 [ [ 139, 117 ], [ 214, 44 ], [ 246, -3 ] ],
801 [ [ 168, 79 ], [ 210, 38 ], [ 203, 17 ] ]
804 const VP6_IDX_TO_AC_BAND: [usize; 64] = [
805 0, 0, 1, 1, 1, 2, 2, 2,
806 2, 2, 2, 3, 3, 3, 3, 3,
807 3, 3, 3, 3, 3, 3, 4, 4,
808 4, 4, 4, 4, 4, 4, 4, 4,
809 4, 4, 4, 4, 4, 5, 5, 5,
810 5, 5, 5, 5, 5, 5, 5, 5,
811 5, 5, 5, 5, 5, 5, 5, 5,
812 5, 5, 5, 5, 5, 5, 5, 5
815 const VP6_BICUBIC_COEFFS: [[[i16; 4]; 8]; 17] = [
873 [ -10, 111, 30, -3 ],
877 [ -3, 30, 111, -10 ],
882 [ -11, 112, 31, -4 ],
884 [ -10, 74, 74, -10 ],
886 [ -4, 31, 112, -11 ],
891 [ -12, 112, 32, -4 ],
893 [ -10, 74, 74, -10 ],
895 [ -4, 32, 112, -12 ],
900 [ -13, 112, 33, -4 ],
902 [ -11, 75, 75, -11 ],
904 [ -4, 33, 112, -13 ],
909 [ -14, 113, 34, -5 ],
911 [ -12, 76, 76, -12 ],
913 [ -5, 34, 112, -13 ],
917 [ -10, 124, 15, -1 ],
918 [ -14, 113, 34, -5 ],
920 [ -13, 77, 77, -13 ],
922 [ -5, 34, 113, -14 ],
926 [ -10, 123, 16, -1 ],
927 [ -15, 113, 35, -5 ],
928 [ -16, 98, 56, -10 ],
929 [ -14, 78, 78, -14 ],
930 [ -10, 56, 98, -16 ],
931 [ -5, 35, 113, -15 ],
935 [ -11, 124, 17, -2 ],
936 [ -16, 113, 36, -5 ],
937 [ -17, 98, 57, -10 ],
938 [ -14, 78, 78, -14 ],
939 [ -10, 57, 98, -17 ],
940 [ -5, 36, 113, -16 ],
944 [ -12, 125, 17, -2 ],
945 [ -17, 114, 37, -6 ],
946 [ -18, 99, 58, -11 ],
947 [ -15, 79, 79, -15 ],
948 [ -11, 58, 99, -18 ],
949 [ -6, 37, 114, -17 ],
953 [ -12, 124, 18, -2 ],
954 [ -18, 114, 38, -6 ],
955 [ -19, 99, 59, -11 ],
956 [ -16, 80, 80, -16 ],
957 [ -11, 59, 99, -19 ],
958 [ -6, 38, 114, -18 ],