Coverage Report

Created: 2025-10-10 06:46

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libhevc/decoder/ihevcd_bitstream.c
Line
Count
Source
1
/******************************************************************************
2
*
3
* Copyright (C) 2012 Ittiam Systems Pvt Ltd, Bangalore
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
/**
19
*******************************************************************************
20
* @file
21
*  ihevcd_bitstream.c
22
*
23
* @brief
24
*  Contains functions for bitstream access
25
*
26
* @author
27
*  Harish
28
*
29
* @par List of Functions:
30
* - ihevcd_bits_init()
31
* - ihevcd_bits_flush()
32
* - ihevcd_bits_flush_to_byte_boundary()
33
* - ihevcd_bits_nxt()
34
* - ihevcd_bits_nxt32()
35
* - ihevcd_bits_get()
36
* - ihevcd_bits_num_bits_remaining()
37
* - ihevcd_bits_num_bits_consumed()
38
* - ihevcd_sev()
39
* - ihevcd_uev()
40
*
41
*
42
* @remarks
43
*  None
44
*
45
*******************************************************************************
46
*/
47
/*****************************************************************************/
48
/* File Includes                                                             */
49
/*****************************************************************************/
50
#include <stdio.h>
51
#include <stddef.h>
52
#include <stdlib.h>
53
#include <string.h>
54
#include <assert.h>
55
#include "ihevc_typedefs.h"
56
#include "iv.h"
57
#include "ivd.h"
58
#include "ihevcd_cxa.h"
59
60
#include "ihevc_defs.h"
61
#include "ihevc_debug.h"
62
#include "ihevc_structs.h"
63
#include "ihevc_macros.h"
64
#include "ihevc_platform_macros.h"
65
#include "ihevc_cabac_tables.h"
66
67
#include "ihevcd_defs.h"
68
#include "ihevcd_function_selector.h"
69
#include "ihevcd_structs.h"
70
#include "ihevcd_error.h"
71
#include "ihevcd_bitstream.h"
72
73
/*****************************************************************************/
74
/* Function Prototypes                                                       */
75
/*****************************************************************************/
76
77
/**
78
*******************************************************************************
79
*
80
* @brief
81
*  Function used for bitstream structure initialization
82
*
83
* @par Description:
84
*  Initialize bitstream structure elements
85
*
86
* @param[in] ps_bitstrm
87
*  Pointer to bitstream structure
88
*
89
* @param[in] pu1_buf
90
*  Pointer to bitstream data
91
*
92
* @param[in] u4_numbytes
93
*  Number of bytes in bitstream
94
*
95
* @returns  none
96
*
97
* @remarks
98
*  Assumes pu1_buf is aligned to 4 bytes. If not aligned  then all bitstream
99
* accesses will be unaligned and hence  costlier. Since this is codec memory
100
* that holds emulation prevented data, assumption of aligned to 4 bytes is
101
* valid
102
*
103
*******************************************************************************
104
*/
105
void ihevcd_bits_init(bitstrm_t *ps_bitstrm,
106
                      UWORD8 *pu1_buf,
107
                      UWORD32 u4_numbytes)
108
175k
{
109
175k
    UWORD32 u4_cur_word;
110
175k
    UWORD32 u4_nxt_word;
111
175k
    UWORD32 u4_temp;
112
175k
    UWORD32 *pu4_buf;
113
114
175k
    pu4_buf     = (UWORD32 *)pu1_buf;
115
175k
    u4_temp = *pu4_buf++;
116
175k
    u4_cur_word = ITT_BIG_ENDIAN(u4_temp);
117
175k
    u4_temp = *pu4_buf++;
118
175k
    u4_nxt_word = ITT_BIG_ENDIAN(u4_temp);
119
120
175k
    ps_bitstrm->u4_bit_ofst     = 0;
121
175k
    ps_bitstrm->pu1_buf_base    = pu1_buf;
122
175k
    ps_bitstrm->pu4_buf         = pu4_buf;
123
175k
    ps_bitstrm->u4_cur_word     = u4_cur_word;
124
175k
    ps_bitstrm->u4_nxt_word     = u4_nxt_word;
125
126
175k
    ps_bitstrm->pu1_buf_max     = pu1_buf + u4_numbytes + 8;
127
128
175k
    return;
129
175k
}
130
131
/**
132
*******************************************************************************
133
*
134
* @brief
135
*  Flushes given number of bits. Bits consumed increases by  this number
136
*
137
* @par Description:
138
*  Increment bit offset by numbits. If bit offset increases  beyond 32, then
139
* move nxt_word to cur_word, read next  word32 to nxt_word after endian
140
* conversion
141
*
142
* @param[in] ps_bitstrm
143
*  Pointer to bitstream structure
144
*
145
* @param[in] u4_numbits
146
*  Number of bits to be flushed
147
*
148
* @returns  None
149
*
150
* @remarks
151
*
152
*
153
*******************************************************************************
154
*/
155
void ihevcd_bits_flush(bitstrm_t *ps_bitstrm, UWORD32 u4_numbits)
156
118k
{
157
158
118k
    BITS_FLUSH(ps_bitstrm->pu4_buf,
159
118k
               ps_bitstrm->u4_bit_ofst,
160
118k
               ps_bitstrm->u4_cur_word,
161
118k
               ps_bitstrm->u4_nxt_word,
162
118k
               u4_numbits);
163
164
118k
    return;
165
118k
}
166
167
/**
168
*******************************************************************************
169
*
170
* @brief
171
*  Flushes to next byte boundary.Bits consumed increases by  this number
172
*
173
* @par Description:
174
*  Compute number of bits remaining in the current byte  then call
175
* ihevcd_bits_flush() bits with this number
176
*
177
* @param[in] ps_bitstrm
178
*  Pointer to bitstream structure
179
*
180
* @returns  None
181
*
182
* @remarks
183
*
184
*
185
*******************************************************************************
186
*/
187
void ihevcd_bits_flush_to_byte_boundary(bitstrm_t *ps_bitstrm)
188
31.0k
{
189
31.0k
    UWORD32 u4_numbits;
190
31.0k
    u4_numbits = (ps_bitstrm->u4_bit_ofst) & 7;
191
192
31.0k
    u4_numbits = 8 - u4_numbits;
193
194
31.0k
    BITS_FLUSH(ps_bitstrm->pu4_buf,
195
31.0k
               ps_bitstrm->u4_bit_ofst,
196
31.0k
               ps_bitstrm->u4_cur_word,
197
31.0k
               ps_bitstrm->u4_nxt_word,
198
31.0k
               u4_numbits);
199
200
31.0k
    return;
201
31.0k
}
202
203
/**
204
*******************************************************************************
205
*
206
* @brief
207
*  Seeks by given number of bits in the bitstream from current position
208
*
209
* @par Description:
210
*  Add given number of bits to bitstream offset and update pu4_buf, cur_word and
211
*  nxt_word accordingly
212
*
213
* @param[in] ps_bitstrm
214
*  Pointer to bitstream structure
215
*
216
* @param[in] numbits
217
*  Number of bits to seek
218
*
219
* @returns  None
220
*
221
* @remarks
222
* Assumes emulation prevention has been done before and the buffer does not
223
* contain any emulation prevention bytes
224
*
225
*******************************************************************************
226
*/
227
void ihevcd_bits_seek(bitstrm_t *ps_bitstrm, WORD32 numbits)
228
13.0k
{
229
13.0k
    WORD32 val;
230
13.0k
    ASSERT(numbits >= -32);
231
13.0k
    ASSERT(numbits <= 32);
232
    /* Check if Seeking backwards*/
233
13.0k
    if(numbits < 0)
234
12.8k
    {
235
12.8k
        UWORD32 abs_numbits = -numbits;
236
12.8k
        if(ps_bitstrm->u4_bit_ofst >= abs_numbits)
237
5.90k
        {
238
            /* If the current offset is greater than number of bits to seek back,
239
             * then subtract abs_numbits from offset and return.
240
             */
241
5.90k
            ps_bitstrm->u4_bit_ofst -= abs_numbits;
242
5.90k
            return;
243
5.90k
        }
244
6.94k
        else
245
6.94k
        {
246
            /* If the current offset is lesser than number of bits to seek back,
247
             * then subtract abs_numbits from offset and add 32 and move cur_word to nxt_word
248
             * and load cur_word appropriately and decrement pu4_buf
249
             */
250
6.94k
            ps_bitstrm->u4_bit_ofst += 32;
251
6.94k
            ps_bitstrm->u4_bit_ofst -= abs_numbits;
252
6.94k
            ps_bitstrm->pu4_buf--;
253
254
6.94k
            val = *(ps_bitstrm->pu4_buf - 2);
255
6.94k
            ps_bitstrm->u4_nxt_word = ps_bitstrm->u4_cur_word;
256
6.94k
            ps_bitstrm->u4_cur_word = ITT_BIG_ENDIAN(val);
257
6.94k
            return;
258
6.94k
        }
259
12.8k
    }
260
210
    else
261
210
    {
262
        /* Not supported/tested currently */
263
210
        ASSERT(1);
264
210
        BITS_FLUSH(ps_bitstrm->pu4_buf,
265
210
                   ps_bitstrm->u4_bit_ofst,
266
210
                   ps_bitstrm->u4_cur_word,
267
210
                   ps_bitstrm->u4_nxt_word,
268
210
                   numbits);
269
270
271
210
    }
272
210
    return;
273
13.0k
}
274
/**
275
*******************************************************************************
276
*
277
* @brief
278
*  Snoops for next numbits number of bits from the bitstream this does not
279
* update the bitstream offset and does not  consume the bits
280
*
281
* @par Description:
282
*  Extract required number of bits from cur_word & nxt_word  return these
283
* bits
284
*
285
* @param[in] ps_bitstrm
286
*  Pointer to bitstream structure
287
*
288
* @param[in] u4_numbits
289
*  Number of bits
290
*
291
* @returns  Next u4_numbits number of bits
292
*
293
* @remarks
294
*
295
*
296
*******************************************************************************
297
*/
298
UWORD32 ihevcd_bits_nxt(bitstrm_t *ps_bitstrm, UWORD32 u4_numbits)
299
1.25M
{
300
1.25M
    UWORD32 u4_bits_read;
301
302
1.25M
    BITS_NXT(u4_bits_read,
303
1.25M
             ps_bitstrm->pu4_buf,
304
1.25M
             ps_bitstrm->u4_bit_ofst,
305
1.25M
             ps_bitstrm->u4_cur_word,
306
1.25M
             ps_bitstrm->u4_nxt_word,
307
1.25M
             u4_numbits);
308
1.25M
    return u4_bits_read;
309
1.25M
}
310
/**
311
*******************************************************************************
312
*
313
* @brief
314
*  Snoops for next 32 bits from the bitstream  this does not update the
315
* bitstream offset and does not  consume the bits
316
*
317
* @par Description:
318
*  Extract required number of bits from cur_word & nxt_word  return these
319
* bits
320
*
321
* @param[in] ps_bitstrm
322
*  Pointer to bitstream structure
323
*
324
* @param[in] u4_numbits
325
*  Number of bits
326
*
327
* @returns  Next 32 bits
328
*
329
* @remarks
330
*
331
*
332
*******************************************************************************
333
*/
334
UWORD32 ihevcd_bits_nxt32(bitstrm_t *ps_bitstrm, UWORD32 u4_numbits)
335
0
{
336
0
    UWORD32 u4_bits_read;
337
0
    UNUSED(u4_numbits);
338
0
    BITS_NXT32(u4_bits_read,
339
0
               ps_bitstrm->pu4_buf,
340
0
               ps_bitstrm->u4_bit_ofst,
341
0
               ps_bitstrm->u4_cur_word,
342
0
               ps_bitstrm->u4_nxt_word);
343
0
    return u4_bits_read;
344
0
}
345
346
/**
347
*******************************************************************************
348
*
349
* @brief
350
*  Reads next numbits number of bits from the bitstream  this updates the
351
* bitstream offset and consumes the bits
352
*
353
* @par Description:
354
*  Extract required number of bits from cur_word & nxt_word  return these
355
* bits
356
*
357
* @param[in] ps_bitstrm
358
*  Pointer to bitstream structure
359
*
360
* @param[in] u4_numbits
361
*  Number of bits
362
*
363
* @returns  Bits read
364
*
365
* @remarks
366
*
367
*
368
*******************************************************************************
369
*/
370
UWORD32 ihevcd_bits_get(bitstrm_t *ps_bitstrm, UWORD32 u4_numbits)
371
7.58M
{
372
7.58M
    UWORD32 u4_bits_read;
373
374
7.58M
    BITS_GET(u4_bits_read,
375
7.58M
             ps_bitstrm->pu4_buf,
376
7.58M
             ps_bitstrm->u4_bit_ofst,
377
7.58M
             ps_bitstrm->u4_cur_word,
378
7.58M
             ps_bitstrm->u4_nxt_word,
379
7.58M
             u4_numbits);
380
7.58M
    return u4_bits_read;
381
382
7.58M
}
383
384
/**
385
*******************************************************************************
386
*
387
* @brief
388
*  Returns the number of bits remaining in the bitstream
389
*
390
* @par Description:
391
*  Compute number of bits remaining based on current pointer and buffer base
392
* and current offset. Since 8 bytes are  read at the start into cur_word and
393
* nxt_word and are not  consumed, 8 has to be subtracted
394
*
395
* @param[in] ps_bitstrm
396
*  Pointer to bitstream structure
397
*
398
* @returns  Total number of bits remaining
399
*
400
* @remarks
401
*
402
*
403
*******************************************************************************
404
*/
405
UWORD32  ihevcd_bits_num_bits_remaining(bitstrm_t *ps_bitstrm)
406
1.26M
{
407
1.26M
    UWORD32 u4_bits_consumed;
408
1.26M
    UWORD32 u4_size_in_bits;
409
410
    /* 8 bytes are read in cur_word and nxt_word at the start. Hence */
411
    /* subtract 8 bytes */
412
1.26M
    u4_bits_consumed = (UWORD32)(((UWORD8 *)ps_bitstrm->pu4_buf -
413
1.26M
                                  (UWORD8 *)ps_bitstrm->pu1_buf_base - 8) <<
414
1.26M
                                 3) + ps_bitstrm->u4_bit_ofst;
415
416
1.26M
    u4_size_in_bits = (UWORD32)(ps_bitstrm->pu1_buf_max -
417
1.26M
                    ps_bitstrm->pu1_buf_base) - 8;
418
1.26M
    u4_size_in_bits <<= 3;
419
1.26M
    if(u4_size_in_bits > u4_bits_consumed)
420
1.24M
    {
421
1.24M
        return (u4_size_in_bits - u4_bits_consumed);
422
1.24M
    }
423
20.5k
    else
424
20.5k
    {
425
20.5k
        return 0;
426
20.5k
    }
427
1.26M
}
428
429
/**
430
*******************************************************************************
431
*
432
* @brief
433
*  Returns the number of bits consumed in the bitstream
434
*
435
* @par Description:
436
*  Compute number of bits consumed based on current pointer  and buffer base
437
* and current offset. Since 8 bytes are  read at the start into cur_word and
438
* nxt_word and are not  consumed, 8 has to be subtracted
439
*
440
* @param[in] ps_bitstrm
441
*  Pointer to bitstream structure
442
*
443
* @returns  Total number of bits bits consumed
444
*
445
* @remarks
446
*
447
*
448
*******************************************************************************
449
*/
450
UWORD32  ihevcd_bits_num_bits_consumed(bitstrm_t *ps_bitstrm)
451
0
{
452
0
    UWORD32 u4_bits_consumed;
453
    /* 8 bytes are read in cur_word and nxt_word at the start. Hence */
454
    /* subtract 8 bytes */
455
456
0
    u4_bits_consumed = (UWORD32)(((UWORD8 *)ps_bitstrm->pu4_buf -
457
0
                                  (UWORD8 *)ps_bitstrm->pu1_buf_base - 8) <<
458
0
                                 3) + ps_bitstrm->u4_bit_ofst;
459
0
    return u4_bits_consumed;
460
0
}
461
462
/**
463
*******************************************************************************
464
*
465
* @brief
466
*  Reads unsigned integer 0-th order exp-golomb-coded syntax element from
467
* the bitstream  Section: 9.2
468
*
469
* @par Description:
470
*  Extract required number of bits from cur_word & nxt_word  return these
471
* bits
472
*
473
* @param[in] ps_bitstrm
474
*  Pointer to bitstream structure
475
*
476
* @returns  UEV decoded syntax element
477
*
478
* @remarks
479
*
480
*
481
*******************************************************************************
482
*/
483
UWORD32 ihevcd_uev(bitstrm_t *ps_bitstrm)
484
695k
{
485
695k
    UWORD32 u4_bits_read;
486
695k
    UWORD32 u4_clz;
487
488
489
    /***************************************************************/
490
    /* Find leading zeros in next 32 bits                          */
491
    /***************************************************************/
492
695k
    BITS_NXT32(u4_bits_read,
493
695k
               ps_bitstrm->pu4_buf,
494
695k
               ps_bitstrm->u4_bit_ofst,
495
695k
               ps_bitstrm->u4_cur_word,
496
695k
               ps_bitstrm->u4_nxt_word);
497
498
499
695k
    u4_clz = CLZ(u4_bits_read);
500
501
695k
    BITS_FLUSH(ps_bitstrm->pu4_buf,
502
695k
               ps_bitstrm->u4_bit_ofst,
503
695k
               ps_bitstrm->u4_cur_word,
504
695k
               ps_bitstrm->u4_nxt_word,
505
695k
               (u4_clz + 1));
506
507
695k
    u4_bits_read = 0;
508
695k
    if(u4_clz)
509
293k
    {
510
293k
        BITS_GET(u4_bits_read,
511
293k
                 ps_bitstrm->pu4_buf,
512
293k
                 ps_bitstrm->u4_bit_ofst,
513
293k
                 ps_bitstrm->u4_cur_word,
514
293k
                 ps_bitstrm->u4_nxt_word,
515
293k
                 u4_clz);
516
293k
    }
517
695k
    return ((1 << u4_clz) + u4_bits_read - 1);
518
519
695k
}
520
521
/**
522
*******************************************************************************
523
*
524
* @brief
525
*  Reads signed integer 0-th order exp-golomb-coded syntax  element from the
526
* bitstream. Function similar to get_uev  Section: 9.2.1
527
*
528
* @par Description:
529
*  Extract required number of bits from cur_word & nxt_word  return these
530
* bits
531
*
532
* @param[in] ps_bitstrm
533
*  Pointer to bitstream structure
534
*
535
* @returns  UEV decoded syntax element
536
*
537
* @remarks
538
*
539
*
540
*******************************************************************************
541
*/
542
WORD32 ihevcd_sev(bitstrm_t *ps_bitstrm)
543
362k
{
544
362k
    UWORD32 u4_bits_read;
545
362k
    UWORD32 u4_clz;
546
362k
    UWORD32 u4_abs_val;
547
548
549
    /***************************************************************/
550
    /* Find leading zeros in next 32 bits                          */
551
    /***************************************************************/
552
362k
    BITS_NXT32(u4_bits_read,
553
362k
               ps_bitstrm->pu4_buf,
554
362k
               ps_bitstrm->u4_bit_ofst,
555
362k
               ps_bitstrm->u4_cur_word,
556
362k
               ps_bitstrm->u4_nxt_word);
557
558
559
362k
    u4_clz = CLZ(u4_bits_read);
560
561
362k
    BITS_FLUSH(ps_bitstrm->pu4_buf,
562
362k
               ps_bitstrm->u4_bit_ofst,
563
362k
               ps_bitstrm->u4_cur_word,
564
362k
               ps_bitstrm->u4_nxt_word,
565
362k
               (u4_clz + 1));
566
567
362k
    u4_bits_read = 0;
568
362k
    if(u4_clz)
569
69.8k
    {
570
69.8k
        BITS_GET(u4_bits_read,
571
69.8k
                 ps_bitstrm->pu4_buf,
572
69.8k
                 ps_bitstrm->u4_bit_ofst,
573
69.8k
                 ps_bitstrm->u4_cur_word,
574
69.8k
                 ps_bitstrm->u4_nxt_word,
575
69.8k
                 u4_clz);
576
69.8k
    }
577
362k
    u4_abs_val = ((1 << u4_clz) + u4_bits_read) >> 1;
578
362k
    if(u4_bits_read & 0x1)
579
31.2k
        return (-(WORD32)u4_abs_val);
580
331k
    else
581
331k
        return (u4_abs_val);
582
362k
}
583
584
585
586
587
588