1/* 2 * Copyright (C) 2007-2008 ARM Limited 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 * 16 */ 17/** 18 * 19 * File Name: armVCM4P2_BlockMatch_Integer.c 20 * OpenMAX DL: v1.0.2 21 * Revision: 9641 22 * Date: Thursday, February 7, 2008 23 * 24 * 25 * 26 * 27 * Description: 28 * Contains modules for Block matching, a full search algorithm 29 * is implemented 30 * 31 */ 32 33#include "omxtypes.h" 34#include "armOMX.h" 35#include "omxVC.h" 36 37#include "armVC.h" 38#include "armCOMM.h" 39 40/** 41 * Function: armVCM4P2_BlockMatch_Integer 42 * 43 * Description: 44 * Performs a 16x16 block search; estimates motion vector and associated minimum SAD. 45 * Both the input and output motion vectors are represented using half-pixel units, and 46 * therefore a shift left or right by 1 bit may be required, respectively, to match the 47 * input or output MVs with other functions that either generate output MVs or expect 48 * input MVs represented using integer pixel units. 49 * 50 * Remarks: 51 * 52 * Parameters: 53 * [in] pSrcRefBuf pointer to the reference Y plane; points to the reference MB that 54 * corresponds to the location of the current macroblock in the current 55 * plane. 56 * [in] refWidth width of the reference plane 57 * [in] pRefRect pointer to the valid rectangular in reference plane. Relative to image origin. 58 * It's not limited to the image boundary, but depended on the padding. For example, 59 * if you pad 4 pixels outside the image border, then the value for left border 60 * can be -4 61 * [in] pSrcCurrBuf pointer to the current macroblock extracted from original plane (linear array, 62 * 256 entries); must be aligned on an 8-byte boundary. 63 * [in] pCurrPointPos position of the current macroblock in the current plane 64 * [in] pSrcPreMV pointer to predicted motion vector; NULL indicates no predicted MV 65 * [in] pSrcPreSAD pointer to SAD associated with the predicted MV (referenced by pSrcPreMV) 66 * [in] searchRange search range for 16X16 integer block,the units of it is full pixel,the search range 67 * is the same in all directions.It is in inclusive of the boundary and specified in 68 * terms of integer pixel units. 69 * [in] pMESpec vendor-specific motion estimation specification structure; must have been allocated 70 * and then initialized using omxVCM4P2_MEInit prior to calling the block matching 71 * function. 72 * [out] pDstMV pointer to estimated MV 73 * [out] pDstSAD pointer to minimum SAD 74 * 75 * Return Value: 76 * OMX_Sts_NoErr �C no error. 77 * OMX_Sts_BadArgErr �C bad arguments 78 * 79 */ 80 81OMXResult armVCM4P2_BlockMatch_Integer( 82 const OMX_U8 *pSrcRefBuf, 83 OMX_INT refWidth, 84 const OMXRect *pRefRect, 85 const OMX_U8 *pSrcCurrBuf, 86 const OMXVCM4P2Coordinate *pCurrPointPos, 87 const OMXVCMotionVector *pSrcPreMV, 88 const OMX_INT *pSrcPreSAD, 89 void *pMESpec, 90 OMXVCMotionVector *pDstMV, 91 OMX_INT *pDstSAD, 92 OMX_U8 BlockSize 93) 94{ 95 96 /* Definitions and Initializations*/ 97 98 OMX_INT outer, inner, count,index; 99 OMX_INT candSAD; 100 /*(256*256 +1) this is to make the SAD max initially*/ 101 OMX_INT minSAD = 0x10001, fromX, toX, fromY, toY; 102 /* Offset to the reference at the begining of the bounding box */ 103 const OMX_U8 *pTempSrcRefBuf; 104 OMX_S16 x, y; 105 OMX_INT searchRange; 106 107 /* Argument error checks */ 108 armRetArgErrIf(pSrcRefBuf == NULL, OMX_Sts_BadArgErr); 109 armRetArgErrIf(pRefRect == NULL, OMX_Sts_BadArgErr); 110 armRetArgErrIf(pSrcCurrBuf == NULL, OMX_Sts_BadArgErr); 111 armRetArgErrIf(pCurrPointPos == NULL, OMX_Sts_BadArgErr); 112 armRetArgErrIf(pMESpec == NULL, OMX_Sts_BadArgErr); 113 armRetArgErrIf(pDstMV == NULL, OMX_Sts_BadArgErr); 114 armRetArgErrIf(pDstSAD == NULL, OMX_Sts_BadArgErr); 115 116 searchRange = ((OMXVCM4P2MEParams *)pMESpec)->searchRange; 117 /* Check for valid region */ 118 fromX = searchRange; 119 toX = searchRange; 120 fromY = searchRange; 121 toY = searchRange; 122 123 if ((pCurrPointPos->x - searchRange) < pRefRect->x) 124 { 125 fromX = pCurrPointPos->x - pRefRect->x; 126 } 127 128 if ((pCurrPointPos->x + BlockSize + searchRange) > (pRefRect->x + pRefRect->width)) 129 { 130 toX = pRefRect->width - (pCurrPointPos->x - pRefRect->x) - BlockSize; 131 } 132 133 if ((pCurrPointPos->y - searchRange) < pRefRect->y) 134 { 135 fromY = pCurrPointPos->y - pRefRect->y; 136 } 137 138 if ((pCurrPointPos->y + BlockSize + searchRange) > (pRefRect->y + pRefRect->height)) 139 { 140 toY = pRefRect->width - (pCurrPointPos->y - pRefRect->y) - BlockSize; 141 } 142 143 pDstMV->dx = -fromX; 144 pDstMV->dy = -fromY; 145 /* Looping on y- axis */ 146 for (y = -fromY; y <= toY; y++) 147 { 148 149 /* Looping on x- axis */ 150 for (x = -fromX; x <= toX; x++) 151 { 152 /* Positioning the pointer */ 153 pTempSrcRefBuf = pSrcRefBuf + (refWidth * y) + x; 154 155 /* Calculate the SAD */ 156 for (outer = 0, count = 0, index = 0, candSAD = 0; 157 outer < BlockSize; 158 outer++, index += refWidth - BlockSize) 159 { 160 for (inner = 0; inner < BlockSize; inner++, count++, index++) 161 { 162 candSAD += armAbs (pTempSrcRefBuf[index] - pSrcCurrBuf[count]); 163 } 164 } 165 166 /* Result calculations */ 167 if (armVCM4P2_CompareMV (x, y, candSAD, pDstMV->dx/2, pDstMV->dy/2, minSAD)) 168 { 169 *pDstSAD = candSAD; 170 minSAD = candSAD; 171 pDstMV->dx = x*2; 172 pDstMV->dy = y*2; 173 } 174 175 } /* End of x- axis */ 176 } /* End of y-axis */ 177 178 return OMX_Sts_NoErr; 179 180} 181 182/* End of file */ 183