Better block center in gm_get_motion_vector fn

Also supports homography models for future experiments.

Change-Id: I4510540f54133e063891ed491c95c087222f7810
diff --git a/av1/common/mv.h b/av1/common/mv.h
index 2b50c61..b43c3ab 100644
--- a/av1/common/mv.h
+++ b/av1/common/mv.h
@@ -135,7 +135,7 @@
 #define GM_ALPHA_MIN -GM_ALPHA_MAX
 #define GM_ROW3HOMO_MIN -GM_ROW3HOMO_MAX
 
-// Bits used for different models
+// Maximum number of bits used for different models
 #define GM_IDENTITY_BITS 0
 #define GM_TRANSLATION_BITS ((GM_ABS_TRANS_BITS + 1) * 2)
 #define GM_ROTZOOM_BITS (GM_TRANSLATION_BITS + (GM_ABS_ALPHA_BITS + 1) * 2)
@@ -152,8 +152,6 @@
                                           int allow_hp, int x, int y) {
   int_mv res;
   const int32_t *mat = gm->wmmat;
-  // Project the center point of the frame and use that to derive the
-  // motion vector. Assume the model is an AFFINE or ROTZOOM model
   int xc, yc;
   int shift = allow_hp ? WARPEDMODEL_PREC_BITS - 3 : WARPEDMODEL_PREC_BITS - 2;
   int scale = allow_hp ? 0 : 1;
@@ -165,6 +163,15 @@
   xc = mat[2] * x + mat[3] * y + mat[0];
   yc = mat[4] * x + mat[5] * y + mat[1];
 
+  if (gm->wmtype > AFFINE) {
+    const int Z =
+        mat[6] * x + mat[7] * y + (1 << WARPEDMODEL_ROW3HOMO_PREC_BITS);
+    xc <<= (WARPEDMODEL_ROW3HOMO_PREC_BITS - WARPEDMODEL_PREC_BITS);
+    yc <<= (WARPEDMODEL_ROW3HOMO_PREC_BITS - WARPEDMODEL_PREC_BITS);
+    xc = xc > 0 ? (xc + Z / 2) / Z : (xc - Z / 2) / Z;
+    yc = yc > 0 ? (yc + Z / 2) / Z : (yc - Z / 2) / Z;
+  }
+
   int tx = (ROUND_POWER_OF_TWO_SIGNED(xc, shift) << scale) - (x << 3);
   int ty = (ROUND_POWER_OF_TWO_SIGNED(yc, shift) << scale) - (y << 3);
 
diff --git a/av1/common/mvref_common.c b/av1/common/mvref_common.c
index ed86122..1c33b64 100644
--- a/av1/common/mvref_common.c
+++ b/av1/common/mvref_common.c
@@ -925,6 +925,7 @@
   int idx, all_zero = 1;
 #if CONFIG_GLOBAL_MOTION
   MV_REFERENCE_FRAME rf[2];
+  BLOCK_SIZE bsize = mi->mbmi.sb_type;
 #endif
 #endif
 #if CONFIG_EXT_INTER
@@ -941,21 +942,21 @@
   av1_set_ref_frame(rf, ref_frame);
   zeromv[0].as_int = gm_get_motion_vector(&cm->global_motion[rf[0]],
                                           cm->allow_high_precision_mv,
-                                          mi_col * MI_SIZE + MI_SIZE / 2,
-                                          mi_row * MI_SIZE + MI_SIZE / 2)
+                                          block_center_x(mi_col, bsize),
+                                          block_center_y(mi_row, bsize))
                          .as_int;
   zeromv[1].as_int = (rf[1] != NONE_FRAME)
                          ? gm_get_motion_vector(&cm->global_motion[rf[1]],
                                                 cm->allow_high_precision_mv,
-                                                mi_col * MI_SIZE + MI_SIZE / 2,
-                                                mi_row * MI_SIZE + MI_SIZE / 2)
+                                                block_center_x(mi_col, bsize),
+                                                block_center_y(mi_row, bsize))
                                .as_int
                          : 0;
 #else
   zeromv[0].as_int = gm_get_motion_vector(&cm->global_motion[ref_frame],
                                           cm->allow_high_precision_mv,
-                                          mi_col * MI_SIZE + MI_SIZE / 2,
-                                          mi_row * MI_SIZE + MI_SIZE / 2)
+                                          block_center_x(mi_col, bsize),
+                                          block_center_y(mi_row, bsize))
                          .as_int;
   zeromv[1].as_int = 0;
 #endif  // CONFIG_REF_MV
@@ -1043,8 +1044,8 @@
 #if CONFIG_GLOBAL_MOTION
   zeromv.as_int =
       gm_get_motion_vector(&cm->global_motion[ref], cm->allow_high_precision_mv,
-                           mi_col * MI_SIZE + MI_SIZE / 2,
-                           mi_row * MI_SIZE + MI_SIZE / 2)
+                           block_center_x(mi_col, mi->mbmi.sb_type),
+                           block_center_y(mi_row, mi->mbmi.sb_type))
           .as_int;
 #else
   zeromv.as_int = 0;
diff --git a/av1/common/mvref_common.h b/av1/common/mvref_common.h
index f5a3919..9b3a246 100644
--- a/av1/common/mvref_common.h
+++ b/av1/common/mvref_common.h
@@ -255,6 +255,18 @@
 };
 #endif
 
+#if CONFIG_GLOBAL_MOTION
+static INLINE int block_center_x(int mi_col, BLOCK_SIZE bs) {
+  const int bw = block_size_wide[bs];
+  return mi_col * MI_SIZE + AOMMAX(bw, MI_SIZE) / 2;
+}
+
+static INLINE int block_center_y(int mi_row, BLOCK_SIZE bs) {
+  const int bh = block_size_high[bs];
+  return mi_row * MI_SIZE + AOMMAX(bh, MI_SIZE) / 2;
+}
+#endif  // CONFIG_GLOBAL_MOTION
+
 static const int idx_n_column_to_subblock[4][2] = {
   { 1, 2 }, { 1, 3 }, { 3, 2 }, { 3, 3 }
 };
diff --git a/av1/decoder/decodemv.c b/av1/decoder/decodemv.c
index daef18b..06534e2 100644
--- a/av1/decoder/decodemv.c
+++ b/av1/decoder/decodemv.c
@@ -1281,13 +1281,13 @@
 #else
   FRAME_CONTEXT *ec_ctx = cm->fc;
 #endif
+  BLOCK_SIZE bsize = xd->mi[0]->mbmi.sb_type;
 #if CONFIG_REF_MV
   MB_MODE_INFO *mbmi = &xd->mi[0]->mbmi;
 #if CONFIG_CB4X4
   int_mv *pred_mv = mbmi->pred_mv;
   (void)block;
 #else
-  BLOCK_SIZE bsize = mbmi->sb_type;
   int_mv *pred_mv =
       (bsize >= BLOCK_8X8) ? mbmi->pred_mv : xd->mi[0]->bmi[block].pred_mv;
 #endif  // CONFIG_CB4X4
@@ -1298,6 +1298,7 @@
   (void)cm;
   (void)mi_row;
   (void)mi_col;
+  (void)bsize;
 
   switch (mode) {
 #if CONFIG_EXT_INTER
@@ -1354,14 +1355,14 @@
 #if CONFIG_GLOBAL_MOTION
       mv[0].as_int = gm_get_motion_vector(&cm->global_motion[ref_frame[0]],
                                           cm->allow_high_precision_mv,
-                                          mi_col * MI_SIZE + MI_SIZE / 2,
-                                          mi_row * MI_SIZE + MI_SIZE / 2)
+                                          block_center_x(mi_col, bsize),
+                                          block_center_y(mi_row, bsize))
                          .as_int;
       if (is_compound)
         mv[1].as_int = gm_get_motion_vector(&cm->global_motion[ref_frame[1]],
                                             cm->allow_high_precision_mv,
-                                            mi_col * MI_SIZE + MI_SIZE / 2,
-                                            mi_row * MI_SIZE + MI_SIZE / 2)
+                                            block_center_x(mi_col, bsize),
+                                            block_center_y(mi_row, bsize))
                            .as_int;
 #else
       mv[0].as_int = 0;
@@ -1511,13 +1512,13 @@
 #if CONFIG_GLOBAL_MOTION
       mv[0].as_int = gm_get_motion_vector(&cm->global_motion[ref_frame[0]],
                                           cm->allow_high_precision_mv,
-                                          mi_col * MI_SIZE + MI_SIZE / 2,
-                                          mi_row * MI_SIZE + MI_SIZE / 2)
+                                          block_center_x(mi_col, bsize),
+                                          block_center_y(mi_row, bsize))
                          .as_int;
       mv[1].as_int = gm_get_motion_vector(&cm->global_motion[ref_frame[1]],
                                           cm->allow_high_precision_mv,
-                                          mi_col * MI_SIZE + MI_SIZE / 2,
-                                          mi_row * MI_SIZE + MI_SIZE / 2)
+                                          block_center_x(mi_col, bsize),
+                                          block_center_y(mi_row, bsize))
                          .as_int;
 #else
       mv[0].as_int = 0;
@@ -1625,15 +1626,15 @@
 #if CONFIG_GLOBAL_MOTION
       zeromv[0].as_int = gm_get_motion_vector(&cm->global_motion[rf[0]],
                                               cm->allow_high_precision_mv,
-                                              mi_col * MI_SIZE + MI_SIZE / 2,
-                                              mi_row * MI_SIZE + MI_SIZE / 2)
+                                              block_center_x(mi_col, bsize),
+                                              block_center_y(mi_row, bsize))
                              .as_int;
       zeromv[1].as_int =
           (rf[1] != NONE_FRAME)
               ? gm_get_motion_vector(&cm->global_motion[rf[1]],
                                      cm->allow_high_precision_mv,
-                                     mi_col * MI_SIZE + MI_SIZE / 2,
-                                     mi_row * MI_SIZE + MI_SIZE / 2)
+                                     block_center_x(mi_col, bsize),
+                                     block_center_y(mi_row, bsize))
                     .as_int
               : 0;
 #else
diff --git a/av1/encoder/rdopt.c b/av1/encoder/rdopt.c
index d9e1b27..7b84fd2 100644
--- a/av1/encoder/rdopt.c
+++ b/av1/encoder/rdopt.c
@@ -5046,7 +5046,8 @@
             gm_get_motion_vector(
                 &cpi->common.global_motion[mbmi->ref_frame[ref]],
                 cpi->common.allow_high_precision_mv,
-                mi_col * MI_SIZE + MI_SIZE / 2, mi_row * MI_SIZE + MI_SIZE / 2)
+                block_center_x(mi_col, mbmi->sb_type),
+                block_center_y(mi_row, mbmi->sb_type))
                 .as_int;
         thismvcost += GLOBAL_MOTION_RATE(cpi, mbmi->ref_frame[ref]);
 #else
@@ -5104,14 +5105,14 @@
       this_mv[0].as_int =
           gm_get_motion_vector(&cpi->common.global_motion[mbmi->ref_frame[0]],
                                cpi->common.allow_high_precision_mv,
-                               mi_col * MI_SIZE + MI_SIZE / 2,
-                               mi_row * MI_SIZE + MI_SIZE / 2)
+                               block_center_x(mi_col, mbmi->sb_type),
+                               block_center_y(mi_row, mbmi->sb_type))
               .as_int;
       this_mv[1].as_int =
           gm_get_motion_vector(&cpi->common.global_motion[mbmi->ref_frame[1]],
                                cpi->common.allow_high_precision_mv,
-                               mi_col * MI_SIZE + MI_SIZE / 2,
-                               mi_row * MI_SIZE + MI_SIZE / 2)
+                               block_center_x(mi_col, mbmi->sb_type),
+                               block_center_y(mi_row, mbmi->sb_type))
               .as_int;
       thismvcost += GLOBAL_MOTION_RATE(cpi, mbmi->ref_frame[0]) +
                     GLOBAL_MOTION_RATE(cpi, mbmi->ref_frame[1]);
@@ -5382,8 +5383,8 @@
       zeromv[cur_frm].as_int =
           gm_get_motion_vector(&cpi->common.global_motion[ref_frames[cur_frm]],
                                cpi->common.allow_high_precision_mv,
-                               mi_col * MI_SIZE + MI_SIZE / 2,
-                               mi_row * MI_SIZE + MI_SIZE / 2)
+                               block_center_x(mi_col, bsize),
+                               block_center_y(mi_row, bsize))
               .as_int;
     else
 #endif  // CONFIG_GLOBAL_MOTION
@@ -5843,9 +5844,10 @@
 #endif  // CONFIG_EXT_INTER
 #if CONFIG_GLOBAL_MOTION
         frame_mv[ZEROMV][frame].as_int =
-            gm_get_motion_vector(
-                &cm->global_motion[frame], cm->allow_high_precision_mv,
-                mi_col * MI_SIZE + MI_SIZE / 2, mi_row * MI_SIZE + MI_SIZE / 2)
+            gm_get_motion_vector(&cm->global_motion[frame],
+                                 cm->allow_high_precision_mv,
+                                 block_center_x(mi_col, mbmi->sb_type),
+                                 block_center_y(mi_row, mbmi->sb_type))
                 .as_int;
 #else   // CONFIG_GLOBAL_MOTION
         frame_mv[ZEROMV][frame].as_int = 0;
@@ -5878,8 +5880,8 @@
           frame_mv[ZERO_ZEROMV][frame].as_int =
               gm_get_motion_vector(&cm->global_motion[frame],
                                    cm->allow_high_precision_mv,
-                                   mi_col * MI_SIZE + MI_SIZE / 2,
-                                   mi_row * MI_SIZE + MI_SIZE / 2)
+                                   block_center_x(mi_col, mbmi->sb_type),
+                                   block_center_y(mi_row, mbmi->sb_type))
                   .as_int;
 #else
           frame_mv[ZERO_ZEROMV][frame].as_int = 0;
@@ -9568,7 +9570,7 @@
     frame_mv[ZEROMV][ref_frame].as_int =
         gm_get_motion_vector(
             &cm->global_motion[ref_frame], cm->allow_high_precision_mv,
-            mi_col * MI_SIZE + MI_SIZE / 2, mi_row * MI_SIZE + MI_SIZE / 2)
+            block_center_x(mi_col, bsize), block_center_y(mi_row, bsize))
             .as_int;
 #else   // CONFIG_GLOBAL_MOTION
     frame_mv[ZEROMV][ref_frame].as_int = 0;
@@ -9580,7 +9582,7 @@
     frame_mv[ZERO_ZEROMV][ref_frame].as_int =
         gm_get_motion_vector(
             &cm->global_motion[ref_frame], cm->allow_high_precision_mv,
-            mi_col * MI_SIZE + MI_SIZE / 2, mi_row * MI_SIZE + MI_SIZE / 2)
+            block_center_x(mi_col, bsize), block_center_y(mi_row, bsize))
             .as_int;
 #else   // CONFIG_GLOBAL_MOTION
     frame_mv[ZERO_ZEROMV][ref_frame].as_int = 0;
@@ -9684,8 +9686,8 @@
 #if CONFIG_GLOBAL_MOTION
       zeromv.as_int = gm_get_motion_vector(&cm->global_motion[ALTREF_FRAME],
                                            cm->allow_high_precision_mv,
-                                           mi_col * MI_SIZE + MI_SIZE / 2,
-                                           mi_row * MI_SIZE + MI_SIZE / 2)
+                                           block_center_x(mi_col, bsize),
+                                           block_center_y(mi_row, bsize))
                           .as_int;
 #else
       zeromv.as_int = 0;
@@ -10853,17 +10855,16 @@
 #if CONFIG_GLOBAL_MOTION
     zeromv[0].as_int = gm_get_motion_vector(&cm->global_motion[refs[0]],
                                             cm->allow_high_precision_mv,
-                                            mi_col * MI_SIZE + MI_SIZE / 2,
-                                            mi_row * MI_SIZE + MI_SIZE / 2)
+                                            block_center_x(mi_col, bsize),
+                                            block_center_y(mi_row, bsize))
                            .as_int;
-    zeromv[1].as_int =
-        comp_pred_mode
-            ? gm_get_motion_vector(&cm->global_motion[refs[1]],
-                                   cm->allow_high_precision_mv,
-                                   mi_col * MI_SIZE + MI_SIZE / 2,
-                                   mi_row * MI_SIZE + MI_SIZE / 2)
-                  .as_int
-            : 0;
+    zeromv[1].as_int = comp_pred_mode
+                           ? gm_get_motion_vector(&cm->global_motion[refs[1]],
+                                                  cm->allow_high_precision_mv,
+                                                  block_center_x(mi_col, bsize),
+                                                  block_center_y(mi_row, bsize))
+                                 .as_int
+                           : 0;
 #else
     zeromv[0].as_int = 0;
     zeromv[1].as_int = 0;
@@ -10973,15 +10974,15 @@
 #if CONFIG_GLOBAL_MOTION
       zeromv[0].as_int = gm_get_motion_vector(&cm->global_motion[refs[0]],
                                               cm->allow_high_precision_mv,
-                                              mi_col * MI_SIZE + MI_SIZE / 2,
-                                              mi_row * MI_SIZE + MI_SIZE / 2)
+                                              block_center_x(mi_col, bsize),
+                                              block_center_y(mi_row, bsize))
                              .as_int;
       zeromv[1].as_int =
           comp_pred_mode
               ? gm_get_motion_vector(&cm->global_motion[refs[1]],
                                      cm->allow_high_precision_mv,
-                                     mi_col * MI_SIZE + MI_SIZE / 2,
-                                     mi_row * MI_SIZE + MI_SIZE / 2)
+                                     block_center_x(mi_col, bsize),
+                                     block_center_y(mi_row, bsize))
                     .as_int
               : 0;
 #else
@@ -11027,13 +11028,13 @@
                                            best_mbmode.ref_frame[1] };
       zeromv[0].as_int = gm_get_motion_vector(&cm->global_motion[refs[0]],
                                               cm->allow_high_precision_mv,
-                                              mi_col * MI_SIZE + MI_SIZE / 2,
-                                              mi_row * MI_SIZE + MI_SIZE / 2)
+                                              block_center_x(mi_col, bsize),
+                                              block_center_y(mi_row, bsize))
                              .as_int;
       zeromv[1].as_int = gm_get_motion_vector(&cm->global_motion[refs[1]],
                                               cm->allow_high_precision_mv,
-                                              mi_col * MI_SIZE + MI_SIZE / 2,
-                                              mi_row * MI_SIZE + MI_SIZE / 2)
+                                              block_center_x(mi_col, bsize),
+                                              block_center_y(mi_row, bsize))
                              .as_int;
       lower_mv_precision(&zeromv[0].as_mv, cm->allow_high_precision_mv);
       lower_mv_precision(&zeromv[1].as_mv, cm->allow_high_precision_mv);
@@ -11196,7 +11197,7 @@
   mbmi->mv[0].as_int =
       gm_get_motion_vector(
           &cm->global_motion[mbmi->ref_frame[0]], cm->allow_high_precision_mv,
-          mi_col * MI_SIZE + MI_SIZE / 2, mi_row * MI_SIZE + MI_SIZE / 2)
+          block_center_x(mi_col, bsize), block_center_y(mi_row, bsize))
           .as_int;
 #else   // CONFIG_GLOBAL_MOTION
   mbmi->mv[0].as_int = 0;