]> granicus.if.org Git - libvpx/commitdiff
Add affine model to global motion
authorSarah Parker <sarahparker@google.com>
Thu, 21 Jul 2016 00:11:39 +0000 (17:11 -0700)
committerSarah Parker <sarahparker@google.com>
Thu, 21 Jul 2016 21:50:18 +0000 (14:50 -0700)
Change-Id: I9cd355a3ea344ef66a61028efa25d94f54e7e2bd

vp10/common/entropymv.c
vp10/common/mv.h
vp10/common/warped_motion.h
vp10/decoder/decodeframe.c
vp10/encoder/bitstream.c
vp10/encoder/encodeframe.c

index ae6209d00b3fa6d52eebc4289e2e9cbb3d461b12..925cc1e1806f676ec650ed5c16841638b882541d 100644 (file)
@@ -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) {
index 255a7243cf2860cc5387a9f3c9f97aede8b3f643..f45f2ab49c5559ea29236169715bd63dd0bf09c0 100644 (file)
@@ -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
index 1d2568853bfe4d41617ef70f559e6eed0c602f4b..11d6124eb8ddaa5cb7bdf80486226a8814affea1 100644 (file)
@@ -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
index 06b3e07b0c18b3a14b4f57a3f59ac63ad922758b..76fe17dffec857b3b6cfef89b0fb77a434fb7777 100644 (file)
@@ -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);
index 6430a710456d509c23dbf9e7a1b9e28af1f0ea21..1adc47087252186b525d760195c5eda903013a33 100644 (file)
@@ -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);
index b91615bf3e03b05966f4409153f35364d535af01..6bebfe637d145884914f1533674b6f6cc8290e57 100644 (file)
@@ -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