Divide mv limits into mv_limits and subpel_mv_limits
Change-Id: I5aefc9d4625a522bfc3c627e80eeebd0998c193a
diff --git a/av1/common/mv.h b/av1/common/mv.h
index d6823a0..8aa364e 100644
--- a/av1/common/mv.h
+++ b/av1/common/mv.h
@@ -50,6 +50,22 @@
int32_t col;
} MV32;
+// The mv limit for fullpel mvs
+typedef struct {
+ int col_min;
+ int col_max;
+ int row_min;
+ int row_max;
+} FullMvLimits;
+
+// The mv limit for subpel mvs
+typedef struct {
+ int col_min;
+ int col_max;
+ int row_min;
+ int row_max;
+} SubpelMvLimits;
+
static AOM_INLINE FULLPEL_MV get_fullmv_from_mv(const MV *subpel_mv) {
const FULLPEL_MV full_mv = { (int16_t)GET_MV_RAWPEL(subpel_mv->row),
(int16_t)GET_MV_RAWPEL(subpel_mv->col) };
@@ -314,16 +330,14 @@
return *((const uint32_t *)a) == *((const uint32_t *)b);
}
-static INLINE void clamp_mv(MV *mv, int min_col, int max_col, int min_row,
- int max_row) {
- mv->col = clamp(mv->col, min_col, max_col);
- mv->row = clamp(mv->row, min_row, max_row);
+static INLINE void clamp_mv(MV *mv, const SubpelMvLimits *mv_limits) {
+ mv->col = clamp(mv->col, mv_limits->col_min, mv_limits->col_max);
+ mv->row = clamp(mv->row, mv_limits->row_min, mv_limits->row_max);
}
-static INLINE void clamp_fullmv(FULLPEL_MV *mv, int min_col, int max_col,
- int min_row, int max_row) {
- mv->col = clamp(mv->col, min_col, max_col);
- mv->row = clamp(mv->row, min_row, max_row);
+static INLINE void clamp_fullmv(FULLPEL_MV *mv, const FullMvLimits *mv_limits) {
+ mv->col = clamp(mv->col, mv_limits->col_min, mv_limits->col_max);
+ mv->row = clamp(mv->row, mv_limits->row_min, mv_limits->row_max);
}
#ifdef __cplusplus
diff --git a/av1/common/mvref_common.h b/av1/common/mvref_common.h
index 9f441e2..dab8c37 100644
--- a/av1/common/mvref_common.h
+++ b/av1/common/mvref_common.h
@@ -50,10 +50,13 @@
}
static INLINE void clamp_mv_ref(MV *mv, int bw, int bh, const MACROBLOCKD *xd) {
- clamp_mv(mv, xd->mb_to_left_edge - GET_MV_SUBPEL(bw) - MV_BORDER,
- xd->mb_to_right_edge + GET_MV_SUBPEL(bw) + MV_BORDER,
- xd->mb_to_top_edge - GET_MV_SUBPEL(bh) - MV_BORDER,
- xd->mb_to_bottom_edge + GET_MV_SUBPEL(bh) + MV_BORDER);
+ const SubpelMvLimits mv_limits = {
+ xd->mb_to_left_edge - GET_MV_SUBPEL(bw) - MV_BORDER,
+ xd->mb_to_right_edge + GET_MV_SUBPEL(bw) + MV_BORDER,
+ xd->mb_to_top_edge - GET_MV_SUBPEL(bh) - MV_BORDER,
+ xd->mb_to_bottom_edge + GET_MV_SUBPEL(bh) + MV_BORDER
+ };
+ clamp_mv(mv, &mv_limits);
}
// This function returns either the appropriate sub block or block's mv
diff --git a/av1/common/reconinter.h b/av1/common/reconinter.h
index 1074759..9834415 100644
--- a/av1/common/reconinter.h
+++ b/av1/common/reconinter.h
@@ -261,11 +261,14 @@
(int16_t)(src_mv->col * (1 << (1 - ss_x))) };
assert(ss_x <= 1);
assert(ss_y <= 1);
+ const SubpelMvLimits mv_limits = {
+ xd->mb_to_left_edge * (1 << (1 - ss_x)) - spel_left,
+ xd->mb_to_right_edge * (1 << (1 - ss_x)) + spel_right,
+ xd->mb_to_top_edge * (1 << (1 - ss_y)) - spel_top,
+ xd->mb_to_bottom_edge * (1 << (1 - ss_y)) + spel_bottom
+ };
- clamp_mv(&clamped_mv, xd->mb_to_left_edge * (1 << (1 - ss_x)) - spel_left,
- xd->mb_to_right_edge * (1 << (1 - ss_x)) + spel_right,
- xd->mb_to_top_edge * (1 << (1 - ss_y)) - spel_top,
- xd->mb_to_bottom_edge * (1 << (1 - ss_y)) + spel_bottom);
+ clamp_mv(&clamped_mv, &mv_limits);
return clamped_mv;
}
diff --git a/av1/encoder/block.h b/av1/encoder/block.h
index 1d964cb..1c6c372 100644
--- a/av1/encoder/block.h
+++ b/av1/encoder/block.h
@@ -115,13 +115,6 @@
} MB_MODE_INFO_EXT_FRAME;
typedef struct {
- int col_min;
- int col_max;
- int row_min;
- int row_max;
-} MvLimits;
-
-typedef struct {
uint8_t best_palette_color_map[MAX_PALETTE_SQUARE];
int kmeans_data_buf[2 * MAX_PALETTE_SQUARE];
} PALETTE_BUFFER;
@@ -324,7 +317,7 @@
// These define limits to motion vector components to prevent them
// from extending outside the UMV borders
- MvLimits mv_limits;
+ FullMvLimits mv_limits;
uint8_t blk_skip[MAX_MIB_SIZE * MAX_MIB_SIZE];
uint8_t tx_type_map[MAX_MIB_SIZE * MAX_MIB_SIZE];
diff --git a/av1/encoder/mcomp.c b/av1/encoder/mcomp.c
index b4d70ba..6115464 100644
--- a/av1/encoder/mcomp.c
+++ b/av1/encoder/mcomp.c
@@ -59,7 +59,7 @@
return &buf->buf[get_offset_from_mv(mv, buf->stride)];
}
-void av1_set_mv_search_range(MvLimits *mv_limits, const MV *mv) {
+void av1_set_mv_search_range(FullMvLimits *mv_limits, const MV *mv) {
int col_min =
GET_MV_RAWPEL(mv->col) - MAX_FULL_PEL_VAL + (mv->col & 7 ? 1 : 0);
int row_min =
@@ -301,56 +301,60 @@
}
/* checks if (r, c) has better score than previous best */
-#define CHECK_BETTER(v, r, c) \
- if (c >= minc && c <= maxc && r >= minr && r <= maxr) { \
- MV this_mv = { r, c }; \
- v = mv_err_cost(&this_mv, ref_mv, mvjcost, mvcost, error_per_bit, \
- mv_cost_type); \
- if (second_pred == NULL) { \
- thismse = vfp->svf(pre(y, y_stride, r, c), y_stride, sp(c), sp(r), \
- src_address, src_stride, &sse); \
- } else if (mask) { \
- thismse = vfp->msvf(pre(y, y_stride, r, c), y_stride, sp(c), sp(r), \
- src_address, src_stride, second_pred, mask, \
- mask_stride, invert_mask, &sse); \
- } else { \
- thismse = vfp->svaf(pre(y, y_stride, r, c), y_stride, sp(c), sp(r), \
- src_address, src_stride, &sse, second_pred); \
- } \
- v += thismse; \
- if (v < besterr) { \
- besterr = v; \
- br = r; \
- bc = c; \
- *distortion = thismse; \
- *sse1 = sse; \
- } \
- } else { \
- v = INT_MAX; \
+#define CHECK_BETTER(v, r, c) \
+ { \
+ const MV this_mv = { r, c }; \
+ if (av1_is_subpelmv_in_range(&mv_limits, this_mv)) { \
+ v = mv_err_cost(&this_mv, ref_mv, mvjcost, mvcost, error_per_bit, \
+ mv_cost_type); \
+ if (second_pred == NULL) { \
+ thismse = vfp->svf(pre(y, y_stride, r, c), y_stride, sp(c), sp(r), \
+ src_address, src_stride, &sse); \
+ } else if (mask) { \
+ thismse = vfp->msvf(pre(y, y_stride, r, c), y_stride, sp(c), sp(r), \
+ src_address, src_stride, second_pred, mask, \
+ mask_stride, invert_mask, &sse); \
+ } else { \
+ thismse = vfp->svaf(pre(y, y_stride, r, c), y_stride, sp(c), sp(r), \
+ src_address, src_stride, &sse, second_pred); \
+ } \
+ v += thismse; \
+ if (v < besterr) { \
+ besterr = v; \
+ br = r; \
+ bc = c; \
+ *distortion = thismse; \
+ *sse1 = sse; \
+ } \
+ } else { \
+ v = INT_MAX; \
+ } \
}
#define CHECK_BETTER0(v, r, c) CHECK_BETTER(v, r, c)
/* checks if (r, c) has better score than previous best */
-#define CHECK_BETTER1(v, r, c) \
- if (c >= minc && c <= maxc && r >= minr && r <= maxr) { \
- MV this_mv = { r, c }; \
- thismse = upsampled_pref_error( \
- xd, cm, mi_row, mi_col, &this_mv, vfp, src_address, src_stride, \
- pre(y, y_stride, r, c), y_stride, sp(c), sp(r), second_pred, mask, \
- mask_stride, invert_mask, w, h, &sse, use_accurate_subpel_search); \
- v = mv_err_cost(&this_mv, ref_mv, mvjcost, mvcost, error_per_bit, \
- mv_cost_type); \
- v += thismse; \
- if (v < besterr) { \
- besterr = v; \
- br = r; \
- bc = c; \
- *distortion = thismse; \
- *sse1 = sse; \
- } \
- } else { \
- v = INT_MAX; \
+#define CHECK_BETTER1(v, r, c) \
+ { \
+ MV this_mv = { r, c }; \
+ if (av1_is_subpelmv_in_range(&mv_limits, this_mv)) { \
+ thismse = upsampled_pref_error( \
+ xd, cm, mi_row, mi_col, &this_mv, vfp, src_address, src_stride, \
+ pre(y, y_stride, r, c), y_stride, sp(c), sp(r), second_pred, mask, \
+ mask_stride, invert_mask, w, h, &sse, use_accurate_subpel_search); \
+ v = mv_err_cost(&this_mv, ref_mv, mvjcost, mvcost, error_per_bit, \
+ mv_cost_type); \
+ v += thismse; \
+ if (v < besterr) { \
+ besterr = v; \
+ br = r; \
+ bc = c; \
+ *distortion = thismse; \
+ *sse1 = sse; \
+ } \
+ } else { \
+ v = INT_MAX; \
+ } \
}
#define FIRST_LEVEL_CHECKS \
@@ -444,11 +448,11 @@
int br = bestmv->row; \
int bc = bestmv->col; \
int hstep = 4; \
- int minc, maxc, minr, maxr; \
+ SubpelMvLimits mv_limits; \
int tr = br; \
int tc = bc; \
\
- set_subpel_mv_search_range(&x->mv_limits, &minc, &maxc, &minr, &maxr, ref_mv);
+ av1_set_subpel_mv_search_range(&mv_limits, &x->mv_limits, ref_mv);
static unsigned int setup_center_error(
const MACROBLOCKD *xd, const MV *bestmv, const MV *ref_mv,
@@ -911,9 +915,9 @@
int idx, best_idx = -1;
unsigned int cost_array[5];
int kr, kc;
- int minc, maxc, minr, maxr;
+ SubpelMvLimits mv_limits;
- set_subpel_mv_search_range(&x->mv_limits, &minc, &maxc, &minr, &maxr, ref_mv);
+ av1_set_subpel_mv_search_range(&mv_limits, &x->mv_limits, ref_mv);
if (!allow_hp)
if (round == 3) round = 2;
@@ -946,9 +950,8 @@
for (idx = 0; idx < 4; ++idx) {
tr = br + search_step[idx].row;
tc = bc + search_step[idx].col;
- if (tc >= minc && tc <= maxc && tr >= minr && tr <= maxr) {
- MV this_mv = { tr, tc };
-
+ const MV this_mv = { tr, tc };
+ if (av1_is_subpelmv_in_range(&mv_limits, this_mv)) {
if (use_accurate_subpel_search) {
thismse = upsampled_pref_error(
xd, cm, mi_row, mi_col, &this_mv, vfp, src_address, src_stride,
@@ -983,32 +986,34 @@
tc = bc + kc;
tr = br + kr;
- if (tc >= minc && tc <= maxc && tr >= minr && tr <= maxr) {
- MV this_mv = { tr, tc };
+ {
+ const MV this_mv = { tr, tc };
+ if (av1_is_subpelmv_in_range(&mv_limits, this_mv)) {
+ if (use_accurate_subpel_search) {
+ thismse = upsampled_pref_error(
+ xd, cm, mi_row, mi_col, &this_mv, vfp, src_address, src_stride,
+ pre(y, y_stride, tr, tc), y_stride, sp(tc), sp(tr), second_pred,
+ mask, mask_stride, invert_mask, w, h, &sse,
+ use_accurate_subpel_search);
+ } else {
+ thismse = estimate_upsampled_pref_error(
+ vfp, src_address, src_stride, pre(y, y_stride, tr, tc), y_stride,
+ sp(tc), sp(tr), second_pred, mask, mask_stride, invert_mask,
+ &sse);
+ }
- if (use_accurate_subpel_search) {
- thismse = upsampled_pref_error(
- xd, cm, mi_row, mi_col, &this_mv, vfp, src_address, src_stride,
- pre(y, y_stride, tr, tc), y_stride, sp(tc), sp(tr), second_pred,
- mask, mask_stride, invert_mask, w, h, &sse,
- use_accurate_subpel_search);
+ cost_array[4] = thismse + mv_err_cost(&this_mv, ref_mv, mvjcost, mvcost,
+ error_per_bit, mv_cost_type);
+
+ if (cost_array[4] < besterr) {
+ best_idx = 4;
+ besterr = cost_array[4];
+ *distortion = thismse;
+ *sse1 = sse;
+ }
} else {
- thismse = estimate_upsampled_pref_error(
- vfp, src_address, src_stride, pre(y, y_stride, tr, tc), y_stride,
- sp(tc), sp(tr), second_pred, mask, mask_stride, invert_mask, &sse);
+ cost_array[idx] = INT_MAX;
}
-
- cost_array[4] = thismse + mv_err_cost(&this_mv, ref_mv, mvjcost, mvcost,
- error_per_bit, mv_cost_type);
-
- if (cost_array[4] < besterr) {
- best_idx = 4;
- besterr = cost_array[4];
- *distortion = thismse;
- *sse1 = sse;
- }
- } else {
- cost_array[idx] = INT_MAX;
}
if (best_idx < 4 && best_idx >= 0) {
@@ -1087,15 +1092,15 @@
WarpedMotionParams best_wm_params = mbmi->wm_params;
int best_num_proj_ref = mbmi->num_proj_ref;
unsigned int bestmse;
- int minc, maxc, minr, maxr;
+ SubpelMvLimits mv_limits;
+
const int start = cm->allow_high_precision_mv ? 0 : 4;
int ite;
- set_subpel_mv_search_range(&x->mv_limits, &minc, &maxc, &minr, &maxr,
- &ref_mv.as_mv);
+ av1_set_subpel_mv_search_range(&mv_limits, &x->mv_limits, &ref_mv.as_mv);
// Calculate the center position's error
- assert(bc >= minc && bc <= maxc && br >= minr && br <= maxr);
+ assert(av1_is_subpelmv_in_range(&mv_limits, mbmi->mv[0].as_mv));
bestmse = av1_compute_motion_cost(cpi, x, bsize, &mbmi->mv[0].as_mv);
// MV search
@@ -1111,8 +1116,8 @@
*tr = br + neighbors[idx].row;
*tc = bc + neighbors[idx].col;
- if (*tc >= minc && *tc <= maxc && *tr >= minr && *tr <= maxr) {
- MV this_mv = { *tr, *tc };
+ MV this_mv = { *tr, *tc };
+ if (av1_is_subpelmv_in_range(&mv_limits, this_mv)) {
int pts[SAMPLES_ARRAY_SIZE], pts_inref[SAMPLES_ARRAY_SIZE];
memcpy(pts, pts0, total_samples * 2 * sizeof(*pts0));
@@ -1150,7 +1155,7 @@
return bestmse;
}
-static INLINE int check_bounds(const MvLimits *mv_limits, int row, int col,
+static INLINE int check_bounds(const FullMvLimits *mv_limits, int row, int col,
int range) {
return ((row - range) >= mv_limits->row_min) &
((row + range) <= mv_limits->row_max) &
@@ -1158,11 +1163,6 @@
((col + range) <= mv_limits->col_max);
}
-static INLINE int is_mv_in(const MvLimits *mv_limits, const FULLPEL_MV *mv) {
- return (mv->col >= mv_limits->col_min) && (mv->col <= mv_limits->col_max) &&
- (mv->row >= mv_limits->row_min) && (mv->row <= mv_limits->row_max);
-}
-
#define CHECK_BETTER \
{ \
if (thissad < bestsad) { \
@@ -1214,7 +1214,7 @@
for (int i = 0; i < 4; i++) {
const FULLPEL_MV neighbor_mv = { br + neighbors[i].row,
bc + neighbors[i].col };
- if (!is_mv_in(&x->mv_limits, &neighbor_mv)) {
+ if (!av1_is_fullmv_in_range(&x->mv_limits, neighbor_mv)) {
cost_list[i + 1] = INT_MAX;
} else {
const MV sub_neighbor_mv = get_mv_from_fullmv(&neighbor_mv);
@@ -1255,7 +1255,7 @@
for (int i = 0; i < 4; i++) {
const FULLPEL_MV this_mv = { br + neighbors[i].row,
bc + neighbors[i].col };
- if (!is_mv_in(&x->mv_limits, &this_mv))
+ if (!av1_is_fullmv_in_range(&x->mv_limits, this_mv))
cost_list[i + 1] = INT_MAX;
else
cost_list[i + 1] =
@@ -1302,8 +1302,7 @@
assert(search_param < MAX_MVSEARCH_STEPS);
int best_init_s = search_param_to_steps[search_param];
// adjust ref_mv to make sure it is within MV range
- clamp_fullmv(start_mv, x->mv_limits.col_min, x->mv_limits.col_max,
- x->mv_limits.row_min, x->mv_limits.row_max);
+ clamp_fullmv(start_mv, &x->mv_limits);
br = start_mv->row;
bc = start_mv->col;
if (cost_list != NULL) {
@@ -1337,7 +1336,7 @@
for (i = 0; i < num_candidates[t]; i++) {
const FULLPEL_MV this_mv = { br + candidates[t][i].row,
bc + candidates[t][i].col };
- if (!is_mv_in(&x->mv_limits, &this_mv)) continue;
+ if (!av1_is_fullmv_in_range(&x->mv_limits, this_mv)) continue;
thissad =
vfp->sdf(what->buf, what->stride,
get_buf_from_mv(in_what, &this_mv), in_what->stride);
@@ -1380,7 +1379,7 @@
for (i = 0; i < num_candidates[s]; i++) {
const FULLPEL_MV this_mv = { br + candidates[s][i].row,
bc + candidates[s][i].col };
- if (!is_mv_in(&x->mv_limits, &this_mv)) continue;
+ if (!av1_is_fullmv_in_range(&x->mv_limits, this_mv)) continue;
thissad =
vfp->sdf(what->buf, what->stride,
get_buf_from_mv(in_what, &this_mv), in_what->stride);
@@ -1421,7 +1420,7 @@
br + candidates[s][next_chkpts_indices[i]].row,
bc + candidates[s][next_chkpts_indices[i]].col
};
- if (!is_mv_in(&x->mv_limits, &this_mv)) continue;
+ if (!av1_is_fullmv_in_range(&x->mv_limits, this_mv)) continue;
thissad =
vfp->sdf(what->buf, what->stride,
get_buf_from_mv(in_what, &this_mv), in_what->stride);
@@ -1454,7 +1453,7 @@
for (i = 0; i < num_candidates[s]; i++) {
const FULLPEL_MV this_mv = { br + candidates[s][i].row,
bc + candidates[s][i].col };
- if (!is_mv_in(&x->mv_limits, &this_mv)) continue;
+ if (!av1_is_fullmv_in_range(&x->mv_limits, this_mv)) continue;
cost_list[i + 1] = thissad =
vfp->sdf(what->buf, what->stride,
get_buf_from_mv(in_what, &this_mv), in_what->stride);
@@ -1495,7 +1494,7 @@
br + candidates[s][next_chkpts_indices[i]].row,
bc + candidates[s][next_chkpts_indices[i]].col
};
- if (!is_mv_in(&x->mv_limits, &this_mv)) {
+ if (!av1_is_fullmv_in_range(&x->mv_limits, this_mv)) {
cost_list[next_chkpts_indices[i] + 1] = INT_MAX;
continue;
}
@@ -1771,8 +1770,7 @@
assert(step >= 1);
- clamp_fullmv(&start_mv_, x->mv_limits.col_min, x->mv_limits.col_max,
- x->mv_limits.row_min, x->mv_limits.row_max);
+ clamp_fullmv(&start_mv_, &x->mv_limits);
*best_mv = start_mv_;
best_sad =
fn_ptr->sdf(what->buf, what->stride, get_buf_from_mv(in_what, &start_mv_),
@@ -1868,8 +1866,7 @@
const int tot_steps = cfg->ss_count - search_param;
const FULLPEL_MV full_ref_mv = get_fullmv_from_mv(ref_mv);
- clamp_fullmv(start_mv, x->mv_limits.col_min, x->mv_limits.col_max,
- x->mv_limits.row_min, x->mv_limits.row_max);
+ clamp_fullmv(start_mv, &x->mv_limits);
*num00 = 0;
best_mv->row = start_mv->row;
best_mv->col = start_mv->col;
@@ -1934,7 +1931,7 @@
const FULLPEL_MV this_mv = { best_mv->row + ss[idx].mv.row,
best_mv->col + ss[idx].mv.col };
- if (is_mv_in(&x->mv_limits, &this_mv)) {
+ if (av1_is_fullmv_in_range(&x->mv_limits, this_mv)) {
const uint8_t *const check_here = ss[idx].offset + best_address;
unsigned int thissad;
@@ -2141,8 +2138,7 @@
int grid_center = SEARCH_GRID_CENTER_8P;
int grid_coord = grid_center;
- clamp_fullmv(best_mv, x->mv_limits.col_min, x->mv_limits.col_max,
- x->mv_limits.row_min, x->mv_limits.row_max);
+ clamp_fullmv(best_mv, &x->mv_limits);
if (mask) {
best_sad = fn_ptr->msdf(what->buf, what->stride,
get_buf_from_mv(in_what, best_mv), in_what->stride,
@@ -2169,7 +2165,7 @@
best_mv->col + neighbors[j].coord.col };
do_refine_search_grid[grid_coord] = 1;
- if (is_mv_in(&x->mv_limits, &mv)) {
+ if (av1_is_fullmv_in_range(&x->mv_limits, mv)) {
unsigned int sad;
if (mask) {
sad = fn_ptr->msdf(what->buf, what->stride,
@@ -2296,7 +2292,6 @@
const int norm_factor = 3 + (bw >> 5);
const YV12_BUFFER_CONFIG *scaled_ref_frame =
av1_get_scaled_ref_frame(cpi, mi->ref_frame[0]);
- MvLimits subpel_mv_limits;
if (scaled_ref_frame) {
int i;
@@ -2396,12 +2391,9 @@
convert_fullmv_to_mv(best_int_mv);
- set_subpel_mv_search_range(
- &x->mv_limits, &subpel_mv_limits.col_min, &subpel_mv_limits.col_max,
- &subpel_mv_limits.row_min, &subpel_mv_limits.row_max, ref_mv);
- clamp_mv(&best_int_mv->as_mv, subpel_mv_limits.col_min,
- subpel_mv_limits.col_max, subpel_mv_limits.row_min,
- subpel_mv_limits.row_max);
+ SubpelMvLimits subpel_mv_limits;
+ av1_set_subpel_mv_search_range(&subpel_mv_limits, &x->mv_limits, ref_mv);
+ clamp_mv(&best_int_mv->as_mv, &subpel_mv_limits);
if (scaled_ref_frame) {
int i;
@@ -2548,7 +2540,7 @@
FULLPEL_MV hash_mv;
hash_mv.col = ref_block_hash.x - x_pos;
hash_mv.row = ref_block_hash.y - y_pos;
- if (!is_mv_in(&x->mv_limits, &hash_mv)) continue;
+ if (!av1_is_fullmv_in_range(&x->mv_limits, hash_mv)) continue;
const int refCost = av1_get_mvpred_var(x, &hash_mv, ref_mv, fn_ptr);
if (refCost < best_hash_cost) {
best_hash_cost = refCost;
@@ -2581,43 +2573,48 @@
13 \
: 0)
-#define CHECK_BETTER(v, r, c) \
- if (c >= minc && c <= maxc && r >= minr && r <= maxr) { \
- const MV diff_mv = { r - ref_mv->row, c - ref_mv->col }; \
- thismse = (DIST(r, c)); \
- if ((v = MVC(&diff_mv) + thismse) < besterr) { \
- besterr = v; \
- br = r; \
- bc = c; \
- *distortion = thismse; \
- *sse1 = sse; \
- } \
- } else { \
- v = INT_MAX; \
+#define CHECK_BETTER(v, r, c) \
+ { \
+ const MV this_mv = { r, c }; \
+ if (av1_is_subpelmv_in_range(&mv_limits, this_mv)) { \
+ const MV diff_mv = { r - ref_mv->row, c - ref_mv->col }; \
+ thismse = (DIST(r, c)); \
+ if ((v = MVC(&diff_mv) + thismse) < besterr) { \
+ besterr = v; \
+ br = r; \
+ bc = c; \
+ *distortion = thismse; \
+ *sse1 = sse; \
+ } \
+ } else { \
+ v = INT_MAX; \
+ } \
}
#undef CHECK_BETTER0
#define CHECK_BETTER0(v, r, c) CHECK_BETTER(v, r, c)
#undef CHECK_BETTER1
-#define CHECK_BETTER1(v, r, c) \
- if (c >= minc && c <= maxc && r >= minr && r <= maxr) { \
- MV this_mv = { r, c }; \
- thismse = upsampled_obmc_pref_error( \
- xd, cm, mi_row, mi_col, &this_mv, mask, vfp, src_address, \
- pre(y, y_stride, r, c), y_stride, sp(c), sp(r), w, h, &sse, \
- use_accurate_subpel_search); \
- v = mv_err_cost(&this_mv, ref_mv, mvjcost, mvcost, error_per_bit, \
- mv_cost_type); \
- if ((v + thismse) < besterr) { \
- besterr = v + thismse; \
- br = r; \
- bc = c; \
- *distortion = thismse; \
- *sse1 = sse; \
- } \
- } else { \
- v = INT_MAX; \
+#define CHECK_BETTER1(v, r, c) \
+ { \
+ const MV this_mv = { r, c }; \
+ if (av1_is_subpelmv_in_range(&mv_limits, this_mv)) { \
+ thismse = upsampled_obmc_pref_error( \
+ xd, cm, mi_row, mi_col, &this_mv, mask, vfp, src_address, \
+ pre(y, y_stride, r, c), y_stride, sp(c), sp(r), w, h, &sse, \
+ use_accurate_subpel_search); \
+ v = mv_err_cost(&this_mv, ref_mv, mvjcost, mvcost, error_per_bit, \
+ mv_cost_type); \
+ if ((v + thismse) < besterr) { \
+ besterr = v + thismse; \
+ br = r; \
+ bc = c; \
+ *distortion = thismse; \
+ *sse1 = sse; \
+ } \
+ } else { \
+ v = INT_MAX; \
+ } \
}
static unsigned int setup_obmc_center_error(
@@ -2714,9 +2711,9 @@
unsigned int cost_array[5];
int kr, kc;
- int minc, maxc, minr, maxr;
+ SubpelMvLimits mv_limits;
- set_subpel_mv_search_range(&x->mv_limits, &minc, &maxc, &minr, &maxr, ref_mv);
+ av1_set_subpel_mv_search_range(&mv_limits, &x->mv_limits, ref_mv);
if (!allow_hp)
if (round == 3) round = 2;
@@ -2737,8 +2734,8 @@
for (idx = 0; idx < 4; ++idx) {
tr = br + search_step[idx].row;
tc = bc + search_step[idx].col;
- if (tc >= minc && tc <= maxc && tr >= minr && tr <= maxr) {
- MV this_mv = { tr, tc };
+ MV this_mv = { tr, tc };
+ if (av1_is_subpelmv_in_range(&mv_limits, this_mv)) {
if (use_accurate_subpel_search) {
thismse = upsampled_obmc_pref_error(
xd, cm, mi_row, mi_col, &this_mv, mask, vfp, src_address,
@@ -2769,30 +2766,31 @@
tc = bc + kc;
tr = br + kr;
- if (tc >= minc && tc <= maxc && tr >= minr && tr <= maxr) {
+ {
MV this_mv = { tr, tc };
+ if (av1_is_subpelmv_in_range(&mv_limits, this_mv)) {
+ if (use_accurate_subpel_search) {
+ thismse = upsampled_obmc_pref_error(
+ xd, cm, mi_row, mi_col, &this_mv, mask, vfp, src_address,
+ pre(y, y_stride, tr, tc), y_stride, sp(tc), sp(tr), w, h, &sse,
+ use_accurate_subpel_search);
+ } else {
+ thismse = vfp->osvf(pre(y, y_stride, tr, tc), y_stride, sp(tc),
+ sp(tr), src_address, mask, &sse);
+ }
- if (use_accurate_subpel_search) {
- thismse = upsampled_obmc_pref_error(
- xd, cm, mi_row, mi_col, &this_mv, mask, vfp, src_address,
- pre(y, y_stride, tr, tc), y_stride, sp(tc), sp(tr), w, h, &sse,
- use_accurate_subpel_search);
+ cost_array[4] = thismse + mv_err_cost(&this_mv, ref_mv, mvjcost, mvcost,
+ error_per_bit, mv_cost_type);
+
+ if (cost_array[4] < besterr) {
+ best_idx = 4;
+ besterr = cost_array[4];
+ *distortion = thismse;
+ *sse1 = sse;
+ }
} else {
- thismse = vfp->osvf(pre(y, y_stride, tr, tc), y_stride, sp(tc), sp(tr),
- src_address, mask, &sse);
+ cost_array[idx] = INT_MAX;
}
-
- cost_array[4] = thismse + mv_err_cost(&this_mv, ref_mv, mvjcost, mvcost,
- error_per_bit, mv_cost_type);
-
- if (cost_array[4] < besterr) {
- best_idx = 4;
- besterr = cost_array[4];
- *distortion = thismse;
- *sse1 = sse;
- }
- } else {
- cost_array[idx] = INT_MAX;
}
if (best_idx < 4 && best_idx >= 0) {
@@ -2871,7 +2869,7 @@
for (j = 0; j < 4; j++) {
const FULLPEL_MV mv = { start_mv->row + neighbors[j].row,
start_mv->col + neighbors[j].col };
- if (is_mv_in(&x->mv_limits, &mv)) {
+ if (av1_is_fullmv_in_range(&x->mv_limits, mv)) {
unsigned int sad = fn_ptr->osdf(get_buf_from_mv(in_what, &mv),
in_what->stride, wsrc, mask);
if (sad < best_sad) {
@@ -2913,8 +2911,7 @@
int best_site = 0;
int step;
- clamp_fullmv(start_mv, x->mv_limits.col_min, x->mv_limits.col_max,
- x->mv_limits.row_min, x->mv_limits.row_max);
+ clamp_fullmv(start_mv, &x->mv_limits);
in_what_ref = get_buf_from_mv(in_what, start_mv);
best_address = in_what_ref;
*num00 = 0;
@@ -2930,7 +2927,7 @@
for (int idx = 1; idx <= cfg->searches_per_step[step]; ++idx) {
const FULLPEL_MV mv = { best_mv->row + ss[idx].mv.row,
best_mv->col + ss[idx].mv.col };
- if (is_mv_in(&x->mv_limits, &mv)) {
+ if (av1_is_fullmv_in_range(&x->mv_limits, mv)) {
int sad = fn_ptr->osdf(best_address + ss[idx].offset, in_what->stride,
wsrc, mask);
if (sad < best_sad) {
@@ -3029,8 +3026,7 @@
const int32_t *mask = x->mask_buf;
const int search_range = 8;
*best_mv = *start_mv;
- clamp_fullmv(best_mv, x->mv_limits.col_min, x->mv_limits.col_max,
- x->mv_limits.row_min, x->mv_limits.row_max);
+ clamp_fullmv(best_mv, &x->mv_limits);
int thissme = obmc_refining_search_sad(x, wsrc, mask, best_mv, sadpb,
search_range, fn_ptr, ref_mv);
if (thissme < INT_MAX)
@@ -3086,8 +3082,6 @@
(void)mask;
(void)mask_stride;
(void)invert_mask;
- (void)minr;
- (void)minc;
(void)cm;
(void)mi_row;
@@ -3095,8 +3089,8 @@
(void)do_reset_fractional_mv;
(void)mv_cost_type;
- bestmv->row = maxr;
- bestmv->col = maxc;
+ bestmv->row = mv_limits.row_max;
+ bestmv->col = mv_limits.col_max;
besterr = 0;
// In the sub-pel motion search, if hp is not used, then the last bit of mv
// has to be 0.
@@ -3113,8 +3107,6 @@
int mask_stride, int invert_mask, int w, int h,
int use_accurate_subpel_search, const int do_reset_fractional_mv) {
COMMON_MV_TEST;
- (void)maxr;
- (void)maxc;
(void)mask;
(void)mask_stride;
(void)invert_mask;
@@ -3125,8 +3117,8 @@
(void)do_reset_fractional_mv;
(void)mv_cost_type;
- bestmv->row = minr;
- bestmv->col = minc;
+ bestmv->row = mv_limits.row_min;
+ bestmv->col = mv_limits.col_min;
besterr = 0;
// In the sub-pel motion search, if hp is not used, then the last bit of mv
// has to be 0.
@@ -3161,7 +3153,7 @@
// ref_mv is used to calculate the cost of the motion vector
const MV ref_mv = kZeroMv;
const int step_param = cpi->mv_step_param;
- const MvLimits tmp_mv_limits = x->mv_limits;
+ const FullMvLimits tmp_mv_limits = x->mv_limits;
const SEARCH_METHODS search_methods = cpi->sf.mv_sf.search_method;
const int do_mesh_search = 0;
const int sadpb = x->sadperbit16;
diff --git a/av1/encoder/mcomp.h b/av1/encoder/mcomp.h
index 1d84370..1078cf3 100644
--- a/av1/encoder/mcomp.h
+++ b/av1/encoder/mcomp.h
@@ -12,6 +12,7 @@
#ifndef AOM_AV1_ENCODER_MCOMP_H_
#define AOM_AV1_ENCODER_MCOMP_H_
+#include "av1/common/mv.h"
#include "av1/encoder/block.h"
#include "aom_dsp/variance.h"
@@ -70,7 +71,7 @@
void av1_init_motion_fpf(search_site_config *cfg, int stride);
void av1_init3smotion_compensation(search_site_config *cfg, int stride);
-void av1_set_mv_search_range(MvLimits *mv_limits, const MV *mv);
+void av1_set_mv_search_range(FullMvLimits *mv_limits, const MV *mv);
int av1_mv_bit_cost(const MV *mv, const MV *ref_mv, const int *mvjcost,
int *mvcost[2], int weight);
@@ -186,10 +187,9 @@
}
}
-static INLINE void set_subpel_mv_search_range(const MvLimits *mv_limits,
- int *col_min, int *col_max,
- int *row_min, int *row_max,
- const MV *ref_mv) {
+static INLINE void av1_set_subpel_mv_search_range(SubpelMvLimits *subpel_limits,
+ const FullMvLimits *mv_limits,
+ const MV *ref_mv) {
const int max_mv = GET_MV_SUBPEL(MAX_FULL_PEL_VAL);
const int minc =
AOMMAX(GET_MV_SUBPEL(mv_limits->col_min), ref_mv->col - max_mv);
@@ -200,10 +200,22 @@
const int maxr =
AOMMIN(GET_MV_SUBPEL(mv_limits->row_max), ref_mv->row + max_mv);
- *col_min = AOMMAX(MV_LOW + 1, minc);
- *col_max = AOMMIN(MV_UPP - 1, maxc);
- *row_min = AOMMAX(MV_LOW + 1, minr);
- *row_max = AOMMIN(MV_UPP - 1, maxr);
+ subpel_limits->col_min = AOMMAX(MV_LOW + 1, minc);
+ subpel_limits->col_max = AOMMIN(MV_UPP - 1, maxc);
+ subpel_limits->row_min = AOMMAX(MV_LOW + 1, minr);
+ subpel_limits->row_max = AOMMIN(MV_UPP - 1, maxr);
+}
+
+static INLINE int av1_is_fullmv_in_range(const FullMvLimits *mv_limits,
+ FULLPEL_MV mv) {
+ return (mv.col >= mv_limits->col_min) && (mv.col <= mv_limits->col_max) &&
+ (mv.row >= mv_limits->row_min) && (mv.row <= mv_limits->row_max);
+}
+
+static INLINE int av1_is_subpelmv_in_range(const SubpelMvLimits *mv_limits,
+ MV mv) {
+ return (mv.col >= mv_limits->col_min) && (mv.col <= mv_limits->col_max) &&
+ (mv.row >= mv_limits->row_min) && (mv.row <= mv_limits->row_max);
}
#ifdef __cplusplus
diff --git a/av1/encoder/motion_search_facade.c b/av1/encoder/motion_search_facade.c
index c8bff71..3c73a40 100644
--- a/av1/encoder/motion_search_facade.c
+++ b/av1/encoder/motion_search_facade.c
@@ -24,7 +24,7 @@
struct buf_2d backup_yv12[MAX_MB_PLANE] = { { 0, 0, 0, 0, 0 } };
int bestsme = INT_MAX;
const int ref = mbmi->ref_frame[ref_idx];
- MvLimits tmp_mv_limits = x->mv_limits;
+ FullMvLimits tmp_mv_limits = x->mv_limits;
const YV12_BUFFER_CONFIG *scaled_ref_frame =
av1_get_scaled_ref_frame(cpi, ref);
const int mi_row = xd->mi_row;
@@ -172,21 +172,15 @@
cpi->sf.mv_sf.use_accurate_subpel_search, 1);
if (try_second) {
- const int minc = AOMMAX(GET_MV_SUBPEL(x->mv_limits.col_min),
- ref_mv.col - MV_MAX);
- const int maxc = AOMMIN(GET_MV_SUBPEL(x->mv_limits.col_max),
- ref_mv.col + MV_MAX);
- const int minr = AOMMAX(GET_MV_SUBPEL(x->mv_limits.row_min),
- ref_mv.row - MV_MAX);
- const int maxr = AOMMIN(GET_MV_SUBPEL(x->mv_limits.row_max),
- ref_mv.row + MV_MAX);
+ SubpelMvLimits subpel_limits;
+ av1_set_subpel_mv_search_range(&subpel_limits, &x->mv_limits,
+ &ref_mv);
MV best_mv = x->best_mv.as_mv;
x->best_mv = x->second_best_mv;
- if (GET_MV_SUBPEL(x->best_mv.as_mv.row) <= maxr &&
- GET_MV_SUBPEL(x->best_mv.as_mv.row) >= minr &&
- GET_MV_SUBPEL(x->best_mv.as_mv.col) <= maxc &&
- GET_MV_SUBPEL(x->best_mv.as_mv.col) >= minc) {
+ if (av1_is_subpelmv_in_range(
+ &subpel_limits,
+ get_mv_from_fullmv(&x->best_mv.as_fullmv))) {
const int this_var = cpi->find_fractional_mv_step(
x, cm, mi_row, mi_col, &ref_mv, cm->allow_high_precision_mv,
x->errorperbit, &cpi->fn_ptr[bsize],
@@ -275,7 +269,7 @@
for (ite = 0; ite < 4; ite++) {
struct buf_2d ref_yv12[2];
int bestsme = INT_MAX;
- MvLimits tmp_mv_limits = x->mv_limits;
+ FullMvLimits 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.
@@ -460,7 +454,7 @@
int_mv *best_int_mv = &x->best_mv;
int search_range = SEARCH_RANGE_8P;
- MvLimits tmp_mv_limits = x->mv_limits;
+ FullMvLimits tmp_mv_limits = x->mv_limits;
// Do compound motion search on the current reference frame.
av1_set_mv_search_range(&x->mv_limits, &ref_mv.as_mv);
diff --git a/av1/encoder/nonrd_pickmode.c b/av1/encoder/nonrd_pickmode.c
index 71e457e..a35e2dc 100644
--- a/av1/encoder/nonrd_pickmode.c
+++ b/av1/encoder/nonrd_pickmode.c
@@ -126,7 +126,7 @@
const MV ref_mv = av1_get_ref_mv(x, mi->ref_mv_idx).as_mv;
MV center_mv;
int dis;
- const MvLimits tmp_mv_limits = x->mv_limits;
+ const FullMvLimits tmp_mv_limits = x->mv_limits;
int rv = 0;
int cost_list[5];
int search_subpel = 1;
diff --git a/av1/encoder/rdopt.c b/av1/encoder/rdopt.c
index c6e5a2e..fdf55df 100644
--- a/av1/encoder/rdopt.c
+++ b/av1/encoder/rdopt.c
@@ -698,13 +698,6 @@
}
}
-static INLINE int mv_check_bounds(const MvLimits *mv_limits, const MV *mv) {
- return GET_MV_RAWPEL(mv->row) < mv_limits->row_min ||
- GET_MV_RAWPEL(mv->row) > mv_limits->row_max ||
- GET_MV_RAWPEL(mv->col) < mv_limits->col_min ||
- GET_MV_RAWPEL(mv->col) > mv_limits->col_max;
-}
-
static INLINE PREDICTION_MODE get_single_mode(PREDICTION_MODE this_mode,
int ref_idx, int is_comp_pred) {
PREDICTION_MODE single_mode;
@@ -940,10 +933,12 @@
// TODO(jingning): this mv clamping function should be block size dependent.
static INLINE void clamp_mv2(MV *mv, const MACROBLOCKD *xd) {
- clamp_mv(mv, xd->mb_to_left_edge - LEFT_TOP_MARGIN,
- xd->mb_to_right_edge + RIGHT_BOTTOM_MARGIN,
- xd->mb_to_top_edge - LEFT_TOP_MARGIN,
- xd->mb_to_bottom_edge + RIGHT_BOTTOM_MARGIN);
+ const SubpelMvLimits mv_limits = { xd->mb_to_left_edge - LEFT_TOP_MARGIN,
+ xd->mb_to_right_edge + RIGHT_BOTTOM_MARGIN,
+ xd->mb_to_top_edge - LEFT_TOP_MARGIN,
+ xd->mb_to_bottom_edge +
+ RIGHT_BOTTOM_MARGIN };
+ clamp_mv(mv, &mv_limits);
}
/* If the current mode shares the same mv with other modes with higher cost,
@@ -1011,7 +1006,8 @@
lower_mv_precision(&out_mv->as_mv, cm->allow_high_precision_mv,
cm->cur_frame_force_integer_mv);
clamp_mv2(&out_mv->as_mv, xd);
- return !mv_check_bounds(&x->mv_limits, &out_mv->as_mv);
+ return av1_is_fullmv_in_range(&x->mv_limits,
+ get_fullmv_from_mv(&out_mv->as_mv));
}
// To use single newmv directly for compound modes, need to clamp the mv to the
@@ -1020,10 +1016,10 @@
static INLINE void clamp_mv_in_range(MACROBLOCK *const x, int_mv *mv,
int ref_idx) {
const int_mv ref_mv = av1_get_ref_mv(x, ref_idx);
- int minc, maxc, minr, maxr;
- set_subpel_mv_search_range(&x->mv_limits, &minc, &maxc, &minr, &maxr,
- &ref_mv.as_mv);
- clamp_mv(&mv->as_mv, minc, maxc, minr, maxr);
+ SubpelMvLimits mv_limits;
+
+ av1_set_subpel_mv_search_range(&mv_limits, &x->mv_limits, &ref_mv.as_mv);
+ clamp_mv(&mv->as_mv, &mv_limits);
}
static int64_t handle_newmv(const AV1_COMP *const cpi, MACROBLOCK *const x,
@@ -2457,7 +2453,7 @@
for (enum IntrabcMotionDirection dir = IBC_MOTION_ABOVE;
dir < IBC_MOTION_DIRECTIONS; ++dir) {
- const MvLimits tmp_mv_limits = x->mv_limits;
+ const FullMvLimits tmp_mv_limits = x->mv_limits;
switch (dir) {
case IBC_MOTION_ABOVE:
x->mv_limits.col_min = (tile->mi_col_start - mi_col) * MI_SIZE;
@@ -2504,7 +2500,8 @@
x->mv_limits = tmp_mv_limits;
if (bestsme == INT_MAX) continue;
const MV dv = get_mv_from_fullmv(&x->best_mv.as_fullmv);
- if (mv_check_bounds(&x->mv_limits, &dv)) continue;
+ if (!av1_is_fullmv_in_range(&x->mv_limits, get_fullmv_from_mv(&dv)))
+ continue;
if (!av1_is_dv_valid(dv, cm, xd, mi_row, mi_col, bsize,
cm->seq_params.mib_size_log2))
continue;
diff --git a/av1/encoder/temporal_filter.c b/av1/encoder/temporal_filter.c
index 180a428..65da401 100644
--- a/av1/encoder/temporal_filter.c
+++ b/av1/encoder/temporal_filter.c
@@ -80,7 +80,7 @@
MACROBLOCKD *const mbd = &mb->e_mbd;
const struct buf_2d ori_src_buf = mb->plane[0].src;
const struct buf_2d ori_pre_buf = mbd->plane[0].pre[0];
- const MvLimits ori_mv_limits = mb->mv_limits;
+ const FullMvLimits ori_mv_limits = mb->mv_limits;
const MV_COST_TYPE ori_mv_cost_type = mb->mv_cost_type;
// Parameters used for motion search.
diff --git a/av1/encoder/tpl_model.c b/av1/encoder/tpl_model.c
index b6ba4bf..e80645f 100644
--- a/av1/encoder/tpl_model.c
+++ b/av1/encoder/tpl_model.c
@@ -134,7 +134,7 @@
int distortion;
uint32_t sse;
int cost_list[5];
- const MvLimits tmp_mv_limits = x->mv_limits;
+ const FullMvLimits tmp_mv_limits = x->mv_limits;
FULLPEL_MV start_mv = get_fullmv_from_mv(¢er_mv);
// Setup frame pointers