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