aac: clear M/S flags
[nihav.git] / nihav-duck / src / codecs / vp56.rs
index 5b4210f902ada2e8339859e9f6dc84c1feda4449..5abea84f07a22fcc62567db91db0f09d2bb50a35 100644 (file)
@@ -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);