Commit 265db6d0 authored by Debargha Mukherjee's avatar Debargha Mukherjee

Improves/refactors rd costing for global motion

Improves and simplifies costing for global motion to use the
actual bits used to communicate the global motion parameters.
Removes some of the old hacks.
This patch also includes necessary refactoring to incorporate
reference based coding of the motion parameters to follow.

lowres results: -1.489% (up from -1.333%)

Change-Id: I994dc97046011de4261633ccb0c9d71e374f2c5a
parent b06af207
......@@ -141,10 +141,10 @@ typedef struct {
// Maximum number of bits used for different models
#define GM_IDENTITY_BITS 0
#define GM_TRANSLATION_BITS ((GM_ABS_TRANS_BITS + 1) * 2)
#define GM_ROTZOOM_BITS (GM_TRANSLATION_BITS + (GM_ABS_ALPHA_BITS + 1) * 2)
#define GM_AFFINE_BITS (GM_ROTZOOM_BITS + (GM_ABS_ALPHA_BITS + 1) * 2)
#define GM_HOMOGRAPHY_BITS (GM_AFFINE_BITS + (GM_ABS_ROW3HOMO_BITS + 1) * 2)
#define GM_TRANSLATION_BITS ((GM_ABS_TRANS_BITS + 2) * 2)
#define GM_ROTZOOM_BITS (GM_TRANSLATION_BITS + (GM_ABS_ALPHA_BITS + 2) * 2)
#define GM_AFFINE_BITS (GM_ROTZOOM_BITS + (GM_ABS_ALPHA_BITS + 2) * 2)
#define GM_HOMOGRAPHY_BITS (GM_AFFINE_BITS + (GM_ABS_ROW3HOMO_BITS + 2) * 2)
#define GM_HORTRAPEZOID_BITS \
(GM_AFFINE_BITS - GM_ABS_ALPHA_BITS + GM_ABS_ROW3HOMO_BITS)
#define GM_VERTRAPEZOID_BITS \
......
......@@ -4612,19 +4612,18 @@ static void write_global_motion(AV1_COMP *cpi, aom_writer *w) {
// With ref-mv, clearing unused global motion models here is
// unsafe, and we need to rely on the recode loop to do it
// instead. See av1_find_mv_refs for details.
if (!cpi->global_motion_used[frame][0]) {
if (!cpi->global_motion_used[frame]) {
set_default_gmparams(&cm->global_motion[frame]);
}
#endif
write_global_motion_params(&cm->global_motion[frame],
cm->fc->global_motion_types_prob, w);
/*
printf("Frame %d/%d: Enc Ref %d (used %d/%d): %d %d %d %d\n",
printf("Frame %d/%d: Enc Ref %d (used %d): %d %d %d %d\n",
cm->current_video_frame, cm->show_frame, frame,
cpi->global_motion_used[frame][0], cpi->global_motion_used[frame][1],
cm->global_motion[frame].wmmat[0], cm->global_motion[frame].wmmat[1],
cm->global_motion[frame].wmmat[2],
cm->global_motion[frame].wmmat[3]);
cpi->global_motion_used[frame], cm->global_motion[frame].wmmat[0],
cm->global_motion[frame].wmmat[1], cm->global_motion[frame].wmmat[2],
cm->global_motion[frame].wmmat[3]);
*/
}
}
......
......@@ -1029,14 +1029,11 @@ static void update_global_motion_used(PREDICTION_MODE mode, BLOCK_SIZE bsize,
|| mode == ZERO_ZEROMV
#endif
) {
const int num_4x4s = bsize >= BLOCK_8X8
? num_4x4_blocks_wide_lookup[bsize] *
num_4x4_blocks_high_lookup[bsize]
: 1;
const int num_4x4s =
num_4x4_blocks_wide_lookup[bsize] * num_4x4_blocks_high_lookup[bsize];
int ref;
for (ref = 0; ref < 1 + has_second_ref(mbmi); ++ref) {
++cpi->global_motion_used[mbmi->ref_frame[ref]][0];
cpi->global_motion_used[mbmi->ref_frame[ref]][1] += num_4x4s;
cpi->global_motion_used[mbmi->ref_frame[ref]] += num_4x4s;
}
}
}
......@@ -5021,6 +5018,45 @@ static int input_fpmb_stats(FIRSTPASS_MB_STATS *firstpass_mb_stats,
}
#endif
#if CONFIG_GLOBAL_MOTION
static int gm_get_params_cost(WarpedMotionParams *gm) {
assert(gm->wmtype < GLOBAL_TRANS_TYPES);
int params_cost = 0;
switch (gm->wmtype) {
case HOMOGRAPHY:
case HORTRAPEZOID:
case VERTRAPEZOID:
if (gm->wmtype != HORTRAPEZOID)
params_cost += gm->wmmat[6] == 0 ? 1 : (GM_ABS_ROW3HOMO_BITS + 2);
if (gm->wmtype != VERTRAPEZOID)
params_cost += gm->wmmat[7] == 0 ? 1 : (GM_ABS_ROW3HOMO_BITS + 2);
// Fallthrough intended
case AFFINE:
case ROTZOOM:
params_cost += gm->wmmat[2] == (1 << WARPEDMODEL_PREC_BITS)
? 1
: (GM_ABS_ALPHA_BITS + 2);
if (gm->wmtype != VERTRAPEZOID)
params_cost += gm->wmmat[3] == 0 ? 1 : (GM_ABS_ALPHA_BITS + 2);
if (gm->wmtype >= AFFINE) {
if (gm->wmtype != HORTRAPEZOID)
params_cost += gm->wmmat[4] == 0 ? 1 : (GM_ABS_ALPHA_BITS + 2);
params_cost += gm->wmmat[5] == (1 << WARPEDMODEL_PREC_BITS)
? 1
: (GM_ABS_ALPHA_BITS + 2);
}
// Fallthrough intended
case TRANSLATION:
params_cost += gm->wmmat[0] == 0 ? 1 : (GM_ABS_TRANS_BITS + 2);
params_cost += gm->wmmat[1] == 0 ? 1 : (GM_ABS_TRANS_BITS + 2);
// Fallthrough intended
case IDENTITY: break;
default: assert(0);
}
return (params_cost << AV1_PROB_COST_SHIFT);
}
#endif // CONFIG_GLOBAL_MOTION
static void encode_frame_internal(AV1_COMP *cpi) {
ThreadData *const td = &cpi->td;
MACROBLOCK *const x = &td->mb;
......@@ -5115,6 +5151,10 @@ static void encode_frame_internal(AV1_COMP *cpi) {
}
aom_clear_system_state();
}
cpi->gmparams_cost[frame] =
gm_get_params_cost(&cm->global_motion[frame]) +
cpi->gmtype_cost[cm->global_motion[frame].wmtype] -
cpi->gmtype_cost[IDENTITY];
}
cpi->global_motion_search_done = 1;
}
......
......@@ -3038,20 +3038,21 @@ static int scale_down(AV1_COMP *cpi, int q) {
}
#if CONFIG_GLOBAL_MOTION
#define GM_RECODE_LOOP_NUM4X4_FACTOR 256
static int recode_loop_test_global_motion(AV1_COMP *cpi) {
static const int min_blocks[TRANS_TYPES] = { 0, 60, 120, 180, 180, 180, 240 };
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][1] <
min_blocks[cm->global_motion[i].wmtype]) {
cpi->global_motion_used[i] * GM_RECODE_LOOP_NUM4X4_FACTOR <
cpi->gmparams_cost[i]) {
set_default_gmparams(&cm->global_motion[i]);
cpi->gmparams_cost[i] = 0;
#if CONFIG_REF_MV
recode = 1;
#else
recode |= (cpi->global_motion_used[i][1] > 0);
recode |= (cpi->global_motion_used[i] > 0);
#endif
}
}
......
......@@ -596,6 +596,7 @@ typedef struct AV1_COMP {
#endif // CONFIG_LOOP_RESTORATION
#if CONFIG_GLOBAL_MOTION
int gmtype_cost[TRANS_TYPES];
int gmparams_cost[TOTAL_REFS_PER_FRAME];
#endif // CONFIG_GLOBAL_MOTION
int multi_arf_allowed;
......@@ -654,9 +655,8 @@ typedef struct AV1_COMP {
int arf_map[MAX_EXT_ARFS + 1];
#endif // CONFIG_EXT_REFS
#if CONFIG_GLOBAL_MOTION
// Stores number of prediction blocks using global motion and the
// number of 4x4 blocks using it per reference frame.
int global_motion_used[TOTAL_REFS_PER_FRAME][2];
// Stores number of 4x4 blocks using global motion per reference frame.
int global_motion_used[TOTAL_REFS_PER_FRAME];
int global_motion_search_done;
#endif
#if CONFIG_REFERENCE_BUFFER
......
......@@ -5128,28 +5128,6 @@ static int get_interinter_compound_type_bits(BLOCK_SIZE bsize,
}
#endif // CONFIG_EXT_INTER
#if CONFIG_GLOBAL_MOTION
static int GLOBAL_MOTION_RATE(const AV1_COMP *const cpi, int ref) {
static const int gm_amortization_blks[TRANS_TYPES] = {
4, 6, 8, 10, 10, 10, 12
};
static const int gm_params_cost[TRANS_TYPES] = {
GM_IDENTITY_BITS, GM_TRANSLATION_BITS, GM_ROTZOOM_BITS,
GM_AFFINE_BITS, GM_HORTRAPEZOID_BITS, GM_VERTRAPEZOID_BITS,
GM_HOMOGRAPHY_BITS,
};
const WarpedMotionParams *gm = &cpi->common.global_motion[(ref)];
assert(gm->wmtype < GLOBAL_TRANS_TYPES);
if (cpi->global_motion_used[ref][0] >= 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];
}
}
#endif // CONFIG_GLOBAL_MOTION
static int set_and_cost_bmi_mvs(
const AV1_COMP *const cpi, MACROBLOCK *x, MACROBLOCKD *xd, int i,
PREDICTION_MODE mode, int_mv this_mv[2],
......@@ -5221,7 +5199,6 @@ static int set_and_cost_bmi_mvs(
cpi->common.allow_high_precision_mv, mbmi->sb_type, mi_col,
mi_row, i)
.as_int;
thismvcost += GLOBAL_MOTION_RATE(cpi, mbmi->ref_frame[ref]);
#else
this_mv[ref].as_int = 0;
#endif // CONFIG_GLOBAL_MOTION
......@@ -5284,8 +5261,6 @@ static int set_and_cost_bmi_mvs(
cpi->common.allow_high_precision_mv,
mbmi->sb_type, mi_col, mi_row, i)
.as_int;
thismvcost += GLOBAL_MOTION_RATE(cpi, mbmi->ref_frame[0]) +
GLOBAL_MOTION_RATE(cpi, mbmi->ref_frame[1]);
#else
this_mv[0].as_int = 0;
this_mv[1].as_int = 0;
......@@ -8659,9 +8634,6 @@ static int64_t motion_mode_rd(
|| this_mode == ZERO_ZEROMV
#endif // CONFIG_EXT_INTER
) {
rd_stats->rate += GLOBAL_MOTION_RATE(cpi, mbmi->ref_frame[0]);
if (is_comp_pred)
rd_stats->rate += GLOBAL_MOTION_RATE(cpi, mbmi->ref_frame[1]);
if (is_nontrans_global_motion(xd)) {
rd_stats->rate -= rs;
#if CONFIG_DUAL_FILTER
......
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