Merge "VP9: get_pred_context_switchable_interp() -- encoder side"

This commit is contained in:
Scott LaVarnway 2016-07-25 11:58:24 +00:00 committed by Gerrit Code Review
commit ad5fea03e6
8 changed files with 49 additions and 68 deletions

View File

@ -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;

View File

@ -66,7 +66,27 @@ static INLINE vpx_prob vp9_get_skip_prob(const VP9_COMMON *cm,
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.

View File

@ -353,36 +353,10 @@ static void read_ref_frames(VP9_COMMON *const cm, MACROBLOCKD *const xd,
}
}
// 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 @@ static void read_intra_block_mode_info(VP9_COMMON *const cm,
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;

View File

@ -293,7 +293,7 @@ static void pack_inter_mode_mvs(VP9_COMP *cpi, const MODE_INFO *mi,
}
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]);

View File

@ -250,6 +250,7 @@ static void duplicate_mode_info_in_sb(VP9_COMMON *cm, MACROBLOCKD *xd,
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 @@ static void update_state(VP9_COMP *cpi, ThreadData *td,
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 @@ static void set_mode_info_seg_skip(MACROBLOCK *x, TX_MODE tx_mode,
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 @@ static void update_state_rt(VP9_COMP *cpi, ThreadData *td,
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 @@ static void rd_pick_partition(VP9_COMP *cpi, ThreadData *td,
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 @@ static void rd_pick_partition(VP9_COMP *cpi, ThreadData *td,
// 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 @@ static void rd_pick_partition(VP9_COMP *cpi, ThreadData *td,
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 @@ static void rd_pick_partition(VP9_COMP *cpi, ThreadData *td,
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 @@ static void rd_pick_partition(VP9_COMP *cpi, ThreadData *td,
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 @@ static void rd_pick_partition(VP9_COMP *cpi, ThreadData *td,
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 @@ static void rd_pick_partition(VP9_COMP *cpi, ThreadData *td,
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);

View File

@ -1081,6 +1081,10 @@ void vp9_pick_intra_mode(VP9_COMP *cpi, MACROBLOCK *x, RD_COST *rd_cost,
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 @@ void vp9_pick_inter_mode(VP9_COMP *cpi, MACROBLOCK *x,
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]);

View File

@ -565,7 +565,7 @@ YV12_BUFFER_CONFIG *vp9_get_scaled_ref_frame(const VP9_COMP *cpi,
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];
}

View File

@ -3573,6 +3573,9 @@ void vp9_rd_pick_inter_mode_sb(VP9_COMP *cpi,
/* 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 @@ void vp9_rd_pick_inter_mode_sub8x8(VP9_COMP *cpi,
/* 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;