From 08706a3ea726fe0c5d3b2c478d755818fff64291 Mon Sep 17 00:00:00 2001 From: Yunqing Wang Date: Tue, 14 Dec 2010 17:39:25 -0500 Subject: [PATCH] Fix a bug in motion search code(2) This fix added MV range checks for NEWMV mode as suggested by Jim. To reduce unnecessary MV range checks, I tried Yaowu's suggestion. Update UMV borders in NEWMV mode to also cover MV range check. Also, in this way, every MV that is valid gets checked in diamond search function. Change-Id: I95a89ce0daf6f178c454448f13d4249f19b30f3a --- vp8/encoder/mcomp.c | 86 ++++++++------------------------------------- vp8/encoder/rdopt.c | 29 +++++++++++++-- 2 files changed, 41 insertions(+), 74 deletions(-) diff --git a/vp8/encoder/mcomp.c b/vp8/encoder/mcomp.c index c5209ff85..9b91739cc 100644 --- a/vp8/encoder/mcomp.c +++ b/vp8/encoder/mcomp.c @@ -941,18 +941,8 @@ int vp8_diamond_search_sad unsigned char *check_here; int thissad; - int search_range = 128>>search_param; - *num00 = 0; - // Trap uncodable vectors - if (((abs(ref_mv->col - center_mv->col) + (search_range<<4)) > MAX_POSSIBLE_MV) || ((abs(ref_mv->row - center_mv->row) + (search_range<<4)) > MAX_POSSIBLE_MV)) - { - best_mv->row = ref_row; - best_mv->col = ref_col; - return INT_MAX; - } - // Work out the start point for the search in_what = (unsigned char *)(*(d->base_pre) + d->pre + (ref_row * (d->pre_stride)) + ref_col); best_address = in_what; @@ -1067,18 +1057,8 @@ int vp8_diamond_search_sadx4 unsigned char *check_here; unsigned int thissad; - int search_range = 128>>search_param; - *num00 = 0; - // Trap uncodable vectors - if (((abs(ref_mv->col - center_mv->col) + (search_range<<4)) > MAX_POSSIBLE_MV) || ((abs(ref_mv->row - center_mv->row) + (search_range<<4)) > MAX_POSSIBLE_MV)) - { - best_mv->row = ref_row; - best_mv->col = ref_col; - return INT_MAX; - } - // Work out the start point for the search in_what = (unsigned char *)(*(d->base_pre) + d->pre + (ref_row * (d->pre_stride)) + ref_col); best_address = in_what; @@ -1214,24 +1194,10 @@ int vp8_full_search_sad(MACROBLOCK *x, BLOCK *b, BLOCKD *d, MV *ref_mv, int erro int ref_row = ref_mv->row >> 3; int ref_col = ref_mv->col >> 3; - int row_min, row_max, col_min, col_max; - - int drow = abs(ref_mv->row - center_mv->row); - int dcol = abs(ref_mv->col - center_mv->col); - - // reduce search distance and make sure MV obtained is in range. - if (((dcol + (distance<<3)) > MAX_POSSIBLE_MV) || (( drow + (distance<<3)) > MAX_POSSIBLE_MV)) - { - if(dcol > drow) - distance = (MAX_POSSIBLE_MV - dcol)>>3; - else - distance = (MAX_POSSIBLE_MV - drow)>>3; - } - - row_min = ref_row - distance; - row_max = ref_row + distance; - col_min = ref_col - distance; - col_max = ref_col + distance; + int row_min = ref_row - distance; + int row_max = ref_row + distance; + int col_min = ref_col - distance; + int col_max = ref_col + distance; // Work out the mid point for the search in_what = *(d->base_pre) + d->pre; @@ -1318,24 +1284,12 @@ int vp8_full_search_sadx3(MACROBLOCK *x, BLOCK *b, BLOCKD *d, MV *ref_mv, int er int ref_row = ref_mv->row >> 3; int ref_col = ref_mv->col >> 3; - int row_min, row_max, col_min, col_max; + int row_min = ref_row - distance; + int row_max = ref_row + distance; + int col_min = ref_col - distance; + int col_max = ref_col + distance; + unsigned int sad_array[3]; - int drow = abs(ref_mv->row - center_mv->row); - int dcol = abs(ref_mv->col - center_mv->col); - - // reduce search distance and make sure MV obtained is in range. - if (((dcol + (distance<<3)) > MAX_POSSIBLE_MV) || (( drow + (distance<<3)) > MAX_POSSIBLE_MV)) - { - if(dcol > drow) - distance = (MAX_POSSIBLE_MV - dcol)>>3; - else - distance = (MAX_POSSIBLE_MV - drow)>>3; - } - - row_min = ref_row - distance; - row_max = ref_row + distance; - col_min = ref_col - distance; - col_max = ref_col + distance; // Work out the mid point for the search in_what = *(d->base_pre) + d->pre; @@ -1455,25 +1409,13 @@ int vp8_full_search_sadx8(MACROBLOCK *x, BLOCK *b, BLOCKD *d, MV *ref_mv, int er int ref_row = ref_mv->row >> 3; int ref_col = ref_mv->col >> 3; - int row_min, row_max, col_min, col_max; + int row_min = ref_row - distance; + int row_max = ref_row + distance; + int col_min = ref_col - distance; + int col_max = ref_col + distance; + unsigned short sad_array8[8]; unsigned int sad_array[3]; - int drow = abs(ref_mv->row - center_mv->row); - int dcol = abs(ref_mv->col - center_mv->col); - - // reduce search distance and make sure MV obtained is in range. - if (((dcol + (distance<<3)) > MAX_POSSIBLE_MV) || (( drow + (distance<<3)) > MAX_POSSIBLE_MV)) - { - if(dcol > drow) - distance = (MAX_POSSIBLE_MV - dcol)>>3; - else - distance = (MAX_POSSIBLE_MV - drow)>>3; - } - - row_min = ref_row - distance; - row_max = ref_row + distance; - col_min = ref_col - distance; - col_max = ref_col + distance; // Work out the mid point for the search in_what = *(d->base_pre) + d->pre; diff --git a/vp8/encoder/rdopt.c b/vp8/encoder/rdopt.c index aa17b31e3..91e8a549b 100644 --- a/vp8/encoder/rdopt.c +++ b/vp8/encoder/rdopt.c @@ -1886,11 +1886,11 @@ int vp8_rd_pick_inter_mode(VP8_COMP *cpi, MACROBLOCK *x, int recon_yoffset, int /* adjust mvp to make sure it is within MV range */ if(mvp.row > best_ref_mv.row + MAX_POSSIBLE_MV) mvp.row = best_ref_mv.row + MAX_POSSIBLE_MV; - if(mvp.row < best_ref_mv.row - MAX_POSSIBLE_MV) + else if(mvp.row < best_ref_mv.row - MAX_POSSIBLE_MV) mvp.row = best_ref_mv.row - MAX_POSSIBLE_MV; if(mvp.col > best_ref_mv.col + MAX_POSSIBLE_MV) mvp.col = best_ref_mv.col + MAX_POSSIBLE_MV; - if(mvp.col < best_ref_mv.col - MAX_POSSIBLE_MV) + else if(mvp.col < best_ref_mv.col - MAX_POSSIBLE_MV) mvp.col = best_ref_mv.col - MAX_POSSIBLE_MV; } @@ -2081,6 +2081,26 @@ int vp8_rd_pick_inter_mode(VP8_COMP *cpi, MACROBLOCK *x, int recon_yoffset, int int further_steps; int n; + int col_min = (best_ref_mv.col - MAX_POSSIBLE_MV) >>3; + int col_max = (best_ref_mv.col + MAX_POSSIBLE_MV) >>3; + int row_min = (best_ref_mv.row - MAX_POSSIBLE_MV) >>3; + int row_max = (best_ref_mv.row + MAX_POSSIBLE_MV) >>3; + + int tmp_col_min = x->mv_col_min; + int tmp_col_max = x->mv_col_max; + int tmp_row_min = x->mv_row_min; + int tmp_row_max = x->mv_row_max; + + // Get intersection of UMV window and valid MV window to reduce # of checks in diamond search. + if (x->mv_col_min < col_min ) + x->mv_col_min = col_min; + if (x->mv_col_max > col_max ) + x->mv_col_max = col_max; + if (x->mv_row_min < row_min ) + x->mv_row_min = row_min; + if (x->mv_row_max > row_max ) + x->mv_row_max = row_max; + //adjust search range according to sr from mv prediction if(sr > step_param) step_param = sr; @@ -2193,6 +2213,11 @@ int vp8_rd_pick_inter_mode(VP8_COMP *cpi, MACROBLOCK *x, int recon_yoffset, int } } + x->mv_col_min = tmp_col_min; + x->mv_col_max = tmp_col_max; + x->mv_row_min = tmp_row_min; + x->mv_row_max = tmp_row_max; + if (bestsme < INT_MAX) // cpi->find_fractional_mv_step(x,b,d,&d->bmi.mv.as_mv,&best_ref_mv,x->errorperbit/2,cpi->fn_ptr.svf,cpi->fn_ptr.vf,x->mvcost); // normal mvc=11 cpi->find_fractional_mv_step(x, b, d, &d->bmi.mv.as_mv, &best_ref_mv, x->errorperbit / 4, &cpi->fn_ptr[BLOCK_16X16], x->mvcost);