Commit e3e00797 authored by Debargha Mukherjee's avatar Debargha Mukherjee

Some refactoring and improvements to gobal motion

To facilitate further experiments.
Fixes border, uses standard interpolation filters for
translation only global model, and some refactoring.

Change-Id: I38af6cb83723f92baed23e28d7fc9a0a9544757e
parent 2837b417
......@@ -152,12 +152,12 @@ static INLINE TransformationType get_gmtype(const WarpedMotionParams *gm) {
return AFFINE;
}
static INLINE void set_default_gmparams(WarpedMotionParams *gm) {
static const int32_t default_gm_params[8] = {
static INLINE void set_default_gmparams(WarpedMotionParams *wm) {
static const int32_t default_wm_mat[8] = {
0, 0, (1 << WARPEDMODEL_PREC_BITS), 0, 0, (1 << WARPEDMODEL_PREC_BITS), 0, 0
};
memcpy(gm->wmmat, default_gm_params, sizeof(gm->wmmat));
gm->wmtype = IDENTITY;
memcpy(wm->wmmat, default_wm_mat, sizeof(wm->wmmat));
wm->wmtype = IDENTITY;
}
#endif // CONFIG_GLOBAL_MOTION
......
......@@ -558,7 +558,7 @@ void build_inter_predictors(MACROBLOCKD *xd, int plane,
for (ref = 0; ref < 1 + is_compound; ++ref) {
gm[ref] = &xd->global_motion[mi->mbmi.ref_frame[ref]];
is_global[ref] =
(get_y_mode(mi, block) == ZEROMV && gm[ref]->wmtype != IDENTITY);
(get_y_mode(mi, block) == ZEROMV && gm[ref]->wmtype > TRANSLATION);
}
// TODO(sarahparker) remove these once gm works with all experiments
(void)gm;
......
......@@ -531,8 +531,8 @@ static double highbd_warp_erroradv(WarpedMotionParams *wm, uint8_t *ref8,
gm_err = dst[(j - p_col) + (i - p_row) * p_stride] -
highbd_warp_interpolate(ref, out[0], out[1], width, height,
stride, bd);
no_gm_err = dst[(j - p_col) + (i - p_row) * p_stride] -
ref[(j - p_col) + (i - p_row) * stride];
no_gm_err =
dst[(j - p_col) + (i - p_row) * p_stride] - ref[j + i * stride];
gm_sumerr += highbd_error_measure(gm_err, bd);
no_gm_sumerr += highbd_error_measure(no_gm_err, bd);
}
......@@ -596,8 +596,8 @@ static double warp_erroradv(WarpedMotionParams *wm, uint8_t *ref, int width,
out[1] = ROUND_POWER_OF_TWO_SIGNED(out[1] * y_scale, 4);
gm_err = dst[(j - p_col) + (i - p_row) * p_stride] -
warp_interpolate(ref, out[0], out[1], width, height, stride);
no_gm_err = dst[(j - p_col) + (i - p_row) * p_stride] -
ref[(j - p_col) + (i - p_row) * stride];
no_gm_err =
dst[(j - p_col) + (i - p_row) * p_stride] - ref[j + i * stride];
gm_sumerr += error_measure(gm_err);
no_gm_sumerr += error_measure(no_gm_err);
}
......
......@@ -4613,7 +4613,56 @@ static int input_fpmb_stats(FIRSTPASS_MB_STATS *firstpass_mb_stats,
#if CONFIG_GLOBAL_MOTION
#define MIN_TRANS_THRESH (1 * GM_TRANS_DECODE_FACTOR)
#define GLOBAL_MOTION_ADVANTAGE_THRESH 0.75
// Border over which to compute the global motion
#define ERRORADV_BORDER 0
static const double gm_advantage_thresh[TRANS_TYPES] = {
1.00, // Identity (not used)
0.85, // Translation
0.75, // Rot zoom
0.65, // Affine
0.50, // Homography
};
static void convert_to_params(const double *params, int32_t *model) {
int i;
int alpha_present = 0;
model[0] = (int32_t)floor(params[0] * (1 << GM_TRANS_PREC_BITS) + 0.5);
model[1] = (int32_t)floor(params[1] * (1 << GM_TRANS_PREC_BITS) + 0.5);
model[0] = (int32_t)clamp(model[0], GM_TRANS_MIN, GM_TRANS_MAX) *
GM_TRANS_DECODE_FACTOR;
model[1] = (int32_t)clamp(model[1], GM_TRANS_MIN, GM_TRANS_MAX) *
GM_TRANS_DECODE_FACTOR;
for (i = 2; i < 6; ++i) {
const int diag_value = ((i == 2 || i == 5) ? (1 << GM_ALPHA_PREC_BITS) : 0);
model[i] = (int32_t)floor(params[i] * (1 << GM_ALPHA_PREC_BITS) + 0.5);
model[i] =
(int32_t)clamp(model[i] - diag_value, GM_ALPHA_MIN, GM_ALPHA_MAX);
alpha_present |= (model[i] != 0);
model[i] = (model[i] + diag_value) * GM_ALPHA_DECODE_FACTOR;
}
for (; i < 8; ++i) {
model[i] = (int32_t)floor(params[i] * (1 << GM_ROW3HOMO_PREC_BITS) + 0.5);
model[i] = (int32_t)clamp(model[i], GM_ROW3HOMO_MIN, GM_ROW3HOMO_MAX) *
GM_ROW3HOMO_DECODE_FACTOR;
alpha_present |= (model[i] != 0);
}
if (!alpha_present) {
if (abs(model[0]) < MIN_TRANS_THRESH && abs(model[1]) < MIN_TRANS_THRESH) {
model[0] = 0;
model[1] = 0;
}
}
}
static void convert_model_to_params(const double *params,
WarpedMotionParams *model) {
convert_to_params(params, model->wmmat);
model->wmtype = get_gmtype(model);
}
// Adds some offset to a global motion parameter and handles
// all of the necessary precision shifts, clamping, and
......@@ -4645,30 +4694,49 @@ static int32_t add_param_offset(int param_index, int32_t param_value,
return param_value + (is_one_centered << WARPEDMODEL_PREC_BITS);
}
static void refine_integerized_param(WarpedMotionParams *wm,
static void force_wmtype(WarpedMotionParams *wm, TransformationType wmtype) {
switch (wmtype) {
case IDENTITY: wm->wmmat[0] = 0; wm->wmmat[1] = 0;
case TRANSLATION:
wm->wmmat[2] = 1 << WARPEDMODEL_PREC_BITS;
wm->wmmat[3] = 0;
case ROTZOOM: wm->wmmat[4] = -wm->wmmat[3]; wm->wmmat[5] = wm->wmmat[2];
case AFFINE: wm->wmmat[6] = wm->wmmat[7] = 0;
case HOMOGRAPHY: break;
default: assert(0);
}
wm->wmtype = wmtype;
}
static double refine_integerized_param(WarpedMotionParams *wm,
TransformationType wmtype,
#if CONFIG_AOM_HIGHBITDEPTH
int use_hbd, int bd,
int use_hbd, int bd,
#endif // CONFIG_AOM_HIGHBITDEPTH
uint8_t *ref, int r_width, int r_height,
int r_stride, uint8_t *dst, int d_width,
int d_height, int d_stride,
int n_refinements) {
uint8_t *ref, int r_width, int r_height,
int r_stride, uint8_t *dst, int d_width,
int d_height, int d_stride,
int n_refinements) {
const int border = ERRORADV_BORDER;
int i = 0, p;
int n_params = n_trans_model_params[wm->wmtype];
int n_params = n_trans_model_params[wmtype];
int32_t *param_mat = wm->wmmat;
double step_error;
int32_t step;
int32_t *param;
int32_t curr_param;
int32_t best_param;
double best_error;
double best_error =
av1_warp_erroradv(wm,
force_wmtype(wm, wmtype);
best_error = av1_warp_erroradv(wm,
#if CONFIG_AOM_HIGHBITDEPTH
use_hbd, bd,
use_hbd, bd,
#endif // CONFIG_AOM_HIGHBITDEPTH
ref, r_width, r_height, r_stride, dst, 0, 0, d_width,
d_height, d_stride, 0, 0, 16, 16);
ref, r_width, r_height, r_stride,
dst + border * d_stride + border, border,
border, d_width - 2 * border,
d_height - 2 * border, d_stride, 0, 0, 16, 16);
for (p = 0; p < n_params; ++p) {
param = param_mat + p;
step = 1 << (n_refinements + 1);
......@@ -4677,13 +4745,14 @@ static void refine_integerized_param(WarpedMotionParams *wm,
for (i = 0; i < n_refinements; i++) {
// look to the left
*param = add_param_offset(p, curr_param, -step);
step_error =
av1_warp_erroradv(wm,
step_error = av1_warp_erroradv(
wm,
#if CONFIG_AOM_HIGHBITDEPTH
use_hbd, bd,
use_hbd, bd,
#endif // CONFIG_AOM_HIGHBITDEPTH
ref, r_width, r_height, r_stride, dst, 0, 0,
d_width, d_height, d_stride, 0, 0, 16, 16);
ref, r_width, r_height, r_stride, dst + border * d_stride + border,
border, border, d_width - 2 * border, d_height - 2 * border, d_stride,
0, 0, 16, 16);
if (step_error < best_error) {
step >>= 1;
best_error = step_error;
......@@ -4694,13 +4763,14 @@ static void refine_integerized_param(WarpedMotionParams *wm,
// look to the right
*param = add_param_offset(p, curr_param, step);
step_error =
av1_warp_erroradv(wm,
step_error = av1_warp_erroradv(
wm,
#if CONFIG_AOM_HIGHBITDEPTH
use_hbd, bd,
use_hbd, bd,
#endif // CONFIG_AOM_HIGHBITDEPTH
ref, r_width, r_height, r_stride, dst, 0, 0,
d_width, d_height, d_stride, 0, 0, 16, 16);
ref, r_width, r_height, r_stride, dst + border * d_stride + border,
border, border, d_width - 2 * border, d_height - 2 * border, d_stride,
0, 0, 16, 16);
if (step_error < best_error) {
step >>= 1;
best_error = step_error;
......@@ -4715,50 +4785,9 @@ static void refine_integerized_param(WarpedMotionParams *wm,
}
*param = best_param;
}
// For rotzoom model enforce the constraints on mat[4] and mat[5]
if (wm->wmtype == ROTZOOM) {
param_mat[5] = param_mat[2];
param_mat[4] = -param_mat[3];
}
}
static void convert_to_params(const double *params, int32_t *model) {
int i;
int alpha_present = 0;
model[0] = (int32_t)floor(params[0] * (1 << GM_TRANS_PREC_BITS) + 0.5);
model[1] = (int32_t)floor(params[1] * (1 << GM_TRANS_PREC_BITS) + 0.5);
model[0] = (int32_t)clamp(model[0], GM_TRANS_MIN, GM_TRANS_MAX) *
GM_TRANS_DECODE_FACTOR;
model[1] = (int32_t)clamp(model[1], GM_TRANS_MIN, GM_TRANS_MAX) *
GM_TRANS_DECODE_FACTOR;
for (i = 2; i < 6; ++i) {
const int diag_value = ((i == 2 || i == 5) ? (1 << GM_ALPHA_PREC_BITS) : 0);
model[i] = (int32_t)floor(params[i] * (1 << GM_ALPHA_PREC_BITS) + 0.5);
model[i] =
(int32_t)clamp(model[i] - diag_value, GM_ALPHA_MIN, GM_ALPHA_MAX);
alpha_present |= (model[i] != 0);
model[i] = (model[i] + diag_value) * GM_ALPHA_DECODE_FACTOR;
}
for (; i < 8; ++i) {
model[i] = (int32_t)floor(params[i] * (1 << GM_ROW3HOMO_PREC_BITS) + 0.5);
model[i] = (int32_t)clamp(model[i], GM_ROW3HOMO_MIN, GM_ROW3HOMO_MAX) *
GM_ROW3HOMO_DECODE_FACTOR;
alpha_present |= (model[i] != 0);
}
if (!alpha_present) {
if (abs(model[0]) < MIN_TRANS_THRESH && abs(model[1]) < MIN_TRANS_THRESH) {
model[0] = 0;
model[1] = 0;
}
}
}
static void convert_model_to_params(const double *params,
WarpedMotionParams *model) {
convert_to_params(params, model->wmmat);
model->wmtype = get_gmtype(model);
force_wmtype(wm, wmtype);
wm->wmtype = get_gmtype(wm);
return best_error;
}
#endif // CONFIG_GLOBAL_MOTION
......@@ -4803,27 +4832,18 @@ static void encode_frame_internal(AV1_COMP *cpi) {
params)) {
convert_model_to_params(params, &cm->global_motion[frame]);
if (cm->global_motion[frame].wmtype != IDENTITY) {
refine_integerized_param(
&cm->global_motion[frame],
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,
#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);
// compute the advantage of using gm parameters over 0 motion
erroradvantage = av1_warp_erroradv(
&cm->global_motion[frame],
#if CONFIG_AOM_HIGHBITDEPTH
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, 0, 0,
cpi->Source->y_width, cpi->Source->y_height,
cpi->Source->y_stride, 0, 0, 16, 16);
if (erroradvantage > GLOBAL_MOTION_ADVANTAGE_THRESH)
// Not enough advantage in using a global model. Make identity.
if (erroradvantage >
gm_advantage_thresh[cm->global_motion[frame].wmtype]) {
set_default_gmparams(&cm->global_motion[frame]);
}
}
}
aom_clear_system_state();
......
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