]> granicus.if.org Git - libvpx/commitdiff
Improve subpel MV search for speed 1
authorHui Su <huisu@google.com>
Tue, 18 Sep 2018 17:33:23 +0000 (10:33 -0700)
committerHui Su <huisu@google.com>
Fri, 21 Sep 2018 16:37:31 +0000 (09:37 -0700)
Do one more subpel MV search each round. This improves coding
efficiency slightly:

lowres 0.12%
midres 0.11%
hdres  0.13%

Also renames the control flag for subpel MV search quality.

Encoding speed loss is less than 1%.

This only affects speed 1.

Change-Id: I3aecd25342f2dcacea6c143db494f7db6282cb92

vp9/encoder/vp9_encoder.c
vp9/encoder/vp9_mbgraph.c
vp9/encoder/vp9_mcomp.c
vp9/encoder/vp9_pickmode.c
vp9/encoder/vp9_rdopt.c
vp9/encoder/vp9_speed_features.c
vp9/encoder/vp9_speed_features.h
vp9/encoder/vp9_temporal_filter.c

index 2de85e735994a40a45ee10733392a2797f93c1ec..b2d3d2d8f40d3ca4df79c4b0c6276a84acdf3fd1 100644 (file)
@@ -5461,7 +5461,7 @@ uint32_t motion_compensated_prediction(VP9_COMP *cpi, ThreadData *td,
   // Ignore mv costing by sending NULL pointer instead of cost array
   bestsme = cpi->find_fractional_mv_step(
       x, mv, &best_ref_mv1, cpi->common.allow_high_precision_mv, x->errorperbit,
-      &cpi->fn_ptr[bsize], 0, mv_sf->subpel_iters_per_step,
+      &cpi->fn_ptr[bsize], 0, mv_sf->subpel_search_level,
       cond_cost_list(cpi, cost_list), NULL, NULL, &distortion, &sse, NULL, 0,
       0);
 
index 46d626def173d92405f36788c2c9a4fa2680aa90..2ec048b5314738c93fa59c12c221b83de2fd20f5 100644 (file)
@@ -59,7 +59,7 @@ static unsigned int do_16x16_motion_iteration(VP9_COMP *cpi, const MV *ref_mv,
     uint32_t sse;
     cpi->find_fractional_mv_step(
         x, dst_mv, ref_mv, cpi->common.allow_high_precision_mv, x->errorperbit,
-        &v_fn_ptr, 0, mv_sf->subpel_iters_per_step,
+        &v_fn_ptr, 0, mv_sf->subpel_search_level,
         cond_cost_list(cpi, cost_list), NULL, NULL, &distortion, &sse, NULL, 0,
         0);
   }
index 430659de3985d9de72e5934becebcc43d59fc23d..30f101574433e88cb7433436f8e6b09c000bb346 100644 (file)
@@ -734,20 +734,30 @@ uint32_t vp9_find_best_sub_pixel_tree(
       bc = tc;
     }
 
-    if (iters_per_step > 1 && best_idx != -1) {
+    if (iters_per_step > 0 && best_idx != -1) {
       unsigned int second;
       const int br0 = br;
       const int bc0 = bc;
       assert(tr == br || tc == bc);
+
       if (tr == br && tc != bc) {
         kc = bc - tc;
+        if (iters_per_step == 1) {
+          CHECK_BETTER(second, br0, bc0 + kc);
+        }
       } else if (tr != br && tc == bc) {
         kr = br - tr;
+        if (iters_per_step == 1) {
+          CHECK_BETTER(second, br0 + kr, bc0);
+        }
       }
-      CHECK_BETTER(second, br0 + kr, bc0);
-      CHECK_BETTER(second, br0, bc0 + kc);
-      if (br0 != br || bc0 != bc) {
-        CHECK_BETTER(second, br0 + kr, bc0 + kc);
+
+      if (iters_per_step > 1) {
+        CHECK_BETTER(second, br0 + kr, bc0);
+        CHECK_BETTER(second, br0, bc0 + kc);
+        if (br0 != br || bc0 != bc) {
+          CHECK_BETTER(second, br0 + kr, bc0 + kc);
+        }
       }
     }
 
index 04c7b3c2c076ed7e6fdf04bf8be3b2fcefebea6e..416d437e07dde5e84a04a5b2a156056e3100591f 100644 (file)
@@ -246,7 +246,7 @@ static int combined_motion_search(VP9_COMP *cpi, MACROBLOCK *x,
     cpi->find_fractional_mv_step(
         x, &tmp_mv->as_mv, &ref_mv, cpi->common.allow_high_precision_mv,
         x->errorperbit, &cpi->fn_ptr[bsize], subpel_force_stop,
-        cpi->sf.mv.subpel_iters_per_step, cond_cost_list(cpi, cost_list),
+        cpi->sf.mv.subpel_search_level, cond_cost_list(cpi, cost_list),
         x->nmvjointcost, x->mvcost, &dis, &x->pred_sse[ref], NULL, 0, 0);
     *rate_mv = vp9_mv_bit_cost(&tmp_mv->as_mv, &ref_mv, x->nmvjointcost,
                                x->mvcost, MV_COST_WEIGHT);
@@ -1538,7 +1538,7 @@ static int search_new_mv(VP9_COMP *cpi, MACROBLOCK *x,
         &x->mbmi_ext->ref_mvs[ref_frame][0].as_mv,
         cpi->common.allow_high_precision_mv, x->errorperbit,
         &cpi->fn_ptr[bsize], cpi->sf.mv.subpel_force_stop,
-        cpi->sf.mv.subpel_iters_per_step, cond_cost_list(cpi, cost_list),
+        cpi->sf.mv.subpel_search_level, cond_cost_list(cpi, cost_list),
         x->nmvjointcost, x->mvcost, &dis, &x->pred_sse[ref_frame], NULL, 0, 0);
   } else if (svc->use_base_mv && svc->spatial_layer_id) {
     if (frame_mv[NEWMV][ref_frame].as_int != INVALID_MV) {
@@ -2756,9 +2756,9 @@ void vp9_pick_inter_mode_sub8x8(VP9_COMP *cpi, MACROBLOCK *x, int mi_row,
                 x, &tmp_mv, &mbmi_ext->ref_mvs[ref_frame][0].as_mv,
                 cpi->common.allow_high_precision_mv, x->errorperbit,
                 &cpi->fn_ptr[bsize], cpi->sf.mv.subpel_force_stop,
-                cpi->sf.mv.subpel_iters_per_step,
-                cond_cost_list(cpi, cost_list), x->nmvjointcost, x->mvcost,
-                &dummy_dist, &x->pred_sse[ref_frame], NULL, 0, 0);
+                cpi->sf.mv.subpel_search_level, cond_cost_list(cpi, cost_list),
+                x->nmvjointcost, x->mvcost, &dummy_dist,
+                &x->pred_sse[ref_frame], NULL, 0, 0);
 
             xd->mi[0]->bmi[i].as_mv[0].as_mv = tmp_mv;
           } else {
index 1f1cd40d8473d56285c340c8c8d0f2620e7ba7eb..b9f50a615c3c2319124a676c6eb8ac6c092492be 100644 (file)
@@ -1820,7 +1820,7 @@ static void joint_motion_search(VP9_COMP *cpi, MACROBLOCK *x, BLOCK_SIZE bsize,
       bestsme = cpi->find_fractional_mv_step(
           x, &tmp_mv, &ref_mv[id].as_mv, cpi->common.allow_high_precision_mv,
           x->errorperbit, &cpi->fn_ptr[bsize], 0,
-          cpi->sf.mv.subpel_iters_per_step, NULL, x->nmvjointcost, x->mvcost,
+          cpi->sf.mv.subpel_search_level, NULL, x->nmvjointcost, x->mvcost,
           &dis, &sse, second_pred, pw, ph);
     }
 
@@ -2009,7 +2009,7 @@ static int64_t rd_pick_best_sub8x8_mode(
             cpi->find_fractional_mv_step(
                 x, new_mv, &bsi->ref_mv[0]->as_mv, cm->allow_high_precision_mv,
                 x->errorperbit, &cpi->fn_ptr[bsize], sf->mv.subpel_force_stop,
-                sf->mv.subpel_iters_per_step, cond_cost_list(cpi, cost_list),
+                sf->mv.subpel_search_level, cond_cost_list(cpi, cost_list),
                 x->nmvjointcost, x->mvcost, &distortion,
                 &x->pred_sse[mi->ref_frame[0]], NULL, 0, 0);
 
@@ -2451,7 +2451,7 @@ static void single_motion_search(VP9_COMP *cpi, MACROBLOCK *x, BLOCK_SIZE bsize,
     cpi->find_fractional_mv_step(
         x, &tmp_mv->as_mv, &ref_mv, cm->allow_high_precision_mv, x->errorperbit,
         &cpi->fn_ptr[bsize], cpi->sf.mv.subpel_force_stop,
-        cpi->sf.mv.subpel_iters_per_step, cond_cost_list(cpi, cost_list),
+        cpi->sf.mv.subpel_search_level, cond_cost_list(cpi, cost_list),
         x->nmvjointcost, x->mvcost, &dis, &x->pred_sse[ref], NULL, 0, 0);
   }
   *rate_mv = vp9_mv_bit_cost(&tmp_mv->as_mv, &ref_mv, x->nmvjointcost,
index b576b1e4b768b92c364f0aa78ab5bf147b7b7fac..836bc3dc7b28bb4533bc9fd0116a7f434d6d93d0 100644 (file)
@@ -270,7 +270,7 @@ static void set_good_speed_feature_framesize_independent(VP9_COMP *cpi,
     sf->adaptive_motion_search = 1;
     sf->mv.auto_mv_step_size = 1;
     sf->adaptive_rd_thresh = 2;
-    sf->mv.subpel_iters_per_step = 1;
+    sf->mv.subpel_search_level = 1;
     sf->mode_skip_start = 10;
     sf->adaptive_pred_interp_filter = 1;
     sf->allow_acl = 0;
@@ -315,6 +315,7 @@ static void set_good_speed_feature_framesize_independent(VP9_COMP *cpi,
     sf->ml_prune_rect_partition_threhold[1] = -1;
     sf->ml_prune_rect_partition_threhold[2] = -1;
     sf->ml_prune_rect_partition_threhold[3] = -1;
+    sf->mv.subpel_search_level = 0;
 
     if (cpi->twopass.fr_content_type == FC_GRAPHICS_ANIMATION) {
       for (i = 0; i < MAX_MESH_STEP; ++i) {
@@ -513,7 +514,7 @@ static void set_rt_speed_feature_framesize_independent(
     sf->disable_filter_search_var_thresh = 100;
     sf->use_uv_intra_rd_estimate = 1;
     sf->skip_encode_sb = 1;
-    sf->mv.subpel_iters_per_step = 1;
+    sf->mv.subpel_search_level = 0;
     sf->adaptive_rd_thresh = 4;
     sf->mode_skip_start = 6;
     sf->allow_skip_recode = 0;
@@ -842,7 +843,7 @@ void vp9_set_speed_features_framesize_independent(VP9_COMP *cpi) {
   sf->mv.search_method = NSTEP;
   sf->recode_loop = ALLOW_RECODE_FIRST;
   sf->mv.subpel_search_method = SUBPEL_TREE;
-  sf->mv.subpel_iters_per_step = 2;
+  sf->mv.subpel_search_level = 2;
   sf->mv.subpel_force_stop = 0;
   sf->optimize_coefficients = !is_lossless_requested(&cpi->oxcf);
   sf->mv.reduce_first_step_size = 0;
index c312731a6ef2beabf648decd5f78728c719abe67..531df704c95a309f657f8be1f881ec08a12c85b2 100644 (file)
@@ -191,8 +191,9 @@ typedef struct MV_SPEED_FEATURES {
   // the same process. Along the way it skips many diagonals.
   SUBPEL_SEARCH_METHODS subpel_search_method;
 
-  // Maximum number of steps in logarithmic subpel search before giving up.
-  int subpel_iters_per_step;
+  // Subpel MV search level. Can take values 0 - 2. Higher values mean more
+  // extensive subpel search.
+  int subpel_search_level;
 
   // Control when to stop subpel search:
   // 0: Full subpel search.
index 54c65bc3378d6e00bb43c87f28dea3e36340aaf9..51668d01d61ac03d1303d16b18e6c0216d81b9f2 100644 (file)
@@ -424,9 +424,9 @@ static uint32_t temporal_filter_find_matching_mb_c(VP9_COMP *cpi,
   // Ignore mv costing by sending NULL pointer instead of cost array
   bestsme = cpi->find_fractional_mv_step(
       x, ref_mv, &best_ref_mv1, cpi->common.allow_high_precision_mv,
-      x->errorperbit, &cpi->fn_ptr[BLOCK_16X16], 0,
-      mv_sf->subpel_iters_per_step, cond_cost_list(cpi, cost_list), NULL, NULL,
-      &distortion, &sse, NULL, 0, 0);
+      x->errorperbit, &cpi->fn_ptr[BLOCK_16X16], 0, mv_sf->subpel_search_level,
+      cond_cost_list(cpi, cost_list), NULL, NULL, &distortion, &sse, NULL, 0,
+      0);
 
   // Restore input state
   x->plane[0].src = src;