Home | History | Annotate | Download | only in src
      1 /**
      2  *
      3  * File Name:  omxVCM4P2_DecodePadMV_PVOP.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  *
     12  * Description:
     13  * Contains module for decoding MV and padding the same
     14  *
     15  */
     16 
     17 #include "omxtypes.h"
     18 #include "armOMX.h"
     19 #include "omxVC.h"
     20 
     21 #include "armCOMM_Bitstream.h"
     22 #include "armCOMM.h"
     23 #include "armVCM4P2_Huff_Tables_VLC.h"
     24 
     25 
     26 
     27 /**
     28  * Function:  omxVCM4P2_DecodePadMV_PVOP   (6.2.5.1.1)
     29  *
     30  * Description:
     31  * Decodes and pads the four motion vectors associated with a non-intra P-VOP
     32  * macroblock.  For macroblocks of type OMX_VC_INTER4V, the output MV is
     33  * padded as specified in [ISO14496-2], subclause 7.6.1.6. Otherwise, for
     34  * macroblocks of types other than OMX_VC_INTER4V, the decoded MV is copied to
     35  * all four output MV buffer entries.
     36  *
     37  * Input Arguments:
     38  *
     39  *   ppBitStream - pointer to the pointer to the current byte in the bit
     40  *            stream buffer
     41  *   pBitOffset - pointer to the bit position in the byte pointed to by
     42  *            *ppBitStream. *pBitOffset is valid within [0-7].
     43  *   pSrcMVLeftMB, pSrcMVUpperMB, and pSrcMVUpperRightMB - pointers to the
     44  *            motion vector buffers of the macroblocks specially at the left,
     45  *            upper, and upper-right side of the current macroblock,
     46  *            respectively; a value of NULL indicates unavailability.  Note:
     47  *            Any neighborhood macroblock outside the current VOP or video
     48  *            packet or outside the current GOB (when short_video_header is
     49  *             1 ) for which gob_header_empty is  0  is treated as
     50  *            transparent, according to [ISO14496-2], subclause 7.6.5.
     51  *   fcodeForward - a code equal to vop_fcode_forward in MPEG-4 bit stream
     52  *            syntax
     53  *   MBType - the type of the current macroblock. If MBType is not equal to
     54  *            OMX_VC_INTER4V, the destination motion vector buffer is still
     55  *            filled with the same decoded vector.
     56  *
     57  * Output Arguments:
     58  *
     59  *   ppBitStream - *ppBitStream is updated after the block is decoded, so
     60  *            that it points to the current byte in the bit stream buffer
     61  *   pBitOffset - *pBitOffset is updated so that it points to the current bit
     62  *            position in the byte pointed by *ppBitStream
     63  *   pDstMVCurMB - pointer to the motion vector buffer for the current
     64  *            macroblock; contains four decoded motion vectors
     65  *
     66  * Return Value:
     67  *
     68  *    OMX_Sts_NoErr - no error
     69  *    OMX_Sts_BadArgErr - bad arguments:
     70  *    -    At least one of the following pointers is NULL:
     71  *         ppBitStream, *ppBitStream, pBitOffset, pDstMVCurMB
     72  *    -    *pBitOffset exceeds [0,7]
     73  *    -    fcodeForward exceeds (0,7]
     74  *    -    MBType less than zero
     75  *    -    motion vector buffer is not 4-byte aligned.
     76  *    OMX_Sts_Err - status error
     77  *
     78  */
     79 
     80 OMXResult omxVCM4P2_DecodePadMV_PVOP(
     81      const OMX_U8 ** ppBitStream,
     82      OMX_INT * pBitOffset,
     83      OMXVCMotionVector * pSrcMVLeftMB,
     84      OMXVCMotionVector *pSrcMVUpperMB,
     85      OMXVCMotionVector * pSrcMVUpperRightMB,
     86      OMXVCMotionVector * pDstMVCurMB,
     87      OMX_INT fcodeForward,
     88      OMXVCM4P2MacroblockType MBType
     89  )
     90 {
     91     OMXVCMotionVector diffMV;
     92     OMXVCMotionVector dstMVPredME[12];
     93     OMX_INT iBlk, i, count = 1;
     94     OMX_S32 mvHorResidual = 1, mvVerResidual = 1, mvHorData, mvVerData;
     95     OMX_S8 scaleFactor, index;
     96     OMX_S16 high, low, range;
     97 
     98 
     99     /* Argument error checks */
    100     armRetArgErrIf(ppBitStream == NULL, OMX_Sts_BadArgErr);
    101     armRetArgErrIf(*ppBitStream == NULL, OMX_Sts_BadArgErr);
    102     armRetArgErrIf(pBitOffset == NULL, OMX_Sts_BadArgErr);
    103     armRetArgErrIf(pDstMVCurMB == NULL, OMX_Sts_BadArgErr);
    104     armRetArgErrIf(((*pBitOffset < 0) || (*pBitOffset > 7)), OMX_Sts_BadArgErr);
    105     armRetArgErrIf(((fcodeForward < 1) || (fcodeForward > 7)), \
    106                     OMX_Sts_BadArgErr);
    107     armRetArgErrIf(!armIs4ByteAligned(pDstMVCurMB), OMX_Sts_BadArgErr);
    108 
    109     if ((MBType == OMX_VC_INTRA) ||
    110         (MBType == OMX_VC_INTRA_Q)
    111        )
    112     {
    113         /* All MV's are zero */
    114         for (i = 0; i < 4; i++)
    115         {
    116             pDstMVCurMB[i].dx = 0;
    117             pDstMVCurMB[i].dy = 0;
    118         }
    119 
    120         return OMX_Sts_NoErr;
    121     }
    122 
    123     if ((MBType == OMX_VC_INTER4V) || (MBType == OMX_VC_INTER4V_Q))
    124     {
    125         count = 4;
    126     }
    127     else if ((MBType == OMX_VC_INTER) || (MBType == OMX_VC_INTER_Q))
    128     {
    129         count = 1;
    130     }
    131 
    132     /* Calculating the scale factor */
    133     scaleFactor = 1 << (fcodeForward -1);
    134     high =  ( 32 * scaleFactor) - 1;
    135     low =   ( (-32) * scaleFactor);
    136     range = ( 64 * scaleFactor);
    137 
    138     /* Huffman decoding and MV reconstruction */
    139     for (iBlk = 0; iBlk < count; iBlk++)
    140     {
    141 
    142         /* Huffman decoding to get Horizontal data and residual */
    143         index = armUnPackVLC32(ppBitStream, pBitOffset,
    144                                             armVCM4P2_aVlcMVD);
    145         armRetDataErrIf(index == -1, OMX_Sts_Err);
    146 
    147         mvHorData = index - 32;
    148 
    149         if ((fcodeForward > 1) && (mvHorData != 0))
    150         {
    151             mvHorResidual = (OMX_S32) armGetBits(ppBitStream,
    152                                             pBitOffset, (fcodeForward -1));
    153         }
    154 
    155         /* Huffman decoding to get Vertical data and residual */
    156         index = armUnPackVLC32(ppBitStream, pBitOffset, armVCM4P2_aVlcMVD);
    157         armRetDataErrIf(index == -1, OMX_Sts_Err);
    158 
    159         mvVerData = index - 32;
    160 
    161         if ((fcodeForward > 1) && (mvVerData != 0))
    162         {
    163             mvVerResidual = (OMX_S32) armGetBits(ppBitStream,
    164                                             pBitOffset, (fcodeForward -1));
    165         }
    166 
    167         /* Calculating the differtial MV */
    168         if ( (scaleFactor == 1) || (mvHorData == 0) )
    169         {
    170             diffMV.dx = mvHorData;
    171         }
    172         else
    173         {
    174             diffMV.dx = ((armAbs(mvHorData) - 1) * fcodeForward)
    175                          + mvHorResidual + 1;
    176             if (mvHorData < 0)
    177             {
    178                 diffMV.dx = -diffMV.dx;
    179             }
    180         }
    181 
    182         if ( (scaleFactor == 1) || (mvVerData == 0) )
    183         {
    184             diffMV.dy = mvVerData;
    185         }
    186         else
    187         {
    188             diffMV.dy = ((armAbs(mvVerData) - 1) * fcodeForward)
    189                          + mvVerResidual + 1;
    190             if (mvVerData < 0)
    191             {
    192                 diffMV.dy = -diffMV.dy;
    193             }
    194         }
    195 
    196         /* Find the predicted vector */
    197         omxVCM4P2_FindMVpred (
    198             pDstMVCurMB,
    199             pSrcMVLeftMB,
    200             pSrcMVUpperMB,
    201             pSrcMVUpperRightMB,
    202             &pDstMVCurMB[iBlk],
    203             dstMVPredME,
    204             iBlk);
    205 
    206         /* Adding the difference to the predicted MV to reconstruct MV */
    207         pDstMVCurMB[iBlk].dx += diffMV.dx;
    208         pDstMVCurMB[iBlk].dy += diffMV.dy;
    209 
    210         /* Checking the range and keeping it within the limits */
    211         if ( pDstMVCurMB[iBlk].dx < low )
    212         {
    213             pDstMVCurMB[iBlk].dx += range;
    214         }
    215         if (pDstMVCurMB[iBlk].dx > high)
    216         {
    217             pDstMVCurMB[iBlk].dx -= range;
    218         }
    219 
    220         if ( pDstMVCurMB[iBlk].dy < low )
    221         {
    222             pDstMVCurMB[iBlk].dy += range;
    223         }
    224         if (pDstMVCurMB[iBlk].dy > high)
    225         {
    226             pDstMVCurMB[iBlk].dy -= range;
    227         }
    228     }
    229 
    230     if ((MBType == OMX_VC_INTER) || (MBType == OMX_VC_INTER_Q))
    231     {
    232         pDstMVCurMB[1] = pDstMVCurMB[0];
    233         pDstMVCurMB[2] = pDstMVCurMB[0];
    234         pDstMVCurMB[3] = pDstMVCurMB[0];
    235     }
    236 
    237     return OMX_Sts_NoErr;
    238 }
    239 
    240 
    241 /* End of file */
    242 
    243 
    244