Use RD_STATS for interp rd params
Replaced the stat variables of rate, dist, skip, sse with RD_STATS
structure.
Change-Id: I67429cff3112b32e14a8ffe5c38f50dcf4d79c64
diff --git a/av1/encoder/rd.h b/av1/encoder/rd.h
index 67add28..de8e0b3 100644
--- a/av1/encoder/rd.h
+++ b/av1/encoder/rd.h
@@ -379,6 +379,17 @@
#endif
}
+static INLINE void av1_accumulate_rd_stats(RD_STATS *rd_stats, int64_t dist,
+ int rate, int skip, int64_t sse,
+ int zero_rate) {
+ assert(rd_stats->rate != INT_MAX && rate != INT_MAX);
+ rd_stats->rate += rate;
+ if (!rd_stats->zero_rate) rd_stats->zero_rate = zero_rate;
+ rd_stats->dist += dist;
+ rd_stats->skip &= skip;
+ rd_stats->sse += sse;
+}
+
static INLINE int64_t av1_calculate_rd_cost(int mult, int rate, int64_t dist) {
assert(mult >= 0);
if (rate >= 0) {
diff --git a/av1/encoder/rdopt.c b/av1/encoder/rdopt.c
index f3491ab..48e0300 100644
--- a/av1/encoder/rdopt.c
+++ b/av1/encoder/rdopt.c
@@ -8105,17 +8105,18 @@
MACROBLOCK *const x, const AV1_COMP *const cpi,
const TileDataEnc *tile_data, BLOCK_SIZE bsize, int mi_row, int mi_col,
const BUFFER_SET *const orig_dst, int64_t *const rd,
- int *const switchable_rate, int *const skip_txfm_sb,
- int64_t *const skip_sse_sb, const BUFFER_SET *dst_bufs[2], int filter_idx,
- const int switchable_ctx[2], const int skip_pred, int *rate,
- int64_t *dist) {
+ RD_STATS *rd_stats_luma, 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) {
const AV1_COMMON *cm = &cpi->common;
const int num_planes = av1_num_planes(cm);
MACROBLOCKD *const xd = &x->e_mbd;
MB_MODE_INFO *const mbmi = xd->mi[0];
- int tmp_rate[2], tmp_skip_sb[2] = { 1, 1 };
- int64_t tmp_dist[2], tmp_skip_sse[2] = { 0, 0 };
+ RD_STATS this_rd_stats_luma, this_rd_stats;
+ // Initialize rd_stats structures to default values.
+ av1_init_rd_stats(&this_rd_stats_luma);
+ av1_init_rd_stats(&this_rd_stats);
const int_interpfilters last_best = mbmi->interp_filters;
mbmi->interp_filters = filter_sets[filter_idx];
const int tmp_rs =
@@ -8130,15 +8131,12 @@
(void)tile_data;
assert(skip_pred != 2);
+ assert((rd_stats_luma->rate >= 0) && (rd_stats->rate >= 0));
+ assert((rd_stats_luma->dist >= 0) && (rd_stats->dist >= 0));
+ assert((rd_stats_luma->sse >= 0) && (rd_stats->sse >= 0));
+ assert((rd_stats_luma->skip == 0) || (rd_stats_luma->skip == 1));
+ assert((rd_stats->skip == 0) || (rd_stats->skip == 1));
assert((skip_pred >= 0) && (skip_pred <= cpi->default_interp_skip_flags));
- assert(rate[0] >= 0);
- assert(dist[0] >= 0);
- assert((skip_txfm_sb[0] == 0) || (skip_txfm_sb[0] == 1));
- assert(skip_sse_sb[0] >= 0);
- assert(rate[1] >= 0);
- assert(dist[1] >= 0);
- assert((skip_txfm_sb[1] == 0) || (skip_txfm_sb[1] == 1));
- assert(skip_sse_sb[1] >= 0);
if (skip_pred != cpi->default_interp_skip_flags) {
if (skip_pred != DEFAULT_LUMA_INTERP_SKIP_FLAG) {
@@ -8151,20 +8149,20 @@
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, &tmp_rate[0], &tmp_dist[0],
- &tmp_skip_sb[0], &tmp_skip_sse[0], NULL, NULL, NULL);
- tmp_rate[1] = tmp_rate[0];
- tmp_dist[1] = tmp_dist[0];
+ 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
- tmp_rate[1] = rate[0];
- tmp_dist[1] = dist[0];
+ 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;
for (int plane = 1; plane < num_planes; ++plane) {
- int tmp_rate_uv, tmp_skip_sb_uv;
- int64_t tmp_dist_uv, tmp_skip_sse_uv;
- int64_t tmp_rd = RDCOST(x->rdmult, tmp_rs + tmp_rate[1], tmp_dist[1]);
+ int64_t tmp_rd =
+ RDCOST(x->rdmult, tmp_rs + this_rd_stats.rate, this_rd_stats.dist);
if (tmp_rd >= *rd) {
mbmi->interp_filters = last_best;
return 0;
@@ -8172,21 +8170,18 @@
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, &tmp_rate_uv,
- &tmp_dist_uv, &tmp_skip_sb_uv, &tmp_skip_sse_uv, NULL, NULL, NULL);
- tmp_rate[1] =
- (int)AOMMIN(((int64_t)tmp_rate[1] + (int64_t)tmp_rate_uv), INT_MAX);
- tmp_dist[1] += tmp_dist_uv;
- tmp_skip_sb[1] &= tmp_skip_sb_uv;
- tmp_skip_sse[1] += tmp_skip_sse_uv;
+ 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);
}
}
} else {
// both luma and chroma MC is skipped
- tmp_rate[1] = rate[1];
- tmp_dist[1] = dist[1];
+ this_rd_stats = *rd_stats;
}
- int64_t tmp_rd = RDCOST(x->rdmult, tmp_rs + tmp_rate[1], tmp_dist[1]);
+ int64_t tmp_rd =
+ RDCOST(x->rdmult, tmp_rs + this_rd_stats.rate, this_rd_stats.dist);
if (tmp_rd < *rd) {
*rd = tmp_rd;
@@ -8194,20 +8189,13 @@
if (skip_pred != cpi->default_interp_skip_flags) {
if (skip_pred == 0) {
// Overwrite the data as current filter is the best one
- tmp_skip_sb[1] = tmp_skip_sb[0] & tmp_skip_sb[1];
- tmp_skip_sse[1] = tmp_skip_sse[0] + tmp_skip_sse[1];
- memcpy(rate, tmp_rate, sizeof(*rate) * 2);
- memcpy(dist, tmp_dist, sizeof(*dist) * 2);
- memcpy(skip_txfm_sb, tmp_skip_sb, sizeof(*skip_txfm_sb) * 2);
- memcpy(skip_sse_sb, tmp_skip_sse, sizeof(*skip_sse_sb) * 2);
+ *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) {
// As luma MC data is not computed, update of luma data can be skipped
- rate[1] = tmp_rate[1];
- dist[1] = tmp_dist[1];
- skip_txfm_sb[1] = skip_txfm_sb[0] & tmp_skip_sb[1];
- skip_sse_sb[1] = skip_sse_sb[0] + tmp_skip_sse[1];
+ *rd_stats = this_rd_stats;
// As luma MC data is not recomputed and current filter is the best,
// indicate the possibility of recomputing MC data
// If current buffer contains valid MC data, toggle to indicate that
@@ -8243,29 +8231,28 @@
static INLINE void pred_dual_interp_filter_rd(
MACROBLOCK *const x, const AV1_COMP *const cpi,
const TileDataEnc *tile_data, BLOCK_SIZE bsize, int mi_row, int mi_col,
- const BUFFER_SET *const orig_dst, int64_t *const rd,
- int *const switchable_rate, int *const skip_txfm_sb,
- int64_t *const skip_sse_sb, const BUFFER_SET *dst_bufs[2], int filter_idx,
- const int switchable_ctx[2], const int skip_pred, int *rate, int64_t *dist,
- InterpFilter af_horiz, InterpFilter af_vert, InterpFilter lf_horiz,
- InterpFilter lf_vert) {
+ 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);
if (filter_idx) {
interpolation_filter_rd(x, cpi, tile_data, bsize, mi_row, mi_col,
- orig_dst, rd, switchable_rate, skip_txfm_sb,
- skip_sse_sb, dst_bufs, filter_idx,
- switchable_ctx, skip_pred, rate, dist);
+ 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, switchable_rate, skip_txfm_sb,
- skip_sse_sb, dst_bufs, filter_idx,
- switchable_ctx, skip_pred, rate, dist);
+ orig_dst, rd, rd_stats_y, rd_stats,
+ switchable_rate, dst_bufs, filter_idx,
+ switchable_ctx, skip_pred);
}
}
}
@@ -8274,9 +8261,9 @@
filter_idx <= ((af_vert * SWITCHABLE_FILTERS) + 2); filter_idx += 1) {
if (filter_idx) {
interpolation_filter_rd(x, cpi, tile_data, bsize, mi_row, mi_col,
- orig_dst, rd, switchable_rate, skip_txfm_sb,
- skip_sse_sb, dst_bufs, filter_idx,
- switchable_ctx, skip_pred, rate, dist);
+ orig_dst, rd, rd_stats_y, rd_stats,
+ switchable_rate, dst_bufs, filter_idx,
+ switchable_ctx, skip_pred);
}
}
}
@@ -8286,11 +8273,10 @@
static INLINE void find_best_non_dual_interp_filter(
MACROBLOCK *const x, const AV1_COMP *const cpi,
const TileDataEnc *tile_data, BLOCK_SIZE bsize, int mi_row, int mi_col,
- const BUFFER_SET *const orig_dst, int64_t *const rd,
- int *const switchable_rate, int *const skip_txfm_sb,
- int64_t *const skip_sse_sb, const BUFFER_SET *dst_bufs[2],
- const int switchable_ctx[2], const int skip_ver, const int skip_hor,
- int *rate, int64_t *dist, int filter_set_size) {
+ 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], const int switchable_ctx[2],
+ const int skip_ver, const int skip_hor, int filter_set_size) {
int16_t i;
MACROBLOCKD *const xd = &x->e_mbd;
MB_MODE_INFO *const mbmi = xd->mi[0];
@@ -8324,10 +8310,10 @@
return;
}
if (filter_idx) {
- interpolation_filter_rd(
- x, cpi, tile_data, bsize, mi_row, mi_col, orig_dst, rd,
- switchable_rate, skip_txfm_sb, skip_sse_sb, dst_bufs, filter_idx,
- switchable_ctx, (skip_hor & skip_ver), rate, dist);
+ 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_hor & skip_ver));
}
return;
}
@@ -8356,10 +8342,9 @@
(cpi->sf.interp_filter_search_mask & (1 << (i >> 2)))) {
continue;
}
- interpolation_filter_rd(x, cpi, tile_data, bsize, mi_row, mi_col,
- orig_dst, rd, switchable_rate, skip_txfm_sb,
- skip_sse_sb, dst_bufs, i, switchable_ctx,
- skip_pred, rate, dist);
+ interpolation_filter_rd(
+ x, cpi, tile_data, bsize, mi_row, mi_col, orig_dst, rd, rd_stats_y,
+ rd_stats, switchable_rate, dst_bufs, i, switchable_ctx, skip_pred);
skip_pred = (skip_hor & skip_ver);
}
} else {
@@ -8373,10 +8358,9 @@
(cpi->sf.interp_filter_search_mask & (1 << (i >> 2)))) {
continue;
}
- interpolation_filter_rd(x, cpi, tile_data, bsize, mi_row, mi_col,
- orig_dst, rd, switchable_rate, skip_txfm_sb,
- skip_sse_sb, dst_bufs, i, switchable_ctx,
- skip_pred, rate, dist);
+ interpolation_filter_rd(
+ x, cpi, tile_data, bsize, mi_row, mi_col, orig_dst, rd, rd_stats_y,
+ rd_stats, switchable_rate, dst_bufs, i, switchable_ctx, skip_pred);
// In first iteration, smooth filter is evaluated. If smooth filter
// (which is less sharper) is the winner among regular and smooth filters,
// sharp filter evaluation is skipped
@@ -8545,13 +8529,12 @@
const int need_search =
av1_is_interp_needed(xd) && av1_is_interp_search_needed(xd);
int i;
- // Index 0 corresponds to luma rd data and index 1 corresponds to cummulative
- // data of all planes
- int tmp_rate[2] = { 0, 0 };
- int64_t tmp_dist[2] = { 0, 0 };
- int best_skip_txfm_sb[2] = { 1, 1 };
- int64_t best_skip_sse_sb[2] = { 0, 0 };
const int ref_frame = xd->mi[0]->ref_frame[0];
+ RD_STATS rd_stats_luma, rd_stats;
+
+ // Initialization of rd_stats structures with default values
+ av1_init_rd_stats(&rd_stats_luma);
+ av1_init_rd_stats(&rd_stats);
(void)single_filter;
int match_found_idx = -1;
@@ -8589,25 +8572,26 @@
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, &tmp_rate[0], &tmp_dist[0],
- &best_skip_txfm_sb[0], &best_skip_sse_sb[0], 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, &tmp_rate[1],
- &tmp_dist[1], &best_skip_txfm_sb[1], &best_skip_sse_sb[1], NULL, NULL,
- NULL);
- tmp_rate[1] =
- (int)AOMMIN((int64_t)tmp_rate[0] + (int64_t)tmp_rate[1], INT_MAX);
- assert(tmp_rate[1] >= 0);
- tmp_dist[1] = tmp_dist[0] + tmp_dist[1];
- best_skip_txfm_sb[1] = best_skip_txfm_sb[0] & best_skip_txfm_sb[1];
- best_skip_sse_sb[1] = best_skip_sse_sb[0] + best_skip_sse_sb[1];
- *rd = RDCOST(x->rdmult, (*switchable_rate + tmp_rate[1]), tmp_dist[1]);
- *skip_txfm_sb = best_skip_txfm_sb[1];
- *skip_sse_sb = best_skip_sse_sb[1];
- x->pred_sse[ref_frame] = (unsigned int)(best_skip_sse_sb[0] >> 4);
+ 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);
+ }
+ av1_merge_rd_stats(&rd_stats, &rd_stats_luma);
+
+ assert(rd_stats.rate >= 0);
+
+ *rd = RDCOST(x->rdmult, *switchable_rate + rd_stats.rate, rd_stats.dist);
+ *skip_txfm_sb = rd_stats.skip;
+ *skip_sse_sb = rd_stats.sse;
+ x->pred_sse[ref_frame] = (unsigned int)(rd_stats_luma.sse >> 4);
+ }
if (assign_filter != SWITCHABLE || match_found_idx != -1) {
return 0;
}
@@ -8714,18 +8698,18 @@
cpi, bsize, mi_row, mi_col, af_horiz, af_vert, lf_horiz, lf_vert);
}
if (pred_filter_search) {
- pred_dual_interp_filter_rd(
- x, cpi, tile_data, bsize, mi_row, mi_col, orig_dst, rd,
- switchable_rate, best_skip_txfm_sb, best_skip_sse_sb, dst_bufs,
- filter_idx, switchable_ctx, (skip_hor & skip_ver), tmp_rate, tmp_dist,
- af_horiz, af_vert, lf_horiz, lf_vert);
+ pred_dual_interp_filter_rd(x, cpi, tile_data, bsize, mi_row, mi_col,
+ orig_dst, rd, &rd_stats_luma, &rd_stats,
+ switchable_rate, dst_bufs, filter_idx,
+ switchable_ctx, (skip_hor & skip_ver),
+ af_horiz, af_vert, lf_horiz, lf_vert);
} else {
skip_pred = bw <= 4 ? cpi->default_interp_skip_flags : skip_hor;
for (i = (SWITCHABLE_FILTERS - 1); i >= 1; --i) {
- if (interpolation_filter_rd(
- x, cpi, tile_data, bsize, mi_row, mi_col, orig_dst, rd,
- switchable_rate, best_skip_txfm_sb, best_skip_sse_sb, dst_bufs,
- i, switchable_ctx, skip_pred, tmp_rate, tmp_dist)) {
+ if (interpolation_filter_rd(x, cpi, tile_data, bsize, mi_row, mi_col,
+ orig_dst, rd, &rd_stats_luma, &rd_stats,
+ switchable_rate, dst_bufs, i,
+ switchable_ctx, skip_pred)) {
best_dual_mode = i;
}
skip_pred = skip_hor;
@@ -8736,25 +8720,26 @@
for (i = (best_dual_mode + (SWITCHABLE_FILTERS * 2));
i >= (best_dual_mode + SWITCHABLE_FILTERS);
i -= SWITCHABLE_FILTERS) {
- interpolation_filter_rd(
- x, cpi, tile_data, bsize, mi_row, mi_col, orig_dst, rd,
- switchable_rate, best_skip_txfm_sb, best_skip_sse_sb, dst_bufs, i,
- switchable_ctx, skip_pred, tmp_rate, tmp_dist);
+ interpolation_filter_rd(x, cpi, tile_data, bsize, mi_row, mi_col,
+ orig_dst, rd, &rd_stats_luma, &rd_stats,
+ switchable_rate, dst_bufs, i, switchable_ctx,
+ skip_pred);
skip_pred = skip_ver;
}
}
} else if (cm->seq_params.enable_dual_filter == 0) {
- find_best_non_dual_interp_filter(
- x, cpi, tile_data, bsize, mi_row, mi_col, orig_dst, rd, switchable_rate,
- best_skip_txfm_sb, best_skip_sse_sb, dst_bufs, switchable_ctx, skip_ver,
- skip_hor, tmp_rate, tmp_dist, filter_set_size);
+ find_best_non_dual_interp_filter(x, cpi, tile_data, bsize, mi_row, mi_col,
+ orig_dst, rd, &rd_stats_luma, &rd_stats,
+ switchable_rate, dst_bufs, switchable_ctx,
+ skip_ver, skip_hor, filter_set_size);
+
} else {
// EIGHTTAP_REGULAR mode is calculated beforehand
for (i = 1; i < filter_set_size; ++i) {
interpolation_filter_rd(x, cpi, tile_data, bsize, mi_row, mi_col,
- orig_dst, rd, switchable_rate, best_skip_txfm_sb,
- best_skip_sse_sb, dst_bufs, i, switchable_ctx,
- (skip_hor & skip_ver), tmp_rate, tmp_dist);
+ orig_dst, rd, &rd_stats_luma, &rd_stats,
+ switchable_rate, dst_bufs, i, switchable_ctx,
+ (skip_hor & skip_ver));
}
}
swap_dst_buf(xd, dst_bufs, num_planes);
@@ -8767,9 +8752,9 @@
av1_enc_build_inter_predictor(cm, xd, mi_row, mi_col, orig_dst, bsize,
AOM_PLANE_Y, AOM_PLANE_Y);
}
- *skip_txfm_sb = best_skip_txfm_sb[1];
- *skip_sse_sb = best_skip_sse_sb[1];
- x->pred_sse[ref_frame] = (unsigned int)(best_skip_sse_sb[0] >> 4);
+ *skip_txfm_sb = rd_stats.skip;
+ *skip_sse_sb = rd_stats.sse;
+ x->pred_sse[ref_frame] = (unsigned int)(rd_stats_luma.sse >> 4);
// save search results
if (cpi->sf.skip_repeat_interpolation_filter_search) {