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