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