diff options
author | Yaowu Xu <yaowu@google.com> | 2012-08-06 10:51:20 -0700 |
---|---|---|
committer | Yaowu Xu <yaowu@google.com> | 2012-08-07 11:25:57 -0700 |
commit | 8b2f57d0b8da5a51e4579da6baa3e7bf4ea40b5b (patch) | |
tree | e6350cabc46cc6f01fd9c2db560c183c604908d4 /vp8/common/findnearmv.c | |
parent | 66f440f1ee6c993eff908da9c75cc2ae9de08775 (diff) | |
download | libvpx-8b2f57d0b8da5a51e4579da6baa3e7bf4ea40b5b.tar libvpx-8b2f57d0b8da5a51e4579da6baa3e7bf4ea40b5b.tar.gz libvpx-8b2f57d0b8da5a51e4579da6baa3e7bf4ea40b5b.tar.bz2 libvpx-8b2f57d0b8da5a51e4579da6baa3e7bf4ea40b5b.zip |
a new way of determining reference motion vector
Using surrounding reconstructed pixels from left and above to select
best matching mv to use as reference motion vector for mv encoding.
Test results:
AVGPSNR GLBPSNR VPXSSIM
Derf: 1.107% 1.062% 0.992%
Std-hd:1.209% 1.176% 1.029%
Change-Id: I8f10e09ee6538c05df2fb9f069abcaf1edb3fca6
Diffstat (limited to 'vp8/common/findnearmv.c')
-rw-r--r-- | vp8/common/findnearmv.c | 139 |
1 files changed, 119 insertions, 20 deletions
diff --git a/vp8/common/findnearmv.c b/vp8/common/findnearmv.c index d35e2c4d4..303893d9d 100644 --- a/vp8/common/findnearmv.c +++ b/vp8/common/findnearmv.c @@ -10,6 +10,7 @@ #include "findnearmv.h" +#include <limits.h> const unsigned char vp8_mbsplit_offset[4][16] = { { 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, @@ -18,6 +19,15 @@ const unsigned char vp8_mbsplit_offset[4][16] = { { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15} }; +static void lower_mv_precision(int_mv *mv) +{ + if (mv->as_mv.row & 1) + mv->as_mv.row += (mv->as_mv.row > 0 ? -1 : 1); + if (mv->as_mv.col & 1) + mv->as_mv.col += (mv->as_mv.col > 0 ? -1 : 1); +} + + /* Predict motion vectors using those from already-decoded nearby blocks. Note that we only consider one 4x4 subblock from each candidate 16x16 macroblock. */ @@ -32,8 +42,7 @@ void vp8_find_near_mvs int_mv *best_mv, int cnt[4], int refframe, - int *ref_frame_sign_bias -) { + int *ref_frame_sign_bias) { const MODE_INFO *above = here - xd->mode_info_stride; const MODE_INFO *left = here - 1; const MODE_INFO *aboveleft = above - 1; @@ -43,16 +52,30 @@ void vp8_find_near_mvs int *cntx = cnt; enum {CNT_INTRA, CNT_NEAREST, CNT_NEAR, CNT_SPLITMV}; +#if CONFIG_NEWBESTREFMV + int_mv *ref_mv = xd->ref_mv; +#endif + /* Zero accumulators */ mv[0].as_int = mv[1].as_int = mv[2].as_int = 0; cnt[0] = cnt[1] = cnt[2] = cnt[3] = 0; +#if CONFIG_NEWBESTREFMV + ref_mv[0].as_int = ref_mv[1].as_int + = ref_mv[2].as_int + = ref_mv[3].as_int + = 0; +#endif /* Process above */ if (above->mbmi.ref_frame != INTRA_FRAME) { if (above->mbmi.mv.as_int) { - (++mv)->as_int = above->mbmi.mv.as_int; + ++ mv; + mv->as_int = above->mbmi.mv.as_int; mv_bias(ref_frame_sign_bias[above->mbmi.ref_frame], refframe, mv, ref_frame_sign_bias); +#if CONFIG_NEWBESTREFMV + ref_mv[0].as_int = mv->as_int; +#endif ++cntx; } *cntx += 2; @@ -65,10 +88,13 @@ void vp8_find_near_mvs this_mv.as_int = left->mbmi.mv.as_int; mv_bias(ref_frame_sign_bias[left->mbmi.ref_frame], refframe, &this_mv, ref_frame_sign_bias); - +#if CONFIG_NEWBESTREFMV + ref_mv[1].as_int = this_mv.as_int; +#endif if (this_mv.as_int != mv->as_int) { - (++mv)->as_int = this_mv.as_int; - ++cntx; + ++ mv; + mv->as_int = this_mv.as_int; + ++ cntx; } *cntx += 2; } else @@ -79,9 +105,21 @@ void vp8_find_near_mvs (lf_here->mbmi.ref_frame == LAST_FRAME && refframe == LAST_FRAME)) { if (aboveleft->mbmi.mv.as_int) { third = aboveleft; +#if CONFIG_NEWBESTREFMV + ref_mv[2].as_int = aboveleft->mbmi.mv.as_int; + mv_bias(ref_frame_sign_bias[aboveleft->mbmi.ref_frame], + refframe, (ref_mv+2), ref_frame_sign_bias); +#endif } else if (lf_here->mbmi.mv.as_int) { third = lf_here; } +#if CONFIG_NEWBESTREFMV + if (lf_here->mbmi.mv.as_int) { + ref_mv[3].as_int = lf_here->mbmi.mv.as_int; + mv_bias(ref_frame_sign_bias[lf_here->mbmi.ref_frame], + refframe, (ref_mv+3), ref_frame_sign_bias); + } +#endif if (third) { int_mv this_mv; this_mv.as_int = third->mbmi.mv.as_int; @@ -89,8 +127,9 @@ void vp8_find_near_mvs refframe, &this_mv, ref_frame_sign_bias); if (this_mv.as_int != mv->as_int) { - (++mv)->as_int = this_mv.as_int; - ++cntx; + ++ mv; + mv->as_int = this_mv.as_int; + ++ cntx; } *cntx += 1; } else @@ -134,18 +173,9 @@ void vp8_find_near_mvs * is not being used, by truncating the last bit towards 0 */ if (!xd->allow_high_precision_mv) { - if (best_mv->as_mv.row & 1) - best_mv->as_mv.row += (best_mv->as_mv.row > 0 ? -1 : 1); - if (best_mv->as_mv.col & 1) - best_mv->as_mv.col += (best_mv->as_mv.col > 0 ? -1 : 1); - if (nearest->as_mv.row & 1) - nearest->as_mv.row += (nearest->as_mv.row > 0 ? -1 : 1); - if (nearest->as_mv.col & 1) - nearest->as_mv.col += (nearest->as_mv.col > 0 ? -1 : 1); - if (nearby->as_mv.row & 1) - nearby->as_mv.row += (nearby->as_mv.row > 0 ? -1 : 1); - if (nearby->as_mv.col & 1) - nearby->as_mv.col += (nearby->as_mv.col > 0 ? -1 : 1); + lower_mv_precision(best_mv); + lower_mv_precision(nearest); + lower_mv_precision(nearby); } // TODO: move clamp outside findnearmv @@ -163,3 +193,72 @@ vp8_prob *vp8_mv_ref_probs(VP8_COMMON *pc, p[3] = pc->fc.vp8_mode_contexts [near_mv_ref_ct[3]] [3]; return p; } + +#if CONFIG_NEWBESTREFMV +/* check a list of motion vectors by sad score using a number rows of pixels + * above and a number cols of pixels in the left to select the one with best + * score to use as ref motion vector + */ +void vp8_find_best_ref_mvs(MACROBLOCKD *xd, + unsigned char *ref_y_buffer, + int ref_y_stride, + int_mv *best_mv){ + int_mv *ref_mv = xd->ref_mv; + int bestsad = INT_MAX; + int i; + unsigned char *above_src; + unsigned char *left_src; + unsigned char *above_ref; + unsigned char *left_ref; + int sad; + + above_src = xd->dst.y_buffer - xd->dst.y_stride * 2; + left_src = xd->dst.y_buffer - 2; + above_ref = ref_y_buffer - ref_y_stride * 2; + left_ref = ref_y_buffer - 2; + + bestsad = vp8_sad16x2_c(above_src, xd->dst.y_stride, + above_ref, ref_y_stride, + INT_MAX); + bestsad += vp8_sad2x16_c(left_src, xd->dst.y_stride, + left_ref, ref_y_stride, + INT_MAX); + best_mv->as_int = 0; + + for(i = 0; i < 4; ++i) { + if (ref_mv[i].as_int) { + int_mv this_mv; + int offset=0; + int row_offset, col_offset; + this_mv.as_int = ref_mv[i].as_int; + vp8_clamp_mv(&this_mv, + xd->mb_to_left_edge - LEFT_TOP_MARGIN + 16, + xd->mb_to_right_edge + RIGHT_BOTTOM_MARGIN, + xd->mb_to_top_edge - LEFT_TOP_MARGIN + 16, + xd->mb_to_bottom_edge + RIGHT_BOTTOM_MARGIN); + + row_offset = (this_mv.as_mv.row > 0) ? + ((this_mv.as_mv.row + 3) >> 3):((this_mv.as_mv.row + 4) >> 3); + col_offset = (this_mv.as_mv.col > 0) ? + ((this_mv.as_mv.col + 3) >> 3):((this_mv.as_mv.col + 4) >> 3); + offset = ref_y_stride * row_offset + col_offset; + + sad = vp8_sad16x2_c(above_src, xd->dst.y_stride, + above_ref + offset, ref_y_stride, INT_MAX); + + sad += vp8_sad2x16_c(left_src, xd->dst.y_stride, + left_ref + offset, ref_y_stride, INT_MAX); + + if (sad < bestsad) { + bestsad = sad; + best_mv->as_int = this_mv.as_int; + } + } + } + if (!xd->allow_high_precision_mv) + lower_mv_precision(best_mv); + + vp8_clamp_mv2(best_mv, xd); +} + +#endif |