use super::vp78dsp::*;
use super::vp8dsp::*;
-#[derive(Clone,Copy,PartialEq,Debug)]
+#[derive(Clone,Copy,PartialEq,Debug,Default)]
enum VP8Ref {
+ #[default]
Intra,
Last,
Golden,
AltRef,
}
-impl Default for VP8Ref {
- fn default() -> Self { VP8Ref::Intra }
-}
-
#[derive(Default)]
pub struct VP8Shuffler {
lastframe: Option<NAVideoBufferRef<u8>>,
self.altframe = Some(buf);
}
pub fn get_last(&mut self) -> Option<NAVideoBufferRef<u8>> {
- if let Some(ref frm) = self.lastframe {
- Some(frm.clone())
- } else {
- None
- }
+ self.lastframe.as_ref().cloned()
}
pub fn get_golden(&mut self) -> Option<NAVideoBufferRef<u8>> {
- if let Some(ref frm) = self.goldframe {
- Some(frm.clone())
- } else {
- None
- }
+ self.goldframe.as_ref().cloned()
}
pub fn get_altref(&mut self) -> Option<NAVideoBufferRef<u8>> {
- if let Some(ref frm) = self.altframe {
- Some(frm.clone())
- } else {
- None
- }
+ self.altframe.as_ref().cloned()
}
pub fn has_refs(&self) -> bool {
self.lastframe.is_some()
}
Ok(())
}
+ #[allow(clippy::collapsible_if)]
fn mb_lf_adjustments(&mut self, bc: &mut BoolCoder) -> DecoderResult<()> {
self.dstate.lf_delta = bc.read_bool();
if self.dstate.lf_delta {
Ok(())
}
fn read_dct_coef_prob_upd(&mut self, bc: &mut BoolCoder) -> DecoderResult<()> {
- for i in 0..4 {
- for j in 0..8 {
- for k in 0..3 {
- for l in 0..11 {
- if bc.read_prob(DCT_UPDATE_PROBS[i][j][k][l]) {
- self.dstate.coef_probs[i][j][k][l] = bc.read_byte();
+ for (probs, upd_probs) in self.dstate.coef_probs.iter_mut().zip(DCT_UPDATE_PROBS.iter()) {
+ for (probs, upd_probs) in probs.iter_mut().zip(upd_probs.iter()) {
+ for (probs, upd_probs) in probs.iter_mut().zip(upd_probs.iter()) {
+ for (prob, &upd_prob) in probs.iter_mut().zip(upd_probs.iter()) {
+ if bc.read_prob(upd_prob) {
+ *prob = bc.read_byte();
}
}
}
[ 237, 246, 253, 253, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 250, 250, 252, 254, 254 ],
[ 231, 243, 245, 253, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 251, 251, 254, 254, 254 ]
];
- for comp in 0..2 {
- for i in 0..19 {
- if bc.read_prob(MV_UPDATE_PROBS[comp][i]) {
- self.dstate.mv_probs[comp][i] = bc.read_probability();
+ for (prob_row, upd_row) in self.dstate.mv_probs.iter_mut()
+ .zip(MV_UPDATE_PROBS.iter()) {
+ for (prob, &upd_prob) in prob_row.iter_mut().zip(upd_row.iter()) {
+ if bc.read_prob(upd_prob) {
+ *prob = bc.read_probability();
}
}
}
ytype = 3;
}
sbparams.qmat = &self.qmat[qmat_idx][0];
- for i in 0..16 {
+ let (y_coeffs, c_coeffs) = self.coeffs.split_at_mut(16);
+ for (i, (coeffs, y_has_ac)) in y_coeffs.iter_mut().zip(has_ac.iter_mut()).enumerate() {
let bx = i & 3;
let by = i >> 2;
let pred = &self.pcache.y_pred;
let pidx = pred.xpos + mb_x * 4 + bx + by * pred.stride;
let pctx = self.pcache.y_pred_left[by] + pred.data[pidx - pred.stride];
- let has_nz = decode_subblock(bc, &mut self.coeffs[i], ytype, pctx, &sbparams);
+ let has_nz = decode_subblock(bc, coeffs, ytype, pctx, &sbparams);
self.pcache.y_pred.data[pidx] = has_nz;
self.pcache.y_pred_left[by] = has_nz;
- has_ac[i] = has_nz > 0;
- coded |= has_ac[i] | (self.coeffs[i][0] != 0);
+ *y_has_ac = has_nz > 0;
+ coded |= *y_has_ac | (coeffs[0] != 0);
}
sbparams.qmat = &self.qmat[qmat_idx][1];
- for i in 16..20 {
+ let (u_coeffs, v_coeffs) = c_coeffs.split_at_mut(4);
+ let (u_has_ac, v_has_ac) = has_ac[16..24].split_at_mut(4);
+ for (i, (coeffs, u_has_ac)) in u_coeffs.iter_mut().zip(u_has_ac.iter_mut()).enumerate() {
let bx = i & 1;
let by = (i >> 1) & 1;
let pred = &self.pcache.u_pred;
let pidx = pred.xpos + mb_x * 2 + bx + by * pred.stride;
let pctx = self.pcache.u_pred_left[by] + pred.data[pidx - pred.stride];
- let has_nz = decode_subblock(bc, &mut self.coeffs[i], 2, pctx, &sbparams);
+ let has_nz = decode_subblock(bc, coeffs, 2, pctx, &sbparams);
self.pcache.u_pred.data[pidx] = has_nz;
self.pcache.u_pred_left[by] = has_nz;
- has_ac[i] = has_nz > 0;
- coded |= has_ac[i] | (self.coeffs[i][0] != 0);
+ *u_has_ac = has_nz > 0;
+ coded |= *u_has_ac | (coeffs[0] != 0);
}
- for i in 20..24 {
+ for (i, (coeffs, v_has_ac)) in v_coeffs.iter_mut().zip(v_has_ac.iter_mut()).enumerate() {
let bx = i & 1;
let by = (i >> 1) & 1;
let pred = &self.pcache.v_pred;
let pidx = pred.xpos + mb_x * 2 + bx + by * pred.stride;
let pctx = self.pcache.v_pred_left[by] + pred.data[pidx - pred.stride];
- let has_nz = decode_subblock(bc, &mut self.coeffs[i], 2, pctx, &sbparams);
+ let has_nz = decode_subblock(bc, coeffs, 2, pctx, &sbparams);
self.pcache.v_pred.data[pidx] = has_nz;
self.pcache.v_pred_left[by] = has_nz;
- has_ac[i] = has_nz > 0;
- coded |= has_ac[i] | (self.coeffs[i][0] != 0);
+ *v_has_ac = has_nz > 0;
+ coded |= *v_has_ac | (coeffs[0] != 0);
}
if self.dstate.has_y2 {
self.coeffs[i][0] = self.coeffs[24][i];
}
}
- for i in 0..24 {
- if has_ac[i] {
- idct4x4(&mut self.coeffs[i]);
- } else if self.coeffs[i][0] != 0 {
- idct4x4_dc(&mut self.coeffs[i]);
+ for (&has_ac, coeffs) in has_ac.iter().zip(self.coeffs.iter_mut()).take(24) {
+ if has_ac {
+ idct4x4(coeffs);
+ } else if coeffs[0] != 0 {
+ idct4x4_dc(coeffs);
}
}
},
}
}
+ #[allow(clippy::identity_op)]
fn do_split_mv(&mut self, bc: &mut BoolCoder, mb_x: usize, mb_y: usize, pred_mv: MV) -> DecoderResult<()> {
let split_mode = bc.read_tree(MV_SPLIT_MODE_TREE, &MV_SPLIT_MODE_PROBS);
let mut mvidx = mb_x * 4 + mb_y * 4 * self.mv_stride;
}.unwrap();
let single_mv = self.mb_info[mb_x + mb_y * self.mb_w].mb_type != VPMBType::InterFourMV;
let mut iidx = mb_x * 4 + mb_y * 4 * self.mv_stride;
- let mut mc_buf = self.mc_buf.get_data_mut().unwrap();
+ let mc_buf = self.mc_buf.get_data_mut().unwrap();
let dst = &mut dframe.data[0..];
let ystride = dframe.stride[0];
if single_mv {
if self.dstate.version == 0 {
mc_block16x16(dst, yoff, ystride, mb_x * 16, mb_y * 16,
- self.mvs[iidx].x * 2, self.mvs[iidx].y * 2, refframe.clone(), 0, &mut mc_buf);
+ self.mvs[iidx].x * 2, self.mvs[iidx].y * 2, refframe.clone(), 0, mc_buf);
} else {
mc_block16x16_bilin(dst, yoff, ystride, mb_x * 16, mb_y * 16,
- self.mvs[iidx].x * 2, self.mvs[iidx].y * 2, refframe.clone(), 0, &mut mc_buf);
+ self.mvs[iidx].x * 2, self.mvs[iidx].y * 2, refframe.clone(), 0, mc_buf);
}
} else {
for y in 0..4 {
for x in 0..4 {
if self.dstate.version == 0 {
mc_block4x4(dst, yoff + x * 4, ystride, mb_x * 16 + x * 4, mb_y * 16 + y * 4,
- self.mvs[iidx + x].x * 2, self.mvs[iidx + x].y * 2, refframe.clone(), 0, &mut mc_buf);
+ self.mvs[iidx + x].x * 2, self.mvs[iidx + x].y * 2, refframe.clone(), 0, mc_buf);
} else {
mc_block4x4_bilin(dst, yoff + x * 4, ystride, mb_x * 16 + x * 4, mb_y * 16 + y * 4,
- self.mvs[iidx + x].x * 2, self.mvs[iidx + x].y * 2, refframe.clone(), 0, &mut mc_buf);
+ self.mvs[iidx + x].x * 2, self.mvs[iidx + x].y * 2, refframe.clone(), 0, mc_buf);
}
}
yoff += 4 * ystride;
let mut chroma_mv = self.mvs[iidx];
if self.dstate.version == 0 {
- mc_block8x8(dst, uoff, ustride, mb_x * 8, mb_y * 8, chroma_mv.x, chroma_mv.y, refframe.clone(), 1, &mut mc_buf);
- mc_block8x8(dst, voff, vstride, mb_x * 8, mb_y * 8, chroma_mv.x, chroma_mv.y, refframe, 2, &mut mc_buf);
+ mc_block8x8(dst, uoff, ustride, mb_x * 8, mb_y * 8, chroma_mv.x, chroma_mv.y, refframe.clone(), 1, mc_buf);
+ mc_block8x8(dst, voff, vstride, mb_x * 8, mb_y * 8, chroma_mv.x, chroma_mv.y, refframe, 2, mc_buf);
} else {
if self.dstate.version == 3 {
chroma_mv.x &= !7;
chroma_mv.y &= !7;
}
- mc_block8x8_bilin(dst, uoff, ustride, mb_x * 8, mb_y * 8, chroma_mv.x, chroma_mv.y, refframe.clone(), 1, &mut mc_buf);
- mc_block8x8_bilin(dst, voff, vstride, mb_x * 8, mb_y * 8, chroma_mv.x, chroma_mv.y, refframe, 2, &mut mc_buf);
+ mc_block8x8_bilin(dst, uoff, ustride, mb_x * 8, mb_y * 8, chroma_mv.x, chroma_mv.y, refframe.clone(), 1, mc_buf);
+ mc_block8x8_bilin(dst, voff, vstride, mb_x * 8, mb_y * 8, chroma_mv.x, chroma_mv.y, refframe, 2, mc_buf);
}
} else {
for y in 0..2 {
if self.dstate.version == 0 {
mc_block4x4(dst, uoff + x * 4, ustride, mb_x * 8 + x * 4, mb_y * 8 + y * 4,
- chroma_mv.x, chroma_mv.y, refframe.clone(), 1, &mut mc_buf);
+ chroma_mv.x, chroma_mv.y, refframe.clone(), 1, mc_buf);
mc_block4x4(dst, voff + x * 4, vstride, mb_x * 8 + x * 4, mb_y * 8 + y * 4,
- chroma_mv.x, chroma_mv.y, refframe.clone(), 2, &mut mc_buf);
+ chroma_mv.x, chroma_mv.y, refframe.clone(), 2, mc_buf);
} else {
mc_block4x4_bilin(dst, uoff + x * 4, ustride, mb_x * 8 + x * 4, mb_y * 8 + y * 4,
- chroma_mv.x, chroma_mv.y, refframe.clone(), 1, &mut mc_buf);
+ chroma_mv.x, chroma_mv.y, refframe.clone(), 1, mc_buf);
mc_block4x4_bilin(dst, voff + x * 4, vstride, mb_x * 8 + x * 4, mb_y * 8 + y * 4,
- chroma_mv.x, chroma_mv.y, refframe.clone(), 2, &mut mc_buf);
+ chroma_mv.x, chroma_mv.y, refframe.clone(), 2, mc_buf);
}
}
uoff += ustride * 4;
}
}
#[allow(clippy::cognitive_complexity)]
+ #[allow(clippy::collapsible_else_if)]
fn decode(&mut self, supp: &mut NADecoderSupport, pkt: &NAPacket) -> DecoderResult<NAFrameRef> {
let src = pkt.get_buffer();
validate!(src.len() > 4);
for start in part_offs[num_partitions..].iter_mut() {
*start = data_start;
}
- let mut bc_src = unsafe {
- let mut arr: [BoolCoder; 8] = std::mem::MaybeUninit::uninit().assume_init();
- for (bc, &off) in arr.iter_mut().zip(part_offs.iter()) {
- std::ptr::write(bc, BoolCoder::new(&src[off..]).unwrap());
- }
- arr
- };
+ let mut bc_src = Vec::new();
+ for &off in part_offs.iter() {
+ bc_src.push(BoolCoder::new(&src[off..]).unwrap());
+ }
let vinfo = NAVideoInfo::new(self.width, self.height, false, YUV420_FORMAT);
let ret = supp.pool_u8.get_free();
use crate::duck_register_all_decoders;
use crate::duck_register_all_demuxers;
+ // all samples are from the official VP8 test bitstreams set
fn test_vp8_core(name: &str, hash: [u32; 4]) {
let mut dmx_reg = RegisteredDemuxers::new();
duck_register_all_demuxers(&mut dmx_reg);
let mut dec_reg = RegisteredDecoders::new();
duck_register_all_decoders(&mut dec_reg);
- test_decoding("ivf", "vp8", name, None, &dmx_reg,
+ test_decoding("dkivf", "vp8", name, None, &dmx_reg,
&dec_reg, ExpectedTestResult::MD5(hash));
}