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