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

Side by Side 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 unified diff | Download patch | Annotate | Revision Log
« 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 »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright (c) 2012 The WebM project authors. All Rights Reserved. 2 * Copyright (c) 2012 The WebM project authors. All Rights Reserved.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license 4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source 5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found 6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may 7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree. 8 * be found in the AUTHORS file in the root of the source tree.
9 */ 9 */
10 10
11 #include "vp9/common/vp9_mvref_common.h" 11 #include "vp9/common/vp9_mvref_common.h"
12 12
13 #define MVREF_NEIGHBOURS 8 13 #define MVREF_NEIGHBOURS 8
14 static int mb_mv_ref_search[MVREF_NEIGHBOURS][2] = { 14 static int mb_mv_ref_search[MVREF_NEIGHBOURS][2] = {
15 {0, -1}, {-1, 0}, {-1, -1}, {0, -2}, 15 {0, -1}, {-1, 0}, {-1, -1}, {0, -2},
16 {-2, 0}, {-1, -2}, {-2, -1}, {-2, -2} 16 {-2, 0}, {-1, -2}, {-2, -1}, {-2, -2}
17 }; 17 };
18 static int mb_ref_distance_weight[MVREF_NEIGHBOURS] = 18 static int mb_ref_distance_weight[MVREF_NEIGHBOURS] =
19 { 3, 3, 2, 1, 1, 1, 1, 1 }; 19 { 3, 3, 2, 1, 1, 1, 1, 1 };
20 #if CONFIG_SUPERBLOCKS
21 static int sb_mv_ref_search[MVREF_NEIGHBOURS][2] = { 20 static int sb_mv_ref_search[MVREF_NEIGHBOURS][2] = {
22 {0, -1}, {-1, 0}, {1, -1}, {-1, 1}, 21 {0, -1}, {-1, 0}, {1, -1}, {-1, 1},
23 {-1, -1}, {0, -2}, {-2, 0}, {-1, -2} 22 {-1, -1}, {0, -2}, {-2, 0}, {-1, -2}
24 }; 23 };
25 static int sb_ref_distance_weight[MVREF_NEIGHBOURS] = 24 static int sb_ref_distance_weight[MVREF_NEIGHBOURS] =
26 { 3, 3, 2, 2, 2, 1, 1, 1 }; 25 { 3, 3, 2, 2, 2, 1, 1, 1 };
27 #endif 26
28 // clamp_mv 27 // clamp_mv
29 #define MV_BORDER (16 << 3) // Allow 16 pels in 1/8th pel units 28 #define MV_BORDER (16 << 3) // Allow 16 pels in 1/8th pel units
30 static void clamp_mv(const MACROBLOCKD *xd, int_mv *mv) { 29 static void clamp_mv(const MACROBLOCKD *xd, int_mv *mv) {
31 30
32 if (mv->as_mv.col < (xd->mb_to_left_edge - MV_BORDER)) 31 if (mv->as_mv.col < (xd->mb_to_left_edge - MV_BORDER))
33 mv->as_mv.col = xd->mb_to_left_edge - MV_BORDER; 32 mv->as_mv.col = xd->mb_to_left_edge - MV_BORDER;
34 else if (mv->as_mv.col > xd->mb_to_right_edge + MV_BORDER) 33 else if (mv->as_mv.col > xd->mb_to_right_edge + MV_BORDER)
35 mv->as_mv.col = xd->mb_to_right_edge + MV_BORDER; 34 mv->as_mv.col = xd->mb_to_right_edge + MV_BORDER;
36 35
37 if (mv->as_mv.row < (xd->mb_to_top_edge - MV_BORDER)) 36 if (mv->as_mv.row < (xd->mb_to_top_edge - MV_BORDER))
38 mv->as_mv.row = xd->mb_to_top_edge - MV_BORDER; 37 mv->as_mv.row = xd->mb_to_top_edge - MV_BORDER;
39 else if (mv->as_mv.row > xd->mb_to_bottom_edge + MV_BORDER) 38 else if (mv->as_mv.row > xd->mb_to_bottom_edge + MV_BORDER)
40 mv->as_mv.row = xd->mb_to_bottom_edge + MV_BORDER; 39 mv->as_mv.row = xd->mb_to_bottom_edge + MV_BORDER;
41 } 40 }
42 41
42 // Gets a candidate refenence motion vector from the given mode info
43 // structure if one exists that matches the given reference frame.
44 static int get_matching_candidate(
45 const MODE_INFO *candidate_mi,
46 MV_REFERENCE_FRAME ref_frame,
47 int_mv *c_mv
48 ) {
49 int ret_val = TRUE;
43 50
44 // Gets a best matching candidate refenence motion vector 51 if (ref_frame == candidate_mi->mbmi.ref_frame) {
45 // from the given mode info structure (if available) 52 c_mv->as_int = candidate_mi->mbmi.mv[0].as_int;
46 static int get_candidate_mvref( 53 } else if (ref_frame == candidate_mi->mbmi.second_ref_frame) {
54 c_mv->as_int = candidate_mi->mbmi.mv[1].as_int;
55 } else {
56 ret_val = FALSE;
57 }
58
59 return ret_val;
60 }
61
62 // Gets candidate refenence motion vector(s) from the given mode info
63 // structure if they exists and do NOT match the given reference frame.
64 static void get_non_matching_candidates(
47 const MODE_INFO *candidate_mi, 65 const MODE_INFO *candidate_mi,
48 MV_REFERENCE_FRAME ref_frame, 66 MV_REFERENCE_FRAME ref_frame,
49 MV_REFERENCE_FRAME *c_ref_frame, 67 MV_REFERENCE_FRAME *c_ref_frame,
50 int_mv *c_mv, 68 int_mv *c_mv,
51 MV_REFERENCE_FRAME *c2_ref_frame, 69 MV_REFERENCE_FRAME *c2_ref_frame,
52 int_mv *c2_mv 70 int_mv *c2_mv
53 ) { 71 ) {
54 72
55 int ret_val = FALSE; 73 c_mv->as_int = 0;
56 c2_mv->as_int = 0; 74 c2_mv->as_int = 0;
75 *c_ref_frame = INTRA_FRAME;
57 *c2_ref_frame = INTRA_FRAME; 76 *c2_ref_frame = INTRA_FRAME;
58 77
59 // Target ref frame matches candidate first ref frame 78 // If first candidate not valid neither will be.
60 if (ref_frame == candidate_mi->mbmi.ref_frame) { 79 if (candidate_mi->mbmi.ref_frame > INTRA_FRAME) {
61 c_mv->as_int = candidate_mi->mbmi.mv[0].as_int; 80 // First candidate
62 *c_ref_frame = ref_frame; 81 if (candidate_mi->mbmi.ref_frame != ref_frame) {
63 ret_val = TRUE; 82 *c_ref_frame = candidate_mi->mbmi.ref_frame;
64 83 c_mv->as_int = candidate_mi->mbmi.mv[0].as_int;
65 // Is there a second non zero vector we can use.
66 if ((candidate_mi->mbmi.second_ref_frame > INTRA_FRAME) &&
67 (candidate_mi->mbmi.mv[1].as_int != 0) &&
68 (candidate_mi->mbmi.mv[1].as_int != c_mv->as_int)) {
69 c2_mv->as_int = candidate_mi->mbmi.mv[1].as_int;
70 *c2_ref_frame = candidate_mi->mbmi.second_ref_frame;
71 } 84 }
72 85
73 // Target ref frame matches candidate second ref frame 86 // Second candidate
74 } else if (ref_frame == candidate_mi->mbmi.second_ref_frame) { 87 if ((candidate_mi->mbmi.second_ref_frame > INTRA_FRAME) &&
75 c_mv->as_int = candidate_mi->mbmi.mv[1].as_int; 88 (candidate_mi->mbmi.second_ref_frame != ref_frame)) { // &&
76 *c_ref_frame = ref_frame; 89 // (candidate_mi->mbmi.mv[1].as_int != 0) &&
77 ret_val = TRUE; 90 // (candidate_mi->mbmi.mv[1].as_int !=
78 91 // candidate_mi->mbmi.mv[0].as_int)) {
79 // Is there a second non zero vector we can use. 92 *c2_ref_frame = candidate_mi->mbmi.second_ref_frame;
80 if ((candidate_mi->mbmi.ref_frame > INTRA_FRAME) && 93 c2_mv->as_int = candidate_mi->mbmi.mv[1].as_int;
81 (candidate_mi->mbmi.mv[0].as_int != 0) &&
82 (candidate_mi->mbmi.mv[0].as_int != c_mv->as_int)) {
83 c2_mv->as_int = candidate_mi->mbmi.mv[0].as_int;
84 *c2_ref_frame = candidate_mi->mbmi.ref_frame;
85 } 94 }
86
87 // No ref frame matches so use first ref mv as first choice
88 } else if (candidate_mi->mbmi.ref_frame > INTRA_FRAME) {
89 c_mv->as_int = candidate_mi->mbmi.mv[0].as_int;
90 *c_ref_frame = candidate_mi->mbmi.ref_frame;
91 ret_val = TRUE;
92
93 // Is there a second non zero vector we can use.
94 if ((candidate_mi->mbmi.second_ref_frame > INTRA_FRAME) &&
95 (candidate_mi->mbmi.mv[1].as_int != 0) &&
96 (candidate_mi->mbmi.mv[1].as_int != c_mv->as_int)) {
97 c2_mv->as_int = candidate_mi->mbmi.mv[1].as_int;
98 *c2_ref_frame = candidate_mi->mbmi.second_ref_frame;
99 }
100
101 // If only the second ref mv is valid:- (Should not trigger in current code
102 // base given current possible compound prediction options).
103 } else if (candidate_mi->mbmi.second_ref_frame > INTRA_FRAME) {
104 c_mv->as_int = candidate_mi->mbmi.mv[1].as_int;
105 *c_ref_frame = candidate_mi->mbmi.second_ref_frame;
106 ret_val = TRUE;
107 } 95 }
108
109 return ret_val;
110 } 96 }
111 97
112 // Performs mv adjustment based on reference frame and clamps the MV 98 // Performs mv adjustment based on reference frame and clamps the MV
113 // if it goes off the edge of the buffer. 99 // if it goes off the edge of the buffer.
114 static void scale_mv( 100 static void scale_mv(
115 MACROBLOCKD *xd, 101 MACROBLOCKD *xd,
116 MV_REFERENCE_FRAME this_ref_frame, 102 MV_REFERENCE_FRAME this_ref_frame,
117 MV_REFERENCE_FRAME candidate_ref_frame, 103 MV_REFERENCE_FRAME candidate_ref_frame,
118 int_mv *candidate_mv, 104 int_mv *candidate_mv,
119 int *ref_sign_bias 105 int *ref_sign_bias
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
163 // If it is not new then the score of the existing candidate that it matches 149 // If it is not new then the score of the existing candidate that it matches
164 // is increased and the list is resorted. 150 // is increased and the list is resorted.
165 static void addmv_and_shuffle( 151 static void addmv_and_shuffle(
166 int_mv *mv_list, 152 int_mv *mv_list,
167 int *mv_scores, 153 int *mv_scores,
168 int *index, 154 int *index,
169 int_mv candidate_mv, 155 int_mv candidate_mv,
170 int weight 156 int weight
171 ) { 157 ) {
172 158
173 int i = *index; 159 int i;
160 int insert_point;
174 int duplicate_found = FALSE; 161 int duplicate_found = FALSE;
175 162
176 // Check for duplicates. If there is one increment its score. 163 // Check for duplicates. If there is one increase its score.
177 // Duplicate defined as being the same full pel vector with rounding. 164 // We only compare vs the current top candidates.
165 insert_point = (*index < (MAX_MV_REF_CANDIDATES - 1))
166 ? *index : (MAX_MV_REF_CANDIDATES - 1);
167
168 i = insert_point;
169 if (*index > i)
170 i++;
178 while (i > 0) { 171 while (i > 0) {
179 i--; 172 i--;
180
181 if (candidate_mv.as_int == mv_list[i].as_int) { 173 if (candidate_mv.as_int == mv_list[i].as_int) {
182 duplicate_found = TRUE; 174 duplicate_found = TRUE;
183 mv_scores[i] += weight; 175 mv_scores[i] += weight;
184 break; 176 break;
185 } 177 }
186 } 178 }
187 179
188 // If no duplicate was found add the new vector and give it a weight 180 // If no duplicate and the new candidate is good enough then add it.
189 if (!duplicate_found) { 181 if (!duplicate_found ) {
190 mv_list[*index].as_int = candidate_mv.as_int; 182 if (weight > mv_scores[insert_point]) {
191 mv_scores[*index] = weight; 183 mv_list[insert_point].as_int = candidate_mv.as_int;
192 i = *index; 184 mv_scores[insert_point] = weight;
185 i = insert_point;
186 }
193 (*index)++; 187 (*index)++;
194 } 188 }
195 189
196 // Reshuffle the list so that highest scoring mvs at the top. 190 // Reshuffle the list so that highest scoring mvs at the top.
197 while (i > 0) { 191 while (i > 0) {
198 if (mv_scores[i] > mv_scores[i-1]) { 192 if (mv_scores[i] > mv_scores[i-1]) {
199 int tmp_score = mv_scores[i-1]; 193 int tmp_score = mv_scores[i-1];
200 int_mv tmp_mv = mv_list[i-1]; 194 int_mv tmp_mv = mv_list[i-1];
201 195
202 mv_scores[i-1] = mv_scores[i]; 196 mv_scores[i-1] = mv_scores[i];
(...skipping 14 matching lines...) Expand all
217 MODE_INFO *here, 211 MODE_INFO *here,
218 MODE_INFO *lf_here, 212 MODE_INFO *lf_here,
219 MV_REFERENCE_FRAME ref_frame, 213 MV_REFERENCE_FRAME ref_frame,
220 int_mv *mv_ref_list, 214 int_mv *mv_ref_list,
221 int *ref_sign_bias 215 int *ref_sign_bias
222 ) { 216 ) {
223 217
224 int i; 218 int i;
225 MODE_INFO *candidate_mi; 219 MODE_INFO *candidate_mi;
226 MB_MODE_INFO * mbmi = &xd->mode_info_context->mbmi; 220 MB_MODE_INFO * mbmi = &xd->mode_info_context->mbmi;
227 int_mv candidate_mvs[MAX_MV_REFS]; 221 int_mv candidate_mvs[MAX_MV_REF_CANDIDATES];
228 int_mv c_refmv; 222 int_mv c_refmv;
223 int_mv c2_refmv;
229 MV_REFERENCE_FRAME c_ref_frame; 224 MV_REFERENCE_FRAME c_ref_frame;
230 int_mv c2_refmv;
231 MV_REFERENCE_FRAME c2_ref_frame; 225 MV_REFERENCE_FRAME c2_ref_frame;
232 int candidate_scores[MAX_MV_REFS]; 226 int candidate_scores[MAX_MV_REF_CANDIDATES];
233 int index = 0; 227 int index = 0;
234 int split_count = 0; 228 int split_count = 0;
235 int ref_weight = 0;
236 int valid_mv_ref;
237 int (*mv_ref_search)[2]; 229 int (*mv_ref_search)[2];
238 int *ref_distance_weight; 230 int *ref_distance_weight;
239 231
240 // Blank the reference vector lists and other local structures. 232 // Blank the reference vector lists and other local structures.
241 vpx_memset(mv_ref_list, 0, sizeof(int_mv) * MAX_MV_REFS); 233 vpx_memset(mv_ref_list, 0, sizeof(int_mv) * MAX_MV_REF_CANDIDATES);
242 vpx_memset(candidate_mvs, 0, sizeof(int_mv) * MAX_MV_REFS); 234 vpx_memset(candidate_mvs, 0, sizeof(int_mv) * MAX_MV_REF_CANDIDATES);
243 vpx_memset(candidate_scores, 0, sizeof(candidate_scores)); 235 vpx_memset(candidate_scores, 0, sizeof(candidate_scores));
244 236
245 #if CONFIG_SUPERBLOCKS 237 if (mbmi->sb_type) {
246 if (mbmi->encoded_as_sb) {
247 mv_ref_search = sb_mv_ref_search; 238 mv_ref_search = sb_mv_ref_search;
248 ref_distance_weight = sb_ref_distance_weight; 239 ref_distance_weight = sb_ref_distance_weight;
249 } else { 240 } else {
250 mv_ref_search = mb_mv_ref_search; 241 mv_ref_search = mb_mv_ref_search;
251 ref_distance_weight = mb_ref_distance_weight; 242 ref_distance_weight = mb_ref_distance_weight;
252 } 243 }
253 #else 244
254 mv_ref_search = mb_mv_ref_search; 245 // We first scan for candidate vectors that match the current reference frame
255 ref_distance_weight = mb_ref_distance_weight; 246 // Look at nearest neigbours
256 #endif
257 // Populate a list with candidate reference vectors from the
258 // spatial neighbours.
259 for (i = 0; i < 2; ++i) { 247 for (i = 0; i < 2; ++i) {
260 if (((mv_ref_search[i][0] << 7) >= xd->mb_to_left_edge) && 248 if (((mv_ref_search[i][0] << 7) >= xd->mb_to_left_edge) &&
261 ((mv_ref_search[i][1] << 7) >= xd->mb_to_top_edge)) { 249 ((mv_ref_search[i][1] << 7) >= xd->mb_to_top_edge)) {
262 250
263 candidate_mi = here + mv_ref_search[i][0] + 251 candidate_mi = here + mv_ref_search[i][0] +
264 (mv_ref_search[i][1] * xd->mode_info_stride); 252 (mv_ref_search[i][1] * xd->mode_info_stride);
265 253
266 valid_mv_ref = get_candidate_mvref(candidate_mi, ref_frame, 254 if (get_matching_candidate(candidate_mi, ref_frame, &c_refmv)) {
267 &c_ref_frame, &c_refmv, 255 clamp_mv(xd, &c_refmv);
268 &c2_ref_frame, &c2_refmv); 256 addmv_and_shuffle(candidate_mvs, candidate_scores,
257 &index, c_refmv, ref_distance_weight[i] + 16);
258 }
259 split_count += (candidate_mi->mbmi.mode == SPLITMV);
260 }
261 }
262 // Look in the last frame
263 candidate_mi = lf_here;
264 if (get_matching_candidate(candidate_mi, ref_frame, &c_refmv)) {
265 clamp_mv(xd, &c_refmv);
266 addmv_and_shuffle(candidate_mvs, candidate_scores,
267 &index, c_refmv, 18);
268 }
269 // More distant neigbours
270 for (i = 2; (i < MVREF_NEIGHBOURS) &&
271 (index < (MAX_MV_REF_CANDIDATES - 1)); ++i) {
272 if (((mv_ref_search[i][0] << 7) >= xd->mb_to_left_edge) &&
273 ((mv_ref_search[i][1] << 7) >= xd->mb_to_top_edge)) {
274 candidate_mi = here + mv_ref_search[i][0] +
275 (mv_ref_search[i][1] * xd->mode_info_stride);
269 276
270 // If there is a valid MV candidate then add it to the list 277 if (get_matching_candidate(candidate_mi, ref_frame, &c_refmv)) {
271 if (valid_mv_ref) { 278 clamp_mv(xd, &c_refmv);
272 scale_mv(xd, ref_frame, c_ref_frame, &c_refmv, ref_sign_bias );
273 ref_weight = ref_distance_weight[i] +
274 ((c_ref_frame == ref_frame) << 4);
275 split_count += (candidate_mi->mbmi.mode == SPLITMV);
276
277 addmv_and_shuffle(candidate_mvs, candidate_scores, 279 addmv_and_shuffle(candidate_mvs, candidate_scores,
278 &index, c_refmv, ref_weight); 280 &index, c_refmv, ref_distance_weight[i] + 16);
279
280 // If there is a second valid mv then add it as well.
281 if (c2_ref_frame > INTRA_FRAME) {
282 scale_mv(xd, ref_frame, c2_ref_frame, &c2_refmv, ref_sign_bias );
283 ref_weight = ref_distance_weight[i] +
284 ((c2_ref_frame == ref_frame) << 4);
285
286 addmv_and_shuffle(candidate_mvs, candidate_scores,
287 &index, c2_refmv, ref_weight);
288 }
289 } 281 }
290 } 282 }
291 } 283 }
292 284
293 // Look at the corresponding vector in the last frame 285 // If we have not found enough candidates consider ones where the
294 candidate_mi = lf_here; 286 // reference frame does not match. Break out when we have
295 valid_mv_ref = get_candidate_mvref(candidate_mi, ref_frame, 287 // MAX_MV_REF_CANDIDATES candidates.
296 &c_ref_frame, &c_refmv, 288 // Look first at spatial neighbours
297 &c2_ref_frame, &c2_refmv); 289 if (index < (MAX_MV_REF_CANDIDATES - 1)) {
290 for (i = 0; i < MVREF_NEIGHBOURS; ++i) {
291 if (((mv_ref_search[i][0] << 7) >= xd->mb_to_left_edge) &&
292 ((mv_ref_search[i][1] << 7) >= xd->mb_to_top_edge)) {
298 293
299 // If there is a valid MV candidate then add it to the list 294 candidate_mi = here + mv_ref_search[i][0] +
300 if (valid_mv_ref) { 295 (mv_ref_search[i][1] * xd->mode_info_stride);
301 scale_mv(xd, ref_frame, c_ref_frame, &c_refmv, ref_sign_bias );
302 ref_weight = 2 + ((c_ref_frame == ref_frame) << 4);
303 addmv_and_shuffle(candidate_mvs, candidate_scores,
304 &index, c_refmv, ref_weight);
305 296
306 // If there is a second valid mv then add it as well. 297 get_non_matching_candidates(candidate_mi, ref_frame,
307 if (c2_ref_frame > INTRA_FRAME) { 298 &c_ref_frame, &c_refmv,
308 scale_mv(xd, ref_frame, c2_ref_frame, &c2_refmv, ref_sign_bias ); 299 &c2_ref_frame, &c2_refmv);
309 ref_weight = ref_distance_weight[i] +
310 ((c2_ref_frame == ref_frame) << 4);
311 300
301 if (c_ref_frame != INTRA_FRAME) {
302 scale_mv(xd, ref_frame, c_ref_frame, &c_refmv, ref_sign_bias);
303 addmv_and_shuffle(candidate_mvs, candidate_scores,
304 &index, c_refmv, ref_distance_weight[i]);
305 }
306
307 if (c2_ref_frame != INTRA_FRAME) {
308 scale_mv(xd, ref_frame, c2_ref_frame, &c2_refmv, ref_sign_bias);
309 addmv_and_shuffle(candidate_mvs, candidate_scores,
310 &index, c2_refmv, ref_distance_weight[i]);
311 }
312 }
313
314 if (index >= (MAX_MV_REF_CANDIDATES - 1)) {
315 break;
316 }
317 }
318 }
319 // Look at the last frame
320 if (index < (MAX_MV_REF_CANDIDATES - 1)) {
321 candidate_mi = lf_here;
322 get_non_matching_candidates(candidate_mi, ref_frame,
323 &c_ref_frame, &c_refmv,
324 &c2_ref_frame, &c2_refmv);
325
326 if (c_ref_frame != INTRA_FRAME) {
327 scale_mv(xd, ref_frame, c_ref_frame, &c_refmv, ref_sign_bias);
312 addmv_and_shuffle(candidate_mvs, candidate_scores, 328 addmv_and_shuffle(candidate_mvs, candidate_scores,
313 &index, c2_refmv, ref_weight); 329 &index, c_refmv, 2);
330 }
331
332 if (c2_ref_frame != INTRA_FRAME) {
333 scale_mv(xd, ref_frame, c2_ref_frame, &c2_refmv, ref_sign_bias);
334 addmv_and_shuffle(candidate_mvs, candidate_scores,
335 &index, c2_refmv, 2);
314 } 336 }
315 } 337 }
316 338
317 // Populate a list with candidate reference vectors from the
318 // spatial neighbours.
319 for (i = 2; (i < MVREF_NEIGHBOURS) && (index < (MAX_MV_REFS - 2)); ++i) {
320 if (((mv_ref_search[i][0] << 7) >= xd->mb_to_left_edge) &&
321 ((mv_ref_search[i][1] << 7) >= xd->mb_to_top_edge)) {
322
323 candidate_mi = here + mv_ref_search[i][0] +
324 (mv_ref_search[i][1] * xd->mode_info_stride);
325
326 valid_mv_ref = get_candidate_mvref(candidate_mi, ref_frame,
327 &c_ref_frame, &c_refmv,
328 &c2_ref_frame, &c2_refmv);
329
330 // If there is a valid MV candidate then add it to the list
331 if (valid_mv_ref) {
332 scale_mv(xd, ref_frame, c_ref_frame, &c_refmv, ref_sign_bias );
333 ref_weight = ref_distance_weight[i] +
334 ((c_ref_frame == ref_frame) << 4);
335
336 addmv_and_shuffle(candidate_mvs, candidate_scores,
337 &index, c_refmv, ref_weight);
338
339 // If there is a second valid mv then add it as well.
340 if (c2_ref_frame > INTRA_FRAME) {
341 scale_mv(xd, ref_frame, c2_ref_frame, &c2_refmv, ref_sign_bias );
342 ref_weight = ref_distance_weight[i] +
343 ((c2_ref_frame == ref_frame) << 4);
344
345 addmv_and_shuffle(candidate_mvs, candidate_scores,
346 &index, c2_refmv, ref_weight);
347 }
348 }
349 }
350 }
351
352 // Make sure we are able to add 0,0
353 if (index > (MAX_MV_REFS - 1)) {
354 index = (MAX_MV_REFS - 1);
355 }
356
357 // Define inter mode coding context. 339 // Define inter mode coding context.
358 // 0,0 was best 340 // 0,0 was best
359 if (candidate_mvs[0].as_int == 0) { 341 if (candidate_mvs[0].as_int == 0) {
360 // 0,0 is only candidate 342 // 0,0 is only candidate
361 if (index <= 1) { 343 if (index <= 1) {
362 mbmi->mb_mode_context[ref_frame] = 0; 344 mbmi->mb_mode_context[ref_frame] = 0;
363 // non zero candidates candidates available 345 // non zero candidates candidates available
364 } else if (split_count == 0) { 346 } else if (split_count == 0) {
365 mbmi->mb_mode_context[ref_frame] = 1; 347 mbmi->mb_mode_context[ref_frame] = 1;
366 } else { 348 } else {
367 mbmi->mb_mode_context[ref_frame] = 2; 349 mbmi->mb_mode_context[ref_frame] = 2;
368 } 350 }
369 // Non zero best, No Split MV cases 351 // Non zero best, No Split MV cases
370 } else if (split_count == 0) { 352 } else if (split_count == 0) {
371 if (candidate_scores[0] >= 32) { 353 if (candidate_scores[0] >= 32) {
372 mbmi->mb_mode_context[ref_frame] = 3; 354 mbmi->mb_mode_context[ref_frame] = 3;
373 } else { 355 } else {
374 mbmi->mb_mode_context[ref_frame] = 4; 356 mbmi->mb_mode_context[ref_frame] = 4;
375 } 357 }
376 // Non zero best, some split mv 358 // Non zero best, some split mv
377 } else { 359 } else {
378 if (candidate_scores[0] >= 32) { 360 if (candidate_scores[0] >= 32) {
379 mbmi->mb_mode_context[ref_frame] = 5; 361 mbmi->mb_mode_context[ref_frame] = 5;
380 } else { 362 } else {
381 mbmi->mb_mode_context[ref_frame] = 6; 363 mbmi->mb_mode_context[ref_frame] = 6;
382 } 364 }
383 } 365 }
384 366
385 // 0,0 is always a valid reference. 367 // 0,0 is always a valid reference.
386 for (i = 0; i < index; ++i) { 368 for (i = 0; i < MAX_MV_REF_CANDIDATES; ++i) {
387 if (candidate_mvs[i].as_int == 0) 369 if (candidate_mvs[i].as_int == 0)
388 break; 370 break;
389 } 371 }
390 if (i == index) { 372 if (i == MAX_MV_REF_CANDIDATES) {
391 c_refmv.as_int = 0; 373 candidate_mvs[MAX_MV_REF_CANDIDATES-1].as_int = 0;
392 addmv_and_shuffle(candidate_mvs, candidate_scores,
393 &index, c_refmv, candidate_scores[3]+1 );
394 } 374 }
395 375
396 // Copy over the candidate list. 376 // Copy over the candidate list.
397 vpx_memcpy(mv_ref_list, candidate_mvs, sizeof(candidate_mvs)); 377 vpx_memcpy(mv_ref_list, candidate_mvs, sizeof(candidate_mvs));
398 } 378 }
OLDNEW
« 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