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