summaryrefslogtreecommitdiff
path: root/vp8/common
diff options
context:
space:
mode:
Diffstat (limited to 'vp8/common')
-rw-r--r--vp8/common/blockd.h20
-rw-r--r--vp8/common/findnearmv.c112
-rw-r--r--vp8/common/findnearmv.h1
-rw-r--r--vp8/common/mvref_common.c146
-rw-r--r--vp8/common/mvref_common.h6
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,