Compute source frame feature points outside of the ref loop

No change in psnr, 0.5% speedup.

Change-Id: I02ec36c22acd78f2de8b997e997516372837ef57
diff --git a/av1/encoder/encodeframe.c b/av1/encoder/encodeframe.c
index 71e8f6a..18cb98c 100644
--- a/av1/encoder/encodeframe.c
+++ b/av1/encoder/encodeframe.c
@@ -47,6 +47,7 @@
 #include "av1/encoder/aq_complexity.h"
 #include "av1/encoder/aq_cyclicrefresh.h"
 #include "av1/encoder/aq_variance.h"
+#include "av1/encoder/corner_detect.h"
 #include "av1/encoder/global_motion.h"
 #include "av1/encoder/encodeframe.h"
 #include "av1/encoder/encodemb.h"
@@ -5005,7 +5006,19 @@
     };
     // clang-format on
     int num_refs_using_gm = 0;
-
+    int num_frm_corners;
+    int frm_corners[2 * MAX_CORNERS];
+    unsigned char *frm_buffer = cpi->source->y_buffer;
+    if (cpi->source->flags & YV12_FLAG_HIGHBITDEPTH) {
+      // The frame buffer is 16-bit, so we need to convert to 8 bits for the
+      // following code. We cache the result until the frame is released.
+      frm_buffer =
+          downconvert_frame(cpi->source, cpi->common.seq_params.bit_depth);
+    }
+    // compute interest points using FAST features
+    num_frm_corners = fast_corner_detect(
+        frm_buffer, cpi->source->y_width, cpi->source->y_height,
+        cpi->source->y_stride, frm_corners, MAX_CORNERS);
     for (frame = ALTREF_FRAME; frame >= LAST_FRAME; --frame) {
       ref_buf[frame] = NULL;
       RefCntBuffer *buf = get_ref_frame_buf(cm, frame);
@@ -5056,10 +5069,12 @@
                    (MAX_PARAMDIM - 1) * sizeof(*params_by_motion));
           }
 
-          av1_compute_global_motion(model, cpi->source, ref_buf[frame],
-                                    cpi->common.seq_params.bit_depth,
-                                    gm_estimation_type, inliers_by_motion,
-                                    params_by_motion, RANSAC_NUM_MOTIONS);
+          av1_compute_global_motion(
+              model, frm_buffer, cpi->source->y_width, cpi->source->y_height,
+              cpi->source->y_stride, frm_corners, num_frm_corners,
+              ref_buf[frame], cpi->common.seq_params.bit_depth,
+              gm_estimation_type, inliers_by_motion, params_by_motion,
+              RANSAC_NUM_MOTIONS);
 
           for (i = 0; i < RANSAC_NUM_MOTIONS; ++i) {
             if (inliers_by_motion[i] == 0) continue;
diff --git a/av1/encoder/global_motion.c b/av1/encoder/global_motion.c
index b8b13c3..8921a53 100644
--- a/av1/encoder/global_motion.c
+++ b/av1/encoder/global_motion.c
@@ -28,7 +28,6 @@
 #include "av1/encoder/corner_match.h"
 #include "av1/encoder/ransac.h"
 
-#define MAX_CORNERS 4096
 #define MIN_INLIER_PROB 0.1
 
 #define MIN_TRANS_THRESH (1 * GM_TRANS_DECODE_FACTOR)
@@ -257,8 +256,7 @@
   }
 }
 
-static unsigned char *downconvert_frame(YV12_BUFFER_CONFIG *frm,
-                                        int bit_depth) {
+unsigned char *downconvert_frame(YV12_BUFFER_CONFIG *frm, int bit_depth) {
   int i, j;
   uint16_t *orig_buf = CONVERT_TO_SHORTPTR(frm->y_buffer);
   uint8_t *buf_8bit = frm->y_buffer_8bit;
@@ -276,30 +274,22 @@
 }
 
 static int compute_global_motion_feature_based(
-    TransformationType type, YV12_BUFFER_CONFIG *frm, YV12_BUFFER_CONFIG *ref,
-    int bit_depth, int *num_inliers_by_motion, double *params_by_motion,
-    int num_motions) {
+    TransformationType type, unsigned char *frm_buffer, int frm_width,
+    int frm_height, int frm_stride, int *frm_corners, int num_frm_corners,
+    YV12_BUFFER_CONFIG *ref, int bit_depth, int *num_inliers_by_motion,
+    double *params_by_motion, int num_motions) {
   int i;
-  int num_frm_corners, num_ref_corners;
+  int num_ref_corners;
   int num_correspondences;
   int *correspondences;
-  int frm_corners[2 * MAX_CORNERS], ref_corners[2 * MAX_CORNERS];
-  unsigned char *frm_buffer = frm->y_buffer;
+  int ref_corners[2 * MAX_CORNERS];
   unsigned char *ref_buffer = ref->y_buffer;
   RansacFunc ransac = get_ransac_type(type);
 
-  if (frm->flags & YV12_FLAG_HIGHBITDEPTH) {
-    // The frame buffer is 16-bit, so we need to convert to 8 bits for the
-    // following code. We cache the result until the frame is released.
-    frm_buffer = downconvert_frame(frm, bit_depth);
-  }
   if (ref->flags & YV12_FLAG_HIGHBITDEPTH) {
     ref_buffer = downconvert_frame(ref, bit_depth);
   }
 
-  // compute interest points in images using FAST features
-  num_frm_corners = fast_corner_detect(frm_buffer, frm->y_width, frm->y_height,
-                                       frm->y_stride, frm_corners, MAX_CORNERS);
   num_ref_corners = fast_corner_detect(ref_buffer, ref->y_width, ref->y_height,
                                        ref->y_stride, ref_corners, MAX_CORNERS);
 
@@ -308,8 +298,8 @@
       (int *)malloc(num_frm_corners * 4 * sizeof(*correspondences));
   num_correspondences = determine_correspondence(
       frm_buffer, (int *)frm_corners, num_frm_corners, ref_buffer,
-      (int *)ref_corners, num_ref_corners, frm->y_width, frm->y_height,
-      frm->y_stride, ref->y_stride, correspondences);
+      (int *)ref_corners, num_ref_corners, frm_width, frm_height, frm_stride,
+      ref->y_stride, correspondences);
 
   ransac(correspondences, num_correspondences, num_inliers_by_motion,
          params_by_motion, num_motions);
@@ -777,20 +767,16 @@
 }
 
 static int compute_global_motion_disflow_based(
-    TransformationType type, YV12_BUFFER_CONFIG *frm, YV12_BUFFER_CONFIG *ref,
-    int bit_depth, int *num_inliers_by_motion, double *params_by_motion,
-    int num_motions) {
-  unsigned char *frm_buffer = frm->y_buffer;
+    TransformationType type, unsigned char *frm_buffer, int frm_width,
+    int frm_height, int frm_stride, int *frm_corners, int num_frm_corners,
+    YV12_BUFFER_CONFIG *ref, int bit_depth, int *num_inliers_by_motion,
+    double *params_by_motion, int num_motions) {
   unsigned char *ref_buffer = ref->y_buffer;
-  const int frm_width = frm->y_width;
-  const int frm_height = frm->y_height;
   const int ref_width = ref->y_width;
   const int ref_height = ref->y_height;
   const int pad_size = AOMMAX(PATCH_SIZE, MIN_PAD);
-  int num_frm_corners;
   int num_correspondences;
   double *correspondences;
-  int frm_corners[2 * MAX_CORNERS];
   RansacFuncDouble ransac = get_ransac_double_prec_type(type);
   assert(frm_width == ref_width);
   assert(frm_height == ref_height);
@@ -800,11 +786,6 @@
       frm_width < frm_height ? get_msb(frm_width) : get_msb(frm_height);
   const int n_levels = AOMMIN(msb, N_LEVELS);
 
-  if (frm->flags & YV12_FLAG_HIGHBITDEPTH) {
-    // The frame buffer is 16-bit, so we need to convert to 8 bits for the
-    // following code. We cache the result until the frame is released.
-    frm_buffer = downconvert_frame(frm, bit_depth);
-  }
   if (ref->flags & YV12_FLAG_HIGHBITDEPTH) {
     ref_buffer = downconvert_frame(ref, bit_depth);
   }
@@ -819,8 +800,8 @@
   int compute_gradient = 1;
   ImagePyramid *frm_pyr =
       alloc_pyramid(frm_width, frm_height, pad_size, compute_gradient);
-  compute_flow_pyramids(frm_buffer, frm_width, frm_height, frm->y_stride,
-                        n_levels, pad_size, compute_gradient, frm_pyr);
+  compute_flow_pyramids(frm_buffer, frm_width, frm_height, frm_stride, n_levels,
+                        pad_size, compute_gradient, frm_pyr);
   // Allocate ref image pyramids
   compute_gradient = 0;
   ImagePyramid *ref_pyr =
@@ -840,9 +821,6 @@
 
   compute_flow_field(frm_pyr, ref_pyr, flow_u, flow_v);
 
-  // compute interest points in images using FAST features
-  num_frm_corners = fast_corner_detect(frm_buffer, frm_width, frm_height,
-                                       frm->y_stride, frm_corners, MAX_CORNERS);
   // find correspondences between the two images using the flow field
   correspondences = aom_malloc(num_frm_corners * 4 * sizeof(*correspondences));
   num_correspondences = determine_disflow_correspondence(
@@ -870,20 +848,25 @@
   return 0;
 }
 
-int av1_compute_global_motion(TransformationType type, YV12_BUFFER_CONFIG *frm,
-                              YV12_BUFFER_CONFIG *ref, int bit_depth,
+int av1_compute_global_motion(TransformationType type,
+                              unsigned char *frm_buffer, int frm_width,
+                              int frm_height, int frm_stride, int *frm_corners,
+                              int num_frm_corners, YV12_BUFFER_CONFIG *ref,
+                              int bit_depth,
                               GlobalMotionEstimationType gm_estimation_type,
                               int *num_inliers_by_motion,
                               double *params_by_motion, int num_motions) {
   switch (gm_estimation_type) {
     case GLOBAL_MOTION_FEATURE_BASED:
-      return compute_global_motion_feature_based(type, frm, ref, bit_depth,
-                                                 num_inliers_by_motion,
-                                                 params_by_motion, num_motions);
+      return compute_global_motion_feature_based(
+          type, frm_buffer, frm_width, frm_height, frm_stride, frm_corners,
+          num_frm_corners, ref, bit_depth, num_inliers_by_motion,
+          params_by_motion, num_motions);
     case GLOBAL_MOTION_DISFLOW_BASED:
-      return compute_global_motion_disflow_based(type, frm, ref, bit_depth,
-                                                 num_inliers_by_motion,
-                                                 params_by_motion, num_motions);
+      return compute_global_motion_disflow_based(
+          type, frm_buffer, frm_width, frm_height, frm_stride, frm_corners,
+          num_frm_corners, ref, bit_depth, num_inliers_by_motion,
+          params_by_motion, num_motions);
     default: assert(0 && "Unknown global motion estimation type");
   }
   return 0;
diff --git a/av1/encoder/global_motion.h b/av1/encoder/global_motion.h
index 2cfddad..1e498a7 100644
--- a/av1/encoder/global_motion.h
+++ b/av1/encoder/global_motion.h
@@ -20,6 +20,7 @@
 extern "C" {
 #endif
 
+#define MAX_CORNERS 4096
 #define RANSAC_NUM_MOTIONS 1
 
 typedef enum {
@@ -27,6 +28,8 @@
   GLOBAL_MOTION_DISFLOW_BASED,
 } GlobalMotionEstimationType;
 
+unsigned char *downconvert_frame(YV12_BUFFER_CONFIG *frm, int bit_depth);
+
 void av1_convert_model_to_params(const double *params,
                                  WarpedMotionParams *model);
 
@@ -59,8 +62,11 @@
   number of inlier feature points for each motion. Params for which the
   num_inliers entry is 0 should be ignored by the caller.
 */
-int av1_compute_global_motion(TransformationType type, YV12_BUFFER_CONFIG *frm,
-                              YV12_BUFFER_CONFIG *ref, int bit_depth,
+int av1_compute_global_motion(TransformationType type,
+                              unsigned char *frm_buffer, int frm_width,
+                              int frm_height, int frm_stride, int *frm_corners,
+                              int num_frm_corners, YV12_BUFFER_CONFIG *ref,
+                              int bit_depth,
                               GlobalMotionEstimationType gm_estimation_type,
                               int *num_inliers_by_motion,
                               double *params_by_motion, int num_motions);