Home | History | Annotate | Download | only in src
      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