xref: /aosp_15_r20/external/libavc/encoder/ih264e_bitstream.c (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.c
25 *
26 * @brief
27 *  This file contains function definitions related to bitstream generation
28 *
29 * @author
30 *  ittiam
31 *
32 * @par List of Functions:
33 *  - ih264e_bitstrm_init
34 *  - ih264e_put_bits
35 *  - ih264e_put_bit
36 *  - ih264e_put_rbsp_trailing_bits
37 *  - ih264e_put_uev
38 *  - ih264e_put_sev
39 *  - ih264e_put_nal_start_code_prefix
40 *
41 ******************************************************************************
42 */
43 
44 /*****************************************************************************/
45 /* File Includes                                                             */
46 /*****************************************************************************/
47 
48 /* System Include Files */
49 #include <stdio.h>
50 #include <string.h>
51 #include <stdlib.h>
52 #include <assert.h>
53 #include <stdarg.h>
54 #include <math.h>
55 
56 /* User Include Files */
57 #include "ih264e_config.h"
58 #include "ih264_typedefs.h"
59 
60 #include "ih264_debug.h"
61 #include "ih264_macros.h"
62 #include "ih264_defs.h"
63 #include "ih264_platform_macros.h"
64 
65 #include "ih264e_error.h"
66 #include "ih264e_bitstream.h"
67 
68 /*****************************************************************************/
69 /* Function Definitions                                                      */
70 /*****************************************************************************/
71 
72 /**
73 ******************************************************************************
74 *
75 *  @brief Initializes the encoder bitstream engine
76 *
77 *  @par   Description
78 *  This routine needs to be called at start of slice/frame encode
79 *
80 *  @param[in]   ps_bitstrm
81 *  pointer to bitstream context (handle)
82 *
83 *  @param[in]   p1_bitstrm_buf
84 *  bitstream buffer pointer where the encoded stream is generated in byte order
85 *
86 *  @param[in]   u4_max_bitstrm_size
87 *  indicates maximum bitstream buffer size. (in bytes)
88 *  If actual stream size exceeds the maximum size, encoder should
89 *   1. Not corrupt data beyond u4_max_bitstrm_size bytes
90 *   2. Report an error back to application indicating overflow
91 *
92 *  @return      success or failure error code
93 *
94 ******************************************************************************
95 */
ih264e_bitstrm_init(bitstrm_t * ps_bitstrm,UWORD8 * pu1_bitstrm_buf,UWORD32 u4_max_bitstrm_size)96 IH264E_ERROR_T ih264e_bitstrm_init(bitstrm_t *ps_bitstrm,
97                                    UWORD8 *pu1_bitstrm_buf,
98                                    UWORD32 u4_max_bitstrm_size)
99 {
100     ps_bitstrm->pu1_strm_buffer  = pu1_bitstrm_buf;
101     ps_bitstrm->u4_max_strm_size = u4_max_bitstrm_size;
102 
103     /* Default init values for other members of bitstream context */
104     ps_bitstrm->u4_strm_buf_offset  = 0;
105     ps_bitstrm->u4_cur_word         = 0;
106     ps_bitstrm->i4_bits_left_in_cw  = WORD_SIZE;
107     ps_bitstrm->i4_zero_bytes_run   = 0;
108 
109     return(IH264E_SUCCESS);
110 }
111 
112 /**
113 ******************************************************************************
114 *
115 *  @brief puts a code with specified number of bits into the bitstream
116 *
117 *  @par   Description
118 *  inserts code_len number of bits from lsb of code_val into the
119 *  bitstream. updates context members like u4_cur_word, u4_strm_buf_offset and
120 *  i4_bits_left_in_cw. If the total words (u4_strm_buf_offset) exceeds max
121 *  available size (u4_max_strm_size), returns error without corrupting data
122 *  beyond it
123 *
124 *  @param[in]    ps_bitstrm
125 *  pointer to bitstream context (handle)
126 *
127 *  @param[in]    u4_code_val
128 *  code value that needs to be inserted in the stream.
129 *
130 *  @param[in]    code_len
131 *  indicates code length (in bits) of code_val that would be inserted in
132 *  bitstream buffer size. Range of length[1:WORD_SIZE]
133 *
134 *  @remarks     Assumptions: all bits from bit position code_len to msb of
135 *   code_val shall be zero
136 *
137 *  @return      success or failure error code
138 *
139 ******************************************************************************
140 */
ih264e_put_bits(bitstrm_t * ps_bitstrm,UWORD32 u4_code_val,WORD32 code_len)141 IH264E_ERROR_T ih264e_put_bits(bitstrm_t *ps_bitstrm,
142                                UWORD32 u4_code_val,
143                                WORD32 code_len)
144 {
145     UWORD32 u4_cur_word = ps_bitstrm->u4_cur_word;
146     WORD32  bits_left_in_cw = ps_bitstrm->i4_bits_left_in_cw;
147 
148 
149     /* check assumptions made in the module */
150     ASSERT(code_len > 0 && code_len <= WORD_SIZE);
151 
152     if(code_len < WORD_SIZE)
153         ASSERT((u4_code_val >> code_len) == 0);
154 
155     /* sanity check on the bitstream engine state */
156     ASSERT(bits_left_in_cw > 0 && bits_left_in_cw <= WORD_SIZE);
157 
158     ASSERT(ps_bitstrm->i4_zero_bytes_run <= EPB_ZERO_BYTES);
159 
160     ASSERT(ps_bitstrm->pu1_strm_buffer != NULL);
161 
162 
163     if(bits_left_in_cw > code_len)
164     {
165         /*******************************************************************/
166         /* insert the code in local bitstream word and return              */
167         /* code is inserted in position of bits left (post decrement)      */
168         /*******************************************************************/
169         bits_left_in_cw -= code_len;
170         u4_cur_word     |= (u4_code_val << bits_left_in_cw);
171 
172         ps_bitstrm->u4_cur_word         = u4_cur_word;
173         ps_bitstrm->i4_bits_left_in_cw  = bits_left_in_cw;
174 
175         return(IH264E_SUCCESS);
176     }
177     else
178     {
179         /********************************************************************/
180         /* 1. insert partial code corresponding to bits left in cur word    */
181         /* 2. flush all the bits of cur word to bitstream                   */
182         /* 3. insert emulation prevention bytes while flushing the bits     */
183         /* 4. insert remaining bits of code starting from msb of cur word   */
184         /* 5. update bitsleft in current word and stream buffer offset      */
185         /********************************************************************/
186         WORD32  i, rem_bits = (code_len - bits_left_in_cw);
187 
188         /* insert parital code corresponding to bits left in cur word */
189         u4_cur_word |= u4_code_val >> rem_bits;
190 
191         for(i = WORD_SIZE; i > 0; i -= 8)
192         {
193             /* flush the bits in cur word byte by byte and copy to stream */
194             UWORD8   u1_next_byte = (u4_cur_word >> (i-8)) & 0xFF;
195 
196             IH264E_ERROR_T status = ih264e_put_byte_epb(ps_bitstrm, u1_next_byte);
197             if (status != IH264E_SUCCESS) return status;
198         }
199 
200         /* insert the remaining bits from code val into current word */
201         u4_cur_word = rem_bits ? (u4_code_val << (WORD_SIZE - rem_bits)) : 0;
202 
203         /* update the state variables and return success */
204         ps_bitstrm->u4_cur_word         = u4_cur_word;
205         ps_bitstrm->i4_bits_left_in_cw  = WORD_SIZE - rem_bits;
206         return (IH264E_SUCCESS);
207 
208     }
209 }
210 
211 /**
212 ******************************************************************************
213 *
214 *  @brief inserts a 1-bit code into the bitstream
215 *
216 *  @par   Description
217 *  inserts 1bit lsb of code_val into the bitstream
218 *  updates context members like u4_cur_word, u4_strm_buf_offset and
219 *  i4_bits_left_in_cw. If the total words (u4_strm_buf_offset) exceeds max
220 *  available size (u4_max_strm_size), returns error without corrupting data
221 *  beyond it
222 *
223 *  @param[in]    ps_bitstrm
224 *  pointer to bitstream context (handle)
225 *
226 *  @param[in]    u4_code_val
227 *  code value that needs to be inserted in the stream.
228 *
229 *  @remarks     Assumptions: all bits from bit position 1 to msb of code_val
230 *  shall be zero
231 *
232 *  @return      success or failure error code
233 *
234 ******************************************************************************
235 */
ih264e_put_bit(bitstrm_t * ps_bitstrm,UWORD32 u4_code_val)236 IH264E_ERROR_T ih264e_put_bit(bitstrm_t *ps_bitstrm, UWORD32 u4_code_val)
237 {
238     /* call the put bits function for 1 bit and return */
239     return(ih264e_put_bits(ps_bitstrm, u4_code_val, 1));
240 }
241 
242 /**
243 ******************************************************************************
244 *
245 *  @brief inserts rbsp trailing bits at the end of stream buffer (NAL)
246 *
247 *  @par   Description
248 *  inserts rbsp trailing bits, updates context members like u4_cur_word and
249 *  i4_bits_left_in_cw and flushes the same in the bitstream buffer. If the
250 *  total words (u4_strm_buf_offset) exceeds max available size
251 *  (u4_max_strm_size), returns error without corrupting data beyond it
252 *
253 *  @param[in]    ps_bitstrm
254 *  pointer to bitstream context (handle)
255 *
256 *  @return      success or failure error code
257 *
258 ******************************************************************************
259 */
ih264e_put_rbsp_trailing_bits(bitstrm_t * ps_bitstrm)260 IH264E_ERROR_T ih264e_put_rbsp_trailing_bits(bitstrm_t *ps_bitstrm)
261 {
262     WORD32 i;
263     UWORD32 u4_cur_word = ps_bitstrm->u4_cur_word;
264     WORD32  bits_left_in_cw = ps_bitstrm->i4_bits_left_in_cw;
265     WORD32  bytes_left_in_cw = (bits_left_in_cw - 1) >> 3;
266 
267     /* insert a 1 at the end of current word and flush all the bits */
268     u4_cur_word |= (1 << (bits_left_in_cw - 1));
269 
270     /* get the bits to be inserted in msbdb of the word */
271     //u4_cur_word <<= (WORD_SIZE - bytes_left_in_cw + 1);
272 
273     for(i = WORD_SIZE; i > (bytes_left_in_cw*8); i -= 8)
274     {
275         /* flush the bits in cur word byte by byte  and copy to stream */
276         UWORD8   u1_next_byte = (u4_cur_word >> (i-8)) & 0xFF;
277 
278         IH264E_ERROR_T status = ih264e_put_byte_epb(ps_bitstrm, u1_next_byte);
279         if (status != IH264E_SUCCESS) return status;
280     }
281 
282     /* Default init values for scratch variables of bitstream context */
283     ps_bitstrm->u4_cur_word         = 0;
284     ps_bitstrm->i4_bits_left_in_cw  = WORD_SIZE;
285     ps_bitstrm->i4_zero_bytes_run   = 0;
286 
287     return (IH264E_SUCCESS);
288 }
289 
290 /**
291 ******************************************************************************
292 *
293 *  @brief puts exponential golomb code of a unsigned integer into bitstream
294 *
295 *  @par   Description
296 *  computes uev code for given syntax element and inserts the same into
297 *  bitstream by calling ih264e_put_bits() interface.
298 *
299 *  @param[in]    ps_bitstrm
300 *  pointer to bitstream context (handle)
301 *
302 *  @param[in]    u4_code_num
303 *  unsigned integer input whose golomb code is written in stream
304 *
305 *  @remarks     Assumptions: code value can be represented in less than 16bits
306 *
307 *  @return      success or failure error code
308 *
309 ******************************************************************************
310 */
ih264e_put_uev(bitstrm_t * ps_bitstrm,UWORD32 u4_code_num)311 IH264E_ERROR_T ih264e_put_uev(bitstrm_t *ps_bitstrm, UWORD32 u4_code_num)
312 {
313     UWORD32 u4_bit_str, u4_range;
314     IH264E_ERROR_T e_error;
315 
316     /* convert the codenum to exp-golomb bit code: Table 9-2 JCTVC-J1003_d7 */
317     u4_bit_str = u4_code_num + 1;
318 
319     /* get range of the bit string and put using put_bits()                 */
320     GETRANGE(u4_range, u4_bit_str);
321 
322     e_error = ih264e_put_bits(ps_bitstrm, u4_bit_str, (2 * u4_range - 1));
323 
324     return(e_error);
325 }
326 
327 /**
328 ******************************************************************************
329 *
330 *  @brief puts exponential golomb code of a signed integer into bitstream
331 *
332 *  @par   Description
333 *  computes sev code for given syntax element and inserts the same into
334 *  bitstream by calling ih264e_put_bits() interface.
335 *
336 *  @param[in]    ps_bitstrm
337 *  pointer to bitstream context (handle)
338 *
339 *  @param[in]    syntax_elem
340 *  signed integer input whose golomb code is written in stream
341 *
342 *  @remarks     Assumptions: code value can be represented in less than 16bits
343 *
344 *  @return      success or failure error code
345 *
346 ******************************************************************************
347 */
ih264e_put_sev(bitstrm_t * ps_bitstrm,WORD32 syntax_elem)348 IH264E_ERROR_T ih264e_put_sev(bitstrm_t *ps_bitstrm, WORD32 syntax_elem)
349 {
350     UWORD32 u4_code_num, u4_bit_str, u4_range;
351     IH264E_ERROR_T e_error;
352 
353     /************************************************************************/
354     /* convert the codenum to exp-golomb bit code for signed syntax element */
355     /* See Table9-2 and Table 9-3 of standard JCTVC-J1003_d7                */
356     /************************************************************************/
357     if(syntax_elem <= 0)
358     {
359         /* codeNum for non-positive integer =  2*abs(x) : Table9-3  */
360         u4_code_num = ((-syntax_elem) << 1);
361     }
362     else
363     {
364         /* codeNum for positive integer     =  2x-1     : Table9-3  */
365         u4_code_num = (syntax_elem << 1) - 1;
366     }
367 
368     /* convert the codenum to exp-golomb bit code: Table 9-2 JCTVC-J1003_d7 */
369     u4_bit_str = u4_code_num + 1;
370 
371     /* get range of the bit string and put using put_bits()                 */
372     GETRANGE(u4_range, u4_bit_str);
373 
374     e_error = ih264e_put_bits(ps_bitstrm, u4_bit_str, (2 * u4_range - 1));
375 
376     return(e_error);
377 }
378 
379 /**
380 ******************************************************************************
381 *
382 *  @brief insert NAL start code prefix (0x000001) into bitstream with an option
383 *  of inserting leading_zero_8bits (which makes startcode prefix as 0x00000001)
384 *
385 *  @par   Description
386 *  Although start code prefix could have been put by calling ih264e_put_bits(),
387 *  ih264e_put_nal_start_code_prefix() is specially added to make sure emulation
388 *  prevention insertion is not done for the NAL start code prefix which will
389 *  surely happen otherwise by calling ih264e_put_bits() interface.
390 *
391 *  @param[in]    ps_bitstrm
392 *  pointer to bitstream context (handle)
393 *
394 *  @param[in]    insert_leading_zero_8bits
395 *  flag indicating if one more zero bytes needs to prefixed before start code
396 *
397 *  @return      success or failure error code
398 *
399 ******************************************************************************
400 */
ih264e_put_nal_start_code_prefix(bitstrm_t * ps_bitstrm,WORD32 insert_leading_zero_8bits)401 IH264E_ERROR_T ih264e_put_nal_start_code_prefix(bitstrm_t *ps_bitstrm,
402                                                 WORD32 insert_leading_zero_8bits)
403 {
404     UWORD32 u4_strm_buf_offset  = ps_bitstrm->u4_strm_buf_offset;
405     UWORD8* pu1_strm_buf        = ps_bitstrm->pu1_strm_buffer;
406 
407     /* Bitstream buffer overflow check assuming worst case of 4 bytes */
408     if((u4_strm_buf_offset + 4) >= ps_bitstrm->u4_max_strm_size)
409     {
410         return(IH264E_BITSTREAM_BUFFER_OVERFLOW);
411     }
412 
413     /* Insert leading zero 8 bits conditionally */
414     if(insert_leading_zero_8bits)
415     {
416         pu1_strm_buf[u4_strm_buf_offset] = 0x00;
417         u4_strm_buf_offset++;
418     }
419 
420     /* Insert NAL start code prefix 0x00 00 01 */
421     pu1_strm_buf[u4_strm_buf_offset] = 0x00;
422     u4_strm_buf_offset++;
423 
424     pu1_strm_buf[u4_strm_buf_offset] = 0x00;
425     u4_strm_buf_offset++;
426 
427     pu1_strm_buf[u4_strm_buf_offset] = 0x01;
428     u4_strm_buf_offset++;
429 
430     /* update the stream offset */
431     ps_bitstrm->u4_strm_buf_offset = u4_strm_buf_offset;
432 
433     return (IH264E_SUCCESS);
434 }
435 
436