| OLD | NEW |
| 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 } | |
| OLD | NEW |