1 /** 2 * 3 * File Name: armCOMM_Bitstream.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 * Defines bitstream encode and decode functions common to all codecs 13 */ 14 15 #include "omxtypes.h" 16 #include "armCOMM.h" 17 #include "armCOMM_Bitstream.h" 18 19 /*************************************** 20 * Fixed bit length Decode 21 ***************************************/ 22 23 /** 24 * Function: armLookAheadBits() 25 * 26 * Description: 27 * Get the next N bits from the bitstream without advancing the bitstream pointer 28 * 29 * Parameters: 30 * [in] **ppBitStream 31 * [in] *pOffset 32 * [in] N=1...32 33 * 34 * Returns Value 35 */ 36 37 OMX_U32 armLookAheadBits(const OMX_U8 **ppBitStream, OMX_INT *pOffset, OMX_INT N) 38 { 39 const OMX_U8 *pBitStream = *ppBitStream; 40 OMX_INT Offset = *pOffset; 41 OMX_U32 Value; 42 43 armAssert(Offset>=0 && Offset<=7); 44 armAssert(N>=1 && N<=32); 45 46 /* Read next 32 bits from stream */ 47 Value = (pBitStream[0] << 24 ) | ( pBitStream[1] << 16) | (pBitStream[2] << 8 ) | (pBitStream[3]) ; 48 Value = (Value << Offset ) | (pBitStream[4] >> (8-Offset)); 49 50 /* Return N bits */ 51 return Value >> (32-N); 52 } 53 54 55 /** 56 * Function: armGetBits() 57 * 58 * Description: 59 * Read N bits from the bitstream 60 * 61 * Parameters: 62 * [in] *ppBitStream 63 * [in] *pOffset 64 * [in] N=1..32 65 * 66 * [out] *ppBitStream 67 * [out] *pOffset 68 * Returns Value 69 */ 70 71 72 OMX_U32 armGetBits(const OMX_U8 **ppBitStream, OMX_INT *pOffset, OMX_INT N) 73 { 74 const OMX_U8 *pBitStream = *ppBitStream; 75 OMX_INT Offset = *pOffset; 76 OMX_U32 Value; 77 78 if(N == 0) 79 { 80 return 0; 81 } 82 83 armAssert(Offset>=0 && Offset<=7); 84 armAssert(N>=1 && N<=32); 85 86 /* Read next 32 bits from stream */ 87 Value = (pBitStream[0] << 24 ) | ( pBitStream[1] << 16) | (pBitStream[2] << 8 ) | (pBitStream[3]) ; 88 Value = (Value << Offset ) | (pBitStream[4] >> (8-Offset)); 89 90 /* Advance bitstream pointer by N bits */ 91 Offset += N; 92 *ppBitStream = pBitStream + (Offset>>3); 93 *pOffset = Offset & 7; 94 95 /* Return N bits */ 96 return Value >> (32-N); 97 } 98 99 /** 100 * Function: armByteAlign() 101 * 102 * Description: 103 * Align the pointer *ppBitStream to the next byte boundary 104 * 105 * Parameters: 106 * [in] *ppBitStream 107 * [in] *pOffset 108 * 109 * [out] *ppBitStream 110 * [out] *pOffset 111 * 112 **/ 113 114 OMXVoid armByteAlign(const OMX_U8 **ppBitStream,OMX_INT *pOffset) 115 { 116 if(*pOffset > 0) 117 { 118 *ppBitStream += 1; 119 *pOffset = 0; 120 } 121 } 122 123 /** 124 * Function: armSkipBits() 125 * 126 * Description: 127 * Skip N bits from the value at *ppBitStream 128 * 129 * Parameters: 130 * [in] *ppBitStream 131 * [in] *pOffset 132 * [in] N 133 * 134 * [out] *ppBitStream 135 * [out] *pOffset 136 * 137 **/ 138 139 140 OMXVoid armSkipBits(const OMX_U8 **ppBitStream,OMX_INT *pOffset,OMX_INT N) 141 { 142 OMX_INT Offset = *pOffset; 143 const OMX_U8 *pBitStream = *ppBitStream; 144 145 /* Advance bitstream pointer by N bits */ 146 Offset += N; 147 *ppBitStream = pBitStream + (Offset>>3); 148 *pOffset = Offset & 7; 149 } 150 151 /*************************************** 152 * Variable bit length Decode 153 ***************************************/ 154 155 /** 156 * Function: armUnPackVLC32() 157 * 158 * Description: 159 * Variable length decode of variable length symbol (max size 32 bits) read from 160 * the bit stream pointed by *ppBitStream at *pOffset by using the table 161 * pointed by pCodeBook 162 * 163 * Parameters: 164 * [in] *pBitStream 165 * [in] *pOffset 166 * [in] pCodeBook 167 * 168 * [out] *pBitStream 169 * [out] *pOffset 170 * 171 * Returns : Code Book Index if successfull. 172 * : ARM_NO_CODEBOOK_INDEX = -1 if search fails. 173 **/ 174 #ifndef C_OPTIMIZED_IMPLEMENTATION 175 176 OMX_U16 armUnPackVLC32( 177 const OMX_U8 **ppBitStream, 178 OMX_INT *pOffset, 179 const ARM_VLC32 *pCodeBook 180 ) 181 { 182 const OMX_U8 *pBitStream = *ppBitStream; 183 OMX_INT Offset = *pOffset; 184 OMX_U32 Value; 185 OMX_INT Index; 186 187 armAssert(Offset>=0 && Offset<=7); 188 189 /* Read next 32 bits from stream */ 190 Value = (pBitStream[0] << 24 ) | ( pBitStream[1] << 16) | (pBitStream[2] << 8 ) | (pBitStream[3]) ; 191 Value = (Value << Offset ) | (pBitStream[4] >> (8-Offset)); 192 193 /* Search through the codebook */ 194 for (Index=0; pCodeBook->codeLen != 0; Index++) 195 { 196 if (pCodeBook->codeWord == (Value >> (32 - pCodeBook->codeLen))) 197 { 198 Offset = Offset + pCodeBook->codeLen; 199 *ppBitStream = pBitStream + (Offset >> 3) ; 200 *pOffset = Offset & 7; 201 202 return Index; 203 } 204 pCodeBook++; 205 } 206 207 /* No code match found */ 208 return ARM_NO_CODEBOOK_INDEX; 209 } 210 211 #endif 212 213 /*************************************** 214 * Fixed bit length Encode 215 ***************************************/ 216 217 /** 218 * Function: armPackBits 219 * 220 * Description: 221 * Pack a VLC code word into the bitstream 222 * 223 * Remarks: 224 * 225 * Parameters: 226 * [in] ppBitStream pointer to the pointer to the current byte 227 * in the bit stream. 228 * [in] pOffset pointer to the bit position in the byte 229 * pointed by *ppBitStream. Valid within 0 230 * to 7. 231 * [in] codeWord Code word that need to be inserted in to the 232 * bitstream 233 * [in] codeLength Length of the code word valid range 1...32 234 * 235 * [out] ppBitStream *ppBitStream is updated after the block is encoded, 236 * so that it points to the current byte in the bit 237 * stream buffer. 238 * [out] pBitOffset *pBitOffset is updated so that it points to the 239 * current bit position in the byte pointed by 240 * *ppBitStream. 241 * 242 * Return Value: 243 * Standard OMX_RESULT result. See enumeration for possible result codes. 244 * 245 */ 246 247 OMXResult armPackBits ( 248 OMX_U8 **ppBitStream, 249 OMX_INT *pOffset, 250 OMX_U32 codeWord, 251 OMX_INT codeLength 252 ) 253 { 254 OMX_U8 *pBitStream = *ppBitStream; 255 OMX_INT Offset = *pOffset; 256 OMX_U32 Value; 257 258 /* checking argument validity */ 259 armRetArgErrIf(Offset < 0, OMX_Sts_BadArgErr); 260 armRetArgErrIf(Offset > 7, OMX_Sts_BadArgErr); 261 armRetArgErrIf(codeLength < 1, OMX_Sts_BadArgErr); 262 armRetArgErrIf(codeLength > 32, OMX_Sts_BadArgErr); 263 264 /* Prepare the first byte */ 265 codeWord = codeWord << (32-codeLength); 266 Value = (pBitStream[0] >> (8-Offset)) << (8-Offset); 267 Value = Value | (codeWord >> (24+Offset)); 268 269 /* Write out whole bytes */ 270 while (8-Offset <= codeLength) 271 { 272 *pBitStream++ = (OMX_U8)Value; 273 codeWord = codeWord << (8-Offset); 274 codeLength = codeLength - (8-Offset); 275 Offset = 0; 276 Value = codeWord >> 24; 277 } 278 279 /* Write out final partial byte */ 280 *pBitStream = (OMX_U8)Value; 281 *ppBitStream = pBitStream; 282 *pOffset = Offset + codeLength; 283 284 return OMX_Sts_NoErr; 285 } 286 287 /*************************************** 288 * Variable bit length Encode 289 ***************************************/ 290 291 /** 292 * Function: armPackVLC32 293 * 294 * Description: 295 * Pack a VLC code word into the bitstream 296 * 297 * Remarks: 298 * 299 * Parameters: 300 * [in] ppBitStream pointer to the pointer to the current byte 301 * in the bit stream. 302 * [in] pBitOffset pointer to the bit position in the byte 303 * pointed by *ppBitStream. Valid within 0 304 * to 7. 305 * [in] code VLC code word that need to be inserted in to the 306 * bitstream 307 * 308 * [out] ppBitStream *ppBitStream is updated after the block is encoded, 309 * so that it points to the current byte in the bit 310 * stream buffer. 311 * [out] pBitOffset *pBitOffset is updated so that it points to the 312 * current bit position in the byte pointed by 313 * *ppBitStream. 314 * 315 * Return Value: 316 * Standard OMX_RESULT result. See enumeration for possible result codes. 317 * 318 */ 319 320 OMXResult armPackVLC32 ( 321 OMX_U8 **ppBitStream, 322 OMX_INT *pBitOffset, 323 ARM_VLC32 code 324 ) 325 { 326 return (armPackBits(ppBitStream, pBitOffset, code.codeWord, code.codeLen)); 327 } 328 329 /*End of File*/ 330