Home | History | Annotate | Download | only in src
      1 /**
      2  *
      3  * File Name:  omxVCM4P2_EncodeMV.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 predicting MV of MB
     14  *
     15  */
     16 
     17 #include "omxtypes.h"
     18 #include "armOMX.h"
     19 #include "omxVC.h"
     20 
     21 #include "armCOMM.h"
     22 #include "armCOMM_Bitstream.h"
     23 #include "armVCM4P2_Huff_Tables_VLC.h"
     24 
     25 
     26 
     27 /**
     28  * Function:  omxVCM4P2_EncodeMV   (6.2.4.5.4)
     29  *
     30  * Description:
     31  * Predicts a motion vector for the current macroblock, encodes the
     32  * difference, and writes the output to the stream buffer. The input MVs
     33  * pMVCurMB, pSrcMVLeftMB, pSrcMVUpperMB, and pSrcMVUpperRightMB should lie
     34  * within the ranges associated with the input parameter fcodeForward, as
     35  * described in [ISO14496-2], subclause 7.6.3.  This function provides a
     36  * superset of the functionality associated with the function
     37  * omxVCM4P2_FindMVpred.
     38  *
     39  * Input Arguments:
     40  *
     41  *   ppBitStream - double pointer to the current byte in the bitstream buffer
     42  *   pBitOffset - index of the first free (next available) bit in the stream
     43  *            buffer referenced by *ppBitStream, valid in the range 0 to 7.
     44  *   pMVCurMB - pointer to the current macroblock motion vector; a value of
     45  *            NULL indicates unavailability.
     46  *   pSrcMVLeftMB - pointer to the source left macroblock motion vector; a
     47  *            value of  NULLindicates unavailability.
     48  *   pSrcMVUpperMB - pointer to source upper macroblock motion vector; a
     49  *            value of NULL indicates unavailability.
     50  *   pSrcMVUpperRightMB - pointer to source upper right MB motion vector; a
     51  *            value of NULL indicates unavailability.
     52  *   fcodeForward - an integer with values from 1 to 7; used in encoding
     53  *            motion vectors related to search range, as described in
     54  *            [ISO14496-2], subclause 7.6.3.
     55  *   MBType - macro block type, valid in the range 0 to 5
     56  *
     57  * Output Arguments:
     58  *
     59  *   ppBitStream - updated pointer to the current byte in the bit stream
     60  *            buffer
     61  *   pBitOffset - updated index of the next available bit position in stream
     62  *            buffer referenced by *ppBitStream
     63  *
     64  * Return Value:
     65  *
     66  *    OMX_Sts_NoErr - no error
     67  *    OMX_Sts_BadArgErr - bad arguments
     68  *    -    At least one of the following pointers is NULL: ppBitStream,
     69  *              *ppBitStream, pBitOffset, pMVCurMB
     70  *    -    *pBitOffset < 0, or *pBitOffset >7.
     71  *    -    fcodeForward <= 0, or fcodeForward > 7, or MBType < 0.
     72  *
     73  */
     74 
     75 OMXResult omxVCM4P2_EncodeMV(
     76      OMX_U8 **ppBitStream,
     77      OMX_INT *pBitOffset,
     78      const OMXVCMotionVector * pMVCurMB,
     79      const OMXVCMotionVector * pSrcMVLeftMB,
     80      const OMXVCMotionVector * pSrcMVUpperMB,
     81      const OMXVCMotionVector * pSrcMVUpperRightMB,
     82      OMX_INT fcodeForward,
     83      OMXVCM4P2MacroblockType MBType
     84 )
     85 {
     86     OMXVCMotionVector dstMVPred, diffMV;
     87     OMXVCMotionVector dstMVPredME[12];
     88     /* Initialized to remove compilation warning */
     89     OMX_INT iBlk, i, count = 1;
     90     OMX_S32 mvHorResidual, mvVerResidual, mvHorData, mvVerData;
     91     OMX_U8 scaleFactor, index;
     92 
     93     /* Argument error checks */
     94     armRetArgErrIf(ppBitStream == NULL, OMX_Sts_BadArgErr);
     95     armRetArgErrIf(*ppBitStream == NULL, OMX_Sts_BadArgErr);
     96     armRetArgErrIf(pBitOffset == NULL, OMX_Sts_BadArgErr);
     97     armRetArgErrIf(pMVCurMB == NULL, OMX_Sts_BadArgErr);
     98     armRetArgErrIf(((*pBitOffset < 0) || (*pBitOffset > 7)), OMX_Sts_BadArgErr);
     99     armRetArgErrIf(((fcodeForward < 1) || (fcodeForward > 7)), \
    100                     OMX_Sts_BadArgErr);
    101 
    102     if ((MBType == OMX_VC_INTRA) ||
    103         (MBType == OMX_VC_INTRA_Q)
    104        )
    105     {
    106         /* No candidate vectors hence make them zero */
    107         for (i = 0; i < 12; i++)
    108         {
    109             dstMVPredME[i].dx = 0;
    110             dstMVPredME[i].dy = 0;
    111         }
    112 
    113         return OMX_Sts_NoErr;
    114     }
    115 
    116     if ((MBType == OMX_VC_INTER4V) || (MBType == OMX_VC_INTER4V_Q))
    117     {
    118         count = 4;
    119     }
    120     else if ((MBType == OMX_VC_INTER) || (MBType == OMX_VC_INTER_Q))
    121     {
    122         count = 1;
    123     }
    124 
    125     /* Calculating the scale factor */
    126     scaleFactor = 1 << (fcodeForward -1);
    127 
    128     for (iBlk = 0; iBlk < count; iBlk++)
    129     {
    130 
    131         /* Find the predicted vector */
    132         omxVCM4P2_FindMVpred (
    133             pMVCurMB,
    134             pSrcMVLeftMB,
    135             pSrcMVUpperMB,
    136             pSrcMVUpperRightMB,
    137             &dstMVPred,
    138             dstMVPredME,
    139             iBlk );
    140 
    141         /* Calculating the differential motion vector (diffMV) */
    142         diffMV.dx = pMVCurMB[iBlk].dx - dstMVPred.dx;
    143         diffMV.dy = pMVCurMB[iBlk].dy - dstMVPred.dy;
    144 
    145         /* Calculating the mv_data and mv_residual for Horizantal MV */
    146         if (diffMV.dx == 0)
    147         {
    148             mvHorResidual = 0;
    149             mvHorData = 0;
    150         }
    151         else
    152         {
    153             mvHorResidual = ( armAbs(diffMV.dx) - 1) % scaleFactor;
    154             mvHorData = (armAbs(diffMV.dx) - mvHorResidual + (scaleFactor - 1))
    155                      / scaleFactor;
    156             if (diffMV.dx < 0)
    157             {
    158                 mvHorData = -mvHorData;
    159             }
    160         }
    161 
    162         /* Calculating the mv_data and mv_residual for Vertical MV */
    163         if (diffMV.dy == 0)
    164         {
    165             mvVerResidual = 0;
    166             mvVerData = 0;
    167         }
    168         else
    169         {
    170             mvVerResidual = ( armAbs(diffMV.dy) - 1) % scaleFactor;
    171             mvVerData = (armAbs(diffMV.dy) - mvVerResidual + (scaleFactor - 1))
    172                      / scaleFactor;
    173             if (diffMV.dy < 0)
    174             {
    175                 mvVerData = -mvVerData;
    176             }
    177         }
    178 
    179         /* Huffman encoding */
    180 
    181         /* The index is actually calculate as
    182            index = ((float) (mvHorData/2) + 16) * 2,
    183            meaning the MV data is halfed and then normalized
    184            to begin with zero and then doubled to take care of indexing
    185            the fractional part included */
    186         index = mvHorData + 32;
    187         armPackVLC32 (ppBitStream, pBitOffset, armVCM4P2_aVlcMVD[index]);
    188         if ((fcodeForward > 1) && (diffMV.dx != 0))
    189         {
    190             armPackBits (ppBitStream, pBitOffset, mvHorResidual, (fcodeForward -1));
    191         }
    192 
    193         /* The index is actually calculate as
    194            index = ((float) (mvVerData/2) + 16) * 2,
    195            meaning the MV data is halfed and then normalized
    196            to begin with zero and then doubled to take care of indexing
    197            the fractional part included */
    198         index = mvVerData + 32;
    199         armPackVLC32 (ppBitStream, pBitOffset, armVCM4P2_aVlcMVD[index]);
    200         if ((fcodeForward > 1) && (diffMV.dy != 0))
    201         {
    202             armPackBits (ppBitStream, pBitOffset, mvVerResidual, (fcodeForward -1));
    203         }
    204     }
    205 
    206     return OMX_Sts_NoErr;
    207 }
    208 
    209 
    210 /* End of file */
    211 
    212 
    213