ref: 7dbdada49f0d63d18173fa91d9510fc5f17bb21a
parent: d1cdda88bd3d98b4e8c84dafa3dfecfebbfb8c88
parent: 36eabb1c3cf182173109643a7031e4c5ed2c7114
author: Yunqing Wang <[email protected]>
date: Wed May 6 13:12:10 EDT 2015
Merge "Add intra mode early termination in non-rd mode"
--- a/vp9/encoder/vp9_pickmode.c
+++ b/vp9/encoder/vp9_pickmode.c
@@ -923,7 +923,7 @@
}
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 @@
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 @@
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 @@
}
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);
+ }
}
}
}