10c1bc742181ded4930842b46e9507372f0b1b963James Dong/** 20c1bc742181ded4930842b46e9507372f0b1b963James Dong * 30c1bc742181ded4930842b46e9507372f0b1b963James Dong * File Name: armVCM4P2_BlockMatch_Integer.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_Integer 270c1bc742181ded4930842b46e9507372f0b1b963James Dong * 280c1bc742181ded4930842b46e9507372f0b1b963James Dong * Description: 290c1bc742181ded4930842b46e9507372f0b1b963James Dong * Performs a 16x16 block search; estimates motion vector and associated minimum SAD. 300c1bc742181ded4930842b46e9507372f0b1b963James Dong * Both the input and output motion vectors are represented using half-pixel units, and 310c1bc742181ded4930842b46e9507372f0b1b963James Dong * therefore a shift left or right by 1 bit may be required, respectively, to match the 320c1bc742181ded4930842b46e9507372f0b1b963James Dong * input or output MVs with other functions that either generate output MVs or expect 330c1bc742181ded4930842b46e9507372f0b1b963James Dong * input MVs represented using integer pixel units. 340c1bc742181ded4930842b46e9507372f0b1b963James Dong * 350c1bc742181ded4930842b46e9507372f0b1b963James Dong * Remarks: 360c1bc742181ded4930842b46e9507372f0b1b963James Dong * 370c1bc742181ded4930842b46e9507372f0b1b963James Dong * Parameters: 380c1bc742181ded4930842b46e9507372f0b1b963James Dong * [in] pSrcRefBuf pointer to the reference Y plane; points to the reference MB that 390c1bc742181ded4930842b46e9507372f0b1b963James Dong * corresponds to the location of the current macroblock in the current 400c1bc742181ded4930842b46e9507372f0b1b963James Dong * plane. 410c1bc742181ded4930842b46e9507372f0b1b963James Dong * [in] refWidth width of the reference plane 420c1bc742181ded4930842b46e9507372f0b1b963James Dong * [in] pRefRect pointer to the valid rectangular in reference plane. Relative to image origin. 430c1bc742181ded4930842b46e9507372f0b1b963James Dong * It's not limited to the image boundary, but depended on the padding. For example, 440c1bc742181ded4930842b46e9507372f0b1b963James Dong * if you pad 4 pixels outside the image border, then the value for left border 450c1bc742181ded4930842b46e9507372f0b1b963James Dong * can be -4 460c1bc742181ded4930842b46e9507372f0b1b963James Dong * [in] pSrcCurrBuf pointer to the current macroblock extracted from original plane (linear array, 470c1bc742181ded4930842b46e9507372f0b1b963James Dong * 256 entries); must be aligned on an 8-byte boundary. 480c1bc742181ded4930842b46e9507372f0b1b963James Dong * [in] pCurrPointPos position of the current macroblock in the current plane 490c1bc742181ded4930842b46e9507372f0b1b963James Dong * [in] pSrcPreMV pointer to predicted motion vector; NULL indicates no predicted MV 500c1bc742181ded4930842b46e9507372f0b1b963James Dong * [in] pSrcPreSAD pointer to SAD associated with the predicted MV (referenced by pSrcPreMV) 510c1bc742181ded4930842b46e9507372f0b1b963James Dong * [in] searchRange search range for 16X16 integer block,the units of it is full pixel,the search range 520c1bc742181ded4930842b46e9507372f0b1b963James Dong * is the same in all directions.It is in inclusive of the boundary and specified in 530c1bc742181ded4930842b46e9507372f0b1b963James Dong * terms of integer pixel units. 540c1bc742181ded4930842b46e9507372f0b1b963James Dong * [in] pMESpec vendor-specific motion estimation specification structure; must have been allocated 550c1bc742181ded4930842b46e9507372f0b1b963James Dong * and then initialized using omxVCM4P2_MEInit prior to calling the block matching 560c1bc742181ded4930842b46e9507372f0b1b963James Dong * function. 570c1bc742181ded4930842b46e9507372f0b1b963James Dong * [out] pDstMV pointer to estimated MV 580c1bc742181ded4930842b46e9507372f0b1b963James Dong * [out] pDstSAD pointer to minimum SAD 590c1bc742181ded4930842b46e9507372f0b1b963James Dong * 600c1bc742181ded4930842b46e9507372f0b1b963James Dong * Return Value: 610c1bc742181ded4930842b46e9507372f0b1b963James Dong * OMX_Sts_NoErr �C no error. 620c1bc742181ded4930842b46e9507372f0b1b963James Dong * OMX_Sts_BadArgErr �C bad arguments 630c1bc742181ded4930842b46e9507372f0b1b963James Dong * 640c1bc742181ded4930842b46e9507372f0b1b963James Dong */ 650c1bc742181ded4930842b46e9507372f0b1b963James Dong 660c1bc742181ded4930842b46e9507372f0b1b963James DongOMXResult armVCM4P2_BlockMatch_Integer( 670c1bc742181ded4930842b46e9507372f0b1b963James Dong const OMX_U8 *pSrcRefBuf, 680c1bc742181ded4930842b46e9507372f0b1b963James Dong OMX_INT refWidth, 690c1bc742181ded4930842b46e9507372f0b1b963James Dong const OMXRect *pRefRect, 700c1bc742181ded4930842b46e9507372f0b1b963James Dong const OMX_U8 *pSrcCurrBuf, 710c1bc742181ded4930842b46e9507372f0b1b963James Dong const OMXVCM4P2Coordinate *pCurrPointPos, 720c1bc742181ded4930842b46e9507372f0b1b963James Dong const OMXVCMotionVector *pSrcPreMV, 730c1bc742181ded4930842b46e9507372f0b1b963James Dong const OMX_INT *pSrcPreSAD, 740c1bc742181ded4930842b46e9507372f0b1b963James Dong void *pMESpec, 750c1bc742181ded4930842b46e9507372f0b1b963James Dong OMXVCMotionVector *pDstMV, 760c1bc742181ded4930842b46e9507372f0b1b963James Dong OMX_INT *pDstSAD, 770c1bc742181ded4930842b46e9507372f0b1b963James Dong OMX_U8 BlockSize 780c1bc742181ded4930842b46e9507372f0b1b963James Dong) 790c1bc742181ded4930842b46e9507372f0b1b963James Dong{ 800c1bc742181ded4930842b46e9507372f0b1b963James Dong 810c1bc742181ded4930842b46e9507372f0b1b963James Dong /* Definitions and Initializations*/ 820c1bc742181ded4930842b46e9507372f0b1b963James Dong 830c1bc742181ded4930842b46e9507372f0b1b963James Dong OMX_INT outer, inner, count,index; 840c1bc742181ded4930842b46e9507372f0b1b963James Dong OMX_INT candSAD; 850c1bc742181ded4930842b46e9507372f0b1b963James Dong /*(256*256 +1) this is to make the SAD max initially*/ 860c1bc742181ded4930842b46e9507372f0b1b963James Dong OMX_INT minSAD = 0x10001, fromX, toX, fromY, toY; 870c1bc742181ded4930842b46e9507372f0b1b963James Dong /* Offset to the reference at the begining of the bounding box */ 880c1bc742181ded4930842b46e9507372f0b1b963James Dong const OMX_U8 *pTempSrcRefBuf; 890c1bc742181ded4930842b46e9507372f0b1b963James Dong OMX_S16 x, y; 900c1bc742181ded4930842b46e9507372f0b1b963James Dong OMX_INT searchRange; 910c1bc742181ded4930842b46e9507372f0b1b963James Dong 920c1bc742181ded4930842b46e9507372f0b1b963James Dong /* Argument error checks */ 930c1bc742181ded4930842b46e9507372f0b1b963James Dong armRetArgErrIf(pSrcRefBuf == NULL, OMX_Sts_BadArgErr); 940c1bc742181ded4930842b46e9507372f0b1b963James Dong armRetArgErrIf(pRefRect == NULL, OMX_Sts_BadArgErr); 950c1bc742181ded4930842b46e9507372f0b1b963James Dong armRetArgErrIf(pSrcCurrBuf == NULL, OMX_Sts_BadArgErr); 960c1bc742181ded4930842b46e9507372f0b1b963James Dong armRetArgErrIf(pCurrPointPos == NULL, OMX_Sts_BadArgErr); 970c1bc742181ded4930842b46e9507372f0b1b963James Dong armRetArgErrIf(pMESpec == NULL, OMX_Sts_BadArgErr); 980c1bc742181ded4930842b46e9507372f0b1b963James Dong armRetArgErrIf(pDstMV == NULL, OMX_Sts_BadArgErr); 990c1bc742181ded4930842b46e9507372f0b1b963James Dong armRetArgErrIf(pDstSAD == NULL, OMX_Sts_BadArgErr); 1000c1bc742181ded4930842b46e9507372f0b1b963James Dong 1010c1bc742181ded4930842b46e9507372f0b1b963James Dong searchRange = ((OMXVCM4P2MEParams *)pMESpec)->searchRange; 1020c1bc742181ded4930842b46e9507372f0b1b963James Dong /* Check for valid region */ 1030c1bc742181ded4930842b46e9507372f0b1b963James Dong fromX = searchRange; 1040c1bc742181ded4930842b46e9507372f0b1b963James Dong toX = searchRange; 1050c1bc742181ded4930842b46e9507372f0b1b963James Dong fromY = searchRange; 1060c1bc742181ded4930842b46e9507372f0b1b963James Dong toY = searchRange; 1070c1bc742181ded4930842b46e9507372f0b1b963James Dong 1080c1bc742181ded4930842b46e9507372f0b1b963James Dong if ((pCurrPointPos->x - searchRange) < pRefRect->x) 1090c1bc742181ded4930842b46e9507372f0b1b963James Dong { 1100c1bc742181ded4930842b46e9507372f0b1b963James Dong fromX = pCurrPointPos->x - pRefRect->x; 1110c1bc742181ded4930842b46e9507372f0b1b963James Dong } 1120c1bc742181ded4930842b46e9507372f0b1b963James Dong 1130c1bc742181ded4930842b46e9507372f0b1b963James Dong if ((pCurrPointPos->x + BlockSize + searchRange) > (pRefRect->x + pRefRect->width)) 1140c1bc742181ded4930842b46e9507372f0b1b963James Dong { 1150c1bc742181ded4930842b46e9507372f0b1b963James Dong toX = pRefRect->width - (pCurrPointPos->x - pRefRect->x) - BlockSize; 1160c1bc742181ded4930842b46e9507372f0b1b963James Dong } 1170c1bc742181ded4930842b46e9507372f0b1b963James Dong 1180c1bc742181ded4930842b46e9507372f0b1b963James Dong if ((pCurrPointPos->y - searchRange) < pRefRect->y) 1190c1bc742181ded4930842b46e9507372f0b1b963James Dong { 1200c1bc742181ded4930842b46e9507372f0b1b963James Dong fromY = pCurrPointPos->y - pRefRect->y; 1210c1bc742181ded4930842b46e9507372f0b1b963James Dong } 1220c1bc742181ded4930842b46e9507372f0b1b963James Dong 1230c1bc742181ded4930842b46e9507372f0b1b963James Dong if ((pCurrPointPos->y + BlockSize + searchRange) > (pRefRect->y + pRefRect->height)) 1240c1bc742181ded4930842b46e9507372f0b1b963James Dong { 1250c1bc742181ded4930842b46e9507372f0b1b963James Dong toY = pRefRect->width - (pCurrPointPos->y - pRefRect->y) - BlockSize; 1260c1bc742181ded4930842b46e9507372f0b1b963James Dong } 1270c1bc742181ded4930842b46e9507372f0b1b963James Dong 1280c1bc742181ded4930842b46e9507372f0b1b963James Dong pDstMV->dx = -fromX; 1290c1bc742181ded4930842b46e9507372f0b1b963James Dong pDstMV->dy = -fromY; 1300c1bc742181ded4930842b46e9507372f0b1b963James Dong /* Looping on y- axis */ 1310c1bc742181ded4930842b46e9507372f0b1b963James Dong for (y = -fromY; y <= toY; y++) 1320c1bc742181ded4930842b46e9507372f0b1b963James Dong { 1330c1bc742181ded4930842b46e9507372f0b1b963James Dong 1340c1bc742181ded4930842b46e9507372f0b1b963James Dong /* Looping on x- axis */ 1350c1bc742181ded4930842b46e9507372f0b1b963James Dong for (x = -fromX; x <= toX; x++) 1360c1bc742181ded4930842b46e9507372f0b1b963James Dong { 1370c1bc742181ded4930842b46e9507372f0b1b963James Dong /* Positioning the pointer */ 1380c1bc742181ded4930842b46e9507372f0b1b963James Dong pTempSrcRefBuf = pSrcRefBuf + (refWidth * y) + x; 1390c1bc742181ded4930842b46e9507372f0b1b963James Dong 1400c1bc742181ded4930842b46e9507372f0b1b963James Dong /* Calculate the SAD */ 1410c1bc742181ded4930842b46e9507372f0b1b963James Dong for (outer = 0, count = 0, index = 0, candSAD = 0; 1420c1bc742181ded4930842b46e9507372f0b1b963James Dong outer < BlockSize; 1430c1bc742181ded4930842b46e9507372f0b1b963James Dong outer++, index += refWidth - BlockSize) 1440c1bc742181ded4930842b46e9507372f0b1b963James Dong { 1450c1bc742181ded4930842b46e9507372f0b1b963James Dong for (inner = 0; inner < BlockSize; inner++, count++, index++) 1460c1bc742181ded4930842b46e9507372f0b1b963James Dong { 1470c1bc742181ded4930842b46e9507372f0b1b963James Dong candSAD += armAbs (pTempSrcRefBuf[index] - pSrcCurrBuf[count]); 1480c1bc742181ded4930842b46e9507372f0b1b963James Dong } 1490c1bc742181ded4930842b46e9507372f0b1b963James Dong } 1500c1bc742181ded4930842b46e9507372f0b1b963James Dong 1510c1bc742181ded4930842b46e9507372f0b1b963James Dong /* Result calculations */ 1520c1bc742181ded4930842b46e9507372f0b1b963James Dong if (armVCM4P2_CompareMV (x, y, candSAD, pDstMV->dx/2, pDstMV->dy/2, minSAD)) 1530c1bc742181ded4930842b46e9507372f0b1b963James Dong { 1540c1bc742181ded4930842b46e9507372f0b1b963James Dong *pDstSAD = candSAD; 1550c1bc742181ded4930842b46e9507372f0b1b963James Dong minSAD = candSAD; 1560c1bc742181ded4930842b46e9507372f0b1b963James Dong pDstMV->dx = x*2; 1570c1bc742181ded4930842b46e9507372f0b1b963James Dong pDstMV->dy = y*2; 1580c1bc742181ded4930842b46e9507372f0b1b963James Dong } 1590c1bc742181ded4930842b46e9507372f0b1b963James Dong 1600c1bc742181ded4930842b46e9507372f0b1b963James Dong } /* End of x- axis */ 1610c1bc742181ded4930842b46e9507372f0b1b963James Dong } /* End of y-axis */ 1620c1bc742181ded4930842b46e9507372f0b1b963James Dong 1630c1bc742181ded4930842b46e9507372f0b1b963James Dong return OMX_Sts_NoErr; 1640c1bc742181ded4930842b46e9507372f0b1b963James Dong 1650c1bc742181ded4930842b46e9507372f0b1b963James Dong} 1660c1bc742181ded4930842b46e9507372f0b1b963James Dong 1670c1bc742181ded4930842b46e9507372f0b1b963James Dong/* End of file */ 168