Commit e9bd26b8 authored by Sarah Parker's avatar Sarah Parker

Add affine model to global motion

Change-Id: I9cd355a3ea344ef66a61028efa25d94f54e7e2bd
parent f9c01c7b
......@@ -124,11 +124,12 @@ static const uint8_t log_in_base_2[] = {
const vpx_tree_index vp10_global_motion_types_tree
[TREE_SIZE(GLOBAL_MOTION_TYPES)] = {
-GLOBAL_ZERO, 2,
-GLOBAL_TRANSLATION, -GLOBAL_ROTZOOM
-GLOBAL_TRANSLATION, 4,
-GLOBAL_ROTZOOM, -GLOBAL_AFFINE
};
static const vpx_prob default_global_motion_types_prob
[GLOBAL_MOTION_TYPES - 1] = {224, 128};
[GLOBAL_MOTION_TYPES - 1] = {224, 128, 128};
#endif // CONFIG_GLOBAL_MOTION
static INLINE int mv_class_base(MV_CLASS_TYPE c) {
......
......@@ -41,6 +41,10 @@ typedef struct mv32 {
// | a b|
// |-b a|
//
// and a, b, c, d in affine model:
// | a b|
// | c d|
//
// Anything ending in PREC_BITS is the number of bits of precision
// to maintain when converting from double to integer.
//
......@@ -76,6 +80,7 @@ typedef enum {
GLOBAL_ZERO = 0,
GLOBAL_TRANSLATION = 1,
GLOBAL_ROTZOOM = 2,
GLOBAL_AFFINE = 3,
GLOBAL_MOTION_TYPES
} GLOBAL_MOTION_TYPE;
......@@ -84,12 +89,36 @@ typedef struct {
WarpedMotionParams motion_params;
} Global_Motion_Params;
static INLINE TransformationType gm_to_trans_type(GLOBAL_MOTION_TYPE gmtype) {
switch (gmtype) {
case GLOBAL_ZERO:
return UNKNOWN_TRANSFORM;
break;
case GLOBAL_TRANSLATION:
return TRANSLATION;
break;
case GLOBAL_ROTZOOM:
return ROTZOOM;
break;
case GLOBAL_AFFINE:
return AFFINE;
break;
default:
assert(0);
}
return UNKNOWN_TRANSFORM;
}
static INLINE GLOBAL_MOTION_TYPE get_gmtype(const Global_Motion_Params *gm) {
if (gm->motion_params.wmmat[2] == 0 && gm->motion_params.wmmat[3] == 0) {
return ((gm->motion_params.wmmat[0] | gm->motion_params.wmmat[1]) ?
GLOBAL_TRANSLATION : GLOBAL_ZERO);
if (gm->motion_params.wmmat[4] == 0 && gm->motion_params.wmmat[5] == 0) {
if (gm->motion_params.wmmat[2] == 0 && gm->motion_params.wmmat[3] == 0) {
return ((gm->motion_params.wmmat[0] | gm->motion_params.wmmat[1]) ?
GLOBAL_TRANSLATION : GLOBAL_ZERO);
} else {
return GLOBAL_ROTZOOM;
}
} else {
return GLOBAL_ROTZOOM;
return GLOBAL_AFFINE;
}
}
#endif // CONFIG_GLOBAL_MOTION
......
......@@ -42,9 +42,13 @@ typedef enum {
HOMOGRAPHY, // homography, 8-parameter
AFFINE, // affine, 6-parameter
ROTZOOM, // simplified affine with rotation and zoom only, 4-parameter
TRANSLATION // translational motion 2-parameter
TRANSLATION, // translational motion 2-parameter
TRANS_TYPES
} TransformationType;
// number of parameters used by each transformation in TransformationTypes
static const int n_trans_model_params[TRANS_TYPES] = {9, 6, 4, 2};
typedef struct {
TransformationType wmtype;
int wmmat[8]; // For homography wmmat[9] is assumed to be 1
......
......@@ -3450,32 +3450,31 @@ static void read_global_motion_params(Global_Motion_Params *params,
GLOBAL_MOTION_TYPE gmtype = vp10_read_tree(r, vp10_global_motion_types_tree,
probs);
params->gmtype = gmtype;
params->motion_params.wmtype = gm_to_trans_type(gmtype);
switch (gmtype) {
case GLOBAL_ZERO:
break;
case GLOBAL_TRANSLATION:
params->motion_params.wmtype = TRANSLATION;
params->motion_params.wmmat[0] =
vp10_read_primitive_symmetric(r, GM_ABS_TRANS_BITS) *
GM_TRANS_DECODE_FACTOR;
params->motion_params.wmmat[1] =
vp10_read_primitive_symmetric(r, GM_ABS_TRANS_BITS) *
GM_TRANS_DECODE_FACTOR;
break;
case GLOBAL_AFFINE:
params->motion_params.wmmat[4] =
(vp10_read_primitive_symmetric(r, GM_ABS_ALPHA_BITS) *
GM_ALPHA_DECODE_FACTOR) + (1 << WARPEDMODEL_PREC_BITS);
params->motion_params.wmmat[5] =
vp10_read_primitive_symmetric(r, GM_ABS_ALPHA_BITS) *
GM_ALPHA_DECODE_FACTOR;
case GLOBAL_ROTZOOM:
params->motion_params.wmtype = ROTZOOM;
params->motion_params.wmmat[0] =
vp10_read_primitive_symmetric(r, GM_ABS_TRANS_BITS) *
GM_TRANS_DECODE_FACTOR;
params->motion_params.wmmat[1] =
vp10_read_primitive_symmetric(r, GM_ABS_TRANS_BITS) *
GM_TRANS_DECODE_FACTOR;
params->motion_params.wmmat[2] =
(vp10_read_primitive_symmetric(r, GM_ABS_ALPHA_BITS) *
GM_ALPHA_DECODE_FACTOR) + (1 << WARPEDMODEL_PREC_BITS);
params->motion_params.wmmat[3] =
vp10_read_primitive_symmetric(r, GM_ABS_ALPHA_BITS) *
GM_ALPHA_DECODE_FACTOR;
case GLOBAL_TRANSLATION:
params->motion_params.wmmat[0] =
vp10_read_primitive_symmetric(r, GM_ABS_TRANS_BITS) *
GM_TRANS_DECODE_FACTOR;
params->motion_params.wmmat[1] =
vp10_read_primitive_symmetric(r, GM_ABS_TRANS_BITS) *
GM_TRANS_DECODE_FACTOR;
break;
default:
assert(0);
......
......@@ -3187,6 +3187,7 @@ static void write_uncompressed_header(VP10_COMP *cpi,
write_tile_info(cm, wb);
}
#if CONFIG_GLOBAL_MOTION
static void write_global_motion_params(Global_Motion_Params *params,
vpx_prob *probs,
......@@ -3197,21 +3198,21 @@ static void write_global_motion_params(Global_Motion_Params *params,
switch (gmtype) {
case GLOBAL_ZERO:
break;
case GLOBAL_TRANSLATION:
vp10_write_primitive_symmetric(w, params->motion_params.wmmat[0],
GM_ABS_TRANS_BITS);
vp10_write_primitive_symmetric(w, params->motion_params.wmmat[1],
GM_ABS_TRANS_BITS);
break;
case GLOBAL_AFFINE:
vp10_write_primitive_symmetric(w, params->motion_params.wmmat[4],
GM_ABS_ALPHA_BITS);
vp10_write_primitive_symmetric(w, params->motion_params.wmmat[5],
GM_ABS_ALPHA_BITS);
case GLOBAL_ROTZOOM:
vp10_write_primitive_symmetric(w, params->motion_params.wmmat[0],
GM_ABS_TRANS_BITS);
vp10_write_primitive_symmetric(w, params->motion_params.wmmat[1],
GM_ABS_TRANS_BITS);
vp10_write_primitive_symmetric(w, params->motion_params.wmmat[2],
GM_ABS_ALPHA_BITS);
vp10_write_primitive_symmetric(w, params->motion_params.wmmat[3],
GM_ABS_ALPHA_BITS);
case GLOBAL_TRANSLATION:
vp10_write_primitive_symmetric(w, params->motion_params.wmmat[0],
GM_ABS_TRANS_BITS);
vp10_write_primitive_symmetric(w, params->motion_params.wmmat[1],
GM_ABS_TRANS_BITS);
break;
default:
assert(0);
......
......@@ -4538,28 +4538,11 @@ static int input_fpmb_stats(FIRSTPASS_MB_STATS *firstpass_mb_stats,
#if CONFIG_GLOBAL_MOTION
#define MIN_TRANS_THRESH 8
static void convert_translation_to_params(
double *H, Global_Motion_Params *model) {
model->motion_params.wmmat[0] = (int) floor(H[0] *
(1 << GM_TRANS_PREC_BITS) + 0.5);
model->motion_params.wmmat[1] = (int) floor(H[1] *
(1 << GM_TRANS_PREC_BITS) + 0.5);
if (abs(model->motion_params.wmmat[0]) < MIN_TRANS_THRESH &&
abs(model->motion_params.wmmat[1]) < MIN_TRANS_THRESH) {
model->motion_params.wmmat[0] = 0;
model->motion_params.wmmat[1] = 0;
} else {
model->motion_params.wmmat[0] =
clamp(model->motion_params.wmmat[0],
GM_TRANS_MIN, GM_TRANS_MAX);
model->motion_params.wmmat[1] =
clamp(model->motion_params.wmmat[1],
GM_TRANS_MIN, GM_TRANS_MAX);
}
}
static void convert_rotzoom_to_params(double *H, Global_Motion_Params *model) {
static void convert_to_params(double *H, TransformationType type,
Global_Motion_Params *model) {
int i;
int alpha_present = 0;
int n_params = n_trans_model_params[type];
model->motion_params.wmmat[0] = (int) floor(H[0] *
(1 << GM_TRANS_PREC_BITS) + 0.5);
model->motion_params.wmmat[1] = (int) floor(H[1] *
......@@ -4571,19 +4554,17 @@ static void convert_rotzoom_to_params(double *H, Global_Motion_Params *model) {
clamp(model->motion_params.wmmat[1],
GM_TRANS_MIN, GM_TRANS_MAX);
model->motion_params.wmmat[2] = (int) floor(H[2] *
(1 << GM_ALPHA_PREC_BITS) + 0.5) -
(1 << GM_ALPHA_PREC_BITS);
model->motion_params.wmmat[3] = (int) floor(H[3] *
(1 << GM_ALPHA_PREC_BITS) + 0.5);
model->motion_params.wmmat[2] = clamp(model->motion_params.wmmat[2],
GM_ALPHA_MIN, GM_ALPHA_MAX);
model->motion_params.wmmat[3] = clamp(model->motion_params.wmmat[3],
GM_ALPHA_MIN, GM_ALPHA_MAX);
for (i = 2; i < n_params; ++i) {
model->motion_params.wmmat[i] =
(int) floor(H[i] *
(1 << GM_ALPHA_PREC_BITS) + 0.5) -
(!(i & 1) * (1 << GM_ALPHA_PREC_BITS));
model->motion_params.wmmat[i] = clamp(model->motion_params.wmmat[i],
GM_ALPHA_MIN, GM_ALPHA_MAX);
alpha_present |= (model->motion_params.wmmat[i] != 0);
}
if (model->motion_params.wmmat[2] == 0 &&
model->motion_params.wmmat[3] == 0) {
if (!alpha_present) {
if (abs(model->motion_params.wmmat[0]) < MIN_TRANS_THRESH &&
abs(model->motion_params.wmmat[1]) < MIN_TRANS_THRESH) {
model->motion_params.wmmat[0] = 0;
......@@ -4594,16 +4575,9 @@ static void convert_rotzoom_to_params(double *H, Global_Motion_Params *model) {
static void convert_model_to_params(double *H, TransformationType type,
Global_Motion_Params *model) {
switch (type) {
case ROTZOOM:
convert_rotzoom_to_params(H, model);
break;
case TRANSLATION:
convert_translation_to_params(H, model);
break;
default:
break;
}
// TODO(sarahparker) implement for homography
if (type > HOMOGRAPHY)
convert_to_params(H, type, model);
model->gmtype = get_gmtype(model);
}
#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