omxVCM4P10_BlockMatch_Half.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_Half.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 half 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_Half   (6.3.5.2.2)
42 *
43 * Description:
44 * Performs a half-pel block match using results from a prior integer search.
45 *  Returns the best MV and associated cost.  This function estimates the
46 * half-pixel motion vector by interpolating the integer resolution motion
47 * vector referenced by the input parameter pSrcDstBestMV, i.e., the initial
48 * integer MV is generated externally.  The function
49 * omxVCM4P10_BlockMatch_Integer may be used for integer 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 integer search,
73 *            represented in terms of 1/4-pel units
74 *
75 * Output Arguments:
76 *
77 *   pSrcDstBestMV - Best MV resulting from the half-pel search, expressed in
78 *            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 *    -    any of the following pointers is NULL: pSrcOrgY, pSrcRefY,
86 *              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_Half(
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, integerMV;
112    OMX_U8      interpolY[256];
113
114    /* Argument error checks */
115    armRetArgErrIf((iBlockWidth ==  4) && (!armIs4ByteAligned(pSrcOrgY)), OMX_Sts_BadArgErr);
116    armRetArgErrIf((iBlockWidth ==  8) && (!armIs8ByteAligned(pSrcOrgY)), OMX_Sts_BadArgErr);
117    armRetArgErrIf((iBlockWidth == 16) && (!armIs16ByteAligned(pSrcOrgY)), OMX_Sts_BadArgErr);
118	armRetArgErrIf((iBlockWidth ==  4) && (!armIs4ByteAligned(pSrcRefY)), OMX_Sts_BadArgErr);
119    armRetArgErrIf((iBlockWidth ==  8) && (!armIs8ByteAligned(pSrcRefY)), OMX_Sts_BadArgErr);
120    armRetArgErrIf((iBlockWidth == 16) && (!armIs16ByteAligned(pSrcRefY)), OMX_Sts_BadArgErr);
121    armRetArgErrIf((nSrcOrgStep % iBlockWidth), OMX_Sts_BadArgErr);
122    armRetArgErrIf(pSrcOrgY == NULL, OMX_Sts_BadArgErr);
123    armRetArgErrIf(pSrcRefY == NULL, OMX_Sts_BadArgErr);
124    armRetArgErrIf(pMVPred == NULL, OMX_Sts_BadArgErr);
125    armRetArgErrIf(pSrcDstBestMV == NULL, OMX_Sts_BadArgErr);
126    armRetArgErrIf(pBestCost == NULL, OMX_Sts_BadArgErr);
127	armRetArgErrIf(((iBlockWidth!=4)&&(iBlockWidth!=8)&&(iBlockWidth!=16)) , OMX_Sts_BadArgErr);
128	armRetArgErrIf(((iBlockHeight!=4)&&(iBlockHeight!=8)&&(iBlockHeight!=16)) , OMX_Sts_BadArgErr);
129
130
131    /* Check for valid region */
132    fromX = 1;
133    toX   = 1;
134    fromY = 1;
135    toY   = 1;
136
137    /* Initialize to max value as a start point */
138    *pBestCost = 0x7fffffff;
139
140    integerMV.dx = pSrcDstBestMV->dx;
141    integerMV.dy = pSrcDstBestMV->dy;
142
143    /* Looping on y- axis */
144    for (y = -fromY; y <= toY; y++)
145    {
146        /* Looping on x- axis */
147        for (x = -fromX; x <= toX; x++)
148        {
149            /* Positioning the pointer */
150            pTempSrcRefY = pSrcRefY + (nSrcRefStep * (integerMV.dy/4)) + (integerMV.dx/4);
151            if (x < 0)
152            {
153                pTempSrcRefY = pTempSrcRefY + x;
154            }
155            if (y < 0)
156            {
157                pTempSrcRefY = pTempSrcRefY + (y * nSrcRefStep);
158            }
159            pTempSrcOrgY = pSrcOrgY;
160
161            /* Prepare cand MV */
162            candMV.dx = integerMV.dx + x * 2;
163            candMV.dy = integerMV.dy + y * 2;
164
165            /* Interpolate half pel for the current position*/
166            armVCM4P10_Interpolate_Luma(
167                        pTempSrcRefY,
168                        nSrcRefStep,
169                        interpolY,
170                        iBlockWidth,
171                        iBlockWidth,
172                        iBlockHeight,
173                        armAbs(x) * 2,
174                        armAbs(y) * 2);
175
176            /* Calculate the SAD */
177            armVCCOMM_SAD(
178                        pTempSrcOrgY,
179                        nSrcOrgStep,
180                        interpolY,
181                        iBlockWidth,
182                        &candSAD,
183                        iBlockHeight,
184                        iBlockWidth);
185
186            diffMV.dx = candMV.dx - pMVPred->dx;
187            diffMV.dy = candMV.dy - pMVPred->dy;
188
189            /* Result calculations */
190            armVCM4P10_CompareMotionCostToMV (
191                        candMV.dx,
192                        candMV.dy,
193                        diffMV,
194                        candSAD,
195                        pSrcDstBestMV,
196                        nLamda,
197                        pBestCost);
198
199        } /* End of x- axis */
200    } /* End of y-axis */
201
202    return OMX_Sts_NoErr;
203
204}
205
206/* End of file */
207