Commit 6554333b authored by Alex Converse's avatar Alex Converse

Refactor mv limits.

Change-Id: Ifebdc9ef37850508eb4b8e572fd0f6026ab04987
parent 6a8d4631
......@@ -52,6 +52,13 @@ typedef struct {
uint8_t mode_context[MAX_REF_FRAMES];
} MB_MODE_INFO_EXT;
typedef struct {
int col_min;
int col_max;
int row_min;
int row_max;
} MvLimits;
typedef struct macroblock MACROBLOCK;
struct macroblock {
struct macroblock_plane plane[MAX_MB_PLANE];
......@@ -103,10 +110,7 @@ struct macroblock {
// These define limits to motion vector components to prevent them
// from extending outside the UMV borders
int mv_col_min;
int mv_col_max;
int mv_row_min;
int mv_row_max;
MvLimits mv_limits;
// Notes transform blocks where no coefficents are coded.
// Set during mode selection. Read during block encoding.
......
......@@ -184,6 +184,7 @@ static void set_offsets(VP9_COMP *cpi, const TileInfo *const tile,
const int mi_width = num_8x8_blocks_wide_lookup[bsize];
const int mi_height = num_8x8_blocks_high_lookup[bsize];
const struct segmentation *const seg = &cm->seg;
MvLimits *const mv_limits = &x->mv_limits;
set_skip_context(xd, mi_row, mi_col);
......@@ -196,10 +197,10 @@ static void set_offsets(VP9_COMP *cpi, const TileInfo *const tile,
// Set up limit values for MV components.
// Mv beyond the range do not produce new/different prediction block.
x->mv_row_min = -(((mi_row + mi_height) * MI_SIZE) + VP9_INTERP_EXTEND);
x->mv_col_min = -(((mi_col + mi_width) * MI_SIZE) + VP9_INTERP_EXTEND);
x->mv_row_max = (cm->mi_rows - mi_row) * MI_SIZE + VP9_INTERP_EXTEND;
x->mv_col_max = (cm->mi_cols - mi_col) * MI_SIZE + VP9_INTERP_EXTEND;
mv_limits->row_min = -(((mi_row + mi_height) * MI_SIZE) + VP9_INTERP_EXTEND);
mv_limits->col_min = -(((mi_col + mi_width) * MI_SIZE) + VP9_INTERP_EXTEND);
mv_limits->row_max = (cm->mi_rows - mi_row) * MI_SIZE + VP9_INTERP_EXTEND;
mv_limits->col_max = (cm->mi_cols - mi_col) * MI_SIZE + VP9_INTERP_EXTEND;
// Set up distance of MB to edge of frame in 1/8th pel units.
assert(!(mi_col & (mi_width - 1)) && !(mi_row & (mi_height - 1)));
......
......@@ -805,8 +805,9 @@ void vp9_first_pass(VP9_COMP *cpi, const struct lookahead_entry *source) {
// Set up limit values for motion vectors to prevent them extending
// outside the UMV borders.
x->mv_row_min = -((mb_row * 16) + BORDER_MV_PIXELS_B16);
x->mv_row_max = ((cm->mb_rows - 1 - mb_row) * 16) + BORDER_MV_PIXELS_B16;
x->mv_limits.row_min = -((mb_row * 16) + BORDER_MV_PIXELS_B16);
x->mv_limits.row_max =
((cm->mb_rows - 1 - mb_row) * 16) + BORDER_MV_PIXELS_B16;
for (mb_col = 0; mb_col < cm->mb_cols; ++mb_col) {
int this_error;
......@@ -929,8 +930,9 @@ void vp9_first_pass(VP9_COMP *cpi, const struct lookahead_entry *source) {
// Set up limit values for motion vectors to prevent them extending
// outside the UMV borders.
x->mv_col_min = -((mb_col * 16) + BORDER_MV_PIXELS_B16);
x->mv_col_max = ((cm->mb_cols - 1 - mb_col) * 16) + BORDER_MV_PIXELS_B16;
x->mv_limits.col_min = -((mb_col * 16) + BORDER_MV_PIXELS_B16);
x->mv_limits.col_max =
((cm->mb_cols - 1 - mb_col) * 16) + BORDER_MV_PIXELS_B16;
// Other than for the first frame do a motion search.
if ((lc == NULL && cm->current_video_frame > 0) ||
......
......@@ -30,11 +30,7 @@ static unsigned int do_16x16_motion_iteration(VP9_COMP *cpi, const MV *ref_mv,
MV_SPEED_FEATURES *const mv_sf = &cpi->sf.mv;
const SEARCH_METHODS old_search_method = mv_sf->search_method;
const vp9_variance_fn_ptr_t v_fn_ptr = cpi->fn_ptr[BLOCK_16X16];
const int tmp_col_min = x->mv_col_min;
const int tmp_col_max = x->mv_col_max;
const int tmp_row_min = x->mv_row_min;
const int tmp_row_max = x->mv_row_max;
const MvLimits tmp_mv_limits = x->mv_limits;
MV ref_full;
int cost_list[5];
......@@ -42,7 +38,7 @@ static unsigned int do_16x16_motion_iteration(VP9_COMP *cpi, const MV *ref_mv,
int step_param = mv_sf->reduce_first_step_size;
step_param = VPXMIN(step_param, MAX_MVSEARCH_STEPS - 2);
vp9_set_mv_search_range(x, ref_mv);
vp9_set_mv_search_range(&x->mv_limits, ref_mv);
ref_full.col = ref_mv->col >> 3;
ref_full.row = ref_mv->row >> 3;
......@@ -71,10 +67,7 @@ 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);
/* restore UMV window */
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;
x->mv_limits = tmp_mv_limits;
return vpx_sad16x16(x->plane[0].src.buf, x->plane[0].src.stride,
xd->plane[0].dst.buf, xd->plane[0].dst.stride);
......@@ -233,8 +226,8 @@ static void update_mbgraph_frame_stats(VP9_COMP *cpi,
vp9_zero(mi_local);
// Set up limit values for motion vectors to prevent them extending outside
// the UMV borders.
x->mv_row_min = -BORDER_MV_PIXELS_B16;
x->mv_row_max = (cm->mb_rows - 1) * 8 + BORDER_MV_PIXELS_B16;
x->mv_limits.row_min = -BORDER_MV_PIXELS_B16;
x->mv_limits.row_max = (cm->mb_rows - 1) * 8 + BORDER_MV_PIXELS_B16;
// Signal to vp9_predict_intra_block() that above is not available
xd->above_mi = NULL;
......@@ -254,8 +247,8 @@ static void update_mbgraph_frame_stats(VP9_COMP *cpi,
// Set up limit values for motion vectors to prevent them extending outside
// the UMV borders.
x->mv_col_min = -BORDER_MV_PIXELS_B16;
x->mv_col_max = (cm->mb_cols - 1) * 8 + BORDER_MV_PIXELS_B16;
x->mv_limits.col_min = -BORDER_MV_PIXELS_B16;
x->mv_limits.col_max = (cm->mb_cols - 1) * 8 + BORDER_MV_PIXELS_B16;
// Signal to vp9_predict_intra_block() that left is not available
xd->left_mi = NULL;
......@@ -274,8 +267,8 @@ static void update_mbgraph_frame_stats(VP9_COMP *cpi,
mb_y_in_offset += 16;
gld_y_in_offset += 16;
arf_y_in_offset += 16;
x->mv_col_min -= 16;
x->mv_col_max -= 16;
x->mv_limits.col_min -= 16;
x->mv_limits.col_max -= 16;
}
// Signal to vp9_predict_intra_block() that above is available
......@@ -284,8 +277,8 @@ static void update_mbgraph_frame_stats(VP9_COMP *cpi,
mb_y_offset += buf->y_stride * 16;
gld_y_offset += golden_ref->y_stride * 16;
if (alt_ref) arf_y_offset += alt_ref->y_stride * 16;
x->mv_row_min -= 16;
x->mv_row_max -= 16;
x->mv_limits.row_min -= 16;
x->mv_limits.row_max -= 16;
offset += cm->mb_cols;
}
}
......
This diff is collapsed.
......@@ -41,7 +41,7 @@ typedef struct search_site_config {
void vp9_init_dsmotion_compensation(search_site_config *cfg, int stride);
void vp9_init3smotion_compensation(search_site_config *cfg, int stride);
void vp9_set_mv_search_range(MACROBLOCK *x, const MV *mv);
void vp9_set_mv_search_range(MvLimits *mv_limits, const MV *mv);
int vp9_mv_bit_cost(const MV *mv, const MV *ref, const int *mvjcost,
int *mvcost[2], int weight);
......
......@@ -155,10 +155,7 @@ static int combined_motion_search(VP9_COMP *cpi, MACROBLOCK *x,
MV center_mv;
uint32_t dis;
int rate_mode;
const int tmp_col_min = x->mv_col_min;
const int tmp_col_max = x->mv_col_max;
const int tmp_row_min = x->mv_row_min;
const int tmp_row_max = x->mv_row_max;
const MvLimits tmp_mv_limits = x->mv_limits;
int rv = 0;
int cost_list[5];
const YV12_BUFFER_CONFIG *scaled_ref_frame =
......@@ -171,7 +168,7 @@ static int combined_motion_search(VP9_COMP *cpi, MACROBLOCK *x,
for (i = 0; i < MAX_MB_PLANE; i++) backup_yv12[i] = xd->plane[i].pre[0];
vp9_setup_pre_planes(xd, 0, scaled_ref_frame, mi_row, mi_col, NULL);
}
vp9_set_mv_search_range(x, &ref_mv);
vp9_set_mv_search_range(&x->mv_limits, &ref_mv);
assert(x->mv_best_ref_index[ref] <= 2);
if (x->mv_best_ref_index[ref] < 2)
......@@ -191,10 +188,7 @@ static int combined_motion_search(VP9_COMP *cpi, MACROBLOCK *x,
cond_cost_list(cpi, cost_list), &center_mv,
&tmp_mv->as_mv, INT_MAX, 0);
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;
x->mv_limits = tmp_mv_limits;
// calculate the bit cost on motion vector
mvp_full.row = tmp_mv->as_mv.row * 8;
......@@ -2182,10 +2176,7 @@ void vp9_pick_inter_mode_sub8x8(VP9_COMP *cpi, MACROBLOCK *x, int mi_row,
MV mvp_full;
MV tmp_mv;
int cost_list[5];
const int tmp_col_min = x->mv_col_min;
const int tmp_col_max = x->mv_col_max;
const int tmp_row_min = x->mv_row_min;
const int tmp_row_max = x->mv_row_max;
const MvLimits tmp_mv_limits = x->mv_limits;
uint32_t dummy_dist;
if (i == 0) {
......@@ -2196,17 +2187,15 @@ void vp9_pick_inter_mode_sub8x8(VP9_COMP *cpi, MACROBLOCK *x, int mi_row,
mvp_full.col = xd->mi[0]->bmi[0].as_mv[0].as_mv.col >> 3;
}
vp9_set_mv_search_range(x, &mbmi_ext->ref_mvs[0]->as_mv);
vp9_set_mv_search_range(&x->mv_limits,
&mbmi_ext->ref_mvs[0]->as_mv);
vp9_full_pixel_search(cpi, x, bsize, &mvp_full, step_param,
x->sadperbit4, cond_cost_list(cpi, cost_list),
&mbmi_ext->ref_mvs[ref_frame][0].as_mv,
&tmp_mv, INT_MAX, 0);
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;
x->mv_limits = tmp_mv_limits;
// calculate the bit cost on motion vector
mvp_full.row = tmp_mv.row * 8;
......
......@@ -1626,9 +1626,11 @@ typedef struct {
int mvthresh;
} BEST_SEG_INFO;
static INLINE int mv_check_bounds(const MACROBLOCK *x, const MV *mv) {
return (mv->row >> 3) < x->mv_row_min || (mv->row >> 3) > x->mv_row_max ||
(mv->col >> 3) < x->mv_col_min || (mv->col >> 3) > x->mv_col_max;
static INLINE int mv_check_bounds(const MvLimits *mv_limits, const MV *mv) {
return (mv->row >> 3) < mv_limits->row_min ||
(mv->row >> 3) > mv_limits->row_max ||
(mv->col >> 3) < mv_limits->col_min ||
(mv->col >> 3) > mv_limits->col_max;
}
static INLINE void mi_buf_shift(MACROBLOCK *x, int i) {
......@@ -1765,10 +1767,7 @@ static void joint_motion_search(VP9_COMP *cpi, MACROBLOCK *x, BLOCK_SIZE bsize,
MV tmp_mv;
int search_range = 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;
const MvLimits tmp_mv_limits = x->mv_limits;
int id = ite % 2; // Even iterations search in the first reference frame,
// odd iterations search in the second. The predictor
// found for the 'other' reference frame is factored in.
......@@ -1801,7 +1800,7 @@ static void joint_motion_search(VP9_COMP *cpi, MACROBLOCK *x, BLOCK_SIZE bsize,
// Do compound motion search on the current reference frame.
if (id) xd->plane[0].pre[0] = ref_yv12[id];
vp9_set_mv_search_range(x, &ref_mv[id].as_mv);
vp9_set_mv_search_range(&x->mv_limits, &ref_mv[id].as_mv);
// Use the mv result from the single mode as mv predictor.
tmp_mv = frame_mv[refs[id]].as_mv;
......@@ -1817,10 +1816,7 @@ static void joint_motion_search(VP9_COMP *cpi, MACROBLOCK *x, BLOCK_SIZE bsize,
bestsme = vp9_get_mvpred_av_var(x, &tmp_mv, &ref_mv[id].as_mv,
second_pred, &cpi->fn_ptr[bsize], 1);
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;
x->mv_limits = tmp_mv_limits;
if (bestsme < UINT_MAX) {
uint32_t dis; /* TODO: use dis in distortion calculation later. */
......@@ -1958,10 +1954,7 @@ static int64_t rd_pick_best_sub8x8_mode(
MV mvp_full;
int max_mv;
int cost_list[5];
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;
const MvLimits tmp_mv_limits = x->mv_limits;
/* Is the best so far sufficiently good that we cant justify doing
* and new motion search. */
......@@ -2002,17 +1995,14 @@ static int64_t rd_pick_best_sub8x8_mode(
// adjust src pointer for this block
mi_buf_shift(x, i);
vp9_set_mv_search_range(x, &bsi->ref_mv[0]->as_mv);
vp9_set_mv_search_range(&x->mv_limits, &bsi->ref_mv[0]->as_mv);
bestsme = vp9_full_pixel_search(
cpi, x, bsize, &mvp_full, step_param, sadpb,
sf->mv.subpel_search_method != SUBPEL_TREE ? cost_list : NULL,
&bsi->ref_mv[0]->as_mv, new_mv, INT_MAX, 1);
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;
x->mv_limits = tmp_mv_limits;
if (bestsme < UINT_MAX) {
uint32_t distortion;
......@@ -2073,8 +2063,9 @@ static int64_t rd_pick_best_sub8x8_mode(
}
// Trap vectors that reach beyond the UMV borders
if (mv_check_bounds(x, &mode_mv[this_mode][0].as_mv) ||
(has_second_rf && mv_check_bounds(x, &mode_mv[this_mode][1].as_mv)))
if (mv_check_bounds(&x->mv_limits, &mode_mv[this_mode][0].as_mv) ||
(has_second_rf &&
mv_check_bounds(&x->mv_limits, &mode_mv[this_mode][1].as_mv)))
continue;
if (filter_idx > 0) {
......@@ -2335,11 +2326,7 @@ static void single_motion_search(VP9_COMP *cpi, MACROBLOCK *x, BLOCK_SIZE bsize,
MV mvp_full;
int ref = mi->ref_frame[0];
MV ref_mv = x->mbmi_ext->ref_mvs[ref][0].as_mv;
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;
const MvLimits tmp_mv_limits = x->mv_limits;
int cost_list[5];
const YV12_BUFFER_CONFIG *scaled_ref_frame =
......@@ -2360,7 +2347,7 @@ static void single_motion_search(VP9_COMP *cpi, MACROBLOCK *x, BLOCK_SIZE bsize,
vp9_setup_pre_planes(xd, 0, scaled_ref_frame, mi_row, mi_col, NULL);
}
vp9_set_mv_search_range(x, &ref_mv);
vp9_set_mv_search_range(&x->mv_limits, &ref_mv);
// Work out the size of the first step in the mv step search.
// 0 here is maximum length first step. 1 is VPXMAX >> 1 etc.
......@@ -2418,10 +2405,7 @@ static void single_motion_search(VP9_COMP *cpi, MACROBLOCK *x, BLOCK_SIZE bsize,
cond_cost_list(cpi, cost_list), &ref_mv,
&tmp_mv->as_mv, INT_MAX, 1);
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;
x->mv_limits = tmp_mv_limits;
if (bestsme < INT_MAX) {
uint32_t dis; /* TODO: use dis in distortion calculation later. */
......@@ -2594,7 +2578,7 @@ static int64_t handle_inter_mode(
// Clip "next_nearest" so that it does not extend to far out of image
if (this_mode != NEWMV) clamp_mv2(&cur_mv[i].as_mv, xd);
if (mv_check_bounds(x, &cur_mv[i].as_mv)) return INT64_MAX;
if (mv_check_bounds(&x->mv_limits, &cur_mv[i].as_mv)) return INT64_MAX;
mi->mv[i].as_int = cur_mv[i].as_int;
}
......
......@@ -316,8 +316,9 @@ static void temporal_filter_iterate_c(VP9_COMP *cpi,
// 8 - VP9_INTERP_EXTEND.
// To keep the mv in play for both Y and UV planes the max that it
// can be on a border is therefore 16 - (2*VP9_INTERP_EXTEND+1).
cpi->td.mb.mv_row_min = -((mb_row * 16) + (17 - 2 * VP9_INTERP_EXTEND));
cpi->td.mb.mv_row_max =
cpi->td.mb.mv_limits.row_min =
-((mb_row * 16) + (17 - 2 * VP9_INTERP_EXTEND));
cpi->td.mb.mv_limits.row_max =
((mb_rows - 1 - mb_row) * 16) + (17 - 2 * VP9_INTERP_EXTEND);
for (mb_col = 0; mb_col < mb_cols; mb_col++) {
......@@ -327,8 +328,9 @@ static void temporal_filter_iterate_c(VP9_COMP *cpi,
memset(accumulator, 0, 16 * 16 * 3 * sizeof(accumulator[0]));
memset(count, 0, 16 * 16 * 3 * sizeof(count[0]));
cpi->td.mb.mv_col_min = -((mb_col * 16) + (17 - 2 * VP9_INTERP_EXTEND));
cpi->td.mb.mv_col_max =
cpi->td.mb.mv_limits.col_min =
-((mb_col * 16) + (17 - 2 * VP9_INTERP_EXTEND));
cpi->td.mb.mv_limits.col_max =
((mb_cols - 1 - mb_col) * 16) + (17 - 2 * VP9_INTERP_EXTEND);
for (frame = 0; frame < frame_count; frame++) {
......
......@@ -75,9 +75,9 @@ int vp9_diamond_search_sad_avx(const MACROBLOCK *x,
MV *best_mv, int search_param, int sad_per_bit,
int *num00, const vp9_variance_fn_ptr_t *fn_ptr,
const MV *center_mv) {
const int_mv maxmv = pack_int_mv(x->mv_row_max, x->mv_col_max);
const int_mv maxmv = pack_int_mv(x->mv_limits.row_max, x->mv_limits.col_max);
const __m128i v_max_mv_w = _mm_set1_epi32(maxmv.as_int);
const int_mv minmv = pack_int_mv(x->mv_row_min, x->mv_col_min);
const int_mv minmv = pack_int_mv(x->mv_limits.row_min, x->mv_limits.col_min);
const __m128i v_min_mv_w = _mm_set1_epi32(minmv.as_int);
const __m128i v_spb_d = _mm_set1_epi32(sad_per_bit);
......
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