| /* |
| * 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: omxVCM4P10_BlockMatch_Integer.c |
| * OpenMAX DL: v1.0.2 |
| * Revision: 9641 |
| * Date: Thursday, February 7, 2008 |
| * |
| * |
| * |
| * |
| * Description: |
| * Contains modules for Block matching, a full search algorithm |
| * is implemented |
| * |
| */ |
| |
| #include "omxtypes.h" |
| #include "armOMX.h" |
| #include "omxVC.h" |
| |
| #include "armVC.h" |
| #include "armCOMM.h" |
| |
| /** |
| * Function: omxVCM4P10_BlockMatch_Integer (6.3.5.2.1) |
| * |
| * Description: |
| * Performs integer block match. Returns best MV and associated cost. |
| * |
| * Input Arguments: |
| * |
| * pSrcOrgY - Pointer to the top-left corner of the current block. If |
| * iBlockWidth==4, 4-byte alignment required. If iBlockWidth==8, |
| * 8-byte alignment required. If iBlockWidth==16, 16-byte alignment |
| * required. |
| * pSrcRefY - Pointer to the top-left corner of the co-located block in the |
| * reference picture. If iBlockWidth==4, 4-byte alignment |
| * required. If iBlockWidth==8, 8-byte alignment required. If |
| * iBlockWidth==16, 16-byte alignment required. |
| * nSrcOrgStep - Stride of the original picture plane, expressed in terms |
| * of integer pixels; must be a multiple of iBlockWidth. |
| * nSrcRefStep - Stride of the reference picture plane, expressed in terms |
| * of integer pixels |
| * pRefRect - pointer to the valid reference rectangle inside the reference |
| * picture plane |
| * nCurrPointPos - position of the current block in the current plane |
| * iBlockWidth - Width of the current block, expressed in terms of integer |
| * pixels; must be equal to either 4, 8, or 16. |
| * iBlockHeight - Height of the current block, expressed in terms of |
| * integer pixels; must be equal to either 4, 8, or 16. |
| * nLamda - Lamda factor; used to compute motion cost |
| * pMVPred - Predicted MV; used to compute motion cost, expressed in terms |
| * of 1/4-pel units |
| * pMVCandidate - Candidate MV; used to initialize the motion search, |
| * expressed in terms of integer pixels |
| * pMESpec - pointer to the ME specification structure |
| * |
| * Output Arguments: |
| * |
| * pDstBestMV - Best MV resulting from integer search, expressed in terms |
| * of 1/4-pel units |
| * pBestCost - Motion cost associated with the best MV; computed as |
| * SAD+Lamda*BitsUsedByMV |
| * |
| * Return Value: |
| * OMX_Sts_NoErr, if the function runs without error. |
| * OMX_Sts_BadArgErr - bad arguments: if one of the following cases occurs: |
| * - any of the following poitners are NULL: |
| * pSrcOrgY, pSrcRefY, pRefRect, pMVPred, pMVCandidate, or pMESpec. |
| * - Either iBlockWidth or iBlockHeight are values other than 4, 8, or 16. |
| * - Any alignment restrictions are violated |
| * |
| */ |
| |
| OMXResult omxVCM4P10_BlockMatch_Integer ( |
| const OMX_U8 *pSrcOrgY, |
| OMX_S32 nSrcOrgStep, |
| const OMX_U8 *pSrcRefY, |
| OMX_S32 nSrcRefStep, |
| const OMXRect *pRefRect, |
| const OMXVCM4P2Coordinate *pCurrPointPos, |
| OMX_U8 iBlockWidth, |
| OMX_U8 iBlockHeight, |
| OMX_U32 nLamda, |
| const OMXVCMotionVector *pMVPred, |
| const OMXVCMotionVector *pMVCandidate, |
| OMXVCMotionVector *pBestMV, |
| OMX_S32 *pBestCost, |
| void *pMESpec |
| ) |
| { |
| /* Definitions and Initializations*/ |
| OMX_INT candSAD; |
| OMX_INT fromX, toX, fromY, toY; |
| /* Offset to the reference at the begining of the bounding box */ |
| const OMX_U8 *pTempSrcRefY, *pTempSrcOrgY; |
| OMX_S16 x, y; |
| OMXVCMotionVector diffMV; |
| OMX_S32 nSearchRange; |
| ARMVCM4P10_MESpec *armMESpec = (ARMVCM4P10_MESpec *) pMESpec; |
| |
| /* Argument error checks */ |
| armRetArgErrIf((iBlockWidth == 4) && (!armIs4ByteAligned(pSrcOrgY)), OMX_Sts_BadArgErr); |
| armRetArgErrIf((iBlockWidth == 8) && (!armIs8ByteAligned(pSrcOrgY)), OMX_Sts_BadArgErr); |
| armRetArgErrIf((iBlockWidth == 16) && (!armIs16ByteAligned(pSrcOrgY)), OMX_Sts_BadArgErr); |
| armRetArgErrIf((iBlockWidth == 4) && (!armIs4ByteAligned(pSrcRefY)), OMX_Sts_BadArgErr); |
| armRetArgErrIf((iBlockWidth == 8) && (!armIs8ByteAligned(pSrcRefY)), OMX_Sts_BadArgErr); |
| armRetArgErrIf((iBlockWidth == 16) && (!armIs16ByteAligned(pSrcRefY)), OMX_Sts_BadArgErr); |
| armRetArgErrIf(pSrcOrgY == NULL, OMX_Sts_BadArgErr); |
| armRetArgErrIf(pSrcRefY == NULL, OMX_Sts_BadArgErr); |
| armRetArgErrIf(pMVPred == NULL, OMX_Sts_BadArgErr); |
| armRetArgErrIf(pMVCandidate == NULL, OMX_Sts_BadArgErr); |
| armRetArgErrIf(pBestMV == NULL, OMX_Sts_BadArgErr); |
| armRetArgErrIf(pBestCost == NULL, OMX_Sts_BadArgErr); |
| armRetArgErrIf(((iBlockWidth!=4)&&(iBlockWidth!=8)&&(iBlockWidth!=16)) , OMX_Sts_BadArgErr); |
| armRetArgErrIf(((iBlockHeight!=4)&&(iBlockHeight!=8)&&(iBlockHeight!=16)) , OMX_Sts_BadArgErr); |
| armIgnore (pMESpec); |
| |
| if(iBlockWidth == 4) |
| { |
| nSearchRange = armMESpec->MEParams.searchRange4x4; |
| } |
| else if(iBlockWidth == 8) |
| { |
| nSearchRange = armMESpec->MEParams.searchRange8x8; |
| } |
| else |
| { |
| nSearchRange = armMESpec->MEParams.searchRange16x16; |
| } |
| /* Check for valid region */ |
| fromX = nSearchRange; |
| toX = nSearchRange; |
| fromY = nSearchRange; |
| toY = nSearchRange; |
| |
| if ((pCurrPointPos->x - nSearchRange) < pRefRect->x) |
| { |
| fromX = pCurrPointPos->x - pRefRect->x; |
| } |
| |
| if ((pCurrPointPos->x + iBlockWidth + nSearchRange) > (pRefRect->x + pRefRect->width)) |
| { |
| toX = pRefRect->width - (pCurrPointPos->x - pRefRect->x) - iBlockWidth; |
| } |
| |
| if ((pCurrPointPos->y - nSearchRange) < pRefRect->y) |
| { |
| fromY = pCurrPointPos->y - pRefRect->y; |
| } |
| |
| if ((pCurrPointPos->y + iBlockWidth + nSearchRange) > (pRefRect->y + pRefRect->height)) |
| { |
| toY = pRefRect->width - (pCurrPointPos->y - pRefRect->y) - iBlockWidth; |
| } |
| |
| pBestMV->dx = -fromX * 4; |
| pBestMV->dy = -fromY * 4; |
| /* Initialize to max value as a start point */ |
| *pBestCost = 0x7fffffff; |
| |
| /* Looping on y- axis */ |
| for (y = -fromY; y <= toY; y++) |
| { |
| /* Looping on x- axis */ |
| for (x = -fromX; x <= toX; x++) |
| { |
| /* Positioning the pointer */ |
| pTempSrcRefY = pSrcRefY + (nSrcRefStep * y) + x; |
| pTempSrcOrgY = pSrcOrgY; |
| |
| /* Calculate the SAD */ |
| armVCCOMM_SAD( |
| pTempSrcOrgY, |
| nSrcOrgStep, |
| pTempSrcRefY, |
| nSrcRefStep, |
| &candSAD, |
| iBlockHeight, |
| iBlockWidth); |
| |
| diffMV.dx = (x * 4) - pMVPred->dx; |
| diffMV.dy = (y * 4) - pMVPred->dy; |
| |
| /* Result calculations */ |
| armVCM4P10_CompareMotionCostToMV ((x * 4), (y * 4), diffMV, candSAD, pBestMV, nLamda, pBestCost); |
| |
| } /* End of x- axis */ |
| } /* End of y-axis */ |
| |
| return OMX_Sts_NoErr; |
| |
| } |
| |
| /* End of file */ |