diff options
Diffstat (limited to 'vp9')
-rw-r--r-- | vp9/encoder/vp9_encoder.c | 101 | ||||
-rw-r--r-- | vp9/encoder/vp9_pickmode.c | 12 |
2 files changed, 87 insertions, 26 deletions
diff --git a/vp9/encoder/vp9_encoder.c b/vp9/encoder/vp9_encoder.c index eaeb3d96e..b8c86ea43 100644 --- a/vp9/encoder/vp9_encoder.c +++ b/vp9/encoder/vp9_encoder.c @@ -2583,6 +2583,7 @@ void vp9_remove_compressor(VP9_COMP *cpi) { for (sqr_bsize = 0; sqr_bsize < SQUARE_BLOCK_SIZES; ++sqr_bsize) { vpx_free(cpi->tpl_stats[frame].pyramid_mv_arr[rf_idx][sqr_bsize]); } + vpx_free(cpi->tpl_stats[frame].mv_mode_arr[rf_idx]); } #endif vpx_free(cpi->tpl_stats[frame].tpl_stats_ptr); @@ -6014,22 +6015,27 @@ static void mode_estimation(VP9_COMP *cpi, MACROBLOCK *x, MACROBLOCKD *xd, } #if CONFIG_NON_GREEDY_MV -static void get_block_src_pred_buf(MACROBLOCKD *xd, GF_PICTURE *gf_picture, - int frame_idx, int rf_idx, int mi_row, - int mi_col, struct buf_2d *src, - struct buf_2d *pre) { +static int get_block_src_pred_buf(MACROBLOCKD *xd, GF_PICTURE *gf_picture, + int frame_idx, int rf_idx, int mi_row, + int mi_col, struct buf_2d *src, + struct buf_2d *pre) { const int mb_y_offset = mi_row * MI_SIZE * xd->cur_buf->y_stride + mi_col * MI_SIZE; YV12_BUFFER_CONFIG *ref_frame = NULL; int ref_frame_idx = gf_picture[frame_idx].ref_frame[rf_idx]; if (ref_frame_idx != -1) { ref_frame = gf_picture[ref_frame_idx].frame; + src->buf = xd->cur_buf->y_buffer + mb_y_offset; + src->stride = xd->cur_buf->y_stride; + pre->buf = ref_frame->y_buffer + mb_y_offset; + pre->stride = ref_frame->y_stride; + assert(src->stride == pre->stride); + return 1; + } else { + printf("invalid ref_frame_idx"); + assert(ref_frame_idx != -1); + return 0; } - src->buf = xd->cur_buf->y_buffer + mb_y_offset; - src->stride = xd->cur_buf->y_stride; - pre->buf = ref_frame->y_buffer + mb_y_offset; - pre->stride = ref_frame->y_stride; - assert(src->stride == pre->stride); } #define kMvPreCheckLines 5 @@ -6135,18 +6141,60 @@ static double get_mv_dist(int mv_mode, VP9_COMP *cpi, MACROBLOCKD *xd, *mv = get_mv_from_mv_mode(mv_mode, cpi, tpl_frame, rf_idx, bsize, mi_row, mi_col); full_mv = get_full_mv(&mv->as_mv); - get_block_src_pred_buf(xd, gf_picture, frame_idx, rf_idx, mi_row, mi_col, - &src, &pre); - // TODO(angiebird): Consider subpixel when computing the sse. - cpi->fn_ptr[bsize].vf(src.buf, src.stride, get_buf_from_mv(&pre, &full_mv), - pre.stride, &sse); - return (double)sse; + if (get_block_src_pred_buf(xd, gf_picture, frame_idx, rf_idx, mi_row, mi_col, + &src, &pre)) { + // TODO(angiebird): Consider subpixel when computing the sse. + cpi->fn_ptr[bsize].vf(src.buf, src.stride, get_buf_from_mv(&pre, &full_mv), + pre.stride, &sse); + return (double)sse; + } else { + assert(0); + return 0; + } } -static double get_mv_cost(int mv_mode) { - // TODO(angiebird): Implement this function. - (void)mv_mode; - return 0; +static int get_mv_mode_cost(int mv_mode) { + // TODO(angiebird): The probabilities are roughly inferred from + // default_inter_mode_probs. Check if there is a better way to set the + // probabilities. + const int zero_mv_prob = 9; + const int new_mv_prob = 77; + const int ref_mv_prob = 170; + assert(zero_mv_prob + new_mv_prob + ref_mv_prob == 256); + switch (mv_mode) { + case ZERO_MV_MODE: return vp9_prob_cost[zero_mv_prob]; break; + case NEW_MV_MODE: return vp9_prob_cost[new_mv_prob]; break; + case NEAREST_MV_MODE: return vp9_prob_cost[ref_mv_prob]; break; + case NEAR_MV_MODE: return vp9_prob_cost[ref_mv_prob]; break; + default: assert(0); return -1; + } +} + +static INLINE double get_mv_diff_cost(MV *new_mv, MV *ref_mv) { + double mv_diff_cost = log2(1 + abs(new_mv->row - ref_mv->row)) + + log2(1 + abs(new_mv->col - ref_mv->col)); + mv_diff_cost *= (1 << VP9_PROB_COST_SHIFT); + return mv_diff_cost; +} +static double get_mv_cost(int mv_mode, VP9_COMP *cpi, TplDepFrame *tpl_frame, + int rf_idx, BLOCK_SIZE bsize, int mi_row, + int mi_col) { + double mv_cost = get_mv_mode_cost(mv_mode); + if (mv_mode == NEW_MV_MODE) { + MV new_mv = get_mv_from_mv_mode(mv_mode, cpi, tpl_frame, rf_idx, bsize, + mi_row, mi_col) + .as_mv; + MV nearest_mv = get_mv_from_mv_mode(NEAREST_MV_MODE, cpi, tpl_frame, rf_idx, + bsize, mi_row, mi_col) + .as_mv; + MV near_mv = get_mv_from_mv_mode(NEAR_MV_MODE, cpi, tpl_frame, rf_idx, + bsize, mi_row, mi_col) + .as_mv; + double nearest_cost = get_mv_diff_cost(&new_mv, &nearest_mv); + double near_cost = get_mv_diff_cost(&new_mv, &near_mv); + mv_cost += nearest_cost < near_cost ? nearest_cost : near_cost; + } + return mv_cost; } static double rd_cost(int rdmult, int rddiv, double rate, double dist) { @@ -6160,7 +6208,9 @@ static double eval_mv_mode(int mv_mode, VP9_COMP *cpi, MACROBLOCK *x, MACROBLOCKD *xd = &x->e_mbd; double mv_dist = get_mv_dist(mv_mode, cpi, xd, gf_picture, frame_idx, tpl_frame, rf_idx, bsize, mi_row, mi_col, mv); - double mv_cost = get_mv_cost(mv_mode); + double mv_cost = + get_mv_cost(mv_mode, cpi, tpl_frame, rf_idx, bsize, mi_row, mi_col); + return rd_cost(x->rdmult, x->rddiv, mv_cost, mv_dist); } @@ -6218,7 +6268,7 @@ static void predict_mv_mode(VP9_COMP *cpi, MACROBLOCK *x, // no new mv // diagnal scan order tmp_idx = 0; - for (idx = 0; idx < kMvPreCheckSize; ++idx) { + for (idx = 0; idx < kMvPreCheckLines; ++idx) { int r; for (r = 0; r <= idx; ++r) { int c = idx - r; @@ -6245,7 +6295,7 @@ static void predict_mv_mode(VP9_COMP *cpi, MACROBLOCK *x, &select_mv_arr[mi_row * stride + mi_col]); // We start from idx = 1 because idx = 0 is evaluated as NEW_MV_MODE // beforehand. - for (idx = 1; idx < kMvPreCheckSize; ++idx) { + for (idx = 1; idx < kMvPreCheckLines; ++idx) { int r; for (r = 0; r <= idx; ++r) { int c = idx - r; @@ -6266,7 +6316,7 @@ static void predict_mv_mode(VP9_COMP *cpi, MACROBLOCK *x, tmp_idx = 0; if (no_new_mv_rd < new_mv_rd) { *rd = no_new_mv_rd; - for (idx = 0; idx < kMvPreCheckSize; ++idx) { + for (idx = 0; idx < kMvPreCheckLines; ++idx) { int r; for (r = 0; r <= idx; ++r) { int c = idx - r; @@ -6783,6 +6833,11 @@ static void init_tpl_buffer(VP9_COMP *cpi) { sizeof( *cpi->tpl_stats[frame].pyramid_mv_arr[rf_idx][sqr_bsize]))); } + vpx_free(cpi->tpl_stats[frame].mv_mode_arr[rf_idx]); + CHECK_MEM_ERROR( + cm, cpi->tpl_stats[frame].mv_mode_arr[rf_idx], + vpx_calloc(mi_rows * mi_cols * 4, + sizeof(*cpi->tpl_stats[frame].mv_mode_arr[rf_idx]))); } #endif vpx_free(cpi->tpl_stats[frame].tpl_stats_ptr); diff --git a/vp9/encoder/vp9_pickmode.c b/vp9/encoder/vp9_pickmode.c index 0fdc61649..8cd1e6e31 100644 --- a/vp9/encoder/vp9_pickmode.c +++ b/vp9/encoder/vp9_pickmode.c @@ -1943,8 +1943,9 @@ void vp9_pick_inter_mode(VP9_COMP *cpi, MACROBLOCK *x, TileDataEnc *tile_data, // For SVC with quality layers, when QP of lower layer is lower // than current layer: force check of GF-ZEROMV before early exit // due to skip flag. - if (svc->spatial_layer_id > 0 && usable_ref_frame == GOLDEN_FRAME && - no_scaling && cm->base_qindex > svc->lower_layer_qindex + 10) + if (svc->spatial_layer_id > 0 && no_scaling && + (cpi->ref_frame_flags & flag_list[GOLDEN_FRAME]) && + cm->base_qindex > svc->lower_layer_qindex + 10) force_test_gf_zeromv = 1; for (idx = 0; idx < num_inter_modes + comp_modes; ++idx) { @@ -2407,6 +2408,8 @@ void vp9_pick_inter_mode(VP9_COMP *cpi, MACROBLOCK *x, TileDataEnc *tile_data, // Perform intra prediction search, if the best SAD is above a certain // threshold. if (best_rdc.rdcost == INT64_MAX || + (cpi->oxcf.content == VP9E_CONTENT_SCREEN && x->source_variance == 0 && + !x->zero_temp_sad_source) || (scene_change_detected && perform_intra_pred) || ((!force_skip_low_temp_var || bsize < BLOCK_32X32 || x->content_state_sb == kVeryHighSad) && @@ -2449,8 +2452,11 @@ void vp9_pick_inter_mode(VP9_COMP *cpi, MACROBLOCK *x, TileDataEnc *tile_data, 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]; + // For spatially flat blocks, under short_circuit_flat_blocks flag: + // only check DC mode for stationary blocks, otherwise also check + // H and V mode. if (sf->short_circuit_flat_blocks && x->source_variance == 0 && - this_mode != DC_PRED) { + ((x->zero_temp_sad_source && this_mode != DC_PRED) || i > 2)) { continue; } |