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