Add global motion experiment to rdopt

This patch completes the global motion experiment
implementation. It modifies the format of the motion
parameters to use the mv union to facilitate faster
copying and checks for parameters equal to 0 that occur
frequently in rdopt. The rd decisions for the global motion experiment
have also been added to rdopt.
Change-Id: Idfb9f0c6d23e538221763881099c5a2a3891f5a9
diff --git a/av1/common/mv.h b/av1/common/mv.h
index 4908d74..fe08e9d 100644
--- a/av1/common/mv.h
+++ b/av1/common/mv.h
@@ -13,9 +13,6 @@
 
 #include "av1/common/common.h"
 #include "aom_dsp/aom_filter.h"
-#if CONFIG_GLOBAL_MOTION
-#include "av1/common/warped_motion.h"
-#endif  // CONFIG_GLOBAL_MOTION
 
 #ifdef __cplusplus
 extern "C" {
@@ -36,6 +33,41 @@
   int32_t col;
 } MV32;
 
+#if CONFIG_GLOBAL_MOTION || CONFIG_WARPED_MOTION
+// Bits of precision used for the model
+#define WARPEDMODEL_PREC_BITS 8
+#define WARPEDMODEL_ROW3HOMO_PREC_BITS 12
+
+// Bits of subpel precision for warped interpolation
+#define WARPEDPIXEL_PREC_BITS 6
+#define WARPEDPIXEL_PREC_SHIFTS (1 << WARPEDPIXEL_PREC_BITS)
+
+// Taps for ntap filter
+#define WARPEDPIXEL_FILTER_TAPS 6
+
+// Precision of filter taps
+#define WARPEDPIXEL_FILTER_BITS 7
+
+#define WARPEDDIFF_PREC_BITS (WARPEDMODEL_PREC_BITS - WARPEDPIXEL_PREC_BITS)
+
+typedef enum {
+  UNKNOWN_TRANSFORM = -1,
+  HOMOGRAPHY,   // homography, 8-parameter
+  AFFINE,       // affine, 6-parameter
+  ROTZOOM,      // simplified affine with rotation and zoom only, 4-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_mv wmmat[4];  // For homography wmmat[9] is assumed to be 1
+} WarpedMotionParams;
+#endif  // CONFIG_GLOBAL_MOTION || CONFIG_WARPED_MOTION
+
 #if CONFIG_GLOBAL_MOTION
 // ALPHA here refers to parameters a and b in rotzoom model:
 // | a   b|
@@ -61,16 +93,16 @@
 //
 // XX_MIN, XX_MAX are also computed to avoid repeated computation
 
-#define GM_TRANS_PREC_BITS 5
+#define GM_TRANS_PREC_BITS 8
 #define GM_TRANS_PREC_DIFF (WARPEDMODEL_PREC_BITS - GM_TRANS_PREC_BITS)
 #define GM_TRANS_DECODE_FACTOR (1 << GM_TRANS_PREC_DIFF)
 
-#define GM_ALPHA_PREC_BITS 5
+#define GM_ALPHA_PREC_BITS 8
 #define GM_ALPHA_PREC_DIFF (WARPEDMODEL_PREC_BITS - GM_ALPHA_PREC_BITS)
 #define GM_ALPHA_DECODE_FACTOR (1 << GM_ALPHA_PREC_DIFF)
 
-#define GM_ABS_ALPHA_BITS 8
-#define GM_ABS_TRANS_BITS 8
+#define GM_ABS_ALPHA_BITS 18
+#define GM_ABS_TRANS_BITS 18
 
 #define GM_TRANS_MAX (1 << GM_ABS_TRANS_BITS)
 #define GM_ALPHA_MAX (1 << GM_ABS_ALPHA_BITS)
@@ -102,11 +134,10 @@
 }
 
 static INLINE GLOBAL_MOTION_TYPE get_gmtype(const Global_Motion_Params *gm) {
-  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);
+  if (!gm->motion_params.wmmat[2].as_int) {
+    if (!gm->motion_params.wmmat[1].as_int) {
+      return (gm->motion_params.wmmat[0].as_int ? GLOBAL_TRANSLATION
+                                                : GLOBAL_ZERO);
     } else {
       return GLOBAL_ROTZOOM;
     }
diff --git a/av1/common/warped_motion.c b/av1/common/warped_motion.c
index c742c36..2ff1fce 100644
--- a/av1/common/warped_motion.c
+++ b/av1/common/warped_motion.c
@@ -26,7 +26,7 @@
   }
 }
 
-void projectPointsTranslation(int *mat, int *points, int *proj, const int n,
+void projectPointsTranslation(int16_t *mat, int *points, int *proj, const int n,
                               const int stride_points, const int stride_proj,
                               const int subsampling_x,
                               const int subsampling_y) {
@@ -35,24 +35,24 @@
     const int x = *(points++), y = *(points++);
     if (subsampling_x)
       *(proj++) = ROUND_POWER_OF_TWO_SIGNED(
-          ((x << (WARPEDMODEL_PREC_BITS + 1)) + mat[0]),
+          ((x << (WARPEDMODEL_PREC_BITS + 1)) + mat[1]),
           WARPEDDIFF_PREC_BITS + 1);
     else
       *(proj++) = ROUND_POWER_OF_TWO_SIGNED(
-          ((x << WARPEDMODEL_PREC_BITS)) + mat[0], WARPEDDIFF_PREC_BITS);
+          ((x << WARPEDMODEL_PREC_BITS) + mat[1]), WARPEDDIFF_PREC_BITS);
     if (subsampling_y)
       *(proj++) = ROUND_POWER_OF_TWO_SIGNED(
-          ((y << (WARPEDMODEL_PREC_BITS + 1)) + mat[1]),
+          ((y << (WARPEDMODEL_PREC_BITS + 1)) + mat[0]),
           WARPEDDIFF_PREC_BITS + 1);
     else
       *(proj++) = ROUND_POWER_OF_TWO_SIGNED(
-          ((y << WARPEDMODEL_PREC_BITS)) + mat[1], WARPEDDIFF_PREC_BITS);
+          ((y << WARPEDMODEL_PREC_BITS)) + mat[0], WARPEDDIFF_PREC_BITS);
     points += stride_points - 2;
     proj += stride_proj - 2;
   }
 }
 
-void projectPointsRotZoom(int *mat, int *points, int *proj, const int n,
+void projectPointsRotZoom(int16_t *mat, int *points, int *proj, const int n,
                           const int stride_points, const int stride_proj,
                           const int subsampling_x, const int subsampling_y) {
   int i;
@@ -60,26 +60,26 @@
     const int x = *(points++), y = *(points++);
     if (subsampling_x)
       *(proj++) = ROUND_POWER_OF_TWO_SIGNED(
-          mat[2] * 2 * x + mat[3] * 2 * y + mat[0] +
-              (mat[2] + mat[3] - (1 << WARPEDMODEL_PREC_BITS)) / 2,
+          mat[3] * 2 * x + mat[2] * 2 * y + mat[1] +
+              (mat[3] + mat[2] - (1 << WARPEDMODEL_PREC_BITS)) / 2,
           WARPEDDIFF_PREC_BITS + 1);
     else
-      *(proj++) = ROUND_POWER_OF_TWO_SIGNED(mat[2] * x + mat[3] * y + mat[0],
+      *(proj++) = ROUND_POWER_OF_TWO_SIGNED(mat[3] * x + mat[2] * y + mat[1],
                                             WARPEDDIFF_PREC_BITS);
     if (subsampling_y)
       *(proj++) = ROUND_POWER_OF_TWO_SIGNED(
-          -mat[3] * 2 * x + mat[2] * 2 * y + mat[1] +
-              (-mat[3] + mat[2] - (1 << WARPEDMODEL_PREC_BITS)) / 2,
+          -mat[2] * 2 * x + mat[3] * 2 * y + mat[0] +
+              (-mat[2] + mat[3] - (1 << WARPEDMODEL_PREC_BITS)) / 2,
           WARPEDDIFF_PREC_BITS + 1);
     else
-      *(proj++) = ROUND_POWER_OF_TWO_SIGNED(-mat[3] * x + mat[2] * y + mat[1],
+      *(proj++) = ROUND_POWER_OF_TWO_SIGNED(-mat[2] * x + mat[3] * y + mat[0],
                                             WARPEDDIFF_PREC_BITS);
     points += stride_points - 2;
     proj += stride_proj - 2;
   }
 }
 
-void projectPointsAffine(int *mat, int *points, int *proj, const int n,
+void projectPointsAffine(int16_t *mat, int *points, int *proj, const int n,
                          const int stride_points, const int stride_proj,
                          const int subsampling_x, const int subsampling_y) {
   int i;
@@ -87,26 +87,26 @@
     const int x = *(points++), y = *(points++);
     if (subsampling_x)
       *(proj++) = ROUND_POWER_OF_TWO_SIGNED(
-          mat[2] * 2 * x + mat[3] * 2 * y + mat[0] +
-              (mat[2] + mat[3] - (1 << WARPEDMODEL_PREC_BITS)) / 2,
+          mat[3] * 2 * x + mat[2] * 2 * y + mat[1] +
+              (mat[3] + mat[2] - (1 << WARPEDMODEL_PREC_BITS)) / 2,
           WARPEDDIFF_PREC_BITS + 1);
     else
-      *(proj++) = ROUND_POWER_OF_TWO_SIGNED(mat[2] * x + mat[3] * y + mat[0],
+      *(proj++) = ROUND_POWER_OF_TWO_SIGNED(mat[3] * x + mat[2] * y + mat[1],
                                             WARPEDDIFF_PREC_BITS);
     if (subsampling_y)
       *(proj++) = ROUND_POWER_OF_TWO_SIGNED(
-          mat[4] * 2 * x + mat[5] * 2 * y + mat[1] +
-              (mat[4] + mat[5] - (1 << WARPEDMODEL_PREC_BITS)) / 2,
+          mat[5] * 2 * x + mat[4] * 2 * y + mat[0] +
+              (mat[5] + mat[4] - (1 << WARPEDMODEL_PREC_BITS)) / 2,
           WARPEDDIFF_PREC_BITS + 1);
     else
-      *(proj++) = ROUND_POWER_OF_TWO_SIGNED(mat[4] * x + mat[5] * y + mat[1],
+      *(proj++) = ROUND_POWER_OF_TWO_SIGNED(mat[5] * x + mat[4] * y + mat[0],
                                             WARPEDDIFF_PREC_BITS);
     points += stride_points - 2;
     proj += stride_proj - 2;
   }
 }
 
-void projectPointsHomography(int *mat, int *points, int *proj, const int n,
+void projectPointsHomography(int16_t *mat, int *points, int *proj, const int n,
                              const int stride_points, const int stride_proj,
                              const int subsampling_x, const int subsampling_y) {
   int i;
@@ -117,11 +117,11 @@
     x = (subsampling_x ? 4 * x + 1 : 2 * x);
     y = (subsampling_y ? 4 * y + 1 : 2 * y);
 
-    Z = (mat[6] * x + mat[7] * y + (1 << (WARPEDMODEL_ROW3HOMO_PREC_BITS + 1)));
-    xp = (mat[0] * x + mat[1] * y + 2 * mat[2])
+    Z = (mat[7] * x + mat[6] * y + (1 << (WARPEDMODEL_ROW3HOMO_PREC_BITS + 1)));
+    xp = (mat[1] * x + mat[0] * y + 2 * mat[3])
          << (WARPEDPIXEL_PREC_BITS + WARPEDMODEL_ROW3HOMO_PREC_BITS -
              WARPEDMODEL_PREC_BITS);
-    yp = (mat[3] * x + mat[4] * y + 2 * mat[5])
+    yp = (mat[2] * x + mat[5] * y + 2 * mat[4])
          << (WARPEDPIXEL_PREC_BITS + WARPEDMODEL_ROW3HOMO_PREC_BITS -
              WARPEDMODEL_PREC_BITS);
 
@@ -483,7 +483,8 @@
       int in[2], out[2];
       in[0] = j;
       in[1] = i;
-      projectpoints(wm->wmmat, in, out, 1, 2, 2, subsampling_x, subsampling_y);
+      projectpoints((int16_t *)wm->wmmat, in, out, 1, 2, 2, subsampling_x,
+                    subsampling_y);
       out[0] = ROUND_POWER_OF_TWO_SIGNED(out[0] * x_scale, 4);
       out[1] = ROUND_POWER_OF_TWO_SIGNED(out[1] * y_scale, 4);
       gm_err = dst[(j - p_col) + (i - p_row) * p_stride] -
@@ -514,7 +515,8 @@
       int in[2], out[2];
       in[0] = j;
       in[1] = i;
-      projectpoints(wm->wmmat, in, out, 1, 2, 2, subsampling_x, subsampling_y);
+      projectpoints((int16_t *)wm->wmmat, in, out, 1, 2, 2, subsampling_x,
+                    subsampling_y);
       out[0] = ROUND_POWER_OF_TWO_SIGNED(out[0] * x_scale, 4);
       out[1] = ROUND_POWER_OF_TWO_SIGNED(out[1] * y_scale, 4);
       pred[(j - p_col) + (i - p_row) * p_stride] = highbd_warp_interpolate(
@@ -538,7 +540,8 @@
       int in[2], out[2];
       in[0] = j;
       in[1] = i;
-      projectpoints(wm->wmmat, in, out, 1, 2, 2, subsampling_x, subsampling_y);
+      projectpoints((int16_t *)wm->wmmat, in, out, 1, 2, 2, subsampling_x,
+                    subsampling_y);
       out[0] = ROUND_POWER_OF_TWO_SIGNED(out[0] * x_scale, 4);
       out[1] = ROUND_POWER_OF_TWO_SIGNED(out[1] * y_scale, 4);
       gm_err = dst[(j - p_col) + (i - p_row) * p_stride] -
@@ -565,7 +568,8 @@
       int in[2], out[2];
       in[0] = j;
       in[1] = i;
-      projectpoints(wm->wmmat, in, out, 1, 2, 2, subsampling_x, subsampling_y);
+      projectpoints((int16_t *)wm->wmmat, in, out, 1, 2, 2, subsampling_x,
+                    subsampling_y);
       out[0] = ROUND_POWER_OF_TWO_SIGNED(out[0] * x_scale, 4);
       out[1] = ROUND_POWER_OF_TWO_SIGNED(out[1] * y_scale, 4);
       pred[(j - p_col) + (i - p_row) * p_stride] =
@@ -620,22 +624,28 @@
   switch (wmtype) {
     case HOMOGRAPHY:
       assert(fabs(model[8] - 1.0) < 1e-12);
-      wm->wmmat[7] =
-          (int)lrint(model[7] * (1 << WARPEDMODEL_ROW3HOMO_PREC_BITS));
-      wm->wmmat[6] =
-          (int)lrint(model[6] * (1 << WARPEDMODEL_ROW3HOMO_PREC_BITS));
+      wm->wmmat[3].as_mv.row =
+          (int16_t)lrint(model[6] * (1 << WARPEDMODEL_ROW3HOMO_PREC_BITS));
+      wm->wmmat[3].as_mv.col =
+          (int16_t)lrint(model[7] * (1 << WARPEDMODEL_ROW3HOMO_PREC_BITS));
     /* fallthrough intended */
     case AFFINE:
-      wm->wmmat[5] = (int)lrint(model[5] * (1 << WARPEDMODEL_PREC_BITS));
-      wm->wmmat[4] = (int)lrint(model[4] * (1 << WARPEDMODEL_PREC_BITS));
+      wm->wmmat[2].as_mv.row =
+          (int16_t)lrint(model[4] * (1 << WARPEDMODEL_PREC_BITS));
+      wm->wmmat[2].as_mv.col =
+          (int16_t)lrint(model[5] * (1 << WARPEDMODEL_PREC_BITS));
     /* fallthrough intended */
     case ROTZOOM:
-      wm->wmmat[3] = (int)lrint(model[3] * (1 << WARPEDMODEL_PREC_BITS));
-      wm->wmmat[2] = (int)lrint(model[2] * (1 << WARPEDMODEL_PREC_BITS));
+      wm->wmmat[1].as_mv.row =
+          (int16_t)lrint(model[2] * (1 << WARPEDMODEL_PREC_BITS));
+      wm->wmmat[1].as_mv.col =
+          (int16_t)lrint(model[3] * (1 << WARPEDMODEL_PREC_BITS));
     /* fallthrough intended */
     case TRANSLATION:
-      wm->wmmat[1] = (int)lrint(model[1] * (1 << WARPEDMODEL_PREC_BITS));
-      wm->wmmat[0] = (int)lrint(model[0] * (1 << WARPEDMODEL_PREC_BITS));
+      wm->wmmat[0].as_mv.row =
+          (int16_t)lrint(model[0] * (1 << WARPEDMODEL_PREC_BITS));
+      wm->wmmat[0].as_mv.col =
+          (int16_t)lrint(model[1] * (1 << WARPEDMODEL_PREC_BITS));
       break;
     default: assert(0 && "Invalid TransformationType");
   }
diff --git a/av1/common/warped_motion.h b/av1/common/warped_motion.h
index 965b296..d957401 100644
--- a/av1/common/warped_motion.h
+++ b/av1/common/warped_motion.h
@@ -20,6 +20,7 @@
 #include "./aom_config.h"
 #include "aom_ports/mem.h"
 #include "aom_dsp/aom_dsp_common.h"
+#include "av1/common/mv.h"
 
 // Bits of precision used for the model
 #define WARPEDMODEL_PREC_BITS 8
@@ -37,49 +38,36 @@
 
 #define WARPEDDIFF_PREC_BITS (WARPEDMODEL_PREC_BITS - WARPEDPIXEL_PREC_BITS)
 
-typedef void (*ProjectPointsType)(int *mat, int *points, int *proj, const int n,
-                                  const int stride_points,
+typedef void (*ProjectPointsType)(int16_t *mat, int *points, int *proj,
+                                  const int n, const int stride_points,
                                   const int stride_proj,
                                   const int subsampling_x,
                                   const int subsampling_y);
-void projectPointsHomography(int *mat, int *points, int *proj, const int n,
+
+void projectPointsHomography(int16_t *mat, int *points, int *proj, const int n,
                              const int stride_points, const int stride_proj,
                              const int subsampling_x, const int subsampling_y);
-void projectPointsAffine(int *mat, int *points, int *proj, const int n,
+
+void projectPointsAffine(int16_t *mat, int *points, int *proj, const int n,
                          const int stride_points, const int stride_proj,
                          const int subsampling_x, const int subsampling_y);
-void projectPointsRotZoom(int *mat, int *points, int *proj, const int n,
+
+void projectPointsRotZoom(int16_t *mat, int *points, int *proj, const int n,
                           const int stride_points, const int stride_proj,
                           const int subsampling_x, const int subsampling_y);
-void projectPointsTranslation(int *mat, int *points, int *proj, const int n,
+
+void projectPointsTranslation(int16_t *mat, int *points, int *proj, const int n,
                               const int stride_points, const int stride_proj,
                               const int subsampling_x, const int subsampling_y);
 
-typedef enum {
-  UNKNOWN_TRANSFORM = -1,
-  HOMOGRAPHY,   // homography, 8-parameter
-  AFFINE,       // affine, 6-parameter
-  ROTZOOM,      // simplified affine with rotation and zoom only, 4-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
-} WarpedMotionParams;
-
 double av1_warp_erroradv(WarpedMotionParams *wm,
-#if CONFIG_AOM_HIGHBITDEPTH
-                         int use_hbd, int bd,
-#endif  // CONFIG_AOM_HIGHBITDEPTH
-                         uint8_t *ref, int width, int height, int stride,
-                         uint8_t *dst, int p_col, int p_row, int p_width,
-                         int p_height, int p_stride, int subsampling_x,
-                         int subsampling_y, int x_scale, int y_scale);
+#if CONFIG_VP9_HIGHBITDEPTH
+                          int use_hbd, int bd,
+#endif  // CONFIG_VP9_HIGHBITDEPTH
+                          uint8_t *ref, int width, int height, int stride,
+                          uint8_t *dst, int p_col, int p_row, int p_width,
+                          int p_height, int p_stride, int subsampling_x,
+                          int subsampling_y, int x_scale, int y_scale);
 
 void av1_warp_plane(WarpedMotionParams *wm,
 #if CONFIG_AOM_HIGHBITDEPTH
diff --git a/av1/decoder/decodeframe.c b/av1/decoder/decodeframe.c
index 638fa01..50ecef3 100644
--- a/av1/decoder/decodeframe.c
+++ b/av1/decoder/decodeframe.c
@@ -3423,28 +3423,28 @@
   switch (gmtype) {
     case GLOBAL_ZERO: break;
     case GLOBAL_AFFINE:
-      params->motion_params.wmmat[4] =
-          (aom_read_primitive_symmetric(r, GM_ABS_ALPHA_BITS) *
-           GM_ALPHA_DECODE_FACTOR);
-      params->motion_params.wmmat[5] =
+      params->motion_params.wmmat[2].as_mv.row =
           aom_read_primitive_symmetric(r, GM_ABS_ALPHA_BITS) *
               GM_ALPHA_DECODE_FACTOR +
           (1 << WARPEDMODEL_PREC_BITS);
+      params->motion_params.wmmat[2].as_mv.col =
+          (aom_read_primitive_symmetric(r, GM_ABS_ALPHA_BITS) *
+           GM_ALPHA_DECODE_FACTOR);
     // fallthrough intended
     case GLOBAL_ROTZOOM:
-      params->motion_params.wmmat[2] =
+      params->motion_params.wmmat[1].as_mv.row =
+          aom_read_primitive_symmetric(r, GM_ABS_ALPHA_BITS) *
+          GM_ALPHA_DECODE_FACTOR;
+      params->motion_params.wmmat[1].as_mv.col =
           (aom_read_primitive_symmetric(r, GM_ABS_ALPHA_BITS) *
            GM_ALPHA_DECODE_FACTOR) +
           (1 << WARPEDMODEL_PREC_BITS);
-      params->motion_params.wmmat[3] =
-          aom_read_primitive_symmetric(r, GM_ABS_ALPHA_BITS) *
-          GM_ALPHA_DECODE_FACTOR;
     // fallthrough intended
     case GLOBAL_TRANSLATION:
-      params->motion_params.wmmat[0] =
+      params->motion_params.wmmat[0].as_mv.row =
           aom_read_primitive_symmetric(r, GM_ABS_TRANS_BITS) *
           GM_TRANS_DECODE_FACTOR;
-      params->motion_params.wmmat[1] =
+      params->motion_params.wmmat[0].as_mv.col =
           aom_read_primitive_symmetric(r, GM_ABS_TRANS_BITS) *
           GM_TRANS_DECODE_FACTOR;
       break;
@@ -3458,6 +3458,14 @@
   for (frame = LAST_FRAME; frame <= ALTREF_FRAME; ++frame) {
     read_global_motion_params(&cm->global_motion[frame],
                               cm->fc->global_motion_types_prob, r);
+    /*
+          printf("Dec Ref %d [%d]: %d %d %d %d\n",
+                 frame, cm->current_video_frame,
+                 cm->global_motion[frame].motion_params.wmmat[0].as_mv.row,
+                 cm->global_motion[frame].motion_params.wmmat[0].as_mv.col,
+                 cm->global_motion[frame].motion_params.wmmat[1].as_mv.row,
+                 cm->global_motion[frame].motion_params.wmmat[1].as_mv.col);
+    */
   }
 }
 #endif  // CONFIG_GLOBAL_MOTION
diff --git a/av1/decoder/decodemv.c b/av1/decoder/decodemv.c
index 47cfea6..59554a4 100644
--- a/av1/decoder/decodemv.c
+++ b/av1/decoder/decodemv.c
@@ -938,6 +938,7 @@
 
 static INLINE int assign_mv(AV1_COMMON *cm, MACROBLOCKD *xd,
                             PREDICTION_MODE mode,
+                            MV_REFERENCE_FRAME ref_frame[2],
 #if CONFIG_REF_MV
                             int block,
 #endif
@@ -952,6 +953,7 @@
   int_mv *pred_mv =
       (bsize >= BLOCK_8X8) ? mbmi->pred_mv : xd->mi[0]->bmi[block].pred_mv_s8;
 #endif
+  (void)ref_frame;
 
   switch (mode) {
 #if CONFIG_EXT_INTER
@@ -1006,8 +1008,16 @@
       break;
     }
     case ZEROMV: {
+#if CONFIG_GLOBAL_MOTION
+      mv[0].as_int =
+          cm->global_motion[ref_frame[0]].motion_params.wmmat[0].as_int;
+      if (is_compound)
+        mv[1].as_int =
+            cm->global_motion[ref_frame[1]].motion_params.wmmat[0].as_int;
+#else
       mv[0].as_int = 0;
       if (is_compound) mv[1].as_int = 0;
+#endif  // CONFIG_GLOBAL_MOTION
 
 #if CONFIG_REF_MV
       pred_mv[0].as_int = 0;
@@ -1428,7 +1438,7 @@
         (void)ref_mv_s8;
 #endif
 
-        if (!assign_mv(cm, xd, b_mode,
+        if (!assign_mv(cm, xd, b_mode, mbmi->ref_frame,
 #if CONFIG_REF_MV
                        j,
 #endif
@@ -1480,7 +1490,7 @@
     }
 
     xd->corrupted |=
-        !assign_mv(cm, xd, mbmi->mode,
+        !assign_mv(cm, xd, mbmi->mode, mbmi->ref_frame,
 #if CONFIG_REF_MV
                    0,
 #endif
diff --git a/av1/encoder/bitstream.c b/av1/encoder/bitstream.c
index 305a672..f5a4858 100644
--- a/av1/encoder/bitstream.c
+++ b/av1/encoder/bitstream.c
@@ -3195,29 +3195,29 @@
   switch (gmtype) {
     case GLOBAL_ZERO: break;
     case GLOBAL_AFFINE:
-      av1_write_primitive_symmetric(
-          w, params->motion_params.wmmat[4] >> GM_ALPHA_PREC_DIFF,
-          GM_ABS_ALPHA_BITS);
-      av1_write_primitive_symmetric(
-          w, (params->motion_params.wmmat[5] >> GM_ALPHA_PREC_DIFF) -
+      aom_write_primitive_symmetric(
+          w, (params->motion_params.wmmat[2].as_mv.row >> GM_ALPHA_PREC_DIFF) -
                  (1 << GM_ALPHA_PREC_BITS),
           GM_ABS_ALPHA_BITS);
+      aom_write_primitive_symmetric(
+          w, (params->motion_params.wmmat[2].as_mv.col >> GM_ALPHA_PREC_DIFF),
+          GM_ABS_ALPHA_BITS);
     // fallthrough intended
     case GLOBAL_ROTZOOM:
       aom_write_primitive_symmetric(
-          w, (params->motion_params.wmmat[2] >> GM_ALPHA_PREC_DIFF) -
-                 (1 << GM_ALPHA_PREC_BITS),
+          w, (params->motion_params.wmmat[1].as_mv.row >> GM_ALPHA_PREC_DIFF),
           GM_ABS_ALPHA_BITS);
       aom_write_primitive_symmetric(
-          w, params->motion_params.wmmat[3] >> GM_ALPHA_PREC_DIFF,
+          w, (params->motion_params.wmmat[1].as_mv.col >> GM_ALPHA_PREC_DIFF) -
+                 (1 << GM_ALPHA_PREC_BITS),
           GM_ABS_ALPHA_BITS);
     // fallthrough intended
     case GLOBAL_TRANSLATION:
       aom_write_primitive_symmetric(
-          w, params->motion_params.wmmat[0] >> GM_TRANS_PREC_DIFF,
+          w, (params->motion_params.wmmat[0].as_mv.row >> GM_TRANS_PREC_DIFF),
           GM_ABS_TRANS_BITS);
       aom_write_primitive_symmetric(
-          w, params->motion_params.wmmat[1] >> GM_TRANS_PREC_DIFF,
+          w, (params->motion_params.wmmat[0].as_mv.col >> GM_TRANS_PREC_DIFF),
           GM_ABS_TRANS_BITS);
       break;
     default: assert(0);
@@ -3233,6 +3233,14 @@
     }
     write_global_motion_params(&cm->global_motion[frame],
                                cm->fc->global_motion_types_prob, w);
+    /*
+          printf("Enc Ref %d [%d] (used %d): %d %d %d %d\n",
+                 frame, cm->current_video_frame, cpi->global_motion_used[frame],
+                 cm->global_motion[frame].motion_params.wmmat[0].as_mv.row,
+                 cm->global_motion[frame].motion_params.wmmat[0].as_mv.col,
+                 cm->global_motion[frame].motion_params.wmmat[1].as_mv.row,
+                 cm->global_motion[frame].motion_params.wmmat[1].as_mv.col);
+    */
   }
 }
 #endif
diff --git a/av1/encoder/encodeframe.c b/av1/encoder/encodeframe.c
index a7183f9..d510b19 100644
--- a/av1/encoder/encodeframe.c
+++ b/av1/encoder/encodeframe.c
@@ -40,6 +40,7 @@
 #include "av1/encoder/cost.h"
 #endif
 #if CONFIG_GLOBAL_MOTION
+#include "av1/common/warped_motion.h"
 #include "av1/encoder/global_motion.h"
 #endif
 #include "av1/encoder/encodeframe.h"
@@ -4401,37 +4402,30 @@
 #if CONFIG_GLOBAL_MOTION
 #define MIN_TRANS_THRESH 8
 #define GLOBAL_MOTION_ADVANTAGE_THRESH 0.60
-#define GLOBAL_MOTION_MODEL ROTZOOM
+#define GLOBAL_MOTION_MODEL TRANSLATION
 static void convert_to_params(double *H, TransformationType type,
-                              Global_Motion_Params *model) {
+                              int16_t *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] * (1 << GM_TRANS_PREC_BITS) + 0.5);
-  model->motion_params.wmmat[0] =
-      clamp(model->motion_params.wmmat[0], GM_TRANS_MIN, GM_TRANS_MAX) *
-      GM_TRANS_DECODE_FACTOR;
-  model->motion_params.wmmat[1] =
-      clamp(model->motion_params.wmmat[1], GM_TRANS_MIN, GM_TRANS_MAX) *
-      GM_TRANS_DECODE_FACTOR;
+  model[0] = (int16_t)floor(H[0] * (1 << GM_TRANS_PREC_BITS) + 0.5);
+  model[1] = (int16_t)floor(H[1] * (1 << GM_TRANS_PREC_BITS) + 0.5);
+  model[0] = (int16_t)clamp(model[0], GM_TRANS_MIN, GM_TRANS_MAX) *
+             GM_TRANS_DECODE_FACTOR;
+  model[1] = (int16_t)clamp(model[1], GM_TRANS_MIN, GM_TRANS_MAX) *
+             GM_TRANS_DECODE_FACTOR;
 
   for (i = 2; i < n_params; ++i) {
-    model->motion_params.wmmat[i] =
-        (int)floor(H[i] * (1 << GM_ALPHA_PREC_BITS) + 0.5);
-    model->motion_params.wmmat[i] =
-        clamp(model->motion_params.wmmat[i], GM_ALPHA_MIN, GM_ALPHA_MAX) *
-        GM_ALPHA_DECODE_FACTOR;
-    alpha_present |= (model->motion_params.wmmat[i] != 0);
+    model[i] = (int16_t)floor(H[i] * (1 << GM_ALPHA_PREC_BITS) + 0.5);
+    model[i] = (int16_t)clamp(model[i], GM_ALPHA_MIN, GM_ALPHA_MAX) *
+               GM_ALPHA_DECODE_FACTOR;
+    alpha_present |= (model[i] != 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;
-      model->motion_params.wmmat[1] = 0;
+    if (abs(model[0]) < MIN_TRANS_THRESH && abs(model[1]) < MIN_TRANS_THRESH) {
+      model[0] = 0;
+      model[1] = 0;
     }
   }
 }
@@ -4439,7 +4433,8 @@
 static void convert_model_to_params(double *H, TransformationType type,
                                     Global_Motion_Params *model) {
   // TODO(sarahparker) implement for homography
-  if (type > HOMOGRAPHY) convert_to_params(H, type, model);
+  if (type > HOMOGRAPHY)
+    convert_to_params(H, type, (int16_t *)model->motion_params.wmmat);
   model->gmtype = get_gmtype(model);
   model->motion_params.wmtype = gm_to_trans_type(model->gmtype);
 }
diff --git a/av1/encoder/ransac.c b/av1/encoder/ransac.c
index 0beaab8..a3072bc 100644
--- a/av1/encoder/ransac.c
+++ b/av1/encoder/ransac.c
@@ -469,7 +469,8 @@
     }
 
     av1_integerize_model(H, type, &wm);
-    projectpoints(wm.wmmat, corners1_int, image1_coord, npoints, 2, 2, 0, 0);
+    projectpoints((int16_t *)wm.wmmat, corners1_int, image1_coord, npoints, 2,
+                  2, 0, 0);
 
     for (i = 0; i < npoints; ++i) {
       double dx =
@@ -610,12 +611,12 @@
   Ha[6] = Ha[7] = 0;
   Ha[8] = 1;
   denormalizeHomography(Ha, T1, T2);
-  H[0] = Ha[2];
-  H[1] = Ha[5];
-  H[2] = Ha[0];
-  H[3] = Ha[1];
-  H[4] = Ha[3];
-  H[5] = Ha[4];
+  H[0] = Ha[5];
+  H[1] = Ha[2];
+  H[2] = Ha[1];
+  H[3] = Ha[0];
+  H[4] = Ha[4];
+  H[5] = Ha[3];
 }
 
 static void denormalizeRotZoom(double *H, double *T1, double *T2) {
@@ -629,10 +630,10 @@
   Ha[6] = Ha[7] = 0;
   Ha[8] = 1;
   denormalizeHomography(Ha, T1, T2);
-  H[0] = Ha[2];
-  H[1] = Ha[5];
-  H[2] = Ha[0];
-  H[3] = Ha[1];
+  H[0] = Ha[5];
+  H[1] = Ha[2];
+  H[2] = Ha[1];
+  H[3] = Ha[0];
 }
 
 static void denormalizeTranslation(double *H, double *T1, double *T2) {
@@ -646,8 +647,8 @@
   Ha[6] = Ha[7] = 0;
   Ha[8] = 1;
   denormalizeHomography(Ha, T1, T2);
-  H[0] = Ha[2];
-  H[1] = Ha[5];
+  H[0] = Ha[5];
+  H[1] = Ha[2];
 }
 
 static int is_collinear3(double *p1, double *p2, double *p3) {
diff --git a/av1/encoder/rdopt.c b/av1/encoder/rdopt.c
index bd93746..e3941cb 100644
--- a/av1/encoder/rdopt.c
+++ b/av1/encoder/rdopt.c
@@ -4068,6 +4068,31 @@
 #endif
 }
 
+#if CONFIG_GLOBAL_MOTION
+static int get_gmbitcost(const Global_Motion_Params *gm,
+                         const aom_prob *probs) {
+  int gmtype_cost[GLOBAL_MOTION_TYPES];
+  int bits;
+  av1_cost_tokens(gmtype_cost, probs, av1_global_motion_types_tree);
+  if (gm->motion_params.wmmat[2].as_int) {
+    bits = (GM_ABS_TRANS_BITS + 1) * 2 + 4 * GM_ABS_ALPHA_BITS + 4;
+  } else if (gm->motion_params.wmmat[1].as_int) {
+    bits = (GM_ABS_TRANS_BITS + 1) * 2 + 2 * GM_ABS_ALPHA_BITS + 2;
+  } else {
+    bits =
+        (gm->motion_params.wmmat[0].as_int ? ((GM_ABS_TRANS_BITS + 1) * 2) : 0);
+  }
+  return (bits << AV1_PROB_COST_SHIFT) + gmtype_cost[gm->gmtype];
+}
+
+#define GLOBAL_MOTION_RATE(ref)                            \
+  (cpi->global_motion_used[ref] >= 2                       \
+       ? 0                                                 \
+       : get_gmbitcost(&cm->global_motion[(ref)],          \
+                       cm->fc->global_motion_types_prob) / \
+             2);
+#endif  // CONFIG_GLOBAL_MOTION
+
 static int set_and_cost_bmi_mvs(
     AV1_COMP *cpi, MACROBLOCK *x, MACROBLOCKD *xd, int i, PREDICTION_MODE mode,
     int_mv this_mv[2], int_mv frame_mv[MB_MODE_COUNT][TOTAL_REFS_PER_FRAME],
@@ -4076,6 +4101,9 @@
     int_mv compound_seg_newmvs[2],
 #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;
@@ -4127,8 +4155,21 @@
         this_mv[1].as_int = frame_mv[mode][mbmi->ref_frame[1]].as_int;
       break;
     case ZEROMV:
+#if CONFIG_GLOBAL_MOTION
+      this_mv[0].as_int = cpi->common.global_motion[mbmi->ref_frame[0]]
+                              .motion_params.wmmat[0]
+                              .as_int;
+      thismvcost += GLOBAL_MOTION_RATE(mbmi->ref_frame[0]);
+      if (is_compound) {
+        this_mv[1].as_int = cpi->common.global_motion[mbmi->ref_frame[1]]
+                                .motion_params.wmmat[0]
+                                .as_int;
+        thismvcost += GLOBAL_MOTION_RATE(mbmi->ref_frame[1]);
+      }
+#else   // CONFIG_GLOBAL_MOTION
       this_mv[0].as_int = 0;
       if (is_compound) this_mv[1].as_int = 0;
+#endif  // CONFIG_GLOBAL_MOTION
       break;
 #if CONFIG_EXT_INTER
     case NEW_NEWMV:
@@ -4837,7 +4878,12 @@
         av1_update_mv_context(xd, mi, frame, mv_ref_list, i, mi_row, mi_col,
                               NULL);
 #endif  // CONFIG_EXT_INTER
+#if CONFIG_GLOBAL_MOTION
+        frame_mv[ZEROMV][frame].as_int =
+            cm->global_motion[frame].motion_params.wmmat[0].as_int;
+#else   // CONFIG_GLOBAL_MOTION
         frame_mv[ZEROMV][frame].as_int = 0;
+#endif  // CONFIG_GLOBAL_MOTION
         av1_append_sub8x8_mvs_for_idx(cm, xd, i, ref, mi_row, mi_col,
 #if CONFIG_REF_MV
                                       ref_mv_stack[ref], &ref_mv_count[ref],
@@ -4973,12 +5019,19 @@
 #endif  // CONFIG_EXT_INTER
 #endif  // CONFIG_REF_MV
 
-        if (!check_best_zero_mv(cpi, mbmi_ext->mode_context,
+#if CONFIG_GLOBAL_MOTION
+        if (get_gmtype(&cm->global_motion[mbmi->ref_frame[0]]) == GLOBAL_ZERO &&
+            (!has_second_rf ||
+             get_gmtype(&cm->global_motion[mbmi->ref_frame[1]]) == GLOBAL_ZERO))
+#endif  // CONFIG_GLOBAL_MOTION
+
+          if (!check_best_zero_mv(cpi, mbmi_ext->mode_context,
 #if CONFIG_REF_MV && CONFIG_EXT_INTER
-                                mbmi_ext->compound_mode_context,
+                                  mbmi_ext->compound_mode_context,
 #endif  // CONFIG_REF_MV && CONFIG_EXT_INTER
-                                frame_mv, this_mode, mbmi->ref_frame, bsize, i))
-          continue;
+                                  frame_mv, this_mode, mbmi->ref_frame, bsize,
+                                  i))
+            continue;
 
         memcpy(orig_pre, pd->pre, sizeof(orig_pre));
         memcpy(bsi->rdstat[i][mode_idx].ta, t_above,
@@ -7638,6 +7691,12 @@
       *rate_uv = 0;
       *skippable = 1;
     }
+#if CONFIG_GLOBAL_MOTION
+    if (this_mode == ZEROMV) {
+      *rate2 += GLOBAL_MOTION_RATE(mbmi->ref_frame[0]);
+      if (is_comp_pred) *rate2 += GLOBAL_MOTION_RATE(mbmi->ref_frame[1]);
+    }
+#endif  // CONFIG_GLOBAL_MOTION
 
 #if CONFIG_OBMC || CONFIG_WARPED_MOTION
     tmp_rd = RDCOST(x->rdmult, x->rddiv, *rate2, *distortion);
@@ -8274,7 +8333,12 @@
                          frame_mv[NEARESTMV], frame_mv[NEARMV], yv12_mb);
     }
     frame_mv[NEWMV][ref_frame].as_int = INVALID_MV;
+#if CONFIG_GLOBAL_MOTION
+    frame_mv[ZEROMV][ref_frame].as_int =
+        cm->global_motion[ref_frame].motion_params.wmmat[0].as_int;
+#else   // CONFIG_GLOBAL_MOTION
     frame_mv[ZEROMV][ref_frame].as_int = 0;
+#endif  // CONFIG_GLOBAL_MOTION
 #if CONFIG_EXT_INTER
     frame_mv[NEWFROMNEARMV][ref_frame].as_int = INVALID_MV;
     frame_mv[NEW_NEWMV][ref_frame].as_int = INVALID_MV;
@@ -8351,6 +8415,7 @@
     // an unfiltered alternative. We allow near/nearest as well
     // because they may result in zero-zero MVs but be cheaper.
     if (cpi->rc.is_src_frame_alt_ref && (cpi->oxcf.arnr_max_frames == 0)) {
+      int_mv zeromv;
       ref_frame_skip_mask[0] = (1 << LAST_FRAME) |
 #if CONFIG_EXT_REFS
                                (1 << LAST2_FRAME) | (1 << LAST3_FRAME) |
@@ -8361,18 +8426,24 @@
       // TODO(zoeliu): To further explore whether following needs to be done for
       //               BWDREF_FRAME as well.
       mode_skip_mask[ALTREF_FRAME] = ~INTER_NEAREST_NEAR_ZERO;
-      if (frame_mv[NEARMV][ALTREF_FRAME].as_int != 0)
+#if CONFIG_GLOBAL_MOTION
+      zeromv.as_int =
+          cm->global_motion[ALTREF_FRAME].motion_params.wmmat[0].as_int;
+#else
+      zeromv.as_int = 0;
+#endif  // CONFIG_GLOBAL_MOTION
+      if (frame_mv[NEARMV][ALTREF_FRAME].as_int != zeromv.as_int)
         mode_skip_mask[ALTREF_FRAME] |= (1 << NEARMV);
-      if (frame_mv[NEARESTMV][ALTREF_FRAME].as_int != 0)
+      if (frame_mv[NEARESTMV][ALTREF_FRAME].as_int != zeromv.as_int)
         mode_skip_mask[ALTREF_FRAME] |= (1 << NEARESTMV);
 #if CONFIG_EXT_INTER
-      if (frame_mv[NEAREST_NEARESTMV][ALTREF_FRAME].as_int != 0)
+      if (frame_mv[NEAREST_NEARESTMV][ALTREF_FRAME].as_int != zeromv.as_int)
         mode_skip_mask[ALTREF_FRAME] |= (1 << NEAREST_NEARESTMV);
-      if (frame_mv[NEAREST_NEARMV][ALTREF_FRAME].as_int != 0)
+      if (frame_mv[NEAREST_NEARMV][ALTREF_FRAME].as_int != zeromv.as_int)
         mode_skip_mask[ALTREF_FRAME] |= (1 << NEAREST_NEARMV);
-      if (frame_mv[NEAR_NEARESTMV][ALTREF_FRAME].as_int != 0)
+      if (frame_mv[NEAR_NEARESTMV][ALTREF_FRAME].as_int != zeromv.as_int)
         mode_skip_mask[ALTREF_FRAME] |= (1 << NEAR_NEARESTMV);
-      if (frame_mv[NEAR_NEARMV][ALTREF_FRAME].as_int != 0)
+      if (frame_mv[NEAR_NEARMV][ALTREF_FRAME].as_int != zeromv.as_int)
         mode_skip_mask[ALTREF_FRAME] |= (1 << NEAR_NEARMV);
 #endif  // CONFIG_EXT_INTER
     }
@@ -8580,7 +8651,14 @@
           if (conditional_skipintra(this_mode, best_intra_mode)) continue;
         }
       }
+#if CONFIG_GLOBAL_MOTION
+    } else if (get_gmtype(&cm->global_motion[ref_frame]) == GLOBAL_ZERO &&
+               (!comp_pred ||
+                get_gmtype(&cm->global_motion[second_ref_frame]) ==
+                    GLOBAL_ZERO)) {
+#else   // CONFIG_GLOBAL_MOTION
     } else {
+#endif  // CONFIG_GLOBAL_MOTION
       const MV_REFERENCE_FRAME ref_frames[2] = { ref_frame, second_ref_frame };
       if (!check_best_zero_mv(cpi, mbmi_ext->mode_context,
 #if CONFIG_REF_MV && CONFIG_EXT_INTER
@@ -9426,8 +9504,18 @@
     const MV_REFERENCE_FRAME refs[2] = { best_mbmode.ref_frame[0],
                                          best_mbmode.ref_frame[1] };
     int comp_pred_mode = refs[1] > INTRA_FRAME;
+    int_mv zeromv[2];
 #if CONFIG_REF_MV
     const uint8_t rf_type = av1_ref_frame_type(best_mbmode.ref_frame);
+#endif  // CONFIG_REF_MV
+#if CONFIG_GLOBAL_MOTION
+    zeromv[0].as_int = cm->global_motion[refs[0]].motion_params.wmmat[0].as_int;
+    zeromv[1].as_int = cm->global_motion[refs[1]].motion_params.wmmat[0].as_int;
+#else
+    zeromv[0].as_int = 0;
+    zeromv[1].as_int = 0;
+#endif  // CONFIG_GLOBAL_MOTION
+#if CONFIG_REF_MV
     if (!comp_pred_mode) {
       int i;
       int ref_set = (mbmi_ext->ref_mv_count[rf_type] >= 2)
@@ -9444,7 +9532,7 @@
 
       if (frame_mv[NEARESTMV][refs[0]].as_int == best_mbmode.mv[0].as_int)
         best_mbmode.mode = NEARESTMV;
-      else if (best_mbmode.mv[0].as_int == 0)
+      else if (best_mbmode.mv[0].as_int == zeromv[0].as_int)
         best_mbmode.mode = ZEROMV;
     } else {
       int_mv nearestmv[2];
@@ -9500,7 +9588,8 @@
         best_mbmode.mode = ZERO_ZEROMV;
 #else
         best_mbmode.mode = NEARESTMV;
-      else if (best_mbmode.mv[0].as_int == 0 && best_mbmode.mv[1].as_int == 0)
+      else if (best_mbmode.mv[0].as_int == zeromv[0].as_int &&
+               best_mbmode.mv[1].as_int == zeromv[1].as_int)
         best_mbmode.mode = ZEROMV;
 #endif  // CONFIG_EXT_INTER
     }
@@ -9519,8 +9608,9 @@
                      best_mbmode.mv[1].as_int) ||
                 !comp_pred_mode))
         best_mbmode.mode = NEARMV;
-      else if (best_mbmode.mv[0].as_int == 0 &&
-               ((comp_pred_mode && best_mbmode.mv[1].as_int == 0) ||
+      else if (best_mbmode.mv[0].as_int == zeromv[0].as_int &&
+               ((comp_pred_mode &&
+                 best_mbmode.mv[1].as_int == zeromv[1].as_int) ||
                 !comp_pred_mode))
         best_mbmode.mode = ZEROMV;
 #if CONFIG_EXT_INTER
@@ -9692,7 +9782,13 @@
   mbmi->uv_mode = DC_PRED;
   mbmi->ref_frame[0] = LAST_FRAME;
   mbmi->ref_frame[1] = NONE;
+#if CONFIG_GLOBAL_MOTION
+  mbmi->mv[0].as_int =
+      cm->global_motion[mbmi->ref_frame[0]].motion_params.wmmat[0].as_int;
+#else   // CONFIG_GLOBAL_MOTION
   mbmi->mv[0].as_int = 0;
+#endif  // CONFIG_GLOBAL_MOTION
+
 #if CONFIG_REF_MV
   mbmi->ref_mv_idx = 0;
   mbmi->pred_mv[0].as_int = 0;