00001
00015 #include "global.h"
00016
00023 static void GetMotionVectorPredictorMBAFF (Macroblock *currMB,
00024 PixelPos *block,
00025 short pmv[2],
00026 short ref_frame,
00027 char **refPic,
00028 short ***tmp_mv,
00029 int mb_x,
00030 int mb_y,
00031 int blockshape_x,
00032 int blockshape_y)
00033 {
00034 int mv_a, mv_b, mv_c, pred_vec=0;
00035 int mvPredType, rFrameL, rFrameU, rFrameUR;
00036 int hv;
00037 ImageParameters *p_Img = currMB->p_Img;
00038
00039 mvPredType = MVPRED_MEDIAN;
00040
00041
00042 if (currMB->mb_field)
00043 {
00044 rFrameL = block[0].available
00045 ? (p_Img->mb_data[block[0].mb_addr].mb_field
00046 ? refPic[block[0].pos_y][block[0].pos_x]
00047 : refPic[block[0].pos_y][block[0].pos_x] * 2) : -1;
00048 rFrameU = block[1].available
00049 ? (p_Img->mb_data[block[1].mb_addr].mb_field
00050 ? refPic[block[1].pos_y][block[1].pos_x]
00051 : refPic[block[1].pos_y][block[1].pos_x] * 2) : -1;
00052 rFrameUR = block[2].available
00053 ? (p_Img->mb_data[block[2].mb_addr].mb_field
00054 ? refPic[block[2].pos_y][block[2].pos_x]
00055 : refPic[block[2].pos_y][block[2].pos_x] * 2) : -1;
00056 }
00057 else
00058 {
00059 rFrameL = block[0].available
00060 ? (p_Img->mb_data[block[0].mb_addr].mb_field
00061 ? refPic[block[0].pos_y][block[0].pos_x] >>1
00062 : refPic[block[0].pos_y][block[0].pos_x]) : -1;
00063 rFrameU = block[1].available
00064 ? (p_Img->mb_data[block[1].mb_addr].mb_field
00065 ? refPic[block[1].pos_y][block[1].pos_x] >>1
00066 : refPic[block[1].pos_y][block[1].pos_x]) : -1;
00067 rFrameUR = block[2].available
00068 ? (p_Img->mb_data[block[2].mb_addr].mb_field
00069 ? refPic[block[2].pos_y][block[2].pos_x] >>1
00070 : refPic[block[2].pos_y][block[2].pos_x]) : -1;
00071 }
00072
00073
00074
00075
00076
00077 if(rFrameL == ref_frame && rFrameU != ref_frame && rFrameUR != ref_frame)
00078 mvPredType = MVPRED_L;
00079 else if(rFrameL != ref_frame && rFrameU == ref_frame && rFrameUR != ref_frame)
00080 mvPredType = MVPRED_U;
00081 else if(rFrameL != ref_frame && rFrameU != ref_frame && rFrameUR == ref_frame)
00082 mvPredType = MVPRED_UR;
00083
00084 if(blockshape_x == 8 && blockshape_y == 16)
00085 {
00086 if(mb_x == 0)
00087 {
00088 if(rFrameL == ref_frame)
00089 mvPredType = MVPRED_L;
00090 }
00091 else
00092 {
00093 if( rFrameUR == ref_frame)
00094 mvPredType = MVPRED_UR;
00095 }
00096 }
00097 else if(blockshape_x == 16 && blockshape_y == 8)
00098 {
00099 if(mb_y == 0)
00100 {
00101 if(rFrameU == ref_frame)
00102 mvPredType = MVPRED_U;
00103 }
00104 else
00105 {
00106 if(rFrameL == ref_frame)
00107 mvPredType = MVPRED_L;
00108 }
00109 }
00110
00111 for (hv=0; hv < 2; hv++)
00112 {
00113 if (hv == 0)
00114 {
00115 mv_a = block[0].available ? tmp_mv[block[0].pos_y][block[0].pos_x][hv] : 0;
00116 mv_b = block[1].available ? tmp_mv[block[1].pos_y][block[1].pos_x][hv] : 0;
00117 mv_c = block[2].available ? tmp_mv[block[2].pos_y][block[2].pos_x][hv] : 0;
00118 }
00119 else
00120 {
00121 if (currMB->mb_field)
00122 {
00123 mv_a = block[0].available ? p_Img->mb_data[block[0].mb_addr].mb_field
00124 ? tmp_mv[block[0].pos_y][block[0].pos_x][hv]
00125 : tmp_mv[block[0].pos_y][block[0].pos_x][hv] / 2
00126 : 0;
00127 mv_b = block[1].available ? p_Img->mb_data[block[1].mb_addr].mb_field
00128 ? tmp_mv[block[1].pos_y][block[1].pos_x][hv]
00129 : tmp_mv[block[1].pos_y][block[1].pos_x][hv] / 2
00130 : 0;
00131 mv_c = block[2].available ? p_Img->mb_data[block[2].mb_addr].mb_field
00132 ? tmp_mv[block[2].pos_y][block[2].pos_x][hv]
00133 : tmp_mv[block[2].pos_y][block[2].pos_x][hv] / 2
00134 : 0;
00135 }
00136 else
00137 {
00138 mv_a = block[0].available ? p_Img->mb_data[block[0].mb_addr].mb_field
00139 ? tmp_mv[block[0].pos_y][block[0].pos_x][hv] * 2
00140 : tmp_mv[block[0].pos_y][block[0].pos_x][hv]
00141 : 0;
00142 mv_b = block[1].available ? p_Img->mb_data[block[1].mb_addr].mb_field
00143 ? tmp_mv[block[1].pos_y][block[1].pos_x][hv] * 2
00144 : tmp_mv[block[1].pos_y][block[1].pos_x][hv]
00145 : 0;
00146 mv_c = block[2].available ? p_Img->mb_data[block[2].mb_addr].mb_field
00147 ? tmp_mv[block[2].pos_y][block[2].pos_x][hv] * 2
00148 : tmp_mv[block[2].pos_y][block[2].pos_x][hv]
00149 : 0;
00150 }
00151 }
00152
00153 switch (mvPredType)
00154 {
00155 case MVPRED_MEDIAN:
00156 if(!(block[1].available || block[2].available))
00157 {
00158 pred_vec = mv_a;
00159 }
00160 else
00161 {
00162 pred_vec = mv_a + mv_b + mv_c - imin(mv_a, imin(mv_b, mv_c)) - imax(mv_a, imax(mv_b ,mv_c));
00163 }
00164 break;
00165 case MVPRED_L:
00166 pred_vec = mv_a;
00167 break;
00168 case MVPRED_U:
00169 pred_vec = mv_b;
00170 break;
00171 case MVPRED_UR:
00172 pred_vec = mv_c;
00173 break;
00174 default:
00175 break;
00176 }
00177
00178 pmv[hv] = (short) pred_vec;
00179 }
00180 }
00181
00188 static void GetMotionVectorPredictorNormal (Macroblock *currMB,
00189 PixelPos *block,
00190 short pmv[2],
00191 short ref_frame,
00192 char **refPic,
00193 short ***tmp_mv,
00194 int mb_x,
00195 int mb_y,
00196 int blockshape_x,
00197 int blockshape_y)
00198 {
00199 int mv_a, mv_b, mv_c, pred_vec = 0;
00200 int mvPredType, rFrameL, rFrameU, rFrameUR;
00201 int hv;
00202
00203 mvPredType = MVPRED_MEDIAN;
00204
00205 rFrameL = block[0].available ? refPic[block[0].pos_y][block[0].pos_x] : -1;
00206 rFrameU = block[1].available ? refPic[block[1].pos_y][block[1].pos_x] : -1;
00207 rFrameUR = block[2].available ? refPic[block[2].pos_y][block[2].pos_x] : -1;
00208
00209
00210
00211
00212 if(rFrameL == ref_frame && rFrameU != ref_frame && rFrameUR != ref_frame)
00213 mvPredType = MVPRED_L;
00214 else if(rFrameL != ref_frame && rFrameU == ref_frame && rFrameUR != ref_frame)
00215 mvPredType = MVPRED_U;
00216 else if(rFrameL != ref_frame && rFrameU != ref_frame && rFrameUR == ref_frame)
00217 mvPredType = MVPRED_UR;
00218
00219 if(blockshape_x == 8 && blockshape_y == 16)
00220 {
00221 if(mb_x == 0)
00222 {
00223 if(rFrameL == ref_frame)
00224 mvPredType = MVPRED_L;
00225 }
00226 else
00227 {
00228 if(rFrameUR == ref_frame)
00229 mvPredType = MVPRED_UR;
00230 }
00231 }
00232 else if(blockshape_x == 16 && blockshape_y == 8)
00233 {
00234 if(mb_y == 0)
00235 {
00236 if(rFrameU == ref_frame)
00237 mvPredType = MVPRED_U;
00238 }
00239 else
00240 {
00241 if(rFrameL == ref_frame)
00242 mvPredType = MVPRED_L;
00243 }
00244 }
00245
00246 for (hv=0; hv < 2; hv++)
00247 {
00248 mv_a = block[0].available ? tmp_mv[block[0].pos_y][block[0].pos_x][hv] : 0;
00249 mv_b = block[1].available ? tmp_mv[block[1].pos_y][block[1].pos_x][hv] : 0;
00250 mv_c = block[2].available ? tmp_mv[block[2].pos_y][block[2].pos_x][hv] : 0;
00251
00252 switch (mvPredType)
00253 {
00254 case MVPRED_MEDIAN:
00255 if(!(block[1].available || block[2].available))
00256 {
00257 pred_vec = mv_a;
00258 }
00259 else
00260 {
00261 pred_vec = mv_a + mv_b + mv_c - imin(mv_a, imin(mv_b, mv_c)) - imax(mv_a, imax(mv_b ,mv_c));
00262 }
00263 break;
00264 case MVPRED_L:
00265 pred_vec = mv_a;
00266 break;
00267 case MVPRED_U:
00268 pred_vec = mv_b;
00269 break;
00270 case MVPRED_UR:
00271 pred_vec = mv_c;
00272 break;
00273 default:
00274 break;
00275 }
00276
00277 pmv[hv] = (short) pred_vec;
00278 }
00279 }
00280
00281 void InitMotionVectorPrediction(Macroblock *currMB, int MbaffFrameFlag)
00282 {
00283 if (MbaffFrameFlag)
00284 currMB->GetMVPredictor = GetMotionVectorPredictorMBAFF;
00285 else
00286 currMB->GetMVPredictor = GetMotionVectorPredictorNormal;
00287 }