summaryrefslogtreecommitdiff
path: root/vp9/encoder
diff options
context:
space:
mode:
Diffstat (limited to 'vp9/encoder')
-rw-r--r--vp9/encoder/vp9_context_tree.h2
-rw-r--r--vp9/encoder/vp9_encodeframe.c53
-rw-r--r--vp9/encoder/vp9_encoder.c125
-rw-r--r--vp9/encoder/vp9_rdopt.c9
-rw-r--r--vp9/encoder/vp9_speed_features.c15
-rw-r--r--vp9/encoder/vp9_speed_features.h3
6 files changed, 163 insertions, 44 deletions
diff --git a/vp9/encoder/vp9_context_tree.h b/vp9/encoder/vp9_context_tree.h
index 73423c075..2bcc26e94 100644
--- a/vp9/encoder/vp9_context_tree.h
+++ b/vp9/encoder/vp9_context_tree.h
@@ -75,6 +75,8 @@ typedef struct {
// Used for the machine learning-based early termination
int32_t sum_y_eobs;
+ // Skip certain ref frames during RD search of rectangular partitions.
+ uint8_t skip_ref_frame_mask;
} PICK_MODE_CONTEXT;
typedef struct PC_TREE {
diff --git a/vp9/encoder/vp9_encodeframe.c b/vp9/encoder/vp9_encodeframe.c
index 8f622d0ed..f3a4ae7fe 100644
--- a/vp9/encoder/vp9_encodeframe.c
+++ b/vp9/encoder/vp9_encodeframe.c
@@ -2633,6 +2633,7 @@ static void rd_use_partition(VP9_COMP *cpi, ThreadData *td,
ctx, INT64_MAX);
break;
case PARTITION_HORZ:
+ pc_tree->horizontal[0].skip_ref_frame_mask = 0;
rd_pick_sb_modes(cpi, tile_data, x, mi_row, mi_col, &last_part_rdc,
subsize, &pc_tree->horizontal[0], INT64_MAX);
if (last_part_rdc.rate != INT_MAX && bsize >= BLOCK_8X8 &&
@@ -2642,6 +2643,7 @@ static void rd_use_partition(VP9_COMP *cpi, ThreadData *td,
vp9_rd_cost_init(&tmp_rdc);
update_state(cpi, td, ctx, mi_row, mi_col, subsize, 0);
encode_superblock(cpi, td, tp, 0, mi_row, mi_col, subsize, ctx);
+ pc_tree->horizontal[1].skip_ref_frame_mask = 0;
rd_pick_sb_modes(cpi, tile_data, x, mi_row + (mi_step >> 1), mi_col,
&tmp_rdc, subsize, &pc_tree->horizontal[1], INT64_MAX);
if (tmp_rdc.rate == INT_MAX || tmp_rdc.dist == INT64_MAX) {
@@ -2654,6 +2656,7 @@ static void rd_use_partition(VP9_COMP *cpi, ThreadData *td,
}
break;
case PARTITION_VERT:
+ pc_tree->vertical[0].skip_ref_frame_mask = 0;
rd_pick_sb_modes(cpi, tile_data, x, mi_row, mi_col, &last_part_rdc,
subsize, &pc_tree->vertical[0], INT64_MAX);
if (last_part_rdc.rate != INT_MAX && bsize >= BLOCK_8X8 &&
@@ -2663,6 +2666,7 @@ static void rd_use_partition(VP9_COMP *cpi, ThreadData *td,
vp9_rd_cost_init(&tmp_rdc);
update_state(cpi, td, ctx, mi_row, mi_col, subsize, 0);
encode_superblock(cpi, td, tp, 0, mi_row, mi_col, subsize, ctx);
+ pc_tree->vertical[bsize > BLOCK_8X8].skip_ref_frame_mask = 0;
rd_pick_sb_modes(cpi, tile_data, x, mi_row, mi_col + (mi_step >> 1),
&tmp_rdc, subsize,
&pc_tree->vertical[bsize > BLOCK_8X8], INT64_MAX);
@@ -3712,10 +3716,12 @@ static void rd_pick_partition(VP9_COMP *cpi, ThreadData *td,
int64_t dist_breakout_thr = cpi->sf.partition_search_breakout_thr.dist;
int rate_breakout_thr = cpi->sf.partition_search_breakout_thr.rate;
int must_split = 0;
-
int partition_mul = cpi->sf.enable_tpl_model && cpi->oxcf.aq_mode == NO_AQ
? x->cb_rdmult
: cpi->rd.RDMULT;
+ // Ref frames picked in the [i_th] quarter subblock during square partition
+ // RD search. It may be used to prune ref frame selection of rect partitions.
+ uint8_t ref_frames_used[4] = { 0, 0, 0, 0 };
(void)*tp_orig;
@@ -3846,6 +3852,14 @@ static void rd_pick_partition(VP9_COMP *cpi, ThreadData *td,
rd_pick_sb_modes(cpi, tile_data, x, mi_row, mi_col, &this_rdc, bsize, ctx,
best_rdc.rdcost);
if (this_rdc.rate != INT_MAX) {
+ if (cpi->sf.prune_ref_frame_for_rect_partitions) {
+ const int ref1 = ctx->mic.ref_frame[0];
+ const int ref2 = ctx->mic.ref_frame[1];
+ for (i = 0; i < 4; ++i) {
+ ref_frames_used[i] |= (1 << ref1);
+ if (ref2 > 0) ref_frames_used[i] |= (1 << ref2);
+ }
+ }
if (bsize >= BLOCK_8X8) {
this_rdc.rdcost += RDCOST(partition_mul, x->rddiv,
cpi->partition_cost[pl][PARTITION_NONE], 0);
@@ -3970,8 +3984,18 @@ static void rd_pick_partition(VP9_COMP *cpi, ThreadData *td,
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);
-
- if (sum_rdc.rate == INT_MAX) sum_rdc.rdcost = INT64_MAX;
+ if (sum_rdc.rate == INT_MAX) {
+ sum_rdc.rdcost = INT64_MAX;
+ } else {
+ if (cpi->sf.prune_ref_frame_for_rect_partitions) {
+ const int ref1 = pc_tree->leaf_split[0]->mic.ref_frame[0];
+ const int ref2 = pc_tree->leaf_split[0]->mic.ref_frame[1];
+ for (i = 0; i < 4; ++i) {
+ ref_frames_used[i] |= (1 << ref1);
+ if (ref2 > 0) ref_frames_used[i] |= (1 << ref2);
+ }
+ }
+ }
} else {
for (i = 0; (i < 4) && ((sum_rdc.rdcost < best_rdc.rdcost) || must_split);
++i) {
@@ -3999,6 +4023,13 @@ static void rd_pick_partition(VP9_COMP *cpi, ThreadData *td,
sum_rdc.rdcost = INT64_MAX;
break;
} else {
+ if (cpi->sf.prune_ref_frame_for_rect_partitions &&
+ pc_tree->split[i]->none.rate != INT_MAX) {
+ const int ref1 = pc_tree->split[i]->none.mic.ref_frame[0];
+ const int ref2 = pc_tree->split[i]->none.mic.ref_frame[1];
+ ref_frames_used[i] |= (1 << ref1);
+ if (ref2 > 0) ref_frames_used[i] |= (1 << ref2);
+ }
sum_rdc.rate += this_rdc.rate;
sum_rdc.dist += this_rdc.dist;
sum_rdc.rdcost += this_rdc.rdcost;
@@ -4036,6 +4067,22 @@ static void rd_pick_partition(VP9_COMP *cpi, ThreadData *td,
restore_context(x, mi_row, mi_col, a, l, sa, sl, bsize);
}
+ pc_tree->horizontal[0].skip_ref_frame_mask = 0;
+ pc_tree->horizontal[1].skip_ref_frame_mask = 0;
+ pc_tree->vertical[0].skip_ref_frame_mask = 0;
+ pc_tree->vertical[1].skip_ref_frame_mask = 0;
+ if (cpi->sf.prune_ref_frame_for_rect_partitions) {
+ uint8_t used_frames;
+ used_frames = ref_frames_used[0] | ref_frames_used[1];
+ if (used_frames) pc_tree->horizontal[0].skip_ref_frame_mask = ~used_frames;
+ used_frames = ref_frames_used[2] | ref_frames_used[3];
+ if (used_frames) pc_tree->horizontal[1].skip_ref_frame_mask = ~used_frames;
+ used_frames = ref_frames_used[0] | ref_frames_used[2];
+ if (used_frames) pc_tree->vertical[0].skip_ref_frame_mask = ~used_frames;
+ used_frames = ref_frames_used[1] | ref_frames_used[3];
+ if (used_frames) pc_tree->vertical[1].skip_ref_frame_mask = ~used_frames;
+ }
+
// PARTITION_HORZ
if (partition_horz_allowed &&
(do_rect || vp9_active_h_edge(cpi, mi_row, mi_step))) {
diff --git a/vp9/encoder/vp9_encoder.c b/vp9/encoder/vp9_encoder.c
index b55e89e5b..de5519dce 100644
--- a/vp9/encoder/vp9_encoder.c
+++ b/vp9/encoder/vp9_encoder.c
@@ -5579,7 +5579,7 @@ void init_tpl_stats(VP9_COMP *cpi) {
uint32_t motion_compensated_prediction(VP9_COMP *cpi, ThreadData *td,
uint8_t *cur_frame_buf,
uint8_t *ref_frame_buf, int stride,
- MV *mv) {
+ MV *mv, BLOCK_SIZE bsize) {
MACROBLOCK *const x = &td->mb;
MACROBLOCKD *const xd = &x->e_mbd;
MV_SPEED_FEATURES *const mv_sf = &cpi->sf.mv;
@@ -5609,7 +5609,7 @@ uint32_t motion_compensated_prediction(VP9_COMP *cpi, ThreadData *td,
vp9_set_mv_search_range(&x->mv_limits, &best_ref_mv1);
- vp9_full_pixel_search(cpi, x, BLOCK_32X32, &best_ref_mv1_full, step_param,
+ vp9_full_pixel_search(cpi, x, bsize, &best_ref_mv1_full, step_param,
search_method, sadpb, cond_cost_list(cpi, cost_list),
&best_ref_mv1, mv, 0, 0);
@@ -5619,7 +5619,7 @@ uint32_t motion_compensated_prediction(VP9_COMP *cpi, ThreadData *td,
// Ignore mv costing by sending NULL pointer instead of cost array
bestsme = cpi->find_fractional_mv_step(
x, mv, &best_ref_mv1, cpi->common.allow_high_precision_mv, x->errorperbit,
- &cpi->fn_ptr[BLOCK_32X32], 0, mv_sf->subpel_iters_per_step,
+ &cpi->fn_ptr[bsize], 0, mv_sf->subpel_iters_per_step,
cond_cost_list(cpi, cost_list), NULL, NULL, &distortion, &sse, NULL, 0,
0);
@@ -5627,25 +5627,28 @@ uint32_t motion_compensated_prediction(VP9_COMP *cpi, ThreadData *td,
}
int get_overlap_area(int grid_pos_row, int grid_pos_col, int ref_pos_row,
- int ref_pos_col, int block) {
+ int ref_pos_col, int block, BLOCK_SIZE bsize) {
int overlap_area;
int width = 0, height = 0;
+ int bw = 4 << b_width_log2_lookup[bsize];
+ int bh = 4 << b_height_log2_lookup[bsize];
+
switch (block) {
case 0:
- width = grid_pos_col + 4 * MI_SIZE - ref_pos_col;
- height = grid_pos_row + 4 * MI_SIZE - ref_pos_row;
+ width = grid_pos_col + bw - ref_pos_col;
+ height = grid_pos_row + bh - ref_pos_row;
break;
case 1:
- width = ref_pos_col + 4 * MI_SIZE - grid_pos_col;
- height = grid_pos_row + 4 * MI_SIZE - ref_pos_row;
+ width = ref_pos_col + bw - grid_pos_col;
+ height = grid_pos_row + bh - ref_pos_row;
break;
case 2:
- width = grid_pos_col + 4 * MI_SIZE - ref_pos_col;
- height = ref_pos_row + 4 * MI_SIZE - grid_pos_row;
+ width = grid_pos_col + bw - ref_pos_col;
+ height = ref_pos_row + bh - grid_pos_row;
break;
case 3:
- width = ref_pos_col + 4 * MI_SIZE - grid_pos_col;
- height = ref_pos_row + 4 * MI_SIZE - grid_pos_row;
+ width = ref_pos_col + bw - grid_pos_col;
+ height = ref_pos_row + bh - grid_pos_row;
break;
default: assert(0);
}
@@ -5663,8 +5666,34 @@ int round_floor(int ref_pos, int bsize_pix) {
return round;
}
-void tpl_model_update(TplDepFrame *tpl_frame, TplDepStats *tpl_stats,
- int mi_row, int mi_col, const BLOCK_SIZE bsize) {
+void tpl_model_store(TplDepStats *tpl_stats, int mi_row, int mi_col,
+ BLOCK_SIZE bsize, int stride, int64_t intra_cost,
+ int64_t inter_cost, int ref_frame_idx, int_mv mv) {
+ const int mi_height = num_8x8_blocks_high_lookup[bsize];
+ const int mi_width = num_8x8_blocks_wide_lookup[bsize];
+ int idx, idy;
+
+ intra_cost = intra_cost / (mi_height * mi_width);
+ inter_cost = inter_cost / (mi_height * mi_width);
+
+ intra_cost = VPXMAX(1, intra_cost);
+ inter_cost = VPXMAX(1, inter_cost);
+
+ for (idy = 0; idy < mi_height; ++idy) {
+ for (idx = 0; idx < mi_width; ++idx) {
+ TplDepStats *tpl_ptr =
+ &tpl_stats[(mi_row + idy) * stride + (mi_col + idx)];
+ tpl_ptr->intra_cost = intra_cost;
+ tpl_ptr->inter_cost = inter_cost;
+ tpl_ptr->mc_dep_cost = tpl_ptr->intra_cost + tpl_ptr->mc_flow;
+ tpl_ptr->ref_frame_index = ref_frame_idx;
+ tpl_ptr->mv.as_int = mv.as_int;
+ }
+ }
+}
+
+void tpl_model_update_b(TplDepFrame *tpl_frame, TplDepStats *tpl_stats,
+ int mi_row, int mi_col, const BLOCK_SIZE bsize) {
TplDepFrame *ref_tpl_frame = &tpl_frame[tpl_stats->ref_frame_index];
TplDepStats *ref_stats = ref_tpl_frame->tpl_stats_ptr;
MV mv = tpl_stats->mv.as_mv;
@@ -5691,8 +5720,8 @@ void tpl_model_update(TplDepFrame *tpl_frame, TplDepStats *tpl_stats,
if (grid_pos_row >= 0 && grid_pos_row < ref_tpl_frame->mi_rows * MI_SIZE &&
grid_pos_col >= 0 && grid_pos_col < ref_tpl_frame->mi_cols * MI_SIZE) {
- int overlap_area = get_overlap_area(grid_pos_row, grid_pos_col,
- ref_pos_row, ref_pos_col, block);
+ int overlap_area = get_overlap_area(
+ grid_pos_row, grid_pos_col, ref_pos_row, ref_pos_col, block, bsize);
int ref_mi_row = round_floor(grid_pos_row, bh) * mi_height;
int ref_mi_col = round_floor(grid_pos_col, bw) * mi_width;
@@ -5700,13 +5729,37 @@ void tpl_model_update(TplDepFrame *tpl_frame, TplDepStats *tpl_stats,
(tpl_stats->mc_dep_cost * tpl_stats->inter_cost) /
tpl_stats->intra_cost;
- ref_stats[ref_mi_row * ref_tpl_frame->stride + ref_mi_col].mc_flow +=
- (mc_flow * overlap_area) / pix_num;
+ int idx, idy;
+
+ for (idy = 0; idy < mi_height; ++idy) {
+ for (idx = 0; idx < mi_width; ++idx) {
+ TplDepStats *des_stats =
+ &ref_stats[(ref_mi_row + idy) * ref_tpl_frame->stride +
+ (ref_mi_col + idx)];
+
+ des_stats->mc_flow += (mc_flow * overlap_area) / pix_num;
+ des_stats->mc_ref_cost +=
+ ((tpl_stats->intra_cost - tpl_stats->inter_cost) * overlap_area) /
+ pix_num;
+ assert(overlap_area >= 0);
+ }
+ }
+ }
+ }
+}
+
+void tpl_model_update(TplDepFrame *tpl_frame, TplDepStats *tpl_stats,
+ int mi_row, int mi_col, const BLOCK_SIZE bsize) {
+ int idx, idy;
+ const int mi_height = num_8x8_blocks_high_lookup[bsize];
+ const int mi_width = num_8x8_blocks_wide_lookup[bsize];
- ref_stats[ref_mi_row * ref_tpl_frame->stride + ref_mi_col].mc_ref_cost +=
- ((tpl_stats->intra_cost - tpl_stats->inter_cost) * overlap_area) /
- pix_num;
- assert(overlap_area >= 0);
+ for (idy = 0; idy < mi_height; ++idy) {
+ for (idx = 0; idx < mi_width; ++idx) {
+ TplDepStats *tpl_ptr =
+ &tpl_stats[(mi_row + idy) * tpl_frame->stride + (mi_col + idx)];
+ tpl_model_update_b(tpl_frame, tpl_ptr, mi_row + idy, mi_col + idx,
+ BLOCK_8X8);
}
}
}
@@ -5720,14 +5773,16 @@ void get_quantize_error(MACROBLOCK *x, int plane, tran_low_t *coeff,
const scan_order *const scan_order = &vp9_default_scan_orders[tx_size];
uint16_t eob;
int pix_num = 1 << num_pels_log2_lookup[txsize_to_bsize[tx_size]];
+ const int shift = tx_size == TX_32X32 ? 0 : 2;
vp9_quantize_fp_32x32(coeff, pix_num, x->skip_block, p->round_fp, p->quant_fp,
qcoeff, dqcoeff, pd->dequant, &eob, scan_order->scan,
scan_order->iscan);
- *recon_error = vp9_block_error(coeff, dqcoeff, pix_num, sse);
-
+ *recon_error = vp9_block_error(coeff, dqcoeff, pix_num, sse) >> shift;
*recon_error = VPXMAX(*recon_error, 1);
+
+ *sse = (*sse) >> shift;
*sse = VPXMAX(*sse, 1);
}
@@ -5770,7 +5825,7 @@ void mc_flow_dispenser(VP9_COMP *cpi, GF_PICTURE *gf_picture, int frame_idx) {
MODE_INFO mi_above, mi_left;
const BLOCK_SIZE bsize = BLOCK_32X32;
- const TX_SIZE tx_size = TX_32X32;
+ const TX_SIZE tx_size = max_txsize_lookup[bsize];
const int bw = 4 << b_width_log2_lookup[bsize];
const int bh = 4 << b_height_log2_lookup[bsize];
const int mi_height = num_8x8_blocks_high_lookup[bsize];
@@ -5835,9 +5890,6 @@ void mc_flow_dispenser(VP9_COMP *cpi, GF_PICTURE *gf_picture, int frame_idx) {
int64_t intra_cost;
PREDICTION_MODE mode;
- TplDepStats *tpl_stats =
- &tpl_frame->tpl_stats_ptr[mi_row * tpl_frame->stride + mi_col];
-
// Intra prediction search
for (mode = DC_PRED; mode <= TM_PRED; ++mode) {
uint8_t *src, *dst;
@@ -5890,7 +5942,7 @@ void mc_flow_dispenser(VP9_COMP *cpi, GF_PICTURE *gf_picture, int frame_idx) {
motion_compensated_prediction(cpi, td,
this_frame->y_buffer + mb_y_offset,
ref_frame[rf_idx]->y_buffer + mb_y_offset,
- this_frame->y_stride, &mv.as_mv);
+ this_frame->y_stride, &mv.as_mv, bsize);
// TODO(jingning): Not yet support high bit-depth in the next three
// steps.
@@ -5939,13 +5991,16 @@ void mc_flow_dispenser(VP9_COMP *cpi, GF_PICTURE *gf_picture, int frame_idx) {
// Motion flow dependency dispenser.
best_intra_cost = VPXMAX(best_intra_cost, 1);
best_inter_cost = VPXMIN(best_inter_cost, best_intra_cost);
- tpl_stats->inter_cost = best_inter_cost << TPL_DEP_COST_SCALE_LOG2;
- tpl_stats->intra_cost = best_intra_cost << TPL_DEP_COST_SCALE_LOG2;
- tpl_stats->mc_dep_cost = tpl_stats->intra_cost + tpl_stats->mc_flow;
- tpl_stats->ref_frame_index = gf_picture[frame_idx].ref_frame[best_rf_idx];
- tpl_stats->mv.as_int = best_mv.as_int;
- tpl_model_update(cpi->tpl_stats, tpl_stats, mi_row, mi_col, bsize);
+ best_intra_cost <<= TPL_DEP_COST_SCALE_LOG2;
+ best_inter_cost <<= TPL_DEP_COST_SCALE_LOG2;
+
+ tpl_model_store(tpl_frame->tpl_stats_ptr, mi_row, mi_col, bsize,
+ tpl_frame->stride, best_intra_cost, best_inter_cost,
+ gf_picture[frame_idx].ref_frame[best_rf_idx], best_mv);
+
+ tpl_model_update(cpi->tpl_stats, tpl_frame->tpl_stats_ptr, mi_row, mi_col,
+ bsize);
}
}
}
diff --git a/vp9/encoder/vp9_rdopt.c b/vp9/encoder/vp9_rdopt.c
index e3672edf5..ad4b48a9c 100644
--- a/vp9/encoder/vp9_rdopt.c
+++ b/vp9/encoder/vp9_rdopt.c
@@ -3073,6 +3073,8 @@ void vp9_rd_pick_inter_mode_sb(VP9_COMP *cpi, TileDataEnc *tile_data,
// lock mechanism involved with reads from
// tile_mode_map
const int mode_search_skip_flags = sf->mode_search_skip_flags;
+ const int is_rect_partition =
+ num_4x4_blocks_wide_lookup[bsize] != num_4x4_blocks_high_lookup[bsize];
int64_t mask_filter = 0;
int64_t filter_cache[SWITCHABLE_FILTER_CONTEXTS];
@@ -3224,6 +3226,13 @@ void vp9_rd_pick_inter_mode_sb(VP9_COMP *cpi, TileDataEnc *tile_data,
vp9_zero(x->sum_y_eobs);
+ if (is_rect_partition) {
+ if (ctx->skip_ref_frame_mask & (1 << ref_frame)) continue;
+ if (second_ref_frame > 0 &&
+ (ctx->skip_ref_frame_mask & (1 << second_ref_frame)))
+ continue;
+ }
+
// Look at the reference frame of the best mode so far and set the
// skip mask to look at a subset of the remaining modes.
if (midx == mode_skip_start && best_mode_index >= 0) {
diff --git a/vp9/encoder/vp9_speed_features.c b/vp9/encoder/vp9_speed_features.c
index 80adf845e..75a8de270 100644
--- a/vp9/encoder/vp9_speed_features.c
+++ b/vp9/encoder/vp9_speed_features.c
@@ -70,11 +70,14 @@ static void set_good_speed_feature_framesize_dependent(VP9_COMP *cpi,
// speed 0 features
sf->partition_search_breakout_thr.dist = (1 << 20);
sf->partition_search_breakout_thr.rate = 80;
+ sf->use_square_only_threshold = BLOCK_SIZES;
- // Currently, the machine-learning based partition search early termination
- // is only used while VPXMIN(cm->width, cm->height) >= 480 and speed = 0.
if (is_480p_or_larger) {
+ // Currently, the machine-learning based partition search early termination
+ // is only used while VPXMIN(cm->width, cm->height) >= 480 and speed = 0.
sf->ml_partition_search_early_termination = 1;
+ } else {
+ sf->use_square_only_threshold = BLOCK_32X32;
}
if (!is_1080p_or_larger) {
@@ -92,6 +95,7 @@ static void set_good_speed_feature_framesize_dependent(VP9_COMP *cpi,
if (speed >= 1) {
sf->ml_partition_search_early_termination = 0;
+ sf->use_square_only_threshold = BLOCK_4X4;
if (is_720p_or_larger) {
sf->disable_split_mask =
@@ -193,7 +197,7 @@ static void set_good_speed_feature_framesize_independent(VP9_COMP *cpi,
sf->allow_skip_recode = 1;
sf->less_rectangular_check = 1;
sf->use_square_partition_only = !frame_is_boosted(cpi);
- sf->use_square_only_threshold = BLOCK_16X16;
+ sf->prune_ref_frame_for_rect_partitions = 1;
if (cpi->twopass.fr_content_type == FC_GRAPHICS_ANIMATION) {
sf->exhaustive_searches_thresh = (1 << 22);
@@ -210,6 +214,7 @@ static void set_good_speed_feature_framesize_independent(VP9_COMP *cpi,
if (speed >= 1) {
sf->enable_tpl_model = 0;
+ sf->prune_ref_frame_for_rect_partitions = 0;
if (oxcf->pass == 2) {
TWO_PASS *const twopass = &cpi->twopass;
if ((twopass->fr_content_type == FC_GRAPHICS_ANIMATION) ||
@@ -226,10 +231,7 @@ static void set_good_speed_feature_framesize_independent(VP9_COMP *cpi,
sf->tx_domain_thresh = tx_dom_thresholds[(speed < 6) ? speed : 5];
sf->allow_quant_coeff_opt = sf->optimize_coefficients;
sf->quant_opt_thresh = qopt_thresholds[(speed < 6) ? speed : 5];
-
- sf->use_square_only_threshold = BLOCK_4X4;
sf->less_rectangular_check = 1;
-
sf->use_rd_breakout = 1;
sf->adaptive_motion_search = 1;
sf->mv.auto_mv_step_size = 1;
@@ -848,6 +850,7 @@ void vp9_set_speed_features_framesize_independent(VP9_COMP *cpi) {
#else
sf->enable_tpl_model = 1;
#endif
+ sf->prune_ref_frame_for_rect_partitions = 0;
for (i = 0; i < TX_SIZES; i++) {
sf->intra_y_mode_mask[i] = INTRA_ALL;
diff --git a/vp9/encoder/vp9_speed_features.h b/vp9/encoder/vp9_speed_features.h
index 7a591e491..fd4973fb2 100644
--- a/vp9/encoder/vp9_speed_features.h
+++ b/vp9/encoder/vp9_speed_features.h
@@ -319,6 +319,9 @@ typedef struct SPEED_FEATURES {
int use_square_partition_only;
BLOCK_SIZE use_square_only_threshold;
+ // Prune reference frames for rectangular partitions.
+ int prune_ref_frame_for_rect_partitions;
+
// Sets min and max partition sizes for this 64x64 region based on the
// same 64x64 in last encoded frame, and the left and above neighbor.
AUTO_MIN_MAX_MODE auto_min_max_partition_size;