shithub: libvpx

Download patch

ref: ad0f0cbc0c227da5ce64864d2c3d63e4cd49a2b2
parent: 43cab8f4e84b5baadda093a5a204a746921f0ac0
author: Angie Chiang <angiebird@google.com>
date: Thu Jul 11 12:04:13 EDT 2019

Refactor exhaustive_mesh_search_new

Add the following two functions:
exhaustive_mesh_search_multi_step
exhaustive_mesh_search_single_step

Change-Id: I02fac56a815b091beab2203afce560d7d29aad44

--- a/vp9/encoder/vp9_mcomp.c
+++ b/vp9/encoder/vp9_mcomp.c
@@ -1923,89 +1923,98 @@
   return best_cost;
 }
 
-static int64_t exhaustive_mesh_search_new(const MACROBLOCK *x, MV *best_mv,
-                                          int range, int step,
-                                          const vp9_variance_fn_ptr_t *fn_ptr,
-                                          const MV *center_mv, int lambda,
-                                          const int_mv *nb_full_mvs,
-                                          int full_mv_num) {
-  const MACROBLOCKD *const xd = &x->e_mbd;
-  const struct buf_2d *const what = &x->plane[0].src;
-  const struct buf_2d *const in_what = &xd->plane[0].pre[0];
+static int64_t exhaustive_mesh_search_multi_step(
+    MV *best_mv, const MV *center_mv, int range, int step,
+    const struct buf_2d *src, const struct buf_2d *pre, int lambda,
+    const int_mv *nb_full_mvs, int full_mv_num, const MvLimits *mv_limits,
+    const vp9_variance_fn_ptr_t *fn_ptr) {
   int64_t best_sad;
+  int r, c;
+  int start_col, end_col, start_row, end_row;
+  *best_mv = *center_mv;
+  best_sad =
+      ((int64_t)fn_ptr->sdf(src->buf, src->stride,
+                            get_buf_from_mv(pre, center_mv), pre->stride)
+       << LOG2_PRECISION) +
+      lambda * vp9_nb_mvs_inconsistency(best_mv, nb_full_mvs, full_mv_num);
+  start_row = VPXMAX(center_mv->row - range, mv_limits->row_min);
+  start_col = VPXMAX(center_mv->col - range, mv_limits->col_min);
+  end_row = VPXMIN(center_mv->row + range, mv_limits->row_max);
+  end_col = VPXMIN(center_mv->col + range, mv_limits->col_max);
+  for (r = start_row; r <= end_row; r += step) {
+    for (c = start_col; c <= end_col; c += step) {
+      const MV mv = { r, c };
+      int64_t sad = (int64_t)fn_ptr->sdf(src->buf, src->stride,
+                                         get_buf_from_mv(pre, &mv), pre->stride)
+                    << LOG2_PRECISION;
+      if (sad < best_sad) {
+        sad += lambda * vp9_nb_mvs_inconsistency(&mv, nb_full_mvs, full_mv_num);
+        if (sad < best_sad) {
+          best_sad = sad;
+          *best_mv = mv;
+        }
+      }
+    }
+  }
+  return best_sad;
+}
+
+static int64_t exhaustive_mesh_search_single_step(
+    MV *best_mv, const MV *center_mv, int range, const struct buf_2d *src,
+    const struct buf_2d *pre, int lambda, const int_mv *nb_full_mvs,
+    int full_mv_num, const MvLimits *mv_limits,
+    const vp9_variance_fn_ptr_t *fn_ptr) {
+  int64_t best_sad;
   int r, c, i;
   int start_col, end_col, start_row, end_row;
-  int col_step = (step > 1) ? step : 4;
 
-  assert(step >= 1);
-  assert(is_mv_in(&x->mv_limits, center_mv));
-
   *best_mv = *center_mv;
   best_sad =
-      ((int64_t)fn_ptr->sdf(what->buf, what->stride,
-                            get_buf_from_mv(in_what, center_mv),
-                            in_what->stride)
+      ((int64_t)fn_ptr->sdf(src->buf, src->stride,
+                            get_buf_from_mv(pre, center_mv), pre->stride)
        << LOG2_PRECISION) +
       lambda * vp9_nb_mvs_inconsistency(best_mv, nb_full_mvs, full_mv_num);
-  start_row = VPXMAX(center_mv->row - range, x->mv_limits.row_min);
-  start_col = VPXMAX(center_mv->col - range, x->mv_limits.col_min);
-  end_row = VPXMIN(center_mv->row + range, x->mv_limits.row_max);
-  end_col = VPXMIN(center_mv->col + range, x->mv_limits.col_max);
+  start_row = VPXMAX(center_mv->row - range, mv_limits->row_min);
+  start_col = VPXMAX(center_mv->col - range, mv_limits->col_min);
+  end_row = VPXMIN(center_mv->row + range, mv_limits->row_max);
+  end_col = VPXMIN(center_mv->col + range, mv_limits->col_max);
+  for (r = start_row; r <= end_row; r += 1) {
+    for (c = start_col; c <= end_col; c += 4) {
+      // 4 sads in a single call if we are checking every location
+      if (c + 3 <= end_col) {
+        unsigned int sads[4];
+        const uint8_t *addrs[4];
+        for (i = 0; i < 4; ++i) {
+          const MV mv = { r, c + i };
+          addrs[i] = get_buf_from_mv(pre, &mv);
+        }
+        fn_ptr->sdx4df(src->buf, src->stride, addrs, pre->stride, sads);
 
-  for (r = start_row; r <= end_row; r += step) {
-    for (c = start_col; c <= end_col; c += col_step) {
-      // Step > 1 means we are not checking every location in this pass.
-      if (step > 1) {
-        const MV mv = { r, c };
-        int64_t sad =
-            (int64_t)fn_ptr->sdf(what->buf, what->stride,
-                                 get_buf_from_mv(in_what, &mv), in_what->stride)
-            << LOG2_PRECISION;
-        if (sad < best_sad) {
-          sad +=
-              lambda * vp9_nb_mvs_inconsistency(&mv, nb_full_mvs, full_mv_num);
+        for (i = 0; i < 4; ++i) {
+          int64_t sad = (int64_t)sads[i] << LOG2_PRECISION;
           if (sad < best_sad) {
-            best_sad = sad;
-            *best_mv = mv;
-          }
-        }
-      } else {
-        // 4 sads in a single call if we are checking every location
-        if (c + 3 <= end_col) {
-          unsigned int sads[4];
-          const uint8_t *addrs[4];
-          for (i = 0; i < 4; ++i) {
             const MV mv = { r, c + i };
-            addrs[i] = get_buf_from_mv(in_what, &mv);
-          }
-          fn_ptr->sdx4df(what->buf, what->stride, addrs, in_what->stride, sads);
-
-          for (i = 0; i < 4; ++i) {
-            int64_t sad = (int64_t)sads[i] << LOG2_PRECISION;
+            sad += lambda *
+                   vp9_nb_mvs_inconsistency(&mv, nb_full_mvs, full_mv_num);
             if (sad < best_sad) {
-              const MV mv = { r, c + i };
-              sad += lambda *
-                     vp9_nb_mvs_inconsistency(&mv, nb_full_mvs, full_mv_num);
-              if (sad < best_sad) {
-                best_sad = sad;
-                *best_mv = mv;
-              }
+              best_sad = sad;
+              *best_mv = mv;
             }
           }
-        } else {
-          for (i = 0; i < end_col - c; ++i) {
-            const MV mv = { r, c + i };
-            int64_t sad = (int64_t)fn_ptr->sdf(what->buf, what->stride,
-                                               get_buf_from_mv(in_what, &mv),
-                                               in_what->stride)
-                          << LOG2_PRECISION;
+        }
+      } else {
+        for (i = 0; i < end_col - c; ++i) {
+          const MV mv = { r, c + i };
+          int64_t sad =
+              (int64_t)fn_ptr->sdf(src->buf, src->stride,
+                                   get_buf_from_mv(pre, &mv), pre->stride)
+              << LOG2_PRECISION;
+          if (sad < best_sad) {
+            sad += lambda *
+                   vp9_nb_mvs_inconsistency(&mv, nb_full_mvs, full_mv_num);
             if (sad < best_sad) {
-              sad += lambda *
-                     vp9_nb_mvs_inconsistency(&mv, nb_full_mvs, full_mv_num);
-              if (sad < best_sad) {
-                best_sad = sad;
-                *best_mv = mv;
-              }
+              best_sad = sad;
+              *best_mv = mv;
             }
           }
         }
@@ -2012,8 +2021,28 @@
       }
     }
   }
-
   return best_sad;
+}
+
+static int64_t exhaustive_mesh_search_new(const MACROBLOCK *x, MV *best_mv,
+                                          int range, int step,
+                                          const vp9_variance_fn_ptr_t *fn_ptr,
+                                          const MV *center_mv, int lambda,
+                                          const int_mv *nb_full_mvs,
+                                          int full_mv_num) {
+  const MACROBLOCKD *const xd = &x->e_mbd;
+  const struct buf_2d *src = &x->plane[0].src;
+  const struct buf_2d *pre = &xd->plane[0].pre[0];
+  assert(step >= 1);
+  assert(is_mv_in(&x->mv_limits, center_mv));
+  if (step == 1) {
+    return exhaustive_mesh_search_single_step(
+        best_mv, center_mv, range, src, pre, lambda, nb_full_mvs, full_mv_num,
+        &x->mv_limits, fn_ptr);
+  }
+  return exhaustive_mesh_search_multi_step(best_mv, center_mv, range, step, src,
+                                           pre, lambda, nb_full_mvs,
+                                           full_mv_num, &x->mv_limits, fn_ptr);
 }
 
 static int64_t full_pixel_exhaustive_new(const VP9_COMP *cpi, MACROBLOCK *x,