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