Home | History | Annotate | Download | only in src
      1 /* ----------------------------------------------------------------
      2  *
      3  *
      4  * File Name:  armVCM4P10_DecodeCoeffsToPair.c
      5  * OpenMAX DL: v1.0.2
      6  * Revision:   9641
      7  * Date:       Thursday, February 7, 2008
      8  *
      9  * (c) Copyright 2007-2008 ARM Limited. All Rights Reserved.
     10  *
     11  *
     12  *
     13  * H.264 decode coefficients module
     14  *
     15  */
     16 
     17 #ifdef DEBUG_ARMVCM4P10_DECODECOEFFSTOPAIR
     18 #undef DEBUG_ON
     19 #define DEBUG_ON
     20 #endif
     21 
     22 #include "omxtypes.h"
     23 #include "armOMX.h"
     24 #include "omxVC.h"
     25 
     26 #include "armCOMM.h"
     27 #include "armCOMM_Bitstream.h"
     28 #include "armVCM4P10_CAVLCTables.h"
     29 
     30 /* 4x4 DeZigZag table */
     31 
     32 static const OMX_U8 armVCM4P10_ZigZag[16] =
     33 {
     34     0, 1, 4, 8, 5, 2, 3, 6, 9, 12, 13, 10, 7, 11, 14, 15
     35 };
     36 
     37 /*
     38  * Description:
     39  * This function perform the work required by the OpenMAX
     40  * DecodeCoeffsToPair function and DecodeChromaDCCoeffsToPair.
     41  * Since most of the code is common we share it here.
     42  *
     43  * Parameters:
     44  * [in]	ppBitStream		Double pointer to current byte in bit stream buffer
     45  * [in]	pOffset			Pointer to current bit position in the byte pointed
     46  *								to by *ppBitStream
     47  * [in]	sMaxNumCoeff	Maximum number of non-zero coefficients in current
     48  *								block (4,15 or 16)
     49  * [in]	nTable          Table number (0 to 4) according to the five columns
     50  *                      of Table 9-5 in the H.264 spec
     51  * [out]	ppBitStream		*ppBitStream is updated after each block is decoded
     52  * [out]	pOffset			*pOffset is updated after each block is decoded
     53  * [out]	pNumCoeff		Pointer to the number of nonzero coefficients in
     54  *								this block
     55  * [out]	ppPosCoefbuf	Double pointer to destination residual
     56  *								coefficient-position pair buffer
     57  * Return Value:
     58  * Standard omxError result. See enumeration for possible result codes.
     59 
     60  */
     61 
     62 OMXResult armVCM4P10_DecodeCoeffsToPair(
     63      const OMX_U8** ppBitStream,
     64      OMX_S32* pOffset,
     65      OMX_U8* pNumCoeff,
     66      OMX_U8  **ppPosCoefbuf,
     67      OMX_INT nTable,
     68      OMX_INT sMaxNumCoeff
     69  )
     70 {
     71     int CoeffToken, TotalCoeff, TrailingOnes;
     72     int Level, LevelCode, LevelPrefix, LevelSuffix, LevelSuffixSize;
     73     int SuffixLength, Run, ZerosLeft,CoeffNum;
     74     int i, Flags;
     75     OMX_U8 *pPosCoefbuf = *ppPosCoefbuf;
     76     OMX_S16 pLevel[16];
     77     OMX_U8  pRun[16];
     78 
     79     CoeffToken = armUnPackVLC32(ppBitStream, pOffset, armVCM4P10_CAVLCCoeffTokenTables[nTable]);
     80     armRetDataErrIf(CoeffToken == ARM_NO_CODEBOOK_INDEX, OMX_Sts_Err);
     81 
     82     TrailingOnes = armVCM4P10_CAVLCTrailingOnes[CoeffToken];
     83     TotalCoeff   = armVCM4P10_CAVLCTotalCoeff[CoeffToken];
     84     *pNumCoeff   = (OMX_U8)TotalCoeff;
     85 
     86     DEBUG_PRINTF_2("TotalCoeff = %d, TrailingOnes = %d\n", TotalCoeff, TrailingOnes);
     87 
     88     if (TotalCoeff == 0)
     89     {
     90         /* Nothing to do */
     91         return OMX_Sts_NoErr;
     92     }
     93 
     94     /* Decode trailing ones */
     95     for (i=TotalCoeff-1; i>=TotalCoeff-TrailingOnes; i--)
     96     {
     97         if (armGetBits(ppBitStream, pOffset, 1))
     98         {
     99             Level = -1;
    100         }
    101         else
    102         {
    103             Level = +1;
    104         }
    105         pLevel[i] = (OMX_S16)Level;
    106 
    107         DEBUG_PRINTF_2("Level[%d] = %d\n", i, pLevel[i]);
    108     }
    109 
    110     /* Decode (non zero) level values */
    111     SuffixLength = 0;
    112     if (TotalCoeff>10 && TrailingOnes<3)
    113     {
    114         SuffixLength=1;
    115     }
    116     for ( ; i>=0; i--)
    117     {
    118         LevelPrefix = armUnPackVLC32(ppBitStream, pOffset, armVCM4P10_CAVLCLevelPrefix);
    119         armRetDataErrIf(LevelPrefix == ARM_NO_CODEBOOK_INDEX, OMX_Sts_Err);
    120 
    121         LevelSuffixSize = SuffixLength;
    122         if (LevelPrefix==14 && SuffixLength==0)
    123         {
    124             LevelSuffixSize = 4;
    125         }
    126         if (LevelPrefix==15)
    127         {
    128             LevelSuffixSize = 12;
    129         }
    130 
    131         LevelSuffix = 0;
    132         if (LevelSuffixSize > 0)
    133         {
    134             LevelSuffix = armGetBits(ppBitStream, pOffset, LevelSuffixSize);
    135         }
    136 
    137         LevelCode = (LevelPrefix << SuffixLength) + LevelSuffix;
    138 
    139 
    140         if (LevelPrefix==15 && SuffixLength==0)
    141         {
    142             LevelCode += 15;
    143         }
    144 
    145         /* LevelCode = 2*(magnitude-1) + sign */
    146 
    147         if (i==TotalCoeff-1-TrailingOnes && TrailingOnes<3)
    148         {
    149             /* Level magnitude can't be 1 */
    150             LevelCode += 2;
    151         }
    152         if (LevelCode & 1)
    153         {
    154             /* 2a+1 maps to -a-1 */
    155             Level = (-LevelCode-1)>>1;
    156         }
    157         else
    158         {
    159             /* 2a+0 maps to +a+1 */
    160             Level = (LevelCode+2)>>1;
    161         }
    162         pLevel[i] = (OMX_S16)Level;
    163 
    164         DEBUG_PRINTF_2("Level[%d] = %d\n", i, pLevel[i]);
    165 
    166         if (SuffixLength==0)
    167         {
    168             SuffixLength=1;
    169         }
    170         if ( ((LevelCode>>1)+1)>(3<<(SuffixLength-1)) && SuffixLength<6 )
    171         {
    172             SuffixLength++;
    173         }
    174     }
    175 
    176     /* Decode run values */
    177     ZerosLeft = 0;
    178     if (TotalCoeff < sMaxNumCoeff)
    179     {
    180         /* Decode TotalZeros VLC */
    181         if (sMaxNumCoeff==4)
    182         {
    183             ZerosLeft = armUnPackVLC32(ppBitStream, pOffset, armVCM4P10_CAVLCTotalZeros2x2Tables[TotalCoeff-1]);
    184             armRetDataErrIf(ZerosLeft ==ARM_NO_CODEBOOK_INDEX , OMX_Sts_Err);
    185         }
    186         else
    187         {
    188             ZerosLeft = armUnPackVLC32(ppBitStream, pOffset, armVCM4P10_CAVLCTotalZeroTables[TotalCoeff-1]);
    189              armRetDataErrIf(ZerosLeft ==ARM_NO_CODEBOOK_INDEX , OMX_Sts_Err);
    190 	    }
    191     }
    192 
    193     DEBUG_PRINTF_1("TotalZeros = %d\n", ZerosLeft);
    194 
    195 	CoeffNum=ZerosLeft+TotalCoeff-1;
    196 
    197     for (i=TotalCoeff-1; i>0; i--)
    198     {
    199         Run = 0;
    200         if (ZerosLeft > 0)
    201         {
    202             int Table = ZerosLeft;
    203             if (Table > 6)
    204             {
    205                 Table = 7;
    206             }
    207             Run = armUnPackVLC32(ppBitStream, pOffset, armVCM4P10_CAVLCRunBeforeTables[Table-1]);
    208             armRetDataErrIf(Run == ARM_NO_CODEBOOK_INDEX, OMX_Sts_Err);
    209         }
    210         pRun[i] = (OMX_U8)Run;
    211 
    212         DEBUG_PRINTF_2("Run[%d] = %d\n", i, pRun[i]);
    213 
    214         ZerosLeft -= Run;
    215     }
    216     pRun[0] = (OMX_U8)ZerosLeft;
    217 
    218     DEBUG_PRINTF_1("Run[0] = %d\n", pRun[i]);
    219 
    220 
    221     /* Fill in coefficients */
    222 
    223     if (sMaxNumCoeff==15)
    224     {
    225         CoeffNum++; /* Skip the DC position */
    226     }
    227 
    228 	/*for (i=0;i<TotalCoeff;i++)
    229 		CoeffNum += pRun[i]+1;*/
    230 
    231 	for (i=(TotalCoeff-1); i>=0; i--)
    232     {
    233         /*CoeffNum += pRun[i]+1;*/
    234         Level     = pLevel[i];
    235 
    236         DEBUG_PRINTF_2("Coef[%d] = %d\n", CoeffNum, Level);
    237 
    238         Flags = CoeffNum;
    239 		CoeffNum -= (pRun[i]+1);
    240         if (sMaxNumCoeff>4)
    241         {
    242             /* Perform 4x4 DeZigZag */
    243             Flags = armVCM4P10_ZigZag[Flags];
    244         }
    245         if (i==0)
    246         {
    247             /* End of block flag */
    248             Flags += 0x20;
    249         }
    250         if (Level<-128 || Level>127)
    251         {
    252             /* Overflow flag */
    253             Flags += 0x10;
    254         }
    255 
    256         *pPosCoefbuf++ = (OMX_U8)(Flags);
    257         *pPosCoefbuf++ = (OMX_U8)(Level & 0xFF);
    258         if (Flags & 0x10)
    259         {
    260             *pPosCoefbuf++ = (OMX_U8)(Level>>8);
    261         }
    262     }
    263 
    264     *ppPosCoefbuf = pPosCoefbuf;
    265 
    266     return OMX_Sts_NoErr;
    267 }
    268