Commit e06c242b authored by Yunqing Wang's avatar Yunqing Wang

Only call vp8_find_near_mvs() once for each macroblock

While doing motion search on a macroblock, we usually call
vp8_find_near_mvs once per reference frame. Actually, for
different reference frames, the only difference in calculating
these near_mvs is they may have different sign_bias, which
causes a sign change in resulting near_mvs. In this change, we
only do find_near_mvs for the first reference frame. For other
reference frames, only need to adjust the near_mvs according to
that reference frame's sign_bias value.

Change-Id: I661394b49c6ad79fed7d0f2eb2be239b9c56f149
parent c4aeff94
......@@ -432,23 +432,16 @@ void vp8_pick_inter_mode(VP8_COMP *cpi, MACROBLOCK *x, int recon_yoffset,
int saddone=0;
int sr=0; //search range got from mv_pred(). It uses step_param levels. (0-7)
int_mv nearest_mv[4];
int_mv near_mv[4];
int_mv frame_best_ref_mv[4];
int MDCounts[4][4];
unsigned char *y_buffer[4];
unsigned char *u_buffer[4];
unsigned char *v_buffer[4];
int i;
int ref_frame_map[4];
int found_near_mvs[4] = {0, 0, 0, 0};
int sign_bias = 0;
int have_subp_search = cpi->sf.half_pixel_search; /* In real-time mode, when Speed >= 15, no sub-pixel search. */
vpx_memset(mode_mv, 0, sizeof(mode_mv));
vpx_memset(nearest_mv, 0, sizeof(nearest_mv));
vpx_memset(near_mv, 0, sizeof(near_mv));
vpx_memset(&best_mbmode, 0, sizeof(best_mbmode));
/* Setup search priorities */
......@@ -463,6 +456,22 @@ void vp8_pick_inter_mode(VP8_COMP *cpi, MACROBLOCK *x, int recon_yoffset,
for(; i<4; i++)
ref_frame_map[i] = -1;
/* Check to see if there is at least 1 valid reference frame that we need
* to calculate near_mvs.
*/
if (ref_frame_map[1] > 0)
{
vp8_find_near_mvs(&x->e_mbd,
x->e_mbd.mode_info_context,
&mode_mv[NEARESTMV], &mode_mv[NEARMV],
&best_ref_mv,
mdcounts,
ref_frame_map[1],
cpi->common.ref_frame_sign_bias);
sign_bias = cpi->common.ref_frame_sign_bias[ref_frame_map[1]];
}
// set up all the refframe dependent pointers.
if (cpi->ref_frame_flags & VP8_LAST_FLAG)
{
......@@ -531,21 +540,6 @@ void vp8_pick_inter_mode(VP8_COMP *cpi, MACROBLOCK *x, int recon_yoffset,
}
}
// If nearby MVs haven't been found for this reference frame then do it now.
if (x->e_mbd.mode_info_context->mbmi.ref_frame != INTRA_FRAME &&
!found_near_mvs[x->e_mbd.mode_info_context->mbmi.ref_frame])
{
int ref_frame = x->e_mbd.mode_info_context->mbmi.ref_frame;
vp8_find_near_mvs(&x->e_mbd,
x->e_mbd.mode_info_context,
&nearest_mv[ref_frame], &near_mv[ref_frame],
&frame_best_ref_mv[ref_frame],
MDCounts[ref_frame],
ref_frame,
cpi->common.ref_frame_sign_bias);
found_near_mvs[ref_frame] = 1;
}
// We have now reached the point where we are going to test the current mode so increment the counter for the number of times it has been tested
cpi->mode_test_hit_counts[mode_index] ++;
......@@ -571,10 +565,19 @@ void vp8_pick_inter_mode(VP8_COMP *cpi, MACROBLOCK *x, int recon_yoffset,
x->e_mbd.pre.y_buffer = y_buffer[x->e_mbd.mode_info_context->mbmi.ref_frame];
x->e_mbd.pre.u_buffer = u_buffer[x->e_mbd.mode_info_context->mbmi.ref_frame];
x->e_mbd.pre.v_buffer = v_buffer[x->e_mbd.mode_info_context->mbmi.ref_frame];
mode_mv[NEARESTMV] = nearest_mv[x->e_mbd.mode_info_context->mbmi.ref_frame];
mode_mv[NEARMV] = near_mv[x->e_mbd.mode_info_context->mbmi.ref_frame];
best_ref_mv = frame_best_ref_mv[x->e_mbd.mode_info_context->mbmi.ref_frame];
memcpy(mdcounts, MDCounts[x->e_mbd.mode_info_context->mbmi.ref_frame], sizeof(mdcounts));
if (sign_bias !=
cpi->common.ref_frame_sign_bias[x->e_mbd.mode_info_context->mbmi.ref_frame])
{
mode_mv[NEARESTMV].as_mv.row *= -1;
mode_mv[NEARESTMV].as_mv.col *= -1;
mode_mv[NEARMV].as_mv.row *= -1;
mode_mv[NEARMV].as_mv.col *= -1;
best_ref_mv.as_mv.row *= -1;
best_ref_mv.as_mv.col *= -1;
sign_bias
= cpi->common.ref_frame_sign_bias[x->e_mbd.mode_info_context->mbmi.ref_frame];
}
}
// Only consider ZEROMV/ALTREF_FRAME for alt ref frame,
......@@ -910,7 +913,14 @@ void vp8_pick_inter_mode(VP8_COMP *cpi, MACROBLOCK *x, int recon_yoffset,
pick_intra_mbuv_mode(x);
}
update_mvcount(cpi, &x->e_mbd, &frame_best_ref_mv[xd->mode_info_context->mbmi.ref_frame]);
if (sign_bias
!= cpi->common.ref_frame_sign_bias[xd->mode_info_context->mbmi.ref_frame])
{
best_ref_mv.as_mv.row *= -1;
best_ref_mv.as_mv.col *= -1;
}
update_mvcount(cpi, &x->e_mbd, &best_ref_mv);
}
......
......@@ -1716,7 +1716,9 @@ static void rd_update_mvcount(VP8_COMP *cpi, MACROBLOCK *x, int_mv *best_ref_mv)
}
}
void vp8_rd_pick_inter_mode(VP8_COMP *cpi, MACROBLOCK *x, int recon_yoffset, int recon_uvoffset, int *returnrate, int *returndistortion, int *returnintra)
void vp8_rd_pick_inter_mode(VP8_COMP *cpi, MACROBLOCK *x, int recon_yoffset,
int recon_uvoffset, int *returnrate,
int *returndistortion, int *returnintra)
{
BLOCK *b = &x->block[0];
BLOCKD *d = &x->e_mbd.block[0];
......@@ -1743,27 +1745,20 @@ void vp8_rd_pick_inter_mode(VP8_COMP *cpi, MACROBLOCK *x, int recon_yoffset, int
int distortion_uv;
int best_yrd = INT_MAX;
//int all_rds[MAX_MODES]; // Experimental debug code.
//int all_rates[MAX_MODES];
//int all_dist[MAX_MODES];
//int intermodecost[MAX_MODES];
MB_PREDICTION_MODE uv_intra_mode;
int_mv mvp;
int near_sadidx[8] = {0, 1, 2, 3, 4, 5, 6, 7};
int saddone=0;
int sr=0; //search range got from mv_pred(). It uses step_param levels. (0-7)
int_mv frame_nearest_mv[4];
int_mv frame_near_mv[4];
int_mv frame_best_ref_mv[4];
int frame_mdcounts[4][4];
int frame_lf_or_gf[4];
unsigned char *y_buffer[4];
unsigned char *u_buffer[4];
unsigned char *v_buffer[4];
int ref_frame_map[4];
int sign_bias = 0;
vpx_memset(mode_mv, 0, sizeof(mode_mv));
vpx_memset(&best_mbmode, 0, sizeof(best_mbmode));
vpx_memset(&best_bmodes, 0, sizeof(best_bmodes));
......@@ -1779,17 +1774,29 @@ void vp8_rd_pick_inter_mode(VP8_COMP *cpi, MACROBLOCK *x, int recon_yoffset, int
for(; i<4; i++)
ref_frame_map[i] = -1;
/* Check to see if there is at least 1 valid reference frame that we need
* to calculate near_mvs.
*/
if (ref_frame_map[1] > 0)
{
vp8_find_near_mvs(&x->e_mbd,
x->e_mbd.mode_info_context,
&mode_mv[NEARESTMV], &mode_mv[NEARMV],
&best_ref_mv,
mdcounts,
ref_frame_map[1],
cpi->common.ref_frame_sign_bias);
sign_bias = cpi->common.ref_frame_sign_bias[ref_frame_map[1]];
}
if (cpi->ref_frame_flags & VP8_LAST_FLAG)
{
YV12_BUFFER_CONFIG *lst_yv12 = &cpi->common.yv12_fb[cpi->common.lst_fb_idx];
vp8_find_near_mvs(&x->e_mbd, x->e_mbd.mode_info_context, &frame_nearest_mv[LAST_FRAME], &frame_near_mv[LAST_FRAME],
&frame_best_ref_mv[LAST_FRAME], frame_mdcounts[LAST_FRAME], LAST_FRAME, cpi->common.ref_frame_sign_bias);
y_buffer[LAST_FRAME] = lst_yv12->y_buffer + recon_yoffset;
u_buffer[LAST_FRAME] = lst_yv12->u_buffer + recon_uvoffset;
v_buffer[LAST_FRAME] = lst_yv12->v_buffer + recon_uvoffset;
frame_lf_or_gf[LAST_FRAME] = 0;
}
......@@ -1797,13 +1804,9 @@ void vp8_rd_pick_inter_mode(VP8_COMP *cpi, MACROBLOCK *x, int recon_yoffset, int
{
YV12_BUFFER_CONFIG *gld_yv12 = &cpi->common.yv12_fb[cpi->common.gld_fb_idx];
vp8_find_near_mvs(&x->e_mbd, x->e_mbd.mode_info_context, &frame_nearest_mv[GOLDEN_FRAME], &frame_near_mv[GOLDEN_FRAME],
&frame_best_ref_mv[GOLDEN_FRAME], frame_mdcounts[GOLDEN_FRAME], GOLDEN_FRAME, cpi->common.ref_frame_sign_bias);
y_buffer[GOLDEN_FRAME] = gld_yv12->y_buffer + recon_yoffset;
u_buffer[GOLDEN_FRAME] = gld_yv12->u_buffer + recon_uvoffset;
v_buffer[GOLDEN_FRAME] = gld_yv12->v_buffer + recon_uvoffset;
frame_lf_or_gf[GOLDEN_FRAME] = 1;
}
......@@ -1811,13 +1814,9 @@ void vp8_rd_pick_inter_mode(VP8_COMP *cpi, MACROBLOCK *x, int recon_yoffset, int
{
YV12_BUFFER_CONFIG *alt_yv12 = &cpi->common.yv12_fb[cpi->common.alt_fb_idx];
vp8_find_near_mvs(&x->e_mbd, x->e_mbd.mode_info_context, &frame_nearest_mv[ALTREF_FRAME], &frame_near_mv[ALTREF_FRAME],
&frame_best_ref_mv[ALTREF_FRAME], frame_mdcounts[ALTREF_FRAME], ALTREF_FRAME, cpi->common.ref_frame_sign_bias);
y_buffer[ALTREF_FRAME] = alt_yv12->y_buffer + recon_yoffset;
u_buffer[ALTREF_FRAME] = alt_yv12->u_buffer + recon_uvoffset;
v_buffer[ALTREF_FRAME] = alt_yv12->v_buffer + recon_uvoffset;
frame_lf_or_gf[ALTREF_FRAME] = 1;
}
......@@ -1826,8 +1825,6 @@ void vp8_rd_pick_inter_mode(VP8_COMP *cpi, MACROBLOCK *x, int recon_yoffset, int
x->skip = 0;
vpx_memset(mode_mv, 0, sizeof(mode_mv));
x->e_mbd.mode_info_context->mbmi.ref_frame = INTRA_FRAME;
rd_pick_intra_mbuv_mode(cpi, x, &uv_intra_rate, &uv_intra_rate_tokenonly, &uv_intra_distortion);
uv_intra_mode = x->e_mbd.mode_info_context->mbmi.uv_mode;
......@@ -1840,13 +1837,6 @@ void vp8_rd_pick_inter_mode(VP8_COMP *cpi, MACROBLOCK *x, int recon_yoffset, int
int other_cost = 0;
int this_ref_frame = ref_frame_map[vp8_ref_frame_order[mode_index]];
// Experimental debug code.
// Record of rd values recorded for this MB. -1 indicates not measured
//all_rds[mode_index] = -1;
//all_rates[mode_index] = -1;
//all_dist[mode_index] = -1;
//intermodecost[mode_index] = -1;
// Test best rd so far against threshold for trying this mode.
if (best_rd <= cpi->rd_threshes[mode_index])
continue;
......@@ -1879,10 +1869,20 @@ void vp8_rd_pick_inter_mode(VP8_COMP *cpi, MACROBLOCK *x, int recon_yoffset, int
x->e_mbd.pre.y_buffer = y_buffer[x->e_mbd.mode_info_context->mbmi.ref_frame];
x->e_mbd.pre.u_buffer = u_buffer[x->e_mbd.mode_info_context->mbmi.ref_frame];
x->e_mbd.pre.v_buffer = v_buffer[x->e_mbd.mode_info_context->mbmi.ref_frame];
mode_mv[NEARESTMV] = frame_nearest_mv[x->e_mbd.mode_info_context->mbmi.ref_frame];
mode_mv[NEARMV] = frame_near_mv[x->e_mbd.mode_info_context->mbmi.ref_frame];
best_ref_mv = frame_best_ref_mv[x->e_mbd.mode_info_context->mbmi.ref_frame];
vpx_memcpy(mdcounts, frame_mdcounts[x->e_mbd.mode_info_context->mbmi.ref_frame], sizeof(mdcounts));
if (sign_bias !=
cpi->common.ref_frame_sign_bias[x->e_mbd.mode_info_context->mbmi.ref_frame])
{
mode_mv[NEARESTMV].as_mv.row *= -1;
mode_mv[NEARESTMV].as_mv.col *= -1;
mode_mv[NEARMV].as_mv.row *= -1;
mode_mv[NEARMV].as_mv.col *= -1;
best_ref_mv.as_mv.row *= -1;
best_ref_mv.as_mv.col *= -1;
sign_bias
= cpi->common.ref_frame_sign_bias[x->e_mbd.mode_info_context->mbmi.ref_frame];
}
lf_or_gf = frame_lf_or_gf[x->e_mbd.mode_info_context->mbmi.ref_frame];
}
......@@ -2286,11 +2286,6 @@ void vp8_rd_pick_inter_mode(VP8_COMP *cpi, MACROBLOCK *x, int recon_yoffset, int
this_rd = RDCOST(x->rdmult, x->rddiv, rate2, distortion2);
}
// Experimental debug code.
//all_rds[mode_index] = this_rd;
//all_rates[mode_index] = rate2;
//all_dist[mode_index] = distortion2;
// Keep record of best intra distortion
if ((x->e_mbd.mode_info_context->mbmi.ref_frame == INTRA_FRAME) &&
(this_rd < best_intra_rd) )
......@@ -2418,10 +2413,14 @@ void vp8_rd_pick_inter_mode(VP8_COMP *cpi, MACROBLOCK *x, int recon_yoffset, int
x->partition_info->bmi[15].mv.as_int;
}
rd_update_mvcount(cpi, x, &frame_best_ref_mv[xd->mode_info_context->mbmi.ref_frame]);
if (sign_bias
!= cpi->common.ref_frame_sign_bias[xd->mode_info_context->mbmi.ref_frame])
{
best_ref_mv.as_mv.row *= -1;
best_ref_mv.as_mv.col *= -1;
}
rd_update_mvcount(cpi, x, &best_ref_mv);
}
void vp8_rd_pick_intra_mode(VP8_COMP *cpi, MACROBLOCK *x, int *rate_)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment