Home | History | Annotate | Download | only in src
      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  */
     41 static 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  */
     83 static 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  */
    128 static 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  */
    182 static 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  */
    223 static 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  */
    287 OMXResult 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