| 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 |