omxVCM4P2_MCReconBlock.c revision 0c1bc742181ded4930842b46e9507372f0b1b963
1/**
2 *
3 * File Name:  omxVCM4P2_MCReconBlock.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 * Description:
12 * MPEG4 motion compensation prediction for an 8x8 block using
13 * interpolation
14 *
15 */
16
17#include "omxtypes.h"
18#include "armOMX.h"
19#include "omxVC.h"
20
21#include "armCOMM.h"
22
23/**
24 * Function: armVCM4P2_HalfPelVer
25 *
26 * Description:
27 * Performs half pel motion compensation for an 8x8 block using vertical
28 * interpolation described in ISO/IEC 14496-2, subclause 7.6.2.
29 *
30 * Remarks:
31 *
32 * Parameters:
33 * [in] pSrc        pointer to the block in the reference plane.
34 * [in] srcStep     distance between the start of consecutive lines
35 *                  in the reference plane, in bytes; must be a multiple
36 *                  of 8.
37 * [in] rndVal      rounding control parameter: 0 - disabled; 1 - enabled.
38 * [out] pDst       pointer to the linaer 8x8 destination buffer;
39 *
40 */
41static OMXVoid armVCM4P2_HalfPelVer(
42      const OMX_U8 *pSrc,
43      OMX_INT srcStep,
44      OMX_U8 *pDst,
45      OMX_INT rndVal)
46{
47  const OMX_U8 *pTempSrc1;
48  const OMX_U8 *pTempSrc2;
49  OMX_INT y, x;
50
51  pTempSrc1 = pSrc;
52  pTempSrc2 = pSrc + srcStep;
53  srcStep -= 8;
54  for (y = 0; y < 8; y++)
55  {
56    for (x = 0; x < 8; x++)
57    {
58      *pDst++ = ((*pTempSrc1++ + *pTempSrc2++) + 1 - rndVal) >> 1;
59    }
60    pTempSrc1 += srcStep;
61    pTempSrc2 += srcStep;
62  }
63}
64
65/**
66 * Function: armVCM4P2_HalfPelHor
67 *
68 * Description:
69 * Performs half pel motion compensation for an 8x8 block using horizontal
70 * interpolation described in ISO/IEC 14496-2, subclause 7.6.2.
71 *
72 * Remarks:
73 *
74 * Parameters:
75 * [in] pSrc        pointer to the block in the reference plane.
76 * [in] srcStep     distance between the start of consecutive lines
77 *                  in the reference plane, in bytes; must be a multiple
78 *                  of 8.
79 * [in] rndVal      rounding control parameter: 0 - disabled; 1 - enabled.
80 * [out] pDst       pointer to the linaer 8x8 destination buffer;
81 *
82 */
83static OMXVoid armVCM4P2_HalfPelHor(
84      const OMX_U8 *pSrc,
85      OMX_INT srcStep,
86      OMX_U8 *pDst,
87      OMX_INT rndVal)
88{
89  const OMX_U8 *pTempSrc1;
90  const OMX_U8 *pTempSrc2;
91  OMX_INT y, x;
92
93  pTempSrc1 = pSrc;
94  pTempSrc2 = pTempSrc1 + 1;
95
96  srcStep -= 8;
97  for (y=0; y<8; y++)
98  {
99    for (x=0; x<8; x++)
100    {
101      *pDst++ = ((*pTempSrc1++ + *pTempSrc2++) + 1 - rndVal) >> 1;
102    }
103    pTempSrc1 += srcStep;
104    pTempSrc2 += srcStep;
105  }
106}
107
108
109/**
110 * Function: armVCM4P2_HalfPelVerHor
111 *
112 * Description:
113 * Performs half pel motion compensation for an 8x8 block using both
114 * horizontal and vertical interpolation described in ISO/IEC 14496-2,
115 * subclause 7.6.2.
116 *
117 * Remarks:
118 *
119 * Parameters:
120 * [in] pSrc        pointer to the block in the reference plane.
121 * [in] srcStep     distance between the start of consecutive lines
122 *                  in the reference plane, in bytes; must be a multiple
123 *                  of 8.
124 * [in] rndVal      rounding control parameter: 0 - disabled; 1 - enabled.
125 * [out] pDst       pointer to the linaer 8x8 destination buffer;
126 *
127 */
128static OMXVoid armVCM4P2_HalfPelVerHor(
129      const OMX_U8 *pSrc,
130      OMX_INT srcStep,
131      OMX_U8 *pDst,
132      OMX_INT rndVal)
133{
134  const OMX_U8 *pTempSrc1;
135  const OMX_U8 *pTempSrc2;
136  const OMX_U8 *pTempSrc3;
137  const OMX_U8 *pTempSrc4;
138  OMX_INT y, x;
139
140  pTempSrc1 = pSrc;
141  pTempSrc2 = pSrc + srcStep;
142  pTempSrc3 = pSrc + 1;
143  pTempSrc4 = pSrc + srcStep + 1;
144
145  srcStep -= 8;
146  for (y=0; y<8; y++)
147  {
148    for (x=0; x<8; x++)
149	{
150	  *pDst++ = ((*pTempSrc1++ + *pTempSrc2++ + *pTempSrc3++ + *pTempSrc4++) +
151	                  2 - rndVal) >> 2;
152	}
153    pTempSrc1 += srcStep;
154    pTempSrc2 += srcStep;
155    pTempSrc3 += srcStep;
156    pTempSrc4 += srcStep;
157  }
158}
159
160/**
161 * Function: armVCM4P2_MCReconBlock_NoRes
162 *
163 * Description:
164 * Do motion compensation and copy the result to the current block.
165 *
166 * Remarks:
167 *
168 * Parameters:
169 * [in] pSrc        pointer to the block in the reference plane.
170 * [in] srcStep     distance between the start of consecutive lines
171 *                  in the reference plane, in bytes; must be a multiple
172 *                  of 8.
173 * [in] dstStep     distance between the start of consecutive lines in the
174 *                  destination plane, in bytes; must be a multiple of 8.
175 * [in] predictType bilinear interpolation type, as defined in section 6.2.1.2.
176 * [in] rndVal      rounding control parameter: 0 - disabled; 1 - enabled.
177 * [out] pDst       pointer to the destination buffer; must be 8-byte aligned.
178 *                  If prediction residuals are added then output intensities
179 *                  are clipped to the range [0,255].
180 *
181 */
182static OMXVoid armVCM4P2_MCReconBlock_NoRes(
183      const OMX_U8 *pSrc,
184      OMX_INT srcStep,
185      OMX_U8 *pDst,
186      OMX_INT dstStep)
187{
188    OMX_U8 x,y,count,index;
189
190    /* Copying the ref 8x8 blk to the curr blk */
191    for (y = 0, count = 0, index = 0; y < 8; y++,index += (srcStep -8), count += (dstStep - 8))
192    {
193        for (x = 0; x < 8; x++, count++,index++)
194        {
195            pDst[count] = pSrc[index];
196        }
197    }
198}
199
200/**
201 * Function: armVCM4P2_MCReconBlock_Res
202 *
203 * Description:
204 * Reconstructs INTER block by summing the motion compensation results
205 * and the results of the inverse transformation (prediction residuals).
206 * Output intensities are clipped to the range [0,255].
207 *
208 * Remarks:
209 *
210 * Parameters:
211 * [in] pSrc        pointer to the block in the reference plane.
212 * [in] pSrcResidue pointer to a buffer containing the 16-bit prediction
213 *                  residuals. If the pointer is NULL,then no prediction
214 *                  is done, only motion compensation, i.e., the block is
215 *                  moved with interpolation.
216 * [in] dstStep     distance between the start of consecutive lines in the
217 *                  destination plane, in bytes; must be a multiple of 8.
218 * [out] pDst       pointer to the destination buffer; must be 8-byte aligned.
219 *                  If prediction residuals are added then output intensities
220 *                  are clipped to the range [0,255].
221 *
222 */
223static OMXVoid armVCM4P2_MCReconBlock_Res(
224      const OMX_U8 *pSrc,
225      const OMX_S16 *pSrcResidue,
226      OMX_U8 *pDst,
227      OMX_INT dstStep)
228{
229
230  OMX_U8 x,y;
231  OMX_INT temp;
232
233  for(y = 0; y < 8; y++)
234  {
235    for(x = 0; x < 8; x++)
236    {
237      temp = pSrc[x] + pSrcResidue[x];
238      pDst[x] = armClip(0,255,temp);
239    }
240    pDst += dstStep;
241    pSrc += 8;
242    pSrcResidue += 8;
243  }
244}
245
246/**
247 * Function:  omxVCM4P2_MCReconBlock   (6.2.5.5.1)
248 *
249 * Description:
250 * Performs motion compensation prediction for an 8x8 block using
251 * interpolation described in [ISO14496-2], subclause 7.6.2.
252 *
253 * Input Arguments:
254 *
255 *   pSrc - pointer to the block in the reference plane.
256 *   srcStep - distance between the start of consecutive lines in the
257 *            reference plane, in bytes; must be a multiple of 8.
258 *   dstStep - distance between the start of consecutive lines in the
259 *            destination plane, in bytes; must be a multiple of 8.
260 *   pSrcResidue - pointer to a buffer containing the 16-bit prediction
261 *            residuals; must be 16-byte aligned. If the pointer is NULL, then
262 *            no prediction is done, only motion compensation, i.e., the block
263 *            is moved with interpolation.
264 *   predictType - bilinear interpolation type, as defined in section
265 *            6.2.1.2.
266 *   rndVal - rounding control parameter: 0 - disabled; 1 - enabled.
267 *
268 * Output Arguments:
269 *
270 *   pDst - pointer to the destination buffer; must be 8-byte aligned.  If
271 *            prediction residuals are added then output intensities are
272 *            clipped to the range [0,255].
273 *
274 * Return Value:
275 *
276 *    OMX_Sts_NoErr - no error
277 *    OMX_Sts_BadArgErr - bad arguments; returned under any of the following
278 *              conditions:
279 *    -    pDst is not 8-byte aligned.
280 *    -    pSrcResidue is not 16-byte aligned.
281 *    -    one or more of the following pointers is NULL: pSrc or pDst.
282 *    -    either srcStep or dstStep is not a multiple of 8.
283 *    -    invalid type specified for the parameter predictType.
284 *    -    the parameter rndVal is not equal either to 0 or 1.
285 *
286 */
287OMXResult omxVCM4P2_MCReconBlock(
288		const OMX_U8 *pSrc,
289		OMX_INT srcStep,
290		const OMX_S16 *pSrcResidue,
291		OMX_U8 *pDst,
292		OMX_INT dstStep,
293		OMX_INT predictType,
294		OMX_INT rndVal)
295{
296    /* Definitions and Initializations*/
297    OMX_U8 pTempDst[64];
298
299    /* Argument error checks */
300    armRetArgErrIf(pSrc == NULL, OMX_Sts_BadArgErr);
301    armRetArgErrIf(pDst == NULL, OMX_Sts_BadArgErr);
302    armRetArgErrIf(!armIs8ByteAligned(pDst), OMX_Sts_BadArgErr);
303    armRetArgErrIf(!armIs16ByteAligned(pSrcResidue), OMX_Sts_BadArgErr);
304    armRetArgErrIf(((dstStep % 8) || (srcStep % 8)), OMX_Sts_BadArgErr);
305    armRetArgErrIf(((predictType != OMX_VC_INTEGER_PIXEL) &&
306                    (predictType != OMX_VC_HALF_PIXEL_X) &&
307                    (predictType != OMX_VC_HALF_PIXEL_Y) &&
308                    (predictType != OMX_VC_HALF_PIXEL_XY)
309                   ),OMX_Sts_BadArgErr);
310    armRetArgErrIf(((rndVal != 0) && (rndVal != 1)),OMX_Sts_BadArgErr);
311
312    switch(predictType)
313    {
314        case OMX_VC_INTEGER_PIXEL:
315                                   armVCM4P2_MCReconBlock_NoRes(pSrc,
316                                                                    srcStep,
317                                                                    &(pTempDst[0]),
318                                                                    8);
319                                   break;
320        case OMX_VC_HALF_PIXEL_X:
321                                   armVCM4P2_HalfPelHor(pSrc,
322                                                            srcStep,
323                                                            &(pTempDst[0]),
324                                                            rndVal);
325                                   break;
326        case OMX_VC_HALF_PIXEL_Y:
327                                   armVCM4P2_HalfPelVer(pSrc,
328                                                            srcStep,
329                                                            &(pTempDst[0]),
330                                                            rndVal);
331                                   break;
332        case OMX_VC_HALF_PIXEL_XY:
333                                   armVCM4P2_HalfPelVerHor(pSrc,
334                                                            srcStep,
335                                                            &(pTempDst[0]),
336                                                            rndVal);
337                                   break;
338    }
339
340    if(pSrcResidue == NULL)
341    {
342      armVCM4P2_MCReconBlock_NoRes(&(pTempDst[0]),
343                                         8,
344                                         pDst,
345                                         dstStep);
346    }
347    else
348    {
349      armVCM4P2_MCReconBlock_Res(&(pTempDst[0]),
350                                          pSrcResidue,
351                                          pDst,
352                                          dstStep);
353    }
354
355    return OMX_Sts_NoErr;
356}
357
358