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