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
diff --git a/av1/common/mv.h b/av1/common/mv.h index a591329..cd4b4e6 100644 --- a/av1/common/mv.h +++ b/av1/common/mv.h
@@ -55,14 +55,14 @@ 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
diff --git a/av1/encoder/encodeframe.c b/av1/encoder/encodeframe.c index e4873ab..47ca2fc 100644 --- a/av1/encoder/encodeframe.c +++ b/av1/encoder/encodeframe.c
@@ -4896,28 +4896,32 @@ 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(); }
diff --git a/av1/encoder/encoder.c b/av1/encoder/encoder.c index b21727b..1123cf5 100644 --- a/av1/encoder/encoder.c +++ b/av1/encoder/encoder.c
@@ -2884,14 +2884,14 @@ } #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;
diff --git a/av1/encoder/ransac.c b/av1/encoder/ransac.c index 9c19903..8bacfe5 100644 --- a/av1/encoder/ransac.c +++ b/av1/encoder/ransac.c
@@ -151,7 +151,6 @@ *number_of_inliers = 0; if (npoints < minpts * MINPTS_MULTIPLIER || npoints == 0) { - printf("Cannot find motion with %d matches\n", npoints); return 1; }
diff --git a/av1/encoder/rdopt.c b/av1/encoder/rdopt.c index b7faf03..3b62c1c 100644 --- a/av1/encoder/rdopt.c +++ b/av1/encoder/rdopt.c
@@ -4333,29 +4333,22 @@ #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 @@ #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 @@ 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 @@ #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