Enable iterative motion search for 4x4 inter pred
authorJingning Han <jingning@google.com>
Thu, 30 May 2013 04:59:41 +0000 (21:59 -0700)
committerPaul Wilkins <paulwilkins@google.com>
Thu, 30 May 2013 09:49:35 +0000 (10:49 +0100)
This commit enables iterative motion search for 4x4/4x8/8x4 block
size compound inter-inter prediction.

WIP: borg run testing

Change-Id: I2b318db4a03cdca5a8002b3fa6c0fa89b129288b

vp9/encoder/vp9_onyx_if.c
vp9/encoder/vp9_onyx_int.h
vp9/encoder/vp9_rdopt.c

index b484925..d96d062 100644 (file)
@@ -775,7 +775,7 @@ void vp9_set_speed_features(VP9_COMP *cpi) {
   sf->optimize_coefficients = !cpi->oxcf.lossless;
   sf->first_step = 0;
   sf->max_step_search_steps = MAX_MVSEARCH_STEPS;
-  sf->comp_inter_joint_serach = 1;
+  sf->comp_inter_joint_search = 1;
 #if CONFIG_MULTIPLE_ARF
   // Switch segmentation off.
   sf->static_segmentation = 0;
@@ -810,7 +810,7 @@ void vp9_set_speed_features(VP9_COMP *cpi) {
         /* Disable coefficient optimization above speed 0 */
         sf->optimize_coefficients = 0;
         sf->no_skip_block4x4_search = 0;
-        sf->comp_inter_joint_serach = 0;
+        sf->comp_inter_joint_search = 0;
 
         sf->first_step = 1;
 
index 24a2acb..f3dea93 100644 (file)
@@ -225,7 +225,7 @@ typedef struct {
   int search_best_filter;
   int mb16_breakout;
   int static_segmentation;
-  int comp_inter_joint_serach;
+  int comp_inter_joint_search;
 } SPEED_FEATURES;
 
 enum BlockSize {
index 1026bd6..4ee43d5 100644 (file)
@@ -941,7 +941,7 @@ static int labels2mode(MACROBLOCK *x, int i,
                        MB_PREDICTION_MODE this_mode,
                        int_mv *this_mv, int_mv *this_second_mv,
                        int_mv frame_mv[MB_MODE_COUNT][MAX_REF_FRAMES],
-                       int_mv seg_mvs[MAX_REF_FRAMES - 1],
+                       int_mv seg_mvs[MAX_REF_FRAMES],
                        int_mv *best_ref_mv,
                        int_mv *second_best_ref_mv,
                        int *mvjcost, int *mvcost[2], VP9_COMP *cpi) {
@@ -962,14 +962,11 @@ static int labels2mode(MACROBLOCK *x, int i,
   // is when we are on a new label  (jbb May 08, 2007)
   switch (m = this_mode) {
     case NEWMV:
-      if (mbmi->second_ref_frame > 0) {
-        this_mv->as_int = seg_mvs[mbmi->ref_frame - 1].as_int;
-        this_second_mv->as_int = seg_mvs[mbmi->second_ref_frame - 1].as_int;
-      }
-
+      this_mv->as_int = seg_mvs[mbmi->ref_frame].as_int;
       thismvcost  = vp9_mv_bit_cost(this_mv, best_ref_mv, mvjcost, mvcost,
                                     102, xd->allow_high_precision_mv);
       if (mbmi->second_ref_frame > 0) {
+        this_second_mv->as_int = seg_mvs[mbmi->second_ref_frame].as_int;
         thismvcost += vp9_mv_bit_cost(this_second_mv, second_best_ref_mv,
                                       mvjcost, mvcost, 102,
                                       xd->allow_high_precision_mv);
@@ -1174,9 +1171,44 @@ static enum BlockSize get_block_size(int bw, int bh) {
   return -1;
 }
 
+static INLINE void mi_buf_shift(MACROBLOCK *x, int i) {
+  MB_MODE_INFO *mbmi = &x->e_mbd.mode_info_context->mbmi;
+  x->plane[0].src.buf =
+      raster_block_offset_uint8(&x->e_mbd, BLOCK_SIZE_SB8X8, 0, i,
+                                x->plane[0].src.buf,
+                                x->plane[0].src.stride);
+  assert(((intptr_t)x->e_mbd.plane[0].pre[0].buf & 0x7) == 0);
+  x->e_mbd.plane[0].pre[0].buf =
+      raster_block_offset_uint8(&x->e_mbd, BLOCK_SIZE_SB8X8, 0, i,
+                                x->e_mbd.plane[0].pre[0].buf,
+                                x->e_mbd.plane[0].pre[0].stride);
+  if (mbmi->second_ref_frame)
+    x->e_mbd.plane[0].pre[1].buf =
+        raster_block_offset_uint8(&x->e_mbd, BLOCK_SIZE_SB8X8, 0, i,
+                                  x->e_mbd.plane[0].pre[1].buf,
+                                  x->e_mbd.plane[0].pre[1].stride);
+}
+
+static INLINE void mi_buf_restore(MACROBLOCK *x, struct buf_2d orig_src,
+                                  struct buf_2d orig_pre[2]) {
+  MB_MODE_INFO *mbmi = &x->e_mbd.mode_info_context->mbmi;
+  x->plane[0].src = orig_src;
+  x->e_mbd.plane[0].pre[0] = orig_pre[0];
+  if (mbmi->second_ref_frame)
+    x->e_mbd.plane[0].pre[1] = orig_pre[1];
+}
+
+static void iterative_motion_search(VP9_COMP *cpi, MACROBLOCK *x,
+                                    BLOCK_SIZE_TYPE bsize,
+                                    int_mv *frame_mv,
+                                    YV12_BUFFER_CONFIG **scaled_ref_frame,
+                                    int mi_row, int mi_col,
+                                    int_mv single_newmv[MAX_REF_FRAMES]);
+
 static void rd_check_segment_txsize(VP9_COMP *cpi, MACROBLOCK *x,
                                     BEST_SEG_INFO *bsi,
-                                    int_mv seg_mvs[4][MAX_REF_FRAMES - 1]) {
+                                    int_mv seg_mvs[4][MAX_REF_FRAMES],
+                                    int mi_row, int mi_col) {
   int i, j;
   int br = 0, bd = 0;
   MB_PREDICTION_MODE this_mode;
@@ -1193,7 +1225,7 @@ static void rd_check_segment_txsize(VP9_COMP *cpi, MACROBLOCK *x,
   int bhl = b_height_log2(bsize), bh = 1 << bhl;
   int idx, idy;
   vp9_variance_fn_ptr_t *v_fn_ptr;
-
+  YV12_BUFFER_CONFIG *scaled_ref_frame[2] = {NULL, NULL};
   ENTROPY_CONTEXT t_above[4], t_left[4];
   ENTROPY_CONTEXT t_above_b[4], t_left_b[4];
 
@@ -1240,6 +1272,10 @@ static void rd_check_segment_txsize(VP9_COMP *cpi, MACROBLOCK *x,
         int distortion;
         int labelyrate;
         ENTROPY_CONTEXT t_above_s[4], t_left_s[4];
+        const struct buf_2d orig_src = x->plane[0].src;
+        struct buf_2d orig_pre[2];
+
+        vpx_memcpy(orig_pre, x->e_mbd.plane[0].pre, sizeof(orig_pre));
 
         vpx_memcpy(t_above_s, t_above, sizeof(t_above_s));
         vpx_memcpy(t_left_s, t_left, sizeof(t_left_s));
@@ -1249,8 +1285,6 @@ static void rd_check_segment_txsize(VP9_COMP *cpi, MACROBLOCK *x,
           int step_param = 0;
           int further_steps;
           int thissme, bestsme = INT_MAX;
-          const struct buf_2d orig_src = x->plane[0].src;
-          const struct buf_2d orig_pre = x->e_mbd.plane[0].pre[0];
           int sadpb = x->sadperbit4;
           int_mv mvp_full;
 
@@ -1276,17 +1310,8 @@ static void rd_check_segment_txsize(VP9_COMP *cpi, MACROBLOCK *x,
           mvp_full.as_mv.row = bsi->mvp.as_mv.row >> 3;
           mvp_full.as_mv.col = bsi->mvp.as_mv.col >> 3;
 
-          // adjust src pointer for this segment
-          x->plane[0].src.buf =
-              raster_block_offset_uint8(&x->e_mbd, BLOCK_SIZE_SB8X8, 0, i,
-                                        x->plane[0].src.buf,
-                                        x->plane[0].src.stride);
-          assert(((intptr_t)x->e_mbd.plane[0].pre[0].buf & 0x7) == 0);
-          x->e_mbd.plane[0].pre[0].buf =
-              raster_block_offset_uint8(&x->e_mbd, BLOCK_SIZE_SB8X8, 0, i,
-                                        x->e_mbd.plane[0].pre[0].buf,
-                                        x->e_mbd.plane[0].pre[0].stride);
-
+          // adjust src pointer for this block
+          mi_buf_shift(x, i);
           bestsme = vp9_full_pixel_diamond(cpi, x, &mvp_full, step_param,
                                            sadpb, further_steps, 0, v_fn_ptr,
                                            bsi->ref_mv, &mode_mv[NEWMV]);
@@ -1323,16 +1348,29 @@ static void rd_check_segment_txsize(VP9_COMP *cpi, MACROBLOCK *x,
                                          &distortion, &sse);
 
             // safe motion search result for use in compound prediction
-            seg_mvs[i][mbmi->ref_frame - 1].as_int = mode_mv[NEWMV].as_int;
+            seg_mvs[i][mbmi->ref_frame].as_int = mode_mv[NEWMV].as_int;
           }
 
           // restore src pointers
-          x->plane[0].src = orig_src;
-          x->e_mbd.plane[0].pre[0] = orig_pre;
+          mi_buf_restore(x, orig_src, orig_pre);
         } else if (mbmi->second_ref_frame > 0 && this_mode == NEWMV) {
-          if (seg_mvs[i][mbmi->second_ref_frame - 1].as_int == INVALID_MV ||
-              seg_mvs[i][mbmi->ref_frame        - 1].as_int == INVALID_MV)
+          if (seg_mvs[i][mbmi->second_ref_frame].as_int == INVALID_MV ||
+              seg_mvs[i][mbmi->ref_frame       ].as_int == INVALID_MV)
             continue;
+
+          // adjust src pointers
+          mi_buf_shift(x, i);
+          if (cpi->sf.comp_inter_joint_search) {
+            iterative_motion_search(cpi, x, bsize, frame_mv[this_mode],
+                                    scaled_ref_frame,
+                                    mi_row, mi_col, seg_mvs[i]);
+            seg_mvs[i][mbmi->ref_frame].as_int =
+                frame_mv[this_mode][mbmi->ref_frame].as_int;
+            seg_mvs[i][mbmi->second_ref_frame].as_int =
+                frame_mv[this_mode][mbmi->second_ref_frame].as_int;
+          }
+          // restore src pointers
+          mi_buf_restore(x, orig_src, orig_pre);
         }
 
         rate = labels2mode(x, i, this_mode, &mode_mv[this_mode],
@@ -1411,12 +1449,6 @@ static void rd_check_segment_txsize(VP9_COMP *cpi, MACROBLOCK *x,
   }
 }
 
-static void rd_check_segment(VP9_COMP *cpi, MACROBLOCK *x,
-                             BEST_SEG_INFO *bsi,
-                             int_mv seg_mvs[4][MAX_REF_FRAMES - 1]) {
-  rd_check_segment_txsize(cpi, x, bsi, seg_mvs);
-}
-
 static int rd_pick_best_mbsegmentation(VP9_COMP *cpi, MACROBLOCK *x,
                                        int_mv *best_ref_mv,
                                        int_mv *second_best_ref_mv,
@@ -1425,7 +1457,8 @@ static int rd_pick_best_mbsegmentation(VP9_COMP *cpi, MACROBLOCK *x,
                                        int *returnyrate,
                                        int *returndistortion,
                                        int *skippable, int mvthresh,
-                                       int_mv seg_mvs[4][MAX_REF_FRAMES - 1]) {
+                                       int_mv seg_mvs[4][MAX_REF_FRAMES],
+                                       int mi_row, int mi_col) {
   int i;
   BEST_SEG_INFO bsi;
   MB_MODE_INFO * mbmi = &x->e_mbd.mode_info_context->mbmi;
@@ -1441,7 +1474,7 @@ static int rd_pick_best_mbsegmentation(VP9_COMP *cpi, MACROBLOCK *x,
   for (i = 0; i < 4; i++)
     bsi.modes[i] = ZEROMV;
 
-  rd_check_segment(cpi, x, &bsi, seg_mvs);
+  rd_check_segment_txsize(cpi, x, &bsi, seg_mvs, mi_row, mi_col);
 
   /* set it to the best */
   for (i = 0; i < 4; i++) {
@@ -2044,7 +2077,7 @@ static int64_t handle_inter_mode(VP9_COMP *cpi, MACROBLOCK *x,
         frame_mv[refs[0]].as_int = single_newmv[refs[0]].as_int;
         frame_mv[refs[1]].as_int = single_newmv[refs[1]].as_int;
 
-        if (cpi->sf.comp_inter_joint_serach)
+        if (cpi->sf.comp_inter_joint_search)
           iterative_motion_search(cpi, x, bsize, frame_mv, scaled_ref_frame,
                                   mi_row, mi_col, single_newmv);
 
@@ -2444,14 +2477,14 @@ int64_t vp9_rd_pick_inter_mode_sb(VP9_COMP *cpi, MACROBLOCK *x,
   int64_t frame_distortions[MAX_REF_FRAMES] = {-1};
   int intra_cost_penalty = 20 * vp9_dc_quant(cpi->common.base_qindex,
                                              cpi->common.y_dc_delta_q);
-  int_mv seg_mvs[4][MAX_REF_FRAMES - 1];
+  int_mv seg_mvs[4][MAX_REF_FRAMES];
   union b_mode_info best_bmodes[4];
   PARTITION_INFO best_partition;
 
   for (i = 0; i < 4; i++) {
     int j;
 
-    for (j = 0; j < MAX_REF_FRAMES - 1; j++)
+    for (j = 0; j < MAX_REF_FRAMES; j++)
       seg_mvs[i][j].as_int = INVALID_MV;
   }
   // Everywhere the flag is set the error is much higher than its neighbors.
@@ -2740,7 +2773,8 @@ int64_t vp9_rd_pick_inter_mode_sb(VP9_COMP *cpi, MACROBLOCK *x,
                                              second_ref, INT64_MAX,
                                              &rate, &rate_y, &distortion,
                                              &skippable,
-                                             (int)this_rd_thresh, seg_mvs);
+                                             (int)this_rd_thresh, seg_mvs,
+                                             mi_row, mi_col);
         if (cpi->common.mcomp_filter_type == SWITCHABLE) {
           const int rs = get_switchable_rate(cm, x);
           tmp_rd += RDCOST(x->rdmult, x->rddiv, rs, 0);
@@ -2779,7 +2813,8 @@ int64_t vp9_rd_pick_inter_mode_sb(VP9_COMP *cpi, MACROBLOCK *x,
                                              second_ref, INT64_MAX,
                                              &rate, &rate_y, &distortion,
                                              &skippable,
-                                             (int)this_rd_thresh, seg_mvs);
+                                             (int)this_rd_thresh, seg_mvs,
+                                             mi_row, mi_col);
       } else {
         if (cpi->common.mcomp_filter_type == SWITCHABLE) {
           int rs = get_switchable_rate(cm, x);