1 /** 2 * 3 * File Name: omxVCM4P10_BlockMatch_Integer.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: omxVCM4P10_BlockMatch_Integer (6.3.5.2.1) 27 * 28 * Description: 29 * Performs integer block match. Returns best MV and associated cost. 30 * 31 * Input Arguments: 32 * 33 * pSrcOrgY - Pointer to the top-left corner of the current block. If 34 * iBlockWidth==4, 4-byte alignment required. If iBlockWidth==8, 35 * 8-byte alignment required. If iBlockWidth==16, 16-byte alignment 36 * required. 37 * pSrcRefY - Pointer to the top-left corner of the co-located block in the 38 * reference picture. If iBlockWidth==4, 4-byte alignment 39 * required. If iBlockWidth==8, 8-byte alignment required. If 40 * iBlockWidth==16, 16-byte alignment required. 41 * nSrcOrgStep - Stride of the original picture plane, expressed in terms 42 * of integer pixels; must be a multiple of iBlockWidth. 43 * nSrcRefStep - Stride of the reference picture plane, expressed in terms 44 * of integer pixels 45 * pRefRect - pointer to the valid reference rectangle inside the reference 46 * picture plane 47 * nCurrPointPos - position of the current block in the current plane 48 * iBlockWidth - Width of the current block, expressed in terms of integer 49 * pixels; must be equal to either 4, 8, or 16. 50 * iBlockHeight - Height of the current block, expressed in terms of 51 * integer pixels; must be equal to either 4, 8, or 16. 52 * nLamda - Lamda factor; used to compute motion cost 53 * pMVPred - Predicted MV; used to compute motion cost, expressed in terms 54 * of 1/4-pel units 55 * pMVCandidate - Candidate MV; used to initialize the motion search, 56 * expressed in terms of integer pixels 57 * pMESpec - pointer to the ME specification structure 58 * 59 * Output Arguments: 60 * 61 * pDstBestMV - Best MV resulting from integer search, expressed in terms 62 * of 1/4-pel units 63 * pBestCost - Motion cost associated with the best MV; computed as 64 * SAD+Lamda*BitsUsedByMV 65 * 66 * Return Value: 67 * OMX_Sts_NoErr, if the function runs without error. 68 * OMX_Sts_BadArgErr - bad arguments: if one of the following cases occurs: 69 * - any of the following poitners are NULL: 70 * pSrcOrgY, pSrcRefY, pRefRect, pMVPred, pMVCandidate, or pMESpec. 71 * - Either iBlockWidth or iBlockHeight are values other than 4, 8, or 16. 72 * - Any alignment restrictions are violated 73 * 74 */ 75 76 OMXResult omxVCM4P10_BlockMatch_Integer ( 77 const OMX_U8 *pSrcOrgY, 78 OMX_S32 nSrcOrgStep, 79 const OMX_U8 *pSrcRefY, 80 OMX_S32 nSrcRefStep, 81 const OMXRect *pRefRect, 82 const OMXVCM4P2Coordinate *pCurrPointPos, 83 OMX_U8 iBlockWidth, 84 OMX_U8 iBlockHeight, 85 OMX_U32 nLamda, 86 const OMXVCMotionVector *pMVPred, 87 const OMXVCMotionVector *pMVCandidate, 88 OMXVCMotionVector *pBestMV, 89 OMX_S32 *pBestCost, 90 void *pMESpec 91 ) 92 { 93 /* Definitions and Initializations*/ 94 OMX_INT candSAD; 95 OMX_INT fromX, toX, fromY, toY; 96 /* Offset to the reference at the begining of the bounding box */ 97 const OMX_U8 *pTempSrcRefY, *pTempSrcOrgY; 98 OMX_S16 x, y; 99 OMXVCMotionVector diffMV; 100 OMX_S32 nSearchRange; 101 ARMVCM4P10_MESpec *armMESpec = (ARMVCM4P10_MESpec *) pMESpec; 102 103 /* Argument error checks */ 104 armRetArgErrIf((iBlockWidth == 4) && (!armIs4ByteAligned(pSrcOrgY)), OMX_Sts_BadArgErr); 105 armRetArgErrIf((iBlockWidth == 8) && (!armIs8ByteAligned(pSrcOrgY)), OMX_Sts_BadArgErr); 106 armRetArgErrIf((iBlockWidth == 16) && (!armIs16ByteAligned(pSrcOrgY)), OMX_Sts_BadArgErr); 107 armRetArgErrIf((iBlockWidth == 4) && (!armIs4ByteAligned(pSrcRefY)), OMX_Sts_BadArgErr); 108 armRetArgErrIf((iBlockWidth == 8) && (!armIs8ByteAligned(pSrcRefY)), OMX_Sts_BadArgErr); 109 armRetArgErrIf((iBlockWidth == 16) && (!armIs16ByteAligned(pSrcRefY)), OMX_Sts_BadArgErr); 110 armRetArgErrIf(pSrcOrgY == NULL, OMX_Sts_BadArgErr); 111 armRetArgErrIf(pSrcRefY == NULL, OMX_Sts_BadArgErr); 112 armRetArgErrIf(pMVPred == NULL, OMX_Sts_BadArgErr); 113 armRetArgErrIf(pMVCandidate == NULL, OMX_Sts_BadArgErr); 114 armRetArgErrIf(pBestMV == NULL, OMX_Sts_BadArgErr); 115 armRetArgErrIf(pBestCost == NULL, OMX_Sts_BadArgErr); 116 armRetArgErrIf(((iBlockWidth!=4)&&(iBlockWidth!=8)&&(iBlockWidth!=16)) , OMX_Sts_BadArgErr); 117 armRetArgErrIf(((iBlockHeight!=4)&&(iBlockHeight!=8)&&(iBlockHeight!=16)) , OMX_Sts_BadArgErr); 118 armIgnore (pMESpec); 119 120 if(iBlockWidth == 4) 121 { 122 nSearchRange = armMESpec->MEParams.searchRange4x4; 123 } 124 else if(iBlockWidth == 8) 125 { 126 nSearchRange = armMESpec->MEParams.searchRange8x8; 127 } 128 else 129 { 130 nSearchRange = armMESpec->MEParams.searchRange16x16; 131 } 132 /* Check for valid region */ 133 fromX = nSearchRange; 134 toX = nSearchRange; 135 fromY = nSearchRange; 136 toY = nSearchRange; 137 138 if ((pCurrPointPos->x - nSearchRange) < pRefRect->x) 139 { 140 fromX = pCurrPointPos->x - pRefRect->x; 141 } 142 143 if ((pCurrPointPos->x + iBlockWidth + nSearchRange) > (pRefRect->x + pRefRect->width)) 144 { 145 toX = pRefRect->width - (pCurrPointPos->x - pRefRect->x) - iBlockWidth; 146 } 147 148 if ((pCurrPointPos->y - nSearchRange) < pRefRect->y) 149 { 150 fromY = pCurrPointPos->y - pRefRect->y; 151 } 152 153 if ((pCurrPointPos->y + iBlockWidth + nSearchRange) > (pRefRect->y + pRefRect->height)) 154 { 155 toY = pRefRect->width - (pCurrPointPos->y - pRefRect->y) - iBlockWidth; 156 } 157 158 pBestMV->dx = -fromX * 4; 159 pBestMV->dy = -fromY * 4; 160 /* Initialize to max value as a start point */ 161 *pBestCost = 0x7fffffff; 162 163 /* Looping on y- axis */ 164 for (y = -fromY; y <= toY; y++) 165 { 166 /* Looping on x- axis */ 167 for (x = -fromX; x <= toX; x++) 168 { 169 /* Positioning the pointer */ 170 pTempSrcRefY = pSrcRefY + (nSrcRefStep * y) + x; 171 pTempSrcOrgY = pSrcOrgY; 172 173 /* Calculate the SAD */ 174 armVCCOMM_SAD( 175 pTempSrcOrgY, 176 nSrcOrgStep, 177 pTempSrcRefY, 178 nSrcRefStep, 179 &candSAD, 180 iBlockHeight, 181 iBlockWidth); 182 183 diffMV.dx = (x * 4) - pMVPred->dx; 184 diffMV.dy = (y * 4) - pMVPred->dy; 185 186 /* Result calculations */ 187 armVCM4P10_CompareMotionCostToMV ((x * 4), (y * 4), diffMV, candSAD, pBestMV, nLamda, pBestCost); 188 189 } /* End of x- axis */ 190 } /* End of y-axis */ 191 192 return OMX_Sts_NoErr; 193 194 } 195 196 /* End of file */ 197