Add max and min partition sizes to rd_pick_partition()
Change-Id: I7c13d087b13c830c55dbad42f5378f3f6796e56c
diff --git a/av1/encoder/encodeframe.c b/av1/encoder/encodeframe.c
index ebfc8c2..d32be49 100644
--- a/av1/encoder/encodeframe.c
+++ b/av1/encoder/encodeframe.c
@@ -3538,6 +3538,7 @@
static void rd_pick_partition(AV1_COMP *const cpi, ThreadData *td,
TileDataEnc *tile_data, TOKENEXTRA **tp,
int mi_row, int mi_col, BLOCK_SIZE bsize,
+ BLOCK_SIZE max_bsize, BLOCK_SIZE min_bsize,
RD_STATS *rd_cost, int64_t best_rd,
PC_TREE *pc_tree, int64_t *none_rd) {
const AV1_COMMON *const cm = &cpi->common;
@@ -3571,6 +3572,15 @@
int vert_ctx_is_ready = 0;
BLOCK_SIZE bsize2 = get_partition_subsize(bsize, PARTITION_SPLIT);
+ // If max and min partition sizes (squares only) are enforced,
+ // only PARTITION_NONE is allowed if the current node equals min_bsize,
+ // only PARTITION_SPLIT is allowed if the current node exceeds max_bsize.
+ assert(block_size_wide[min_bsize] == block_size_high[min_bsize]);
+ assert(block_size_wide[max_bsize] == block_size_high[max_bsize]);
+ assert(min_bsize <= max_bsize);
+ int is_eq_min_bsize = bsize == min_bsize;
+ int is_gt_max_bsize = bsize > max_bsize;
+
if (best_rd < 0) {
pc_tree->none.rdcost = INT64_MAX;
pc_tree->none.skip = 0;
@@ -3861,7 +3871,7 @@
#endif
// PARTITION_NONE
- if (partition_none_allowed) {
+ if ((partition_none_allowed && !is_gt_max_bsize) || is_eq_min_bsize) {
int pt_cost = 0;
if (bsize_at_least_8x8) {
pt_cost = partition_cost[PARTITION_NONE] < INT_MAX
@@ -4001,7 +4011,7 @@
if (cpi->sf.adaptive_motion_search) store_pred_mv(x, ctx_none);
// PARTITION_SPLIT
- if (do_square_split) {
+ if ((do_square_split && !is_eq_min_bsize) || is_gt_max_bsize) {
av1_init_rd_stats(&sum_rdc);
subsize = get_partition_subsize(bsize, PARTITION_SPLIT);
sum_rdc.rate = partition_cost[PARTITION_SPLIT];
@@ -4025,8 +4035,8 @@
if (cpi->sf.prune_ref_frame_for_rect_partitions)
pc_tree->split[idx]->none.rate = INT_MAX;
rd_pick_partition(cpi, td, tile_data, tp, mi_row + y_idx, mi_col + x_idx,
- subsize, &this_rdc, best_remain_rdcost,
- pc_tree->split[idx], p_split_rd);
+ subsize, max_bsize, min_bsize, &this_rdc,
+ best_remain_rdcost, pc_tree->split[idx], p_split_rd);
if (this_rdc.rate == INT_MAX) {
sum_rdc.rdcost = INT64_MAX;
@@ -4176,7 +4186,8 @@
// PARTITION_HORZ
if (partition_horz_allowed && !prune_horz &&
- (do_rectangular_split || active_h_edge(cpi, mi_row, mi_step))) {
+ (do_rectangular_split || active_h_edge(cpi, mi_row, mi_step)) &&
+ !is_eq_min_bsize && !is_gt_max_bsize) {
av1_init_rd_stats(&sum_rdc);
subsize = get_partition_subsize(bsize, PARTITION_HORZ);
if (cpi->sf.adaptive_motion_search) load_pred_mv(x, ctx_none);
@@ -4249,7 +4260,8 @@
// PARTITION_VERT
if (partition_vert_allowed && !prune_vert &&
- (do_rectangular_split || active_v_edge(cpi, mi_col, mi_step))) {
+ (do_rectangular_split || active_v_edge(cpi, mi_col, mi_step)) &&
+ !is_eq_min_bsize && !is_gt_max_bsize) {
av1_init_rd_stats(&sum_rdc);
subsize = get_partition_subsize(bsize, PARTITION_VERT);
@@ -4425,7 +4437,8 @@
}
// PARTITION_HORZ_A
- if (partition_horz_allowed && horza_partition_allowed) {
+ if (partition_horz_allowed && horza_partition_allowed && !is_eq_min_bsize &&
+ !is_gt_max_bsize) {
subsize = get_partition_subsize(bsize, PARTITION_HORZ_A);
pc_tree->horizontala[0].rd_mode_is_ready = 0;
pc_tree->horizontala[1].rd_mode_is_ready = 0;
@@ -4490,7 +4503,8 @@
restore_context(x, &x_ctx, mi_row, mi_col, bsize, num_planes);
}
// PARTITION_HORZ_B
- if (partition_horz_allowed && horzb_partition_allowed) {
+ if (partition_horz_allowed && horzb_partition_allowed && !is_eq_min_bsize &&
+ !is_gt_max_bsize) {
subsize = get_partition_subsize(bsize, PARTITION_HORZ_B);
pc_tree->horizontalb[0].rd_mode_is_ready = 0;
pc_tree->horizontalb[1].rd_mode_is_ready = 0;
@@ -4550,7 +4564,8 @@
}
// PARTITION_VERT_A
- if (partition_vert_allowed && verta_partition_allowed) {
+ if (partition_vert_allowed && verta_partition_allowed && !is_eq_min_bsize &&
+ !is_gt_max_bsize) {
subsize = get_partition_subsize(bsize, PARTITION_VERT_A);
pc_tree->verticala[0].rd_mode_is_ready = 0;
pc_tree->verticala[1].rd_mode_is_ready = 0;
@@ -4606,7 +4621,8 @@
restore_context(x, &x_ctx, mi_row, mi_col, bsize, num_planes);
}
// PARTITION_VERT_B
- if (partition_vert_allowed && vertb_partition_allowed) {
+ if (partition_vert_allowed && vertb_partition_allowed && !is_eq_min_bsize &&
+ !is_gt_max_bsize) {
subsize = get_partition_subsize(bsize, PARTITION_VERT_B);
pc_tree->verticalb[0].rd_mode_is_ready = 0;
pc_tree->verticalb[1].rd_mode_is_ready = 0;
@@ -4701,7 +4717,8 @@
// PARTITION_HORZ_4
if (partition_horz4_allowed && has_rows &&
- (do_rectangular_split || active_h_edge(cpi, mi_row, mi_step))) {
+ (do_rectangular_split || active_h_edge(cpi, mi_row, mi_step)) &&
+ !is_eq_min_bsize && !is_gt_max_bsize) {
av1_init_rd_stats(&sum_rdc);
const int quarter_step = mi_size_high[bsize] / 4;
PICK_MODE_CONTEXT *ctx_prev = ctx_none;
@@ -4745,7 +4762,8 @@
// PARTITION_VERT_4
if (partition_vert4_allowed && has_cols &&
- (do_rectangular_split || active_v_edge(cpi, mi_row, mi_step))) {
+ (do_rectangular_split || active_v_edge(cpi, mi_row, mi_step)) &&
+ !is_eq_min_bsize && !is_gt_max_bsize) {
av1_init_rd_stats(&sum_rdc);
const int quarter_step = mi_size_wide[bsize] / 4;
PICK_MODE_CONTEXT *ctx_prev = ctx_none;
@@ -5144,7 +5162,8 @@
}
rd_pick_partition(cpi, td, tile_data, tp, mi_row, mi_col, sb_size,
- &dummy_rdc, INT64_MAX, pc_root, NULL);
+ sb_size, BLOCK_4X4, &dummy_rdc, INT64_MAX, pc_root,
+ NULL);
}
#if CONFIG_COLLECT_INTER_MODE_RD_STATS
// TODO(angiebird): Let inter_mode_rd_model_estimation support multi-tile.