Add intra mode early termination in non-rd mode

Added the intra mode early termination in order to
speed up the mode search in non-rd case since we
started to include more intra modes in the search
list. Borg tests(rtc set) showed a 0.048% PSNR gain
and 0.061 SSIM gain. No speed change.

Change-Id: I6f255fe534dc50b736e6a66a726ad458eb9b4443
This commit is contained in:
Yunqing Wang 2015-05-01 13:20:50 -07:00
Родитель ccae5d99d2
Коммит 36eabb1c3c
1 изменённых файлов: 64 добавлений и 14 удалений

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

@ -923,7 +923,7 @@ static void estimate_block_intra(int plane, int block, BLOCK_SIZE plane_bsize,
}
static const THR_MODES mode_idx[MAX_REF_FRAMES - 1][4] = {
{THR_DC, THR_H_PRED, THR_V_PRED, THR_TM},
{THR_DC, THR_V_PRED, THR_H_PRED, THR_TM},
{THR_NEARESTMV, THR_NEARMV, THR_ZEROMV, THR_NEWMV},
{THR_NEARESTG, THR_NEARG, THR_ZEROG, THR_NEWG},
};
@ -932,6 +932,40 @@ static const PREDICTION_MODE intra_mode_list[] = {
DC_PRED, V_PRED, H_PRED, TM_PRED
};
static int mode_offset(const PREDICTION_MODE mode) {
if (mode >= NEARESTMV) {
return INTER_OFFSET(mode);
} else {
switch (mode) {
case DC_PRED:
return 0;
case V_PRED:
return 1;
case H_PRED:
return 2;
case TM_PRED:
return 3;
default:
return -1;
}
}
}
static INLINE void update_thresh_freq_fact(VP9_COMP *cpi,
TileDataEnc *tile_data,
BLOCK_SIZE bsize,
MV_REFERENCE_FRAME ref_frame,
THR_MODES best_mode_idx,
PREDICTION_MODE mode) {
THR_MODES thr_mode_idx = mode_idx[ref_frame][mode_offset(mode)];
int *freq_fact = &tile_data->thresh_freq_fact[bsize][thr_mode_idx];
if (thr_mode_idx == best_mode_idx)
*freq_fact -= (*freq_fact >> 4);
else
*freq_fact = MIN(*freq_fact + RD_THRESH_INC,
cpi->sf.adaptive_rd_thresh * RD_THRESH_MAX_FACT);
}
void vp9_pick_intra_mode(VP9_COMP *cpi, MACROBLOCK *x, RD_COST *rd_cost,
BLOCK_SIZE bsize, PICK_MODE_CONTEXT *ctx) {
MACROBLOCKD *const xd = &x->e_mbd;
@ -1489,8 +1523,16 @@ void vp9_pick_inter_mode(VP9_COMP *cpi, MACROBLOCK *x,
for (i = 0; i < 4; ++i) {
const PREDICTION_MODE this_mode = intra_mode_list[i];
THR_MODES mode_index = mode_idx[INTRA_FRAME][mode_offset(this_mode)];
int mode_rd_thresh = rd_threshes[mode_index];
if (!((1 << this_mode) & cpi->sf.intra_y_mode_bsize_mask[bsize]))
continue;
if (rd_less_than_thresh(best_rdc.rdcost, mode_rd_thresh,
rd_thresh_freq_fact[mode_index]))
continue;
mbmi->mode = this_mode;
mbmi->ref_frame[0] = INTRA_FRAME;
args.mode = this_mode;
@ -1551,20 +1593,28 @@ void vp9_pick_inter_mode(VP9_COMP *cpi, MACROBLOCK *x,
}
if (cpi->sf.adaptive_rd_thresh) {
THR_MODES best_mode_idx = is_inter_block(mbmi) ?
mode_idx[best_ref_frame][INTER_OFFSET(mbmi->mode)] :
mode_idx[INTRA_FRAME][mbmi->mode];
THR_MODES best_mode_idx = mode_idx[best_ref_frame][mode_offset(mbmi->mode)];
PREDICTION_MODE this_mode;
for (ref_frame = LAST_FRAME; ref_frame <= GOLDEN_FRAME; ++ref_frame) {
if (best_ref_frame != ref_frame) continue;
for (this_mode = NEARESTMV; this_mode <= NEWMV; ++this_mode) {
THR_MODES thr_mode_idx = mode_idx[ref_frame][INTER_OFFSET(this_mode)];
int *freq_fact = &tile_data->thresh_freq_fact[bsize][thr_mode_idx];
if (thr_mode_idx == best_mode_idx)
*freq_fact -= (*freq_fact >> 4);
else
*freq_fact = MIN(*freq_fact + RD_THRESH_INC,
cpi->sf.adaptive_rd_thresh * RD_THRESH_MAX_FACT);
if (best_ref_frame == INTRA_FRAME) {
// Only consider the modes that are included in the intra_mode_list.
int intra_modes = sizeof(intra_mode_list)/sizeof(PREDICTION_MODE);
int i;
// TODO(yunqingwang): Check intra mode mask and only update freq_fact
// for those valid modes.
for (i = 0; i < intra_modes; i++) {
PREDICTION_MODE this_mode = intra_mode_list[i];
update_thresh_freq_fact(cpi, tile_data, bsize, INTRA_FRAME,
best_mode_idx, this_mode);
}
} else {
for (ref_frame = LAST_FRAME; ref_frame <= GOLDEN_FRAME; ++ref_frame) {
if (best_ref_frame != ref_frame) continue;
for (this_mode = NEARESTMV; this_mode <= NEWMV; ++this_mode) {
update_thresh_freq_fact(cpi, tile_data, bsize, ref_frame,
best_mode_idx, this_mode);
}
}
}
}