+fn recon_b_mb(buf: &mut NAVideoBuffer<u8>, ipbs: &mut IPBShuffler, bdsp: &BlockDSP, mvi: &mut MVInfo, mvi2: &mut MVInfo, mb_pos: usize, mb_w: usize, sstate: &SliceState, binfo: &BlockInfo, mv_data: &[BlockMVInfo], bsdiff: u16, tsdiff: u16) {
+ let mb_x = mb_pos % mb_w;
+ let mb_y = mb_pos / mb_w;
+
+ let ref_mv_info = mv_data[mb_pos];
+ let has_fwd = binfo.get_num_mvs() > 0;
+ let has_bwd = binfo.get_num_mvs2() > 0;
+
+ if has_fwd || has_bwd {
+ let fwd_mv;
+ if has_fwd {
+ fwd_mv = mvi.predict(mb_x, 0, false, binfo.get_mv(0), sstate.first_line, sstate.first_mb);
+ } else {
+ fwd_mv = ZERO_MV;
+ mvi.set_zero_mv(mb_x);
+ }
+ let bwd_mv;
+ if has_bwd {
+ bwd_mv = mvi2.predict(mb_x, 0, false, binfo.get_mv2(0), sstate.first_line, sstate.first_mb);
+ } else {
+ bwd_mv = ZERO_MV;
+ mvi2.set_zero_mv(mb_x);
+ }
+ if let (Some(ref fwd_buf), Some(ref bck_buf)) = (ipbs.get_nextref(), ipbs.get_lastref()) {
+ if has_fwd && has_bwd {
+ bdsp.copy_blocks(buf, fwd_buf.clone(), mb_x * 16, mb_y * 16, fwd_mv);
+ bdsp.avg_blocks (buf, bck_buf.clone(), mb_x * 16, mb_y * 16, bwd_mv);
+ } else if has_fwd {
+ bdsp.copy_blocks(buf, fwd_buf.clone(), mb_x * 16, mb_y * 16, fwd_mv);
+ } else {
+ bdsp.copy_blocks(buf, bck_buf.clone(), mb_x * 16, mb_y * 16, bwd_mv);
+ }
+ }
+ } else {
+ if let BlockMVInfo::Inter_4MV(mvs) = ref_mv_info {
+ let mut mv_f = [ZERO_MV; 4];
+ let mut mv_b = [ZERO_MV; 4];
+ for blk_no in 0..4 {
+ let ref_mv = mvs[blk_no];
+ let ref_mv_fwd = ref_mv.scale(bsdiff, tsdiff);
+ let ref_mv_bwd = ref_mv - ref_mv_fwd;
+ mv_f[blk_no] = ref_mv_fwd;
+ mv_b[blk_no] = ref_mv_bwd;
+ }
+ if let (Some(ref fwd_buf), Some(ref bck_buf)) = (ipbs.get_nextref(), ipbs.get_lastref()) {
+ bdsp.copy_blocks8x8(buf, fwd_buf.clone(), mb_x * 16, mb_y * 16, &mv_f);
+ bdsp.avg_blocks8x8 (buf, bck_buf.clone(), mb_x * 16, mb_y * 16, &mv_b);
+ }
+ } else {
+ let ref_mv = if let BlockMVInfo::Inter_1MV(mv_) = ref_mv_info { mv_ } else { ZERO_MV };
+ let ref_mv_fwd = ref_mv.scale(bsdiff, tsdiff);
+ let ref_mv_bwd = MV::b_sub(ref_mv, ref_mv_fwd, ZERO_MV, bsdiff, tsdiff);
+
+ if let (Some(ref fwd_buf), Some(ref bck_buf)) = (ipbs.get_nextref(), ipbs.get_lastref()) {
+ bdsp.copy_blocks(buf, fwd_buf.clone(), mb_x * 16, mb_y * 16, ref_mv_fwd);
+ bdsp.avg_blocks (buf, bck_buf.clone(), mb_x * 16, mb_y * 16, ref_mv_bwd);
+ }
+ }
+ mvi.set_zero_mv(mb_x);
+ mvi2.set_zero_mv(mb_x);
+ }
+}
+