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

Side by Side Diff: source/libvpx/vp9/common/vp9_mvref_common.c

Issue 23600008: libvpx: Pull from upstream (Closed) Base URL: svn://chrome-svn/chrome/trunk/deps/third_party/libvpx/
Patch Set: Created 7 years, 3 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_onyxc_int.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 const int mv_ref_blocks[BLOCK_SIZE_TYPES][MVREF_NEIGHBOURS][2] = { 14
15 // SB4X4 15 typedef enum {
16 {{0, -1}, {-1, 0}, {-1, -1}, {0, -2}, {-2, 0}, {-1, -2}, {-2, -1}, {-2, -2}}, 16 BOTH_ZERO = 0,
17 // SB4X8 17 ZERO_PLUS_PREDICTED = 1,
18 {{0, -1}, {-1, 0}, {-1, -1}, {0, -2}, {-2, 0}, {-1, -2}, {-2, -1}, {-2, -2}}, 18 BOTH_PREDICTED = 2,
19 // SB8X4 19 NEW_PLUS_NON_INTRA = 3,
20 {{0, -1}, {-1, 0}, {-1, -1}, {0, -2}, {-2, 0}, {-1, -2}, {-2, -1}, {-2, -2}}, 20 BOTH_NEW = 4,
21 // SB8X8 21 INTRA_PLUS_NON_INTRA = 5,
22 {{0, -1}, {-1, 0}, {-1, -1}, {0, -2}, {-2, 0}, {-1, -2}, {-2, -1}, {-2, -2}}, 22 BOTH_INTRA = 6,
23 // SB8X16 23 INVALID_CASE = 9
24 } motion_vector_context;
25
26 // This is used to figure out a context for the ref blocks. The code flattens
27 // an array that would have 3 possible counts (0, 1 & 2) for 3 choices by
28 // adding 9 for each intra block, 3 for each zero mv and 1 for each new
29 // motion vector. This single number is then converted into a context
30 // with a single lookup ( counter_to_context ).
31 static const int mode_2_counter[MB_MODE_COUNT] = {
32 9, // DC_PRED
33 9, // V_PRED
34 9, // H_PRED
35 9, // D45_PRED
36 9, // D135_PRED
37 9, // D117_PRED
38 9, // D153_PRED
39 9, // D207_PRED
40 9, // D63_PRED
41 9, // TM_PRED
42 0, // NEARESTMV
43 0, // NEARMV
44 3, // ZEROMV
45 1, // NEWMV
46 };
47
48 // There are 3^3 different combinations of 3 counts that can be either 0,1 or
49 // 2. However the actual count can never be greater than 2 so the highest
50 // counter we need is 18. 9 is an invalid counter that's never used.
51 static const int counter_to_context[19] = {
52 BOTH_PREDICTED, // 0
53 NEW_PLUS_NON_INTRA, // 1
54 BOTH_NEW, // 2
55 ZERO_PLUS_PREDICTED, // 3
56 NEW_PLUS_NON_INTRA, // 4
57 INVALID_CASE, // 5
58 BOTH_ZERO, // 6
59 INVALID_CASE, // 7
60 INVALID_CASE, // 8
61 INTRA_PLUS_NON_INTRA, // 9
62 INTRA_PLUS_NON_INTRA, // 10
63 INVALID_CASE, // 11
64 INTRA_PLUS_NON_INTRA, // 12
65 INVALID_CASE, // 13
66 INVALID_CASE, // 14
67 INVALID_CASE, // 15
68 INVALID_CASE, // 16
69 INVALID_CASE, // 17
70 BOTH_INTRA // 18
71 };
72
73 static const MV mv_ref_blocks[BLOCK_SIZES][MVREF_NEIGHBOURS] = {
74 // 4X4
75 {{-1, 0}, {0, -1}, {-1, -1}, {-2, 0}, {0, -2}, {-2, -1}, {-1, -2}, {-2, -2}},
76 // 4X8
77 {{-1, 0}, {0, -1}, {-1, -1}, {-2, 0}, {0, -2}, {-2, -1}, {-1, -2}, {-2, -2}},
78 // 8X4
79 {{-1, 0}, {0, -1}, {-1, -1}, {-2, 0}, {0, -2}, {-2, -1}, {-1, -2}, {-2, -2}},
80 // 8X8
81 {{-1, 0}, {0, -1}, {-1, -1}, {-2, 0}, {0, -2}, {-2, -1}, {-1, -2}, {-2, -2}},
82 // 8X16
83 {{0, -1}, {-1, 0}, {1, -1}, {-1, -1}, {0, -2}, {-2, 0}, {-2, -1}, {-1, -2}},
84 // 16X8
24 {{-1, 0}, {0, -1}, {-1, 1}, {-1, -1}, {-2, 0}, {0, -2}, {-1, -2}, {-2, -1}}, 85 {{-1, 0}, {0, -1}, {-1, 1}, {-1, -1}, {-2, 0}, {0, -2}, {-1, -2}, {-2, -1}},
25 // SB16X8 86 // 16X16
26 {{0, -1}, {-1, 0}, {1, -1}, {-1, -1}, {0, -2}, {-2, 0}, {-2, -1}, {-1, -2}}, 87 {{-1, 0}, {0, -1}, {-1, 1}, {1, -1}, {-1, -1}, {-3, 0}, {0, -3}, {-3, -3}},
27 // SB16X16 88 // 16X32
28 {{0, -1}, {-1, 0}, {1, -1}, {-1, 1}, {-1, -1}, {0, -3}, {-3, 0}, {-3, -3}}, 89 {{0, -1}, {-1, 0}, {2, -1}, {-1, -1}, {-1, 1}, {0, -3}, {-3, 0}, {-3, -3}},
29 // SB16X32 90 // 32X16
30 {{-1, 0}, {0, -1}, {-1, 2}, {-1, -1}, {1, -1}, {-3, 0}, {0, -3}, {-3, -3}}, 91 {{-1, 0}, {0, -1}, {-1, 2}, {-1, -1}, {1, -1}, {-3, 0}, {0, -3}, {-3, -3}},
31 // SB32X16 92 // 32X32
32 {{0, -1}, {-1, 0}, {2, -1}, {-1, -1}, {-1, 1}, {0, -3}, {-3, 0}, {-3, -3}}, 93 {{-1, 1}, {1, -1}, {-1, 2}, {2, -1}, {-1, -1}, {-3, 0}, {0, -3}, {-3, -3}},
33 // SB32X32 94 // 32X64
34 {{1, -1}, {-1, 1}, {2, -1}, {-1, 2}, {-1, -1}, {0, -3}, {-3, 0}, {-3, -3}}, 95 {{0, -1}, {-1, 0}, {4, -1}, {-1, 2}, {-1, -1}, {0, -3}, {-3, 0}, {2, -1}},
35 // SB32X64 96 // 64X32
36 {{-1, 0}, {0, -1}, {-1, 4}, {2, -1}, {-1, -1}, {-3, 0}, {0, -3}, {-1, 2}}, 97 {{-1, 0}, {0, -1}, {-1, 4}, {2, -1}, {-1, -1}, {-3, 0}, {0, -3}, {-1, 2}},
37 // SB64X32 98 // 64X64
38 {{0, -1}, {-1, 0}, {4, -1}, {-1, 2}, {-1, -1}, {0, -3}, {-3, 0}, {2, -1}}, 99 {{-1, 3}, {3, -1}, {-1, 4}, {4, -1}, {-1, -1}, {-1, 0}, {0, -1}, {-1, 6}}
39 // SB64X64 100 };
40 {{3, -1}, {-1, 3}, {4, -1}, {-1, 4}, {-1, -1}, {0, -1}, {-1, 0}, {6, -1}} 101
41 }; 102 static const int idx_n_column_to_subblock[4][2] = {
103 {1, 2},
104 {1, 3},
105 {3, 2},
106 {3, 3}
107 };
108
42 // clamp_mv_ref 109 // clamp_mv_ref
43 #define MV_BORDER (16 << 3) // Allow 16 pels in 1/8th pel units 110 #define MV_BORDER (16 << 3) // Allow 16 pels in 1/8th pel units
44 111
45 static void clamp_mv_ref(const MACROBLOCKD *xd, int_mv *mv) { 112 static void clamp_mv_ref(MV *mv, const MACROBLOCKD *xd) {
46 mv->as_mv.col = clamp(mv->as_mv.col, xd->mb_to_left_edge - MV_BORDER, 113 clamp_mv(mv, xd->mb_to_left_edge - MV_BORDER,
47 xd->mb_to_right_edge + MV_BORDER); 114 xd->mb_to_right_edge + MV_BORDER,
48 mv->as_mv.row = clamp(mv->as_mv.row, xd->mb_to_top_edge - MV_BORDER, 115 xd->mb_to_top_edge - MV_BORDER,
49 xd->mb_to_bottom_edge + MV_BORDER); 116 xd->mb_to_bottom_edge + MV_BORDER);
50 } 117 }
51 118
52 // Gets a candidate reference motion vector from the given mode info 119 // This function returns either the appropriate sub block or block's mv
53 // structure if one exists that matches the given reference frame. 120 // on whether the block_size < 8x8 and we have check_sub_blocks set.
54 static int get_matching_candidate(const MODE_INFO *candidate_mi, 121 static INLINE int_mv get_sub_block_mv(const MODE_INFO *candidate,
55 MV_REFERENCE_FRAME ref_frame, 122 int check_sub_blocks, int which_mv,
56 int_mv *c_mv, int block_idx) { 123 int search_col, int block_idx) {
57 if (ref_frame == candidate_mi->mbmi.ref_frame[0]) { 124 return check_sub_blocks && candidate->mbmi.sb_type < BLOCK_8X8
58 if (block_idx >= 0 && candidate_mi->mbmi.sb_type < BLOCK_SIZE_SB8X8) 125 ? candidate->bmi[idx_n_column_to_subblock[block_idx][search_col == 0]]
59 c_mv->as_int = candidate_mi->bmi[block_idx].as_mv[0].as_int; 126 .as_mv[which_mv]
60 else 127 : candidate->mbmi.mv[which_mv];
61 c_mv->as_int = candidate_mi->mbmi.mv[0].as_int;
62 } else if (ref_frame == candidate_mi->mbmi.ref_frame[1]) {
63 if (block_idx >= 0 && candidate_mi->mbmi.sb_type < BLOCK_SIZE_SB8X8)
64 c_mv->as_int = candidate_mi->bmi[block_idx].as_mv[1].as_int;
65 else
66 c_mv->as_int = candidate_mi->mbmi.mv[1].as_int;
67 } else {
68 return 0;
69 }
70
71 return 1;
72 }
73
74 // Gets candidate reference motion vector(s) from the given mode info
75 // structure if they exists and do NOT match the given reference frame.
76 static void get_non_matching_candidates(const MODE_INFO *candidate_mi,
77 MV_REFERENCE_FRAME ref_frame,
78 MV_REFERENCE_FRAME *c_ref_frame,
79 int_mv *c_mv,
80 MV_REFERENCE_FRAME *c2_ref_frame,
81 int_mv *c2_mv) {
82
83 c_mv->as_int = 0;
84 c2_mv->as_int = 0;
85 *c_ref_frame = INTRA_FRAME;
86 *c2_ref_frame = INTRA_FRAME;
87
88 // If first candidate not valid neither will be.
89 if (candidate_mi->mbmi.ref_frame[0] > INTRA_FRAME) {
90 // First candidate
91 if (candidate_mi->mbmi.ref_frame[0] != ref_frame) {
92 *c_ref_frame = candidate_mi->mbmi.ref_frame[0];
93 c_mv->as_int = candidate_mi->mbmi.mv[0].as_int;
94 }
95
96 // Second candidate
97 if ((candidate_mi->mbmi.ref_frame[1] > INTRA_FRAME) &&
98 (candidate_mi->mbmi.ref_frame[1] != ref_frame) &&
99 (candidate_mi->mbmi.mv[1].as_int != candidate_mi->mbmi.mv[0].as_int)) {
100 *c2_ref_frame = candidate_mi->mbmi.ref_frame[1];
101 c2_mv->as_int = candidate_mi->mbmi.mv[1].as_int;
102 }
103 }
104 } 128 }
105 129
106 130
107 // Performs mv sign inversion if indicated by the reference frame combination. 131 // Performs mv sign inversion if indicated by the reference frame combination.
108 static void scale_mv(MACROBLOCKD *xd, MV_REFERENCE_FRAME this_ref_frame, 132 static INLINE int_mv scale_mv(const MB_MODE_INFO *mbmi, int ref,
109 MV_REFERENCE_FRAME candidate_ref_frame, 133 const MV_REFERENCE_FRAME this_ref_frame,
110 int_mv *candidate_mv, int *ref_sign_bias) { 134 const int *ref_sign_bias) {
111 135 int_mv mv = mbmi->mv[ref];
112 // Sign inversion where appropriate. 136 if (ref_sign_bias[mbmi->ref_frame[ref]] != ref_sign_bias[this_ref_frame]) {
113 if (ref_sign_bias[candidate_ref_frame] != ref_sign_bias[this_ref_frame]) { 137 mv.as_mv.row *= -1;
114 candidate_mv->as_mv.row = -candidate_mv->as_mv.row; 138 mv.as_mv.col *= -1;
115 candidate_mv->as_mv.col = -candidate_mv->as_mv.col; 139 }
116 } 140 return mv;
117 } 141 }
118 142
119 // Add a candidate mv. 143 // This macro is used to add a motion vector mv_ref list if it isn't
120 // Discard if it has already been seen. 144 // already in the list. If it's the second motion vector it will also
121 static void add_candidate_mv(int_mv *mv_list, int *mv_scores, 145 // skip all additional processing and jump to done!
122 int *candidate_count, int_mv candidate_mv, 146 #define ADD_MV_REF_LIST(MV) \
123 int weight) { 147 do { \
124 if (*candidate_count == 0) { 148 if (refmv_count) { \
125 mv_list[0].as_int = candidate_mv.as_int; 149 if ((MV).as_int != mv_ref_list[0].as_int) { \
126 mv_scores[0] = weight; 150 mv_ref_list[refmv_count] = (MV); \
127 *candidate_count += 1; 151 goto Done; \
128 } else if ((*candidate_count == 1) && 152 } \
129 (candidate_mv.as_int != mv_list[0].as_int)) { 153 } else { \
130 mv_list[1].as_int = candidate_mv.as_int; 154 mv_ref_list[refmv_count++] = (MV); \
131 mv_scores[1] = weight; 155 } \
132 *candidate_count += 1; 156 } while (0)
133 } 157
158 // If either reference frame is different, not INTRA, and they
159 // are different from each other scale and add the mv to our list.
160 #define IF_DIFF_REF_FRAME_ADD_MV(CANDIDATE) \
161 do { \
162 if ((CANDIDATE)->ref_frame[0] != ref_frame) \
163 ADD_MV_REF_LIST(scale_mv((CANDIDATE), 0, ref_frame, ref_sign_bias)); \
164 if ((CANDIDATE)->ref_frame[1] != ref_frame && \
165 has_second_ref(CANDIDATE) && \
166 (CANDIDATE)->mv[1].as_int != (CANDIDATE)->mv[0].as_int) \
167 ADD_MV_REF_LIST(scale_mv((CANDIDATE), 1, ref_frame, ref_sign_bias)); \
168 } while (0)
169
170
171 // Checks that the given mi_row, mi_col and search point
172 // are inside the borders of the tile.
173 static INLINE int is_inside(const VP9_COMMON *cm, int mi_col, int mi_row,
174 const MV *mv) {
175 return !(mi_row + mv->row < 0 ||
176 mi_col + mv->col < cm->cur_tile_mi_col_start ||
177 mi_row + mv->row >= cm->mi_rows ||
178 mi_col + mv->col >= cm->cur_tile_mi_col_end);
134 } 179 }
135 180
136 // This function searches the neighbourhood of a given MB/SB 181 // This function searches the neighbourhood of a given MB/SB
137 // to try and find candidate reference vectors. 182 // to try and find candidate reference vectors.
138 // 183 void vp9_find_mv_refs_idx(const VP9_COMMON *cm, const MACROBLOCKD *xd,
139 void vp9_find_mv_refs_idx(VP9_COMMON *cm, MACROBLOCKD *xd, MODE_INFO *here, 184 MODE_INFO *mi, const MODE_INFO *prev_mi,
140 MODE_INFO *lf_here, MV_REFERENCE_FRAME ref_frame, 185 MV_REFERENCE_FRAME ref_frame,
141 int_mv *mv_ref_list, int *ref_sign_bias, 186 int_mv *mv_ref_list,
142 int block_idx) { 187 int block_idx,
143 int i; 188 int mi_row, int mi_col) {
144 MODE_INFO *candidate_mi; 189 const int *ref_sign_bias = cm->ref_frame_sign_bias;
145 MB_MODE_INFO * mbmi = &xd->mode_info_context->mbmi; 190 int i, refmv_count = 0;
146 int_mv c_refmv; 191 const MV *const mv_ref_search = mv_ref_blocks[mi->mbmi.sb_type];
147 int_mv c2_refmv; 192 const MB_MODE_INFO *const prev_mbmi = prev_mi ? &prev_mi->mbmi : NULL;
148 MV_REFERENCE_FRAME c_ref_frame; 193 int different_ref_found = 0;
149 MV_REFERENCE_FRAME c2_ref_frame; 194 int context_counter = 0;
150 int candidate_scores[MAX_MV_REF_CANDIDATES] = { 0 }; 195
151 int refmv_count = 0; 196 // Blank the reference vector list
152 const int (*mv_ref_search)[2] = mv_ref_blocks[mbmi->sb_type]; 197 vpx_memset(mv_ref_list, 0, sizeof(*mv_ref_list) * MAX_MV_REF_CANDIDATES);
153 const int mi_col = get_mi_col(xd); 198
154 const int mi_row = get_mi_row(xd); 199 // The nearest 2 blocks are treated differently
155 int intra_count = 0; 200 // if the size < 8x8 we get the mv from the bmi substructure,
156 int zero_count = 0; 201 // and we also need to keep a mode count.
157 int newmv_count = 0;
158 int x_idx = 0, y_idx = 0;
159
160 // Blank the reference vector lists and other local structures.
161 vpx_memset(mv_ref_list, 0, sizeof(int_mv) * MAX_MV_REF_CANDIDATES);
162
163 if (mbmi->sb_type < BLOCK_SIZE_SB8X8) {
164 x_idx = block_idx & 1;
165 y_idx = block_idx >> 1;
166 }
167
168 // We first scan for candidate vectors that match the current reference frame
169 // Look at nearest neigbours
170 for (i = 0; i < 2; ++i) { 202 for (i = 0; i < 2; ++i) {
171 const int mi_search_col = mi_col + mv_ref_search[i][0]; 203 const MV *const mv_ref = &mv_ref_search[i];
172 const int mi_search_row = mi_row + mv_ref_search[i][1]; 204 if (is_inside(cm, mi_col, mi_row, mv_ref)) {
173 if ((mi_search_col >= cm->cur_tile_mi_col_start) && 205 const int check_sub_blocks = block_idx >= 0;
174 (mi_search_col < cm->cur_tile_mi_col_end) && 206 const MODE_INFO *const candidate_mi = &mi[mv_ref->col + mv_ref->row
175 (mi_search_row >= 0) && (mi_search_row < cm->mi_rows)) { 207 * xd->mode_info_stride];
176 int b; 208 const MB_MODE_INFO *const candidate = &candidate_mi->mbmi;
177 209 // Keep counts for entropy encoding.
178 candidate_mi = here + mv_ref_search[i][0] + 210 context_counter += mode_2_counter[candidate->mode];
179 (mv_ref_search[i][1] * xd->mode_info_stride); 211
180 212 // Check if the candidate comes from the same reference frame.
181 if (block_idx >= 0) { 213 if (candidate->ref_frame[0] == ref_frame) {
182 if (mv_ref_search[i][0]) 214 ADD_MV_REF_LIST(get_sub_block_mv(candidate_mi, check_sub_blocks, 0,
183 b = 1 + y_idx * 2; 215 mv_ref->col, block_idx));
184 else 216 different_ref_found = candidate->ref_frame[1] != ref_frame;
185 b = 2 + x_idx;
186 } else { 217 } else {
187 b = -1; 218 if (candidate->ref_frame[1] == ref_frame)
188 } 219 // Add second motion vector if it has the same ref_frame.
189 if (get_matching_candidate(candidate_mi, ref_frame, &c_refmv, b)) { 220 ADD_MV_REF_LIST(get_sub_block_mv(candidate_mi, check_sub_blocks, 1,
190 add_candidate_mv(mv_ref_list, candidate_scores, 221 mv_ref->col, block_idx));
191 &refmv_count, c_refmv, 16); 222 different_ref_found = 1;
192 }
193
194 // Count number of neihgbours coded intra and zeromv
195 intra_count += (candidate_mi->mbmi.mode < NEARESTMV);
196 zero_count += (candidate_mi->mbmi.mode == ZEROMV);
197 newmv_count += (candidate_mi->mbmi.mode >= NEWMV);
198 }
199 }
200
201 // More distant neigbours
202 for (i = 2; (i < MVREF_NEIGHBOURS) &&
203 (refmv_count < MAX_MV_REF_CANDIDATES); ++i) {
204 const int mi_search_col = mi_col + mv_ref_search[i][0];
205 const int mi_search_row = mi_row + mv_ref_search[i][1];
206 if ((mi_search_col >= cm->cur_tile_mi_col_start) &&
207 (mi_search_col < cm->cur_tile_mi_col_end) &&
208 (mi_search_row >= 0) && (mi_search_row < cm->mi_rows)) {
209 candidate_mi = here + mv_ref_search[i][0] +
210 (mv_ref_search[i][1] * xd->mode_info_stride);
211
212 if (get_matching_candidate(candidate_mi, ref_frame, &c_refmv, -1)) {
213 add_candidate_mv(mv_ref_list, candidate_scores,
214 &refmv_count, c_refmv, 16);
215 } 223 }
216 } 224 }
217 } 225 }
218 226
219 // Look in the last frame if it exists 227 // Check the rest of the neighbors in much the same way
220 if (lf_here && (refmv_count < MAX_MV_REF_CANDIDATES)) { 228 // as before except we don't need to keep track of sub blocks or
221 candidate_mi = lf_here; 229 // mode counts.
222 if (get_matching_candidate(candidate_mi, ref_frame, &c_refmv, -1)) { 230 for (; i < MVREF_NEIGHBOURS; ++i) {
223 add_candidate_mv(mv_ref_list, candidate_scores, 231 const MV *const mv_ref = &mv_ref_search[i];
224 &refmv_count, c_refmv, 16); 232 if (is_inside(cm, mi_col, mi_row, mv_ref)) {
225 } 233 const MB_MODE_INFO *const candidate = &mi[mv_ref->col + mv_ref->row
226 } 234 * xd->mode_info_stride].mbmi;
227 235
228 // If we have not found enough candidates consider ones where the 236 if (candidate->ref_frame[0] == ref_frame) {
229 // reference frame does not match. Break out when we have 237 ADD_MV_REF_LIST(candidate->mv[0]);
230 // MAX_MV_REF_CANDIDATES candidates. 238 different_ref_found = candidate->ref_frame[1] != ref_frame;
231 // Look first at spatial neighbours 239 } else {
232 for (i = 0; (i < MVREF_NEIGHBOURS) && 240 if (candidate->ref_frame[1] == ref_frame)
233 (refmv_count < MAX_MV_REF_CANDIDATES); ++i) { 241 ADD_MV_REF_LIST(candidate->mv[1]);
234 const int mi_search_col = mi_col + mv_ref_search[i][0]; 242 different_ref_found = 1;
235 const int mi_search_row = mi_row + mv_ref_search[i][1];
236 if ((mi_search_col >= cm->cur_tile_mi_col_start) &&
237 (mi_search_col < cm->cur_tile_mi_col_end) &&
238 (mi_search_row >= 0) && (mi_search_row < cm->mi_rows)) {
239 candidate_mi = here + mv_ref_search[i][0] +
240 (mv_ref_search[i][1] * xd->mode_info_stride);
241
242 get_non_matching_candidates(candidate_mi, ref_frame,
243 &c_ref_frame, &c_refmv,
244 &c2_ref_frame, &c2_refmv);
245
246 if (c_ref_frame != INTRA_FRAME) {
247 scale_mv(xd, ref_frame, c_ref_frame, &c_refmv, ref_sign_bias);
248 add_candidate_mv(mv_ref_list, candidate_scores,
249 &refmv_count, c_refmv, 1);
250 }
251
252 if (c2_ref_frame != INTRA_FRAME) {
253 scale_mv(xd, ref_frame, c2_ref_frame, &c2_refmv, ref_sign_bias);
254 add_candidate_mv(mv_ref_list, candidate_scores,
255 &refmv_count, c2_refmv, 1);
256 } 243 }
257 } 244 }
258 } 245 }
259 246
260 // Look at the last frame if it exists 247 // Check the last frame's mode and mv info.
261 if (lf_here && (refmv_count < MAX_MV_REF_CANDIDATES)) { 248 if (prev_mbmi) {
262 candidate_mi = lf_here; 249 if (prev_mbmi->ref_frame[0] == ref_frame)
263 get_non_matching_candidates(candidate_mi, ref_frame, 250 ADD_MV_REF_LIST(prev_mbmi->mv[0]);
264 &c_ref_frame, &c_refmv, 251 else if (prev_mbmi->ref_frame[1] == ref_frame)
265 &c2_ref_frame, &c2_refmv); 252 ADD_MV_REF_LIST(prev_mbmi->mv[1]);
266 253 }
267 if (c_ref_frame != INTRA_FRAME) { 254
268 scale_mv(xd, ref_frame, c_ref_frame, &c_refmv, ref_sign_bias); 255 // Since we couldn't find 2 mvs from the same reference frame
269 add_candidate_mv(mv_ref_list, candidate_scores, 256 // go back through the neighbors and find motion vectors from
270 &refmv_count, c_refmv, 1); 257 // different reference frames.
258 if (different_ref_found) {
259 for (i = 0; i < MVREF_NEIGHBOURS; ++i) {
260 const MV *mv_ref = &mv_ref_search[i];
261 if (is_inside(cm, mi_col, mi_row, mv_ref)) {
262 const MB_MODE_INFO *const candidate = &mi[mv_ref->col + mv_ref->row
263 * xd->mode_info_stride].mbmi;
264
265 // If the candidate is INTRA we don't want to consider its mv.
266 if (is_inter_block(candidate))
267 IF_DIFF_REF_FRAME_ADD_MV(candidate);
268 }
271 } 269 }
272 270 }
273 if (c2_ref_frame != INTRA_FRAME) { 271
274 scale_mv(xd, ref_frame, c2_ref_frame, &c2_refmv, ref_sign_bias); 272 // Since we still don't have a candidate we'll try the last frame.
275 add_candidate_mv(mv_ref_list, candidate_scores, 273 if (prev_mbmi && is_inter_block(prev_mbmi))
276 &refmv_count, c2_refmv, 1); 274 IF_DIFF_REF_FRAME_ADD_MV(prev_mbmi);
277 } 275
278 } 276 Done:
279 277
280 if (!intra_count) { 278 mi->mbmi.mode_context[ref_frame] = counter_to_context[context_counter];
281 if (!newmv_count) {
282 // 0 = both zero mv
283 // 1 = one zero mv + one a predicted mv
284 // 2 = two predicted mvs
285 mbmi->mb_mode_context[ref_frame] = 2 - zero_count;
286 } else {
287 // 3 = one predicted/zero and one new mv
288 // 4 = two new mvs
289 mbmi->mb_mode_context[ref_frame] = 2 + newmv_count;
290 }
291 } else {
292 // 5 = one intra neighbour + x
293 // 6 = two intra neighbours
294 mbmi->mb_mode_context[ref_frame] = 4 + intra_count;
295 }
296 279
297 // Clamp vectors 280 // Clamp vectors
298 for (i = 0; i < MAX_MV_REF_CANDIDATES; ++i) { 281 for (i = 0; i < MAX_MV_REF_CANDIDATES; ++i)
299 clamp_mv_ref(xd, &mv_ref_list[i]); 282 clamp_mv_ref(&mv_ref_list[i].as_mv, xd);
300 } 283 }
301 }
OLDNEW
« no previous file with comments | « source/libvpx/vp9/common/vp9_mvref_common.h ('k') | source/libvpx/vp9/common/vp9_onyxc_int.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698