Commit eca93642 authored by Pengchong Jin's avatar Pengchong Jin

Add a speed feature to give the tighter search range

Add a speed feature to give the tighter partition search
range. Before partition search, calculate the histogram
of the partition sizes of the left, above and previous
co-located blocks of the current block. If the variance of
observed partition sizes is small enough, adjust the search
range around the mean partition size, which will be tigher.

The feature is currently turned on at speed 2. Experiments on
sample youtube clips show on average the runtime is reduced
by 3-7%.

For hard stdhd clips:
park_joy_1080p @ 15000kbps:       509251 ms -> 491953 ms (3.3%)
pedestrian_area_1080p @ 2000kbps: 223941 ms -> 214226 ms (4.3%)

The PSNR performance is changed:
derf: -0.112%
yt:   -0.099%
hd:   -0.090%
stdhd:-0.102%

Change-Id: Ie205ec5325bf92ec5676c243e30ba9d0adca10f2
parent 5b63c279
......@@ -1724,7 +1724,8 @@ static const BLOCK_SIZE max_partition_size[BLOCK_SIZES] = {
// function so repeat calls can accumulate a min and max of more than one sb64.
static void get_sb_partition_size_range(MACROBLOCKD *xd, MODE_INFO **mi_8x8,
BLOCK_SIZE *min_block_size,
BLOCK_SIZE *max_block_size ) {
BLOCK_SIZE *max_block_size,
int bs_hist[BLOCK_SIZES]) {
int sb_width_in_blocks = MI_BLOCK_SIZE;
int sb_height_in_blocks = MI_BLOCK_SIZE;
int i, j;
......@@ -1735,6 +1736,7 @@ static void get_sb_partition_size_range(MACROBLOCKD *xd, MODE_INFO **mi_8x8,
for (j = 0; j < sb_width_in_blocks; ++j) {
MODE_INFO * mi = mi_8x8[index+j];
BLOCK_SIZE sb_type = mi ? mi->mbmi.sb_type : 0;
bs_hist[sb_type]++;
*min_block_size = MIN(*min_block_size, sb_type);
*max_block_size = MAX(*max_block_size, sb_type);
}
......@@ -1767,6 +1769,9 @@ static void rd_auto_partition_range(VP9_COMP *cpi, const TileInfo *const tile,
int bh, bw;
BLOCK_SIZE min_size = BLOCK_4X4;
BLOCK_SIZE max_size = BLOCK_64X64;
int i = 0;
int bs_hist[BLOCK_SIZES] = {0};
// Trap case where we do not have a prediction.
if (left_in_image || above_in_image || cm->frame_type != KEY_FRAME) {
// Default "min to max" and "max to min"
......@@ -1779,22 +1784,51 @@ static void rd_auto_partition_range(VP9_COMP *cpi, const TileInfo *const tile,
if (cm->frame_type != KEY_FRAME) {
MODE_INFO **const prev_mi =
&cm->prev_mi_grid_visible[mi_row * xd->mi_stride + mi_col];
get_sb_partition_size_range(xd, prev_mi, &min_size, &max_size);
get_sb_partition_size_range(xd, prev_mi, &min_size, &max_size, bs_hist);
}
// Find the min and max partition sizes used in the left SB64
if (left_in_image) {
MODE_INFO **left_sb64_mi = &mi[-MI_BLOCK_SIZE];
get_sb_partition_size_range(xd, left_sb64_mi, &min_size, &max_size);
get_sb_partition_size_range(xd, left_sb64_mi, &min_size, &max_size,
bs_hist);
}
// Find the min and max partition sizes used in the above SB64.
if (above_in_image) {
MODE_INFO **above_sb64_mi = &mi[-xd->mi_stride * MI_BLOCK_SIZE];
get_sb_partition_size_range(xd, above_sb64_mi, &min_size, &max_size);
get_sb_partition_size_range(xd, above_sb64_mi, &min_size, &max_size,
bs_hist);
}
// adjust observed min and max
if (cpi->sf.auto_min_max_partition_size == RELAXED_NEIGHBORING_MIN_MAX) {
min_size = min_partition_size[min_size];
max_size = max_partition_size[max_size];
} else if (cpi->sf.auto_min_max_partition_size ==
CONSTRAIN_NEIGHBORING_MIN_MAX) {
// adjust the search range based on the histogram of the observed
// partition sizes from left, above the previous co-located blocks
int sum = 0;
int first_moment = 0;
int second_moment = 0;
int var_unnormalized = 0;
for (i = 0; i < BLOCK_SIZES; i++) {
sum += bs_hist[i];
first_moment += bs_hist[i] * i;
second_moment += bs_hist[i] * i * i;
}
// if variance is small enough,
// adjust the range around its mean size, which gives a tighter range
var_unnormalized = second_moment - first_moment * first_moment / sum;
if (var_unnormalized <= 4 * sum) {
int mean = first_moment / sum;
min_size = min_partition_size[mean];
max_size = max_partition_size[mean];
} else {
min_size = min_partition_size[min_size];
max_size = max_partition_size[max_size];
}
}
}
......@@ -1811,6 +1845,7 @@ static void rd_auto_partition_range(VP9_COMP *cpi, const TileInfo *const tile,
next_square_size[max_size] < min_size) {
min_size = next_square_size[max_size];
}
*min_block_size = min_size;
*max_block_size = max_size;
}
......
......@@ -102,7 +102,7 @@ static void set_good_speed_feature(VP9_COMP *cpi, VP9_COMMON *cm,
FLAG_SKIP_INTRA_LOWVAR;
sf->disable_filter_search_var_thresh = 100;
sf->comp_inter_joint_search_thresh = BLOCK_SIZES;
sf->auto_min_max_partition_size = RELAXED_NEIGHBORING_MIN_MAX;
sf->auto_min_max_partition_size = CONSTRAIN_NEIGHBORING_MIN_MAX;
sf->use_lastframe_partitioning = LAST_FRAME_PARTITION_LOW_MOTION;
sf->adjust_partitioning_from_last_frame = 1;
}
......
......@@ -63,7 +63,8 @@ typedef enum {
typedef enum {
NOT_IN_USE = 0,
RELAXED_NEIGHBORING_MIN_MAX = 1,
STRICT_NEIGHBORING_MIN_MAX = 2
CONSTRAIN_NEIGHBORING_MIN_MAX = 2,
STRICT_NEIGHBORING_MIN_MAX = 3
} AUTO_MIN_MAX_MODE;
typedef enum {
......
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