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 /**
22 *******************************************************************************
23 * @file
24 * ih264e_bitstream.h
25 *
26 * @brief
27 * This file contains encoder bitstream engine related structures and
28 * interface prototypes
29 *
30 * @author
31 * ittiam
32 *
33 * @remarks
34 * none
35 *
36 *******************************************************************************
37 */
38
39 #ifndef _IH264E_BITSTREAM_H_
40 #define _IH264E_BITSTREAM_H_
41
42 /*****************************************************************************/
43 /* Constant Macros */
44 /*****************************************************************************/
45
46 /**
47 ******************************************************************************
48 * @brief defines the maximum number of bits in a bitstream word
49 ******************************************************************************
50 */
51 #define WORD_SIZE 32
52
53 /**
54 ******************************************************************************
55 * @brief The number of consecutive zero bytes for emulation prevention check
56 ******************************************************************************
57 */
58 #define EPB_ZERO_BYTES 2
59
60 /**
61 ******************************************************************************
62 * @brief Emulation prevention insertion byte
63 ******************************************************************************
64 */
65 #define EPB_BYTE 0x03
66
67
68 /**
69 ******************************************************************************
70 * @brief Stream buffer allocated per frame should be atleast MIN_STREAM_SIZE
71 ******************************************************************************
72 */
73 #define MIN_STREAM_SIZE 0x800
74
75
76 /*****************************************************************************/
77 /* Function Macros */
78 /*****************************************************************************/
79
80 /**
81 ******************************************************************************
82 * @brief Macro to check if emulation prevention byte insertion is required
83 ******************************************************************************
84 */
85 #define SHOULD_INSERT_EPB(zero_run, next_byte) \
86 ((zero_run) == EPB_ZERO_BYTES) && (0 == ((next_byte) & 0xFC))
87
88 /**
89 ******************************************************************************
90 * @brief returns the bit position of a leading 1 (msb) in a code value
91 ******************************************************************************
92 */
93 #if !MSVC
94 #define GETRANGE(r,value) \
95 { \
96 r = 0; \
97 if(0 == value) \
98 r = 1; \
99 else \
100 { \
101 r = 32-CLZ(value); \
102 }\
103 }
104 #else
105 #define GETRANGE(r,value) \
106 { \
107 unsigned long msb_one_bit = 0; \
108 r = _BitScanReverse(&msb_one_bit, value) ? (UWORD32)(msb_one_bit + 1) : 1 ; \
109 }
110 #endif
111
112 /**
113 ******************************************************************************
114 * @brief returns bits required to code a value
115 ******************************************************************************
116 */
117 #define UE_LENGTH(bits,x) \
118 { \
119 UWORD32 r_bit; \
120 GETRANGE(r_bit,x+1) \
121 bits =(((r_bit - 1) << 1)+1);\
122 } \
123
124 /**
125 ******************************************************************************
126 * @brief Inserts 1 byte and Emulation Prevention Byte(if any) into bitstream
127 * Increments the stream offset and zero run correspondingly
128 ******************************************************************************
129 */
130 #define PUTBYTE_EPB(ptr,off,byte,zero_run) \
131 { \
132 if( SHOULD_INSERT_EPB(zero_run, byte) ) \
133 { \
134 ptr[off] = EPB_BYTE; \
135 off++; \
136 zero_run = 0; \
137 } \
138 \
139 ptr[off] = byte; \
140 off++; \
141 zero_run = byte ? 0 : zero_run+1; \
142 } \
143
144 /**
145 ******************************************************************************
146 * @brief Ensures Byte alignment of the slice header
147 ******************************************************************************
148 */
149 #define BYTE_ALIGNMENT(ps_bitstrm) ih264e_put_rbsp_trailing_bits(ps_bitstrm)
150
151 /**
152 ******************************************************************************
153 * @brief Gets number of bits coded
154 ******************************************************************************
155 */
156
157 #define GET_NUM_BITS(ps_bitstream) ((ps_bitstream->u4_strm_buf_offset << 3) \
158 + 32 - ps_bitstream->i4_bits_left_in_cw);
159
160
161
162 /**
163 ******************************************************************************
164 * @macro Align bitstream to byte - Remainig bits are filled with '1'
165 ******************************************************************************
166 */
167 #define BITSTREAM_BYTE_ALIGN(ps_bitstrm) \
168 if (ps_bitstrm->i4_bits_left_in_cw & 0x07) \
169 { \
170 const WORD32 len = (WORD32)((ps_bitstrm->i4_bits_left_in_cw) & 0x07);\
171 ih264e_put_bits(ps_bitstrm, (UWORD32)((1 << len) - 1), len); \
172 } \
173
174
175 /*****************************************************************************/
176 /* Structures */
177 /*****************************************************************************/
178
179 /**
180 ******************************************************************************
181 * @brief Bitstream context for encoder
182 ******************************************************************************
183 */
184 typedef struct bitstrm
185 {
186 /** points to start of stream buffer. */
187 UWORD8 *pu1_strm_buffer;
188
189 /**
190 * max bitstream size (in bytes).
191 * Encoded stream shall not exceed this size.
192 */
193 UWORD32 u4_max_strm_size;
194
195 /**
196 * byte offset (w.r.t pu1_strm_buffer) where next byte would be written
197 * Bitstream engine makes sure it would not corrupt data beyond
198 * u4_max_strm_size bytes
199 */
200 UWORD32 u4_strm_buf_offset;
201
202 /**
203 * current bitstream word; It is a scratch word containing max of
204 * WORD_SIZE bits. Will be copied to stream buffer when the word is
205 * full
206 */
207 UWORD32 u4_cur_word;
208
209 /**
210 * signifies number of bits available in u4_cur_word
211 * bits from msb to i4_bits_left_in_cw of u4_cur_word have already been
212 * inserted next bits would be inserted from pos [i4_bits_left_in_cw-1]
213 * Range of this variable [1 : WORD_SIZE]
214 */
215 WORD32 i4_bits_left_in_cw;
216
217 /**
218 * signifies the number of consecutive zero bytes propogated from previous
219 * word. It is used for emulation prevention byte insertion in the stream
220 */
221 WORD32 i4_zero_bytes_run;
222
223 } bitstrm_t;
224
225
226 /**
227 ******************************************************************************
228 * @brief Inserts 1 byte and Emulation Prevention Byte(if any) into bitstream
229 * Increments the stream offset and zero run correspondingly
230 ******************************************************************************
231 */
ih264e_put_byte_epb(bitstrm_t * ps_bitstrm,UWORD8 byte)232 static inline IH264E_ERROR_T ih264e_put_byte_epb(bitstrm_t *ps_bitstrm, UWORD8 byte)
233 {
234 if (SHOULD_INSERT_EPB(ps_bitstrm->i4_zero_bytes_run, byte))
235 {
236 if ((ps_bitstrm->u4_strm_buf_offset + 1) >= ps_bitstrm->u4_max_strm_size)
237 {
238 return IH264E_BITSTREAM_BUFFER_OVERFLOW;
239 }
240 ps_bitstrm->pu1_strm_buffer[ps_bitstrm->u4_strm_buf_offset++] = EPB_BYTE;
241 ps_bitstrm->i4_zero_bytes_run = 0;
242 }
243
244 if ((ps_bitstrm->u4_strm_buf_offset + 1) >= ps_bitstrm->u4_max_strm_size)
245 {
246 return IH264E_BITSTREAM_BUFFER_OVERFLOW;
247 }
248 ps_bitstrm->pu1_strm_buffer[ps_bitstrm->u4_strm_buf_offset++] = byte;
249 ps_bitstrm->i4_zero_bytes_run = byte ? 0 : ps_bitstrm->i4_zero_bytes_run + 1;
250
251 return IH264E_SUCCESS;
252 }
253
254 /**
255 ******************************************************************************
256 * flush the bits in cur word byte by byte and copy to stream *
257 * (current word is assumed to be byte aligned) *
258 ******************************************************************************
259 */
260 #define BITSTREAM_FLUSH(ps_bitstrm, err) \
261 { \
262 WORD32 i; \
263 for (i = WORD_SIZE; i > ps_bitstrm->i4_bits_left_in_cw; i -= 8) \
264 { \
265 UWORD8 u1_next_byte = (ps_bitstrm->u4_cur_word >> (i - 8)) & 0xFF; \
266 err |= ih264e_put_byte_epb(ps_bitstrm, u1_next_byte); \
267 } \
268 if (err == IH264E_SUCCESS) { \
269 ps_bitstrm->u4_cur_word = 0; \
270 ps_bitstrm->i4_bits_left_in_cw = WORD_SIZE; \
271 } \
272 }
273
274
275 /*****************************************************************************/
276 /* Function Declarations */
277 /*****************************************************************************/
278
279 IH264E_ERROR_T ih264e_bitstrm_init(bitstrm_t *ps_bitstrm,
280 UWORD8 *pu1_bitstrm_buf,
281 UWORD32 u4_max_bitstrm_size);
282
283 IH264E_ERROR_T ih264e_put_bits(bitstrm_t *ps_bitstrm, UWORD32 u4_code_val,
284 WORD32 code_len);
285
286 IH264E_ERROR_T ih264e_put_bit(bitstrm_t *ps_bitstrm, UWORD32 u4_code_val);
287
288 IH264E_ERROR_T ih264e_put_rbsp_trailing_bits(bitstrm_t *ps_bitstrm);
289
290 IH264E_ERROR_T ih264e_put_uev(bitstrm_t *ps_bitstrm, UWORD32 u4_code_num);
291
292 IH264E_ERROR_T ih264e_put_sev(bitstrm_t *ps_bitstrm, WORD32 syntax_elem);
293
294 IH264E_ERROR_T ih264e_put_nal_start_code_prefix(bitstrm_t *ps_bitstrm,
295 WORD32 insert_leading_zero_8bits);
296
297 #endif /* _IH264E_BITSTREAM_H_ */
298