diff options
-rw-r--r-- | vp9/encoder/vp9_encodeframe.c | 89 | ||||
-rw-r--r-- | vp9/encoder/vp9_encodeframe.h | 2 | ||||
-rw-r--r-- | vp9/encoder/vp9_encoder.c | 3 | ||||
-rw-r--r-- | vp9/encoder/vp9_encoder.h | 7 | ||||
-rw-r--r-- | vp9/encoder/vp9_speed_features.h | 1 |
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_ - |