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 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
101 }; | 101 }; |
102 | 102 |
103 static const int idx_n_column_to_subblock[4][2] = { | 103 static const int idx_n_column_to_subblock[4][2] = { |
104 {1, 2}, | 104 {1, 2}, |
105 {1, 3}, | 105 {1, 3}, |
106 {3, 2}, | 106 {3, 2}, |
107 {3, 3} | 107 {3, 3} |
108 }; | 108 }; |
109 | 109 |
110 // clamp_mv_ref | 110 // clamp_mv_ref |
111 #define MV_BORDER (16 << 3) // Allow 16 pels in 1/8th pel units | 111 #define MV_BORDER (16 << 3) // Allow 16 pels in 1/8th pel units |
112 | 112 |
113 static void clamp_mv_ref(MV *mv, const MACROBLOCKD *xd) { | 113 static void clamp_mv_ref(MV *mv, const MACROBLOCKD *xd) { |
114 clamp_mv(mv, xd->mb_to_left_edge - MV_BORDER, | 114 clamp_mv(mv, xd->mb_to_left_edge - MV_BORDER, |
115 xd->mb_to_right_edge + MV_BORDER, | 115 xd->mb_to_right_edge + MV_BORDER, |
116 xd->mb_to_top_edge - MV_BORDER, | 116 xd->mb_to_top_edge - MV_BORDER, |
117 xd->mb_to_bottom_edge + MV_BORDER); | 117 xd->mb_to_bottom_edge + MV_BORDER); |
118 } | 118 } |
119 | 119 |
120 // This function returns either the appropriate sub block or block's mv | 120 // This function returns either the appropriate sub block or block's mv |
121 // on whether the block_size < 8x8 and we have check_sub_blocks set. | 121 // on whether the block_size < 8x8 and we have check_sub_blocks set. |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
163 ADD_MV_REF_LIST(scale_mv((CANDIDATE), 0, ref_frame, ref_sign_bias)); \ | 163 ADD_MV_REF_LIST(scale_mv((CANDIDATE), 0, ref_frame, ref_sign_bias)); \ |
164 if ((CANDIDATE)->ref_frame[1] != ref_frame && \ | 164 if ((CANDIDATE)->ref_frame[1] != ref_frame && \ |
165 has_second_ref(CANDIDATE) && \ | 165 has_second_ref(CANDIDATE) && \ |
166 (CANDIDATE)->mv[1].as_int != (CANDIDATE)->mv[0].as_int) \ | 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)); \ | 167 ADD_MV_REF_LIST(scale_mv((CANDIDATE), 1, ref_frame, ref_sign_bias)); \ |
168 } while (0) | 168 } while (0) |
169 | 169 |
170 | 170 |
171 // Checks that the given mi_row, mi_col and search point | 171 // Checks that the given mi_row, mi_col and search point |
172 // are inside the borders of the tile. | 172 // are inside the borders of the tile. |
173 static INLINE int is_inside(const VP9_COMMON *cm, int mi_col, int mi_row, | 173 static INLINE int is_inside(const TileInfo *const tile, |
| 174 int mi_col, int mi_row, int mi_rows, |
174 const MV *mv) { | 175 const MV *mv) { |
175 return !(mi_row + mv->row < 0 || | 176 return !(mi_row + mv->row < 0 || |
176 mi_col + mv->col < cm->cur_tile_mi_col_start || | 177 mi_col + mv->col < tile->mi_col_start || |
177 mi_row + mv->row >= cm->mi_rows || | 178 mi_row + mv->row >= mi_rows || |
178 mi_col + mv->col >= cm->cur_tile_mi_col_end); | 179 mi_col + mv->col >= tile->mi_col_end); |
179 } | 180 } |
180 | 181 |
181 // This function searches the neighbourhood of a given MB/SB | 182 // This function searches the neighbourhood of a given MB/SB |
182 // to try and find candidate reference vectors. | 183 // to try and find candidate reference vectors. |
183 void vp9_find_mv_refs_idx(const VP9_COMMON *cm, const MACROBLOCKD *xd, | 184 void vp9_find_mv_refs_idx(const VP9_COMMON *cm, const MACROBLOCKD *xd, |
| 185 const TileInfo *const tile, |
184 MODE_INFO *mi, const MODE_INFO *prev_mi, | 186 MODE_INFO *mi, const MODE_INFO *prev_mi, |
185 MV_REFERENCE_FRAME ref_frame, | 187 MV_REFERENCE_FRAME ref_frame, |
186 int_mv *mv_ref_list, | 188 int_mv *mv_ref_list, |
187 int block_idx, | 189 int block_idx, |
188 int mi_row, int mi_col) { | 190 int mi_row, int mi_col) { |
189 const int *ref_sign_bias = cm->ref_frame_sign_bias; | 191 const int *ref_sign_bias = cm->ref_frame_sign_bias; |
190 int i, refmv_count = 0; | 192 int i, refmv_count = 0; |
191 const MV *const mv_ref_search = mv_ref_blocks[mi->mbmi.sb_type]; | 193 const MV *const mv_ref_search = mv_ref_blocks[mi->mbmi.sb_type]; |
192 const MB_MODE_INFO *const prev_mbmi = prev_mi ? &prev_mi->mbmi : NULL; | 194 const MB_MODE_INFO *const prev_mbmi = prev_mi ? &prev_mi->mbmi : NULL; |
193 int different_ref_found = 0; | 195 int different_ref_found = 0; |
194 int context_counter = 0; | 196 int context_counter = 0; |
195 | 197 |
196 // Blank the reference vector list | 198 // Blank the reference vector list |
197 vpx_memset(mv_ref_list, 0, sizeof(*mv_ref_list) * MAX_MV_REF_CANDIDATES); | 199 vpx_memset(mv_ref_list, 0, sizeof(*mv_ref_list) * MAX_MV_REF_CANDIDATES); |
198 | 200 |
199 // The nearest 2 blocks are treated differently | 201 // The nearest 2 blocks are treated differently |
200 // if the size < 8x8 we get the mv from the bmi substructure, | 202 // if the size < 8x8 we get the mv from the bmi substructure, |
201 // and we also need to keep a mode count. | 203 // and we also need to keep a mode count. |
202 for (i = 0; i < 2; ++i) { | 204 for (i = 0; i < 2; ++i) { |
203 const MV *const mv_ref = &mv_ref_search[i]; | 205 const MV *const mv_ref = &mv_ref_search[i]; |
204 if (is_inside(cm, mi_col, mi_row, mv_ref)) { | 206 if (is_inside(tile, mi_col, mi_row, cm->mi_rows, mv_ref)) { |
205 const MODE_INFO *const candidate_mi = xd->mi_8x8[mv_ref->col + mv_ref->row | 207 const MODE_INFO *const candidate_mi = xd->mi_8x8[mv_ref->col + mv_ref->row |
206 * xd->mode_info_stride]; | 208 * xd->mode_info_stride]; |
207 const MB_MODE_INFO *const candidate = &candidate_mi->mbmi; | 209 const MB_MODE_INFO *const candidate = &candidate_mi->mbmi; |
208 // Keep counts for entropy encoding. | 210 // Keep counts for entropy encoding. |
209 context_counter += mode_2_counter[candidate->mode]; | 211 context_counter += mode_2_counter[candidate->mode]; |
210 | 212 |
211 // Check if the candidate comes from the same reference frame. | 213 // Check if the candidate comes from the same reference frame. |
212 if (candidate->ref_frame[0] == ref_frame) { | 214 if (candidate->ref_frame[0] == ref_frame) { |
213 ADD_MV_REF_LIST(get_sub_block_mv(candidate_mi, 0, | 215 ADD_MV_REF_LIST(get_sub_block_mv(candidate_mi, 0, |
214 mv_ref->col, block_idx)); | 216 mv_ref->col, block_idx)); |
215 different_ref_found = candidate->ref_frame[1] != ref_frame; | 217 different_ref_found = candidate->ref_frame[1] != ref_frame; |
216 } else { | 218 } else { |
217 if (candidate->ref_frame[1] == ref_frame) | 219 if (candidate->ref_frame[1] == ref_frame) |
218 // Add second motion vector if it has the same ref_frame. | 220 // Add second motion vector if it has the same ref_frame. |
219 ADD_MV_REF_LIST(get_sub_block_mv(candidate_mi, 1, | 221 ADD_MV_REF_LIST(get_sub_block_mv(candidate_mi, 1, |
220 mv_ref->col, block_idx)); | 222 mv_ref->col, block_idx)); |
221 different_ref_found = 1; | 223 different_ref_found = 1; |
222 } | 224 } |
223 } | 225 } |
224 } | 226 } |
225 | 227 |
226 // Check the rest of the neighbors in much the same way | 228 // Check the rest of the neighbors in much the same way |
227 // as before except we don't need to keep track of sub blocks or | 229 // as before except we don't need to keep track of sub blocks or |
228 // mode counts. | 230 // mode counts. |
229 for (; i < MVREF_NEIGHBOURS; ++i) { | 231 for (; i < MVREF_NEIGHBOURS; ++i) { |
230 const MV *const mv_ref = &mv_ref_search[i]; | 232 const MV *const mv_ref = &mv_ref_search[i]; |
231 if (is_inside(cm, mi_col, mi_row, mv_ref)) { | 233 if (is_inside(tile, mi_col, mi_row, cm->mi_rows, mv_ref)) { |
232 const MB_MODE_INFO *const candidate = &xd->mi_8x8[mv_ref->col + | 234 const MB_MODE_INFO *const candidate = &xd->mi_8x8[mv_ref->col + |
233 mv_ref->row | 235 mv_ref->row |
234 * xd->mode_info_stride]->mbmi; | 236 * xd->mode_info_stride]->mbmi; |
235 | 237 |
236 if (candidate->ref_frame[0] == ref_frame) { | 238 if (candidate->ref_frame[0] == ref_frame) { |
237 ADD_MV_REF_LIST(candidate->mv[0]); | 239 ADD_MV_REF_LIST(candidate->mv[0]); |
238 different_ref_found = candidate->ref_frame[1] != ref_frame; | 240 different_ref_found = candidate->ref_frame[1] != ref_frame; |
239 } else { | 241 } else { |
240 if (candidate->ref_frame[1] == ref_frame) | 242 if (candidate->ref_frame[1] == ref_frame) |
241 ADD_MV_REF_LIST(candidate->mv[1]); | 243 ADD_MV_REF_LIST(candidate->mv[1]); |
242 different_ref_found = 1; | 244 different_ref_found = 1; |
243 } | 245 } |
244 } | 246 } |
245 } | 247 } |
246 | 248 |
247 // Check the last frame's mode and mv info. | 249 // Check the last frame's mode and mv info. |
248 if (prev_mbmi) { | 250 if (prev_mbmi) { |
249 if (prev_mbmi->ref_frame[0] == ref_frame) | 251 if (prev_mbmi->ref_frame[0] == ref_frame) |
250 ADD_MV_REF_LIST(prev_mbmi->mv[0]); | 252 ADD_MV_REF_LIST(prev_mbmi->mv[0]); |
251 else if (prev_mbmi->ref_frame[1] == ref_frame) | 253 else if (prev_mbmi->ref_frame[1] == ref_frame) |
252 ADD_MV_REF_LIST(prev_mbmi->mv[1]); | 254 ADD_MV_REF_LIST(prev_mbmi->mv[1]); |
253 } | 255 } |
254 | 256 |
255 // 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 |
256 // go back through the neighbors and find motion vectors from | 258 // go back through the neighbors and find motion vectors from |
257 // different reference frames. | 259 // different reference frames. |
258 if (different_ref_found) { | 260 if (different_ref_found) { |
259 for (i = 0; i < MVREF_NEIGHBOURS; ++i) { | 261 for (i = 0; i < MVREF_NEIGHBOURS; ++i) { |
260 const MV *mv_ref = &mv_ref_search[i]; | 262 const MV *mv_ref = &mv_ref_search[i]; |
261 if (is_inside(cm, mi_col, mi_row, mv_ref)) { | 263 if (is_inside(tile, mi_col, mi_row, cm->mi_rows, mv_ref)) { |
262 const MB_MODE_INFO *const candidate = &xd->mi_8x8[mv_ref->col + | 264 const MB_MODE_INFO *const candidate = &xd->mi_8x8[mv_ref->col + |
263 mv_ref->row | 265 mv_ref->row |
264 * xd->mode_info_stride]->mbmi; | 266 * xd->mode_info_stride]->mbmi; |
265 | 267 |
266 // If the candidate is INTRA we don't want to consider its mv. | 268 // If the candidate is INTRA we don't want to consider its mv. |
267 if (is_inter_block(candidate)) | 269 if (is_inter_block(candidate)) |
268 IF_DIFF_REF_FRAME_ADD_MV(candidate); | 270 IF_DIFF_REF_FRAME_ADD_MV(candidate); |
269 } | 271 } |
270 } | 272 } |
271 } | 273 } |
272 | 274 |
273 // Since we still don't have a candidate we'll try the last frame. | 275 // Since we still don't have a candidate we'll try the last frame. |
274 if (prev_mbmi && is_inter_block(prev_mbmi)) | 276 if (prev_mbmi && is_inter_block(prev_mbmi)) |
275 IF_DIFF_REF_FRAME_ADD_MV(prev_mbmi); | 277 IF_DIFF_REF_FRAME_ADD_MV(prev_mbmi); |
276 | 278 |
277 Done: | 279 Done: |
278 | 280 |
279 mi->mbmi.mode_context[ref_frame] = counter_to_context[context_counter]; | 281 mi->mbmi.mode_context[ref_frame] = counter_to_context[context_counter]; |
280 | 282 |
281 // Clamp vectors | 283 // Clamp vectors |
282 for (i = 0; i < MAX_MV_REF_CANDIDATES; ++i) | 284 for (i = 0; i < MAX_MV_REF_CANDIDATES; ++i) |
283 clamp_mv_ref(&mv_ref_list[i].as_mv, xd); | 285 clamp_mv_ref(&mv_ref_list[i].as_mv, xd); |
284 } | 286 } |
OLD | NEW |