armVCM4P2_BlockMatch_Integer.c revision 78e52bfac041d71ce53b5b13c2abf78af742b09d
1/*
2 * Copyright (C) 2007-2008 ARM Limited
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 *
16 */
17/**
18 *
19 * File Name:  armVCM4P2_BlockMatch_Integer.c
20 * OpenMAX DL: v1.0.2
21 * Revision:   9641
22 * Date:       Thursday, February 7, 2008
23 *
24 *
25 *
26 *
27 * Description:
28 * Contains modules for Block matching, a full search algorithm
29 * is implemented
30 *
31 */
32
33#include "omxtypes.h"
34#include "armOMX.h"
35#include "omxVC.h"
36
37#include "armVC.h"
38#include "armCOMM.h"
39
40/**
41 * Function: armVCM4P2_BlockMatch_Integer
42 *
43 * Description:
44 * Performs a 16x16 block search; estimates motion vector and associated minimum SAD.
45 * Both the input and output motion vectors are represented using half-pixel units, and
46 * therefore a shift left or right by 1 bit may be required, respectively, to match the
47 * input or output MVs with other functions that either generate output MVs or expect
48 * input MVs represented using integer pixel units.
49 *
50 * Remarks:
51 *
52 * Parameters:
53 * [in]	pSrcRefBuf		pointer to the reference Y plane; points to the reference MB that
54 *                    corresponds to the location of the current macroblock in the current
55 *                    plane.
56 * [in]	refWidth		  width of the reference plane
57 * [in]	pRefRect		  pointer to the valid rectangular in reference plane. Relative to image origin.
58 *                    It's not limited to the image boundary, but depended on the padding. For example,
59 *                    if you pad 4 pixels outside the image border, then the value for left border
60 *                    can be -4
61 * [in]	pSrcCurrBuf		pointer to the current macroblock extracted from original plane (linear array,
62 *                    256 entries); must be aligned on an 8-byte boundary.
63 * [in] pCurrPointPos	position of the current macroblock in the current plane
64 * [in] pSrcPreMV		  pointer to predicted motion vector; NULL indicates no predicted MV
65 * [in] pSrcPreSAD		pointer to SAD associated with the predicted MV (referenced by pSrcPreMV)
66 * [in] searchRange		search range for 16X16 integer block,the units of it is full pixel,the search range
67 *                    is the same in all directions.It is in inclusive of the boundary and specified in
68 *                    terms of integer pixel units.
69 * [in] pMESpec			  vendor-specific motion estimation specification structure; must have been allocated
70 *                    and then initialized using omxVCM4P2_MEInit prior to calling the block matching
71 *                    function.
72 * [out]	pDstMV			pointer to estimated MV
73 * [out]	pDstSAD			pointer to minimum SAD
74 *
75 * Return Value:
76 * OMX_Sts_NoErr �C no error.
77 * OMX_Sts_BadArgErr �C bad arguments
78 *
79 */
80
81OMXResult armVCM4P2_BlockMatch_Integer(
82     const OMX_U8 *pSrcRefBuf,
83     OMX_INT refWidth,
84     const OMXRect *pRefRect,
85     const OMX_U8 *pSrcCurrBuf,
86     const OMXVCM4P2Coordinate *pCurrPointPos,
87     const OMXVCMotionVector *pSrcPreMV,
88     const OMX_INT *pSrcPreSAD,
89     void *pMESpec,
90     OMXVCMotionVector *pDstMV,
91     OMX_INT *pDstSAD,
92     OMX_U8 BlockSize
93)
94{
95
96    /* Definitions and Initializations*/
97
98    OMX_INT     outer, inner, count,index;
99    OMX_INT     candSAD;
100    /*(256*256 +1) this is to make the SAD max initially*/
101    OMX_INT     minSAD = 0x10001, fromX, toX, fromY, toY;
102    /* Offset to the reference at the begining of the bounding box */
103    const OMX_U8      *pTempSrcRefBuf;
104    OMX_S16     x, y;
105    OMX_INT searchRange;
106
107    /* Argument error checks */
108    armRetArgErrIf(pSrcRefBuf == NULL, OMX_Sts_BadArgErr);
109    armRetArgErrIf(pRefRect == NULL, OMX_Sts_BadArgErr);
110    armRetArgErrIf(pSrcCurrBuf == NULL, OMX_Sts_BadArgErr);
111    armRetArgErrIf(pCurrPointPos == NULL, OMX_Sts_BadArgErr);
112    armRetArgErrIf(pMESpec == NULL, OMX_Sts_BadArgErr);
113    armRetArgErrIf(pDstMV == NULL, OMX_Sts_BadArgErr);
114    armRetArgErrIf(pDstSAD == NULL, OMX_Sts_BadArgErr);
115
116    searchRange = ((OMXVCM4P2MEParams *)pMESpec)->searchRange;
117    /* Check for valid region */
118    fromX = searchRange;
119    toX   = searchRange;
120    fromY = searchRange;
121    toY   = searchRange;
122
123    if ((pCurrPointPos->x - searchRange) < pRefRect->x)
124    {
125        fromX =  pCurrPointPos->x - pRefRect->x;
126    }
127
128    if ((pCurrPointPos->x + BlockSize + searchRange) > (pRefRect->x + pRefRect->width))
129    {
130        toX   = pRefRect->width - (pCurrPointPos->x - pRefRect->x) - BlockSize;
131    }
132
133    if ((pCurrPointPos->y - searchRange) < pRefRect->y)
134    {
135        fromY = pCurrPointPos->y - pRefRect->y;
136    }
137
138    if ((pCurrPointPos->y + BlockSize + searchRange) > (pRefRect->y + pRefRect->height))
139    {
140        toY   = pRefRect->width - (pCurrPointPos->y - pRefRect->y) - BlockSize;
141    }
142
143    pDstMV->dx = -fromX;
144    pDstMV->dy = -fromY;
145    /* Looping on y- axis */
146    for (y = -fromY; y <= toY; y++)
147    {
148
149        /* Looping on x- axis */
150        for (x = -fromX; x <= toX; x++)
151        {
152            /* Positioning the pointer */
153            pTempSrcRefBuf = pSrcRefBuf + (refWidth * y) + x;
154
155            /* Calculate the SAD */
156            for (outer = 0, count = 0, index = 0, candSAD = 0;
157                 outer < BlockSize;
158                 outer++, index += refWidth - BlockSize)
159            {
160                for (inner = 0; inner < BlockSize; inner++, count++, index++)
161                {
162                    candSAD += armAbs (pTempSrcRefBuf[index] - pSrcCurrBuf[count]);
163                }
164            }
165
166            /* Result calculations */
167            if (armVCM4P2_CompareMV (x, y, candSAD, pDstMV->dx/2, pDstMV->dy/2, minSAD))
168            {
169                *pDstSAD = candSAD;
170                minSAD   = candSAD;
171                pDstMV->dx = x*2;
172                pDstMV->dy = y*2;
173            }
174
175        } /* End of x- axis */
176    } /* End of y-axis */
177
178    return OMX_Sts_NoErr;
179
180}
181
182/* End of file */
183