OLD | NEW |
1 | 1 |
2 /* | 2 /* |
3 * Copyright (c) 2012 The WebM project authors. All Rights Reserved. | 3 * Copyright (c) 2012 The WebM project authors. All Rights Reserved. |
4 * | 4 * |
5 * Use of this source code is governed by a BSD-style license | 5 * Use of this source code is governed by a BSD-style license |
6 * that can be found in the LICENSE file in the root of the source | 6 * that can be found in the LICENSE file in the root of the source |
7 * tree. An additional intellectual property rights grant can be found | 7 * tree. An additional intellectual property rights grant can be found |
8 * in the file PATENTS. All contributing project authors may | 8 * in the file PATENTS. All contributing project authors may |
9 * be found in the AUTHORS file in the root of the source tree. | 9 * be found in the AUTHORS file in the root of the source tree. |
10 */ | 10 */ |
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
141 if (ref_sign_bias[mbmi->ref_frame[ref]] != ref_sign_bias[this_ref_frame]) { | 141 if (ref_sign_bias[mbmi->ref_frame[ref]] != ref_sign_bias[this_ref_frame]) { |
142 mv.as_mv.row *= -1; | 142 mv.as_mv.row *= -1; |
143 mv.as_mv.col *= -1; | 143 mv.as_mv.col *= -1; |
144 } | 144 } |
145 return mv; | 145 return mv; |
146 } | 146 } |
147 | 147 |
148 // This macro is used to add a motion vector mv_ref list if it isn't | 148 // This macro is used to add a motion vector mv_ref list if it isn't |
149 // already in the list. If it's the second motion vector it will also | 149 // already in the list. If it's the second motion vector it will also |
150 // skip all additional processing and jump to done! | 150 // skip all additional processing and jump to done! |
151 #define ADD_MV_REF_LIST(MV) \ | 151 #define ADD_MV_REF_LIST(mv) \ |
152 do { \ | 152 do { \ |
153 if (refmv_count) { \ | 153 if (refmv_count) { \ |
154 if ((MV).as_int != mv_ref_list[0].as_int) { \ | 154 if ((mv).as_int != mv_ref_list[0].as_int) { \ |
155 mv_ref_list[refmv_count] = (MV); \ | 155 mv_ref_list[refmv_count] = (mv); \ |
156 goto Done; \ | 156 goto Done; \ |
157 } \ | 157 } \ |
158 } else { \ | 158 } else { \ |
159 mv_ref_list[refmv_count++] = (MV); \ | 159 mv_ref_list[refmv_count++] = (mv); \ |
160 } \ | 160 } \ |
161 } while (0) | 161 } while (0) |
162 | 162 |
163 // If either reference frame is different, not INTRA, and they | 163 // If either reference frame is different, not INTRA, and they |
164 // are different from each other scale and add the mv to our list. | 164 // are different from each other scale and add the mv to our list. |
165 #define IF_DIFF_REF_FRAME_ADD_MV(CANDIDATE) \ | 165 #define IF_DIFF_REF_FRAME_ADD_MV(mbmi) \ |
166 do { \ | 166 do { \ |
167 if ((CANDIDATE)->ref_frame[0] != ref_frame) \ | 167 if (is_inter_block(mbmi)) { \ |
168 ADD_MV_REF_LIST(scale_mv((CANDIDATE), 0, ref_frame, ref_sign_bias)); \ | 168 if ((mbmi)->ref_frame[0] != ref_frame) \ |
169 if ((CANDIDATE)->ref_frame[1] != ref_frame && \ | 169 ADD_MV_REF_LIST(scale_mv((mbmi), 0, ref_frame, ref_sign_bias)); \ |
170 has_second_ref(CANDIDATE) && \ | 170 if (has_second_ref(mbmi) && \ |
171 (CANDIDATE)->mv[1].as_int != (CANDIDATE)->mv[0].as_int) \ | 171 (mbmi)->ref_frame[1] != ref_frame && \ |
172 ADD_MV_REF_LIST(scale_mv((CANDIDATE), 1, ref_frame, ref_sign_bias)); \ | 172 (mbmi)->mv[1].as_int != (mbmi)->mv[0].as_int) \ |
| 173 ADD_MV_REF_LIST(scale_mv((mbmi), 1, ref_frame, ref_sign_bias)); \ |
| 174 } \ |
173 } while (0) | 175 } while (0) |
174 | 176 |
175 | 177 |
176 // Checks that the given mi_row, mi_col and search point | 178 // Checks that the given mi_row, mi_col and search point |
177 // are inside the borders of the tile. | 179 // are inside the borders of the tile. |
178 static INLINE int is_inside(const TileInfo *const tile, | 180 static INLINE int is_inside(const TileInfo *const tile, |
179 int mi_col, int mi_row, int mi_rows, | 181 int mi_col, int mi_row, int mi_rows, |
180 const POSITION *mi_pos) { | 182 const POSITION *mi_pos) { |
181 return !(mi_row + mi_pos->row < 0 || | 183 return !(mi_row + mi_pos->row < 0 || |
182 mi_col + mi_pos->col < tile->mi_col_start || | 184 mi_col + mi_pos->col < tile->mi_col_start || |
183 mi_row + mi_pos->row >= mi_rows || | 185 mi_row + mi_pos->row >= mi_rows || |
184 mi_col + mi_pos->col >= tile->mi_col_end); | 186 mi_col + mi_pos->col >= tile->mi_col_end); |
185 } | 187 } |
186 | 188 |
187 // This function searches the neighbourhood of a given MB/SB | 189 // This function searches the neighbourhood of a given MB/SB |
188 // to try and find candidate reference vectors. | 190 // to try and find candidate reference vectors. |
189 static void find_mv_refs_idx(const VP9_COMMON *cm, const MACROBLOCKD *xd, | 191 static void find_mv_refs_idx(const VP9_COMMON *cm, const MACROBLOCKD *xd, |
190 const TileInfo *const tile, | 192 const TileInfo *const tile, |
191 MODE_INFO *mi, const MODE_INFO *prev_mi, | 193 MODE_INFO *mi, MV_REFERENCE_FRAME ref_frame, |
192 MV_REFERENCE_FRAME ref_frame, | |
193 int_mv *mv_ref_list, | 194 int_mv *mv_ref_list, |
194 int block_idx, int mi_row, int mi_col) { | 195 int block, int mi_row, int mi_col) { |
195 const int *ref_sign_bias = cm->ref_frame_sign_bias; | 196 const int *ref_sign_bias = cm->ref_frame_sign_bias; |
196 int i, refmv_count = 0; | 197 int i, refmv_count = 0; |
| 198 const MODE_INFO *prev_mi = cm->coding_use_prev_mi && cm->prev_mi |
| 199 ? cm->prev_mi_grid_visible[mi_row * xd->mi_stride + mi_col] |
| 200 : NULL; |
| 201 const MB_MODE_INFO *const prev_mbmi = prev_mi ? &prev_mi->mbmi : NULL; |
| 202 |
| 203 |
197 const POSITION *const mv_ref_search = mv_ref_blocks[mi->mbmi.sb_type]; | 204 const POSITION *const mv_ref_search = mv_ref_blocks[mi->mbmi.sb_type]; |
198 const MB_MODE_INFO *const prev_mbmi = cm->coding_use_prev_mi && prev_mi ? | 205 |
199 &prev_mi->mbmi : NULL; | |
200 int different_ref_found = 0; | 206 int different_ref_found = 0; |
201 int context_counter = 0; | 207 int context_counter = 0; |
202 | 208 |
203 // Blank the reference vector list | 209 // Blank the reference vector list |
204 vpx_memset(mv_ref_list, 0, sizeof(*mv_ref_list) * MAX_MV_REF_CANDIDATES); | 210 vpx_memset(mv_ref_list, 0, sizeof(*mv_ref_list) * MAX_MV_REF_CANDIDATES); |
205 | 211 |
206 // The nearest 2 blocks are treated differently | 212 // The nearest 2 blocks are treated differently |
207 // if the size < 8x8 we get the mv from the bmi substructure, | 213 // if the size < 8x8 we get the mv from the bmi substructure, |
208 // and we also need to keep a mode count. | 214 // and we also need to keep a mode count. |
209 for (i = 0; i < 2; ++i) { | 215 for (i = 0; i < 2; ++i) { |
210 const POSITION *const mv_ref = &mv_ref_search[i]; | 216 const POSITION *const mv_ref = &mv_ref_search[i]; |
211 if (is_inside(tile, mi_col, mi_row, cm->mi_rows, mv_ref)) { | 217 if (is_inside(tile, mi_col, mi_row, cm->mi_rows, mv_ref)) { |
212 const MODE_INFO *const candidate_mi = xd->mi_8x8[mv_ref->col + mv_ref->row | 218 const MODE_INFO *const candidate_mi = xd->mi[mv_ref->col + mv_ref->row * |
213 * xd->mode_info_stride]; | 219 xd->mi_stride]; |
214 const MB_MODE_INFO *const candidate = &candidate_mi->mbmi; | 220 const MB_MODE_INFO *const candidate = &candidate_mi->mbmi; |
215 // Keep counts for entropy encoding. | 221 // Keep counts for entropy encoding. |
216 context_counter += mode_2_counter[candidate->mode]; | 222 context_counter += mode_2_counter[candidate->mode]; |
| 223 different_ref_found = 1; |
217 | 224 |
218 // Check if the candidate comes from the same reference frame. | 225 if (candidate->ref_frame[0] == ref_frame) |
219 if (candidate->ref_frame[0] == ref_frame) { | 226 ADD_MV_REF_LIST(get_sub_block_mv(candidate_mi, 0, mv_ref->col, block)); |
220 ADD_MV_REF_LIST(get_sub_block_mv(candidate_mi, 0, | 227 else if (candidate->ref_frame[1] == ref_frame) |
221 mv_ref->col, block_idx)); | 228 ADD_MV_REF_LIST(get_sub_block_mv(candidate_mi, 1, mv_ref->col, block)); |
222 different_ref_found = candidate->ref_frame[1] != ref_frame; | |
223 } else { | |
224 if (candidate->ref_frame[1] == ref_frame) | |
225 // Add second motion vector if it has the same ref_frame. | |
226 ADD_MV_REF_LIST(get_sub_block_mv(candidate_mi, 1, | |
227 mv_ref->col, block_idx)); | |
228 different_ref_found = 1; | |
229 } | |
230 } | 229 } |
231 } | 230 } |
232 | 231 |
233 // Check the rest of the neighbors in much the same way | 232 // Check the rest of the neighbors in much the same way |
234 // as before except we don't need to keep track of sub blocks or | 233 // as before except we don't need to keep track of sub blocks or |
235 // mode counts. | 234 // mode counts. |
236 for (; i < MVREF_NEIGHBOURS; ++i) { | 235 for (; i < MVREF_NEIGHBOURS; ++i) { |
237 const POSITION *const mv_ref = &mv_ref_search[i]; | 236 const POSITION *const mv_ref = &mv_ref_search[i]; |
238 if (is_inside(tile, mi_col, mi_row, cm->mi_rows, mv_ref)) { | 237 if (is_inside(tile, mi_col, mi_row, cm->mi_rows, mv_ref)) { |
239 const MB_MODE_INFO *const candidate = &xd->mi_8x8[mv_ref->col + | 238 const MB_MODE_INFO *const candidate = &xd->mi[mv_ref->col + mv_ref->row * |
240 mv_ref->row | 239 xd->mi_stride]->mbmi; |
241 * xd->mode_info_stride]->mbmi; | 240 different_ref_found = 1; |
242 | 241 |
243 if (candidate->ref_frame[0] == ref_frame) { | 242 if (candidate->ref_frame[0] == ref_frame) |
244 ADD_MV_REF_LIST(candidate->mv[0]); | 243 ADD_MV_REF_LIST(candidate->mv[0]); |
245 different_ref_found = candidate->ref_frame[1] != ref_frame; | 244 else if (candidate->ref_frame[1] == ref_frame) |
246 } else { | 245 ADD_MV_REF_LIST(candidate->mv[1]); |
247 if (candidate->ref_frame[1] == ref_frame) | |
248 ADD_MV_REF_LIST(candidate->mv[1]); | |
249 different_ref_found = 1; | |
250 } | |
251 } | 246 } |
252 } | 247 } |
253 | 248 |
254 // Check the last frame's mode and mv info. | 249 // Check the last frame's mode and mv info. |
255 if (prev_mbmi) { | 250 if (prev_mbmi) { |
256 if (prev_mbmi->ref_frame[0] == ref_frame) | 251 if (prev_mbmi->ref_frame[0] == ref_frame) |
257 ADD_MV_REF_LIST(prev_mbmi->mv[0]); | 252 ADD_MV_REF_LIST(prev_mbmi->mv[0]); |
258 else if (prev_mbmi->ref_frame[1] == ref_frame) | 253 else if (prev_mbmi->ref_frame[1] == ref_frame) |
259 ADD_MV_REF_LIST(prev_mbmi->mv[1]); | 254 ADD_MV_REF_LIST(prev_mbmi->mv[1]); |
260 } | 255 } |
261 | 256 |
262 // Since we couldn't find 2 mvs from the same reference frame | 257 // Since we couldn't find 2 mvs from the same reference frame |
263 // go back through the neighbors and find motion vectors from | 258 // go back through the neighbors and find motion vectors from |
264 // different reference frames. | 259 // different reference frames. |
265 if (different_ref_found) { | 260 if (different_ref_found) { |
266 for (i = 0; i < MVREF_NEIGHBOURS; ++i) { | 261 for (i = 0; i < MVREF_NEIGHBOURS; ++i) { |
267 const POSITION *mv_ref = &mv_ref_search[i]; | 262 const POSITION *mv_ref = &mv_ref_search[i]; |
268 if (is_inside(tile, mi_col, mi_row, cm->mi_rows, mv_ref)) { | 263 if (is_inside(tile, mi_col, mi_row, cm->mi_rows, mv_ref)) { |
269 const MB_MODE_INFO *const candidate = &xd->mi_8x8[mv_ref->col + | 264 const MB_MODE_INFO *const candidate = &xd->mi[mv_ref->col + mv_ref->row |
270 mv_ref->row | 265 * xd->mi_stride]->mbmi; |
271 * xd->mode_info_stride]->mbmi; | |
272 | 266 |
273 // If the candidate is INTRA we don't want to consider its mv. | 267 // If the candidate is INTRA we don't want to consider its mv. |
274 if (is_inter_block(candidate)) | 268 IF_DIFF_REF_FRAME_ADD_MV(candidate); |
275 IF_DIFF_REF_FRAME_ADD_MV(candidate); | |
276 } | 269 } |
277 } | 270 } |
278 } | 271 } |
279 | 272 |
280 // Since we still don't have a candidate we'll try the last frame. | 273 // Since we still don't have a candidate we'll try the last frame. |
281 if (prev_mbmi && is_inter_block(prev_mbmi)) | 274 if (prev_mbmi) |
282 IF_DIFF_REF_FRAME_ADD_MV(prev_mbmi); | 275 IF_DIFF_REF_FRAME_ADD_MV(prev_mbmi); |
283 | 276 |
284 Done: | 277 Done: |
285 | 278 |
286 mi->mbmi.mode_context[ref_frame] = counter_to_context[context_counter]; | 279 mi->mbmi.mode_context[ref_frame] = counter_to_context[context_counter]; |
287 | 280 |
288 // Clamp vectors | 281 // Clamp vectors |
289 for (i = 0; i < MAX_MV_REF_CANDIDATES; ++i) | 282 for (i = 0; i < MAX_MV_REF_CANDIDATES; ++i) |
290 clamp_mv_ref(&mv_ref_list[i].as_mv, xd); | 283 clamp_mv_ref(&mv_ref_list[i].as_mv, xd); |
291 } | 284 } |
292 | 285 |
293 void vp9_find_mv_refs(const VP9_COMMON *cm, const MACROBLOCKD *xd, | 286 void vp9_find_mv_refs(const VP9_COMMON *cm, const MACROBLOCKD *xd, |
294 const TileInfo *const tile, | 287 const TileInfo *const tile, |
295 MODE_INFO *mi, const MODE_INFO *prev_mi, | 288 MODE_INFO *mi, MV_REFERENCE_FRAME ref_frame, |
296 MV_REFERENCE_FRAME ref_frame, | |
297 int_mv *mv_ref_list, | 289 int_mv *mv_ref_list, |
298 int mi_row, int mi_col) { | 290 int mi_row, int mi_col) { |
299 find_mv_refs_idx(cm, xd, tile, mi, prev_mi, ref_frame, mv_ref_list, -1, | 291 find_mv_refs_idx(cm, xd, tile, mi, ref_frame, mv_ref_list, -1, |
300 mi_row, mi_col); | 292 mi_row, mi_col); |
301 } | 293 } |
302 | 294 |
303 static void lower_mv_precision(MV *mv, int allow_hp) { | 295 static void lower_mv_precision(MV *mv, int allow_hp) { |
304 const int use_hp = allow_hp && vp9_use_mv_hp(mv); | 296 const int use_hp = allow_hp && vp9_use_mv_hp(mv); |
305 if (!use_hp) { | 297 if (!use_hp) { |
306 if (mv->row & 1) | 298 if (mv->row & 1) |
307 mv->row += (mv->row > 0 ? -1 : 1); | 299 mv->row += (mv->row > 0 ? -1 : 1); |
308 if (mv->col & 1) | 300 if (mv->col & 1) |
309 mv->col += (mv->col > 0 ? -1 : 1); | 301 mv->col += (mv->col > 0 ? -1 : 1); |
(...skipping 11 matching lines...) Expand all Loading... |
321 } | 313 } |
322 *nearest = mvlist[0]; | 314 *nearest = mvlist[0]; |
323 *near = mvlist[1]; | 315 *near = mvlist[1]; |
324 } | 316 } |
325 | 317 |
326 void vp9_append_sub8x8_mvs_for_idx(VP9_COMMON *cm, MACROBLOCKD *xd, | 318 void vp9_append_sub8x8_mvs_for_idx(VP9_COMMON *cm, MACROBLOCKD *xd, |
327 const TileInfo *const tile, | 319 const TileInfo *const tile, |
328 int block, int ref, int mi_row, int mi_col, | 320 int block, int ref, int mi_row, int mi_col, |
329 int_mv *nearest, int_mv *near) { | 321 int_mv *nearest, int_mv *near) { |
330 int_mv mv_list[MAX_MV_REF_CANDIDATES]; | 322 int_mv mv_list[MAX_MV_REF_CANDIDATES]; |
331 MODE_INFO *const mi = xd->mi_8x8[0]; | 323 MODE_INFO *const mi = xd->mi[0]; |
332 b_mode_info *bmi = mi->bmi; | 324 b_mode_info *bmi = mi->bmi; |
333 int n; | 325 int n; |
334 | 326 |
335 assert(MAX_MV_REF_CANDIDATES == 2); | 327 assert(MAX_MV_REF_CANDIDATES == 2); |
336 | 328 |
337 find_mv_refs_idx(cm, xd, tile, mi, xd->last_mi, mi->mbmi.ref_frame[ref], | 329 find_mv_refs_idx(cm, xd, tile, mi, mi->mbmi.ref_frame[ref], mv_list, block, |
338 mv_list, block, mi_row, mi_col); | 330 mi_row, mi_col); |
339 | 331 |
340 near->as_int = 0; | 332 near->as_int = 0; |
341 switch (block) { | 333 switch (block) { |
342 case 0: | 334 case 0: |
343 nearest->as_int = mv_list[0].as_int; | 335 nearest->as_int = mv_list[0].as_int; |
344 near->as_int = mv_list[1].as_int; | 336 near->as_int = mv_list[1].as_int; |
345 break; | 337 break; |
346 case 1: | 338 case 1: |
347 case 2: | 339 case 2: |
348 nearest->as_int = bmi[0].as_mv[ref].as_int; | 340 nearest->as_int = bmi[0].as_mv[ref].as_int; |
(...skipping 15 matching lines...) Expand all Loading... |
364 if (nearest->as_int != candidates[n].as_int) { | 356 if (nearest->as_int != candidates[n].as_int) { |
365 near->as_int = candidates[n].as_int; | 357 near->as_int = candidates[n].as_int; |
366 break; | 358 break; |
367 } | 359 } |
368 break; | 360 break; |
369 } | 361 } |
370 default: | 362 default: |
371 assert("Invalid block index."); | 363 assert("Invalid block index."); |
372 } | 364 } |
373 } | 365 } |
OLD | NEW |