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 12 #ifndef VP8_COMMON_FINDNEARMV_H_ 13 #define VP8_COMMON_FINDNEARMV_H_ 14 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 25 static void mv_bias(int refmb_ref_frame_sign_bias, int refframe, int_mv *mvp, 26 const int *ref_frame_sign_bias) 27 { 28 if (refmb_ref_frame_sign_bias != ref_frame_sign_bias[refframe]) 29 { 30 mvp->as_mv.row *= -1; 31 mvp->as_mv.col *= -1; 32 } 33 } 34 35 #define LEFT_TOP_MARGIN (16 << 3) 36 #define RIGHT_BOTTOM_MARGIN (16 << 3) 37 static void vp8_clamp_mv2(int_mv *mv, const MACROBLOCKD *xd) 38 { 39 if (mv->as_mv.col < (xd->mb_to_left_edge - LEFT_TOP_MARGIN)) 40 mv->as_mv.col = xd->mb_to_left_edge - LEFT_TOP_MARGIN; 41 else if (mv->as_mv.col > xd->mb_to_right_edge + RIGHT_BOTTOM_MARGIN) 42 mv->as_mv.col = xd->mb_to_right_edge + RIGHT_BOTTOM_MARGIN; 43 44 if (mv->as_mv.row < (xd->mb_to_top_edge - LEFT_TOP_MARGIN)) 45 mv->as_mv.row = xd->mb_to_top_edge - LEFT_TOP_MARGIN; 46 else if (mv->as_mv.row > xd->mb_to_bottom_edge + RIGHT_BOTTOM_MARGIN) 47 mv->as_mv.row = xd->mb_to_bottom_edge + RIGHT_BOTTOM_MARGIN; 48 } 49 50 static void vp8_clamp_mv(int_mv *mv, int mb_to_left_edge, int mb_to_right_edge, 51 int mb_to_top_edge, int mb_to_bottom_edge) 52 { 53 mv->as_mv.col = (mv->as_mv.col < mb_to_left_edge) ? 54 mb_to_left_edge : mv->as_mv.col; 55 mv->as_mv.col = (mv->as_mv.col > mb_to_right_edge) ? 56 mb_to_right_edge : mv->as_mv.col; 57 mv->as_mv.row = (mv->as_mv.row < mb_to_top_edge) ? 58 mb_to_top_edge : mv->as_mv.row; 59 mv->as_mv.row = (mv->as_mv.row > mb_to_bottom_edge) ? 60 mb_to_bottom_edge : mv->as_mv.row; 61 } 62 static unsigned int vp8_check_mv_bounds(int_mv *mv, int mb_to_left_edge, 63 int mb_to_right_edge, int mb_to_top_edge, 64 int mb_to_bottom_edge) 65 { 66 unsigned int need_to_clamp; 67 need_to_clamp = (mv->as_mv.col < mb_to_left_edge); 68 need_to_clamp |= (mv->as_mv.col > mb_to_right_edge); 69 need_to_clamp |= (mv->as_mv.row < mb_to_top_edge); 70 need_to_clamp |= (mv->as_mv.row > mb_to_bottom_edge); 71 return need_to_clamp; 72 } 73 74 void vp8_find_near_mvs 75 ( 76 MACROBLOCKD *xd, 77 const MODE_INFO *here, 78 int_mv *nearest, int_mv *nearby, int_mv *best, 79 int near_mv_ref_cts[4], 80 int refframe, 81 int *ref_frame_sign_bias 82 ); 83 84 85 int vp8_find_near_mvs_bias 86 ( 87 MACROBLOCKD *xd, 88 const MODE_INFO *here, 89 int_mv mode_mv_sb[2][MB_MODE_COUNT], 90 int_mv best_mv_sb[2], 91 int cnt[4], 92 int refframe, 93 int *ref_frame_sign_bias 94 ); 95 96 97 vp8_prob *vp8_mv_ref_probs( 98 vp8_prob p[VP8_MVREFS-1], const int near_mv_ref_ct[4] 99 ); 100 101 extern const unsigned char vp8_mbsplit_offset[4][16]; 102 103 104 static int left_block_mv(const MODE_INFO *cur_mb, int b) 105 { 106 if (!(b & 3)) 107 { 108 /* On L edge, get from MB to left of us */ 109 --cur_mb; 110 111 if(cur_mb->mbmi.mode != SPLITMV) 112 return cur_mb->mbmi.mv.as_int; 113 b += 4; 114 } 115 116 return (cur_mb->bmi + b - 1)->mv.as_int; 117 } 118 119 static int above_block_mv(const MODE_INFO *cur_mb, int b, int mi_stride) 120 { 121 if (!(b >> 2)) 122 { 123 /* On top edge, get from MB above us */ 124 cur_mb -= mi_stride; 125 126 if(cur_mb->mbmi.mode != SPLITMV) 127 return cur_mb->mbmi.mv.as_int; 128 b += 16; 129 } 130 131 return (cur_mb->bmi + (b - 4))->mv.as_int; 132 } 133 static B_PREDICTION_MODE left_block_mode(const MODE_INFO *cur_mb, int b) 134 { 135 if (!(b & 3)) 136 { 137 /* On L edge, get from MB to left of us */ 138 --cur_mb; 139 switch (cur_mb->mbmi.mode) 140 { 141 case B_PRED: 142 return (cur_mb->bmi + b + 3)->as_mode; 143 case DC_PRED: 144 return B_DC_PRED; 145 case V_PRED: 146 return B_VE_PRED; 147 case H_PRED: 148 return B_HE_PRED; 149 case TM_PRED: 150 return B_TM_PRED; 151 default: 152 return B_DC_PRED; 153 } 154 } 155 156 return (cur_mb->bmi + b - 1)->as_mode; 157 } 158 159 static B_PREDICTION_MODE above_block_mode(const MODE_INFO *cur_mb, int b, int mi_stride) 160 { 161 if (!(b >> 2)) 162 { 163 /* On top edge, get from MB above us */ 164 cur_mb -= mi_stride; 165 166 switch (cur_mb->mbmi.mode) 167 { 168 case B_PRED: 169 return (cur_mb->bmi + b + 12)->as_mode; 170 case DC_PRED: 171 return B_DC_PRED; 172 case V_PRED: 173 return B_VE_PRED; 174 case H_PRED: 175 return B_HE_PRED; 176 case TM_PRED: 177 return B_TM_PRED; 178 default: 179 return B_DC_PRED; 180 } 181 } 182 183 return (cur_mb->bmi + b - 4)->as_mode; 184 } 185 186 #ifdef __cplusplus 187 } // extern "C" 188 #endif 189 190 #endif // VP8_COMMON_FINDNEARMV_H_ 191