+ let ref_mv_info = self.mv_data[mb_pos];
+ let has_fwd = binfo.get_num_mvs() > 0;
+ let has_bwd = binfo.get_num_mvs2() > 0;
+ let is_direct = has_fwd && has_bwd;
+//todo refactor
+ if let BlockMVInfo::Inter_4MV(mvs) = ref_mv_info {
+ for blk_no in 0..4 {
+ let ref_mv = mvs[blk_no];
+ let mut ref_mv_fwd = ref_mv.scale(bsdiff, tsdiff);
+ let mut ref_mv_bwd = ref_mv - ref_mv_fwd;
+ let xoff = mb_x * 16 + (blk_no & 1) * 8;
+ let yoff = mb_y * 16 + (blk_no & 2) * 4;
+ if has_fwd { ref_mv_fwd = MV::add_umv(ref_mv_fwd, binfo.get_mv(0), pinfo.get_mvmode()); }
+ if has_bwd { ref_mv_bwd = MV::add_umv(ref_mv_bwd, binfo.get_mv2(0), pinfo.get_mvmode()); }
+ if let (Some(ref bck_buf), Some(ref fwd_buf)) = (self.ipbs.get_nextref(), self.ipbs.get_lastref()) {
+ if is_direct || (!has_fwd && !has_bwd) {
+ bdsp.copy_blocks(&mut buf, fwd_buf, xoff, yoff, 8, 8, ref_mv_fwd);
+ bdsp.avg_blocks(&mut buf, bck_buf, xoff, yoff, 8, 8, ref_mv_bwd);
+ } else if has_fwd {
+ bdsp.copy_blocks(&mut buf, fwd_buf, xoff, yoff, 8, 8, ref_mv_fwd);
+ } else {
+ bdsp.copy_blocks(&mut buf, bck_buf, xoff, yoff, 8, 8, ref_mv_bwd);
+ }
+ }
+ }
+ } else {
+ let ref_mv = if let BlockMVInfo::Inter_1MV(mv_) = ref_mv_info { mv_ } else { ZERO_MV };
+ let mut ref_mv_fwd = ref_mv.scale(bsdiff, tsdiff);
+ let mut ref_mv_bwd = ref_mv - ref_mv_fwd;
+ if has_fwd { ref_mv_fwd = MV::add_umv(ref_mv_fwd, binfo.get_mv(0), pinfo.get_mvmode()); }
+ if has_bwd { ref_mv_bwd = MV::add_umv(ref_mv_bwd, binfo.get_mv2(0), pinfo.get_mvmode()); }
+ if let (Some(ref bck_buf), Some(ref fwd_buf)) = (self.ipbs.get_nextref(), self.ipbs.get_lastref()) {
+ if is_direct || (!has_fwd && !has_bwd) {
+ bdsp.copy_blocks(&mut buf, fwd_buf, mb_x * 16, mb_y * 16, 16, 16, ref_mv_fwd);
+ bdsp.avg_blocks(&mut buf, bck_buf, mb_x * 16, mb_y * 16, 16, 16, ref_mv_bwd);
+ } else if has_fwd {
+ bdsp.copy_blocks(&mut buf, fwd_buf, mb_x * 16, mb_y * 16, 16, 16, ref_mv_fwd);
+ } else {
+ bdsp.copy_blocks(&mut buf, bck_buf, mb_x * 16, mb_y * 16, 16, 16, ref_mv_bwd);
+ }
+ }
+ }