From 1dd9a63929495a0f1d39848f33a970a159bf03de Mon Sep 17 00:00:00 2001 From: Yunqing Wang Date: Thu, 4 Sep 2014 15:16:12 -0700 Subject: [PATCH] Correct the mode decisions in special cases The rate costs calculated for inter modes are not precise in some cases, which causes NEWMV is chosen instead of NEARESTMV, NEARMV, and ZEROMV. This patch added checks for these cases, and corrected the mode decisions. Borg tests at speed 3 showed: 1. stdhd set: 0.102% PSNR gain and 0.088% SSIM gain. 2. derf set: 0.147% PSNR gain and 0.132% SSIM gain. No speed change. Change-Id: I35d17684b89ad4734fb610942d707899146426db --- vp9/encoder/vp9_rdopt.c | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/vp9/encoder/vp9_rdopt.c b/vp9/encoder/vp9_rdopt.c index a70669f..9f9bed6 100644 --- a/vp9/encoder/vp9_rdopt.c +++ b/vp9/encoder/vp9_rdopt.c @@ -2850,6 +2850,8 @@ int64_t vp9_rd_pick_inter_mode_sb(VP9_COMP *cpi, MACROBLOCK *x, // them for this frame. mbmi->interp_filter = cm->interp_filter == SWITCHABLE ? EIGHTTAP : cm->interp_filter; + mbmi->mv[0].as_int = mbmi->mv[1].as_int = 0; + x->skip = 0; set_ref_ptrs(cm, xd, ref_frame, second_ref_frame); @@ -3095,6 +3097,28 @@ int64_t vp9_rd_pick_inter_mode_sb(VP9_COMP *cpi, MACROBLOCK *x, break; } + // The inter modes' rate costs are not calculated precisely in some cases. + // Therefore, sometimes, NEWMV is chosen instead of NEARESTMV, NEARMV, and + // ZEROMV. Here, checks are added for those cases, and the mode decisions + // are corrected. + if (best_mbmode.mode == NEWMV) { + const MV_REFERENCE_FRAME refs[2] = {best_mbmode.ref_frame[0], + best_mbmode.ref_frame[1]}; + int comp_pred_mode = refs[1] > INTRA_FRAME; + + if (frame_mv[NEARESTMV][refs[0]].as_int == best_mbmode.mv[0].as_int && + ((comp_pred_mode && frame_mv[NEARESTMV][refs[1]].as_int == + best_mbmode.mv[1].as_int) || !comp_pred_mode)) + best_mbmode.mode = NEARESTMV; + else if (frame_mv[NEARMV][refs[0]].as_int == best_mbmode.mv[0].as_int && + ((comp_pred_mode && frame_mv[NEARMV][refs[1]].as_int == + best_mbmode.mv[1].as_int) || !comp_pred_mode)) + best_mbmode.mode = NEARMV; + else if (best_mbmode.mv[0].as_int == 0 && + ((comp_pred_mode && best_mbmode.mv[1].as_int == 0) || !comp_pred_mode)) + best_mbmode.mode = ZEROMV; + } + if (best_mode_index < 0 || best_rd >= best_rd_so_far) return INT64_MAX; -- 2.7.4