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