Add gm parameter coding based on ref parameters

Change-Id: Ic2344a6475b967fa07f70b3ffad2714de657bb49
diff --git a/aom_dsp/binary_codes_reader.c b/aom_dsp/binary_codes_reader.c
index 0bbcffa..4664ff5 100644
--- a/aom_dsp/binary_codes_reader.c
+++ b/aom_dsp/binary_codes_reader.c
@@ -108,3 +108,12 @@
   return inv_recenter_finite_nonneg(n, ref,
                                     aom_read_primitive_subexpfin(r, n, k));
 }
+
+// Decode finite subexponential code that for a symbol v in [-(n-1), n-1] with
+// parameter k based on a reference ref also in [-(n-1), n-1].
+int16_t aom_read_signed_primitive_refsubexpfin(aom_reader *r, uint16_t n,
+                                               uint16_t k, int16_t ref) {
+  ref += n - 1;
+  const uint16_t scaled_n = (n << 1) - 1;
+  return aom_read_primitive_refsubexpfin(r, scaled_n, k, ref) - n + 1;
+}
diff --git a/aom_dsp/binary_codes_reader.h b/aom_dsp/binary_codes_reader.h
index d1c4d4c..738d91d 100644
--- a/aom_dsp/binary_codes_reader.h
+++ b/aom_dsp/binary_codes_reader.h
@@ -29,6 +29,8 @@
 uint16_t aom_read_primitive_subexpfin(aom_reader *r, uint16_t n, uint16_t k);
 uint16_t aom_read_primitive_refsubexpfin(aom_reader *r, uint16_t n, uint16_t k,
                                          uint16_t ref);
+int16_t aom_read_signed_primitive_refsubexpfin(aom_reader *r, uint16_t n,
+                                               uint16_t k, int16_t ref);
 #ifdef __cplusplus
 }  // extern "C"
 #endif
diff --git a/aom_dsp/binary_codes_writer.c b/aom_dsp/binary_codes_writer.c
index 9edb018..91e807b 100644
--- a/aom_dsp/binary_codes_writer.c
+++ b/aom_dsp/binary_codes_writer.c
@@ -184,11 +184,28 @@
 // based on a reference ref also in [0, n-1].
 // Recenters symbol around r first and then uses a finite subexponential code.
 void aom_write_primitive_refsubexpfin(aom_writer *w, uint16_t n, uint16_t k,
-                                      uint16_t ref, uint16_t v) {
+                                      int16_t ref, int16_t v) {
   aom_write_primitive_subexpfin(w, n, k, recenter_finite_nonneg(n, ref, v));
 }
 
+void aom_write_signed_primitive_refsubexpfin(aom_writer *w, uint16_t n,
+                                             uint16_t k, uint16_t ref,
+                                             uint16_t v) {
+  ref += n - 1;
+  v += n - 1;
+  const uint16_t scaled_n = (n << 1) - 1;
+  aom_write_primitive_refsubexpfin(w, scaled_n, k, ref, v);
+}
+
 int aom_count_primitive_refsubexpfin(uint16_t n, uint16_t k, uint16_t ref,
                                      uint16_t v) {
   return aom_count_primitive_subexpfin(n, k, recenter_finite_nonneg(n, ref, v));
 }
+
+int aom_count_signed_primitive_refsubexpfin(uint16_t n, uint16_t k, int16_t ref,
+                                            int16_t v) {
+  ref += n - 1;
+  v += n - 1;
+  const uint16_t scaled_n = (n << 1) - 1;
+  return aom_count_primitive_refsubexpfin(scaled_n, k, ref, v);
+}
diff --git a/aom_dsp/binary_codes_writer.h b/aom_dsp/binary_codes_writer.h
index d80de9e..ab5ccbf 100644
--- a/aom_dsp/binary_codes_writer.h
+++ b/aom_dsp/binary_codes_writer.h
@@ -47,6 +47,12 @@
 void aom_write_primitive_refsubexpfin(aom_writer *w, uint16_t n, uint16_t k,
                                       uint16_t ref, uint16_t v);
 
+// Finite subexponential code that codes a symbol v in [-(n-1), n-1] with
+// parameter k based on a reference ref also in [-(n-1), n-1].
+void aom_write_signed_primitive_refsubexpfin(aom_writer *w, uint16_t n,
+                                             uint16_t k, int16_t ref,
+                                             int16_t v);
+
 // Functions that counts bits for the above primitives
 int aom_count_primitive_symmetric(int16_t v, unsigned int mag_bits);
 int aom_count_primitive_quniform(uint16_t n, uint16_t v);
@@ -55,6 +61,8 @@
 int aom_count_primitive_subexpfin(uint16_t n, uint16_t k, uint16_t v);
 int aom_count_primitive_refsubexpfin(uint16_t n, uint16_t k, uint16_t ref,
                                      uint16_t v);
+int aom_count_signed_primitive_refsubexpfin(uint16_t n, uint16_t k, int16_t ref,
+                                            int16_t v);
 #ifdef __cplusplus
 }  // extern "C"
 #endif
diff --git a/av1/common/mv.h b/av1/common/mv.h
index 67f36b6..d516934 100644
--- a/av1/common/mv.h
+++ b/av1/common/mv.h
@@ -121,6 +121,7 @@
 //
 // XX_MIN, XX_MAX are also computed to avoid repeated computation
 
+#define SUBEXPFIN_K 3
 #define GM_TRANS_PREC_BITS 6
 #define GM_ABS_TRANS_BITS 12
 #define GM_ABS_TRANS_ONLY_BITS (GM_ABS_TRANS_BITS - GM_TRANS_PREC_BITS + 3)
diff --git a/av1/common/onyxc_int.h b/av1/common/onyxc_int.h
index f5558b2..7079cdd 100644
--- a/av1/common/onyxc_int.h
+++ b/av1/common/onyxc_int.h
@@ -108,6 +108,9 @@
   MV_REF *mvs;
   int mi_rows;
   int mi_cols;
+#if CONFIG_GLOBAL_MOTION
+  WarpedMotionParams global_motion[TOTAL_REFS_PER_FRAME];
+#endif  // CONFIG_GLOBAL_MOTION
   aom_codec_frame_buffer_t raw_frame_buffer;
   YV12_BUFFER_CONFIG buf;
 #if CONFIG_TEMPMV_SIGNALING
diff --git a/av1/decoder/decodeframe.c b/av1/decoder/decodeframe.c
index a209d6d..1ae815a 100644
--- a/av1/decoder/decodeframe.c
+++ b/av1/decoder/decodeframe.c
@@ -4401,12 +4401,14 @@
 
 #if CONFIG_GLOBAL_MOTION
 static void read_global_motion_params(WarpedMotionParams *params,
+                                      WarpedMotionParams *ref_params,
                                       aom_prob *probs, aom_reader *r,
                                       int allow_hp) {
   TransformationType type =
       aom_read_tree(r, av1_global_motion_types_tree, probs, ACCT_STR);
   int trans_bits;
   int trans_dec_factor;
+  int trans_prec_diff;
   set_default_gmparams(params);
   params->wmtype = type;
   switch (type) {
@@ -4415,26 +4417,39 @@
     case VERTRAPEZOID:
       if (type != HORTRAPEZOID)
         params->wmmat[6] =
-            aom_read_primitive_symmetric(r, GM_ABS_ROW3HOMO_BITS) *
+            aom_read_signed_primitive_refsubexpfin(
+                r, GM_ROW3HOMO_MAX + 1, SUBEXPFIN_K,
+                (ref_params->wmmat[6] >> GM_ROW3HOMO_PREC_DIFF)) *
             GM_ROW3HOMO_DECODE_FACTOR;
       if (type != VERTRAPEZOID)
         params->wmmat[7] =
-            aom_read_primitive_symmetric(r, GM_ABS_ROW3HOMO_BITS) *
+            aom_read_signed_primitive_refsubexpfin(
+                r, GM_ROW3HOMO_MAX + 1, SUBEXPFIN_K,
+                (ref_params->wmmat[7] >> GM_ROW3HOMO_PREC_DIFF)) *
             GM_ROW3HOMO_DECODE_FACTOR;
     case AFFINE:
     case ROTZOOM:
-      params->wmmat[2] = aom_read_primitive_symmetric(r, GM_ABS_ALPHA_BITS) *
+      params->wmmat[2] = aom_read_signed_primitive_refsubexpfin(
+                             r, GM_ALPHA_MAX + 1, SUBEXPFIN_K,
+                             (ref_params->wmmat[2] >> GM_ALPHA_PREC_DIFF) -
+                                 (1 << GM_ALPHA_PREC_BITS)) *
                              GM_ALPHA_DECODE_FACTOR +
                          (1 << WARPEDMODEL_PREC_BITS);
       if (type != VERTRAPEZOID)
-        params->wmmat[3] = aom_read_primitive_symmetric(r, GM_ABS_ALPHA_BITS) *
+        params->wmmat[3] = aom_read_signed_primitive_refsubexpfin(
+                               r, GM_ALPHA_MAX + 1, SUBEXPFIN_K,
+                               (ref_params->wmmat[3] >> GM_ALPHA_PREC_DIFF)) *
                            GM_ALPHA_DECODE_FACTOR;
       if (type >= AFFINE) {
         if (type != HORTRAPEZOID)
-          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) *
+          params->wmmat[4] = aom_read_signed_primitive_refsubexpfin(
+                                 r, GM_ALPHA_MAX + 1, SUBEXPFIN_K,
+                                 (ref_params->wmmat[4] >> GM_ALPHA_PREC_DIFF)) *
+                             GM_ALPHA_DECODE_FACTOR;
+        params->wmmat[5] = aom_read_signed_primitive_refsubexpfin(
+                               r, GM_ALPHA_MAX + 1, SUBEXPFIN_K,
+                               (ref_params->wmmat[5] >> GM_ALPHA_PREC_DIFF) -
+                                   (1 << GM_ALPHA_PREC_BITS)) *
                                GM_ALPHA_DECODE_FACTOR +
                            (1 << WARPEDMODEL_PREC_BITS);
       } else {
@@ -4448,11 +4463,17 @@
       trans_dec_factor = (type == TRANSLATION)
                              ? GM_TRANS_ONLY_DECODE_FACTOR * (1 << !allow_hp)
                              : GM_TRANS_DECODE_FACTOR;
-      params->wmmat[0] =
-          aom_read_primitive_symmetric(r, trans_bits) * trans_dec_factor;
-      params->wmmat[1] =
-          aom_read_primitive_symmetric(r, trans_bits) * trans_dec_factor;
-      break;
+      trans_prec_diff = (type == TRANSLATION)
+                            ? GM_TRANS_ONLY_PREC_DIFF + !allow_hp
+                            : GM_TRANS_PREC_DIFF;
+      params->wmmat[0] = aom_read_signed_primitive_refsubexpfin(
+                             r, (1 << trans_bits) + 1, SUBEXPFIN_K,
+                             (ref_params->wmmat[0] >> trans_prec_diff)) *
+                         trans_dec_factor;
+      params->wmmat[1] = aom_read_signed_primitive_refsubexpfin(
+                             r, (1 << trans_bits) + 1, SUBEXPFIN_K,
+                             (ref_params->wmmat[1] >> trans_prec_diff)) *
+                         trans_dec_factor;
     case IDENTITY: break;
     default: assert(0);
   }
@@ -4463,9 +4484,9 @@
 static void read_global_motion(AV1_COMMON *cm, aom_reader *r) {
   int frame;
   for (frame = LAST_FRAME; frame <= ALTREF_FRAME; ++frame) {
-    read_global_motion_params(&cm->global_motion[frame],
-                              cm->fc->global_motion_types_prob, r,
-                              cm->allow_high_precision_mv);
+    read_global_motion_params(
+        &cm->global_motion[frame], &cm->prev_frame->global_motion[frame],
+        cm->fc->global_motion_types_prob, r, cm->allow_high_precision_mv);
     /*
     printf("Dec Ref %d [%d/%d]: %d %d %d %d\n",
            frame, cm->current_video_frame, cm->show_frame,
@@ -4475,6 +4496,8 @@
            cm->global_motion[frame].wmmat[3]);
            */
   }
+  memcpy(cm->cur_frame->global_motion, cm->global_motion,
+         TOTAL_REFS_PER_FRAME * sizeof(WarpedMotionParams));
 }
 #endif  // CONFIG_GLOBAL_MOTION
 
@@ -4824,6 +4847,11 @@
   new_fb = get_frame_new_buffer(cm);
   xd->cur_buf = new_fb;
 #if CONFIG_GLOBAL_MOTION
+  int i;
+  for (i = LAST_FRAME; i <= ALTREF_FRAME; ++i) {
+    set_default_gmparams(&cm->global_motion[i]);
+    set_default_gmparams(&cm->cur_frame->global_motion[i]);
+  }
   xd->global_motion = cm->global_motion;
 #endif  // CONFIG_GLOBAL_MOTION
 
diff --git a/av1/encoder/bitstream.c b/av1/encoder/bitstream.c
index 382d5cc..8ebbedc 100644
--- a/av1/encoder/bitstream.c
+++ b/av1/encoder/bitstream.c
@@ -4598,6 +4598,7 @@
 
 #if CONFIG_GLOBAL_MOTION
 static void write_global_motion_params(WarpedMotionParams *params,
+                                       WarpedMotionParams *ref_params,
                                        aom_prob *probs, aom_writer *w,
                                        int allow_hp) {
   TransformationType type = params->wmtype;
@@ -4610,31 +4611,40 @@
     case HORTRAPEZOID:
     case VERTRAPEZOID:
       if (type != HORTRAPEZOID)
-        aom_write_primitive_symmetric(
-            w, (params->wmmat[6] >> GM_ROW3HOMO_PREC_DIFF),
-            GM_ABS_ROW3HOMO_BITS);
+        aom_write_signed_primitive_refsubexpfin(
+            w, GM_ROW3HOMO_MAX + 1, SUBEXPFIN_K,
+            (ref_params->wmmat[6] >> GM_ROW3HOMO_PREC_DIFF),
+            (params->wmmat[6] >> GM_ROW3HOMO_PREC_DIFF));
       if (type != VERTRAPEZOID)
-        aom_write_primitive_symmetric(
-            w, (params->wmmat[7] >> GM_ROW3HOMO_PREC_DIFF),
-            GM_ABS_ROW3HOMO_BITS);
+        aom_write_signed_primitive_refsubexpfin(
+            w, GM_ROW3HOMO_MAX + 1, SUBEXPFIN_K,
+            (ref_params->wmmat[7] >> GM_ROW3HOMO_PREC_DIFF),
+            (params->wmmat[7] >> GM_ROW3HOMO_PREC_DIFF));
     // fallthrough intended
     case AFFINE:
     case ROTZOOM:
-      aom_write_primitive_symmetric(
-          w,
-          (params->wmmat[2] >> GM_ALPHA_PREC_DIFF) - (1 << GM_ALPHA_PREC_BITS),
-          GM_ABS_ALPHA_BITS);
+      aom_write_signed_primitive_refsubexpfin(
+          w, GM_ALPHA_MAX + 1, SUBEXPFIN_K,
+          (ref_params->wmmat[2] >> GM_ALPHA_PREC_DIFF) -
+              (1 << GM_ALPHA_PREC_BITS),
+          (params->wmmat[2] >> GM_ALPHA_PREC_DIFF) - (1 << GM_ALPHA_PREC_BITS));
       if (type != VERTRAPEZOID)
-        aom_write_primitive_symmetric(
-            w, (params->wmmat[3] >> GM_ALPHA_PREC_DIFF), GM_ABS_ALPHA_BITS);
+        aom_write_signed_primitive_refsubexpfin(
+            w, GM_ALPHA_MAX + 1, SUBEXPFIN_K,
+            (ref_params->wmmat[3] >> GM_ALPHA_PREC_DIFF),
+            (params->wmmat[3] >> GM_ALPHA_PREC_DIFF));
       if (type >= AFFINE) {
         if (type != HORTRAPEZOID)
-          aom_write_primitive_symmetric(
-              w, (params->wmmat[4] >> GM_ALPHA_PREC_DIFF), GM_ABS_ALPHA_BITS);
-        aom_write_primitive_symmetric(w,
-                                      (params->wmmat[5] >> GM_ALPHA_PREC_DIFF) -
-                                          (1 << GM_ALPHA_PREC_BITS),
-                                      GM_ABS_ALPHA_BITS);
+          aom_write_signed_primitive_refsubexpfin(
+              w, GM_ALPHA_MAX + 1, SUBEXPFIN_K,
+              (ref_params->wmmat[4] >> GM_ALPHA_PREC_DIFF),
+              (params->wmmat[4] >> GM_ALPHA_PREC_DIFF));
+        aom_write_signed_primitive_refsubexpfin(
+            w, GM_ALPHA_MAX + 1, SUBEXPFIN_K,
+            (ref_params->wmmat[5] >> GM_ALPHA_PREC_DIFF) -
+                (1 << GM_ALPHA_PREC_BITS),
+            (params->wmmat[5] >> GM_ALPHA_PREC_DIFF) -
+                (1 << GM_ALPHA_PREC_BITS));
       }
     // fallthrough intended
     case TRANSLATION:
@@ -4643,10 +4653,14 @@
       trans_prec_diff = (type == TRANSLATION)
                             ? GM_TRANS_ONLY_PREC_DIFF + !allow_hp
                             : GM_TRANS_PREC_DIFF;
-      aom_write_primitive_symmetric(w, (params->wmmat[0] >> trans_prec_diff),
-                                    trans_bits);
-      aom_write_primitive_symmetric(w, (params->wmmat[1] >> trans_prec_diff),
-                                    trans_bits);
+      aom_write_signed_primitive_refsubexpfin(
+          w, (1 << trans_bits) + 1, SUBEXPFIN_K,
+          (ref_params->wmmat[0] >> trans_prec_diff),
+          (params->wmmat[0] >> trans_prec_diff));
+      aom_write_signed_primitive_refsubexpfin(
+          w, (1 << trans_bits) + 1, SUBEXPFIN_K,
+          (ref_params->wmmat[1] >> trans_prec_diff),
+          (params->wmmat[1] >> trans_prec_diff));
       break;
     case IDENTITY: break;
     default: assert(0);
@@ -4665,9 +4679,9 @@
       set_default_gmparams(&cm->global_motion[frame]);
     }
 #endif
-    write_global_motion_params(&cm->global_motion[frame],
-                               cm->fc->global_motion_types_prob, w,
-                               cm->allow_high_precision_mv);
+    write_global_motion_params(
+        &cm->global_motion[frame], &cm->prev_frame->global_motion[frame],
+        cm->fc->global_motion_types_prob, w, cm->allow_high_precision_mv);
     /*
     printf("Frame %d/%d: Enc Ref %d (used %d): %d %d %d %d\n",
            cm->current_video_frame, cm->show_frame, frame,
diff --git a/av1/encoder/encodeframe.c b/av1/encoder/encodeframe.c
index 1158dc9..3d77f6c 100644
--- a/av1/encoder/encodeframe.c
+++ b/av1/encoder/encodeframe.c
@@ -18,6 +18,7 @@
 #include "./aom_config.h"
 
 #include "aom_dsp/aom_dsp_common.h"
+#include "aom_dsp/binary_codes_writer.h"
 #include "aom_ports/mem.h"
 #include "aom_ports/aom_timer.h"
 #include "aom_ports/system_state.h"
@@ -5022,36 +5023,65 @@
 #endif
 
 #if CONFIG_GLOBAL_MOTION
-static int gm_get_params_cost(WarpedMotionParams *gm) {
+static int gm_get_params_cost(WarpedMotionParams *gm,
+                              WarpedMotionParams *ref_gm, int allow_hp) {
   assert(gm->wmtype < GLOBAL_TRANS_TYPES);
   int params_cost = 0;
+  int trans_bits, trans_prec_diff;
   switch (gm->wmtype) {
     case HOMOGRAPHY:
     case HORTRAPEZOID:
     case VERTRAPEZOID:
       if (gm->wmtype != HORTRAPEZOID)
-        params_cost += gm->wmmat[6] == 0 ? 1 : (GM_ABS_ROW3HOMO_BITS + 2);
+        params_cost += aom_count_signed_primitive_refsubexpfin(
+            GM_ROW3HOMO_MAX + 1, SUBEXPFIN_K,
+            (ref_gm->wmmat[6] >> GM_ROW3HOMO_PREC_DIFF),
+            (gm->wmmat[6] >> GM_ROW3HOMO_PREC_DIFF));
       if (gm->wmtype != VERTRAPEZOID)
-        params_cost += gm->wmmat[7] == 0 ? 1 : (GM_ABS_ROW3HOMO_BITS + 2);
+        params_cost += aom_count_signed_primitive_refsubexpfin(
+            GM_ROW3HOMO_MAX + 1, SUBEXPFIN_K,
+            (ref_gm->wmmat[7] >> GM_ROW3HOMO_PREC_DIFF),
+            (gm->wmmat[7] >> GM_ROW3HOMO_PREC_DIFF));
     // Fallthrough intended
     case AFFINE:
     case ROTZOOM:
-      params_cost += gm->wmmat[2] == (1 << WARPEDMODEL_PREC_BITS)
-                         ? 1
-                         : (GM_ABS_ALPHA_BITS + 2);
+      params_cost += aom_count_signed_primitive_refsubexpfin(
+          GM_ALPHA_MAX + 1, SUBEXPFIN_K,
+          (ref_gm->wmmat[2] >> GM_ALPHA_PREC_DIFF) - (1 << GM_ALPHA_PREC_BITS),
+          (gm->wmmat[2] >> GM_ALPHA_PREC_DIFF) - (1 << GM_ALPHA_PREC_BITS));
       if (gm->wmtype != VERTRAPEZOID)
-        params_cost += gm->wmmat[3] == 0 ? 1 : (GM_ABS_ALPHA_BITS + 2);
+        params_cost += aom_count_signed_primitive_refsubexpfin(
+            GM_ALPHA_MAX + 1, SUBEXPFIN_K,
+            (ref_gm->wmmat[3] >> GM_ALPHA_PREC_DIFF),
+            (gm->wmmat[3] >> GM_ALPHA_PREC_DIFF));
       if (gm->wmtype >= AFFINE) {
         if (gm->wmtype != HORTRAPEZOID)
-          params_cost += gm->wmmat[4] == 0 ? 1 : (GM_ABS_ALPHA_BITS + 2);
-        params_cost += gm->wmmat[5] == (1 << WARPEDMODEL_PREC_BITS)
-                           ? 1
-                           : (GM_ABS_ALPHA_BITS + 2);
+          params_cost += aom_count_signed_primitive_refsubexpfin(
+              GM_ALPHA_MAX + 1, SUBEXPFIN_K,
+              (ref_gm->wmmat[4] >> GM_ALPHA_PREC_DIFF),
+              (gm->wmmat[4] >> GM_ALPHA_PREC_DIFF));
+        params_cost += aom_count_signed_primitive_refsubexpfin(
+            GM_ALPHA_MAX + 1, SUBEXPFIN_K,
+            (ref_gm->wmmat[5] >> GM_ALPHA_PREC_DIFF) -
+                (1 << GM_ALPHA_PREC_BITS),
+            (gm->wmmat[5] >> GM_ALPHA_PREC_DIFF) - (1 << GM_ALPHA_PREC_BITS));
       }
     // Fallthrough intended
     case TRANSLATION:
-      params_cost += gm->wmmat[0] == 0 ? 1 : (GM_ABS_TRANS_BITS + 2);
-      params_cost += gm->wmmat[1] == 0 ? 1 : (GM_ABS_TRANS_BITS + 2);
+      trans_bits = (gm->wmtype == TRANSLATION)
+                       ? GM_ABS_TRANS_ONLY_BITS - !allow_hp
+                       : GM_ABS_TRANS_BITS;
+      trans_prec_diff = (gm->wmtype == TRANSLATION)
+                            ? GM_TRANS_ONLY_PREC_DIFF + !allow_hp
+                            : GM_TRANS_PREC_DIFF;
+      params_cost += aom_count_signed_primitive_refsubexpfin(
+          (1 << trans_bits) + 1, SUBEXPFIN_K,
+          (ref_gm->wmmat[0] >> trans_prec_diff),
+          (gm->wmmat[0] >> trans_prec_diff));
+      params_cost += aom_count_signed_primitive_refsubexpfin(
+          (1 << trans_bits) + 1, SUBEXPFIN_K,
+          (ref_gm->wmmat[1] >> trans_prec_diff),
+          (gm->wmmat[1] >> trans_prec_diff));
     // Fallthrough intended
     case IDENTITY: break;
     default: assert(0);
@@ -5170,12 +5200,16 @@
         aom_clear_system_state();
       }
       cpi->gmparams_cost[frame] =
-          gm_get_params_cost(&cm->global_motion[frame]) +
+          gm_get_params_cost(&cm->global_motion[frame],
+                             &cm->prev_frame->global_motion[frame],
+                             cm->allow_high_precision_mv) +
           cpi->gmtype_cost[cm->global_motion[frame].wmtype] -
           cpi->gmtype_cost[IDENTITY];
     }
     cpi->global_motion_search_done = 1;
   }
+  memcpy(cm->cur_frame->global_motion, cm->global_motion,
+         TOTAL_REFS_PER_FRAME * sizeof(WarpedMotionParams));
 #endif  // CONFIG_GLOBAL_MOTION
 
   for (i = 0; i < MAX_SEGMENTS; ++i) {