]> granicus.if.org Git - libvpx/commitdiff
Add enhanced_full_pixel_motion_search feature
authorHui Su <huisu@google.com>
Tue, 7 Aug 2018 01:01:25 +0000 (18:01 -0700)
committerHui Su <huisu@google.com>
Tue, 7 Aug 2018 18:10:57 +0000 (11:10 -0700)
Do some extra full pixel search to improve motion vector quality.
Currently it is enabled for speed 1 only; disabled for real time mode.

Coding gain for speed 1:
         avg_psnr   ovr_psnr   ssim
lowres   -0.23%     -0.23%    -0.35%
midres   -0.33%     -0.35%    -0.38%
hdres    -0.28%     -0.29%    -0.28%

Tested encoding time over 10 HD sequences. Overall speed overhead is
1.5% for QP=30; 0.6 % for QP=40.

Change-Id: Ic2ea4d78c4979de9d5090c9d7c702944f155f8af

vp9/encoder/vp9_rdopt.c
vp9/encoder/vp9_speed_features.c
vp9/encoder/vp9_speed_features.h

index 4005f85b120b133c57f222e3ea461024b927fe88..b20d5733273bffc90f800d1a683d6bfe1a1b395c 100644 (file)
@@ -2409,6 +2409,31 @@ static void single_motion_search(VP9_COMP *cpi, MACROBLOCK *x, BLOCK_SIZE bsize,
       cpi, x, bsize, &mvp_full, step_param, cpi->sf.mv.search_method, sadpb,
       cond_cost_list(cpi, cost_list), &ref_mv, &tmp_mv->as_mv, INT_MAX, 1);
 
+  if (cpi->sf.enhanced_full_pixel_motion_search) {
+    if (x->mv_best_ref_index[ref] == 2) {
+      const int diff_row = ((int)pred_mv[0].row - pred_mv[2].row) >> 3;
+      const int diff_col = ((int)pred_mv[0].col - pred_mv[2].col) >> 3;
+      const int diff_sse = diff_row * diff_row + diff_col * diff_col;
+      // If pred_mv[0] and pred_mv[2] are very different, also search around
+      // pred_mv[0].
+      if (diff_sse > 10) {
+        int this_me;
+        MV this_mv;
+        mvp_full = pred_mv[0];
+        mvp_full.col >>= 3;
+        mvp_full.row >>= 3;
+        this_me = vp9_full_pixel_search(cpi, x, bsize, &mvp_full, step_param,
+                                        cpi->sf.mv.search_method, sadpb,
+                                        cond_cost_list(cpi, cost_list), &ref_mv,
+                                        &this_mv, INT_MAX, 1);
+        if (this_me < bestsme) {
+          tmp_mv->as_mv = this_mv;
+          bestsme = this_me;
+        }
+      }
+    }
+  }
+
   x->mv_limits = tmp_mv_limits;
 
   if (bestsme < INT_MAX) {
index 347139011d6aabbf1814818a1008d91f19e6ae22..859e626bb0411ff6f579a0a8315a186d7323a179 100644 (file)
@@ -277,6 +277,7 @@ static void set_good_speed_feature_framesize_independent(VP9_COMP *cpi,
     sf->auto_min_max_partition_size = RELAXED_NEIGHBORING_MIN_MAX;
     sf->recode_tolerance_low = 15;
     sf->recode_tolerance_high = 45;
+    sf->enhanced_full_pixel_motion_search = 0;
 
     if (cpi->twopass.fr_content_type == FC_GRAPHICS_ANIMATION) {
       for (i = 0; i < MAX_MESH_STEP; ++i) {
@@ -408,6 +409,7 @@ static void set_rt_speed_feature_framesize_independent(
   sf->disable_16x16part_nonkey = 0;
   sf->disable_golden_ref = 0;
   sf->enable_tpl_model = 0;
+  sf->enhanced_full_pixel_motion_search = 0;
 
   if (speed >= 1) {
     sf->allow_txfm_domain_distortion = 1;
@@ -817,6 +819,7 @@ void vp9_set_speed_features_framesize_independent(VP9_COMP *cpi) {
   sf->tx_size_search_method = USE_FULL_RD;
   sf->use_lp32x32fdct = 0;
   sf->adaptive_motion_search = 0;
+  sf->enhanced_full_pixel_motion_search = 1;
   sf->adaptive_pred_interp_filter = 0;
   sf->adaptive_mode_search = 0;
   sf->cb_pred_filter_search = 0;
index 406b40755dec6fa9f82fdb12ad2dceee0aa5acc4..89fc82ebf6ee929be398192308a3a706a1dcfdbb 100644 (file)
@@ -353,6 +353,9 @@ typedef struct SPEED_FEATURES {
   // point for this motion search and limits the search range around it.
   int adaptive_motion_search;
 
+  // Do extra full pixel motion search to obtain better motion vector.
+  int enhanced_full_pixel_motion_search;
+
   // Threshold for allowing exhaistive motion search.
   int exhaustive_searches_thresh;