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