1bebc99d6fa433c04139294a5057f8439d772dbd9James Dong/**
2bebc99d6fa433c04139294a5057f8439d772dbd9James Dong *
3bebc99d6fa433c04139294a5057f8439d772dbd9James Dong * File Name:  armVCM4P2_BlockMatch_Half.c
4bebc99d6fa433c04139294a5057f8439d772dbd9James Dong * OpenMAX DL: v1.0.2
5bebc99d6fa433c04139294a5057f8439d772dbd9James Dong * Revision:   9641
6bebc99d6fa433c04139294a5057f8439d772dbd9James Dong * Date:       Thursday, February 7, 2008
7bebc99d6fa433c04139294a5057f8439d772dbd9James Dong *
8bebc99d6fa433c04139294a5057f8439d772dbd9James Dong * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
9bebc99d6fa433c04139294a5057f8439d772dbd9James Dong *
10bebc99d6fa433c04139294a5057f8439d772dbd9James Dong *
11bebc99d6fa433c04139294a5057f8439d772dbd9James Dong *
12bebc99d6fa433c04139294a5057f8439d772dbd9James Dong * Description:
13bebc99d6fa433c04139294a5057f8439d772dbd9James Dong * Contains modules for Block matching, a full search algorithm
14bebc99d6fa433c04139294a5057f8439d772dbd9James Dong * is implemented
15bebc99d6fa433c04139294a5057f8439d772dbd9James Dong *
16bebc99d6fa433c04139294a5057f8439d772dbd9James Dong */
17bebc99d6fa433c04139294a5057f8439d772dbd9James Dong
18bebc99d6fa433c04139294a5057f8439d772dbd9James Dong#include "omxtypes.h"
19bebc99d6fa433c04139294a5057f8439d772dbd9James Dong#include "armOMX.h"
20bebc99d6fa433c04139294a5057f8439d772dbd9James Dong#include "omxVC.h"
21bebc99d6fa433c04139294a5057f8439d772dbd9James Dong
22bebc99d6fa433c04139294a5057f8439d772dbd9James Dong#include "armVC.h"
23bebc99d6fa433c04139294a5057f8439d772dbd9James Dong#include "armCOMM.h"
24bebc99d6fa433c04139294a5057f8439d772dbd9James Dong
25bebc99d6fa433c04139294a5057f8439d772dbd9James Dong/**
26bebc99d6fa433c04139294a5057f8439d772dbd9James Dong * Function: armVCM4P2_BlockMatch_Half
27bebc99d6fa433c04139294a5057f8439d772dbd9James Dong *
28bebc99d6fa433c04139294a5057f8439d772dbd9James Dong * Description:
29bebc99d6fa433c04139294a5057f8439d772dbd9James Dong * Performs a 16x16 block match with half-pixel resolution.  Returns the estimated
30bebc99d6fa433c04139294a5057f8439d772dbd9James Dong * motion vector and associated minimum SAD.  This function estimates the half-pixel
31bebc99d6fa433c04139294a5057f8439d772dbd9James Dong * motion vector by interpolating the integer resolution motion vector referenced
32bebc99d6fa433c04139294a5057f8439d772dbd9James Dong * by the input parameter pSrcDstMV, i.e., the initial integer MV is generated
33bebc99d6fa433c04139294a5057f8439d772dbd9James Dong * externally.  The input parameters pSrcRefBuf and pSearchPointRefPos should be
34bebc99d6fa433c04139294a5057f8439d772dbd9James Dong * shifted by the winning MV of 16x16 integer search prior to calling BlockMatch_Half_16x16.
35bebc99d6fa433c04139294a5057f8439d772dbd9James Dong * The function BlockMatch_Integer_16x16 may be used for integer motion estimation.
36bebc99d6fa433c04139294a5057f8439d772dbd9James Dong *
37bebc99d6fa433c04139294a5057f8439d772dbd9James Dong * Remarks:
38bebc99d6fa433c04139294a5057f8439d772dbd9James Dong *
39bebc99d6fa433c04139294a5057f8439d772dbd9James Dong * Parameters:
40bebc99d6fa433c04139294a5057f8439d772dbd9James Dong * [in]	pSrcRefBuf		pointer to the reference Y plane; points to the reference MB
41bebc99d6fa433c04139294a5057f8439d772dbd9James Dong *                    that corresponds to the location of the current macroblock in
42bebc99d6fa433c04139294a5057f8439d772dbd9James Dong *                    the	current plane.
43bebc99d6fa433c04139294a5057f8439d772dbd9James Dong * [in]	refWidth		  width of the reference plane
44bebc99d6fa433c04139294a5057f8439d772dbd9James Dong * [in]	pRefRect		  reference plane valid region rectangle
45bebc99d6fa433c04139294a5057f8439d772dbd9James Dong * [in]	pSrcCurrBuf		pointer to the current macroblock extracted from original plane
46bebc99d6fa433c04139294a5057f8439d772dbd9James Dong *                    (linear array, 256 entries); must be aligned on an 8-byte boundary.
47bebc99d6fa433c04139294a5057f8439d772dbd9James Dong * [in]	pSearchPointRefPos	position of the starting point for half pixel search (specified
48bebc99d6fa433c04139294a5057f8439d772dbd9James Dong *                          in terms of integer pixel units) in the reference plane.
49bebc99d6fa433c04139294a5057f8439d772dbd9James Dong * [in]	rndVal			  rounding control bit for half pixel motion estimation;
50bebc99d6fa433c04139294a5057f8439d772dbd9James Dong *                    0=rounding control disabled; 1=rounding control enabled
51bebc99d6fa433c04139294a5057f8439d772dbd9James Dong * [in]	pSrcDstMV		pointer to the initial MV estimate; typically generated during a prior
52bebc99d6fa433c04139294a5057f8439d772dbd9James Dong *                  16X16 integer search and its unit is half pixel.
53bebc99d6fa433c04139294a5057f8439d772dbd9James Dong * [in] BlockSize     MacroBlock Size i.e either 16x16 or 8x8.
54bebc99d6fa433c04139294a5057f8439d772dbd9James Dong * [out]pSrcDstMV		pointer to estimated MV
55bebc99d6fa433c04139294a5057f8439d772dbd9James Dong * [out]pDstSAD			pointer to minimum SAD
56bebc99d6fa433c04139294a5057f8439d772dbd9James Dong *
57bebc99d6fa433c04139294a5057f8439d772dbd9James Dong * Return Value:
58bebc99d6fa433c04139294a5057f8439d772dbd9James Dong * OMX_Sts_NoErr �C no error
59bebc99d6fa433c04139294a5057f8439d772dbd9James Dong * OMX_Sts_BadArgErr �C bad arguments
60bebc99d6fa433c04139294a5057f8439d772dbd9James Dong *
61bebc99d6fa433c04139294a5057f8439d772dbd9James Dong */
62bebc99d6fa433c04139294a5057f8439d772dbd9James Dong
63bebc99d6fa433c04139294a5057f8439d772dbd9James DongOMXResult armVCM4P2_BlockMatch_Half(
64bebc99d6fa433c04139294a5057f8439d772dbd9James Dong     const OMX_U8 *pSrcRefBuf,
65bebc99d6fa433c04139294a5057f8439d772dbd9James Dong     OMX_INT refWidth,
66bebc99d6fa433c04139294a5057f8439d772dbd9James Dong     const OMXRect *pRefRect,
67bebc99d6fa433c04139294a5057f8439d772dbd9James Dong     const OMX_U8 *pSrcCurrBuf,
68bebc99d6fa433c04139294a5057f8439d772dbd9James Dong     const OMXVCM4P2Coordinate *pSearchPointRefPos,
69bebc99d6fa433c04139294a5057f8439d772dbd9James Dong     OMX_INT rndVal,
70bebc99d6fa433c04139294a5057f8439d772dbd9James Dong     OMXVCMotionVector *pSrcDstMV,
71bebc99d6fa433c04139294a5057f8439d772dbd9James Dong     OMX_INT *pDstSAD,
72bebc99d6fa433c04139294a5057f8439d772dbd9James Dong     OMX_U8 BlockSize
73bebc99d6fa433c04139294a5057f8439d772dbd9James Dong)
74bebc99d6fa433c04139294a5057f8439d772dbd9James Dong{
75bebc99d6fa433c04139294a5057f8439d772dbd9James Dong    OMX_INT     outer, inner, count, index;
76bebc99d6fa433c04139294a5057f8439d772dbd9James Dong    OMX_S16     halfPelX = 0, halfPelY = 0, x, y;
77bebc99d6fa433c04139294a5057f8439d772dbd9James Dong    OMX_INT     candSAD, refSAD = 0;
78bebc99d6fa433c04139294a5057f8439d772dbd9James Dong    OMX_INT     minSAD, fromX, toX, fromY, toY;
79bebc99d6fa433c04139294a5057f8439d772dbd9James Dong    /* Offset to the reference at the begining of the bounding box */
80bebc99d6fa433c04139294a5057f8439d772dbd9James Dong    const OMX_U8      *pTempSrcRefBuf;
81bebc99d6fa433c04139294a5057f8439d772dbd9James Dong    OMX_U8 tempPel;
82bebc99d6fa433c04139294a5057f8439d772dbd9James Dong
83bebc99d6fa433c04139294a5057f8439d772dbd9James Dong    /* Argument error checks */
84bebc99d6fa433c04139294a5057f8439d772dbd9James Dong    armRetArgErrIf(pSrcRefBuf == NULL, OMX_Sts_BadArgErr);
85bebc99d6fa433c04139294a5057f8439d772dbd9James Dong    armRetArgErrIf(pRefRect == NULL, OMX_Sts_BadArgErr);
86bebc99d6fa433c04139294a5057f8439d772dbd9James Dong    armRetArgErrIf(pSrcCurrBuf == NULL, OMX_Sts_BadArgErr);
87bebc99d6fa433c04139294a5057f8439d772dbd9James Dong    armRetArgErrIf(pSearchPointRefPos == NULL, OMX_Sts_BadArgErr);
88bebc99d6fa433c04139294a5057f8439d772dbd9James Dong    armRetArgErrIf(pSrcDstMV == NULL, OMX_Sts_BadArgErr);
89bebc99d6fa433c04139294a5057f8439d772dbd9James Dong    armRetArgErrIf(pDstSAD == NULL, OMX_Sts_BadArgErr);
90bebc99d6fa433c04139294a5057f8439d772dbd9James Dong
91bebc99d6fa433c04139294a5057f8439d772dbd9James Dong    /* Positioning the pointer */
92bebc99d6fa433c04139294a5057f8439d772dbd9James Dong    pTempSrcRefBuf = pSrcRefBuf + (refWidth * (pSrcDstMV->dy/2)) + (pSrcDstMV->dx/2);
93bebc99d6fa433c04139294a5057f8439d772dbd9James Dong
94bebc99d6fa433c04139294a5057f8439d772dbd9James Dong    /* Copy the candidate to the temporary linear array */
95bebc99d6fa433c04139294a5057f8439d772dbd9James Dong    for (outer = 0, count = 0,index = 0;
96bebc99d6fa433c04139294a5057f8439d772dbd9James Dong         outer < BlockSize;
97bebc99d6fa433c04139294a5057f8439d772dbd9James Dong         outer++, index += refWidth - BlockSize)
98bebc99d6fa433c04139294a5057f8439d772dbd9James Dong    {
99bebc99d6fa433c04139294a5057f8439d772dbd9James Dong        for (inner = 0; inner < BlockSize; inner++, count++, index++)
100bebc99d6fa433c04139294a5057f8439d772dbd9James Dong        {
101bebc99d6fa433c04139294a5057f8439d772dbd9James Dong            refSAD += armAbs (pTempSrcRefBuf[index] - pSrcCurrBuf[count]);
102bebc99d6fa433c04139294a5057f8439d772dbd9James Dong        }
103bebc99d6fa433c04139294a5057f8439d772dbd9James Dong    }
104bebc99d6fa433c04139294a5057f8439d772dbd9James Dong
105bebc99d6fa433c04139294a5057f8439d772dbd9James Dong    /* Set the minSad as reference SAD */
106bebc99d6fa433c04139294a5057f8439d772dbd9James Dong    minSAD = refSAD;
107bebc99d6fa433c04139294a5057f8439d772dbd9James Dong    *pDstSAD = refSAD;
108bebc99d6fa433c04139294a5057f8439d772dbd9James Dong
109bebc99d6fa433c04139294a5057f8439d772dbd9James Dong    /* Check for valid region */
110bebc99d6fa433c04139294a5057f8439d772dbd9James Dong    fromX = 1;
111bebc99d6fa433c04139294a5057f8439d772dbd9James Dong    toX   = 1;
112bebc99d6fa433c04139294a5057f8439d772dbd9James Dong    fromY = 1;
113bebc99d6fa433c04139294a5057f8439d772dbd9James Dong    toY   = 1;
114bebc99d6fa433c04139294a5057f8439d772dbd9James Dong    if ((pSearchPointRefPos->x - 1) < pRefRect->x)
115bebc99d6fa433c04139294a5057f8439d772dbd9James Dong    {
116bebc99d6fa433c04139294a5057f8439d772dbd9James Dong        fromX = 0;
117bebc99d6fa433c04139294a5057f8439d772dbd9James Dong    }
118bebc99d6fa433c04139294a5057f8439d772dbd9James Dong
119bebc99d6fa433c04139294a5057f8439d772dbd9James Dong    if ((pSearchPointRefPos->x + BlockSize + 1) > (pRefRect->x + pRefRect->width))
120bebc99d6fa433c04139294a5057f8439d772dbd9James Dong    {
121bebc99d6fa433c04139294a5057f8439d772dbd9James Dong        toX   = 0;
122bebc99d6fa433c04139294a5057f8439d772dbd9James Dong    }
123bebc99d6fa433c04139294a5057f8439d772dbd9James Dong
124bebc99d6fa433c04139294a5057f8439d772dbd9James Dong    if ((pSearchPointRefPos->y - 1) < pRefRect->y)
125bebc99d6fa433c04139294a5057f8439d772dbd9James Dong    {
126bebc99d6fa433c04139294a5057f8439d772dbd9James Dong        fromY = 0;
127bebc99d6fa433c04139294a5057f8439d772dbd9James Dong    }
128bebc99d6fa433c04139294a5057f8439d772dbd9James Dong
129bebc99d6fa433c04139294a5057f8439d772dbd9James Dong    if ((pSearchPointRefPos->y + BlockSize + 1) > (pRefRect->y + pRefRect->height))
130bebc99d6fa433c04139294a5057f8439d772dbd9James Dong    {
131bebc99d6fa433c04139294a5057f8439d772dbd9James Dong        toY   = 0;
132bebc99d6fa433c04139294a5057f8439d772dbd9James Dong    }
133bebc99d6fa433c04139294a5057f8439d772dbd9James Dong
134bebc99d6fa433c04139294a5057f8439d772dbd9James Dong    /* Looping on y- axis */
135bebc99d6fa433c04139294a5057f8439d772dbd9James Dong    for (y = -fromY; y <= toY; y++)
136bebc99d6fa433c04139294a5057f8439d772dbd9James Dong    {
137bebc99d6fa433c04139294a5057f8439d772dbd9James Dong        /* Looping on x- axis */
138bebc99d6fa433c04139294a5057f8439d772dbd9James Dong        for (x = -fromX; x <= toX; x++)
139bebc99d6fa433c04139294a5057f8439d772dbd9James Dong        {
140bebc99d6fa433c04139294a5057f8439d772dbd9James Dong            /* check for integer position */
141bebc99d6fa433c04139294a5057f8439d772dbd9James Dong            if ( x == 0 && y == 0)
142bebc99d6fa433c04139294a5057f8439d772dbd9James Dong            {
143bebc99d6fa433c04139294a5057f8439d772dbd9James Dong                continue;
144bebc99d6fa433c04139294a5057f8439d772dbd9James Dong            }
145bebc99d6fa433c04139294a5057f8439d772dbd9James Dong            /* Positioning the pointer */
146bebc99d6fa433c04139294a5057f8439d772dbd9James Dong            pTempSrcRefBuf = pSrcRefBuf + (refWidth * (pSrcDstMV->dy/2))
147bebc99d6fa433c04139294a5057f8439d772dbd9James Dong                             + (pSrcDstMV->dx/2);
148bebc99d6fa433c04139294a5057f8439d772dbd9James Dong
149bebc99d6fa433c04139294a5057f8439d772dbd9James Dong            /* Interpolate the pixel and calculate the SAD*/
150bebc99d6fa433c04139294a5057f8439d772dbd9James Dong            for (outer = 0, count = 0, candSAD = 0,index = 0;
151bebc99d6fa433c04139294a5057f8439d772dbd9James Dong                 outer < BlockSize;
152bebc99d6fa433c04139294a5057f8439d772dbd9James Dong                 outer++, index += refWidth - BlockSize)
153bebc99d6fa433c04139294a5057f8439d772dbd9James Dong            {
154bebc99d6fa433c04139294a5057f8439d772dbd9James Dong                for (inner = 0; inner < BlockSize; inner++, count++,index++)
155bebc99d6fa433c04139294a5057f8439d772dbd9James Dong                {
156bebc99d6fa433c04139294a5057f8439d772dbd9James Dong                    tempPel = (
157bebc99d6fa433c04139294a5057f8439d772dbd9James Dong                                pTempSrcRefBuf[index]
158bebc99d6fa433c04139294a5057f8439d772dbd9James Dong                                + pTempSrcRefBuf[index + x] * armAbs(x)
159bebc99d6fa433c04139294a5057f8439d772dbd9James Dong                                + pTempSrcRefBuf[index + refWidth * y] * armAbs(y)
160bebc99d6fa433c04139294a5057f8439d772dbd9James Dong                                + pTempSrcRefBuf[index + refWidth * y + x]
161bebc99d6fa433c04139294a5057f8439d772dbd9James Dong                                  * armAbs(x*y)
162bebc99d6fa433c04139294a5057f8439d772dbd9James Dong                                + armAbs (x) + armAbs (y) - rndVal
163bebc99d6fa433c04139294a5057f8439d772dbd9James Dong                              ) / (2 * (armAbs (x) + armAbs (y)));
164bebc99d6fa433c04139294a5057f8439d772dbd9James Dong                    candSAD += armAbs (tempPel - pSrcCurrBuf[count]);
165bebc99d6fa433c04139294a5057f8439d772dbd9James Dong                }
166bebc99d6fa433c04139294a5057f8439d772dbd9James Dong            }
167bebc99d6fa433c04139294a5057f8439d772dbd9James Dong
168bebc99d6fa433c04139294a5057f8439d772dbd9James Dong            /* Result calculations */
169bebc99d6fa433c04139294a5057f8439d772dbd9James Dong            if (armVCM4P2_CompareMV (x, y, candSAD, halfPelX, halfPelY, minSAD))
170bebc99d6fa433c04139294a5057f8439d772dbd9James Dong            {
171bebc99d6fa433c04139294a5057f8439d772dbd9James Dong                *pDstSAD = candSAD;
172bebc99d6fa433c04139294a5057f8439d772dbd9James Dong                minSAD   = candSAD;
173bebc99d6fa433c04139294a5057f8439d772dbd9James Dong                halfPelX = x;
174bebc99d6fa433c04139294a5057f8439d772dbd9James Dong                halfPelY = y;
175bebc99d6fa433c04139294a5057f8439d772dbd9James Dong            }
176bebc99d6fa433c04139294a5057f8439d772dbd9James Dong
177bebc99d6fa433c04139294a5057f8439d772dbd9James Dong        } /* End of x- axis */
178bebc99d6fa433c04139294a5057f8439d772dbd9James Dong    } /* End of y-axis */
179bebc99d6fa433c04139294a5057f8439d772dbd9James Dong
180bebc99d6fa433c04139294a5057f8439d772dbd9James Dong    pSrcDstMV->dx += halfPelX;
181bebc99d6fa433c04139294a5057f8439d772dbd9James Dong    pSrcDstMV->dy += halfPelY;
182bebc99d6fa433c04139294a5057f8439d772dbd9James Dong
183bebc99d6fa433c04139294a5057f8439d772dbd9James Dong    return OMX_Sts_NoErr;
184bebc99d6fa433c04139294a5057f8439d772dbd9James Dong
185bebc99d6fa433c04139294a5057f8439d772dbd9James Dong}
186bebc99d6fa433c04139294a5057f8439d772dbd9James Dong
187bebc99d6fa433c04139294a5057f8439d772dbd9James Dong/* End of file */
188