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