Home | History | Annotate | Download | only in src
      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  */
     56 static 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  */
     98 static 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  */
    143 static 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  */
    197 static 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  */
    238 static 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  */
    302 OMXResult 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