omxVCM4P10_BlockMatch_Quarter.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_Quarter.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 quater pel Block matching,
29 *
30 */
31
32#include "omxtypes.h"
33#include "armOMX.h"
34#include "omxVC.h"
35
36#include "armVC.h"
37#include "armCOMM.h"
38
39
40/**
41 * Function:  omxVCM4P10_BlockMatch_Quarter   (6.3.5.2.3)
42 *
43 * Description:
44 * Performs a quarter-pel block match using results from a prior half-pel
45 * search.  Returns the best MV and associated cost.  This function estimates
46 * the quarter-pixel motion vector by interpolating the half-pel resolution
47 * motion vector referenced by the input parameter pSrcDstBestMV, i.e., the
48 * initial half-pel MV is generated externally.  The function
49 * omxVCM4P10_BlockMatch_Half may be used for half-pel motion estimation.
50 *
51 * Input Arguments:
52 *
53 *   pSrcOrgY - Pointer to the current position in original picture plane. If
54 *            iBlockWidth==4,  4-byte alignment required. If iBlockWidth==8,
55 *            8-byte alignment required. If iBlockWidth==16, 16-byte alignment
56 *            required.
57 *   pSrcRefY - Pointer to the top-left corner of the co-located block in the
58 *            reference picture  If iBlockWidth==4,  4-byte alignment
59 *            required.  If iBlockWidth==8,  8-byte alignment required.  If
60 *            iBlockWidth==16, 16-byte alignment required.
61 *   nSrcOrgStep - Stride of the original picture plane in terms of full
62 *            pixels; must be a multiple of iBlockWidth.
63 *   nSrcRefStep - Stride of the reference picture plane in terms of full
64 *            pixels
65 *   iBlockWidth - Width of the current block in terms of full pixels; must
66 *            be equal to either 4, 8, or 16.
67 *   iBlockHeight - Height of the current block in terms of full pixels; must
68 *            be equal to either 4, 8, or 16.
69 *   nLamda - Lamda factor, used to compute motion cost
70 *   pMVPred - Predicted MV, represented in terms of 1/4-pel units; used to
71 *            compute motion cost
72 *   pSrcDstBestMV - The best MV resulting from a prior half-pel search,
73 *            represented in terms of 1/4 pel units
74 *
75 * Output Arguments:
76 *
77 *   pSrcDstBestMV - Best MV resulting from the quarter-pel search, expressed
78 *            in terms of 1/4-pel units
79 *   pBestCost - Motion cost associated with the best MV; computed as
80 *            SAD+Lamda*BitsUsedByMV
81 *
82 * Return Value:
83 *    OMX_Sts_NoErr, if the function runs without error.
84 *    OMX_Sts_BadArgErr - bad arguments: if one of the following cases occurs:
85 *    -    One of more of the following pointers is NULL:
86 *         pSrcOrgY, pSrcRefY, pSrcDstBestMV, pMVPred, pBestCost
87 *    -    iBlockWidth or iBlockHeight are equal to values other than 4, 8, or 16.
88 *    -    Any alignment restrictions are violated
89 *
90 */
91
92OMXResult omxVCM4P10_BlockMatch_Quarter(
93    const OMX_U8* pSrcOrgY,
94    OMX_S32 nSrcOrgStep,
95    const OMX_U8* pSrcRefY,
96    OMX_S32 nSrcRefStep,
97    OMX_U8 iBlockWidth,
98    OMX_U8 iBlockHeight,
99    OMX_U32 nLamda,
100    const OMXVCMotionVector* pMVPred,
101    OMXVCMotionVector* pSrcDstBestMV,
102    OMX_S32* pBestCost
103)
104{
105    /* Definitions and Initializations*/
106    OMX_INT     candSAD;
107    OMX_INT     fromX, toX, fromY, toY;
108    /* Offset to the reference at the begining of the bounding box */
109    const OMX_U8      *pTempSrcRefY, *pTempSrcOrgY;
110    OMX_S16     x, y;
111    OMXVCMotionVector diffMV, candMV, initialMV;
112    OMX_U8      interpolY[256];
113    OMX_S32     pelPosX, pelPosY;
114
115    /* Argument error checks */
116    armRetArgErrIf((iBlockWidth ==  4) && (!armIs4ByteAligned(pSrcOrgY)), OMX_Sts_BadArgErr);
117    armRetArgErrIf((iBlockWidth ==  8) && (!armIs8ByteAligned(pSrcOrgY)), OMX_Sts_BadArgErr);
118    armRetArgErrIf((iBlockWidth == 16) && (!armIs16ByteAligned(pSrcOrgY)), OMX_Sts_BadArgErr);
119	armRetArgErrIf((iBlockWidth ==  4) && (!armIs4ByteAligned(pSrcRefY)), OMX_Sts_BadArgErr);
120    armRetArgErrIf((iBlockWidth ==  8) && (!armIs8ByteAligned(pSrcRefY)), OMX_Sts_BadArgErr);
121    armRetArgErrIf((iBlockWidth == 16) && (!armIs16ByteAligned(pSrcRefY)), OMX_Sts_BadArgErr);
122    armRetArgErrIf((nSrcOrgStep % iBlockWidth), OMX_Sts_BadArgErr);
123    armRetArgErrIf(pSrcOrgY == NULL, OMX_Sts_BadArgErr);
124    armRetArgErrIf(pSrcRefY == NULL, OMX_Sts_BadArgErr);
125    armRetArgErrIf(pMVPred == NULL, OMX_Sts_BadArgErr);
126    armRetArgErrIf(pSrcDstBestMV == NULL, OMX_Sts_BadArgErr);
127    armRetArgErrIf(pBestCost == NULL, OMX_Sts_BadArgErr);
128	armRetArgErrIf(((iBlockWidth!=4)&&(iBlockWidth!=8)&&(iBlockWidth!=16)) , OMX_Sts_BadArgErr);
129	armRetArgErrIf(((iBlockHeight!=4)&&(iBlockHeight!=8)&&(iBlockHeight!=16)) , OMX_Sts_BadArgErr);
130
131
132    /* Check for valid region */
133    fromX = 1;
134    toX   = 1;
135    fromY = 1;
136    toY   = 1;
137
138    /* Initialize to max value as a start point */
139    *pBestCost = 0x7fffffff;
140
141    initialMV.dx = pSrcDstBestMV->dx;
142    initialMV.dy = pSrcDstBestMV->dy;
143
144    /* Looping on y- axis */
145    for (y = -fromY; y <= toY; y++)
146    {
147        /* Looping on x- axis */
148        for (x = -fromX; x <= toX; x++)
149        {
150            /* Positioning the pointer */
151            pTempSrcRefY = pSrcRefY + (nSrcRefStep * (initialMV.dy/4)) + (initialMV.dx/4);
152
153            /* Calculating the fract pel position */
154            pelPosX = (initialMV.dx % 4) + x;
155            if (pelPosX < 0)
156            {
157                pTempSrcRefY = pTempSrcRefY - 1;
158                pelPosX += 4;
159            }
160            pelPosY = (initialMV.dy % 4) + y;
161            if (pelPosY < 0)
162            {
163                pTempSrcRefY = pTempSrcRefY - (1 * nSrcRefStep);
164                pelPosY += 4;
165            }
166
167            pTempSrcOrgY = pSrcOrgY;
168
169            /* Prepare cand MV */
170            candMV.dx = initialMV.dx + x;
171            candMV.dy = initialMV.dy + y;
172
173            /* Interpolate Quater pel for the current position*/
174            armVCM4P10_Interpolate_Luma(
175                        pTempSrcRefY,
176                        nSrcRefStep,
177                        interpolY,
178                        iBlockWidth,
179                        iBlockWidth,
180                        iBlockHeight,
181                        pelPosX,
182                        pelPosY);
183
184            /* Calculate the SAD */
185            armVCCOMM_SAD(
186                        pTempSrcOrgY,
187                        nSrcOrgStep,
188                        interpolY,
189                        iBlockWidth,
190                        &candSAD,
191                        iBlockHeight,
192                        iBlockWidth);
193
194            diffMV.dx = candMV.dx - pMVPred->dx;
195            diffMV.dy = candMV.dy - pMVPred->dy;
196
197            /* Result calculations */
198            armVCM4P10_CompareMotionCostToMV (
199                        candMV.dx,
200                        candMV.dy,
201                        diffMV,
202                        candSAD,
203                        pSrcDstBestMV,
204                        nLamda,
205                        pBestCost);
206
207        } /* End of x- axis */
208    } /* End of y-axis */
209
210    return OMX_Sts_NoErr;
211
212}
213
214/* End of file */
215