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