Home | History | Annotate | Download | only in src
      1 /**
      2  *
      3  * File Name:  omxVCM4P10_GetVLCInfo.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  *
     13  * This function extracts run-length encoding (RLE) information
     14  */
     15 
     16 #include "omxtypes.h"
     17 #include "armOMX.h"
     18 #include "omxVC.h"
     19 
     20 #include "armCOMM.h"
     21 #include "armVC.h"
     22 
     23 /**
     24  * Function:  omxVCM4P10_GetVLCInfo   (6.3.5.9.1)
     25  *
     26  * Description:
     27  * This function extracts run-length encoding (RLE) information from the
     28  * coefficient matrix.  The results are returned in an OMXVCM4P10VLCInfo
     29  * structure.
     30  *
     31  * Input Arguments:
     32  *
     33  *   pSrcCoeff - pointer to the transform coefficient matrix.  8-byte
     34  *            alignment required.
     35  *   pScanMatrix - pointer to the scan order definition matrix.  For a luma
     36  *            block the scan matrix should follow [ISO14496-10] section 8.5.4,
     37  *            and should contain the values 0, 1, 4, 8, 5, 2, 3, 6, 9, 12, 13,
     38  *            10, 7, 11, 14, 15.  For a chroma block, the scan matrix should
     39  *            contain the values 0, 1, 2, 3.
     40  *   bAC - indicates presence of a DC coefficient; 0 = DC coefficient
     41  *            present, 1= DC coefficient absent.
     42  *   MaxNumCoef - specifies the number of coefficients contained in the
     43  *            transform coefficient matrix, pSrcCoeff. The value should be 16
     44  *            for blocks of type LUMADC, LUMAAC, LUMALEVEL, and CHROMAAC. The
     45  *            value should be 4 for blocks of type CHROMADC.
     46  *
     47  * Output Arguments:
     48  *
     49  *   pDstVLCInfo - pointer to structure that stores information for
     50  *            run-length coding.
     51  *
     52  * Return Value:
     53  *
     54  *    OMX_Sts_NoErr - no error
     55  *    OMX_Sts_BadArgErr - bad arguments; returned if any of the following
     56  *              conditions are true:
     57  *    -    at least one of the following pointers is NULL:
     58  *            pSrcCoeff, pScanMatrix, pDstVLCInfo
     59  *    -    pSrcCoeff is not aligned on an 8-byte boundary
     60  *
     61  */
     62 OMXResult omxVCM4P10_GetVLCInfo (
     63 	const OMX_S16*		    pSrcCoeff,
     64 	const OMX_U8*			    pScanMatrix,
     65 	OMX_U8			    bAC,
     66 	OMX_U32			    MaxNumCoef,
     67 	OMXVCM4P10VLCInfo*	pDstVLCInfo
     68 )
     69 {
     70     OMX_INT     i, MinIndex;
     71     OMX_S32     Value;
     72     OMX_U32     Mask = 4, RunBefore;
     73     OMX_S16     *pLevel;
     74     OMX_U8      *pRun;
     75     OMX_S16     Buf [16];
     76 
     77     /* check for argument error */
     78     armRetArgErrIf(pSrcCoeff == NULL, OMX_Sts_BadArgErr)
     79     armRetArgErrIf(armNot8ByteAligned(pSrcCoeff), OMX_Sts_BadArgErr)
     80     armRetArgErrIf(pScanMatrix == NULL, OMX_Sts_BadArgErr)
     81     armRetArgErrIf(pDstVLCInfo == NULL, OMX_Sts_BadArgErr)
     82     armRetArgErrIf(bAC > 1, OMX_Sts_BadArgErr)
     83     armRetArgErrIf(MaxNumCoef > 16, OMX_Sts_BadArgErr)
     84 
     85     /* Initialize RLE Info structure */
     86     pDstVLCInfo->uTrailing_Ones = 0;
     87     pDstVLCInfo->uTrailing_One_Signs = 0;
     88     pDstVLCInfo->uNumCoeffs = 0;
     89     pDstVLCInfo->uTotalZeros = 0;
     90 
     91     for (i = 0; i < 16; i++)
     92     {
     93         pDstVLCInfo->iLevels [i] = 0;
     94         pDstVLCInfo->uRuns [i] = 0;
     95     }
     96 
     97     MinIndex = (bAC == 0 && MaxNumCoef == 15) ? 1 : 0;
     98     for (i = MinIndex; i < (MaxNumCoef + MinIndex); i++)
     99     {
    100         /* Scan */
    101         Buf [i - MinIndex] = pSrcCoeff [pScanMatrix [i]];
    102     }
    103 
    104     /* skip zeros at the end */
    105     i = MaxNumCoef - 1;
    106     while (!Buf [i] && i >= 0)
    107     {
    108         i--;
    109     }
    110 
    111     if (i < 0)
    112     {
    113         return OMX_Sts_NoErr;
    114     }
    115 
    116     /* Fill RLE Info structure */
    117     pLevel = pDstVLCInfo->iLevels;
    118     pRun = pDstVLCInfo->uRuns;
    119     RunBefore = 0;
    120 
    121     /* Handle first non zero separate */
    122     pDstVLCInfo->uNumCoeffs++;
    123     Value = Buf [i];
    124     if (Value == 1 || Value == -1)
    125     {
    126         pDstVLCInfo->uTrailing_Ones++;
    127 
    128         pDstVLCInfo->uTrailing_One_Signs |=
    129             Value == -1 ? Mask : 0;
    130         Mask >>= 1;
    131     }
    132     else
    133     {
    134         Value -= (Value > 0 ? 1 : -1);
    135         *pLevel++ = Value;
    136         Mask = 0;
    137     }
    138 
    139     /* Remaining non zero */
    140     while (--i >= 0)
    141     {
    142         Value = Buf [i];
    143         if (Value)
    144         {
    145             pDstVLCInfo->uNumCoeffs++;
    146 
    147             /* Mask becomes zero after entering */
    148             if (Mask &&
    149                 (Value == 1 ||
    150                  Value == -1))
    151             {
    152                 pDstVLCInfo->uTrailing_Ones++;
    153 
    154                 pDstVLCInfo->uTrailing_One_Signs |=
    155                     Value == -1 ? Mask : 0;
    156                 Mask >>= 1;
    157                 *pRun++ = RunBefore;
    158                 RunBefore = 0;
    159             }
    160             else
    161             {
    162                 /* If 3 trailing ones are not completed */
    163                 if (Mask)
    164                 {
    165                     Mask = 0;
    166                     Value -= (Value > 0 ? 1 : -1);
    167                 }
    168                 *pLevel++ = Value;
    169                 *pRun++ = RunBefore;
    170                 RunBefore = 0;
    171             }
    172         }
    173         else
    174         {
    175             pDstVLCInfo->uTotalZeros++;
    176             RunBefore++;
    177         }
    178     }
    179 
    180     /* Update last run */
    181     if (RunBefore)
    182     {
    183         *pRun++ = RunBefore;
    184     }
    185 
    186     return OMX_Sts_NoErr;
    187 }
    188 
    189 /*****************************************************************************
    190  *                              END OF FILE
    191  *****************************************************************************/
    192 
    193