From: Yunqing Wang Date: Tue, 25 Jan 2011 20:54:34 +0000 (-0500) Subject: Refine motion vector prediction for NEWMV mode X-Git-Tag: 1.0_branch~698^2 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=dcaaadd8edd543c1033915556be62576ff37bf59;p=profile%2Fivi%2Flibvpx.git Refine motion vector prediction for NEWMV mode Adjust checking points in motion vector prediction to better cover possible movements, and get a better prediction. Tests on test clips showed a 0.1% improvement in SSIM, and no change in PSNR and performance. Change-Id: Ifdab05d35e10faea1445c61bb73debf888c9d2f8 --- diff --git a/vp8/encoder/onyx_if.c b/vp8/encoder/onyx_if.c index 9007853..5aa2224 100644 --- a/vp8/encoder/onyx_if.c +++ b/vp8/encoder/onyx_if.c @@ -2224,9 +2224,9 @@ VP8_PTR vp8_create_compressor(VP8_CONFIG *oxcf) cpi->gold_is_alt = 0 ; // allocate memory for storing last frame's MVs for MV prediction. - CHECK_MEM_ERROR(cpi->lfmv, vpx_calloc((cpi->common.mb_rows+1) * (cpi->common.mb_cols+1), sizeof(int_mv))); - CHECK_MEM_ERROR(cpi->lf_ref_frame_sign_bias, vpx_calloc((cpi->common.mb_rows+1) * (cpi->common.mb_cols+1), sizeof(int))); - CHECK_MEM_ERROR(cpi->lf_ref_frame, vpx_calloc((cpi->common.mb_rows+1) * (cpi->common.mb_cols+1), sizeof(int))); + CHECK_MEM_ERROR(cpi->lfmv, vpx_calloc((cpi->common.mb_rows+2) * (cpi->common.mb_cols+2), sizeof(int_mv))); + CHECK_MEM_ERROR(cpi->lf_ref_frame_sign_bias, vpx_calloc((cpi->common.mb_rows+2) * (cpi->common.mb_cols+2), sizeof(int))); + CHECK_MEM_ERROR(cpi->lf_ref_frame, vpx_calloc((cpi->common.mb_rows+2) * (cpi->common.mb_cols+2), sizeof(int))); // Create the encoder segmentation map and set all entries to 0 CHECK_MEM_ERROR(cpi->segmentation_map, vpx_calloc(cpi->common.mb_rows * cpi->common.mb_cols, 1)); @@ -4386,30 +4386,31 @@ static void encode_frame_to_data_rate } // This frame's MVs are saved and will be used in next frame's MV prediction. + // Last frame has one more line(add to bottom) and one more column(add to right) than cm->mip. The edge elements are initialized to 0. if(cm->show_frame) //do not save for altref frame { - int mb_row; - int mb_col; - MODE_INFO *tmp = cm->mip; //point to beginning of allocated MODE_INFO arrays. - //static int last_video_frame = 0; + int mb_row; + int mb_col; + MODE_INFO *tmp = cm->mip; //point to beginning of allocated MODE_INFO arrays. - if(cm->frame_type != KEY_FRAME) - { - for (mb_row = 0; mb_row < cm->mb_rows+1; mb_row ++) + if(cm->frame_type != KEY_FRAME) { - for (mb_col = 0; mb_col < cm->mb_cols+1; mb_col ++) - { - if(tmp->mbmi.ref_frame != INTRA_FRAME) - cpi->lfmv[mb_col + mb_row*(cm->mode_info_stride)].as_int = tmp->mbmi.mv.as_int; - - cpi->lf_ref_frame_sign_bias[mb_col + mb_row*(cm->mode_info_stride)] = cm->ref_frame_sign_bias[tmp->mbmi.ref_frame]; - cpi->lf_ref_frame[mb_col + mb_row*(cm->mode_info_stride)] = tmp->mbmi.ref_frame; - tmp++; - } + for (mb_row = 0; mb_row < cm->mb_rows+1; mb_row ++) + { + for (mb_col = 0; mb_col < cm->mb_cols+1; mb_col ++) + { + if(tmp->mbmi.ref_frame != INTRA_FRAME) + cpi->lfmv[mb_col + mb_row*(cm->mode_info_stride+1)].as_int = tmp->mbmi.mv.as_int; + + cpi->lf_ref_frame_sign_bias[mb_col + mb_row*(cm->mode_info_stride+1)] = cm->ref_frame_sign_bias[tmp->mbmi.ref_frame]; + cpi->lf_ref_frame[mb_col + mb_row*(cm->mode_info_stride+1)] = tmp->mbmi.ref_frame; + tmp++; + } + } } - } } + // Update the GF useage maps. // This is done after completing the compression of a frame when all modes etc. are finalized but before loop filter vp8_update_gf_useage_maps(cpi, cm, &cpi->mb); diff --git a/vp8/encoder/rdopt.c b/vp8/encoder/rdopt.c index b2a3e11..f04a746 100644 --- a/vp8/encoder/rdopt.c +++ b/vp8/encoder/rdopt.c @@ -1561,23 +1561,23 @@ static void vp8_mv_pred const MODE_INFO *above = here - xd->mode_info_stride; const MODE_INFO *left = here - 1; const MODE_INFO *aboveleft = above - 1; - int_mv near_mvs[7]; - int near_ref[7]; + int_mv near_mvs[8]; + int near_ref[8]; int_mv mv; int vcnt=0; int find=0; int mb_offset; - int mvx[7]; - int mvy[7]; + int mvx[8]; + int mvy[8]; int i; mv.as_int = 0; if(here->mbmi.ref_frame != INTRA_FRAME) { - near_mvs[0].as_int = near_mvs[1].as_int = near_mvs[2].as_int = near_mvs[3].as_int = near_mvs[4].as_int = near_mvs[5].as_int = near_mvs[6].as_int = 0; - near_ref[0] = near_ref[1] = near_ref[2] = near_ref[3] = near_ref[4] = near_ref[5] = near_ref[6] = 0; + near_mvs[0].as_int = near_mvs[1].as_int = near_mvs[2].as_int = near_mvs[3].as_int = near_mvs[4].as_int = near_mvs[5].as_int = near_mvs[6].as_int = near_mvs[7].as_int = 0; + near_ref[0] = near_ref[1] = near_ref[2] = near_ref[3] = near_ref[4] = near_ref[5] = near_ref[6] = near_ref[7] = 0; // read in 3 nearby block's MVs from current frame as prediction candidates. if (above->mbmi.ref_frame != INTRA_FRAME) @@ -1602,10 +1602,10 @@ static void vp8_mv_pred } vcnt++; - // read in 4 nearby block's MVs from last frame. + // read in 5 nearby block's MVs from last frame. if(cpi->common.last_frame_type != KEY_FRAME) { - mb_offset = (-xd->mb_to_top_edge/128 + 1) * (xd->mode_info_stride) + (-xd->mb_to_left_edge/128 +1) ; + mb_offset = (-xd->mb_to_top_edge/128 + 1) * (xd->mode_info_stride +1) + (-xd->mb_to_left_edge/128 +1) ; // current in last frame if (cpi->lf_ref_frame[mb_offset] != INTRA_FRAME) @@ -1617,11 +1617,11 @@ static void vp8_mv_pred vcnt++; // above in last frame - if (cpi->lf_ref_frame[mb_offset - xd->mode_info_stride] != INTRA_FRAME) + if (cpi->lf_ref_frame[mb_offset - xd->mode_info_stride-1] != INTRA_FRAME) { - near_mvs[vcnt].as_int = cpi->lfmv[mb_offset - xd->mode_info_stride].as_int; - lf_mv_bias(cpi->lf_ref_frame_sign_bias[mb_offset - xd->mode_info_stride], refframe, &near_mvs[vcnt], ref_frame_sign_bias); - near_ref[vcnt] = cpi->lf_ref_frame[mb_offset - xd->mode_info_stride]; + near_mvs[vcnt].as_int = cpi->lfmv[mb_offset - xd->mode_info_stride-1].as_int; + lf_mv_bias(cpi->lf_ref_frame_sign_bias[mb_offset - xd->mode_info_stride-1], refframe, &near_mvs[vcnt], ref_frame_sign_bias); + near_ref[vcnt] = cpi->lf_ref_frame[mb_offset - xd->mode_info_stride-1]; } vcnt++; @@ -1634,12 +1634,21 @@ static void vp8_mv_pred } vcnt++; - // aboveleft in last frame - if (cpi->lf_ref_frame[mb_offset - xd->mode_info_stride -1] != INTRA_FRAME) + // right in last frame + if (cpi->lf_ref_frame[mb_offset +1] != INTRA_FRAME) { - near_mvs[vcnt].as_int = cpi->lfmv[mb_offset - xd->mode_info_stride -1].as_int; - lf_mv_bias(cpi->lf_ref_frame_sign_bias[mb_offset - xd->mode_info_stride -1], refframe, &near_mvs[vcnt], ref_frame_sign_bias); - near_ref[vcnt] = cpi->lf_ref_frame[mb_offset - xd->mode_info_stride -1]; + near_mvs[vcnt].as_int = cpi->lfmv[mb_offset +1].as_int; + lf_mv_bias(cpi->lf_ref_frame_sign_bias[mb_offset +1], refframe, &near_mvs[vcnt], ref_frame_sign_bias); + near_ref[vcnt] = cpi->lf_ref_frame[mb_offset +1]; + } + vcnt++; + + // below in last frame + if (cpi->lf_ref_frame[mb_offset + xd->mode_info_stride +1] != INTRA_FRAME) + { + near_mvs[vcnt].as_int = cpi->lfmv[mb_offset + xd->mode_info_stride +1].as_int; + lf_mv_bias(cpi->lf_ref_frame_sign_bias[mb_offset + xd->mode_info_stride +1], refframe, &near_mvs[vcnt], ref_frame_sign_bias); + near_ref[vcnt] = cpi->lf_ref_frame[mb_offset + xd->mode_info_stride +1]; } vcnt++; } @@ -1652,9 +1661,7 @@ static void vp8_mv_pred { mv.as_int = near_mvs[near_sadidx[i]].as_int; find = 1; - if(vcnt<2) - *sr = 4; - else if (vcnt<4) + if (i < 3) *sr = 3; else *sr = 2; @@ -1724,8 +1731,8 @@ int vp8_rd_pick_inter_mode(VP8_COMP *cpi, MACROBLOCK *x, int recon_yoffset, int int force_no_skip = 0; MV mvp; - int near_sad[7]; // 0-cf above, 1-cf left, 2-cf aboveleft, 3-lf current, 4-lf above, 5-lf left, 6-lf aboveleft - int near_sadidx[7] = {0, 1, 2, 3, 4, 5, 6}; + int near_sad[8] = {0}; // 0-cf above, 1-cf left, 2-cf aboveleft, 3-lf current, 4-lf above, 5-lf left, 6-lf right, 7-lf below + 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) @@ -1897,36 +1904,29 @@ int vp8_rd_pick_inter_mode(VP8_COMP *cpi, MACROBLOCK *x, int recon_yoffset, int if(cpi->common.last_frame_type != KEY_FRAME) { - //calculate sad for last frame 4 nearby MBs. + //calculate sad for last frame 5 nearby MBs. unsigned char *pre_y_buffer = cpi->common.yv12_fb[cpi->common.lst_fb_idx].y_buffer + recon_yoffset; int pre_y_stride = cpi->common.yv12_fb[cpi->common.lst_fb_idx].y_stride; - if( xd->mb_to_top_edge==0 && xd->mb_to_left_edge ==0) - { - near_sad[4] = near_sad[5] = near_sad[6] = INT_MAX; - near_sad[3] = cpi->fn_ptr[BLOCK_16X16].sdf(x->src.y_buffer, x->src.y_stride, pre_y_buffer, pre_y_stride, 0x7fffffff); - }else if(xd->mb_to_top_edge==0) - { //only has left MB for sad calculation. - near_sad[4] = near_sad[6] = INT_MAX; - near_sad[3] = cpi->fn_ptr[BLOCK_16X16].sdf(x->src.y_buffer, x->src.y_stride, pre_y_buffer, pre_y_stride, 0x7fffffff); - near_sad[5] = cpi->fn_ptr[BLOCK_16X16].sdf(x->src.y_buffer, x->src.y_stride, pre_y_buffer - 16, pre_y_stride, 0x7fffffff); - }else if(xd->mb_to_left_edge ==0) - { //only has left MB for sad calculation. - near_sad[5] = near_sad[6] = INT_MAX; - near_sad[3] = cpi->fn_ptr[BLOCK_16X16].sdf(x->src.y_buffer, x->src.y_stride, pre_y_buffer, pre_y_stride, 0x7fffffff); - near_sad[4] = cpi->fn_ptr[BLOCK_16X16].sdf(x->src.y_buffer, x->src.y_stride, pre_y_buffer - pre_y_stride *16, pre_y_stride, 0x7fffffff); - }else - { - near_sad[3] = cpi->fn_ptr[BLOCK_16X16].sdf(x->src.y_buffer, x->src.y_stride, pre_y_buffer, pre_y_stride, 0x7fffffff); + if(xd->mb_to_top_edge==0) near_sad[4] = INT_MAX; + if(xd->mb_to_left_edge ==0) near_sad[5] = INT_MAX; + if(xd->mb_to_right_edge ==0) near_sad[6] = INT_MAX; + if(xd->mb_to_bottom_edge==0) near_sad[7] = INT_MAX; + + if(near_sad[4] != INT_MAX) near_sad[4] = cpi->fn_ptr[BLOCK_16X16].sdf(x->src.y_buffer, x->src.y_stride, pre_y_buffer - pre_y_stride *16, pre_y_stride, 0x7fffffff); + if(near_sad[5] != INT_MAX) near_sad[5] = cpi->fn_ptr[BLOCK_16X16].sdf(x->src.y_buffer, x->src.y_stride, pre_y_buffer - 16, pre_y_stride, 0x7fffffff); - near_sad[6] = cpi->fn_ptr[BLOCK_16X16].sdf(x->src.y_buffer, x->src.y_stride, pre_y_buffer - pre_y_stride *16 -16, pre_y_stride, 0x7fffffff); - } + near_sad[3] = cpi->fn_ptr[BLOCK_16X16].sdf(x->src.y_buffer, x->src.y_stride, pre_y_buffer, pre_y_stride, 0x7fffffff); + if(near_sad[6] != INT_MAX) + near_sad[6] = cpi->fn_ptr[BLOCK_16X16].sdf(x->src.y_buffer, x->src.y_stride, pre_y_buffer + 16, pre_y_stride, 0x7fffffff); + if(near_sad[7] != INT_MAX) + near_sad[7] = cpi->fn_ptr[BLOCK_16X16].sdf(x->src.y_buffer, x->src.y_stride, pre_y_buffer + pre_y_stride *16, pre_y_stride, 0x7fffffff); } if(cpi->common.last_frame_type != KEY_FRAME) { - quicksortsad(near_sad, near_sadidx, 0, 6); + quicksortsad(near_sad, near_sadidx, 0, 7); }else { quicksortsad(near_sad, near_sadidx, 0, 2);