Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(4)

Unified Diff: source/libvpx/vp9/common/vp9_mvref_common.c

Issue 11974002: libvpx: Pull from upstream (Closed) Base URL: svn://chrome-svn/chrome/trunk/deps/third_party/libvpx/
Patch Set: Created 7 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « source/libvpx/vp9/common/vp9_mvref_common.h ('k') | source/libvpx/vp9/common/vp9_onyx.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: source/libvpx/vp9/common/vp9_mvref_common.c
===================================================================
--- source/libvpx/vp9/common/vp9_mvref_common.c (revision 177019)
+++ source/libvpx/vp9/common/vp9_mvref_common.c (working copy)
@@ -17,14 +17,13 @@
};
static int mb_ref_distance_weight[MVREF_NEIGHBOURS] =
{ 3, 3, 2, 1, 1, 1, 1, 1 };
-#if CONFIG_SUPERBLOCKS
static int sb_mv_ref_search[MVREF_NEIGHBOURS][2] = {
{0, -1}, {-1, 0}, {1, -1}, {-1, 1},
{-1, -1}, {0, -2}, {-2, 0}, {-1, -2}
};
static int sb_ref_distance_weight[MVREF_NEIGHBOURS] =
{ 3, 3, 2, 2, 2, 1, 1, 1 };
-#endif
+
// clamp_mv
#define MV_BORDER (16 << 3) // Allow 16 pels in 1/8th pel units
static void clamp_mv(const MACROBLOCKD *xd, int_mv *mv) {
@@ -40,10 +39,29 @@
mv->as_mv.row = xd->mb_to_bottom_edge + MV_BORDER;
}
+// Gets a candidate refenence motion vector from the given mode info
+// structure if one exists that matches the given reference frame.
+static int get_matching_candidate(
+ const MODE_INFO *candidate_mi,
+ MV_REFERENCE_FRAME ref_frame,
+ int_mv *c_mv
+) {
+ int ret_val = TRUE;
-// Gets a best matching candidate refenence motion vector
-// from the given mode info structure (if available)
-static int get_candidate_mvref(
+ if (ref_frame == candidate_mi->mbmi.ref_frame) {
+ c_mv->as_int = candidate_mi->mbmi.mv[0].as_int;
+ } else if (ref_frame == candidate_mi->mbmi.second_ref_frame) {
+ c_mv->as_int = candidate_mi->mbmi.mv[1].as_int;
+ } else {
+ ret_val = FALSE;
+ }
+
+ return ret_val;
+}
+
+// Gets candidate refenence motion vector(s) from the given mode info
+// structure if they exists and do NOT match the given reference frame.
+static void get_non_matching_candidates(
const MODE_INFO *candidate_mi,
MV_REFERENCE_FRAME ref_frame,
MV_REFERENCE_FRAME *c_ref_frame,
@@ -52,61 +70,29 @@
int_mv *c2_mv
) {
- int ret_val = FALSE;
+ c_mv->as_int = 0;
c2_mv->as_int = 0;
+ *c_ref_frame = INTRA_FRAME;
*c2_ref_frame = INTRA_FRAME;
- // Target ref frame matches candidate first ref frame
- if (ref_frame == candidate_mi->mbmi.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;
+ // If first candidate not valid neither will be.
+ if (candidate_mi->mbmi.ref_frame > INTRA_FRAME) {
+ // First candidate
+ if (candidate_mi->mbmi.ref_frame != ref_frame) {
+ *c_ref_frame = candidate_mi->mbmi.ref_frame;
+ c_mv->as_int = candidate_mi->mbmi.mv[0].as_int;
}
- // Target ref frame matches candidate second ref frame
- } else if (ref_frame == candidate_mi->mbmi.second_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) {
- 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.
+ // Second candidate
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;
+ (candidate_mi->mbmi.second_ref_frame != ref_frame)) { // &&
+ // (candidate_mi->mbmi.mv[1].as_int != 0) &&
+ // (candidate_mi->mbmi.mv[1].as_int !=
+ // candidate_mi->mbmi.mv[0].as_int)) {
*c2_ref_frame = candidate_mi->mbmi.second_ref_frame;
+ c2_mv->as_int = candidate_mi->mbmi.mv[1].as_int;
}
-
- // 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) {
- c_mv->as_int = candidate_mi->mbmi.mv[1].as_int;
- *c_ref_frame = candidate_mi->mbmi.second_ref_frame;
- ret_val = TRUE;
}
-
- return ret_val;
}
// Performs mv adjustment based on reference frame and clamps the MV
@@ -170,14 +156,20 @@
int weight
) {
- int i = *index;
+ int i;
+ int insert_point;
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.
+ // Check for duplicates. If there is one increase its score.
+ // We only compare vs the current top candidates.
+ insert_point = (*index < (MAX_MV_REF_CANDIDATES - 1))
+ ? *index : (MAX_MV_REF_CANDIDATES - 1);
+
+ i = insert_point;
+ if (*index > i)
+ i++;
while (i > 0) {
i--;
-
if (candidate_mv.as_int == mv_list[i].as_int) {
duplicate_found = TRUE;
mv_scores[i] += weight;
@@ -185,11 +177,13 @@
}
}
- // If no duplicate was found add the new vector and give it a weight
- if (!duplicate_found) {
- mv_list[*index].as_int = candidate_mv.as_int;
- mv_scores[*index] = weight;
- i = *index;
+ // If no duplicate and the new candidate is good enough then add it.
+ if (!duplicate_found ) {
+ if (weight > mv_scores[insert_point]) {
+ mv_list[insert_point].as_int = candidate_mv.as_int;
+ mv_scores[insert_point] = weight;
+ i = insert_point;
+ }
(*index)++;
}
@@ -224,38 +218,32 @@
int i;
MODE_INFO *candidate_mi;
MB_MODE_INFO * mbmi = &xd->mode_info_context->mbmi;
- int_mv candidate_mvs[MAX_MV_REFS];
+ int_mv candidate_mvs[MAX_MV_REF_CANDIDATES];
int_mv c_refmv;
- MV_REFERENCE_FRAME c_ref_frame;
int_mv c2_refmv;
+ MV_REFERENCE_FRAME c_ref_frame;
MV_REFERENCE_FRAME c2_ref_frame;
- int candidate_scores[MAX_MV_REFS];
+ int candidate_scores[MAX_MV_REF_CANDIDATES];
int index = 0;
int split_count = 0;
- int ref_weight = 0;
- int valid_mv_ref;
int (*mv_ref_search)[2];
int *ref_distance_weight;
// Blank the reference vector lists and other local structures.
- vpx_memset(mv_ref_list, 0, sizeof(int_mv) * MAX_MV_REFS);
- vpx_memset(candidate_mvs, 0, sizeof(int_mv) * MAX_MV_REFS);
+ vpx_memset(mv_ref_list, 0, sizeof(int_mv) * MAX_MV_REF_CANDIDATES);
+ vpx_memset(candidate_mvs, 0, sizeof(int_mv) * MAX_MV_REF_CANDIDATES);
vpx_memset(candidate_scores, 0, sizeof(candidate_scores));
-#if CONFIG_SUPERBLOCKS
- if (mbmi->encoded_as_sb) {
+ if (mbmi->sb_type) {
mv_ref_search = sb_mv_ref_search;
ref_distance_weight = sb_ref_distance_weight;
} else {
mv_ref_search = mb_mv_ref_search;
ref_distance_weight = mb_ref_distance_weight;
}
-#else
- mv_ref_search = mb_mv_ref_search;
- ref_distance_weight = mb_ref_distance_weight;
-#endif
- // Populate a list with candidate reference vectors from the
- // spatial neighbours.
+
+ // We first scan for candidate vectors that match the current reference frame
+ // Look at nearest neigbours
for (i = 0; i < 2; ++i) {
if (((mv_ref_search[i][0] << 7) >= xd->mb_to_left_edge) &&
((mv_ref_search[i][1] << 7) >= xd->mb_to_top_edge)) {
@@ -263,95 +251,89 @@
candidate_mi = here + mv_ref_search[i][0] +
(mv_ref_search[i][1] * xd->mode_info_stride);
- valid_mv_ref = get_candidate_mvref(candidate_mi, ref_frame,
- &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 = ref_distance_weight[i] +
- ((c_ref_frame == ref_frame) << 4);
- split_count += (candidate_mi->mbmi.mode == SPLITMV);
-
+ if (get_matching_candidate(candidate_mi, ref_frame, &c_refmv)) {
+ clamp_mv(xd, &c_refmv);
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);
- }
+ &index, c_refmv, ref_distance_weight[i] + 16);
}
+ split_count += (candidate_mi->mbmi.mode == SPLITMV);
}
}
-
- // Look at the corresponding vector in the last frame
+ // Look in the last frame
candidate_mi = lf_here;
- valid_mv_ref = get_candidate_mvref(candidate_mi, ref_frame,
- &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) << 4);
+ if (get_matching_candidate(candidate_mi, ref_frame, &c_refmv)) {
+ clamp_mv(xd, &c_refmv);
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);
- }
+ &index, c_refmv, 18);
}
-
- // Populate a list with candidate reference vectors from the
- // spatial neighbours.
- for (i = 2; (i < MVREF_NEIGHBOURS) && (index < (MAX_MV_REFS - 2)); ++i) {
+ // More distant neigbours
+ for (i = 2; (i < MVREF_NEIGHBOURS) &&
+ (index < (MAX_MV_REF_CANDIDATES - 1)); ++i) {
if (((mv_ref_search[i][0] << 7) >= xd->mb_to_left_edge) &&
((mv_ref_search[i][1] << 7) >= xd->mb_to_top_edge)) {
-
candidate_mi = here + mv_ref_search[i][0] +
(mv_ref_search[i][1] * xd->mode_info_stride);
- valid_mv_ref = get_candidate_mvref(candidate_mi, ref_frame,
- &c_ref_frame, &c_refmv,
- &c2_ref_frame, &c2_refmv);
+ if (get_matching_candidate(candidate_mi, ref_frame, &c_refmv)) {
+ clamp_mv(xd, &c_refmv);
+ addmv_and_shuffle(candidate_mvs, candidate_scores,
+ &index, c_refmv, ref_distance_weight[i] + 16);
+ }
+ }
+ }
- // 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 = ref_distance_weight[i] +
- ((c_ref_frame == ref_frame) << 4);
+ // If we have not found enough candidates consider ones where the
+ // reference frame does not match. Break out when we have
+ // MAX_MV_REF_CANDIDATES candidates.
+ // Look first at spatial neighbours
+ if (index < (MAX_MV_REF_CANDIDATES - 1)) {
+ for (i = 0; i < MVREF_NEIGHBOURS; ++i) {
+ if (((mv_ref_search[i][0] << 7) >= xd->mb_to_left_edge) &&
+ ((mv_ref_search[i][1] << 7) >= xd->mb_to_top_edge)) {
- addmv_and_shuffle(candidate_mvs, candidate_scores,
- &index, c_refmv, ref_weight);
+ candidate_mi = here + mv_ref_search[i][0] +
+ (mv_ref_search[i][1] * xd->mode_info_stride);
- // 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);
+ get_non_matching_candidates(candidate_mi, ref_frame,
+ &c_ref_frame, &c_refmv,
+ &c2_ref_frame, &c2_refmv);
+ if (c_ref_frame != INTRA_FRAME) {
+ scale_mv(xd, ref_frame, c_ref_frame, &c_refmv, ref_sign_bias);
addmv_and_shuffle(candidate_mvs, candidate_scores,
- &index, c2_refmv, ref_weight);
+ &index, c_refmv, ref_distance_weight[i]);
}
+
+ if (c2_ref_frame != INTRA_FRAME) {
+ scale_mv(xd, ref_frame, c2_ref_frame, &c2_refmv, ref_sign_bias);
+ addmv_and_shuffle(candidate_mvs, candidate_scores,
+ &index, c2_refmv, ref_distance_weight[i]);
+ }
}
+
+ if (index >= (MAX_MV_REF_CANDIDATES - 1)) {
+ break;
+ }
}
}
+ // Look at the last frame
+ if (index < (MAX_MV_REF_CANDIDATES - 1)) {
+ candidate_mi = lf_here;
+ get_non_matching_candidates(candidate_mi, ref_frame,
+ &c_ref_frame, &c_refmv,
+ &c2_ref_frame, &c2_refmv);
- // Make sure we are able to add 0,0
- if (index > (MAX_MV_REFS - 1)) {
- index = (MAX_MV_REFS - 1);
+ if (c_ref_frame != INTRA_FRAME) {
+ scale_mv(xd, ref_frame, c_ref_frame, &c_refmv, ref_sign_bias);
+ addmv_and_shuffle(candidate_mvs, candidate_scores,
+ &index, c_refmv, 2);
+ }
+
+ if (c2_ref_frame != INTRA_FRAME) {
+ scale_mv(xd, ref_frame, c2_ref_frame, &c2_refmv, ref_sign_bias);
+ addmv_and_shuffle(candidate_mvs, candidate_scores,
+ &index, c2_refmv, 2);
+ }
}
// Define inter mode coding context.
@@ -383,14 +365,12 @@
}
// 0,0 is always a valid reference.
- for (i = 0; i < index; ++i) {
+ for (i = 0; i < MAX_MV_REF_CANDIDATES; ++i) {
if (candidate_mvs[i].as_int == 0)
break;
}
- if (i == index) {
- c_refmv.as_int = 0;
- addmv_and_shuffle(candidate_mvs, candidate_scores,
- &index, c_refmv, candidate_scores[3]+1 );
+ if (i == MAX_MV_REF_CANDIDATES) {
+ candidate_mvs[MAX_MV_REF_CANDIDATES-1].as_int = 0;
}
// Copy over the candidate list.
« no previous file with comments | « source/libvpx/vp9/common/vp9_mvref_common.h ('k') | source/libvpx/vp9/common/vp9_onyx.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698