Support for homography in global motion experiment

Change-Id: If4a480633032d8738a84fa8173c6ebd90564f0a4
diff --git a/av1/common/entropymv.c b/av1/common/entropymv.c
index a727169..2443d71 100644
--- a/av1/common/entropymv.c
+++ b/av1/common/entropymv.c
@@ -128,7 +128,15 @@
 };
 
 #if CONFIG_GLOBAL_MOTION
-#if GLOBAL_TRANS_TYPES == 4
+#if GLOBAL_TRANS_TYPES == 5
+const aom_tree_index av1_global_motion_types_tree[TREE_SIZE(
+    GLOBAL_TRANS_TYPES)] = { -IDENTITY, 2, -TRANSLATION, 4, -ROTZOOM, 6,
+    -AFFINE, -HOMOGRAPHY };
+
+static const aom_prob default_global_motion_types_prob[GLOBAL_TRANS_TYPES - 1] =
+    { 224, 128, 192, 192 };
+
+#elif GLOBAL_TRANS_TYPES == 4
 const aom_tree_index av1_global_motion_types_tree[TREE_SIZE(
     GLOBAL_TRANS_TYPES)] = { -IDENTITY, 2, -TRANSLATION, 4, -ROTZOOM, -AFFINE };
 
diff --git a/av1/decoder/decodeframe.c b/av1/decoder/decodeframe.c
index 4870899..b4a56f5 100644
--- a/av1/decoder/decodeframe.c
+++ b/av1/decoder/decodeframe.c
@@ -4027,17 +4027,21 @@
   set_default_gmparams(params);
   params->wmtype = type;
   switch (type) {
-    case IDENTITY: break;
+    case HOMOGRAPHY:
+      params->wmmat[6] = aom_read_primitive_symmetric(r, GM_ABS_ROW3HOMO_BITS) *
+          GM_ROW3HOMO_DECODE_FACTOR;
+      params->wmmat[7] = aom_read_primitive_symmetric(r, GM_ABS_ROW3HOMO_BITS) *
+          GM_ROW3HOMO_DECODE_FACTOR;
     case AFFINE:
     case ROTZOOM:
-      params->wmmat[2] = (aom_read_primitive_symmetric(r, GM_ABS_ALPHA_BITS) *
-                          GM_ALPHA_DECODE_FACTOR) +
+      params->wmmat[2] = aom_read_primitive_symmetric(r, GM_ABS_ALPHA_BITS) *
+                          GM_ALPHA_DECODE_FACTOR +
                          (1 << WARPEDMODEL_PREC_BITS);
       params->wmmat[3] = aom_read_primitive_symmetric(r, GM_ABS_ALPHA_BITS) *
                          GM_ALPHA_DECODE_FACTOR;
-      if (type == AFFINE) {
-        params->wmmat[4] = (aom_read_primitive_symmetric(r, GM_ABS_ALPHA_BITS) *
-                            GM_ALPHA_DECODE_FACTOR);
+      if (type == AFFINE || type == HOMOGRAPHY) {
+        params->wmmat[4] = aom_read_primitive_symmetric(r, GM_ABS_ALPHA_BITS) *
+                            GM_ALPHA_DECODE_FACTOR;
         params->wmmat[5] = aom_read_primitive_symmetric(r, GM_ABS_ALPHA_BITS) *
                                GM_ALPHA_DECODE_FACTOR +
                            (1 << WARPEDMODEL_PREC_BITS);
@@ -4052,6 +4056,7 @@
       params->wmmat[1] = aom_read_primitive_symmetric(r, GM_ABS_TRANS_BITS) *
                          GM_TRANS_DECODE_FACTOR;
       break;
+    case IDENTITY: break;
     default: assert(0);
   }
 }
diff --git a/av1/encoder/bitstream.c b/av1/encoder/bitstream.c
index 4192801..a36f0c9 100644
--- a/av1/encoder/bitstream.c
+++ b/av1/encoder/bitstream.c
@@ -3970,7 +3970,14 @@
   av1_write_token(w, av1_global_motion_types_tree, probs,
                   &global_motion_types_encodings[type]);
   switch (type) {
-    case IDENTITY: break;
+    case HOMOGRAPHY:
+        aom_write_primitive_symmetric(
+            w, (params->wmmat[6] >> GM_ROW3HOMO_PREC_DIFF),
+            GM_ABS_ROW3HOMO_BITS);
+        aom_write_primitive_symmetric(
+            w, (params->wmmat[7] >> GM_ROW3HOMO_PREC_DIFF),
+            GM_ABS_ROW3HOMO_BITS);
+    // fallthrough intended
     case AFFINE:
     case ROTZOOM:
       aom_write_primitive_symmetric(
@@ -3979,7 +3986,7 @@
           GM_ABS_ALPHA_BITS);
       aom_write_primitive_symmetric(w, (params->wmmat[3] >> GM_ALPHA_PREC_DIFF),
                                     GM_ABS_ALPHA_BITS);
-      if (type == AFFINE) {
+      if (type == AFFINE || type == HOMOGRAPHY) {
         aom_write_primitive_symmetric(
             w, (params->wmmat[4] >> GM_ALPHA_PREC_DIFF), GM_ABS_ALPHA_BITS);
         aom_write_primitive_symmetric(w,
@@ -3994,6 +4001,7 @@
       aom_write_primitive_symmetric(w, (params->wmmat[1] >> GM_TRANS_PREC_DIFF),
                                     GM_ABS_TRANS_BITS);
       break;
+    case IDENTITY: break;
     default: assert(0);
   }
 }
diff --git a/av1/encoder/encodeframe.c b/av1/encoder/encodeframe.c
index 8922417..bbd84d5 100644
--- a/av1/encoder/encodeframe.c
+++ b/av1/encoder/encodeframe.c
@@ -4614,7 +4614,6 @@
 #if CONFIG_GLOBAL_MOTION
 #define MIN_TRANS_THRESH (1 * GM_TRANS_DECODE_FACTOR)
 #define GLOBAL_MOTION_ADVANTAGE_THRESH 0.75
-#define GLOBAL_MOTION_MODEL ROTZOOM
 
 // Adds some offset to a global motion parameter and handles
 // all of the necessary precision shifts, clamping, and
@@ -4798,7 +4797,7 @@
     for (frame = LAST_FRAME; frame <= ALTREF_FRAME; ++frame) {
       ref_buf = get_ref_frame_buffer(cpi, frame);
       if (ref_buf) {
-        if (compute_global_motion_feature_based(GLOBAL_MOTION_MODEL,
+        if (compute_global_motion_feature_based(GLOBAL_TRANS_TYPES - 1,
                                                 cpi->Source, ref_buf, params)) {
           convert_model_to_params(params, &cm->global_motion[frame]);
           if (cm->global_motion[frame].wmtype != IDENTITY) {
diff --git a/av1/encoder/ransac.c b/av1/encoder/ransac.c
index 33b45ca..31614ea 100644
--- a/av1/encoder/ransac.c
+++ b/av1/encoder/ransac.c
@@ -240,7 +240,6 @@
       int temp;
       double fracinliers, pNoOutliers, mean_distance, variance;
 
-      assert(num_inliers > 1);
       mean_distance = sum_distance / ((double)num_inliers);
       variance = sum_distance_squared / ((double)num_inliers - 1.0) -
                  mean_distance * mean_distance * ((double)num_inliers) /
@@ -262,7 +261,6 @@
         pNoOutliers = 1 - pow(fracinliers, minpts);
         pNoOutliers = fmax(EPS, pNoOutliers);
         pNoOutliers = fmin(1 - EPS, pNoOutliers);
-        // assert(fabs(1.0 - pNoOutliers) > 0.00001);
         temp = (int)(log(1.0 - PROBABILITY_REQUIRED) / log(pNoOutliers));
         if (temp > 0 && temp < N) {
           N = AOMMAX(temp, MIN_TRIALS);
diff --git a/av1/encoder/rdopt.c b/av1/encoder/rdopt.c
index b2d78f9..3242f3d 100644
--- a/av1/encoder/rdopt.c
+++ b/av1/encoder/rdopt.c
@@ -4337,6 +4337,10 @@
   TransformationType type = gm->wmtype;
   av1_cost_tokens(gmtype_cost, probs, av1_global_motion_types_tree);
   switch (type) {
+    case HOMOGRAPHY:
+      bits = (GM_ABS_TRANS_BITS + 1) * 2 + (GM_ABS_ALPHA_BITS + 1) * 4 +
+             (GM_ABS_ROW3HOMO_BITS + 1) * 2;
+      break;
     case AFFINE:
       bits = (GM_ABS_TRANS_BITS + 1) * 2 + (GM_ABS_ALPHA_BITS + 1) * 4;
       break;