1 /* 2 * Copyright (c) 2010 The WebM project authors. All Rights Reserved. 3 * 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 6 * tree. An additional intellectual property rights grant can be found 7 * in the file PATENTS. All contributing project authors may 8 * be found in the AUTHORS file in the root of the source tree. 9 */ 10 11 #ifndef VP8_COMMON_FINDNEARMV_H_ 12 #define VP8_COMMON_FINDNEARMV_H_ 13 14 #include "./vpx_config.h" 15 #include "mv.h" 16 #include "blockd.h" 17 #include "modecont.h" 18 #include "treecoder.h" 19 20 #ifdef __cplusplus 21 extern "C" { 22 #endif 23 24 static INLINE void mv_bias(int refmb_ref_frame_sign_bias, int refframe, 25 int_mv *mvp, const int *ref_frame_sign_bias) { 26 if (refmb_ref_frame_sign_bias != ref_frame_sign_bias[refframe]) { 27 mvp->as_mv.row *= -1; 28 mvp->as_mv.col *= -1; 29 } 30 } 31 32 #define LEFT_TOP_MARGIN (16 << 3) 33 #define RIGHT_BOTTOM_MARGIN (16 << 3) 34 static INLINE void vp8_clamp_mv2(int_mv *mv, const MACROBLOCKD *xd) { 35 if (mv->as_mv.col < (xd->mb_to_left_edge - LEFT_TOP_MARGIN)) { 36 mv->as_mv.col = xd->mb_to_left_edge - LEFT_TOP_MARGIN; 37 } else if (mv->as_mv.col > xd->mb_to_right_edge + RIGHT_BOTTOM_MARGIN) { 38 mv->as_mv.col = xd->mb_to_right_edge + RIGHT_BOTTOM_MARGIN; 39 } 40 41 if (mv->as_mv.row < (xd->mb_to_top_edge - LEFT_TOP_MARGIN)) { 42 mv->as_mv.row = xd->mb_to_top_edge - LEFT_TOP_MARGIN; 43 } else if (mv->as_mv.row > xd->mb_to_bottom_edge + RIGHT_BOTTOM_MARGIN) { 44 mv->as_mv.row = xd->mb_to_bottom_edge + RIGHT_BOTTOM_MARGIN; 45 } 46 } 47 48 static INLINE void vp8_clamp_mv(int_mv *mv, int mb_to_left_edge, 49 int mb_to_right_edge, int mb_to_top_edge, 50 int mb_to_bottom_edge) { 51 mv->as_mv.col = 52 (mv->as_mv.col < mb_to_left_edge) ? mb_to_left_edge : mv->as_mv.col; 53 mv->as_mv.col = 54 (mv->as_mv.col > mb_to_right_edge) ? mb_to_right_edge : mv->as_mv.col; 55 mv->as_mv.row = 56 (mv->as_mv.row < mb_to_top_edge) ? mb_to_top_edge : mv->as_mv.row; 57 mv->as_mv.row = 58 (mv->as_mv.row > mb_to_bottom_edge) ? mb_to_bottom_edge : mv->as_mv.row; 59 } 60 static INLINE unsigned int vp8_check_mv_bounds(int_mv *mv, int mb_to_left_edge, 61 int mb_to_right_edge, 62 int mb_to_top_edge, 63 int mb_to_bottom_edge) { 64 unsigned int need_to_clamp; 65 need_to_clamp = (mv->as_mv.col < mb_to_left_edge); 66 need_to_clamp |= (mv->as_mv.col > mb_to_right_edge); 67 need_to_clamp |= (mv->as_mv.row < mb_to_top_edge); 68 need_to_clamp |= (mv->as_mv.row > mb_to_bottom_edge); 69 return need_to_clamp; 70 } 71 72 void vp8_find_near_mvs(MACROBLOCKD *xd, const MODE_INFO *here, int_mv *nearest, 73 int_mv *nearby, int_mv *best, int near_mv_ref_cts[4], 74 int refframe, int *ref_frame_sign_bias); 75 76 int vp8_find_near_mvs_bias(MACROBLOCKD *xd, const MODE_INFO *here, 77 int_mv mode_mv_sb[2][MB_MODE_COUNT], 78 int_mv best_mv_sb[2], int cnt[4], int refframe, 79 int *ref_frame_sign_bias); 80 81 vp8_prob *vp8_mv_ref_probs(vp8_prob p[VP8_MVREFS - 1], 82 const int near_mv_ref_ct[4]); 83 84 extern const unsigned char vp8_mbsplit_offset[4][16]; 85 86 static INLINE uint32_t left_block_mv(const MODE_INFO *cur_mb, int b) { 87 if (!(b & 3)) { 88 /* On L edge, get from MB to left of us */ 89 --cur_mb; 90 91 if (cur_mb->mbmi.mode != SPLITMV) return cur_mb->mbmi.mv.as_int; 92 b += 4; 93 } 94 95 return (cur_mb->bmi + b - 1)->mv.as_int; 96 } 97 98 static INLINE uint32_t above_block_mv(const MODE_INFO *cur_mb, int b, 99 int mi_stride) { 100 if (!(b >> 2)) { 101 /* On top edge, get from MB above us */ 102 cur_mb -= mi_stride; 103 104 if (cur_mb->mbmi.mode != SPLITMV) return cur_mb->mbmi.mv.as_int; 105 b += 16; 106 } 107 108 return (cur_mb->bmi + (b - 4))->mv.as_int; 109 } 110 static INLINE B_PREDICTION_MODE left_block_mode(const MODE_INFO *cur_mb, 111 int b) { 112 if (!(b & 3)) { 113 /* On L edge, get from MB to left of us */ 114 --cur_mb; 115 switch (cur_mb->mbmi.mode) { 116 case B_PRED: return (cur_mb->bmi + b + 3)->as_mode; 117 case DC_PRED: return B_DC_PRED; 118 case V_PRED: return B_VE_PRED; 119 case H_PRED: return B_HE_PRED; 120 case TM_PRED: return B_TM_PRED; 121 default: return B_DC_PRED; 122 } 123 } 124 125 return (cur_mb->bmi + b - 1)->as_mode; 126 } 127 128 static INLINE B_PREDICTION_MODE above_block_mode(const MODE_INFO *cur_mb, int b, 129 int mi_stride) { 130 if (!(b >> 2)) { 131 /* On top edge, get from MB above us */ 132 cur_mb -= mi_stride; 133 134 switch (cur_mb->mbmi.mode) { 135 case B_PRED: return (cur_mb->bmi + b + 12)->as_mode; 136 case DC_PRED: return B_DC_PRED; 137 case V_PRED: return B_VE_PRED; 138 case H_PRED: return B_HE_PRED; 139 case TM_PRED: return B_TM_PRED; 140 default: return B_DC_PRED; 141 } 142 } 143 144 return (cur_mb->bmi + b - 4)->as_mode; 145 } 146 147 #ifdef __cplusplus 148 } // extern "C" 149 #endif 150 151 #endif // VP8_COMMON_FINDNEARMV_H_ 152