Commit b0f6bd44 authored by Debargha Mukherjee's avatar Debargha Mukherjee

Support affine/homography models for global motion

With this patch affine or homography models can be enabled
by simply changing the value of the GLOBAL_TRANS_TYPES
macro in common/mv.h to 4 and 5 respectively. Currently
it is left at supporting only rotzoom. There is a small
gain with enabling affine.

Also refactors costing to change based on the model type.

Change-Id: I46c1759de06c42c176c64ec21307ff347ddcc259
parent 91ad0e8b
......@@ -55,14 +55,14 @@ typedef struct mv32 {
typedef enum {
IDENTITY = 0, // identity transformation, 0-parameter
TRANSLATION = 1, // translational motion 2-parameter
ROTZOOM = 2, // simplified affine with rotation and zoom only, 4-parameter
ROTZOOM = 2, // simplified affine with rotation + zoom only, 4-parameter
AFFINE = 3, // affine, 6-parameter
HOMOGRAPHY = 4, // homography, 8-parameter
TRANS_TYPES = 5,
} TransformationType;
/* clang-format on */
// Number of types used for global motion (must be <= TRANS_TYPES)
// Number of types used for global motion (must be >= 3 and <= TRANS_TYPES)
#define GLOBAL_TRANS_TYPES 3
// number of parameters used by each transformation in TransformationTypes
......
......@@ -4896,28 +4896,32 @@ static void encode_frame_internal(AV1_COMP *cpi) {
for (frame = LAST_FRAME; frame <= ALTREF_FRAME; ++frame) {
ref_buf = get_ref_frame_buffer(cpi, frame);
if (ref_buf) {
TransformationType model;
aom_clear_system_state();
if (compute_global_motion_feature_based(GLOBAL_TRANS_TYPES - 1,
cpi->Source, ref_buf,
for (model = ROTZOOM; model < GLOBAL_TRANS_TYPES; ++model) {
if (compute_global_motion_feature_based(model, cpi->Source, ref_buf,
#if CONFIG_AOM_HIGHBITDEPTH
cpi->common.bit_depth,
cpi->common.bit_depth,
#endif // CONFIG_AOM_HIGHBITDEPTH
params)) {
convert_model_to_params(params, &cm->global_motion[frame]);
if (cm->global_motion[frame].wmtype != IDENTITY) {
erroradvantage = refine_integerized_param(
&cm->global_motion[frame], cm->global_motion[frame].wmtype,
params)) {
convert_model_to_params(params, &cm->global_motion[frame]);
if (cm->global_motion[frame].wmtype != IDENTITY) {
erroradvantage = refine_integerized_param(
&cm->global_motion[frame], cm->global_motion[frame].wmtype,
#if CONFIG_AOM_HIGHBITDEPTH
xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH, xd->bd,
xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH, xd->bd,
#endif // CONFIG_AOM_HIGHBITDEPTH
ref_buf->y_buffer, ref_buf->y_width, ref_buf->y_height,
ref_buf->y_stride, cpi->Source->y_buffer, cpi->Source->y_width,
cpi->Source->y_height, cpi->Source->y_stride, 3);
if (erroradvantage >
gm_advantage_thresh[cm->global_motion[frame].wmtype]) {
set_default_gmparams(&cm->global_motion[frame]);
ref_buf->y_buffer, ref_buf->y_width, ref_buf->y_height,
ref_buf->y_stride, cpi->Source->y_buffer,
cpi->Source->y_width, cpi->Source->y_height,
cpi->Source->y_stride, 3);
if (erroradvantage >
gm_advantage_thresh[cm->global_motion[frame].wmtype]) {
set_default_gmparams(&cm->global_motion[frame]);
}
}
}
if (cm->global_motion[frame].wmtype != IDENTITY) break;
}
aom_clear_system_state();
}
......
......@@ -2884,14 +2884,14 @@ static int scale_down(AV1_COMP *cpi, int q) {
}
#if CONFIG_GLOBAL_MOTION
#define MIN_GLOBAL_MOTION_BLKS 4
static int recode_loop_test_global_motion(AV1_COMP *cpi) {
static const int min_blocks[TRANS_TYPES] = { 0, 2, 4, 6, 8 };
int i;
int recode = 0;
AV1_COMMON *const cm = &cpi->common;
for (i = LAST_FRAME; i <= ALTREF_FRAME; ++i) {
if (cm->global_motion[i].wmtype != IDENTITY &&
cpi->global_motion_used[i] < MIN_GLOBAL_MOTION_BLKS) {
cpi->global_motion_used[i] < min_blocks[cm->global_motion[i].wmtype]) {
set_default_gmparams(&cm->global_motion[i]);
#if CONFIG_REF_MV
recode = 1;
......
......@@ -151,7 +151,6 @@ static int ransac(double *matched_points, int npoints, int *number_of_inliers,
*number_of_inliers = 0;
if (npoints < minpts * MINPTS_MULTIPLIER || npoints == 0) {
printf("Cannot find motion with %d matches\n", npoints);
return 1;
}
......
......@@ -4333,29 +4333,22 @@ static int get_interinter_compound_type_bits(BLOCK_SIZE bsize,
#endif // CONFIG_EXT_INTER
#if CONFIG_GLOBAL_MOTION
#define GLOBAL_MOTION_COST_AMORTIZATION_BLKS 8
#if GLOBAL_MOTION_COST_AMORTIZATION_BLKS > 0
static int get_gmbitcost(const AV1_COMP *const cpi,
const WarpedMotionParams *gm) {
static int GLOBAL_MOTION_RATE(const AV1_COMP *const cpi, int ref) {
static const int gm_amortization_blks[TRANS_TYPES] = { 4, 6, 8, 10, 12 };
static const int gm_params_cost[TRANS_TYPES] = {
GM_IDENTITY_BITS, GM_TRANSLATION_BITS, GM_ROTZOOM_BITS,
GM_AFFINE_BITS, GM_HOMOGRAPHY_BITS,
};
const int cost = (gm_params_cost[gm->wmtype] << AV1_PROB_COST_SHIFT) +
cpi->gmtype_cost[gm->wmtype];
const WarpedMotionParams *gm = &cpi->common.global_motion[(ref)];
assert(gm->wmtype < GLOBAL_TRANS_TYPES);
return cost;
if (cpi->global_motion_used[ref] >= gm_amortization_blks[gm->wmtype]) {
return 0;
} else {
const int cost = (gm_params_cost[gm->wmtype] << AV1_PROB_COST_SHIFT) +
cpi->gmtype_cost[gm->wmtype];
return cost / gm_amortization_blks[gm->wmtype];
}
}
#define GLOBAL_MOTION_RATE(ref) \
(cpi->global_motion_used[ref] >= GLOBAL_MOTION_COST_AMORTIZATION_BLKS \
? 0 \
: get_gmbitcost(cpi, &cm->global_motion[(ref)]) / \
GLOBAL_MOTION_COST_AMORTIZATION_BLKS)
#else
#define GLOBAL_MOTION_RATE(ref) 0
#endif // GLOBAL_MOTION_COST_AMORTIZATION_BLKS > 0
#endif // CONFIG_GLOBAL_MOTION
static int set_and_cost_bmi_mvs(const AV1_COMP *const cpi, MACROBLOCK *x,
......@@ -4369,9 +4362,6 @@ static int set_and_cost_bmi_mvs(const AV1_COMP *const cpi, MACROBLOCK *x,
#endif // CONFIG_EXT_INTER
int_mv *best_ref_mv[2], const int *mvjcost,
int *mvcost[2]) {
#if CONFIG_GLOBAL_MOTION
const AV1_COMMON *cm = &cpi->common;
#endif // CONFIG_GLOBAL_MOTION
MODE_INFO *const mic = xd->mi[0];
const MB_MODE_INFO *const mbmi = &mic->mbmi;
const MB_MODE_INFO_EXT *const mbmi_ext = x->mbmi_ext;
......@@ -4427,13 +4417,13 @@ static int set_and_cost_bmi_mvs(const AV1_COMP *const cpi, MACROBLOCK *x,
gm_get_motion_vector(&cpi->common.global_motion[mbmi->ref_frame[0]],
cpi->common.allow_high_precision_mv)
.as_int;
thismvcost += GLOBAL_MOTION_RATE(mbmi->ref_frame[0]);
thismvcost += GLOBAL_MOTION_RATE(cpi, mbmi->ref_frame[0]);
if (is_compound) {
this_mv[1].as_int =
gm_get_motion_vector(&cpi->common.global_motion[mbmi->ref_frame[1]],
cpi->common.allow_high_precision_mv)
.as_int;
thismvcost += GLOBAL_MOTION_RATE(mbmi->ref_frame[1]);
thismvcost += GLOBAL_MOTION_RATE(cpi, mbmi->ref_frame[1]);
}
#else // CONFIG_GLOBAL_MOTION
this_mv[0].as_int = 0;
......@@ -8059,9 +8049,9 @@ static int64_t handle_inter_mode(
#endif // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
#if CONFIG_GLOBAL_MOTION
if (this_mode == ZEROMV) {
rd_stats->rate += GLOBAL_MOTION_RATE(mbmi->ref_frame[0]);
rd_stats->rate += GLOBAL_MOTION_RATE(cpi, mbmi->ref_frame[0]);
if (is_comp_pred)
rd_stats->rate += GLOBAL_MOTION_RATE(mbmi->ref_frame[1]);
rd_stats->rate += GLOBAL_MOTION_RATE(cpi, mbmi->ref_frame[1]);
}
#endif // CONFIG_GLOBAL_MOTION
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment