Modify pred_filter_search function
Change-Id: Ie6f246f622ddfd2c255f0cfa14ec18c49c3a2d44
diff --git a/av1/common/filter.h b/av1/common/filter.h
index 98c0846..d6a86a7 100644
--- a/av1/common/filter.h
+++ b/av1/common/filter.h
@@ -52,6 +52,12 @@
INTERP_SKIP_LUMA_SKIP_CHROMA,
} UENUM1BYTE(INTERP_EVAL_PLANE);
+enum {
+ INTERP_HORZ_NEQ_VERT_NEQ = 0,
+ INTERP_HORZ_EQ_VERT_NEQ,
+ INTERP_HORZ_NEQ_VERT_EQ,
+ INTERP_HORZ_EQ_VERT_EQ,
+} UENUM1BYTE(INTERP_PRED_TYPE);
// Pack two InterpFilter's into a uint32_t: since there are at most 10 filters,
// we can use 16 bits for each and have more than enough space. This reduces
// argument passing and unifies the operation of setting a (pair of) filters.
diff --git a/av1/encoder/rdopt.c b/av1/encoder/rdopt.c
index 9184a46..9b8ce17 100644
--- a/av1/encoder/rdopt.c
+++ b/av1/encoder/rdopt.c
@@ -8253,22 +8253,39 @@
return 0;
}
-static INLINE int is_pred_filter_search_allowed(
- const AV1_COMP *const cpi, BLOCK_SIZE bsize, int mi_row, int mi_col,
- InterpFilter af_horiz, InterpFilter af_vert, InterpFilter lf_horiz,
- InterpFilter lf_vert) {
+static INLINE INTERP_PRED_TYPE is_pred_filter_search_allowed(
+ const AV1_COMP *const cpi, MACROBLOCKD *xd, BLOCK_SIZE bsize, int mi_row,
+ int mi_col, int_interpfilters *af, int_interpfilters *lf) {
const AV1_COMMON *cm = &cpi->common;
+ const MB_MODE_INFO *const above_mbmi = xd->above_mbmi;
+ const MB_MODE_INFO *const left_mbmi = xd->left_mbmi;
const int bsl = mi_size_wide_log2[bsize];
- int pred_filter_search =
+ int is_horiz_eq = 0, is_vert_eq = 0;
+
+ if (above_mbmi && is_inter_block(above_mbmi))
+ *af = above_mbmi->interp_filters;
+
+ if (left_mbmi && is_inter_block(left_mbmi)) *lf = left_mbmi->interp_filters;
+
+ if (af->as_filters.x_filter != INTERP_INVALID)
+ is_horiz_eq = af->as_filters.x_filter == lf->as_filters.x_filter;
+ if (af->as_filters.y_filter != INTERP_INVALID)
+ is_vert_eq = af->as_filters.y_filter == lf->as_filters.y_filter;
+
+ INTERP_PRED_TYPE pred_filter_type = (is_vert_eq << 1) + is_horiz_eq;
+ int pred_filter_enable =
cpi->sf.cb_pred_filter_search
? (((mi_row + mi_col) >> bsl) +
get_chessboard_index(cm->current_frame.frame_number)) &
0x1
: 0;
- pred_filter_search &=
- ((af_horiz == lf_horiz) && (af_horiz != INTERP_INVALID)) ||
- ((af_vert == lf_vert) && (af_vert != INTERP_INVALID));
- return pred_filter_search;
+ pred_filter_enable &= is_horiz_eq || is_vert_eq;
+ // pred_filter_search = 0: pred_filter is disabled
+ // pred_filter_search = 1: pred_filter is enabled and only horz pred matching
+ // pred_filter_search = 2: pred_filter is enabled and only vert pred matching
+ // pred_filter_search = 3: pred_filter is enabled and
+ // both vert, horz pred matching
+ return pred_filter_enable * pred_filter_type;
}
static INLINE void pred_dual_interp_filter_rd(
@@ -8276,30 +8293,30 @@
const TileDataEnc *tile_data, BLOCK_SIZE bsize, int mi_row, int mi_col,
const BUFFER_SET *const orig_dst, int64_t *const rd, RD_STATS *rd_stats_y,
RD_STATS *rd_stats, int *const switchable_rate,
- const BUFFER_SET *dst_bufs[2], int filter_idx, const int switchable_ctx[2],
- const int skip_pred, InterpFilter af_horiz, InterpFilter af_vert,
- InterpFilter lf_horiz, InterpFilter lf_vert) {
- if ((af_horiz == lf_horiz) && (af_horiz != INTERP_INVALID)) {
- if (((af_vert == lf_vert) && (af_vert != INTERP_INVALID))) {
- filter_idx = af_horiz + (af_vert * SWITCHABLE_FILTERS);
+ const BUFFER_SET *dst_bufs[2], const int switchable_ctx[2],
+ const int skip_pred, INTERP_PRED_TYPE pred_filt_type, int_interpfilters *af,
+ int_interpfilters *lf) {
+ (void)lf;
+ int filter_idx = 0;
+ InterpFilter af_horiz = INTERP_INVALID, af_vert = INTERP_INVALID;
+ af_horiz = af->as_filters.x_filter;
+ af_vert = af->as_filters.y_filter;
+ assert(pred_filt_type != INTERP_HORZ_NEQ_VERT_NEQ);
+
+ // pred_filter_search = 1: pred_filter is enabled and only horz pred matching
+ if (pred_filt_type == INTERP_HORZ_EQ_VERT_NEQ) {
+ for (filter_idx = af_horiz; filter_idx < (DUAL_FILTER_SET_SIZE);
+ filter_idx += SWITCHABLE_FILTERS) {
if (filter_idx) {
interpolation_filter_rd(x, cpi, tile_data, bsize, mi_row, mi_col,
orig_dst, rd, rd_stats_y, rd_stats,
switchable_rate, dst_bufs, filter_idx,
switchable_ctx, skip_pred);
}
- } else {
- for (filter_idx = af_horiz; filter_idx < (DUAL_FILTER_SET_SIZE);
- filter_idx += SWITCHABLE_FILTERS) {
- if (filter_idx) {
- interpolation_filter_rd(x, cpi, tile_data, bsize, mi_row, mi_col,
- orig_dst, rd, rd_stats_y, rd_stats,
- switchable_rate, dst_bufs, filter_idx,
- switchable_ctx, skip_pred);
- }
- }
}
- } else if ((af_vert == lf_vert) && (af_vert != INTERP_INVALID)) {
+ } else if (pred_filt_type == INTERP_HORZ_NEQ_VERT_EQ) {
+ // pred_filter_search = 2: pred_filter is enabled and
+ // only vert pred matching
for (filter_idx = (af_vert * SWITCHABLE_FILTERS);
filter_idx <= ((af_vert * SWITCHABLE_FILTERS) + 2); filter_idx += 1) {
if (filter_idx) {
@@ -8309,6 +8326,18 @@
switchable_ctx, skip_pred);
}
}
+ } else if (pred_filt_type == INTERP_HORZ_EQ_VERT_EQ) {
+ // pred_filter_search = 3: pred_filter is enabled and
+ // both vert, horz pred matching
+ filter_idx = af_horiz + (af_vert * SWITCHABLE_FILTERS);
+ if (filter_idx) {
+ interpolation_filter_rd(x, cpi, tile_data, bsize, mi_row, mi_col,
+ orig_dst, rd, rd_stats_y, rd_stats,
+ switchable_rate, dst_bufs, filter_idx,
+ switchable_ctx, skip_pred);
+ }
+ } else {
+ assert(0);
}
}
// Evaluate dual filter type
@@ -8324,30 +8353,19 @@
const int skip_hor, const int skip_ver) {
MACROBLOCKD *const xd = &x->e_mbd;
MB_MODE_INFO *const mbmi = xd->mi[0];
- int pred_filter_search = 0;
- InterpFilter af_horiz = INTERP_INVALID, af_vert = INTERP_INVALID,
- lf_horiz = INTERP_INVALID, lf_vert = INTERP_INVALID;
- if (!have_newmv_in_inter_mode(mbmi->mode)) {
- const MB_MODE_INFO *const above_mbmi = xd->above_mbmi;
- const MB_MODE_INFO *const left_mbmi = xd->left_mbmi;
- if (above_mbmi && is_inter_block(above_mbmi)) {
- af_horiz = above_mbmi->interp_filters.as_filters.x_filter;
- af_vert = above_mbmi->interp_filters.as_filters.y_filter;
- }
- if (left_mbmi && is_inter_block(left_mbmi)) {
- lf_horiz = left_mbmi->interp_filters.as_filters.x_filter;
- lf_vert = left_mbmi->interp_filters.as_filters.y_filter;
- }
- pred_filter_search = is_pred_filter_search_allowed(
- cpi, bsize, mi_row, mi_col, af_horiz, af_vert, lf_horiz, lf_vert);
- }
+ INTERP_PRED_TYPE pred_filter_type = INTERP_HORZ_NEQ_VERT_NEQ;
+ int_interpfilters af = av1_broadcast_interp_filter(INTERP_INVALID);
+ int_interpfilters lf = af;
- if (pred_filter_search) {
- int filter_idx = 0;
+ if (!have_newmv_in_inter_mode(mbmi->mode))
+ pred_filter_type =
+ is_pred_filter_search_allowed(cpi, xd, bsize, mi_row, mi_col, &af, &lf);
+
+ if (pred_filter_type) {
pred_dual_interp_filter_rd(
x, cpi, tile_data, bsize, mi_row, mi_col, orig_dst, rd, rd_stats_y,
- rd_stats, switchable_rate, dst_bufs, filter_idx, switchable_ctx,
- (skip_hor & skip_ver), af_horiz, af_vert, lf_horiz, lf_vert);
+ rd_stats, switchable_rate, dst_bufs, switchable_ctx,
+ (skip_hor & skip_ver), pred_filter_type, &af, &lf);
} else {
const int bw = block_size_wide[bsize];
const int bh = block_size_high[bsize];
@@ -8391,22 +8409,15 @@
assert(x->e_mbd.mi[0]->interp_filters.as_int == filter_sets[0].as_int);
assert(filter_set_size == DUAL_FILTER_SET_SIZE);
if ((skip_hor & skip_ver) != cpi->default_interp_skip_flags) {
- int pred_filter_search;
- InterpFilter af_horiz = INTERP_INVALID, lf_horiz = INTERP_INVALID;
- int filter_idx;
- const MB_MODE_INFO *const above_mbmi = xd->above_mbmi;
- const MB_MODE_INFO *const left_mbmi = xd->left_mbmi;
- if (above_mbmi && is_inter_block(above_mbmi)) {
- af_horiz = above_mbmi->interp_filters.as_filters.x_filter;
- }
- if (left_mbmi && is_inter_block(left_mbmi)) {
- lf_horiz = left_mbmi->interp_filters.as_filters.x_filter;
- }
- pred_filter_search = is_pred_filter_search_allowed(
- cpi, bsize, mi_row, mi_col, af_horiz, af_horiz, lf_horiz, lf_horiz);
- if (pred_filter_search) {
- assert(af_horiz != INTERP_INVALID);
- filter_idx = SWITCHABLE * af_horiz;
+ INTERP_PRED_TYPE pred_filter_type = INTERP_HORZ_NEQ_VERT_NEQ;
+ int_interpfilters af = av1_broadcast_interp_filter(INTERP_INVALID);
+ int_interpfilters lf = af;
+
+ pred_filter_type =
+ is_pred_filter_search_allowed(cpi, xd, bsize, mi_row, mi_col, &af, &lf);
+ if (pred_filter_type) {
+ assert(af.as_filters.x_filter != INTERP_INVALID);
+ int filter_idx = SWITCHABLE * af.as_filters.x_filter;
// This assert tells that (filter_x == filter_y) for non-dual filter case
assert(filter_sets[filter_idx].as_filters.x_filter ==
filter_sets[filter_idx].as_filters.y_filter);