Adjust full-pixel clamping and motion vector limit calculation

Do mvp clamping in full-pixel precision instead of 1/8-pixel
precision to avoid error caused by right shifting operation.
Also, further fixed the motion vector limit calculation in change:
b7480454706a6b15bf091e659cd6227ab373c1a6

Change-Id: Ied88a4f7ddfb0476eb9f7afc6ceeddbf209fffd7
This commit is contained in:
Yunqing Wang 2011-07-07 11:21:41 -04:00
parent b4f70084cc
commit 40991faeae
5 changed files with 54 additions and 64 deletions

View File

@ -431,6 +431,7 @@ static void first_pass_motion_search(VP8_COMP *cpi, MACROBLOCK *x,
int num00; int num00;
int_mv tmp_mv; int_mv tmp_mv;
int_mv ref_mv_full;
int tmp_err; int tmp_err;
int step_param = 3; //3; // Dont search over full range for first pass int step_param = 3; //3; // Dont search over full range for first pass
@ -447,7 +448,9 @@ static void first_pass_motion_search(VP8_COMP *cpi, MACROBLOCK *x,
// Initial step/diamond search centred on best mv // Initial step/diamond search centred on best mv
tmp_mv.as_int = 0; tmp_mv.as_int = 0;
tmp_err = cpi->diamond_search_sad(x, b, d, ref_mv, &tmp_mv, step_param, ref_mv_full.as_mv.col = ref_mv->as_mv.col>>3;
ref_mv_full.as_mv.row = ref_mv->as_mv.row>>3;
tmp_err = cpi->diamond_search_sad(x, b, d, &ref_mv_full, &tmp_mv, step_param,
x->sadperbit16, &num00, &v_fn_ptr, x->sadperbit16, &num00, &v_fn_ptr,
x->mvcost, ref_mv); x->mvcost, ref_mv);
if ( tmp_err < INT_MAX-new_mv_mode_penalty ) if ( tmp_err < INT_MAX-new_mv_mode_penalty )
@ -472,7 +475,7 @@ static void first_pass_motion_search(VP8_COMP *cpi, MACROBLOCK *x,
num00--; num00--;
else else
{ {
tmp_err = cpi->diamond_search_sad(x, b, d, ref_mv, &tmp_mv, tmp_err = cpi->diamond_search_sad(x, b, d, &ref_mv_full, &tmp_mv,
step_param + n, x->sadperbit16, step_param + n, x->sadperbit16,
&num00, &v_fn_ptr, x->mvcost, &num00, &v_fn_ptr, x->mvcost,
ref_mv); ref_mv);

View File

@ -834,7 +834,7 @@ int vp8_hex_search
unsigned char *what = (*(b->base_src) + b->src); unsigned char *what = (*(b->base_src) + b->src);
int what_stride = b->src_stride; int what_stride = b->src_stride;
int in_what_stride = d->pre_stride; int in_what_stride = d->pre_stride;
int br = ref_mv->as_mv.row >> 3, bc = ref_mv->as_mv.col >> 3; int br = ref_mv->as_mv.row, bc = ref_mv->as_mv.col;
int_mv this_mv; int_mv this_mv;
unsigned int bestsad = 0x7fffffff; unsigned int bestsad = 0x7fffffff;
unsigned int thissad; unsigned int thissad;
@ -1011,8 +1011,8 @@ int vp8_diamond_search_sad
int best_site = 0; int best_site = 0;
int last_site = 0; int last_site = 0;
int ref_row = ref_mv->as_mv.row >> 3; int ref_row = ref_mv->as_mv.row;
int ref_col = ref_mv->as_mv.col >> 3; int ref_col = ref_mv->as_mv.col;
int this_row_offset; int this_row_offset;
int this_col_offset; int this_col_offset;
search_site *ss; search_site *ss;
@ -1130,8 +1130,8 @@ int vp8_diamond_search_sadx4
int best_site = 0; int best_site = 0;
int last_site = 0; int last_site = 0;
int ref_row = ref_mv->as_mv.row >> 3; int ref_row = ref_mv->as_mv.row;
int ref_col = ref_mv->as_mv.col >> 3; int ref_col = ref_mv->as_mv.col;
int this_row_offset; int this_row_offset;
int this_col_offset; int this_col_offset;
search_site *ss; search_site *ss;

View File

@ -585,13 +585,6 @@ void vp8_pick_inter_mode(VP8_COMP *cpi, MACROBLOCK *x, int recon_yoffset,
vp8_mv_pred(cpi, &x->e_mbd, x->e_mbd.mode_info_context, &mvp, vp8_mv_pred(cpi, &x->e_mbd, x->e_mbd.mode_info_context, &mvp,
x->e_mbd.mode_info_context->mbmi.ref_frame, cpi->common.ref_frame_sign_bias, &sr, &near_sadidx[0]); x->e_mbd.mode_info_context->mbmi.ref_frame, cpi->common.ref_frame_sign_bias, &sr, &near_sadidx[0]);
/* adjust mvp to make sure it is within MV range */
vp8_clamp_mv(&mvp,
best_ref_mv.as_mv.col - (MAX_FULL_PEL_VAL<<3),
best_ref_mv.as_mv.col + (MAX_FULL_PEL_VAL<<3),
best_ref_mv.as_mv.row - (MAX_FULL_PEL_VAL<<3),
best_ref_mv.as_mv.row + (MAX_FULL_PEL_VAL<<3));
} }
switch (this_mode) switch (this_mode)
@ -654,11 +647,12 @@ void vp8_pick_inter_mode(VP8_COMP *cpi, MACROBLOCK *x, int recon_yoffset,
int further_steps; int further_steps;
int n = 0; int n = 0;
int sadpb = x->sadperbit16; int sadpb = x->sadperbit16;
int_mv mvp_full;
int col_min; int col_min = (best_ref_mv.as_mv.col>>3) - MAX_FULL_PEL_VAL + ((best_ref_mv.as_mv.col & 7)?1:0);
int col_max; int row_min = (best_ref_mv.as_mv.row>>3) - MAX_FULL_PEL_VAL + ((best_ref_mv.as_mv.row & 7)?1:0);
int row_min; int col_max = (best_ref_mv.as_mv.col>>3) + MAX_FULL_PEL_VAL;
int row_max; int row_max = (best_ref_mv.as_mv.row>>3) + MAX_FULL_PEL_VAL;
int tmp_col_min = x->mv_col_min; int tmp_col_min = x->mv_col_min;
int tmp_col_max = x->mv_col_max; int tmp_col_max = x->mv_col_max;
@ -676,20 +670,19 @@ void vp8_pick_inter_mode(VP8_COMP *cpi, MACROBLOCK *x, int recon_yoffset,
//adjust search range according to sr from mv prediction //adjust search range according to sr from mv prediction
if(sr > step_param) if(sr > step_param)
step_param = sr; step_param = sr;
mvp_full.as_mv.col = mvp.as_mv.col>>3;
mvp_full.as_mv.row = mvp.as_mv.row>>3;
/* adjust mvp to make sure it is within MV range */
vp8_clamp_mv(&mvp_full, col_min, col_max, row_min, row_max);
}else }else
{ {
mvp.as_int = best_ref_mv.as_int; mvp.as_int = best_ref_mv.as_int;
mvp_full.as_mv.col = best_ref_mv.as_mv.col>>3;
mvp_full.as_mv.row = best_ref_mv.as_mv.row>>3;
} }
col_min = (best_ref_mv.as_mv.col < 0)?(-((abs(best_ref_mv.as_mv.col))>>3) - MAX_FULL_PEL_VAL)
:((best_ref_mv.as_mv.col>>3) - MAX_FULL_PEL_VAL);
col_max = (best_ref_mv.as_mv.col < 0)?(-((abs(best_ref_mv.as_mv.col))>>3) + MAX_FULL_PEL_VAL)
:((best_ref_mv.as_mv.col>>3) + MAX_FULL_PEL_VAL);
row_min = (best_ref_mv.as_mv.row < 0)?(-((abs(best_ref_mv.as_mv.row))>>3) - MAX_FULL_PEL_VAL)
:((best_ref_mv.as_mv.row>>3) - MAX_FULL_PEL_VAL);
row_max = (best_ref_mv.as_mv.row < 0)?(-((abs(best_ref_mv.as_mv.row))>>3) + MAX_FULL_PEL_VAL)
:((best_ref_mv.as_mv.row>>3) + MAX_FULL_PEL_VAL);
// Get intersection of UMV window and valid MV window to reduce # of checks in diamond search. // Get intersection of UMV window and valid MV window to reduce # of checks in diamond search.
if (x->mv_col_min < col_min ) if (x->mv_col_min < col_min )
x->mv_col_min = col_min; x->mv_col_min = col_min;
@ -704,14 +697,14 @@ void vp8_pick_inter_mode(VP8_COMP *cpi, MACROBLOCK *x, int recon_yoffset,
if (cpi->sf.search_method == HEX) if (cpi->sf.search_method == HEX)
{ {
bestsme = vp8_hex_search(x, b, d, &mvp, &d->bmi.mv, step_param, bestsme = vp8_hex_search(x, b, d, &mvp_full, &d->bmi.mv, step_param,
sadpb, &cpi->fn_ptr[BLOCK_16X16], sadpb, &cpi->fn_ptr[BLOCK_16X16],
x->mvsadcost, x->mvcost, &best_ref_mv); x->mvsadcost, x->mvcost, &best_ref_mv);
mode_mv[NEWMV].as_int = d->bmi.mv.as_int; mode_mv[NEWMV].as_int = d->bmi.mv.as_int;
} }
else else
{ {
bestsme = cpi->diamond_search_sad(x, b, d, &mvp, &d->bmi.mv, bestsme = cpi->diamond_search_sad(x, b, d, &mvp_full, &d->bmi.mv,
step_param, sadpb, &num00, step_param, sadpb, &num00,
&cpi->fn_ptr[BLOCK_16X16], &cpi->fn_ptr[BLOCK_16X16],
x->mvcost, &best_ref_mv); x->mvcost, &best_ref_mv);
@ -733,7 +726,7 @@ void vp8_pick_inter_mode(VP8_COMP *cpi, MACROBLOCK *x, int recon_yoffset,
else else
{ {
thissme = thissme =
cpi->diamond_search_sad(x, b, d, &mvp, cpi->diamond_search_sad(x, b, d, &mvp_full,
&d->bmi.mv, &d->bmi.mv,
step_param + n, step_param + n,
sadpb, &num00, sadpb, &num00,

View File

@ -1133,6 +1133,10 @@ static void rd_check_segment(VP8_COMP *cpi, MACROBLOCK *x,
{ {
int sadpb = x->sadperbit4; int sadpb = x->sadperbit4;
int_mv mvp_full;
mvp_full.as_mv.row = bsi->mvp.as_mv.row >>3;
mvp_full.as_mv.col = bsi->mvp.as_mv.col >>3;
// find first label // find first label
n = vp8_mbsplit_offset[segmentation][i]; n = vp8_mbsplit_offset[segmentation][i];
@ -1141,7 +1145,7 @@ static void rd_check_segment(VP8_COMP *cpi, MACROBLOCK *x,
e = &x->e_mbd.block[n]; e = &x->e_mbd.block[n];
{ {
bestsme = cpi->diamond_search_sad(x, c, e, &bsi->mvp, bestsme = cpi->diamond_search_sad(x, c, e, &mvp_full,
&mode_mv[NEW4X4], step_param, &mode_mv[NEW4X4], step_param,
sadpb, &num00, v_fn_ptr, sadpb, &num00, v_fn_ptr,
x->mvcost, bsi->ref_mv); x->mvcost, bsi->ref_mv);
@ -1158,7 +1162,7 @@ static void rd_check_segment(VP8_COMP *cpi, MACROBLOCK *x,
else else
{ {
thissme = cpi->diamond_search_sad(x, c, e, thissme = cpi->diamond_search_sad(x, c, e,
&bsi->mvp, &temp_mv, &mvp_full, &temp_mv,
step_param + n, sadpb, step_param + n, sadpb,
&num00, v_fn_ptr, &num00, v_fn_ptr,
x->mvcost, bsi->ref_mv); x->mvcost, bsi->ref_mv);
@ -1177,12 +1181,7 @@ static void rd_check_segment(VP8_COMP *cpi, MACROBLOCK *x,
// Should we do a full search (best quality only) // Should we do a full search (best quality only)
if ((cpi->compressor_speed == 0) && (bestsme >> sseshift) > 4000) if ((cpi->compressor_speed == 0) && (bestsme >> sseshift) > 4000)
{ {
int_mv full_mvp; thissme = cpi->full_search_sad(x, c, e, &mvp_full,
full_mvp.as_mv.row = bsi->mvp.as_mv.row >>3;
full_mvp.as_mv.col = bsi->mvp.as_mv.col >>3;
thissme = cpi->full_search_sad(x, c, e, &full_mvp,
sadpb, 16, v_fn_ptr, sadpb, 16, v_fn_ptr,
x->mvcost, bsi->ref_mv); x->mvcost, bsi->ref_mv);
@ -1330,14 +1329,10 @@ static int vp8_rd_pick_best_mbsegmentation(VP8_COMP *cpi, MACROBLOCK *x,
if (bsi.segment_rd < best_rd) if (bsi.segment_rd < best_rd)
{ {
int col_min = (best_ref_mv->as_mv.col < 0)?(-((abs(best_ref_mv->as_mv.col))>>3) - MAX_FULL_PEL_VAL) int col_min = (best_ref_mv->as_mv.col>>3) - MAX_FULL_PEL_VAL + ((best_ref_mv->as_mv.col & 7)?1:0);
:((best_ref_mv->as_mv.col>>3) - MAX_FULL_PEL_VAL); int row_min = (best_ref_mv->as_mv.row>>3) - MAX_FULL_PEL_VAL + ((best_ref_mv->as_mv.row & 7)?1:0);
int col_max = (best_ref_mv->as_mv.col < 0)?(-((abs(best_ref_mv->as_mv.col))>>3) + MAX_FULL_PEL_VAL) int col_max = (best_ref_mv->as_mv.col>>3) + MAX_FULL_PEL_VAL;
:((best_ref_mv->as_mv.col>>3) + MAX_FULL_PEL_VAL); int row_max = (best_ref_mv->as_mv.row>>3) + MAX_FULL_PEL_VAL;
int row_min = (best_ref_mv->as_mv.row < 0)?(-((abs(best_ref_mv->as_mv.row))>>3) - MAX_FULL_PEL_VAL)
:((best_ref_mv->as_mv.row>>3) - MAX_FULL_PEL_VAL);
int row_max = (best_ref_mv->as_mv.row < 0)?(-((abs(best_ref_mv->as_mv.row))>>3) + MAX_FULL_PEL_VAL)
:((best_ref_mv->as_mv.row>>3) + MAX_FULL_PEL_VAL);
int tmp_col_min = x->mv_col_min; int tmp_col_min = x->mv_col_min;
int tmp_col_max = x->mv_col_max; int tmp_col_max = x->mv_col_max;
@ -1879,13 +1874,6 @@ void vp8_rd_pick_inter_mode(VP8_COMP *cpi, MACROBLOCK *x, int recon_yoffset, int
vp8_mv_pred(cpi, &x->e_mbd, x->e_mbd.mode_info_context, &mvp, vp8_mv_pred(cpi, &x->e_mbd, x->e_mbd.mode_info_context, &mvp,
x->e_mbd.mode_info_context->mbmi.ref_frame, cpi->common.ref_frame_sign_bias, &sr, &near_sadidx[0]); x->e_mbd.mode_info_context->mbmi.ref_frame, cpi->common.ref_frame_sign_bias, &sr, &near_sadidx[0]);
/* adjust mvp to make sure it is within MV range */
vp8_clamp_mv(&mvp,
best_ref_mv.as_mv.col - (MAX_FULL_PEL_VAL<<3),
best_ref_mv.as_mv.col + (MAX_FULL_PEL_VAL<<3),
best_ref_mv.as_mv.row - (MAX_FULL_PEL_VAL<<3),
best_ref_mv.as_mv.row + (MAX_FULL_PEL_VAL<<3));
} }
// Check to see if the testing frequency for this mode is at its max // Check to see if the testing frequency for this mode is at its max
@ -2016,21 +2004,24 @@ void vp8_rd_pick_inter_mode(VP8_COMP *cpi, MACROBLOCK *x, int recon_yoffset, int
we will do a final 1-away diamond refining search */ we will do a final 1-away diamond refining search */
int sadpb = x->sadperbit16; int sadpb = x->sadperbit16;
int_mv mvp_full;
int col_min = (best_ref_mv.as_mv.col < 0)?(-((abs(best_ref_mv.as_mv.col))>>3) - MAX_FULL_PEL_VAL) int col_min = (best_ref_mv.as_mv.col>>3) - MAX_FULL_PEL_VAL + ((best_ref_mv.as_mv.col & 7)?1:0);
:((best_ref_mv.as_mv.col>>3) - MAX_FULL_PEL_VAL); int row_min = (best_ref_mv.as_mv.row>>3) - MAX_FULL_PEL_VAL + ((best_ref_mv.as_mv.row & 7)?1:0);
int col_max = (best_ref_mv.as_mv.col < 0)?(-((abs(best_ref_mv.as_mv.col))>>3) + MAX_FULL_PEL_VAL) int col_max = (best_ref_mv.as_mv.col>>3) + MAX_FULL_PEL_VAL;
:((best_ref_mv.as_mv.col>>3) + MAX_FULL_PEL_VAL); int row_max = (best_ref_mv.as_mv.row>>3) + MAX_FULL_PEL_VAL;
int row_min = (best_ref_mv.as_mv.row < 0)?(-((abs(best_ref_mv.as_mv.row))>>3) - MAX_FULL_PEL_VAL)
:((best_ref_mv.as_mv.row>>3) - MAX_FULL_PEL_VAL);
int row_max = (best_ref_mv.as_mv.row < 0)?(-((abs(best_ref_mv.as_mv.row))>>3) + MAX_FULL_PEL_VAL)
:((best_ref_mv.as_mv.row>>3) + MAX_FULL_PEL_VAL);
int tmp_col_min = x->mv_col_min; int tmp_col_min = x->mv_col_min;
int tmp_col_max = x->mv_col_max; int tmp_col_max = x->mv_col_max;
int tmp_row_min = x->mv_row_min; int tmp_row_min = x->mv_row_min;
int tmp_row_max = x->mv_row_max; int tmp_row_max = x->mv_row_max;
mvp_full.as_mv.col = mvp.as_mv.col>>3;
mvp_full.as_mv.row = mvp.as_mv.row>>3;
/* adjust mvp to make sure it is within MV range */
vp8_clamp_mv(&mvp_full, col_min, col_max, row_min, row_max);
// Get intersection of UMV window and valid MV window to reduce # of checks in diamond search. // Get intersection of UMV window and valid MV window to reduce # of checks in diamond search.
if (x->mv_col_min < col_min ) if (x->mv_col_min < col_min )
x->mv_col_min = col_min; x->mv_col_min = col_min;
@ -2047,7 +2038,7 @@ void vp8_rd_pick_inter_mode(VP8_COMP *cpi, MACROBLOCK *x, int recon_yoffset, int
// Initial step/diamond search // Initial step/diamond search
{ {
bestsme = cpi->diamond_search_sad(x, b, d, &mvp, &d->bmi.mv, bestsme = cpi->diamond_search_sad(x, b, d, &mvp_full, &d->bmi.mv,
step_param, sadpb, &num00, step_param, sadpb, &num00,
&cpi->fn_ptr[BLOCK_16X16], &cpi->fn_ptr[BLOCK_16X16],
x->mvcost, &best_ref_mv); x->mvcost, &best_ref_mv);
@ -2072,7 +2063,7 @@ void vp8_rd_pick_inter_mode(VP8_COMP *cpi, MACROBLOCK *x, int recon_yoffset, int
num00--; num00--;
else else
{ {
thissme = cpi->diamond_search_sad(x, b, d, &mvp, thissme = cpi->diamond_search_sad(x, b, d, &mvp_full,
&d->bmi.mv, step_param + n, sadpb, &num00, &d->bmi.mv, step_param + n, sadpb, &num00,
&cpi->fn_ptr[BLOCK_16X16], x->mvcost, &cpi->fn_ptr[BLOCK_16X16], x->mvcost,
&best_ref_mv); &best_ref_mv);

View File

@ -157,6 +157,7 @@ static int vp8_temporal_filter_find_matching_mb_c
BLOCK *b = &x->block[0]; BLOCK *b = &x->block[0];
BLOCKD *d = &x->e_mbd.block[0]; BLOCKD *d = &x->e_mbd.block[0];
int_mv best_ref_mv1; int_mv best_ref_mv1;
int_mv best_ref_mv1_full; /* full-pixel value of best_ref_mv1 */
int *mvcost[2] = { &dummy_cost[mv_max+1], &dummy_cost[mv_max+1] }; int *mvcost[2] = { &dummy_cost[mv_max+1], &dummy_cost[mv_max+1] };
int *mvsadcost[2] = { &dummy_cost[mv_max+1], &dummy_cost[mv_max+1] }; int *mvsadcost[2] = { &dummy_cost[mv_max+1], &dummy_cost[mv_max+1] };
@ -170,6 +171,8 @@ static int vp8_temporal_filter_find_matching_mb_c
int pre_stride = d->pre_stride; int pre_stride = d->pre_stride;
best_ref_mv1.as_int = 0; best_ref_mv1.as_int = 0;
best_ref_mv1_full.as_mv.col = best_ref_mv1.as_mv.col >>3;
best_ref_mv1_full.as_mv.row = best_ref_mv1.as_mv.row >>3;
// Setup frame pointers // Setup frame pointers
b->base_src = &arf_frame->y_buffer; b->base_src = &arf_frame->y_buffer;
@ -197,7 +200,7 @@ static int vp8_temporal_filter_find_matching_mb_c
/*cpi->sf.search_method == HEX*/ /*cpi->sf.search_method == HEX*/
// TODO Check that the 16x16 vf & sdf are selected here // TODO Check that the 16x16 vf & sdf are selected here
bestsme = vp8_hex_search(x, b, d, bestsme = vp8_hex_search(x, b, d,
&best_ref_mv1, &d->bmi.mv, &best_ref_mv1_full, &d->bmi.mv,
step_param, step_param,
sadpb, sadpb,
&cpi->fn_ptr[BLOCK_16X16], &cpi->fn_ptr[BLOCK_16X16],