Home | History | Annotate | Download | only in src
      1 /**
      2  *
      3  * File Name:  armVCM4P2_BlockMatch_Integer.c
      4  * OpenMAX DL: v1.0.2
      5  * Revision:   9641
      6  * Date:       Thursday, February 7, 2008
      7  *
      8  * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
      9  *
     10  *
     11  *
     12  * Description:
     13  * Contains modules for Block matching, a full search algorithm
     14  * is implemented
     15  *
     16  */
     17 
     18 #include "omxtypes.h"
     19 #include "armOMX.h"
     20 #include "omxVC.h"
     21 
     22 #include "armVC.h"
     23 #include "armCOMM.h"
     24 
     25 /**
     26  * Function: armVCM4P2_BlockMatch_Integer
     27  *
     28  * Description:
     29  * Performs a 16x16 block search; estimates motion vector and associated minimum SAD.
     30  * Both the input and output motion vectors are represented using half-pixel units, and
     31  * therefore a shift left or right by 1 bit may be required, respectively, to match the
     32  * input or output MVs with other functions that either generate output MVs or expect
     33  * input MVs represented using integer pixel units.
     34  *
     35  * Remarks:
     36  *
     37  * Parameters:
     38  * [in]	pSrcRefBuf		pointer to the reference Y plane; points to the reference MB that
     39  *                    corresponds to the location of the current macroblock in the current
     40  *                    plane.
     41  * [in]	refWidth		  width of the reference plane
     42  * [in]	pRefRect		  pointer to the valid rectangular in reference plane. Relative to image origin.
     43  *                    It's not limited to the image boundary, but depended on the padding. For example,
     44  *                    if you pad 4 pixels outside the image border, then the value for left border
     45  *                    can be -4
     46  * [in]	pSrcCurrBuf		pointer to the current macroblock extracted from original plane (linear array,
     47  *                    256 entries); must be aligned on an 8-byte boundary.
     48  * [in] pCurrPointPos	position of the current macroblock in the current plane
     49  * [in] pSrcPreMV		  pointer to predicted motion vector; NULL indicates no predicted MV
     50  * [in] pSrcPreSAD		pointer to SAD associated with the predicted MV (referenced by pSrcPreMV)
     51  * [in] searchRange		search range for 16X16 integer block,the units of it is full pixel,the search range
     52  *                    is the same in all directions.It is in inclusive of the boundary and specified in
     53  *                    terms of integer pixel units.
     54  * [in] pMESpec			  vendor-specific motion estimation specification structure; must have been allocated
     55  *                    and then initialized using omxVCM4P2_MEInit prior to calling the block matching
     56  *                    function.
     57  * [out]	pDstMV			pointer to estimated MV
     58  * [out]	pDstSAD			pointer to minimum SAD
     59  *
     60  * Return Value:
     61  * OMX_Sts_NoErr C no error.
     62  * OMX_Sts_BadArgErr C bad arguments
     63  *
     64  */
     65 
     66 OMXResult armVCM4P2_BlockMatch_Integer(
     67      const OMX_U8 *pSrcRefBuf,
     68      OMX_INT refWidth,
     69      const OMXRect *pRefRect,
     70      const OMX_U8 *pSrcCurrBuf,
     71      const OMXVCM4P2Coordinate *pCurrPointPos,
     72      const OMXVCMotionVector *pSrcPreMV,
     73      const OMX_INT *pSrcPreSAD,
     74      void *pMESpec,
     75      OMXVCMotionVector *pDstMV,
     76      OMX_INT *pDstSAD,
     77      OMX_U8 BlockSize
     78 )
     79 {
     80 
     81     /* Definitions and Initializations*/
     82 
     83     OMX_INT     outer, inner, count,index;
     84     OMX_INT     candSAD;
     85     /*(256*256 +1) this is to make the SAD max initially*/
     86     OMX_INT     minSAD = 0x10001, fromX, toX, fromY, toY;
     87     /* Offset to the reference at the begining of the bounding box */
     88     const OMX_U8      *pTempSrcRefBuf;
     89     OMX_S16     x, y;
     90     OMX_INT searchRange;
     91 
     92     /* Argument error checks */
     93     armRetArgErrIf(pSrcRefBuf == NULL, OMX_Sts_BadArgErr);
     94     armRetArgErrIf(pRefRect == NULL, OMX_Sts_BadArgErr);
     95     armRetArgErrIf(pSrcCurrBuf == NULL, OMX_Sts_BadArgErr);
     96     armRetArgErrIf(pCurrPointPos == NULL, OMX_Sts_BadArgErr);
     97     armRetArgErrIf(pMESpec == NULL, OMX_Sts_BadArgErr);
     98     armRetArgErrIf(pDstMV == NULL, OMX_Sts_BadArgErr);
     99     armRetArgErrIf(pDstSAD == NULL, OMX_Sts_BadArgErr);
    100 
    101     searchRange = ((OMXVCM4P2MEParams *)pMESpec)->searchRange;
    102     /* Check for valid region */
    103     fromX = searchRange;
    104     toX   = searchRange;
    105     fromY = searchRange;
    106     toY   = searchRange;
    107 
    108     if ((pCurrPointPos->x - searchRange) < pRefRect->x)
    109     {
    110         fromX =  pCurrPointPos->x - pRefRect->x;
    111     }
    112 
    113     if ((pCurrPointPos->x + BlockSize + searchRange) > (pRefRect->x + pRefRect->width))
    114     {
    115         toX   = pRefRect->width - (pCurrPointPos->x - pRefRect->x) - BlockSize;
    116     }
    117 
    118     if ((pCurrPointPos->y - searchRange) < pRefRect->y)
    119     {
    120         fromY = pCurrPointPos->y - pRefRect->y;
    121     }
    122 
    123     if ((pCurrPointPos->y + BlockSize + searchRange) > (pRefRect->y + pRefRect->height))
    124     {
    125         toY   = pRefRect->width - (pCurrPointPos->y - pRefRect->y) - BlockSize;
    126     }
    127 
    128     pDstMV->dx = -fromX;
    129     pDstMV->dy = -fromY;
    130     /* Looping on y- axis */
    131     for (y = -fromY; y <= toY; y++)
    132     {
    133 
    134         /* Looping on x- axis */
    135         for (x = -fromX; x <= toX; x++)
    136         {
    137             /* Positioning the pointer */
    138             pTempSrcRefBuf = pSrcRefBuf + (refWidth * y) + x;
    139 
    140             /* Calculate the SAD */
    141             for (outer = 0, count = 0, index = 0, candSAD = 0;
    142                  outer < BlockSize;
    143                  outer++, index += refWidth - BlockSize)
    144             {
    145                 for (inner = 0; inner < BlockSize; inner++, count++, index++)
    146                 {
    147                     candSAD += armAbs (pTempSrcRefBuf[index] - pSrcCurrBuf[count]);
    148                 }
    149             }
    150 
    151             /* Result calculations */
    152             if (armVCM4P2_CompareMV (x, y, candSAD, pDstMV->dx/2, pDstMV->dy/2, minSAD))
    153             {
    154                 *pDstSAD = candSAD;
    155                 minSAD   = candSAD;
    156                 pDstMV->dx = x*2;
    157                 pDstMV->dy = y*2;
    158             }
    159 
    160         } /* End of x- axis */
    161     } /* End of y-axis */
    162 
    163     return OMX_Sts_NoErr;
    164 
    165 }
    166 
    167 /* End of file */
    168