omxVCM4P2_FindMVpred.c revision 0c1bc742181ded4930842b46e9507372f0b1b963
1/** 2 * 3 * File Name: omxVCM4P2_FindMVpred.c 4 * OpenMAX DL: v1.0.2 5 * Revision: 9641 6 * Date: Thursday, February 7, 2008 7 * 8 * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved. 9 * 10 * 11 * 12 * Description: 13 * Contains module for predicting MV of MB 14 * 15 */ 16 17#include "omxtypes.h" 18#include "armOMX.h" 19#include "omxVC.h" 20 21#include "armCOMM.h" 22 23/** 24 * Function: omxVCM4P2_FindMVpred (6.2.3.1.1) 25 * 26 * Description: 27 * Predicts a motion vector for the current block using the procedure 28 * specified in [ISO14496-2], subclause 7.6.5. The resulting predicted MV is 29 * returned in pDstMVPred. If the parameter pDstMVPredME if is not NULL then 30 * the set of three MV candidates used for prediction is also returned, 31 * otherwise pDstMVPredMEis NULL upon return. 32 * 33 * Input Arguments: 34 * 35 * pSrcMVCurMB - pointer to the MV buffer associated with the current Y 36 * macroblock; a value of NULL indicates unavailability. 37 * pSrcCandMV1 - pointer to the MV buffer containing the 4 MVs associated 38 * with the MB located to the left of the current MB; set to NULL 39 * if there is no MB to the left. 40 * pSrcCandMV2 - pointer to the MV buffer containing the 4 MVs associated 41 * with the MB located above the current MB; set to NULL if there 42 * is no MB located above the current MB. 43 * pSrcCandMV3 - pointer to the MV buffer containing the 4 MVs associated 44 * with the MB located to the right and above the current MB; set 45 * to NULL if there is no MB located to the above-right. 46 * iBlk - the index of block in the current macroblock 47 * pDstMVPredME - MV candidate return buffer; if set to NULL then 48 * prediction candidate MVs are not returned and pDstMVPredME will 49 * be NULL upon function return; if pDstMVPredME is non-NULL then it 50 * must point to a buffer containing sufficient space for three 51 * return MVs. 52 * 53 * Output Arguments: 54 * 55 * pDstMVPred - pointer to the predicted motion vector 56 * pDstMVPredME - if non-NULL upon input then pDstMVPredME points upon 57 * return to a buffer containing the three motion vector candidates 58 * used for prediction as specified in [ISO14496-2], subclause 59 * 7.6.5, otherwise if NULL upon input then pDstMVPredME is NULL 60 * upon output. 61 * 62 * Return Value: 63 * 64 * OMX_Sts_NoErr - no error 65 * OMX_Sts_BadArgErr - bad arguments; returned under any of the following 66 * conditions: 67 * - the pointer pDstMVPred is NULL 68 * - the parameter iBlk does not fall into the range 0 <= iBlk<=3 69 * 70 */ 71 72OMXResult omxVCM4P2_FindMVpred( 73 const OMXVCMotionVector* pSrcMVCurMB, 74 const OMXVCMotionVector* pSrcCandMV1, 75 const OMXVCMotionVector* pSrcCandMV2, 76 const OMXVCMotionVector* pSrcCandMV3, 77 OMXVCMotionVector* pDstMVPred, 78 OMXVCMotionVector* pDstMVPredME, 79 OMX_INT iBlk 80 ) 81{ 82 OMXVCMotionVector CandMV; 83 const OMXVCMotionVector *pCandMV1; 84 const OMXVCMotionVector *pCandMV2; 85 const OMXVCMotionVector *pCandMV3; 86 87 /* Argument error checks */ 88 armRetArgErrIf(iBlk!=0 && pSrcMVCurMB == NULL, OMX_Sts_BadArgErr); 89 armRetArgErrIf(pDstMVPred == NULL, OMX_Sts_BadArgErr); 90 armRetArgErrIf((iBlk < 0) || (iBlk > 3), OMX_Sts_BadArgErr); 91 92 CandMV.dx = CandMV.dy = 0; 93 /* Based on the position of the block extract the motion vectors and 94 the tranperancy status */ 95 96 97 /* Set the default value for these to be used if pSrcCandMV[1|2|3] == NULL */ 98 pCandMV1 = pCandMV2 = pCandMV3 = &CandMV; 99 100 101 switch (iBlk) 102 { 103 case 0: 104 { 105 if(pSrcCandMV1 != NULL) 106 { 107 pCandMV1 = &pSrcCandMV1[1]; 108 } 109 if(pSrcCandMV2 != NULL) 110 { 111 pCandMV2 = &pSrcCandMV2[2]; 112 } 113 if(pSrcCandMV3 != NULL) 114 { 115 pCandMV3 = &pSrcCandMV3[2]; 116 } 117 if ((pSrcCandMV1 == NULL) && (pSrcCandMV2 == NULL)) 118 { 119 pCandMV1 = pCandMV2 = pCandMV3; 120 } 121 else if((pSrcCandMV1 == NULL) && (pSrcCandMV3 == NULL)) 122 { 123 pCandMV1 = pCandMV3 = pCandMV2; 124 } 125 else if((pSrcCandMV2 == NULL) && (pSrcCandMV3 == NULL)) 126 { 127 pCandMV2 = pCandMV3 = pCandMV1; 128 } 129 break; 130 } 131 case 1: 132 { 133 pCandMV1 = &pSrcMVCurMB[0]; 134 if(pSrcCandMV2 != NULL) 135 { 136 pCandMV2 = &pSrcCandMV2[3]; 137 } 138 if(pSrcCandMV3 != NULL) 139 { 140 pCandMV3 = &pSrcCandMV3[2]; 141 } 142 if((pSrcCandMV2 == NULL) && (pSrcCandMV3 == NULL)) 143 { 144 pCandMV2 = pCandMV3 = pCandMV1; 145 } 146 break; 147 } 148 case 2: 149 { 150 if(pSrcCandMV1 != NULL) 151 { 152 pCandMV1 = &pSrcCandMV1[3]; 153 } 154 pCandMV2 = &pSrcMVCurMB[0]; 155 pCandMV3 = &pSrcMVCurMB[1]; 156 break; 157 } 158 case 3: 159 { 160 pCandMV1 = &pSrcMVCurMB[2]; 161 pCandMV2 = &pSrcMVCurMB[0]; 162 pCandMV3 = &pSrcMVCurMB[1]; 163 break; 164 } 165 } 166 167 /* Find the median of the 3 candidate MV's */ 168 pDstMVPred->dx = armMedianOf3 (pCandMV1->dx, pCandMV2->dx, pCandMV3->dx); 169 pDstMVPred->dy = armMedianOf3 (pCandMV1->dy, pCandMV2->dy, pCandMV3->dy); 170 171 if (pDstMVPredME != NULL) 172 { 173 /* Store the candidate MV's into the pDstMVPredME, these can be used 174 in the fast algorithm if implemented */ 175 pDstMVPredME[0].dx = pCandMV1->dx; 176 pDstMVPredME[0].dy = pCandMV1->dy; 177 pDstMVPredME[1].dx = pCandMV2->dx; 178 pDstMVPredME[1].dy = pCandMV2->dy; 179 pDstMVPredME[2].dx = pCandMV3->dx; 180 pDstMVPredME[2].dy = pCandMV3->dy; 181 } 182 183 return OMX_Sts_NoErr; 184} 185 186 187/* End of file */ 188 189