shithub: libvpx

Download patch

ref: b147c64c16b9f8c471b23afebc38b0b55f20a85e
parent: 7de64f35d3782c0be451305ed3d9f4fdbb0bfa2a
parent: 722972454c3e26e953e2ff578fea021c4665158e
author: Ronald S. Bultje <rbultje@google.com>
date: Tue Nov 13 09:12:48 EST 2012

Merge "Fix edge MV handling in SBs." into experimental

--- a/vp9/common/pred_common.c
+++ b/vp9/common/pred_common.c
@@ -228,11 +228,11 @@
       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 @@
       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 @@
       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;
         }
       }
--- a/vp9/common/reconinter.c
+++ b/vp9/common/reconinter.c
@@ -753,12 +753,21 @@
   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;
@@ -780,6 +789,11 @@
         dst_ystride, dst_uvstride);
     }
   }
+
+  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;
--- a/vp9/decoder/decodemv.c
+++ b/vp9/decoder/decodemv.c
@@ -679,8 +679,17 @@
     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
--- a/vp9/decoder/decodframe.c
+++ b/vp9/decoder/decodframe.c
@@ -653,6 +653,10 @@
         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 @@
        * 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 @@
       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);
--- a/vp9/encoder/bitstream.c
+++ b/vp9/encoder/bitstream.c
@@ -600,12 +600,12 @@
   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;
     }
@@ -807,9 +807,19 @@
         // 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;
--- a/vp9/encoder/encodeframe.c
+++ b/vp9/encoder/encodeframe.c
@@ -464,11 +464,11 @@
 #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));
     }
   }
@@ -855,8 +855,8 @@
   // 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 */
@@ -1031,31 +1031,32 @@
     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
--- a/vp9/encoder/segmentation.c
+++ b/vp9/encoder/segmentation.c
@@ -214,9 +214,7 @@
         }
 
         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 @@
               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