shithub: libvpx

Download patch

ref: 7b5553e139887a4b11e293aafe9efa3da3a53121
parent: 319c93f20d87cc06d7506f1e3ae67152400a52e4
author: Jingning Han <jingning@google.com>
date: Tue Jul 31 05:43:17 EDT 2018

Use mesh full pixel motion search to build the source ARF

Append mesh search to the diamond shape search to refine
the full pixel motion estimation for source ARF generation.
It improves the average compression performance.

Speed 0
        avg PSNR     overall PSNR     SSIM
mid      -0.18%        -0.18%        -0.22%
hd       -0.25%        -0.23%        -0.36%
nflx2k   -0.22%        -0.23%        -0.37%

Speed 1
       avg PSNR     overall PSNR      SSIM
mid     -0.10%         -0.08%        -0.11%
hd      -0.25%         -0.27%        -0.38%
nflx2k  -0.20%         -0.20%        -0.34%

The additional encoding time is close to the sample noise
range. For bus_cif at 1000 kbps, the speed 0 encoding time
goes from 83.0 s -> 83.6 s.

Change-Id: I48647f50ec3e8f7ae4550a4bde831f569f46ecf3

--- a/vp9/encoder/vp9_mcomp.c
+++ b/vp9/encoder/vp9_mcomp.c
@@ -2186,6 +2186,8 @@
   const SEARCH_METHODS method = (SEARCH_METHODS)search_method;
   vp9_variance_fn_ptr_t *fn_ptr = &cpi->fn_ptr[bsize];
   int var = 0;
+  int run_mesh_search = (method == MESH);
+
   if (cost_list) {
     cost_list[0] = INT_MAX;
     cost_list[1] = INT_MAX;
@@ -2216,29 +2218,32 @@
                           fn_ptr, 1, ref_mv, tmp_mv);
       break;
     default:
-      assert(method == NSTEP);
+      assert(method == NSTEP || method == MESH);
       var = full_pixel_diamond(cpi, x, mvp_full, step_param, error_per_bit,
                                MAX_MVSEARCH_STEPS - 1 - step_param, 1,
                                cost_list, fn_ptr, ref_mv, tmp_mv);
 
-      // Should we allow a follow on exhaustive search?
-      if ((sf->exhaustive_searches_thresh < INT_MAX) &&
-          !cpi->rc.is_src_frame_alt_ref) {
-        int64_t exhuastive_thr = sf->exhaustive_searches_thresh;
-        exhuastive_thr >>=
-            8 - (b_width_log2_lookup[bsize] + b_height_log2_lookup[bsize]);
+      // Should we allow a follow on exhaustive search, in regular rd search
+      // mode.
+      if (run_mesh_search == 0) {
+        if ((sf->exhaustive_searches_thresh < INT_MAX) &&
+            !cpi->rc.is_src_frame_alt_ref) {
+          int64_t exhuastive_thr = sf->exhaustive_searches_thresh;
+          exhuastive_thr >>=
+              8 - (b_width_log2_lookup[bsize] + b_height_log2_lookup[bsize]);
+          if (var > exhuastive_thr) run_mesh_search = 1;
+        }
+      }
 
-        // Threshold variance for an exhaustive full search.
-        if (var > exhuastive_thr) {
-          int var_ex;
-          MV tmp_mv_ex;
-          var_ex = full_pixel_exhaustive(cpi, x, tmp_mv, error_per_bit,
-                                         cost_list, fn_ptr, ref_mv, &tmp_mv_ex);
+      if (run_mesh_search) {
+        int var_ex;
+        MV tmp_mv_ex;
+        var_ex = full_pixel_exhaustive(cpi, x, tmp_mv, error_per_bit, cost_list,
+                                       fn_ptr, ref_mv, &tmp_mv_ex);
 
-          if (var_ex < var) {
-            var = var_ex;
-            *tmp_mv = tmp_mv_ex;
-          }
+        if (var_ex < var) {
+          var = var_ex;
+          *tmp_mv = tmp_mv_ex;
         }
       }
       break;
--- a/vp9/encoder/vp9_speed_features.c
+++ b/vp9/encoder/vp9_speed_features.c
@@ -201,15 +201,16 @@
 
   if (cpi->twopass.fr_content_type == FC_GRAPHICS_ANIMATION) {
     sf->exhaustive_searches_thresh = (1 << 22);
-    for (i = 0; i < MAX_MESH_STEP; ++i) {
-      int mesh_density_level = 0;
-      sf->mesh_patterns[i].range =
-          good_quality_mesh_patterns[mesh_density_level][i].range;
-      sf->mesh_patterns[i].interval =
-          good_quality_mesh_patterns[mesh_density_level][i].interval;
-    }
   } else {
     sf->exhaustive_searches_thresh = INT_MAX;
+  }
+
+  for (i = 0; i < MAX_MESH_STEP; ++i) {
+    const int mesh_density_level = 0;
+    sf->mesh_patterns[i].range =
+        good_quality_mesh_patterns[mesh_density_level][i].range;
+    sf->mesh_patterns[i].interval =
+        good_quality_mesh_patterns[mesh_density_level][i].interval;
   }
 
   if (speed >= 1) {
--- a/vp9/encoder/vp9_speed_features.h
+++ b/vp9/encoder/vp9_speed_features.h
@@ -57,7 +57,8 @@
   BIGDIA = 3,
   SQUARE = 4,
   FAST_HEX = 5,
-  FAST_DIAMOND = 6
+  FAST_DIAMOND = 6,
+  MESH = 7
 } SEARCH_METHODS;
 
 typedef enum {
--- a/vp9/encoder/vp9_temporal_filter.c
+++ b/vp9/encoder/vp9_temporal_filter.c
@@ -230,7 +230,7 @@
   MACROBLOCK *const x = &td->mb;
   MACROBLOCKD *const xd = &x->e_mbd;
   MV_SPEED_FEATURES *const mv_sf = &cpi->sf.mv;
-  const SEARCH_METHODS search_method = NSTEP;
+  const SEARCH_METHODS search_method = MESH;
   int step_param;
   int sadpb = x->sadperbit16;
   uint32_t bestsme = UINT_MAX;