shithub: libvpx

Download patch

ref: c969b2b02b1035130fc09573236dc627ec101106
parent: 16e069b8bb4d523007bf84be7c0a1bdde58539c4
author: Scott LaVarnway <[email protected]>
date: Thu Jul 21 07:47:51 EDT 2016

VP9: get_pred_context_switchable_interp() -- encoder side

Change-Id: I7217c90d5cf38c51b76759a2dc4f10070f3a40ac

--- a/vp9/common/vp9_pred_common.c
+++ b/vp9/common/vp9_pred_common.c
@@ -13,29 +13,6 @@
 #include "vp9/common/vp9_pred_common.h"
 #include "vp9/common/vp9_seg_common.h"
 
-// Returns a context number for the given MB prediction signal
-int vp9_get_pred_context_switchable_interp(const MACROBLOCKD *xd) {
-  // Note:
-  // The mode info data structure has a one element border above and to the
-  // left of the entries corresponding to real macroblocks.
-  // The prediction flags in these dummy entries are initialized to 0.
-  const MODE_INFO *const left_mi = xd->left_mi;
-  const int left_type = left_mi && is_inter_block(left_mi) ?
-                            left_mi->interp_filter : SWITCHABLE_FILTERS;
-  const MODE_INFO *const above_mi = xd->above_mi;
-  const int above_type = above_mi && is_inter_block(above_mi) ?
-                             above_mi->interp_filter : SWITCHABLE_FILTERS;
-
-  if (left_type == above_type)
-    return left_type;
-  else if (left_type == SWITCHABLE_FILTERS)
-    return above_type;
-  else if (above_type == SWITCHABLE_FILTERS)
-    return left_type;
-  else
-    return SWITCHABLE_FILTERS;
-}
-
 int vp9_get_reference_mode_context(const VP9_COMMON *cm,
                                    const MACROBLOCKD *xd) {
   int ctx;
--- a/vp9/common/vp9_pred_common.h
+++ b/vp9/common/vp9_pred_common.h
@@ -66,7 +66,27 @@
   return cm->fc->skip_probs[vp9_get_skip_context(xd)];
 }
 
-int vp9_get_pred_context_switchable_interp(const MACROBLOCKD *xd);
+// Returns a context number for the given MB prediction signal
+static INLINE int get_pred_context_switchable_interp(const MACROBLOCKD *xd) {
+  // Note:
+  // The mode info data structure has a one element border above and to the
+  // left of the entries corresponding to real macroblocks.
+  // The prediction flags in these dummy entries are initialized to 0.
+  const MODE_INFO *const left_mi = xd->left_mi;
+  const int left_type = left_mi ? left_mi->interp_filter : SWITCHABLE_FILTERS;
+  const MODE_INFO *const above_mi = xd->above_mi;
+  const int above_type = above_mi ? above_mi->interp_filter
+                             : SWITCHABLE_FILTERS;
+
+  if (left_type == above_type)
+    return left_type;
+  else if (left_type == SWITCHABLE_FILTERS)
+    return above_type;
+  else if (above_type == SWITCHABLE_FILTERS)
+    return left_type;
+  else
+    return SWITCHABLE_FILTERS;
+}
 
 // The mode info data structure has a one element border above and to the
 // left of the entries corresponding to real macroblocks.
--- a/vp9/decoder/vp9_decodemv.c
+++ b/vp9/decoder/vp9_decodemv.c
@@ -353,36 +353,10 @@
   }
 }
 
-// TODO(slavarnway): Move this decoder version of
-// vp9_get_pred_context_switchable_interp() to vp9_pred_common.h and update the
-// encoder.
-//
-// Returns a context number for the given MB prediction signal
-static int dec_get_pred_context_switchable_interp(const MACROBLOCKD *xd) {
-  // Note:
-  // The mode info data structure has a one element border above and to the
-  // left of the entries corresponding to real macroblocks.
-  // The prediction flags in these dummy entries are initialized to 0.
-  const MODE_INFO *const left_mi = xd->left_mi;
-  const int left_type = left_mi ? left_mi->interp_filter : SWITCHABLE_FILTERS;
-  const MODE_INFO *const above_mi = xd->above_mi;
-  const int above_type = above_mi ? above_mi->interp_filter
-                             : SWITCHABLE_FILTERS;
-
-  if (left_type == above_type)
-    return left_type;
-  else if (left_type == SWITCHABLE_FILTERS)
-    return above_type;
-  else if (above_type == SWITCHABLE_FILTERS)
-    return left_type;
-  else
-    return SWITCHABLE_FILTERS;
-}
-
 static INLINE INTERP_FILTER read_switchable_interp_filter(
     VP9_COMMON *const cm, MACROBLOCKD *const xd,
     vpx_reader *r) {
-  const int ctx = dec_get_pred_context_switchable_interp(xd);
+  const int ctx = get_pred_context_switchable_interp(xd);
   const INTERP_FILTER type =
       (INTERP_FILTER)vpx_read_tree(r, vp9_switchable_interp_tree,
                                    cm->fc->switchable_interp_prob[ctx]);
@@ -423,7 +397,7 @@
   mi->uv_mode = read_intra_mode_uv(cm, xd, r, mi->mode);
 
   // Initialize interp_filter here so we do not have to check for inter block
-  // modes in dec_get_pred_context_switchable_interp()
+  // modes in get_pred_context_switchable_interp()
   mi->interp_filter = SWITCHABLE_FILTERS;
 
   mi->ref_frame[0] = INTRA_FRAME;
--- a/vp9/encoder/vp9_bitstream.c
+++ b/vp9/encoder/vp9_bitstream.c
@@ -293,7 +293,7 @@
     }
 
     if (cm->interp_filter == SWITCHABLE) {
-      const int ctx = vp9_get_pred_context_switchable_interp(xd);
+      const int ctx = get_pred_context_switchable_interp(xd);
       vp9_write_token(w, vp9_switchable_interp_tree,
                       cm->fc->switchable_interp_prob[ctx],
                       &switchable_interp_encodings[mi->interp_filter]);
--- a/vp9/encoder/vp9_encodeframe.c
+++ b/vp9/encoder/vp9_encodeframe.c
@@ -250,6 +250,7 @@
   const int mi_stride = xd->mi_stride;
   MODE_INFO *const src_mi = xd->mi[0];
   int i, j;
+
   for (j = 0; j < block_height; ++j)
     for (i = 0; i < block_width; ++i)
       xd->mi[j * mi_stride + i] = src_mi;
@@ -1277,7 +1278,7 @@
       vp9_update_mv_count(td);
 
       if (cm->interp_filter == SWITCHABLE) {
-        const int ctx = vp9_get_pred_context_switchable_interp(xd);
+        const int ctx = get_pred_context_switchable_interp(xd);
         ++td->counts->switchable_interp[ctx][xdmi->interp_filter];
       }
     }
@@ -1323,7 +1324,7 @@
   MODE_INFO *const mi = xd->mi[0];
   INTERP_FILTER filter_ref;
 
-  filter_ref = vp9_get_pred_context_switchable_interp(xd);
+  filter_ref = get_pred_context_switchable_interp(xd);
   if (filter_ref == SWITCHABLE_FILTERS)
     filter_ref = EIGHTTAP;
 
@@ -1900,7 +1901,7 @@
   if (is_inter_block(mi)) {
     vp9_update_mv_count(td);
     if (cm->interp_filter == SWITCHABLE) {
-      const int pred_ctx = vp9_get_pred_context_switchable_interp(xd);
+      const int pred_ctx = get_pred_context_switchable_interp(xd);
       ++td->counts->switchable_interp[pred_ctx][mi->interp_filter];
     }
 
@@ -2554,6 +2555,7 @@
   RD_COST this_rdc, sum_rdc, best_rdc;
   int do_split = bsize >= BLOCK_8X8;
   int do_rect = 1;
+  INTERP_FILTER pred_interp_filter;
 
   // Override skipping rectangular partition operations for edge blocks
   const int force_horz_split = (mi_row + mi_step >= cm->mi_rows);
@@ -2776,7 +2778,9 @@
   // If the interp_filter is marked as SWITCHABLE_FILTERS, it was for an
   // intra block and used for context purposes.
   if (ctx->mic.interp_filter == SWITCHABLE_FILTERS) {
-    ctx->mic.interp_filter = EIGHTTAP;
+    pred_interp_filter = EIGHTTAP;
+  } else {
+    pred_interp_filter = ctx->mic.interp_filter;
   }
 
   // PARTITION_SPLIT
@@ -2787,8 +2791,7 @@
     if (bsize == BLOCK_8X8) {
       i = 4;
       if (cpi->sf.adaptive_pred_interp_filter && partition_none_allowed)
-        pc_tree->leaf_split[0]->pred_interp_filter =
-            ctx->mic.interp_filter;
+        pc_tree->leaf_split[0]->pred_interp_filter = pred_interp_filter;
       rd_pick_sb_modes(cpi, tile_data, x, mi_row, mi_col, &sum_rdc, subsize,
                        pc_tree->leaf_split[0], best_rdc.rdcost);
 
@@ -2858,8 +2861,7 @@
       load_pred_mv(x, ctx);
     if (cpi->sf.adaptive_pred_interp_filter && bsize == BLOCK_8X8 &&
         partition_none_allowed)
-      pc_tree->horizontal[0].pred_interp_filter =
-          ctx->mic.interp_filter;
+      pc_tree->horizontal[0].pred_interp_filter = pred_interp_filter;
     rd_pick_sb_modes(cpi, tile_data, x, mi_row, mi_col, &sum_rdc, subsize,
                      &pc_tree->horizontal[0], best_rdc.rdcost);
 
@@ -2873,8 +2875,7 @@
         load_pred_mv(x, ctx);
       if (cpi->sf.adaptive_pred_interp_filter && bsize == BLOCK_8X8 &&
           partition_none_allowed)
-        pc_tree->horizontal[1].pred_interp_filter =
-            ctx->mic.interp_filter;
+        pc_tree->horizontal[1].pred_interp_filter = pred_interp_filter;
       rd_pick_sb_modes(cpi, tile_data, x, mi_row + mi_step, mi_col,
                        &this_rdc, subsize, &pc_tree->horizontal[1],
                        best_rdc.rdcost - sum_rdc.rdcost);
@@ -2911,8 +2912,7 @@
       load_pred_mv(x, ctx);
     if (cpi->sf.adaptive_pred_interp_filter && bsize == BLOCK_8X8 &&
         partition_none_allowed)
-      pc_tree->vertical[0].pred_interp_filter =
-          ctx->mic.interp_filter;
+      pc_tree->vertical[0].pred_interp_filter = pred_interp_filter;
     rd_pick_sb_modes(cpi, tile_data, x, mi_row, mi_col, &sum_rdc, subsize,
                      &pc_tree->vertical[0], best_rdc.rdcost);
     if (sum_rdc.rdcost < best_rdc.rdcost && mi_col + mi_step < cm->mi_cols &&
@@ -2925,8 +2925,7 @@
         load_pred_mv(x, ctx);
       if (cpi->sf.adaptive_pred_interp_filter && bsize == BLOCK_8X8 &&
           partition_none_allowed)
-        pc_tree->vertical[1].pred_interp_filter =
-            ctx->mic.interp_filter;
+        pc_tree->vertical[1].pred_interp_filter = pred_interp_filter;
       rd_pick_sb_modes(cpi, tile_data, x, mi_row, mi_col + mi_step,
                        &this_rdc, subsize,
                        &pc_tree->vertical[1], best_rdc.rdcost - sum_rdc.rdcost);
--- a/vp9/encoder/vp9_pickmode.c
+++ b/vp9/encoder/vp9_pickmode.c
@@ -1081,6 +1081,10 @@
   vp9_rd_cost_reset(&this_rdc);
 
   mi->ref_frame[0] = INTRA_FRAME;
+  // Initialize interp_filter here so we do not have to check for inter block
+  // modes in get_pred_context_switchable_interp()
+  mi->interp_filter = SWITCHABLE_FILTERS;
+
   mi->mv[0].as_int = INVALID_MV;
   mi->uv_mode = DC_PRED;
   memset(x->skip_txfm, 0, sizeof(x->skip_txfm));
@@ -1514,6 +1518,7 @@
   mi->sb_type = bsize;
   mi->ref_frame[0] = NONE;
   mi->ref_frame[1] = NONE;
+
   mi->tx_size = VPXMIN(max_txsize_lookup[bsize],
                        tx_mode_to_biggest_tx_size[cm->tx_mode]);
 
--- a/vp9/encoder/vp9_rd.c
+++ b/vp9/encoder/vp9_rd.c
@@ -565,7 +565,7 @@
 
 int vp9_get_switchable_rate(const VP9_COMP *cpi, const MACROBLOCKD *const xd) {
   const MODE_INFO *const mi = xd->mi[0];
-  const int ctx = vp9_get_pred_context_switchable_interp(xd);
+  const int ctx = get_pred_context_switchable_interp(xd);
   return SWITCHABLE_INTERP_RATE_FACTOR *
              cpi->switchable_interp_costs[ctx][mi->interp_filter];
 }
--- a/vp9/encoder/vp9_rdopt.c
+++ b/vp9/encoder/vp9_rdopt.c
@@ -3573,6 +3573,9 @@
           /* required for left and above block mv */
           mi->mv[0].as_int = 0;
           max_plane = 1;
+          // Initialize interp_filter here so we do not have to check for
+          // inter block modes in get_pred_context_switchable_interp()
+          mi->interp_filter = SWITCHABLE_FILTERS;
         } else {
           best_pred_sse = x->pred_sse[ref_frame];
         }
@@ -4356,6 +4359,9 @@
           /* required for left and above block mv */
           mi->mv[0].as_int = 0;
           max_plane = 1;
+          // Initialize interp_filter here so we do not have to check for
+          // inter block modes in get_pred_context_switchable_interp()
+          mi->interp_filter = SWITCHABLE_FILTERS;
         }
 
         rd_cost->rate = rate2;