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, msx, msy) = if is_luma {
357 (mv.x >> 2, mv.y >> 2, (mv.x & 3) << 1, (mv.y & 3) << 1, mv.x / 4, mv.y / 4)
359 (mv.x >> 3, mv.y >> 3, mv.x & 7, mv.y & 7, mv.x / 8, mv.y / 8)
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 foff = (8 - (sx & 7)) as usize;
366 vp31_loop_filter(tmp_blk, off, 1, 16, 12, loop_str);
369 let foff = (8 - (sy & 7)) as usize;
370 let off = (2 + foff) * 16;
371 vp31_loop_filter(tmp_blk, off, 16, 1, 12, loop_str);
373 let copy_mode = (mx == 0) && (my == 0);
374 let mut bicubic = !copy_mode && is_luma && self.bicubic;
375 if is_luma && !copy_mode && (self.profile == VP6_ADVANCED_PROFILE) {
376 if !self.autosel_pm {
379 let mv_limit = 1 << (self.mv_thresh + 1);
380 if (mv.x.abs() <= mv_limit) && (mv.y.abs() <= mv_limit) {
381 let mut var_off = 16 * 2 + 2;
382 if mv.x < 0 { var_off += 1; }
383 if mv.y < 0 { var_off += 16; }
384 let var = calc_variance(&tmp_blk[var_off..], 16);
385 if var >= self.var_thresh {
391 let dstride = dst.stride[plane];
392 let dbuf = &mut dst.data[dst.offset[plane] + x + y * dstride..];
394 let src = &tmp_blk[2 * 16 + 2..];
395 for (dline, sline) in dbuf.chunks_mut(dst.stride[plane]).zip(src.chunks(16)).take(8) {
396 for i in 0..8 { dline[i] = sline[i]; }
399 let coeff_h = &VP6_BICUBIC_COEFFS[self.filter_alpha][mx as usize];
400 let coeff_v = &VP6_BICUBIC_COEFFS[self.filter_alpha][my as usize];
401 mc_bicubic(dbuf, dstride, tmp_blk, 16 * 2 + 2, 16, coeff_h, coeff_v);
403 mc_bilinear(dbuf, dstride, tmp_blk, 16 * 2 + 2, 16, mx as u16, my as u16);
408 fn update_scan(model: &mut VP6Models) {
412 if model.scan_order[i] == band {
419 model.zigzag[i] = ZIGZAG[model.scan[i]];
423 fn reset_scan(model: &mut VP6Models, interlaced: bool) {
424 const VP6_DEFAULT_SCAN_ORDER: [usize; 64] = [
425 0, 0, 1, 1, 1, 2, 2, 2,
426 2, 2, 2, 3, 3, 4, 4, 4,
427 5, 5, 5, 5, 6, 6, 7, 7,
428 7, 7, 7, 8, 8, 9, 9, 9,
429 9, 9, 9, 10, 10, 11, 11, 11,
430 11, 11, 11, 12, 12, 12, 12, 12,
431 12, 13, 13, 13, 13, 13, 14, 14,
432 14, 14, 15, 15, 15, 15, 15, 15
434 const VP6_INTERLACED_SCAN_ORDER: [usize; 64] = [
435 0, 1, 0, 1, 1, 2, 5, 3,
436 2, 2, 2, 2, 4, 7, 8, 10,
437 9, 7, 5, 4, 2, 3, 5, 6,
438 8, 9, 11, 12, 13, 12, 11, 10,
439 9, 7, 5, 4, 6, 7, 9, 11,
440 12, 12, 13, 13, 14, 12, 11, 9,
441 7, 9, 11, 12, 14, 14, 14, 15,
442 13, 11, 13, 15, 15, 15, 15, 15
446 model.scan_order.copy_from_slice(&VP6_DEFAULT_SCAN_ORDER);
448 model.scan_order.copy_from_slice(&VP6_INTERLACED_SCAN_ORDER);
450 for i in 0..64 { model.scan[i] = i; }
451 model.zigzag.copy_from_slice(&ZIGZAG);
454 fn decode_token_bc(bc: &mut BoolCoder, probs: &[u8], prob34: u8, is_dc: bool, has_nnz: bool) -> u8 {
455 if has_nnz && !bc.read_prob(probs[0]) {
456 if is_dc || bc.read_prob(probs[1]) {
462 vp_tree!(bc, probs[2],
464 vp_tree!(bc, probs[3],
465 vp_tree!(bc, probs[4],
467 vp_tree!(bc, prob34, 3, 4)),
472 fn decode_zero_run_bc(bc: &mut BoolCoder, probs: &[u8; 14]) -> usize {
473 let val = vp_tree!(bc, probs[0],
474 vp_tree!(bc, probs[1],
475 vp_tree!(bc, probs[2], 0, 1),
476 vp_tree!(bc, probs[3], 2, 3)),
477 vp_tree!(bc, probs[4],
478 vp_tree!(bc, probs[5],
479 vp_tree!(bc, probs[6], 4, 5),
480 vp_tree!(bc, probs[7], 6, 7)),
487 nval += (bc.read_prob(probs[i + 8]) as usize) << i;
493 fn decode_token_huff(br: &mut BitReader, huff: &VP6Huff) -> DecoderResult<(i16, bool)> {
494 const COEF_ADD_BITS: [u8; 6] = [ 1, 2, 3, 4, 5, 11 ];
495 let tok = br.read_huff(huff)?;
499 if !br.read_bool()? {
500 Ok((tok as i16, false))
502 Ok((-(tok as i16), false))
505 5 | 6 | 7 | 8 | 9 | 10 => {
506 let base = (tok - 5) as usize;
507 let add_bits = br.read(COEF_ADD_BITS[base])? as i16;
508 let val = VP56_COEF_BASE[base] + add_bits;
509 if !br.read_bool()? {
519 fn decode_eob_run_huff(br: &mut BitReader) -> DecoderResult<usize> {
520 let val = br.read(2)?;
525 let val = br.read(2)?;
526 Ok((val as usize) + 2)
530 Ok((br.read(6)? as usize) + 10)
532 Ok((br.read(2)? as usize) + 6)
538 fn decode_zero_run_huff(br: &mut BitReader, huff: &VP6Huff) -> DecoderResult<usize> {
539 let val = br.read_huff(huff)?;
543 Ok((br.read(6)? as usize) + 8)
548 fn get_block(dst: &mut [u8], dstride: usize, src: NAVideoBufferRef<u8>, comp: usize,
549 dx: usize, dy: usize, mv_x: i16, mv_y: i16)
551 let (w, h) = src.get_dimensions(comp);
552 let sx = (dx as isize) + (mv_x as isize);
553 let sy = (dy as isize) + (mv_y as isize);
555 if (sx - 2 < 0) || (sx + 8 + 2 > (w as isize)) ||
556 (sy - 2 < 0) || (sy + 8 + 2 > (h as isize)) {
557 edge_emu(&src, sx - 2, sy - 2, 8 + 2 + 2, 8 + 2 + 2,
560 let sstride = src.get_stride(comp);
561 let soff = src.get_offset(comp);
562 let sdta = src.get_data();
563 let sbuf: &[u8] = sdta.as_slice();
564 let saddr = soff + ((sx - 2) as usize) + ((sy - 2) as usize) * sstride;
565 let src = &sbuf[saddr..];
566 for (dline, sline) in dst.chunks_mut(dstride).zip(src.chunks(sstride)).take(12) {
574 fn calc_variance(src: &[u8], stride: usize) -> u16 {
577 for line in src.chunks(stride * 2).take(4) {
578 for el in line.iter().take(8).step_by(2) {
579 let pix = *el as u32;
584 ((ssum * 16 - sum * sum) >> 8) as u16
587 macro_rules! mc_filter {
588 (bilinear; $a: expr, $b: expr, $c: expr) => {
589 ((($a as u16) * (8 - $c) + ($b as u16) * $c + 4) >> 3) as u8
591 (bicubic; $src: expr, $off: expr, $step: expr, $coeffs: expr) => {
592 ((($src[$off - $step] as i32) * ($coeffs[0] as i32) +
593 ($src[$off] as i32) * ($coeffs[1] as i32) +
594 ($src[$off + $step] as i32) * ($coeffs[2] as i32) +
595 ($src[$off + $step * 2] as i32) * ($coeffs[3] as i32) + 64) >> 7).min(255).max(0) as u8
599 //#[allow(snake_case)]
600 fn mc_bilinear(dst: &mut [u8], dstride: usize, src: &[u8], mut soff: usize, sstride: usize, mx: u16, my: u16) {
602 for dline in dst.chunks_mut(dstride).take(8) {
604 dline[i] = mc_filter!(bilinear; src[soff + i], src[soff + i + 1], mx);
609 for dline in dst.chunks_mut(dstride).take(8) {
611 dline[i] = mc_filter!(bilinear; src[soff + i], src[soff + i + sstride], my);
616 let mut tmp = [0u8; 8];
618 tmp[i] = mc_filter!(bilinear; src[soff + i], src[soff + i + 1], mx);
621 for dline in dst.chunks_mut(dstride).take(8) {
623 let cur = mc_filter!(bilinear; src[soff + i], src[soff + i + 1], mx);
624 dline[i] = mc_filter!(bilinear; tmp[i], cur, my);
632 fn mc_bicubic(dst: &mut [u8], dstride: usize, src: &[u8], mut soff: usize, sstride: usize, coeffs_w: &[i16; 4], coeffs_h: &[i16; 4]) {
633 if coeffs_h[1] == 128 {
634 for dline in dst.chunks_mut(dstride).take(8) {
636 dline[i] = mc_filter!(bicubic; src, soff + i, 1, coeffs_w);
640 } else if coeffs_w[1] == 128 { // horizontal-only interpolation
641 for dline in dst.chunks_mut(dstride).take(8) {
643 dline[i] = mc_filter!(bicubic; src, soff + i, sstride, coeffs_h);
648 let mut buf = [0u8; 16 * 11];
650 for dline in buf.chunks_mut(16) {
652 dline[i] = mc_filter!(bicubic; src, soff + i, 1, coeffs_w);
657 for dline in dst.chunks_mut(dstride).take(8) {
659 dline[i] = mc_filter!(bicubic; buf, soff + i, 16, coeffs_h);
668 info: NACodecInfoRef,
674 fn new(has_alpha: bool) -> Self {
676 dec: VP56Decoder::new(6, has_alpha, true),
677 info: NACodecInfoRef::default(),
684 impl NADecoder for VP6Decoder {
685 fn init(&mut self, supp: &mut NADecoderSupport, info: NACodecInfoRef) -> DecoderResult<()> {
686 if let NACodecTypeInfo::Video(vinfo) = info.get_properties() {
687 let fmt = if !self.has_alpha {
690 NAPixelFormaton::new(ColorModel::YUV(YUVSubmodel::YUVJ),
691 Some(NAPixelChromaton::new(0, 0, false, 8, 0, 0, 1)),
692 Some(NAPixelChromaton::new(1, 1, false, 8, 0, 1, 1)),
693 Some(NAPixelChromaton::new(1, 1, false, 8, 0, 2, 1)),
694 Some(NAPixelChromaton::new(0, 0, false, 8, 0, 3, 1)),
698 let myvinfo = NAVideoInfo::new(vinfo.get_width(), vinfo.get_height(), false, fmt);
699 let myinfo = NACodecTypeInfo::Video(myvinfo.clone());
700 self.info = NACodecInfo::new_ref(info.get_name(), myinfo, info.get_extradata()).into_ref();
701 self.dec.init(supp, myvinfo)?;
704 Err(DecoderError::InvalidData)
707 fn decode(&mut self, supp: &mut NADecoderSupport, pkt: &NAPacket) -> DecoderResult<NAFrameRef> {
708 let src = pkt.get_buffer();
710 let (bufinfo, ftype) = self.dec.decode_frame(supp, src.as_slice(), &mut self.br)?;
712 let mut frm = NAFrame::new_from_pkt(pkt, self.info.clone(), bufinfo);
713 frm.set_keyframe(ftype == FrameType::I);
714 frm.set_frame_type(ftype);
717 fn flush(&mut self) {
722 pub fn get_decoder_vp6() -> Box<NADecoder + Send> {
723 Box::new(VP6Decoder::new(false))
726 pub fn get_decoder_vp6_alpha() -> Box<NADecoder + Send> {
727 Box::new(VP6Decoder::new(true))
732 use nihav_core::codecs::RegisteredDecoders;
733 use nihav_core::demuxers::RegisteredDemuxers;
734 use nihav_core::test::dec_video::*;
735 use crate::codecs::duck_register_all_codecs;
736 use nihav_commonfmt::demuxers::generic_register_all_demuxers;
740 let mut dmx_reg = RegisteredDemuxers::new();
741 generic_register_all_demuxers(&mut dmx_reg);
742 let mut dec_reg = RegisteredDecoders::new();
743 duck_register_all_codecs(&mut dec_reg);
745 //let file = "assets/Duck/predator2_vp60.avi";
746 //let file = "assets/Duck/predator2_vp61.avi";
747 //let file = "assets/Duck/vp6_crash.avi";
748 let file = "assets/Duck/vp6_interlaced.avi";
749 //let file = "assets/Duck/vp6_vid.avi";
750 //let file = "assets/Duck/selection_720x576_300kBit_vp60i.avi";
751 //let file = "assets/Duck/selection_720x576_300kBit_flipped_vp60i.avi";
752 test_file_decoding("avi", file, Some(17), true, false, None/*Some("vp6")*/, &dmx_reg, &dec_reg);
757 const VP6_AC_PROBS: [[[[u8; 11]; 6]; 2]; 3] = [
760 [ 227, 246, 230, 247, 244, 255, 255, 255, 255, 255, 255 ],
761 [ 255, 255, 209, 231, 231, 249, 249, 253, 255, 255, 255 ],
762 [ 255, 255, 225, 242, 241, 251, 253, 255, 255, 255, 255 ],
763 [ 255, 255, 241, 253, 252, 255, 255, 255, 255, 255, 255 ],
764 [ 255, 255, 248, 255, 255, 255, 255, 255, 255, 255, 255 ],
765 [ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 ]
767 [ 240, 255, 248, 255, 255, 255, 255, 255, 255, 255, 255 ],
768 [ 255, 255, 240, 253, 255, 255, 255, 255, 255, 255, 255 ],
769 [ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 ],
770 [ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 ],
771 [ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 ],
772 [ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 ]
776 [ 206, 203, 227, 239, 247, 255, 253, 255, 255, 255, 255 ],
777 [ 207, 199, 220, 236, 243, 252, 252, 255, 255, 255, 255 ],
778 [ 212, 219, 230, 243, 244, 253, 252, 255, 255, 255, 255 ],
779 [ 236, 237, 247, 252, 253, 255, 255, 255, 255, 255, 255 ],
780 [ 240, 240, 248, 255, 255, 255, 255, 255, 255, 255, 255 ],
781 [ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 ]
783 [ 230, 233, 249, 255, 255, 255, 255, 255, 255, 255, 255 ],
784 [ 238, 238, 250, 255, 255, 255, 255, 255, 255, 255, 255 ],
785 [ 248, 251, 255, 255, 255, 255, 255, 255, 255, 255, 255 ],
786 [ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 ],
787 [ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 ],
788 [ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 ]
792 [ 225, 239, 227, 231, 244, 253, 243, 255, 255, 253, 255 ],
793 [ 232, 234, 224, 228, 242, 249, 242, 252, 251, 251, 255 ],
794 [ 235, 249, 238, 240, 251, 255, 249, 255, 253, 253, 255 ],
795 [ 249, 253, 251, 250, 255, 255, 255, 255, 255, 255, 255 ],
796 [ 251, 250, 249, 255, 255, 255, 255, 255, 255, 255, 255 ],
797 [ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 ]
799 [ 243, 244, 250, 250, 255, 255, 255, 255, 255, 255, 255 ],
800 [ 249, 248, 250, 253, 255, 255, 255, 255, 255, 255, 255 ],
801 [ 253, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 ],
802 [ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 ],
803 [ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 ],
804 [ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 ]
809 const VP6_DC_WEIGHTS: [[[i16; 2]; 3]; 5] = [
810 [ [ 122, 133 ], [ 133, 51 ], [ 142, -16 ] ],
811 [ [ 0, 1 ], [ 0, 1 ], [ 0, 1 ] ],
812 [ [ 78, 171 ], [ 169, 71 ], [ 221, -30 ] ],
813 [ [ 139, 117 ], [ 214, 44 ], [ 246, -3 ] ],
814 [ [ 168, 79 ], [ 210, 38 ], [ 203, 17 ] ]
817 const VP6_IDX_TO_AC_BAND: [usize; 64] = [
818 0, 0, 1, 1, 1, 2, 2, 2,
819 2, 2, 2, 3, 3, 3, 3, 3,
820 3, 3, 3, 3, 3, 3, 4, 4,
821 4, 4, 4, 4, 4, 4, 4, 4,
822 4, 4, 4, 4, 4, 5, 5, 5,
823 5, 5, 5, 5, 5, 5, 5, 5,
824 5, 5, 5, 5, 5, 5, 5, 5,
825 5, 5, 5, 5, 5, 5, 5, 5
828 const VP6_BICUBIC_COEFFS: [[[i16; 4]; 8]; 17] = [
886 [ -10, 111, 30, -3 ],
890 [ -3, 30, 111, -10 ],
895 [ -11, 112, 31, -4 ],
897 [ -10, 74, 74, -10 ],
899 [ -4, 31, 112, -11 ],
904 [ -12, 112, 32, -4 ],
906 [ -10, 74, 74, -10 ],
908 [ -4, 32, 112, -12 ],
913 [ -13, 112, 33, -4 ],
915 [ -11, 75, 75, -11 ],
917 [ -4, 33, 112, -13 ],
922 [ -14, 113, 34, -5 ],
924 [ -12, 76, 76, -12 ],
926 [ -5, 34, 112, -13 ],
930 [ -10, 124, 15, -1 ],
931 [ -14, 113, 34, -5 ],
933 [ -13, 77, 77, -13 ],
935 [ -5, 34, 113, -14 ],
939 [ -10, 123, 16, -1 ],
940 [ -15, 113, 35, -5 ],
941 [ -16, 98, 56, -10 ],
942 [ -14, 78, 78, -14 ],
943 [ -10, 56, 98, -16 ],
944 [ -5, 35, 113, -15 ],
948 [ -11, 124, 17, -2 ],
949 [ -16, 113, 36, -5 ],
950 [ -17, 98, 57, -10 ],
951 [ -14, 78, 78, -14 ],
952 [ -10, 57, 98, -17 ],
953 [ -5, 36, 113, -16 ],
957 [ -12, 125, 17, -2 ],
958 [ -17, 114, 37, -6 ],
959 [ -18, 99, 58, -11 ],
960 [ -15, 79, 79, -15 ],
961 [ -11, 58, 99, -18 ],
962 [ -6, 37, 114, -17 ],
966 [ -12, 124, 18, -2 ],
967 [ -18, 114, 38, -6 ],
968 [ -19, 99, 59, -11 ],
969 [ -16, 80, 80, -16 ],
970 [ -11, 59, 99, -19 ],
971 [ -6, 38, 114, -18 ],