| /* |
| * 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: armVCM4P2_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: armVCM4P2_BlockMatch_Integer |
| * |
| * Description: |
| * Performs a 16x16 block search; estimates motion vector and associated minimum SAD. |
| * Both the input and output motion vectors are represented using half-pixel units, and |
| * therefore a shift left or right by 1 bit may be required, respectively, to match the |
| * input or output MVs with other functions that either generate output MVs or expect |
| * input MVs represented using integer pixel units. |
| * |
| * 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] refWidth 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 8-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) |
| * [in] searchRange search range for 16X16 integer block,the units of it is full pixel,the search range |
| * is the same in all directions.It is in inclusive of the boundary and specified in |
| * terms of integer pixel units. |
| * [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 ¨C no error. |
| * OMX_Sts_BadArgErr ¨C bad arguments |
| * |
| */ |
| |
| OMXResult armVCM4P2_BlockMatch_Integer( |
| const OMX_U8 *pSrcRefBuf, |
| OMX_INT refWidth, |
| const OMXRect *pRefRect, |
| const OMX_U8 *pSrcCurrBuf, |
| const OMXVCM4P2Coordinate *pCurrPointPos, |
| const OMXVCMotionVector *pSrcPreMV, |
| const OMX_INT *pSrcPreSAD, |
| void *pMESpec, |
| OMXVCMotionVector *pDstMV, |
| OMX_INT *pDstSAD, |
| OMX_U8 BlockSize |
| ) |
| { |
| |
| /* Definitions and Initializations*/ |
| |
| OMX_INT outer, inner, count,index; |
| OMX_INT candSAD; |
| /*(256*256 +1) this is to make the SAD max initially*/ |
| OMX_INT minSAD = 0x10001, fromX, toX, fromY, toY; |
| /* Offset to the reference at the begining of the bounding box */ |
| const OMX_U8 *pTempSrcRefBuf; |
| OMX_S16 x, y; |
| OMX_INT searchRange; |
| |
| /* Argument error checks */ |
| armRetArgErrIf(pSrcRefBuf == NULL, OMX_Sts_BadArgErr); |
| armRetArgErrIf(pRefRect == NULL, OMX_Sts_BadArgErr); |
| armRetArgErrIf(pSrcCurrBuf == NULL, OMX_Sts_BadArgErr); |
| armRetArgErrIf(pCurrPointPos == NULL, OMX_Sts_BadArgErr); |
| armRetArgErrIf(pMESpec == NULL, OMX_Sts_BadArgErr); |
| armRetArgErrIf(pDstMV == NULL, OMX_Sts_BadArgErr); |
| armRetArgErrIf(pDstSAD == NULL, OMX_Sts_BadArgErr); |
| |
| searchRange = ((OMXVCM4P2MEParams *)pMESpec)->searchRange; |
| /* Check for valid region */ |
| fromX = searchRange; |
| toX = searchRange; |
| fromY = searchRange; |
| toY = searchRange; |
| |
| if ((pCurrPointPos->x - searchRange) < pRefRect->x) |
| { |
| fromX = pCurrPointPos->x - pRefRect->x; |
| } |
| |
| if ((pCurrPointPos->x + BlockSize + searchRange) > (pRefRect->x + pRefRect->width)) |
| { |
| toX = pRefRect->width - (pCurrPointPos->x - pRefRect->x) - BlockSize; |
| } |
| |
| if ((pCurrPointPos->y - searchRange) < pRefRect->y) |
| { |
| fromY = pCurrPointPos->y - pRefRect->y; |
| } |
| |
| if ((pCurrPointPos->y + BlockSize + searchRange) > (pRefRect->y + pRefRect->height)) |
| { |
| toY = pRefRect->width - (pCurrPointPos->y - pRefRect->y) - BlockSize; |
| } |
| |
| pDstMV->dx = -fromX; |
| pDstMV->dy = -fromY; |
| /* Looping on y- axis */ |
| for (y = -fromY; y <= toY; y++) |
| { |
| |
| /* Looping on x- axis */ |
| for (x = -fromX; x <= toX; x++) |
| { |
| /* Positioning the pointer */ |
| pTempSrcRefBuf = pSrcRefBuf + (refWidth * y) + x; |
| |
| /* Calculate the SAD */ |
| for (outer = 0, count = 0, index = 0, candSAD = 0; |
| outer < BlockSize; |
| outer++, index += refWidth - BlockSize) |
| { |
| for (inner = 0; inner < BlockSize; inner++, count++, index++) |
| { |
| candSAD += armAbs (pTempSrcRefBuf[index] - pSrcCurrBuf[count]); |
| } |
| } |
| |
| /* Result calculations */ |
| if (armVCM4P2_CompareMV (x, y, candSAD, pDstMV->dx/2, pDstMV->dy/2, minSAD)) |
| { |
| *pDstSAD = candSAD; |
| minSAD = candSAD; |
| pDstMV->dx = x*2; |
| pDstMV->dy = y*2; |
| } |
| |
| } /* End of x- axis */ |
| } /* End of y-axis */ |
| |
| return OMX_Sts_NoErr; |
| |
| } |
| |
| /* End of file */ |