Commit fe5e2a91 authored by Paul Wilkins's avatar Paul Wilkins
Browse files

Auto min and max partition size experiment.

Speed feature experiment to set an upper and lower
partition size limit based on what has been seen
in spatial neighbors.

This seems to gives quite reasonable speed gains in local
(10-15%) and when used with speed 0 the losses are small
(0.25% derf, 0.35% stdhd). However, for now I am only
enabling it on speed 1 as there may be clashes with the existing
temporal partition selection in speed 2.

Using a tighter min / max around the range derived from the
neighbors increases speed further but at the cost of a
bigger quality loss. However,  I think this spatial method could
be combined with data from either the last frame or a variance
method (or both) to refine the range of minimum and maximum
partition size. I.e. consider the min and max from spatial and
temporal neighbors and the variance recommendation.

Change-Id: I1b96bf8b84368d6aad0c7aa600fe141b4f07435f
parent 67b07c52
......@@ -1429,6 +1429,56 @@ static void rd_use_partition(VP9_COMP *cpi, MODE_INFO *m, TOKENEXTRA **tp,
*dist = chosen_dist;
}
static BLOCK_SIZE_TYPE min_partition_size[BLOCK_SIZE_TYPES] =
{ BLOCK_4X4, BLOCK_4X4, BLOCK_4X4, BLOCK_4X4,
BLOCK_4X4, BLOCK_4X4, BLOCK_8X8, BLOCK_8X8,
BLOCK_8X8, BLOCK_16X16, BLOCK_16X16, BLOCK_16X16, BLOCK_16X16 };
static BLOCK_SIZE_TYPE max_partition_size[BLOCK_SIZE_TYPES] =
{ BLOCK_8X8, BLOCK_16X16, BLOCK_16X16, BLOCK_16X16,
BLOCK_32X32, BLOCK_32X32, BLOCK_32X32, BLOCK_64X64,
BLOCK_64X64, BLOCK_64X64, BLOCK_64X64, BLOCK_64X64, BLOCK_64X64 };
// Look at neighbouring blocks and set a min and max partition size based on
// what they chose.
static void rd_auto_partition_range(VP9_COMP *cpi,
BLOCK_SIZE_TYPE * min_block_size,
BLOCK_SIZE_TYPE * max_block_size) {
MACROBLOCKD *const xd = &cpi->mb.e_mbd;
const MODE_INFO *const mi = xd->mode_info_context;
const MB_MODE_INFO *const above_mbmi = &mi[-xd->mode_info_stride].mbmi;
const MB_MODE_INFO *const left_mbmi = &mi[-1].mbmi;
const int left_in_image = xd->left_available && left_mbmi->mb_in_image;
const int above_in_image = xd->up_available && above_mbmi->mb_in_image;
// Frequency check
if (cpi->sf.auto_min_max_partition_count <= 0) {
cpi->sf.auto_min_max_partition_count =
cpi->sf.auto_min_max_partition_interval;
*min_block_size = BLOCK_4X4;
*max_block_size = BLOCK_64X64;
return;
} else {
--cpi->sf.auto_min_max_partition_count;
}
// Check for edge cases
if (!left_in_image && !above_in_image) {
*min_block_size = BLOCK_4X4;
*max_block_size = BLOCK_64X64;
} else if (!left_in_image) {
*min_block_size = min_partition_size[above_mbmi->sb_type];
*max_block_size = max_partition_size[above_mbmi->sb_type];
} else if (!above_in_image) {
*min_block_size = min_partition_size[left_mbmi->sb_type];
*max_block_size = max_partition_size[left_mbmi->sb_type];
} else {
*min_block_size =
min_partition_size[MIN(left_mbmi->sb_type, above_mbmi->sb_type)];
*max_block_size =
max_partition_size[MAX(left_mbmi->sb_type, above_mbmi->sb_type)];
}
}
// TODO(jingning,jimbankoski,rbultje): properly skip partition types that are
// unlikely to be selected depending on previously rate-distortion optimization
......@@ -1462,8 +1512,8 @@ static void rd_pick_partition(VP9_COMP *cpi, TOKENEXTRA **tp, int mi_row,
save_context(cpi, mi_row, mi_col, a, l, sa, sl, bsize);
// PARTITION_SPLIT
if (!cpi->sf.use_partitions_greater_than ||
bsize > cpi->sf.greater_than_block_size) {
if (!cpi->sf.auto_min_max_partition_size ||
bsize >= cpi->sf.min_partition_size) {
if (bsize > BLOCK_SIZE_SB8X8) {
int r4 = 0;
int64_t d4 = 0, sum_rd = 0;
......@@ -1604,8 +1654,8 @@ static void rd_pick_partition(VP9_COMP *cpi, TOKENEXTRA **tp, int mi_row,
}
}
if (!cpi->sf.use_partitions_less_than ||
bsize <= cpi->sf.less_than_block_size) {
if (!cpi->sf.use_max_partition_size ||
bsize <= cpi->sf.max_partition_size) {
int larger_is_better = 0;
// PARTITION_NONE
if ((mi_row + (ms >> 1) < cm->mi_rows) &&
......@@ -1876,6 +1926,12 @@ static void encode_sb_row(VP9_COMP *cpi, int mi_row, TOKENEXTRA **tp,
|| cpi->common.show_frame == 0
|| cpi->common.frame_type == KEY_FRAME
|| cpi->is_src_frame_alt_ref) {
// If required set upper and lower partition size limits
if (cpi->sf.auto_min_max_partition_size) {
rd_auto_partition_range(cpi,
&cpi->sf.min_partition_size,
&cpi->sf.max_partition_size);
}
rd_pick_partition(cpi, tp, mi_row, mi_col, BLOCK_SIZE_SB64X64,
&dummy_rate, &dummy_dist, 1, INT64_MAX);
} else {
......@@ -1885,6 +1941,13 @@ static void encode_sb_row(VP9_COMP *cpi, int mi_row, TOKENEXTRA **tp,
}
}
} else {
// If required set upper and lower partition size limits
if (cpi->sf.auto_min_max_partition_size) {
rd_auto_partition_range(cpi,
&cpi->sf.min_partition_size,
&cpi->sf.max_partition_size);
}
rd_pick_partition(cpi, tp, mi_row, mi_col, BLOCK_SIZE_SB64X64,
&dummy_rate, &dummy_dist, 1, INT64_MAX);
}
......
......@@ -731,10 +731,13 @@ void vp9_set_speed_features(VP9_COMP *cpi) {
sf->use_one_partition_size_always = 0;
sf->less_rectangular_check = 0;
sf->use_square_partition_only = 0;
sf->use_partitions_less_than = 0;
sf->less_than_block_size = BLOCK_SIZE_MB16X16;
sf->use_partitions_greater_than = 0;
sf->greater_than_block_size = BLOCK_SIZE_SB8X8;
sf->auto_min_max_partition_size = 0;
sf->auto_min_max_partition_interval = 0;
sf->auto_min_max_partition_count = 0;
sf->use_max_partition_size = 0;
sf->max_partition_size = BLOCK_64X64;
sf->use_min_partition_size = 0;
sf->min_partition_size = BLOCK_4X4;
sf->adjust_partitioning_from_last_frame = 0;
sf->last_partitioning_redo_frequency = 4;
sf->disable_splitmv = 0;
......@@ -788,10 +791,15 @@ void vp9_set_speed_features(VP9_COMP *cpi) {
sf->mode_search_skip_flags = FLAG_SKIP_INTRA_DIRMISMATCH |
FLAG_SKIP_INTRA_BESTINTER |
FLAG_SKIP_COMP_BESTINTRA;
sf->last_chroma_intra_mode = H_PRED;
sf->use_uv_intra_rd_estimate = 1;
sf->use_rd_breakout = 1;
sf->skip_encode_sb = 1;
sf->auto_mv_step_size = 1;
sf->auto_min_max_partition_size = 1;
sf->use_max_partition_size = 1;
sf->use_min_partition_size = 1;
sf->auto_min_max_partition_interval = 1;
}
if (speed == 2) {
sf->adjust_thresholds_by_speed = 1;
......@@ -812,9 +820,9 @@ void vp9_set_speed_features(VP9_COMP *cpi) {
FLAG_SKIP_COMP_BESTINTRA |
FLAG_SKIP_COMP_REFMISMATCH;
sf->last_chroma_intra_mode = DC_PRED;
sf->use_uv_intra_rd_estimate = 1;
sf->use_rd_breakout = 1;
sf->skip_encode_sb = 1;
sf->use_uv_intra_rd_estimate = 1;
sf->using_small_partition_info = 1;
sf->disable_splitmv =
(MIN(cpi->common.width, cpi->common.height) >= 720)? 1 : 0;
......@@ -862,14 +870,14 @@ void vp9_set_speed_features(VP9_COMP *cpi) {
if (speed == 2) {
sf->first_step = 0;
sf->comp_inter_joint_search_thresh = BLOCK_SIZE_SB8X8;
sf->use_partitions_less_than = 1;
sf->less_than_block_size = BLOCK_SIZE_MB16X16;
sf->use_max_partition_size = 1;
sf->max_partition_size = BLOCK_SIZE_MB16X16;
}
if (speed == 3) {
sf->first_step = 0;
sf->comp_inter_joint_search_thresh = BLOCK_SIZE_SB8X8;
sf->use_partitions_greater_than = 1;
sf->greater_than_block_size = BLOCK_SIZE_SB8X8;
sf->use_min_partition_size = 1;
sf->min_partition_size = BLOCK_SIZE_SB8X8;
}
*/
......
......@@ -258,10 +258,13 @@ typedef struct {
int unused_mode_skip_lvl;
int reference_masking;
BLOCK_SIZE_TYPE always_this_block_size;
int use_partitions_greater_than;
BLOCK_SIZE_TYPE greater_than_block_size;
int use_partitions_less_than;
BLOCK_SIZE_TYPE less_than_block_size;
int auto_min_max_partition_size;
int auto_min_max_partition_interval;
int auto_min_max_partition_count;
int use_min_partition_size;
BLOCK_SIZE_TYPE min_partition_size;
int use_max_partition_size;
BLOCK_SIZE_TYPE max_partition_size;
int adjust_partitioning_from_last_frame;
int last_partitioning_redo_frequency;
int disable_splitmv;
......
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