Coverage Report

Created: 2025-07-11 06:43

/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
364k
{
91
364k
    ps_bitstrm->pu1_strm_buffer = pu1_bitstrm_buf;
92
364k
    ps_bitstrm->u4_max_strm_size = u4_max_bitstrm_size;
93
94
    /* Default init values for other members of bitstream context */
95
364k
    ps_bitstrm->u4_strm_buf_offset = 0;
96
364k
    ps_bitstrm->u4_cur_word = 0;
97
364k
    ps_bitstrm->i4_bits_left_in_cw = WORD_SIZE;
98
364k
    ps_bitstrm->i4_zero_bytes_run = 0;
99
100
364k
    return (IHEVCE_SUCCESS);
101
364k
}
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.7M
{
134
12.7M
    UWORD32 u4_cur_word = ps_bitstrm->u4_cur_word;
135
12.7M
    WORD32 bits_left_in_cw = ps_bitstrm->i4_bits_left_in_cw;
136
137
    /* check assumptions made in the module */
138
12.7M
    ASSERT(code_len > 0 && code_len <= WORD_SIZE);
139
140
12.7M
    if(code_len < WORD_SIZE)
141
12.7M
        ASSERT((u4_code_val >> code_len) == 0);
142
143
    /* sanity check on the bitstream engine state */
144
12.7M
    ASSERT(bits_left_in_cw > 0 && bits_left_in_cw <= WORD_SIZE);
145
146
12.7M
    ASSERT(ps_bitstrm->i4_zero_bytes_run <= EPB_ZERO_BYTES);
147
148
12.7M
    ASSERT(ps_bitstrm->pu1_strm_buffer != NULL);
149
150
12.7M
    if(bits_left_in_cw > code_len)
151
11.8M
    {
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.8M
        bits_left_in_cw -= code_len;
157
11.8M
        u4_cur_word |= (u4_code_val << bits_left_in_cw);
158
159
11.8M
        ps_bitstrm->u4_cur_word = u4_cur_word;
160
11.8M
        ps_bitstrm->i4_bits_left_in_cw = bits_left_in_cw;
161
162
11.8M
        return (IHEVCE_SUCCESS);
163
11.8M
    }
164
834k
    else
165
834k
    {
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
834k
        UWORD32 u4_strm_buf_offset = ps_bitstrm->u4_strm_buf_offset;
174
175
834k
        UWORD32 u4_max_strm_size = ps_bitstrm->u4_max_strm_size;
176
177
834k
        WORD32 zero_run = ps_bitstrm->i4_zero_bytes_run;
178
179
834k
        UWORD8 *pu1_strm_buf = ps_bitstrm->pu1_strm_buffer;
180
181
834k
        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
834k
        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
834k
        u4_cur_word |= u4_code_val >> rem_bits;
195
196
4.17M
        for(i = WORD_SIZE; i > 0; i -= 8)
197
3.33M
        {
198
            /* flush the bits in cur word byte by byte and copy to stream */
199
3.33M
            UWORD8 u1_next_byte = (u4_cur_word >> (i - 8)) & 0xFF;
200
201
3.33M
            PUTBYTE_EPB(pu1_strm_buf, u4_strm_buf_offset, u1_next_byte, zero_run);
202
3.33M
        }
203
204
        /* insert the remaining bits from code val into current word */
205
834k
        u4_cur_word = rem_bits ? (u4_code_val << (WORD_SIZE - rem_bits)) : 0;
206
207
        /* update the state variables and return success */
208
834k
        ps_bitstrm->u4_cur_word = u4_cur_word;
209
834k
        ps_bitstrm->i4_bits_left_in_cw = WORD_SIZE - rem_bits;
210
834k
        ps_bitstrm->i4_zero_bytes_run = zero_run;
211
834k
        ps_bitstrm->u4_strm_buf_offset = u4_strm_buf_offset;
212
834k
        return (IHEVCE_SUCCESS);
213
834k
    }
214
12.7M
}
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
316k
{
267
316k
    WORD32 i;
268
316k
    UWORD32 u4_cur_word = ps_bitstrm->u4_cur_word;
269
316k
    WORD32 bits_left_in_cw = ps_bitstrm->i4_bits_left_in_cw;
270
316k
    WORD32 bytes_left_in_cw = (bits_left_in_cw - 1) >> 3;
271
272
316k
    UWORD32 u4_strm_buf_offset = ps_bitstrm->u4_strm_buf_offset;
273
316k
    UWORD32 u4_max_strm_size = ps_bitstrm->u4_max_strm_size;
274
316k
    WORD32 zero_run = ps_bitstrm->i4_zero_bytes_run;
275
316k
    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
316k
    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
316k
    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
1.01M
    for(i = WORD_SIZE; i > (bytes_left_in_cw * 8); i -= 8)
294
695k
    {
295
        /* flush the bits in cur word byte by byte  and copy to stream */
296
695k
        UWORD8 u1_next_byte = (u4_cur_word >> (i - 8)) & 0xFF;
297
298
695k
        PUTBYTE_EPB(pu1_strm_buf, u4_strm_buf_offset, u1_next_byte, zero_run);
299
695k
    }
300
301
    /* update the stream offset */
302
316k
    ps_bitstrm->u4_strm_buf_offset = u4_strm_buf_offset;
303
304
    /* Default init values for scratch variables of bitstream context */
305
316k
    ps_bitstrm->u4_cur_word = 0;
306
316k
    ps_bitstrm->i4_bits_left_in_cw = WORD_SIZE;
307
316k
    ps_bitstrm->i4_zero_bytes_run = 0;
308
309
316k
    return (IHEVCE_SUCCESS);
310
316k
}
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.81M
{
335
2.81M
    UWORD32 u4_bit_str, u4_range;
336
2.81M
    IHEVCE_ERROR_T e_error;
337
338
    /* convert the codenum to exp-golomb bit code: Table 9-2 JCTVC-J1003_d7 */
339
2.81M
    u4_bit_str = u4_code_num + 1;
340
341
    /* get range of the bit string and put using put_bits()                 */
342
2.81M
    GETRANGE(u4_range, u4_bit_str);
343
344
2.81M
    e_error = ihevce_put_bits(ps_bitstrm, u4_bit_str, (2 * u4_range - 1));
345
346
2.81M
    return (e_error);
347
2.81M
}
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
369k
{
372
369k
    UWORD32 u4_code_num, u4_bit_str, u4_range;
373
369k
    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
369k
    if(syntax_elem <= 0)
380
261k
    {
381
        /* codeNum for non-positive integer =  2*abs(x) : Table9-3  */
382
261k
        u4_code_num = ((-syntax_elem) << 1);
383
261k
    }
384
108k
    else
385
108k
    {
386
        /* codeNum for positive integer     =  2x-1     : Table9-3  */
387
108k
        u4_code_num = (syntax_elem << 1) - 1;
388
108k
    }
389
390
    /* convert the codenum to exp-golomb bit code: Table 9-2 JCTVC-J1003_d7 */
391
369k
    u4_bit_str = u4_code_num + 1;
392
393
    /* get range of the bit string and put using put_bits()                 */
394
369k
    GETRANGE(u4_range, u4_bit_str);
395
396
369k
    e_error = ihevce_put_bits(ps_bitstrm, u4_bit_str, (2 * u4_range - 1));
397
398
369k
    return (e_error);
399
369k
}
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
313k
{
426
313k
    UWORD32 u4_strm_buf_offset = ps_bitstrm->u4_strm_buf_offset;
427
313k
    UWORD8 *pu1_strm_buf = ps_bitstrm->pu1_strm_buffer;
428
313k
    WORD32 num_nals = ps_bitstrm->i4_num_nal;
429
430
    /* Bitstream buffer overflow check assuming worst case of 4 bytes */
431
313k
    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
313k
    ASSERT(num_nals >= 0);
438
313k
    ASSERT(num_nals < MAX_NALS_IN_AU);
439
313k
    if(num_nals < MAX_NALS_IN_AU)
440
313k
    {
441
313k
        ps_bitstrm->apu1_nal_start[num_nals] = pu1_strm_buf + u4_strm_buf_offset;
442
313k
        ps_bitstrm->i4_num_nal++;
443
313k
    }
444
445
    /* Insert leading zero 8 bits conditionally */
446
313k
    if(insert_leading_zero_8bits)
447
313k
    {
448
313k
        pu1_strm_buf[u4_strm_buf_offset] = 0x00;
449
313k
        u4_strm_buf_offset++;
450
313k
    }
451
452
    /* Insert NAL start code prefix 0x00 00 01 */
453
313k
    pu1_strm_buf[u4_strm_buf_offset] = 0x00;
454
313k
    u4_strm_buf_offset++;
455
456
313k
    pu1_strm_buf[u4_strm_buf_offset] = 0x00;
457
313k
    u4_strm_buf_offset++;
458
459
313k
    pu1_strm_buf[u4_strm_buf_offset] = 0x01;
460
313k
    u4_strm_buf_offset++;
461
462
    /* update the stream offset */
463
313k
    ps_bitstrm->u4_strm_buf_offset = u4_strm_buf_offset;
464
465
313k
    return (IHEVCE_SUCCESS);
466
313k
}