1 /** 2 * 3 * File Name: armVCM4P2_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 Block matching, a full search algorithm 14 * is implemented 15 * 16 */ 17 18 #include "omxtypes.h" 19 #include "armOMX.h" 20 #include "omxVC.h" 21 22 #include "armVC.h" 23 #include "armCOMM.h" 24 25 /** 26 * Function: armVCM4P2_BlockMatch_Half 27 * 28 * Description: 29 * Performs a 16x16 block match with half-pixel resolution. Returns the estimated 30 * motion vector and associated minimum SAD. This function estimates the half-pixel 31 * motion vector by interpolating the integer resolution motion vector referenced 32 * by the input parameter pSrcDstMV, i.e., the initial integer MV is generated 33 * externally. The input parameters pSrcRefBuf and pSearchPointRefPos should be 34 * shifted by the winning MV of 16x16 integer search prior to calling BlockMatch_Half_16x16. 35 * The function BlockMatch_Integer_16x16 may be used for integer motion estimation. 36 * 37 * Remarks: 38 * 39 * Parameters: 40 * [in] pSrcRefBuf pointer to the reference Y plane; points to the reference MB 41 * that corresponds to the location of the current macroblock in 42 * the current plane. 43 * [in] refWidth width of the reference plane 44 * [in] pRefRect reference plane valid region rectangle 45 * [in] pSrcCurrBuf pointer to the current macroblock extracted from original plane 46 * (linear array, 256 entries); must be aligned on an 8-byte boundary. 47 * [in] pSearchPointRefPos position of the starting point for half pixel search (specified 48 * in terms of integer pixel units) in the reference plane. 49 * [in] rndVal rounding control bit for half pixel motion estimation; 50 * 0=rounding control disabled; 1=rounding control enabled 51 * [in] pSrcDstMV pointer to the initial MV estimate; typically generated during a prior 52 * 16X16 integer search and its unit is half pixel. 53 * [in] BlockSize MacroBlock Size i.e either 16x16 or 8x8. 54 * [out]pSrcDstMV pointer to estimated MV 55 * [out]pDstSAD pointer to minimum SAD 56 * 57 * Return Value: 58 * OMX_Sts_NoErr C no error 59 * OMX_Sts_BadArgErr C bad arguments 60 * 61 */ 62 63 OMXResult armVCM4P2_BlockMatch_Half( 64 const OMX_U8 *pSrcRefBuf, 65 OMX_INT refWidth, 66 const OMXRect *pRefRect, 67 const OMX_U8 *pSrcCurrBuf, 68 const OMXVCM4P2Coordinate *pSearchPointRefPos, 69 OMX_INT rndVal, 70 OMXVCMotionVector *pSrcDstMV, 71 OMX_INT *pDstSAD, 72 OMX_U8 BlockSize 73 ) 74 { 75 OMX_INT outer, inner, count, index; 76 OMX_S16 halfPelX = 0, halfPelY = 0, x, y; 77 OMX_INT candSAD, refSAD = 0; 78 OMX_INT minSAD, fromX, toX, fromY, toY; 79 /* Offset to the reference at the begining of the bounding box */ 80 const OMX_U8 *pTempSrcRefBuf; 81 OMX_U8 tempPel; 82 83 /* Argument error checks */ 84 armRetArgErrIf(pSrcRefBuf == NULL, OMX_Sts_BadArgErr); 85 armRetArgErrIf(pRefRect == NULL, OMX_Sts_BadArgErr); 86 armRetArgErrIf(pSrcCurrBuf == NULL, OMX_Sts_BadArgErr); 87 armRetArgErrIf(pSearchPointRefPos == NULL, OMX_Sts_BadArgErr); 88 armRetArgErrIf(pSrcDstMV == NULL, OMX_Sts_BadArgErr); 89 armRetArgErrIf(pDstSAD == NULL, OMX_Sts_BadArgErr); 90 91 /* Positioning the pointer */ 92 pTempSrcRefBuf = pSrcRefBuf + (refWidth * (pSrcDstMV->dy/2)) + (pSrcDstMV->dx/2); 93 94 /* Copy the candidate to the temporary linear array */ 95 for (outer = 0, count = 0,index = 0; 96 outer < BlockSize; 97 outer++, index += refWidth - BlockSize) 98 { 99 for (inner = 0; inner < BlockSize; inner++, count++, index++) 100 { 101 refSAD += armAbs (pTempSrcRefBuf[index] - pSrcCurrBuf[count]); 102 } 103 } 104 105 /* Set the minSad as reference SAD */ 106 minSAD = refSAD; 107 *pDstSAD = refSAD; 108 109 /* Check for valid region */ 110 fromX = 1; 111 toX = 1; 112 fromY = 1; 113 toY = 1; 114 if ((pSearchPointRefPos->x - 1) < pRefRect->x) 115 { 116 fromX = 0; 117 } 118 119 if ((pSearchPointRefPos->x + BlockSize + 1) > (pRefRect->x + pRefRect->width)) 120 { 121 toX = 0; 122 } 123 124 if ((pSearchPointRefPos->y - 1) < pRefRect->y) 125 { 126 fromY = 0; 127 } 128 129 if ((pSearchPointRefPos->y + BlockSize + 1) > (pRefRect->y + pRefRect->height)) 130 { 131 toY = 0; 132 } 133 134 /* Looping on y- axis */ 135 for (y = -fromY; y <= toY; y++) 136 { 137 /* Looping on x- axis */ 138 for (x = -fromX; x <= toX; x++) 139 { 140 /* check for integer position */ 141 if ( x == 0 && y == 0) 142 { 143 continue; 144 } 145 /* Positioning the pointer */ 146 pTempSrcRefBuf = pSrcRefBuf + (refWidth * (pSrcDstMV->dy/2)) 147 + (pSrcDstMV->dx/2); 148 149 /* Interpolate the pixel and calculate the SAD*/ 150 for (outer = 0, count = 0, candSAD = 0,index = 0; 151 outer < BlockSize; 152 outer++, index += refWidth - BlockSize) 153 { 154 for (inner = 0; inner < BlockSize; inner++, count++,index++) 155 { 156 tempPel = ( 157 pTempSrcRefBuf[index] 158 + pTempSrcRefBuf[index + x] * armAbs(x) 159 + pTempSrcRefBuf[index + refWidth * y] * armAbs(y) 160 + pTempSrcRefBuf[index + refWidth * y + x] 161 * armAbs(x*y) 162 + armAbs (x) + armAbs (y) - rndVal 163 ) / (2 * (armAbs (x) + armAbs (y))); 164 candSAD += armAbs (tempPel - pSrcCurrBuf[count]); 165 } 166 } 167 168 /* Result calculations */ 169 if (armVCM4P2_CompareMV (x, y, candSAD, halfPelX, halfPelY, minSAD)) 170 { 171 *pDstSAD = candSAD; 172 minSAD = candSAD; 173 halfPelX = x; 174 halfPelY = y; 175 } 176 177 } /* End of x- axis */ 178 } /* End of y-axis */ 179 180 pSrcDstMV->dx += halfPelX; 181 pSrcDstMV->dy += halfPelY; 182 183 return OMX_Sts_NoErr; 184 185 } 186 187 /* End of file */ 188