diff options
author | Pengchong Jin <pengchong@google.com> | 2014-08-15 19:51:04 -0700 |
---|---|---|
committer | Gerrit Code Review <gerrit@gerrit.golo.chromium.org> | 2014-08-15 19:51:04 -0700 |
commit | 997db6fc3f67aa499574e362b37adf4b07534ff7 (patch) | |
tree | 356cdcb1434dcd8fd4ec05eb4985451259053127 /vp9 | |
parent | 90d21bb28e2def7f43d5e59305c08b684a14b594 (diff) | |
parent | eca93642e28102e5e30d6499f9661b89e8fdc27b (diff) | |
download | libvpx-997db6fc3f67aa499574e362b37adf4b07534ff7.tar.gz |
Merge "Add a speed feature to give the tighter search range"
Diffstat (limited to 'vp9')
-rw-r--r-- | vp9/encoder/vp9_encodeframe.c | 43 | ||||
-rw-r--r-- | vp9/encoder/vp9_speed_features.c | 2 | ||||
-rw-r--r-- | vp9/encoder/vp9_speed_features.h | 3 |
3 files changed, 42 insertions, 6 deletions
diff --git a/vp9/encoder/vp9_encodeframe.c b/vp9/encoder/vp9_encodeframe.c index a30473214..711354b7f 100644 --- a/vp9/encoder/vp9_encodeframe.c +++ b/vp9/encoder/vp9_encodeframe.c @@ -1723,7 +1723,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; @@ -1734,6 +1735,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); } @@ -1766,6 +1768,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" @@ -1778,22 +1783,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]; + } } } @@ -1810,6 +1844,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; } diff --git a/vp9/encoder/vp9_speed_features.c b/vp9/encoder/vp9_speed_features.c index 6ac511d20..67b6e269e 100644 --- a/vp9/encoder/vp9_speed_features.c +++ b/vp9/encoder/vp9_speed_features.c @@ -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; } diff --git a/vp9/encoder/vp9_speed_features.h b/vp9/encoder/vp9_speed_features.h index 7334874dd..8edcb1d72 100644 --- a/vp9/encoder/vp9_speed_features.h +++ b/vp9/encoder/vp9_speed_features.h @@ -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 { |