Support affine/homography models for global motion

With this patch affine or homography models can be enabled
by simply changing the value of the GLOBAL_TRANS_TYPES
macro in common/mv.h to 4 and 5 respectively. Currently
it is left at supporting only rotzoom. There is a small
gain with enabling affine.

Also refactors costing to change based on the model type.

Change-Id: I46c1759de06c42c176c64ec21307ff347ddcc259
diff --git a/av1/common/mv.h b/av1/common/mv.h
index a591329..cd4b4e6 100644
--- a/av1/common/mv.h
+++ b/av1/common/mv.h
@@ -55,14 +55,14 @@
 typedef enum {
   IDENTITY = 0,     // identity transformation, 0-parameter
   TRANSLATION = 1,  // translational motion 2-parameter
-  ROTZOOM = 2,      // simplified affine with rotation and zoom only, 4-parameter
+  ROTZOOM = 2,      // simplified affine with rotation + zoom only, 4-parameter
   AFFINE = 3,       // affine, 6-parameter
   HOMOGRAPHY = 4,   // homography, 8-parameter
   TRANS_TYPES = 5,
 } TransformationType;
 /* clang-format on */
 
-// Number of types used for global motion (must be <= TRANS_TYPES)
+// Number of types used for global motion (must be >= 3 and <= TRANS_TYPES)
 #define GLOBAL_TRANS_TYPES 3
 
 // number of parameters used by each transformation in TransformationTypes
diff --git a/av1/encoder/encodeframe.c b/av1/encoder/encodeframe.c
index e4873ab..47ca2fc 100644
--- a/av1/encoder/encodeframe.c
+++ b/av1/encoder/encodeframe.c
@@ -4896,28 +4896,32 @@
     for (frame = LAST_FRAME; frame <= ALTREF_FRAME; ++frame) {
       ref_buf = get_ref_frame_buffer(cpi, frame);
       if (ref_buf) {
+        TransformationType model;
         aom_clear_system_state();
-        if (compute_global_motion_feature_based(GLOBAL_TRANS_TYPES - 1,
-                                                cpi->Source, ref_buf,
+        for (model = ROTZOOM; model < GLOBAL_TRANS_TYPES; ++model) {
+          if (compute_global_motion_feature_based(model, cpi->Source, ref_buf,
 #if CONFIG_AOM_HIGHBITDEPTH
-                                                cpi->common.bit_depth,
+                                                  cpi->common.bit_depth,
 #endif  // CONFIG_AOM_HIGHBITDEPTH
-                                                params)) {
-          convert_model_to_params(params, &cm->global_motion[frame]);
-          if (cm->global_motion[frame].wmtype != IDENTITY) {
-            erroradvantage = refine_integerized_param(
-                &cm->global_motion[frame], cm->global_motion[frame].wmtype,
+                                                  params)) {
+            convert_model_to_params(params, &cm->global_motion[frame]);
+            if (cm->global_motion[frame].wmtype != IDENTITY) {
+              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,
+                  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);
-            if (erroradvantage >
-                gm_advantage_thresh[cm->global_motion[frame].wmtype]) {
-              set_default_gmparams(&cm->global_motion[frame]);
+                  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);
+              if (erroradvantage >
+                  gm_advantage_thresh[cm->global_motion[frame].wmtype]) {
+                set_default_gmparams(&cm->global_motion[frame]);
+              }
             }
           }
+          if (cm->global_motion[frame].wmtype != IDENTITY) break;
         }
         aom_clear_system_state();
       }
diff --git a/av1/encoder/encoder.c b/av1/encoder/encoder.c
index b21727b..1123cf5 100644
--- a/av1/encoder/encoder.c
+++ b/av1/encoder/encoder.c
@@ -2884,14 +2884,14 @@
 }
 
 #if CONFIG_GLOBAL_MOTION
-#define MIN_GLOBAL_MOTION_BLKS 4
 static int recode_loop_test_global_motion(AV1_COMP *cpi) {
+  static const int min_blocks[TRANS_TYPES] = { 0, 2, 4, 6, 8 };
   int i;
   int recode = 0;
   AV1_COMMON *const cm = &cpi->common;
   for (i = LAST_FRAME; i <= ALTREF_FRAME; ++i) {
     if (cm->global_motion[i].wmtype != IDENTITY &&
-        cpi->global_motion_used[i] < MIN_GLOBAL_MOTION_BLKS) {
+        cpi->global_motion_used[i] < min_blocks[cm->global_motion[i].wmtype]) {
       set_default_gmparams(&cm->global_motion[i]);
 #if CONFIG_REF_MV
       recode = 1;
diff --git a/av1/encoder/ransac.c b/av1/encoder/ransac.c
index 9c19903..8bacfe5 100644
--- a/av1/encoder/ransac.c
+++ b/av1/encoder/ransac.c
@@ -151,7 +151,6 @@
 
   *number_of_inliers = 0;
   if (npoints < minpts * MINPTS_MULTIPLIER || npoints == 0) {
-    printf("Cannot find motion with %d matches\n", npoints);
     return 1;
   }
 
diff --git a/av1/encoder/rdopt.c b/av1/encoder/rdopt.c
index b7faf03..3b62c1c 100644
--- a/av1/encoder/rdopt.c
+++ b/av1/encoder/rdopt.c
@@ -4333,29 +4333,22 @@
 #endif  // CONFIG_EXT_INTER
 
 #if CONFIG_GLOBAL_MOTION
-#define GLOBAL_MOTION_COST_AMORTIZATION_BLKS 8
-
-#if GLOBAL_MOTION_COST_AMORTIZATION_BLKS > 0
-static int get_gmbitcost(const AV1_COMP *const cpi,
-                         const WarpedMotionParams *gm) {
+static int GLOBAL_MOTION_RATE(const AV1_COMP *const cpi, int ref) {
+  static const int gm_amortization_blks[TRANS_TYPES] = { 4, 6, 8, 10, 12 };
   static const int gm_params_cost[TRANS_TYPES] = {
     GM_IDENTITY_BITS, GM_TRANSLATION_BITS, GM_ROTZOOM_BITS,
     GM_AFFINE_BITS,   GM_HOMOGRAPHY_BITS,
   };
-  const int cost = (gm_params_cost[gm->wmtype] << AV1_PROB_COST_SHIFT) +
-                   cpi->gmtype_cost[gm->wmtype];
+  const WarpedMotionParams *gm = &cpi->common.global_motion[(ref)];
   assert(gm->wmtype < GLOBAL_TRANS_TYPES);
-  return cost;
+  if (cpi->global_motion_used[ref] >= gm_amortization_blks[gm->wmtype]) {
+    return 0;
+  } else {
+    const int cost = (gm_params_cost[gm->wmtype] << AV1_PROB_COST_SHIFT) +
+                     cpi->gmtype_cost[gm->wmtype];
+    return cost / gm_amortization_blks[gm->wmtype];
+  }
 }
-
-#define GLOBAL_MOTION_RATE(ref)                                         \
-  (cpi->global_motion_used[ref] >= GLOBAL_MOTION_COST_AMORTIZATION_BLKS \
-       ? 0                                                              \
-       : get_gmbitcost(cpi, &cm->global_motion[(ref)]) /                \
-             GLOBAL_MOTION_COST_AMORTIZATION_BLKS)
-#else
-#define GLOBAL_MOTION_RATE(ref) 0
-#endif  // GLOBAL_MOTION_COST_AMORTIZATION_BLKS > 0
 #endif  // CONFIG_GLOBAL_MOTION
 
 static int set_and_cost_bmi_mvs(const AV1_COMP *const cpi, MACROBLOCK *x,
@@ -4369,9 +4362,6 @@
 #endif  // CONFIG_EXT_INTER
                                 int_mv *best_ref_mv[2], const int *mvjcost,
                                 int *mvcost[2]) {
-#if CONFIG_GLOBAL_MOTION
-  const AV1_COMMON *cm = &cpi->common;
-#endif  // CONFIG_GLOBAL_MOTION
   MODE_INFO *const mic = xd->mi[0];
   const MB_MODE_INFO *const mbmi = &mic->mbmi;
   const MB_MODE_INFO_EXT *const mbmi_ext = x->mbmi_ext;
@@ -4427,13 +4417,13 @@
           gm_get_motion_vector(&cpi->common.global_motion[mbmi->ref_frame[0]],
                                cpi->common.allow_high_precision_mv)
               .as_int;
-      thismvcost += GLOBAL_MOTION_RATE(mbmi->ref_frame[0]);
+      thismvcost += GLOBAL_MOTION_RATE(cpi, mbmi->ref_frame[0]);
       if (is_compound) {
         this_mv[1].as_int =
             gm_get_motion_vector(&cpi->common.global_motion[mbmi->ref_frame[1]],
                                  cpi->common.allow_high_precision_mv)
                 .as_int;
-        thismvcost += GLOBAL_MOTION_RATE(mbmi->ref_frame[1]);
+        thismvcost += GLOBAL_MOTION_RATE(cpi, mbmi->ref_frame[1]);
       }
 #else   // CONFIG_GLOBAL_MOTION
       this_mv[0].as_int = 0;
@@ -8059,9 +8049,9 @@
 #endif  // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
 #if CONFIG_GLOBAL_MOTION
     if (this_mode == ZEROMV) {
-      rd_stats->rate += GLOBAL_MOTION_RATE(mbmi->ref_frame[0]);
+      rd_stats->rate += GLOBAL_MOTION_RATE(cpi, mbmi->ref_frame[0]);
       if (is_comp_pred)
-        rd_stats->rate += GLOBAL_MOTION_RATE(mbmi->ref_frame[1]);
+        rd_stats->rate += GLOBAL_MOTION_RATE(cpi, mbmi->ref_frame[1]);
     }
 #endif  // CONFIG_GLOBAL_MOTION