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; /* points to first bit beyond the 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 
92 #define EXCEED_OFFSET(ps_bitstrm) \
93   (ps_bitstrm->u4_ofst > ps_bitstrm->u4_max_ofst)
94 #define CHECK_BITS_SUFFICIENT(ps_bitstrm, bits_to_read) \
95   (ps_bitstrm->u4_ofst + bits_to_read <= ps_bitstrm->u4_max_ofst)
96 #define MORE_RBSP_DATA(ps_bitstrm) \
97     CHECK_BITS_SUFFICIENT(ps_bitstrm, 1)
98 
99 void GoToByteBoundary(dec_bit_stream_t * ps_bitstrm);
100 UWORD8 ih264d_check_byte_aligned(dec_bit_stream_t * ps_bitstrm);
101 
102 /*****************************************************************************/
103 /* Define a macro for inlining of GETBIT:                                    */
104 /*****************************************************************************/
105 #define   GETBIT(u4_code, u4_offset, pu4_bitstream)                         \
106 {                                                                           \
107     UWORD32 *pu4_buf =  (pu4_bitstream);                                    \
108     UWORD32 u4_word_off = ((u4_offset) >> 5);                               \
109     UWORD32 u4_bit_off = (u4_offset) & 0x1F;                                \
110     u4_code = pu4_buf[u4_word_off] << u4_bit_off;                           \
111     (u4_offset)++;                                                          \
112     u4_code = (u4_code >> 31);                                              \
113 }
114 
115 
116 
117 /*****************************************************************************/
118 /* Define a macro for inlining of GETBITS: u4_no_bits shall not exceed 32    */
119 /*****************************************************************************/
120 #define     GETBITS(u4_code, u4_offset, pu4_bitstream, u4_no_bits)          \
121 {                                                                           \
122     UWORD32 *pu4_buf =  (pu4_bitstream);                                    \
123     UWORD32 u4_word_off = ((u4_offset) >> 5);                               \
124     UWORD32 u4_bit_off = (u4_offset) & 0x1F;                                \
125     u4_code = pu4_buf[u4_word_off++] << u4_bit_off;                         \
126                                                                             \
127     if(u4_bit_off)                                                          \
128         u4_code |= (pu4_buf[u4_word_off] >> (INT_IN_BITS - u4_bit_off));    \
129     u4_code = u4_code >> (INT_IN_BITS - u4_no_bits);                        \
130     (u4_offset) += u4_no_bits;                                              \
131 }                                                                           \
132                                                                             \
133 
134 /*****************************************************************************/
135 /* Define a macro for inlining of NEXTBITS                                   */
136 /*****************************************************************************/
137 #define     NEXTBITS(u4_word, u4_offset, pu4_bitstream, u4_no_bits)         \
138 {                                                                           \
139     UWORD32 *pu4_buf =  (pu4_bitstream);                                    \
140     UWORD32 u4_word_off = ((u4_offset) >> 5);                               \
141     UWORD32 u4_bit_off = (u4_offset) & 0x1F;                                \
142     u4_word = pu4_buf[u4_word_off++] << u4_bit_off;                         \
143     if(u4_bit_off)                                                          \
144         u4_word |= (pu4_buf[u4_word_off] >> (INT_IN_BITS - u4_bit_off));    \
145     u4_word = u4_word >> (INT_IN_BITS - u4_no_bits);                        \
146 }
147 /*****************************************************************************/
148 /* Define a macro for inlining of NEXTBITS_32                                */
149 /*****************************************************************************/
150 #define     NEXTBITS_32(u4_word, u4_offset, pu4_bitstream)                  \
151 {                                                                           \
152     UWORD32 *pu4_buf =  (pu4_bitstream);                                    \
153     UWORD32 u4_word_off = ((u4_offset) >> 5);                               \
154     UWORD32 u4_bit_off = (u4_offset) & 0x1F;                                \
155                                                                             \
156     u4_word = pu4_buf[u4_word_off++] << u4_bit_off;                         \
157     if(u4_bit_off)                                                          \
158     u4_word |= (pu4_buf[u4_word_off] >> (INT_IN_BITS - u4_bit_off));        \
159 }
160 
161 
162 /*****************************************************************************/
163 /* Define a macro for inlining of FIND_ONE_IN_STREAM_32                      */
164 /*****************************************************************************/
165 #define   FIND_ONE_IN_STREAM_32(u4_ldz, u4_offset, pu4_bitstream)           \
166 {                                                                           \
167     UWORD32 u4_word;                                                        \
168     NEXTBITS_32(u4_word, u4_offset, pu4_bitstream);                         \
169     u4_ldz = CLZ(u4_word);                                     \
170     (u4_offset) += (u4_ldz + 1);                                            \
171 }
172 
173 /*****************************************************************************/
174 /* Define a macro for inlining of FIND_ONE_IN_STREAM_LEN                     */
175 /*****************************************************************************/
176 #define   FIND_ONE_IN_STREAM_LEN(u4_ldz, u4_offset, pu4_bitstream, u4_len)  \
177 {                                                                           \
178     UWORD32 u4_word;                                                        \
179     NEXTBITS_32(u4_word, u4_offset, pu4_bitstream);                         \
180     u4_ldz = CLZ(u4_word);                                     \
181     if(u4_ldz < u4_len)                                                     \
182     (u4_offset) += (u4_ldz + 1);                                            \
183     else                                                                    \
184     {                                                                       \
185         u4_ldz = u4_len;                                                    \
186         (u4_offset) += u4_ldz;                                              \
187     }                                                                       \
188 }
189 
190 /*****************************************************************************/
191 /* Define a macro for inlining of FLUSHBITS                                  */
192 /*****************************************************************************/
193 #define   FLUSHBITS(u4_offset, u4_no_bits)                                  \
194 {                                                                           \
195         (u4_offset) += (u4_no_bits);                                        \
196 }
197 
198 #endif  /* _BITSTREAM_H_ */
199