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:  armVCM4P2_GetVLCBits.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 VLC get bits from the stream
     29  *
     30  */
     31 
     32 #include "omxtypes.h"
     33 #include "armOMX.h"
     34 
     35 #include "armVC.h"
     36 #include "armCOMM.h"
     37 #include "armCOMM_Bitstream.h"
     38 #include "armVCM4P2_ZigZag_Tables.h"
     39 #include "armVCM4P2_Huff_Tables_VLC.h"
     40 
     41 
     42 /**
     43  * Function: armVCM4P2_GetVLCBits
     44  *
     45  * Description:
     46  * Performs escape mode decision based on the run, run+, level, level+ and
     47  * last combinations.
     48  *
     49  * Remarks:
     50  *
     51  * Parameters:
     52  * [in]	ppBitStream		pointer to the pointer to the current byte in
     53  *								the bit stream
     54  * [in]	pBitOffset		pointer to the bit position in the byte pointed
     55  *								by *ppBitStream. Valid within 0 to 7
     56  * [in] start           start indicates whether the encoding begins with
     57  *                      0th element or 1st.
     58  * [in/out] pLast       pointer to last status flag
     59  * [in] runBeginSingleLevelEntriesL0      The run value from which level
     60  *                                        will be equal to 1: last == 0
     61  * [in] IndexBeginSingleLevelEntriesL0    Array index in the VLC table
     62  *                                        pointing to the
     63  *                                        runBeginSingleLevelEntriesL0
     64  * [in] runBeginSingleLevelEntriesL1      The run value from which level
     65  *                                        will be equal to 1: last == 1
     66  * [in] IndexBeginSingleLevelEntriesL1    Array index in the VLC table
     67  *                                        pointing to the
     68  *                                        runBeginSingleLevelEntriesL0
     69  * [in] pRunIndexTableL0    Run Index table defined in
     70  *                          armVCM4P2_Huff_Tables_VLC.c for last == 0
     71  * [in] pVlcTableL0         VLC table for last == 0
     72  * [in] pRunIndexTableL1    Run Index table defined in
     73  *                          armVCM4P2_Huff_Tables_VLC.c for last == 1
     74  * [in] pVlcTableL1         VLC table for last == 1
     75  * [in] pLMAXTableL0        Level MAX table defined in
     76  *                          armVCM4P2_Huff_Tables_VLC.c for last == 0
     77  * [in] pLMAXTableL1        Level MAX table defined in
     78  *                          armVCM4P2_Huff_Tables_VLC.c for last == 1
     79  * [in] pRMAXTableL0        Run MAX table defined in
     80  *                          armVCM4P2_Huff_Tables_VLC.c for last == 0
     81  * [in] pRMAXTableL1        Run MAX table defined in
     82  *                          armVCM4P2_Huff_Tables_VLC.c for last == 1
     83  * [out]pDst			    pointer to the coefficient buffer of current
     84  *							block. Should be 32-bit aligned
     85  *
     86  * Return Value:
     87  * Standard OMXResult result. See enumeration for possible result codes.
     88  *
     89  */
     90 
     91 OMXResult armVCM4P2_GetVLCBits (
     92               const OMX_U8 **ppBitStream,
     93               OMX_INT * pBitOffset,
     94 			  OMX_S16 * pDst,
     95 			  OMX_INT shortVideoHeader,
     96 			  OMX_U8    start,
     97 			  OMX_U8  * pLast,
     98 			  OMX_U8    runBeginSingleLevelEntriesL0,
     99 			  OMX_U8    maxIndexForMultipleEntriesL0,
    100 			  OMX_U8    maxRunForMultipleEntriesL1,
    101 			  OMX_U8    maxIndexForMultipleEntriesL1,
    102               const OMX_U8  * pRunIndexTableL0,
    103               const ARM_VLC32 *pVlcTableL0,
    104 			  const OMX_U8  * pRunIndexTableL1,
    105               const ARM_VLC32 *pVlcTableL1,
    106               const OMX_U8  * pLMAXTableL0,
    107               const OMX_U8  * pLMAXTableL1,
    108               const OMX_U8  * pRMAXTableL0,
    109               const OMX_U8  * pRMAXTableL1,
    110               const OMX_U8  * pZigzagTable
    111 )
    112 {
    113     OMX_U32 storeRun;
    114     OMX_U8  tabIndex, markerBit;
    115     OMX_S16 storeLevel;
    116     OMX_U16 unpackRetIndex;
    117 	OMX_U8  i, fType, escape;
    118 	OMX_U8  sign = 0;
    119 
    120 	/* Unpacking the bitstream and RLD */
    121     for (i = start; i < 64;)
    122     {
    123 		escape = armLookAheadBits(ppBitStream, pBitOffset, 7);
    124 		if (escape != 3)
    125 		{
    126 			fType = 0; /* Not in escape mode */
    127 		}
    128 		else
    129 		{
    130 			armSkipBits (ppBitStream, pBitOffset, 7);
    131 			if(shortVideoHeader)
    132 			{
    133 			  *pLast = armGetBits(ppBitStream, pBitOffset, 1);
    134 			  storeRun = armGetBits(ppBitStream, pBitOffset, 6);
    135 			  storeLevel = armGetBits(ppBitStream, pBitOffset, 8);
    136 
    137 			  /* Ref to Table B-18 (c) in MPEG4 Standard- FLC code for  */
    138 			  /* LEVEL when short_video_header is 1, the storeLevel is  */
    139 			  /* a signed value and the sign and the unsigned value for */
    140 			  /* storeLevel need to be extracted and passed to arm      */
    141 			  /* FillVLDBuffer function                                 */
    142 
    143 			  sign = (storeLevel & 0x80);
    144 			  if(sign==0x80)
    145 			  {
    146 			  	storeLevel=(storeLevel^0xff)+1;
    147 			  	sign=1;
    148 
    149 			  }
    150 
    151 			  armRetDataErrIf( storeLevel == 0 || sign*storeLevel == 128 , OMX_Sts_Err); /* Invalid FLC */
    152 			  armRetDataErrIf((i + storeRun) >= 64, OMX_Sts_Err);
    153 			  armVCM4P2_FillVLDBuffer(
    154 			    storeRun,
    155 			    pDst,
    156 			    storeLevel,
    157 			    sign,
    158 			    *pLast,
    159 			    &i,
    160 			    pZigzagTable);
    161 			    return OMX_Sts_NoErr;
    162 
    163 			}
    164 			if (armGetBits(ppBitStream, pBitOffset, 1))
    165 			{
    166 				if (armGetBits(ppBitStream, pBitOffset, 1))
    167 				{
    168 					fType = 3;
    169 				}
    170 				else
    171 				{
    172 					fType = 2;
    173 				}
    174 			}
    175 			else
    176 			{
    177 				fType = 1;
    178 			}
    179 		}
    180 
    181 	    if (fType < 3)
    182 	    {
    183 	        unpackRetIndex = armUnPackVLC32(ppBitStream, pBitOffset,
    184 										pVlcTableL0);
    185 			if (unpackRetIndex != ARM_NO_CODEBOOK_INDEX)
    186 		    {
    187 			    /* Decode run and level from the index */
    188 			    /* last = 0 */
    189 			    *pLast = 0;
    190 			    if (unpackRetIndex > maxIndexForMultipleEntriesL0)
    191 			    {
    192 				    storeLevel = 1;
    193 				    storeRun = (unpackRetIndex - maxIndexForMultipleEntriesL0)
    194 							+ runBeginSingleLevelEntriesL0;
    195 			    }
    196 			    else
    197 			    {
    198 				    tabIndex = 1;
    199 				    while (pRunIndexTableL0[tabIndex] <= unpackRetIndex)
    200 				    {
    201 					    tabIndex++;
    202 				    }
    203 				    storeRun = tabIndex - 1;
    204 				    storeLevel = unpackRetIndex - pRunIndexTableL0[tabIndex - 1] + 1;
    205 			    }
    206 			    sign = (OMX_U8) armGetBits(ppBitStream, pBitOffset, 1);
    207 
    208 			    if (fType == 1)
    209 			    {
    210 				    storeLevel = (armAbs(storeLevel) + pLMAXTableL0[storeRun]);
    211 			    }
    212 			    else if (fType == 2)
    213 			    {
    214 				    storeRun = storeRun + pRMAXTableL0[storeLevel-1] + 1;
    215 			    }
    216 		    }
    217 		    else
    218 		    {
    219 			    unpackRetIndex = armUnPackVLC32(ppBitStream, pBitOffset,
    220 											pVlcTableL1);
    221 
    222 			    armRetDataErrIf(unpackRetIndex == ARM_NO_CODEBOOK_INDEX, OMX_Sts_Err);
    223 
    224 			    /* Decode run and level from the index */
    225 			    /* last = 1 */
    226 			    *pLast = 1;
    227 			    if (unpackRetIndex > maxIndexForMultipleEntriesL1)
    228 			    {
    229 				    storeLevel = 1;
    230 				    storeRun = (unpackRetIndex - maxIndexForMultipleEntriesL1)
    231 							+ maxRunForMultipleEntriesL1;
    232 		        }
    233 		        else
    234 			    {
    235 				    tabIndex = 1;
    236 				    while (pRunIndexTableL1[tabIndex] <= unpackRetIndex)
    237 				    {
    238 					    tabIndex++;
    239 				    }
    240 				    storeRun = tabIndex - 1;
    241 				    storeLevel = unpackRetIndex - pRunIndexTableL1[tabIndex - 1] + 1;
    242 			    }
    243 			    sign = (OMX_U8) armGetBits(ppBitStream, pBitOffset, 1);
    244 
    245 			    if (fType == 1)
    246 			    {
    247 			        storeLevel = (armAbs(storeLevel) + pLMAXTableL1[storeRun]);
    248 			    }
    249 			    else if (fType == 2)
    250 			    {
    251 				    storeRun = storeRun + pRMAXTableL1[storeLevel-1] + 1;
    252 			    }
    253 		    }
    254             armRetDataErrIf((i + storeRun) >= 64, OMX_Sts_Err);
    255 		    armVCM4P2_FillVLDBuffer(
    256 			    storeRun,
    257 			    pDst,
    258 			    storeLevel,
    259 			    sign,
    260 			    *pLast,
    261 			    &i,
    262 			    pZigzagTable);
    263 	    }
    264 	    else
    265 	    {
    266 		    *pLast = armGetBits(ppBitStream, pBitOffset, 1);
    267 		    storeRun  = armGetBits(ppBitStream, pBitOffset, 6);
    268 		    armRetDataErrIf((i + storeRun) >= 64, OMX_Sts_Err);
    269 		    markerBit = armGetBits(ppBitStream, pBitOffset, 1);
    270 		    armRetDataErrIf( markerBit == 0, OMX_Sts_Err);
    271 		    storeLevel  = armGetBits(ppBitStream, pBitOffset, 12);
    272 		    if (storeLevel & 0x800)
    273 		    {
    274 			    storeLevel -= 4096;
    275 		    }
    276 		    armRetDataErrIf( storeLevel == 0 || storeLevel == -2048 , OMX_Sts_Err); /* Invalid FLC */
    277 		    armGetBits(ppBitStream, pBitOffset, 1);
    278 		    armVCM4P2_FillVLDBuffer(
    279 			    storeRun,
    280 			    pDst,
    281 			    storeLevel,
    282 			    0, /* Sign is not used, preprocessing done */
    283 			    *pLast,
    284 			    &i,
    285 			    pZigzagTable);
    286 
    287 	    }
    288     } /* End of forloop for i */
    289 	return OMX_Sts_NoErr;
    290 }
    291 
    292 /* End of File */
    293 
    294