Merge "Fix for out of range motion vector bug in sub-pel motion estimation"
This commit is contained in:
commit
41fac44707
@ -49,6 +49,9 @@ static unsigned int do_16x16_motion_iteration(VP9_COMP *cpi, const MV *ref_mv,
|
|||||||
cond_cost_list(cpi, cost_list), ref_mv, dst_mv, 0, 0);
|
cond_cost_list(cpi, cost_list), ref_mv, dst_mv, 0, 0);
|
||||||
mv_sf->search_method = old_search_method;
|
mv_sf->search_method = old_search_method;
|
||||||
|
|
||||||
|
/* restore UMV window */
|
||||||
|
x->mv_limits = tmp_mv_limits;
|
||||||
|
|
||||||
// Try sub-pixel MC
|
// Try sub-pixel MC
|
||||||
// if (bestsme > error_thresh && bestsme < INT_MAX)
|
// if (bestsme > error_thresh && bestsme < INT_MAX)
|
||||||
{
|
{
|
||||||
@ -66,9 +69,6 @@ static unsigned int do_16x16_motion_iteration(VP9_COMP *cpi, const MV *ref_mv,
|
|||||||
|
|
||||||
vp9_build_inter_predictors_sby(xd, mb_row, mb_col, BLOCK_16X16);
|
vp9_build_inter_predictors_sby(xd, mb_row, mb_col, BLOCK_16X16);
|
||||||
|
|
||||||
/* restore UMV window */
|
|
||||||
x->mv_limits = tmp_mv_limits;
|
|
||||||
|
|
||||||
return vpx_sad16x16(x->plane[0].src.buf, x->plane[0].src.stride,
|
return vpx_sad16x16(x->plane[0].src.buf, x->plane[0].src.stride,
|
||||||
xd->plane[0].dst.buf, xd->plane[0].dst.stride);
|
xd->plane[0].dst.buf, xd->plane[0].dst.stride);
|
||||||
}
|
}
|
||||||
|
@ -52,6 +52,24 @@ void vp9_set_mv_search_range(MvLimits *mv_limits, const MV *mv) {
|
|||||||
if (mv_limits->row_max > row_max) mv_limits->row_max = row_max;
|
if (mv_limits->row_max > row_max) mv_limits->row_max = row_max;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void vp9_set_subpel_mv_search_range(MvLimits *subpel_mv_limits,
|
||||||
|
const MvLimits *umv_window_limits,
|
||||||
|
const MV *ref_mv) {
|
||||||
|
subpel_mv_limits->col_min = VPXMAX(umv_window_limits->col_min * 8,
|
||||||
|
ref_mv->col - MAX_FULL_PEL_VAL * 8);
|
||||||
|
subpel_mv_limits->col_max = VPXMIN(umv_window_limits->col_max * 8,
|
||||||
|
ref_mv->col + MAX_FULL_PEL_VAL * 8);
|
||||||
|
subpel_mv_limits->row_min = VPXMAX(umv_window_limits->row_min * 8,
|
||||||
|
ref_mv->row - MAX_FULL_PEL_VAL * 8);
|
||||||
|
subpel_mv_limits->row_max = VPXMIN(umv_window_limits->row_max * 8,
|
||||||
|
ref_mv->row + MAX_FULL_PEL_VAL * 8);
|
||||||
|
|
||||||
|
subpel_mv_limits->col_min = VPXMAX(MV_LOW + 1, subpel_mv_limits->col_min);
|
||||||
|
subpel_mv_limits->col_max = VPXMIN(MV_UPP - 1, subpel_mv_limits->col_max);
|
||||||
|
subpel_mv_limits->row_min = VPXMAX(MV_LOW + 1, subpel_mv_limits->row_min);
|
||||||
|
subpel_mv_limits->row_max = VPXMIN(MV_UPP - 1, subpel_mv_limits->row_max);
|
||||||
|
}
|
||||||
|
|
||||||
int vp9_init_search_range(int size) {
|
int vp9_init_search_range(int size) {
|
||||||
int sr = 0;
|
int sr = 0;
|
||||||
// Minimum search size no matter what the passed in value.
|
// Minimum search size no matter what the passed in value.
|
||||||
@ -267,34 +285,38 @@ static INLINE const uint8_t *pre(const uint8_t *buf, int stride, int r, int c) {
|
|||||||
} \
|
} \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define SETUP_SUBPEL_SEARCH \
|
#define SETUP_SUBPEL_SEARCH \
|
||||||
const uint8_t *const z = x->plane[0].src.buf; \
|
const uint8_t *const z = x->plane[0].src.buf; \
|
||||||
const int src_stride = x->plane[0].src.stride; \
|
const int src_stride = x->plane[0].src.stride; \
|
||||||
const MACROBLOCKD *xd = &x->e_mbd; \
|
const MACROBLOCKD *xd = &x->e_mbd; \
|
||||||
unsigned int besterr = UINT_MAX; \
|
unsigned int besterr = UINT_MAX; \
|
||||||
unsigned int sse; \
|
unsigned int sse; \
|
||||||
unsigned int whichdir; \
|
unsigned int whichdir; \
|
||||||
int thismse; \
|
int thismse; \
|
||||||
const unsigned int halfiters = iters_per_step; \
|
const unsigned int halfiters = iters_per_step; \
|
||||||
const unsigned int quarteriters = iters_per_step; \
|
const unsigned int quarteriters = iters_per_step; \
|
||||||
const unsigned int eighthiters = iters_per_step; \
|
const unsigned int eighthiters = iters_per_step; \
|
||||||
const int y_stride = xd->plane[0].pre[0].stride; \
|
const int y_stride = xd->plane[0].pre[0].stride; \
|
||||||
const int offset = bestmv->row * y_stride + bestmv->col; \
|
const int offset = bestmv->row * y_stride + bestmv->col; \
|
||||||
const uint8_t *const y = xd->plane[0].pre[0].buf; \
|
const uint8_t *const y = xd->plane[0].pre[0].buf; \
|
||||||
\
|
\
|
||||||
int rr = ref_mv->row; \
|
int rr = ref_mv->row; \
|
||||||
int rc = ref_mv->col; \
|
int rc = ref_mv->col; \
|
||||||
int br = bestmv->row * 8; \
|
int br = bestmv->row * 8; \
|
||||||
int bc = bestmv->col * 8; \
|
int bc = bestmv->col * 8; \
|
||||||
int hstep = 4; \
|
int hstep = 4; \
|
||||||
const int minc = VPXMAX(x->mv_limits.col_min * 8, ref_mv->col - MV_MAX); \
|
int minc, maxc, minr, maxr; \
|
||||||
const int maxc = VPXMIN(x->mv_limits.col_max * 8, ref_mv->col + MV_MAX); \
|
int tr = br; \
|
||||||
const int minr = VPXMAX(x->mv_limits.row_min * 8, ref_mv->row - MV_MAX); \
|
int tc = bc; \
|
||||||
const int maxr = VPXMIN(x->mv_limits.row_max * 8, ref_mv->row + MV_MAX); \
|
MvLimits subpel_mv_limits; \
|
||||||
int tr = br; \
|
\
|
||||||
int tc = bc; \
|
vp9_set_subpel_mv_search_range(&subpel_mv_limits, &x->mv_limits, ref_mv); \
|
||||||
\
|
minc = subpel_mv_limits.col_min; \
|
||||||
bestmv->row *= 8; \
|
maxc = subpel_mv_limits.col_max; \
|
||||||
|
minr = subpel_mv_limits.row_min; \
|
||||||
|
maxr = subpel_mv_limits.row_max; \
|
||||||
|
\
|
||||||
|
bestmv->row *= 8; \
|
||||||
bestmv->col *= 8;
|
bestmv->col *= 8;
|
||||||
|
|
||||||
static unsigned int setup_center_error(
|
static unsigned int setup_center_error(
|
||||||
@ -395,10 +417,6 @@ uint32_t vp9_skip_sub_pixel_tree(const MACROBLOCK *x, MV *bestmv,
|
|||||||
(void)thismse;
|
(void)thismse;
|
||||||
(void)cost_list;
|
(void)cost_list;
|
||||||
|
|
||||||
if ((abs(bestmv->col - ref_mv->col) > (MAX_FULL_PEL_VAL << 3)) ||
|
|
||||||
(abs(bestmv->row - ref_mv->row) > (MAX_FULL_PEL_VAL << 3)))
|
|
||||||
return UINT_MAX;
|
|
||||||
|
|
||||||
return besterr;
|
return besterr;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -464,10 +482,6 @@ uint32_t vp9_find_best_sub_pixel_tree_pruned_evenmore(
|
|||||||
bestmv->row = br;
|
bestmv->row = br;
|
||||||
bestmv->col = bc;
|
bestmv->col = bc;
|
||||||
|
|
||||||
if ((abs(bestmv->col - ref_mv->col) > (MAX_FULL_PEL_VAL << 3)) ||
|
|
||||||
(abs(bestmv->row - ref_mv->row) > (MAX_FULL_PEL_VAL << 3)))
|
|
||||||
return UINT_MAX;
|
|
||||||
|
|
||||||
return besterr;
|
return besterr;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -528,10 +542,6 @@ uint32_t vp9_find_best_sub_pixel_tree_pruned_more(
|
|||||||
bestmv->row = br;
|
bestmv->row = br;
|
||||||
bestmv->col = bc;
|
bestmv->col = bc;
|
||||||
|
|
||||||
if ((abs(bestmv->col - ref_mv->col) > (MAX_FULL_PEL_VAL << 3)) ||
|
|
||||||
(abs(bestmv->row - ref_mv->row) > (MAX_FULL_PEL_VAL << 3)))
|
|
||||||
return UINT_MAX;
|
|
||||||
|
|
||||||
return besterr;
|
return besterr;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -614,10 +624,6 @@ uint32_t vp9_find_best_sub_pixel_tree_pruned(
|
|||||||
bestmv->row = br;
|
bestmv->row = br;
|
||||||
bestmv->col = bc;
|
bestmv->col = bc;
|
||||||
|
|
||||||
if ((abs(bestmv->col - ref_mv->col) > (MAX_FULL_PEL_VAL << 3)) ||
|
|
||||||
(abs(bestmv->row - ref_mv->row) > (MAX_FULL_PEL_VAL << 3)))
|
|
||||||
return UINT_MAX;
|
|
||||||
|
|
||||||
return besterr;
|
return besterr;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -653,16 +659,21 @@ uint32_t vp9_find_best_sub_pixel_tree(
|
|||||||
int bc = bestmv->col * 8;
|
int bc = bestmv->col * 8;
|
||||||
int hstep = 4;
|
int hstep = 4;
|
||||||
int iter, round = 3 - forced_stop;
|
int iter, round = 3 - forced_stop;
|
||||||
const int minc = VPXMAX(x->mv_limits.col_min * 8, ref_mv->col - MV_MAX);
|
|
||||||
const int maxc = VPXMIN(x->mv_limits.col_max * 8, ref_mv->col + MV_MAX);
|
int minc, maxc, minr, maxr;
|
||||||
const int minr = VPXMAX(x->mv_limits.row_min * 8, ref_mv->row - MV_MAX);
|
|
||||||
const int maxr = VPXMIN(x->mv_limits.row_max * 8, ref_mv->row + MV_MAX);
|
|
||||||
int tr = br;
|
int tr = br;
|
||||||
int tc = bc;
|
int tc = bc;
|
||||||
const MV *search_step = search_step_table;
|
const MV *search_step = search_step_table;
|
||||||
int idx, best_idx = -1;
|
int idx, best_idx = -1;
|
||||||
unsigned int cost_array[5];
|
unsigned int cost_array[5];
|
||||||
int kr, kc;
|
int kr, kc;
|
||||||
|
MvLimits subpel_mv_limits;
|
||||||
|
|
||||||
|
vp9_set_subpel_mv_search_range(&subpel_mv_limits, &x->mv_limits, ref_mv);
|
||||||
|
minc = subpel_mv_limits.col_min;
|
||||||
|
maxc = subpel_mv_limits.col_max;
|
||||||
|
minr = subpel_mv_limits.row_min;
|
||||||
|
maxr = subpel_mv_limits.row_max;
|
||||||
|
|
||||||
if (!(allow_hp && use_mv_hp(ref_mv)))
|
if (!(allow_hp && use_mv_hp(ref_mv)))
|
||||||
if (round == 3) round = 2;
|
if (round == 3) round = 2;
|
||||||
@ -763,10 +774,6 @@ uint32_t vp9_find_best_sub_pixel_tree(
|
|||||||
bestmv->row = br;
|
bestmv->row = br;
|
||||||
bestmv->col = bc;
|
bestmv->col = bc;
|
||||||
|
|
||||||
if ((abs(bestmv->col - ref_mv->col) > (MAX_FULL_PEL_VAL << 3)) ||
|
|
||||||
(abs(bestmv->row - ref_mv->row) > (MAX_FULL_PEL_VAL << 3)))
|
|
||||||
return UINT_MAX;
|
|
||||||
|
|
||||||
return besterr;
|
return besterr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -109,6 +109,10 @@ int vp9_full_pixel_search(struct VP9_COMP *cpi, MACROBLOCK *x, BLOCK_SIZE bsize,
|
|||||||
int error_per_bit, int *cost_list, const MV *ref_mv,
|
int error_per_bit, int *cost_list, const MV *ref_mv,
|
||||||
MV *tmp_mv, int var_max, int rd);
|
MV *tmp_mv, int var_max, int rd);
|
||||||
|
|
||||||
|
void vp9_set_subpel_mv_search_range(MvLimits *subpel_mv_limits,
|
||||||
|
const MvLimits *umv_window_limits,
|
||||||
|
const MV *ref_mv);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
} // extern "C"
|
} // extern "C"
|
||||||
#endif
|
#endif
|
||||||
|
@ -2369,7 +2369,7 @@ void vp9_pick_inter_mode_sub8x8(VP9_COMP *cpi, MACROBLOCK *x, int mi_row,
|
|||||||
}
|
}
|
||||||
|
|
||||||
vp9_set_mv_search_range(&x->mv_limits,
|
vp9_set_mv_search_range(&x->mv_limits,
|
||||||
&mbmi_ext->ref_mvs[0]->as_mv);
|
&mbmi_ext->ref_mvs[ref_frame][0].as_mv);
|
||||||
|
|
||||||
vp9_full_pixel_search(
|
vp9_full_pixel_search(
|
||||||
cpi, x, bsize, &mvp_full, step_param, cpi->sf.mv.search_method,
|
cpi, x, bsize, &mvp_full, step_param, cpi->sf.mv.search_method,
|
||||||
|
@ -226,6 +226,7 @@ static uint32_t temporal_filter_find_matching_mb_c(VP9_COMP *cpi,
|
|||||||
uint32_t distortion;
|
uint32_t distortion;
|
||||||
uint32_t sse;
|
uint32_t sse;
|
||||||
int cost_list[5];
|
int cost_list[5];
|
||||||
|
const MvLimits tmp_mv_limits = x->mv_limits;
|
||||||
|
|
||||||
MV best_ref_mv1 = { 0, 0 };
|
MV best_ref_mv1 = { 0, 0 };
|
||||||
MV best_ref_mv1_full; /* full-pixel value of best_ref_mv1 */
|
MV best_ref_mv1_full; /* full-pixel value of best_ref_mv1 */
|
||||||
@ -246,10 +247,15 @@ static uint32_t temporal_filter_find_matching_mb_c(VP9_COMP *cpi,
|
|||||||
step_param = mv_sf->reduce_first_step_size;
|
step_param = mv_sf->reduce_first_step_size;
|
||||||
step_param = VPXMIN(step_param, MAX_MVSEARCH_STEPS - 2);
|
step_param = VPXMIN(step_param, MAX_MVSEARCH_STEPS - 2);
|
||||||
|
|
||||||
|
vp9_set_mv_search_range(&x->mv_limits, &best_ref_mv1);
|
||||||
|
|
||||||
vp9_full_pixel_search(cpi, x, BLOCK_16X16, &best_ref_mv1_full, step_param,
|
vp9_full_pixel_search(cpi, x, BLOCK_16X16, &best_ref_mv1_full, step_param,
|
||||||
search_method, sadpb, cond_cost_list(cpi, cost_list),
|
search_method, sadpb, cond_cost_list(cpi, cost_list),
|
||||||
&best_ref_mv1, ref_mv, 0, 0);
|
&best_ref_mv1, ref_mv, 0, 0);
|
||||||
|
|
||||||
|
/* restore UMV window */
|
||||||
|
x->mv_limits = tmp_mv_limits;
|
||||||
|
|
||||||
// Ignore mv costing by sending NULL pointer instead of cost array
|
// Ignore mv costing by sending NULL pointer instead of cost array
|
||||||
bestsme = cpi->find_fractional_mv_step(
|
bestsme = cpi->find_fractional_mv_step(
|
||||||
x, ref_mv, &best_ref_mv1, cpi->common.allow_high_precision_mv,
|
x, ref_mv, &best_ref_mv1, cpi->common.allow_high_precision_mv,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user