From: Yunqing Wang Date: Wed, 5 Aug 2015 16:15:03 +0000 (-0700) Subject: Improve the second-level sub-pixel motion search X-Git-Tag: v1.5.0~312^2 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=7418b176ce1c985637c639280d70b12bdc850e57;p=libvpx Improve the second-level sub-pixel motion search Re-investigated the second-level sub-pixel motion search. Improved the way of choosing search points. Rewrote the second-level search code. At speed 0, the borg tests showed: 1. for stdhd set, Avg PSNR gain: 0.216%; Overall PSNR gain: 0.196%; SSIM gain: 0.206%. Only 1 out of 15 clips showed PSNR loss. 2. for derf set, Avg PSNR gain: 0.171%; Overall PSNR gain: 0.192%; SSIM gain: 0.207%. Only 3 out of 30 clips showed PSNR losses. Added the condition for third-point checking, namely, less points were checked. Speed tests showed no speed loss(Avg 0.3% speedup at speed 0). Change-Id: I6284ebb3fa7ba63be8528184c49e06757211a7f1 --- diff --git a/vp9/encoder/vp9_mcomp.c b/vp9/encoder/vp9_mcomp.c index 63a35526b..6697a2540 100644 --- a/vp9/encoder/vp9_mcomp.c +++ b/vp9/encoder/vp9_mcomp.c @@ -256,6 +256,27 @@ static INLINE const uint8_t *pre(const uint8_t *buf, int stride, int r, int c) { } \ } +// TODO(yunqingwang): SECOND_LEVEL_CHECKS_BEST was a rewrote of +// SECOND_LEVEL_CHECKS, and SECOND_LEVEL_CHECKS should be rewritten +// later in the same way. +#define SECOND_LEVEL_CHECKS_BEST \ + { \ + unsigned int second; \ + int br0 = br; \ + int bc0 = bc; \ + assert(tr == br || tc == bc); \ + if (tr == br && tc != bc) { \ + kc = bc - tc; \ + } else if (tr != br && tc == bc) { \ + kr = br - tr; \ + } \ + CHECK_BETTER(second, br0 + kr, bc0); \ + CHECK_BETTER(second, br0, bc0 + kc); \ + if (br0 != br || bc0 != bc) { \ + CHECK_BETTER(second, br0 + kr, bc0 + kc); \ + } \ + } + #define SETUP_SUBPEL_SEARCH \ const uint8_t *const z = x->plane[0].src.buf; \ const int src_stride = x->plane[0].src.stride; \ @@ -636,7 +657,6 @@ int vp9_find_best_sub_pixel_tree(const MACROBLOCK *x, const MACROBLOCKD *xd = &x->e_mbd; unsigned int besterr = INT_MAX; unsigned int sse; - unsigned int whichdir = 0; int thismse; const int y_stride = xd->plane[0].pre[0].stride; const int offset = bestmv->row * y_stride + bestmv->col; @@ -657,6 +677,7 @@ int vp9_find_best_sub_pixel_tree(const MACROBLOCK *x, const MV *search_step = search_step_table; int idx, best_idx = -1; unsigned int cost_array[5]; + int kr, kc; if (!(allow_hp && vp9_use_mv_hp(ref_mv))) if (round == 3) @@ -703,8 +724,11 @@ int vp9_find_best_sub_pixel_tree(const MACROBLOCK *x, } // Check diagonal sub-pixel position - tc = bc + (cost_array[0] <= cost_array[1] ? -hstep : hstep); - tr = br + (cost_array[2] <= cost_array[3] ? -hstep : hstep); + kc = (cost_array[0] <= cost_array[1] ? -hstep : hstep); + kr = (cost_array[2] <= cost_array[3] ? -hstep : hstep); + + tc = bc + kc; + tr = br + kr; if (tc >= minc && tc <= maxc && tr >= minr && tr <= maxr) { const uint8_t *const pre_address = y + (tr >> 3) * y_stride + (tc >> 3); MV this_mv = {tr, tc}; @@ -736,7 +760,7 @@ int vp9_find_best_sub_pixel_tree(const MACROBLOCK *x, } if (iters_per_step > 1 && best_idx != -1) - SECOND_LEVEL_CHECKS; + SECOND_LEVEL_CHECKS_BEST; tr = br; tc = bc;