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:  omxVCM4P2_MotionEstimationMB.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 module for motion search 16x16 macroblock
290c1bc742181ded4930842b46e9507372f0b1b963James Dong *
300c1bc742181ded4930842b46e9507372f0b1b963James Dong */
310c1bc742181ded4930842b46e9507372f0b1b963James Dong
320c1bc742181ded4930842b46e9507372f0b1b963James Dong#include "omxtypes.h"
330c1bc742181ded4930842b46e9507372f0b1b963James Dong#include "armOMX.h"
340c1bc742181ded4930842b46e9507372f0b1b963James Dong#include "omxVC.h"
350c1bc742181ded4930842b46e9507372f0b1b963James Dong
360c1bc742181ded4930842b46e9507372f0b1b963James Dong#include "armVC.h"
370c1bc742181ded4930842b46e9507372f0b1b963James Dong#include "armCOMM.h"
380c1bc742181ded4930842b46e9507372f0b1b963James Dong
390c1bc742181ded4930842b46e9507372f0b1b963James Dong/**
400c1bc742181ded4930842b46e9507372f0b1b963James Dong * Function: armVCM4P2_BlockMatch_16x16
410c1bc742181ded4930842b46e9507372f0b1b963James Dong *
420c1bc742181ded4930842b46e9507372f0b1b963James Dong * Description:
430c1bc742181ded4930842b46e9507372f0b1b963James Dong * 16x16 block match wrapper function, calls omxVCM4P2_BlockMatch_Integer_16x16.
440c1bc742181ded4930842b46e9507372f0b1b963James Dong * If half pel search is enabled it also calls omxVCM4P2_BlockMatch_Half_16x16
450c1bc742181ded4930842b46e9507372f0b1b963James Dong *
460c1bc742181ded4930842b46e9507372f0b1b963James Dong * Remarks:
470c1bc742181ded4930842b46e9507372f0b1b963James Dong *
480c1bc742181ded4930842b46e9507372f0b1b963James Dong * Parameters:
490c1bc742181ded4930842b46e9507372f0b1b963James Dong * [in]	pSrcRefBuf	  pointer to the reference Y plane; points to the reference MB that
500c1bc742181ded4930842b46e9507372f0b1b963James Dong *                    corresponds to the location of the current macroblock in the current
510c1bc742181ded4930842b46e9507372f0b1b963James Dong *                    plane.
520c1bc742181ded4930842b46e9507372f0b1b963James Dong * [in]	srcRefStep	  width of the reference plane
530c1bc742181ded4930842b46e9507372f0b1b963James Dong * [in]	pRefRect	  pointer to the valid rectangular in reference plane. Relative to image origin.
540c1bc742181ded4930842b46e9507372f0b1b963James Dong *                    It's not limited to the image boundary, but depended on the padding. For example,
550c1bc742181ded4930842b46e9507372f0b1b963James Dong *                    if you pad 4 pixels outside the image border, then the value for left border
560c1bc742181ded4930842b46e9507372f0b1b963James Dong *                    can be -4
570c1bc742181ded4930842b46e9507372f0b1b963James Dong * [in]	pSrcCurrBuf	  pointer to the current macroblock extracted from original plane (linear array,
580c1bc742181ded4930842b46e9507372f0b1b963James Dong *                    256 entries); must be aligned on an 16-byte boundary.
590c1bc742181ded4930842b46e9507372f0b1b963James Dong * [in] pCurrPointPos position of the current macroblock in the current plane
600c1bc742181ded4930842b46e9507372f0b1b963James Dong * [in] pSrcPreMV	  pointer to predicted motion vector; NULL indicates no predicted MV
610c1bc742181ded4930842b46e9507372f0b1b963James Dong * [in] pSrcPreSAD	  pointer to SAD associated with the predicted MV (referenced by pSrcPreMV); may be set to NULL if unavailable.
620c1bc742181ded4930842b46e9507372f0b1b963James Dong * [in] pMESpec		  vendor-specific motion estimation specification structure; must have been allocated
630c1bc742181ded4930842b46e9507372f0b1b963James Dong *                    and then initialized using omxVCM4P2_MEInit prior to calling the block matching
640c1bc742181ded4930842b46e9507372f0b1b963James Dong *                    function.
650c1bc742181ded4930842b46e9507372f0b1b963James Dong * [out] pDstMV	      pointer to estimated MV
660c1bc742181ded4930842b46e9507372f0b1b963James Dong * [out] pDstSAD	  pointer to minimum SAD
670c1bc742181ded4930842b46e9507372f0b1b963James Dong * *
680c1bc742181ded4930842b46e9507372f0b1b963James Dong * Return Value:
690c1bc742181ded4930842b46e9507372f0b1b963James Dong * OMX_Sts_NoErr - no error
700c1bc742181ded4930842b46e9507372f0b1b963James Dong * OMX_Sts_BadArgErr - bad arguments
710c1bc742181ded4930842b46e9507372f0b1b963James Dong *
720c1bc742181ded4930842b46e9507372f0b1b963James Dong */
730c1bc742181ded4930842b46e9507372f0b1b963James Dongstatic OMXResult armVCM4P2_BlockMatch_16x16(
740c1bc742181ded4930842b46e9507372f0b1b963James Dong     const OMX_U8 *pSrcRefBuf,
750c1bc742181ded4930842b46e9507372f0b1b963James Dong     const OMX_INT srcRefStep,
760c1bc742181ded4930842b46e9507372f0b1b963James Dong     const OMXRect *pRefRect,
770c1bc742181ded4930842b46e9507372f0b1b963James Dong     const OMX_U8 *pSrcCurrBuf,
780c1bc742181ded4930842b46e9507372f0b1b963James Dong     const OMXVCM4P2Coordinate *pCurrPointPos,
790c1bc742181ded4930842b46e9507372f0b1b963James Dong     OMXVCMotionVector *pSrcPreMV,
800c1bc742181ded4930842b46e9507372f0b1b963James Dong     OMX_INT *pSrcPreSAD,
810c1bc742181ded4930842b46e9507372f0b1b963James Dong     void *pMESpec,
820c1bc742181ded4930842b46e9507372f0b1b963James Dong     OMXVCMotionVector *pDstMV,
830c1bc742181ded4930842b46e9507372f0b1b963James Dong     OMX_INT *pDstSAD
840c1bc742181ded4930842b46e9507372f0b1b963James Dong)
850c1bc742181ded4930842b46e9507372f0b1b963James Dong{
860c1bc742181ded4930842b46e9507372f0b1b963James Dong    OMXVCM4P2MEParams *pMEParams = (OMXVCM4P2MEParams *)pMESpec;
870c1bc742181ded4930842b46e9507372f0b1b963James Dong    OMX_INT rndVal;
880c1bc742181ded4930842b46e9507372f0b1b963James Dong
890c1bc742181ded4930842b46e9507372f0b1b963James Dong    rndVal = pMEParams->rndVal;
900c1bc742181ded4930842b46e9507372f0b1b963James Dong
910c1bc742181ded4930842b46e9507372f0b1b963James Dong    omxVCM4P2_BlockMatch_Integer_16x16(
920c1bc742181ded4930842b46e9507372f0b1b963James Dong        pSrcRefBuf,
930c1bc742181ded4930842b46e9507372f0b1b963James Dong        srcRefStep,
940c1bc742181ded4930842b46e9507372f0b1b963James Dong        pRefRect,
950c1bc742181ded4930842b46e9507372f0b1b963James Dong        pSrcCurrBuf,
960c1bc742181ded4930842b46e9507372f0b1b963James Dong        pCurrPointPos,
970c1bc742181ded4930842b46e9507372f0b1b963James Dong        pSrcPreMV,
980c1bc742181ded4930842b46e9507372f0b1b963James Dong        pSrcPreSAD,
990c1bc742181ded4930842b46e9507372f0b1b963James Dong        pMEParams,
1000c1bc742181ded4930842b46e9507372f0b1b963James Dong        pDstMV,
1010c1bc742181ded4930842b46e9507372f0b1b963James Dong        pDstSAD);
1020c1bc742181ded4930842b46e9507372f0b1b963James Dong
1030c1bc742181ded4930842b46e9507372f0b1b963James Dong    if (pMEParams->halfPelSearchEnable)
1040c1bc742181ded4930842b46e9507372f0b1b963James Dong    {
1050c1bc742181ded4930842b46e9507372f0b1b963James Dong        omxVCM4P2_BlockMatch_Half_16x16(
1060c1bc742181ded4930842b46e9507372f0b1b963James Dong            pSrcRefBuf,
1070c1bc742181ded4930842b46e9507372f0b1b963James Dong            srcRefStep,
1080c1bc742181ded4930842b46e9507372f0b1b963James Dong            pRefRect,
1090c1bc742181ded4930842b46e9507372f0b1b963James Dong            pSrcCurrBuf,
1100c1bc742181ded4930842b46e9507372f0b1b963James Dong            pCurrPointPos,
1110c1bc742181ded4930842b46e9507372f0b1b963James Dong            rndVal,
1120c1bc742181ded4930842b46e9507372f0b1b963James Dong            pDstMV,
1130c1bc742181ded4930842b46e9507372f0b1b963James Dong            pDstSAD);
1140c1bc742181ded4930842b46e9507372f0b1b963James Dong    }
1150c1bc742181ded4930842b46e9507372f0b1b963James Dong
1160c1bc742181ded4930842b46e9507372f0b1b963James Dong    return OMX_Sts_NoErr;
1170c1bc742181ded4930842b46e9507372f0b1b963James Dong}
1180c1bc742181ded4930842b46e9507372f0b1b963James Dong
1190c1bc742181ded4930842b46e9507372f0b1b963James Dong/**
1200c1bc742181ded4930842b46e9507372f0b1b963James Dong * Function: armVCM4P2_BlockMatch_8x8
1210c1bc742181ded4930842b46e9507372f0b1b963James Dong *
1220c1bc742181ded4930842b46e9507372f0b1b963James Dong * Description:
1230c1bc742181ded4930842b46e9507372f0b1b963James Dong * 8x8 block match wrapper function, calls omxVCM4P2_BlockMatch_Integer_8x8.
1240c1bc742181ded4930842b46e9507372f0b1b963James Dong * If half pel search is enabled it also calls omxVCM4P2_BlockMatch_Half_8x8
1250c1bc742181ded4930842b46e9507372f0b1b963James Dong *
1260c1bc742181ded4930842b46e9507372f0b1b963James Dong * Remarks:
1270c1bc742181ded4930842b46e9507372f0b1b963James Dong *
1280c1bc742181ded4930842b46e9507372f0b1b963James Dong * Parameters:
1290c1bc742181ded4930842b46e9507372f0b1b963James Dong * [in]	pSrcRefBuf	  pointer to the reference Y plane; points to the reference MB that
1300c1bc742181ded4930842b46e9507372f0b1b963James Dong *                    corresponds to the location of the current macroblock in the current
1310c1bc742181ded4930842b46e9507372f0b1b963James Dong *                    plane.
1320c1bc742181ded4930842b46e9507372f0b1b963James Dong * [in]	srcRefStep	  width of the reference plane
1330c1bc742181ded4930842b46e9507372f0b1b963James Dong * [in]	pRefRect	  pointer to the valid rectangular in reference plane. Relative to image origin.
1340c1bc742181ded4930842b46e9507372f0b1b963James Dong *                    It's not limited to the image boundary, but depended on the padding. For example,
1350c1bc742181ded4930842b46e9507372f0b1b963James Dong *                    if you pad 4 pixels outside the image border, then the value for left border
1360c1bc742181ded4930842b46e9507372f0b1b963James Dong *                    can be -4
1370c1bc742181ded4930842b46e9507372f0b1b963James Dong * [in]	pSrcCurrBuf	  pointer to the current macroblock extracted from original plane (linear array,
1380c1bc742181ded4930842b46e9507372f0b1b963James Dong *                    256 entries); must be aligned on an 16-byte boundary.
1390c1bc742181ded4930842b46e9507372f0b1b963James Dong * [in] pCurrPointPos position of the current macroblock in the current plane
1400c1bc742181ded4930842b46e9507372f0b1b963James Dong * [in] pSrcPreMV	  pointer to predicted motion vector; NULL indicates no predicted MV
1410c1bc742181ded4930842b46e9507372f0b1b963James Dong * [in] pSrcPreSAD	  pointer to SAD associated with the predicted MV (referenced by pSrcPreMV); may be set to NULL if unavailable.
1420c1bc742181ded4930842b46e9507372f0b1b963James Dong * [in] pMESpec		  vendor-specific motion estimation specification structure; must have been allocated
1430c1bc742181ded4930842b46e9507372f0b1b963James Dong *                    and then initialized using omxVCM4P2_MEInit prior to calling the block matching
1440c1bc742181ded4930842b46e9507372f0b1b963James Dong *                    function.
1450c1bc742181ded4930842b46e9507372f0b1b963James Dong * [out] pDstMV	      pointer to estimated MV
1460c1bc742181ded4930842b46e9507372f0b1b963James Dong * [out] pDstSAD	  pointer to minimum SAD
1470c1bc742181ded4930842b46e9507372f0b1b963James Dong * *
1480c1bc742181ded4930842b46e9507372f0b1b963James Dong * Return Value:
1490c1bc742181ded4930842b46e9507372f0b1b963James Dong * OMX_Sts_NoErr - no error
1500c1bc742181ded4930842b46e9507372f0b1b963James Dong * OMX_Sts_BadArgErr - bad arguments
1510c1bc742181ded4930842b46e9507372f0b1b963James Dong *
1520c1bc742181ded4930842b46e9507372f0b1b963James Dong */
1530c1bc742181ded4930842b46e9507372f0b1b963James Dongstatic OMXResult armVCM4P2_BlockMatch_8x8(
1540c1bc742181ded4930842b46e9507372f0b1b963James Dong     const OMX_U8 *pSrcRefBuf,
1550c1bc742181ded4930842b46e9507372f0b1b963James Dong     OMX_INT srcRefStep,
1560c1bc742181ded4930842b46e9507372f0b1b963James Dong     const OMXRect *pRefRect,
1570c1bc742181ded4930842b46e9507372f0b1b963James Dong     const OMX_U8 *pSrcCurrBuf,
1580c1bc742181ded4930842b46e9507372f0b1b963James Dong     const OMXVCM4P2Coordinate *pCurrPointPos,
1590c1bc742181ded4930842b46e9507372f0b1b963James Dong     OMXVCMotionVector *pSrcPreMV,
1600c1bc742181ded4930842b46e9507372f0b1b963James Dong     OMX_INT *pSrcPreSAD,
1610c1bc742181ded4930842b46e9507372f0b1b963James Dong     void *pMESpec,
1620c1bc742181ded4930842b46e9507372f0b1b963James Dong     OMXVCMotionVector *pSrcDstMV,
1630c1bc742181ded4930842b46e9507372f0b1b963James Dong     OMX_INT *pDstSAD
1640c1bc742181ded4930842b46e9507372f0b1b963James Dong)
1650c1bc742181ded4930842b46e9507372f0b1b963James Dong{
1660c1bc742181ded4930842b46e9507372f0b1b963James Dong    OMXVCM4P2MEParams *pMEParams = (OMXVCM4P2MEParams *)pMESpec;
1670c1bc742181ded4930842b46e9507372f0b1b963James Dong    OMX_INT rndVal;
1680c1bc742181ded4930842b46e9507372f0b1b963James Dong
1690c1bc742181ded4930842b46e9507372f0b1b963James Dong    rndVal = pMEParams->rndVal;
1700c1bc742181ded4930842b46e9507372f0b1b963James Dong
1710c1bc742181ded4930842b46e9507372f0b1b963James Dong    omxVCM4P2_BlockMatch_Integer_8x8(
1720c1bc742181ded4930842b46e9507372f0b1b963James Dong        pSrcRefBuf,
1730c1bc742181ded4930842b46e9507372f0b1b963James Dong        srcRefStep,
1740c1bc742181ded4930842b46e9507372f0b1b963James Dong        pRefRect,
1750c1bc742181ded4930842b46e9507372f0b1b963James Dong        pSrcCurrBuf,
1760c1bc742181ded4930842b46e9507372f0b1b963James Dong        pCurrPointPos,
1770c1bc742181ded4930842b46e9507372f0b1b963James Dong        pSrcPreMV,
1780c1bc742181ded4930842b46e9507372f0b1b963James Dong        pSrcPreSAD,
1790c1bc742181ded4930842b46e9507372f0b1b963James Dong        pMEParams,
1800c1bc742181ded4930842b46e9507372f0b1b963James Dong        pSrcDstMV,
1810c1bc742181ded4930842b46e9507372f0b1b963James Dong        pDstSAD);
1820c1bc742181ded4930842b46e9507372f0b1b963James Dong
1830c1bc742181ded4930842b46e9507372f0b1b963James Dong    if (pMEParams->halfPelSearchEnable)
1840c1bc742181ded4930842b46e9507372f0b1b963James Dong    {
1850c1bc742181ded4930842b46e9507372f0b1b963James Dong        omxVCM4P2_BlockMatch_Half_8x8(
1860c1bc742181ded4930842b46e9507372f0b1b963James Dong            pSrcRefBuf,
1870c1bc742181ded4930842b46e9507372f0b1b963James Dong            srcRefStep,
1880c1bc742181ded4930842b46e9507372f0b1b963James Dong            pRefRect,
1890c1bc742181ded4930842b46e9507372f0b1b963James Dong            pSrcCurrBuf,
1900c1bc742181ded4930842b46e9507372f0b1b963James Dong            pCurrPointPos,
1910c1bc742181ded4930842b46e9507372f0b1b963James Dong            rndVal,
1920c1bc742181ded4930842b46e9507372f0b1b963James Dong            pSrcDstMV,
1930c1bc742181ded4930842b46e9507372f0b1b963James Dong            pDstSAD);
1940c1bc742181ded4930842b46e9507372f0b1b963James Dong    }
1950c1bc742181ded4930842b46e9507372f0b1b963James Dong
1960c1bc742181ded4930842b46e9507372f0b1b963James Dong    return OMX_Sts_NoErr;
1970c1bc742181ded4930842b46e9507372f0b1b963James Dong}
1980c1bc742181ded4930842b46e9507372f0b1b963James Dong
1990c1bc742181ded4930842b46e9507372f0b1b963James Dong
2000c1bc742181ded4930842b46e9507372f0b1b963James Dong/**
2010c1bc742181ded4930842b46e9507372f0b1b963James Dong * Function:  omxVCM4P2_MotionEstimationMB   (6.2.4.3.1)
2020c1bc742181ded4930842b46e9507372f0b1b963James Dong *
2030c1bc742181ded4930842b46e9507372f0b1b963James Dong * Description:
2040c1bc742181ded4930842b46e9507372f0b1b963James Dong * Performs motion search for a 16x16 macroblock.  Selects best motion search
2050c1bc742181ded4930842b46e9507372f0b1b963James Dong * strategy from among inter-1MV, inter-4MV, and intra modes.  Supports
2060c1bc742181ded4930842b46e9507372f0b1b963James Dong * integer and half pixel resolution.
2070c1bc742181ded4930842b46e9507372f0b1b963James Dong *
2080c1bc742181ded4930842b46e9507372f0b1b963James Dong * Input Arguments:
2090c1bc742181ded4930842b46e9507372f0b1b963James Dong *
2100c1bc742181ded4930842b46e9507372f0b1b963James Dong *   pSrcCurrBuf - pointer to the top-left corner of the current MB in the
2110c1bc742181ded4930842b46e9507372f0b1b963James Dong *            original picture plane; must be aligned on a 16-byte boundary.
2120c1bc742181ded4930842b46e9507372f0b1b963James Dong *            The function does not expect source data outside the region
2130c1bc742181ded4930842b46e9507372f0b1b963James Dong *            bounded by the MB to be available; for example it is not
2140c1bc742181ded4930842b46e9507372f0b1b963James Dong *            necessary for the caller to guarantee the availability of
2150c1bc742181ded4930842b46e9507372f0b1b963James Dong *            pSrcCurrBuf[-SrcCurrStep], i.e., the row of pixels above the MB
2160c1bc742181ded4930842b46e9507372f0b1b963James Dong *            to be processed.
2170c1bc742181ded4930842b46e9507372f0b1b963James Dong *   srcCurrStep - width of the original picture plane, in terms of full
2180c1bc742181ded4930842b46e9507372f0b1b963James Dong *            pixels; must be a multiple of 16.
2190c1bc742181ded4930842b46e9507372f0b1b963James Dong *   pSrcRefBuf - pointer to the reference Y plane; points to the reference
2200c1bc742181ded4930842b46e9507372f0b1b963James Dong *            plane location corresponding to the location of the current
2210c1bc742181ded4930842b46e9507372f0b1b963James Dong *            macroblock in the current plane; must be aligned on a 16-byte
2220c1bc742181ded4930842b46e9507372f0b1b963James Dong *            boundary.
2230c1bc742181ded4930842b46e9507372f0b1b963James Dong *   srcRefStep - width of the reference picture plane, in terms of full
2240c1bc742181ded4930842b46e9507372f0b1b963James Dong *            pixels; must be a multiple of 16.
2250c1bc742181ded4930842b46e9507372f0b1b963James Dong *   pRefRect - reference plane valid region rectangle, specified relative to
2260c1bc742181ded4930842b46e9507372f0b1b963James Dong *            the image origin
2270c1bc742181ded4930842b46e9507372f0b1b963James Dong *   pCurrPointPos - position of the current macroblock in the current plane
2280c1bc742181ded4930842b46e9507372f0b1b963James Dong *   pMESpec - pointer to the vendor-specific motion estimation specification
2290c1bc742181ded4930842b46e9507372f0b1b963James Dong *            structure; must be allocated and then initialized using
2300c1bc742181ded4930842b46e9507372f0b1b963James Dong *            omxVCM4P2_MEInit prior to calling this function.
2310c1bc742181ded4930842b46e9507372f0b1b963James Dong *   pMBInfo - array, of dimension four, containing pointers to information
2320c1bc742181ded4930842b46e9507372f0b1b963James Dong *            associated with four nearby MBs:
2330c1bc742181ded4930842b46e9507372f0b1b963James Dong *            -   pMBInfo[0] - pointer to left MB information
2340c1bc742181ded4930842b46e9507372f0b1b963James Dong *            -   pMBInfo[1] - pointer to top MB information
2350c1bc742181ded4930842b46e9507372f0b1b963James Dong *            -   pMBInfo[2] - pointer to top-left MB information
2360c1bc742181ded4930842b46e9507372f0b1b963James Dong *            -   pMBInfo[3] - pointer to top-right MB information
2370c1bc742181ded4930842b46e9507372f0b1b963James Dong *            Any pointer in the array may be set equal to NULL if the
2380c1bc742181ded4930842b46e9507372f0b1b963James Dong *            corresponding MB doesn't exist.  For each MB, the following structure
2390c1bc742181ded4930842b46e9507372f0b1b963James Dong *            members are used:
2400c1bc742181ded4930842b46e9507372f0b1b963James Dong *            -   mbType - macroblock type, either OMX_VC_INTRA, OMX_VC_INTER, or
2410c1bc742181ded4930842b46e9507372f0b1b963James Dong *                OMX_VC_INTER4V
2420c1bc742181ded4930842b46e9507372f0b1b963James Dong *            -   pMV0[2][2] - estimated motion vectors; represented
2430c1bc742181ded4930842b46e9507372f0b1b963James Dong *                in 1/2 pixel units
2440c1bc742181ded4930842b46e9507372f0b1b963James Dong *            -   sliceID - number of the slice to which the MB belongs
2450c1bc742181ded4930842b46e9507372f0b1b963James Dong *   pSrcDstMBCurr - pointer to information structure for the current MB.
2460c1bc742181ded4930842b46e9507372f0b1b963James Dong *            The following entries should be set prior to calling the
2470c1bc742181ded4930842b46e9507372f0b1b963James Dong *            function: sliceID - the number of the slice the to which the
2480c1bc742181ded4930842b46e9507372f0b1b963James Dong *            current MB belongs.  The structure elements cbpy and cbpc are
2490c1bc742181ded4930842b46e9507372f0b1b963James Dong *            ignored.
2500c1bc742181ded4930842b46e9507372f0b1b963James Dong *
2510c1bc742181ded4930842b46e9507372f0b1b963James Dong * Output Arguments:
2520c1bc742181ded4930842b46e9507372f0b1b963James Dong *
2530c1bc742181ded4930842b46e9507372f0b1b963James Dong *   pSrcDstMBCurr - pointer to updated information structure for the current
2540c1bc742181ded4930842b46e9507372f0b1b963James Dong *            MB after MB-level motion estimation has been completed.  The
2550c1bc742181ded4930842b46e9507372f0b1b963James Dong *            following structure members are updated by the ME function:
2560c1bc742181ded4930842b46e9507372f0b1b963James Dong *              -  mbType - macroblock type: OMX_VC_INTRA, OMX_VC_INTER, or
2570c1bc742181ded4930842b46e9507372f0b1b963James Dong *                 OMX_VC_INTER4V.
2580c1bc742181ded4930842b46e9507372f0b1b963James Dong *              -  pMV0[2][2] - estimated motion vectors; represented in
2590c1bc742181ded4930842b46e9507372f0b1b963James Dong *                 terms of 1/2 pel units.
2600c1bc742181ded4930842b46e9507372f0b1b963James Dong *              -  pMVPred[2][2] - predicted motion vectors; represented
2610c1bc742181ded4930842b46e9507372f0b1b963James Dong *                 in terms of 1/2 pel units.
2620c1bc742181ded4930842b46e9507372f0b1b963James Dong *            The structure members cbpy and cbpc are not updated by the function.
2630c1bc742181ded4930842b46e9507372f0b1b963James Dong *   pDstSAD - pointer to the minimum SAD for INTER1V, or sum of minimum SADs
2640c1bc742181ded4930842b46e9507372f0b1b963James Dong *            for INTER4V
2650c1bc742181ded4930842b46e9507372f0b1b963James Dong *   pDstBlockSAD - pointer to an array of SAD values for each of the four
2660c1bc742181ded4930842b46e9507372f0b1b963James Dong *            8x8 luma blocks in the MB.  The block SADs are in scan order for
2670c1bc742181ded4930842b46e9507372f0b1b963James Dong *            each MB.
2680c1bc742181ded4930842b46e9507372f0b1b963James Dong *
2690c1bc742181ded4930842b46e9507372f0b1b963James Dong * Return Value:
2700c1bc742181ded4930842b46e9507372f0b1b963James Dong *
2710c1bc742181ded4930842b46e9507372f0b1b963James Dong *    OMX_Sts_NoErr - no error
2720c1bc742181ded4930842b46e9507372f0b1b963James Dong *    OMX_Sts_BadArgErr - bad arguments.  Returned if one or more of the
2730c1bc742181ded4930842b46e9507372f0b1b963James Dong *              following conditions is true:
2740c1bc742181ded4930842b46e9507372f0b1b963James Dong *    -    at least one of the following pointers is NULL: pSrcCurrBuf,
2750c1bc742181ded4930842b46e9507372f0b1b963James Dong *              pSrcRefBuf, pRefRect, pCurrPointPos, pMBInter, pMBIntra,
2760c1bc742181ded4930842b46e9507372f0b1b963James Dong *              pSrcDstMBCurr, or pDstSAD.
2770c1bc742181ded4930842b46e9507372f0b1b963James Dong *
2780c1bc742181ded4930842b46e9507372f0b1b963James Dong */
2790c1bc742181ded4930842b46e9507372f0b1b963James Dong
2800c1bc742181ded4930842b46e9507372f0b1b963James DongOMXResult omxVCM4P2_MotionEstimationMB (
2810c1bc742181ded4930842b46e9507372f0b1b963James Dong    const OMX_U8 *pSrcCurrBuf,
2820c1bc742181ded4930842b46e9507372f0b1b963James Dong    OMX_S32 srcCurrStep,
2830c1bc742181ded4930842b46e9507372f0b1b963James Dong    const OMX_U8 *pSrcRefBuf,
2840c1bc742181ded4930842b46e9507372f0b1b963James Dong    OMX_S32 srcRefStep,
2850c1bc742181ded4930842b46e9507372f0b1b963James Dong    const OMXRect*pRefRect,
2860c1bc742181ded4930842b46e9507372f0b1b963James Dong    const OMXVCM4P2Coordinate *pCurrPointPos,
2870c1bc742181ded4930842b46e9507372f0b1b963James Dong    void *pMESpec,
2880c1bc742181ded4930842b46e9507372f0b1b963James Dong    const OMXVCM4P2MBInfoPtr *pMBInfo,
2890c1bc742181ded4930842b46e9507372f0b1b963James Dong    OMXVCM4P2MBInfo *pSrcDstMBCurr,
2900c1bc742181ded4930842b46e9507372f0b1b963James Dong    OMX_U16 *pDstSAD,
2910c1bc742181ded4930842b46e9507372f0b1b963James Dong    OMX_U16 *pDstBlockSAD
2920c1bc742181ded4930842b46e9507372f0b1b963James Dong)
2930c1bc742181ded4930842b46e9507372f0b1b963James Dong{
2940c1bc742181ded4930842b46e9507372f0b1b963James Dong
2950c1bc742181ded4930842b46e9507372f0b1b963James Dong    OMX_INT intraSAD, average, count, index, x, y;
2960c1bc742181ded4930842b46e9507372f0b1b963James Dong    OMXVCMotionVector dstMV16x16;
2970c1bc742181ded4930842b46e9507372f0b1b963James Dong    OMX_INT           dstSAD16x16;
2980c1bc742181ded4930842b46e9507372f0b1b963James Dong    OMX_INT           dstSAD8x8;
2990c1bc742181ded4930842b46e9507372f0b1b963James Dong    OMXVCM4P2MEParams  *pMEParams;
3000c1bc742181ded4930842b46e9507372f0b1b963James Dong	OMXVCM4P2Coordinate TempCurrPointPos;
3010c1bc742181ded4930842b46e9507372f0b1b963James Dong    OMXVCM4P2Coordinate *pTempCurrPointPos;
3020c1bc742181ded4930842b46e9507372f0b1b963James Dong    OMX_U8 aTempSrcCurrBuf[271];
3030c1bc742181ded4930842b46e9507372f0b1b963James Dong    OMX_U8 *pTempSrcCurrBuf;
3040c1bc742181ded4930842b46e9507372f0b1b963James Dong    OMX_U8 *pDst;
3050c1bc742181ded4930842b46e9507372f0b1b963James Dong    OMX_U8 aDst[71];
3060c1bc742181ded4930842b46e9507372f0b1b963James Dong    OMX_S32 dstStep = 8;
3070c1bc742181ded4930842b46e9507372f0b1b963James Dong    OMX_INT predictType;
3080c1bc742181ded4930842b46e9507372f0b1b963James Dong	OMX_S32 Sad;
3090c1bc742181ded4930842b46e9507372f0b1b963James Dong    const OMX_U8 *pTempSrcRefBuf;
3100c1bc742181ded4930842b46e9507372f0b1b963James Dong    OMXVCMotionVector* pSrcCandMV1[4];
3110c1bc742181ded4930842b46e9507372f0b1b963James Dong    OMXVCMotionVector* pSrcCandMV2[4];
3120c1bc742181ded4930842b46e9507372f0b1b963James Dong    OMXVCMotionVector* pSrcCandMV3[4];
3130c1bc742181ded4930842b46e9507372f0b1b963James Dong
3140c1bc742181ded4930842b46e9507372f0b1b963James Dong    /* Argument error checks */
3150c1bc742181ded4930842b46e9507372f0b1b963James Dong    armRetArgErrIf(!armIs16ByteAligned(pSrcCurrBuf), OMX_Sts_BadArgErr);
3160c1bc742181ded4930842b46e9507372f0b1b963James Dong	armRetArgErrIf(!armIs16ByteAligned(pSrcRefBuf), OMX_Sts_BadArgErr);
3170c1bc742181ded4930842b46e9507372f0b1b963James Dong    armRetArgErrIf(((srcCurrStep % 16) || (srcRefStep % 16)), OMX_Sts_BadArgErr);
3180c1bc742181ded4930842b46e9507372f0b1b963James Dong	armRetArgErrIf(pSrcCurrBuf == NULL, OMX_Sts_BadArgErr);
3190c1bc742181ded4930842b46e9507372f0b1b963James Dong	armRetArgErrIf(pSrcRefBuf == NULL, OMX_Sts_BadArgErr);
3200c1bc742181ded4930842b46e9507372f0b1b963James Dong    armRetArgErrIf(pRefRect == NULL, OMX_Sts_BadArgErr);
3210c1bc742181ded4930842b46e9507372f0b1b963James Dong    armRetArgErrIf(pCurrPointPos == NULL, OMX_Sts_BadArgErr);
3220c1bc742181ded4930842b46e9507372f0b1b963James Dong    armRetArgErrIf(pSrcDstMBCurr == NULL, OMX_Sts_BadArgErr);
3230c1bc742181ded4930842b46e9507372f0b1b963James Dong    armRetArgErrIf(pDstSAD == NULL, OMX_Sts_BadArgErr);
3240c1bc742181ded4930842b46e9507372f0b1b963James Dong
3250c1bc742181ded4930842b46e9507372f0b1b963James Dong
3260c1bc742181ded4930842b46e9507372f0b1b963James Dong    pTempCurrPointPos = &(TempCurrPointPos);
3270c1bc742181ded4930842b46e9507372f0b1b963James Dong    pTempSrcCurrBuf = armAlignTo16Bytes(aTempSrcCurrBuf);
3280c1bc742181ded4930842b46e9507372f0b1b963James Dong    pMEParams = (OMXVCM4P2MEParams *)pMESpec;
3290c1bc742181ded4930842b46e9507372f0b1b963James Dong    pTempCurrPointPos->x = pCurrPointPos->x;
3300c1bc742181ded4930842b46e9507372f0b1b963James Dong    pTempCurrPointPos->y = pCurrPointPos->y;
3310c1bc742181ded4930842b46e9507372f0b1b963James Dong    pSrcDstMBCurr->mbType = OMX_VC_INTER;
3320c1bc742181ded4930842b46e9507372f0b1b963James Dong
3330c1bc742181ded4930842b46e9507372f0b1b963James Dong    /* Preparing a linear buffer for block match */
3340c1bc742181ded4930842b46e9507372f0b1b963James Dong    for (y = 0, index = count = 0; y < 16; y++, index += srcCurrStep - 16)
3350c1bc742181ded4930842b46e9507372f0b1b963James Dong    {
3360c1bc742181ded4930842b46e9507372f0b1b963James Dong        for(x = 0; x < 16; x++, count++, index++)
3370c1bc742181ded4930842b46e9507372f0b1b963James Dong        {
3380c1bc742181ded4930842b46e9507372f0b1b963James Dong            pTempSrcCurrBuf[count] = pSrcCurrBuf[index];
3390c1bc742181ded4930842b46e9507372f0b1b963James Dong        }
3400c1bc742181ded4930842b46e9507372f0b1b963James Dong    }
3410c1bc742181ded4930842b46e9507372f0b1b963James Dong    for(y = 0, index = 0; y < 2; y++)
3420c1bc742181ded4930842b46e9507372f0b1b963James Dong    {
3430c1bc742181ded4930842b46e9507372f0b1b963James Dong        for(x = 0; x < 2; x++,index++)
3440c1bc742181ded4930842b46e9507372f0b1b963James Dong        {
3450c1bc742181ded4930842b46e9507372f0b1b963James Dong            if((pMBInfo[0] != NULL) && (pMBInfo[0]->mbType != OMX_VC_INTRA))
3460c1bc742181ded4930842b46e9507372f0b1b963James Dong            {
3470c1bc742181ded4930842b46e9507372f0b1b963James Dong               pSrcCandMV1[index] = &(pMBInfo[0]->pMV0[y][x]);
3480c1bc742181ded4930842b46e9507372f0b1b963James Dong            }
3490c1bc742181ded4930842b46e9507372f0b1b963James Dong            else
3500c1bc742181ded4930842b46e9507372f0b1b963James Dong            {
3510c1bc742181ded4930842b46e9507372f0b1b963James Dong               pSrcCandMV1[index] = NULL;
3520c1bc742181ded4930842b46e9507372f0b1b963James Dong            }
3530c1bc742181ded4930842b46e9507372f0b1b963James Dong            if((pMBInfo[1] != NULL) && (pMBInfo[1]->mbType != OMX_VC_INTRA))
3540c1bc742181ded4930842b46e9507372f0b1b963James Dong            {
3550c1bc742181ded4930842b46e9507372f0b1b963James Dong               pSrcCandMV2[index] = &(pMBInfo[1]->pMV0[y][x]);
3560c1bc742181ded4930842b46e9507372f0b1b963James Dong            }
3570c1bc742181ded4930842b46e9507372f0b1b963James Dong            else
3580c1bc742181ded4930842b46e9507372f0b1b963James Dong            {
3590c1bc742181ded4930842b46e9507372f0b1b963James Dong               pSrcCandMV2[index] = NULL;
3600c1bc742181ded4930842b46e9507372f0b1b963James Dong            }
3610c1bc742181ded4930842b46e9507372f0b1b963James Dong            if((pMBInfo[3] != NULL) && (pMBInfo[3]->mbType != OMX_VC_INTRA))
3620c1bc742181ded4930842b46e9507372f0b1b963James Dong            {
3630c1bc742181ded4930842b46e9507372f0b1b963James Dong               pSrcCandMV3[index] = &(pMBInfo[3]->pMV0[y][x]);
3640c1bc742181ded4930842b46e9507372f0b1b963James Dong            }
3650c1bc742181ded4930842b46e9507372f0b1b963James Dong            else
3660c1bc742181ded4930842b46e9507372f0b1b963James Dong            {
3670c1bc742181ded4930842b46e9507372f0b1b963James Dong               pSrcCandMV3[index] = NULL;
3680c1bc742181ded4930842b46e9507372f0b1b963James Dong            }
3690c1bc742181ded4930842b46e9507372f0b1b963James Dong        }
3700c1bc742181ded4930842b46e9507372f0b1b963James Dong    }
3710c1bc742181ded4930842b46e9507372f0b1b963James Dong	/* Calculating SAD at MV(0,0) */
3720c1bc742181ded4930842b46e9507372f0b1b963James Dong	armVCCOMM_SAD(pTempSrcCurrBuf,
3730c1bc742181ded4930842b46e9507372f0b1b963James Dong					  16,
3740c1bc742181ded4930842b46e9507372f0b1b963James Dong					  pSrcRefBuf,
3750c1bc742181ded4930842b46e9507372f0b1b963James Dong					  srcRefStep,
3760c1bc742181ded4930842b46e9507372f0b1b963James Dong					  &Sad,
3770c1bc742181ded4930842b46e9507372f0b1b963James Dong					  16,
3780c1bc742181ded4930842b46e9507372f0b1b963James Dong					  16);
3790c1bc742181ded4930842b46e9507372f0b1b963James Dong	*pDstSAD = Sad;
3800c1bc742181ded4930842b46e9507372f0b1b963James Dong
3810c1bc742181ded4930842b46e9507372f0b1b963James Dong    /* Mode decision for NOT_CODED MB */
3820c1bc742181ded4930842b46e9507372f0b1b963James Dong	if(*pDstSAD == 0)
3830c1bc742181ded4930842b46e9507372f0b1b963James Dong	{
3840c1bc742181ded4930842b46e9507372f0b1b963James Dong        pSrcDstMBCurr->pMV0[0][0].dx = 0;
3850c1bc742181ded4930842b46e9507372f0b1b963James Dong        pSrcDstMBCurr->pMV0[0][0].dy = 0;
3860c1bc742181ded4930842b46e9507372f0b1b963James Dong        *pDstSAD   = 0;
3870c1bc742181ded4930842b46e9507372f0b1b963James Dong		return OMX_Sts_NoErr;
3880c1bc742181ded4930842b46e9507372f0b1b963James Dong	}
3890c1bc742181ded4930842b46e9507372f0b1b963James Dong
3900c1bc742181ded4930842b46e9507372f0b1b963James Dong    omxVCM4P2_FindMVpred(
3910c1bc742181ded4930842b46e9507372f0b1b963James Dong                    &(pSrcDstMBCurr->pMV0[0][0]),
3920c1bc742181ded4930842b46e9507372f0b1b963James Dong                    pSrcCandMV1[0],
3930c1bc742181ded4930842b46e9507372f0b1b963James Dong                    pSrcCandMV2[0],
3940c1bc742181ded4930842b46e9507372f0b1b963James Dong                    pSrcCandMV3[0],
3950c1bc742181ded4930842b46e9507372f0b1b963James Dong                    &(pSrcDstMBCurr->pMVPred[0][0]),
3960c1bc742181ded4930842b46e9507372f0b1b963James Dong                    NULL,
3970c1bc742181ded4930842b46e9507372f0b1b963James Dong                    0);
3980c1bc742181ded4930842b46e9507372f0b1b963James Dong
3990c1bc742181ded4930842b46e9507372f0b1b963James Dong    /* Inter 1 MV */
4000c1bc742181ded4930842b46e9507372f0b1b963James Dong    armVCM4P2_BlockMatch_16x16(
4010c1bc742181ded4930842b46e9507372f0b1b963James Dong        pSrcRefBuf,
4020c1bc742181ded4930842b46e9507372f0b1b963James Dong        srcRefStep,
4030c1bc742181ded4930842b46e9507372f0b1b963James Dong        pRefRect,
4040c1bc742181ded4930842b46e9507372f0b1b963James Dong        pTempSrcCurrBuf,
4050c1bc742181ded4930842b46e9507372f0b1b963James Dong        pCurrPointPos,
4060c1bc742181ded4930842b46e9507372f0b1b963James Dong        &(pSrcDstMBCurr->pMVPred[0][0]),
4070c1bc742181ded4930842b46e9507372f0b1b963James Dong        NULL,
4080c1bc742181ded4930842b46e9507372f0b1b963James Dong        pMEParams,
4090c1bc742181ded4930842b46e9507372f0b1b963James Dong        &dstMV16x16,
4100c1bc742181ded4930842b46e9507372f0b1b963James Dong        &dstSAD16x16);
4110c1bc742181ded4930842b46e9507372f0b1b963James Dong
4120c1bc742181ded4930842b46e9507372f0b1b963James Dong    /* Initialize all with 1 MV values */
4130c1bc742181ded4930842b46e9507372f0b1b963James Dong    pSrcDstMBCurr->pMV0[0][0].dx = dstMV16x16.dx;
4140c1bc742181ded4930842b46e9507372f0b1b963James Dong    pSrcDstMBCurr->pMV0[0][0].dy = dstMV16x16.dy;
4150c1bc742181ded4930842b46e9507372f0b1b963James Dong    pSrcDstMBCurr->pMV0[0][1].dx = dstMV16x16.dx;
4160c1bc742181ded4930842b46e9507372f0b1b963James Dong    pSrcDstMBCurr->pMV0[0][1].dy = dstMV16x16.dy;
4170c1bc742181ded4930842b46e9507372f0b1b963James Dong    pSrcDstMBCurr->pMV0[1][0].dx = dstMV16x16.dx;
4180c1bc742181ded4930842b46e9507372f0b1b963James Dong    pSrcDstMBCurr->pMV0[1][0].dy = dstMV16x16.dy;
4190c1bc742181ded4930842b46e9507372f0b1b963James Dong    pSrcDstMBCurr->pMV0[1][1].dx = dstMV16x16.dx;
4200c1bc742181ded4930842b46e9507372f0b1b963James Dong    pSrcDstMBCurr->pMV0[1][1].dy = dstMV16x16.dy;
4210c1bc742181ded4930842b46e9507372f0b1b963James Dong
4220c1bc742181ded4930842b46e9507372f0b1b963James Dong    *pDstSAD   = dstSAD16x16;
4230c1bc742181ded4930842b46e9507372f0b1b963James Dong
4240c1bc742181ded4930842b46e9507372f0b1b963James Dong    if (pMEParams->searchEnable8x8)
4250c1bc742181ded4930842b46e9507372f0b1b963James Dong    {
4260c1bc742181ded4930842b46e9507372f0b1b963James Dong        /* Inter 4MV */
4270c1bc742181ded4930842b46e9507372f0b1b963James Dong        armVCM4P2_BlockMatch_8x8 (pSrcRefBuf,
4280c1bc742181ded4930842b46e9507372f0b1b963James Dong                                      srcRefStep, pRefRect,
4290c1bc742181ded4930842b46e9507372f0b1b963James Dong                                      pTempSrcCurrBuf, pTempCurrPointPos,
4300c1bc742181ded4930842b46e9507372f0b1b963James Dong                                      &(pSrcDstMBCurr->pMVPred[0][0]), NULL,
4310c1bc742181ded4930842b46e9507372f0b1b963James Dong                                      pMEParams, &(pSrcDstMBCurr->pMV0[0][0]),
4320c1bc742181ded4930842b46e9507372f0b1b963James Dong                                      &dstSAD8x8
4330c1bc742181ded4930842b46e9507372f0b1b963James Dong                                      );
4340c1bc742181ded4930842b46e9507372f0b1b963James Dong        pDstBlockSAD[0] = dstSAD8x8;
4350c1bc742181ded4930842b46e9507372f0b1b963James Dong        *pDstSAD = dstSAD8x8;
4360c1bc742181ded4930842b46e9507372f0b1b963James Dong        pTempCurrPointPos->x += 8;
4370c1bc742181ded4930842b46e9507372f0b1b963James Dong        pSrcRefBuf += 8;
4380c1bc742181ded4930842b46e9507372f0b1b963James Dong        omxVCM4P2_FindMVpred(
4390c1bc742181ded4930842b46e9507372f0b1b963James Dong                    &(pSrcDstMBCurr->pMV0[0][1]),
4400c1bc742181ded4930842b46e9507372f0b1b963James Dong                    pSrcCandMV1[1],
4410c1bc742181ded4930842b46e9507372f0b1b963James Dong                    pSrcCandMV2[1],
4420c1bc742181ded4930842b46e9507372f0b1b963James Dong                    pSrcCandMV3[1],
4430c1bc742181ded4930842b46e9507372f0b1b963James Dong                    &(pSrcDstMBCurr->pMVPred[0][1]),
4440c1bc742181ded4930842b46e9507372f0b1b963James Dong                    NULL,
4450c1bc742181ded4930842b46e9507372f0b1b963James Dong                    1);
4460c1bc742181ded4930842b46e9507372f0b1b963James Dong
4470c1bc742181ded4930842b46e9507372f0b1b963James Dong        armVCM4P2_BlockMatch_8x8 (pSrcRefBuf,
4480c1bc742181ded4930842b46e9507372f0b1b963James Dong                                      srcRefStep, pRefRect,
4490c1bc742181ded4930842b46e9507372f0b1b963James Dong                                      pTempSrcCurrBuf, pTempCurrPointPos,
4500c1bc742181ded4930842b46e9507372f0b1b963James Dong                                      &(pSrcDstMBCurr->pMVPred[0][1]), NULL,
4510c1bc742181ded4930842b46e9507372f0b1b963James Dong                                      pMEParams, &(pSrcDstMBCurr->pMV0[0][1]),
4520c1bc742181ded4930842b46e9507372f0b1b963James Dong                                      &dstSAD8x8
4530c1bc742181ded4930842b46e9507372f0b1b963James Dong                                      );
4540c1bc742181ded4930842b46e9507372f0b1b963James Dong        pDstBlockSAD[1] = dstSAD8x8;
4550c1bc742181ded4930842b46e9507372f0b1b963James Dong        *pDstSAD += dstSAD8x8;
4560c1bc742181ded4930842b46e9507372f0b1b963James Dong        pTempCurrPointPos->x -= 8;
4570c1bc742181ded4930842b46e9507372f0b1b963James Dong        pTempCurrPointPos->y += 8;
4580c1bc742181ded4930842b46e9507372f0b1b963James Dong        pSrcRefBuf += (srcRefStep * 8) - 8;
4590c1bc742181ded4930842b46e9507372f0b1b963James Dong
4600c1bc742181ded4930842b46e9507372f0b1b963James Dong        omxVCM4P2_FindMVpred(
4610c1bc742181ded4930842b46e9507372f0b1b963James Dong                    &(pSrcDstMBCurr->pMV0[1][0]),
4620c1bc742181ded4930842b46e9507372f0b1b963James Dong                    pSrcCandMV1[2],
4630c1bc742181ded4930842b46e9507372f0b1b963James Dong                    pSrcCandMV2[2],
4640c1bc742181ded4930842b46e9507372f0b1b963James Dong                    pSrcCandMV3[2],
4650c1bc742181ded4930842b46e9507372f0b1b963James Dong                    &(pSrcDstMBCurr->pMVPred[1][0]),
4660c1bc742181ded4930842b46e9507372f0b1b963James Dong                    NULL,
4670c1bc742181ded4930842b46e9507372f0b1b963James Dong                    2);
4680c1bc742181ded4930842b46e9507372f0b1b963James Dong        armVCM4P2_BlockMatch_8x8 (pSrcRefBuf,
4690c1bc742181ded4930842b46e9507372f0b1b963James Dong                                      srcRefStep, pRefRect,
4700c1bc742181ded4930842b46e9507372f0b1b963James Dong                                      pTempSrcCurrBuf, pTempCurrPointPos,
4710c1bc742181ded4930842b46e9507372f0b1b963James Dong                                      &(pSrcDstMBCurr->pMVPred[1][0]), NULL,
4720c1bc742181ded4930842b46e9507372f0b1b963James Dong                                      pMEParams, &(pSrcDstMBCurr->pMV0[1][0]),
4730c1bc742181ded4930842b46e9507372f0b1b963James Dong                                      &dstSAD8x8
4740c1bc742181ded4930842b46e9507372f0b1b963James Dong                                      );
4750c1bc742181ded4930842b46e9507372f0b1b963James Dong        pDstBlockSAD[2] = dstSAD8x8;
4760c1bc742181ded4930842b46e9507372f0b1b963James Dong        *pDstSAD += dstSAD8x8;
4770c1bc742181ded4930842b46e9507372f0b1b963James Dong        pTempCurrPointPos->x += 8;
4780c1bc742181ded4930842b46e9507372f0b1b963James Dong        pSrcRefBuf += 8;
4790c1bc742181ded4930842b46e9507372f0b1b963James Dong        omxVCM4P2_FindMVpred(
4800c1bc742181ded4930842b46e9507372f0b1b963James Dong                    &(pSrcDstMBCurr->pMV0[1][1]),
4810c1bc742181ded4930842b46e9507372f0b1b963James Dong                    pSrcCandMV1[3],
4820c1bc742181ded4930842b46e9507372f0b1b963James Dong                    pSrcCandMV2[3],
4830c1bc742181ded4930842b46e9507372f0b1b963James Dong                    pSrcCandMV3[3],
4840c1bc742181ded4930842b46e9507372f0b1b963James Dong                    &(pSrcDstMBCurr->pMVPred[1][1]),
4850c1bc742181ded4930842b46e9507372f0b1b963James Dong                    NULL,
4860c1bc742181ded4930842b46e9507372f0b1b963James Dong                    3);
4870c1bc742181ded4930842b46e9507372f0b1b963James Dong        armVCM4P2_BlockMatch_8x8 (pSrcRefBuf,
4880c1bc742181ded4930842b46e9507372f0b1b963James Dong                                      srcRefStep, pRefRect,
4890c1bc742181ded4930842b46e9507372f0b1b963James Dong                                      pTempSrcCurrBuf, pTempCurrPointPos,
4900c1bc742181ded4930842b46e9507372f0b1b963James Dong                                      &(pSrcDstMBCurr->pMVPred[1][1]), NULL,
4910c1bc742181ded4930842b46e9507372f0b1b963James Dong                                      pMEParams, &(pSrcDstMBCurr->pMV0[1][1]),
4920c1bc742181ded4930842b46e9507372f0b1b963James Dong                                      &dstSAD8x8
4930c1bc742181ded4930842b46e9507372f0b1b963James Dong                                      );
4940c1bc742181ded4930842b46e9507372f0b1b963James Dong        pDstBlockSAD[3] = dstSAD8x8;
4950c1bc742181ded4930842b46e9507372f0b1b963James Dong        *pDstSAD += dstSAD8x8;
4960c1bc742181ded4930842b46e9507372f0b1b963James Dong
4970c1bc742181ded4930842b46e9507372f0b1b963James Dong
4980c1bc742181ded4930842b46e9507372f0b1b963James Dong        /* Checking if 4MV is equal to 1MV */
4990c1bc742181ded4930842b46e9507372f0b1b963James Dong        if (
5000c1bc742181ded4930842b46e9507372f0b1b963James Dong            (pSrcDstMBCurr->pMV0[0][0].dx != dstMV16x16.dx) ||
5010c1bc742181ded4930842b46e9507372f0b1b963James Dong            (pSrcDstMBCurr->pMV0[0][0].dy != dstMV16x16.dy) ||
5020c1bc742181ded4930842b46e9507372f0b1b963James Dong            (pSrcDstMBCurr->pMV0[0][1].dx != dstMV16x16.dx) ||
5030c1bc742181ded4930842b46e9507372f0b1b963James Dong            (pSrcDstMBCurr->pMV0[0][1].dy != dstMV16x16.dy) ||
5040c1bc742181ded4930842b46e9507372f0b1b963James Dong            (pSrcDstMBCurr->pMV0[1][0].dx != dstMV16x16.dx) ||
5050c1bc742181ded4930842b46e9507372f0b1b963James Dong            (pSrcDstMBCurr->pMV0[1][0].dy != dstMV16x16.dy) ||
5060c1bc742181ded4930842b46e9507372f0b1b963James Dong            (pSrcDstMBCurr->pMV0[1][1].dx != dstMV16x16.dx) ||
5070c1bc742181ded4930842b46e9507372f0b1b963James Dong            (pSrcDstMBCurr->pMV0[1][1].dy != dstMV16x16.dy)
5080c1bc742181ded4930842b46e9507372f0b1b963James Dong           )
5090c1bc742181ded4930842b46e9507372f0b1b963James Dong        {
5100c1bc742181ded4930842b46e9507372f0b1b963James Dong            /* select the 4 MV */
5110c1bc742181ded4930842b46e9507372f0b1b963James Dong            pSrcDstMBCurr->mbType = OMX_VC_INTER4V;
5120c1bc742181ded4930842b46e9507372f0b1b963James Dong        }
5130c1bc742181ded4930842b46e9507372f0b1b963James Dong    }
5140c1bc742181ded4930842b46e9507372f0b1b963James Dong
5150c1bc742181ded4930842b46e9507372f0b1b963James Dong    /* finding the error in intra mode */
5160c1bc742181ded4930842b46e9507372f0b1b963James Dong    for (count = 0, average = 0; count < 256 ; count++)
5170c1bc742181ded4930842b46e9507372f0b1b963James Dong    {
5180c1bc742181ded4930842b46e9507372f0b1b963James Dong        average = average + pTempSrcCurrBuf[count];
5190c1bc742181ded4930842b46e9507372f0b1b963James Dong    }
5200c1bc742181ded4930842b46e9507372f0b1b963James Dong    average = average/256;
5210c1bc742181ded4930842b46e9507372f0b1b963James Dong
5220c1bc742181ded4930842b46e9507372f0b1b963James Dong	intraSAD = 0;
5230c1bc742181ded4930842b46e9507372f0b1b963James Dong
5240c1bc742181ded4930842b46e9507372f0b1b963James Dong    /* Intra SAD calculation */
5250c1bc742181ded4930842b46e9507372f0b1b963James Dong    for (count = 0; count < 256 ; count++)
5260c1bc742181ded4930842b46e9507372f0b1b963James Dong    {
5270c1bc742181ded4930842b46e9507372f0b1b963James Dong        intraSAD += armAbs ((pTempSrcCurrBuf[count]) - (average));
5280c1bc742181ded4930842b46e9507372f0b1b963James Dong    }
5290c1bc742181ded4930842b46e9507372f0b1b963James Dong
5300c1bc742181ded4930842b46e9507372f0b1b963James Dong	/* Using the MPEG4 VM formula for intra/inter mode decision
5310c1bc742181ded4930842b46e9507372f0b1b963James Dong	   Var < (SAD - 2*NB) where NB = N^2 is the number of pixels
5320c1bc742181ded4930842b46e9507372f0b1b963James Dong	   of the macroblock.*/
5330c1bc742181ded4930842b46e9507372f0b1b963James Dong
5340c1bc742181ded4930842b46e9507372f0b1b963James Dong    if (intraSAD <= (*pDstSAD - 512))
5350c1bc742181ded4930842b46e9507372f0b1b963James Dong    {
5360c1bc742181ded4930842b46e9507372f0b1b963James Dong        pSrcDstMBCurr->mbType = OMX_VC_INTRA;
5370c1bc742181ded4930842b46e9507372f0b1b963James Dong        pSrcDstMBCurr->pMV0[0][0].dx = 0;
5380c1bc742181ded4930842b46e9507372f0b1b963James Dong        pSrcDstMBCurr->pMV0[0][0].dy = 0;
5390c1bc742181ded4930842b46e9507372f0b1b963James Dong        *pDstSAD   = intraSAD;
5400c1bc742181ded4930842b46e9507372f0b1b963James Dong        pDstBlockSAD[0] = 0xFFFF;
5410c1bc742181ded4930842b46e9507372f0b1b963James Dong        pDstBlockSAD[1] = 0xFFFF;
5420c1bc742181ded4930842b46e9507372f0b1b963James Dong        pDstBlockSAD[2] = 0xFFFF;
5430c1bc742181ded4930842b46e9507372f0b1b963James Dong        pDstBlockSAD[3] = 0xFFFF;
5440c1bc742181ded4930842b46e9507372f0b1b963James Dong    }
5450c1bc742181ded4930842b46e9507372f0b1b963James Dong
5460c1bc742181ded4930842b46e9507372f0b1b963James Dong    if(pSrcDstMBCurr->mbType == OMX_VC_INTER)
5470c1bc742181ded4930842b46e9507372f0b1b963James Dong    {
5480c1bc742181ded4930842b46e9507372f0b1b963James Dong      pTempSrcRefBuf = pSrcRefBuf + (srcRefStep * dstMV16x16.dy) + dstMV16x16.dx;
5490c1bc742181ded4930842b46e9507372f0b1b963James Dong
5500c1bc742181ded4930842b46e9507372f0b1b963James Dong      if((dstMV16x16.dx & 0x1) && (dstMV16x16.dy & 0x1))
5510c1bc742181ded4930842b46e9507372f0b1b963James Dong      {
5520c1bc742181ded4930842b46e9507372f0b1b963James Dong        predictType = OMX_VC_HALF_PIXEL_XY;
5530c1bc742181ded4930842b46e9507372f0b1b963James Dong      }
5540c1bc742181ded4930842b46e9507372f0b1b963James Dong      else if(dstMV16x16.dx & 0x1)
5550c1bc742181ded4930842b46e9507372f0b1b963James Dong      {
5560c1bc742181ded4930842b46e9507372f0b1b963James Dong        predictType = OMX_VC_HALF_PIXEL_X;
5570c1bc742181ded4930842b46e9507372f0b1b963James Dong      }
5580c1bc742181ded4930842b46e9507372f0b1b963James Dong      else if(dstMV16x16.dy & 0x1)
5590c1bc742181ded4930842b46e9507372f0b1b963James Dong      {
5600c1bc742181ded4930842b46e9507372f0b1b963James Dong        predictType = OMX_VC_HALF_PIXEL_Y;
5610c1bc742181ded4930842b46e9507372f0b1b963James Dong      }
5620c1bc742181ded4930842b46e9507372f0b1b963James Dong      else
5630c1bc742181ded4930842b46e9507372f0b1b963James Dong      {
5640c1bc742181ded4930842b46e9507372f0b1b963James Dong        predictType = OMX_VC_INTEGER_PIXEL;
5650c1bc742181ded4930842b46e9507372f0b1b963James Dong      }
5660c1bc742181ded4930842b46e9507372f0b1b963James Dong
5670c1bc742181ded4930842b46e9507372f0b1b963James Dong      pDst = armAlignTo8Bytes(&(aDst[0]));
5680c1bc742181ded4930842b46e9507372f0b1b963James Dong      /* Calculating Block SAD at MV(dstMV16x16.dx,dstMV16x16.dy) */
5690c1bc742181ded4930842b46e9507372f0b1b963James Dong	  /* Block 0 */
5700c1bc742181ded4930842b46e9507372f0b1b963James Dong      omxVCM4P2_MCReconBlock(pTempSrcRefBuf,
5710c1bc742181ded4930842b46e9507372f0b1b963James Dong	                             srcRefStep,
5720c1bc742181ded4930842b46e9507372f0b1b963James Dong                                 NULL,
5730c1bc742181ded4930842b46e9507372f0b1b963James Dong                                 pDst,
5740c1bc742181ded4930842b46e9507372f0b1b963James Dong                                 dstStep,
5750c1bc742181ded4930842b46e9507372f0b1b963James Dong                                 predictType,
5760c1bc742181ded4930842b46e9507372f0b1b963James Dong                                 pMEParams->rndVal);
5770c1bc742181ded4930842b46e9507372f0b1b963James Dong
5780c1bc742181ded4930842b46e9507372f0b1b963James Dong      armVCCOMM_SAD(pTempSrcCurrBuf,
5790c1bc742181ded4930842b46e9507372f0b1b963James Dong                        16,
5800c1bc742181ded4930842b46e9507372f0b1b963James Dong                        pDst,
5810c1bc742181ded4930842b46e9507372f0b1b963James Dong                        dstStep,
5820c1bc742181ded4930842b46e9507372f0b1b963James Dong                        &Sad,
5830c1bc742181ded4930842b46e9507372f0b1b963James Dong                        8,
5840c1bc742181ded4930842b46e9507372f0b1b963James Dong                        8);
5850c1bc742181ded4930842b46e9507372f0b1b963James Dong      pDstBlockSAD[0] = Sad;
5860c1bc742181ded4930842b46e9507372f0b1b963James Dong
5870c1bc742181ded4930842b46e9507372f0b1b963James Dong      /* Block 1 */
5880c1bc742181ded4930842b46e9507372f0b1b963James Dong      omxVCM4P2_MCReconBlock(pTempSrcRefBuf + 8,
5890c1bc742181ded4930842b46e9507372f0b1b963James Dong                                 srcRefStep,
5900c1bc742181ded4930842b46e9507372f0b1b963James Dong                                 NULL,
5910c1bc742181ded4930842b46e9507372f0b1b963James Dong                                 pDst,
5920c1bc742181ded4930842b46e9507372f0b1b963James Dong                                 dstStep,
5930c1bc742181ded4930842b46e9507372f0b1b963James Dong                                 predictType,
5940c1bc742181ded4930842b46e9507372f0b1b963James Dong                                 pMEParams->rndVal);
5950c1bc742181ded4930842b46e9507372f0b1b963James Dong
5960c1bc742181ded4930842b46e9507372f0b1b963James Dong      armVCCOMM_SAD(pTempSrcCurrBuf + 8,
5970c1bc742181ded4930842b46e9507372f0b1b963James Dong                        16,
5980c1bc742181ded4930842b46e9507372f0b1b963James Dong                        pDst,
5990c1bc742181ded4930842b46e9507372f0b1b963James Dong                        dstStep,
6000c1bc742181ded4930842b46e9507372f0b1b963James Dong                        &Sad,
6010c1bc742181ded4930842b46e9507372f0b1b963James Dong                        8,
6020c1bc742181ded4930842b46e9507372f0b1b963James Dong                        8);
6030c1bc742181ded4930842b46e9507372f0b1b963James Dong      pDstBlockSAD[1] = Sad;
6040c1bc742181ded4930842b46e9507372f0b1b963James Dong
6050c1bc742181ded4930842b46e9507372f0b1b963James Dong      /* Block 2 */
6060c1bc742181ded4930842b46e9507372f0b1b963James Dong      omxVCM4P2_MCReconBlock(pTempSrcRefBuf + (srcRefStep*8),
6070c1bc742181ded4930842b46e9507372f0b1b963James Dong                                 srcRefStep,
6080c1bc742181ded4930842b46e9507372f0b1b963James Dong                                 NULL,
6090c1bc742181ded4930842b46e9507372f0b1b963James Dong                                 pDst,
6100c1bc742181ded4930842b46e9507372f0b1b963James Dong                                 dstStep,
6110c1bc742181ded4930842b46e9507372f0b1b963James Dong                                 predictType,
6120c1bc742181ded4930842b46e9507372f0b1b963James Dong                                 pMEParams->rndVal);
6130c1bc742181ded4930842b46e9507372f0b1b963James Dong
6140c1bc742181ded4930842b46e9507372f0b1b963James Dong      armVCCOMM_SAD(pTempSrcCurrBuf + (16*8),
6150c1bc742181ded4930842b46e9507372f0b1b963James Dong                        16,
6160c1bc742181ded4930842b46e9507372f0b1b963James Dong                        pDst,
6170c1bc742181ded4930842b46e9507372f0b1b963James Dong                        dstStep,
6180c1bc742181ded4930842b46e9507372f0b1b963James Dong                        &Sad,
6190c1bc742181ded4930842b46e9507372f0b1b963James Dong                        8,
6200c1bc742181ded4930842b46e9507372f0b1b963James Dong                        8);
6210c1bc742181ded4930842b46e9507372f0b1b963James Dong      pDstBlockSAD[2] = Sad;
6220c1bc742181ded4930842b46e9507372f0b1b963James Dong
6230c1bc742181ded4930842b46e9507372f0b1b963James Dong	  /* Block 3 */
6240c1bc742181ded4930842b46e9507372f0b1b963James Dong      omxVCM4P2_MCReconBlock(pTempSrcRefBuf + (srcRefStep*8) + 8,
6250c1bc742181ded4930842b46e9507372f0b1b963James Dong                                 srcRefStep,
6260c1bc742181ded4930842b46e9507372f0b1b963James Dong                                 NULL,
6270c1bc742181ded4930842b46e9507372f0b1b963James Dong                                 pDst,
6280c1bc742181ded4930842b46e9507372f0b1b963James Dong                                 dstStep,
6290c1bc742181ded4930842b46e9507372f0b1b963James Dong                                 predictType,
6300c1bc742181ded4930842b46e9507372f0b1b963James Dong                                 pMEParams->rndVal);
6310c1bc742181ded4930842b46e9507372f0b1b963James Dong
6320c1bc742181ded4930842b46e9507372f0b1b963James Dong      armVCCOMM_SAD(pTempSrcCurrBuf + (16*8) + 8,
6330c1bc742181ded4930842b46e9507372f0b1b963James Dong                        16,
6340c1bc742181ded4930842b46e9507372f0b1b963James Dong                        pDst,
6350c1bc742181ded4930842b46e9507372f0b1b963James Dong                        dstStep,
6360c1bc742181ded4930842b46e9507372f0b1b963James Dong                        &Sad,
6370c1bc742181ded4930842b46e9507372f0b1b963James Dong                        8,
6380c1bc742181ded4930842b46e9507372f0b1b963James Dong                        8);
6390c1bc742181ded4930842b46e9507372f0b1b963James Dong      pDstBlockSAD[3] = Sad;
6400c1bc742181ded4930842b46e9507372f0b1b963James Dong    }
6410c1bc742181ded4930842b46e9507372f0b1b963James Dong    return OMX_Sts_NoErr;
6420c1bc742181ded4930842b46e9507372f0b1b963James Dong}
6430c1bc742181ded4930842b46e9507372f0b1b963James Dong
6440c1bc742181ded4930842b46e9507372f0b1b963James Dong/* End of file */
6450c1bc742181ded4930842b46e9507372f0b1b963James Dong
646