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:  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