omxVCM4P10_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:  omxVCM4P10_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:  omxVCM4P10_BlockMatch_Integer   (6.3.5.2.1)
42 *
43 * Description:
44 * Performs integer block match.  Returns best MV and associated cost.
45 *
46 * Input Arguments:
47 *
48 *   pSrcOrgY - Pointer to the top-left corner of the current block. If
49 *            iBlockWidth==4,  4-byte alignment required. If iBlockWidth==8,
50 *            8-byte alignment required. If iBlockWidth==16, 16-byte alignment
51 *            required.
52 *   pSrcRefY - Pointer to the top-left corner of the co-located block in the
53 *            reference picture. If iBlockWidth==4,  4-byte alignment
54 *            required.  If iBlockWidth==8,  8-byte alignment required.  If
55 *            iBlockWidth==16, 16-byte alignment required.
56 *   nSrcOrgStep - Stride of the original picture plane, expressed in terms
57 *            of integer pixels; must be a multiple of iBlockWidth.
58 *   nSrcRefStep - Stride of the reference picture plane, expressed in terms
59 *            of integer pixels
60 *   pRefRect - pointer to the valid reference rectangle inside the reference
61 *            picture plane
62 *   nCurrPointPos - position of the current block in the current plane
63 *   iBlockWidth - Width of the current block, expressed in terms of integer
64 *            pixels; must be equal to either 4, 8, or 16.
65 *   iBlockHeight - Height of the current block, expressed in terms of
66 *            integer pixels; must be equal to either 4, 8, or 16.
67 *   nLamda - Lamda factor; used to compute motion cost
68 *   pMVPred - Predicted MV; used to compute motion cost, expressed in terms
69 *            of 1/4-pel units
70 *   pMVCandidate - Candidate MV; used to initialize the motion search,
71 *            expressed in terms of integer pixels
72 *   pMESpec - pointer to the ME specification structure
73 *
74 * Output Arguments:
75 *
76 *   pDstBestMV - Best MV resulting from integer search, expressed in terms
77 *            of 1/4-pel units
78 *   pBestCost - Motion cost associated with the best MV; computed as
79 *            SAD+Lamda*BitsUsedByMV
80 *
81 * Return Value:
82 *    OMX_Sts_NoErr, if the function runs without error.
83 *    OMX_Sts_BadArgErr - bad arguments: if one of the following cases occurs:
84 *    -    any of the following poitners are NULL:
85 *         pSrcOrgY, pSrcRefY, pRefRect, pMVPred, pMVCandidate, or pMESpec.
86 *    -    Either iBlockWidth or iBlockHeight are values other than 4, 8, or 16.
87 *    -    Any alignment restrictions are violated
88 *
89 */
90
91 OMXResult omxVCM4P10_BlockMatch_Integer (
92     const OMX_U8 *pSrcOrgY,
93     OMX_S32 nSrcOrgStep,
94     const OMX_U8 *pSrcRefY,
95     OMX_S32 nSrcRefStep,
96	 const OMXRect *pRefRect,
97	 const OMXVCM4P2Coordinate *pCurrPointPos,
98     OMX_U8 iBlockWidth,
99     OMX_U8 iBlockHeight,
100     OMX_U32 nLamda,
101     const OMXVCMotionVector *pMVPred,
102     const OMXVCMotionVector *pMVCandidate,
103     OMXVCMotionVector *pBestMV,
104     OMX_S32 *pBestCost,
105     void *pMESpec
106)
107{
108    /* Definitions and Initializations*/
109    OMX_INT candSAD;
110    OMX_INT fromX, toX, fromY, toY;
111    /* Offset to the reference at the begining of the bounding box */
112    const OMX_U8 *pTempSrcRefY, *pTempSrcOrgY;
113    OMX_S16 x, y;
114    OMXVCMotionVector diffMV;
115    OMX_S32 nSearchRange;
116    ARMVCM4P10_MESpec *armMESpec = (ARMVCM4P10_MESpec *) pMESpec;
117
118    /* Argument error checks */
119    armRetArgErrIf((iBlockWidth ==  4) && (!armIs4ByteAligned(pSrcOrgY)), OMX_Sts_BadArgErr);
120    armRetArgErrIf((iBlockWidth ==  8) && (!armIs8ByteAligned(pSrcOrgY)), OMX_Sts_BadArgErr);
121    armRetArgErrIf((iBlockWidth == 16) && (!armIs16ByteAligned(pSrcOrgY)), OMX_Sts_BadArgErr);
122	armRetArgErrIf((iBlockWidth ==  4) && (!armIs4ByteAligned(pSrcRefY)), OMX_Sts_BadArgErr);
123    armRetArgErrIf((iBlockWidth ==  8) && (!armIs8ByteAligned(pSrcRefY)), OMX_Sts_BadArgErr);
124    armRetArgErrIf((iBlockWidth == 16) && (!armIs16ByteAligned(pSrcRefY)), OMX_Sts_BadArgErr);
125    armRetArgErrIf(pSrcOrgY == NULL, OMX_Sts_BadArgErr);
126    armRetArgErrIf(pSrcRefY == NULL, OMX_Sts_BadArgErr);
127    armRetArgErrIf(pMVPred == NULL, OMX_Sts_BadArgErr);
128    armRetArgErrIf(pMVCandidate == NULL, OMX_Sts_BadArgErr);
129    armRetArgErrIf(pBestMV == NULL, OMX_Sts_BadArgErr);
130    armRetArgErrIf(pBestCost == NULL, OMX_Sts_BadArgErr);
131	armRetArgErrIf(((iBlockWidth!=4)&&(iBlockWidth!=8)&&(iBlockWidth!=16)) , OMX_Sts_BadArgErr);
132	armRetArgErrIf(((iBlockHeight!=4)&&(iBlockHeight!=8)&&(iBlockHeight!=16)) , OMX_Sts_BadArgErr);
133    armIgnore (pMESpec);
134
135    if(iBlockWidth == 4)
136    {
137        nSearchRange = armMESpec->MEParams.searchRange4x4;
138    }
139    else if(iBlockWidth == 8)
140    {
141        nSearchRange = armMESpec->MEParams.searchRange8x8;
142    }
143    else
144    {
145        nSearchRange = armMESpec->MEParams.searchRange16x16;
146    }
147    /* Check for valid region */
148    fromX = nSearchRange;
149    toX   = nSearchRange;
150    fromY = nSearchRange;
151    toY   = nSearchRange;
152
153    if ((pCurrPointPos->x - nSearchRange) < pRefRect->x)
154    {
155        fromX =  pCurrPointPos->x - pRefRect->x;
156    }
157
158    if ((pCurrPointPos->x + iBlockWidth + nSearchRange) > (pRefRect->x + pRefRect->width))
159    {
160        toX   = pRefRect->width - (pCurrPointPos->x - pRefRect->x) - iBlockWidth;
161    }
162
163    if ((pCurrPointPos->y - nSearchRange) < pRefRect->y)
164    {
165        fromY = pCurrPointPos->y - pRefRect->y;
166    }
167
168    if ((pCurrPointPos->y + iBlockWidth + nSearchRange) > (pRefRect->y + pRefRect->height))
169    {
170        toY   = pRefRect->width - (pCurrPointPos->y - pRefRect->y) - iBlockWidth;
171    }
172
173    pBestMV->dx = -fromX * 4;
174    pBestMV->dy = -fromY * 4;
175    /* Initialize to max value as a start point */
176    *pBestCost = 0x7fffffff;
177
178    /* Looping on y- axis */
179    for (y = -fromY; y <= toY; y++)
180    {
181        /* Looping on x- axis */
182        for (x = -fromX; x <= toX; x++)
183        {
184            /* Positioning the pointer */
185            pTempSrcRefY = pSrcRefY + (nSrcRefStep * y) + x;
186            pTempSrcOrgY = pSrcOrgY;
187
188            /* Calculate the SAD */
189            armVCCOMM_SAD(
190    	        pTempSrcOrgY,
191    	        nSrcOrgStep,
192    	        pTempSrcRefY,
193    	        nSrcRefStep,
194    	        &candSAD,
195    	        iBlockHeight,
196    	        iBlockWidth);
197
198            diffMV.dx = (x * 4) - pMVPred->dx;
199            diffMV.dy = (y * 4) - pMVPred->dy;
200
201            /* Result calculations */
202            armVCM4P10_CompareMotionCostToMV ((x * 4), (y * 4), diffMV, candSAD, pBestMV, nLamda, pBestCost);
203
204        } /* End of x- axis */
205    } /* End of y-axis */
206
207    return OMX_Sts_NoErr;
208
209}
210
211/* End of file */
212