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