Commit 8dd466ed authored by paulwilkins's avatar paulwilkins

Changes to use of rectangular partitions.

Changes to allow more use of rectangular partitions at
speeds 1 and 2 for content classed by the first pass as
animation and for blocks near the active image edge.

This has quite a big impact in quality for the animated
test sequence but also hurts encode speed for speed 2.

For other content types the impact on both speed and
quality is small.

Added some plumbing for detection of internal vertical
image edges.

Change-Id: I3fc48de2349f8cb87946caaf0b06dbb0ea261a9a
parent a126b6ce
......@@ -2642,8 +2642,9 @@ static void rd_pick_partition(VP9_COMP *cpi, ThreadData *td,
}
// PARTITION_HORZ
if (partition_horz_allowed && do_rect) {
subsize = get_subsize(bsize, PARTITION_HORZ);
if (partition_horz_allowed &&
(do_rect || vp9_active_h_edge(cpi, mi_row, mi_step))) {
subsize = get_subsize(bsize, PARTITION_HORZ);
if (cpi->sf.adaptive_motion_search)
load_pred_mv(x, ctx);
if (cpi->sf.adaptive_pred_interp_filter && bsize == BLOCK_8X8 &&
......@@ -2689,8 +2690,9 @@ static void rd_pick_partition(VP9_COMP *cpi, ThreadData *td,
restore_context(x, mi_row, mi_col, a, l, sa, sl, bsize);
}
// PARTITION_VERT
if (partition_vert_allowed && do_rect) {
subsize = get_subsize(bsize, PARTITION_VERT);
if (partition_vert_allowed &&
(do_rect || vp9_active_v_edge(cpi, mi_col, mi_step))) {
subsize = get_subsize(bsize, PARTITION_VERT);
if (cpi->sf.adaptive_motion_search)
load_pred_mv(x, ctx);
......
......@@ -2906,16 +2906,13 @@ int vp9_internal_image_edge(VP9_COMP *cpi) {
(cpi->twopass.this_frame_stats.inactive_zone_cols > 0));
}
// Checks to see if a macro block is at the edge of the active image.
// Checks to see if a super block is on a horizontal image edge.
// In most cases this is the "real" edge unless there are formatting
// bars embedded in the stream.
int vp9_active_edge_sb(VP9_COMP *cpi,
int mi_row, int mi_col) {
int is_active_edge = 0;
int vp9_active_h_edge(VP9_COMP *cpi, int mi_row, int mi_step) {
int top_edge = 0;
int bottom_edge = cpi->common.mi_rows;
int left_edge = 0;
int right_edge = cpi->common.mi_cols;
int is_active_h_edge = 0;
// For two pass account for any formatting bars detected.
if (cpi->oxcf.pass == 2) {
......@@ -2929,14 +2926,47 @@ int vp9_active_edge_sb(VP9_COMP *cpi,
bottom_edge = MAX(top_edge, bottom_edge);
}
if (((top_edge >= mi_row) && (top_edge < (mi_row + MI_BLOCK_SIZE))) ||
((bottom_edge >= mi_row) && (bottom_edge < (mi_row + MI_BLOCK_SIZE))) ||
((left_edge >= mi_col) && (left_edge < (mi_col + MI_BLOCK_SIZE))) ||
((right_edge >= mi_col) && (right_edge < (mi_col + MI_BLOCK_SIZE)))) {
is_active_edge = 1;
if (((top_edge >= mi_row) && (top_edge < (mi_row + mi_step))) ||
((bottom_edge >= mi_row) && (bottom_edge < (mi_row + mi_step)))) {
is_active_h_edge = 1;
}
return is_active_h_edge;
}
// Checks to see if a super block is on a vertical image edge.
// In most cases this is the "real" edge unless there are formatting
// bars embedded in the stream.
int vp9_active_v_edge(VP9_COMP *cpi, int mi_col, int mi_step) {
int left_edge = 0;
int right_edge = cpi->common.mi_cols;
int is_active_v_edge = 0;
// For two pass account for any formatting bars detected.
if (cpi->oxcf.pass == 2) {
TWO_PASS *twopass = &cpi->twopass;
// The inactive region is specified in MBs not mi units.
// The image edge is in the following MB row.
left_edge += (int)(twopass->this_frame_stats.inactive_zone_cols * 2);
right_edge -= (int)(twopass->this_frame_stats.inactive_zone_cols * 2);
right_edge = MAX(left_edge, right_edge);
}
if (((left_edge >= mi_col) && (left_edge < (mi_col + mi_step))) ||
((right_edge >= mi_col) && (right_edge < (mi_col + mi_step)))) {
is_active_v_edge = 1;
}
return is_active_v_edge;
}
return is_active_edge;
// Checks to see if a super block is at the edge of the active image.
// In most cases this is the "real" edge unless there are formatting
// bars embedded in the stream.
int vp9_active_edge_sb(VP9_COMP *cpi,
int mi_row, int mi_col) {
return vp9_active_h_edge(cpi, mi_row, MI_BLOCK_SIZE) ||
vp9_active_v_edge(cpi, mi_col, MI_BLOCK_SIZE);
}
void vp9_rd_pick_inter_mode_sb(VP9_COMP *cpi,
......
......@@ -55,6 +55,8 @@ void vp9_rd_pick_inter_mode_sb_seg_skip(struct VP9_COMP *cpi,
int64_t best_rd_so_far);
int vp9_internal_image_edge(struct VP9_COMP *cpi);
int vp9_active_h_edge(struct VP9_COMP *cpi, int mi_row, int mi_step);
int vp9_active_v_edge(struct VP9_COMP *cpi, int mi_col, int mi_step);
int vp9_active_edge_sb(struct VP9_COMP *cpi, int mi_row, int mi_col);
void vp9_rd_pick_inter_mode_sub8x8(struct VP9_COMP *cpi,
......
......@@ -91,6 +91,7 @@ static void set_good_speed_feature_framesize_dependent(VP9_COMP *cpi,
// If this is a two pass clip that fits the criteria for animated or
// graphics content then reset disable_split_mask for speeds 1-4.
// Also if the image edge is internal to the coded area.
if ((speed >= 1) && (cpi->oxcf.pass == 2) &&
((cpi->twopass.fr_content_type == FC_GRAPHICS_ANIMATION) ||
(vp9_internal_image_edge(cpi)))) {
......@@ -115,7 +116,12 @@ static void set_good_speed_feature(VP9_COMP *cpi, VP9_COMMON *cm,
sf->allow_skip_recode = 1;
if (speed >= 1) {
sf->use_square_partition_only = !frame_is_intra_only(cm);
if ((cpi->twopass.fr_content_type == FC_GRAPHICS_ANIMATION) ||
vp9_internal_image_edge(cpi)) {
sf->use_square_partition_only = frame_is_boosted(cpi);
} else {
sf->use_square_partition_only = !frame_is_intra_only(cm);
}
sf->less_rectangular_check = 1;
sf->use_rd_breakout = 1;
......@@ -155,6 +161,7 @@ static void set_good_speed_feature(VP9_COMP *cpi, VP9_COMMON *cm,
}
if (speed >= 3) {
sf->use_square_partition_only = !frame_is_intra_only(cm);
sf->tx_size_search_method = frame_is_intra_only(cm) ? USE_FULL_RD
: USE_LARGESTALL;
sf->mv.subpel_search_method = SUBPEL_TREE_PRUNED;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment