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:
Jingning Han 2014-03-19 11:25:40 -07:00
Родитель 98fd11c567
Коммит 60f9ebc3f1
4 изменённых файлов: 63 добавлений и 5 удалений

Просмотреть файл

@ -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) {