| /* |
| * Copyright (C) 2007-2008 ARM Limited |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| * |
| */ |
| /** |
| * |
| * File Name: omxVCM4P2_MotionEstimationMB.c |
| * OpenMAX DL: v1.0.2 |
| * Revision: 9641 |
| * Date: Thursday, February 7, 2008 |
| * |
| * |
| * |
| * |
| * 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 */ |
| |