Clean up mcomp.c
This CL contains the following changes:
- MV is now split into two structs: MV and FULLPEL_MV. MV is used to
hold motion vectors in 1/8-pel precision. FULLPEL_MV is used to hold
motion vectors in fullpel precision.
- To facilitate the containment of MV and FULLPEL_MV, int_mv is now a
union of int, MV, and FULLPEL_MV
- The names of functional parameters is now more consistent. For
instance, the starting point of the motion search is now always
called start_mv. The mv with respect to which we calculate the mv
cost is now always called ref_mv.
- Some typos are fixed.
Change-Id: Iad00a8e2f3bc26aa770449332d182610ac86f291
diff --git a/av1/common/mv.h b/av1/common/mv.h
index fe821ee..adbe779 100644
--- a/av1/common/mv.h
+++ b/av1/common/mv.h
@@ -21,17 +21,28 @@
#endif
#define INVALID_MV 0x80008000
+#define GET_MV_RAWPEL(x) ((x) >> 3)
+#define GET_MV_SUBPEL(x) ((x)*8)
+// The motion vector in units of full pixel
+typedef struct fullpel_mv {
+ int16_t row;
+ int16_t col;
+} FULLPEL_MV;
+
+// The motion vector in units of 1/8-pel
typedef struct mv {
int16_t row;
int16_t col;
} MV;
static const MV kZeroMv = { 0, 0 };
+static const FULLPEL_MV kZeroFullMv = { 0, 0 };
typedef union int_mv {
uint32_t as_int;
MV as_mv;
+ FULLPEL_MV as_fullmv;
} int_mv; /* facilitates faster equality tests and copies */
typedef struct mv32 {
@@ -39,6 +50,18 @@
int32_t col;
} MV32;
+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) };
+ return full_mv;
+}
+
+static AOM_INLINE MV get_mv_from_fullmv(const FULLPEL_MV *full_mv) {
+ const MV subpel_mv = { (int16_t)GET_MV_SUBPEL(full_mv->row),
+ (int16_t)GET_MV_SUBPEL(full_mv->col) };
+ return subpel_mv;
+}
+
// Bits of precision used for the model
#define WARPEDMODEL_PREC_BITS 16
#define WARPEDMODEL_ROW3HOMO_PREC_BITS 16
@@ -293,6 +316,12 @@
mv->row = clamp(mv->row, min_row, max_row);
}
+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);
+}
+
#ifdef __cplusplus
} // extern "C"
#endif
diff --git a/av1/encoder/context_tree.h b/av1/encoder/context_tree.h
index ca311cc..24f002a 100644
--- a/av1/encoder/context_tree.h
+++ b/av1/encoder/context_tree.h
@@ -77,7 +77,7 @@
int index;
// Simple motion search_features
- MV mv_ref_fulls[REF_FRAMES];
+ FULLPEL_MV start_mvs[REF_FRAMES];
unsigned int sms_none_feat[2];
unsigned int sms_rect_feat[8];
int sms_none_valid;
diff --git a/av1/encoder/encodeframe.c b/av1/encoder/encodeframe.c
index 6c8d307..9881a25 100644
--- a/av1/encoder/encodeframe.c
+++ b/av1/encoder/encodeframe.c
@@ -804,9 +804,9 @@
av1_get_sby_perpixel_variance(cpi, &x->plane[0].src, bsize);
}
if (use_pb_simple_motion_pred_sse(cpi)) {
- const MV ref_mv_full = { .row = 0, .col = 0 };
+ const FULLPEL_MV start_mv = kZeroFullMv;
unsigned int var = 0;
- av1_simple_motion_sse_var(cpi, x, mi_row, mi_col, bsize, ref_mv_full, 0,
+ av1_simple_motion_sse_var(cpi, x, mi_row, mi_col, bsize, start_mv, 0,
&x->simple_motion_pred_sse, &var);
}
@@ -3244,10 +3244,10 @@
if (use_pb_simple_motion_pred_sse(cpi) &&
pb_simple_motion_pred_sse == UINT_MAX) {
- const MV ref_mv_full = { .row = 0, .col = 0 };
+ const FULLPEL_MV start_mv = kZeroFullMv;
unsigned int var = 0;
- av1_simple_motion_sse_var(cpi, x, mi_row, mi_col, bsize, ref_mv_full, 0,
+ av1_simple_motion_sse_var(cpi, x, mi_row, mi_col, bsize, start_mv, 0,
&pb_simple_motion_pred_sse, &var);
}
diff --git a/av1/encoder/firstpass.c b/av1/encoder/firstpass.c
index 8a1be0e..d747bf0 100644
--- a/av1/encoder/firstpass.c
+++ b/av1/encoder/firstpass.c
@@ -17,13 +17,13 @@
#include "config/aom_scale_rtcd.h"
#include "aom_dsp/aom_dsp_common.h"
+#include "aom_dsp/variance.h"
#include "aom_mem/aom_mem.h"
#include "aom_ports/mem.h"
#include "aom_ports/system_state.h"
#include "aom_scale/aom_scale.h"
#include "aom_scale/yv12config.h"
-#include "aom_dsp/variance.h"
#include "av1/common/entropymv.h"
#include "av1/common/quant_common.h"
#include "av1/common/reconinter.h" // av1_setup_dst_planes()
@@ -222,7 +222,7 @@
const MV *ref_mv, MV *best_mv,
int *best_motion_err) {
MACROBLOCKD *const xd = &x->e_mbd;
- MV ref_mv_full = { ref_mv->row >> 3, ref_mv->col >> 3 };
+ FULLPEL_MV start_mv = get_fullmv_from_mv(ref_mv);
int tmp_err;
const BLOCK_SIZE bsize = xd->mi[0]->sb_type;
aom_variance_fn_ptr_t v_fn_ptr = cpi->fn_ptr[bsize];
@@ -232,14 +232,15 @@
int cost_list[5];
tmp_err = av1_full_pixel_search(
- cpi, x, bsize, &ref_mv_full, step_param, 0, NSTEP, 0, x->sadperbit16,
+ cpi, x, bsize, &start_mv, step_param, 0, NSTEP, 0, x->sadperbit16,
cond_cost_list(cpi, cost_list), ref_mv, INT_MAX, 0,
(MI_SIZE * xd->mi_col), (MI_SIZE * xd->mi_row), 0,
&cpi->ss_cfg[SS_CFG_FPF], 0);
if (tmp_err < INT_MAX)
- tmp_err = av1_get_mvpred_var(x, &x->best_mv.as_mv, ref_mv, &v_fn_ptr, 0) +
- new_mv_mode_penalty;
+ tmp_err =
+ av1_get_mvpred_var(x, &x->best_mv.as_fullmv, ref_mv, &v_fn_ptr, 0) +
+ new_mv_mode_penalty;
if (tmp_err < *best_motion_err) {
*best_motion_err = tmp_err;
diff --git a/av1/encoder/mcomp.c b/av1/encoder/mcomp.c
index 7ef27e9..980c0bb 100644
--- a/av1/encoder/mcomp.c
+++ b/av1/encoder/mcomp.c
@@ -51,20 +51,22 @@
#define SAD_LAMBDA_HDRES 8 // Used by mvsad_err_cost during full pixel search
static INLINE const uint8_t *get_buf_from_mv(const struct buf_2d *buf,
- const MV *mv) {
+ const FULLPEL_MV *mv) {
return &buf->buf[mv->row * buf->stride + mv->col];
}
void av1_set_mv_search_range(MvLimits *mv_limits, const MV *mv) {
- int col_min = (mv->col >> 3) - MAX_FULL_PEL_VAL + (mv->col & 7 ? 1 : 0);
- int row_min = (mv->row >> 3) - MAX_FULL_PEL_VAL + (mv->row & 7 ? 1 : 0);
- int col_max = (mv->col >> 3) + MAX_FULL_PEL_VAL;
- int row_max = (mv->row >> 3) + MAX_FULL_PEL_VAL;
+ int col_min =
+ GET_MV_RAWPEL(mv->col) - MAX_FULL_PEL_VAL + (mv->col & 7 ? 1 : 0);
+ int row_min =
+ GET_MV_RAWPEL(mv->row) - MAX_FULL_PEL_VAL + (mv->row & 7 ? 1 : 0);
+ int col_max = GET_MV_RAWPEL(mv->col) + MAX_FULL_PEL_VAL;
+ int row_max = GET_MV_RAWPEL(mv->row) + MAX_FULL_PEL_VAL;
- col_min = AOMMAX(col_min, (MV_LOW >> 3) + 1);
- row_min = AOMMAX(row_min, (MV_LOW >> 3) + 1);
- col_max = AOMMIN(col_max, (MV_UPP >> 3) - 1);
- row_max = AOMMIN(row_max, (MV_UPP >> 3) - 1);
+ col_min = AOMMAX(col_min, GET_MV_RAWPEL(MV_LOW) + 1);
+ row_min = AOMMAX(row_min, GET_MV_RAWPEL(MV_LOW) + 1);
+ col_max = AOMMIN(col_max, GET_MV_RAWPEL(MV_UPP) - 1);
+ row_max = AOMMIN(row_max, GET_MV_RAWPEL(MV_UPP) - 1);
// Get intersection of UMV window and valid MV window to reduce # of checks
// in diamond search.
@@ -99,19 +101,19 @@
// is defined as the rate required to encode diff * weight, rounded to the
// nearest 2 ** 7.
// This is NOT used during motion compensation.
-int av1_mv_bit_cost(const MV *mv, const MV *ref, const int *mvjcost,
+int av1_mv_bit_cost(const MV *mv, const MV *ref_mv, const int *mvjcost,
int *mvcost[2], int weight) {
- const MV diff = { mv->row - ref->row, mv->col - ref->col };
+ const MV diff = { mv->row - ref_mv->row, mv->col - ref_mv->col };
return ROUND_POWER_OF_TWO(mv_cost(&diff, mvjcost, mvcost) * weight, 7);
}
// Returns the cost of using the current mv during the motion search. This is
// used when var is used as the error metric.
#define PIXEL_TRANSFORM_ERROR_SCALE 4
-static int mv_err_cost(const MV *mv, const MV *ref, const int *mvjcost,
+static int mv_err_cost(const MV *mv, const MV *ref_mv, const int *mvjcost,
int *mvcost[2], int error_per_bit,
MV_COST_TYPE mv_cost_type) {
- const MV diff = { mv->row - ref->row, mv->col - ref->col };
+ const MV diff = { mv->row - ref_mv->row, mv->col - ref_mv->col };
const MV abs_diff = { abs(diff.row), abs(diff.col) };
switch (mv_cost_type) {
@@ -137,9 +139,10 @@
// Returns the cost of using the current mv during the motion search. This is
// only used during full pixel motion search when sad is used as the error
// metric.
-static int mvsad_err_cost(const MACROBLOCK *x, const MV *mv, const MV *ref,
- int sad_per_bit) {
- const MV diff = { (mv->row - ref->row) * 8, (mv->col - ref->col) * 8 };
+static int mvsad_err_cost(const MACROBLOCK *x, const FULLPEL_MV *mv,
+ const FULLPEL_MV *ref_mv, int sad_per_bit) {
+ const MV diff = { GET_MV_SUBPEL(mv->row - ref_mv->row),
+ GET_MV_SUBPEL(mv->col - ref_mv->col) };
const MV_COST_TYPE mv_cost_type = x->mv_cost_type;
switch (mv_cost_type) {
case MV_COST_ENTROPY:
@@ -169,7 +172,7 @@
for (int radius = MAX_FIRST_STEP; radius > 0; radius /= 2) {
int num_search_pts = 8;
- const MV ss_mvs[13] = {
+ const FULLPEL_MV ss_mvs[13] = {
{ 0, 0 }, { -radius, 0 }, { radius, 0 },
{ 0, -radius }, { 0, radius }, { -radius, -radius },
{ radius, radius }, { -radius, radius }, { radius, -radius },
@@ -203,7 +206,7 @@
int num_search_pts = 12;
if (radius == 1) num_search_pts = 8;
- const MV ss_mvs[13] = {
+ const FULLPEL_MV ss_mvs[13] = {
{ 0, 0 },
{ -radius, 0 },
{ radius, 0 },
@@ -245,7 +248,7 @@
tan_radius = radius;
num_search_pts = 8;
}
- const MV ss_mvs[13] = {
+ const FULLPEL_MV ss_mvs[13] = {
{ 0, 0 },
{ -radius, 0 },
{ radius, 0 },
@@ -1155,36 +1158,37 @@
((col + range) <= mv_limits->col_max);
}
-static INLINE int is_mv_in(const MvLimits *mv_limits, const MV *mv) {
+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) { \
- if (use_mvcost) \
- thissad += mvsad_err_cost(x, &this_mv, &fcenter_mv, sad_per_bit); \
- if (thissad < bestsad) { \
- bestsad = thissad; \
- best_site = i; \
- } \
- } \
+#define CHECK_BETTER \
+ { \
+ if (thissad < bestsad) { \
+ if (use_mvcost) \
+ thissad += mvsad_err_cost(x, &this_mv, &full_ref_mv, sad_per_bit); \
+ if (thissad < bestsad) { \
+ bestsad = thissad; \
+ best_site = i; \
+ } \
+ } \
}
#define MAX_PATTERN_SCALES 11
-#define MAX_PATTERN_CANDIDATES 8 // max number of canddiates per scale
+#define MAX_PATTERN_CANDIDATES 8 // max number of candidates per scale
#define PATTERN_CANDIDATES_REF 3 // number of refinement candidates
// Calculate and return a sad+mvcost list around an integer best pel.
static INLINE void calc_int_cost_list(const MACROBLOCK *x,
const MV *const ref_mv, int sadpb,
const aom_variance_fn_ptr_t *fn_ptr,
- const MV *best_mv, int *cost_list) {
+ const FULLPEL_MV *best_mv,
+ int *cost_list) {
static const MV neighbors[4] = { { 0, -1 }, { 1, 0 }, { 0, 1 }, { -1, 0 } };
const struct buf_2d *const what = &x->plane[0].src;
const struct buf_2d *const in_what = &x->e_mbd.plane[0].pre[0];
- const MV fcenter_mv = { ref_mv->row >> 3, ref_mv->col >> 3 };
+ const FULLPEL_MV full_ref_mv = get_fullmv_from_mv(ref_mv);
const int br = best_mv->row;
const int bc = best_mv->col;
const MV_COST_TYPE mv_cost_type = x->mv_cost_type;
@@ -1193,32 +1197,32 @@
cost_list[0] =
fn_ptr->vf(what->buf, what->stride, get_buf_from_mv(in_what, best_mv),
in_what->stride, &sse) +
- mvsad_err_cost(x, best_mv, &fcenter_mv, sadpb);
+ mvsad_err_cost(x, best_mv, &full_ref_mv, sadpb);
if (check_bounds(&x->mv_limits, br, bc, 1)) {
for (int i = 0; i < 4; i++) {
- const MV neighbor_mv = { br + neighbors[i].row, bc + neighbors[i].col };
- const MV neighbor_mv_subpel = { neighbor_mv.row * 8,
- neighbor_mv.col * 8 };
+ const FULLPEL_MV neighbor_mv = { br + neighbors[i].row,
+ bc + neighbors[i].col };
+ const MV sub_neighbor_mv = get_mv_from_fullmv(&neighbor_mv);
cost_list[i + 1] =
fn_ptr->vf(what->buf, what->stride,
get_buf_from_mv(in_what, &neighbor_mv), in_what->stride,
&sse) +
- mv_err_cost(&neighbor_mv_subpel, ref_mv, x->nmv_vec_cost,
+ mv_err_cost(&sub_neighbor_mv, ref_mv, x->nmv_vec_cost,
x->mv_cost_stack, x->errorperbit, mv_cost_type);
}
} else {
for (int i = 0; i < 4; i++) {
- const MV neighbor_mv = { br + neighbors[i].row, bc + neighbors[i].col };
+ const FULLPEL_MV neighbor_mv = { br + neighbors[i].row,
+ bc + neighbors[i].col };
if (!is_mv_in(&x->mv_limits, &neighbor_mv)) {
cost_list[i + 1] = INT_MAX;
} else {
- const MV neighbor_mv_subpel = { neighbor_mv.row * 8,
- neighbor_mv.col * 8 };
+ const MV sub_neighbor_mv = get_mv_from_fullmv(&neighbor_mv);
cost_list[i + 1] =
fn_ptr->vf(what->buf, what->stride,
get_buf_from_mv(in_what, &neighbor_mv), in_what->stride,
&sse) +
- mv_err_cost(&neighbor_mv_subpel, ref_mv, x->nmv_vec_cost,
+ mv_err_cost(&sub_neighbor_mv, ref_mv, x->nmv_vec_cost,
x->mv_cost_stack, x->errorperbit, mv_cost_type);
}
}
@@ -1228,27 +1232,29 @@
static INLINE void calc_int_sad_list(const MACROBLOCK *x,
const MV *const ref_mv, int sadpb,
const aom_variance_fn_ptr_t *fn_ptr,
- const MV *best_mv, int *cost_list,
+ const FULLPEL_MV *best_mv, int *cost_list,
const int use_mvcost, const int bestsad) {
static const MV neighbors[4] = { { 0, -1 }, { 1, 0 }, { 0, 1 }, { -1, 0 } };
const struct buf_2d *const what = &x->plane[0].src;
const struct buf_2d *const in_what = &x->e_mbd.plane[0].pre[0];
const int br = best_mv->row;
const int bc = best_mv->col;
- const MV ref_mv_fullpel = { ref_mv->row >> 3, ref_mv->col >> 3 };
+ const FULLPEL_MV full_ref_mv = get_fullmv_from_mv(ref_mv);
if (cost_list[0] == INT_MAX) {
cost_list[0] = bestsad;
if (check_bounds(&x->mv_limits, br, bc, 1)) {
for (int i = 0; i < 4; i++) {
- const MV this_mv = { br + neighbors[i].row, bc + neighbors[i].col };
+ const FULLPEL_MV this_mv = { br + neighbors[i].row,
+ bc + neighbors[i].col };
cost_list[i + 1] =
fn_ptr->sdf(what->buf, what->stride,
get_buf_from_mv(in_what, &this_mv), in_what->stride);
}
} else {
for (int i = 0; i < 4; i++) {
- const MV this_mv = { br + neighbors[i].row, bc + neighbors[i].col };
+ const FULLPEL_MV this_mv = { br + neighbors[i].row,
+ bc + neighbors[i].col };
if (!is_mv_in(&x->mv_limits, &this_mv))
cost_list[i + 1] = INT_MAX;
else
@@ -1260,10 +1266,10 @@
} else {
if (use_mvcost) {
for (int i = 0; i < 4; i++) {
- const MV this_mv = { br + neighbors[i].row, bc + neighbors[i].col };
+ const FULLPEL_MV this_mv = { br + neighbors[i].row,
+ bc + neighbors[i].col };
if (cost_list[i + 1] != INT_MAX) {
- cost_list[i + 1] +=
- mvsad_err_cost(x, &this_mv, &ref_mv_fullpel, sadpb);
+ cost_list[i + 1] += mvsad_err_cost(x, &this_mv, &full_ref_mv, sadpb);
}
}
}
@@ -1274,11 +1280,10 @@
// Each scale can have a different number of candidates and shape of
// candidates as indicated in the num_candidates and candidates arrays
// passed into this function
-//
static int pattern_search(
- MACROBLOCK *x, MV *start_mv, int search_param, int sad_per_bit,
+ MACROBLOCK *x, FULLPEL_MV *start_mv, int search_param, int sad_per_bit,
int do_init_search, int *cost_list, const aom_variance_fn_ptr_t *vfp,
- int use_mvcost, const MV *center_mv,
+ int use_mvcost, const MV *ref_mv,
const int num_candidates[MAX_PATTERN_SCALES],
const MV candidates[MAX_PATTERN_SCALES][MAX_PATTERN_CANDIDATES]) {
const MACROBLOCKD *const xd = &x->e_mbd;
@@ -1293,12 +1298,12 @@
int bestsad = INT_MAX;
int thissad;
int k = -1;
- const MV fcenter_mv = { center_mv->row >> 3, center_mv->col >> 3 };
+ const FULLPEL_MV full_ref_mv = get_fullmv_from_mv(ref_mv);
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_mv(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.col_min, x->mv_limits.col_max,
+ x->mv_limits.row_min, x->mv_limits.row_max);
br = start_mv->row;
bc = start_mv->col;
if (cost_list != NULL) {
@@ -1309,9 +1314,9 @@
// Work out the start point for the search
bestsad = vfp->sdf(what->buf, what->stride,
get_buf_from_mv(in_what, start_mv), in_what->stride) +
- mvsad_err_cost(x, start_mv, &fcenter_mv, sad_per_bit);
+ mvsad_err_cost(x, start_mv, &full_ref_mv, sad_per_bit);
- // Search all possible scales upto the search param around the center point
+ // Search all possible scales up to the search param around the center point
// pick the scale of the point that is best as the starting scale of
// further steps around it.
if (do_init_search) {
@@ -1321,8 +1326,8 @@
int best_site = -1;
if (check_bounds(&x->mv_limits, br, bc, 1 << t)) {
for (i = 0; i < num_candidates[t]; i++) {
- const MV this_mv = { br + candidates[t][i].row,
- bc + candidates[t][i].col };
+ const FULLPEL_MV this_mv = { br + candidates[t][i].row,
+ bc + candidates[t][i].col };
thissad =
vfp->sdf(what->buf, what->stride,
get_buf_from_mv(in_what, &this_mv), in_what->stride);
@@ -1330,8 +1335,8 @@
}
} else {
for (i = 0; i < num_candidates[t]; i++) {
- const MV this_mv = { br + candidates[t][i].row,
- bc + candidates[t][i].col };
+ 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;
thissad =
vfp->sdf(what->buf, what->stride,
@@ -1364,8 +1369,8 @@
if (!do_init_search || s != best_init_s) {
if (check_bounds(&x->mv_limits, br, bc, 1 << s)) {
for (i = 0; i < num_candidates[s]; i++) {
- const MV this_mv = { br + candidates[s][i].row,
- bc + candidates[s][i].col };
+ const FULLPEL_MV this_mv = { br + candidates[s][i].row,
+ bc + candidates[s][i].col };
thissad =
vfp->sdf(what->buf, what->stride,
get_buf_from_mv(in_what, &this_mv), in_what->stride);
@@ -1373,8 +1378,8 @@
}
} else {
for (i = 0; i < num_candidates[s]; i++) {
- const MV this_mv = { br + candidates[s][i].row,
- bc + candidates[s][i].col };
+ 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;
thissad =
vfp->sdf(what->buf, what->stride,
@@ -1401,7 +1406,7 @@
if (check_bounds(&x->mv_limits, br, bc, 1 << s)) {
for (i = 0; i < PATTERN_CANDIDATES_REF; i++) {
- const MV this_mv = {
+ const FULLPEL_MV this_mv = {
br + candidates[s][next_chkpts_indices[i]].row,
bc + candidates[s][next_chkpts_indices[i]].col
};
@@ -1412,7 +1417,7 @@
}
} else {
for (i = 0; i < PATTERN_CANDIDATES_REF; i++) {
- const MV this_mv = {
+ const FULLPEL_MV this_mv = {
br + candidates[s][next_chkpts_indices[i]].row,
bc + candidates[s][next_chkpts_indices[i]].col
};
@@ -1438,8 +1443,8 @@
if (!do_init_search || s != best_init_s) {
if (check_bounds(&x->mv_limits, br, bc, 1 << s)) {
for (i = 0; i < num_candidates[s]; i++) {
- const MV this_mv = { br + candidates[s][i].row,
- bc + candidates[s][i].col };
+ const FULLPEL_MV this_mv = { br + candidates[s][i].row,
+ bc + candidates[s][i].col };
cost_list[i + 1] = thissad =
vfp->sdf(what->buf, what->stride,
get_buf_from_mv(in_what, &this_mv), in_what->stride);
@@ -1447,8 +1452,8 @@
}
} else {
for (i = 0; i < num_candidates[s]; i++) {
- const MV this_mv = { br + candidates[s][i].row,
- bc + candidates[s][i].col };
+ 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;
cost_list[i + 1] = thissad =
vfp->sdf(what->buf, what->stride,
@@ -1475,7 +1480,7 @@
if (check_bounds(&x->mv_limits, br, bc, 1 << s)) {
for (i = 0; i < PATTERN_CANDIDATES_REF; i++) {
- const MV this_mv = {
+ const FULLPEL_MV this_mv = {
br + candidates[s][next_chkpts_indices[i]].row,
bc + candidates[s][next_chkpts_indices[i]].col
};
@@ -1486,7 +1491,7 @@
}
} else {
for (i = 0; i < PATTERN_CANDIDATES_REF; i++) {
- const MV this_mv = {
+ const FULLPEL_MV this_mv = {
br + candidates[s][next_chkpts_indices[i]].row,
bc + candidates[s][next_chkpts_indices[i]].col
};
@@ -1517,13 +1522,12 @@
// cost_list[3]: cost/sad at delta { 0, 1} (right) from the best integer pel
// cost_list[4]: cost/sad at delta {-1, 0} (top) from the best integer pel
if (cost_list) {
- const MV best_int_mv = { br, bc };
+ const FULLPEL_MV best_int_mv = { br, bc };
if (last_is_4) {
- calc_int_sad_list(x, center_mv, sad_per_bit, vfp, &best_int_mv, cost_list,
+ calc_int_sad_list(x, ref_mv, sad_per_bit, vfp, &best_int_mv, cost_list,
use_mvcost, bestsad);
} else {
- calc_int_cost_list(x, center_mv, sad_per_bit, vfp, &best_int_mv,
- cost_list);
+ calc_int_cost_list(x, ref_mv, sad_per_bit, vfp, &best_int_mv, cost_list);
}
}
x->best_mv.as_mv.row = br;
@@ -1531,13 +1535,13 @@
return bestsad;
}
-int av1_get_mvpred_var(const MACROBLOCK *x, const MV *best_mv,
- const MV *center_mv, const aom_variance_fn_ptr_t *vfp,
+int av1_get_mvpred_var(const MACROBLOCK *x, const FULLPEL_MV *best_mv,
+ const MV *ref_mv, const aom_variance_fn_ptr_t *vfp,
int use_var) {
const MACROBLOCKD *const xd = &x->e_mbd;
const struct buf_2d *const what = &x->plane[0].src;
const struct buf_2d *const in_what = &xd->plane[0].pre[0];
- const MV mv = { best_mv->row * 8, best_mv->col * 8 };
+ const MV mv = get_mv_from_fullmv(best_mv);
const MV_COST_TYPE mv_cost_type = x->mv_cost_type;
unsigned int sse, var;
@@ -1546,38 +1550,38 @@
if (!use_var) var = sse;
- return var + mv_err_cost(&mv, center_mv, x->nmv_vec_cost, x->mv_cost_stack,
+ return var + mv_err_cost(&mv, ref_mv, x->nmv_vec_cost, x->mv_cost_stack,
x->errorperbit, mv_cost_type);
}
-int av1_get_mvpred_av_var(const MACROBLOCK *x, const MV *best_mv,
- const MV *center_mv, const uint8_t *second_pred,
+int av1_get_mvpred_av_var(const MACROBLOCK *x, const FULLPEL_MV *best_mv,
+ const MV *ref_mv, const uint8_t *second_pred,
const aom_variance_fn_ptr_t *vfp,
const struct buf_2d *src, const struct buf_2d *pre,
int use_mvcost) {
const struct buf_2d *const what = src;
const struct buf_2d *const in_what = pre;
- const MV mv = { best_mv->row * 8, best_mv->col * 8 };
+ const MV mv = get_mv_from_fullmv(best_mv);
const MV_COST_TYPE mv_cost_type = x->mv_cost_type;
unsigned int unused;
return vfp->svaf(get_buf_from_mv(in_what, best_mv), in_what->stride, 0, 0,
what->buf, what->stride, &unused, second_pred) +
(use_mvcost
- ? mv_err_cost(&mv, center_mv, x->nmv_vec_cost, x->mv_cost_stack,
+ ? mv_err_cost(&mv, ref_mv, x->nmv_vec_cost, x->mv_cost_stack,
x->errorperbit, mv_cost_type)
: 0);
}
-int av1_get_mvpred_mask_var(const MACROBLOCK *x, const MV *best_mv,
- const MV *center_mv, const uint8_t *second_pred,
+int av1_get_mvpred_mask_var(const MACROBLOCK *x, const FULLPEL_MV *best_mv,
+ const MV *ref_mv, const uint8_t *second_pred,
const uint8_t *mask, int mask_stride,
int invert_mask, const aom_variance_fn_ptr_t *vfp,
const struct buf_2d *src, const struct buf_2d *pre,
int use_mvcost) {
const struct buf_2d *const what = src;
const struct buf_2d *const in_what = pre;
- const MV mv = { best_mv->row * 8, best_mv->col * 8 };
+ const MV mv = get_mv_from_fullmv(best_mv);
const MV_COST_TYPE mv_cost_type = x->mv_cost_type;
unsigned int unused;
@@ -1585,15 +1589,30 @@
get_buf_from_mv(in_what, best_mv), in_what->stride,
second_pred, mask, mask_stride, invert_mask, &unused) +
(use_mvcost
- ? mv_err_cost(&mv, center_mv, x->nmv_vec_cost, x->mv_cost_stack,
+ ? mv_err_cost(&mv, ref_mv, x->nmv_vec_cost, x->mv_cost_stack,
x->errorperbit, mv_cost_type)
: 0);
}
-int av1_hex_search(MACROBLOCK *x, MV *start_mv, int search_param,
+// For the following foo_search, the input arguments are:
+// x: The struct used to hold a bunch of random configs.
+// start_mv: where we are starting our motion search
+// search_param: how many steps to skip in our motion search. For example,
+// a value 3 suggests that 3 search steps have already taken place prior to
+// this function call, so we jump directly to step 4 of the search process
+// sad_per_bit: a multiplier used to convert rate to sad cost
+// do_init_search: if on, do an initial search of all possible scales around the
+// start_mv, and then pick the best scale.
+// cond_list: used to hold the cost around the best full mv so we can use it to
+// speed up subpel search later.
+// vfp: a function pointer to the simd function so we can compute the cost
+// efficiently
+// use_mv_cost: whether we want include the cost of encoding a mv in our search.
+// ref_mf: the reference mv used to compute the mv cost
+int av1_hex_search(MACROBLOCK *x, FULLPEL_MV *start_mv, int search_param,
int sad_per_bit, int do_init_search, int *cost_list,
const aom_variance_fn_ptr_t *vfp, int use_mvcost,
- const MV *center_mv) {
+ const MV *ref_mv) {
// First scale has 8-closest points, the rest have 6 points in hex shape
// at increasing scales
static const int hex_num_candidates[MAX_PATTERN_SCALES] = { 8, 6, 6, 6, 6, 6,
@@ -1622,14 +1641,14 @@
};
/* clang-format on */
return pattern_search(x, start_mv, search_param, sad_per_bit, do_init_search,
- cost_list, vfp, use_mvcost, center_mv,
- hex_num_candidates, hex_candidates);
+ cost_list, vfp, use_mvcost, ref_mv, hex_num_candidates,
+ hex_candidates);
}
-static int bigdia_search(MACROBLOCK *x, MV *start_mv, int search_param,
+static int bigdia_search(MACROBLOCK *x, FULLPEL_MV *start_mv, int search_param,
int sad_per_bit, int do_init_search, int *cost_list,
const aom_variance_fn_ptr_t *vfp, int use_mvcost,
- const MV *center_mv) {
+ const MV *ref_mv) {
// First scale has 4-closest points, the rest have 8 points in diamond
// shape at increasing scales
static const int bigdia_num_candidates[MAX_PATTERN_SCALES] = {
@@ -1663,14 +1682,14 @@
};
/* clang-format on */
return pattern_search(x, start_mv, search_param, sad_per_bit, do_init_search,
- cost_list, vfp, use_mvcost, center_mv,
+ cost_list, vfp, use_mvcost, ref_mv,
bigdia_num_candidates, bigdia_candidates);
}
-static int square_search(MACROBLOCK *x, MV *start_mv, int search_param,
+static int square_search(MACROBLOCK *x, FULLPEL_MV *start_mv, int search_param,
int sad_per_bit, int do_init_search, int *cost_list,
const aom_variance_fn_ptr_t *vfp, int use_mvcost,
- const MV *center_mv) {
+ const MV *ref_mv) {
// All scales have 8 closest points in square shape
static const int square_num_candidates[MAX_PATTERN_SCALES] = {
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
@@ -1704,41 +1723,43 @@
};
/* clang-format on */
return pattern_search(x, start_mv, search_param, sad_per_bit, do_init_search,
- cost_list, vfp, use_mvcost, center_mv,
+ cost_list, vfp, use_mvcost, ref_mv,
square_num_candidates, square_candidates);
}
-static int fast_hex_search(MACROBLOCK *x, MV *ref_mv, int search_param,
- int sad_per_bit,
+static int fast_hex_search(MACROBLOCK *x, FULLPEL_MV *start_mv,
+ int search_param, int sad_per_bit,
int do_init_search, // must be zero for fast_hex
int *cost_list, const aom_variance_fn_ptr_t *vfp,
- int use_mvcost, const MV *center_mv) {
- return av1_hex_search(x, ref_mv, AOMMAX(MAX_MVSEARCH_STEPS - 2, search_param),
- sad_per_bit, do_init_search, cost_list, vfp, use_mvcost,
- center_mv);
+ int use_mvcost, const MV *ref_mv) {
+ return av1_hex_search(
+ x, start_mv, AOMMAX(MAX_MVSEARCH_STEPS - 2, search_param), sad_per_bit,
+ do_init_search, cost_list, vfp, use_mvcost, ref_mv);
}
-static int fast_dia_search(MACROBLOCK *x, MV *ref_mv, int search_param,
- int sad_per_bit, int do_init_search, int *cost_list,
+static int fast_dia_search(MACROBLOCK *x, FULLPEL_MV *start_mv,
+ int search_param, int sad_per_bit,
+ int do_init_search, int *cost_list,
const aom_variance_fn_ptr_t *vfp, int use_mvcost,
- const MV *center_mv) {
- return bigdia_search(x, ref_mv, AOMMAX(MAX_MVSEARCH_STEPS - 2, search_param),
- sad_per_bit, do_init_search, cost_list, vfp, use_mvcost,
- center_mv);
+ const MV *ref_mv) {
+ return bigdia_search(
+ x, start_mv, AOMMAX(MAX_MVSEARCH_STEPS - 2, search_param), sad_per_bit,
+ do_init_search, cost_list, vfp, use_mvcost, ref_mv);
}
#undef CHECK_BETTER
-// Exhuastive motion search around a given centre position with a given
+// Exhaustive motion search around a given centre position with a given
// step size.
-static int exhuastive_mesh_search(MACROBLOCK *x, MV *ref_mv, MV *best_mv,
- int range, int step, int sad_per_bit,
+static int exhuastive_mesh_search(MACROBLOCK *x, FULLPEL_MV *ref_mv,
+ FULLPEL_MV *best_mv, int range, int step,
+ int sad_per_bit,
const aom_variance_fn_ptr_t *fn_ptr,
- const MV *center_mv) {
+ const FULLPEL_MV *start_mv) {
const MACROBLOCKD *const xd = &x->e_mbd;
const struct buf_2d *const what = &x->plane[0].src;
const struct buf_2d *const in_what = &xd->plane[0].pre[0];
- MV fcenter_mv = { center_mv->row, center_mv->col };
+ FULLPEL_MV start_mv_ = *start_mv;
unsigned int best_sad = INT_MAX;
int r, c, i;
int start_col, end_col, start_row, end_row;
@@ -1746,23 +1767,23 @@
assert(step >= 1);
- clamp_mv(&fcenter_mv, x->mv_limits.col_min, x->mv_limits.col_max,
- x->mv_limits.row_min, x->mv_limits.row_max);
- *best_mv = fcenter_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);
+ *best_mv = start_mv_;
best_sad =
- fn_ptr->sdf(what->buf, what->stride,
- get_buf_from_mv(in_what, &fcenter_mv), in_what->stride) +
- mvsad_err_cost(x, &fcenter_mv, ref_mv, sad_per_bit);
- start_row = AOMMAX(-range, x->mv_limits.row_min - fcenter_mv.row);
- start_col = AOMMAX(-range, x->mv_limits.col_min - fcenter_mv.col);
- end_row = AOMMIN(range, x->mv_limits.row_max - fcenter_mv.row);
- end_col = AOMMIN(range, x->mv_limits.col_max - fcenter_mv.col);
+ fn_ptr->sdf(what->buf, what->stride, get_buf_from_mv(in_what, &start_mv_),
+ in_what->stride) +
+ mvsad_err_cost(x, &start_mv_, ref_mv, sad_per_bit);
+ start_row = AOMMAX(-range, x->mv_limits.row_min - start_mv_.row);
+ start_col = AOMMAX(-range, x->mv_limits.col_min - start_mv_.col);
+ end_row = AOMMIN(range, x->mv_limits.row_max - start_mv_.row);
+ end_col = AOMMIN(range, x->mv_limits.col_max - start_mv_.col);
for (r = start_row; r <= end_row; r += step) {
for (c = start_col; c <= end_col; c += col_step) {
// Step > 1 means we are not checking every location in this pass.
if (step > 1) {
- const MV mv = { fcenter_mv.row + r, fcenter_mv.col + c };
+ const FULLPEL_MV mv = { start_mv_.row + r, start_mv_.col + c };
unsigned int sad =
fn_ptr->sdf(what->buf, what->stride, get_buf_from_mv(in_what, &mv),
in_what->stride);
@@ -1770,7 +1791,7 @@
sad += mvsad_err_cost(x, &mv, ref_mv, sad_per_bit);
if (sad < best_sad) {
best_sad = sad;
- x->second_best_mv.as_mv = *best_mv;
+ x->second_best_mv.as_fullmv = *best_mv;
*best_mv = mv;
}
}
@@ -1780,26 +1801,27 @@
unsigned int sads[4];
const uint8_t *addrs[4];
for (i = 0; i < 4; ++i) {
- const MV mv = { fcenter_mv.row + r, fcenter_mv.col + c + i };
+ const FULLPEL_MV mv = { start_mv_.row + r, start_mv_.col + c + i };
addrs[i] = get_buf_from_mv(in_what, &mv);
}
fn_ptr->sdx4df(what->buf, what->stride, addrs, in_what->stride, sads);
for (i = 0; i < 4; ++i) {
if (sads[i] < best_sad) {
- const MV mv = { fcenter_mv.row + r, fcenter_mv.col + c + i };
+ const FULLPEL_MV mv = { start_mv_.row + r,
+ start_mv_.col + c + i };
const unsigned int sad =
sads[i] + mvsad_err_cost(x, &mv, ref_mv, sad_per_bit);
if (sad < best_sad) {
best_sad = sad;
- x->second_best_mv.as_mv = *best_mv;
+ x->second_best_mv.as_fullmv = *best_mv;
*best_mv = mv;
}
}
}
} else {
for (i = 0; i < end_col - c; ++i) {
- const MV mv = { fcenter_mv.row + r, fcenter_mv.col + c + i };
+ const FULLPEL_MV mv = { start_mv_.row + r, start_mv_.col + c + i };
unsigned int sad =
fn_ptr->sdf(what->buf, what->stride,
get_buf_from_mv(in_what, &mv), in_what->stride);
@@ -1807,7 +1829,7 @@
sad += mvsad_err_cost(x, &mv, ref_mv, sad_per_bit);
if (sad < best_sad) {
best_sad = sad;
- x->second_best_mv.as_mv = *best_mv;
+ x->second_best_mv.as_fullmv = *best_mv;
*best_mv = mv;
}
}
@@ -1821,10 +1843,10 @@
}
int av1_diamond_search_sad_c(MACROBLOCK *x, const search_site_config *cfg,
- MV *ref_mv, MV *best_mv, int search_param,
- int sad_per_bit, int *num00,
+ FULLPEL_MV *start_mv, FULLPEL_MV *best_mv,
+ int search_param, int sad_per_bit, int *num00,
const aom_variance_fn_ptr_t *fn_ptr,
- const MV *center_mv, uint8_t *second_pred,
+ const MV *ref_mv, uint8_t *second_pred,
uint8_t *mask, int mask_stride, int inv_mask) {
const MACROBLOCKD *const xd = &x->e_mbd;
uint8_t *what = x->plane[0].src.buf;
@@ -1837,24 +1859,19 @@
int best_site = 0;
int is_off_center = 0;
- int ref_row;
- int ref_col;
-
// search_param determines the length of the initial step and hence the number
// of iterations.
const int tot_steps = cfg->ss_count - search_param;
- const MV fcenter_mv = { center_mv->row >> 3, center_mv->col >> 3 };
- clamp_mv(ref_mv, x->mv_limits.col_min, x->mv_limits.col_max,
- x->mv_limits.row_min, x->mv_limits.row_max);
- ref_row = ref_mv->row;
- ref_col = ref_mv->col;
+ 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);
*num00 = 0;
- best_mv->row = ref_row;
- best_mv->col = ref_col;
+ best_mv->row = start_mv->row;
+ best_mv->col = start_mv->col;
// Work out the start point for the search
- in_what = xd->plane[0].pre[0].buf + ref_row * in_what_stride + ref_col;
+ in_what = get_buf_from_mv(&xd->plane[0].pre[0], start_mv);
best_address = in_what;
// Check the starting position
@@ -1869,7 +1886,7 @@
else
bestsad = fn_ptr->sdf(what, what_stride, in_what, in_what_stride);
- bestsad += mvsad_err_cost(x, best_mv, &fcenter_mv, sad_per_bit);
+ bestsad += mvsad_err_cost(x, best_mv, &full_ref_mv, sad_per_bit);
int next_step_size = tot_steps > 2 ? cfg->radius[tot_steps - 2] : 1;
for (int step = tot_steps - 1; step >= 0; --step) {
@@ -1896,10 +1913,11 @@
fn_ptr->sdx4df(what, what_stride, block_offset, in_what_stride, sads);
for (j = 0; j < 4; j++) {
if (sads[j] < bestsad) {
- const MV this_mv = { best_mv->row + ss[idx + j].mv.row,
- best_mv->col + ss[idx + j].mv.col };
+ const FULLPEL_MV this_mv = { best_mv->row + ss[idx + j].mv.row,
+ best_mv->col + ss[idx + j].mv.col };
unsigned int thissad =
- sads[j] + mvsad_err_cost(x, &this_mv, &fcenter_mv, sad_per_bit);
+ sads[j] +
+ mvsad_err_cost(x, &this_mv, &full_ref_mv, sad_per_bit);
if (thissad < bestsad) {
bestsad = thissad;
best_site = idx + j;
@@ -1909,8 +1927,8 @@
}
} else {
for (int idx = 1; idx <= cfg->searches_per_step[step]; idx++) {
- const MV this_mv = { best_mv->row + ss[idx].mv.row,
- best_mv->col + ss[idx].mv.col };
+ 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)) {
const uint8_t *const check_here = ss[idx].offset + best_address;
@@ -1928,7 +1946,7 @@
fn_ptr->sdf(what, what_stride, check_here, in_what_stride);
if (thissad < bestsad) {
- thissad += mvsad_err_cost(x, &this_mv, &fcenter_mv, sad_per_bit);
+ thissad += mvsad_err_cost(x, &this_mv, &full_ref_mv, sad_per_bit);
if (thissad < bestsad) {
bestsad = thissad;
best_site = idx;
@@ -1939,7 +1957,7 @@
}
if (best_site != 0) {
- x->second_best_mv.as_mv = *best_mv;
+ x->second_best_mv.as_fullmv = *best_mv;
best_mv->row += ss[best_site].mv.row;
best_mv->col += ss[best_site].mv.col;
best_address += ss[best_site].offset;
@@ -1963,32 +1981,33 @@
/* do_refine: If last step (1-away) of n-step search doesn't pick the center
point as the best match, we will do a final 1-away diamond
refining search */
-static int full_pixel_diamond(MACROBLOCK *x, MV *mvp_full, int step_param,
- int use_var, int sadpb, int *cost_list,
+static int full_pixel_diamond(MACROBLOCK *x, FULLPEL_MV *start_mv,
+ int step_param, int use_var, int sadpb,
+ int *cost_list,
const aom_variance_fn_ptr_t *fn_ptr,
const MV *ref_mv, const search_site_config *cfg,
uint8_t *second_pred, uint8_t *mask,
int mask_stride, int inv_mask) {
- MV temp_mv;
+ FULLPEL_MV best_mv;
int thissme, n, num00 = 0;
- int bestsme = av1_diamond_search_sad_c(x, cfg, mvp_full, &temp_mv, step_param,
+ int bestsme = av1_diamond_search_sad_c(x, cfg, start_mv, &best_mv, step_param,
sadpb, &n, fn_ptr, ref_mv, second_pred,
mask, mask_stride, inv_mask);
if (bestsme < INT_MAX) {
if (mask)
bestsme = av1_get_mvpred_mask_var(
- x, &temp_mv, ref_mv, second_pred, mask, mask_stride, inv_mask, fn_ptr,
+ x, &best_mv, ref_mv, second_pred, mask, mask_stride, inv_mask, fn_ptr,
&x->plane[0].src, &x->e_mbd.plane[0].pre[0], use_var);
else if (second_pred)
- bestsme = av1_get_mvpred_av_var(x, &temp_mv, ref_mv, second_pred, fn_ptr,
+ bestsme = av1_get_mvpred_av_var(x, &best_mv, ref_mv, second_pred, fn_ptr,
&x->plane[0].src,
&x->e_mbd.plane[0].pre[0], use_var);
else
- bestsme = av1_get_mvpred_var(x, &temp_mv, ref_mv, fn_ptr, use_var);
+ bestsme = av1_get_mvpred_var(x, &best_mv, ref_mv, fn_ptr, use_var);
}
- x->best_mv.as_mv = temp_mv;
+ x->best_mv.as_fullmv = best_mv;
// If there won't be more n-step search, check to see if refining search is
// needed.
@@ -2000,32 +2019,33 @@
num00--;
} else {
thissme = av1_diamond_search_sad_c(
- x, cfg, mvp_full, &temp_mv, step_param + n, sadpb, &num00, fn_ptr,
+ x, cfg, start_mv, &best_mv, step_param + n, sadpb, &num00, fn_ptr,
ref_mv, second_pred, mask, mask_stride, inv_mask);
if (thissme < INT_MAX) {
if (mask)
thissme = av1_get_mvpred_mask_var(
- x, &temp_mv, ref_mv, second_pred, mask, mask_stride, inv_mask,
+ x, &best_mv, ref_mv, second_pred, mask, mask_stride, inv_mask,
fn_ptr, &x->plane[0].src, &x->e_mbd.plane[0].pre[0], use_var);
else if (second_pred)
- thissme = av1_get_mvpred_av_var(x, &temp_mv, ref_mv, second_pred,
+ thissme = av1_get_mvpred_av_var(x, &best_mv, ref_mv, second_pred,
fn_ptr, &x->plane[0].src,
&x->e_mbd.plane[0].pre[0], use_var);
else
- thissme = av1_get_mvpred_var(x, &temp_mv, ref_mv, fn_ptr, use_var);
+ thissme = av1_get_mvpred_var(x, &best_mv, ref_mv, fn_ptr, use_var);
}
if (thissme < bestsme) {
bestsme = thissme;
- x->best_mv.as_mv = temp_mv;
+ x->best_mv.as_fullmv = best_mv;
}
}
}
// Return cost list.
if (cost_list) {
- calc_int_cost_list(x, ref_mv, sadpb, fn_ptr, &x->best_mv.as_mv, cost_list);
+ calc_int_cost_list(x, ref_mv, sadpb, fn_ptr, &x->best_mv.as_fullmv,
+ cost_list);
}
return bestsme;
}
@@ -2036,17 +2056,18 @@
// Runs an limited range exhaustive mesh search using a pattern set
// according to the encode speed profile.
static int full_pixel_exhaustive(
- MACROBLOCK *x, const MV *centre_mv_full, int sadpb, int *cost_list,
- const aom_variance_fn_ptr_t *fn_ptr, const MV *ref_mv, MV *dst_mv,
+ MACROBLOCK *x, const FULLPEL_MV *start_mv, int sadpb, int *cost_list,
+ const aom_variance_fn_ptr_t *fn_ptr, const MV *ref_mv, FULLPEL_MV *best_mv,
const struct MESH_PATTERN *const mesh_patterns) {
- MV temp_mv = { centre_mv_full->row, centre_mv_full->col };
- MV f_ref_mv = { ref_mv->row >> 3, ref_mv->col >> 3 };
+ FULLPEL_MV full_ref_mv = get_fullmv_from_mv(ref_mv);
int bestsme;
int i;
int interval = mesh_patterns[0].interval;
int range = mesh_patterns[0].range;
int baseline_interval_divisor;
+ *best_mv = *start_mv;
+
// Keep track of number of exhaustive calls (this frame in this thread).
if (x->ex_search_count_ptr != NULL) ++(*x->ex_search_count_ptr);
@@ -2059,13 +2080,13 @@
// Check size of proposed first range against magnitude of the centre
// value used as a starting point.
- range = AOMMAX(range, (5 * AOMMAX(abs(temp_mv.row), abs(temp_mv.col))) / 4);
+ range = AOMMAX(range, (5 * AOMMAX(abs(best_mv->row), abs(best_mv->col))) / 4);
range = AOMMIN(range, MAX_RANGE);
interval = AOMMAX(interval, range / baseline_interval_divisor);
// initial search
- bestsme = exhuastive_mesh_search(x, &f_ref_mv, &temp_mv, range, interval,
- sadpb, fn_ptr, &temp_mv);
+ bestsme = exhuastive_mesh_search(x, &full_ref_mv, best_mv, range, interval,
+ sadpb, fn_ptr, best_mv);
if ((interval > MIN_INTERVAL) && (range > MIN_RANGE)) {
// Progressive searches with range and step size decreasing each time
@@ -2073,20 +2094,19 @@
for (i = 1; i < MAX_MESH_STEP; ++i) {
// First pass with coarser step and longer range
bestsme = exhuastive_mesh_search(
- x, &f_ref_mv, &temp_mv, mesh_patterns[i].range,
- mesh_patterns[i].interval, sadpb, fn_ptr, &temp_mv);
+ x, &full_ref_mv, best_mv, mesh_patterns[i].range,
+ mesh_patterns[i].interval, sadpb, fn_ptr, best_mv);
if (mesh_patterns[i].interval == 1) break;
}
}
if (bestsme < INT_MAX)
- bestsme = av1_get_mvpred_var(x, &temp_mv, ref_mv, fn_ptr, 1);
- *dst_mv = temp_mv;
+ bestsme = av1_get_mvpred_var(x, best_mv, ref_mv, fn_ptr, 1);
// Return cost list.
if (cost_list) {
- calc_int_cost_list(x, ref_mv, sadpb, fn_ptr, dst_mv, cost_list);
+ calc_int_cost_list(x, ref_mv, sadpb, fn_ptr, best_mv, cost_list);
}
return bestsme;
}
@@ -2096,7 +2116,7 @@
int av1_refining_search_8p_c(MACROBLOCK *x, int error_per_bit, int search_range,
const aom_variance_fn_ptr_t *fn_ptr,
const uint8_t *mask, int mask_stride,
- int invert_mask, const MV *center_mv,
+ int invert_mask, const MV *ref_mv,
const uint8_t *second_pred,
const struct buf_2d *src,
const struct buf_2d *pre) {
@@ -2112,8 +2132,8 @@
};
const struct buf_2d *const what = src;
const struct buf_2d *const in_what = pre;
- const MV fcenter_mv = { center_mv->row >> 3, center_mv->col >> 3 };
- MV *best_mv = &x->best_mv.as_mv;
+ const FULLPEL_MV full_ref_mv = get_fullmv_from_mv(ref_mv);
+ FULLPEL_MV *best_mv = &x->best_mv.as_fullmv;
unsigned int best_sad = INT_MAX;
int i, j;
uint8_t do_refine_search_grid[SEARCH_GRID_STRIDE_8P *
@@ -2121,18 +2141,18 @@
int grid_center = SEARCH_GRID_CENTER_8P;
int grid_coord = grid_center;
- clamp_mv(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.col_min, x->mv_limits.col_max,
+ x->mv_limits.row_min, x->mv_limits.row_max);
if (mask) {
best_sad = fn_ptr->msdf(what->buf, what->stride,
get_buf_from_mv(in_what, best_mv), in_what->stride,
second_pred, mask, mask_stride, invert_mask) +
- mvsad_err_cost(x, best_mv, &fcenter_mv, error_per_bit);
+ mvsad_err_cost(x, best_mv, &full_ref_mv, error_per_bit);
} else {
best_sad =
fn_ptr->sdaf(what->buf, what->stride, get_buf_from_mv(in_what, best_mv),
in_what->stride, second_pred) +
- mvsad_err_cost(x, best_mv, &fcenter_mv, error_per_bit);
+ mvsad_err_cost(x, best_mv, &full_ref_mv, error_per_bit);
}
do_refine_search_grid[grid_coord] = 1;
@@ -2145,8 +2165,8 @@
if (do_refine_search_grid[grid_coord] == 1) {
continue;
}
- const MV mv = { best_mv->row + neighbors[j].coord.row,
- best_mv->col + neighbors[j].coord.col };
+ const FULLPEL_MV mv = { best_mv->row + neighbors[j].coord.row,
+ best_mv->col + neighbors[j].coord.col };
do_refine_search_grid[grid_coord] = 1;
if (is_mv_in(&x->mv_limits, &mv)) {
@@ -2161,7 +2181,7 @@
second_pred);
}
if (sad < best_sad) {
- sad += mvsad_err_cost(x, &mv, &fcenter_mv, error_per_bit);
+ sad += mvsad_err_cost(x, &mv, &full_ref_mv, error_per_bit);
if (sad < best_sad) {
best_sad = sad;
best_site = j;
@@ -2286,9 +2306,8 @@
const int src_stride = x->plane[0].src.stride;
const int ref_stride = xd->plane[0].pre[0].stride;
uint8_t const *ref_buf, *src_buf;
- MV *tmp_mv = &xd->mi[0]->mv[0].as_mv;
+ int_mv *best_int_mv = &xd->mi[0]->mv[0];
unsigned int best_sad, tmp_sad, this_sad[4];
- MV this_mv;
const int norm_factor = 3 + (bw >> 5);
const YV12_BUFFER_CONFIG *scaled_ref_frame =
av1_get_scaled_ref_frame(cpi, mi->ref_frame[0]);
@@ -2306,8 +2325,7 @@
if (xd->bd != 8) {
unsigned int sad;
- tmp_mv->row = 0;
- tmp_mv->col = 0;
+ best_int_mv->as_fullmv = kZeroFullMv;
sad = cpi->fn_ptr[bsize].sdf(x->plane[0].src.buf, src_stride,
xd->plane[0].pre[0].buf, ref_stride);
@@ -2344,12 +2362,14 @@
}
// Find the best match per 1-D search
- tmp_mv->col = vector_match(hbuf, src_hbuf, mi_size_wide_log2[bsize]);
- tmp_mv->row = vector_match(vbuf, src_vbuf, mi_size_high_log2[bsize]);
+ best_int_mv->as_fullmv.col =
+ vector_match(hbuf, src_hbuf, mi_size_wide_log2[bsize]);
+ best_int_mv->as_fullmv.row =
+ vector_match(vbuf, src_vbuf, mi_size_high_log2[bsize]);
- this_mv = *tmp_mv;
+ FULLPEL_MV this_mv = best_int_mv->as_fullmv;
src_buf = x->plane[0].src.buf;
- ref_buf = xd->plane[0].pre[0].buf + this_mv.row * ref_stride + this_mv.col;
+ ref_buf = get_buf_from_mv(&xd->plane[0].pre[0], &this_mv);
best_sad = cpi->fn_ptr[bsize].sdf(src_buf, src_stride, ref_buf, ref_stride);
{
@@ -2366,8 +2386,8 @@
for (idx = 0; idx < 4; ++idx) {
if (this_sad[idx] < best_sad) {
best_sad = this_sad[idx];
- tmp_mv->row = search_pos[idx].row + this_mv.row;
- tmp_mv->col = search_pos[idx].col + this_mv.col;
+ best_int_mv->as_fullmv.row = search_pos[idx].row + this_mv.row;
+ best_int_mv->as_fullmv.col = search_pos[idx].col + this_mv.col;
}
}
@@ -2381,22 +2401,22 @@
else
this_mv.col += 1;
- ref_buf = xd->plane[0].pre[0].buf + this_mv.row * ref_stride + this_mv.col;
+ ref_buf = get_buf_from_mv(&xd->plane[0].pre[0], &this_mv);
tmp_sad = cpi->fn_ptr[bsize].sdf(src_buf, src_stride, ref_buf, ref_stride);
if (best_sad > tmp_sad) {
- *tmp_mv = this_mv;
+ best_int_mv->as_fullmv = this_mv;
best_sad = tmp_sad;
}
- tmp_mv->row *= 8;
- tmp_mv->col *= 8;
+ best_int_mv->as_mv = get_mv_from_fullmv(&best_int_mv->as_fullmv);
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(tmp_mv, subpel_mv_limits.col_min, subpel_mv_limits.col_max,
- subpel_mv_limits.row_min, subpel_mv_limits.row_max);
+ 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);
if (scaled_ref_frame) {
int i;
@@ -2407,8 +2427,8 @@
}
int av1_full_pixel_search(const AV1_COMP *cpi, MACROBLOCK *x, BLOCK_SIZE bsize,
- MV *mvp_full, int step_param, int use_var, int method,
- int run_mesh_search, int error_per_bit,
+ FULLPEL_MV *start_mv, int step_param, int use_var,
+ int method, int run_mesh_search, int error_per_bit,
int *cost_list, const MV *ref_mv, int var_max, int rd,
int x_pos, int y_pos, int intra,
const search_site_config *cfg,
@@ -2430,29 +2450,29 @@
switch (method) {
case FAST_DIAMOND:
- var = fast_dia_search(x, mvp_full, step_param, error_per_bit, 0,
+ var = fast_dia_search(x, start_mv, step_param, error_per_bit, 0,
cost_list, fn_ptr, 1, ref_mv);
break;
case FAST_HEX:
- var = fast_hex_search(x, mvp_full, step_param, error_per_bit, 0,
+ var = fast_hex_search(x, start_mv, step_param, error_per_bit, 0,
cost_list, fn_ptr, 1, ref_mv);
break;
case HEX:
- var = av1_hex_search(x, mvp_full, step_param, error_per_bit, 1, cost_list,
+ var = av1_hex_search(x, start_mv, step_param, error_per_bit, 1, cost_list,
fn_ptr, 1, ref_mv);
break;
case SQUARE:
- var = square_search(x, mvp_full, step_param, error_per_bit, 1, cost_list,
+ var = square_search(x, start_mv, step_param, error_per_bit, 1, cost_list,
fn_ptr, 1, ref_mv);
break;
case BIGDIA:
- var = bigdia_search(x, mvp_full, step_param, error_per_bit, 1, cost_list,
+ var = bigdia_search(x, start_mv, step_param, error_per_bit, 1, cost_list,
fn_ptr, 1, ref_mv);
break;
case NSTEP:
case DIAMOND:
var =
- full_pixel_diamond(x, mvp_full, step_param, use_var, error_per_bit,
+ full_pixel_diamond(x, start_mv, step_param, use_var, error_per_bit,
cost_list, fn_ptr, ref_mv, cfg, NULL, NULL, 0, 0);
break;
default: assert(0 && "Invalid search method.");
@@ -2477,8 +2497,8 @@
// filtering. Can extend it to intrabc.
if (!use_intrabc_mesh_pattern && sf->mv_sf.prune_mesh_search) {
const int full_pel_mv_diff =
- AOMMAX(abs(mvp_full->row - x->best_mv.as_mv.row),
- abs(mvp_full->col - x->best_mv.as_mv.col));
+ AOMMAX(abs(start_mv->row - x->best_mv.as_fullmv.row),
+ abs(start_mv->col - x->best_mv.as_fullmv.col));
if (full_pel_mv_diff <= 4) {
run_mesh_search = 0;
}
@@ -2486,23 +2506,23 @@
if (run_mesh_search) {
int var_ex;
- MV tmp_mv_ex;
+ FULLPEL_MV tmp_mv_ex;
// Pick the mesh pattern for exhaustive search based on the toolset (intraBC
// or non-intraBC)
const MESH_PATTERN *const mesh_patterns =
use_intrabc_mesh_pattern ? sf->mv_sf.intrabc_mesh_patterns
: sf->mv_sf.mesh_patterns;
- var_ex =
- full_pixel_exhaustive(x, &x->best_mv.as_mv, error_per_bit, cost_list,
- fn_ptr, ref_mv, &tmp_mv_ex, mesh_patterns);
+ var_ex = full_pixel_exhaustive(x, &x->best_mv.as_fullmv, error_per_bit,
+ cost_list, fn_ptr, ref_mv, &tmp_mv_ex,
+ mesh_patterns);
if (var_ex < var) {
var = var_ex;
- x->best_mv.as_mv = tmp_mv_ex;
+ x->best_mv.as_fullmv = tmp_mv_ex;
}
}
if (method != NSTEP && rd && var < var_max)
- var = av1_get_mvpred_var(x, &x->best_mv.as_mv, ref_mv, fn_ptr, 1);
+ var = av1_get_mvpred_var(x, &x->best_mv.as_fullmv, ref_mv, fn_ptr, 1);
// Use hash-me for intrablock copy
do {
@@ -2518,7 +2538,7 @@
uint8_t *what = x->plane[0].src.buf;
const int what_stride = x->plane[0].src.stride;
uint32_t hash_value1, hash_value2;
- MV best_hash_mv;
+ FULLPEL_MV best_hash_mv;
int best_hash_cost = INT_MAX;
// for the hashMap
@@ -2549,7 +2569,7 @@
bsize, cpi->common.seq_params.mib_size_log2))
continue;
}
- MV hash_mv;
+ 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;
@@ -2563,7 +2583,7 @@
}
if (best_hash_cost < var) {
x->second_best_mv = x->best_mv;
- x->best_mv.as_mv = best_hash_mv;
+ x->best_mv.as_fullmv = best_hash_mv;
var = best_hash_cost;
}
}
@@ -2850,49 +2870,50 @@
#undef CHECK_BETTER
static int get_obmc_mvpred_var(const MACROBLOCK *x, const int32_t *wsrc,
- const int32_t *mask, const MV *best_mv,
- const MV *center_mv,
+ const int32_t *mask, const FULLPEL_MV *best_mv,
+ const MV *ref_mv,
const aom_variance_fn_ptr_t *vfp, int use_mvcost,
int is_second) {
const MACROBLOCKD *const xd = &x->e_mbd;
const struct buf_2d *const in_what = &xd->plane[0].pre[is_second];
- const MV mv = { best_mv->row * 8, best_mv->col * 8 };
+ const MV mv = get_mv_from_fullmv(best_mv);
const MV_COST_TYPE mv_cost_type = x->mv_cost_type;
unsigned int unused;
return vfp->ovf(get_buf_from_mv(in_what, best_mv), in_what->stride, wsrc,
mask, &unused) +
(use_mvcost
- ? mv_err_cost(&mv, center_mv, x->nmv_vec_cost, x->mv_cost_stack,
+ ? mv_err_cost(&mv, ref_mv, x->nmv_vec_cost, x->mv_cost_stack,
x->errorperbit, mv_cost_type)
: 0);
}
static int obmc_refining_search_sad(const MACROBLOCK *x, const int32_t *wsrc,
- const int32_t *mask, MV *ref_mv,
+ const int32_t *mask, FULLPEL_MV *start_mv,
int error_per_bit, int search_range,
const aom_variance_fn_ptr_t *fn_ptr,
- const MV *center_mv, int is_second) {
+ const MV *ref_mv, int is_second) {
const MV neighbors[4] = { { -1, 0 }, { 0, -1 }, { 0, 1 }, { 1, 0 } };
const MACROBLOCKD *const xd = &x->e_mbd;
const struct buf_2d *const in_what = &xd->plane[0].pre[is_second];
- const MV fcenter_mv = { center_mv->row >> 3, center_mv->col >> 3 };
- unsigned int best_sad = fn_ptr->osdf(get_buf_from_mv(in_what, ref_mv),
- in_what->stride, wsrc, mask) +
- mvsad_err_cost(x, ref_mv, &fcenter_mv, error_per_bit);
+ const FULLPEL_MV full_ref_mv = get_fullmv_from_mv(ref_mv);
+ unsigned int best_sad =
+ fn_ptr->osdf(get_buf_from_mv(in_what, start_mv), in_what->stride, wsrc,
+ mask) +
+ mvsad_err_cost(x, start_mv, &full_ref_mv, error_per_bit);
int i, j;
for (i = 0; i < search_range; i++) {
int best_site = -1;
for (j = 0; j < 4; j++) {
- const MV mv = { ref_mv->row + neighbors[j].row,
- ref_mv->col + neighbors[j].col };
+ const FULLPEL_MV mv = { start_mv->row + neighbors[j].row,
+ start_mv->col + neighbors[j].col };
if (is_mv_in(&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) {
- sad += mvsad_err_cost(x, &mv, &fcenter_mv, error_per_bit);
+ sad += mvsad_err_cost(x, &mv, &full_ref_mv, error_per_bit);
if (sad < best_sad) {
best_sad = sad;
best_site = j;
@@ -2904,20 +2925,18 @@
if (best_site == -1) {
break;
} else {
- ref_mv->row += neighbors[best_site].row;
- ref_mv->col += neighbors[best_site].col;
+ start_mv->row += neighbors[best_site].row;
+ start_mv->col += neighbors[best_site].col;
}
}
return best_sad;
}
-static int obmc_diamond_search_sad(const MACROBLOCK *x,
- const search_site_config *cfg,
- const int32_t *wsrc, const int32_t *mask,
- MV *ref_mv, MV *best_mv, int search_param,
- int sad_per_bit, int *num00,
- const aom_variance_fn_ptr_t *fn_ptr,
- const MV *center_mv, int is_second) {
+static int obmc_diamond_search_sad(
+ const MACROBLOCK *x, const search_site_config *cfg, const int32_t *wsrc,
+ const int32_t *mask, FULLPEL_MV *start_mv, FULLPEL_MV *best_mv,
+ int search_param, int sad_per_bit, int *num00,
+ const aom_variance_fn_ptr_t *fn_ptr, const MV *ref_mv, int is_second) {
const MACROBLOCKD *const xd = &x->e_mbd;
const struct buf_2d *const in_what = &xd->plane[0].pre[is_second];
// search_param determines the length of the initial step and hence the number
@@ -2926,34 +2945,34 @@
// (MAX_FIRST_STEP/4) pel... etc.
const int tot_steps = MAX_MVSEARCH_STEPS - 1 - search_param;
- const MV fcenter_mv = { center_mv->row >> 3, center_mv->col >> 3 };
+ const FULLPEL_MV full_ref_mv = get_fullmv_from_mv(ref_mv);
const uint8_t *best_address, *in_what_ref;
int best_sad = INT_MAX;
int best_site = 0;
int step;
- clamp_mv(ref_mv, x->mv_limits.col_min, x->mv_limits.col_max,
- x->mv_limits.row_min, x->mv_limits.row_max);
- in_what_ref = in_what->buf + ref_mv->row * in_what->stride + ref_mv->col;
+ clamp_fullmv(start_mv, x->mv_limits.col_min, x->mv_limits.col_max,
+ x->mv_limits.row_min, x->mv_limits.row_max);
+ in_what_ref = get_buf_from_mv(in_what, start_mv);
best_address = in_what_ref;
*num00 = 0;
- *best_mv = *ref_mv;
+ *best_mv = *start_mv;
// Check the starting position
best_sad = fn_ptr->osdf(best_address, in_what->stride, wsrc, mask) +
- mvsad_err_cost(x, best_mv, &fcenter_mv, sad_per_bit);
+ mvsad_err_cost(x, best_mv, &full_ref_mv, sad_per_bit);
for (step = tot_steps; step >= 0; --step) {
const search_site *const ss = cfg->ss[step];
best_site = 0;
for (int idx = 1; idx <= cfg->searches_per_step[step]; ++idx) {
- const MV mv = { best_mv->row + ss[idx].mv.row,
- best_mv->col + ss[idx].mv.col };
+ 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)) {
int sad = fn_ptr->osdf(best_address + ss[idx].offset, in_what->stride,
wsrc, mask);
if (sad < best_sad) {
- sad += mvsad_err_cost(x, &mv, &fcenter_mv, sad_per_bit);
+ sad += mvsad_err_cost(x, &mv, &full_ref_mv, sad_per_bit);
if (sad < best_sad) {
best_sad = sad;
best_site = idx;
@@ -2974,23 +2993,24 @@
}
static int obmc_full_pixel_diamond(const AV1_COMP *cpi, MACROBLOCK *x,
- MV *mvp_full, int step_param, int sadpb,
- int further_steps, int do_refine,
+ FULLPEL_MV *start_mv, int step_param,
+ int sadpb, int further_steps, int do_refine,
const aom_variance_fn_ptr_t *fn_ptr,
- const MV *ref_mv, MV *dst_mv, int is_second,
+ const MV *ref_mv, FULLPEL_MV *best_mv,
+ int is_second,
const search_site_config *cfg) {
(void)cpi; // to silence compiler warning
const int32_t *wsrc = x->wsrc_buf;
const int32_t *mask = x->mask_buf;
- MV temp_mv;
+ FULLPEL_MV tmp_mv;
int thissme, n, num00 = 0;
int bestsme =
- obmc_diamond_search_sad(x, cfg, wsrc, mask, mvp_full, &temp_mv,
- step_param, sadpb, &n, fn_ptr, ref_mv, is_second);
+ obmc_diamond_search_sad(x, cfg, wsrc, mask, start_mv, &tmp_mv, step_param,
+ sadpb, &n, fn_ptr, ref_mv, is_second);
if (bestsme < INT_MAX)
- bestsme = get_obmc_mvpred_var(x, wsrc, mask, &temp_mv, ref_mv, fn_ptr, 1,
+ bestsme = get_obmc_mvpred_var(x, wsrc, mask, &tmp_mv, ref_mv, fn_ptr, 1,
is_second);
- *dst_mv = temp_mv;
+ *best_mv = tmp_mv;
// If there won't be more n-step search, check to see if refining search is
// needed.
@@ -3002,19 +3022,19 @@
if (num00) {
num00--;
} else {
- thissme = obmc_diamond_search_sad(x, cfg, wsrc, mask, mvp_full, &temp_mv,
+ thissme = obmc_diamond_search_sad(x, cfg, wsrc, mask, start_mv, &tmp_mv,
step_param + n, sadpb, &num00, fn_ptr,
ref_mv, is_second);
if (thissme < INT_MAX)
- thissme = get_obmc_mvpred_var(x, wsrc, mask, &temp_mv, ref_mv, fn_ptr,
- 1, is_second);
+ thissme = get_obmc_mvpred_var(x, wsrc, mask, &tmp_mv, ref_mv, fn_ptr, 1,
+ is_second);
// check to see if refining search is needed.
if (num00 > further_steps - n) do_refine = 0;
if (thissme < bestsme) {
bestsme = thissme;
- *dst_mv = temp_mv;
+ *best_mv = tmp_mv;
}
}
}
@@ -3022,41 +3042,42 @@
// final 1-away diamond refining search
if (do_refine) {
const int search_range = 8;
- MV best_mv = *dst_mv;
- thissme = obmc_refining_search_sad(x, wsrc, mask, &best_mv, sadpb,
+ tmp_mv = *best_mv;
+ thissme = obmc_refining_search_sad(x, wsrc, mask, &tmp_mv, sadpb,
search_range, fn_ptr, ref_mv, is_second);
if (thissme < INT_MAX)
- thissme = get_obmc_mvpred_var(x, wsrc, mask, &best_mv, ref_mv, fn_ptr, 1,
+ thissme = get_obmc_mvpred_var(x, wsrc, mask, &tmp_mv, ref_mv, fn_ptr, 1,
is_second);
if (thissme < bestsme) {
bestsme = thissme;
- *dst_mv = best_mv;
+ *best_mv = tmp_mv;
}
}
return bestsme;
}
-int av1_obmc_full_pixel_search(const AV1_COMP *cpi, MACROBLOCK *x, MV *mvp_full,
- int step_param, int sadpb, int further_steps,
- int do_refine,
+int av1_obmc_full_pixel_search(const AV1_COMP *cpi, MACROBLOCK *x,
+ FULLPEL_MV *start_mv, int step_param, int sadpb,
+ int further_steps, int do_refine,
const aom_variance_fn_ptr_t *fn_ptr,
- const MV *ref_mv, MV *dst_mv, int is_second,
- const search_site_config *cfg) {
+ const MV *ref_mv, FULLPEL_MV *best_mv,
+ int is_second, const search_site_config *cfg) {
if (cpi->sf.inter_sf.obmc_full_pixel_search_level == 0) {
- return obmc_full_pixel_diamond(cpi, x, mvp_full, step_param, sadpb,
- further_steps, do_refine, fn_ptr, ref_mv,
- dst_mv, is_second, cfg);
+ const int bestsme = obmc_full_pixel_diamond(
+ cpi, x, start_mv, step_param, sadpb, further_steps, do_refine, fn_ptr,
+ ref_mv, best_mv, is_second, cfg);
+ return bestsme;
} else {
const int32_t *wsrc = x->wsrc_buf;
const int32_t *mask = x->mask_buf;
const int search_range = 8;
- *dst_mv = *mvp_full;
- clamp_mv(dst_mv, x->mv_limits.col_min, x->mv_limits.col_max,
- x->mv_limits.row_min, x->mv_limits.row_max);
+ *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);
int thissme = obmc_refining_search_sad(
- x, wsrc, mask, dst_mv, sadpb, search_range, fn_ptr, ref_mv, is_second);
+ x, wsrc, mask, best_mv, sadpb, search_range, fn_ptr, ref_mv, is_second);
if (thissme < INT_MAX)
- thissme = get_obmc_mvpred_var(x, wsrc, mask, dst_mv, ref_mv, fn_ptr, 1,
+ thissme = get_obmc_mvpred_var(x, wsrc, mask, best_mv, ref_mv, fn_ptr, 1,
is_second);
return thissme;
}
@@ -3159,7 +3180,7 @@
void av1_simple_motion_search(AV1_COMP *const cpi, MACROBLOCK *x, int mi_row,
int mi_col, BLOCK_SIZE bsize, int ref,
- MV ref_mv_full, int num_planes,
+ FULLPEL_MV start_mv, int num_planes,
int use_subpixel) {
assert(num_planes == 1 &&
"Currently simple_motion_search only supports luma plane");
@@ -3181,9 +3202,8 @@
const YV12_BUFFER_CONFIG *scaled_ref_frame =
av1_get_scaled_ref_frame(cpi, ref);
struct buf_2d backup_yv12;
- // ref_mv is used to code the motion vector. ref_mv_full is the initial point.
- // ref_mv is in units of 1/8 pel whereas ref_mv_full is in units of pel.
- MV ref_mv = { 0, 0 };
+ // 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 SEARCH_METHODS search_methods = cpi->sf.mv_sf.search_method;
@@ -3205,9 +3225,9 @@
// This overwrites the mv_limits so we will need to restore it later.
av1_set_mv_search_range(&x->mv_limits, &ref_mv);
var = av1_full_pixel_search(
- cpi, x, bsize, &ref_mv_full, step_param, 1, search_methods,
- do_mesh_search, sadpb, cond_cost_list(cpi, cost_list), &ref_mv, INT_MAX,
- 1, mi_col * MI_SIZE, mi_row * MI_SIZE, 0, &cpi->ss_cfg[SS_CFG_SRC], 0);
+ cpi, x, bsize, &start_mv, step_param, 1, search_methods, do_mesh_search,
+ sadpb, cond_cost_list(cpi, cost_list), &ref_mv, INT_MAX, 1,
+ mi_col * MI_SIZE, mi_row * MI_SIZE, 0, &cpi->ss_cfg[SS_CFG_SRC], 0);
// Restore
x->mv_limits = tmp_mv_limits;
@@ -3238,11 +3258,10 @@
} else {
// Manually convert from units of pixel to 1/8-pixels if we are not doing
// subpel search
- x->best_mv.as_mv.row *= 8;
- x->best_mv.as_mv.col *= 8;
+ x->best_mv.as_mv = get_mv_from_fullmv(&x->best_mv.as_fullmv);
}
- mbmi->mv[0].as_mv = x->best_mv.as_mv;
+ mbmi->mv[0] = x->best_mv;
// Get a copy of the prediction output
av1_enc_build_inter_predictor(cm, xd, mi_row, mi_col, NULL, bsize,
@@ -3257,13 +3276,13 @@
void av1_simple_motion_sse_var(AV1_COMP *cpi, MACROBLOCK *x, int mi_row,
int mi_col, BLOCK_SIZE bsize,
- const MV ref_mv_full, int use_subpixel,
+ const FULLPEL_MV start_mv, int use_subpixel,
unsigned int *sse, unsigned int *var) {
MACROBLOCKD *xd = &x->e_mbd;
const MV_REFERENCE_FRAME ref =
cpi->rc.is_src_frame_alt_ref ? ALTREF_FRAME : LAST_FRAME;
- av1_simple_motion_search(cpi, x, mi_row, mi_col, bsize, ref, ref_mv_full, 1,
+ av1_simple_motion_search(cpi, x, mi_row, mi_col, bsize, ref, start_mv, 1,
use_subpixel);
const uint8_t *src = x->plane[0].src.buf;
diff --git a/av1/encoder/mcomp.h b/av1/encoder/mcomp.h
index 7e95289..cdd92a7 100644
--- a/av1/encoder/mcomp.h
+++ b/av1/encoder/mcomp.h
@@ -20,6 +20,16 @@
extern "C" {
#endif
+// In this file, the following variables always have the same meaning:
+// start_mv: the motion vector where we start the motion search
+// ref_mv: the motion vector with respect to which we calculate the mv_cost
+// best_mv: when it is not const, it is the destination where to store the
+// best motion vector
+// full_*: a prefix of full indicates that the mv is a FULLPEL_MV
+//
+// When a mv needs to both act as a fullpel_mv and subpel_mv, it is stored as an
+// int_mv, which is a union of int, FULLPEL_MV, and MV
+
// The maximum number of steps in a step search given the largest
// allowed initial step
#define MAX_MVSEARCH_STEPS 11
@@ -39,7 +49,7 @@
// motion search site
typedef struct search_site {
- MV mv;
+ FULLPEL_MV mv;
int offset;
} search_site;
@@ -62,20 +72,20 @@
void av1_set_mv_search_range(MvLimits *mv_limits, const MV *mv);
-int av1_mv_bit_cost(const MV *mv, const MV *ref, const int *mvjcost,
+int av1_mv_bit_cost(const MV *mv, const MV *ref_mv, const int *mvjcost,
int *mvcost[2], int weight);
// Utility to compute variance + MV rate cost for a given MV
-int av1_get_mvpred_var(const MACROBLOCK *x, const MV *best_mv,
- const MV *center_mv, const aom_variance_fn_ptr_t *vfp,
+int av1_get_mvpred_var(const MACROBLOCK *x, const FULLPEL_MV *best_mv,
+ const MV *ref_mv, const aom_variance_fn_ptr_t *vfp,
int use_var);
-int av1_get_mvpred_av_var(const MACROBLOCK *x, const MV *best_mv,
- const MV *center_mv, const uint8_t *second_pred,
+int av1_get_mvpred_av_var(const MACROBLOCK *x, const FULLPEL_MV *best_mv,
+ const MV *ref_mv, const uint8_t *second_pred,
const aom_variance_fn_ptr_t *vfp,
const struct buf_2d *src, const struct buf_2d *pre,
int use_mvcost);
-int av1_get_mvpred_mask_var(const MACROBLOCK *x, const MV *best_mv,
- const MV *center_mv, const uint8_t *second_pred,
+int av1_get_mvpred_mask_var(const MACROBLOCK *x, const FULLPEL_MV *best_mv,
+ const MV *ref_mv, const uint8_t *second_pred,
const uint8_t *mask, int mask_stride,
int invert_mask, const aom_variance_fn_ptr_t *vfp,
const struct buf_2d *src, const struct buf_2d *pre,
@@ -92,16 +102,10 @@
const MV *ref_mv);
// Runs sequence of diamond searches in smaller steps for RD.
-int av1_full_pixel_diamond(const struct AV1_COMP *cpi, MACROBLOCK *x,
- MV *mvp_full, int step_param, int sadpb,
- int further_steps, int do_refine, int *cost_list,
- const aom_variance_fn_ptr_t *fn_ptr,
- const MV *ref_mv, MV *dst_mv);
-
-int av1_hex_search(MACROBLOCK *x, MV *start_mv, int search_param,
+int av1_hex_search(MACROBLOCK *x, FULLPEL_MV *start_mv, int search_param,
int sad_per_bit, int do_init_search, int *cost_list,
const aom_variance_fn_ptr_t *vfp, int use_mvcost,
- const MV *center_mv);
+ const MV *ref_mv);
typedef int(fractional_mv_step_fp)(
MACROBLOCK *x, const AV1_COMMON *const cm, int mi_row, int mi_col,
@@ -123,32 +127,33 @@
int av1_refining_search_8p_c(MACROBLOCK *x, int error_per_bit, int search_range,
const aom_variance_fn_ptr_t *fn_ptr,
const uint8_t *mask, int mask_stride,
- int invert_mask, const MV *center_mv,
+ int invert_mask, const MV *ref_mv,
const uint8_t *second_pred,
const struct buf_2d *src,
const struct buf_2d *pre);
int av1_diamond_search_sad_c(MACROBLOCK *x, const search_site_config *cfg,
- MV *ref_mv, MV *best_mv, int search_param,
- int sad_per_bit, int *num00,
+ FULLPEL_MV *start_mv, FULLPEL_MV *best_mv,
+ int search_param, int sad_per_bit, int *num00,
const aom_variance_fn_ptr_t *fn_ptr,
- const MV *center_mv, uint8_t *second_pred,
+ const MV *ref_mv, uint8_t *second_pred,
uint8_t *mask, int mask_stride, int inv_mask);
int av1_full_pixel_search(const struct AV1_COMP *cpi, MACROBLOCK *x,
- BLOCK_SIZE bsize, MV *mvp_full, int step_param,
- int use_var, int method, int run_mesh_search,
- int error_per_bit, int *cost_list, const MV *ref_mv,
- int var_max, int rd, int x_pos, int y_pos, int intra,
+ BLOCK_SIZE bsize, FULLPEL_MV *start_mv,
+ int step_param, int use_var, int method,
+ int run_mesh_search, int error_per_bit,
+ int *cost_list, const MV *ref_mv, int var_max, int rd,
+ int x_pos, int y_pos, int intra,
const search_site_config *cfg,
int use_intrabc_mesh_pattern);
int av1_obmc_full_pixel_search(const struct AV1_COMP *cpi, MACROBLOCK *x,
- MV *mvp_full, int step_param, int sadpb,
+ FULLPEL_MV *start_mv, int step_param, int sadpb,
int further_steps, int do_refine,
const aom_variance_fn_ptr_t *fn_ptr,
- const MV *ref_mv, MV *dst_mv, int is_second,
- const search_site_config *cfg);
+ const MV *ref_mv, FULLPEL_MV *dst_mv,
+ int is_second, const search_site_config *cfg);
int av1_find_best_obmc_sub_pixel_tree_up(
MACROBLOCK *x, const AV1_COMMON *const cm, int mi_row, int mi_col,
MV *bestmv, const MV *ref_mv, int allow_hp, int error_per_bit,
@@ -169,12 +174,13 @@
// after calling this function.
void av1_simple_motion_search(struct AV1_COMP *const cpi, MACROBLOCK *x,
int mi_row, int mi_col, BLOCK_SIZE bsize, int ref,
- MV ref_mv_full, int num_planes, int use_subpixel);
+ FULLPEL_MV start_mv, int num_planes,
+ int use_subpixel);
// Performs a simple motion search to calculate the sse and var of the residue
void av1_simple_motion_sse_var(struct AV1_COMP *cpi, MACROBLOCK *x, int mi_row,
int mi_col, BLOCK_SIZE bsize,
- const MV ref_mv_full, int use_subpixel,
+ const FULLPEL_MV start_mv, int use_subpixel,
unsigned int *sse, unsigned int *var);
static INLINE void av1_set_fractional_mv(int_mv *fractional_best_mv) {
diff --git a/av1/encoder/motion_search_facade.c b/av1/encoder/motion_search_facade.c
index 0063ac1..1c9008c 100644
--- a/av1/encoder/motion_search_facade.c
+++ b/av1/encoder/motion_search_facade.c
@@ -113,14 +113,11 @@
// after full-pixel motion search.
av1_set_mv_search_range(&x->mv_limits, &ref_mv);
- MV mvp_full;
+ FULLPEL_MV start_mv;
if (mbmi->motion_mode != SIMPLE_TRANSLATION)
- mvp_full = mbmi->mv[0].as_mv;
+ start_mv = get_fullmv_from_mv(&mbmi->mv[0].as_mv);
else
- mvp_full = ref_mv;
-
- mvp_full.col >>= 3;
- mvp_full.row >>= 3;
+ start_mv = get_fullmv_from_mv(&ref_mv);
const int sadpb = x->sadperbit16;
int cost_list[5];
@@ -128,16 +125,16 @@
switch (mbmi->motion_mode) {
case SIMPLE_TRANSLATION:
bestsme = av1_full_pixel_search(
- cpi, x, bsize, &mvp_full, step_param, 1, cpi->sf.mv_sf.search_method,
+ cpi, x, bsize, &start_mv, step_param, 1, cpi->sf.mv_sf.search_method,
0, sadpb, cond_cost_list(cpi, cost_list), &ref_mv, INT_MAX, 1,
(MI_SIZE * mi_col), (MI_SIZE * mi_row), 0, &cpi->ss_cfg[SS_CFG_SRC],
0);
break;
case OBMC_CAUSAL:
bestsme = av1_obmc_full_pixel_search(
- cpi, x, &mvp_full, step_param, sadpb,
+ cpi, x, &start_mv, step_param, sadpb,
MAX_MVSEARCH_STEPS - 1 - step_param, 1, &cpi->fn_ptr[bsize], &ref_mv,
- &(x->best_mv.as_mv), 0, &cpi->ss_cfg[SS_CFG_SRC]);
+ &(x->best_mv.as_fullmv), 0, &cpi->ss_cfg[SS_CFG_SRC]);
break;
default: assert(0 && "Invalid motion mode!\n");
}
@@ -270,8 +267,8 @@
// Prediction buffer from second frame.
DECLARE_ALIGNED(16, uint8_t, second_pred16[MAX_SB_SQUARE * sizeof(uint16_t)]);
uint8_t *second_pred = get_buf_by_bd(xd, second_pred16);
+ int_mv *best_int_mv = &x->best_mv;
- MV *const best_mv = &x->best_mv.as_mv;
const int search_range = SEARCH_RANGE_8P;
const int sadpb = x->sadperbit16;
// Allow joint search multiple times iteratively for each reference frame
@@ -342,10 +339,7 @@
av1_set_mv_search_range(&x->mv_limits, &ref_mv[id].as_mv);
// Use the mv result from the single mode as mv predictor.
- *best_mv = cur_mv[id].as_mv;
-
- best_mv->col >>= 3;
- best_mv->row >>= 3;
+ best_int_mv->as_fullmv = get_fullmv_from_mv(&cur_mv[id].as_mv);
// Small-range full-pixel motion search.
bestsme = av1_refining_search_8p_c(
@@ -353,13 +347,14 @@
&ref_mv[id].as_mv, second_pred, &x->plane[0].src, &ref_yv12[id]);
if (bestsme < INT_MAX) {
if (mask)
- bestsme = av1_get_mvpred_mask_var(
- x, best_mv, &ref_mv[id].as_mv, second_pred, mask, mask_stride, id,
- &cpi->fn_ptr[bsize], &x->plane[0].src, &ref_yv12[id], 1);
+ bestsme = av1_get_mvpred_mask_var(x, &best_int_mv->as_fullmv,
+ &ref_mv[id].as_mv, second_pred, mask,
+ mask_stride, id, &cpi->fn_ptr[bsize],
+ &x->plane[0].src, &ref_yv12[id], 1);
else
- bestsme = av1_get_mvpred_av_var(x, best_mv, &ref_mv[id].as_mv,
- second_pred, &cpi->fn_ptr[bsize],
- &x->plane[0].src, &ref_yv12[id], 1);
+ bestsme = av1_get_mvpred_av_var(
+ x, &best_int_mv->as_fullmv, &ref_mv[id].as_mv, second_pred,
+ &cpi->fn_ptr[bsize], &x->plane[0].src, &ref_yv12[id], 1);
}
x->mv_limits = tmp_mv_limits;
@@ -382,8 +377,7 @@
if (id) xd->plane[plane].pre[0] = ref_yv12[id];
if (cpi->common.cur_frame_force_integer_mv) {
- x->best_mv.as_mv.row *= 8;
- x->best_mv.as_mv.col *= 8;
+ best_int_mv->as_mv = get_mv_from_fullmv(&best_int_mv->as_fullmv);
}
if (bestsme < INT_MAX && cpi->common.cur_frame_force_integer_mv == 0) {
int dis; /* TODO: use dis in distortion calculation later. */
@@ -399,7 +393,7 @@
// Restore the pointer to the first prediction buffer.
if (id) xd->plane[plane].pre[0] = ref_yv12[0];
if (bestsme < last_besterr[id]) {
- cur_mv[id].as_mv = *best_mv;
+ cur_mv[id] = *best_int_mv;
last_besterr[id] = bestsme;
} else {
break;
@@ -464,7 +458,7 @@
int bestsme = INT_MAX;
int sadpb = x->sadperbit16;
- MV *const best_mv = &x->best_mv.as_mv;
+ int_mv *best_int_mv = &x->best_mv;
int search_range = SEARCH_RANGE_8P;
MvLimits tmp_mv_limits = x->mv_limits;
@@ -473,10 +467,7 @@
av1_set_mv_search_range(&x->mv_limits, &ref_mv.as_mv);
// Use the mv result from the single mode as mv predictor.
- *best_mv = *this_mv;
-
- best_mv->col >>= 3;
- best_mv->row >>= 3;
+ best_int_mv->as_fullmv = get_fullmv_from_mv(this_mv);
// Small-range full-pixel motion search.
bestsme = av1_refining_search_8p_c(
@@ -485,12 +476,13 @@
if (bestsme < INT_MAX) {
if (mask)
bestsme = av1_get_mvpred_mask_var(
- x, best_mv, &ref_mv.as_mv, second_pred, mask, mask_stride, ref_idx,
- &cpi->fn_ptr[bsize], &x->plane[0].src, &ref_yv12, 1);
+ x, &best_int_mv->as_fullmv, &ref_mv.as_mv, second_pred, mask,
+ mask_stride, ref_idx, &cpi->fn_ptr[bsize], &x->plane[0].src,
+ &ref_yv12, 1);
else
- bestsme = av1_get_mvpred_av_var(x, best_mv, &ref_mv.as_mv, second_pred,
- &cpi->fn_ptr[bsize], &x->plane[0].src,
- &ref_yv12, 1);
+ bestsme = av1_get_mvpred_av_var(x, &best_int_mv->as_fullmv, &ref_mv.as_mv,
+ second_pred, &cpi->fn_ptr[bsize],
+ &x->plane[0].src, &ref_yv12, 1);
}
x->mv_limits = tmp_mv_limits;
@@ -503,8 +495,7 @@
}
if (cpi->common.cur_frame_force_integer_mv) {
- x->best_mv.as_mv.row *= 8;
- x->best_mv.as_mv.col *= 8;
+ best_int_mv->as_mv = get_mv_from_fullmv(&best_int_mv->as_fullmv);
}
const int use_fractional_mv =
bestsme < INT_MAX && cpi->common.cur_frame_force_integer_mv == 0;
@@ -525,7 +516,7 @@
// Restore the pointer to the first unscaled prediction buffer.
if (ref_idx) pd->pre[0] = orig_yv12;
- if (bestsme < INT_MAX) *this_mv = *best_mv;
+ if (bestsme < INT_MAX) *this_mv = best_int_mv->as_mv;
*rate_mv = 0;
diff --git a/av1/encoder/nonrd_pickmode.c b/av1/encoder/nonrd_pickmode.c
index 11f3132..750d285 100644
--- a/av1/encoder/nonrd_pickmode.c
+++ b/av1/encoder/nonrd_pickmode.c
@@ -121,7 +121,7 @@
struct buf_2d backup_yv12[MAX_MB_PLANE] = { { 0, 0, 0, 0, 0 } };
int step_param = cpi->mv_step_param;
const int sadpb = x->sadperbit16;
- MV mvp_full;
+ FULLPEL_MV start_mv;
const int ref = mi->ref_frame[0];
const MV ref_mv = av1_get_ref_mv(x, mi->ref_mv_idx).as_mv;
MV center_mv;
@@ -144,10 +144,7 @@
}
av1_set_mv_search_range(&x->mv_limits, &ref_mv);
- mvp_full = ref_mv;
-
- mvp_full.col >>= 3;
- mvp_full.row >>= 3;
+ start_mv = get_fullmv_from_mv(&ref_mv);
if (!use_base_mv)
center_mv = ref_mv;
@@ -155,13 +152,14 @@
center_mv = tmp_mv->as_mv;
av1_full_pixel_search(
- cpi, x, bsize, &mvp_full, step_param, 1, cpi->sf.mv_sf.search_method, 0,
+ cpi, x, bsize, &start_mv, step_param, 1, cpi->sf.mv_sf.search_method, 0,
sadpb, cond_cost_list(cpi, cost_list), ¢er_mv, INT_MAX, 0,
(MI_SIZE * mi_col), (MI_SIZE * mi_row), 0, &cpi->ss_cfg[SS_CFG_SRC], 0);
x->mv_limits = tmp_mv_limits;
*tmp_mv = x->best_mv;
// calculate the bit cost on motion vector
+ MV mvp_full;
mvp_full.row = tmp_mv->as_mv.row * 8;
mvp_full.col = tmp_mv->as_mv.col * 8;
diff --git a/av1/encoder/partition_strategy.c b/av1/encoder/partition_strategy.c
index 8d91210..8832944 100644
--- a/av1/encoder/partition_strategy.c
+++ b/av1/encoder/partition_strategy.c
@@ -326,7 +326,6 @@
// Otherwise do loop through the reference frames and find the one with the
// minimum SSE
const MACROBLOCKD *xd = &x->e_mbd;
- const MV *mv_ref_fulls = pc_tree->mv_ref_fulls;
const int num_planes = 1;
@@ -336,9 +335,10 @@
const int ref = refs[ref_idx];
if (cpi->ref_frame_flags & av1_ref_frame_flag_list[ref]) {
+ const FULLPEL_MV *start_mvs = pc_tree->start_mvs;
unsigned int curr_sse = 0, curr_var = 0;
av1_simple_motion_search(cpi, x, mi_row, mi_col, bsize, ref,
- mv_ref_fulls[ref], num_planes, use_subpixel);
+ start_mvs[ref], num_planes, use_subpixel);
curr_var = cpi->fn_ptr[bsize].vf(
x->plane[0].src.buf, x->plane[0].src.stride, xd->plane[0].dst.buf,
xd->plane[0].dst.stride, &curr_sse);
@@ -349,18 +349,14 @@
}
if (save_mv) {
- const int new_mv_row = x->best_mv.as_mv.row / 8;
- const int new_mv_col = x->best_mv.as_mv.col / 8;
-
- pc_tree->mv_ref_fulls[ref].row = new_mv_row;
- pc_tree->mv_ref_fulls[ref].col = new_mv_col;
+ pc_tree->start_mvs[ref].row = x->best_mv.as_mv.row / 8;
+ pc_tree->start_mvs[ref].col = x->best_mv.as_mv.col / 8;
if (bsize >= BLOCK_8X8) {
for (int r_idx = 0; r_idx < 4; r_idx++) {
// Propagate the new motion vectors to a lower level
PC_TREE *sub_tree = pc_tree->split[r_idx];
- sub_tree->mv_ref_fulls[ref].row = new_mv_row;
- sub_tree->mv_ref_fulls[ref].col = new_mv_col;
+ sub_tree->start_mvs[ref] = pc_tree->start_mvs[ref];
}
}
}
@@ -663,10 +659,10 @@
const int this_mi_col = mi_col + (mb_col << mb_in_mi_size_wide_log2);
unsigned int sse = 0;
unsigned int var = 0;
- const MV ref_mv_full = { .row = 0, .col = 0 };
+ const FULLPEL_MV start_mv = kZeroFullMv;
av1_simple_motion_sse_var(cpi, x, this_mi_row, this_mi_col, mb_size,
- ref_mv_full, 0, &sse, &var);
+ start_mv, 0, &sse, &var);
aom_clear_system_state();
const float mv_row = (float)(x->best_mv.as_mv.row / 8);
diff --git a/av1/encoder/partition_strategy.h b/av1/encoder/partition_strategy.h
index 3b6c50a..ee1d475 100644
--- a/av1/encoder/partition_strategy.h
+++ b/av1/encoder/partition_strategy.h
@@ -173,7 +173,7 @@
}
static INLINE void init_simple_motion_search_mvs(PC_TREE *pc_tree) {
- av1_zero(pc_tree->mv_ref_fulls);
+ av1_zero(pc_tree->start_mvs);
av1_zero(pc_tree->sms_none_feat);
av1_zero(pc_tree->sms_rect_feat);
diff --git a/av1/encoder/rdopt.c b/av1/encoder/rdopt.c
index fcf40eb..33553b5 100644
--- a/av1/encoder/rdopt.c
+++ b/av1/encoder/rdopt.c
@@ -2492,21 +2492,19 @@
}
int step_param = cpi->mv_step_param;
- MV mvp_full = dv_ref.as_mv;
- mvp_full.col >>= 3;
- mvp_full.row >>= 3;
+ FULLPEL_MV start_mv = get_fullmv_from_mv(&dv_ref.as_mv);
const int sadpb = x->sadperbit16;
int cost_list[5];
const int bestsme = av1_full_pixel_search(
- cpi, x, bsize, &mvp_full, step_param, 1, cpi->sf.mv_sf.search_method, 0,
+ cpi, x, bsize, &start_mv, step_param, 1, cpi->sf.mv_sf.search_method, 0,
sadpb, cond_cost_list(cpi, cost_list), &dv_ref.as_mv, INT_MAX, 1,
(MI_SIZE * mi_col), (MI_SIZE * mi_row), 1,
&cpi->ss_cfg[SS_CFG_LOOKAHEAD], 1);
x->mv_limits = tmp_mv_limits;
if (bestsme == INT_MAX) continue;
- mvp_full = x->best_mv.as_mv;
- const MV dv = { .row = mvp_full.row * 8, .col = mvp_full.col * 8 };
+ const MV dv = { .row = x->best_mv.as_mv.row * 8,
+ .col = x->best_mv.as_mv.col * 8 };
if (mv_check_bounds(&x->mv_limits, &dv)) continue;
if (!av1_is_dv_valid(dv, cm, xd, mi_row, mi_col, bsize,
cm->seq_params.mib_size_log2))
diff --git a/av1/encoder/temporal_filter.c b/av1/encoder/temporal_filter.c
index 970c6a5..c44c426 100644
--- a/av1/encoder/temporal_filter.c
+++ b/av1/encoder/temporal_filter.c
@@ -37,10 +37,6 @@
// NOTE: All `tf` in this file means `temporal filtering`.
-// Motion search supports 1/8 precision for sub-pixel.
-#define GET_MV_SUBPEL(x) ((x) << 3)
-#define GET_MV_RAWPEL(x) ((x) >> 3)
-
// Does motion search for blocks in temporal filtering. This is the first step
// for temporal filtering. More specifically, given a frame to be filtered and
// another frame as reference, this function searches the reference frame to
@@ -104,7 +100,7 @@
: (min_frame_size >= 480 ? MV_COST_L1_MIDRES : MV_COST_L1_LOWRES);
// Starting position for motion search.
- MV start_mv = { GET_MV_RAWPEL(ref_mv->row), GET_MV_RAWPEL(ref_mv->col) };
+ FULLPEL_MV start_mv = get_fullmv_from_mv(ref_mv);
// Baseline position for motion search (used for rate distortion comparison).
const MV baseline_mv = kZeroMv;
@@ -153,8 +149,8 @@
const BLOCK_SIZE subblock_size = ss_size_lookup[block_size][1][1];
const int subblock_height = block_size_high[subblock_size];
const int subblock_width = block_size_wide[subblock_size];
- start_mv.row = GET_MV_RAWPEL(ref_mv->row);
- start_mv.col = GET_MV_RAWPEL(ref_mv->col);
+ start_mv = get_fullmv_from_mv(ref_mv);
+
int subblock_idx = 0;
for (int i = 0; i < mb_height; i += subblock_height) {
for (int j = 0; j < mb_width; j += subblock_width) {
diff --git a/av1/encoder/tpl_model.c b/av1/encoder/tpl_model.c
index 49d7d3b..2d656b1 100644
--- a/av1/encoder/tpl_model.c
+++ b/av1/encoder/tpl_model.c
@@ -135,10 +135,7 @@
uint32_t sse;
int cost_list[5];
const MvLimits tmp_mv_limits = x->mv_limits;
- MV best_ref_mv1_full; /* full-pixel value of best_ref_mv1 */
-
- best_ref_mv1_full.col = center_mv.col >> 3;
- best_ref_mv1_full.row = center_mv.row >> 3;
+ FULLPEL_MV start_mv = get_fullmv_from_mv(¢er_mv);
// Setup frame pointers
x->plane[0].src.buf = cur_frame_buf;
@@ -156,10 +153,10 @@
assert(ss_cfg->stride == stride_ref);
- av1_full_pixel_search(cpi, x, bsize, &best_ref_mv1_full, step_param, 1,
- search_method, 0, sadpb, cond_cost_list(cpi, cost_list),
- ¢er_mv, INT_MAX, 0, (MI_SIZE * mi_col),
- (MI_SIZE * mi_row), 0, ss_cfg, 0);
+ av1_full_pixel_search(cpi, x, bsize, &start_mv, step_param, 1, search_method,
+ 0, sadpb, cond_cost_list(cpi, cost_list), ¢er_mv,
+ INT_MAX, 0, (MI_SIZE * mi_col), (MI_SIZE * mi_row), 0,
+ ss_cfg, 0);
/* restore UMV window */
x->mv_limits = tmp_mv_limits;