summaryrefslogtreecommitdiff
path: root/vp9
diff options
context:
space:
mode:
authorYaowu Xu <yaowu@google.com>2015-02-09 10:21:17 -0800
committerYaowu Xu <yaowu@google.com>2015-02-10 15:41:52 -0800
commitee5d79995e5e5adc2b4f38f374f3f63624b73c57 (patch)
tree155d2652de6231ba4140b3d0435cfa035b87a039 /vp9
parent2d924161c74ede567c925ab26ce489d78af12ccd (diff)
downloadlibvpx-ee5d79995e5e5adc2b4f38f374f3f63624b73c57.tar
libvpx-ee5d79995e5e5adc2b4f38f374f3f63624b73c57.tar.gz
libvpx-ee5d79995e5e5adc2b4f38f374f3f63624b73c57.tar.bz2
libvpx-ee5d79995e5e5adc2b4f38f374f3f63624b73c57.zip
Move computation up to frame level
This is to avoid redo the same calculation repeatly, and also allow easier adjustments for further experiments. This commit shall have no effect on quality/compression. Change-Id: I4460acf5c808ff5518da18d21e002c5da58af857
Diffstat (limited to 'vp9')
-rw-r--r--vp9/encoder/vp9_encodeframe.c89
-rw-r--r--vp9/encoder/vp9_encodeframe.h2
-rw-r--r--vp9/encoder/vp9_encoder.c3
-rw-r--r--vp9/encoder/vp9_encoder.h7
-rw-r--r--vp9/encoder/vp9_speed_features.h1
5 files changed, 61 insertions, 41 deletions
diff --git a/vp9/encoder/vp9_encodeframe.c b/vp9/encoder/vp9_encodeframe.c
index 0885909cd..99bb9300e 100644
--- a/vp9/encoder/vp9_encodeframe.c
+++ b/vp9/encoder/vp9_encodeframe.c
@@ -471,6 +471,43 @@ static int set_vt_partitioning(VP9_COMP *cpi,
return 0;
}
+
+void vp9_set_vbp_thresholds(VP9_COMP *cpi, int q) {
+ SPEED_FEATURES *const sf = &cpi->sf;
+ if (sf->partition_search_type != VAR_BASED_PARTITION) {
+ return;
+ } else {
+ VP9_COMMON *const cm = &cpi->common;
+ const VP9EncoderConfig *const oxcf = &cpi->oxcf;
+ const int is_key_frame = (cm->frame_type == KEY_FRAME);
+ const int use_4x4_partition = is_key_frame;
+ const int low_res = (cm->width <= 352 && cm->height <= 288);
+ const int threshold_multiplier = is_key_frame ? 80 : 4;
+ const int64_t threshold_base = (int64_t)(threshold_multiplier *
+ vp9_convert_qindex_to_q(q, cm->bit_depth));
+ cpi->vbp_threshold = threshold_base;
+ cpi->vbp_threshold_bsize_min = threshold_base << oxcf->speed;
+ cpi->vbp_threshold_bsize_max = threshold_base;
+
+ if (is_key_frame) {
+ cpi->vbp_threshold = threshold_base >> 2;
+ cpi->vbp_threshold_bsize_min = threshold_base << 2;
+ } else if (low_res) {
+ cpi->vbp_threshold_bsize_min = threshold_base << 3;
+ cpi->vbp_threshold_bsize_max = threshold_base >> 2;
+ }
+ // TODO(marpan): Allow 4x4 partitions for inter-frames.
+ // use_4x4_partition = (variance4x4downsample[i2 + j] == 1);
+ // If 4x4 partition is not used, then 8x8 partition will be selected
+ // if variance of 16x16 block is very high, so use larger threshold
+ // for 16x16 (threshold_bsize_min) in that case.
+ cpi->vbp_threshold_16x16 = (use_4x4_partition) ?
+ cpi->vbp_threshold : cpi->vbp_threshold_bsize_min;
+ cpi->vbp_bsize_min = (use_4x4_partition) ? BLOCK_8X8 : BLOCK_16X16;
+ }
+}
+
+
// This function chooses partitioning based on the variance between source and
// reconstructed last, where variance is computed for downs-sampled inputs.
static void choose_partitioning(VP9_COMP *cpi,
@@ -479,7 +516,6 @@ static void choose_partitioning(VP9_COMP *cpi,
int mi_row, int mi_col) {
VP9_COMMON * const cm = &cpi->common;
MACROBLOCKD *xd = &x->e_mbd;
-
int i, j, k, m;
v64x64 vt;
v16x16 vt2[16];
@@ -489,34 +525,12 @@ static void choose_partitioning(VP9_COMP *cpi,
int dp;
int pixels_wide = 64, pixels_high = 64;
const YV12_BUFFER_CONFIG *yv12 = get_ref_frame_buffer(cpi, LAST_FRAME);
- const struct scale_factors *const sf = &cm->frame_refs[LAST_FRAME - 1].sf;
+
// Always use 4x4 partition for key frame.
const int is_key_frame = (cm->frame_type == KEY_FRAME);
const int use_4x4_partition = is_key_frame;
+ const int low_res = (cm->width <= 352 && cm->height <= 288);
int variance4x4downsample[16];
- int low_res = (cm->width <= 352 && cm->height <= 288) ? 1 : 0;
- const int threshold_multiplier = is_key_frame ? 80 : 4;
- int64_t threshold_base;
- int64_t threshold;
- int64_t threshold_bsize_min;
- int64_t threshold_bsize_max;
-
- vp9_clear_system_state();
- threshold_base = (int64_t)(threshold_multiplier *
- vp9_convert_qindex_to_q(cm->base_qindex, cm->bit_depth));
- threshold = threshold_base;
- threshold_bsize_min = threshold_base << cpi->oxcf.speed;
- threshold_bsize_max = threshold_base;
-
- // Modify thresholds for key frame and for low-resolutions (set lower
- // thresholds to favor split).
- if (is_key_frame) {
- threshold = threshold_base >> 2;
- threshold_bsize_min = threshold_base << 2;
- } else if (low_res) {
- threshold_bsize_min = threshold_base << 3;
- threshold_bsize_max = threshold_base >> 2;
- }
set_offsets(cpi, tile, x, mi_row, mi_col, BLOCK_64X64);
@@ -531,7 +545,8 @@ static void choose_partitioning(VP9_COMP *cpi,
if (!is_key_frame) {
MB_MODE_INFO *mbmi = &xd->mi[0].src_mi->mbmi;
unsigned int var = 0, sse;
- vp9_setup_pre_planes(xd, 0, yv12, mi_row, mi_col, sf);
+ vp9_setup_pre_planes(xd, 0, yv12, mi_row, mi_col,
+ &cm->frame_refs[LAST_FRAME - 1].sf);
mbmi->ref_frame[0] = LAST_FRAME;
mbmi->ref_frame[1] = NONE;
mbmi->sb_type = BLOCK_64X64;
@@ -619,7 +634,7 @@ static void choose_partitioning(VP9_COMP *cpi,
}
if (is_key_frame || (low_res &&
vt.split[i].split[j].part_variances.none.variance >
- (threshold << 1))) {
+ (cpi->vbp_threshold << 1))) {
// Go down to 4x4 down-sampling for variance.
variance4x4downsample[i2 + j] = 1;
for (k = 0; k < 4; k++) {
@@ -680,30 +695,22 @@ static void choose_partitioning(VP9_COMP *cpi,
}
fill_variance_tree(&vt, BLOCK_64X64);
-
// Now go through the entire structure, splitting every block size until
// we get to one that's got a variance lower than our threshold.
if ( mi_col + 8 > cm->mi_cols || mi_row + 8 > cm->mi_rows ||
!set_vt_partitioning(cpi, xd, &vt, BLOCK_64X64, mi_row, mi_col,
- threshold_bsize_max, BLOCK_16X16)) {
+ cpi->vbp_threshold_bsize_max, BLOCK_16X16)) {
for (i = 0; i < 4; ++i) {
const int x32_idx = ((i & 1) << 2);
const int y32_idx = ((i >> 1) << 2);
const int i2 = i << 2;
if (!set_vt_partitioning(cpi, xd, &vt.split[i], BLOCK_32X32,
(mi_row + y32_idx), (mi_col + x32_idx),
- threshold, BLOCK_16X16)) {
+ cpi->vbp_threshold,
+ BLOCK_16X16)) {
for (j = 0; j < 4; ++j) {
const int x16_idx = ((j & 1) << 1);
const int y16_idx = ((j >> 1) << 1);
- // TODO(marpan): Allow 4x4 partitions for inter-frames.
- // use_4x4_partition = (variance4x4downsample[i2 + j] == 1);
- // If 4x4 partition is not used, then 8x8 partition will be selected
- // if variance of 16x16 block is very high, so use larger threshold
- // for 16x16 (threshold_bsize_min) in that case.
- uint64_t threshold_16x16 = (use_4x4_partition) ? threshold :
- threshold_bsize_min;
- BLOCK_SIZE bsize_min = (use_4x4_partition) ? BLOCK_8X8 : BLOCK_16X16;
// For inter frames: if variance4x4downsample[] == 1 for this 16x16
// block, then the variance is based on 4x4 down-sampling, so use vt2
// in set_vt_partioning(), otherwise use vt.
@@ -713,7 +720,8 @@ static void choose_partitioning(VP9_COMP *cpi,
if (!set_vt_partitioning(cpi, xd, vtemp, BLOCK_16X16,
mi_row + y32_idx + y16_idx,
mi_col + x32_idx + x16_idx,
- threshold_16x16, bsize_min)) {
+ cpi->vbp_threshold_16x16,
+ cpi->vbp_bsize_min)) {
for (k = 0; k < 4; ++k) {
const int x8_idx = (k & 1);
const int y8_idx = (k >> 1);
@@ -722,7 +730,8 @@ static void choose_partitioning(VP9_COMP *cpi,
BLOCK_8X8,
mi_row + y32_idx + y16_idx + y8_idx,
mi_col + x32_idx + x16_idx + x8_idx,
- threshold_bsize_min, BLOCK_8X8)) {
+ cpi->vbp_threshold_bsize_min,
+ BLOCK_8X8)) {
set_block_size(cpi, xd,
(mi_row + y32_idx + y16_idx + y8_idx),
(mi_col + x32_idx + x16_idx + x8_idx),
diff --git a/vp9/encoder/vp9_encodeframe.h b/vp9/encoder/vp9_encodeframe.h
index 556f3a5a1..8d545b671 100644
--- a/vp9/encoder/vp9_encodeframe.h
+++ b/vp9/encoder/vp9_encodeframe.h
@@ -38,6 +38,8 @@ void vp9_init_tile_data(struct VP9_COMP *cpi);
void vp9_encode_tile(struct VP9_COMP *cpi, struct ThreadData *td,
int tile_row, int tile_col);
+void vp9_set_vbp_thresholds(struct VP9_COMP *cpi, int q);
+
#ifdef __cplusplus
} // extern "C"
#endif
diff --git a/vp9/encoder/vp9_encoder.c b/vp9/encoder/vp9_encoder.c
index 65b660528..eda38ff3d 100644
--- a/vp9/encoder/vp9_encoder.c
+++ b/vp9/encoder/vp9_encoder.c
@@ -2800,7 +2800,10 @@ static void encode_without_recode_loop(VP9_COMP *cpi) {
set_size_dependent_vars(cpi, &q, &bottom_index, &top_index);
vp9_set_quantizer(cm, q);
+ vp9_set_vbp_thresholds(cpi, q);
+
setup_frame(cpi);
+
// Variance adaptive and in frame q adjustment experiments are mutually
// exclusive.
if (cpi->oxcf.aq_mode == VARIANCE_AQ) {
diff --git a/vp9/encoder/vp9_encoder.h b/vp9/encoder/vp9_encoder.h
index 1e4c982ff..35c5a487b 100644
--- a/vp9/encoder/vp9_encoder.h
+++ b/vp9/encoder/vp9_encoder.h
@@ -450,6 +450,13 @@ typedef struct VP9_COMP {
int resize_pending;
+ // VAR_BASED_PARTITION thresholds
+ int64_t vbp_threshold;
+ int64_t vbp_threshold_bsize_min;
+ int64_t vbp_threshold_bsize_max;
+ int64_t vbp_threshold_16x16;
+ BLOCK_SIZE vbp_bsize_min;
+
// Multi-threading
int num_workers;
VP9Worker *workers;
diff --git a/vp9/encoder/vp9_speed_features.h b/vp9/encoder/vp9_speed_features.h
index eaa0accdb..8722d9cec 100644
--- a/vp9/encoder/vp9_speed_features.h
+++ b/vp9/encoder/vp9_speed_features.h
@@ -421,4 +421,3 @@ void vp9_set_speed_features_framesize_dependent(struct VP9_COMP *cpi);
#endif
#endif // VP9_ENCODER_VP9_SPEED_FEATURES_H_
-