From: Yunqing Wang Date: Wed, 14 Dec 2011 20:35:04 +0000 (-0500) Subject: Only call vp8_find_near_mvs() once for each macroblock X-Git-Tag: v1.0.0~50^2 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=e06c242baa46ead2fb3d9801b5197ee199f8c60d;p=platform%2Fupstream%2Flibvpx.git Only call vp8_find_near_mvs() once for each macroblock While doing motion search on a macroblock, we usually call vp8_find_near_mvs once per reference frame. Actually, for different reference frames, the only difference in calculating these near_mvs is they may have different sign_bias, which causes a sign change in resulting near_mvs. In this change, we only do find_near_mvs for the first reference frame. For other reference frames, only need to adjust the near_mvs according to that reference frame's sign_bias value. Change-Id: I661394b49c6ad79fed7d0f2eb2be239b9c56f149 --- diff --git a/vp8/encoder/pickinter.c b/vp8/encoder/pickinter.c index d9c8975..0537d66 100644 --- a/vp8/encoder/pickinter.c +++ b/vp8/encoder/pickinter.c @@ -432,23 +432,16 @@ void vp8_pick_inter_mode(VP8_COMP *cpi, MACROBLOCK *x, int recon_yoffset, int saddone=0; int sr=0; //search range got from mv_pred(). It uses step_param levels. (0-7) - int_mv nearest_mv[4]; - int_mv near_mv[4]; - int_mv frame_best_ref_mv[4]; - int MDCounts[4][4]; unsigned char *y_buffer[4]; unsigned char *u_buffer[4]; unsigned char *v_buffer[4]; int i; int ref_frame_map[4]; - - int found_near_mvs[4] = {0, 0, 0, 0}; + int sign_bias = 0; int have_subp_search = cpi->sf.half_pixel_search; /* In real-time mode, when Speed >= 15, no sub-pixel search. */ vpx_memset(mode_mv, 0, sizeof(mode_mv)); - vpx_memset(nearest_mv, 0, sizeof(nearest_mv)); - vpx_memset(near_mv, 0, sizeof(near_mv)); vpx_memset(&best_mbmode, 0, sizeof(best_mbmode)); /* Setup search priorities */ @@ -463,6 +456,22 @@ void vp8_pick_inter_mode(VP8_COMP *cpi, MACROBLOCK *x, int recon_yoffset, for(; i<4; i++) ref_frame_map[i] = -1; + /* Check to see if there is at least 1 valid reference frame that we need + * to calculate near_mvs. + */ + if (ref_frame_map[1] > 0) + { + vp8_find_near_mvs(&x->e_mbd, + x->e_mbd.mode_info_context, + &mode_mv[NEARESTMV], &mode_mv[NEARMV], + &best_ref_mv, + mdcounts, + ref_frame_map[1], + cpi->common.ref_frame_sign_bias); + + sign_bias = cpi->common.ref_frame_sign_bias[ref_frame_map[1]]; + } + // set up all the refframe dependent pointers. if (cpi->ref_frame_flags & VP8_LAST_FLAG) { @@ -531,21 +540,6 @@ void vp8_pick_inter_mode(VP8_COMP *cpi, MACROBLOCK *x, int recon_yoffset, } } - // If nearby MVs haven't been found for this reference frame then do it now. - if (x->e_mbd.mode_info_context->mbmi.ref_frame != INTRA_FRAME && - !found_near_mvs[x->e_mbd.mode_info_context->mbmi.ref_frame]) - { - int ref_frame = x->e_mbd.mode_info_context->mbmi.ref_frame; - vp8_find_near_mvs(&x->e_mbd, - x->e_mbd.mode_info_context, - &nearest_mv[ref_frame], &near_mv[ref_frame], - &frame_best_ref_mv[ref_frame], - MDCounts[ref_frame], - ref_frame, - cpi->common.ref_frame_sign_bias); - found_near_mvs[ref_frame] = 1; - } - // We have now reached the point where we are going to test the current mode so increment the counter for the number of times it has been tested cpi->mode_test_hit_counts[mode_index] ++; @@ -571,10 +565,19 @@ void vp8_pick_inter_mode(VP8_COMP *cpi, MACROBLOCK *x, int recon_yoffset, x->e_mbd.pre.y_buffer = y_buffer[x->e_mbd.mode_info_context->mbmi.ref_frame]; x->e_mbd.pre.u_buffer = u_buffer[x->e_mbd.mode_info_context->mbmi.ref_frame]; x->e_mbd.pre.v_buffer = v_buffer[x->e_mbd.mode_info_context->mbmi.ref_frame]; - mode_mv[NEARESTMV] = nearest_mv[x->e_mbd.mode_info_context->mbmi.ref_frame]; - mode_mv[NEARMV] = near_mv[x->e_mbd.mode_info_context->mbmi.ref_frame]; - best_ref_mv = frame_best_ref_mv[x->e_mbd.mode_info_context->mbmi.ref_frame]; - memcpy(mdcounts, MDCounts[x->e_mbd.mode_info_context->mbmi.ref_frame], sizeof(mdcounts)); + + if (sign_bias != + cpi->common.ref_frame_sign_bias[x->e_mbd.mode_info_context->mbmi.ref_frame]) + { + mode_mv[NEARESTMV].as_mv.row *= -1; + mode_mv[NEARESTMV].as_mv.col *= -1; + mode_mv[NEARMV].as_mv.row *= -1; + mode_mv[NEARMV].as_mv.col *= -1; + best_ref_mv.as_mv.row *= -1; + best_ref_mv.as_mv.col *= -1; + sign_bias + = cpi->common.ref_frame_sign_bias[x->e_mbd.mode_info_context->mbmi.ref_frame]; + } } // Only consider ZEROMV/ALTREF_FRAME for alt ref frame, @@ -910,7 +913,14 @@ void vp8_pick_inter_mode(VP8_COMP *cpi, MACROBLOCK *x, int recon_yoffset, pick_intra_mbuv_mode(x); } - update_mvcount(cpi, &x->e_mbd, &frame_best_ref_mv[xd->mode_info_context->mbmi.ref_frame]); + if (sign_bias + != cpi->common.ref_frame_sign_bias[xd->mode_info_context->mbmi.ref_frame]) + { + best_ref_mv.as_mv.row *= -1; + best_ref_mv.as_mv.col *= -1; + } + + update_mvcount(cpi, &x->e_mbd, &best_ref_mv); } diff --git a/vp8/encoder/rdopt.c b/vp8/encoder/rdopt.c index 4f9a0ce..79fe63c 100644 --- a/vp8/encoder/rdopt.c +++ b/vp8/encoder/rdopt.c @@ -1716,7 +1716,9 @@ static void rd_update_mvcount(VP8_COMP *cpi, MACROBLOCK *x, int_mv *best_ref_mv) } } -void vp8_rd_pick_inter_mode(VP8_COMP *cpi, MACROBLOCK *x, int recon_yoffset, int recon_uvoffset, int *returnrate, int *returndistortion, int *returnintra) +void vp8_rd_pick_inter_mode(VP8_COMP *cpi, MACROBLOCK *x, int recon_yoffset, + int recon_uvoffset, int *returnrate, + int *returndistortion, int *returnintra) { BLOCK *b = &x->block[0]; BLOCKD *d = &x->e_mbd.block[0]; @@ -1743,27 +1745,20 @@ void vp8_rd_pick_inter_mode(VP8_COMP *cpi, MACROBLOCK *x, int recon_yoffset, int int distortion_uv; int best_yrd = INT_MAX; - //int all_rds[MAX_MODES]; // Experimental debug code. - //int all_rates[MAX_MODES]; - //int all_dist[MAX_MODES]; - //int intermodecost[MAX_MODES]; - MB_PREDICTION_MODE uv_intra_mode; int_mv mvp; int near_sadidx[8] = {0, 1, 2, 3, 4, 5, 6, 7}; int saddone=0; int sr=0; //search range got from mv_pred(). It uses step_param levels. (0-7) - int_mv frame_nearest_mv[4]; - int_mv frame_near_mv[4]; - int_mv frame_best_ref_mv[4]; - int frame_mdcounts[4][4]; int frame_lf_or_gf[4]; unsigned char *y_buffer[4]; unsigned char *u_buffer[4]; unsigned char *v_buffer[4]; int ref_frame_map[4]; + int sign_bias = 0; + vpx_memset(mode_mv, 0, sizeof(mode_mv)); vpx_memset(&best_mbmode, 0, sizeof(best_mbmode)); vpx_memset(&best_bmodes, 0, sizeof(best_bmodes)); @@ -1779,17 +1774,29 @@ void vp8_rd_pick_inter_mode(VP8_COMP *cpi, MACROBLOCK *x, int recon_yoffset, int for(; i<4; i++) ref_frame_map[i] = -1; + /* Check to see if there is at least 1 valid reference frame that we need + * to calculate near_mvs. + */ + if (ref_frame_map[1] > 0) + { + vp8_find_near_mvs(&x->e_mbd, + x->e_mbd.mode_info_context, + &mode_mv[NEARESTMV], &mode_mv[NEARMV], + &best_ref_mv, + mdcounts, + ref_frame_map[1], + cpi->common.ref_frame_sign_bias); + + sign_bias = cpi->common.ref_frame_sign_bias[ref_frame_map[1]]; + } + if (cpi->ref_frame_flags & VP8_LAST_FLAG) { YV12_BUFFER_CONFIG *lst_yv12 = &cpi->common.yv12_fb[cpi->common.lst_fb_idx]; - vp8_find_near_mvs(&x->e_mbd, x->e_mbd.mode_info_context, &frame_nearest_mv[LAST_FRAME], &frame_near_mv[LAST_FRAME], - &frame_best_ref_mv[LAST_FRAME], frame_mdcounts[LAST_FRAME], LAST_FRAME, cpi->common.ref_frame_sign_bias); - y_buffer[LAST_FRAME] = lst_yv12->y_buffer + recon_yoffset; u_buffer[LAST_FRAME] = lst_yv12->u_buffer + recon_uvoffset; v_buffer[LAST_FRAME] = lst_yv12->v_buffer + recon_uvoffset; - frame_lf_or_gf[LAST_FRAME] = 0; } @@ -1797,13 +1804,9 @@ void vp8_rd_pick_inter_mode(VP8_COMP *cpi, MACROBLOCK *x, int recon_yoffset, int { YV12_BUFFER_CONFIG *gld_yv12 = &cpi->common.yv12_fb[cpi->common.gld_fb_idx]; - vp8_find_near_mvs(&x->e_mbd, x->e_mbd.mode_info_context, &frame_nearest_mv[GOLDEN_FRAME], &frame_near_mv[GOLDEN_FRAME], - &frame_best_ref_mv[GOLDEN_FRAME], frame_mdcounts[GOLDEN_FRAME], GOLDEN_FRAME, cpi->common.ref_frame_sign_bias); - y_buffer[GOLDEN_FRAME] = gld_yv12->y_buffer + recon_yoffset; u_buffer[GOLDEN_FRAME] = gld_yv12->u_buffer + recon_uvoffset; v_buffer[GOLDEN_FRAME] = gld_yv12->v_buffer + recon_uvoffset; - frame_lf_or_gf[GOLDEN_FRAME] = 1; } @@ -1811,13 +1814,9 @@ void vp8_rd_pick_inter_mode(VP8_COMP *cpi, MACROBLOCK *x, int recon_yoffset, int { YV12_BUFFER_CONFIG *alt_yv12 = &cpi->common.yv12_fb[cpi->common.alt_fb_idx]; - vp8_find_near_mvs(&x->e_mbd, x->e_mbd.mode_info_context, &frame_nearest_mv[ALTREF_FRAME], &frame_near_mv[ALTREF_FRAME], - &frame_best_ref_mv[ALTREF_FRAME], frame_mdcounts[ALTREF_FRAME], ALTREF_FRAME, cpi->common.ref_frame_sign_bias); - y_buffer[ALTREF_FRAME] = alt_yv12->y_buffer + recon_yoffset; u_buffer[ALTREF_FRAME] = alt_yv12->u_buffer + recon_uvoffset; v_buffer[ALTREF_FRAME] = alt_yv12->v_buffer + recon_uvoffset; - frame_lf_or_gf[ALTREF_FRAME] = 1; } @@ -1826,8 +1825,6 @@ void vp8_rd_pick_inter_mode(VP8_COMP *cpi, MACROBLOCK *x, int recon_yoffset, int x->skip = 0; - vpx_memset(mode_mv, 0, sizeof(mode_mv)); - x->e_mbd.mode_info_context->mbmi.ref_frame = INTRA_FRAME; rd_pick_intra_mbuv_mode(cpi, x, &uv_intra_rate, &uv_intra_rate_tokenonly, &uv_intra_distortion); uv_intra_mode = x->e_mbd.mode_info_context->mbmi.uv_mode; @@ -1840,13 +1837,6 @@ void vp8_rd_pick_inter_mode(VP8_COMP *cpi, MACROBLOCK *x, int recon_yoffset, int int other_cost = 0; int this_ref_frame = ref_frame_map[vp8_ref_frame_order[mode_index]]; - // Experimental debug code. - // Record of rd values recorded for this MB. -1 indicates not measured - //all_rds[mode_index] = -1; - //all_rates[mode_index] = -1; - //all_dist[mode_index] = -1; - //intermodecost[mode_index] = -1; - // Test best rd so far against threshold for trying this mode. if (best_rd <= cpi->rd_threshes[mode_index]) continue; @@ -1879,10 +1869,20 @@ void vp8_rd_pick_inter_mode(VP8_COMP *cpi, MACROBLOCK *x, int recon_yoffset, int x->e_mbd.pre.y_buffer = y_buffer[x->e_mbd.mode_info_context->mbmi.ref_frame]; x->e_mbd.pre.u_buffer = u_buffer[x->e_mbd.mode_info_context->mbmi.ref_frame]; x->e_mbd.pre.v_buffer = v_buffer[x->e_mbd.mode_info_context->mbmi.ref_frame]; - mode_mv[NEARESTMV] = frame_nearest_mv[x->e_mbd.mode_info_context->mbmi.ref_frame]; - mode_mv[NEARMV] = frame_near_mv[x->e_mbd.mode_info_context->mbmi.ref_frame]; - best_ref_mv = frame_best_ref_mv[x->e_mbd.mode_info_context->mbmi.ref_frame]; - vpx_memcpy(mdcounts, frame_mdcounts[x->e_mbd.mode_info_context->mbmi.ref_frame], sizeof(mdcounts)); + + if (sign_bias != + cpi->common.ref_frame_sign_bias[x->e_mbd.mode_info_context->mbmi.ref_frame]) + { + mode_mv[NEARESTMV].as_mv.row *= -1; + mode_mv[NEARESTMV].as_mv.col *= -1; + mode_mv[NEARMV].as_mv.row *= -1; + mode_mv[NEARMV].as_mv.col *= -1; + best_ref_mv.as_mv.row *= -1; + best_ref_mv.as_mv.col *= -1; + sign_bias + = cpi->common.ref_frame_sign_bias[x->e_mbd.mode_info_context->mbmi.ref_frame]; + } + lf_or_gf = frame_lf_or_gf[x->e_mbd.mode_info_context->mbmi.ref_frame]; } @@ -2286,11 +2286,6 @@ void vp8_rd_pick_inter_mode(VP8_COMP *cpi, MACROBLOCK *x, int recon_yoffset, int this_rd = RDCOST(x->rdmult, x->rddiv, rate2, distortion2); } - // Experimental debug code. - //all_rds[mode_index] = this_rd; - //all_rates[mode_index] = rate2; - //all_dist[mode_index] = distortion2; - // Keep record of best intra distortion if ((x->e_mbd.mode_info_context->mbmi.ref_frame == INTRA_FRAME) && (this_rd < best_intra_rd) ) @@ -2418,10 +2413,14 @@ void vp8_rd_pick_inter_mode(VP8_COMP *cpi, MACROBLOCK *x, int recon_yoffset, int x->partition_info->bmi[15].mv.as_int; } - rd_update_mvcount(cpi, x, &frame_best_ref_mv[xd->mode_info_context->mbmi.ref_frame]); - - + if (sign_bias + != cpi->common.ref_frame_sign_bias[xd->mode_info_context->mbmi.ref_frame]) + { + best_ref_mv.as_mv.row *= -1; + best_ref_mv.as_mv.col *= -1; + } + rd_update_mvcount(cpi, x, &best_ref_mv); } void vp8_rd_pick_intra_mode(VP8_COMP *cpi, MACROBLOCK *x, int *rate_)