Abstract common code in partition4 search
BUG=aomedia:2687
Change-Id: Ice476e0e579f58df2220741c1ad38757c4068bf9
diff --git a/av1/encoder/encodeframe.c b/av1/encoder/encodeframe.c
index 5576885..2f84590 100644
--- a/av1/encoder/encodeframe.c
+++ b/av1/encoder/encodeframe.c
@@ -3408,6 +3408,95 @@
}
}
+// Set mi positions for HORZ4 / VERT4 sub-block partitions.
+static AOM_INLINE void set_mi_pos_partition4(
+ const int inc_step[NUM_PART4_TYPES], int mi_pos[PART4_SUB_PARTITIONS][2],
+ const int mi_row, const int mi_col) {
+ for (int i = 0; i < PART4_SUB_PARTITIONS; i++) {
+ mi_pos[i][0] = mi_row + i * inc_step[HORZ4];
+ mi_pos[i][1] = mi_col + i * inc_step[VERT4];
+ }
+}
+
+// Set context and RD cost for HORZ4 / VERT4 partition types.
+static AOM_INLINE void set_4_part_ctx_and_rdcost(
+ MACROBLOCK *x, const AV1_COMMON *const cm, ThreadData *td,
+ PICK_MODE_CONTEXT *cur_part_ctx[PART4_SUB_PARTITIONS],
+ PartitionSearchState *part_search_state, PARTITION_TYPE partition_type,
+ BLOCK_SIZE bsize) {
+ // Initialize sum_rdc RD cost structure.
+ av1_init_rd_stats(&part_search_state->sum_rdc);
+ const int subsize = get_partition_subsize(bsize, partition_type);
+ part_search_state->sum_rdc.rate =
+ part_search_state->partition_cost[partition_type];
+ part_search_state->sum_rdc.rdcost =
+ RDCOST(x->rdmult, part_search_state->sum_rdc.rate, 0);
+ for (int i = 0; i < PART4_SUB_PARTITIONS; ++i)
+ cur_part_ctx[i] = av1_alloc_pmc(cm, subsize, &td->shared_coeff_buf);
+}
+
+// Partition search of HORZ4 / VERT4 partition types.
+static AOM_INLINE void rd_pick_4partition(
+ AV1_COMP *const cpi, ThreadData *td, TileDataEnc *tile_data,
+ TokenExtra **tp, MACROBLOCK *x, RD_SEARCH_MACROBLOCK_CONTEXT *x_ctx,
+ PC_TREE *pc_tree, PICK_MODE_CONTEXT *cur_part_ctx[PART4_SUB_PARTITIONS],
+ PartitionSearchState *part_search_state, RD_STATS *best_rdc,
+ const int inc_step[NUM_PART4_TYPES], PARTITION_TYPE partition_type) {
+ const AV1_COMMON *const cm = &cpi->common;
+ PartitionBlkParams blk_params = part_search_state->part_blk_params;
+ // mi positions needed for HORZ4 and VERT4 partition types.
+ int mi_pos_check[NUM_PART4_TYPES] = { cm->mi_params.mi_rows,
+ cm->mi_params.mi_cols };
+ const PART4_TYPES part4_idx = (partition_type != PARTITION_HORZ_4);
+ int mi_pos[PART4_SUB_PARTITIONS][2];
+
+ blk_params.subsize = get_partition_subsize(blk_params.bsize, partition_type);
+ // Set partition context and RD cost.
+ set_4_part_ctx_and_rdcost(x, cm, td, cur_part_ctx, part_search_state,
+ partition_type, blk_params.bsize);
+ // Set mi positions for sub-block sizes.
+ set_mi_pos_partition4(inc_step, mi_pos, blk_params.mi_row, blk_params.mi_col);
+#if CONFIG_COLLECT_PARTITION_STATS
+ if (best_rdc.rdcost - part_search_state->sum_rdc.rdcost >= 0) {
+ partition_attempts[partition_type] += 1;
+ aom_usec_timer_start(&partition_timer);
+ partition_timer_on = 1;
+ }
+#endif
+ // Loop over sub-block partitions.
+ for (int i = 0; i < PART4_SUB_PARTITIONS; ++i) {
+ if (i > 0 && mi_pos[i][part4_idx] >= mi_pos_check[part4_idx]) break;
+
+ // Sub-block evaluation of Horz4 / Vert4 partition type.
+ cur_part_ctx[i]->rd_mode_is_ready = 0;
+ if (!rd_try_subblock(
+ cpi, td, tile_data, tp, (i == PART4_SUB_PARTITIONS - 1),
+ mi_pos[i][0], mi_pos[i][1], blk_params.subsize, *best_rdc,
+ &part_search_state->sum_rdc, partition_type, cur_part_ctx[i])) {
+ av1_invalid_rd_stats(&part_search_state->sum_rdc);
+ break;
+ }
+ }
+
+ // Calculate the total cost and update the best partition.
+ av1_rd_cost_update(x->rdmult, &part_search_state->sum_rdc);
+ if (part_search_state->sum_rdc.rdcost < best_rdc->rdcost) {
+ *best_rdc = part_search_state->sum_rdc;
+ part_search_state->found_best_partition = true;
+ pc_tree->partitioning = partition_type;
+ }
+#if CONFIG_COLLECT_PARTITION_STATS
+ if (partition_timer_on) {
+ aom_usec_timer_mark(&partition_timer);
+ int64_t time = aom_usec_timer_elapsed(&partition_timer);
+ partition_times[partition_type] += time;
+ partition_timer_on = 0;
+ }
+#endif
+ restore_context(x, x_ctx, blk_params.mi_row, blk_params.mi_col,
+ blk_params.bsize, av1_num_planes(cm));
+}
+
/*!\brief AV1 block partition search (full search).
*
* \ingroup partition_search
@@ -3944,7 +4033,7 @@
(partition_horz4_allowed || partition_vert4_allowed)) {
// Count of child blocks in which HORZ or VERT partition has won
int num_child_horz_win = 0, num_child_vert_win = 0;
- for (int idx = 0; idx < 4; idx++) {
+ for (int idx = 0; idx < PART4_SUB_PARTITIONS; idx++) {
num_child_horz_win +=
(part_search_state.split_part_rect_win[idx].rect_part_win[HORZ]) ? 1
: 0;
@@ -3971,61 +4060,12 @@
partition_horz4_allowed && blk_params.has_rows &&
(part_search_state.do_rectangular_split ||
active_h_edge(cpi, mi_row, blk_params.mi_step))) {
- av1_init_rd_stats(&part_search_state.sum_rdc);
- const int quarter_step = mi_size_high[bsize] / 4;
-
- blk_params.subsize = get_partition_subsize(bsize, PARTITION_HORZ_4);
- part_search_state.sum_rdc.rate =
- part_search_state.partition_cost[PARTITION_HORZ_4];
- part_search_state.sum_rdc.rdcost =
- RDCOST(x->rdmult, part_search_state.sum_rdc.rate, 0);
-
- for (int i = 0; i < 4; ++i) {
- pc_tree->horizontal4[i] =
- av1_alloc_pmc(cm, blk_params.subsize, &td->shared_coeff_buf);
- }
-
-#if CONFIG_COLLECT_PARTITION_STATS
- if (best_rdc.rdcost - part_search_state.sum_rdc.rdcost >= 0) {
- partition_attempts[PARTITION_HORZ_4] += 1;
- aom_usec_timer_start(&partition_timer);
- partition_timer_on = 1;
- }
-#endif
- for (int i = 0; i < 4; ++i) {
- const int this_mi_row = mi_row + i * quarter_step;
-
- if (i > 0 && this_mi_row >= mi_params->mi_rows) break;
-
- PICK_MODE_CONTEXT *ctx_this = pc_tree->horizontal4[i];
-
- ctx_this->rd_mode_is_ready = 0;
- if (!rd_try_subblock(cpi, td, tile_data, tp, (i == 3), this_mi_row,
- mi_col, blk_params.subsize, best_rdc,
- &part_search_state.sum_rdc, PARTITION_HORZ_4,
- ctx_this)) {
- av1_invalid_rd_stats(&part_search_state.sum_rdc);
- break;
- }
- }
-
- // Calculate the total cost and update the best partition.
- av1_rd_cost_update(x->rdmult, &part_search_state.sum_rdc);
- if (part_search_state.sum_rdc.rdcost < best_rdc.rdcost) {
- best_rdc = part_search_state.sum_rdc;
- part_search_state.found_best_partition = true;
- pc_tree->partitioning = PARTITION_HORZ_4;
- }
-
-#if CONFIG_COLLECT_PARTITION_STATS
- if (partition_timer_on) {
- aom_usec_timer_mark(&partition_timer);
- int64_t time = aom_usec_timer_elapsed(&partition_timer);
- partition_times[PARTITION_HORZ_4] += time;
- partition_timer_on = 0;
- }
-#endif
- restore_context(x, &x_ctx, mi_row, mi_col, bsize, num_planes);
+ const int inc_step[NUM_PART4_TYPES] = { mi_size_high[blk_params.bsize] / 4,
+ 0 };
+ // Evaluation of Horz4 partition type.
+ rd_pick_4partition(cpi, td, tile_data, tp, x, &x_ctx, pc_tree,
+ pc_tree->horizontal4, &part_search_state, &best_rdc,
+ inc_step, PARTITION_HORZ_4);
}
// PARTITION_VERT_4
@@ -4034,59 +4074,12 @@
partition_vert4_allowed && blk_params.has_cols &&
(part_search_state.do_rectangular_split ||
active_v_edge(cpi, mi_row, blk_params.mi_step))) {
- av1_init_rd_stats(&part_search_state.sum_rdc);
- const int quarter_step = mi_size_wide[bsize] / 4;
-
- blk_params.subsize = get_partition_subsize(bsize, PARTITION_VERT_4);
- part_search_state.sum_rdc.rate =
- part_search_state.partition_cost[PARTITION_VERT_4];
- part_search_state.sum_rdc.rdcost =
- RDCOST(x->rdmult, part_search_state.sum_rdc.rate, 0);
-
- for (int i = 0; i < 4; ++i)
- pc_tree->vertical4[i] =
- av1_alloc_pmc(cm, blk_params.subsize, &td->shared_coeff_buf);
-
-#if CONFIG_COLLECT_PARTITION_STATS
- if (best_rdc.rdcost - part_search_state.sum_rdc.rdcost >= 0) {
- partition_attempts[PARTITION_VERT_4] += 1;
- aom_usec_timer_start(&partition_timer);
- partition_timer_on = 1;
- }
-#endif
- for (int i = 0; i < 4; ++i) {
- const int this_mi_col = mi_col + i * quarter_step;
-
- if (i > 0 && this_mi_col >= mi_params->mi_cols) break;
-
- PICK_MODE_CONTEXT *ctx_this = pc_tree->vertical4[i];
-
- ctx_this->rd_mode_is_ready = 0;
- if (!rd_try_subblock(cpi, td, tile_data, tp, (i == 3), mi_row,
- this_mi_col, blk_params.subsize, best_rdc,
- &part_search_state.sum_rdc, PARTITION_VERT_4,
- ctx_this)) {
- av1_invalid_rd_stats(&part_search_state.sum_rdc);
- break;
- }
- }
-
- // Calculate the total cost and update the best partition
- av1_rd_cost_update(x->rdmult, &part_search_state.sum_rdc);
- if (part_search_state.sum_rdc.rdcost < best_rdc.rdcost) {
- best_rdc = part_search_state.sum_rdc;
- part_search_state.found_best_partition = true;
- pc_tree->partitioning = PARTITION_VERT_4;
- }
-#if CONFIG_COLLECT_PARTITION_STATS
- if (partition_timer_on) {
- aom_usec_timer_mark(&partition_timer);
- int64_t time = aom_usec_timer_elapsed(&partition_timer);
- partition_times[PARTITION_VERT_4] += time;
- partition_timer_on = 0;
- }
-#endif
- restore_context(x, &x_ctx, mi_row, mi_col, bsize, num_planes);
+ const int inc_step[NUM_PART4_TYPES] = { 0, mi_size_wide[blk_params.bsize] /
+ 4 };
+ // Evaluation of Vert4 partition type.
+ rd_pick_4partition(cpi, td, tile_data, tp, x, &x_ctx, pc_tree,
+ pc_tree->vertical4, &part_search_state, &best_rdc,
+ inc_step, PARTITION_VERT_4);
}
if (bsize == cm->seq_params.sb_size &&
diff --git a/av1/encoder/partition_strategy.h b/av1/encoder/partition_strategy.h
index b651673..9c30fb4 100644
--- a/av1/encoder/partition_strategy.h
+++ b/av1/encoder/partition_strategy.h
@@ -36,6 +36,12 @@
// Number of sub-partitions in AB partition types.
#define SUB_PARTITIONS_AB 3
+// Number of sub-partitions in 4-part partition types.
+#define PART4_SUB_PARTITIONS 4
+
+// 4part parition types.
+enum { HORZ4 = 0, VERT4, NUM_PART4_TYPES } UENUM1BYTE(PART4_TYPES);
+
// AB parition types.
enum {
HORZ_A = 0,