Refactor global motion functions out of encodeframe

Change-Id: I76dd7365454206229e86cf5d942e89cff4a4a519
diff --git a/av1/encoder/encodeframe.c b/av1/encoder/encodeframe.c
index 7bd1ee1..d4d8526 100644
--- a/av1/encoder/encodeframe.c
+++ b/av1/encoder/encodeframe.c
@@ -4670,200 +4670,6 @@
 }
 #endif
 
-#if CONFIG_GLOBAL_MOTION
-#define MIN_TRANS_THRESH (1 * GM_TRANS_DECODE_FACTOR)
-
-// Border over which to compute the global motion
-#define ERRORADV_BORDER 0
-
-static const double gm_advantage_thresh[TRANS_TYPES] = {
-  1.00,  // Identity (not used)
-  0.85,  // Translation
-  0.75,  // Rot zoom
-  0.65,  // Affine
-  0.50,  // Homography
-};
-
-static void convert_to_params(const double *params, int32_t *model) {
-  int i;
-  int alpha_present = 0;
-  model[0] = (int32_t)floor(params[0] * (1 << GM_TRANS_PREC_BITS) + 0.5);
-  model[1] = (int32_t)floor(params[1] * (1 << GM_TRANS_PREC_BITS) + 0.5);
-  model[0] = (int32_t)clamp(model[0], GM_TRANS_MIN, GM_TRANS_MAX) *
-             GM_TRANS_DECODE_FACTOR;
-  model[1] = (int32_t)clamp(model[1], GM_TRANS_MIN, GM_TRANS_MAX) *
-             GM_TRANS_DECODE_FACTOR;
-
-  for (i = 2; i < 6; ++i) {
-    const int diag_value = ((i == 2 || i == 5) ? (1 << GM_ALPHA_PREC_BITS) : 0);
-    model[i] = (int32_t)floor(params[i] * (1 << GM_ALPHA_PREC_BITS) + 0.5);
-    model[i] =
-        (int32_t)clamp(model[i] - diag_value, GM_ALPHA_MIN, GM_ALPHA_MAX);
-    alpha_present |= (model[i] != 0);
-    model[i] = (model[i] + diag_value) * GM_ALPHA_DECODE_FACTOR;
-  }
-  for (; i < 8; ++i) {
-    model[i] = (int32_t)floor(params[i] * (1 << GM_ROW3HOMO_PREC_BITS) + 0.5);
-    model[i] = (int32_t)clamp(model[i], GM_ROW3HOMO_MIN, GM_ROW3HOMO_MAX) *
-               GM_ROW3HOMO_DECODE_FACTOR;
-    alpha_present |= (model[i] != 0);
-  }
-
-  if (!alpha_present) {
-    if (abs(model[0]) < MIN_TRANS_THRESH && abs(model[1]) < MIN_TRANS_THRESH) {
-      model[0] = 0;
-      model[1] = 0;
-    }
-  }
-}
-
-static void convert_model_to_params(const double *params,
-                                    WarpedMotionParams *model) {
-  convert_to_params(params, model->wmmat);
-  model->wmtype = get_gmtype(model);
-}
-
-// Adds some offset to a global motion parameter and handles
-// all of the necessary precision shifts, clamping, and
-// zero-centering.
-static int32_t add_param_offset(int param_index, int32_t param_value,
-                                int32_t offset) {
-  const int scale_vals[3] = { GM_TRANS_PREC_DIFF, GM_ALPHA_PREC_DIFF,
-                              GM_ROW3HOMO_PREC_DIFF };
-  const int clamp_vals[3] = { GM_TRANS_MAX, GM_ALPHA_MAX, GM_ROW3HOMO_MAX };
-  // type of param: 0 - translation, 1 - affine, 2 - homography
-  const int param_type = (param_index < 2 ? 0 : (param_index < 6 ? 1 : 2));
-  const int is_one_centered = (param_index == 2 || param_index == 5);
-
-  // Make parameter zero-centered and offset the shift that was done to make
-  // it compatible with the warped model
-  param_value = (param_value - (is_one_centered << WARPEDMODEL_PREC_BITS)) >>
-                scale_vals[param_type];
-  // Add desired offset to the rescaled/zero-centered parameter
-  param_value += offset;
-  // Clamp the parameter so it does not overflow the number of bits allotted
-  // to it in the bitstream
-  param_value = (int32_t)clamp(param_value, -clamp_vals[param_type],
-                               clamp_vals[param_type]);
-  // Rescale the parameter to WARPEDMODEL_PRECISION_BITS so it is compatible
-  // with the warped motion library
-  param_value *= (1 << scale_vals[param_type]);
-
-  // Undo the zero-centering step if necessary
-  return param_value + (is_one_centered << WARPEDMODEL_PREC_BITS);
-}
-
-static void force_wmtype(WarpedMotionParams *wm, TransformationType wmtype) {
-  switch (wmtype) {
-    case IDENTITY: wm->wmmat[0] = 0; wm->wmmat[1] = 0;
-    case TRANSLATION:
-      wm->wmmat[2] = 1 << WARPEDMODEL_PREC_BITS;
-      wm->wmmat[3] = 0;
-    case ROTZOOM: wm->wmmat[4] = -wm->wmmat[3]; wm->wmmat[5] = wm->wmmat[2];
-    case AFFINE: wm->wmmat[6] = wm->wmmat[7] = 0;
-    case HOMOGRAPHY: break;
-    default: assert(0);
-  }
-  wm->wmtype = wmtype;
-}
-
-static double refine_integerized_param(WarpedMotionParams *wm,
-                                       TransformationType wmtype,
-#if CONFIG_AOM_HIGHBITDEPTH
-                                       int use_hbd, int bd,
-#endif  // CONFIG_AOM_HIGHBITDEPTH
-                                       uint8_t *ref, int r_width, int r_height,
-                                       int r_stride, uint8_t *dst, int d_width,
-                                       int d_height, int d_stride,
-                                       int n_refinements) {
-  const int border = ERRORADV_BORDER;
-  int i = 0, p;
-  int n_params = n_trans_model_params[wmtype];
-  int32_t *param_mat = wm->wmmat;
-  double step_error;
-  int32_t step;
-  int32_t *param;
-  int32_t curr_param;
-  int32_t best_param;
-  double best_error;
-
-  force_wmtype(wm, wmtype);
-  best_error = av1_warp_erroradv(wm,
-#if CONFIG_AOM_HIGHBITDEPTH
-                                 use_hbd, bd,
-#endif  // CONFIG_AOM_HIGHBITDEPTH
-                                 ref, r_width, r_height, r_stride,
-                                 dst + border * d_stride + border, border,
-                                 border, d_width - 2 * border,
-                                 d_height - 2 * border, d_stride, 0, 0, 16, 16);
-  step = 1 << (n_refinements + 1);
-  for (i = 0; i < n_refinements; i++, step >>= 1) {
-    for (p = 0; p < n_params; ++p) {
-      int step_dir = 0;
-      param = param_mat + p;
-      curr_param = *param;
-      best_param = curr_param;
-      // look to the left
-      *param = add_param_offset(p, curr_param, -step);
-      step_error = av1_warp_erroradv(
-          wm,
-#if CONFIG_AOM_HIGHBITDEPTH
-          use_hbd, bd,
-#endif  // CONFIG_AOM_HIGHBITDEPTH
-          ref, r_width, r_height, r_stride, dst + border * d_stride + border,
-          border, border, d_width - 2 * border, d_height - 2 * border, d_stride,
-          0, 0, 16, 16);
-      if (step_error < best_error) {
-        best_error = step_error;
-        best_param = *param;
-        step_dir = -1;
-      }
-
-      // look to the right
-      *param = add_param_offset(p, curr_param, step);
-      step_error = av1_warp_erroradv(
-          wm,
-#if CONFIG_AOM_HIGHBITDEPTH
-          use_hbd, bd,
-#endif  // CONFIG_AOM_HIGHBITDEPTH
-          ref, r_width, r_height, r_stride, dst + border * d_stride + border,
-          border, border, d_width - 2 * border, d_height - 2 * border, d_stride,
-          0, 0, 16, 16);
-      if (step_error < best_error) {
-        best_error = step_error;
-        best_param = *param;
-        step_dir = 1;
-      }
-      *param = best_param;
-
-      // look to the direction chosen above repeatedly until error increases
-      // for the biggest step size
-      while (step_dir) {
-        *param = add_param_offset(p, best_param, step * step_dir);
-        step_error = av1_warp_erroradv(
-            wm,
-#if CONFIG_AOM_HIGHBITDEPTH
-            use_hbd, bd,
-#endif  // CONFIG_AOM_HIGHBITDEPTH
-            ref, r_width, r_height, r_stride, dst + border * d_stride + border,
-            border, border, d_width - 2 * border, d_height - 2 * border,
-            d_stride, 0, 0, 16, 16);
-        if (step_error < best_error) {
-          best_error = step_error;
-          best_param = *param;
-        } else {
-          *param = best_param;
-          step_dir = 0;
-        }
-      }
-    }
-  }
-  force_wmtype(wm, wmtype);
-  wm->wmtype = get_gmtype(wm);
-  return best_error;
-}
-#endif  // CONFIG_GLOBAL_MOTION
-
 static void encode_frame_internal(AV1_COMP *cpi) {
   ThreadData *const td = &cpi->td;
   MACROBLOCK *const x = &td->mb;
diff --git a/av1/encoder/global_motion.c b/av1/encoder/global_motion.c
index 9380bb7..526e897 100644
--- a/av1/encoder/global_motion.c
+++ b/av1/encoder/global_motion.c
@@ -18,7 +18,6 @@
 #include "av1/common/warped_motion.h"
 
 #include "av1/encoder/segmentation.h"
-#include "av1/encoder/global_motion.h"
 #include "av1/encoder/corner_detect.h"
 #include "av1/encoder/corner_match.h"
 #include "av1/encoder/ransac.h"
@@ -26,6 +25,187 @@
 #define MAX_CORNERS 4096
 #define MIN_INLIER_PROB 0.1
 
+#define MIN_TRANS_THRESH (1 * GM_TRANS_DECODE_FACTOR)
+
+// Border over which to compute the global motion
+#define ERRORADV_BORDER 0
+
+void convert_to_params(const double *params, int32_t *model) {
+  int i;
+  int alpha_present = 0;
+  model[0] = (int32_t)floor(params[0] * (1 << GM_TRANS_PREC_BITS) + 0.5);
+  model[1] = (int32_t)floor(params[1] * (1 << GM_TRANS_PREC_BITS) + 0.5);
+  model[0] = (int32_t)clamp(model[0], GM_TRANS_MIN, GM_TRANS_MAX) *
+             GM_TRANS_DECODE_FACTOR;
+  model[1] = (int32_t)clamp(model[1], GM_TRANS_MIN, GM_TRANS_MAX) *
+             GM_TRANS_DECODE_FACTOR;
+
+  for (i = 2; i < 6; ++i) {
+    const int diag_value = ((i == 2 || i == 5) ? (1 << GM_ALPHA_PREC_BITS) : 0);
+    model[i] = (int32_t)floor(params[i] * (1 << GM_ALPHA_PREC_BITS) + 0.5);
+    model[i] =
+        (int32_t)clamp(model[i] - diag_value, GM_ALPHA_MIN, GM_ALPHA_MAX);
+    alpha_present |= (model[i] != 0);
+    model[i] = (model[i] + diag_value) * GM_ALPHA_DECODE_FACTOR;
+  }
+  for (; i < 8; ++i) {
+    model[i] = (int32_t)floor(params[i] * (1 << GM_ROW3HOMO_PREC_BITS) + 0.5);
+    model[i] = (int32_t)clamp(model[i], GM_ROW3HOMO_MIN, GM_ROW3HOMO_MAX) *
+               GM_ROW3HOMO_DECODE_FACTOR;
+    alpha_present |= (model[i] != 0);
+  }
+
+  if (!alpha_present) {
+    if (abs(model[0]) < MIN_TRANS_THRESH && abs(model[1]) < MIN_TRANS_THRESH) {
+      model[0] = 0;
+      model[1] = 0;
+    }
+  }
+}
+
+void convert_model_to_params(const double *params, WarpedMotionParams *model) {
+  convert_to_params(params, model->wmmat);
+  model->wmtype = get_gmtype(model);
+}
+
+// Adds some offset to a global motion parameter and handles
+// all of the necessary precision shifts, clamping, and
+// zero-centering.
+int32_t add_param_offset(int param_index, int32_t param_value, int32_t offset) {
+  const int scale_vals[3] = { GM_TRANS_PREC_DIFF, GM_ALPHA_PREC_DIFF,
+                              GM_ROW3HOMO_PREC_DIFF };
+  const int clamp_vals[3] = { GM_TRANS_MAX, GM_ALPHA_MAX, GM_ROW3HOMO_MAX };
+  // type of param: 0 - translation, 1 - affine, 2 - homography
+  const int param_type = (param_index < 2 ? 0 : (param_index < 6 ? 1 : 2));
+  const int is_one_centered = (param_index == 2 || param_index == 5);
+
+  // Make parameter zero-centered and offset the shift that was done to make
+  // it compatible with the warped model
+  param_value = (param_value - (is_one_centered << WARPEDMODEL_PREC_BITS)) >>
+                scale_vals[param_type];
+  // Add desired offset to the rescaled/zero-centered parameter
+  param_value += offset;
+  // Clamp the parameter so it does not overflow the number of bits allotted
+  // to it in the bitstream
+  param_value = (int32_t)clamp(param_value, -clamp_vals[param_type],
+                               clamp_vals[param_type]);
+  // Rescale the parameter to WARPEDMODEL_PRECISION_BITS so it is compatible
+  // with the warped motion library
+  param_value *= (1 << scale_vals[param_type]);
+
+  // Undo the zero-centering step if necessary
+  return param_value + (is_one_centered << WARPEDMODEL_PREC_BITS);
+}
+
+void force_wmtype(WarpedMotionParams *wm, TransformationType wmtype) {
+  switch (wmtype) {
+    case IDENTITY: wm->wmmat[0] = 0; wm->wmmat[1] = 0;
+    case TRANSLATION:
+      wm->wmmat[2] = 1 << WARPEDMODEL_PREC_BITS;
+      wm->wmmat[3] = 0;
+    case ROTZOOM: wm->wmmat[4] = -wm->wmmat[3]; wm->wmmat[5] = wm->wmmat[2];
+    case AFFINE: wm->wmmat[6] = wm->wmmat[7] = 0;
+    case HOMOGRAPHY: break;
+    default: assert(0);
+  }
+  wm->wmtype = wmtype;
+}
+
+double refine_integerized_param(WarpedMotionParams *wm,
+                                TransformationType wmtype,
+#if CONFIG_AOM_HIGHBITDEPTH
+                                int use_hbd, int bd,
+#endif  // CONFIG_AOM_HIGHBITDEPTH
+                                uint8_t *ref, int r_width, int r_height,
+                                int r_stride, uint8_t *dst, int d_width,
+                                int d_height, int d_stride, int n_refinements) {
+  const int border = ERRORADV_BORDER;
+  int i = 0, p;
+  int n_params = n_trans_model_params[wmtype];
+  int32_t *param_mat = wm->wmmat;
+  double step_error;
+  int32_t step;
+  int32_t *param;
+  int32_t curr_param;
+  int32_t best_param;
+  double best_error;
+
+  force_wmtype(wm, wmtype);
+  best_error = av1_warp_erroradv(wm,
+#if CONFIG_AOM_HIGHBITDEPTH
+                                 use_hbd, bd,
+#endif  // CONFIG_AOM_HIGHBITDEPTH
+                                 ref, r_width, r_height, r_stride,
+                                 dst + border * d_stride + border, border,
+                                 border, d_width - 2 * border,
+                                 d_height - 2 * border, d_stride, 0, 0, 16, 16);
+  step = 1 << (n_refinements + 1);
+  for (i = 0; i < n_refinements; i++, step >>= 1) {
+    for (p = 0; p < n_params; ++p) {
+      int step_dir = 0;
+      param = param_mat + p;
+      curr_param = *param;
+      best_param = curr_param;
+      // look to the left
+      *param = add_param_offset(p, curr_param, -step);
+      step_error = av1_warp_erroradv(
+          wm,
+#if CONFIG_AOM_HIGHBITDEPTH
+          use_hbd, bd,
+#endif  // CONFIG_AOM_HIGHBITDEPTH
+          ref, r_width, r_height, r_stride, dst + border * d_stride + border,
+          border, border, d_width - 2 * border, d_height - 2 * border, d_stride,
+          0, 0, 16, 16);
+      if (step_error < best_error) {
+        best_error = step_error;
+        best_param = *param;
+        step_dir = -1;
+      }
+
+      // look to the right
+      *param = add_param_offset(p, curr_param, step);
+      step_error = av1_warp_erroradv(
+          wm,
+#if CONFIG_AOM_HIGHBITDEPTH
+          use_hbd, bd,
+#endif  // CONFIG_AOM_HIGHBITDEPTH
+          ref, r_width, r_height, r_stride, dst + border * d_stride + border,
+          border, border, d_width - 2 * border, d_height - 2 * border, d_stride,
+          0, 0, 16, 16);
+      if (step_error < best_error) {
+        best_error = step_error;
+        best_param = *param;
+        step_dir = 1;
+      }
+      *param = best_param;
+
+      // look to the direction chosen above repeatedly until error increases
+      // for the biggest step size
+      while (step_dir) {
+        *param = add_param_offset(p, best_param, step * step_dir);
+        step_error = av1_warp_erroradv(
+            wm,
+#if CONFIG_AOM_HIGHBITDEPTH
+            use_hbd, bd,
+#endif  // CONFIG_AOM_HIGHBITDEPTH
+            ref, r_width, r_height, r_stride, dst + border * d_stride + border,
+            border, border, d_width - 2 * border, d_height - 2 * border,
+            d_stride, 0, 0, 16, 16);
+        if (step_error < best_error) {
+          best_error = step_error;
+          best_param = *param;
+        } else {
+          *param = best_param;
+          step_dir = 0;
+        }
+      }
+    }
+  }
+  force_wmtype(wm, wmtype);
+  wm->wmtype = get_gmtype(wm);
+  return best_error;
+}
+
 static INLINE RansacFunc get_ransac_type(TransformationType type) {
   switch (type) {
     case HOMOGRAPHY: return ransac_homography;
diff --git a/av1/encoder/global_motion.h b/av1/encoder/global_motion.h
index ef04a23..1f9b5a2 100644
--- a/av1/encoder/global_motion.h
+++ b/av1/encoder/global_motion.h
@@ -18,6 +18,34 @@
 extern "C" {
 #endif
 
+const double gm_advantage_thresh[TRANS_TYPES] = {
+  1.00,  // Identity (not used)
+  0.85,  // Translation
+  0.75,  // Rot zoom
+  0.65,  // Affine
+  0.50,  // Homography
+};
+
+void convert_to_params(const double *params, int32_t *model);
+
+void convert_model_to_params(const double *params, WarpedMotionParams *model);
+
+// Adds some offset to a global motion parameter and handles
+// all of the necessary precision shifts, clamping, and
+// zero-centering.
+int32_t add_param_offset(int param_index, int32_t param_value, int32_t offset);
+
+void force_wmtype(WarpedMotionParams *wm, TransformationType wmtype);
+
+double refine_integerized_param(WarpedMotionParams *wm,
+                                TransformationType wmtype,
+#if CONFIG_AOM_HIGHBITDEPTH
+                                int use_hbd, int bd,
+#endif  // CONFIG_AOM_HIGHBITDEPTH
+                                uint8_t *ref, int r_width, int r_height,
+                                int r_stride, uint8_t *dst, int d_width,
+                                int d_height, int d_stride, int n_refinements);
+
 /*
   Computes global motion parameters between two frames. The array
   "params" should be length 9, where the first 2 slots are translation