diff options
Diffstat (limited to 'vp8/common')
-rw-r--r-- | vp8/common/blockd.h | 20 | ||||
-rw-r--r-- | vp8/common/findnearmv.c | 112 | ||||
-rw-r--r-- | vp8/common/findnearmv.h | 1 | ||||
-rw-r--r-- | vp8/common/mvref_common.c | 146 | ||||
-rw-r--r-- | vp8/common/mvref_common.h | 6 |
5 files changed, 109 insertions, 176 deletions
diff --git a/vp8/common/blockd.h b/vp8/common/blockd.h index a77ce8709..facbebb31 100644 --- a/vp8/common/blockd.h +++ b/vp8/common/blockd.h @@ -44,8 +44,8 @@ void vpx_log(const char *format, ...); /* Segment Feature Masks */ #define SEGMENT_DELTADATA 0 #define SEGMENT_ABSDATA 1 -#if CONFIG_NEW_MVREF -#define MAX_MV_REFS 10 +#if CONFIG_NEWBESTREFMV || CONFIG_NEW_MVREF +#define MAX_MV_REFS 19 #endif typedef struct { @@ -186,14 +186,6 @@ typedef enum { B_MODE_COUNT } B_PREDICTION_MODE; -#if CONFIG_NEW_MVREF -// Segment level features. -typedef enum { - FIRST_REF = 0, - SECOND_REF = 1 -} MV_REF_TYPE; -#endif - #if CONFIG_HYBRIDTRANSFORM8X8 || CONFIG_HYBRIDTRANSFORM16X16 // convert MB_PREDICTION_MODE to B_PREDICTION_MODE static B_PREDICTION_MODE pred_mode_conv(MB_PREDICTION_MODE mode) { @@ -283,10 +275,8 @@ typedef struct { MV_REFERENCE_FRAME ref_frame, second_ref_frame; TX_SIZE txfm_size; int_mv mv[2]; // for each reference frame used -#if CONFIG_NEWBESTREFMV || CONFIG_NEW_MVREF +#if CONFIG_NEWBESTREFMV int_mv ref_mv, second_ref_mv; -#endif -#if CONFIG_NEW_MVREF int_mv ref_mvs[MAX_REF_FRAMES][MAX_MV_REFS]; int mv_ref_index[MAX_REF_FRAMES]; #endif @@ -454,11 +444,7 @@ typedef struct MacroBlockD { int mb_index; // Index of the MB in the SB (0..3) #if CONFIG_NEWBESTREFMV -#if CONFIG_NEW_MVREF int_mv ref_mv[MAX_MV_REFS]; -#else - int_mv ref_mv[4]; -#endif #endif #if CONFIG_HYBRIDTRANSFORM || CONFIG_HYBRIDTRANSFORM8X8 || CONFIG_HYBRIDTRANSFORM16X16 diff --git a/vp8/common/findnearmv.c b/vp8/common/findnearmv.c index 694f4cc32..3363d46ca 100644 --- a/vp8/common/findnearmv.c +++ b/vp8/common/findnearmv.c @@ -201,15 +201,13 @@ vp8_prob *vp8_mv_ref_probs(VP8_COMMON *pc, * score to use as ref motion vector */ -#if CONFIG_NEW_MVREF - void vp8_find_best_ref_mvs(MACROBLOCKD *xd, unsigned char *ref_y_buffer, int ref_y_stride, + int_mv *mvlist, int_mv *best_mv, int_mv *nearest, int_mv *near) { - int_mv *ref_mv = xd->ref_mv; int i, j; unsigned char *above_src; unsigned char *left_src; @@ -229,12 +227,14 @@ void vp8_find_best_ref_mvs(MACROBLOCKD *xd, above_ref = ref_y_buffer - ref_y_stride * 2; left_ref = ref_y_buffer - 2; - for(i = 0; i < MAX_MV_REFS; ++i) { + //for(i = 0; i < MAX_MV_REFS; ++i) { + // Limit search to the predicted best 4 + for(i = 0; i < 4; ++i) { int_mv this_mv; int offset=0; int row_offset, col_offset; - this_mv.as_int = ref_mv[i].as_int; + this_mv.as_int = mvlist[i].as_int; // If we see a 0,0 vector for a second time we have reached the end of // the list of valid candidate vectors. @@ -278,32 +278,6 @@ void vp8_find_best_ref_mvs(MACROBLOCKD *xd, } } - // If not see add 0,0 as a possibility - /*if ( (i < MAX_MV_REFS) && !zero_seen ) { - - sad = vp8_sad16x2_c(above_src, xd->dst.y_stride, - above_ref, ref_y_stride, - INT_MAX); - sad += vp8_sad2x16_c(left_src, xd->dst.y_stride, - left_ref, ref_y_stride, - INT_MAX); - this_mv.as_int = 0; - - // Add the entry to our list and then resort the list on score. - sad_scores[i] = sad; - sorted_mvs[i].as_int = this_mv.as_int; - j = i; - while (j > 0) { - if (sad_scores[j] < sad_scores[j-1]) { - sad_scores[j] = sad_scores[j-1]; - sorted_mvs[j].as_int = sorted_mvs[j-1].as_int; - sad_scores[j-1] = sad; - sorted_mvs[j-1].as_int = this_mv.as_int; - j--; - } else - break; - } - }*/ // Set the best mv to the first entry in the sorted list best_mv->as_int = sorted_mvs[0].as_int; @@ -325,83 +299,13 @@ void vp8_find_best_ref_mvs(MACROBLOCKD *xd, near->as_int = sorted_mvs[2].as_int; } - if (!xd->allow_high_precision_mv) - lower_mv_precision(best_mv); - - vp8_clamp_mv2(best_mv, xd); -} - -#else // !CONFIG_NEW_MVREF + // Copy back the re-ordered mv list + vpx_memcpy(mvlist, sorted_mvs, sizeof(sorted_mvs)); -void vp8_find_best_ref_mvs(MACROBLOCKD *xd, - unsigned char *ref_y_buffer, - int ref_y_stride, - int_mv *best_mv, - int_mv *nearest, - int_mv *near) { - int_mv *ref_mv = xd->ref_mv; - int bestsad = INT_MAX; - int i; - unsigned char *above_src; - unsigned char *left_src; - unsigned char *above_ref; - unsigned char *left_ref; - int sad; - - above_src = xd->dst.y_buffer - xd->dst.y_stride * 2; - left_src = xd->dst.y_buffer - 2; - above_ref = ref_y_buffer - ref_y_stride * 2; - left_ref = ref_y_buffer - 2; - - bestsad = vp8_sad16x2_c(above_src, xd->dst.y_stride, - above_ref, ref_y_stride, - INT_MAX); - bestsad += vp8_sad2x16_c(left_src, xd->dst.y_stride, - left_ref, ref_y_stride, - INT_MAX); - best_mv->as_int = 0; - - for(i = 0; i < 4; ++i) { - if (ref_mv[i].as_int) { - int_mv this_mv; - int offset=0; - int row_offset, col_offset; - this_mv.as_int = ref_mv[i].as_int; - vp8_clamp_mv(&this_mv, - xd->mb_to_left_edge - LEFT_TOP_MARGIN + 16, - xd->mb_to_right_edge + RIGHT_BOTTOM_MARGIN, - xd->mb_to_top_edge - LEFT_TOP_MARGIN + 16, - xd->mb_to_bottom_edge + RIGHT_BOTTOM_MARGIN); - - row_offset = (this_mv.as_mv.row > 0) ? - ((this_mv.as_mv.row + 3) >> 3):((this_mv.as_mv.row + 4) >> 3); - col_offset = (this_mv.as_mv.col > 0) ? - ((this_mv.as_mv.col + 3) >> 3):((this_mv.as_mv.col + 4) >> 3); - offset = ref_y_stride * row_offset + col_offset; - - sad = vp8_sad16x2_c(above_src, xd->dst.y_stride, - above_ref + offset, ref_y_stride, INT_MAX); - - sad += vp8_sad2x16_c(left_src, xd->dst.y_stride, - left_ref + offset, ref_y_stride, INT_MAX); - - if (sad < bestsad) { - bestsad = sad; - best_mv->as_int = this_mv.as_int; - } - } - } if (!xd->allow_high_precision_mv) lower_mv_precision(best_mv); vp8_clamp_mv2(best_mv, xd); - - if (best_mv->as_int != 0 && - (best_mv->as_mv.row >> 3) != (nearest->as_mv.row >>3 ) && - (best_mv->as_mv.col >> 3) != (nearest->as_mv.col >>3 )) { - near->as_int = nearest->as_int; - nearest->as_int = best_mv->as_int; - } } -#endif // CONFIG_NEW_MVREF + #endif // CONFIG_NEWBESTREFMV diff --git a/vp8/common/findnearmv.h b/vp8/common/findnearmv.h index e3cdab5ce..cd7b87adf 100644 --- a/vp8/common/findnearmv.h +++ b/vp8/common/findnearmv.h @@ -26,6 +26,7 @@ void vp8_find_best_ref_mvs(MACROBLOCKD *xd, unsigned char *ref_y_buffer, int ref_y_stride, + int_mv *mvlist, int_mv *best_mv, int_mv *nearest, int_mv *near); diff --git a/vp8/common/mvref_common.c b/vp8/common/mvref_common.c index 1c345dba5..b6040cd59 100644 --- a/vp8/common/mvref_common.c +++ b/vp8/common/mvref_common.c @@ -10,14 +10,13 @@ #include "mvref_common.h" -#if CONFIG_NEW_MVREF +#if CONFIG_NEWBESTREFMV #define MVREF_NEIGHBOURS 8 static int mv_ref_search[MVREF_NEIGHBOURS][2] = { {0,-1},{-1,0},{-1,-1},{0,-2},{-2,0},{-1,-2},{-2,-1},{-2,-2} }; static int ref_distance_weight[MVREF_NEIGHBOURS] = { 3,3,2,1,1,1,1,1 }; - //{ 4,4,2,1,1,1,1,1 }; // clamp_mv #define MV_BORDER (16 << 3) // Allow 16 pels in 1/8th pel units @@ -47,30 +46,63 @@ unsigned int mv_distance(int_mv *mv1, int_mv *mv2) { int get_candidate_mvref( const MODE_INFO *candidate_mi, MV_REFERENCE_FRAME ref_frame, - MV_REFERENCE_FRAME *candidate_ref_frame, - int_mv *candidate_mv + MV_REFERENCE_FRAME *c_ref_frame, + int_mv *c_mv, + MV_REFERENCE_FRAME *c2_ref_frame, + int_mv *c2_mv ) { int ret_val = FALSE; + c2_mv->as_int = 0; + *c2_ref_frame = INTRA_FRAME; + // Target ref frame matches candidate first ref frame if (ref_frame == candidate_mi->mbmi.ref_frame) { - candidate_mv->as_int = candidate_mi->mbmi.mv[FIRST_REF].as_int; - *candidate_ref_frame = ref_frame; + c_mv->as_int = candidate_mi->mbmi.mv[0].as_int; + *c_ref_frame = ref_frame; ret_val = TRUE; + // Is there a second non zero vector we can use. + if ((candidate_mi->mbmi.second_ref_frame != INTRA_FRAME) && + (candidate_mi->mbmi.mv[1].as_int != 0) && + (candidate_mi->mbmi.mv[1].as_int != c_mv->as_int)) { + c2_mv->as_int = candidate_mi->mbmi.mv[1].as_int; + *c2_ref_frame = candidate_mi->mbmi.second_ref_frame; + } + + // Target ref frame matches candidate second ref frame } else if (ref_frame == candidate_mi->mbmi.second_ref_frame) { - candidate_mv->as_int = candidate_mi->mbmi.mv[SECOND_REF].as_int; - *candidate_ref_frame = ref_frame; + c_mv->as_int = candidate_mi->mbmi.mv[1].as_int; + *c_ref_frame = ref_frame; ret_val = TRUE; + // Is there a second non zero vector we can use. + if ((candidate_mi->mbmi.ref_frame != INTRA_FRAME) && + (candidate_mi->mbmi.mv[0].as_int != 0) && + (candidate_mi->mbmi.mv[0].as_int != c_mv->as_int)) { + c2_mv->as_int = candidate_mi->mbmi.mv[0].as_int; + *c2_ref_frame = candidate_mi->mbmi.ref_frame; + } + + // No ref frame matches so use first ref mv as first choice } else if (candidate_mi->mbmi.ref_frame != INTRA_FRAME) { - candidate_mv->as_int = candidate_mi->mbmi.mv[FIRST_REF].as_int; - *candidate_ref_frame = candidate_mi->mbmi.ref_frame; + c_mv->as_int = candidate_mi->mbmi.mv[0].as_int; + *c_ref_frame = candidate_mi->mbmi.ref_frame; ret_val = TRUE; + // Is there a second non zero vector we can use. + if ((candidate_mi->mbmi.second_ref_frame != INTRA_FRAME) && + (candidate_mi->mbmi.mv[1].as_int != 0) && + (candidate_mi->mbmi.mv[1].as_int != c_mv->as_int)) { + c2_mv->as_int = candidate_mi->mbmi.mv[1].as_int; + *c2_ref_frame = candidate_mi->mbmi.second_ref_frame; + } + + // If only the second ref mv is valid:- (Should not trigger in current code + // base given current possible compound prediction options). } else if (candidate_mi->mbmi.second_ref_frame != INTRA_FRAME) { - candidate_mv->as_int = candidate_mi->mbmi.mv[SECOND_REF].as_int; - *candidate_ref_frame = candidate_mi->mbmi.second_ref_frame; + c_mv->as_int = candidate_mi->mbmi.mv[1].as_int; + *c_ref_frame = candidate_mi->mbmi.second_ref_frame; ret_val = TRUE; } @@ -142,8 +174,10 @@ void addmv_and_shuffle( int duplicate_found = FALSE; // Check for duplicates. If there is one increment its score. + // Duplicate defined as being the same full pel vector with rounding. while (i > 0) { i--; + if (candidate_mv.as_int == mv_list[i].as_int) { duplicate_found = TRUE; mv_scores[i] += weight; @@ -175,33 +209,6 @@ void addmv_and_shuffle( } } - -// Measure the distance of each reference candidate from the actual -// residual vector and return the nearest -unsigned int pick_best_mv_ref( int_mv target_mv, - int_mv * mv_ref_list, - int_mv * best_ref ) { - - int i; - int best_index = 0; - unsigned int distance, distance2; - - distance = mv_distance(&target_mv, &mv_ref_list[0]); - - for (i = 1; i < MAX_MV_REFS; ++i ) { - distance2 = - mv_distance(&target_mv, &mv_ref_list[i]); - if (distance2 < distance) { - distance = distance2; - best_index = i; - } - } - - (*best_ref).as_int = mv_ref_list[best_index].as_int; - - return best_index; -} - // This function searches the neighbourhood of a given MB/SB and populates a // list of candidate reference vectors. // @@ -219,6 +226,8 @@ void find_mv_refs( int_mv candidate_mvs[MAX_MV_REFS]; int_mv c_refmv; MV_REFERENCE_FRAME c_ref_frame; + int_mv c2_refmv; + MV_REFERENCE_FRAME c2_ref_frame; int candidate_scores[MAX_MV_REFS]; int index = 0; int ref_weight = 0; @@ -239,15 +248,27 @@ void find_mv_refs( (mv_ref_search[i][1] * xd->mode_info_stride); valid_mv_ref = get_candidate_mvref(candidate_mi, ref_frame, - &c_ref_frame, &c_refmv); + &c_ref_frame, &c_refmv, + &c2_ref_frame, &c2_refmv); + // If there is a valid MV candidate then add it to the list if (valid_mv_ref) { - scale_mv(xd, ref_frame, c_ref_frame, &c_refmv, ref_sign_bias ); + scale_mv(xd, ref_frame, c_ref_frame, &c_refmv, ref_sign_bias ); + ref_weight = ref_distance_weight[i] + + ((c_ref_frame == ref_frame) << 4); + + addmv_and_shuffle(candidate_mvs, candidate_scores, + &index, c_refmv, ref_weight); + + // If there is a second valid mv then add it as well. + if (c2_ref_frame != INTRA_FRAME) { + scale_mv(xd, ref_frame, c2_ref_frame, &c2_refmv, ref_sign_bias ); ref_weight = ref_distance_weight[i] + - ((c_ref_frame == ref_frame) << 3); + ((c2_ref_frame == ref_frame) << 4); addmv_and_shuffle(candidate_mvs, candidate_scores, - &index, c_refmv, ref_weight); + &index, c2_refmv, ref_weight); + } } } } @@ -255,12 +276,25 @@ void find_mv_refs( // Look at the corresponding vector in the last frame candidate_mi = lf_here; valid_mv_ref = get_candidate_mvref(candidate_mi, ref_frame, - &c_ref_frame, &c_refmv); + &c_ref_frame, &c_refmv, + &c2_ref_frame, &c2_refmv); + + // If there is a valid MV candidate then add it to the list if (valid_mv_ref) { scale_mv(xd, ref_frame, c_ref_frame, &c_refmv, ref_sign_bias ); - ref_weight = 2 + ((c_ref_frame == ref_frame) << 3); + ref_weight = 2 + ((c_ref_frame == ref_frame) << 4); addmv_and_shuffle(candidate_mvs, candidate_scores, &index, c_refmv, ref_weight); + + // If there is a second valid mv then add it as well. + if (c2_ref_frame != INTRA_FRAME) { + scale_mv(xd, ref_frame, c2_ref_frame, &c2_refmv, ref_sign_bias ); + ref_weight = ref_distance_weight[i] + + ((c2_ref_frame == ref_frame) << 4); + + addmv_and_shuffle(candidate_mvs, candidate_scores, + &index, c2_refmv, ref_weight); + } } // Populate a list with candidate reference vectors from the @@ -273,15 +307,27 @@ void find_mv_refs( (mv_ref_search[i][1] * xd->mode_info_stride); valid_mv_ref = get_candidate_mvref(candidate_mi, ref_frame, - &c_ref_frame, &c_refmv); + &c_ref_frame, &c_refmv, + &c2_ref_frame, &c2_refmv); + // If there is a valid MV candidate then add it to the list if (valid_mv_ref) { - scale_mv(xd, ref_frame, c_ref_frame, &c_refmv, ref_sign_bias ); + scale_mv(xd, ref_frame, c_ref_frame, &c_refmv, ref_sign_bias ); + ref_weight = ref_distance_weight[i] + + ((c_ref_frame == ref_frame) << 4); + + addmv_and_shuffle(candidate_mvs, candidate_scores, + &index, c_refmv, ref_weight); + + // If there is a second valid mv then add it as well. + if (c2_ref_frame != INTRA_FRAME) { + scale_mv(xd, ref_frame, c2_ref_frame, &c2_refmv, ref_sign_bias ); ref_weight = ref_distance_weight[i] + - ((c_ref_frame == ref_frame) << 3); + ((c2_ref_frame == ref_frame) << 4); addmv_and_shuffle(candidate_mvs, candidate_scores, - &index, c_refmv, ref_weight); + &index, c2_refmv, ref_weight); + } } } } @@ -293,7 +339,7 @@ void find_mv_refs( if (i == index) { c_refmv.as_int = 0; addmv_and_shuffle(candidate_mvs, candidate_scores, - &index, c_refmv, 1); + &index, c_refmv, candidate_scores[3]+1 ); } // Copy over the candidate list. diff --git a/vp8/common/mvref_common.h b/vp8/common/mvref_common.h index 9be408894..3f19ddbdb 100644 --- a/vp8/common/mvref_common.h +++ b/vp8/common/mvref_common.h @@ -12,17 +12,13 @@ #include "blockd.h" // MR reference entropy header file. -#if CONFIG_NEW_MVREF +#if CONFIG_NEWBESTREFMV #ifndef __INC_MVREF_COMMON_H #define __INC_MVREF_COMMON_H unsigned int mv_distance(int_mv *mv1, int_mv *mv2); -unsigned int pick_best_mv_ref( int_mv target_mv, - int_mv * mv_ref_list, - int_mv * best_ref ); - void find_mv_refs( MACROBLOCKD *xd, MODE_INFO *here, |