xref: /aosp_15_r20/external/libavc/encoder/ih264e_bitstream.h (revision 495ae853bb871d1e5a258cb02c2cc13cde8ddb9a)
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