shithub: libvpx

Download patch

ref: 6b5db3f9da3f8b21cf582ba0d8e375a70427d0e1
parent: 548974b293aafd6b49d9fd8d6653914a284eb929
parent: 706f1f10e016f30f6f68afd938e25df9765ffb87
author: Angie Chiang <[email protected]>
date: Thu Jul 18 18:12:12 EDT 2019

Merge changes I3216c984,I70d40060

* changes:
  Make vp9_prepare_nb_full_mvs only return valid mvs
  Let vp9_nb_mvs_inconsistency call log2 just once

--- a/vp9/encoder/vp9_encoder.c
+++ b/vp9/encoder/vp9_encoder.c
@@ -5912,6 +5912,7 @@
   // TODO(angiebird): Figure out lambda's proper value.
   const int lambda = cpi->tpl_stats[frame_idx].lambda;
   int_mv nb_full_mvs[NB_MVS_NUM];
+  int nb_full_mv_num;
 #endif
 
   MV best_ref_mv1 = { 0, 0 };
@@ -5934,10 +5935,11 @@
 #if CONFIG_NON_GREEDY_MV
   (void)search_method;
   (void)sadpb;
-  vp9_prepare_nb_full_mvs(&cpi->tpl_stats[frame_idx], mi_row, mi_col, rf_idx,
-                          bsize, nb_full_mvs);
+  nb_full_mv_num = vp9_prepare_nb_full_mvs(&cpi->tpl_stats[frame_idx], mi_row,
+                                           mi_col, rf_idx, bsize, 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, NB_MVS_NUM, mv);
+                             &cpi->fn_ptr[bsize], nb_full_mvs, nb_full_mv_num,
+                             mv);
 #else
   (void)frame_idx;
   (void)mi_row;
--- a/vp9/encoder/vp9_mcomp.c
+++ b/vp9/encoder/vp9_mcomp.c
@@ -1899,28 +1899,32 @@
   }
 }
 
-int64_t vp9_nb_mvs_inconsistency(const MV *mv, const int_mv *nb_mvs,
+int64_t vp9_nb_mvs_inconsistency(const MV *mv, const int_mv *nb_full_mvs,
                                  int mv_num) {
+  // The bahavior of this function is to compute log2 of mv difference,
+  // i.e. min log2(1 + row_diff * row_diff + col_diff * col_diff)
+  // against available neghbor mvs.
+  // Since the log2 is monotonic increasing, we can compute
+  // min row_diff * row_diff + col_diff * col_diff first
+  // then apply log2 in the end
   int i;
-  int update = 0;
-  int64_t best_cost = 0;
-  vpx_clear_system_state();
+  int64_t min_abs_diff = INT64_MAX;
+  int cnt = 0;
+  assert(mv_num <= NB_MVS_NUM);
   for (i = 0; i < mv_num; ++i) {
-    if (nb_mvs[i].as_int != INVALID_MV) {
-      MV nb_mv = nb_mvs[i].as_mv;
-      const int64_t row_diff = abs(mv->row - nb_mv.row);
-      const int64_t col_diff = abs(mv->col - nb_mv.col);
-      const int64_t cost =
-          log2_approximation(1 + row_diff * row_diff + col_diff * col_diff);
-      if (update == 0) {
-        best_cost = cost;
-        update = 1;
-      } else {
-        best_cost = cost < best_cost ? cost : best_cost;
-      }
-    }
+    MV nb_mv = nb_full_mvs[i].as_mv;
+    const int64_t row_diff = abs(mv->row - nb_mv.row);
+    const int64_t col_diff = abs(mv->col - nb_mv.col);
+    const int64_t abs_diff = row_diff * row_diff + col_diff * col_diff;
+    assert(nb_full_mvs[i].as_int != INVALID_MV);
+    min_abs_diff = VPXMIN(abs_diff, min_abs_diff);
+    ++cnt;
   }
-  return best_cost;
+  if (cnt) {
+    return log2_approximation(1 + min_abs_diff);
+  } else {
+    return 0;
+  }
 }
 
 static int64_t exhaustive_mesh_search_multi_step(
@@ -2247,12 +2251,13 @@
   return bestsad;
 }
 
-void vp9_prepare_nb_full_mvs(const TplDepFrame *tpl_frame, int mi_row,
-                             int mi_col, int rf_idx, BLOCK_SIZE bsize,
-                             int_mv *nb_full_mvs) {
+int vp9_prepare_nb_full_mvs(const TplDepFrame *tpl_frame, int mi_row,
+                            int mi_col, int rf_idx, BLOCK_SIZE bsize,
+                            int_mv *nb_full_mvs) {
   const int mi_width = num_8x8_blocks_wide_lookup[bsize];
   const int mi_height = num_8x8_blocks_high_lookup[bsize];
   const int dirs[NB_MVS_NUM][2] = { { -1, 0 }, { 0, -1 }, { 1, 0 }, { 0, 1 } };
+  int nb_full_mv_num = 0;
   int i;
   for (i = 0; i < NB_MVS_NUM; ++i) {
     int r = dirs[i][0] * mi_height;
@@ -2262,17 +2267,15 @@
       const TplDepStats *tpl_ptr =
           &tpl_frame
                ->tpl_stats_ptr[(mi_row + r) * tpl_frame->stride + mi_col + c];
-      int_mv *mv =
-          get_pyramid_mv(tpl_frame, rf_idx, bsize, mi_row + r, mi_col + c);
       if (tpl_ptr->ready[rf_idx]) {
-        nb_full_mvs[i].as_mv = get_full_mv(&mv->as_mv);
-      } else {
-        nb_full_mvs[i].as_int = INVALID_MV;
+        int_mv *mv =
+            get_pyramid_mv(tpl_frame, rf_idx, bsize, mi_row + r, mi_col + c);
+        nb_full_mvs[nb_full_mv_num].as_mv = get_full_mv(&mv->as_mv);
+        ++nb_full_mv_num;
       }
-    } else {
-      nb_full_mvs[i].as_int = INVALID_MV;
     }
   }
+  return nb_full_mv_num;
 }
 #endif  // CONFIG_NON_GREEDY_MV
 
--- a/vp9/encoder/vp9_mcomp.h
+++ b/vp9/encoder/vp9_mcomp.h
@@ -149,9 +149,9 @@
   return out_mv;
 }
 struct TplDepFrame;
-void vp9_prepare_nb_full_mvs(const struct TplDepFrame *tpl_frame, int mi_row,
-                             int mi_col, int rf_idx, BLOCK_SIZE bsize,
-                             int_mv *nb_full_mvs);
+int vp9_prepare_nb_full_mvs(const struct TplDepFrame *tpl_frame, int mi_row,
+                            int mi_col, int rf_idx, BLOCK_SIZE bsize,
+                            int_mv *nb_full_mvs);
 
 static INLINE BLOCK_SIZE get_square_block_size(BLOCK_SIZE bsize) {
   BLOCK_SIZE square_bsize;
--- a/vp9/encoder/vp9_rdopt.c
+++ b/vp9/encoder/vp9_rdopt.c
@@ -2496,15 +2496,15 @@
 
   int bestsme = INT_MAX;
 #if CONFIG_NON_GREEDY_MV
-  int_mv nb_full_mvs[NB_MVS_NUM];
-  const int nb_full_mv_num = NB_MVS_NUM;
   int gf_group_idx = cpi->twopass.gf_group.index;
   int gf_rf_idx = ref_frame_to_gf_rf_idx(ref);
   BLOCK_SIZE square_bsize = get_square_block_size(bsize);
+  int_mv nb_full_mvs[NB_MVS_NUM];
+  const int nb_full_mv_num =
+      vp9_prepare_nb_full_mvs(&cpi->tpl_stats[gf_group_idx], mi_row, mi_col,
+                              gf_rf_idx, square_bsize, nb_full_mvs);
   const int lambda = (pw * ph) / 4;
   assert(pw * ph == lambda << 2);
-  vp9_prepare_nb_full_mvs(&cpi->tpl_stats[gf_group_idx], mi_row, mi_col,
-                          gf_rf_idx, square_bsize, nb_full_mvs);
 #else   // CONFIG_NON_GREEDY_MV
   int sadpb = x->sadperbit16;
 #endif  // CONFIG_NON_GREEDY_MV