summaryrefslogtreecommitdiffstats
path: root/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/omxVCM4P2_MotionEstimationMB.c
diff options
context:
space:
mode:
Diffstat (limited to 'media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/omxVCM4P2_MotionEstimationMB.c')
-rw-r--r--media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/omxVCM4P2_MotionEstimationMB.c630
1 files changed, 630 insertions, 0 deletions
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/omxVCM4P2_MotionEstimationMB.c b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/omxVCM4P2_MotionEstimationMB.c
new file mode 100644
index 0000000..9549050
--- /dev/null
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/vc/m4p2/src/omxVCM4P2_MotionEstimationMB.c
@@ -0,0 +1,630 @@
+/**
+ *
+ * File Name: omxVCM4P2_MotionEstimationMB.c
+ * OpenMAX DL: v1.0.2
+ * Revision: 9641
+ * Date: Thursday, February 7, 2008
+ *
+ * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
+ *
+ *
+ *
+ * Description:
+ * Contains module for motion search 16x16 macroblock
+ *
+ */
+
+#include "omxtypes.h"
+#include "armOMX.h"
+#include "omxVC.h"
+
+#include "armVC.h"
+#include "armCOMM.h"
+
+/**
+ * Function: armVCM4P2_BlockMatch_16x16
+ *
+ * Description:
+ * 16x16 block match wrapper function, calls omxVCM4P2_BlockMatch_Integer_16x16.
+ * If half pel search is enabled it also calls omxVCM4P2_BlockMatch_Half_16x16
+ *
+ * Remarks:
+ *
+ * Parameters:
+ * [in] pSrcRefBuf pointer to the reference Y plane; points to the reference MB that
+ * corresponds to the location of the current macroblock in the current
+ * plane.
+ * [in] srcRefStep width of the reference plane
+ * [in] pRefRect pointer to the valid rectangular in reference plane. Relative to image origin.
+ * It's not limited to the image boundary, but depended on the padding. For example,
+ * if you pad 4 pixels outside the image border, then the value for left border
+ * can be -4
+ * [in] pSrcCurrBuf pointer to the current macroblock extracted from original plane (linear array,
+ * 256 entries); must be aligned on an 16-byte boundary.
+ * [in] pCurrPointPos position of the current macroblock in the current plane
+ * [in] pSrcPreMV pointer to predicted motion vector; NULL indicates no predicted MV
+ * [in] pSrcPreSAD pointer to SAD associated with the predicted MV (referenced by pSrcPreMV); may be set to NULL if unavailable.
+ * [in] pMESpec vendor-specific motion estimation specification structure; must have been allocated
+ * and then initialized using omxVCM4P2_MEInit prior to calling the block matching
+ * function.
+ * [out] pDstMV pointer to estimated MV
+ * [out] pDstSAD pointer to minimum SAD
+ * *
+ * Return Value:
+ * OMX_Sts_NoErr - no error
+ * OMX_Sts_BadArgErr - bad arguments
+ *
+ */
+static OMXResult armVCM4P2_BlockMatch_16x16(
+ const OMX_U8 *pSrcRefBuf,
+ const OMX_INT srcRefStep,
+ const OMXRect *pRefRect,
+ const OMX_U8 *pSrcCurrBuf,
+ const OMXVCM4P2Coordinate *pCurrPointPos,
+ OMXVCMotionVector *pSrcPreMV,
+ OMX_INT *pSrcPreSAD,
+ void *pMESpec,
+ OMXVCMotionVector *pDstMV,
+ OMX_INT *pDstSAD
+)
+{
+ OMXVCM4P2MEParams *pMEParams = (OMXVCM4P2MEParams *)pMESpec;
+ OMX_INT rndVal;
+
+ rndVal = pMEParams->rndVal;
+
+ omxVCM4P2_BlockMatch_Integer_16x16(
+ pSrcRefBuf,
+ srcRefStep,
+ pRefRect,
+ pSrcCurrBuf,
+ pCurrPointPos,
+ pSrcPreMV,
+ pSrcPreSAD,
+ pMEParams,
+ pDstMV,
+ pDstSAD);
+
+ if (pMEParams->halfPelSearchEnable)
+ {
+ omxVCM4P2_BlockMatch_Half_16x16(
+ pSrcRefBuf,
+ srcRefStep,
+ pRefRect,
+ pSrcCurrBuf,
+ pCurrPointPos,
+ rndVal,
+ pDstMV,
+ pDstSAD);
+ }
+
+ return OMX_Sts_NoErr;
+}
+
+/**
+ * Function: armVCM4P2_BlockMatch_8x8
+ *
+ * Description:
+ * 8x8 block match wrapper function, calls omxVCM4P2_BlockMatch_Integer_8x8.
+ * If half pel search is enabled it also calls omxVCM4P2_BlockMatch_Half_8x8
+ *
+ * Remarks:
+ *
+ * Parameters:
+ * [in] pSrcRefBuf pointer to the reference Y plane; points to the reference MB that
+ * corresponds to the location of the current macroblock in the current
+ * plane.
+ * [in] srcRefStep width of the reference plane
+ * [in] pRefRect pointer to the valid rectangular in reference plane. Relative to image origin.
+ * It's not limited to the image boundary, but depended on the padding. For example,
+ * if you pad 4 pixels outside the image border, then the value for left border
+ * can be -4
+ * [in] pSrcCurrBuf pointer to the current macroblock extracted from original plane (linear array,
+ * 256 entries); must be aligned on an 16-byte boundary.
+ * [in] pCurrPointPos position of the current macroblock in the current plane
+ * [in] pSrcPreMV pointer to predicted motion vector; NULL indicates no predicted MV
+ * [in] pSrcPreSAD pointer to SAD associated with the predicted MV (referenced by pSrcPreMV); may be set to NULL if unavailable.
+ * [in] pMESpec vendor-specific motion estimation specification structure; must have been allocated
+ * and then initialized using omxVCM4P2_MEInit prior to calling the block matching
+ * function.
+ * [out] pDstMV pointer to estimated MV
+ * [out] pDstSAD pointer to minimum SAD
+ * *
+ * Return Value:
+ * OMX_Sts_NoErr - no error
+ * OMX_Sts_BadArgErr - bad arguments
+ *
+ */
+static OMXResult armVCM4P2_BlockMatch_8x8(
+ const OMX_U8 *pSrcRefBuf,
+ OMX_INT srcRefStep,
+ const OMXRect *pRefRect,
+ const OMX_U8 *pSrcCurrBuf,
+ const OMXVCM4P2Coordinate *pCurrPointPos,
+ OMXVCMotionVector *pSrcPreMV,
+ OMX_INT *pSrcPreSAD,
+ void *pMESpec,
+ OMXVCMotionVector *pSrcDstMV,
+ OMX_INT *pDstSAD
+)
+{
+ OMXVCM4P2MEParams *pMEParams = (OMXVCM4P2MEParams *)pMESpec;
+ OMX_INT rndVal;
+
+ rndVal = pMEParams->rndVal;
+
+ omxVCM4P2_BlockMatch_Integer_8x8(
+ pSrcRefBuf,
+ srcRefStep,
+ pRefRect,
+ pSrcCurrBuf,
+ pCurrPointPos,
+ pSrcPreMV,
+ pSrcPreSAD,
+ pMEParams,
+ pSrcDstMV,
+ pDstSAD);
+
+ if (pMEParams->halfPelSearchEnable)
+ {
+ omxVCM4P2_BlockMatch_Half_8x8(
+ pSrcRefBuf,
+ srcRefStep,
+ pRefRect,
+ pSrcCurrBuf,
+ pCurrPointPos,
+ rndVal,
+ pSrcDstMV,
+ pDstSAD);
+ }
+
+ return OMX_Sts_NoErr;
+}
+
+
+/**
+ * Function: omxVCM4P2_MotionEstimationMB (6.2.4.3.1)
+ *
+ * Description:
+ * Performs motion search for a 16x16 macroblock. Selects best motion search
+ * strategy from among inter-1MV, inter-4MV, and intra modes. Supports
+ * integer and half pixel resolution.
+ *
+ * Input Arguments:
+ *
+ * pSrcCurrBuf - pointer to the top-left corner of the current MB in the
+ * original picture plane; must be aligned on a 16-byte boundary.
+ * The function does not expect source data outside the region
+ * bounded by the MB to be available; for example it is not
+ * necessary for the caller to guarantee the availability of
+ * pSrcCurrBuf[-SrcCurrStep], i.e., the row of pixels above the MB
+ * to be processed.
+ * srcCurrStep - width of the original picture plane, in terms of full
+ * pixels; must be a multiple of 16.
+ * pSrcRefBuf - pointer to the reference Y plane; points to the reference
+ * plane location corresponding to the location of the current
+ * macroblock in the current plane; must be aligned on a 16-byte
+ * boundary.
+ * srcRefStep - width of the reference picture plane, in terms of full
+ * pixels; must be a multiple of 16.
+ * pRefRect - reference plane valid region rectangle, specified relative to
+ * the image origin
+ * pCurrPointPos - position of the current macroblock in the current plane
+ * pMESpec - pointer to the vendor-specific motion estimation specification
+ * structure; must be allocated and then initialized using
+ * omxVCM4P2_MEInit prior to calling this function.
+ * pMBInfo - array, of dimension four, containing pointers to information
+ * associated with four nearby MBs:
+ * - pMBInfo[0] - pointer to left MB information
+ * - pMBInfo[1] - pointer to top MB information
+ * - pMBInfo[2] - pointer to top-left MB information
+ * - pMBInfo[3] - pointer to top-right MB information
+ * Any pointer in the array may be set equal to NULL if the
+ * corresponding MB doesn't exist. For each MB, the following structure
+ * members are used:
+ * - mbType - macroblock type, either OMX_VC_INTRA, OMX_VC_INTER, or
+ * OMX_VC_INTER4V
+ * - pMV0[2][2] - estimated motion vectors; represented
+ * in 1/2 pixel units
+ * - sliceID - number of the slice to which the MB belongs
+ * pSrcDstMBCurr - pointer to information structure for the current MB.
+ * The following entries should be set prior to calling the
+ * function: sliceID - the number of the slice the to which the
+ * current MB belongs. The structure elements cbpy and cbpc are
+ * ignored.
+ *
+ * Output Arguments:
+ *
+ * pSrcDstMBCurr - pointer to updated information structure for the current
+ * MB after MB-level motion estimation has been completed. The
+ * following structure members are updated by the ME function:
+ * - mbType - macroblock type: OMX_VC_INTRA, OMX_VC_INTER, or
+ * OMX_VC_INTER4V.
+ * - pMV0[2][2] - estimated motion vectors; represented in
+ * terms of 1/2 pel units.
+ * - pMVPred[2][2] - predicted motion vectors; represented
+ * in terms of 1/2 pel units.
+ * The structure members cbpy and cbpc are not updated by the function.
+ * pDstSAD - pointer to the minimum SAD for INTER1V, or sum of minimum SADs
+ * for INTER4V
+ * pDstBlockSAD - pointer to an array of SAD values for each of the four
+ * 8x8 luma blocks in the MB. The block SADs are in scan order for
+ * each MB.
+ *
+ * Return Value:
+ *
+ * OMX_Sts_NoErr - no error
+ * OMX_Sts_BadArgErr - bad arguments. Returned if one or more of the
+ * following conditions is true:
+ * - at least one of the following pointers is NULL: pSrcCurrBuf,
+ * pSrcRefBuf, pRefRect, pCurrPointPos, pMBInter, pMBIntra,
+ * pSrcDstMBCurr, or pDstSAD.
+ *
+ */
+
+OMXResult omxVCM4P2_MotionEstimationMB (
+ const OMX_U8 *pSrcCurrBuf,
+ OMX_S32 srcCurrStep,
+ const OMX_U8 *pSrcRefBuf,
+ OMX_S32 srcRefStep,
+ const OMXRect*pRefRect,
+ const OMXVCM4P2Coordinate *pCurrPointPos,
+ void *pMESpec,
+ const OMXVCM4P2MBInfoPtr *pMBInfo,
+ OMXVCM4P2MBInfo *pSrcDstMBCurr,
+ OMX_U16 *pDstSAD,
+ OMX_U16 *pDstBlockSAD
+)
+{
+
+ OMX_INT intraSAD, average, count, index, x, y;
+ OMXVCMotionVector dstMV16x16;
+ OMX_INT dstSAD16x16;
+ OMX_INT dstSAD8x8;
+ OMXVCM4P2MEParams *pMEParams;
+ OMXVCM4P2Coordinate TempCurrPointPos;
+ OMXVCM4P2Coordinate *pTempCurrPointPos;
+ OMX_U8 aTempSrcCurrBuf[271];
+ OMX_U8 *pTempSrcCurrBuf;
+ OMX_U8 *pDst;
+ OMX_U8 aDst[71];
+ OMX_S32 dstStep = 8;
+ OMX_INT predictType;
+ OMX_S32 Sad;
+ const OMX_U8 *pTempSrcRefBuf;
+ OMXVCMotionVector* pSrcCandMV1[4];
+ OMXVCMotionVector* pSrcCandMV2[4];
+ OMXVCMotionVector* pSrcCandMV3[4];
+
+ /* Argument error checks */
+ armRetArgErrIf(!armIs16ByteAligned(pSrcCurrBuf), OMX_Sts_BadArgErr);
+ armRetArgErrIf(!armIs16ByteAligned(pSrcRefBuf), OMX_Sts_BadArgErr);
+ armRetArgErrIf(((srcCurrStep % 16) || (srcRefStep % 16)), OMX_Sts_BadArgErr);
+ armRetArgErrIf(pSrcCurrBuf == NULL, OMX_Sts_BadArgErr);
+ armRetArgErrIf(pSrcRefBuf == NULL, OMX_Sts_BadArgErr);
+ armRetArgErrIf(pRefRect == NULL, OMX_Sts_BadArgErr);
+ armRetArgErrIf(pCurrPointPos == NULL, OMX_Sts_BadArgErr);
+ armRetArgErrIf(pSrcDstMBCurr == NULL, OMX_Sts_BadArgErr);
+ armRetArgErrIf(pDstSAD == NULL, OMX_Sts_BadArgErr);
+
+
+ pTempCurrPointPos = &(TempCurrPointPos);
+ pTempSrcCurrBuf = armAlignTo16Bytes(aTempSrcCurrBuf);
+ pMEParams = (OMXVCM4P2MEParams *)pMESpec;
+ pTempCurrPointPos->x = pCurrPointPos->x;
+ pTempCurrPointPos->y = pCurrPointPos->y;
+ pSrcDstMBCurr->mbType = OMX_VC_INTER;
+
+ /* Preparing a linear buffer for block match */
+ for (y = 0, index = count = 0; y < 16; y++, index += srcCurrStep - 16)
+ {
+ for(x = 0; x < 16; x++, count++, index++)
+ {
+ pTempSrcCurrBuf[count] = pSrcCurrBuf[index];
+ }
+ }
+ for(y = 0, index = 0; y < 2; y++)
+ {
+ for(x = 0; x < 2; x++,index++)
+ {
+ if((pMBInfo[0] != NULL) && (pMBInfo[0]->mbType != OMX_VC_INTRA))
+ {
+ pSrcCandMV1[index] = &(pMBInfo[0]->pMV0[y][x]);
+ }
+ else
+ {
+ pSrcCandMV1[index] = NULL;
+ }
+ if((pMBInfo[1] != NULL) && (pMBInfo[1]->mbType != OMX_VC_INTRA))
+ {
+ pSrcCandMV2[index] = &(pMBInfo[1]->pMV0[y][x]);
+ }
+ else
+ {
+ pSrcCandMV2[index] = NULL;
+ }
+ if((pMBInfo[3] != NULL) && (pMBInfo[3]->mbType != OMX_VC_INTRA))
+ {
+ pSrcCandMV3[index] = &(pMBInfo[3]->pMV0[y][x]);
+ }
+ else
+ {
+ pSrcCandMV3[index] = NULL;
+ }
+ }
+ }
+ /* Calculating SAD at MV(0,0) */
+ armVCCOMM_SAD(pTempSrcCurrBuf,
+ 16,
+ pSrcRefBuf,
+ srcRefStep,
+ &Sad,
+ 16,
+ 16);
+ *pDstSAD = Sad;
+
+ /* Mode decision for NOT_CODED MB */
+ if(*pDstSAD == 0)
+ {
+ pSrcDstMBCurr->pMV0[0][0].dx = 0;
+ pSrcDstMBCurr->pMV0[0][0].dy = 0;
+ *pDstSAD = 0;
+ return OMX_Sts_NoErr;
+ }
+
+ omxVCM4P2_FindMVpred(
+ &(pSrcDstMBCurr->pMV0[0][0]),
+ pSrcCandMV1[0],
+ pSrcCandMV2[0],
+ pSrcCandMV3[0],
+ &(pSrcDstMBCurr->pMVPred[0][0]),
+ NULL,
+ 0);
+
+ /* Inter 1 MV */
+ armVCM4P2_BlockMatch_16x16(
+ pSrcRefBuf,
+ srcRefStep,
+ pRefRect,
+ pTempSrcCurrBuf,
+ pCurrPointPos,
+ &(pSrcDstMBCurr->pMVPred[0][0]),
+ NULL,
+ pMEParams,
+ &dstMV16x16,
+ &dstSAD16x16);
+
+ /* Initialize all with 1 MV values */
+ pSrcDstMBCurr->pMV0[0][0].dx = dstMV16x16.dx;
+ pSrcDstMBCurr->pMV0[0][0].dy = dstMV16x16.dy;
+ pSrcDstMBCurr->pMV0[0][1].dx = dstMV16x16.dx;
+ pSrcDstMBCurr->pMV0[0][1].dy = dstMV16x16.dy;
+ pSrcDstMBCurr->pMV0[1][0].dx = dstMV16x16.dx;
+ pSrcDstMBCurr->pMV0[1][0].dy = dstMV16x16.dy;
+ pSrcDstMBCurr->pMV0[1][1].dx = dstMV16x16.dx;
+ pSrcDstMBCurr->pMV0[1][1].dy = dstMV16x16.dy;
+
+ *pDstSAD = dstSAD16x16;
+
+ if (pMEParams->searchEnable8x8)
+ {
+ /* Inter 4MV */
+ armVCM4P2_BlockMatch_8x8 (pSrcRefBuf,
+ srcRefStep, pRefRect,
+ pTempSrcCurrBuf, pTempCurrPointPos,
+ &(pSrcDstMBCurr->pMVPred[0][0]), NULL,
+ pMEParams, &(pSrcDstMBCurr->pMV0[0][0]),
+ &dstSAD8x8
+ );
+ pDstBlockSAD[0] = dstSAD8x8;
+ *pDstSAD = dstSAD8x8;
+ pTempCurrPointPos->x += 8;
+ pSrcRefBuf += 8;
+ omxVCM4P2_FindMVpred(
+ &(pSrcDstMBCurr->pMV0[0][1]),
+ pSrcCandMV1[1],
+ pSrcCandMV2[1],
+ pSrcCandMV3[1],
+ &(pSrcDstMBCurr->pMVPred[0][1]),
+ NULL,
+ 1);
+
+ armVCM4P2_BlockMatch_8x8 (pSrcRefBuf,
+ srcRefStep, pRefRect,
+ pTempSrcCurrBuf, pTempCurrPointPos,
+ &(pSrcDstMBCurr->pMVPred[0][1]), NULL,
+ pMEParams, &(pSrcDstMBCurr->pMV0[0][1]),
+ &dstSAD8x8
+ );
+ pDstBlockSAD[1] = dstSAD8x8;
+ *pDstSAD += dstSAD8x8;
+ pTempCurrPointPos->x -= 8;
+ pTempCurrPointPos->y += 8;
+ pSrcRefBuf += (srcRefStep * 8) - 8;
+
+ omxVCM4P2_FindMVpred(
+ &(pSrcDstMBCurr->pMV0[1][0]),
+ pSrcCandMV1[2],
+ pSrcCandMV2[2],
+ pSrcCandMV3[2],
+ &(pSrcDstMBCurr->pMVPred[1][0]),
+ NULL,
+ 2);
+ armVCM4P2_BlockMatch_8x8 (pSrcRefBuf,
+ srcRefStep, pRefRect,
+ pTempSrcCurrBuf, pTempCurrPointPos,
+ &(pSrcDstMBCurr->pMVPred[1][0]), NULL,
+ pMEParams, &(pSrcDstMBCurr->pMV0[1][0]),
+ &dstSAD8x8
+ );
+ pDstBlockSAD[2] = dstSAD8x8;
+ *pDstSAD += dstSAD8x8;
+ pTempCurrPointPos->x += 8;
+ pSrcRefBuf += 8;
+ omxVCM4P2_FindMVpred(
+ &(pSrcDstMBCurr->pMV0[1][1]),
+ pSrcCandMV1[3],
+ pSrcCandMV2[3],
+ pSrcCandMV3[3],
+ &(pSrcDstMBCurr->pMVPred[1][1]),
+ NULL,
+ 3);
+ armVCM4P2_BlockMatch_8x8 (pSrcRefBuf,
+ srcRefStep, pRefRect,
+ pTempSrcCurrBuf, pTempCurrPointPos,
+ &(pSrcDstMBCurr->pMVPred[1][1]), NULL,
+ pMEParams, &(pSrcDstMBCurr->pMV0[1][1]),
+ &dstSAD8x8
+ );
+ pDstBlockSAD[3] = dstSAD8x8;
+ *pDstSAD += dstSAD8x8;
+
+
+ /* Checking if 4MV is equal to 1MV */
+ if (
+ (pSrcDstMBCurr->pMV0[0][0].dx != dstMV16x16.dx) ||
+ (pSrcDstMBCurr->pMV0[0][0].dy != dstMV16x16.dy) ||
+ (pSrcDstMBCurr->pMV0[0][1].dx != dstMV16x16.dx) ||
+ (pSrcDstMBCurr->pMV0[0][1].dy != dstMV16x16.dy) ||
+ (pSrcDstMBCurr->pMV0[1][0].dx != dstMV16x16.dx) ||
+ (pSrcDstMBCurr->pMV0[1][0].dy != dstMV16x16.dy) ||
+ (pSrcDstMBCurr->pMV0[1][1].dx != dstMV16x16.dx) ||
+ (pSrcDstMBCurr->pMV0[1][1].dy != dstMV16x16.dy)
+ )
+ {
+ /* select the 4 MV */
+ pSrcDstMBCurr->mbType = OMX_VC_INTER4V;
+ }
+ }
+
+ /* finding the error in intra mode */
+ for (count = 0, average = 0; count < 256 ; count++)
+ {
+ average = average + pTempSrcCurrBuf[count];
+ }
+ average = average/256;
+
+ intraSAD = 0;
+
+ /* Intra SAD calculation */
+ for (count = 0; count < 256 ; count++)
+ {
+ intraSAD += armAbs ((pTempSrcCurrBuf[count]) - (average));
+ }
+
+ /* Using the MPEG4 VM formula for intra/inter mode decision
+ Var < (SAD - 2*NB) where NB = N^2 is the number of pixels
+ of the macroblock.*/
+
+ if (intraSAD <= (*pDstSAD - 512))
+ {
+ pSrcDstMBCurr->mbType = OMX_VC_INTRA;
+ pSrcDstMBCurr->pMV0[0][0].dx = 0;
+ pSrcDstMBCurr->pMV0[0][0].dy = 0;
+ *pDstSAD = intraSAD;
+ pDstBlockSAD[0] = 0xFFFF;
+ pDstBlockSAD[1] = 0xFFFF;
+ pDstBlockSAD[2] = 0xFFFF;
+ pDstBlockSAD[3] = 0xFFFF;
+ }
+
+ if(pSrcDstMBCurr->mbType == OMX_VC_INTER)
+ {
+ pTempSrcRefBuf = pSrcRefBuf + (srcRefStep * dstMV16x16.dy) + dstMV16x16.dx;
+
+ if((dstMV16x16.dx & 0x1) && (dstMV16x16.dy & 0x1))
+ {
+ predictType = OMX_VC_HALF_PIXEL_XY;
+ }
+ else if(dstMV16x16.dx & 0x1)
+ {
+ predictType = OMX_VC_HALF_PIXEL_X;
+ }
+ else if(dstMV16x16.dy & 0x1)
+ {
+ predictType = OMX_VC_HALF_PIXEL_Y;
+ }
+ else
+ {
+ predictType = OMX_VC_INTEGER_PIXEL;
+ }
+
+ pDst = armAlignTo8Bytes(&(aDst[0]));
+ /* Calculating Block SAD at MV(dstMV16x16.dx,dstMV16x16.dy) */
+ /* Block 0 */
+ omxVCM4P2_MCReconBlock(pTempSrcRefBuf,
+ srcRefStep,
+ NULL,
+ pDst,
+ dstStep,
+ predictType,
+ pMEParams->rndVal);
+
+ armVCCOMM_SAD(pTempSrcCurrBuf,
+ 16,
+ pDst,
+ dstStep,
+ &Sad,
+ 8,
+ 8);
+ pDstBlockSAD[0] = Sad;
+
+ /* Block 1 */
+ omxVCM4P2_MCReconBlock(pTempSrcRefBuf + 8,
+ srcRefStep,
+ NULL,
+ pDst,
+ dstStep,
+ predictType,
+ pMEParams->rndVal);
+
+ armVCCOMM_SAD(pTempSrcCurrBuf + 8,
+ 16,
+ pDst,
+ dstStep,
+ &Sad,
+ 8,
+ 8);
+ pDstBlockSAD[1] = Sad;
+
+ /* Block 2 */
+ omxVCM4P2_MCReconBlock(pTempSrcRefBuf + (srcRefStep*8),
+ srcRefStep,
+ NULL,
+ pDst,
+ dstStep,
+ predictType,
+ pMEParams->rndVal);
+
+ armVCCOMM_SAD(pTempSrcCurrBuf + (16*8),
+ 16,
+ pDst,
+ dstStep,
+ &Sad,
+ 8,
+ 8);
+ pDstBlockSAD[2] = Sad;
+
+ /* Block 3 */
+ omxVCM4P2_MCReconBlock(pTempSrcRefBuf + (srcRefStep*8) + 8,
+ srcRefStep,
+ NULL,
+ pDst,
+ dstStep,
+ predictType,
+ pMEParams->rndVal);
+
+ armVCCOMM_SAD(pTempSrcCurrBuf + (16*8) + 8,
+ 16,
+ pDst,
+ dstStep,
+ &Sad,
+ 8,
+ 8);
+ pDstBlockSAD[3] = Sad;
+ }
+ return OMX_Sts_NoErr;
+}
+
+/* End of file */
+