Refactor interpolation_filter_rd()
Removed nested-if logic in interpolation_filter_rd()
and introduced switch case based on skip_pred.
Change-Id: Ib3dc96290f1d5585f65c80d2aa7e8484abe32ec2
diff --git a/av1/common/filter.h b/av1/common/filter.h
index 99b2e22..98c0846 100644
--- a/av1/common/filter.h
+++ b/av1/common/filter.h
@@ -45,6 +45,13 @@
USE_8_TAPS,
} UENUM1BYTE(SUBPEL_SEARCH_TYPE);
+enum {
+ INTERP_EVAL_LUMA_EVAL_CHROMA = 0,
+ INTERP_SKIP_LUMA_EVAL_CHROMA,
+ INTERP_EVAL_INVALID,
+ INTERP_SKIP_LUMA_SKIP_CHROMA,
+} UENUM1BYTE(INTERP_EVAL_PLANE);
+
// 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/encodeframe.c b/av1/encoder/encodeframe.c
index 3c7e465..8bb81bf 100644
--- a/av1/encoder/encodeframe.c
+++ b/av1/encoder/encodeframe.c
@@ -4543,8 +4543,8 @@
static void set_default_interp_skip_flags(AV1_COMP *cpi) {
const int num_planes = av1_num_planes(&cpi->common);
cpi->default_interp_skip_flags = (num_planes == 1)
- ? DEFAULT_LUMA_INTERP_SKIP_FLAG
- : DEFAULT_INTERP_SKIP_FLAG;
+ ? INTERP_SKIP_LUMA_EVAL_CHROMA
+ : INTERP_SKIP_LUMA_SKIP_CHROMA;
}
static void encode_frame_internal(AV1_COMP *cpi) {
diff --git a/av1/encoder/rdopt.c b/av1/encoder/rdopt.c
index 0fc3e35..000f5c8 100644
--- a/av1/encoder/rdopt.c
+++ b/av1/encoder/rdopt.c
@@ -8100,6 +8100,29 @@
return SWITCHABLE_INTERP_RATE_FACTOR * inter_filter_cost;
}
+// Build inter predictor and calculate model rd
+// for a given plane.
+static INLINE void interp_model_rd_eval(
+ MACROBLOCK *const x, const AV1_COMP *const cpi, BLOCK_SIZE bsize,
+ int mi_row, int mi_col, const BUFFER_SET *const orig_dst, int plane_from,
+ int plane_to, RD_STATS *rd_stats, int is_skip_build_pred) {
+ const AV1_COMMON *cm = &cpi->common;
+ MACROBLOCKD *const xd = &x->e_mbd;
+ RD_STATS tmp_rd_stats;
+
+ // Skip inter predictor if the predictor is already avilable.
+ if (!is_skip_build_pred)
+ av1_enc_build_inter_predictor(cm, xd, mi_row, mi_col, orig_dst, bsize,
+ plane_from, plane_to);
+
+ model_rd_sb_fn[MODELRD_TYPE_INTERP_FILTER](
+ cpi, bsize, x, xd, plane_from, plane_to, mi_row, mi_col,
+ &tmp_rd_stats.rate, &tmp_rd_stats.dist, &tmp_rd_stats.skip,
+ &tmp_rd_stats.sse, NULL, NULL, NULL);
+
+ av1_merge_rd_stats(rd_stats, &tmp_rd_stats);
+}
+
// calculate the rdcost of given interpolation_filter
static INLINE int64_t interpolation_filter_rd(
MACROBLOCK *const x, const AV1_COMP *const cpi,
@@ -8116,7 +8139,7 @@
// Initialize rd_stats structures to default values.
av1_init_rd_stats(&this_rd_stats_luma);
- av1_init_rd_stats(&this_rd_stats);
+ this_rd_stats = *rd_stats_luma;
const int_interpfilters last_best = mbmi->interp_filters;
mbmi->interp_filters = filter_sets[filter_idx];
const int tmp_rs =
@@ -8138,28 +8161,33 @@
assert((rd_stats->skip == 0) || (rd_stats->skip == 1));
assert((skip_pred >= 0) && (skip_pred <= cpi->default_interp_skip_flags));
- if (skip_pred != cpi->default_interp_skip_flags) {
- if (skip_pred != DEFAULT_LUMA_INTERP_SKIP_FLAG) {
- av1_enc_build_inter_predictor(cm, xd, mi_row, mi_col, orig_dst, bsize,
- AOM_PLANE_Y, AOM_PLANE_Y);
+ // When skip pred is equal to default_interp_skip_flags,
+ // skip both luma and chroma MC.
+ // For mono-chrome images:
+ // num_planes = 1 and cpi->default_interp_skip_flags = 1,
+ // skip_pred = 1: skip both luma and chroma
+ // skip_pred = 0: Evaluate luma and as num_planes=1,
+ // skip chroma evaluation
+ int tmp_skip_pred = (skip_pred == cpi->default_interp_skip_flags)
+ ? INTERP_SKIP_LUMA_SKIP_CHROMA
+ : skip_pred;
+
+ switch (tmp_skip_pred) {
+ case INTERP_EVAL_LUMA_EVAL_CHROMA:
+ // skip_pred = 0: Evaluate both luma and chroma.
+ // Luma MC
+ interp_model_rd_eval(x, cpi, bsize, mi_row, mi_col, orig_dst, AOM_PLANE_Y,
+ AOM_PLANE_Y, &this_rd_stats_luma, 0);
+ this_rd_stats = this_rd_stats_luma;
#if CONFIG_COLLECT_RD_STATS == 3
RD_STATS rd_stats_y;
pick_tx_size_type_yrd(cpi, x, &rd_stats_y, bsize, mi_row, mi_col,
INT64_MAX);
PrintPredictionUnitStats(cpi, tile_data, x, &rd_stats_y, bsize);
#endif // CONFIG_COLLECT_RD_STATS == 3
- model_rd_sb_fn[MODELRD_TYPE_INTERP_FILTER](
- cpi, bsize, x, xd, 0, 0, mi_row, mi_col, &this_rd_stats_luma.rate,
- &this_rd_stats_luma.dist, &this_rd_stats_luma.skip,
- &this_rd_stats_luma.sse, NULL, NULL, NULL);
- this_rd_stats = this_rd_stats_luma;
- } else {
- // only luma MC is skipped
- this_rd_stats = *rd_stats_luma;
- }
- if (num_planes > 1) {
- int64_t this_dist = 0, this_skip_sse = 0;
- int this_rate = 0, this_skip_sb = 1;
+ case INTERP_SKIP_LUMA_EVAL_CHROMA:
+ // skip_pred = 1: skip luma evaluation (retain previous best luma stats)
+ // and do chroma evaluation.
for (int plane = 1; plane < num_planes; ++plane) {
int64_t tmp_rd =
RDCOST(x->rdmult, tmp_rs + this_rd_stats.rate, this_rd_stats.dist);
@@ -8167,18 +8195,16 @@
mbmi->interp_filters = last_best;
return 0;
}
- av1_enc_build_inter_predictor(cm, xd, mi_row, mi_col, orig_dst, bsize,
- plane, plane);
- model_rd_sb_fn[MODELRD_TYPE_INTERP_FILTER](
- cpi, bsize, x, xd, plane, plane, mi_row, mi_col, &this_rate,
- &this_dist, &this_skip_sb, &this_skip_sse, NULL, NULL, NULL);
- av1_accumulate_rd_stats(&this_rd_stats, this_dist, this_rate,
- this_skip_sb, this_skip_sse, 0);
+ interp_model_rd_eval(x, cpi, bsize, mi_row, mi_col, orig_dst, plane,
+ plane, &this_rd_stats, 0);
}
- }
- } else {
- // both luma and chroma MC is skipped
- this_rd_stats = *rd_stats;
+ break;
+ case INTERP_SKIP_LUMA_SKIP_CHROMA:
+ // both luma and chroma evaluation is skipped
+ this_rd_stats = *rd_stats;
+ break;
+ case INTERP_EVAL_INVALID:
+ default: assert(1); return 0;
}
int64_t tmp_rd =
RDCOST(x->rdmult, tmp_rs + this_rd_stats.rate, this_rd_stats.dist);
@@ -8187,13 +8213,13 @@
*rd = tmp_rd;
*switchable_rate = tmp_rs;
if (skip_pred != cpi->default_interp_skip_flags) {
- if (skip_pred == 0) {
+ if (skip_pred == INTERP_EVAL_LUMA_EVAL_CHROMA) {
// Overwrite the data as current filter is the best one
*rd_stats_luma = this_rd_stats_luma;
*rd_stats = this_rd_stats;
// As luma MC data is computed, no need to recompute after the search
x->recalc_luma_mc_data = 0;
- } else if (skip_pred == DEFAULT_LUMA_INTERP_SKIP_FLAG) {
+ } else if (skip_pred == INTERP_SKIP_LUMA_EVAL_CHROMA) {
// As luma MC data is not computed, update of luma data can be skipped
*rd_stats = this_rd_stats;
// As luma MC data is not recomputed and current filter is the best,
@@ -8553,35 +8579,30 @@
switchable_ctx[1] = av1_get_pred_context_switchable_interp(xd, 1);
*switchable_rate =
get_switchable_rate(x, mbmi->interp_filters, switchable_ctx);
- if (!(*skip_build_pred)) {
- av1_enc_build_inter_predictor(cm, xd, mi_row, mi_col, orig_dst, bsize, 0,
- av1_num_planes(cm) - 1);
- *skip_build_pred = 1;
- }
+
+ // Do MC evaluation for default filter_type.
+ // Luma MC
+ interp_model_rd_eval(x, cpi, bsize, mi_row, mi_col, orig_dst, AOM_PLANE_Y,
+ AOM_PLANE_Y, &rd_stats_luma, *skip_build_pred);
#if CONFIG_COLLECT_RD_STATS == 3
RD_STATS rd_stats_y;
pick_tx_size_type_yrd(cpi, x, &rd_stats_y, bsize, mi_row, mi_col, INT64_MAX);
PrintPredictionUnitStats(cpi, tile_data, x, &rd_stats_y, bsize);
#endif // CONFIG_COLLECT_RD_STATS == 3
- {
- model_rd_sb_fn[MODELRD_TYPE_INTERP_FILTER](
- cpi, bsize, x, xd, 0, 0, mi_row, mi_col, &rd_stats_luma.rate,
- &rd_stats_luma.dist, &rd_stats_luma.skip, &rd_stats_luma.sse, NULL,
- NULL, NULL);
- if (num_planes > 1) {
- model_rd_sb_fn[MODELRD_TYPE_INTERP_FILTER](
- cpi, bsize, x, xd, 1, num_planes - 1, mi_row, mi_col, &rd_stats.rate,
- &rd_stats.dist, &rd_stats.skip, &rd_stats.sse, NULL, NULL, NULL);
- }
+ // Chroma MC
+ if (num_planes > 1)
+ interp_model_rd_eval(x, cpi, bsize, mi_row, mi_col, orig_dst, AOM_PLANE_U,
+ AOM_PLANE_V, &rd_stats, *skip_build_pred);
+ *skip_build_pred = 1;
- av1_merge_rd_stats(&rd_stats, &rd_stats_luma);
+ av1_merge_rd_stats(&rd_stats, &rd_stats_luma);
- assert(rd_stats.rate >= 0);
+ assert(rd_stats.rate >= 0);
- *rd = RDCOST(x->rdmult, *switchable_rate + rd_stats.rate, rd_stats.dist);
- x->pred_sse[ref_frame] = (unsigned int)(rd_stats_luma.sse >> 4);
- }
+ *rd = RDCOST(x->rdmult, *switchable_rate + rd_stats.rate, rd_stats.dist);
+ x->pred_sse[ref_frame] = (unsigned int)(rd_stats_luma.sse >> 4);
+
if (assign_filter != SWITCHABLE || match_found_idx != -1) {
return 0;
}
diff --git a/av1/encoder/rdopt.h b/av1/encoder/rdopt.h
index bf21cee..0241829 100644
--- a/av1/encoder/rdopt.h
+++ b/av1/encoder/rdopt.h
@@ -27,10 +27,6 @@
#endif
#define MAX_REF_MV_SEARCH 3
-#define DEFAULT_LUMA_INTERP_SKIP_FLAG 1
-#define DEFAULT_CHROMA_INTERP_SKIP_FLAG 2
-#define DEFAULT_INTERP_SKIP_FLAG \
- (DEFAULT_LUMA_INTERP_SKIP_FLAG | DEFAULT_CHROMA_INTERP_SKIP_FLAG)
#define INTER_INTRA_RD_THRESH_SCALE 9
#define INTER_INTRA_RD_THRESH_SHIFT 4
#define COMP_TYPE_RD_THRESH_SCALE 11