1 use nihav_core::codecs::*;
2 use nihav_core::io::bitreader::*;
3 use nihav_codec_support::codecs::{MV, ZIGZAG};
4 use super::vpcommon::*;
15 impl VP56Parser for VP5BR {
16 fn parse_header(&mut self, bc: &mut BoolCoder) -> DecoderResult<VP56Header> {
17 let mut hdr = VP56Header::default();
18 hdr.is_intra = !bc.read_bool();
19 hdr.is_golden = hdr.is_intra;
21 hdr.quant = bc.read_bits(6) as u8;
23 hdr.version = bc.read_bits(13) as u8;
24 validate!(hdr.version == 5);
25 hdr.profile = bc.read_bits(2) as u8;
26 hdr.interlaced = bc.read_bool();
27 validate!(!hdr.interlaced);
28 hdr.mb_h = bc.read_bits(8) as u8;
29 hdr.mb_w = bc.read_bits(8) as u8;
30 hdr.disp_h = bc.read_bits(8) as u8;
31 hdr.disp_w = bc.read_bits(8) as u8;
32 validate!((hdr.mb_h > 0) && (hdr.mb_w > 0) && (hdr.disp_w > 0) && (hdr.disp_h > 0));
33 validate!((hdr.disp_w <= hdr.mb_w) && (hdr.disp_h <= hdr.mb_h));
34 hdr.scale = bc.read_bits(2) as u8;
39 fn decode_mv(&self, bc: &mut BoolCoder, model: &VP56MVModel) -> i16 {
40 if bc.read_prob(model.nz_prob) {
41 let sign = bc.read_prob(model.sign_prob);
42 let b0 = bc.read_prob(model.raw_probs[0]) as i16;
43 let b1 = bc.read_prob(model.raw_probs[1]) as i16;
44 let top: i16 = vp_tree!(bc, model.tree_probs[0],
45 vp_tree!(bc, model.tree_probs[1],
46 vp_tree!(bc, model.tree_probs[2], 0, 1),
47 vp_tree!(bc, model.tree_probs[3], 2, 3)
49 vp_tree!(bc, model.tree_probs[4],
50 vp_tree!(bc, model.tree_probs[5], 4, 5),
51 vp_tree!(bc, model.tree_probs[6], 6, 7)
54 let val = (top << 2) | (b1 << 1) | b0;
64 fn reset_models(&self, models: &mut VP56Models) {
65 for mdl in models.mv_models.iter_mut() {
68 mdl.raw_probs[0] = 85;
69 mdl.raw_probs[1] = 128;
70 mdl.tree_probs = [128; 7];
73 fn decode_mv_models(&self, bc: &mut BoolCoder, models: &mut [VP56MVModel; 2]) -> DecoderResult<()> {
74 const HAS_NZ_PROB: [u8; 2] = [ 243, 235 ];
75 const HAS_SIGN_PROB: [u8; 2] = [ 220, 211 ];
76 const HAS_RAW0_PROB: [u8; 2] = [ 251, 246 ];
77 const HAS_RAW1_PROB: [u8; 2] = [ 253, 249 ];
78 const HAS_TREE_PROB: [[u8; 7]; 2] = [
79 [ 237, 232, 241, 245, 247, 251, 253 ],
80 [ 234, 231, 248, 249, 252, 252, 254 ]
83 if bc.read_prob(HAS_NZ_PROB[comp]) {
84 models[comp].nz_prob = bc.read_probability();
86 if bc.read_prob(HAS_SIGN_PROB[comp]) {
87 models[comp].sign_prob = bc.read_probability();
89 if bc.read_prob(HAS_RAW0_PROB[comp]) {
90 models[comp].raw_probs[0] = bc.read_probability();
92 if bc.read_prob(HAS_RAW1_PROB[comp]) {
93 models[comp].raw_probs[1] = bc.read_probability();
98 if bc.read_prob(HAS_TREE_PROB[comp][i]) {
99 models[comp].tree_probs[i] = bc.read_probability();
105 #[allow(clippy::needless_range_loop)]
106 fn decode_coeff_models(&self, bc: &mut BoolCoder, models: &mut VP56Models, is_intra: bool) -> DecoderResult<()> {
107 const COEF_PROBS: [[u8; 11]; 2] = [
108 [ 146, 197, 181, 207, 232, 243, 238, 251, 244, 250, 249 ],
109 [ 179, 219, 214, 240, 250, 254, 244, 254, 254, 254, 254 ]
112 let mut def_prob = [128u8; 11];
113 for (coef_mdl, coef_probs) in models.coeff_models.iter_mut().zip(COEF_PROBS.iter()) {
114 for ((dc_prob, def_prob), &coef_prob) in coef_mdl.dc_value_probs.iter_mut()
115 .zip(def_prob.iter_mut()).zip(coef_probs.iter()) {
116 if bc.read_prob(coef_prob) {
117 *def_prob = bc.read_probability();
118 *dc_prob = *def_prob;
120 *dc_prob = *def_prob;
128 if bc.read_prob(VP5_AC_PROBS[ctype][plane][group][i]) {
129 def_prob[i] = bc.read_probability();
130 models.coeff_models[plane].ac_val_probs[ctype][group][i] = def_prob[i];
132 models.coeff_models[plane].ac_val_probs[ctype][group][i] = def_prob[i];
138 for mdl in models.coeff_models.iter_mut() {
142 mdl.dc_token_probs[i][j][k] = rescale_prob(mdl.dc_value_probs[k], &VP5_DC_WEIGHTS[k][i][j], 254);
150 mdl.ac_type_probs[ctype][group][i][j] = rescale_prob(mdl.ac_val_probs[ctype][group][j], &VP5_AC_WEIGHTS[ctype][group][j][i], 254);
158 fn decode_block(&self, bc: &mut BoolCoder, coeffs: &mut [i16; 64], model: &VP56CoeffModel, _vp6model: &VP6Models, fstate: &mut FrameState) -> DecoderResult<()> {
159 const COEF_GROUPS: [u8; 64] = [
160 0, 0, 1, 1, 2, 1, 1, 2,
161 2, 1, 1, 2, 2, 2, 1, 2,
162 2, 2, 2, 2, 1, 1, 2, 2,
163 3, 3, 4, 3, 4, 4, 4, 3,
164 3, 3, 3, 3, 4, 3, 3, 3,
165 4, 4, 4, 4, 4, 3, 3, 4,
166 4, 4, 3, 4, 4, 4, 4, 4,
167 4, 4, 5, 5, 5, 5, 5, 5
171 let left_ctx = fstate.coeff_cat[fstate.ctx_idx][0] as usize;
172 let top_ctx = fstate.top_ctx as usize;
174 let mut val_probs: &[u8; 11] = &model.dc_value_probs;
175 let mut tok_probs: &[u8] = &model.dc_token_probs[left_ctx][top_ctx];
178 let token = vp_tree!(bc, tok_probs[0],
179 if ctype != 0 { vp_tree!(bc, tok_probs[1], break, 0) } else { 0 },
180 vp_tree!(bc, tok_probs[2],
182 vp_tree!(bc, tok_probs[3],
183 vp_tree!(bc, tok_probs[4], 2,
184 vp_tree!(bc, val_probs[5], 3, 4)),
186 let val = expand_token_bc(bc, val_probs, token, 5);
187 ctype = token.min(2) as usize;
188 if token < TOKEN_LARGE {
189 fstate.coeff_cat[fstate.ctx_idx][idx] = token.min(3);
191 fstate.coeff_cat[fstate.ctx_idx][idx] = 4;
193 coeffs[ZIGZAG[idx]] = val;
195 coeffs[ZIGZAG[idx]] *= fstate.ac_quant;
202 let group = COEF_GROUPS[idx] as usize;
203 val_probs = &model.ac_val_probs[ctype][group];
204 tok_probs = if group > 2 { val_probs
206 let ctx = fstate.coeff_cat[fstate.ctx_idx][idx] as usize;
207 &model.ac_type_probs[ctype][group][ctx]
210 let end = fstate.last_idx[fstate.ctx_idx].min(24);
211 fstate.last_idx[fstate.ctx_idx] = idx;
213 fstate.coeff_cat[fstate.ctx_idx][i] = 5;
215 fstate.top_ctx = fstate.coeff_cat[fstate.ctx_idx][0];
219 fn decode_block_huff(&self, _br: &mut BitReader, _coeffs: &mut [i16; 64], _vp6model: &VP6Models, _model: &VP6HuffModels, _fstate: &mut FrameState) -> DecoderResult<()> {
222 fn mc_block(&self, dst: &mut NASimpleVideoFrame<u8>, mc_buf: NAVideoBufferRef<u8>, src: NAVideoBufferRef<u8>, plane: usize, x: usize, y: usize, mv: MV, loop_str: i16) {
223 let (sx, sy, mx, my) = if (plane != 1) && (plane != 2) {
224 (mv.x >> 1, mv.y >> 1, mv.x & 1, mv.y & 1)
226 (mv.x >> 2, mv.y >> 2, if (mv.x & 3) != 0 { 1 } else { 0 }, if (mv.y & 3) != 0 { 1 } else { 0 })
228 let mode1 = (mx as usize) + (my as usize) * 2;
229 let mode = if (mode1 == 3) && (mv.x ^ mv.y < 0) {
234 vp_copy_block(dst, src, plane, x, y, sx, sy, 0, 1, loop_str,
235 mode, VP3_INTERP_FUNCS, mc_buf);
241 info: NACodecInfoRef,
248 dec: VP56Decoder::new(5, false, true),
249 info: NACodecInfoRef::default(),
255 impl NADecoder for VP5Decoder {
256 fn init(&mut self, supp: &mut NADecoderSupport, info: NACodecInfoRef) -> DecoderResult<()> {
257 if let NACodecTypeInfo::Video(vinfo) = info.get_properties() {
258 let myvinfo = NAVideoInfo::new(vinfo.get_width(), vinfo.get_height(), false, YUV420_FORMAT);
259 let myinfo = NACodecTypeInfo::Video(myvinfo);
260 self.info = NACodecInfo::new_ref(info.get_name(), myinfo, info.get_extradata()).into_ref();
261 self.dec.init(supp, myvinfo)?;
264 Err(DecoderError::InvalidData)
267 fn decode(&mut self, supp: &mut NADecoderSupport, pkt: &NAPacket) -> DecoderResult<NAFrameRef> {
268 let src = pkt.get_buffer();
270 let (bufinfo, ftype) = self.dec.decode_frame(supp, src.as_slice(), &mut self.br)?;
272 let mut frm = NAFrame::new_from_pkt(pkt, self.info.clone(), bufinfo);
273 frm.set_keyframe(ftype == FrameType::I);
274 frm.set_frame_type(ftype);
277 fn flush(&mut self) {
282 impl NAOptionHandler for VP5Decoder {
283 fn get_supported_options(&self) -> &[NAOptionDefinition] { &[] }
284 fn set_options(&mut self, _options: &[NAOption]) { }
285 fn query_option_value(&self, _name: &str) -> Option<NAValue> { None }
288 pub fn get_decoder() -> Box<dyn NADecoder + Send> {
289 Box::new(VP5Decoder::new())
294 use nihav_core::codecs::RegisteredDecoders;
295 use nihav_core::demuxers::RegisteredDemuxers;
296 use nihav_codec_support::test::dec_video::*;
297 use crate::duck_register_all_decoders;
298 use nihav_commonfmt::generic_register_all_demuxers;
302 let mut dmx_reg = RegisteredDemuxers::new();
303 generic_register_all_demuxers(&mut dmx_reg);
304 let mut dec_reg = RegisteredDecoders::new();
305 duck_register_all_decoders(&mut dec_reg);
307 let file = "assets/Duck/Cell-140.vp5";
308 //let file = "assets/Duck/Chocolat-500.vp5";
309 // sample: https://samples.mplayerhq.hu/V-codecs/VP5/Cell-140.vp5
310 test_decoding("avi", "vp5", file, Some(96), &dmx_reg, &dec_reg,
311 ExpectedTestResult::MD5([0x9ad78b0f, 0xed988ead, 0x88ed2ea9, 0xcdb75cdf]));
315 const VP5_AC_PROBS: [[[[u8; 11]; 6]; 2]; 3] = [
318 [ 227, 246, 230, 247, 244, 254, 254, 254, 254, 254, 254 ],
319 [ 202, 254, 209, 231, 231, 249, 249, 253, 254, 254, 254 ],
320 [ 206, 254, 225, 242, 241, 251, 253, 254, 254, 254, 254 ],
321 [ 235, 254, 241, 253, 252, 254, 254, 254, 254, 254, 254 ],
322 [ 234, 254, 248, 254, 254, 254, 254, 254, 254, 254, 254 ],
323 [ 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254 ]
325 [ 240, 254, 248, 254, 254, 254, 254, 254, 254, 254, 254 ],
326 [ 238, 254, 240, 253, 254, 254, 254, 254, 254, 254, 254 ],
327 [ 244, 254, 251, 254, 254, 254, 254, 254, 254, 254, 254 ],
328 [ 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254 ],
329 [ 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254 ],
330 [ 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254 ]
334 [ 206, 203, 227, 239, 247, 254, 253, 254, 254, 254, 254 ],
335 [ 207, 199, 220, 236, 243, 252, 252, 254, 254, 254, 254 ],
336 [ 212, 219, 230, 243, 244, 253, 252, 254, 254, 254, 254 ],
337 [ 236, 237, 247, 252, 253, 254, 254, 254, 254, 254, 254 ],
338 [ 240, 240, 248, 254, 254, 254, 254, 254, 254, 254, 254 ],
339 [ 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254 ]
341 [ 230, 233, 249, 254, 254, 254, 254, 254, 254, 254, 254 ],
342 [ 238, 238, 250, 254, 254, 254, 254, 254, 254, 254, 254 ],
343 [ 248, 251, 254, 254, 254, 254, 254, 254, 254, 254, 254 ],
344 [ 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254 ],
345 [ 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254 ],
346 [ 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254 ]
350 [ 225, 239, 227, 231, 244, 253, 243, 254, 254, 253, 254 ],
351 [ 232, 234, 224, 228, 242, 249, 242, 252, 251, 251, 254 ],
352 [ 235, 249, 238, 240, 251, 254, 249, 254, 253, 253, 254 ],
353 [ 249, 253, 251, 250, 254, 254, 254, 254, 254, 254, 254 ],
354 [ 251, 250, 249, 254, 254, 254, 254, 254, 254, 254, 254 ],
355 [ 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254 ]
357 [ 243, 244, 250, 250, 254, 254, 254, 254, 254, 254, 254 ],
358 [ 249, 248, 250, 253, 254, 254, 254, 254, 254, 254, 254 ],
359 [ 253, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254 ],
360 [ 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254 ],
361 [ 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254 ],
362 [ 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254 ]
367 const VP5_DC_WEIGHTS: [[[[i16; 2]; 6]; 6]; 5] = [
369 [ [154, 61], [141, 54], [ 90, 45], [ 54, 34], [ 54, 13], [128, 109] ],
370 [ [136, 54], [148, 45], [ 92, 41], [ 54, 33], [ 51, 15], [ 87, 113] ],
371 [ [ 87, 44], [ 97, 40], [ 67, 36], [ 46, 29], [ 41, 15], [ 64, 80] ],
372 [ [ 59, 33], [ 61, 31], [ 51, 28], [ 44, 22], [ 33, 12], [ 49, 63] ],
373 [ [ 69, 12], [ 59, 16], [ 46, 14], [ 31, 13], [ 26, 6], [ 92, 26] ],
374 [ [128, 108], [ 77, 119], [ 54, 84], [ 26, 71], [ 87, 19], [ 95, 155] ]
376 [ [154, 4], [182, 0], [159, -8], [128, -5], [143, -5], [187, 55] ],
377 [ [182, 0], [228, -3], [187, -7], [174, -9], [189, -11], [169, 79] ],
378 [ [161, -9], [192, -8], [187, -9], [169, -10], [136, -9], [184, 40] ],
379 [ [164, -11], [179, -10], [174, -10], [161, -10], [115, -7], [197, 20] ],
380 [ [195, -11], [195, -11], [146, -10], [110, -6], [ 95, -4], [195, 39] ],
381 [ [182, 55], [172, 77], [177, 37], [169, 29], [172, 52], [ 92, 162] ]
383 [ [174, 80], [164, 80], [ 95, 80], [ 46, 66], [ 56, 24], [ 36, 193] ],
384 [ [164, 80], [166, 77], [105, 76], [ 49, 68], [ 46, 31], [ 49, 186] ],
385 [ [ 97, 78], [110, 74], [ 72, 72], [ 44, 60], [ 33, 30], [ 69, 131] ],
386 [ [ 61, 61], [ 69, 63], [ 51, 57], [ 31, 48], [ 26, 27], [ 64, 89] ],
387 [ [ 67, 23], [ 51, 32], [ 36, 33], [ 26, 28], [ 20, 12], [ 44, 68] ],
388 [ [ 26, 197], [ 41, 189], [ 61, 129], [ 28, 103], [ 49, 52], [-12, 245] ]
390 [ [102, 141], [ 79, 166], [ 72, 162], [ 97, 125], [179, 4], [307, 0] ],
391 [ [ 72, 168], [ 69, 175], [ 84, 160], [105, 127], [148, 34], [310, 0] ],
392 [ [ 84, 151], [ 82, 161], [ 87, 153], [ 87, 135], [115, 51], [317, 0] ],
393 [ [ 97, 125], [102, 131], [105, 125], [ 87, 122], [ 84, 64], [ 54, 184] ],
394 [ [166, 18], [146, 43], [125, 51], [ 90, 64], [ 95, 7], [ 38, 154] ],
395 [ [294, 0], [ 13, 225], [ 10, 225], [ 67, 168], [ 0, 167], [161, 94] ]
397 [ [172, 76], [172, 75], [136, 80], [ 64, 98], [ 74, 67], [315, 0] ],
398 [ [169, 76], [207, 56], [164, 66], [ 97, 80], [ 67, 72], [328, 0] ],
399 [ [136, 80], [187, 53], [154, 62], [ 72, 85], [ -2, 105], [305, 0] ],
400 [ [ 74, 91], [128, 64], [113, 64], [ 61, 77], [ 41, 75], [259, 0] ],
401 [ [ 46, 84], [ 51, 81], [ 28, 89], [ 31, 78], [ 23, 77], [202, 0] ],
402 [ [323, 0], [323, 0], [300, 0], [236, 0], [195, 0], [328, 0] ]
406 const VP5_AC_WEIGHTS: [[[[[i16; 2]; 6]; 5]; 3]; 3] = [
409 [ [276, 0], [238, 0], [195, 0], [156, 0], [113, 0], [274, 0] ],
410 [ [ 0, 1], [ 0, 1], [ 0, 1], [ 0, 1], [ 0, 1], [ 0, 1] ],
411 [ [192, 59], [182, 50], [141, 48], [110, 40], [ 92, 19], [125,128] ],
412 [ [169, 87], [169, 83], [184, 62], [220, 16], [184, 0], [264, 0] ],
413 [ [212, 40], [212, 36], [169, 49], [174, 27], [ 8,120], [182, 71] ]
415 [ [259, 10], [197, 19], [143, 22], [123, 16], [110, 8], [133, 88] ],
416 [ [ 0, 1], [256, 0], [ 0, 1], [ 0, 1], [ 0, 1], [ 0, 1] ],
417 [ [207, 46], [187, 50], [ 97, 83], [ 23,100], [ 41, 56], [ 56,188] ],
418 [ [166, 90], [146,108], [161, 88], [136, 95], [174, 0], [266, 0] ],
419 [ [264, 7], [243, 18], [184, 43], [-14,154], [ 20,112], [ 20,199] ]
421 [ [230, 26], [197, 22], [159, 20], [146, 12], [136, 4], [ 54,162] ],
422 [ [ 0, 1], [ 0, 1], [ 0, 1], [ 0, 1], [ 0, 1], [ 0, 1] ],
423 [ [192, 59], [156, 72], [ 84,101], [ 49,101], [ 79, 47], [ 79,167] ],
424 [ [138,115], [136,116], [166, 80], [238, 0], [195, 0], [261, 0] ],
425 [ [225, 33], [205, 42], [159, 61], [ 79, 96], [ 92, 66], [ 28,195] ]
429 [ [200, 37], [197, 18], [159, 13], [143, 7], [102, 5], [123,126] ],
430 [ [197, 3], [220, -9], [210,-12], [187, -6], [151, -2], [174, 80] ],
431 [ [200, 53], [187, 47], [159, 40], [118, 38], [100, 18], [141,111] ],
432 [ [179, 78], [166, 86], [197, 50], [207, 27], [187, 0], [115,139] ],
433 [ [218, 34], [220, 29], [174, 46], [128, 61], [ 54, 89], [187, 65] ]
435 [ [238, 14], [197, 18], [125, 26], [ 90, 25], [ 82, 13], [161, 86] ],
436 [ [189, 1], [205, -2], [156, -4], [143, -4], [146, -4], [172, 72] ],
437 [ [230, 31], [192, 45], [102, 76], [ 38, 85], [ 56, 41], [ 64,173] ],
438 [ [166, 91], [141,111], [128,116], [118,109], [177, 0], [ 23,222] ],
439 [ [253, 14], [236, 21], [174, 49], [ 33,118], [ 44, 93], [ 23,187] ]
441 [ [218, 28], [179, 28], [118, 35], [ 95, 30], [ 72, 24], [128,108] ],
442 [ [187, 1], [174, -1], [125, -1], [110, -1], [108, -1], [202, 52] ],
443 [ [197, 53], [146, 75], [ 46,118], [ 33,103], [ 64, 50], [118,126] ],
444 [ [138,114], [128,122], [161, 86], [243, -6], [195, 0], [ 38,210] ],
445 [ [215, 39], [179, 58], [ 97,101], [ 95, 85], [ 87, 70], [ 69,152] ]
449 [ [236, 24], [205, 18], [172, 12], [154, 6], [125, 1], [169, 75] ],
450 [ [187, 4], [230, -2], [228, -4], [236, -4], [241, -2], [192, 66] ],
451 [ [200, 46], [187, 42], [159, 34], [136, 25], [105, 10], [179, 62] ],
452 [ [207, 55], [192, 63], [192, 54], [195, 36], [177, 1], [143, 98] ],
453 [ [225, 27], [207, 34], [200, 30], [131, 57], [ 97, 60], [197, 45] ]
455 [ [271, 8], [218, 13], [133, 19], [ 90, 19], [ 72, 7], [182, 51] ],
456 [ [179, 1], [225, -1], [154, -2], [110, -1], [ 92, 0], [195, 41] ],
457 [ [241, 26], [189, 40], [ 82, 64], [ 33, 60], [ 67, 17], [120, 94] ],
458 [ [192, 68], [151, 94], [146, 90], [143, 72], [161, 0], [113,128] ],
459 [ [256, 12], [218, 29], [166, 48], [ 44, 99], [ 31, 87], [148, 78] ]
461 [ [238, 20], [184, 22], [113, 27], [ 90, 22], [ 74, 9], [192, 37] ],
462 [ [184, 0], [215, -1], [141, -1], [ 97, 0], [ 49, 0], [264, 13] ],
463 [ [182, 51], [138, 61], [ 95, 63], [ 54, 59], [ 64, 25], [200, 45] ],
464 [ [179, 75], [156, 87], [174, 65], [177, 44], [174, 0], [164, 85] ],
465 [ [195, 45], [148, 65], [105, 79], [ 95, 72], [ 87, 60], [169, 63] ]