• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /******************************************************************************
2  *
3  * Copyright (C) 2022 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 *******************************************************************************
23 * @file
24 *  isvce_cabac.c
25 *
26 * @brief
27 *  Contains all leaf level functions for CABAC entropy coding.
28 *
29 *
30 * @author
31 * Doney Alex
32 *
33 * @par List of Functions:
34 *
35 *
36 * @remarks
37 *  None
38 *
39 *******************************************************************************
40 */
41 
42 /*****************************************************************************/
43 /* File Includes                                                             */
44 /*****************************************************************************/
45 
46 /* System include files */
47 #include <stdio.h>
48 #include <assert.h>
49 #include <limits.h>
50 #include <string.h>
51 
52 /* User include files */
53 #include "ih264e_config.h"
54 #include "ih264_typedefs.h"
55 #include "iv2.h"
56 #include "ive2.h"
57 #include "ih264_debug.h"
58 #include "ih264_macros.h"
59 #include "isvc_defs.h"
60 #include "isvce_defs.h"
61 #include "isvc_macros.h"
62 #include "ih264e_error.h"
63 #include "ih264e_bitstream.h"
64 #include "ime_distortion_metrics.h"
65 #include "ime_defs.h"
66 #include "ime_structs.h"
67 #include "ih264_error.h"
68 #include "isvc_structs.h"
69 #include "isvc_trans_quant_itrans_iquant.h"
70 #include "isvc_inter_pred_filters.h"
71 #include "isvc_mem_fns.h"
72 #include "ih264_padding.h"
73 #include "ih264_platform_macros.h"
74 #include "ih264_intra_pred_filters.h"
75 #include "ih264_deblk_edge_filters.h"
76 #include "isvc_cabac_tables.h"
77 #include "irc_cntrl_param.h"
78 #include "irc_frame_info_collector.h"
79 #include "isvce_rate_control.h"
80 #include "isvce_cabac_structs.h"
81 #include "isvce_structs.h"
82 #include "isvce_cabac.h"
83 #include "isvce_encode_header.h"
84 #include "ih264_cavlc_tables.h"
85 #include "ih264e_statistics.h"
86 #include "ih264e_trace.h"
87 
88 /*****************************************************************************/
89 /* Function Definitions                                                      */
90 /*****************************************************************************/
91 
92 /**
93  *******************************************************************************
94  *
95  * @brief
96  *  k-th order Exp-Golomb (UEGk) binarization process: Implements concatenated
97  *   unary/ k-th order Exp-Golomb  (UEGk) binarization process,
98  *   where k = 0 as defined in 9.3.2.3 of  ITU_T_H264-201402
99  *
100  * @param[in] i2_sufs
101  *  Suffix bit string
102  *
103  * @param[in] pi1_bins_len
104  *  Pointer to length of tthe string
105  *
106  * @returns Binarized value
107  *
108  * @remarks
109  *  None
110  *
111  *******************************************************************************
112  */
113 
isvce_cabac_UEGk0_binarization(WORD16 i2_sufs,WORD8 * pi1_bins_len)114 UWORD32 isvce_cabac_UEGk0_binarization(WORD16 i2_sufs, WORD8 *pi1_bins_len)
115 {
116     WORD32 unary_length;
117     UWORD32 u4_sufs_shiftk_plus1, u4_egk, u4_unary_bins;
118 
119     u4_sufs_shiftk_plus1 = i2_sufs + 1;
120 
121     unary_length = (32 - CLZ(u4_sufs_shiftk_plus1) + (0 == u4_sufs_shiftk_plus1));
122 
123     /* unary code with (unary_length-1) '1's and terminating '0' bin */
124     u4_unary_bins = (1 << unary_length) - 2;
125 
126     /* insert the symbol prefix of (unary length - 1)  bins */
127     u4_egk = (u4_unary_bins << (unary_length - 1)) |
128              (u4_sufs_shiftk_plus1 & ((1 << (unary_length - 1)) - 1));
129 
130     /* length of the code = 2 *(unary_length - 1) + 1 + k */
131     *pi1_bins_len = (2 * unary_length) - 1;
132 
133     return (u4_egk);
134 }
135 
136 /**
137  *******************************************************************************
138  *
139  * @brief
140  *  Get cabac context for the MB :calculates the pointers to Top and   left
141  *          cabac neighbor context depending upon neighbor  availability.
142  *
143  * @param[in] ps_ent_ctxt
144  *  Pointer to entropy context structure
145  *
146  * @param[in] u4_mb_type
147  *  Type of MB
148  *
149  * @returns
150  *
151  * @remarks
152  *  None
153  *
154  *******************************************************************************
155  */
isvce_get_cabac_context(isvce_entropy_ctxt_t * ps_ent_ctxt,WORD32 u4_mb_type)156 void isvce_get_cabac_context(isvce_entropy_ctxt_t *ps_ent_ctxt, WORD32 u4_mb_type)
157 {
158     /* CABAC context */
159     isvce_cabac_ctxt_t *ps_cabac_ctxt = ps_ent_ctxt->ps_cabac;
160     isvce_mb_info_ctxt_t *ps_ctx_inc_mb_map;
161     cab_csbp_t *ps_lft_csbp;
162 
163     WORD32 i4_lft_avail, i4_top_avail, i4_is_intra;
164     WORD32 i4_mb_x, i4_mb_y;
165     UWORD8 *pu1_slice_idx = ps_ent_ctxt->pu1_slice_idx;
166 
167     i4_is_intra = ((u4_mb_type == I16x16) || (u4_mb_type == I8x8) || (u4_mb_type == I4x4));
168 
169     /* derive neighbor availability */
170     i4_mb_x = ps_ent_ctxt->i4_mb_x;
171     i4_mb_y = ps_ent_ctxt->i4_mb_y;
172     pu1_slice_idx += (i4_mb_y * ps_ent_ctxt->i4_wd_mbs);
173     /* left macroblock availability */
174     i4_lft_avail = (i4_mb_x == 0 || (pu1_slice_idx[i4_mb_x - 1] != pu1_slice_idx[i4_mb_x])) ? 0 : 1;
175     /* top macroblock availability */
176     i4_top_avail = (i4_mb_y == 0 ||
177                     (pu1_slice_idx[i4_mb_x - ps_ent_ctxt->i4_wd_mbs] != pu1_slice_idx[i4_mb_x]))
178                        ? 0
179                        : 1;
180     i4_mb_x = ps_ent_ctxt->i4_mb_x;
181     ps_ctx_inc_mb_map = ps_cabac_ctxt->ps_mb_map_ctxt_inc;
182     ps_cabac_ctxt->ps_curr_ctxt_mb_info = ps_ctx_inc_mb_map + i4_mb_x;
183     ps_cabac_ctxt->ps_left_ctxt_mb_info = ps_cabac_ctxt->ps_def_ctxt_mb_info;
184     ps_cabac_ctxt->ps_top_ctxt_mb_info = ps_cabac_ctxt->ps_def_ctxt_mb_info;
185     ps_lft_csbp = ps_cabac_ctxt->ps_lft_csbp;
186     ps_cabac_ctxt->pu1_left_y_ac_csbp = &ps_lft_csbp->u1_y_ac_csbp_top_mb;
187     ps_cabac_ctxt->pu1_left_uv_ac_csbp = &ps_lft_csbp->u1_uv_ac_csbp_top_mb;
188     ps_cabac_ctxt->pu1_left_yuv_dc_csbp = &ps_lft_csbp->u1_yuv_dc_csbp_top_mb;
189     ps_cabac_ctxt->pi1_left_ref_idx_ctxt_inc = &ps_cabac_ctxt->i1_left_ref_idx_ctx_inc_arr[0][0];
190     ps_cabac_ctxt->pu1_left_mv_ctxt_inc = ps_cabac_ctxt->u1_left_mv_ctxt_inc_arr[0];
191 
192     if(i4_lft_avail) ps_cabac_ctxt->ps_left_ctxt_mb_info = ps_cabac_ctxt->ps_curr_ctxt_mb_info - 1;
193     if(i4_top_avail) ps_cabac_ctxt->ps_top_ctxt_mb_info = ps_cabac_ctxt->ps_curr_ctxt_mb_info;
194 
195     if(!i4_lft_avail)
196     {
197         UWORD8 u1_def_csbp = i4_is_intra ? 0xf : 0;
198         *(ps_cabac_ctxt->pu1_left_y_ac_csbp) = u1_def_csbp;
199         *(ps_cabac_ctxt->pu1_left_uv_ac_csbp) = u1_def_csbp;
200         *(ps_cabac_ctxt->pu1_left_yuv_dc_csbp) = u1_def_csbp;
201         *((UWORD32 *) ps_cabac_ctxt->pi1_left_ref_idx_ctxt_inc) = 0;
202         memset(ps_cabac_ctxt->pu1_left_mv_ctxt_inc, 0, 16);
203     }
204     if(!i4_top_avail)
205     {
206         UWORD8 u1_def_csbp = i4_is_intra ? 0xff : 0;
207         ps_cabac_ctxt->ps_top_ctxt_mb_info->u1_yuv_ac_csbp = u1_def_csbp;
208         ps_cabac_ctxt->ps_top_ctxt_mb_info->u1_yuv_dc_csbp = u1_def_csbp;
209         ps_cabac_ctxt->ps_curr_ctxt_mb_info->i1_ref_idx[0] =
210             ps_cabac_ctxt->ps_curr_ctxt_mb_info->i1_ref_idx[1] =
211                 ps_cabac_ctxt->ps_curr_ctxt_mb_info->i1_ref_idx[2] =
212                     ps_cabac_ctxt->ps_curr_ctxt_mb_info->i1_ref_idx[3] = 0;
213         memset(ps_cabac_ctxt->ps_curr_ctxt_mb_info->u1_mv, 0, 16);
214     }
215 }
216 
217 /**
218  *******************************************************************************
219  * @brief
220  *  flushing at termination: Explained in flowchart 9-12(ITU_T_H264-201402).
221  *
222  *  @param[in]   ps_cabac_ctxt
223  *  pointer to cabac context (handle)
224  *
225  * @returns  none
226  *
227  * @remarks
228  *  None
229  *
230  *******************************************************************************
231  */
isvce_cabac_flush(isvce_cabac_ctxt_t * ps_cabac_ctxt)232 void isvce_cabac_flush(isvce_cabac_ctxt_t *ps_cabac_ctxt)
233 {
234     /* bit stream ptr */
235     bitstrm_t *ps_stream = ps_cabac_ctxt->ps_bitstrm;
236     encoding_envirnoment_t *ps_cab_enc_env = &(ps_cabac_ctxt->s_cab_enc_env);
237     UWORD32 u4_low = ps_cab_enc_env->u4_code_int_low;
238     UWORD32 u4_bits_gen = ps_cab_enc_env->u4_bits_gen;
239     UWORD8 *pu1_strm_buf = ps_stream->pu1_strm_buffer;
240     UWORD32 u4_strm_buf_offset = ps_stream->u4_strm_buf_offset;
241     WORD32 zero_run = ps_stream->i4_zero_bytes_run;
242     UWORD32 u4_out_standing_bytes = ps_cab_enc_env->u4_out_standing_bytes;
243 
244     /************************************************************************/
245     /* Insert the carry (propogated in previous byte) along with            */
246     /* outstanding bytes (if any) and flush remaining bits                  */
247     /************************************************************************/
248     {
249         /* carry = 1 => putbit(1); carry propogated due to L renorm */
250         WORD32 carry = (u4_low >> (u4_bits_gen + CABAC_BITS)) & 0x1;
251         WORD32 last_byte;
252         WORD32 bits_left;
253         WORD32 rem_bits;
254 
255         /* carry exists only if pu1_strm_buf has at least 1 byte of data */
256         carry = carry && (u4_strm_buf_offset > 0);
257 
258         if(carry)
259         {
260             /* CORNER CASE: if the previous data is 0x000003, then EPB will be
261              inserted and the data will become 0x00000303 and if the carry is present,
262              it will be added with the last byte and it will become 0x00000304 which
263              is not correct as per standard */
264             /* so check for previous four bytes and if it is equal to 0x00000303
265              then subtract u4_strm_buf_offset by 1 */
266             if((u4_strm_buf_offset >= 4) && pu1_strm_buf[u4_strm_buf_offset - 1] == 0x03 &&
267                pu1_strm_buf[u4_strm_buf_offset - 2] == 0x03 &&
268                pu1_strm_buf[u4_strm_buf_offset - 3] == 0x00 &&
269                pu1_strm_buf[u4_strm_buf_offset - 4] == 0x00)
270             {
271                 u4_strm_buf_offset -= 1;
272             }
273             /* previous byte carry add will not result in overflow to        */
274             /* u4_strm_buf_offset - 2 as we track 0xff as outstanding bytes  */
275             pu1_strm_buf[u4_strm_buf_offset - 1] += carry;
276             zero_run = 0;
277         }
278 
279         /*        Insert outstanding bytes (if any)         */
280         while(u4_out_standing_bytes)
281         {
282             UWORD8 u1_0_or_ff = carry ? 0 : 0xFF;
283 
284             PUTBYTE_EPB(pu1_strm_buf, u4_strm_buf_offset, u1_0_or_ff, zero_run);
285             u4_out_standing_bytes--;
286         }
287 
288         /*  clear the carry in low */
289         if(carry)
290         {
291             u4_low &= ((1 << (u4_bits_gen + CABAC_BITS)) - 1);
292         }
293 
294         /* extract the remaining bits;                                   */
295         /* includes additional msb bit of low as per Figure 9-12      */
296         bits_left = u4_bits_gen + 1;
297         rem_bits = (u4_low >> (u4_bits_gen + CABAC_BITS - bits_left));
298 
299         if(bits_left >= 8)
300         {
301             last_byte = (rem_bits >> (bits_left - 8)) & 0xFF;
302             PUTBYTE_EPB(pu1_strm_buf, u4_strm_buf_offset, last_byte, zero_run);
303             bits_left -= 8;
304         }
305 
306         /* insert last byte along with rbsp stop bit(1) and 0's in the end */
307         last_byte =
308             (rem_bits << (8 - bits_left)) | (1 << (7 - bits_left) | (1 << (7 - bits_left - 1)));
309         last_byte &= 0xFF;
310         PUTBYTE_EPB(pu1_strm_buf, u4_strm_buf_offset, last_byte, zero_run);
311 
312         /* update the state variables and return success */
313         ps_stream->u4_strm_buf_offset = u4_strm_buf_offset;
314         ps_stream->i4_zero_bytes_run = 0;
315         /* Default init values for scratch variables of bitstream context */
316         ps_stream->u4_cur_word = 0;
317         ps_stream->i4_bits_left_in_cw = WORD_SIZE;
318     }
319 }
320 
321 /**
322  ******************************************************************************
323  *
324  *  @brief Puts new byte (and outstanding bytes) into bitstream after cabac
325  *         renormalization
326  *
327  *  @par   Description
328  *  1. Extract the leading byte of low(L)
329  *  2. If leading byte=0xff increment outstanding bytes and return
330  *     (as the actual bits depend on carry propogation later)
331  *  3. If leading byte is not 0xff check for any carry propogation
332  *  4. Insert the carry (propogated in previous byte) along with outstanding
333  *     bytes (if any) and leading byte
334  *
335  *
336  *  @param[in]   ps_cabac_ctxt
337  *  pointer to cabac context (handle)
338  *
339  *  @return
340  *
341  ******************************************************************************
342  */
isvce_cabac_put_byte(isvce_cabac_ctxt_t * ps_cabac_ctxt)343 void isvce_cabac_put_byte(isvce_cabac_ctxt_t *ps_cabac_ctxt)
344 {
345     /* bit stream ptr */
346     bitstrm_t *ps_stream = ps_cabac_ctxt->ps_bitstrm;
347     encoding_envirnoment_t *ps_cab_enc_env = &(ps_cabac_ctxt->s_cab_enc_env);
348     UWORD32 u4_low = ps_cab_enc_env->u4_code_int_low;
349     UWORD32 u4_bits_gen = ps_cab_enc_env->u4_bits_gen;
350     WORD32 lead_byte = u4_low >> (u4_bits_gen + CABAC_BITS - 8);
351 
352     /* Sanity checks */
353     ASSERT((ps_cab_enc_env->u4_code_int_range >= 256) && (ps_cab_enc_env->u4_code_int_range < 512));
354     ASSERT((u4_bits_gen >= 8));
355 
356     /* update bits generated and low after extracting leading byte */
357     u4_bits_gen -= 8;
358     ps_cab_enc_env->u4_code_int_low &= ((1 << (CABAC_BITS + u4_bits_gen)) - 1);
359     ps_cab_enc_env->u4_bits_gen = u4_bits_gen;
360 
361     /************************************************************************/
362     /* 1. Extract the leading byte of low(L)                                */
363     /* 2. If leading byte=0xff increment outstanding bytes and return       */
364     /*      (as the actual bits depend on carry propogation later)          */
365     /* 3. If leading byte is not 0xff check for any carry propogation       */
366     /* 4. Insert the carry (propogated in previous byte) along with         */
367     /*    outstanding bytes (if any) and leading byte                       */
368     /************************************************************************/
369     if(lead_byte == 0xff)
370     {
371         /* actual bits depend on carry propogration     */
372         ps_cab_enc_env->u4_out_standing_bytes++;
373         return;
374     }
375     else
376     {
377         UWORD8 *pu1_strm_buf = ps_stream->pu1_strm_buffer;
378         UWORD32 u4_strm_buf_offset = ps_stream->u4_strm_buf_offset;
379         /* carry = 1 => putbit(1); carry propogated due to L renorm */
380         WORD32 carry = (lead_byte >> 8) & 0x1;
381         WORD32 zero_run = ps_stream->i4_zero_bytes_run;
382         UWORD32 u4_out_standing_bytes = ps_cab_enc_env->u4_out_standing_bytes;
383 
384         /*********************************************************************/
385         /*        Insert the carry propogated in previous byte               */
386         /*                                                                   */
387         /* Note : Do not worry about corruption into slice header align byte */
388         /*        This is because the first bin cannot result in overflow    */
389         /*********************************************************************/
390         if(carry)
391         {
392             /* CORNER CASE: if the previous data is 0x000003, then EPB will be
393              inserted and the data will become 0x00000303 and if the carry is present,
394              it will be added with the last byte and it will become 0x00000304 which
395              is not correct as per standard */
396             /* so check for previous four bytes and if it is equal to 0x00000303
397              then subtract u4_strm_buf_offset by 1 */
398             if((u4_strm_buf_offset > 3) && (pu1_strm_buf[u4_strm_buf_offset - 1] == 0x03) &&
399                (pu1_strm_buf[u4_strm_buf_offset - 2] == 0x03) &&
400                (pu1_strm_buf[u4_strm_buf_offset - 3] == 0x00) &&
401                (pu1_strm_buf[u4_strm_buf_offset - 4] == 0x00))
402             {
403                 u4_strm_buf_offset -= 1;
404             }
405 
406             /* previous byte carry add will not result in overflow to        */
407             /* u4_strm_buf_offset - 2 as we track 0xff as outstanding bytes  */
408             if(u4_strm_buf_offset > 0)
409             {
410                 pu1_strm_buf[u4_strm_buf_offset - 1] += carry;
411                 zero_run = 0;
412             }
413         }
414 
415         /*        Insert outstanding bytes (if any)         */
416         while(u4_out_standing_bytes)
417         {
418             UWORD8 u1_0_or_ff = carry ? 0 : 0xFF;
419 
420             PUTBYTE_EPB(pu1_strm_buf, u4_strm_buf_offset, u1_0_or_ff, zero_run);
421 
422             u4_out_standing_bytes--;
423         }
424         ps_cab_enc_env->u4_out_standing_bytes = 0;
425 
426         /*        Insert the leading byte                   */
427         lead_byte &= 0xFF;
428         PUTBYTE_EPB(pu1_strm_buf, u4_strm_buf_offset, lead_byte, zero_run);
429 
430         /* update the state variables and return success */
431         ps_stream->u4_strm_buf_offset = u4_strm_buf_offset;
432         ps_stream->i4_zero_bytes_run = zero_run;
433     }
434 }
435 
436 /**
437 ******************************************************************************
438 *
439 *  @brief Codes a bin based on probablilty and mps packed context model
440 *
441 *  @par   Description
442 *  1. Apart from encoding bin, context model is updated as per state transition
443 *  2. Range and Low renormalization is done based on bin and original state
444 *  3. After renorm bistream is updated (if required)
445 *
446 *  @param[in]   ps_cabac
447 *  pointer to cabac context (handle)
448 *
449 *  @param[in]   bin
450 *  bin(boolean) to be encoded
451 *
452 *  @param[in]  pu1_bin_ctxts
453 *  index of cabac context model containing pState[bits 5-0] | MPS[bit6]
454 *
455 *  @return
456 *
457 ******************************************************************************
458 */
isvce_cabac_encode_bin(isvce_cabac_ctxt_t * ps_cabac,WORD32 bin,bin_ctxt_model * pu1_bin_ctxts)459 void isvce_cabac_encode_bin(isvce_cabac_ctxt_t *ps_cabac, WORD32 bin, bin_ctxt_model *pu1_bin_ctxts)
460 {
461     encoding_envirnoment_t *ps_cab_enc_env = &(ps_cabac->s_cab_enc_env);
462     UWORD32 u4_range = ps_cab_enc_env->u4_code_int_range;
463     UWORD32 u4_low = ps_cab_enc_env->u4_code_int_low;
464     UWORD32 u4_rlps;
465     UWORD8 state_mps = (*pu1_bin_ctxts) & 0x3F;
466     UWORD8 u1_mps = !!((*pu1_bin_ctxts) & (0x40));
467     WORD32 shift;
468     UWORD32 u4_table_val;
469     /* Sanity checks */
470     ASSERT((bin == 0) || (bin == 1));
471     ASSERT((u4_range >= 256) && (u4_range < 512));
472 
473     /* Get the lps range from LUT based on quantized range and state */
474     u4_table_val = gau4_isvc_cabac_table[state_mps][(u4_range >> 6) & 0x3];
475     u4_rlps = u4_table_val & 0xFF;
476     u4_range -= u4_rlps;
477 
478     /* check if bin is mps or lps */
479     if(u1_mps ^ bin)
480     {
481         /* lps path;  L= L + R; R = RLPS */
482         u4_low += u4_range;
483         u4_range = u4_rlps;
484         if(state_mps == 0)
485         {
486             /* MPS(CtxIdx) = 1 - MPS(CtxIdx) */
487             u1_mps = 1 - u1_mps;
488         } /* update the context model from state transition LUT */
489 
490         state_mps = (u4_table_val >> 15) & 0x3F;
491     }
492     else
493     { /* update the context model from state transition LUT */
494         state_mps = (u4_table_val >> 8) & 0x3F;
495     }
496 
497     (*pu1_bin_ctxts) = (u1_mps << 6) | state_mps;
498 
499     /*****************************************************************/
500     /* Renormalization; calculate bits generated based on range(R)   */
501     /* Note : 6 <= R < 512; R is 2 only for terminating encode       */
502     /*****************************************************************/
503     GETRANGE(shift, u4_range);
504     shift = 9 - shift;
505     u4_low <<= shift;
506     u4_range <<= shift;
507 
508     /* bits to be inserted in the bitstream */
509     ps_cab_enc_env->u4_bits_gen += shift;
510     ps_cab_enc_env->u4_code_int_range = u4_range;
511     ps_cab_enc_env->u4_code_int_low = u4_low;
512 
513     /* generate stream when a byte is ready */
514     if(ps_cab_enc_env->u4_bits_gen > CABAC_BITS)
515     {
516         isvce_cabac_put_byte(ps_cabac);
517     }
518 }
519 
520 /**
521 *******************************************************************************
522 *
523 * @brief
524 *  Encoding process for a binary decision :implements encoding process of a
525 decision
526 *  as defined in 9.3.4.2 . This function encodes multiple bins, of a symbol.
527 Implements
528 *  flowchart Figure 9-7( ITU_T_H264-201402)
529 *
530 * @param[in] u4_bins
531 * array of bin values
532 *
533 * @param[in] i1_bins_len
534 *  Length of bins, maximum 32
535 *
536 * @param[in] u4_ctx_inc
537 *  CtxInc, byte0- bin0, byte1-bin1 ..
538 *
539 * @param[in] i1_valid_len
540 *  valid length of bins, after that CtxInc is constant
541 *
542 * @param[in] pu1_bin_ctxt_type
543 *  Pointer to binary contexts
544 
545 * @param[in] ps_cabac
546 *  Pointer to cabac_context_structure
547 *
548 * @returns
549 *
550 * @remarks
551 *  None
552 *
553 *******************************************************************************
554 */
isvce_encode_decision_bins(UWORD32 u4_bins,WORD8 i1_bins_len,UWORD32 u4_ctx_inc,WORD8 i1_valid_len,bin_ctxt_model * pu1_bin_ctxt_type,isvce_cabac_ctxt_t * ps_cabac)555 void isvce_encode_decision_bins(UWORD32 u4_bins, WORD8 i1_bins_len, UWORD32 u4_ctx_inc,
556                                 WORD8 i1_valid_len, bin_ctxt_model *pu1_bin_ctxt_type,
557                                 isvce_cabac_ctxt_t *ps_cabac)
558 {
559     WORD8 i;
560     UWORD8 u1_ctx_inc, u1_bin;
561 
562     for(i = 0; i < i1_bins_len; i++)
563     {
564         u1_bin = (u4_bins & 0x01);
565         u4_bins = u4_bins >> 1;
566         u1_ctx_inc = u4_ctx_inc & 0x0f;
567         if(i < i1_valid_len) u4_ctx_inc = u4_ctx_inc >> 4;
568         /* Encode the bin */
569         isvce_cabac_encode_bin(ps_cabac, u1_bin, pu1_bin_ctxt_type + u1_ctx_inc);
570     }
571 }
572 
573 /**
574  *******************************************************************************
575  * @brief
576  *  Encoding process for a binary decision before termination:Encoding process
577  *  of a termination(9.3.4.5 :ITU_T_H264-201402) . Explained in flowchart 9-11.
578  *
579  * @param[in] ps_cabac
580  *  Pointer to cabac structure
581  *
582  * @param[in] term_bin
583  *  Symbol value, end of slice or not, term_bin is binary
584  *
585  * @returns
586  *
587  * @remarks
588  *  None
589  *
590  *******************************************************************************
591  */
isvce_cabac_encode_terminate(isvce_cabac_ctxt_t * ps_cabac,WORD32 term_bin)592 void isvce_cabac_encode_terminate(isvce_cabac_ctxt_t *ps_cabac, WORD32 term_bin)
593 {
594     encoding_envirnoment_t *ps_cab_enc_env = &(ps_cabac->s_cab_enc_env);
595 
596     UWORD32 u4_range = ps_cab_enc_env->u4_code_int_range;
597     UWORD32 u4_low = ps_cab_enc_env->u4_code_int_low;
598     UWORD32 u4_rlps;
599     WORD32 shift;
600 
601     /* Sanity checks */
602     ASSERT((u4_range >= 256) && (u4_range < 512));
603     ASSERT((term_bin == 0) || (term_bin == 1));
604 
605     /*  term_bin = 1 has lps range = 2 */
606     u4_rlps = 2;
607     u4_range -= u4_rlps;
608 
609     /* if terminate L is incremented by curR and R=2 */
610     if(term_bin)
611     {
612         /* lps path;  L= L + R; R = RLPS */
613         u4_low += u4_range;
614         u4_range = u4_rlps;
615     }
616 
617     /*****************************************************************/
618     /* Renormalization; calculate bits generated based on range(R)   */
619     /* Note : 6 <= R < 512; R is 2 only for terminating encode       */
620     /*****************************************************************/
621     GETRANGE(shift, u4_range);
622     shift = 9 - shift;
623     u4_low <<= shift;
624     u4_range <<= shift;
625 
626     /* bits to be inserted in the bitstream */
627     ps_cab_enc_env->u4_bits_gen += shift;
628     ps_cab_enc_env->u4_code_int_range = u4_range;
629     ps_cab_enc_env->u4_code_int_low = u4_low;
630 
631     /* generate stream when a byte is ready */
632     if(ps_cab_enc_env->u4_bits_gen > CABAC_BITS)
633     {
634         isvce_cabac_put_byte(ps_cabac);
635     }
636 
637     if(term_bin)
638     {
639         isvce_cabac_flush(ps_cabac);
640     }
641 }
642 
643 /**
644  *******************************************************************************
645  * @brief
646  * Bypass encoding process for binary decisions:  Explained (9.3.4.4
647  *:ITU_T_H264-201402) , flowchart 9-10.
648  *
649  *  @param[ino]  ps_cabac : pointer to cabac context (handle)
650  *
651  *  @param[in]   bin :  bypass bin(0/1) to be encoded
652  *
653  *  @returns
654  *
655  *  @remarks
656  *  None
657  *
658  *******************************************************************************
659  */
660 
isvce_cabac_encode_bypass_bin(isvce_cabac_ctxt_t * ps_cabac,WORD32 bin)661 void isvce_cabac_encode_bypass_bin(isvce_cabac_ctxt_t *ps_cabac, WORD32 bin)
662 {
663     encoding_envirnoment_t *ps_cab_enc_env = &(ps_cabac->s_cab_enc_env);
664 
665     UWORD32 u4_range = ps_cab_enc_env->u4_code_int_range;
666     UWORD32 u4_low = ps_cab_enc_env->u4_code_int_low;
667 
668     /* Sanity checks */
669     ASSERT((u4_range >= 256) && (u4_range < 512));
670     ASSERT((bin == 0) || (bin == 1));
671 
672     u4_low <<= 1;
673     /* add range if bin is 1 */
674     if(bin)
675     {
676         u4_low += u4_range;
677     }
678 
679     /* 1 bit to be inserted in the bitstream */
680     ps_cab_enc_env->u4_bits_gen++;
681     ps_cab_enc_env->u4_code_int_low = u4_low;
682 
683     /* generate stream when a byte is ready */
684     if(ps_cab_enc_env->u4_bits_gen > CABAC_BITS)
685     {
686         isvce_cabac_put_byte(ps_cabac);
687     }
688 }
689 
690 /**
691 ******************************************************************************
692 *
693 *  @brief Encodes a series of bypass bins (FLC bypass bins)
694 *
695 *  @par   Description
696 *  This function is more optimal than calling isvce_cabac_encode_bypass_bin()
697 *  in a loop as cabac low, renorm and generating the stream (8bins at a time)
698 *  can be done in one operation
699 *
700 *  @param[inout]ps_cabac
701 *   pointer to cabac context (handle)
702 *
703 *  @param[in]   u4_bins
704 *   syntax element to be coded (as FLC bins)
705 *
706 *  @param[in]   num_bins
707 *   This is the FLC length for u4_sym
708 *
709 *  @return
710 *
711 ******************************************************************************
712 */
713 
isvce_cabac_encode_bypass_bins(isvce_cabac_ctxt_t * ps_cabac,UWORD32 u4_bins,WORD32 num_bins)714 void isvce_cabac_encode_bypass_bins(isvce_cabac_ctxt_t *ps_cabac, UWORD32 u4_bins, WORD32 num_bins)
715 {
716     encoding_envirnoment_t *ps_cab_enc_env = &(ps_cabac->s_cab_enc_env);
717 
718     UWORD32 u4_range = ps_cab_enc_env->u4_code_int_range;
719     WORD32 next_byte;
720 
721     /* Sanity checks */
722     ASSERT((num_bins < 33) && (num_bins > 0));
723     ASSERT((u4_range >= 256) && (u4_range < 512));
724 
725     /* Compute bit always to populate the trace */
726     /* increment bits generated by num_bins */
727 
728     /* Encode 8bins at a time and put in the bit-stream */
729     while(num_bins > 8)
730     {
731         num_bins -= 8;
732 
733         next_byte = (u4_bins >> (num_bins)) & 0xff;
734 
735         /*  L = (L << 8) +  (R * next_byte) */
736         ps_cab_enc_env->u4_code_int_low <<= 8;
737         ps_cab_enc_env->u4_code_int_low += (next_byte * u4_range);
738         ps_cab_enc_env->u4_bits_gen += 8;
739 
740         if(ps_cab_enc_env->u4_bits_gen > CABAC_BITS)
741         {
742             /*  insert the leading byte of low into stream */
743             isvce_cabac_put_byte(ps_cabac);
744         }
745     }
746 
747     /* Update low with remaining bins and return */
748     next_byte = (u4_bins & ((1 << num_bins) - 1));
749 
750     ps_cab_enc_env->u4_code_int_low <<= num_bins;
751     ps_cab_enc_env->u4_code_int_low += (next_byte * u4_range);
752     ps_cab_enc_env->u4_bits_gen += num_bins;
753 
754     if(ps_cab_enc_env->u4_bits_gen > CABAC_BITS)
755     {
756         /*  insert the leading byte of low into stream */
757         isvce_cabac_put_byte(ps_cabac);
758     }
759 }
760