shithub: libvpx

Download patch

ref: a46bb83e0c0d9592a20e000e843f36c117c96f13
parent: 64c4cedd3a93549b2a9c490734a76c9a28542934
parent: dcea8785ad76c477838a2a0cf0bb7b47ea71c356
author: Angie Chiang <angiebird@google.com>
date: Fri Dec 7 17:27:11 EST 2018

Merge changes Id10f72b3,Icde1b01e,I391aa322

* changes:
  Implement find_prev_nb_full_mvs
  Implement get_full_mv()
  Pass mv_num into vp9_nb_mvs_inconsistency()

--- a/vp9/encoder/vp9_encoder.c
+++ b/vp9/encoder/vp9_encoder.c
@@ -5598,8 +5598,7 @@
           &tpl_frame
                ->tpl_stats_ptr[(mi_row + r) * tpl_frame->stride + mi_col + c];
       if (tpl_ptr->ready[rf_idx]) {
-        nb_full_mvs[i].as_mv.row = tpl_ptr->mv_arr[rf_idx].as_mv.row >> 3;
-        nb_full_mvs[i].as_mv.col = tpl_ptr->mv_arr[rf_idx].as_mv.col >> 3;
+        nb_full_mvs[i].as_mv = get_full_mv(&tpl_ptr->mv_arr[rf_idx].as_mv);
       } else {
         nb_full_mvs[i].as_int = INVALID_MV;
       }
@@ -5666,7 +5665,7 @@
                       nb_full_mvs);
   vp9_full_pixel_diamond_new(
       cpi, x, &best_ref_mv1_full, step_param, lambda, 1, &cpi->fn_ptr[bsize],
-      nb_full_mvs, &tpl_stats->mv_arr[rf_idx].as_mv,
+      nb_full_mvs, NB_MVS_NUM, &tpl_stats->mv_arr[rf_idx].as_mv,
       &tpl_stats->mv_dist[rf_idx], &tpl_stats->mv_cost[rf_idx]);
 #else
   (void)frame_idx;
@@ -6361,7 +6360,7 @@
           full_mv.row = this_tpl_stats->mv_arr[rf_idx].as_mv.row >> 3;
           full_mv.col = this_tpl_stats->mv_arr[rf_idx].as_mv.col >> 3;
           this_tpl_stats->mv_cost[rf_idx] =
-              av1_nb_mvs_inconsistency(&full_mv, nb_full_mvs);
+              vp9_nb_mvs_inconsistency(&full_mv, nb_full_mvs, NB_MVS_NUM);
 #endif  // RE_COMPUTE_MV_INCONSISTENCY
           tpl_frame->mv_dist_sum[rf_idx] += this_tpl_stats->mv_dist[rf_idx];
           tpl_frame->mv_cost_sum[rf_idx] += this_tpl_stats->mv_cost[rf_idx];
--- a/vp9/encoder/vp9_mcomp.c
+++ b/vp9/encoder/vp9_mcomp.c
@@ -1733,12 +1733,13 @@
 }
 
 #if CONFIG_NON_GREEDY_MV
-double av1_nb_mvs_inconsistency(const MV *mv, const int_mv *nb_mvs) {
+double vp9_nb_mvs_inconsistency(const MV *mv, const int_mv *nb_mvs,
+                                int mv_num) {
   int i;
   int update = 0;
   double best_cost = 0;
   vpx_clear_system_state();
-  for (i = 0; i < NB_MVS_NUM; ++i) {
+  for (i = 0; i < mv_num; ++i) {
     if (nb_mvs[i].as_int != INVALID_MV) {
       MV nb_mv = nb_mvs[i].as_mv;
       const double row_diff = mv->row - nb_mv.row;
@@ -1762,7 +1763,7 @@
                                   double *best_mv_dist, double *best_mv_cost,
                                   int search_param, double lambda, int *num00,
                                   const vp9_variance_fn_ptr_t *fn_ptr,
-                                  const int_mv *nb_full_mvs) {
+                                  const int_mv *nb_full_mvs, int full_mv_num) {
   int i, j, step;
 
   const MACROBLOCKD *const xd = &x->e_mbd;
@@ -1799,7 +1800,8 @@
 
   // Check the starting position
   *best_mv_dist = fn_ptr->sdf(what, what_stride, in_what, in_what_stride);
-  *best_mv_cost = av1_nb_mvs_inconsistency(best_full_mv, nb_full_mvs);
+  *best_mv_cost =
+      vp9_nb_mvs_inconsistency(best_full_mv, nb_full_mvs, full_mv_num);
   bestsad = (*best_mv_dist) + lambda * (*best_mv_cost);
 
   i = 0;
@@ -1833,7 +1835,7 @@
                                best_full_mv->col + ss_mv[i].col };
           const double mv_dist = sad_array[t];
           const double mv_cost =
-              av1_nb_mvs_inconsistency(&this_mv, nb_full_mvs);
+              vp9_nb_mvs_inconsistency(&this_mv, nb_full_mvs, full_mv_num);
           double thissad = mv_dist + lambda * mv_cost;
           if (thissad < bestsad) {
             bestsad = thissad;
@@ -1854,7 +1856,7 @@
           const double mv_dist =
               fn_ptr->sdf(what, what_stride, check_here, in_what_stride);
           const double mv_cost =
-              av1_nb_mvs_inconsistency(&this_mv, nb_full_mvs);
+              vp9_nb_mvs_inconsistency(&this_mv, nb_full_mvs, full_mv_num);
           double thissad = mv_dist + lambda * mv_cost;
           if (thissad < bestsad) {
             bestsad = thissad;
@@ -2242,16 +2244,17 @@
                                   MV *mvp_full, int step_param, double lambda,
                                   int do_refine,
                                   const vp9_variance_fn_ptr_t *fn_ptr,
-                                  const int_mv *nb_full_mvs, MV *best_mv,
-                                  double *best_mv_dist, double *best_mv_cost) {
+                                  const int_mv *nb_full_mvs, int full_mv_num,
+                                  MV *best_mv, double *best_mv_dist,
+                                  double *best_mv_cost) {
   int n, num00 = 0;
   double thissme;
   double bestsme;
   const int further_steps = MAX_MVSEARCH_STEPS - 1 - step_param;
   vpx_clear_system_state();
-  bestsme = vp9_diamond_search_sad_new(x, &cpi->ss_cfg, mvp_full, best_mv,
-                                       best_mv_dist, best_mv_cost, step_param,
-                                       lambda, &n, fn_ptr, nb_full_mvs);
+  bestsme = vp9_diamond_search_sad_new(
+      x, &cpi->ss_cfg, mvp_full, best_mv, best_mv_dist, best_mv_cost,
+      step_param, lambda, &n, fn_ptr, nb_full_mvs, full_mv_num);
 
   // If there won't be more n-step search, check to see if refining search is
   // needed.
@@ -2265,9 +2268,9 @@
       MV temp_mv;
       double mv_dist;
       double mv_cost;
-      thissme = vp9_diamond_search_sad_new(x, &cpi->ss_cfg, mvp_full, &temp_mv,
-                                           &mv_dist, &mv_cost, step_param + n,
-                                           lambda, &num00, fn_ptr, nb_full_mvs);
+      thissme = vp9_diamond_search_sad_new(
+          x, &cpi->ss_cfg, mvp_full, &temp_mv, &mv_dist, &mv_cost,
+          step_param + n, lambda, &num00, fn_ptr, nb_full_mvs, full_mv_num);
       // check to see if refining search is needed.
       if (num00 > further_steps - n) do_refine = 0;
 
@@ -2286,9 +2289,9 @@
     MV temp_mv = *best_mv;
     double mv_dist;
     double mv_cost;
-    thissme =
-        vp9_refining_search_sad_new(x, &temp_mv, &mv_dist, &mv_cost, lambda,
-                                    search_range, fn_ptr, nb_full_mvs);
+    thissme = vp9_refining_search_sad_new(x, &temp_mv, &mv_dist, &mv_cost,
+                                          lambda, search_range, fn_ptr,
+                                          nb_full_mvs, full_mv_num);
     if (thissme < bestsme) {
       bestsme = thissme;
       *best_mv = temp_mv;
@@ -2428,7 +2431,7 @@
                                    double *best_mv_dist, double *best_mv_cost,
                                    double lambda, int search_range,
                                    const vp9_variance_fn_ptr_t *fn_ptr,
-                                   const int_mv *nb_full_mvs) {
+                                   const int_mv *nb_full_mvs, int full_mv_num) {
   const MACROBLOCKD *const xd = &x->e_mbd;
   const MV neighbors[4] = { { -1, 0 }, { 0, -1 }, { 0, 1 }, { 1, 0 } };
   const struct buf_2d *const what = &x->plane[0].src;
@@ -2439,7 +2442,8 @@
   vpx_clear_system_state();
   *best_mv_dist =
       fn_ptr->sdf(what->buf, what->stride, best_address, in_what->stride);
-  *best_mv_cost = av1_nb_mvs_inconsistency(best_full_mv, nb_full_mvs);
+  *best_mv_cost =
+      vp9_nb_mvs_inconsistency(best_full_mv, nb_full_mvs, full_mv_num);
   best_sad = (*best_mv_dist) + lambda * (*best_mv_cost);
 
   for (i = 0; i < search_range; i++) {
@@ -2461,7 +2465,8 @@
         const MV mv = { best_full_mv->row + neighbors[j].row,
                         best_full_mv->col + neighbors[j].col };
         const double mv_dist = sads[j];
-        const double mv_cost = av1_nb_mvs_inconsistency(&mv, nb_full_mvs);
+        const double mv_cost =
+            vp9_nb_mvs_inconsistency(&mv, nb_full_mvs, full_mv_num);
         const double thissad = mv_dist + lambda * mv_cost;
         if (thissad < best_sad) {
           best_sad = thissad;
@@ -2479,7 +2484,8 @@
           const double mv_dist =
               fn_ptr->sdf(what->buf, what->stride,
                           get_buf_from_mv(in_what, &mv), in_what->stride);
-          const double mv_cost = av1_nb_mvs_inconsistency(&mv, nb_full_mvs);
+          const double mv_cost =
+              vp9_nb_mvs_inconsistency(&mv, nb_full_mvs, full_mv_num);
           const double thissad = mv_dist + lambda * mv_cost;
           if (thissad < best_sad) {
             best_sad = thissad;
--- a/vp9/encoder/vp9_mcomp.h
+++ b/vp9/encoder/vp9_mcomp.h
@@ -126,16 +126,23 @@
                                    double *best_mv_dist, double *best_mv_cost,
                                    double lambda, int search_range,
                                    const vp9_variance_fn_ptr_t *fn_ptr,
-                                   const int_mv *nb_full_mvs);
+                                   const int_mv *nb_full_mvs, int full_mv_num);
 
 double vp9_full_pixel_diamond_new(const struct VP9_COMP *cpi, MACROBLOCK *x,
                                   MV *mvp_full, int step_param, double lambda,
                                   int do_refine,
                                   const vp9_variance_fn_ptr_t *fn_ptr,
-                                  const int_mv *nb_full_mvs, MV *best_mv,
-                                  double *best_mv_dist, double *best_mv_cost);
+                                  const int_mv *nb_full_mvs, int full_mv_num,
+                                  MV *best_mv, double *best_mv_dist,
+                                  double *best_mv_cost);
 
-double av1_nb_mvs_inconsistency(const MV *mv, const int_mv *nb_mvs);
+double vp9_nb_mvs_inconsistency(const MV *mv, const int_mv *nb_mvs, int mv_num);
+static INLINE MV get_full_mv(const MV *mv) {
+  MV out_mv;
+  out_mv.row = mv->row >> 3;
+  out_mv.col = mv->col >> 3;
+  return out_mv;
+}
 #endif  // CONFIG_NON_GREEDY_MV
 #ifdef __cplusplus
 }  // extern "C"
--- a/vp9/encoder/vp9_rdopt.c
+++ b/vp9/encoder/vp9_rdopt.c
@@ -2315,6 +2315,61 @@
                 block_size);
 }
 
+#if CONFIG_NON_GREEDY_MV
+#define MAX_PREV_NB_FULL_MV_NUM 8
+static int find_prev_nb_full_mvs(const VP9_COMMON *cm, const MACROBLOCKD *xd,
+                                 int ref_frame, BLOCK_SIZE bsize, int mi_row,
+                                 int mi_col, int_mv *nb_full_mvs) {
+  int i;
+  const TileInfo *tile = &xd->tile;
+  int full_mv_num = 0;
+  assert(bsize >= BLOCK_8X8);
+  for (i = 0; i < MVREF_NEIGHBOURS; ++i) {
+    const POSITION *mv_ref = &mv_ref_blocks[bsize][i];
+    if (is_inside(tile, mi_col, mi_row, cm->mi_rows, mv_ref)) {
+      const MODE_INFO *nb_mi =
+          xd->mi[mv_ref->col + mv_ref->row * xd->mi_stride];
+      if (nb_mi->sb_type >= BLOCK_8X8) {
+        if (nb_mi->ref_frame[0] == ref_frame) {
+          nb_full_mvs[full_mv_num].as_mv = get_full_mv(&nb_mi->mv[0].as_mv);
+          ++full_mv_num;
+          if (full_mv_num >= MAX_PREV_NB_FULL_MV_NUM) {
+            return full_mv_num;
+          }
+        } else if (nb_mi->ref_frame[1] == ref_frame) {
+          nb_full_mvs[full_mv_num].as_mv = get_full_mv(&nb_mi->mv[1].as_mv);
+          ++full_mv_num;
+          if (full_mv_num >= MAX_PREV_NB_FULL_MV_NUM) {
+            return full_mv_num;
+          }
+        }
+      } else {
+        int j;
+        for (j = 0; j < 4; ++j) {
+          // TODO(angiebird): avoid using duplicated mvs
+          if (nb_mi->ref_frame[0] == ref_frame) {
+            nb_full_mvs[full_mv_num].as_mv =
+                get_full_mv(&nb_mi->bmi[j].as_mv[0].as_mv);
+            ++full_mv_num;
+            if (full_mv_num >= MAX_PREV_NB_FULL_MV_NUM) {
+              return full_mv_num;
+            }
+          } else if (nb_mi->ref_frame[1] == ref_frame) {
+            nb_full_mvs[full_mv_num].as_mv =
+                get_full_mv(&nb_mi->bmi[j].as_mv[1].as_mv);
+            ++full_mv_num;
+            if (full_mv_num >= MAX_PREV_NB_FULL_MV_NUM) {
+              return full_mv_num;
+            }
+          }
+        }
+      }
+    }
+  }
+  return full_mv_num;
+}
+#endif  // CONFIG_NON_GREEDY_MV
+
 static void single_motion_search(VP9_COMP *cpi, MACROBLOCK *x, BLOCK_SIZE bsize,
                                  int mi_row, int mi_col, int_mv *tmp_mv,
                                  int *rate_mv) {
@@ -2338,11 +2393,12 @@
 #if CONFIG_NON_GREEDY_MV
   double mv_dist = 0;
   double mv_cost = 0;
-  double lambda = 0;
+  double lambda = (pw * ph) / 4;
   double bestsme;
-  int_mv nb_full_mvs[NB_MVS_NUM];
-  // TODO(angiebird): Set nb_full_mvs properly.
-  vp9_zero(nb_full_mvs);
+  int_mv nb_full_mvs[MAX_PREV_NB_FULL_MV_NUM];
+
+  const int nb_full_mv_num =
+      find_prev_nb_full_mvs(cm, xd, ref, bsize, mi_row, mi_col, nb_full_mvs);
 #else   // CONFIG_NON_GREEDY_MV
   int bestsme = INT_MAX;
   int sadpb = x->sadperbit16;
@@ -2418,9 +2474,9 @@
   mvp_full.row >>= 3;
 
 #if CONFIG_NON_GREEDY_MV
-  bestsme = vp9_full_pixel_diamond_new(cpi, x, &mvp_full, step_param, lambda, 1,
-                                       &cpi->fn_ptr[bsize], nb_full_mvs,
-                                       &tmp_mv->as_mv, &mv_dist, &mv_cost);
+  bestsme = vp9_full_pixel_diamond_new(
+      cpi, x, &mvp_full, step_param, lambda, 1, &cpi->fn_ptr[bsize],
+      nb_full_mvs, nb_full_mv_num, &tmp_mv->as_mv, &mv_dist, &mv_cost);
 #else   // CONFIG_NON_GREEDY_MV
   bestsme = vp9_full_pixel_search(
       cpi, x, bsize, &mvp_full, step_param, cpi->sf.mv.search_method, sadpb,
@@ -2461,8 +2517,8 @@
 #if CONFIG_NON_GREEDY_MV
       this_me = vp9_full_pixel_diamond_new(
           cpi, x, &mvp_full, VPXMAX(step_param, MAX_MVSEARCH_STEPS - step),
-          lambda, 1, &cpi->fn_ptr[bsize], nb_full_mvs, &this_mv, &mv_dist,
-          &mv_cost);
+          lambda, 1, &cpi->fn_ptr[bsize], nb_full_mvs, nb_full_mv_num, &this_mv,
+          &mv_dist, &mv_cost);
 #else   // CONFIG_NON_GREEDY_MV
       this_me = vp9_full_pixel_search(
           cpi, x, bsize, &mvp_full,