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