Coverage Report

Created: 2026-05-30 06:23

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libhevc/encoder/ihevce_cabac.c
Line
Count
Source
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_cabac.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_cabac_reset()
32
*  ihevce_cabac_init()
33
*  ihevce_cabac_put_byte()
34
*  ihevce_cabac_encode_bin()
35
*  ihevce_cabac_encode_bypass_bin()
36
*  ihevce_cabac_encode_terminate()
37
*  ihevce_cabac_encode_tunary()
38
*  ihevce_cabac_encode_tunary_bypass()
39
*  ihevce_cabac_encode_bypass_bins()
40
*  ihevce_cabac_encode_egk()
41
*  ihevce_cabac_encode_trunc_rice()
42
*  ihevce_cabac_encode_trunc_rice_ctxt()
43
*  ihevce_cabac_flush()
44
*  ihevce_cabac_ctxt_backup()
45
*  ihevce_cabac_ctxt_row_init()
46
*
47
*******************************************************************************
48
*/
49
50
/*****************************************************************************/
51
/* File Includes                                                             */
52
/*****************************************************************************/
53
/* System include files */
54
#include <stdio.h>
55
#include <string.h>
56
#include <stdlib.h>
57
#include <assert.h>
58
#include <stdarg.h>
59
#include <math.h>
60
61
/* User include files */
62
#include "ihevc_typedefs.h"
63
#include "ihevc_debug.h"
64
#include "ihevc_macros.h"
65
#include "ihevc_platform_macros.h"
66
#include "ihevc_cabac_tables.h"
67
68
#include "ihevce_defs.h"
69
#include "ihevce_error_codes.h"
70
#include "ihevce_bitstream.h"
71
#include "ihevce_cabac.h"
72
73
#define TEST_CABAC_BITESTIMATE 0
74
75
/*****************************************************************************/
76
/* Function Definitions                                                      */
77
/*****************************************************************************/
78
79
/**
80
******************************************************************************
81
*
82
*  @brief Resets the encoder cabac engine
83
*
84
*  @par   Description
85
*  This routine needs to be called at start of dependent slice encode
86
*
87
*  @param[inout]   ps_cabac_ctxt
88
*  pointer to cabac context (handle)
89
*
90
*  @param[in]   ps_bitstrm
91
*  pointer to bitstream context (handle)
92
*
93
*  @param[in]   e_cabac_op_mode
94
*  opertaing mode of cabac; put bits / compute bits mode @sa CABAC_OP_MODE
95
*
96
*  @return      success or failure error code
97
*
98
******************************************************************************
99
*/
100
WORD32
101
    ihevce_cabac_reset(cab_ctxt_t *ps_cabac, bitstrm_t *ps_bitstrm, CABAC_OP_MODE e_cabac_op_mode)
102
0
{
103
    /* Sanity checks */
104
0
    ASSERT(ps_cabac != NULL);
105
0
    ASSERT(
106
0
        (e_cabac_op_mode == CABAC_MODE_ENCODE_BITS) ||
107
0
        (e_cabac_op_mode == CABAC_MODE_COMPUTE_BITS));
108
109
0
    ps_cabac->e_cabac_op_mode = e_cabac_op_mode;
110
111
0
    if(CABAC_MODE_ENCODE_BITS == e_cabac_op_mode)
112
0
    {
113
0
        ASSERT(ps_bitstrm != NULL);
114
115
        /* Bitstream context initialization */
116
0
        ps_cabac->pu1_strm_buffer = ps_bitstrm->pu1_strm_buffer;
117
0
        ps_cabac->u4_max_strm_size = ps_bitstrm->u4_max_strm_size;
118
        /* When entropy sync is enabled start form fixed offset from point
119
         * where slice header extension has ended to handle emulation prevention
120
         *  bytes during insertion of slice offset at end of frame */
121
0
        if(1 == ps_cabac->i1_entropy_coding_sync_enabled_flag)
122
0
        {
123
0
            ps_cabac->u4_strm_buf_offset = ps_cabac->u4_first_slice_start_offset;
124
0
        }
125
0
        else
126
0
        {
127
0
            ps_cabac->u4_strm_buf_offset = ps_bitstrm->u4_strm_buf_offset;
128
0
        }
129
0
        ps_cabac->i4_zero_bytes_run = ps_bitstrm->i4_zero_bytes_run;
130
131
        /* cabac engine initialization */
132
0
        ps_cabac->u4_low = 0;
133
0
        ps_cabac->u4_range = 510;
134
0
        ps_cabac->u4_bits_gen = 0;
135
0
        ps_cabac->u4_out_standing_bytes = 0;
136
0
    }
137
0
    else /* (CABAC_MODE_COMPUTE_BITS == e_cabac_op_mode) */
138
0
    {
139
        /* reset the bits estimated */
140
0
        ps_cabac->u4_bits_estimated_q12 = 0;
141
142
        /* reset the texture bits estimated */
143
0
        ps_cabac->u4_texture_bits_estimated_q12 = 0;
144
145
        /* Setting range to 0 switches off AEV_TRACE in compute bits mode */
146
0
        ps_cabac->u4_range = 0;
147
0
    }
148
149
0
    return (IHEVCE_SUCCESS);
150
0
}
151
152
/**
153
******************************************************************************
154
*
155
*  @brief Initializes the encoder cabac engine
156
*
157
*  @par   Description
158
*  This routine needs to be called at start of slice/frame encode
159
*
160
*  @param[inout]   ps_cabac_ctxt
161
*  pointer to cabac context (handle)
162
*
163
*  @param[in]   ps_bitstrm
164
*  pointer to bitstream context (handle)
165
*
166
*  @param[in]   qp
167
*  current slice qp
168
*
169
*  @param[in]   cabac_init_idc
170
*  current slice init idc (range - [0- 2])*
171
*
172
*  @param[in]   e_cabac_op_mode
173
*  opertaing mode of cabac; put bits / compute bits mode @sa CABAC_OP_MODE
174
*
175
*  @return      success or failure error code
176
*
177
******************************************************************************
178
*/
179
WORD32 ihevce_cabac_init(
180
    cab_ctxt_t *ps_cabac,
181
    bitstrm_t *ps_bitstrm,
182
    WORD32 slice_qp,
183
    WORD32 cabac_init_idc,
184
    CABAC_OP_MODE e_cabac_op_mode)
185
7.56k
{
186
    /* Sanity checks */
187
7.56k
    ASSERT(ps_cabac != NULL);
188
7.56k
    ASSERT((slice_qp >= 0) && (slice_qp < IHEVC_MAX_QP));
189
7.56k
    ASSERT((cabac_init_idc >= 0) && (cabac_init_idc < 3));
190
7.56k
    ASSERT(
191
7.56k
        (e_cabac_op_mode == CABAC_MODE_ENCODE_BITS) ||
192
7.56k
        (e_cabac_op_mode == CABAC_MODE_COMPUTE_BITS));
193
194
7.56k
    ps_cabac->e_cabac_op_mode = e_cabac_op_mode;
195
196
7.56k
    if(CABAC_MODE_ENCODE_BITS == e_cabac_op_mode)
197
2.52k
    {
198
2.52k
        ASSERT(ps_bitstrm != NULL);
199
200
        /* Bitstream context initialization */
201
2.52k
        ps_cabac->pu1_strm_buffer = ps_bitstrm->pu1_strm_buffer;
202
2.52k
        ps_cabac->u4_max_strm_size = ps_bitstrm->u4_max_strm_size;
203
        /* When entropy sync is enabled start form fixed offset from point
204
         * where slice header extension has ended to handle emulation prevention
205
         *  bytes during insertion of slice offset at end of frame */
206
2.52k
        if(1 == ps_cabac->i1_entropy_coding_sync_enabled_flag)
207
72
        {
208
72
            ps_cabac->u4_strm_buf_offset = ps_cabac->u4_first_slice_start_offset;
209
72
        }
210
2.45k
        else
211
2.45k
        {
212
2.45k
            ps_cabac->u4_strm_buf_offset = ps_bitstrm->u4_strm_buf_offset;
213
2.45k
        }
214
2.52k
        ps_cabac->i4_zero_bytes_run = ps_bitstrm->i4_zero_bytes_run;
215
216
        /* cabac engine initialization */
217
2.52k
        ps_cabac->u4_low = 0;
218
2.52k
        ps_cabac->u4_range = 510;
219
2.52k
        ps_cabac->u4_bits_gen = 0;
220
2.52k
        ps_cabac->u4_out_standing_bytes = 0;
221
222
        /* reset the bits estimated */
223
2.52k
        ps_cabac->u4_bits_estimated_q12 = 0;
224
225
        /* reset the texture bits estimated */
226
2.52k
        ps_cabac->u4_texture_bits_estimated_q12 = 0;
227
2.52k
    }
228
5.04k
    else /* (CABAC_MODE_COMPUTE_BITS == e_cabac_op_mode) */
229
5.04k
    {
230
        /* reset the bits estimated */
231
5.04k
        ps_cabac->u4_bits_estimated_q12 = 0;
232
233
        /* reset the texture bits estimated */
234
5.04k
        ps_cabac->u4_texture_bits_estimated_q12 = 0;
235
236
        /* Setting range to 0 switches off AEV_TRACE in compute bits mode */
237
5.04k
        ps_cabac->u4_range = 0;
238
5.04k
    }
239
240
    /* cabac context initialization based on init idc and slice qp */
241
7.56k
    COPY_CABAC_STATES(
242
7.56k
        ps_cabac->au1_ctxt_models,
243
7.56k
        &gau1_ihevc_cab_ctxts[cabac_init_idc][slice_qp][0],
244
7.56k
        IHEVC_CAB_CTXT_END);
245
246
7.56k
    return (IHEVCE_SUCCESS);
247
7.56k
}
248
249
/**
250
******************************************************************************
251
*
252
*  @brief Puts new byte (and outstanding bytes) into bitstream after cabac
253
*         renormalization
254
*
255
*  @par   Description
256
*  1. Extract the leading byte of low(L)
257
*  2. If leading byte=0xff increment outstanding bytes and return
258
*     (as the actual bits depend on carry propogation later)
259
*  3. If leading byte is not 0xff check for any carry propogation
260
*  4. Insert the carry (propogated in previous byte) along with outstanding
261
*     bytes (if any) and leading byte
262
*
263
*
264
*  @param[inout]   ps_cabac
265
*  pointer to cabac context (handle)
266
*
267
*  @return      success or failure error code
268
*
269
******************************************************************************
270
*/
271
WORD32 ihevce_cabac_put_byte(cab_ctxt_t *ps_cabac)
272
9.40M
{
273
9.40M
    UWORD32 u4_low = ps_cabac->u4_low;
274
9.40M
    UWORD32 u4_bits_gen = ps_cabac->u4_bits_gen;
275
9.40M
    WORD32 lead_byte = u4_low >> (u4_bits_gen + CABAC_BITS - 8);
276
277
    /* Sanity checks */
278
9.40M
    ASSERT((ps_cabac->u4_range >= 256) && (ps_cabac->u4_range < 512));
279
9.40M
    ASSERT((u4_bits_gen >= 8));
280
281
    /* update bits generated and low after extracting leading byte */
282
9.40M
    u4_bits_gen -= 8;
283
9.40M
    ps_cabac->u4_low &= ((1 << (CABAC_BITS + u4_bits_gen)) - 1);
284
9.40M
    ps_cabac->u4_bits_gen = u4_bits_gen;
285
286
    /************************************************************************/
287
    /* 1. Extract the leading byte of low(L)                                */
288
    /* 2. If leading byte=0xff increment outstanding bytes and return       */
289
    /*      (as the actual bits depend on carry propogation later)          */
290
    /* 3. If leading byte is not 0xff check for any carry propogation       */
291
    /* 4. Insert the carry (propogated in previous byte) along with         */
292
    /*    outstanding bytes (if any) and leading byte                       */
293
    /************************************************************************/
294
9.40M
    if(lead_byte == 0xff)
295
56.0k
    {
296
        /* actual bits depend on carry propogration     */
297
56.0k
        ps_cabac->u4_out_standing_bytes++;
298
56.0k
        return (IHEVCE_SUCCESS);
299
56.0k
    }
300
9.34M
    else
301
9.34M
    {
302
        /* carry = 1 => putbit(1); carry propogated due to L renorm */
303
9.34M
        WORD32 carry = (lead_byte >> 8) & 0x1;
304
9.34M
        UWORD8 *pu1_strm_buf = ps_cabac->pu1_strm_buffer;
305
9.34M
        UWORD32 u4_strm_buf_offset = ps_cabac->u4_strm_buf_offset;
306
9.34M
        WORD32 zero_run = ps_cabac->i4_zero_bytes_run;
307
9.34M
        UWORD32 u4_out_standing_bytes = ps_cabac->u4_out_standing_bytes;
308
309
        /*********************************************************************/
310
        /* Bitstream overflow check                                          */
311
        /* NOTE: corner case of epb bytes (max 2 for 32bit word) not handled */
312
        /*********************************************************************/
313
9.34M
        if((u4_strm_buf_offset + u4_out_standing_bytes + 1) >= ps_cabac->u4_max_strm_size)
314
213k
        {
315
            /* return without corrupting the buffer beyond its size */
316
213k
            return (IHEVCE_BITSTREAM_BUFFER_OVERFLOW);
317
213k
        }
318
319
        /*********************************************************************/
320
        /*        Insert the carry propogated in previous byte               */
321
        /*                                                                   */
322
        /* Note : Do not worry about corruption into slice header align byte */
323
        /*        This is because the first bin cannot result in overflow    */
324
        /*********************************************************************/
325
9.13M
        if(carry)
326
432k
        {
327
            /* CORNER CASE: if the previous data is 0x000003, then EPB will be inserted
328
            and the data will become 0x00000303 and if the carry is present, it will
329
            be added with the last byte and it will become 0x00000304 which is not correct
330
            as per standard*/
331
            /* so check for previous four bytes and if it is equal to 0x00000303
332
            then subtract u4_strm_buf_offset by 1 */
333
432k
            if(pu1_strm_buf[u4_strm_buf_offset - 1] == 0x03 &&
334
1.73k
               pu1_strm_buf[u4_strm_buf_offset - 2] == 0x03 &&
335
3
               pu1_strm_buf[u4_strm_buf_offset - 3] == 0x00 &&
336
0
               pu1_strm_buf[u4_strm_buf_offset - 4] == 0x00)
337
0
            {
338
0
                u4_strm_buf_offset -= 1;
339
0
            }
340
            /* previous byte carry add will not result in overflow to        */
341
            /* u4_strm_buf_offset - 2 as we track 0xff as outstanding bytes  */
342
432k
            pu1_strm_buf[u4_strm_buf_offset - 1] += carry;
343
432k
            zero_run = 0;
344
432k
        }
345
346
        /*        Insert outstanding bytes (if any)         */
347
9.19M
        while(u4_out_standing_bytes)
348
54.8k
        {
349
54.8k
            UWORD8 u1_0_or_ff = carry ? 0 : 0xFF;
350
351
54.8k
            PUTBYTE_EPB(pu1_strm_buf, u4_strm_buf_offset, u1_0_or_ff, zero_run);
352
353
54.8k
            u4_out_standing_bytes--;
354
54.8k
        }
355
9.13M
        ps_cabac->u4_out_standing_bytes = 0;
356
357
        /*        Insert the leading byte                   */
358
9.13M
        lead_byte &= 0xFF;
359
9.13M
        PUTBYTE_EPB(pu1_strm_buf, u4_strm_buf_offset, lead_byte, zero_run);
360
361
        /* update the state variables and return success */
362
9.13M
        ps_cabac->u4_strm_buf_offset = u4_strm_buf_offset;
363
9.13M
        ps_cabac->i4_zero_bytes_run = zero_run;
364
9.13M
        return (IHEVCE_SUCCESS);
365
9.34M
    }
366
9.40M
}
367
368
/**
369
******************************************************************************
370
*
371
*  @brief Codes a bypass bin (equi probable 0 / 1)
372
*
373
*  @par   Description
374
*  After encoding bypass bin, bits gen incremented by 1 and bitstream generated
375
*
376
*  @param[inout]  ps_cabac : pointer to cabac context (handle)
377
*
378
*  @param[in]   bin :  bypass bin(0/1) to be encoded
379
*
380
*  @return      success or failure error code
381
*
382
******************************************************************************
383
*/
384
WORD32 ihevce_cabac_encode_bypass_bin(cab_ctxt_t *ps_cabac, WORD32 bin)
385
306k
{
386
306k
    UWORD32 u4_range = ps_cabac->u4_range;
387
306k
    UWORD32 u4_low = ps_cabac->u4_low;
388
389
306k
    if(CABAC_MODE_ENCODE_BITS == ps_cabac->e_cabac_op_mode)
390
49.4k
    {
391
        /* Sanity checks */
392
49.4k
        ASSERT((u4_range >= 256) && (u4_range < 512));
393
49.4k
        ASSERT((bin == 0) || (bin == 1));
394
395
        /*Compute bit always to populate the trace*/
396
        /* increment bits generated by 1 */
397
49.4k
        ps_cabac->u4_bits_estimated_q12 += (1 << CABAC_FRAC_BITS_Q);
398
399
49.4k
        u4_low <<= 1;
400
        /* add range if bin is 1 */
401
49.4k
        if(bin)
402
29.5k
        {
403
29.5k
            u4_low += u4_range;
404
29.5k
        }
405
406
        /* 1 bit to be inserted in the bitstream */
407
49.4k
        ps_cabac->u4_bits_gen++;
408
49.4k
        ps_cabac->u4_low = u4_low;
409
410
        /* generate stream when a byte is ready */
411
49.4k
        if(ps_cabac->u4_bits_gen > CABAC_BITS)
412
6.18k
        {
413
6.18k
            return (ihevce_cabac_put_byte(ps_cabac));
414
6.18k
        }
415
49.4k
    }
416
257k
    else /* (CABAC_MODE_COMPUTE_BITS == e_cabac_op_mode) */
417
257k
    {
418
        /* increment bits generated by 1 */
419
257k
        ps_cabac->u4_bits_estimated_q12 += (1 << CABAC_FRAC_BITS_Q);
420
257k
    }
421
422
300k
    return (IHEVCE_SUCCESS);
423
306k
}
424
425
/**
426
******************************************************************************
427
*
428
*  @brief Codes a terminate bin (1:terminate 0:do not terminate)
429
*
430
*  @par   Description
431
*  After encoding bypass bin, bits gen incremented by 1 and bitstream generated
432
*
433
*  @param[inout]  ps_cabac : pointer to cabac context (handle)
434
*
435
*  @param[in]   term_bin : (1:terminate 0:do not terminate)
436
*
437
*  @return      success or failure error code
438
*
439
******************************************************************************
440
*/
441
WORD32
442
    ihevce_cabac_encode_terminate(cab_ctxt_t *ps_cabac, WORD32 term_bin, WORD32 i4_end_of_sub_strm)
443
13.8k
{
444
13.8k
    UWORD32 u4_range = ps_cabac->u4_range;
445
13.8k
    UWORD32 u4_low = ps_cabac->u4_low;
446
13.8k
    UWORD32 u4_rlps;
447
13.8k
    WORD32 shift;
448
13.8k
    WORD32 error = IHEVCE_SUCCESS;
449
450
    /* Sanity checks */
451
13.8k
    ASSERT((u4_range >= 256) && (u4_range < 512));
452
13.8k
    ASSERT((term_bin == 0) || (term_bin == 1));
453
454
    /*  term_bin = 1 has lps range = 2 */
455
13.8k
    u4_rlps = 2;
456
13.8k
    u4_range -= u4_rlps;
457
458
    /* if terminate L is incremented by curR and R=2 */
459
13.8k
    if(term_bin)
460
2.98k
    {
461
        /* lps path;  L= L + R; R = RLPS */
462
2.98k
        u4_low += u4_range;
463
2.98k
        u4_range = u4_rlps;
464
2.98k
    }
465
466
    /*****************************************************************/
467
    /* Renormalization; calculate bits generated based on range(R)   */
468
    /* Note : 6 <= R < 512; R is 2 only for terminating encode       */
469
    /*****************************************************************/
470
13.8k
    GETRANGE(shift, u4_range);
471
13.8k
    shift = 9 - shift;
472
13.8k
    u4_low <<= shift;
473
13.8k
    u4_range <<= shift;
474
475
    /* bits to be inserted in the bitstream */
476
13.8k
    ps_cabac->u4_bits_gen += shift;
477
13.8k
    ps_cabac->u4_range = u4_range;
478
13.8k
    ps_cabac->u4_low = u4_low;
479
480
    /* generate stream when a byte is ready */
481
13.8k
    if(ps_cabac->u4_bits_gen > CABAC_BITS)
482
2.66k
    {
483
2.66k
        error = ihevce_cabac_put_byte(ps_cabac);
484
2.66k
    }
485
486
13.8k
    if(term_bin)
487
2.98k
    {
488
2.98k
        ihevce_cabac_flush(ps_cabac, i4_end_of_sub_strm);
489
2.98k
    }
490
491
    /*Compute bit always to populate the trace*/
492
13.8k
    ps_cabac->u4_bits_estimated_q12 += gau2_ihevce_cabac_bin_to_bits[(62 << 1) | term_bin];
493
494
13.8k
    return (error);
495
13.8k
}
496
497
/**
498
******************************************************************************
499
*
500
*  @brief Encodes a truncated unary symbol associated with context model(s)
501
*
502
*  @par   Description
503
*  Does binarization of tunary symbol as per sec 9.3.2.2 and does the cabac
504
*  encoding of each bin. This is used for computing symbols like qp_delta,
505
*  last_sig_coeff_prefix_x, last_sig_coeff_prefix_y.
506
*
507
*  The context models associated with each bin is computed as :
508
*   current bin context = "base context idx" + (bin_idx >> shift)
509
*  where
510
*   1. "base context idx" is the base index for the syntax element
511
*   2. "bin_idx" is the current bin index of the unary code
512
*   3. "shift" is the shift factor associated with this syntax element
513
*
514
*  @param[inout]ps_cabac
515
*   pointer to cabac context (handle)
516
*
517
*  @param[in]   sym
518
*   syntax element to be coded as truncated unary bins
519
*
520
*  @param[in]   c_max
521
*   maximum value of sym (required for tunary binarization)
522
*
523
*  @param[in]   ctxt_index
524
*   base context model index for this syntax element
525
*
526
*  @param[in]   ctxt_shift
527
*   shift factor for context increments associated with this syntax element
528
*
529
*  @param[in]   ctxt_inc_max
530
*   max value of context increment beyond which all bins will use same ctxt
531
*
532
*  @return      success or failure error code
533
*
534
******************************************************************************
535
*/
536
WORD32 ihevce_cabac_encode_tunary(
537
    cab_ctxt_t *ps_cabac,
538
    WORD32 sym,
539
    WORD32 c_max,
540
    WORD32 ctxt_index,
541
    WORD32 ctxt_shift,
542
    WORD32 ctxt_inc_max)
543
15.2M
{
544
15.2M
    WORD32 bin_ctxt, i;
545
15.2M
    WORD32 error = IHEVCE_SUCCESS;
546
547
    /* Sanity checks */
548
15.2M
    ASSERT(c_max > 0);
549
15.2M
    ASSERT((sym <= c_max) && (sym >= 0));
550
15.2M
    ASSERT((ctxt_index >= 0) && (ctxt_index < IHEVC_CAB_CTXT_END));
551
15.2M
    ASSERT((ctxt_index + (c_max >> ctxt_shift)) < IHEVC_CAB_CTXT_END);
552
553
    /* Special case of sym= 0 */
554
15.2M
    if(0 == sym)
555
1.03M
    {
556
1.03M
        return (ihevce_cabac_encode_bin(ps_cabac, 0, ctxt_index));
557
1.03M
    }
558
559
    /* write '1' bins  */
560
59.8M
    for(i = 0; i < sym; i++)
561
45.5M
    {
562
        /* TODO: encode bin to be inlined later */
563
45.5M
        bin_ctxt = ctxt_index + MIN((i >> ctxt_shift), ctxt_inc_max);
564
45.5M
        error |= ihevce_cabac_encode_bin(ps_cabac, 1, bin_ctxt);
565
45.5M
    }
566
567
    /* write terminating 0 bin */
568
14.2M
    if(sym < c_max)
569
2.03M
    {
570
        /* TODO: encode bin to be inlined later */
571
2.03M
        bin_ctxt = ctxt_index + MIN((i >> ctxt_shift), ctxt_inc_max);
572
2.03M
        error |= ihevce_cabac_encode_bin(ps_cabac, 0, bin_ctxt);
573
2.03M
    }
574
575
14.2M
    return (error);
576
15.2M
}
577
578
/**
579
******************************************************************************
580
*
581
*  @brief Encodes a syntax element as truncated unary bypass bins
582
*
583
*  @par   Description
584
*  Does binarization of tunary symbol as per sec 9.3.2.2 and does the cabac
585
*  encoding of each bin. This is used for computing symbols like merge_idx,
586
*  mpm_idx etc
587
*
588
*  @param[inout]ps_cabac
589
*   pointer to cabac context (handle)
590
*
591
*  @param[in]   sym
592
*   syntax element to be coded as truncated unary bins
593
*
594
*  @param[in]   c_max
595
*   maximum value of sym (required for tunary binarization)
596
*
597
*  @return      success or failure error code
598
*
599
******************************************************************************
600
*/
601
WORD32 ihevce_cabac_encode_tunary_bypass(cab_ctxt_t *ps_cabac, WORD32 sym, WORD32 c_max)
602
277k
{
603
277k
    WORD32 error = IHEVCE_SUCCESS;
604
277k
    WORD32 length;
605
277k
    WORD32 u4_bins;
606
607
    /* Sanity checks */
608
277k
    ASSERT(c_max > 0);
609
277k
    ASSERT((sym <= c_max) && (sym >= 0));
610
611
277k
    if(sym < c_max)
612
271k
    {
613
        /* unary code with (sym) '1's and terminating '0' bin */
614
271k
        length = (sym + 1);
615
271k
        u4_bins = (1 << length) - 2;
616
271k
    }
617
5.75k
    else
618
5.75k
    {
619
        /* tunary code with (sym) '1's */
620
5.75k
        length = sym;
621
5.75k
        u4_bins = (1 << length) - 1;
622
5.75k
    }
623
624
    /* Encode the tunary binarized code as bypass bins */
625
277k
    error = ihevce_cabac_encode_bypass_bins(ps_cabac, u4_bins, length);
626
627
277k
    return (error);
628
277k
}
629
630
/**
631
******************************************************************************
632
*
633
*  @brief Encodes a syntax element as kth order Exp-Golomb code (EGK)
634
*
635
*  @par   Description
636
*  Does binarization of symbol as per sec 9.3.2.4  kth order Exp-Golomb(EGk)
637
*  process and encodes the resulting bypass bins
638
*
639
*  @param[inout]ps_cabac
640
*   pointer to cabac context (handle)
641
*
642
*  @param[in]   u4_sym
643
*   syntax element to be coded as EGK
644
*
645
*  @param[in]   k
646
*   order of EGk
647
*
648
*  @return      success or failure error code
649
*
650
******************************************************************************
651
*/
652
WORD32 ihevce_cabac_encode_egk(cab_ctxt_t *ps_cabac, UWORD32 u4_sym, WORD32 k)
653
7.58M
{
654
7.58M
    WORD32 num_bins, unary_length;
655
7.58M
    UWORD32 u4_sym_shiftk_plus1, u4_egk, u4_unary_bins;
656
657
7.58M
    WORD32 error = IHEVCE_SUCCESS;
658
659
    /* Sanity checks */
660
7.58M
    ASSERT((k >= 0));
661
    /* ASSERT(u4_sym >= (UWORD32)(1 << k)); */
662
663
    /************************************************************************/
664
    /* shift symbol by k bits to find unary code prefix (111110)            */
665
    /* Use GETRANGE to elminate the while loop in sec 9.3.2.4 of HEVC spec  */
666
    /************************************************************************/
667
7.58M
    u4_sym_shiftk_plus1 = (u4_sym >> k) + 1;
668
    /* GETRANGE(unary_length, (u4_sym_shiftk_plus1 + 1)); */
669
7.58M
    GETRANGE(unary_length, u4_sym_shiftk_plus1);
670
671
    /* unary code with (unary_length-1) '1's and terminating '0' bin */
672
7.58M
    u4_unary_bins = (1 << unary_length) - 2;
673
674
    /* insert the symbol prefix of (unary lenght - 1)  bins */
675
7.58M
    u4_egk = (u4_unary_bins << (unary_length - 1)) |
676
7.58M
             (u4_sym_shiftk_plus1 & ((1 << (unary_length - 1)) - 1));
677
678
    /* insert last k bits of symbol in the end */
679
7.58M
    u4_egk = (u4_egk << k) | (u4_sym & ((1 << k) - 1));
680
681
    /* length of the code = 2 *(unary_length - 1) + 1 + k */
682
7.58M
    num_bins = (2 * unary_length) - 1 + k;
683
684
    /* Encode the egk binarized code as bypass bins */
685
7.58M
    error = ihevce_cabac_encode_bypass_bins(ps_cabac, u4_egk, num_bins);
686
687
7.58M
    return (error);
688
7.58M
}
689
690
/**
691
******************************************************************************
692
*
693
*  @brief Encodes a syntax element as truncated rice code (TR)
694
*
695
*  @par   Description
696
*  Does binarization of symbol as per sec 9.3.2.3 Truncated Rice(TR)
697
*  binarization process and encodes the resulting bypass bins
698
*  This function ise used for coeff_abs_level_remaining coding when
699
*  level is less than c_rice_max
700
*
701
*  @param[inout]ps_cabac
702
*   pointer to cabac context (handle)
703
*
704
*  @param[in]   u4_sym
705
*   syntax element to be coded as truncated rice code
706
*
707
*  @param[in]   c_rice_param
708
*    shift factor for truncated unary prefix coding of (u4_sym >> c_rice_param)
709
*
710
*  @param[in]   c_rice_max
711
*    max symbol val below which a suffix is coded as (u4_sym%(1<<c_rice_param))
712
*    This is currently (4 << c_rice_param) for coeff_abs_level_remaining
713
*
714
*  @return      success or failure error code
715
*
716
******************************************************************************
717
*/
718
WORD32 ihevce_cabac_encode_trunc_rice(
719
    cab_ctxt_t *ps_cabac, UWORD32 u4_sym, WORD32 c_rice_param, WORD32 c_rice_max)
720
45.9M
{
721
45.9M
    WORD32 num_bins, unary_length, u4_unary_bins;
722
45.9M
    UWORD32 u4_tr;
723
724
45.9M
    WORD32 error = IHEVCE_SUCCESS;
725
726
45.9M
    (void)c_rice_max;
727
    /* Sanity checks */
728
45.9M
    ASSERT((c_rice_param >= 0));
729
45.9M
    ASSERT((UWORD32)c_rice_max > u4_sym);
730
731
    /************************************************************************/
732
    /* shift symbol by c_rice_param bits to find unary code prefix (111.10) */
733
    /************************************************************************/
734
45.9M
    unary_length = (u4_sym >> c_rice_param) + 1;
735
736
    /* unary code with (unary_length-1) '1's and terminating '0' bin */
737
45.9M
    u4_unary_bins = (1 << unary_length) - 2;
738
739
    /* insert last c_rice_param bits of symbol in the end */
740
45.9M
    u4_tr = (u4_unary_bins << c_rice_param) | (u4_sym & ((1 << c_rice_param) - 1));
741
742
    /* length of the code */
743
45.9M
    num_bins = unary_length + c_rice_param;
744
745
    /* Encode the tr binarized code as bypass bins */
746
45.9M
    error = ihevce_cabac_encode_bypass_bins(ps_cabac, u4_tr, num_bins);
747
748
45.9M
    return (error);
749
45.9M
}
750
751
/**
752
******************************************************************************
753
*
754
*  @brief Flushes the cabac encoder engine as per section 9.3.4 figure 9-12
755
*
756
*  @par   Description
757
*
758
*
759
*  @param[inout]   ps_cabac
760
*  pointer to cabac context (handle)
761
*
762
*  @return      success or failure error code
763
*
764
******************************************************************************
765
*/
766
WORD32 ihevce_cabac_flush(cab_ctxt_t *ps_cabac, WORD32 i4_end_of_sub_strm)
767
2.98k
{
768
2.98k
    UWORD32 u4_low = ps_cabac->u4_low;
769
2.98k
    UWORD32 u4_bits_gen = ps_cabac->u4_bits_gen;
770
771
2.98k
    UWORD8 *pu1_strm_buf = ps_cabac->pu1_strm_buffer;
772
2.98k
    UWORD32 u4_strm_buf_offset = ps_cabac->u4_strm_buf_offset;
773
2.98k
    WORD32 zero_run = ps_cabac->i4_zero_bytes_run;
774
2.98k
    UWORD32 u4_out_standing_bytes = ps_cabac->u4_out_standing_bytes;
775
776
2.98k
    (void)i4_end_of_sub_strm;
777
    /************************************************************************/
778
    /* Insert the carry (propogated in previous byte) along with            */
779
    /* outstanding bytes (if any) and flush remaining bits                  */
780
    /************************************************************************/
781
782
    //TODO: Review this function
783
2.98k
    {
784
        /* carry = 1 => putbit(1); carry propogated due to L renorm */
785
2.98k
        WORD32 carry = (u4_low >> (u4_bits_gen + CABAC_BITS)) & 0x1;
786
2.98k
        WORD32 last_byte;
787
2.98k
        WORD32 bits_left;
788
2.98k
        WORD32 rem_bits;
789
790
        /*********************************************************************/
791
        /* Bitstream overflow check                                          */
792
        /* NOTE: corner case of epb bytes (max 2 for 32bit word) not handled */
793
        /*********************************************************************/
794
2.98k
        if((u4_strm_buf_offset + u4_out_standing_bytes + 1) >= ps_cabac->u4_max_strm_size)
795
118
        {
796
            /* return without corrupting the buffer beyond its size */
797
118
            return (IHEVCE_BITSTREAM_BUFFER_OVERFLOW);
798
118
        }
799
800
2.86k
        if(carry)
801
53
        {
802
            /* CORNER CASE: if the previous data is 0x000003, then EPB will be inserted
803
            and the data will become 0x00000303 and if the carry is present, it will
804
            be added with the last byte and it will become 0x00000304 which is not correct
805
            as per standard*/
806
            /* so check for previous four bytes and if it is equal to 0x00000303
807
            then subtract u4_strm_buf_offset by 1 */
808
53
            if(pu1_strm_buf[u4_strm_buf_offset - 1] == 0x03 &&
809
2
               pu1_strm_buf[u4_strm_buf_offset - 2] == 0x03 &&
810
0
               pu1_strm_buf[u4_strm_buf_offset - 3] == 0x00 &&
811
0
               pu1_strm_buf[u4_strm_buf_offset - 4] == 0x00)
812
0
            {
813
0
                u4_strm_buf_offset -= 1;
814
0
            }
815
            /* previous byte carry add will not result in overflow to        */
816
            /* u4_strm_buf_offset - 2 as we track 0xff as outstanding bytes  */
817
53
            pu1_strm_buf[u4_strm_buf_offset - 1] += carry;
818
53
            zero_run = 0;
819
53
        }
820
821
        /*        Insert outstanding bytes (if any)         */
822
2.90k
        while(u4_out_standing_bytes)
823
33
        {
824
33
            UWORD8 u1_0_or_ff = carry ? 0 : 0xFF;
825
826
33
            PUTBYTE_EPB(pu1_strm_buf, u4_strm_buf_offset, u1_0_or_ff, zero_run);
827
828
33
            u4_out_standing_bytes--;
829
33
        }
830
831
        /*  clear the carry in low */
832
2.86k
        u4_low &= ((1 << (u4_bits_gen + CABAC_BITS)) - 1);
833
834
        /* extract the remaining bits;                                   */
835
        /* includes additional msb bit of low as per Figure 9-12      */
836
2.86k
        bits_left = u4_bits_gen + 1;
837
2.86k
        rem_bits = (u4_low >> (u4_bits_gen + CABAC_BITS - bits_left));
838
839
2.86k
        if(bits_left >= 8)
840
1.12k
        {
841
1.12k
            last_byte = (rem_bits >> (bits_left - 8)) & 0xFF;
842
1.12k
            PUTBYTE_EPB(pu1_strm_buf, u4_strm_buf_offset, last_byte, zero_run);
843
1.12k
            bits_left -= 8;
844
1.12k
        }
845
846
        /* insert last byte along with rbsp stop bit(1) and 0's in the end */
847
2.86k
        last_byte = (rem_bits << (8 - bits_left)) | (1 << (7 - bits_left));
848
2.86k
        last_byte &= 0xFF;
849
2.86k
        PUTBYTE_EPB(pu1_strm_buf, u4_strm_buf_offset, last_byte, zero_run);
850
851
        /* update the state variables and return success */
852
2.86k
        ps_cabac->u4_strm_buf_offset = u4_strm_buf_offset;
853
2.86k
        ps_cabac->i4_zero_bytes_run = 0;
854
2.86k
        return (IHEVCE_SUCCESS);
855
2.98k
    }
856
2.98k
}
857
858
/**
859
******************************************************************************
860
*
861
*  @brief API to backup cabac ctxt at end of 2nd CTB row which is used to init
862
*   context at start of every row
863
*
864
*  @par   Description
865
*         API to backup cabac ctxt at end of 2nd CTB row which is used to init
866
*         context at start of every row
867
*
868
*  @param[inout]   ps_cabac
869
*  pointer to cabac context (handle)
870
*
871
*  @return      success or failure error code
872
*
873
******************************************************************************
874
*/
875
WORD32 ihevce_cabac_ctxt_backup(cab_ctxt_t *ps_cabac)
876
316
{
877
316
    memcpy(
878
316
        ps_cabac->au1_ctxt_models_top_right,
879
316
        ps_cabac->au1_ctxt_models,
880
316
        sizeof(ps_cabac->au1_ctxt_models));
881
316
    return (IHEVCE_SUCCESS);
882
316
}
883
884
/**
885
******************************************************************************
886
*
887
*  @brief Init cabac ctxt at every row start
888
*
889
*  @par   Description
890
*         API to init cabac ctxt at start of every row when entropy sync is
891
*         enabled
892
*
893
*  @param[inout]   ps_cabac
894
*  pointer to cabac context (handle)
895
*
896
*  @return      success or failure error code
897
*
898
******************************************************************************
899
*/
900
WORD32 ihevce_cabac_ctxt_row_init(cab_ctxt_t *ps_cabac)
901
463
{
902
    /* cabac engine initialization */
903
463
    ps_cabac->u4_low = 0;
904
463
    ps_cabac->u4_range = 510;
905
463
    ps_cabac->u4_bits_gen = 0;
906
463
    ps_cabac->u4_out_standing_bytes = 0;
907
463
    ps_cabac->i4_zero_bytes_run = 0;
908
909
    /*copy top right context as init context when starting to encode a row*/
910
463
    COPY_CABAC_STATES(
911
463
        ps_cabac->au1_ctxt_models, ps_cabac->au1_ctxt_models_top_right, IHEVC_CAB_CTXT_END);
912
913
463
    return (IHEVCE_SUCCESS);
914
463
}