1/** 2 * 3 * File Name: armVCM4P2_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: armVCM4P2_BlockMatch_Integer 27 * 28 * Description: 29 * Performs a 16x16 block search; estimates motion vector and associated minimum SAD. 30 * Both the input and output motion vectors are represented using half-pixel units, and 31 * therefore a shift left or right by 1 bit may be required, respectively, to match the 32 * input or output MVs with other functions that either generate output MVs or expect 33 * input MVs represented using integer pixel units. 34 * 35 * Remarks: 36 * 37 * Parameters: 38 * [in] pSrcRefBuf pointer to the reference Y plane; points to the reference MB that 39 * corresponds to the location of the current macroblock in the current 40 * plane. 41 * [in] refWidth width of the reference plane 42 * [in] pRefRect pointer to the valid rectangular in reference plane. Relative to image origin. 43 * It's not limited to the image boundary, but depended on the padding. For example, 44 * if you pad 4 pixels outside the image border, then the value for left border 45 * can be -4 46 * [in] pSrcCurrBuf pointer to the current macroblock extracted from original plane (linear array, 47 * 256 entries); must be aligned on an 8-byte boundary. 48 * [in] pCurrPointPos position of the current macroblock in the current plane 49 * [in] pSrcPreMV pointer to predicted motion vector; NULL indicates no predicted MV 50 * [in] pSrcPreSAD pointer to SAD associated with the predicted MV (referenced by pSrcPreMV) 51 * [in] searchRange search range for 16X16 integer block,the units of it is full pixel,the search range 52 * is the same in all directions.It is in inclusive of the boundary and specified in 53 * terms of integer pixel units. 54 * [in] pMESpec vendor-specific motion estimation specification structure; must have been allocated 55 * and then initialized using omxVCM4P2_MEInit prior to calling the block matching 56 * function. 57 * [out] pDstMV pointer to estimated MV 58 * [out] pDstSAD pointer to minimum SAD 59 * 60 * Return Value: 61 * OMX_Sts_NoErr ¨C no error. 62 * OMX_Sts_BadArgErr ¨C bad arguments 63 * 64 */ 65 66OMXResult armVCM4P2_BlockMatch_Integer( 67 const OMX_U8 *pSrcRefBuf, 68 OMX_INT refWidth, 69 const OMXRect *pRefRect, 70 const OMX_U8 *pSrcCurrBuf, 71 const OMXVCM4P2Coordinate *pCurrPointPos, 72 const OMXVCMotionVector *pSrcPreMV, 73 const OMX_INT *pSrcPreSAD, 74 void *pMESpec, 75 OMXVCMotionVector *pDstMV, 76 OMX_INT *pDstSAD, 77 OMX_U8 BlockSize 78) 79{ 80 81 /* Definitions and Initializations*/ 82 83 OMX_INT outer, inner, count,index; 84 OMX_INT candSAD; 85 /*(256*256 +1) this is to make the SAD max initially*/ 86 OMX_INT minSAD = 0x10001, fromX, toX, fromY, toY; 87 /* Offset to the reference at the begining of the bounding box */ 88 const OMX_U8 *pTempSrcRefBuf; 89 OMX_S16 x, y; 90 OMX_INT searchRange; 91 92 /* Argument error checks */ 93 armRetArgErrIf(pSrcRefBuf == NULL, OMX_Sts_BadArgErr); 94 armRetArgErrIf(pRefRect == NULL, OMX_Sts_BadArgErr); 95 armRetArgErrIf(pSrcCurrBuf == NULL, OMX_Sts_BadArgErr); 96 armRetArgErrIf(pCurrPointPos == NULL, OMX_Sts_BadArgErr); 97 armRetArgErrIf(pMESpec == NULL, OMX_Sts_BadArgErr); 98 armRetArgErrIf(pDstMV == NULL, OMX_Sts_BadArgErr); 99 armRetArgErrIf(pDstSAD == NULL, OMX_Sts_BadArgErr); 100 101 searchRange = ((OMXVCM4P2MEParams *)pMESpec)->searchRange; 102 /* Check for valid region */ 103 fromX = searchRange; 104 toX = searchRange; 105 fromY = searchRange; 106 toY = searchRange; 107 108 if ((pCurrPointPos->x - searchRange) < pRefRect->x) 109 { 110 fromX = pCurrPointPos->x - pRefRect->x; 111 } 112 113 if ((pCurrPointPos->x + BlockSize + searchRange) > (pRefRect->x + pRefRect->width)) 114 { 115 toX = pRefRect->width - (pCurrPointPos->x - pRefRect->x) - BlockSize; 116 } 117 118 if ((pCurrPointPos->y - searchRange) < pRefRect->y) 119 { 120 fromY = pCurrPointPos->y - pRefRect->y; 121 } 122 123 if ((pCurrPointPos->y + BlockSize + searchRange) > (pRefRect->y + pRefRect->height)) 124 { 125 toY = pRefRect->width - (pCurrPointPos->y - pRefRect->y) - BlockSize; 126 } 127 128 pDstMV->dx = -fromX; 129 pDstMV->dy = -fromY; 130 /* Looping on y- axis */ 131 for (y = -fromY; y <= toY; y++) 132 { 133 134 /* Looping on x- axis */ 135 for (x = -fromX; x <= toX; x++) 136 { 137 /* Positioning the pointer */ 138 pTempSrcRefBuf = pSrcRefBuf + (refWidth * y) + x; 139 140 /* Calculate the SAD */ 141 for (outer = 0, count = 0, index = 0, candSAD = 0; 142 outer < BlockSize; 143 outer++, index += refWidth - BlockSize) 144 { 145 for (inner = 0; inner < BlockSize; inner++, count++, index++) 146 { 147 candSAD += armAbs (pTempSrcRefBuf[index] - pSrcCurrBuf[count]); 148 } 149 } 150 151 /* Result calculations */ 152 if (armVCM4P2_CompareMV (x, y, candSAD, pDstMV->dx/2, pDstMV->dy/2, minSAD)) 153 { 154 *pDstSAD = candSAD; 155 minSAD = candSAD; 156 pDstMV->dx = x*2; 157 pDstMV->dy = y*2; 158 } 159 160 } /* End of x- axis */ 161 } /* End of y-axis */ 162 163 return OMX_Sts_NoErr; 164 165} 166 167/* End of file */ 168