178e52bfac041d71ce53b5b13c2abf78af742b09dLajos Molnar/* 278e52bfac041d71ce53b5b13c2abf78af742b09dLajos Molnar * Copyright (C) 2007-2008 ARM Limited 378e52bfac041d71ce53b5b13c2abf78af742b09dLajos Molnar * 478e52bfac041d71ce53b5b13c2abf78af742b09dLajos Molnar * Licensed under the Apache License, Version 2.0 (the "License"); 578e52bfac041d71ce53b5b13c2abf78af742b09dLajos Molnar * you may not use this file except in compliance with the License. 678e52bfac041d71ce53b5b13c2abf78af742b09dLajos Molnar * You may obtain a copy of the License at 778e52bfac041d71ce53b5b13c2abf78af742b09dLajos Molnar * 878e52bfac041d71ce53b5b13c2abf78af742b09dLajos Molnar * http://www.apache.org/licenses/LICENSE-2.0 978e52bfac041d71ce53b5b13c2abf78af742b09dLajos Molnar * 1078e52bfac041d71ce53b5b13c2abf78af742b09dLajos Molnar * Unless required by applicable law or agreed to in writing, software 1178e52bfac041d71ce53b5b13c2abf78af742b09dLajos Molnar * distributed under the License is distributed on an "AS IS" BASIS, 1278e52bfac041d71ce53b5b13c2abf78af742b09dLajos Molnar * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1378e52bfac041d71ce53b5b13c2abf78af742b09dLajos Molnar * See the License for the specific language governing permissions and 1478e52bfac041d71ce53b5b13c2abf78af742b09dLajos Molnar * limitations under the License. 1578e52bfac041d71ce53b5b13c2abf78af742b09dLajos Molnar * 1678e52bfac041d71ce53b5b13c2abf78af742b09dLajos Molnar */ 170c1bc742181ded4930842b46e9507372f0b1b963James Dong/** 180c1bc742181ded4930842b46e9507372f0b1b963James Dong * 190c1bc742181ded4930842b46e9507372f0b1b963James Dong * File Name: armVCM4P2_BlockMatch_Half.c 200c1bc742181ded4930842b46e9507372f0b1b963James Dong * OpenMAX DL: v1.0.2 210c1bc742181ded4930842b46e9507372f0b1b963James Dong * Revision: 9641 220c1bc742181ded4930842b46e9507372f0b1b963James Dong * Date: Thursday, February 7, 2008 230c1bc742181ded4930842b46e9507372f0b1b963James Dong * 240c1bc742181ded4930842b46e9507372f0b1b963James Dong * 250c1bc742181ded4930842b46e9507372f0b1b963James Dong * 260c1bc742181ded4930842b46e9507372f0b1b963James Dong * 270c1bc742181ded4930842b46e9507372f0b1b963James Dong * Description: 280c1bc742181ded4930842b46e9507372f0b1b963James Dong * Contains modules for Block matching, a full search algorithm 290c1bc742181ded4930842b46e9507372f0b1b963James Dong * is implemented 300c1bc742181ded4930842b46e9507372f0b1b963James Dong * 310c1bc742181ded4930842b46e9507372f0b1b963James Dong */ 320c1bc742181ded4930842b46e9507372f0b1b963James Dong 330c1bc742181ded4930842b46e9507372f0b1b963James Dong#include "omxtypes.h" 340c1bc742181ded4930842b46e9507372f0b1b963James Dong#include "armOMX.h" 350c1bc742181ded4930842b46e9507372f0b1b963James Dong#include "omxVC.h" 360c1bc742181ded4930842b46e9507372f0b1b963James Dong 370c1bc742181ded4930842b46e9507372f0b1b963James Dong#include "armVC.h" 380c1bc742181ded4930842b46e9507372f0b1b963James Dong#include "armCOMM.h" 390c1bc742181ded4930842b46e9507372f0b1b963James Dong 400c1bc742181ded4930842b46e9507372f0b1b963James Dong/** 410c1bc742181ded4930842b46e9507372f0b1b963James Dong * Function: armVCM4P2_BlockMatch_Half 420c1bc742181ded4930842b46e9507372f0b1b963James Dong * 430c1bc742181ded4930842b46e9507372f0b1b963James Dong * Description: 440c1bc742181ded4930842b46e9507372f0b1b963James Dong * Performs a 16x16 block match with half-pixel resolution. Returns the estimated 450c1bc742181ded4930842b46e9507372f0b1b963James Dong * motion vector and associated minimum SAD. This function estimates the half-pixel 460c1bc742181ded4930842b46e9507372f0b1b963James Dong * motion vector by interpolating the integer resolution motion vector referenced 470c1bc742181ded4930842b46e9507372f0b1b963James Dong * by the input parameter pSrcDstMV, i.e., the initial integer MV is generated 480c1bc742181ded4930842b46e9507372f0b1b963James Dong * externally. The input parameters pSrcRefBuf and pSearchPointRefPos should be 490c1bc742181ded4930842b46e9507372f0b1b963James Dong * shifted by the winning MV of 16x16 integer search prior to calling BlockMatch_Half_16x16. 500c1bc742181ded4930842b46e9507372f0b1b963James Dong * The function BlockMatch_Integer_16x16 may be used for integer motion estimation. 510c1bc742181ded4930842b46e9507372f0b1b963James Dong * 520c1bc742181ded4930842b46e9507372f0b1b963James Dong * Remarks: 530c1bc742181ded4930842b46e9507372f0b1b963James Dong * 540c1bc742181ded4930842b46e9507372f0b1b963James Dong * Parameters: 550c1bc742181ded4930842b46e9507372f0b1b963James Dong * [in] pSrcRefBuf pointer to the reference Y plane; points to the reference MB 560c1bc742181ded4930842b46e9507372f0b1b963James Dong * that corresponds to the location of the current macroblock in 570c1bc742181ded4930842b46e9507372f0b1b963James Dong * the current plane. 580c1bc742181ded4930842b46e9507372f0b1b963James Dong * [in] refWidth width of the reference plane 590c1bc742181ded4930842b46e9507372f0b1b963James Dong * [in] pRefRect reference plane valid region rectangle 600c1bc742181ded4930842b46e9507372f0b1b963James Dong * [in] pSrcCurrBuf pointer to the current macroblock extracted from original plane 610c1bc742181ded4930842b46e9507372f0b1b963James Dong * (linear array, 256 entries); must be aligned on an 8-byte boundary. 620c1bc742181ded4930842b46e9507372f0b1b963James Dong * [in] pSearchPointRefPos position of the starting point for half pixel search (specified 630c1bc742181ded4930842b46e9507372f0b1b963James Dong * in terms of integer pixel units) in the reference plane. 640c1bc742181ded4930842b46e9507372f0b1b963James Dong * [in] rndVal rounding control bit for half pixel motion estimation; 650c1bc742181ded4930842b46e9507372f0b1b963James Dong * 0=rounding control disabled; 1=rounding control enabled 660c1bc742181ded4930842b46e9507372f0b1b963James Dong * [in] pSrcDstMV pointer to the initial MV estimate; typically generated during a prior 670c1bc742181ded4930842b46e9507372f0b1b963James Dong * 16X16 integer search and its unit is half pixel. 680c1bc742181ded4930842b46e9507372f0b1b963James Dong * [in] BlockSize MacroBlock Size i.e either 16x16 or 8x8. 690c1bc742181ded4930842b46e9507372f0b1b963James Dong * [out]pSrcDstMV pointer to estimated MV 700c1bc742181ded4930842b46e9507372f0b1b963James Dong * [out]pDstSAD pointer to minimum SAD 710c1bc742181ded4930842b46e9507372f0b1b963James Dong * 720c1bc742181ded4930842b46e9507372f0b1b963James Dong * Return Value: 730c1bc742181ded4930842b46e9507372f0b1b963James Dong * OMX_Sts_NoErr �C no error 740c1bc742181ded4930842b46e9507372f0b1b963James Dong * OMX_Sts_BadArgErr �C bad arguments 750c1bc742181ded4930842b46e9507372f0b1b963James Dong * 760c1bc742181ded4930842b46e9507372f0b1b963James Dong */ 770c1bc742181ded4930842b46e9507372f0b1b963James Dong 780c1bc742181ded4930842b46e9507372f0b1b963James DongOMXResult armVCM4P2_BlockMatch_Half( 790c1bc742181ded4930842b46e9507372f0b1b963James Dong const OMX_U8 *pSrcRefBuf, 800c1bc742181ded4930842b46e9507372f0b1b963James Dong OMX_INT refWidth, 810c1bc742181ded4930842b46e9507372f0b1b963James Dong const OMXRect *pRefRect, 820c1bc742181ded4930842b46e9507372f0b1b963James Dong const OMX_U8 *pSrcCurrBuf, 830c1bc742181ded4930842b46e9507372f0b1b963James Dong const OMXVCM4P2Coordinate *pSearchPointRefPos, 840c1bc742181ded4930842b46e9507372f0b1b963James Dong OMX_INT rndVal, 850c1bc742181ded4930842b46e9507372f0b1b963James Dong OMXVCMotionVector *pSrcDstMV, 860c1bc742181ded4930842b46e9507372f0b1b963James Dong OMX_INT *pDstSAD, 870c1bc742181ded4930842b46e9507372f0b1b963James Dong OMX_U8 BlockSize 880c1bc742181ded4930842b46e9507372f0b1b963James Dong) 890c1bc742181ded4930842b46e9507372f0b1b963James Dong{ 900c1bc742181ded4930842b46e9507372f0b1b963James Dong OMX_INT outer, inner, count, index; 910c1bc742181ded4930842b46e9507372f0b1b963James Dong OMX_S16 halfPelX = 0, halfPelY = 0, x, y; 920c1bc742181ded4930842b46e9507372f0b1b963James Dong OMX_INT candSAD, refSAD = 0; 930c1bc742181ded4930842b46e9507372f0b1b963James Dong OMX_INT minSAD, fromX, toX, fromY, toY; 940c1bc742181ded4930842b46e9507372f0b1b963James Dong /* Offset to the reference at the begining of the bounding box */ 950c1bc742181ded4930842b46e9507372f0b1b963James Dong const OMX_U8 *pTempSrcRefBuf; 960c1bc742181ded4930842b46e9507372f0b1b963James Dong OMX_U8 tempPel; 970c1bc742181ded4930842b46e9507372f0b1b963James Dong 980c1bc742181ded4930842b46e9507372f0b1b963James Dong /* Argument error checks */ 990c1bc742181ded4930842b46e9507372f0b1b963James Dong armRetArgErrIf(pSrcRefBuf == NULL, OMX_Sts_BadArgErr); 1000c1bc742181ded4930842b46e9507372f0b1b963James Dong armRetArgErrIf(pRefRect == NULL, OMX_Sts_BadArgErr); 1010c1bc742181ded4930842b46e9507372f0b1b963James Dong armRetArgErrIf(pSrcCurrBuf == NULL, OMX_Sts_BadArgErr); 1020c1bc742181ded4930842b46e9507372f0b1b963James Dong armRetArgErrIf(pSearchPointRefPos == NULL, OMX_Sts_BadArgErr); 1030c1bc742181ded4930842b46e9507372f0b1b963James Dong armRetArgErrIf(pSrcDstMV == NULL, OMX_Sts_BadArgErr); 1040c1bc742181ded4930842b46e9507372f0b1b963James Dong armRetArgErrIf(pDstSAD == NULL, OMX_Sts_BadArgErr); 1050c1bc742181ded4930842b46e9507372f0b1b963James Dong 1060c1bc742181ded4930842b46e9507372f0b1b963James Dong /* Positioning the pointer */ 1070c1bc742181ded4930842b46e9507372f0b1b963James Dong pTempSrcRefBuf = pSrcRefBuf + (refWidth * (pSrcDstMV->dy/2)) + (pSrcDstMV->dx/2); 1080c1bc742181ded4930842b46e9507372f0b1b963James Dong 1090c1bc742181ded4930842b46e9507372f0b1b963James Dong /* Copy the candidate to the temporary linear array */ 1100c1bc742181ded4930842b46e9507372f0b1b963James Dong for (outer = 0, count = 0,index = 0; 1110c1bc742181ded4930842b46e9507372f0b1b963James Dong outer < BlockSize; 1120c1bc742181ded4930842b46e9507372f0b1b963James Dong outer++, index += refWidth - BlockSize) 1130c1bc742181ded4930842b46e9507372f0b1b963James Dong { 1140c1bc742181ded4930842b46e9507372f0b1b963James Dong for (inner = 0; inner < BlockSize; inner++, count++, index++) 1150c1bc742181ded4930842b46e9507372f0b1b963James Dong { 1160c1bc742181ded4930842b46e9507372f0b1b963James Dong refSAD += armAbs (pTempSrcRefBuf[index] - pSrcCurrBuf[count]); 1170c1bc742181ded4930842b46e9507372f0b1b963James Dong } 1180c1bc742181ded4930842b46e9507372f0b1b963James Dong } 1190c1bc742181ded4930842b46e9507372f0b1b963James Dong 1200c1bc742181ded4930842b46e9507372f0b1b963James Dong /* Set the minSad as reference SAD */ 1210c1bc742181ded4930842b46e9507372f0b1b963James Dong minSAD = refSAD; 1220c1bc742181ded4930842b46e9507372f0b1b963James Dong *pDstSAD = refSAD; 1230c1bc742181ded4930842b46e9507372f0b1b963James Dong 1240c1bc742181ded4930842b46e9507372f0b1b963James Dong /* Check for valid region */ 1250c1bc742181ded4930842b46e9507372f0b1b963James Dong fromX = 1; 1260c1bc742181ded4930842b46e9507372f0b1b963James Dong toX = 1; 1270c1bc742181ded4930842b46e9507372f0b1b963James Dong fromY = 1; 1280c1bc742181ded4930842b46e9507372f0b1b963James Dong toY = 1; 1290c1bc742181ded4930842b46e9507372f0b1b963James Dong if ((pSearchPointRefPos->x - 1) < pRefRect->x) 1300c1bc742181ded4930842b46e9507372f0b1b963James Dong { 1310c1bc742181ded4930842b46e9507372f0b1b963James Dong fromX = 0; 1320c1bc742181ded4930842b46e9507372f0b1b963James Dong } 1330c1bc742181ded4930842b46e9507372f0b1b963James Dong 1340c1bc742181ded4930842b46e9507372f0b1b963James Dong if ((pSearchPointRefPos->x + BlockSize + 1) > (pRefRect->x + pRefRect->width)) 1350c1bc742181ded4930842b46e9507372f0b1b963James Dong { 1360c1bc742181ded4930842b46e9507372f0b1b963James Dong toX = 0; 1370c1bc742181ded4930842b46e9507372f0b1b963James Dong } 1380c1bc742181ded4930842b46e9507372f0b1b963James Dong 1390c1bc742181ded4930842b46e9507372f0b1b963James Dong if ((pSearchPointRefPos->y - 1) < pRefRect->y) 1400c1bc742181ded4930842b46e9507372f0b1b963James Dong { 1410c1bc742181ded4930842b46e9507372f0b1b963James Dong fromY = 0; 1420c1bc742181ded4930842b46e9507372f0b1b963James Dong } 1430c1bc742181ded4930842b46e9507372f0b1b963James Dong 1440c1bc742181ded4930842b46e9507372f0b1b963James Dong if ((pSearchPointRefPos->y + BlockSize + 1) > (pRefRect->y + pRefRect->height)) 1450c1bc742181ded4930842b46e9507372f0b1b963James Dong { 1460c1bc742181ded4930842b46e9507372f0b1b963James Dong toY = 0; 1470c1bc742181ded4930842b46e9507372f0b1b963James Dong } 1480c1bc742181ded4930842b46e9507372f0b1b963James Dong 1490c1bc742181ded4930842b46e9507372f0b1b963James Dong /* Looping on y- axis */ 1500c1bc742181ded4930842b46e9507372f0b1b963James Dong for (y = -fromY; y <= toY; y++) 1510c1bc742181ded4930842b46e9507372f0b1b963James Dong { 1520c1bc742181ded4930842b46e9507372f0b1b963James Dong /* Looping on x- axis */ 1530c1bc742181ded4930842b46e9507372f0b1b963James Dong for (x = -fromX; x <= toX; x++) 1540c1bc742181ded4930842b46e9507372f0b1b963James Dong { 1550c1bc742181ded4930842b46e9507372f0b1b963James Dong /* check for integer position */ 1560c1bc742181ded4930842b46e9507372f0b1b963James Dong if ( x == 0 && y == 0) 1570c1bc742181ded4930842b46e9507372f0b1b963James Dong { 1580c1bc742181ded4930842b46e9507372f0b1b963James Dong continue; 1590c1bc742181ded4930842b46e9507372f0b1b963James Dong } 1600c1bc742181ded4930842b46e9507372f0b1b963James Dong /* Positioning the pointer */ 1610c1bc742181ded4930842b46e9507372f0b1b963James Dong pTempSrcRefBuf = pSrcRefBuf + (refWidth * (pSrcDstMV->dy/2)) 1620c1bc742181ded4930842b46e9507372f0b1b963James Dong + (pSrcDstMV->dx/2); 1630c1bc742181ded4930842b46e9507372f0b1b963James Dong 1640c1bc742181ded4930842b46e9507372f0b1b963James Dong /* Interpolate the pixel and calculate the SAD*/ 1650c1bc742181ded4930842b46e9507372f0b1b963James Dong for (outer = 0, count = 0, candSAD = 0,index = 0; 1660c1bc742181ded4930842b46e9507372f0b1b963James Dong outer < BlockSize; 1670c1bc742181ded4930842b46e9507372f0b1b963James Dong outer++, index += refWidth - BlockSize) 1680c1bc742181ded4930842b46e9507372f0b1b963James Dong { 1690c1bc742181ded4930842b46e9507372f0b1b963James Dong for (inner = 0; inner < BlockSize; inner++, count++,index++) 1700c1bc742181ded4930842b46e9507372f0b1b963James Dong { 1710c1bc742181ded4930842b46e9507372f0b1b963James Dong tempPel = ( 1720c1bc742181ded4930842b46e9507372f0b1b963James Dong pTempSrcRefBuf[index] 1730c1bc742181ded4930842b46e9507372f0b1b963James Dong + pTempSrcRefBuf[index + x] * armAbs(x) 1740c1bc742181ded4930842b46e9507372f0b1b963James Dong + pTempSrcRefBuf[index + refWidth * y] * armAbs(y) 1750c1bc742181ded4930842b46e9507372f0b1b963James Dong + pTempSrcRefBuf[index + refWidth * y + x] 1760c1bc742181ded4930842b46e9507372f0b1b963James Dong * armAbs(x*y) 1770c1bc742181ded4930842b46e9507372f0b1b963James Dong + armAbs (x) + armAbs (y) - rndVal 1780c1bc742181ded4930842b46e9507372f0b1b963James Dong ) / (2 * (armAbs (x) + armAbs (y))); 1790c1bc742181ded4930842b46e9507372f0b1b963James Dong candSAD += armAbs (tempPel - pSrcCurrBuf[count]); 1800c1bc742181ded4930842b46e9507372f0b1b963James Dong } 1810c1bc742181ded4930842b46e9507372f0b1b963James Dong } 1820c1bc742181ded4930842b46e9507372f0b1b963James Dong 1830c1bc742181ded4930842b46e9507372f0b1b963James Dong /* Result calculations */ 1840c1bc742181ded4930842b46e9507372f0b1b963James Dong if (armVCM4P2_CompareMV (x, y, candSAD, halfPelX, halfPelY, minSAD)) 1850c1bc742181ded4930842b46e9507372f0b1b963James Dong { 1860c1bc742181ded4930842b46e9507372f0b1b963James Dong *pDstSAD = candSAD; 1870c1bc742181ded4930842b46e9507372f0b1b963James Dong minSAD = candSAD; 1880c1bc742181ded4930842b46e9507372f0b1b963James Dong halfPelX = x; 1890c1bc742181ded4930842b46e9507372f0b1b963James Dong halfPelY = y; 1900c1bc742181ded4930842b46e9507372f0b1b963James Dong } 1910c1bc742181ded4930842b46e9507372f0b1b963James Dong 1920c1bc742181ded4930842b46e9507372f0b1b963James Dong } /* End of x- axis */ 1930c1bc742181ded4930842b46e9507372f0b1b963James Dong } /* End of y-axis */ 1940c1bc742181ded4930842b46e9507372f0b1b963James Dong 1950c1bc742181ded4930842b46e9507372f0b1b963James Dong pSrcDstMV->dx += halfPelX; 1960c1bc742181ded4930842b46e9507372f0b1b963James Dong pSrcDstMV->dy += halfPelY; 1970c1bc742181ded4930842b46e9507372f0b1b963James Dong 1980c1bc742181ded4930842b46e9507372f0b1b963James Dong return OMX_Sts_NoErr; 1990c1bc742181ded4930842b46e9507372f0b1b963James Dong 2000c1bc742181ded4930842b46e9507372f0b1b963James Dong} 2010c1bc742181ded4930842b46e9507372f0b1b963James Dong 2020c1bc742181ded4930842b46e9507372f0b1b963James Dong/* End of file */ 203