Split current block samples for warp estimation

Change-Id: Iebc74024475c7cb88650b65df9f23b1a5e70021c
diff --git a/av1/common/mvref_common.c b/av1/common/mvref_common.c
index b5881a6..9e8f181 100644
--- a/av1/common/mvref_common.c
+++ b/av1/common/mvref_common.c
@@ -1224,37 +1224,8 @@
 
   if (np == 0) {
     return 0;
-  } else {
-    MODE_INFO *mi = xd->mi[0];
-    MB_MODE_INFO *mbmi = &mi->mbmi;
-    int bw = block_size_wide[mbmi->sb_type];
-    int bh = block_size_high[mbmi->sb_type];
-    int mv_row = mbmi->mv[0].as_mv.row;
-    int mv_col = mbmi->mv[0].as_mv.col;
-    int cr_offset = AOMMAX(bh, MI_SIZE) / 2 - 1;
-    int cc_offset = AOMMAX(bw, MI_SIZE) / 2 - 1;
-    int j;
-    int pixelperblock = SAMPLES_PER_NEIGHBOR;
-
-    for (j = 0; j < pixelperblock; j++) {
-      int r_offset = j / 2;
-      int c_offset = j % 2;
-
-      int x = (cc_offset + c_offset + global_offset_c);
-      int y = (cr_offset + r_offset + global_offset_r);
-
-      pts[0] = (x * 8);
-      pts[1] = (y * 8);
-      pts_inref[0] = pts[0] + mv_col;
-      pts_inref[1] = pts[1] + mv_row;
-
-      pts += 2;
-      pts_inref += 2;
-    }
-    np += pixelperblock;
   }
   assert(2 * np <= SAMPLES_ARRAY_SIZE);
-
   return np;
 }
 #endif  // CONFIG_WARPED_MOTION
diff --git a/av1/common/warped_motion.c b/av1/common/warped_motion.c
index a25e9e6..aeba546 100644
--- a/av1/common/warped_motion.c
+++ b/av1/common/warped_motion.c
@@ -1307,8 +1307,9 @@
 #define IDET_WARPEDMODEL_DIFF_BITS (IDET_PREC_BITS - WARPEDMODEL_PREC_BITS)
 #endif  // APPROXIMATE_DIVISOR
 
-static int find_affine_int(const int np, int *pts1, int *pts2,
-                           WarpedMotionParams *wm, int mi_row, int mi_col) {
+static int find_affine_int(const int np, int *pts1, int *pts2, BLOCK_SIZE bsize,
+                           int mvy, int mvx, WarpedMotionParams *wm, int mi_row,
+                           int mi_col) {
   int32_t A[3][3] = { { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 } };
   int32_t Bx[3] = { 0, 0, 0 };
   int32_t By[3] = { 0, 0, 0 };
@@ -1317,6 +1318,10 @@
   int64_t C00, C01, C02, C11, C12, C22;
   int64_t Px[3], Py[3];
   int64_t Det, v;
+  const int bw = block_size_wide[bsize];
+  const int bh = block_size_high[bsize];
+  const int cy_offset = AOMMAX(bh, MI_SIZE) / 2 - 1;
+  const int cx_offset = AOMMAX(bw, MI_SIZE) / 2 - 1;
 
   // Offsets to make the values in the arrays smaller
   const int ux = mi_col * MI_SIZE * 8, uy = mi_row * MI_SIZE * 8;
@@ -1340,15 +1345,16 @@
   // We need to just compute inv(A).Bx and inv(A).By for the solutions.
   //
   for (j = 0; j < SAMPLES_PER_NEIGHBOR && n < LEAST_SQUARES_SAMPLES_MAX; ++j) {
-    for (i = j; i < np && n < LEAST_SQUARES_SAMPLES_MAX;
-         i += SAMPLES_PER_NEIGHBOR) {
-      const int dx = pts2[i * 2] - ux;
-      const int dy = pts2[i * 2 + 1] - uy;
-      const int sx = pts1[i * 2] - ux;
-      const int sy = pts1[i * 2 + 1] - uy;
-      if (abs(sx - dx) >= LEAST_SQUARES_MV_MAX ||
-          abs(sy - dy) >= LEAST_SQUARES_MV_MAX)
-        continue;
+    // Contribution from sample in current block
+    const int y_offset = j >> 1;
+    const int x_offset = j & 1;
+    int sx, sy, dx, dy;
+    sx = (cx_offset + x_offset) * 8;
+    sy = (cy_offset + y_offset) * 8;
+    dx = sx + mvx;
+    dy = sy + mvy;
+    if (abs(sx - dx) < LEAST_SQUARES_MV_MAX &&
+        abs(sy - dy) < LEAST_SQUARES_MV_MAX) {
       A[0][0] += sx * sx;
       A[0][1] += sx * sy;
       A[0][2] += sx;
@@ -1363,6 +1369,30 @@
       By[2] += dy;
       n++;
     }
+    // Contribution from neighbor block
+    for (i = j; i < np && n < LEAST_SQUARES_SAMPLES_MAX;
+         i += SAMPLES_PER_NEIGHBOR) {
+      dx = pts2[i * 2] - ux;
+      dy = pts2[i * 2 + 1] - uy;
+      sx = pts1[i * 2] - ux;
+      sy = pts1[i * 2 + 1] - uy;
+      if (abs(sx - dx) < LEAST_SQUARES_MV_MAX &&
+          abs(sy - dy) < LEAST_SQUARES_MV_MAX) {
+        A[0][0] += sx * sx;
+        A[0][1] += sx * sy;
+        A[0][2] += sx;
+        A[1][1] += sy * sy;
+        A[1][2] += sy;
+        A[2][2] += 1;
+        Bx[0] += sx * dx;
+        Bx[1] += sy * dx;
+        Bx[2] += dx;
+        By[0] += sx * dy;
+        By[1] += sy * dy;
+        By[2] += dy;
+        n++;
+      }
+    }
   }
   // Compute Cofactors of A
   C00 = (int64_t)A[1][1] * A[2][2] - (int64_t)A[1][2] * A[1][2];
@@ -1431,12 +1461,14 @@
   return 0;
 }
 
-int find_projection(const int np, int *pts1, int *pts2,
-                    WarpedMotionParams *wm_params, int mi_row, int mi_col) {
+int find_projection(const int np, int *pts1, int *pts2, BLOCK_SIZE bsize,
+                    int mvy, int mvx, WarpedMotionParams *wm_params, int mi_row,
+                    int mi_col) {
   int result = 1;
   switch (wm_params->wmtype) {
     case AFFINE:
-      result = find_affine_int(np, pts1, pts2, wm_params, mi_row, mi_col);
+      result = find_affine_int(np, pts1, pts2, bsize, mvy, mvx, wm_params,
+                               mi_row, mi_col);
       break;
     default: assert(0 && "Invalid warped motion type!"); return 1;
   }
diff --git a/av1/common/warped_motion.h b/av1/common/warped_motion.h
index 4ac7f2c..4528288 100644
--- a/av1/common/warped_motion.h
+++ b/av1/common/warped_motion.h
@@ -86,6 +86,7 @@
                     int p_height, int p_stride, int subsampling_x,
                     int subsampling_y, int x_scale, int y_scale, int ref_frm);
 
-int find_projection(const int np, int *pts1, int *pts2,
-                    WarpedMotionParams *wm_params, int mi_row, int mi_col);
+int find_projection(const int np, int *pts1, int *pts2, BLOCK_SIZE bsize,
+                    int mvy, int mvx, WarpedMotionParams *wm_params, int mi_row,
+                    int mi_col);
 #endif  // AV1_COMMON_WARPED_MOTION_H_
diff --git a/av1/decoder/decodemv.c b/av1/decoder/decodemv.c
index cc7922a..c997068 100644
--- a/av1/decoder/decodemv.c
+++ b/av1/decoder/decodemv.c
@@ -2030,7 +2030,8 @@
 #if CONFIG_WARPED_MOTION
     if (mbmi->motion_mode == WARPED_CAUSAL) {
       mbmi->wm_params[0].wmtype = DEFAULT_WMTYPE;
-      find_projection(mbmi->num_proj_ref[0], pts, pts_inref,
+      find_projection(mbmi->num_proj_ref[0], pts, pts_inref, bsize,
+                      mbmi->mv[0].as_mv.row, mbmi->mv[0].as_mv.col,
                       &mbmi->wm_params[0], mi_row, mi_col);
     }
 #endif  // CONFIG_WARPED_MOTION
diff --git a/av1/encoder/rdopt.c b/av1/encoder/rdopt.c
index a5bc755..e3843a5 100644
--- a/av1/encoder/rdopt.c
+++ b/av1/encoder/rdopt.c
@@ -8444,7 +8444,8 @@
                                                             : cm->interp_filter;
 #endif  // CONFIG_DUAL_FILTER
 
-      if (find_projection(mbmi->num_proj_ref[0], pts, pts_inref,
+      if (find_projection(mbmi->num_proj_ref[0], pts, pts_inref, bsize,
+                          mbmi->mv[0].as_mv.row, mbmi->mv[0].as_mv.col,
                           &mbmi->wm_params[0], mi_row, mi_col) == 0) {
         int plane;
         for (plane = 0; plane < 3; ++plane) {