X-Git-Url: https://git.nihav.org/?a=blobdiff_plain;f=nihav-duck%2Fsrc%2Fcodecs%2Fvp56.rs;h=5abea84f07a22fcc62567db91db0f09d2bb50a35;hb=e6aaad5c5273cd814b5748b7faf3751835a37217;hp=5b4210f902ada2e8339859e9f6dc84c1feda4449;hpb=6d48a381fd19c59600ba2939bd8bd168486fe56c;p=nihav.git diff --git a/nihav-duck/src/codecs/vp56.rs b/nihav-duck/src/codecs/vp56.rs index 5b4210f..5abea84 100644 --- a/nihav-duck/src/codecs/vp56.rs +++ b/nihav-duck/src/codecs/vp56.rs @@ -461,7 +461,7 @@ impl VP56Decoder { self.top_ctx = [vec![0; self.mb_w * 2], vec![0; self.mb_w], vec![0; self.mb_w], vec![0; self.mb_w * 2]]; } pub fn init(&mut self, supp: &mut NADecoderSupport, vinfo: NAVideoInfo) -> DecoderResult<()> { - supp.pool_u8.set_dec_bufs(3); + supp.pool_u8.set_dec_bufs(3 + if vinfo.get_format().has_alpha() { 1 } else { 0 }); supp.pool_u8.prealloc_video(NAVideoInfo::new(vinfo.get_width(), vinfo.get_height(), false, vinfo.get_format()), 4)?; self.set_dimensions(vinfo.get_width(), vinfo.get_height()); self.dc_pred.resize(self.mb_w); @@ -486,7 +486,7 @@ impl VP56Decoder { let hdr = br.parse_header(&mut bc)?; validate!((hdr.offset as usize) < aoffset); //XXX: take alpha 3 byte offset into account? - if hdr.mb_w != 0 { + if hdr.mb_w != 0 && (usize::from(hdr.mb_w) != self.mb_w || usize::from(hdr.mb_h) != self.mb_h) { self.set_dimensions((hdr.mb_w as usize) * 16, (hdr.mb_h as usize) * 16); } let fmt = if !self.has_alpha { @@ -531,12 +531,34 @@ impl VP56Decoder { std::mem::swap(&mut self.models, &mut self.amodels); let ret = self.decode_planes(br, &mut dframe, &mut bc, &ahdr, asrc, true); std::mem::swap(&mut self.models, &mut self.amodels); - if let Err(err) = ret { - return Err(err); - } + ret?; + match (hdr.is_golden, ahdr.is_golden) { + (true, true) => { self.shuf.add_golden_frame(buf.clone()); }, + (true, false) => { + let cur_golden = self.shuf.get_golden().unwrap(); + let off = cur_golden.get_offset(3); + let stride = cur_golden.get_stride(3); + let mut new_golden = supp.pool_u8.get_copy(&buf).unwrap(); + let dst = new_golden.get_data_mut().unwrap(); + let src = cur_golden.get_data(); + dst[off..][..stride * self.mb_h * 16].copy_from_slice(&src[off..][..stride * self.mb_h * 16]); + self.shuf.add_golden_frame(new_golden); + }, + (false, true) => { + let cur_golden = self.shuf.get_golden().unwrap(); + let off = cur_golden.get_offset(3); + let stride = cur_golden.get_stride(3); + let mut new_golden = supp.pool_u8.get_copy(&cur_golden).unwrap(); + let dst = new_golden.get_data_mut().unwrap(); + let src = buf.get_data(); + dst[off..][..stride * self.mb_h * 16].copy_from_slice(&src[off..][..stride * self.mb_h * 16]); + self.shuf.add_golden_frame(new_golden); + }, + _ => {}, + }; } - if hdr.is_golden { + if hdr.is_golden && !self.has_alpha { self.shuf.add_golden_frame(buf.clone()); } self.shuf.add_frame(buf.clone()); @@ -609,7 +631,7 @@ impl VP56Decoder { self.fstate.last_idx = [24; 4]; for mb_x in 0..self.mb_w { self.fstate.mb_x = mb_x; - self.decode_mb(dframe, bc, &mut cr, br, &hdr, alpha)?; + self.decode_mb(dframe, bc, &mut cr, br, hdr, alpha)?; self.dc_pred.next_mb(); } self.dc_pred.update_row(); @@ -675,16 +697,16 @@ impl VP56Decoder { let sum = u32::from(prob_xmitted[mode * 2]) + u32::from(prob_xmitted[mode * 2 + 1]); mdl.probs[9] = 255 - rescale_mb_mode_prob(u32::from(prob_xmitted[mode * 2 + 1]), sum); - let inter_mv0_weight = (cnt[0] as u32) + (cnt[2] as u32); - let inter_mv1_weight = (cnt[3] as u32) + (cnt[4] as u32); - let gold_mv0_weight = (cnt[5] as u32) + (cnt[6] as u32); - let gold_mv1_weight = (cnt[8] as u32) + (cnt[9] as u32); - let mix_weight = (cnt[1] as u32) + (cnt[7] as u32); + let inter_mv0_weight = cnt[0] + cnt[2]; + let inter_mv1_weight = cnt[3] + cnt[4]; + let gold_mv0_weight = cnt[5] + cnt[6]; + let gold_mv1_weight = cnt[8] + cnt[9]; + let mix_weight = cnt[1] + cnt[7]; mdl.probs[0] = 1 + rescale_mb_mode_prob(inter_mv0_weight + inter_mv1_weight, total); mdl.probs[1] = 1 + rescale_mb_mode_prob(inter_mv0_weight, inter_mv0_weight + inter_mv1_weight); mdl.probs[2] = 1 + rescale_mb_mode_prob(mix_weight, mix_weight + gold_mv0_weight + gold_mv1_weight); - mdl.probs[3] = 1 + rescale_mb_mode_prob(cnt[0] as u32, inter_mv0_weight); - mdl.probs[4] = 1 + rescale_mb_mode_prob(cnt[3] as u32, inter_mv1_weight); + mdl.probs[3] = 1 + rescale_mb_mode_prob(cnt[0], inter_mv0_weight); + mdl.probs[4] = 1 + rescale_mb_mode_prob(cnt[3], inter_mv1_weight); mdl.probs[5] = 1 + rescale_mb_mode_prob(cnt[1], mix_weight); mdl.probs[6] = 1 + rescale_mb_mode_prob(gold_mv0_weight, gold_mv0_weight + gold_mv1_weight); mdl.probs[7] = 1 + rescale_mb_mode_prob(cnt[5], gold_mv0_weight);