1 /** 2 * 3 * File Name: omxVCM4P10_BlockMatch_Half.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 half 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_Half (6.3.5.2.2) 27 * 28 * Description: 29 * Performs a half-pel block match using results from a prior integer search. 30 * Returns the best MV and associated cost. This function estimates the 31 * half-pixel motion vector by interpolating the integer resolution motion 32 * vector referenced by the input parameter pSrcDstBestMV, i.e., the initial 33 * integer MV is generated externally. The function 34 * omxVCM4P10_BlockMatch_Integer may be used for integer 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 integer search, 58 * represented in terms of 1/4-pel units 59 * 60 * Output Arguments: 61 * 62 * pSrcDstBestMV - Best MV resulting from the half-pel search, expressed in 63 * 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 * - any of the following pointers is NULL: pSrcOrgY, pSrcRefY, 71 * 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_Half( 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, integerMV; 97 OMX_U8 interpolY[256]; 98 99 /* Argument error checks */ 100 armRetArgErrIf((iBlockWidth == 4) && (!armIs4ByteAligned(pSrcOrgY)), OMX_Sts_BadArgErr); 101 armRetArgErrIf((iBlockWidth == 8) && (!armIs8ByteAligned(pSrcOrgY)), OMX_Sts_BadArgErr); 102 armRetArgErrIf((iBlockWidth == 16) && (!armIs16ByteAligned(pSrcOrgY)), OMX_Sts_BadArgErr); 103 armRetArgErrIf((iBlockWidth == 4) && (!armIs4ByteAligned(pSrcRefY)), OMX_Sts_BadArgErr); 104 armRetArgErrIf((iBlockWidth == 8) && (!armIs8ByteAligned(pSrcRefY)), OMX_Sts_BadArgErr); 105 armRetArgErrIf((iBlockWidth == 16) && (!armIs16ByteAligned(pSrcRefY)), OMX_Sts_BadArgErr); 106 armRetArgErrIf((nSrcOrgStep % iBlockWidth), OMX_Sts_BadArgErr); 107 armRetArgErrIf(pSrcOrgY == NULL, OMX_Sts_BadArgErr); 108 armRetArgErrIf(pSrcRefY == NULL, OMX_Sts_BadArgErr); 109 armRetArgErrIf(pMVPred == NULL, OMX_Sts_BadArgErr); 110 armRetArgErrIf(pSrcDstBestMV == NULL, OMX_Sts_BadArgErr); 111 armRetArgErrIf(pBestCost == NULL, OMX_Sts_BadArgErr); 112 armRetArgErrIf(((iBlockWidth!=4)&&(iBlockWidth!=8)&&(iBlockWidth!=16)) , OMX_Sts_BadArgErr); 113 armRetArgErrIf(((iBlockHeight!=4)&&(iBlockHeight!=8)&&(iBlockHeight!=16)) , OMX_Sts_BadArgErr); 114 115 116 /* Check for valid region */ 117 fromX = 1; 118 toX = 1; 119 fromY = 1; 120 toY = 1; 121 122 /* Initialize to max value as a start point */ 123 *pBestCost = 0x7fffffff; 124 125 integerMV.dx = pSrcDstBestMV->dx; 126 integerMV.dy = pSrcDstBestMV->dy; 127 128 /* Looping on y- axis */ 129 for (y = -fromY; y <= toY; y++) 130 { 131 /* Looping on x- axis */ 132 for (x = -fromX; x <= toX; x++) 133 { 134 /* Positioning the pointer */ 135 pTempSrcRefY = pSrcRefY + (nSrcRefStep * (integerMV.dy/4)) + (integerMV.dx/4); 136 if (x < 0) 137 { 138 pTempSrcRefY = pTempSrcRefY + x; 139 } 140 if (y < 0) 141 { 142 pTempSrcRefY = pTempSrcRefY + (y * nSrcRefStep); 143 } 144 pTempSrcOrgY = pSrcOrgY; 145 146 /* Prepare cand MV */ 147 candMV.dx = integerMV.dx + x * 2; 148 candMV.dy = integerMV.dy + y * 2; 149 150 /* Interpolate half pel for the current position*/ 151 armVCM4P10_Interpolate_Luma( 152 pTempSrcRefY, 153 nSrcRefStep, 154 interpolY, 155 iBlockWidth, 156 iBlockWidth, 157 iBlockHeight, 158 armAbs(x) * 2, 159 armAbs(y) * 2); 160 161 /* Calculate the SAD */ 162 armVCCOMM_SAD( 163 pTempSrcOrgY, 164 nSrcOrgStep, 165 interpolY, 166 iBlockWidth, 167 &candSAD, 168 iBlockHeight, 169 iBlockWidth); 170 171 diffMV.dx = candMV.dx - pMVPred->dx; 172 diffMV.dy = candMV.dy - pMVPred->dy; 173 174 /* Result calculations */ 175 armVCM4P10_CompareMotionCostToMV ( 176 candMV.dx, 177 candMV.dy, 178 diffMV, 179 candSAD, 180 pSrcDstBestMV, 181 nLamda, 182 pBestCost); 183 184 } /* End of x- axis */ 185 } /* End of y-axis */ 186 187 return OMX_Sts_NoErr; 188 189 } 190 191 /* End of file */ 192