Correct clamping in use of vp8_find_near_mvs()

Commit e06c242ba introduced a change to call vp8_find_near_mvs() only
once instead of once per reference frame by observing that the only
effect that the frame had was on the bias applied to the motion
vector. By keeping track of the sign_bias value, the mv to use could
be flip-flopped by multiplying its components by -1.

This behavior was subtley wrong in the case when clamping was applied
to the motion vectors found by vp8_find_near_mvs(). A motion vector
could be in-bounds with one sign bias, but out of bounds after
inverting the sign, or vice versa. The clamping must match that done
by the decoder.

This change modifies vp8_find_near_mvs() to remove the clamping from
that function. The vp8_pick_inter_mode() and vp8_rd_pick_inter_mode()
functions instead track the correctly clamped values for both bias
values, switching between them by simple assignment. The common
clamping and inversion code is in vp8_find_near_mvs_bias()

Change-Id: I17e1a348d1643497eca0be232e2fbe2acf8478e1
This commit is contained in:
John Koleszar 2012-01-25 14:55:49 -08:00
parent 630d3b95e2
commit 83cef816fd
5 changed files with 98 additions and 53 deletions

View File

@ -134,13 +134,51 @@ void vp8_find_near_mvs
best_mv->as_int = near_mvs[0].as_int;
nearest->as_int = near_mvs[CNT_NEAREST].as_int;
nearby->as_int = near_mvs[CNT_NEAR].as_int;
//TODO: move clamp outside findnearmv
vp8_clamp_mv2(nearest, xd);
vp8_clamp_mv2(nearby, xd);
vp8_clamp_mv2(best_mv, xd);
}
static void invert_and_clamp_mvs(int_mv *inv, int_mv *src, MACROBLOCKD *xd)
{
inv->as_mv.row = src->as_mv.row * -1;
inv->as_mv.col = src->as_mv.col * -1;
vp8_clamp_mv2(inv, xd);
vp8_clamp_mv2(src, xd);
}
int vp8_find_near_mvs_bias
(
MACROBLOCKD *xd,
const MODE_INFO *here,
int_mv mode_mv_sb[2][MB_MODE_COUNT],
int_mv best_mv_sb[2],
int cnt[4],
int refframe,
int *ref_frame_sign_bias
)
{
int sign_bias = ref_frame_sign_bias[refframe];
vp8_find_near_mvs(xd,
here,
&mode_mv_sb[sign_bias][NEARESTMV],
&mode_mv_sb[sign_bias][NEARMV],
&best_mv_sb[sign_bias],
cnt,
refframe,
ref_frame_sign_bias);
invert_and_clamp_mvs(&mode_mv_sb[!sign_bias][NEARESTMV],
&mode_mv_sb[sign_bias][NEARESTMV], xd);
invert_and_clamp_mvs(&mode_mv_sb[!sign_bias][NEARMV],
&mode_mv_sb[sign_bias][NEARMV], xd);
invert_and_clamp_mvs(&best_mv_sb[!sign_bias],
&best_mv_sb[sign_bias], xd);
return sign_bias;
}
vp8_prob *vp8_mv_ref_probs(
vp8_prob p[VP8_MVREFS-1], const int near_mv_ref_ct[4]
)

View File

@ -77,6 +77,19 @@ void vp8_find_near_mvs
int *ref_frame_sign_bias
);
int vp8_find_near_mvs_bias
(
MACROBLOCKD *xd,
const MODE_INFO *here,
int_mv mode_mv_sb[2][MB_MODE_COUNT],
int_mv best_mv_sb[2],
int cnt[4],
int refframe,
int *ref_frame_sign_bias
);
vp8_prob *vp8_mv_ref_probs(
vp8_prob p[VP8_MVREFS-1], const int near_mv_ref_ct[4]
);

View File

@ -1013,6 +1013,8 @@ static void pack_inter_mode_mvs(VP8_COMP *const cpi)
int ct[4];
vp8_find_near_mvs(xd, m, &n1, &n2, &best_mv, ct, rf, cpi->common.ref_frame_sign_bias);
vp8_clamp_mv2(&best_mv, xd);
vp8_mv_ref_probs(mv_ref_p, ct);
#ifdef ENTROPY_STATS

View File

@ -469,8 +469,10 @@ void vp8_pick_inter_mode(VP8_COMP *cpi, MACROBLOCK *x, int recon_yoffset,
MACROBLOCKD *xd = &x->e_mbd;
MB_MODE_INFO best_mbmode;
int_mv best_ref_mv_sb[2];
int_mv mode_mv_sb[2][MB_MODE_COUNT];
int_mv best_ref_mv;
int_mv mode_mv[MB_MODE_COUNT];
int_mv *mode_mv;
MB_PREDICTION_MODE this_mode;
int num00;
int mdcounts[4];
@ -508,7 +510,9 @@ void vp8_pick_inter_mode(VP8_COMP *cpi, MACROBLOCK *x, int recon_yoffset,
&parent_mode, &parent_ref_mv, mb_row, mb_col);
#endif
vpx_memset(mode_mv, 0, sizeof(mode_mv));
mode_mv = mode_mv_sb[sign_bias];
best_ref_mv.as_int = 0;
vpx_memset(mode_mv_sb, 0, sizeof(mode_mv_sb));
vpx_memset(&best_mbmode, 0, sizeof(best_mbmode));
/* Setup search priorities */
@ -519,15 +523,16 @@ void vp8_pick_inter_mode(VP8_COMP *cpi, MACROBLOCK *x, int recon_yoffset,
*/
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 = vp8_find_near_mvs_bias(&x->e_mbd,
x->e_mbd.mode_info_context,
mode_mv_sb,
best_ref_mv_sb,
mdcounts,
ref_frame_map[1],
cpi->common.ref_frame_sign_bias);
sign_bias = cpi->common.ref_frame_sign_bias[ref_frame_map[1]];
mode_mv = mode_mv_sb[sign_bias];
best_ref_mv.as_int = best_ref_mv_sb[sign_bias].as_int;
}
get_predictor_pointers(cpi, plane, recon_yoffset, recon_uvoffset);
@ -578,17 +583,11 @@ void vp8_pick_inter_mode(VP8_COMP *cpi, MACROBLOCK *x, int recon_yoffset,
x->e_mbd.pre.u_buffer = plane[this_ref_frame][1];
x->e_mbd.pre.v_buffer = plane[this_ref_frame][2];
if (sign_bias !=
cpi->common.ref_frame_sign_bias[x->e_mbd.mode_info_context->mbmi.ref_frame])
if (sign_bias != cpi->common.ref_frame_sign_bias[this_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];
sign_bias = cpi->common.ref_frame_sign_bias[this_ref_frame];
mode_mv = mode_mv_sb[sign_bias];
best_ref_mv.as_int = best_ref_mv_sb[sign_bias].as_int;
}
#if CONFIG_MULTI_RES_ENCODING
@ -1049,10 +1048,7 @@ void vp8_pick_inter_mode(VP8_COMP *cpi, MACROBLOCK *x, int recon_yoffset,
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;
}
best_ref_mv.as_int = best_ref_mv_sb[!sign_bias].as_int;
update_mvcount(cpi, &x->e_mbd, &best_ref_mv);
}

View File

@ -1726,8 +1726,10 @@ void vp8_rd_pick_inter_mode(VP8_COMP *cpi, MACROBLOCK *x, int recon_yoffset,
union b_mode_info best_bmodes[16];
MB_MODE_INFO best_mbmode;
PARTITION_INFO best_partition;
int_mv best_ref_mv_sb[2];
int_mv mode_mv_sb[2][MB_MODE_COUNT];
int_mv best_ref_mv;
int_mv mode_mv[MB_MODE_COUNT];
int_mv *mode_mv;
MB_PREDICTION_MODE this_mode;
int num00;
int best_mode_index = 0;
@ -1755,7 +1757,9 @@ void vp8_rd_pick_inter_mode(VP8_COMP *cpi, MACROBLOCK *x, int recon_yoffset,
int ref_frame_map[4];
int sign_bias = 0;
vpx_memset(mode_mv, 0, sizeof(mode_mv));
mode_mv = mode_mv_sb[sign_bias];
best_ref_mv.as_int = 0;
vpx_memset(mode_mv_sb, 0, sizeof(mode_mv_sb));
vpx_memset(&best_mbmode, 0, sizeof(best_mbmode));
vpx_memset(&best_bmodes, 0, sizeof(best_bmodes));
@ -1767,15 +1771,16 @@ void vp8_rd_pick_inter_mode(VP8_COMP *cpi, MACROBLOCK *x, int recon_yoffset,
*/
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 = vp8_find_near_mvs_bias(&x->e_mbd,
x->e_mbd.mode_info_context,
mode_mv_sb,
best_ref_mv_sb,
mdcounts,
ref_frame_map[1],
cpi->common.ref_frame_sign_bias);
sign_bias = cpi->common.ref_frame_sign_bias[ref_frame_map[1]];
mode_mv = mode_mv_sb[sign_bias];
best_ref_mv.as_int = best_ref_mv_sb[sign_bias].as_int;
}
get_predictor_pointers(cpi, plane, recon_yoffset, recon_uvoffset);
@ -1829,17 +1834,11 @@ void vp8_rd_pick_inter_mode(VP8_COMP *cpi, MACROBLOCK *x, int recon_yoffset,
x->e_mbd.pre.u_buffer = plane[this_ref_frame][1];
x->e_mbd.pre.v_buffer = plane[this_ref_frame][2];
if (sign_bias !=
cpi->common.ref_frame_sign_bias[x->e_mbd.mode_info_context->mbmi.ref_frame])
if (sign_bias != cpi->common.ref_frame_sign_bias[this_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];
sign_bias = cpi->common.ref_frame_sign_bias[this_ref_frame];
mode_mv = mode_mv_sb[sign_bias];
best_ref_mv.as_int = best_ref_mv_sb[sign_bias].as_int;
}
}
@ -2372,10 +2371,7 @@ void vp8_rd_pick_inter_mode(VP8_COMP *cpi, MACROBLOCK *x, int recon_yoffset,
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;
}
best_ref_mv.as_int = best_ref_mv_sb[!sign_bias].as_int;
rd_update_mvcount(cpi, x, &best_ref_mv);
}