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