diff --git a/vp9/encoder/vp9_encodeframe.c b/vp9/encoder/vp9_encodeframe.c index 4823c4baa0ed5949fa4f2e0f891291bcab99cd69..1894ea1661ecfb67742e0fe9065fef9e1c7d11e5 100644 --- a/vp9/encoder/vp9_encodeframe.c +++ b/vp9/encoder/vp9_encodeframe.c @@ -1429,6 +1429,56 @@ static void rd_use_partition(VP9_COMP *cpi, MODE_INFO *m, TOKENEXTRA **tp, *dist = chosen_dist; } +static BLOCK_SIZE_TYPE min_partition_size[BLOCK_SIZE_TYPES] = + { BLOCK_4X4, BLOCK_4X4, BLOCK_4X4, BLOCK_4X4, + BLOCK_4X4, BLOCK_4X4, BLOCK_8X8, BLOCK_8X8, + BLOCK_8X8, BLOCK_16X16, BLOCK_16X16, BLOCK_16X16, BLOCK_16X16 }; +static BLOCK_SIZE_TYPE max_partition_size[BLOCK_SIZE_TYPES] = + { BLOCK_8X8, BLOCK_16X16, BLOCK_16X16, BLOCK_16X16, + BLOCK_32X32, BLOCK_32X32, BLOCK_32X32, BLOCK_64X64, + BLOCK_64X64, BLOCK_64X64, BLOCK_64X64, BLOCK_64X64, BLOCK_64X64 }; + + +// Look at neighbouring blocks and set a min and max partition size based on +// what they chose. +static void rd_auto_partition_range(VP9_COMP *cpi, + BLOCK_SIZE_TYPE * min_block_size, + BLOCK_SIZE_TYPE * max_block_size) { + MACROBLOCKD *const xd = &cpi->mb.e_mbd; + const MODE_INFO *const mi = xd->mode_info_context; + const MB_MODE_INFO *const above_mbmi = &mi[-xd->mode_info_stride].mbmi; + const MB_MODE_INFO *const left_mbmi = &mi[-1].mbmi; + const int left_in_image = xd->left_available && left_mbmi->mb_in_image; + const int above_in_image = xd->up_available && above_mbmi->mb_in_image; + + // Frequency check + if (cpi->sf.auto_min_max_partition_count <= 0) { + cpi->sf.auto_min_max_partition_count = + cpi->sf.auto_min_max_partition_interval; + *min_block_size = BLOCK_4X4; + *max_block_size = BLOCK_64X64; + return; + } else { + --cpi->sf.auto_min_max_partition_count; + } + + // Check for edge cases + if (!left_in_image && !above_in_image) { + *min_block_size = BLOCK_4X4; + *max_block_size = BLOCK_64X64; + } else if (!left_in_image) { + *min_block_size = min_partition_size[above_mbmi->sb_type]; + *max_block_size = max_partition_size[above_mbmi->sb_type]; + } else if (!above_in_image) { + *min_block_size = min_partition_size[left_mbmi->sb_type]; + *max_block_size = max_partition_size[left_mbmi->sb_type]; + } else { + *min_block_size = + min_partition_size[MIN(left_mbmi->sb_type, above_mbmi->sb_type)]; + *max_block_size = + max_partition_size[MAX(left_mbmi->sb_type, above_mbmi->sb_type)]; + } +} // TODO(jingning,jimbankoski,rbultje): properly skip partition types that are // unlikely to be selected depending on previously rate-distortion optimization @@ -1462,8 +1512,8 @@ static void rd_pick_partition(VP9_COMP *cpi, TOKENEXTRA **tp, int mi_row, save_context(cpi, mi_row, mi_col, a, l, sa, sl, bsize); // PARTITION_SPLIT - if (!cpi->sf.use_partitions_greater_than || - bsize > cpi->sf.greater_than_block_size) { + if (!cpi->sf.auto_min_max_partition_size || + bsize >= cpi->sf.min_partition_size) { if (bsize > BLOCK_SIZE_SB8X8) { int r4 = 0; int64_t d4 = 0, sum_rd = 0; @@ -1604,8 +1654,8 @@ static void rd_pick_partition(VP9_COMP *cpi, TOKENEXTRA **tp, int mi_row, } } - if (!cpi->sf.use_partitions_less_than || - bsize <= cpi->sf.less_than_block_size) { + if (!cpi->sf.use_max_partition_size || + bsize <= cpi->sf.max_partition_size) { int larger_is_better = 0; // PARTITION_NONE if ((mi_row + (ms >> 1) < cm->mi_rows) && @@ -1876,6 +1926,12 @@ static void encode_sb_row(VP9_COMP *cpi, int mi_row, TOKENEXTRA **tp, || cpi->common.show_frame == 0 || cpi->common.frame_type == KEY_FRAME || cpi->is_src_frame_alt_ref) { + // If required set upper and lower partition size limits + if (cpi->sf.auto_min_max_partition_size) { + rd_auto_partition_range(cpi, + &cpi->sf.min_partition_size, + &cpi->sf.max_partition_size); + } rd_pick_partition(cpi, tp, mi_row, mi_col, BLOCK_SIZE_SB64X64, &dummy_rate, &dummy_dist, 1, INT64_MAX); } else { @@ -1885,6 +1941,13 @@ static void encode_sb_row(VP9_COMP *cpi, int mi_row, TOKENEXTRA **tp, } } } else { + // If required set upper and lower partition size limits + if (cpi->sf.auto_min_max_partition_size) { + rd_auto_partition_range(cpi, + &cpi->sf.min_partition_size, + &cpi->sf.max_partition_size); + } + rd_pick_partition(cpi, tp, mi_row, mi_col, BLOCK_SIZE_SB64X64, &dummy_rate, &dummy_dist, 1, INT64_MAX); } diff --git a/vp9/encoder/vp9_onyx_if.c b/vp9/encoder/vp9_onyx_if.c index fc19bd9514849965a77afcf6d682282474b8bf17..5b9d231a7334f65391826cfc024fe98929ab850b 100644 --- a/vp9/encoder/vp9_onyx_if.c +++ b/vp9/encoder/vp9_onyx_if.c @@ -731,10 +731,13 @@ void vp9_set_speed_features(VP9_COMP *cpi) { sf->use_one_partition_size_always = 0; sf->less_rectangular_check = 0; sf->use_square_partition_only = 0; - sf->use_partitions_less_than = 0; - sf->less_than_block_size = BLOCK_SIZE_MB16X16; - sf->use_partitions_greater_than = 0; - sf->greater_than_block_size = BLOCK_SIZE_SB8X8; + sf->auto_min_max_partition_size = 0; + sf->auto_min_max_partition_interval = 0; + sf->auto_min_max_partition_count = 0; + sf->use_max_partition_size = 0; + sf->max_partition_size = BLOCK_64X64; + sf->use_min_partition_size = 0; + sf->min_partition_size = BLOCK_4X4; sf->adjust_partitioning_from_last_frame = 0; sf->last_partitioning_redo_frequency = 4; sf->disable_splitmv = 0; @@ -788,10 +791,15 @@ void vp9_set_speed_features(VP9_COMP *cpi) { sf->mode_search_skip_flags = FLAG_SKIP_INTRA_DIRMISMATCH | FLAG_SKIP_INTRA_BESTINTER | FLAG_SKIP_COMP_BESTINTRA; - sf->last_chroma_intra_mode = H_PRED; + sf->use_uv_intra_rd_estimate = 1; sf->use_rd_breakout = 1; sf->skip_encode_sb = 1; sf->auto_mv_step_size = 1; + + sf->auto_min_max_partition_size = 1; + sf->use_max_partition_size = 1; + sf->use_min_partition_size = 1; + sf->auto_min_max_partition_interval = 1; } if (speed == 2) { sf->adjust_thresholds_by_speed = 1; @@ -812,9 +820,9 @@ void vp9_set_speed_features(VP9_COMP *cpi) { FLAG_SKIP_COMP_BESTINTRA | FLAG_SKIP_COMP_REFMISMATCH; sf->last_chroma_intra_mode = DC_PRED; + sf->use_uv_intra_rd_estimate = 1; sf->use_rd_breakout = 1; sf->skip_encode_sb = 1; - sf->use_uv_intra_rd_estimate = 1; sf->using_small_partition_info = 1; sf->disable_splitmv = (MIN(cpi->common.width, cpi->common.height) >= 720)? 1 : 0; @@ -862,14 +870,14 @@ void vp9_set_speed_features(VP9_COMP *cpi) { if (speed == 2) { sf->first_step = 0; sf->comp_inter_joint_search_thresh = BLOCK_SIZE_SB8X8; - sf->use_partitions_less_than = 1; - sf->less_than_block_size = BLOCK_SIZE_MB16X16; + sf->use_max_partition_size = 1; + sf->max_partition_size = BLOCK_SIZE_MB16X16; } if (speed == 3) { sf->first_step = 0; sf->comp_inter_joint_search_thresh = BLOCK_SIZE_SB8X8; - sf->use_partitions_greater_than = 1; - sf->greater_than_block_size = BLOCK_SIZE_SB8X8; + sf->use_min_partition_size = 1; + sf->min_partition_size = BLOCK_SIZE_SB8X8; } */ diff --git a/vp9/encoder/vp9_onyx_int.h b/vp9/encoder/vp9_onyx_int.h index 0798927bd525c0db493b62a363f6d23579d24190..dc5e564aeeb3d25a936eaf6f1efc2bf82f697041 100644 --- a/vp9/encoder/vp9_onyx_int.h +++ b/vp9/encoder/vp9_onyx_int.h @@ -258,10 +258,13 @@ typedef struct { int unused_mode_skip_lvl; int reference_masking; BLOCK_SIZE_TYPE always_this_block_size; - int use_partitions_greater_than; - BLOCK_SIZE_TYPE greater_than_block_size; - int use_partitions_less_than; - BLOCK_SIZE_TYPE less_than_block_size; + int auto_min_max_partition_size; + int auto_min_max_partition_interval; + int auto_min_max_partition_count; + int use_min_partition_size; + BLOCK_SIZE_TYPE min_partition_size; + int use_max_partition_size; + BLOCK_SIZE_TYPE max_partition_size; int adjust_partitioning_from_last_frame; int last_partitioning_redo_frequency; int disable_splitmv;