Fix edge MV handling in SBs.
authorRonald S. Bultje <rbultje@google.com>
Mon, 12 Nov 2012 23:43:11 +0000 (15:43 -0800)
committerRonald S. Bultje <rbultje@google.com>
Tue, 13 Nov 2012 01:06:52 +0000 (17:06 -0800)
Change-Id: Ia1eddb108ec463835e9de8769572d698e21bca49

vp9/common/pred_common.c
vp9/common/reconinter.c
vp9/decoder/decodemv.c
vp9/decoder/decodframe.c
vp9/encoder/bitstream.c
vp9/encoder/encodeframe.c
vp9/encoder/segmentation.c

index cc165e0..bac7a09 100644 (file)
@@ -228,11 +228,11 @@ void vp9_set_pred_flag(MACROBLOCKD *const xd,
       xd->mode_info_context->mbmi.seg_id_predicted = pred_flag;
 #if CONFIG_SUPERBLOCKS
       if (xd->mode_info_context->mbmi.encoded_as_sb) {
-        if (xd->mb_to_right_edge > 0)
+        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) {
+        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)
+          if (xd->mb_to_right_edge >= 0)
             xd->mode_info_context[mis + 1].mbmi.seg_id_predicted = pred_flag;
         }
       }
@@ -243,11 +243,11 @@ 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) {
-        if (xd->mb_to_right_edge > 0)
+        if (xd->mb_to_right_edge >= 0)
           xd->mode_info_context[1].mbmi.ref_predicted = pred_flag;
-        if (xd->mb_to_bottom_edge > 0) {
+        if (xd->mb_to_bottom_edge >= 0) {
           xd->mode_info_context[mis].mbmi.ref_predicted = pred_flag;
-          if (xd->mb_to_right_edge > 0)
+          if (xd->mb_to_right_edge >= 0)
             xd->mode_info_context[mis + 1].mbmi.ref_predicted = pred_flag;
         }
       }
@@ -258,11 +258,11 @@ void vp9_set_pred_flag(MACROBLOCKD *const xd,
       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)
+        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) {
+        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)
+          if (xd->mb_to_right_edge >= 0)
             xd->mode_info_context[mis + 1].mbmi.mb_skip_coeff = pred_flag;
         }
       }
index 536b287..8b81b28 100644 (file)
@@ -753,12 +753,21 @@ void vp9_build_inter32x32_predictors_sb(MACROBLOCKD *x,
   uint8_t *y1 = x->pre.y_buffer, *u1 = x->pre.u_buffer, *v1 = x->pre.v_buffer;
   uint8_t *y2 = x->second_pre.y_buffer, *u2 = x->second_pre.u_buffer,
           *v2 = x->second_pre.v_buffer;
-  int n;
+  int edge[4], n;
 
-  for (n = 0; n < 4; n++)
-  {
+  edge[0] = x->mb_to_top_edge;
+  edge[1] = x->mb_to_bottom_edge;
+  edge[2] = x->mb_to_left_edge;
+  edge[3] = x->mb_to_right_edge;
+
+  for (n = 0; n < 4; n++) {
     const int x_idx = n & 1, y_idx = n >> 1;
 
+    x->mb_to_top_edge    = edge[0] -      ((y_idx  * 16) << 3);
+    x->mb_to_bottom_edge = edge[1] + (((1 - y_idx) * 16) << 3);
+    x->mb_to_left_edge   = edge[2] -      ((x_idx  * 16) << 3);
+    x->mb_to_right_edge  = edge[3] + (((1 - x_idx) * 16) << 3);
+
     x->pre.y_buffer = y1 + y_idx * 16 * x->pre.y_stride  + x_idx * 16;
     x->pre.u_buffer = u1 + y_idx *  8 * x->pre.uv_stride + x_idx *  8;
     x->pre.v_buffer = v1 + y_idx *  8 * x->pre.uv_stride + x_idx *  8;
@@ -781,6 +790,11 @@ void vp9_build_inter32x32_predictors_sb(MACROBLOCKD *x,
     }
   }
 
+  x->mb_to_top_edge    = edge[0];
+  x->mb_to_bottom_edge = edge[1];
+  x->mb_to_left_edge   = edge[2];
+  x->mb_to_right_edge  = edge[3];
+
   x->pre.y_buffer = y1;
   x->pre.u_buffer = u1;
   x->pre.v_buffer = v1;
index 52032bc..e9f3795 100644 (file)
@@ -679,8 +679,17 @@ static void read_mb_modes_mv(VP9D_COMP *pbi, MODE_INFO *mi, MB_MODE_INFO *mbmi,
     mb_to_left_edge = -((mb_col * 16) << 3);
   mb_to_left_edge -= LEFT_TOP_MARGIN;
 
-  xd->mb_to_right_edge =
-    mb_to_right_edge = ((pbi->common.mb_cols - 1 - mb_col) * 16) << 3;
+#if CONFIG_SUPERBLOCKS
+  if (mi->mbmi.encoded_as_sb) {
+    xd->mb_to_right_edge =
+      mb_to_right_edge = ((pbi->common.mb_cols - 2 - mb_col) * 16) << 3;
+  } else {
+#endif
+    xd->mb_to_right_edge =
+      mb_to_right_edge = ((pbi->common.mb_cols - 1 - mb_col) * 16) << 3;
+#if CONFIG_SUPERBLOCKS
+  }
+#endif
   mb_to_right_edge += RIGHT_BOTTOM_MARGIN;
 
   // Make sure the MACROBLOCKD mode info pointer is pointed at the
index ebbf166..5b56b15 100644 (file)
@@ -653,6 +653,10 @@ decode_sb_row(VP9D_COMP *pbi, VP9_COMMON *pc, int mbrow, MACROBLOCKD *xd,
         xd->prev_mode_info_context += offset_extended;
         continue;
       }
+#if CONFIG_SUPERBLOCKS
+      if (i)
+        mi->mbmi.encoded_as_sb = 0;
+#endif
 
       // Set above context pointer
       xd->above_context = pc->above_context + mb_col;
@@ -663,10 +667,18 @@ decode_sb_row(VP9D_COMP *pbi, VP9_COMMON *pc, int mbrow, MACROBLOCKD *xd,
        * values that are in 1/8th pel units
        */
       xd->mb_to_top_edge = -((mb_row * 16)) << 3;
-      xd->mb_to_bottom_edge = ((pc->mb_rows - 1 - mb_row) * 16) << 3;
-
       xd->mb_to_left_edge = -((mb_col * 16) << 3);
-      xd->mb_to_right_edge = ((pc->mb_cols - 1 - mb_col) * 16) << 3;
+#if CONFIG_SUPERBLOCKS
+      if (mi->mbmi.encoded_as_sb) {
+        xd->mb_to_bottom_edge = ((pc->mb_rows - 2 - mb_row) * 16) << 3;
+        xd->mb_to_right_edge = ((pc->mb_cols - 2 - mb_col) * 16) << 3;
+      } else {
+#endif
+        xd->mb_to_bottom_edge = ((pc->mb_rows - 1 - mb_row) * 16) << 3;
+        xd->mb_to_right_edge = ((pc->mb_cols - 1 - mb_col) * 16) << 3;
+#if CONFIG_SUPERBLOCKS
+      }
+#endif
 
       xd->up_available = (mb_row != 0);
       xd->left_available = (mb_col != 0);
@@ -679,10 +691,6 @@ decode_sb_row(VP9D_COMP *pbi, VP9_COMMON *pc, int mbrow, MACROBLOCKD *xd,
       xd->dst.u_buffer = pc->yv12_fb[dst_fb_idx].u_buffer + recon_uvoffset;
       xd->dst.v_buffer = pc->yv12_fb[dst_fb_idx].v_buffer + recon_uvoffset;
 
-#if CONFIG_SUPERBLOCKS
-      if (i)
-        mi->mbmi.encoded_as_sb = 0;
-#endif
       vp9_decode_mb_mode_mv(pbi, xd, mb_row, mb_col, bc);
 
       update_blockd_bmi(xd);
index d568e78..187f168 100644 (file)
@@ -746,12 +746,12 @@ static void write_mb_segid(vp9_writer *bc,
   int seg_id = mi->segment_id;
 #if CONFIG_SUPERBLOCKS
   if (mi->encoded_as_sb) {
-    if (xd->mb_to_right_edge > 0)
+    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) {
+    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)
+      if (xd->mb_to_right_edge >= 0)
         seg_id = seg_id &&
                 xd->mode_info_context[xd->mode_info_stride + 1].mbmi.segment_id;
     }
@@ -951,9 +951,19 @@ static void pack_inter_mode_mvs(VP9_COMP *const cpi, vp9_writer *const bc) {
         // These specified to 8th pel as they are always compared to MV
         // values that are in 1/8th pel units
         xd->mb_to_left_edge = -((mb_col * 16) << 3);
-        xd->mb_to_right_edge = ((pc->mb_cols - 1 - mb_col) * 16) << 3;
         xd->mb_to_top_edge = -((mb_row * 16)) << 3;
-        xd->mb_to_bottom_edge = ((pc->mb_rows - 1 - mb_row) * 16) << 3;
+
+#if CONFIG_SUPERBLOCKS
+        if (mi->encoded_as_sb) {
+          xd->mb_to_right_edge = ((pc->mb_cols - 2 - mb_col) * 16) << 3;
+          xd->mb_to_bottom_edge = ((pc->mb_rows - 2 - mb_row) * 16) << 3;
+        } else {
+#endif
+          xd->mb_to_right_edge = ((pc->mb_cols - 1 - mb_col) * 16) << 3;
+          xd->mb_to_bottom_edge = ((pc->mb_rows - 1 - mb_row) * 16) << 3;
+#if CONFIG_SUPERBLOCKS
+        }
+#endif
 
         // Make sure the MacroBlockD mode info pointer is set correctly
         xd->mode_info_context = m;
index 0f5835c..464d300 100644 (file)
@@ -381,11 +381,11 @@ static void update_state(VP9_COMP *cpi, MACROBLOCK *x, PICK_MODE_CONTEXT *ctx) {
 #if CONFIG_SUPERBLOCKS
   if (mi->mbmi.encoded_as_sb) {
     const int mis = cpi->common.mode_info_stride;
-    if (xd->mb_to_right_edge > 0)
+    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) {
+    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)
+      if (xd->mb_to_right_edge >= 0)
         vpx_memcpy(xd->mode_info_context + mis + 1, mi, sizeof(MODE_INFO));
     }
   }
@@ -742,8 +742,8 @@ static void pick_sb_modes (VP9_COMP *cpi,
   // Set up distance of MB to edge of frame in 1/8th pel units
   xd->mb_to_top_edge    = -((mb_row * 16) << 3);
   xd->mb_to_left_edge   = -((mb_col * 16) << 3);
-  xd->mb_to_bottom_edge = ((cm->mb_rows - 1 - mb_row) * 16) << 3;
-  xd->mb_to_right_edge  = ((cm->mb_cols - 1 - mb_col) * 16) << 3;
+  xd->mb_to_bottom_edge = ((cm->mb_rows - 2 - mb_row) * 16) << 3;
+  xd->mb_to_right_edge  = ((cm->mb_cols - 2 - mb_col) * 16) << 3;
 
   /* Set up limit values for MV components to prevent them from
    * extending beyond the UMV borders assuming 16x16 block size */
@@ -918,31 +918,32 @@ static void encode_sb(VP9_COMP *cpi,
     xd->left_context  = cm->left_context + (i >> 1);
 
     // Set up distance of MB to edge of the frame in 1/8th pel units
+    // Set up limit values for MV components to prevent them from
+    // extending beyond the UMV borders assuming 32x32 block size
+    x->mv_row_min = -((mb_row * 16) + VP9BORDERINPIXELS - VP9_INTERP_EXTEND);
+    x->mv_col_min = -((mb_col * 16) + VP9BORDERINPIXELS - VP9_INTERP_EXTEND);
+
     xd->mb_to_top_edge    = -((mb_row * 16) << 3);
     xd->mb_to_left_edge   = -((mb_col * 16) << 3);
-    xd->mb_to_bottom_edge = ((cm->mb_rows - 1 - mb_row) * 16) << 3;
-    xd->mb_to_right_edge  = ((cm->mb_cols - 1 - mb_col) * 16) << 3;
 
 #if CONFIG_SUPERBLOCKS
     if (xd->mode_info_context->mbmi.encoded_as_sb) {
-      // Set up limit values for MV components to prevent them from
-      // extending beyond the UMV borders assuming 32x32 block size
-      x->mv_row_min = -((mb_row * 16) + VP9BORDERINPIXELS - VP9_INTERP_EXTEND);
-      x->mv_col_min = -((mb_col * 16) + VP9BORDERINPIXELS - VP9_INTERP_EXTEND);
       x->mv_row_max = ((cm->mb_rows - mb_row) * 16 +
                        (VP9BORDERINPIXELS - 32 - VP9_INTERP_EXTEND));
       x->mv_col_max = ((cm->mb_cols - mb_col) * 16 +
                        (VP9BORDERINPIXELS - 32 - VP9_INTERP_EXTEND));
+
+      xd->mb_to_bottom_edge = ((cm->mb_rows - 2 - mb_row) * 16) << 3;
+      xd->mb_to_right_edge  = ((cm->mb_cols - 2 - mb_col) * 16) << 3;
     } else {
 #endif
-      // Set up limit values for MV components to prevent them from
-      // extending beyond the UMV borders assuming 16x16 block size
-      x->mv_row_min = -((mb_row * 16) + VP9BORDERINPIXELS - VP9_INTERP_EXTEND);
-      x->mv_col_min = -((mb_col * 16) + VP9BORDERINPIXELS - VP9_INTERP_EXTEND);
       x->mv_row_max = ((cm->mb_rows - mb_row) * 16 +
                        (VP9BORDERINPIXELS - 16 - VP9_INTERP_EXTEND));
       x->mv_col_max = ((cm->mb_cols - mb_col) * 16 +
                        (VP9BORDERINPIXELS - 16 - VP9_INTERP_EXTEND));
+
+      xd->mb_to_bottom_edge = ((cm->mb_rows - 1 - mb_row) * 16) << 3;
+      xd->mb_to_right_edge  = ((cm->mb_cols - 1 - mb_col) * 16) << 3;
 #if CONFIG_SUPERBLOCKS
     }
 #endif
index 463cd4a..501299f 100644 (file)
@@ -214,9 +214,7 @@ void vp9_choose_segmap_coding_method(VP9_COMP *cpi) {
         }
 
         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;
@@ -232,6 +230,13 @@ void vp9_choose_segmap_coding_method(VP9_COMP *cpi) {
               segment_id = segment_id &&
                            xd->mode_info_context[mis + 1].mbmi.segment_id;
           }
+          xd->mb_to_bottom_edge = ((cm->mb_rows - 2 - mb_row) * 16) << 3;
+          xd->mb_to_right_edge  = ((cm->mb_cols - 2 - mb_col) * 16) << 3;
+        } else {
+#endif
+          xd->mb_to_bottom_edge = ((cm->mb_rows - 1 - mb_row) * 16) << 3;
+          xd->mb_to_right_edge  = ((cm->mb_cols - 1 - mb_col) * 16) << 3;
+#if CONFIG_SUPERBLOCKS
         }
 #endif