From: Jingning Han Date: Thu, 30 May 2013 04:59:41 +0000 (-0700) Subject: Enable iterative motion search for 4x4 inter pred X-Git-Tag: v1.3.0~1104^2~96^2~1 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=87626a8f6ea2706a347a03b09a2c1ac570fdb615;p=platform%2Fupstream%2Flibvpx.git Enable iterative motion search for 4x4 inter pred This commit enables iterative motion search for 4x4/4x8/8x4 block size compound inter-inter prediction. WIP: borg run testing Change-Id: I2b318db4a03cdca5a8002b3fa6c0fa89b129288b --- diff --git a/vp9/encoder/vp9_onyx_if.c b/vp9/encoder/vp9_onyx_if.c index b484925..d96d062 100644 --- a/vp9/encoder/vp9_onyx_if.c +++ b/vp9/encoder/vp9_onyx_if.c @@ -775,7 +775,7 @@ void vp9_set_speed_features(VP9_COMP *cpi) { sf->optimize_coefficients = !cpi->oxcf.lossless; sf->first_step = 0; sf->max_step_search_steps = MAX_MVSEARCH_STEPS; - sf->comp_inter_joint_serach = 1; + sf->comp_inter_joint_search = 1; #if CONFIG_MULTIPLE_ARF // Switch segmentation off. sf->static_segmentation = 0; @@ -810,7 +810,7 @@ void vp9_set_speed_features(VP9_COMP *cpi) { /* Disable coefficient optimization above speed 0 */ sf->optimize_coefficients = 0; sf->no_skip_block4x4_search = 0; - sf->comp_inter_joint_serach = 0; + sf->comp_inter_joint_search = 0; sf->first_step = 1; diff --git a/vp9/encoder/vp9_onyx_int.h b/vp9/encoder/vp9_onyx_int.h index 24a2acb..f3dea93 100644 --- a/vp9/encoder/vp9_onyx_int.h +++ b/vp9/encoder/vp9_onyx_int.h @@ -225,7 +225,7 @@ typedef struct { int search_best_filter; int mb16_breakout; int static_segmentation; - int comp_inter_joint_serach; + int comp_inter_joint_search; } SPEED_FEATURES; enum BlockSize { diff --git a/vp9/encoder/vp9_rdopt.c b/vp9/encoder/vp9_rdopt.c index 1026bd6..4ee43d5 100644 --- a/vp9/encoder/vp9_rdopt.c +++ b/vp9/encoder/vp9_rdopt.c @@ -941,7 +941,7 @@ static int labels2mode(MACROBLOCK *x, int i, MB_PREDICTION_MODE this_mode, int_mv *this_mv, int_mv *this_second_mv, int_mv frame_mv[MB_MODE_COUNT][MAX_REF_FRAMES], - int_mv seg_mvs[MAX_REF_FRAMES - 1], + int_mv seg_mvs[MAX_REF_FRAMES], int_mv *best_ref_mv, int_mv *second_best_ref_mv, int *mvjcost, int *mvcost[2], VP9_COMP *cpi) { @@ -962,14 +962,11 @@ static int labels2mode(MACROBLOCK *x, int i, // is when we are on a new label (jbb May 08, 2007) switch (m = this_mode) { case NEWMV: - if (mbmi->second_ref_frame > 0) { - this_mv->as_int = seg_mvs[mbmi->ref_frame - 1].as_int; - this_second_mv->as_int = seg_mvs[mbmi->second_ref_frame - 1].as_int; - } - + this_mv->as_int = seg_mvs[mbmi->ref_frame].as_int; thismvcost = vp9_mv_bit_cost(this_mv, best_ref_mv, mvjcost, mvcost, 102, xd->allow_high_precision_mv); if (mbmi->second_ref_frame > 0) { + this_second_mv->as_int = seg_mvs[mbmi->second_ref_frame].as_int; thismvcost += vp9_mv_bit_cost(this_second_mv, second_best_ref_mv, mvjcost, mvcost, 102, xd->allow_high_precision_mv); @@ -1174,9 +1171,44 @@ static enum BlockSize get_block_size(int bw, int bh) { return -1; } +static INLINE void mi_buf_shift(MACROBLOCK *x, int i) { + MB_MODE_INFO *mbmi = &x->e_mbd.mode_info_context->mbmi; + x->plane[0].src.buf = + raster_block_offset_uint8(&x->e_mbd, BLOCK_SIZE_SB8X8, 0, i, + x->plane[0].src.buf, + x->plane[0].src.stride); + assert(((intptr_t)x->e_mbd.plane[0].pre[0].buf & 0x7) == 0); + x->e_mbd.plane[0].pre[0].buf = + raster_block_offset_uint8(&x->e_mbd, BLOCK_SIZE_SB8X8, 0, i, + x->e_mbd.plane[0].pre[0].buf, + x->e_mbd.plane[0].pre[0].stride); + if (mbmi->second_ref_frame) + x->e_mbd.plane[0].pre[1].buf = + raster_block_offset_uint8(&x->e_mbd, BLOCK_SIZE_SB8X8, 0, i, + x->e_mbd.plane[0].pre[1].buf, + x->e_mbd.plane[0].pre[1].stride); +} + +static INLINE void mi_buf_restore(MACROBLOCK *x, struct buf_2d orig_src, + struct buf_2d orig_pre[2]) { + MB_MODE_INFO *mbmi = &x->e_mbd.mode_info_context->mbmi; + x->plane[0].src = orig_src; + x->e_mbd.plane[0].pre[0] = orig_pre[0]; + if (mbmi->second_ref_frame) + x->e_mbd.plane[0].pre[1] = orig_pre[1]; +} + +static void iterative_motion_search(VP9_COMP *cpi, MACROBLOCK *x, + BLOCK_SIZE_TYPE bsize, + int_mv *frame_mv, + YV12_BUFFER_CONFIG **scaled_ref_frame, + int mi_row, int mi_col, + int_mv single_newmv[MAX_REF_FRAMES]); + static void rd_check_segment_txsize(VP9_COMP *cpi, MACROBLOCK *x, BEST_SEG_INFO *bsi, - int_mv seg_mvs[4][MAX_REF_FRAMES - 1]) { + int_mv seg_mvs[4][MAX_REF_FRAMES], + int mi_row, int mi_col) { int i, j; int br = 0, bd = 0; MB_PREDICTION_MODE this_mode; @@ -1193,7 +1225,7 @@ static void rd_check_segment_txsize(VP9_COMP *cpi, MACROBLOCK *x, int bhl = b_height_log2(bsize), bh = 1 << bhl; int idx, idy; vp9_variance_fn_ptr_t *v_fn_ptr; - + YV12_BUFFER_CONFIG *scaled_ref_frame[2] = {NULL, NULL}; ENTROPY_CONTEXT t_above[4], t_left[4]; ENTROPY_CONTEXT t_above_b[4], t_left_b[4]; @@ -1240,6 +1272,10 @@ static void rd_check_segment_txsize(VP9_COMP *cpi, MACROBLOCK *x, int distortion; int labelyrate; ENTROPY_CONTEXT t_above_s[4], t_left_s[4]; + const struct buf_2d orig_src = x->plane[0].src; + struct buf_2d orig_pre[2]; + + vpx_memcpy(orig_pre, x->e_mbd.plane[0].pre, sizeof(orig_pre)); vpx_memcpy(t_above_s, t_above, sizeof(t_above_s)); vpx_memcpy(t_left_s, t_left, sizeof(t_left_s)); @@ -1249,8 +1285,6 @@ static void rd_check_segment_txsize(VP9_COMP *cpi, MACROBLOCK *x, int step_param = 0; int further_steps; int thissme, bestsme = INT_MAX; - const struct buf_2d orig_src = x->plane[0].src; - const struct buf_2d orig_pre = x->e_mbd.plane[0].pre[0]; int sadpb = x->sadperbit4; int_mv mvp_full; @@ -1276,17 +1310,8 @@ static void rd_check_segment_txsize(VP9_COMP *cpi, MACROBLOCK *x, mvp_full.as_mv.row = bsi->mvp.as_mv.row >> 3; mvp_full.as_mv.col = bsi->mvp.as_mv.col >> 3; - // adjust src pointer for this segment - x->plane[0].src.buf = - raster_block_offset_uint8(&x->e_mbd, BLOCK_SIZE_SB8X8, 0, i, - x->plane[0].src.buf, - x->plane[0].src.stride); - assert(((intptr_t)x->e_mbd.plane[0].pre[0].buf & 0x7) == 0); - x->e_mbd.plane[0].pre[0].buf = - raster_block_offset_uint8(&x->e_mbd, BLOCK_SIZE_SB8X8, 0, i, - x->e_mbd.plane[0].pre[0].buf, - x->e_mbd.plane[0].pre[0].stride); - + // adjust src pointer for this block + mi_buf_shift(x, i); bestsme = vp9_full_pixel_diamond(cpi, x, &mvp_full, step_param, sadpb, further_steps, 0, v_fn_ptr, bsi->ref_mv, &mode_mv[NEWMV]); @@ -1323,16 +1348,29 @@ static void rd_check_segment_txsize(VP9_COMP *cpi, MACROBLOCK *x, &distortion, &sse); // safe motion search result for use in compound prediction - seg_mvs[i][mbmi->ref_frame - 1].as_int = mode_mv[NEWMV].as_int; + seg_mvs[i][mbmi->ref_frame].as_int = mode_mv[NEWMV].as_int; } // restore src pointers - x->plane[0].src = orig_src; - x->e_mbd.plane[0].pre[0] = orig_pre; + mi_buf_restore(x, orig_src, orig_pre); } else if (mbmi->second_ref_frame > 0 && this_mode == NEWMV) { - if (seg_mvs[i][mbmi->second_ref_frame - 1].as_int == INVALID_MV || - seg_mvs[i][mbmi->ref_frame - 1].as_int == INVALID_MV) + if (seg_mvs[i][mbmi->second_ref_frame].as_int == INVALID_MV || + seg_mvs[i][mbmi->ref_frame ].as_int == INVALID_MV) continue; + + // adjust src pointers + mi_buf_shift(x, i); + if (cpi->sf.comp_inter_joint_search) { + iterative_motion_search(cpi, x, bsize, frame_mv[this_mode], + scaled_ref_frame, + mi_row, mi_col, seg_mvs[i]); + seg_mvs[i][mbmi->ref_frame].as_int = + frame_mv[this_mode][mbmi->ref_frame].as_int; + seg_mvs[i][mbmi->second_ref_frame].as_int = + frame_mv[this_mode][mbmi->second_ref_frame].as_int; + } + // restore src pointers + mi_buf_restore(x, orig_src, orig_pre); } rate = labels2mode(x, i, this_mode, &mode_mv[this_mode], @@ -1411,12 +1449,6 @@ static void rd_check_segment_txsize(VP9_COMP *cpi, MACROBLOCK *x, } } -static void rd_check_segment(VP9_COMP *cpi, MACROBLOCK *x, - BEST_SEG_INFO *bsi, - int_mv seg_mvs[4][MAX_REF_FRAMES - 1]) { - rd_check_segment_txsize(cpi, x, bsi, seg_mvs); -} - static int rd_pick_best_mbsegmentation(VP9_COMP *cpi, MACROBLOCK *x, int_mv *best_ref_mv, int_mv *second_best_ref_mv, @@ -1425,7 +1457,8 @@ static int rd_pick_best_mbsegmentation(VP9_COMP *cpi, MACROBLOCK *x, int *returnyrate, int *returndistortion, int *skippable, int mvthresh, - int_mv seg_mvs[4][MAX_REF_FRAMES - 1]) { + int_mv seg_mvs[4][MAX_REF_FRAMES], + int mi_row, int mi_col) { int i; BEST_SEG_INFO bsi; MB_MODE_INFO * mbmi = &x->e_mbd.mode_info_context->mbmi; @@ -1441,7 +1474,7 @@ static int rd_pick_best_mbsegmentation(VP9_COMP *cpi, MACROBLOCK *x, for (i = 0; i < 4; i++) bsi.modes[i] = ZEROMV; - rd_check_segment(cpi, x, &bsi, seg_mvs); + rd_check_segment_txsize(cpi, x, &bsi, seg_mvs, mi_row, mi_col); /* set it to the best */ for (i = 0; i < 4; i++) { @@ -2044,7 +2077,7 @@ static int64_t handle_inter_mode(VP9_COMP *cpi, MACROBLOCK *x, frame_mv[refs[0]].as_int = single_newmv[refs[0]].as_int; frame_mv[refs[1]].as_int = single_newmv[refs[1]].as_int; - if (cpi->sf.comp_inter_joint_serach) + if (cpi->sf.comp_inter_joint_search) iterative_motion_search(cpi, x, bsize, frame_mv, scaled_ref_frame, mi_row, mi_col, single_newmv); @@ -2444,14 +2477,14 @@ int64_t vp9_rd_pick_inter_mode_sb(VP9_COMP *cpi, MACROBLOCK *x, int64_t frame_distortions[MAX_REF_FRAMES] = {-1}; int intra_cost_penalty = 20 * vp9_dc_quant(cpi->common.base_qindex, cpi->common.y_dc_delta_q); - int_mv seg_mvs[4][MAX_REF_FRAMES - 1]; + int_mv seg_mvs[4][MAX_REF_FRAMES]; union b_mode_info best_bmodes[4]; PARTITION_INFO best_partition; for (i = 0; i < 4; i++) { int j; - for (j = 0; j < MAX_REF_FRAMES - 1; j++) + for (j = 0; j < MAX_REF_FRAMES; j++) seg_mvs[i][j].as_int = INVALID_MV; } // Everywhere the flag is set the error is much higher than its neighbors. @@ -2740,7 +2773,8 @@ int64_t vp9_rd_pick_inter_mode_sb(VP9_COMP *cpi, MACROBLOCK *x, second_ref, INT64_MAX, &rate, &rate_y, &distortion, &skippable, - (int)this_rd_thresh, seg_mvs); + (int)this_rd_thresh, seg_mvs, + mi_row, mi_col); if (cpi->common.mcomp_filter_type == SWITCHABLE) { const int rs = get_switchable_rate(cm, x); tmp_rd += RDCOST(x->rdmult, x->rddiv, rs, 0); @@ -2779,7 +2813,8 @@ int64_t vp9_rd_pick_inter_mode_sb(VP9_COMP *cpi, MACROBLOCK *x, second_ref, INT64_MAX, &rate, &rate_y, &distortion, &skippable, - (int)this_rd_thresh, seg_mvs); + (int)this_rd_thresh, seg_mvs, + mi_row, mi_col); } else { if (cpi->common.mcomp_filter_type == SWITCHABLE) { int rs = get_switchable_rate(cm, x);