Home | History | Annotate | Download | only in decoder
      1 /******************************************************************************
      2  *
      3  * Copyright (C) 2015 The Android Open Source Project
      4  *
      5  * Licensed under the Apache License, Version 2.0 (the "License");
      6  * you may not use this file except in compliance with the License.
      7  * You may obtain a copy of the License at:
      8  *
      9  * http://www.apache.org/licenses/LICENSE-2.0
     10  *
     11  * Unless required by applicable law or agreed to in writing, software
     12  * distributed under the License is distributed on an "AS IS" BASIS,
     13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     14  * See the License for the specific language governing permissions and
     15  * limitations under the License.
     16  *
     17  *****************************************************************************
     18  * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
     19 */
     20 
     21 #ifndef _IH264D_BITSTRM_H_
     22 #define _IH264D_BITSTRM_H_
     23 /*!
     24  *************************************************************************
     25  * \file ih264d_bitstrm.h
     26  *
     27  * \brief
     28  *  Contains all the declarations of bitstream reading routines
     29  *
     30  * \date
     31  *    20/11/2002
     32  *
     33  * \author  AI
     34  *************************************************************************
     35  */
     36 
     37 /* Includes */
     38 #include <stdio.h>
     39 #include <stdlib.h>
     40 #include "ih264_typedefs.h"
     41 #include "ih264_macros.h"
     42 #include "ih264_platform_macros.h"
     43 
     44 #define INT_IN_BYTES        4
     45 #define INT_IN_BITS         32
     46 
     47 /* Based on level 1.2 of baseline profile */
     48 /* 396[MAX_FS] * 128 * 1.5 [ChromaFormatParameter] / sizeof(UWORD32)
     49  i.e  396 * 128 * 1.5 / 4 = 19008 */
     50 /* Based on level 3 of main profile */
     51 /* 1620[MAX_FS] * 128 * 1.5 [ChromaFormatParameter] / sizeof(UWORD32)
     52  i.e  1620 * 128 * 1.5 / 4= 77760 */
     53 #define SIZE_OF_BUFFER      77760
     54 
     55 /* Structure for the ps_bitstrm */
     56 typedef struct
     57 {
     58     UWORD32 u4_ofst; /* Offset in the buffer for the current bit */
     59     UWORD32 *pu4_buffer; /* Bitstream Buffer  */
     60     UWORD32 u4_max_ofst; /* Position of the last bit read in the current buffer */
     61     void * pv_codec_handle; /* For Error Handling */
     62 } dec_bit_stream_t;
     63 
     64 /* To read the next bit */
     65 UWORD8 ih264d_get_bit_h264(dec_bit_stream_t *);
     66 
     67 /* To read the next specified number of bits */
     68 UWORD32 ih264d_get_bits_h264(dec_bit_stream_t *, UWORD32);
     69 
     70 /* To see the next specified number of bits */
     71 UWORD32 ih264d_next_bits_h264(dec_bit_stream_t *, UWORD32);
     72 
     73 /* To flush a specified number of bits*/
     74 WORD32 ih264d_flush_bits_h264(dec_bit_stream_t *, WORD32);
     75 
     76 /*!
     77  **************************************************************************
     78  * \if Function name : MoreRbspData \endif
     79  *
     80  * \brief
     81  *    Determines whether there is more data in RBSP or not.
     82  *
     83  * \param ps_bitstrm : Pointer to bitstream
     84  *
     85  * \return
     86  *    Returns 1 if there is more data in RBSP before rbsp_trailing_bits().
     87  *    Otherwise it returns FALSE.
     88  **************************************************************************
     89  */
     90 
     91 #define MORE_RBSP_DATA(ps_bitstrm) \
     92   (ps_bitstrm->u4_ofst < ps_bitstrm->u4_max_ofst)
     93 #define EXCEED_OFFSET(ps_bitstrm) \
     94   (ps_bitstrm->u4_ofst > ps_bitstrm->u4_max_ofst)
     95 
     96 void GoToByteBoundary(dec_bit_stream_t * ps_bitstrm);
     97 UWORD8 ih264d_check_byte_aligned(dec_bit_stream_t * ps_bitstrm);
     98 
     99 /*****************************************************************************/
    100 /* Define a macro for inlining of GETBIT:                                    */
    101 /*****************************************************************************/
    102 #define   GETBIT(u4_code, u4_offset, pu4_bitstream)                         \
    103 {                                                                           \
    104     UWORD32 *pu4_buf =  (pu4_bitstream);                                    \
    105     UWORD32 u4_word_off = ((u4_offset) >> 5);                               \
    106     UWORD32 u4_bit_off = (u4_offset) & 0x1F;                                \
    107     u4_code = pu4_buf[u4_word_off] << u4_bit_off;                           \
    108     (u4_offset)++;                                                          \
    109     u4_code = (u4_code >> 31);                                              \
    110 }
    111 
    112 
    113 
    114 /*****************************************************************************/
    115 /* Define a macro for inlining of GETBITS: u4_no_bits shall not exceed 32    */
    116 /*****************************************************************************/
    117 #define     GETBITS(u4_code, u4_offset, pu4_bitstream, u4_no_bits)          \
    118 {                                                                           \
    119     UWORD32 *pu4_buf =  (pu4_bitstream);                                    \
    120     UWORD32 u4_word_off = ((u4_offset) >> 5);                               \
    121     UWORD32 u4_bit_off = (u4_offset) & 0x1F;                                \
    122     u4_code = pu4_buf[u4_word_off++] << u4_bit_off;                         \
    123                                                                             \
    124     if(u4_bit_off)                                                          \
    125         u4_code |= (pu4_buf[u4_word_off] >> (INT_IN_BITS - u4_bit_off));    \
    126     u4_code = u4_code >> (INT_IN_BITS - u4_no_bits);                        \
    127     (u4_offset) += u4_no_bits;                                              \
    128 }                                                                           \
    129                                                                             \
    130 
    131 /*****************************************************************************/
    132 /* Define a macro for inlining of NEXTBITS                                   */
    133 /*****************************************************************************/
    134 #define     NEXTBITS(u4_word, u4_offset, pu4_bitstream, u4_no_bits)         \
    135 {                                                                           \
    136     UWORD32 *pu4_buf =  (pu4_bitstream);                                    \
    137     UWORD32 u4_word_off = ((u4_offset) >> 5);                               \
    138     UWORD32 u4_bit_off = (u4_offset) & 0x1F;                                \
    139     u4_word = pu4_buf[u4_word_off++] << u4_bit_off;                         \
    140     if(u4_bit_off)                                                          \
    141         u4_word |= (pu4_buf[u4_word_off] >> (INT_IN_BITS - u4_bit_off));    \
    142     u4_word = u4_word >> (INT_IN_BITS - u4_no_bits);                        \
    143 }
    144 /*****************************************************************************/
    145 /* Define a macro for inlining of NEXTBITS_32                                */
    146 /*****************************************************************************/
    147 #define     NEXTBITS_32(u4_word, u4_offset, pu4_bitstream)                  \
    148 {                                                                           \
    149     UWORD32 *pu4_buf =  (pu4_bitstream);                                    \
    150     UWORD32 u4_word_off = ((u4_offset) >> 5);                               \
    151     UWORD32 u4_bit_off = (u4_offset) & 0x1F;                                \
    152                                                                             \
    153     u4_word = pu4_buf[u4_word_off++] << u4_bit_off;                         \
    154     if(u4_bit_off)                                                          \
    155     u4_word |= (pu4_buf[u4_word_off] >> (INT_IN_BITS - u4_bit_off));        \
    156 }
    157 
    158 
    159 /*****************************************************************************/
    160 /* Define a macro for inlining of FIND_ONE_IN_STREAM_32                      */
    161 /*****************************************************************************/
    162 #define   FIND_ONE_IN_STREAM_32(u4_ldz, u4_offset, pu4_bitstream)           \
    163 {                                                                           \
    164     UWORD32 u4_word;                                                        \
    165     NEXTBITS_32(u4_word, u4_offset, pu4_bitstream);                         \
    166     u4_ldz = CLZ(u4_word);                                     \
    167     (u4_offset) += (u4_ldz + 1);                                            \
    168 }
    169 
    170 /*****************************************************************************/
    171 /* Define a macro for inlining of FIND_ONE_IN_STREAM_LEN                     */
    172 /*****************************************************************************/
    173 #define   FIND_ONE_IN_STREAM_LEN(u4_ldz, u4_offset, pu4_bitstream, u4_len)  \
    174 {                                                                           \
    175     UWORD32 u4_word;                                                        \
    176     NEXTBITS_32(u4_word, u4_offset, pu4_bitstream);                         \
    177     u4_ldz = CLZ(u4_word);                                     \
    178     if(u4_ldz < u4_len)                                                     \
    179     (u4_offset) += (u4_ldz + 1);                                            \
    180     else                                                                    \
    181     {                                                                       \
    182         u4_ldz = u4_len;                                                    \
    183         (u4_offset) += u4_ldz;                                              \
    184     }                                                                       \
    185 }
    186 
    187 /*****************************************************************************/
    188 /* Define a macro for inlining of FLUSHBITS                                  */
    189 /*****************************************************************************/
    190 #define   FLUSHBITS(u4_offset, u4_no_bits)                                  \
    191 {                                                                           \
    192         (u4_offset) += (u4_no_bits);                                        \
    193 }
    194 
    195 #endif  /* _BITSTREAM_H_ */
    196