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