]> granicus.if.org Git - libvpx/commitdiff
Fix superblock experiment.
authorRonald S. Bultje <rbultje@google.com>
Tue, 30 Oct 2012 00:58:18 +0000 (17:58 -0700)
committerRonald S. Bultje <rbultje@google.com>
Tue, 30 Oct 2012 00:58:18 +0000 (17:58 -0700)
Also merge some duplicate code related to the superblock experiment
in the RD loop.

Change-Id: Ic93f1d4d1ed81220fd7ecf6e65da2821a215b2de

vp8/common/pred_common.c
vp8/common/pred_common.h
vp8/decoder/decodemv.c
vp8/decoder/decodframe.c
vp8/encoder/bitstream.c
vp8/encoder/encodeframe.c
vp8/encoder/onyx_if.c
vp8/encoder/onyx_int.h
vp8/encoder/rdopt.c
vp8/encoder/rdopt.h
vp8/encoder/segmentation.c

index 6fe12d46de96482c3bf976d333aae424686c575f..8b71c08a34cdc8316add9f75c17f9fe15e16620f 100644 (file)
@@ -219,14 +219,22 @@ unsigned char vp9_get_pred_flag(const MACROBLOCKD *const xd,
 void vp9_set_pred_flag(MACROBLOCKD *const xd,
                        PRED_ID pred_id,
                        unsigned char pred_flag) {
+#if CONFIG_SUPERBLOCKS
+  const int mis = xd->mode_info_stride;
+#endif
+
   switch (pred_id) {
     case PRED_SEG_ID:
       xd->mode_info_context->mbmi.seg_id_predicted = pred_flag;
 #if CONFIG_SUPERBLOCKS
       if (xd->mode_info_context->mbmi.encoded_as_sb) {
-        xd->mode_info_context[1].mbmi.seg_id_predicted = pred_flag;
-        xd->mode_info_context[xd->mode_info_stride].mbmi.seg_id_predicted = pred_flag;
-        xd->mode_info_context[xd->mode_info_stride+1].mbmi.seg_id_predicted = pred_flag;
+        if (xd->mb_to_right_edge > 0)
+          xd->mode_info_context[1].mbmi.seg_id_predicted = pred_flag;
+        if (xd->mb_to_bottom_edge > 0) {
+          xd->mode_info_context[mis].mbmi.seg_id_predicted = pred_flag;
+          if (xd->mb_to_right_edge > 0)
+            xd->mode_info_context[mis + 1].mbmi.seg_id_predicted = pred_flag;
+        }
       }
 #endif
       break;
@@ -235,15 +243,30 @@ void vp9_set_pred_flag(MACROBLOCKD *const xd,
       xd->mode_info_context->mbmi.ref_predicted = pred_flag;
 #if CONFIG_SUPERBLOCKS
       if (xd->mode_info_context->mbmi.encoded_as_sb) {
-        xd->mode_info_context[1].mbmi.ref_predicted = pred_flag;
-        xd->mode_info_context[xd->mode_info_stride].mbmi.ref_predicted = pred_flag;
-        xd->mode_info_context[xd->mode_info_stride+1].mbmi.ref_predicted = pred_flag;
+        if (xd->mb_to_right_edge > 0)
+          xd->mode_info_context[1].mbmi.ref_predicted = pred_flag;
+        if (xd->mb_to_bottom_edge > 0) {
+          xd->mode_info_context[mis].mbmi.ref_predicted = pred_flag;
+          if (xd->mb_to_right_edge > 0)
+            xd->mode_info_context[mis + 1].mbmi.ref_predicted = pred_flag;
+        }
       }
 #endif
       break;
 
     case PRED_MBSKIP:
       xd->mode_info_context->mbmi.mb_skip_coeff = pred_flag;
+#if CONFIG_SUPERBLOCKS
+      if (xd->mode_info_context->mbmi.encoded_as_sb) {
+        if (xd->mb_to_right_edge > 0)
+          xd->mode_info_context[1].mbmi.mb_skip_coeff = pred_flag;
+        if (xd->mb_to_bottom_edge > 0) {
+          xd->mode_info_context[mis].mbmi.mb_skip_coeff = pred_flag;
+          if (xd->mb_to_right_edge > 0)
+            xd->mode_info_context[mis + 1].mbmi.mb_skip_coeff = pred_flag;
+        }
+      }
+#endif
       break;
 
     default:
@@ -257,10 +280,29 @@ void vp9_set_pred_flag(MACROBLOCKD *const xd,
 // peredict various bitstream signals.
 
 // Macroblock segment id prediction function
-unsigned char vp9_get_pred_mb_segid(const VP8_COMMON *const cm, int MbIndex) {
+unsigned char vp9_get_pred_mb_segid(const VP8_COMMON *const cm,
+                                    const MACROBLOCKD *const xd, int MbIndex) {
   // Currently the prediction for the macroblock segment ID is
   // the value stored for this macroblock in the previous frame.
-  return cm->last_frame_seg_map[MbIndex];
+#if CONFIG_SUPERBLOCKS
+  if (!xd->mode_info_context->mbmi.encoded_as_sb) {
+#endif
+    return cm->last_frame_seg_map[MbIndex];
+#if CONFIG_SUPERBLOCKS
+  } else {
+    int seg_id = cm->last_frame_seg_map[MbIndex];
+    int mb_col = MbIndex % cm->mb_cols;
+    int mb_row = MbIndex / cm->mb_cols;
+    if (mb_col + 1 < cm->mb_cols)
+      seg_id = seg_id && cm->last_frame_seg_map[MbIndex + 1];
+    if (mb_row + 1 < cm->mb_rows) {
+      seg_id = seg_id && cm->last_frame_seg_map[MbIndex + cm->mb_cols];
+      if (mb_col + 1 < cm->mb_cols)
+        seg_id = seg_id && cm->last_frame_seg_map[MbIndex + cm->mb_cols + 1];
+    }
+    return seg_id;
+  }
+#endif
 }
 
 MV_REFERENCE_FRAME vp9_get_pred_ref(const VP8_COMMON *const cm,
index 0096e3d79d11951c51f8f38409e5997e17013e4e..fa591defb36d5e62063ebfbbf89d35482761f287 100644 (file)
@@ -46,6 +46,7 @@ extern void vp9_set_pred_flag(MACROBLOCKD *const xd,
 
 
 extern unsigned char vp9_get_pred_mb_segid(const VP8_COMMON *const cm,
+                                           const MACROBLOCKD *const xd,
                                            int MbIndex);
 
 extern MV_REFERENCE_FRAME vp9_get_pred_ref(const VP8_COMMON *const cm,
index 2187e020f89e0fd3c62193cbd87d5713726b832b..d119d54e7f2e6135040b46e96b3db75cf428cef0 100644 (file)
@@ -188,6 +188,11 @@ static void kfread_modes(VP8D_COMP *pbi,
   m->mbmi.second_uv_mode = (MB_PREDICTION_MODE)(DC_PRED - 1);
 #endif
 
+#if CONFIG_SUPERBLOCKS
+  if (m->mbmi.encoded_as_sb)
+    m->mbmi.txfm_size = TX_8X8;
+  else
+#endif
   if (cm->txfm_mode == TX_MODE_SELECT && m->mbmi.mb_skip_coeff == 0 &&
       m->mbmi.mode <= I8X8_PRED) {
     // FIXME(rbultje) code ternary symbol once all experiments are merged
@@ -589,7 +594,7 @@ static void read_mb_segment_id(VP8D_COMP *pbi,
         // If the value is flagged as correctly predicted
         // then use the predicted value
         if (seg_pred_flag) {
-          mbmi->segment_id = vp9_get_pred_mb_segid(cm, index);
+          mbmi->segment_id = vp9_get_pred_mb_segid(cm, xd, index);
         }
         // Else .... decode it explicitly
         else {
@@ -602,10 +607,14 @@ static void read_mb_segment_id(VP8D_COMP *pbi,
       }
 #if CONFIG_SUPERBLOCKS
       if (mbmi->encoded_as_sb) {
-        cm->last_frame_seg_map[index] =
-        cm->last_frame_seg_map[index + 1] =
-        cm->last_frame_seg_map[index + cm->mb_cols] =
-        cm->last_frame_seg_map[index + cm->mb_cols + 1] = mbmi->segment_id;
+        cm->last_frame_seg_map[index] = mbmi->segment_id;
+        if (mb_col + 1 < cm->mb_cols)
+          cm->last_frame_seg_map[index + 1] = mbmi->segment_id;
+        if (mb_row + 1 < cm->mb_rows) {
+          cm->last_frame_seg_map[index + cm->mb_cols] = mbmi->segment_id;
+          if (mb_col + 1 < cm->mb_cols)
+            cm->last_frame_seg_map[index + cm->mb_cols + 1] = mbmi->segment_id;
+        }
       } else
 #endif
       {
@@ -614,11 +623,17 @@ static void read_mb_segment_id(VP8D_COMP *pbi,
     } else {
 #if CONFIG_SUPERBLOCKS
       if (mbmi->encoded_as_sb) {
-        mbmi->segment_id =
-              cm->last_frame_seg_map[index] &&
-              cm->last_frame_seg_map[index + 1] &&
-              cm->last_frame_seg_map[index + cm->mb_cols] &&
-              cm->last_frame_seg_map[index + cm->mb_cols + 1];
+        mbmi->segment_id = cm->last_frame_seg_map[index];
+        if (mb_col < cm->mb_cols - 1)
+          mbmi->segment_id = mbmi->segment_id &&
+                             cm->last_frame_seg_map[index + 1];
+        if (mb_row < cm->mb_rows - 1) {
+          mbmi->segment_id = mbmi->segment_id &&
+                             cm->last_frame_seg_map[index + cm->mb_cols];
+          if (mb_col < cm->mb_cols - 1)
+            mbmi->segment_id = mbmi->segment_id &&
+                               cm->last_frame_seg_map[index + cm->mb_cols + 1];
+        }
       } else
 #endif
       {
@@ -1131,6 +1146,11 @@ static void read_mb_modes_mv(VP8D_COMP *pbi, MODE_INFO *mi, MB_MODE_INFO *mbmi,
 #endif
   }
 
+#if CONFIG_SUPERBLOCKS
+  if (mbmi->encoded_as_sb)
+    mbmi->txfm_size = TX_8X8;
+  else
+#endif
   if (cm->txfm_mode == TX_MODE_SELECT && mbmi->mb_skip_coeff == 0 &&
       ((mbmi->ref_frame == INTRA_FRAME && mbmi->mode <= I8X8_PRED) ||
        (mbmi->ref_frame != INTRA_FRAME && !(mbmi->mode == SPLITMV &&
index c53560dbb53b6ac34937dbc3795172db17948331..39ad8ab007a5ec41007c338f31a8121fca070c46 100644 (file)
@@ -202,7 +202,7 @@ static void skip_recon_mb(VP8D_COMP *pbi, MACROBLOCKD *xd) {
 }
 
 static void decode_macroblock(VP8D_COMP *pbi, MACROBLOCKD *xd,
-                              unsigned int mb_col,
+                              int mb_row, unsigned int mb_col,
                               BOOL_DECODER* const bc) {
   int eobtotal = 0;
   MB_PREDICTION_MODE mode;
@@ -218,24 +218,23 @@ static void decode_macroblock(VP8D_COMP *pbi, MACROBLOCKD *xd,
   if (xd->segmentation_enabled)
     mb_init_dequantizer(pbi, xd);
 
-#if CONFIG_SUPERBLOCKS
-  if (xd->mode_info_context->mbmi.encoded_as_sb) {
-    xd->mode_info_context->mbmi.txfm_size = TX_8X8;
-  }
-#endif
-
   tx_size = xd->mode_info_context->mbmi.txfm_size;
   mode = xd->mode_info_context->mbmi.mode;
 
   if (xd->mode_info_context->mbmi.mb_skip_coeff) {
     vp8_reset_mb_tokens_context(xd);
 #if CONFIG_SUPERBLOCKS
-    if (xd->mode_info_context->mbmi.encoded_as_sb) {
-      xd->above_context++;
-      xd->left_context++;
+    if (xd->mode_info_context->mbmi.encoded_as_sb &&
+        (mb_col < pc->mb_cols - 1 || mb_row < pc->mb_rows - 1)) {
+      if (mb_col < pc->mb_cols - 1)
+        xd->above_context++;
+      if (mb_row < pc->mb_rows - 1)
+        xd->left_context++;
       vp8_reset_mb_tokens_context(xd);
-      xd->above_context--;
-      xd->left_context--;
+      if (mb_col < pc->mb_cols - 1)
+        xd->above_context--;
+      if (mb_row < pc->mb_rows - 1)
+        xd->left_context--;
     }
 #endif
   } else if (!vp8dx_bool_error(bc)) {
@@ -411,6 +410,11 @@ static void decode_macroblock(VP8D_COMP *pbi, MACROBLOCKD *xd,
       void *orig = xd->mode_info_context;
       int n, num = xd->mode_info_context->mbmi.encoded_as_sb ? 4 : 1;
       for (n = 0; n < num; n++) {
+        int x_idx = n & 1, y_idx = n >> 1;
+        if (num == 4 && (mb_col + x_idx >= pc->mb_cols ||
+                         mb_row + y_idx >= pc->mb_rows))
+          continue;
+
         if (n != 0) {
           for (i = 0; i < 25; i++) {
             xd->block[i].eob = 0;
@@ -653,20 +657,17 @@ decode_sb_row(VP8D_COMP *pbi, VP8_COMMON *pc, int mbrow, MACROBLOCKD *xd,
 
 #if CONFIG_SUPERBLOCKS
       if (xd->mode_info_context->mbmi.encoded_as_sb) {
-        mi[1] = mi[0];
-        mi[pc->mode_info_stride] = mi[0];
-        mi[pc->mode_info_stride + 1] = mi[0];
+        if (mb_col < pc->mb_cols - 1)
+          mi[1] = mi[0];
+        if (mb_row < pc->mb_rows - 1) {
+          mi[pc->mode_info_stride] = mi[0];
+          if (mb_col < pc->mb_cols - 1)
+            mi[pc->mode_info_stride + 1] = mi[0];
+        }
       }
 #endif
       vp8_intra_prediction_down_copy(xd);
-      decode_macroblock(pbi, xd, mb_col, bc);
-#if CONFIG_SUPERBLOCKS
-      if (xd->mode_info_context->mbmi.encoded_as_sb) {
-        mi[1].mbmi.txfm_size = mi[0].mbmi.txfm_size;
-        mi[pc->mode_info_stride].mbmi.txfm_size = mi[0].mbmi.txfm_size;
-        mi[pc->mode_info_stride + 1].mbmi.txfm_size = mi[0].mbmi.txfm_size;
-      }
-#endif
+      decode_macroblock(pbi, xd, mb_row, mb_col, bc);
 
       /* check if the boolean decoder has suffered an error */
       xd->corrupted |= vp8dx_bool_error(bc);
index 4c1d61ed87fe748c5c3ed96b033c2f6d3230c793..ff7d836d7b05a4cf8e7497fe1b790a532ea01766 100644 (file)
@@ -744,8 +744,22 @@ static unsigned int pick_best_mv_ref(MACROBLOCK *x,
 static void write_mb_segid(vp8_writer *bc,
                            const MB_MODE_INFO *mi, const MACROBLOCKD *xd) {
   // Encode the MB segment id.
+  int seg_id = mi->segment_id;
+#if CONFIG_SUPERBLOCKS
+  if (mi->encoded_as_sb) {
+    if (xd->mb_to_right_edge > 0)
+      seg_id = seg_id && xd->mode_info_context[1].mbmi.segment_id;
+    if (xd->mb_to_bottom_edge > 0) {
+      seg_id = seg_id &&
+               xd->mode_info_context[xd->mode_info_stride].mbmi.segment_id;
+      if (xd->mb_to_right_edge > 0)
+        seg_id = seg_id &&
+                xd->mode_info_context[xd->mode_info_stride + 1].mbmi.segment_id;
+    }
+  }
+#endif
   if (xd->segmentation_enabled && xd->update_mb_segmentation_map) {
-    switch (mi->segment_id) {
+    switch (seg_id) {
       case 0:
         vp8_write(bc, 0, xd->mb_segment_tree_probs[0]);
         vp8_write(bc, 0, xd->mb_segment_tree_probs[1]);
@@ -952,7 +966,6 @@ static void pack_inter_mode_mvs(VP8_COMP *const cpi, vp8_writer *const bc) {
 #ifdef ENTROPY_STATS
         active_section = 9;
 #endif
-
         if (cpi->mb.e_mbd.update_mb_segmentation_map) {
           // Is temporal coding of the segment map enabled
           if (pc->temporal_update) {
@@ -1245,7 +1258,11 @@ static void pack_inter_mode_mvs(VP8_COMP *const cpi, vp8_writer *const bc) {
           }
         }
 
-        if (((rf == INTRA_FRAME && mode <= I8X8_PRED) ||
+        if (
+#if CONFIG_SUPERBLOCKS
+            !mi->encoded_as_sb &&
+#endif
+            ((rf == INTRA_FRAME && mode <= I8X8_PRED) ||
              (rf != INTRA_FRAME && !(mode == SPLITMV &&
                                      mi->partitioning == PARTITIONING_4X4))) &&
             pc->txfm_mode == TX_MODE_SELECT &&
@@ -1386,7 +1403,11 @@ static void write_mb_modes_kf(const VP8_COMMON  *c,
   } else
     write_uv_mode(bc, m->mbmi.uv_mode, c->kf_uv_mode_prob[ym]);
 
-  if (ym <= I8X8_PRED && c->txfm_mode == TX_MODE_SELECT &&
+  if (
+#if CONFIG_SUPERBLOCKS
+      !m->mbmi.encoded_as_sb &&
+#endif
+      ym <= I8X8_PRED && c->txfm_mode == TX_MODE_SELECT &&
       !((c->mb_no_coeff_skip && m->mbmi.mb_skip_coeff) ||
         (segfeature_active(xd, segment_id, SEG_LVL_EOB) &&
          get_segdata(xd, segment_id, SEG_LVL_EOB) == 0))) {
index e464fde38b8953a13953c9f527e356576b0d8491..0a9a6360705489b5fdbcce7034fc1c37ca2ad9ab 100644 (file)
@@ -389,9 +389,14 @@ static void update_state(VP8_COMP *cpi, MACROBLOCK *x, PICK_MODE_CONTEXT *ctx) {
   vpx_memcpy(xd->mode_info_context, mi, sizeof(MODE_INFO));
 #if CONFIG_SUPERBLOCKS
   if (mi->mbmi.encoded_as_sb) {
-    vpx_memcpy(xd->mode_info_context + 1, mi, sizeof(MODE_INFO));
-    vpx_memcpy(xd->mode_info_context + cpi->common.mode_info_stride, mi, sizeof(MODE_INFO));
-    vpx_memcpy(xd->mode_info_context + cpi->common.mode_info_stride + 1, mi, sizeof(MODE_INFO));
+    const int mis = cpi->common.mode_info_stride;
+    if (xd->mb_to_right_edge > 0)
+      vpx_memcpy(xd->mode_info_context + 1, mi, sizeof(MODE_INFO));
+    if (xd->mb_to_bottom_edge > 0) {
+      vpx_memcpy(xd->mode_info_context + mis, mi, sizeof(MODE_INFO));
+      if (xd->mb_to_right_edge > 0)
+        vpx_memcpy(xd->mode_info_context + mis + 1, mi, sizeof(MODE_INFO));
+    }
   }
 #endif
 
@@ -1442,25 +1447,47 @@ static int check_dual_ref_flags(VP8_COMP *cpi) {
 
 static void reset_skip_txfm_size(VP8_COMP *cpi, TX_SIZE txfm_max) {
   VP8_COMMON *cm = &cpi->common;
-  int mb_row, mb_col, mis = cm->mode_info_stride;
+  int mb_row, mb_col, mis = cm->mode_info_stride, segment_id;
   MODE_INFO *mi, *mi_ptr = cm->mi;
+#if CONFIG_SUPERBLOCKS
+  MODE_INFO *sb_mi_ptr = cm->mi, *sb_mi;
+  MB_MODE_INFO *sb_mbmi;
+#endif
   MB_MODE_INFO *mbmi;
   MACROBLOCK *x = &cpi->mb;
   MACROBLOCKD *xd = &x->e_mbd;
 
   for (mb_row = 0; mb_row < cm->mb_rows; mb_row++, mi_ptr += mis) {
     mi = mi_ptr;
+#if CONFIG_SUPERBLOCKS
+    sb_mi = sb_mi_ptr;
+#endif
     for (mb_col = 0; mb_col < cm->mb_cols; mb_col++, mi++) {
       mbmi = &mi->mbmi;
-      if (mbmi->txfm_size > txfm_max) {
-        int segment_id = mbmi->segment_id;
+#if CONFIG_SUPERBLOCKS
+      sb_mbmi = &sb_mi->mbmi;
+#endif
+      if (
+#if CONFIG_SUPERBLOCKS
+          !sb_mbmi->encoded_as_sb &&
+#endif
+          mbmi->txfm_size > txfm_max) {
+        segment_id = mbmi->segment_id;
         xd->mode_info_context = mi;
         assert((segfeature_active(xd, segment_id, SEG_LVL_EOB) &&
                 get_segdata(xd, segment_id, SEG_LVL_EOB) == 0) ||
                (cm->mb_no_coeff_skip && mbmi->mb_skip_coeff));
         mbmi->txfm_size = txfm_max;
       }
+#if CONFIG_SUPERBLOCKS
+      if (mb_col & 1)
+        sb_mi += 2;
+#endif
     }
+#if CONFIG_SUPERBLOCKS
+    if (mb_row & 1)
+      sb_mi_ptr += 2 * mis;
+#endif
   }
 }
 
@@ -1854,8 +1881,7 @@ void vp8cx_encode_intra_super_block(VP8_COMP *cpi,
   vp8_build_intra_predictors_sbuv_s(&x->e_mbd);
 
   assert(x->e_mbd.mode_info_context->mbmi.txfm_size == TX_8X8);
-  for (n = 0; n < 4; n++)
-  {
+  for (n = 0; n < 4; n++) {
     int x_idx = n & 1, y_idx = n >> 1;
 
     xd->above_context = cm->above_context + mb_col + (n & 1);
@@ -2249,8 +2275,7 @@ void vp8cx_encode_inter_superblock(VP8_COMP *cpi, MACROBLOCK *x, TOKENEXTRA **t,
   }
 
   assert(x->e_mbd.mode_info_context->mbmi.txfm_size == TX_8X8);
-  for (n = 0; n < 4; n++)
-  {
+  for (n = 0; n < 4; n++) {
     int x_idx = n & 1, y_idx = n >> 1;
 
     vp8_subtract_mby_s_c(x->src_diff,
@@ -2281,7 +2306,7 @@ void vp8cx_encode_inter_superblock(VP8_COMP *cpi, MACROBLOCK *x, TOKENEXTRA **t,
     if (!x->skip) {
       if (output_enabled) {
         xd->left_context = cm->left_context + (n >> 1);
-        xd->above_context = cm->above_context + mb_col + (n >> 1);
+        xd->above_context = cm->above_context + mb_col + (n & 1);
         memcpy(&ta[n], xd->above_context, sizeof(ta[n]));
         memcpy(&tl[n], xd->left_context, sizeof(tl[n]));
         tp[n] = *t;
@@ -2298,7 +2323,7 @@ void vp8cx_encode_inter_superblock(VP8_COMP *cpi, MACROBLOCK *x, TOKENEXTRA **t,
       if (cpi->common.mb_no_coeff_skip) {
         skip[n] = xd->mode_info_context->mbmi.mb_skip_coeff = 1;
         xd->left_context = cm->left_context + (n >> 1);
-        xd->above_context = cm->above_context + mb_col + (n >> 1);
+        xd->above_context = cm->above_context + mb_col + (n & 1);
         memcpy(&ta[n], xd->above_context, sizeof(ta[n]));
         memcpy(&tl[n], xd->left_context, sizeof(tl[n]));
         tp[n] = *t;
index 1c37eb1331c47a2355952bd39bbcec7ed908870c..3fefc8ad9b033b9fcc6456198c206f13c78f0be4 100644 (file)
@@ -629,8 +629,14 @@ static void update_reference_segmentation_map(VP8_COMP *cpi) {
       uint8_t *cache = segcache + col * 2;
 #if CONFIG_SUPERBLOCKS
       if (miptr->mbmi.encoded_as_sb) {
-        cache[0] = cache[1] = cache[cm->mb_cols] = cache[cm->mb_cols + 1] =
-          miptr->mbmi.segment_id;
+        cache[0] = miptr->mbmi.segment_id;
+        if (!(cm->mb_cols & 1) || col < sb_cols - 1)
+          cache[1] = miptr->mbmi.segment_id;
+        if (!(cm->mb_rows & 1) || row < sb_rows - 1) {
+          cache[cm->mb_cols] = miptr->mbmi.segment_id;
+          if (!(cm->mb_cols & 1) || col < sb_cols - 1)
+            cache[cm->mb_cols + 1] = miptr->mbmi.segment_id;
+        }
       } else
 #endif
       {
index b94b736bcd1a08ed07988f6bfa0905f7f571c82c..75a767b197e4dd32b186643166d71d0baf97f732 100644 (file)
@@ -353,7 +353,7 @@ typedef struct VP8_ENCODER_RTCD {
   vp8_temporal_rtcd_vtable_t  temporal;
 } VP8_ENCODER_RTCD;
 
-enum {
+enum BlockSize {
   BLOCK_16X8 = PARTITIONING_16X8,
   BLOCK_8X16 = PARTITIONING_8X16,
   BLOCK_8X8 = PARTITIONING_8X8,
index 12ff9c3eccc6f2d23267b6b390d7eb0d2d005aec..410996942ab3c9056b9f2d86f6a946166e7c712e 100644 (file)
@@ -2941,11 +2941,17 @@ void vp8_mv_pred(VP8_COMP *cpi, MACROBLOCKD *xd, const MODE_INFO *here,
   vp8_clamp_mv2(mvp, xd);
 }
 
-void vp8_cal_sad(VP8_COMP *cpi, MACROBLOCKD *xd, MACROBLOCK *x, int recon_yoffset, int near_sadidx[]) {
-
-  int near_sad[8] = {0}; // 0-cf above, 1-cf left, 2-cf aboveleft, 3-lf current, 4-lf above, 5-lf left, 6-lf right, 7-lf below
+static void cal_sad(VP8_COMP *cpi, MACROBLOCKD *xd, MACROBLOCK *x,
+                    int recon_yoffset, int near_sadidx[],
+                    enum BlockSize block_size) {
+  /* 0-cf above, 1-cf left, 2-cf aboveleft, 3-lf current, 4-lf above,
+   * 5-lf left, 6-lf right, 7-lf below */
+  int near_sad[8] = {0};
   BLOCK *b = &x->block[0];
   unsigned char *src_y_ptr = *(b->base_src);
+  const unsigned char *dst_y_ptr = xd->dst.y_buffer;
+  const int bs = (block_size == BLOCK_16X16) ? 16 : 32;
+  const int dst_y_str = xd->dst.y_stride;
 
   // calculate sad for current frame 3 nearby MBs.
   if (xd->mb_to_top_edge == 0 && xd->mb_to_left_edge == 0) {
@@ -2953,36 +2959,56 @@ void vp8_cal_sad(VP8_COMP *cpi, MACROBLOCKD *xd, MACROBLOCK *x, int recon_yoffse
   } else if (xd->mb_to_top_edge == 0) {
     // only has left MB for sad calculation.
     near_sad[0] = near_sad[2] = INT_MAX;
-    near_sad[1] = cpi->fn_ptr[BLOCK_16X16].sdf(src_y_ptr, b->src_stride, xd->dst.y_buffer - 16, xd->dst.y_stride, 0x7fffffff);
+    near_sad[1] = cpi->fn_ptr[block_size].sdf(src_y_ptr, b->src_stride,
+                                              dst_y_ptr - bs,
+                                              dst_y_str, 0x7fffffff);
   } else if (xd->mb_to_left_edge == 0) {
     // only has left MB for sad calculation.
     near_sad[1] = near_sad[2] = INT_MAX;
-    near_sad[0] = cpi->fn_ptr[BLOCK_16X16].sdf(src_y_ptr, b->src_stride, xd->dst.y_buffer - xd->dst.y_stride * 16, xd->dst.y_stride, 0x7fffffff);
+    near_sad[0] = cpi->fn_ptr[block_size].sdf(src_y_ptr, b->src_stride,
+                                              dst_y_ptr - dst_y_str * bs,
+                                              dst_y_str, 0x7fffffff);
   } else {
-    near_sad[0] = cpi->fn_ptr[BLOCK_16X16].sdf(src_y_ptr, b->src_stride, xd->dst.y_buffer - xd->dst.y_stride * 16, xd->dst.y_stride, 0x7fffffff);
-    near_sad[1] = cpi->fn_ptr[BLOCK_16X16].sdf(src_y_ptr, b->src_stride, xd->dst.y_buffer - 16, xd->dst.y_stride, 0x7fffffff);
-    near_sad[2] = cpi->fn_ptr[BLOCK_16X16].sdf(src_y_ptr, b->src_stride, xd->dst.y_buffer - xd->dst.y_stride * 16 - 16, xd->dst.y_stride, 0x7fffffff);
+    near_sad[0] = cpi->fn_ptr[block_size].sdf(src_y_ptr, b->src_stride,
+                                              dst_y_ptr - dst_y_str * bs,
+                                              dst_y_str, 0x7fffffff);
+    near_sad[1] = cpi->fn_ptr[block_size].sdf(src_y_ptr, b->src_stride,
+                                              dst_y_ptr - bs,
+                                              dst_y_str, 0x7fffffff);
+    near_sad[2] = cpi->fn_ptr[block_size].sdf(src_y_ptr, b->src_stride,
+                                              dst_y_ptr - dst_y_str * bs - bs,
+                                              dst_y_str, 0x7fffffff);
   }
 
   if (cpi->common.last_frame_type != KEY_FRAME) {
     // calculate sad for last frame 5 nearby MBs.
     unsigned char *pre_y_buffer = cpi->common.yv12_fb[cpi->common.lst_fb_idx].y_buffer + recon_yoffset;
-    int pre_y_stride = cpi->common.yv12_fb[cpi->common.lst_fb_idx].y_stride;
+    const int pre_y_str = cpi->common.yv12_fb[cpi->common.lst_fb_idx].y_stride;
 
     if (xd->mb_to_top_edge == 0) near_sad[4] = INT_MAX;
     if (xd->mb_to_left_edge == 0) near_sad[5] = INT_MAX;
     if (xd->mb_to_right_edge == 0) near_sad[6] = INT_MAX;
     if (xd->mb_to_bottom_edge == 0) near_sad[7] = INT_MAX;
 
+    near_sad[3] = cpi->fn_ptr[block_size].sdf(src_y_ptr, b->src_stride,
+                                              pre_y_buffer,
+                                              pre_y_str, 0x7fffffff);
     if (near_sad[4] != INT_MAX)
-      near_sad[4] = cpi->fn_ptr[BLOCK_16X16].sdf(src_y_ptr, b->src_stride, pre_y_buffer - pre_y_stride * 16, pre_y_stride, 0x7fffffff);
+      near_sad[4] = cpi->fn_ptr[block_size].sdf(src_y_ptr, b->src_stride,
+                                                pre_y_buffer - pre_y_str * bs,
+                                                pre_y_str, 0x7fffffff);
     if (near_sad[5] != INT_MAX)
-      near_sad[5] = cpi->fn_ptr[BLOCK_16X16].sdf(src_y_ptr, b->src_stride, pre_y_buffer - 16, pre_y_stride, 0x7fffffff);
-    near_sad[3] = cpi->fn_ptr[BLOCK_16X16].sdf(src_y_ptr, b->src_stride, pre_y_buffer, pre_y_stride, 0x7fffffff);
+      near_sad[5] = cpi->fn_ptr[block_size].sdf(src_y_ptr, b->src_stride,
+                                                pre_y_buffer - bs,
+                                                pre_y_str, 0x7fffffff);
     if (near_sad[6] != INT_MAX)
-      near_sad[6] = cpi->fn_ptr[BLOCK_16X16].sdf(src_y_ptr, b->src_stride, pre_y_buffer + 16, pre_y_stride, 0x7fffffff);
+      near_sad[6] = cpi->fn_ptr[block_size].sdf(src_y_ptr, b->src_stride,
+                                                pre_y_buffer + bs,
+                                                pre_y_str, 0x7fffffff);
     if (near_sad[7] != INT_MAX)
-      near_sad[7] = cpi->fn_ptr[BLOCK_16X16].sdf(src_y_ptr, b->src_stride, pre_y_buffer + pre_y_stride * 16, pre_y_stride, 0x7fffffff);
+      near_sad[7] = cpi->fn_ptr[block_size].sdf(src_y_ptr, b->src_stride,
+                                                pre_y_buffer + pre_y_str * bs,
+                                                pre_y_str, 0x7fffffff);
   }
 
   if (cpi->common.last_frame_type != KEY_FRAME) {
@@ -3181,7 +3207,11 @@ static void store_coding_context(MACROBLOCK *x, PICK_MODE_CONTEXT *ctx,
   ctx->comp_pred_diff   = comp_pred_diff;
   ctx->hybrid_pred_diff = hybrid_pred_diff;
 
-  memcpy(ctx->txfm_rd_diff, txfm_size_diff, sizeof(ctx->txfm_rd_diff));
+  if (txfm_size_diff) {
+    memcpy(ctx->txfm_rd_diff, txfm_size_diff, sizeof(ctx->txfm_rd_diff));
+  } else {
+    memset(ctx->txfm_rd_diff, 0, sizeof(ctx->txfm_rd_diff));
+  }
 }
 
 static void inter_mode_cost(VP8_COMP *cpi, MACROBLOCK *x, int this_mode,
@@ -3248,11 +3278,258 @@ void setup_buffer_inter(VP8_COMP *cpi, MACROBLOCK *x, int idx, int frame_type,
 #endif
 }
 
+static int64_t handle_inter_mode(VP8_COMP *cpi, MACROBLOCK *x,
+                                 enum BlockSize block_size,
+                                 int *saddone, int near_sadidx[],
+                                 int mdcounts[4], int64_t txfm_cache[],
+                                 int *rate2, int *distortion, int *skippable,
+                                 int *compmode_cost,
+                                 int *rate_y, int *distortion_y,
+                                 int *rate_uv, int *distortion_uv,
+                                 int *mode_excluded, int *disable_skip,
+                                 int recon_yoffset, int mode_index,
+                                 int_mv frame_mv[MB_MODE_COUNT][MAX_REF_FRAMES],
+                                 int_mv frame_best_ref_mv[4]) {
+  VP8_COMMON *cm = &cpi->common;
+  MACROBLOCKD *xd = &x->e_mbd;
+  MB_MODE_INFO *mbmi = &xd->mode_info_context->mbmi;
+  BLOCK *b = &x->block[0];
+  BLOCKD *d = &xd->block[0];
+  const int is_comp_pred = (mbmi->second_ref_frame != 0);
+  const int num_refs = is_comp_pred ? 2 : 1;
+  const int this_mode = mbmi->mode;
+  int i;
+  int refs[2] = { mbmi->ref_frame, mbmi->second_ref_frame };
+  int_mv cur_mv[2];
+  int_mv mvp;
+  int64_t this_rd = 0;
+
+  switch (this_mode) {
+    case NEWMV:
+      if (is_comp_pred) {
+        if (frame_mv[NEWMV][refs[0]].as_int == INVALID_MV ||
+            frame_mv[NEWMV][refs[1]].as_int == INVALID_MV)
+          return INT64_MAX;
+        *rate2 += vp8_mv_bit_cost(&frame_mv[NEWMV][refs[0]],
+                                  &frame_best_ref_mv[refs[0]],
+                                  XMVCOST, 96,
+                                  x->e_mbd.allow_high_precision_mv);
+        *rate2 += vp8_mv_bit_cost(&frame_mv[NEWMV][refs[1]],
+                                  &frame_best_ref_mv[refs[1]],
+                                  XMVCOST, 96,
+                                  x->e_mbd.allow_high_precision_mv);
+      } else {
+        int bestsme = INT_MAX;
+        int further_steps, step_param = cpi->sf.first_step;
+        int sadpb = x->sadperbit16;
+        int_mv mvp_full, tmp_mv;
+        // search range got from mv_pred(). It uses step_param levels. (0-7)
+        int sr = 0;
+
+        int tmp_col_min = x->mv_col_min;
+        int tmp_col_max = x->mv_col_max;
+        int tmp_row_min = x->mv_row_min;
+        int tmp_row_max = x->mv_row_max;
+
+        vp8_clamp_mv_min_max(x, &frame_best_ref_mv[refs[0]]);
+
+        if (!*saddone) {
+          cal_sad(cpi, xd, x, recon_yoffset, &near_sadidx[0], block_size);
+          *saddone = 1;
+        }
+
+        vp8_mv_pred(cpi, &x->e_mbd, x->e_mbd.mode_info_context, &mvp,
+                    mbmi->ref_frame, cpi->common.ref_frame_sign_bias,
+                    &sr, &near_sadidx[0]);
+
+        mvp_full.as_mv.col = mvp.as_mv.col >> 3;
+        mvp_full.as_mv.row = mvp.as_mv.row >> 3;
+
+        // adjust search range according to sr from mv prediction
+        step_param = MAX(step_param, sr);
+
+        // Further step/diamond searches as necessary
+        further_steps = (cpi->sf.max_step_search_steps - 1) - step_param;
+
+        bestsme = vp8_full_pixel_diamond(cpi, x, b, d, &mvp_full, step_param,
+                                         sadpb, further_steps, 1,
+                                         &cpi->fn_ptr[block_size],
+                                         &frame_best_ref_mv[refs[0]], &tmp_mv);
+
+        x->mv_col_min = tmp_col_min;
+        x->mv_col_max = tmp_col_max;
+        x->mv_row_min = tmp_row_min;
+        x->mv_row_max = tmp_row_max;
+
+        if (bestsme < INT_MAX) {
+          int dis; /* TODO: use dis in distortion calculation later. */
+          unsigned int sse;
+          cpi->find_fractional_mv_step(x, b, d, &tmp_mv,
+                                       &frame_best_ref_mv[refs[0]],
+                                       x->errorperbit,
+                                       &cpi->fn_ptr[block_size],
+                                       XMVCOST, &dis, &sse);
+        }
+        d->bmi.as_mv.first.as_int = tmp_mv.as_int;
+        frame_mv[NEWMV][refs[0]].as_int = d->bmi.as_mv.first.as_int;
+
+        // Add the new motion vector cost to our rolling cost variable
+        *rate2 += vp8_mv_bit_cost(&tmp_mv, &frame_best_ref_mv[refs[0]],
+                                  XMVCOST, 96, xd->allow_high_precision_mv);
+      }
+      break;
+    case NEARESTMV:
+    case NEARMV:
+      // Do not bother proceeding if the vector (from newmv, nearest or
+      // near) is 0,0 as this should then be coded using the zeromv mode.
+      for (i = 0; i < num_refs; ++i)
+        if (frame_mv[this_mode][refs[i]].as_int == 0)
+          return INT64_MAX;
+    case ZEROMV:
+    default:
+      break;
+  }
+  for (i = 0; i < num_refs; ++i) {
+    cur_mv[i] = frame_mv[this_mode][refs[i]];
+    // Clip "next_nearest" so that it does not extend to far out of image
+    vp8_clamp_mv2(&cur_mv[i], xd);
+    if (mv_check_bounds(x, &cur_mv[i]))
+      return INT64_MAX;
+    mbmi->mv[i].as_int = cur_mv[i].as_int;
+  }
+
+#if CONFIG_PRED_FILTER
+  // Filtered prediction:
+  mbmi->pred_filter_enabled = vp8_mode_order[mode_index].pred_filter_flag;
+  *rate2 += vp8_cost_bit(cpi->common.prob_pred_filter_off,
+                         mbmi->pred_filter_enabled);
+#endif
+  if (cpi->common.mcomp_filter_type == SWITCHABLE) {
+    const int c = vp9_get_pred_context(cm, xd, PRED_SWITCHABLE_INTERP);
+    const int m = vp8_switchable_interp_map[mbmi->interp_filter];
+    *rate2 += SWITCHABLE_INTERP_RATE_FACTOR * x->switchable_interp_costs[c][m];
+  }
+
+  /* We don't include the cost of the second reference here, because there
+   * are only three options: Last/Golden, ARF/Last or Golden/ARF, or in other
+   * words if you present them in that order, the second one is always known
+   * if the first is known */
+  *compmode_cost = vp8_cost_bit(vp9_get_pred_prob(cm, xd, PRED_COMP),
+                                is_comp_pred);
+  *rate2 += vp8_cost_mv_ref(cpi, this_mode, mdcounts);
+
+  if (block_size == BLOCK_16X16) {
+    vp8_build_1st_inter16x16_predictors_mby(xd, xd->predictor, 16, 0);
+    if (is_comp_pred)
+      vp8_build_2nd_inter16x16_predictors_mby(xd, xd->predictor, 16);
+  } else {
+#if CONFIG_SUPERBLOCKS
+    vp8_build_inter32x32_predictors_sb(xd,
+                                       xd->dst.y_buffer,
+                                       xd->dst.u_buffer,
+                                       xd->dst.v_buffer,
+                                       xd->dst.y_stride,
+                                       xd->dst.uv_stride);
+#endif
+  }
+
+  if (cpi->active_map_enabled && x->active_ptr[0] == 0)
+    x->skip = 1;
+  else if (x->encode_breakout) {
+    unsigned int sse, var;
+    int threshold = (xd->block[0].dequant[1]
+                     * xd->block[0].dequant[1] >> 4);
+
+    if (threshold < x->encode_breakout)
+      threshold = x->encode_breakout;
+
+    if (block_size == BLOCK_16X16) {
+      var = vp8_variance16x16(*(b->base_src), b->src_stride,
+                              xd->predictor, 16, &sse);
+    } else {
+#if CONFIG_SUPERBLOCKS
+      var = vp8_variance32x32(*(b->base_src), b->src_stride,
+                              xd->dst.y_buffer, xd->dst.y_stride, &sse);
+#endif
+    }
+
+    if (sse < threshold) {
+      unsigned int q2dc = xd->block[24].dequant[0];
+      /* If there is no codeable 2nd order dc
+       or a very small uniform pixel change change */
+      if ((sse - var < q2dc * q2dc >> 4) ||
+          (sse / 2 > var && sse - var < 64)) {
+        // Check u and v to make sure skip is ok
+        int sse2;
+
+        if (block_size == BLOCK_16X16) {
+          sse2 = vp8_uvsse(x);
+        } else {
+          unsigned int sse2u, sse2v;
+          var = vp8_variance16x16(x->src.u_buffer, x->src.uv_stride,
+                                  xd->dst.u_buffer, xd->dst.uv_stride, &sse2u);
+          var = vp8_variance16x16(x->src.v_buffer, x->src.uv_stride,
+                                  xd->dst.v_buffer, xd->dst.uv_stride, &sse2v);
+          sse2 = sse2u + sse2v;
+        }
+
+        if (sse2 * 2 < threshold) {
+          x->skip = 1;
+          *distortion = sse + sse2;
+          *rate2 = 500;
+
+          /* for best_yrd calculation */
+          *rate_uv = 0;
+          *distortion_uv = sse2;
+
+          *disable_skip = 1;
+          this_rd = RDCOST(x->rdmult, x->rddiv, *rate2, *distortion);
+        }
+      }
+    }
+  }
+
+  if (!x->skip) {
+    if (block_size == BLOCK_16X16) {
+      vp8_build_1st_inter16x16_predictors_mbuv(xd, &xd->predictor[256],
+                                               &xd->predictor[320], 8);
+      if (is_comp_pred)
+        vp8_build_2nd_inter16x16_predictors_mbuv(xd, &xd->predictor[256],
+                                                 &xd->predictor[320], 8);
+      inter_mode_cost(cpi, x, this_mode, rate2, distortion,
+                      rate_y, distortion_y, rate_uv, distortion_uv,
+                      skippable, txfm_cache);
+    } else {
+#if CONFIG_SUPERBLOCKS
+      int skippable_y, skippable_uv;
+
+      // Y cost and distortion - FIXME support other transform sizes
+      super_block_yrd_8x8(x, rate_y, distortion_y,
+                          IF_RTCD(&cpi->rtcd), &skippable_y);
+      *rate2 += *rate_y;
+      *distortion += *distortion_y;
+
+      rd_inter32x32_uv_8x8(cpi, x, rate_uv, distortion_uv,
+                           cm->full_pixel, &skippable_uv);
+
+      *rate2 += *rate_uv;
+      *distortion += *distortion_uv;
+      *skippable = skippable_y && skippable_uv;
+#endif
+    }
+  }
+  if (is_comp_pred) {
+    *mode_excluded = (cpi->common.comp_pred_mode == SINGLE_PREDICTION_ONLY);
+  } else {
+    *mode_excluded = (cpi->common.comp_pred_mode == COMP_PREDICTION_ONLY);
+  }
+
+  return this_rd;  // if 0, this will be re-calculated by caller
+}
+
 void vp8_rd_pick_inter_mode(VP8_COMP *cpi, MACROBLOCK *x, int recon_yoffset, int recon_uvoffset,
                             int *returnrate, int *returndistortion, int64_t *returnintra) {
   VP8_COMMON *cm = &cpi->common;
-  BLOCK *b = &x->block[0];
-  BLOCKD *d = &x->e_mbd.block[0];
   MACROBLOCKD *xd = &x->e_mbd;
   union b_mode_info best_bmodes[16];
   MB_MODE_INFO best_mbmode;
@@ -3291,10 +3568,8 @@ void vp8_rd_pick_inter_mode(VP8_COMP *cpi, MACROBLOCK *x, int recon_yoffset, int
   MB_PREDICTION_MODE uv_intra_mode;
   MB_PREDICTION_MODE uv_intra_mode_8x8 = 0;
 
-  int_mv mvp;
   int near_sadidx[8] = {0, 1, 2, 3, 4, 5, 6, 7};
   int saddone = 0;
-  int sr = 0;  // search range got from mv_pred(). It uses step_param levels. (0-7)
 
   int_mv frame_mv[MB_MODE_COUNT][MAX_REF_FRAMES];
   int_mv frame_best_ref_mv[4];
@@ -3377,7 +3652,6 @@ void vp8_rd_pick_inter_mode(VP8_COMP *cpi, MACROBLOCK *x, int recon_yoffset, int
   for (mode_index = 0; mode_index < MAX_MODES;
        mode_index += (!switchable_filter_index)) {
     int64_t this_rd = INT64_MAX;
-    int is_comp_pred;
     int disable_skip = 0, skippable = 0;
     int other_cost = 0;
     int compmode_cost = 0;
@@ -3395,7 +3669,6 @@ void vp8_rd_pick_inter_mode(VP8_COMP *cpi, MACROBLOCK *x, int recon_yoffset, int
     mbmi->uv_mode = DC_PRED;
     mbmi->ref_frame = vp8_mode_order[mode_index].ref_frame;
     mbmi->second_ref_frame = vp8_mode_order[mode_index].second_ref_frame;
-    is_comp_pred = xd->mode_info_context->mbmi.second_ref_frame != 0;
 #if CONFIG_PRED_FILTER
     mbmi->pred_filter_enabled = 0;
 #endif
@@ -3648,6 +3921,7 @@ void vp8_rd_pick_inter_mode(VP8_COMP *cpi, MACROBLOCK *x, int recon_yoffset, int
     // Split MV. The code is very different from the other inter modes so
     // special case it.
     else if (this_mode == SPLITMV) {
+      const int is_comp_pred = mbmi->second_ref_frame != 0;
       int64_t tmp_rd, this_rd_thresh;
       int_mv *second_ref = is_comp_pred ? &second_best_ref_mv : NULL;
 
@@ -3696,189 +3970,15 @@ void vp8_rd_pick_inter_mode(VP8_COMP *cpi, MACROBLOCK *x, int recon_yoffset, int
       mbmi->mode = this_mode;
     }
     else {
-      const int num_refs = is_comp_pred ? 2 : 1;
-      int flag, skip;
-      int refs[2] = {xd->mode_info_context->mbmi.ref_frame,
-                     xd->mode_info_context->mbmi.second_ref_frame};
-      int_mv cur_mv[2];
-      switch (this_mode) {
-        case NEWMV:
-          if (is_comp_pred) {
-            if (frame_mv[NEWMV][refs[0]].as_int == INVALID_MV ||
-                frame_mv[NEWMV][refs[1]].as_int == INVALID_MV)
-              continue;
-            rate2 += vp8_mv_bit_cost(&frame_mv[NEWMV][refs[0]],
-                                     &frame_best_ref_mv[refs[0]],
-                                     XMVCOST, 96,
-                                     xd->allow_high_precision_mv);
-            rate2 += vp8_mv_bit_cost(&frame_mv[NEWMV][refs[1]],
-                                     &frame_best_ref_mv[refs[1]],
-                                     XMVCOST, 96,
-                                     xd->allow_high_precision_mv);
-          } else {
-            int bestsme = INT_MAX;
-            int further_steps, step_param = cpi->sf.first_step;
-            int sadpb = x->sadperbit16;
-            int_mv mvp_full, tmp_mv;
-
-            int tmp_col_min = x->mv_col_min;
-            int tmp_col_max = x->mv_col_max;
-            int tmp_row_min = x->mv_row_min;
-            int tmp_row_max = x->mv_row_max;
-
-            vp8_clamp_mv_min_max(x, &best_ref_mv);
-
-            if (!saddone) {
-              vp8_cal_sad(cpi, xd, x, recon_yoffset, &near_sadidx[0]);
-              saddone = 1;
-            }
-
-            vp8_mv_pred(cpi, &x->e_mbd, xd->mode_info_context, &mvp,
-                        mbmi->ref_frame, cpi->common.ref_frame_sign_bias,
-                        &sr, &near_sadidx[0]);
-
-            mvp_full.as_mv.col = mvp.as_mv.col >> 3;
-            mvp_full.as_mv.row = mvp.as_mv.row >> 3;
-
-            // adjust search range according to sr from mv prediction
-            step_param = MAX(step_param, sr);
-
-            // Further step/diamond searches as necessary
-            further_steps = (cpi->sf.max_step_search_steps - 1) - step_param;
-
-            bestsme = vp8_full_pixel_diamond(cpi, x, b, d, &mvp_full, step_param,
-                                             sadpb, further_steps, 1,
-                                             &cpi->fn_ptr[BLOCK_16X16],
-                                             &best_ref_mv, &tmp_mv);
-
-            x->mv_col_min = tmp_col_min;
-            x->mv_col_max = tmp_col_max;
-            x->mv_row_min = tmp_row_min;
-            x->mv_row_max = tmp_row_max;
-
-            if (bestsme < INT_MAX) {
-              int dis; /* TODO: use dis in distortion calculation later. */
-              unsigned int sse;
-              cpi->find_fractional_mv_step(x, b, d, &tmp_mv, &best_ref_mv,
-                                           x->errorperbit,
-                                           &cpi->fn_ptr[BLOCK_16X16],
-                                           XMVCOST, &dis, &sse);
-            }
-            d->bmi.as_mv.first.as_int = tmp_mv.as_int;
-            frame_mv[NEWMV][refs[0]].as_int = d->bmi.as_mv.first.as_int;
-
-            // Add the new motion vector cost to our rolling cost variable
-            rate2 += vp8_mv_bit_cost(&tmp_mv, &best_ref_mv,
-                                     XMVCOST, 96,
-                                     xd->allow_high_precision_mv);
-          }
-          break;
-        case NEARESTMV:
-        case NEARMV:
-          flag = 0;
-          // Do not bother proceeding if the vector (from newmv, nearest or
-          // near) is 0,0 as this should then be coded using the zeromv mode.
-          for (i = 0; i < num_refs; ++i)
-            if (frame_mv[this_mode][refs[i]].as_int == 0)
-              flag = 1;
-          if (flag)
-            continue;
-
-        case ZEROMV:
-
-        default:
-          break;
-      }
-      flag = 0;
-      for (i = 0; i < num_refs; ++i) {
-        cur_mv[i] = frame_mv[this_mode][refs[i]];
-        // Clip "next_nearest" so that it does not extend to far out of image
-        vp8_clamp_mv2(&cur_mv[i], xd);
-        if (mv_check_bounds(x, &cur_mv[i]))
-          flag = 1;
-        xd->mode_info_context->mbmi.mv[i].as_int = cur_mv[i].as_int;
-      }
-      if (flag)
+      this_rd = handle_inter_mode(cpi, x, BLOCK_16X16,
+                                  &saddone, near_sadidx, mdcounts, txfm_cache,
+                                  &rate2, &distortion2, &skippable,
+                                  &compmode_cost, &rate_y, &distortion,
+                                  &rate_uv, &distortion_uv,
+                                  &mode_excluded, &disable_skip, recon_yoffset,
+                                  mode_index, frame_mv, frame_best_ref_mv);
+      if (this_rd == INT64_MAX)
         continue;
-
-#if CONFIG_PRED_FILTER
-      // Filtered prediction:
-      xd->mode_info_context->mbmi.pred_filter_enabled =
-        vp8_mode_order[mode_index].pred_filter_flag;
-      rate2 += vp8_cost_bit(cpi->common.prob_pred_filter_off,
-                            xd->mode_info_context->mbmi.pred_filter_enabled);
-#endif
-      if (cpi->common.mcomp_filter_type == SWITCHABLE)
-        rate2 += SWITCHABLE_INTERP_RATE_FACTOR * x->switchable_interp_costs
-            [vp9_get_pred_context(&cpi->common, xd, PRED_SWITCHABLE_INTERP)]
-            [vp8_switchable_interp_map[
-            xd->mode_info_context->mbmi.interp_filter]];
-
-      /* We don't include the cost of the second reference here, because there are only
-       * three options: Last/Golden, ARF/Last or Golden/ARF, or in other words if you
-       * present them in that order, the second one is always known if the first is known */
-      compmode_cost = vp8_cost_bit(vp9_get_pred_prob(cm, xd, PRED_COMP),
-                                   is_comp_pred);
-      rate2 += vp8_cost_mv_ref(cpi, this_mode, mdcounts);
-
-      vp8_build_1st_inter16x16_predictors_mby(&x->e_mbd, xd->predictor,
-                                              16, 0);
-      if (is_comp_pred)
-        vp8_build_2nd_inter16x16_predictors_mby(&x->e_mbd, xd->predictor,
-                                                16);
-
-      if (cpi->active_map_enabled && x->active_ptr[0] == 0)
-        x->skip = 1;
-      else if (x->encode_breakout) {
-        unsigned int sse, var;
-        int threshold = (xd->block[0].dequant[1]
-                         * xd->block[0].dequant[1] >> 4);
-
-        if (threshold < x->encode_breakout)
-          threshold = x->encode_breakout;
-
-        var = vp8_variance16x16(*(b->base_src), b->src_stride,
-               xd->predictor, 16, &sse);
-
-        if (sse < threshold) {
-          unsigned int q2dc = xd->block[24].dequant[0];
-          /* If there is no codeable 2nd order dc
-             or a very small uniform pixel change change */
-          if ((sse - var < q2dc *q2dc >> 4) ||
-              (sse / 2 > var && sse - var < 64)) {
-            // Check u and v to make sure skip is ok
-            int sse2 =  vp8_uvsse(x);
-            if (sse2 * 2 < threshold) {
-              x->skip = 1;
-              distortion2 = sse + sse2;
-              rate2 = 500;
-
-              /* for best_yrd calculation */
-              rate_uv = 0;
-              distortion_uv = sse2;
-
-              disable_skip = 1;
-              this_rd = RDCOST(x->rdmult, x->rddiv, rate2, distortion2);
-            }
-          }
-        }
-      }
-
-      if (!x->skip) {
-        vp8_build_1st_inter16x16_predictors_mbuv(&x->e_mbd, &xd->predictor[256],
-                                                 &xd->predictor[320], 8);
-        if (is_comp_pred)
-          vp8_build_2nd_inter16x16_predictors_mbuv(&x->e_mbd,
-                                                   &xd->predictor[256],
-                                                   &xd->predictor[320], 8);
-        inter_mode_cost(cpi, x, this_mode, &rate2, &distortion2,
-                        &rate_y, &distortion, &rate_uv, &distortion_uv,
-                        &skippable, txfm_cache);
-      }
-      if (is_comp_pred)
-        mode_excluded = cpi->common.comp_pred_mode == SINGLE_PREDICTION_ONLY;
-      else
-        mode_excluded = cpi->common.comp_pred_mode == COMP_PREDICTION_ONLY;
     }
 
     if (cpi->common.comp_pred_mode == HYBRID_PREDICTION)
@@ -3895,9 +3995,6 @@ void vp8_rd_pick_inter_mode(VP8_COMP *cpi, MACROBLOCK *x, int recon_yoffset, int
       // segment level as the cost wont have been added in.
       if (cpi->common.mb_no_coeff_skip) {
         int mb_skip_allowed;
-        int has_y2 = (this_mode != SPLITMV
-                      && this_mode != B_PRED
-                      && this_mode != I8X8_PRED);
 
         // Is Mb level skip allowed for this mb.
         mb_skip_allowed =
@@ -4372,71 +4469,59 @@ int64_t vp8_rd_pick_inter_mode_sb(VP8_COMP *cpi, MACROBLOCK *x,
                                   int *returnrate, int *returndistortion) {
   VP8_COMMON *cm = &cpi->common;
   MACROBLOCKD *xd = &x->e_mbd;
-  BLOCK *b = &x->block[0];
-  BLOCKD *d = &xd->block[0];
+  MB_MODE_INFO *mbmi = &xd->mode_info_context->mbmi;
   MB_PREDICTION_MODE this_mode;
   MV_REFERENCE_FRAME ref_frame;
   unsigned char segment_id = xd->mode_info_context->mbmi.segment_id;
   int comp_pred;
-  int_mv best_ref_mv, second_best_ref_mv;
-  int_mv mode_mv[MB_MODE_COUNT];
-  int_mv frame_nearest_mv[4];
-  int_mv frame_near_mv[4];
+  int_mv frame_mv[MB_MODE_COUNT][MAX_REF_FRAMES];
   int_mv frame_best_ref_mv[4];
-  int_mv mc_search_result[4];
   int frame_mdcounts[4][4];
   unsigned char *y_buffer[4];
   unsigned char *u_buffer[4];
   unsigned char *v_buffer[4];
-  static const int flag_list[4] = { 0, VP8_LAST_FLAG, VP8_GOLD_FLAG, VP8_ALT_FLAG };
-  int idx_list[4] = { 0, cpi->common.lst_fb_idx, cpi->common.gld_fb_idx, cpi->common.alt_fb_idx };
+  static const int flag_list[4] = { 0, VP8_LAST_FLAG, VP8_GOLD_FLAG,
+                                    VP8_ALT_FLAG };
+  int idx_list[4] = { 0, cpi->common.lst_fb_idx, cpi->common.gld_fb_idx,
+                      cpi->common.alt_fb_idx };
   int mdcounts[4];
-  int near_sadidx[8] = {0, 1, 2, 3, 4, 5, 6, 7};
+  int near_sadidx[8] = { 0, 1, 2, 3, 4, 5, 6, 7 };
   int saddone = 0;
-  int sr = 0;  // search range got from mv_pred(). It uses step_param levels. (0-7)
   int64_t best_rd = INT64_MAX;
   int64_t best_comp_rd = INT64_MAX;
   int64_t best_single_rd = INT64_MAX;
   int64_t best_hybrid_rd = INT64_MAX;
   int64_t best_yrd = INT64_MAX;
   MB_MODE_INFO best_mbmode;
-  int mode_index = 0;
+  int mode_index, best_mode_index;
   unsigned int ref_costs[MAX_REF_FRAMES];
 
+  x->skip = 0;
   xd->mode_info_context->mbmi.segment_id = segment_id;
   vp8_estimate_ref_frame_costs(cpi, segment_id, ref_costs);
+  vpx_memset(&best_mbmode, 0, sizeof(best_mbmode));
 
   for (ref_frame = LAST_FRAME; ref_frame <= ALTREF_FRAME; ref_frame++) {
     if (cpi->ref_frame_flags & flag_list[ref_frame]) {
-      YV12_BUFFER_CONFIG *ref_buf = &cpi->common.yv12_fb[idx_list[ref_frame]];
-
-      vp8_find_near_mvs(xd, xd->mode_info_context,
-                        xd->prev_mode_info_context,
-                        &frame_nearest_mv[ref_frame], &frame_near_mv[ref_frame],
-                        &frame_best_ref_mv[ref_frame], frame_mdcounts[ref_frame],
-                        ref_frame, cpi->common.ref_frame_sign_bias);
-
-      y_buffer[ref_frame] = ref_buf->y_buffer + recon_yoffset;
-      u_buffer[ref_frame] = ref_buf->u_buffer + recon_uvoffset;
-      v_buffer[ref_frame] = ref_buf->v_buffer + recon_uvoffset;
+      setup_buffer_inter(cpi, x, idx_list[ref_frame], ref_frame,
+                         recon_yoffset, recon_uvoffset, frame_mv[NEARESTMV],
+                         frame_mv[NEARMV], frame_best_ref_mv,
+                         frame_mdcounts, y_buffer, u_buffer, v_buffer);
     }
-    mc_search_result[ref_frame].as_int = INVALID_MV;
+    frame_mv[NEWMV][ref_frame].as_int = INVALID_MV;
+    frame_mv[ZEROMV][ref_frame].as_int = 0;
   }
 
   for (mode_index = 0; mode_index < MAX_MODES; mode_index++) {
-    int_mv mvp;
     int mode_excluded;
     int64_t this_rd = INT64_MAX;
     int disable_skip = 0;
     int other_cost = 0;
     int compmode_cost = 0;
-    int rate2 = 0;
-    int distortion2 = 0;
-    int rate_y = 0;
-    int rate_uv = 0;
-    int distortion_uv;
-    int distortion;
-    int skippable_y, skippable_uv;
+    int rate2 = 0, rate_y = 0, rate_uv = 0;
+    int distortion2 = 0, distortion_y = 0, distortion_uv = 0;
+    int skippable;
+    int64_t txfm_cache[NB_TXFM_MODES];
 
     // Test best rd so far against threshold for trying this mode.
     if (best_rd <= cpi->rd_threshes[mode_index]) {
@@ -4445,17 +4530,13 @@ int64_t vp8_rd_pick_inter_mode_sb(VP8_COMP *cpi, MACROBLOCK *x,
 
     this_mode = vp8_mode_order[mode_index].mode;
     ref_frame = vp8_mode_order[mode_index].ref_frame;
-    xd->mode_info_context->mbmi.ref_frame = ref_frame;
+    mbmi->ref_frame = ref_frame;
     comp_pred = vp8_mode_order[mode_index].second_ref_frame != INTRA_FRAME;
-    xd->mode_info_context->mbmi.mode = this_mode;
-    xd->mode_info_context->mbmi.uv_mode = DC_PRED;
-#if 0 && CONFIG_PRED_FILTER
-    xd->mode_info_context->mbmi.pred_filter_enabled = 0;
-#endif
-
-#if 0 && CONFIG_COMP_INTRA_PRED
-    xd->mode_info_context->mbmi.second_mode = (MB_PREDICTION_MODE)(DC_PRED - 1);
-    xd->mode_info_context->mbmi.second_uv_mode = (MB_PREDICTION_MODE)(DC_PRED - 1);
+    mbmi->mode = this_mode;
+    mbmi->uv_mode = DC_PRED;
+#if CONFIG_COMP_INTRA_PRED
+    mbmi->second_mode = (MB_PREDICTION_MODE)(DC_PRED - 1);
+    mbmi->second_uv_mode = (MB_PREDICTION_MODE)(DC_PRED - 1);
 #endif
 
     if (!(cpi->ref_frame_flags & flag_list[ref_frame]))
@@ -4476,25 +4557,20 @@ int64_t vp8_rd_pick_inter_mode_sb(VP8_COMP *cpi, MACROBLOCK *x,
       }
       if (!(cpi->ref_frame_flags & flag_list[second_ref]))
         continue;
-      xd->mode_info_context->mbmi.second_ref_frame = second_ref;
+      mbmi->second_ref_frame = second_ref;
 
       xd->second_pre.y_buffer = y_buffer[second_ref];
       xd->second_pre.u_buffer = u_buffer[second_ref];
       xd->second_pre.v_buffer = v_buffer[second_ref];
-      second_best_ref_mv  = frame_best_ref_mv[second_ref];
       mode_excluded = cm->comp_pred_mode == SINGLE_PREDICTION_ONLY;
     } else {
-      xd->mode_info_context->mbmi.second_ref_frame = INTRA_FRAME;
+      mbmi->second_ref_frame = INTRA_FRAME;
       mode_excluded = cm->comp_pred_mode == COMP_PREDICTION_ONLY;
     }
 
     xd->pre.y_buffer = y_buffer[ref_frame];
     xd->pre.u_buffer = u_buffer[ref_frame];
     xd->pre.v_buffer = v_buffer[ref_frame];
-    mode_mv[ZEROMV].as_int = 0;
-    mode_mv[NEARESTMV] = frame_nearest_mv[ref_frame];
-    mode_mv[NEARMV] = frame_near_mv[ref_frame];
-    best_ref_mv = frame_best_ref_mv[ref_frame];
     vpx_memcpy(mdcounts, frame_mdcounts[ref_frame], sizeof(mdcounts));
 
     // If the segment reference frame feature is enabled....
@@ -4524,342 +4600,20 @@ int64_t vp8_rd_pick_inter_mode_sb(VP8_COMP *cpi, MACROBLOCK *x,
       }
     }
 
-    if (!comp_pred) {
-      switch (this_mode) {
-        case NEWMV: {
-          int thissme;
-          int bestsme = INT_MAX;
-          int step_param = cpi->sf.first_step;
-          int further_steps;
-          int n;
-          int do_refine = 1;   /* If last step (1-away) of n-step search doesn't pick the center point as the best match,
-                                  we will do a final 1-away diamond refining search  */
-          int num00;
-
-          int sadpb = x->sadperbit16;
-          int_mv mvp_full;
-
-          int col_min = (best_ref_mv.as_mv.col >> 3) - MAX_FULL_PEL_VAL + ((best_ref_mv.as_mv.col & 7) ? 1 : 0);
-          int row_min = (best_ref_mv.as_mv.row >> 3) - MAX_FULL_PEL_VAL + ((best_ref_mv.as_mv.row & 7) ? 1 : 0);
-          int col_max = (best_ref_mv.as_mv.col >> 3) + MAX_FULL_PEL_VAL;
-          int row_max = (best_ref_mv.as_mv.row >> 3) + MAX_FULL_PEL_VAL;
-
-          int tmp_col_min = x->mv_col_min;
-          int tmp_col_max = x->mv_col_max;
-          int tmp_row_min = x->mv_row_min;
-          int tmp_row_max = x->mv_row_max;
-
-          if (!saddone) {
-            vp8_cal_sad(cpi, xd, x, recon_yoffset, &near_sadidx[0]);
-            saddone = 1;
-          }
-
-          vp8_mv_pred(cpi, xd, xd->mode_info_context, &mvp,
-                      xd->mode_info_context->mbmi.ref_frame,
-                      cpi->common.ref_frame_sign_bias, &sr, &near_sadidx[0]);
-
-          mvp_full.as_mv.col = mvp.as_mv.col >> 3;
-          mvp_full.as_mv.row = mvp.as_mv.row >> 3;
-
-          // Get intersection of UMV window and valid MV window to reduce # of checks in diamond search.
-          if (x->mv_col_min < col_min)
-            x->mv_col_min = col_min;
-          if (x->mv_col_max > col_max)
-            x->mv_col_max = col_max;
-          if (x->mv_row_min < row_min)
-            x->mv_row_min = row_min;
-          if (x->mv_row_max > row_max)
-            x->mv_row_max = row_max;
-
-          // adjust search range according to sr from mv prediction
-          if (sr > step_param)
-            step_param = sr;
-
-          // Initial step/diamond search
-          {
-            bestsme = cpi->diamond_search_sad(x, b, d, &mvp_full, &d->bmi.as_mv.first,
-                                              step_param, sadpb, &num00,
-                                              &cpi->fn_ptr[BLOCK_32X32],
-                                              XMVCOST, &best_ref_mv);
-            mode_mv[NEWMV].as_int = d->bmi.as_mv.first.as_int;
-
-            // Further step/diamond searches as necessary
-            n = 0;
-            further_steps = (cpi->sf.max_step_search_steps - 1) - step_param;
-
-            n = num00;
-            num00 = 0;
-
-            /* If there won't be more n-step search, check to see if refining search is needed. */
-            if (n > further_steps)
-              do_refine = 0;
-
-            while (n < further_steps) {
-              n++;
-
-              if (num00)
-                num00--;
-              else {
-                thissme = cpi->diamond_search_sad(x, b, d, &mvp_full,
-                                                  &d->bmi.as_mv.first, step_param + n, sadpb, &num00,
-                                                  &cpi->fn_ptr[BLOCK_32X32],
-                                                  XMVCOST, &best_ref_mv);
-
-                /* check to see if refining search is needed. */
-                if (num00 > (further_steps - n))
-                  do_refine = 0;
-
-                if (thissme < bestsme) {
-                  bestsme = thissme;
-                  mode_mv[NEWMV].as_int = d->bmi.as_mv.first.as_int;
-                } else {
-                  d->bmi.as_mv.first.as_int = mode_mv[NEWMV].as_int;
-                }
-              }
-            }
-          }
-
-          /* final 1-away diamond refining search */
-          if (do_refine == 1) {
-            int search_range;
-
-            // It seems not a good way to set search_range. Need further investigation.
-            // search_range = MAXF(abs((mvp.row>>3) - d->bmi.mv.as_mv.row), abs((mvp.col>>3) - d->bmi.mv.as_mv.col));
-            search_range = 8;
-
-            thissme = cpi->refining_search_sad(x, b, d, &d->bmi.as_mv.first, sadpb,
-                                               search_range, &cpi->fn_ptr[BLOCK_32X32],
-                                               XMVCOST, &best_ref_mv);
-
-            if (thissme < bestsme) {
-              bestsme = thissme;
-              mode_mv[NEWMV].as_int = d->bmi.as_mv.first.as_int;
-            } else {
-              d->bmi.as_mv.first.as_int = mode_mv[NEWMV].as_int;
-            }
-          }
-
-          x->mv_col_min = tmp_col_min;
-          x->mv_col_max = tmp_col_max;
-          x->mv_row_min = tmp_row_min;
-          x->mv_row_max = tmp_row_max;
-
-          if (bestsme < INT_MAX) {
-            int dis; /* TODO: use dis in distortion calculation later. */
-            unsigned int sse;
-            cpi->find_fractional_mv_step(x, b, d, &d->bmi.as_mv.first, &best_ref_mv,
-                                         x->errorperbit,
-                                         &cpi->fn_ptr[BLOCK_32X32],
-                                         XMVCOST, &dis, &sse);
-          }
-          mc_search_result[xd->mode_info_context->mbmi.ref_frame].as_int =
-            d->bmi.as_mv.first.as_int;
-
-          mode_mv[NEWMV].as_int = d->bmi.as_mv.first.as_int;
-
-          // Add the new motion vector cost to our rolling cost variable
-          rate2 += vp8_mv_bit_cost(&mode_mv[NEWMV], &best_ref_mv,
-                                   XMVCOST, 96,
-                                   xd->allow_high_precision_mv);
-        }
-
-        case NEARESTMV:
-        case NEARMV:
-          // Clip "next_nearest" so that it does not extend to far out of image
-          vp8_clamp_mv2(&mode_mv[this_mode], xd);
-
-          // Do not bother proceeding if the vector (from newmv,nearest or near) is 0,0 as this should then be coded using the zeromv mode.
-          if (((this_mode == NEARMV) || (this_mode == NEARESTMV)) && (mode_mv[this_mode].as_int == 0)) {
-            continue;
-          }
-
-        case ZEROMV:
-          // Trap vectors that reach beyond the UMV borders
-          // Note that ALL New MV, Nearest MV Near MV and Zero MV code drops through to this point
-          // because of the lack of break statements in the previous two cases.
-          if (((mode_mv[this_mode].as_mv.row >> 3) < x->mv_row_min) || ((mode_mv[this_mode].as_mv.row >> 3) > x->mv_row_max) ||
-              ((mode_mv[this_mode].as_mv.col >> 3) < x->mv_col_min) || ((mode_mv[this_mode].as_mv.col >> 3) > x->mv_col_max)) {
-            continue;
-          }
-
-          vp8_set_mbmode_and_mvs(x, this_mode, &mode_mv[this_mode]);
-
-#if CONFIG_PRED_FILTER
-          // Filtered prediction:
-          xd->mode_info_context->mbmi.pred_filter_enabled =
-          vp8_mode_order[mode_index].pred_filter_flag;
-          rate2 += vp8_cost_bit(cpi->common.prob_pred_filter_off,
-                                xd->mode_info_context->mbmi.pred_filter_enabled);
-#endif
-
-          vp8_build_inter32x32_predictors_sb(xd,
-                                             xd->dst.y_buffer,
-                                             xd->dst.u_buffer,
-                                             xd->dst.v_buffer,
-                                             xd->dst.y_stride,
-                                             xd->dst.uv_stride);
-
-          compmode_cost =
-            vp8_cost_bit(vp9_get_pred_prob(cm, xd, PRED_COMP), 0);
-
-          if (cpi->active_map_enabled && x->active_ptr[0] == 0) {
-            x->skip = 1;
-          } else if (x->encode_breakout) {
-            unsigned int sse;
-            unsigned int var;
-            int threshold = (xd->block[0].dequant[1] *
-                             xd->block[0].dequant[1] >> 4);
-
-            if (threshold < x->encode_breakout)
-              threshold = x->encode_breakout;
-
-            var = vp8_variance32x32(*(b->base_src), b->src_stride,
-                                    xd->dst.y_buffer, xd->dst.y_stride, &sse);
-
-            if (sse < threshold) {
-              unsigned int q2dc = xd->block[24].dequant[0];
-              /* If there is no codeable 2nd order dc
-                or a very small uniform pixel change change */
-              if ((sse - var < q2dc *q2dc >> 4) ||
-                  (sse / 2 > var && sse - var < 64)) {
-                // Check u and v to make sure skip is ok
-                unsigned int sse2, sse3;
-                var += vp8_variance16x16(x->src.u_buffer, x->src.uv_stride,
-                                   xd->dst.u_buffer, xd->dst.uv_stride, &sse2);
-                var += vp8_variance16x16(x->src.v_buffer, x->src.uv_stride,
-                                   xd->dst.v_buffer, xd->dst.uv_stride, &sse3);
-                sse2 += sse3;
-                if (sse2 * 2 < threshold) {
-                  x->skip = 1;
-                  distortion2 = sse + sse2;
-                  rate2 = 500;
-
-                  /* for best_yrd calculation */
-                  rate_uv = 0;
-                  distortion_uv = sse2;
-
-                  disable_skip = 1;
-                  this_rd = RDCOST(x->rdmult, x->rddiv, rate2, distortion2);
-                  break;
-                }
-              }
-            }
-          }
-
-          // Add in the Mv/mode cost
-          rate2 += vp8_cost_mv_ref(cpi, this_mode, mdcounts);
-
-          // Y cost and distortion - FIXME support other transform sizes
-          super_block_yrd_8x8(x, &rate_y, &distortion,
-                              IF_RTCD(&cpi->rtcd), &skippable_y);
-          rate2 += rate_y;
-          distortion2 += distortion;
-
-          rd_inter32x32_uv_8x8(cpi, x, &rate_uv, &distortion_uv,
-                               cpi->common.full_pixel, &skippable_uv);
-
-          rate2 += rate_uv;
-          distortion2 += distortion_uv;
-          mode_excluded = cpi->common.comp_pred_mode == COMP_PREDICTION_ONLY;
-          break;
-
-        default:
-          break;
-      }
-    } else { /* xd->mode_info_context->mbmi.second_ref_frame != 0 */
-      int ref1 = xd->mode_info_context->mbmi.ref_frame;
-      int ref2 = xd->mode_info_context->mbmi.second_ref_frame;
-
-      mode_excluded = cpi->common.comp_pred_mode == SINGLE_PREDICTION_ONLY;
-      switch (this_mode) {
-        case NEWMV:
-          if (mc_search_result[ref1].as_int == INVALID_MV ||
-              mc_search_result[ref2].as_int == INVALID_MV)
-            continue;
-          xd->mode_info_context->mbmi.mv[0].as_int = mc_search_result[ref1].as_int;
-          xd->mode_info_context->mbmi.mv[1].as_int = mc_search_result[ref2].as_int;
-          rate2 += vp8_mv_bit_cost(&mc_search_result[ref1],
-                                   &frame_best_ref_mv[ref1],
-                                   XMVCOST, 96,
-                                   xd->allow_high_precision_mv);
-          rate2 += vp8_mv_bit_cost(&mc_search_result[ref2],
-                                   &frame_best_ref_mv[ref2],
-                                   XMVCOST, 96,
-                                   xd->allow_high_precision_mv);
-          break;
-        case ZEROMV:
-          xd->mode_info_context->mbmi.mv[0].as_int = 0;
-          xd->mode_info_context->mbmi.mv[1].as_int = 0;
-          break;
-        case NEARMV:
-          if (frame_near_mv[ref1].as_int == 0 || frame_near_mv[ref2].as_int == 0) {
-            continue;
-          }
-          xd->mode_info_context->mbmi.mv[0].as_int = frame_near_mv[ref1].as_int;
-          xd->mode_info_context->mbmi.mv[1].as_int = frame_near_mv[ref2].as_int;
-          break;
-        case NEARESTMV:
-          if (frame_nearest_mv[ref1].as_int == 0 || frame_nearest_mv[ref2].as_int == 0) {
-            continue;
-          }
-          xd->mode_info_context->mbmi.mv[0].as_int = frame_nearest_mv[ref1].as_int;
-          xd->mode_info_context->mbmi.mv[1].as_int = frame_nearest_mv[ref2].as_int;
-          break;
-        default:
-          break;
-      }
-
-      /* Add in the Mv/mode cost */
-      rate2 += vp8_cost_mv_ref(cpi, this_mode, mdcounts);
-
-      vp8_clamp_mv2(&xd->mode_info_context->mbmi.mv[0], xd);
-      vp8_clamp_mv2(&xd->mode_info_context->mbmi.mv[1], xd);
-      if (((xd->mode_info_context->mbmi.mv[0].as_mv.row >> 3) < x->mv_row_min) ||
-          ((xd->mode_info_context->mbmi.mv[0].as_mv.row >> 3) > x->mv_row_max) ||
-          ((xd->mode_info_context->mbmi.mv[0].as_mv.col >> 3) < x->mv_col_min) ||
-          ((xd->mode_info_context->mbmi.mv[0].as_mv.col >> 3) > x->mv_col_max) ||
-          ((xd->mode_info_context->mbmi.mv[1].as_mv.row >> 3) < x->mv_row_min) ||
-          ((xd->mode_info_context->mbmi.mv[1].as_mv.row >> 3) > x->mv_row_max) ||
-          ((xd->mode_info_context->mbmi.mv[1].as_mv.col >> 3) < x->mv_col_min) ||
-          ((xd->mode_info_context->mbmi.mv[1].as_mv.col >> 3) > x->mv_col_max)) {
-        continue;
-      }
-
-      /* build first and second prediction */
-      vp8_build_inter32x32_predictors_sb(xd, xd->dst.y_buffer,
-                                         xd->dst.u_buffer, xd->dst.v_buffer,
-                                         xd->dst.y_stride, xd->dst.uv_stride);
-
-      /* Y cost and distortion - TODO(rbultje) support other transform sizes */
-      super_block_yrd_8x8(x, &rate_y, &distortion,
-                          IF_RTCD(&cpi->rtcd), &skippable_y);
-
-      rate2 += rate_y;
-      distortion2 += distortion;
-
-      /* UV cost and distortion */
-      rd_inter32x32_uv_8x8(cpi, x, &rate_uv, &distortion_uv,
-                           cpi->common.full_pixel, &skippable_uv);
-
-      rate2 += rate_uv;
-      distortion2 += distortion_uv;
-
-      /* don't bother w/ skip, we would never have come here if skip were
-       * enabled */
-      xd->mode_info_context->mbmi.mode = this_mode;
-
-      /* We don't include the cost of the second reference here, because there
-       * are only three options: Last/Golden, ARF/Last or Golden/ARF, or in
-       * other words if you present them in that order, the second one is
-       * always known if the first is known */
-      compmode_cost = vp8_cost_bit(vp9_get_pred_prob(cm, xd, PRED_COMP), 1);
-    }
+    this_rd = handle_inter_mode(cpi, x, BLOCK_32X32,
+                                &saddone, near_sadidx, mdcounts, txfm_cache,
+                                &rate2, &distortion2, &skippable,
+                                &compmode_cost, &rate_y, &distortion_y,
+                                &rate_uv, &distortion_uv,
+                                &mode_excluded, &disable_skip, recon_yoffset,
+                                mode_index, frame_mv, frame_best_ref_mv);
+    if (this_rd == INT64_MAX)
+      continue;
 
     if (cpi->common.comp_pred_mode == HYBRID_PREDICTION) {
       rate2 += compmode_cost;
     }
 
-
     // Estimate the reference frame signaling cost and add it
     // to the rolling cost variable.
     rate2 += ref_costs[xd->mode_info_context->mbmi.ref_frame];
@@ -4870,7 +4624,6 @@ int64_t vp8_rd_pick_inter_mode_sb(VP8_COMP *cpi, MACROBLOCK *x,
       // necessary adjustment for rate. Ignore if skip is coded at
       // segment level as the cost wont have been added in.
       if (cpi->common.mb_no_coeff_skip) {
-        int mb_skippable = skippable_y && skippable_uv;
         int mb_skip_allowed;
 
         // Is Mb level skip allowed for this mb.
@@ -4878,7 +4631,7 @@ int64_t vp8_rd_pick_inter_mode_sb(VP8_COMP *cpi, MACROBLOCK *x,
           !segfeature_active(xd, segment_id, SEG_LVL_EOB) ||
           get_segdata(xd, segment_id, SEG_LVL_EOB);
 
-        if (mb_skippable) {
+        if (skippable) {
           // Back out the coefficient coding costs
           rate2 -= (rate_y + rate_uv);
           // for best_yrd calculation
@@ -4932,10 +4685,10 @@ int64_t vp8_rd_pick_inter_mode_sb(VP8_COMP *cpi, MACROBLOCK *x,
     // Did this mode help.. i.e. is it the new best mode
     if (this_rd < best_rd || x->skip) {
       if (!mode_excluded) {
-#if 0
         // Note index of best mode so far
         best_mode_index = mode_index;
 
+#if 0
         if (this_mode <= B_PRED) {
           xd->mode_info_context->mbmi.uv_mode = uv_intra_mode_8x8;
           /* required for left and above block mv */
@@ -4952,7 +4705,7 @@ int64_t vp8_rd_pick_inter_mode_sb(VP8_COMP *cpi, MACROBLOCK *x,
         *returnrate = rate2;
         *returndistortion = distortion2;
         best_rd = this_rd;
-        vpx_memcpy(&best_mbmode, &xd->mode_info_context->mbmi, sizeof(MB_MODE_INFO));
+        vpx_memcpy(&best_mbmode, mbmi, sizeof(MB_MODE_INFO));
       }
 #if 0
       // Testing this mode gave rise to an improvement in best error score. Lower threshold a bit for next time
@@ -4973,7 +4726,7 @@ int64_t vp8_rd_pick_inter_mode_sb(VP8_COMP *cpi, MACROBLOCK *x,
     }
 
     /* keep record of best compound/single-only prediction */
-    if (!disable_skip && xd->mode_info_context->mbmi.ref_frame != INTRA_FRAME) {
+    if (!disable_skip && mbmi->ref_frame != INTRA_FRAME) {
       int single_rd, hybrid_rd, single_rate, hybrid_rate;
 
       if (cpi->common.comp_pred_mode == HYBRID_PREDICTION) {
@@ -4987,10 +4740,9 @@ int64_t vp8_rd_pick_inter_mode_sb(VP8_COMP *cpi, MACROBLOCK *x,
       single_rd = RDCOST(x->rdmult, x->rddiv, single_rate, distortion2);
       hybrid_rd = RDCOST(x->rdmult, x->rddiv, hybrid_rate, distortion2);
 
-      if (xd->mode_info_context->mbmi.second_ref_frame == INTRA_FRAME &&
-          single_rd < best_single_rd) {
+      if (mbmi->second_ref_frame == INTRA_FRAME && single_rd < best_single_rd) {
         best_single_rd = single_rd;
-      } else if (xd->mode_info_context->mbmi.second_ref_frame != INTRA_FRAME &&
+      } else if (mbmi->second_ref_frame != INTRA_FRAME &&
                  single_rd < best_comp_rd) {
         best_comp_rd = single_rd;
       }
@@ -5027,36 +4779,37 @@ int64_t vp8_rd_pick_inter_mode_sb(VP8_COMP *cpi, MACROBLOCK *x,
       cpi->is_src_frame_alt_ref &&
       (cpi->oxcf.arnr_max_frames == 0) &&
       (best_mbmode.mode != ZEROMV || best_mbmode.ref_frame != ALTREF_FRAME)) {
-    xd->mode_info_context->mbmi.mode = ZEROMV;
-    xd->mode_info_context->mbmi.ref_frame = ALTREF_FRAME;
-    xd->mode_info_context->mbmi.mv[0].as_int = 0;
-    xd->mode_info_context->mbmi.uv_mode = DC_PRED;
-    xd->mode_info_context->mbmi.mb_skip_coeff =
-      (cpi->common.mb_no_coeff_skip) ? 1 : 0;
-    xd->mode_info_context->mbmi.partitioning = 0;
-
-    xd->mode_info_context->mbmi.txfm_size = TX_8X8;
+    mbmi->mode = ZEROMV;
+    mbmi->ref_frame = ALTREF_FRAME;
+    mbmi->second_ref_frame = 0;
+    mbmi->mv[0].as_int = 0;
+    mbmi->uv_mode = DC_PRED;
+    mbmi->mb_skip_coeff = (cpi->common.mb_no_coeff_skip) ? 1 : 0;
+    mbmi->partitioning = 0;
+    mbmi->txfm_size = TX_8X8;
 
     if (best_rd != INT64_MAX)
-      store_coding_context(x, &x->sb_context[0], mode_index, NULL,
-        &frame_best_ref_mv[xd->mode_info_context->mbmi.ref_frame],
-        &frame_best_ref_mv[xd->mode_info_context->mbmi.second_ref_frame],
-        0, 0, 0, NULL);
+      store_coding_context(x, &x->sb_context[0], best_mode_index, NULL,
+                           &frame_best_ref_mv[mbmi->ref_frame],
+                           &frame_best_ref_mv[mbmi->second_ref_frame],
+                           0, 0, 0, NULL);
     return best_rd;
   }
 
   // macroblock modes
-  vpx_memcpy(&xd->mode_info_context->mbmi, &best_mbmode,
-             sizeof(MB_MODE_INFO));
-  xd->mode_info_context->mbmi.txfm_size = TX_8X8;
+  vpx_memcpy(mbmi, &best_mbmode, sizeof(MB_MODE_INFO));
+  mbmi->txfm_size = TX_8X8;
 
   if (best_rd != INT64_MAX)
-    store_coding_context(x, &x->sb_context[0], mode_index, NULL,
-      &frame_best_ref_mv[xd->mode_info_context->mbmi.ref_frame],
-      &frame_best_ref_mv[xd->mode_info_context->mbmi.second_ref_frame],
-      (best_single_rd == INT64_MAX) ? INT_MIN : (best_rd - best_single_rd),
-      (best_comp_rd   == INT64_MAX) ? INT_MIN : (best_rd - best_comp_rd),
-      (best_hybrid_rd == INT64_MAX) ? INT_MIN : (best_rd - best_hybrid_rd),
+    store_coding_context(x, &x->sb_context[0], best_mode_index, NULL,
+                         &frame_best_ref_mv[mbmi->ref_frame],
+                         &frame_best_ref_mv[mbmi->second_ref_frame],
+                         (best_single_rd == INT64_MAX) ? INT_MIN :
+                                        (best_rd - best_single_rd),
+                         (best_comp_rd   == INT64_MAX) ? INT_MIN :
+                                        (best_rd - best_comp_rd),
+                         (best_hybrid_rd == INT64_MAX) ? INT_MIN :
+                                        (best_rd - best_hybrid_rd),
                          NULL);
 
   return best_rd;
index 448a702447ba6f6102c5dc7ac160e64d9776b2f0..0495037eb646775fe5fa0006a71b4fab8a52db37 100644 (file)
@@ -32,7 +32,6 @@ extern void vp8_mv_pred
   int *sr,
   int near_sadidx[]
 );
-extern void vp8_cal_sad(VP8_COMP *cpi, MACROBLOCKD *xd, MACROBLOCK *x, int recon_yoffset, int near_sadidx[]);
 extern void vp8_init_me_luts();
 extern void vp8_set_mbmode_and_mvs(MACROBLOCK *x, MB_PREDICTION_MODE mb, int_mv *mv);
 #endif
index fea816ca217a72144707390c37860615594a59d0..f6f3f311068d79a9841dd39e150a96fd6a82bd8d 100644 (file)
@@ -164,6 +164,7 @@ void choose_segmap_coding_method(VP8_COMP *cpi) {
   VP8_COMMON *const cm = &cpi->common;
   MACROBLOCKD *const xd = &cpi->mb.e_mbd;
 
+  const int mis = cm->mode_info_stride;
   int i;
   int tot_count;
   int no_pred_cost;
@@ -212,8 +213,27 @@ void choose_segmap_coding_method(VP8_COMP *cpi) {
           goto end;
         }
 
+        xd->mb_to_top_edge = -((mb_row * 16) << 3);
+        xd->mb_to_bottom_edge = ((cm->mb_rows - 1 - mb_row) * 16) << 3;
+        xd->mb_to_left_edge = -((mb_col * 16) << 3);
+        xd->mb_to_right_edge = ((cm->mb_cols - 1 - mb_row) * 16) << 3;
+
         segmap_index = (mb_row + y_idx) * cm->mb_cols + mb_col + x_idx;
         segment_id = xd->mode_info_context->mbmi.segment_id;
+#if CONFIG_SUPERBLOCKS
+        if (xd->mode_info_context->mbmi.encoded_as_sb) {
+          if (mb_col + 1 < cm->mb_cols)
+            segment_id = segment_id &&
+                         xd->mode_info_context[1].mbmi.segment_id;
+          if (mb_row + 1 < cm->mb_rows) {
+            segment_id = segment_id &&
+                         xd->mode_info_context[mis].mbmi.segment_id;
+            if (mb_col + 1 < cm->mb_cols)
+              segment_id = segment_id &&
+                           xd->mode_info_context[mis + 1].mbmi.segment_id;
+          }
+        }
+#endif
 
         // Count the number of hits on each segment with no prediction
         no_pred_segcounts[segment_id]++;
@@ -222,7 +242,7 @@ void choose_segmap_coding_method(VP8_COMP *cpi) {
         if (cm->frame_type != KEY_FRAME) {
           // Test to see if the segment id matches the predicted value.
           int seg_predicted =
-            (segment_id == vp9_get_pred_mb_segid(cm, segmap_index));
+            (segment_id == vp9_get_pred_mb_segid(cm, xd, segmap_index));
 
           // Get the segment id prediction context
           pred_context =