Skip uv's tx search if y's cost is too large
During inter frame's intra mode selection, skip
uv's tx search if y's cost is too large.
For encoder, about 0.65% faster shows by encoding 20 frame
of BasketballDrill_832x480_50.y4m target 800kbps at speed 1.
( 272077 ms -> 270315 ms)
Change-Id: I1116a9efde0078765c5eecee95bf9f59bca55c46
diff --git a/av1/encoder/rdopt.c b/av1/encoder/rdopt.c
index 8990488..2ac65de 100644
--- a/av1/encoder/rdopt.c
+++ b/av1/encoder/rdopt.c
@@ -10757,12 +10757,13 @@
set_default_interp_filters(mbmi, cm->interp_filter);
}
-static int handle_intra_mode(InterModeSearchState *search_state,
- const AV1_COMP *cpi, MACROBLOCK *x,
- BLOCK_SIZE bsize, int mi_row, int mi_col,
- int ref_frame_cost, const PICK_MODE_CONTEXT *ctx,
- int disable_skip, RD_STATS *rd_stats,
- RD_STATS *rd_stats_y, RD_STATS *rd_stats_uv) {
+static int64_t handle_intra_mode(InterModeSearchState *search_state,
+ const AV1_COMP *cpi, MACROBLOCK *x,
+ BLOCK_SIZE bsize, int mi_row, int mi_col,
+ int ref_frame_cost,
+ const PICK_MODE_CONTEXT *ctx, int disable_skip,
+ RD_STATS *rd_stats, RD_STATS *rd_stats_y,
+ RD_STATS *rd_stats_uv) {
const AV1_COMMON *cm = &cpi->common;
const SPEED_FEATURES *const sf = &cpi->sf;
MACROBLOCKD *const xd = &x->e_mbd;
@@ -10777,9 +10778,6 @@
const int rows = block_size_high[bsize];
const int cols = block_size_wide[bsize];
const int num_planes = av1_num_planes(cm);
- av1_init_rd_stats(rd_stats);
- av1_init_rd_stats(rd_stats_y);
- av1_init_rd_stats(rd_stats_uv);
TX_SIZE uv_tx;
int is_directional_mode = av1_is_directional_mode(mbmi->mode);
if (is_directional_mode && av1_use_angle_delta(bsize)) {
@@ -10796,12 +10794,14 @@
search_state->directional_mode_skip_mask);
search_state->angle_stats_ready = 1;
}
- if (search_state->directional_mode_skip_mask[mbmi->mode]) return 0;
+ if (search_state->directional_mode_skip_mask[mbmi->mode]) return INT64_MAX;
+ av1_init_rd_stats(rd_stats_y);
rd_stats_y->rate = INT_MAX;
rd_pick_intra_angle_sby(cpi, x, mi_row, mi_col, &rate_dummy, rd_stats_y,
bsize, intra_mode_cost[mbmi->mode],
search_state->best_rd, &model_rd);
} else {
+ av1_init_rd_stats(rd_stats_y);
mbmi->angle_delta[PLANE_TYPE_Y] = 0;
super_block_yrd(cpi, x, rd_stats_y, bsize, search_state->best_rd);
}
@@ -10867,12 +10867,23 @@
mbmi->filter_intra_mode_info.use_filter_intra = 0;
}
}
-
- if (rd_stats_y->rate == INT_MAX) return 0;
-
+ if (rd_stats_y->rate == INT_MAX) return INT64_MAX;
+ const int mode_cost_y =
+ intra_mode_info_cost_y(cpi, x, mbmi, bsize, intra_mode_cost[mbmi->mode]);
+ av1_init_rd_stats(rd_stats);
+ av1_init_rd_stats(rd_stats_uv);
if (num_planes > 1) {
uv_tx = av1_get_tx_size(AOM_PLANE_U, xd);
if (search_state->rate_uv_intra[uv_tx] == INT_MAX) {
+ int rate_y = rd_stats_y->skip ? x->skip_cost[av1_get_skip_context(xd)][1]
+ : rd_stats_y->rate;
+ const int64_t rdy =
+ RDCOST(x->rdmult, rate_y + mode_cost_y, rd_stats_y->dist);
+ if (search_state->best_rd < (INT64_MAX / 2) &&
+ rdy > (search_state->best_rd + (search_state->best_rd >> 2))) {
+ search_state->skip_intra_modes = 1;
+ return INT64_MAX;
+ }
choose_intra_uv_mode(
cpi, x, bsize, uv_tx, &search_state->rate_uv_intra[uv_tx],
&search_state->rate_uv_tokenonly[uv_tx],
@@ -10895,10 +10906,7 @@
}
mbmi->angle_delta[PLANE_TYPE_UV] = search_state->uv_angle_delta[uv_tx];
}
-
- rd_stats->rate =
- rd_stats_y->rate +
- intra_mode_info_cost_y(cpi, x, mbmi, bsize, intra_mode_cost[mbmi->mode]);
+ rd_stats->rate = rd_stats_y->rate + mode_cost_y;
if (!xd->lossless[mbmi->segment_id] && block_signals_txsize(bsize)) {
// super_block_yrd above includes the cost of the tx_size in the
// tokenonly rate, but for intra blocks, tx_size is always coded
@@ -10932,8 +10940,7 @@
rd_stats->rate += x->skip_cost[av1_get_skip_context(xd)][0];
}
// Calculate the final RD estimate for this mode.
- int64_t this_rd = RDCOST(x->rdmult, rd_stats->rate, rd_stats->dist);
-
+ const int64_t this_rd = RDCOST(x->rdmult, rd_stats->rate, rd_stats->dist);
// Keep record of best intra rd
if (this_rd < search_state->best_intra_rd) {
search_state->best_intra_rd = this_rd;
@@ -10951,7 +10958,7 @@
search_state->best_pred_rd[i] =
AOMMIN(search_state->best_pred_rd[i], this_rd);
}
- return 1;
+ return this_rd;
}
static void collect_single_states(MACROBLOCK *x,
@@ -11578,13 +11585,12 @@
const int mode_index = intra_mode_idx_ls[j];
const MV_REFERENCE_FRAME ref_frame =
av1_mode_order[mode_index].ref_frame[0];
- const MV_REFERENCE_FRAME second_ref_frame =
- av1_mode_order[mode_index].ref_frame[1];
+ assert(av1_mode_order[mode_index].ref_frame[1] == NONE_FRAME);
assert(ref_frame == INTRA_FRAME);
if (sf->skip_intra_in_interframe && search_state.skip_intra_modes) break;
init_mbmi(mbmi, mode_index, cm);
x->skip = 0;
- set_ref_ptrs(cm, xd, ref_frame, second_ref_frame);
+ set_ref_ptrs(cm, xd, INTRA_FRAME, NONE_FRAME);
// Select prediction reference frames.
for (i = 0; i < num_planes; i++) {
@@ -11594,13 +11600,9 @@
RD_STATS intra_rd_stats, intra_rd_stats_y, intra_rd_stats_uv;
const int ref_frame_cost = ref_costs_single[ref_frame];
- if (!handle_intra_mode(&search_state, cpi, x, bsize, mi_row, mi_col,
- ref_frame_cost, ctx, 0, &intra_rd_stats,
- &intra_rd_stats_y, &intra_rd_stats_uv)) {
- continue;
- }
- intra_rd_stats.rdcost =
- RDCOST(x->rdmult, intra_rd_stats.rate, intra_rd_stats.dist);
+ intra_rd_stats.rdcost = handle_intra_mode(
+ &search_state, cpi, x, bsize, mi_row, mi_col, ref_frame_cost, ctx, 0,
+ &intra_rd_stats, &intra_rd_stats_y, &intra_rd_stats_uv);
if (intra_rd_stats.rdcost < search_state.best_rd) {
search_state.best_rd = intra_rd_stats.rdcost;
// Note index of best mode so far