X-Git-Url: https://git.nihav.org/?a=blobdiff_plain;f=nihav-duck%2Fsrc%2Fcodecs%2Fvp3.rs;h=08bfd1a97f58de69693c930025f6d7ac0ca307e6;hb=HEAD;hp=7b3411ccffb162c3cd9c806f332b11cd91cfdbe2;hpb=fd8666bc8f48fd374571368cd4b9a0a42e3ea85b;p=nihav.git diff --git a/nihav-duck/src/codecs/vp3.rs b/nihav-duck/src/codecs/vp3.rs index 7b3411c..ba5db75 100644 --- a/nihav-duck/src/codecs/vp3.rs +++ b/nihav-duck/src/codecs/vp3.rs @@ -26,16 +26,12 @@ struct VP30Codes { mbtype_cb: Codebook, } -fn map_mbt(idx: usize) -> VPMBType { - VP30_MBTYPE_SYMS[idx] -} - impl VP30Codes { fn new() -> Self { let dc_cb; let ac_i_cb; let ac_p_cb; - let mut cr = TableCodebookDescReader::new(&VP30_MBTYPE_CODES, &VP30_MBTYPE_BITS, map_mbt); + let mut cr = TableCodebookDescReader::new(&VP30_MBTYPE_CODES, &VP30_MBTYPE_BITS, |idx| VP30_MBTYPE_SYMS[idx]); let mbtype_cb = Codebook::new(&mut cr, CodebookMode::MSB).unwrap(); unsafe { let mut udc_cb: mem::MaybeUninit::<[Codebook; 5]> = mem::MaybeUninit::uninit(); @@ -307,16 +303,16 @@ fn vp30_read_coded_run1(br: &mut BitReader) -> DecoderResult { let sym = (VP30_CRUN1_LUT[idx] >> 4) as usize; let bits = VP30_CRUN1_LUT[idx] & 0xF; br.skip(u32::from(bits))?; - if sym < 7 { - Ok(sym) - } else if sym == 7 { - Ok(7 + (br.read(3)? as usize)) - } else { - let len = br.read_code(UintCodeType::Unary012)?; - match len { - 0 => Ok(15 + (br.read(5)? as usize)), - 1 => Ok(47 + (br.read(8)? as usize)), - _ => Ok(303 + (br.read(16)? as usize)), + match sym { + 0..=6 => Ok(sym), + 7 => Ok(7 + (br.read(3)? as usize)), + _ => { + let len = br.read_code(UintCodeType::Unary012)?; + match len { + 0 => Ok(15 + (br.read(5)? as usize)), + 1 => Ok(47 + (br.read(8)? as usize)), + _ => Ok(303 + (br.read(16)? as usize)), + } } } } @@ -723,17 +719,17 @@ impl VP34Decoder { let nblks = *nblk as usize; if *coded { let mut cb = [false; 4]; - for j in 0..nblks { + for cb in cb[..nblks].iter_mut() { if run == 0 { bit = !bit; run = if bit { vp30_read_coded_run1(br)? } else { vp30_read_coded_run0(br)? }; } run -= 1; - cb[j] = bit; + *cb = bit; } - for j in 0..nblks { - let addr = self.blk_addr[cur_blk + j] >> 2; - self.blocks[addr].coded = cb[j]; + for (&cb, &blk_addr) in cb.iter() + .zip(self.blk_addr[cur_blk..].iter()).take(nblks) { + self.blocks[blk_addr >> 2].coded = cb; } } cur_blk += nblks; @@ -975,6 +971,7 @@ impl VP34Decoder { } Ok(()) } + #[allow(clippy::identity_op)] fn vp31_unpack_mv_info(&mut self, br: &mut BitReader) -> DecoderResult<()> { let mut last_mv = ZERO_MV; let mut last2_mv = ZERO_MV; @@ -1119,8 +1116,8 @@ impl VP34Decoder { } } } - for i in 0..nblks { - self.blocks[addrs[i]].coded = (pat & 8) != 0; + for &addr in addrs[..nblks].iter() { + self.blocks[addr].coded = (pat & 8) != 0; pat <<= 1; cur_blk += 1; } @@ -1141,8 +1138,8 @@ impl VP34Decoder { if let Some(ref codes) = self.aux_codes { for _ in 0..self.y_blocks/4 { if self.blocks[self.blk_addr[cur_blk] >> 2].btype == VPMBType::InterFourMV { - let x_cb = &codes.mv_x_cb[VP40_MV_LUT_INDEX[last_mv.x.abs() as usize]]; - let y_cb = &codes.mv_y_cb[VP40_MV_LUT_INDEX[last_mv.y.abs() as usize]]; + let x_cb = &codes.mv_x_cb[VP40_MV_LUT_INDEX[last_mv.x.unsigned_abs() as usize]]; + let y_cb = &codes.mv_y_cb[VP40_MV_LUT_INDEX[last_mv.y.unsigned_abs() as usize]]; let x_sign = last_mv.x < 0; let y_sign = last_mv.y < 0; last2_mv = last_mv; @@ -1167,8 +1164,8 @@ impl VP34Decoder { cur_mv = ZERO_MV; }, VPMBType::InterMV => { - let x_cb = &codes.mv_x_cb[VP40_MV_LUT_INDEX[last_mv.x.abs() as usize]]; - let y_cb = &codes.mv_y_cb[VP40_MV_LUT_INDEX[last_mv.y.abs() as usize]]; + let x_cb = &codes.mv_x_cb[VP40_MV_LUT_INDEX[last_mv.x.unsigned_abs() as usize]]; + let y_cb = &codes.mv_y_cb[VP40_MV_LUT_INDEX[last_mv.y.unsigned_abs() as usize]]; let x_sign = last_mv.x < 0; let y_sign = last_mv.y < 0; let x = i16::from(br.read_cb(x_cb)?); @@ -1185,8 +1182,8 @@ impl VP34Decoder { std::mem::swap(&mut last_mv, &mut last2_mv); }, _ => { // GoldenMV - let x_cb = &codes.mv_x_cb[VP40_MV_LUT_INDEX[last_mv_g.x.abs() as usize]]; - let y_cb = &codes.mv_y_cb[VP40_MV_LUT_INDEX[last_mv_g.y.abs() as usize]]; + let x_cb = &codes.mv_x_cb[VP40_MV_LUT_INDEX[last_mv_g.x.unsigned_abs() as usize]]; + let y_cb = &codes.mv_y_cb[VP40_MV_LUT_INDEX[last_mv_g.y.unsigned_abs() as usize]]; let x_sign = last_mv_g.x < 0; let y_sign = last_mv_g.y < 0; let x = i16::from(br.read_cb(x_cb)?); @@ -1464,9 +1461,9 @@ impl VP34Decoder { } if pp == 0 { return self.last_dc[ref_id as usize]; } let mut pred = 0i32; - for i in 0..4 { + for (i, (&pred_val, &dc_weight)) in preds.iter().zip(VP31_DC_WEIGHTS[pp].iter()).enumerate() { if (pp & (1 << i)) != 0 { - pred += (preds[i] as i32) * i32::from(VP31_DC_WEIGHTS[pp][i]); + pred += pred_val * i32::from(dc_weight); } } pred /= i32::from(VP31_DC_WEIGHTS[pp][4]); @@ -1477,6 +1474,7 @@ impl VP34Decoder { } pred as i16 } + #[allow(clippy::identity_op)] fn vp40_predict_dc(&self, bx: usize, by: usize, bw: usize, bh: usize, blk_idx: usize, mask: usize, is_luma: bool) -> i16 { let mut preds = [0i32; 4]; let mut pp: usize = 0; @@ -1499,9 +1497,9 @@ impl VP34Decoder { if pp == 0 { return self.last_dc[ref_id as usize]; } let mut pred = 0i32; let mut npred = 0; - for i in 0..4 { + for (i, &pred_val) in preds.iter().enumerate() { if (pp & (1 << i)) != 0 { - pred += preds[i] as i32; + pred += pred_val; npred += 1; if npred == 2 { return (pred / 2) as i16; @@ -1541,7 +1539,7 @@ impl VP34Decoder { let mut biter = self.blocks.iter_mut(); for by in 0..self.mb_h*2 { for bx in 0..self.mb_w*2 { - let mut blk = biter.next().unwrap(); + let blk = biter.next().unwrap(); let qmat = &self.qmat_y; blk.coeffs[0] *= qmat[0]; if blk.has_ac { @@ -1555,7 +1553,7 @@ impl VP34Decoder { for plane in 1..3 { for by in 0..self.mb_h { for bx in 0..self.mb_w { - let mut blk = biter.next().unwrap(); + let blk = biter.next().unwrap(); let qmat = &self.qmat_c; blk.coeffs[0] *= qmat[0]; if blk.has_ac { @@ -1569,6 +1567,7 @@ impl VP34Decoder { } } #[allow(clippy::cognitive_complexity)] + #[allow(clippy::collapsible_else_if)] fn output_blocks_inter(&mut self, frm: &mut NASimpleVideoFrame) { let mut blk_idx = 0; let bstride = self.mb_w * 2; @@ -1586,17 +1585,17 @@ impl VP34Decoder { mv_sum.y = (mv_sum.y + 2) >> 2; let src = self.shuf.get_last().unwrap(); - for i in 0..4 { + for (i, mv) in mvs.iter().enumerate() { let xoff = (i & 1) * 8; let yoff = (i >> 1) * 8; - let mode = vp3_mv_mode(mvs[i].x, mvs[i].y); + let mode = vp3_mv_mode(mv.x, mv.y); if self.version != 4 { copy_block(frm, src.clone(), 0, bx * 8 + xoff, by * 8 + yoff, - mvs[i].x >> 1, mvs[i].y >> 1, 8, 8, 0, 1, mode, VP3_INTERP_FUNCS); + mv.x >> 1, mv.y >> 1, 8, 8, 0, 1, mode, VP3_INTERP_FUNCS); } else { vp_copy_block(frm, src.clone(), 0, bx * 8 + xoff, by * 8 + yoff, - mvs[i].x >> 1, mvs[i].y >> 1, 0, 1, self.loop_str, + mv.x >> 1, mv.y >> 1, 0, 1, self.loop_str, mode, VP3_INTERP_FUNCS, self.mc_buf.clone()); } } @@ -1613,7 +1612,7 @@ impl VP34Decoder { let mut biter = self.blocks.iter_mut(); for by in 0..self.mb_h*2 { for bx in 0..self.mb_w*2 { - let mut blk = biter.next().unwrap(); + let blk = biter.next().unwrap(); // do MC for whole macroblock if !blk.btype.is_intra() && (((bx | by) & 1) == 0) && (blk.btype != VPMBType::InterFourMV) { let src = if blk.btype.get_ref_id() == 1 { @@ -1681,7 +1680,7 @@ impl VP34Decoder { for plane in 1..3 { for by in 0..self.mb_h { for bx in 0..self.mb_w { - let mut blk = biter.next().unwrap(); + let blk = biter.next().unwrap(); let qmat = if blk.btype.is_intra() { &self.qmat_c } else { &self.qmat_c_p }; blk.coeffs[0] *= qmat[0]; if blk.has_ac { @@ -1795,9 +1794,9 @@ impl VP34Decoder { self.sb_mbs.push(nmbs); let mut nblocks = 0; - for blk_no in 0..16 { - let bx = x * 4 + HILBERT_ORDER[blk_no][0]; - let by = y * 4 + HILBERT_ORDER[blk_no][1]; + for (blk_no, order) in HILBERT_ORDER.iter().enumerate() { + let bx = x * 4 + order[0]; + let by = y * 4 + order[1]; if (bx >= blk_w) || (by >= blk_h) { continue; } let idx = base_idx + bx + by * blk_w; self.blk_addr.push(idx * 4 + plane); @@ -1839,6 +1838,7 @@ impl NADecoder for VP34Decoder { Err(DecoderError::InvalidData) } } + #[allow(clippy::collapsible_else_if)] fn decode(&mut self, supp: &mut NADecoderSupport, pkt: &NAPacket) -> DecoderResult { let src = pkt.get_buffer(); validate!(src.len() > 0); @@ -1910,6 +1910,7 @@ mod test { let mut dec_reg = RegisteredDecoders::new(); duck_register_all_decoders(&mut dec_reg); + // sample: https://samples.mplayerhq.hu/V-codecs/VP3/vp30-logo.avi test_decoding("avi", "vp3", "assets/Duck/vp30-logo.avi", Some(23), &dmx_reg, &dec_reg, ExpectedTestResult::MD5([0x51aba7df, 0x6e42534d, 0xef6c5b13, 0x26c38d1f])); } @@ -1926,6 +1927,7 @@ mod test { // let file = "assets/Duck/01-vp31-0500.avi"; // test_file_decoding("avi", file, Some(3), true, false, None/*Some("vp31")*/, &dmx_reg, &dec_reg); //panic!("end"); + // sample: https://samples.mplayerhq.hu/V-codecs/VP3/01-vp31-0500.avi test_decoding("avi", "vp3", "assets/Duck/01-vp31-0500.avi", Some(16), &dmx_reg, &dec_reg, ExpectedTestResult::MD5([0x65112f7e, 0x2914f29b, 0x2908ed2f, 0xce5fc8c5])); } @@ -1937,6 +1939,7 @@ mod test { let mut dec_reg = RegisteredDecoders::new(); duck_register_all_decoders(&mut dec_reg); + // sample: https://samples.mplayerhq.hu/V-codecs/VP4/ot171_vp40.avi test_decoding("avi", "vp3", "assets/Duck/ot171_vp40.avi", Some(86), &dmx_reg, &dec_reg, ExpectedTestResult::MD5([0xd41d8cd9, 0x8f00b204, 0xe9800998, 0xecf8427e])); }