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) {
// | 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.
//
GLOBAL_ZERO = 0,
GLOBAL_TRANSLATION = 1,
GLOBAL_ROTZOOM = 2,
+ GLOBAL_AFFINE = 3,
GLOBAL_MOTION_TYPES
} GLOBAL_MOTION_TYPE;
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
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
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);
write_tile_info(cm, wb);
}
+
#if CONFIG_GLOBAL_MOTION
static void write_global_motion_params(Global_Motion_Params *params,
vpx_prob *probs,
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);
#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] *
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;
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