1 /** 2 * 3 * File Name: omxVCM4P10_BlockMatch_Quarter.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 modules for quater pel Block matching, 14 * 15 */ 16 17 #include "omxtypes.h" 18 #include "armOMX.h" 19 #include "omxVC.h" 20 21 #include "armVC.h" 22 #include "armCOMM.h" 23 24 25 /** 26 * Function: omxVCM4P10_BlockMatch_Quarter (6.3.5.2.3) 27 * 28 * Description: 29 * Performs a quarter-pel block match using results from a prior half-pel 30 * search. Returns the best MV and associated cost. This function estimates 31 * the quarter-pixel motion vector by interpolating the half-pel resolution 32 * motion vector referenced by the input parameter pSrcDstBestMV, i.e., the 33 * initial half-pel MV is generated externally. The function 34 * omxVCM4P10_BlockMatch_Half may be used for half-pel motion estimation. 35 * 36 * Input Arguments: 37 * 38 * pSrcOrgY - Pointer to the current position in original picture plane. If 39 * iBlockWidth==4, 4-byte alignment required. If iBlockWidth==8, 40 * 8-byte alignment required. If iBlockWidth==16, 16-byte alignment 41 * required. 42 * pSrcRefY - Pointer to the top-left corner of the co-located block in the 43 * reference picture If iBlockWidth==4, 4-byte alignment 44 * required. If iBlockWidth==8, 8-byte alignment required. If 45 * iBlockWidth==16, 16-byte alignment required. 46 * nSrcOrgStep - Stride of the original picture plane in terms of full 47 * pixels; must be a multiple of iBlockWidth. 48 * nSrcRefStep - Stride of the reference picture plane in terms of full 49 * pixels 50 * iBlockWidth - Width of the current block in terms of full pixels; must 51 * be equal to either 4, 8, or 16. 52 * iBlockHeight - Height of the current block in terms of full pixels; must 53 * be equal to either 4, 8, or 16. 54 * nLamda - Lamda factor, used to compute motion cost 55 * pMVPred - Predicted MV, represented in terms of 1/4-pel units; used to 56 * compute motion cost 57 * pSrcDstBestMV - The best MV resulting from a prior half-pel search, 58 * represented in terms of 1/4 pel units 59 * 60 * Output Arguments: 61 * 62 * pSrcDstBestMV - Best MV resulting from the quarter-pel search, expressed 63 * in terms of 1/4-pel units 64 * pBestCost - Motion cost associated with the best MV; computed as 65 * SAD+Lamda*BitsUsedByMV 66 * 67 * Return Value: 68 * OMX_Sts_NoErr, if the function runs without error. 69 * OMX_Sts_BadArgErr - bad arguments: if one of the following cases occurs: 70 * - One of more of the following pointers is NULL: 71 * pSrcOrgY, pSrcRefY, pSrcDstBestMV, pMVPred, pBestCost 72 * - iBlockWidth or iBlockHeight are equal to values other than 4, 8, or 16. 73 * - Any alignment restrictions are violated 74 * 75 */ 76 77 OMXResult omxVCM4P10_BlockMatch_Quarter( 78 const OMX_U8* pSrcOrgY, 79 OMX_S32 nSrcOrgStep, 80 const OMX_U8* pSrcRefY, 81 OMX_S32 nSrcRefStep, 82 OMX_U8 iBlockWidth, 83 OMX_U8 iBlockHeight, 84 OMX_U32 nLamda, 85 const OMXVCMotionVector* pMVPred, 86 OMXVCMotionVector* pSrcDstBestMV, 87 OMX_S32* pBestCost 88 ) 89 { 90 /* Definitions and Initializations*/ 91 OMX_INT candSAD; 92 OMX_INT fromX, toX, fromY, toY; 93 /* Offset to the reference at the begining of the bounding box */ 94 const OMX_U8 *pTempSrcRefY, *pTempSrcOrgY; 95 OMX_S16 x, y; 96 OMXVCMotionVector diffMV, candMV, initialMV; 97 OMX_U8 interpolY[256]; 98 OMX_S32 pelPosX, pelPosY; 99 100 /* Argument error checks */ 101 armRetArgErrIf((iBlockWidth == 4) && (!armIs4ByteAligned(pSrcOrgY)), OMX_Sts_BadArgErr); 102 armRetArgErrIf((iBlockWidth == 8) && (!armIs8ByteAligned(pSrcOrgY)), OMX_Sts_BadArgErr); 103 armRetArgErrIf((iBlockWidth == 16) && (!armIs16ByteAligned(pSrcOrgY)), OMX_Sts_BadArgErr); 104 armRetArgErrIf((iBlockWidth == 4) && (!armIs4ByteAligned(pSrcRefY)), OMX_Sts_BadArgErr); 105 armRetArgErrIf((iBlockWidth == 8) && (!armIs8ByteAligned(pSrcRefY)), OMX_Sts_BadArgErr); 106 armRetArgErrIf((iBlockWidth == 16) && (!armIs16ByteAligned(pSrcRefY)), OMX_Sts_BadArgErr); 107 armRetArgErrIf((nSrcOrgStep % iBlockWidth), OMX_Sts_BadArgErr); 108 armRetArgErrIf(pSrcOrgY == NULL, OMX_Sts_BadArgErr); 109 armRetArgErrIf(pSrcRefY == NULL, OMX_Sts_BadArgErr); 110 armRetArgErrIf(pMVPred == NULL, OMX_Sts_BadArgErr); 111 armRetArgErrIf(pSrcDstBestMV == NULL, OMX_Sts_BadArgErr); 112 armRetArgErrIf(pBestCost == NULL, OMX_Sts_BadArgErr); 113 armRetArgErrIf(((iBlockWidth!=4)&&(iBlockWidth!=8)&&(iBlockWidth!=16)) , OMX_Sts_BadArgErr); 114 armRetArgErrIf(((iBlockHeight!=4)&&(iBlockHeight!=8)&&(iBlockHeight!=16)) , OMX_Sts_BadArgErr); 115 116 117 /* Check for valid region */ 118 fromX = 1; 119 toX = 1; 120 fromY = 1; 121 toY = 1; 122 123 /* Initialize to max value as a start point */ 124 *pBestCost = 0x7fffffff; 125 126 initialMV.dx = pSrcDstBestMV->dx; 127 initialMV.dy = pSrcDstBestMV->dy; 128 129 /* Looping on y- axis */ 130 for (y = -fromY; y <= toY; y++) 131 { 132 /* Looping on x- axis */ 133 for (x = -fromX; x <= toX; x++) 134 { 135 /* Positioning the pointer */ 136 pTempSrcRefY = pSrcRefY + (nSrcRefStep * (initialMV.dy/4)) + (initialMV.dx/4); 137 138 /* Calculating the fract pel position */ 139 pelPosX = (initialMV.dx % 4) + x; 140 if (pelPosX < 0) 141 { 142 pTempSrcRefY = pTempSrcRefY - 1; 143 pelPosX += 4; 144 } 145 pelPosY = (initialMV.dy % 4) + y; 146 if (pelPosY < 0) 147 { 148 pTempSrcRefY = pTempSrcRefY - (1 * nSrcRefStep); 149 pelPosY += 4; 150 } 151 152 pTempSrcOrgY = pSrcOrgY; 153 154 /* Prepare cand MV */ 155 candMV.dx = initialMV.dx + x; 156 candMV.dy = initialMV.dy + y; 157 158 /* Interpolate Quater pel for the current position*/ 159 armVCM4P10_Interpolate_Luma( 160 pTempSrcRefY, 161 nSrcRefStep, 162 interpolY, 163 iBlockWidth, 164 iBlockWidth, 165 iBlockHeight, 166 pelPosX, 167 pelPosY); 168 169 /* Calculate the SAD */ 170 armVCCOMM_SAD( 171 pTempSrcOrgY, 172 nSrcOrgStep, 173 interpolY, 174 iBlockWidth, 175 &candSAD, 176 iBlockHeight, 177 iBlockWidth); 178 179 diffMV.dx = candMV.dx - pMVPred->dx; 180 diffMV.dy = candMV.dy - pMVPred->dy; 181 182 /* Result calculations */ 183 armVCM4P10_CompareMotionCostToMV ( 184 candMV.dx, 185 candMV.dy, 186 diffMV, 187 candSAD, 188 pSrcDstBestMV, 189 nLamda, 190 pBestCost); 191 192 } /* End of x- axis */ 193 } /* End of y-axis */ 194 195 return OMX_Sts_NoErr; 196 197 } 198 199 /* End of file */ 200