ref: eca93642e28102e5e30d6499f9661b89e8fdc27b
parent: 5b63c2797a50a6a007a9b20377b071cd0aa6d702
author: Pengchong Jin <pengchong@google.com>
date: Wed Aug 13 16:07:39 EDT 2014
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
--- a/vp9/encoder/vp9_encodeframe.c
+++ b/vp9/encoder/vp9_encodeframe.c
@@ -1724,7 +1724,8 @@
// 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 @@
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 @@
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 @@
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 @@
next_square_size[max_size] < min_size) {
min_size = next_square_size[max_size];
}
+
*min_block_size = min_size;
*max_block_size = max_size;
}
--- a/vp9/encoder/vp9_speed_features.c
+++ b/vp9/encoder/vp9_speed_features.c
@@ -102,7 +102,7 @@
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;
}
--- a/vp9/encoder/vp9_speed_features.h
+++ b/vp9/encoder/vp9_speed_features.h
@@ -63,7 +63,8 @@
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 {
--
⑨