Enable variable block size test in non-RD mode decision
This is an initial attempt to allow variable block size partition in non-RD coding flow. It tests 8x8, 16x16 and 32x32 block size per 64x64 block, all using non-RD mode decision and the associated rate distortion costs from modeling, then selects the best block size to encode the entire 64x64 block. Such operations are triggered every other 3 frames. The blocks of intermediate frames will reuse the collocated block's partition type. It improves the compression performance by 13.2%. Note that the gains are not evenly distributed. For many hard clips, the compression performance is improved by 20% to 28%. Local speed test shows that it will also increase runtime by 50%, as compared to speed -7. It is now enabled in speed -6 setting. Change-Id: Ib4fb8659d21621c9075b3c369ddaa9ecb0a4b204
This commit is contained in:
Родитель
98fd11c567
Коммит
60f9ebc3f1
|
@ -2693,6 +2693,7 @@ static void nonrd_pick_sb_modes(VP9_COMP *cpi, const TileInfo *const tile,
|
|||
MACROBLOCKD *const xd = &x->e_mbd;
|
||||
set_offsets(cpi, tile, mi_row, mi_col, bsize);
|
||||
xd->mi_8x8[0]->mbmi.sb_type = bsize;
|
||||
|
||||
if (!frame_is_intra_only(cm)) {
|
||||
vp9_pick_inter_mode(cpi, x, tile, mi_row, mi_col,
|
||||
rate, dist, bsize);
|
||||
|
@ -2825,6 +2826,8 @@ static void encode_nonrd_sb_row(VP9_COMP *cpi, const TileInfo *const tile,
|
|||
int64_t dummy_dist;
|
||||
const int idx_str = cm->mode_info_stride * mi_row + mi_col;
|
||||
MODE_INFO **mi_8x8 = cm->mi_grid_visible + idx_str;
|
||||
MODE_INFO **prev_mi_8x8 = cm->prev_mi_grid_visible + idx_str;
|
||||
|
||||
BLOCK_SIZE bsize = cpi->sf.partition_search_type == FIXED_PARTITION ?
|
||||
cpi->sf.always_this_block_size :
|
||||
get_nonrd_var_based_fixed_partition(cpi, mi_row, mi_col);
|
||||
|
@ -2834,6 +2837,47 @@ static void encode_nonrd_sb_row(VP9_COMP *cpi, const TileInfo *const tile,
|
|||
// Set the partition type of the 64X64 block
|
||||
if (cpi->sf.partition_search_type == VAR_BASED_PARTITION)
|
||||
choose_partitioning(cpi, tile, mi_row, mi_col);
|
||||
else if (cpi->sf.partition_search_type == REFERENCE_PARTITION) {
|
||||
if (cpi->sf.partition_check) {
|
||||
MACROBLOCK *x = &cpi->mb;
|
||||
int rate1, rate2, rate3;
|
||||
int64_t dist1, dist2, dist3;
|
||||
set_fixed_partitioning(cpi, tile, mi_8x8, mi_row, mi_col, BLOCK_8X8);
|
||||
nonrd_use_partition(cpi, tile, mi_8x8, tp, mi_row, mi_col, BLOCK_64X64,
|
||||
0, &rate1, &dist1);
|
||||
set_fixed_partitioning(cpi, tile, mi_8x8, mi_row, mi_col, BLOCK_16X16);
|
||||
nonrd_use_partition(cpi, tile, mi_8x8, tp, mi_row, mi_col, BLOCK_64X64,
|
||||
0, &rate2, &dist2);
|
||||
set_fixed_partitioning(cpi, tile, mi_8x8, mi_row, mi_col, BLOCK_32X32);
|
||||
nonrd_use_partition(cpi, tile, mi_8x8, tp, mi_row, mi_col, BLOCK_64X64,
|
||||
0, &rate3, &dist3);
|
||||
|
||||
if (RDCOST(x->rdmult, x->rddiv, rate1, dist1) <
|
||||
RDCOST(x->rdmult, x->rddiv, rate2, dist2)) {
|
||||
if (RDCOST(x->rdmult, x->rddiv, rate1, dist1) <
|
||||
RDCOST(x->rdmult, x->rddiv, rate3, dist3))
|
||||
set_fixed_partitioning(cpi, tile, mi_8x8, mi_row, mi_col,
|
||||
BLOCK_8X8);
|
||||
else
|
||||
set_fixed_partitioning(cpi, tile, mi_8x8, mi_row, mi_col,
|
||||
BLOCK_32X32);
|
||||
} else {
|
||||
if (RDCOST(x->rdmult, x->rddiv, rate2, dist2) <
|
||||
RDCOST(x->rdmult, x->rddiv, rate3, dist3))
|
||||
set_fixed_partitioning(cpi, tile, mi_8x8, mi_row, mi_col,
|
||||
BLOCK_16X16);
|
||||
else
|
||||
set_fixed_partitioning(cpi, tile, mi_8x8, mi_row, mi_col,
|
||||
BLOCK_32X32);
|
||||
}
|
||||
|
||||
} else {
|
||||
if (!sb_has_motion(cm, prev_mi_8x8))
|
||||
copy_partitioning(cm, mi_8x8, prev_mi_8x8);
|
||||
else
|
||||
set_fixed_partitioning(cpi, tile, mi_8x8, mi_row, mi_col, bsize);
|
||||
}
|
||||
}
|
||||
else
|
||||
set_fixed_partitioning(cpi, tile, mi_8x8, mi_row, mi_col, bsize);
|
||||
|
||||
|
|
|
@ -874,8 +874,11 @@ static void set_rt_speed_feature(VP9_COMMON *cm,
|
|||
sf->max_intra_bsize = BLOCK_32X32;
|
||||
}
|
||||
if (speed >= 6) {
|
||||
sf->partition_search_type = VAR_BASED_FIXED_PARTITION;
|
||||
sf->search_method = HEX;
|
||||
sf->partition_check =
|
||||
(cm->current_video_frame % sf->last_partitioning_redo_frequency == 1);
|
||||
sf->partition_search_type = REFERENCE_PARTITION;
|
||||
sf->use_nonrd_pick_mode = 1;
|
||||
sf->search_method = FAST_DIAMOND;
|
||||
}
|
||||
if (speed >= 7) {
|
||||
sf->partition_search_type = VAR_BASED_FIXED_PARTITION;
|
||||
|
|
|
@ -213,6 +213,8 @@ typedef enum {
|
|||
// determined based on source variance
|
||||
VAR_BASED_FIXED_PARTITION = 2,
|
||||
|
||||
REFERENCE_PARTITION = 3,
|
||||
|
||||
// Use an arbitrary partitioning scheme based on source variance within
|
||||
// a 64X64 SB
|
||||
VAR_BASED_PARTITION
|
||||
|
@ -357,6 +359,10 @@ typedef struct {
|
|||
// was selected, and 2 means we use 8 tap if no 8x8 filter mode was selected.
|
||||
int adaptive_pred_interp_filter;
|
||||
|
||||
// Search through variable block partition types in non-RD mode decision
|
||||
// encoding process for RTC.
|
||||
int partition_check;
|
||||
|
||||
// Implements various heuristics to skip searching modes
|
||||
// The heuristics selected are based on flags
|
||||
// defined in the MODE_SEARCH_SKIP_HEURISTICS enum
|
||||
|
|
|
@ -233,12 +233,16 @@ int64_t vp9_pick_inter_mode(VP9_COMP *cpi, MACROBLOCK *x,
|
|||
int64_t best_rd = INT64_MAX;
|
||||
int64_t this_rd = INT64_MAX;
|
||||
|
||||
const int64_t inter_mode_thresh = 300;
|
||||
const int64_t intra_mode_cost = 50;
|
||||
|
||||
int rate = INT_MAX;
|
||||
int64_t dist = INT64_MAX;
|
||||
|
||||
VP9_COMMON *cm = &cpi->common;
|
||||
int intra_cost_penalty = 20 * vp9_dc_quant(cm->base_qindex, cm->y_dc_delta_q);
|
||||
|
||||
const int64_t inter_mode_thresh = RDCOST(x->rdmult, x->rddiv,
|
||||
intra_cost_penalty, 0);
|
||||
const int64_t intra_mode_cost = 50;
|
||||
|
||||
x->skip_encode = cpi->sf.skip_encode_frame && x->q_index < QIDX_SKIP_THRESH;
|
||||
|
||||
x->skip = 0;
|
||||
|
@ -345,6 +349,7 @@ int64_t vp9_pick_inter_mode(VP9_COMP *cpi, MACROBLOCK *x,
|
|||
|
||||
model_rd_for_sb_y(cpi, bsize, x, xd, &rate, &dist);
|
||||
rate += x->mbmode_cost[this_mode];
|
||||
rate += intra_cost_penalty;
|
||||
this_rd = RDCOST(x->rdmult, x->rddiv, rate, dist);
|
||||
|
||||
if (this_rd + intra_mode_cost < best_rd) {
|
||||
|
|
Загрузка…
Ссылка в новой задаче