/src/libhevc/encoder/ihevce_bitstream.c
Line | Count | Source (jump to first uncovered line) |
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 |
89 | | ihevce_bitstrm_init(bitstrm_t *ps_bitstrm, UWORD8 *pu1_bitstrm_buf, UWORD32 u4_max_bitstrm_size) |
90 | 321k | { |
91 | 321k | ps_bitstrm->pu1_strm_buffer = pu1_bitstrm_buf; |
92 | 321k | ps_bitstrm->u4_max_strm_size = u4_max_bitstrm_size; |
93 | | |
94 | | /* Default init values for other members of bitstream context */ |
95 | 321k | ps_bitstrm->u4_strm_buf_offset = 0; |
96 | 321k | ps_bitstrm->u4_cur_word = 0; |
97 | 321k | ps_bitstrm->i4_bits_left_in_cw = WORD_SIZE; |
98 | 321k | ps_bitstrm->i4_zero_bytes_run = 0; |
99 | | |
100 | 321k | return (IHEVCE_SUCCESS); |
101 | 321k | } |
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 | | */ |
132 | | IHEVCE_ERROR_T ihevce_put_bits(bitstrm_t *ps_bitstrm, UWORD32 u4_code_val, WORD32 code_len) |
133 | 12.3M | { |
134 | 12.3M | UWORD32 u4_cur_word = ps_bitstrm->u4_cur_word; |
135 | 12.3M | WORD32 bits_left_in_cw = ps_bitstrm->i4_bits_left_in_cw; |
136 | | |
137 | | /* check assumptions made in the module */ |
138 | 12.3M | ASSERT(code_len > 0 && code_len <= WORD_SIZE); |
139 | | |
140 | 12.3M | if(code_len < WORD_SIZE) |
141 | 12.3M | ASSERT((u4_code_val >> code_len) == 0); |
142 | | |
143 | | /* sanity check on the bitstream engine state */ |
144 | 12.3M | ASSERT(bits_left_in_cw > 0 && bits_left_in_cw <= WORD_SIZE); |
145 | | |
146 | 12.3M | ASSERT(ps_bitstrm->i4_zero_bytes_run <= EPB_ZERO_BYTES); |
147 | | |
148 | 12.3M | ASSERT(ps_bitstrm->pu1_strm_buffer != NULL); |
149 | | |
150 | 12.3M | if(bits_left_in_cw > code_len) |
151 | 11.5M | { |
152 | | /*******************************************************************/ |
153 | | /* insert the code in local bitstream word and return */ |
154 | | /* code is inserted in position of bits left (post decrement) */ |
155 | | /*******************************************************************/ |
156 | 11.5M | bits_left_in_cw -= code_len; |
157 | 11.5M | u4_cur_word |= (u4_code_val << bits_left_in_cw); |
158 | | |
159 | 11.5M | ps_bitstrm->u4_cur_word = u4_cur_word; |
160 | 11.5M | ps_bitstrm->i4_bits_left_in_cw = bits_left_in_cw; |
161 | | |
162 | 11.5M | return (IHEVCE_SUCCESS); |
163 | 11.5M | } |
164 | 808k | else |
165 | 808k | { |
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 | 808k | UWORD32 u4_strm_buf_offset = ps_bitstrm->u4_strm_buf_offset; |
174 | | |
175 | 808k | UWORD32 u4_max_strm_size = ps_bitstrm->u4_max_strm_size; |
176 | | |
177 | 808k | WORD32 zero_run = ps_bitstrm->i4_zero_bytes_run; |
178 | | |
179 | 808k | UWORD8 *pu1_strm_buf = ps_bitstrm->pu1_strm_buffer; |
180 | | |
181 | 808k | 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 | 808k | if((u4_strm_buf_offset + (WORD_SIZE >> 3)) >= u4_max_strm_size) |
188 | 0 | { |
189 | | /* return without corrupting the buffer beyond its size */ |
190 | 0 | return (IHEVCE_BITSTREAM_BUFFER_OVERFLOW); |
191 | 0 | } |
192 | | |
193 | | /* insert parital code corresponding to bits left in cur word */ |
194 | 808k | u4_cur_word |= u4_code_val >> rem_bits; |
195 | | |
196 | 4.04M | for(i = WORD_SIZE; i > 0; i -= 8) |
197 | 3.23M | { |
198 | | /* flush the bits in cur word byte by byte and copy to stream */ |
199 | 3.23M | UWORD8 u1_next_byte = (u4_cur_word >> (i - 8)) & 0xFF; |
200 | | |
201 | 3.23M | PUTBYTE_EPB(pu1_strm_buf, u4_strm_buf_offset, u1_next_byte, zero_run); |
202 | 3.23M | } |
203 | | |
204 | | /* insert the remaining bits from code val into current word */ |
205 | 808k | u4_cur_word = rem_bits ? (u4_code_val << (WORD_SIZE - rem_bits)) : 0; |
206 | | |
207 | | /* update the state variables and return success */ |
208 | 808k | ps_bitstrm->u4_cur_word = u4_cur_word; |
209 | 808k | ps_bitstrm->i4_bits_left_in_cw = WORD_SIZE - rem_bits; |
210 | 808k | ps_bitstrm->i4_zero_bytes_run = zero_run; |
211 | 808k | ps_bitstrm->u4_strm_buf_offset = u4_strm_buf_offset; |
212 | 808k | return (IHEVCE_SUCCESS); |
213 | 808k | } |
214 | 12.3M | } |
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 | | */ |
241 | | IHEVCE_ERROR_T ihevce_put_bit(bitstrm_t *ps_bitstrm, UWORD32 u4_code_val) |
242 | 0 | { |
243 | | /* call the put bits function for 1 bit and return */ |
244 | 0 | return (ihevce_put_bits(ps_bitstrm, u4_code_val, 1)); |
245 | 0 | } |
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 | | */ |
265 | | IHEVCE_ERROR_T ihevce_put_rbsp_trailing_bits(bitstrm_t *ps_bitstrm) |
266 | 298k | { |
267 | 298k | WORD32 i; |
268 | 298k | UWORD32 u4_cur_word = ps_bitstrm->u4_cur_word; |
269 | 298k | WORD32 bits_left_in_cw = ps_bitstrm->i4_bits_left_in_cw; |
270 | 298k | WORD32 bytes_left_in_cw = (bits_left_in_cw - 1) >> 3; |
271 | | |
272 | 298k | UWORD32 u4_strm_buf_offset = ps_bitstrm->u4_strm_buf_offset; |
273 | 298k | UWORD32 u4_max_strm_size = ps_bitstrm->u4_max_strm_size; |
274 | 298k | WORD32 zero_run = ps_bitstrm->i4_zero_bytes_run; |
275 | 298k | 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 | 298k | if((u4_strm_buf_offset + (WORD_SIZE >> 3) - bytes_left_in_cw) >= u4_max_strm_size) |
282 | 0 | { |
283 | | /* return without corrupting the buffer beyond its size */ |
284 | 0 | return (IHEVCE_BITSTREAM_BUFFER_OVERFLOW); |
285 | 0 | } |
286 | | |
287 | | /* insert a 1 at the end of current word and flush all the bits */ |
288 | 298k | 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 | 954k | for(i = WORD_SIZE; i > (bytes_left_in_cw * 8); i -= 8) |
294 | 656k | { |
295 | | /* flush the bits in cur word byte by byte and copy to stream */ |
296 | 656k | UWORD8 u1_next_byte = (u4_cur_word >> (i - 8)) & 0xFF; |
297 | | |
298 | 656k | PUTBYTE_EPB(pu1_strm_buf, u4_strm_buf_offset, u1_next_byte, zero_run); |
299 | 656k | } |
300 | | |
301 | | /* update the stream offset */ |
302 | 298k | ps_bitstrm->u4_strm_buf_offset = u4_strm_buf_offset; |
303 | | |
304 | | /* Default init values for scratch variables of bitstream context */ |
305 | 298k | ps_bitstrm->u4_cur_word = 0; |
306 | 298k | ps_bitstrm->i4_bits_left_in_cw = WORD_SIZE; |
307 | 298k | ps_bitstrm->i4_zero_bytes_run = 0; |
308 | | |
309 | 298k | return (IHEVCE_SUCCESS); |
310 | 298k | } |
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 | | */ |
333 | | IHEVCE_ERROR_T ihevce_put_uev(bitstrm_t *ps_bitstrm, UWORD32 u4_code_num) |
334 | 2.57M | { |
335 | 2.57M | UWORD32 u4_bit_str, u4_range; |
336 | 2.57M | IHEVCE_ERROR_T e_error; |
337 | | |
338 | | /* convert the codenum to exp-golomb bit code: Table 9-2 JCTVC-J1003_d7 */ |
339 | 2.57M | u4_bit_str = u4_code_num + 1; |
340 | | |
341 | | /* get range of the bit string and put using put_bits() */ |
342 | 2.57M | GETRANGE(u4_range, u4_bit_str); |
343 | | |
344 | 2.57M | e_error = ihevce_put_bits(ps_bitstrm, u4_bit_str, (2 * u4_range - 1)); |
345 | | |
346 | 2.57M | return (e_error); |
347 | 2.57M | } |
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 | | */ |
370 | | IHEVCE_ERROR_T ihevce_put_sev(bitstrm_t *ps_bitstrm, WORD32 syntax_elem) |
371 | 370k | { |
372 | 370k | UWORD32 u4_code_num, u4_bit_str, u4_range; |
373 | 370k | 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 | 370k | if(syntax_elem <= 0) |
380 | 259k | { |
381 | | /* codeNum for non-positive integer = 2*abs(x) : Table9-3 */ |
382 | 259k | u4_code_num = ((-syntax_elem) << 1); |
383 | 259k | } |
384 | 110k | else |
385 | 110k | { |
386 | | /* codeNum for positive integer = 2x-1 : Table9-3 */ |
387 | 110k | u4_code_num = (syntax_elem << 1) - 1; |
388 | 110k | } |
389 | | |
390 | | /* convert the codenum to exp-golomb bit code: Table 9-2 JCTVC-J1003_d7 */ |
391 | 370k | u4_bit_str = u4_code_num + 1; |
392 | | |
393 | | /* get range of the bit string and put using put_bits() */ |
394 | 370k | GETRANGE(u4_range, u4_bit_str); |
395 | | |
396 | 370k | e_error = ihevce_put_bits(ps_bitstrm, u4_bit_str, (2 * u4_range - 1)); |
397 | | |
398 | 370k | return (e_error); |
399 | 370k | } |
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 |
424 | | ihevce_put_nal_start_code_prefix(bitstrm_t *ps_bitstrm, WORD32 insert_leading_zero_8bits) |
425 | 294k | { |
426 | 294k | UWORD32 u4_strm_buf_offset = ps_bitstrm->u4_strm_buf_offset; |
427 | 294k | UWORD8 *pu1_strm_buf = ps_bitstrm->pu1_strm_buffer; |
428 | 294k | WORD32 num_nals = ps_bitstrm->i4_num_nal; |
429 | | |
430 | | /* Bitstream buffer overflow check assuming worst case of 4 bytes */ |
431 | 294k | if((u4_strm_buf_offset + 4) > ps_bitstrm->u4_max_strm_size) |
432 | 0 | { |
433 | 0 | return (IHEVCE_BITSTREAM_BUFFER_OVERFLOW); |
434 | 0 | } |
435 | | |
436 | | /* Update the current NAL start ptr and increment counter */ |
437 | 294k | ASSERT(num_nals >= 0); |
438 | 294k | ASSERT(num_nals < MAX_NALS_IN_AU); |
439 | 294k | if(num_nals < MAX_NALS_IN_AU) |
440 | 294k | { |
441 | 294k | ps_bitstrm->apu1_nal_start[num_nals] = pu1_strm_buf + u4_strm_buf_offset; |
442 | 294k | ps_bitstrm->i4_num_nal++; |
443 | 294k | } |
444 | | |
445 | | /* Insert leading zero 8 bits conditionally */ |
446 | 294k | if(insert_leading_zero_8bits) |
447 | 294k | { |
448 | 294k | pu1_strm_buf[u4_strm_buf_offset] = 0x00; |
449 | 294k | u4_strm_buf_offset++; |
450 | 294k | } |
451 | | |
452 | | /* Insert NAL start code prefix 0x00 00 01 */ |
453 | 294k | pu1_strm_buf[u4_strm_buf_offset] = 0x00; |
454 | 294k | u4_strm_buf_offset++; |
455 | | |
456 | 294k | pu1_strm_buf[u4_strm_buf_offset] = 0x00; |
457 | 294k | u4_strm_buf_offset++; |
458 | | |
459 | 294k | pu1_strm_buf[u4_strm_buf_offset] = 0x01; |
460 | 294k | u4_strm_buf_offset++; |
461 | | |
462 | | /* update the stream offset */ |
463 | 294k | ps_bitstrm->u4_strm_buf_offset = u4_strm_buf_offset; |
464 | | |
465 | 294k | return (IHEVCE_SUCCESS); |
466 | 294k | } |