xref: /aosp_15_r20/external/libhevc/encoder/ihevce_cabac_cu_pu.c (revision c83a76b084498d55f252f48b2e3786804cdf24b7)
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_cu_pu.c
23*c83a76b0SSuyog Pawar *
24*c83a76b0SSuyog Pawar * @brief
25*c83a76b0SSuyog Pawar *  This file contains function definitions for cabac entropy coding of CU
26*c83a76b0SSuyog Pawar *  and PU structures in HEVC syntax
27*c83a76b0SSuyog Pawar *
28*c83a76b0SSuyog Pawar * @author
29*c83a76b0SSuyog Pawar *  ittiam
30*c83a76b0SSuyog Pawar *
31*c83a76b0SSuyog Pawar * @List of Functions
32*c83a76b0SSuyog Pawar *  ihevce_cabac_encode_intra_pu()
33*c83a76b0SSuyog Pawar *  ihevce_cabac_encode_skip_flag()
34*c83a76b0SSuyog Pawar *  ihevce_cabac_encode_part_mode()
35*c83a76b0SSuyog Pawar *  ihevce_cabac_encode_merge_idx()
36*c83a76b0SSuyog Pawar *  ihevce_cabac_encode_inter_pred_idc()
37*c83a76b0SSuyog Pawar *  ihevce_cabac_encode_refidx()
38*c83a76b0SSuyog Pawar *  ihevce_cabac_encode_mvd()
39*c83a76b0SSuyog Pawar *  ihevce_cabac_encode_inter_pu()
40*c83a76b0SSuyog Pawar *  ihevce_cabac_encode_coding_unit()
41*c83a76b0SSuyog Pawar *  ihevce_cabac_encode_sao()
42*c83a76b0SSuyog Pawar *  ihevce_encode_coding_quadtree()
43*c83a76b0SSuyog Pawar *  ihevce_encode_slice_data()
44*c83a76b0SSuyog Pawar *
45*c83a76b0SSuyog Pawar ******************************************************************************
46*c83a76b0SSuyog Pawar */
47*c83a76b0SSuyog Pawar 
48*c83a76b0SSuyog Pawar /*****************************************************************************/
49*c83a76b0SSuyog Pawar /* File Includes                                                             */
50*c83a76b0SSuyog Pawar /*****************************************************************************/
51*c83a76b0SSuyog Pawar /* System include files */
52*c83a76b0SSuyog Pawar #include <stdio.h>
53*c83a76b0SSuyog Pawar #include <string.h>
54*c83a76b0SSuyog Pawar #include <stdlib.h>
55*c83a76b0SSuyog Pawar #include <assert.h>
56*c83a76b0SSuyog Pawar #include <stdarg.h>
57*c83a76b0SSuyog Pawar #include <math.h>
58*c83a76b0SSuyog Pawar 
59*c83a76b0SSuyog Pawar /* User include files */
60*c83a76b0SSuyog Pawar #include "ihevc_typedefs.h"
61*c83a76b0SSuyog Pawar #include "itt_video_api.h"
62*c83a76b0SSuyog Pawar #include "ihevce_api.h"
63*c83a76b0SSuyog Pawar 
64*c83a76b0SSuyog Pawar #include "rc_cntrl_param.h"
65*c83a76b0SSuyog Pawar #include "rc_frame_info_collector.h"
66*c83a76b0SSuyog Pawar #include "rc_look_ahead_params.h"
67*c83a76b0SSuyog Pawar 
68*c83a76b0SSuyog Pawar #include "ihevc_defs.h"
69*c83a76b0SSuyog Pawar #include "ihevc_structs.h"
70*c83a76b0SSuyog Pawar #include "ihevc_platform_macros.h"
71*c83a76b0SSuyog Pawar #include "ihevc_deblk.h"
72*c83a76b0SSuyog Pawar #include "ihevc_itrans_recon.h"
73*c83a76b0SSuyog Pawar #include "ihevc_chroma_itrans_recon.h"
74*c83a76b0SSuyog Pawar #include "ihevc_chroma_intra_pred.h"
75*c83a76b0SSuyog Pawar #include "ihevc_intra_pred.h"
76*c83a76b0SSuyog Pawar #include "ihevc_inter_pred.h"
77*c83a76b0SSuyog Pawar #include "ihevc_mem_fns.h"
78*c83a76b0SSuyog Pawar #include "ihevc_padding.h"
79*c83a76b0SSuyog Pawar #include "ihevc_weighted_pred.h"
80*c83a76b0SSuyog Pawar #include "ihevc_sao.h"
81*c83a76b0SSuyog Pawar #include "ihevc_resi_trans.h"
82*c83a76b0SSuyog Pawar #include "ihevc_quant_iquant_ssd.h"
83*c83a76b0SSuyog Pawar #include "ihevc_cabac_tables.h"
84*c83a76b0SSuyog Pawar 
85*c83a76b0SSuyog Pawar #include "ihevce_defs.h"
86*c83a76b0SSuyog Pawar #include "ihevce_lap_enc_structs.h"
87*c83a76b0SSuyog Pawar #include "ihevce_multi_thrd_structs.h"
88*c83a76b0SSuyog Pawar #include "ihevce_me_common_defs.h"
89*c83a76b0SSuyog Pawar #include "ihevce_had_satd.h"
90*c83a76b0SSuyog Pawar #include "ihevce_error_codes.h"
91*c83a76b0SSuyog Pawar #include "ihevce_bitstream.h"
92*c83a76b0SSuyog Pawar #include "ihevce_cabac.h"
93*c83a76b0SSuyog Pawar #include "ihevce_rdoq_macros.h"
94*c83a76b0SSuyog Pawar #include "ihevce_function_selector.h"
95*c83a76b0SSuyog Pawar #include "ihevce_enc_structs.h"
96*c83a76b0SSuyog Pawar #include "ihevce_entropy_structs.h"
97*c83a76b0SSuyog Pawar #include "ihevce_cmn_utils_instr_set_router.h"
98*c83a76b0SSuyog Pawar #include "ihevce_enc_loop_structs.h"
99*c83a76b0SSuyog Pawar #include "ihevce_trace.h"
100*c83a76b0SSuyog Pawar 
101*c83a76b0SSuyog Pawar #define TEST_CABAC_BITESTIMATE 0
102*c83a76b0SSuyog Pawar 
103*c83a76b0SSuyog Pawar // clang-format off
104*c83a76b0SSuyog Pawar /**
105*c83a76b0SSuyog Pawar ******************************************************************************
106*c83a76b0SSuyog Pawar * @brief  LUT for binarization of inter partmode bins for cu size > mincu size
107*c83a76b0SSuyog Pawar *  as per Table9-34 of spec
108*c83a76b0SSuyog Pawar *
109*c83a76b0SSuyog Pawar * @input   : amp_enable flag  and part_mode
110*c83a76b0SSuyog Pawar *
111*c83a76b0SSuyog Pawar * @output  : packed bins and count of bins as per following bit packed format
112*c83a76b0SSuyog Pawar *            Bins      : (bits3-bit0) first bin starts from bit3
113*c83a76b0SSuyog Pawar *            Bins Count: (bits7-bit4)
114*c83a76b0SSuyog Pawar *            0xFF in the following table is invalid entry
115*c83a76b0SSuyog Pawar *
116*c83a76b0SSuyog Pawar * @remarks See Table 9-34 of HEVC spec for Binarization of part_mode
117*c83a76b0SSuyog Pawar *******************************************************************************
118*c83a76b0SSuyog Pawar */
119*c83a76b0SSuyog Pawar #define INVALID 0xFF
120*c83a76b0SSuyog Pawar const UWORD8 gu1_hevce_inter_part_mode_bins[2][8] = {
121*c83a76b0SSuyog Pawar 
122*c83a76b0SSuyog Pawar     /*  cusize > minCUsize, no amp       */
123*c83a76b0SSuyog Pawar     { 0x18, 0x24, 0x20, INVALID, INVALID, INVALID, INVALID, INVALID, },
124*c83a76b0SSuyog Pawar 
125*c83a76b0SSuyog Pawar     /*  cusize > minCUsize, amp enable, minCUsize > 8 (irrelevant)  */
126*c83a76b0SSuyog Pawar     { 0x18, 0x36, 0x32, INVALID, 0x44, 0x45, 0x40, 0x41, },
127*c83a76b0SSuyog Pawar 
128*c83a76b0SSuyog Pawar };
129*c83a76b0SSuyog Pawar 
130*c83a76b0SSuyog Pawar /**
131*c83a76b0SSuyog Pawar ******************************************************************************
132*c83a76b0SSuyog Pawar * @brief  LUT for binarization of inter partmode bins for cu size = mincu size
133*c83a76b0SSuyog Pawar *  as per Table9-34 of spec
134*c83a76b0SSuyog Pawar *
135*c83a76b0SSuyog Pawar * @input   : mincusize==8 flag  and part_mode
136*c83a76b0SSuyog Pawar *
137*c83a76b0SSuyog Pawar * @output  : packed bins and count of bins as per following bit packed format
138*c83a76b0SSuyog Pawar *            Bins      : (bits3-bit0) first bin starts from bit3
139*c83a76b0SSuyog Pawar *            Bins Count: (bits7-bit4)
140*c83a76b0SSuyog Pawar *            0xFF in the following table is invalid entry
141*c83a76b0SSuyog Pawar *
142*c83a76b0SSuyog Pawar * @remarks See Table 9-34 of HEVC spec for Binarization of part_mode
143*c83a76b0SSuyog Pawar *******************************************************************************
144*c83a76b0SSuyog Pawar */
145*c83a76b0SSuyog Pawar const UWORD8 gu1_hevce_inter_part_mode_bins_mincu[2][4] = {
146*c83a76b0SSuyog Pawar 
147*c83a76b0SSuyog Pawar     /*  cusize == minCUsize,  minCUsize > 8      */
148*c83a76b0SSuyog Pawar     { 0x18, 0x24, 0x32, 0x30, },
149*c83a76b0SSuyog Pawar 
150*c83a76b0SSuyog Pawar     /* cusize == minCUsize,   minCUsize = 8       */
151*c83a76b0SSuyog Pawar     { 0x18, 0x24, 0x20, INVALID },
152*c83a76b0SSuyog Pawar 
153*c83a76b0SSuyog Pawar };
154*c83a76b0SSuyog Pawar // clang-format on
155*c83a76b0SSuyog Pawar 
156*c83a76b0SSuyog Pawar /*****************************************************************************/
157*c83a76b0SSuyog Pawar /* Function Definitions                                                      */
158*c83a76b0SSuyog Pawar /*****************************************************************************/
159*c83a76b0SSuyog Pawar /**
160*c83a76b0SSuyog Pawar ******************************************************************************
161*c83a76b0SSuyog Pawar *
162*c83a76b0SSuyog Pawar *  @brief Entropy encoding of luma and chroma intra pred modes
163*c83a76b0SSuyog Pawar *
164*c83a76b0SSuyog Pawar *  @par   Description
165*c83a76b0SSuyog Pawar *  Encodes prev_intra_ped_mode, mpm_idx and rem_intra_pred_mode for each
166*c83a76b0SSuyog Pawar *  luma partition and chrom intra pred of cu as per section:7.3.9.1
167*c83a76b0SSuyog Pawar *
168*c83a76b0SSuyog Pawar *  Binzarization, context model as per Table 9-32 for luma
169*c83a76b0SSuyog Pawar *  Binzarization, context model as per Table 9-35, section 9.3.2.8 for chroma
170*c83a76b0SSuyog Pawar *
171*c83a76b0SSuyog Pawar *  @param[inout]   ps_entropy_ctxt
172*c83a76b0SSuyog Pawar *  pointer to entropy context (handle)
173*c83a76b0SSuyog Pawar *
174*c83a76b0SSuyog Pawar *  @param[in]   part_mode
175*c83a76b0SSuyog Pawar *  indicates whether the mode is 2Nx2N or NxN luma parition
176*c83a76b0SSuyog Pawar *
177*c83a76b0SSuyog Pawar *  @param[in]   ps_enc_cu
178*c83a76b0SSuyog Pawar *  pointer to the intra cu whose luma and chroma pred modes are encoded
179*c83a76b0SSuyog Pawar *
180*c83a76b0SSuyog Pawar *  @return      success or failure error code
181*c83a76b0SSuyog Pawar *
182*c83a76b0SSuyog Pawar ******************************************************************************
183*c83a76b0SSuyog Pawar */
ihevce_cabac_encode_intra_pu(entropy_context_t * ps_entropy_ctxt,WORD32 part_mode,cu_enc_loop_out_t * ps_enc_cu)184*c83a76b0SSuyog Pawar WORD32 ihevce_cabac_encode_intra_pu(
185*c83a76b0SSuyog Pawar     entropy_context_t *ps_entropy_ctxt, WORD32 part_mode, cu_enc_loop_out_t *ps_enc_cu)
186*c83a76b0SSuyog Pawar {
187*c83a76b0SSuyog Pawar     WORD32 error = IHEVCE_SUCCESS;
188*c83a76b0SSuyog Pawar     cab_ctxt_t *ps_cabac = &ps_entropy_ctxt->s_cabac_ctxt;
189*c83a76b0SSuyog Pawar     intra_prev_rem_flags_t *ps_prev_mpm_rem_flags = &ps_enc_cu->as_prev_rem[0];
190*c83a76b0SSuyog Pawar     WORD32 i, num_parts;
191*c83a76b0SSuyog Pawar 
192*c83a76b0SSuyog Pawar     /* intra can only be 2Nx2N partition or a NxN partition     */
193*c83a76b0SSuyog Pawar     num_parts = (PART_NxN == part_mode) ? 4 : 1;
194*c83a76b0SSuyog Pawar 
195*c83a76b0SSuyog Pawar     if(ps_cabac->e_cabac_op_mode == CABAC_MODE_ENCODE_BITS)
196*c83a76b0SSuyog Pawar     {
197*c83a76b0SSuyog Pawar         WORD32 cu_size = ps_enc_cu->b4_cu_size << 3;
198*c83a76b0SSuyog Pawar 
199*c83a76b0SSuyog Pawar         /*PIC_INFO : INTRA CU in frame*/
200*c83a76b0SSuyog Pawar         ps_entropy_ctxt->ps_pic_level_info->i8_total_intra_cu++;
201*c83a76b0SSuyog Pawar         ps_entropy_ctxt->ps_pic_level_info->i8_total_pu += num_parts;
202*c83a76b0SSuyog Pawar         ps_entropy_ctxt->ps_pic_level_info->i8_total_intra_pu += num_parts;
203*c83a76b0SSuyog Pawar         /*PIC_INFO : Total CU in frame based on cu size */
204*c83a76b0SSuyog Pawar 
205*c83a76b0SSuyog Pawar         if(PART_2Nx2N == part_mode)
206*c83a76b0SSuyog Pawar         {
207*c83a76b0SSuyog Pawar             // clang-format off
208*c83a76b0SSuyog Pawar             if(cu_size == 64)
209*c83a76b0SSuyog Pawar                 ps_entropy_ctxt->ps_pic_level_info->i8_total_2nx2n_intra_pu[3]++;
210*c83a76b0SSuyog Pawar             else
211*c83a76b0SSuyog Pawar                 ps_entropy_ctxt->ps_pic_level_info->i8_total_2nx2n_intra_pu[cu_size >> 4]++;
212*c83a76b0SSuyog Pawar             // clang-format on
213*c83a76b0SSuyog Pawar         }
214*c83a76b0SSuyog Pawar         else if(PART_NxN == part_mode)
215*c83a76b0SSuyog Pawar         {
216*c83a76b0SSuyog Pawar             ps_entropy_ctxt->ps_pic_level_info->i8_total_nxn_intra_pu++;
217*c83a76b0SSuyog Pawar         }
218*c83a76b0SSuyog Pawar     }
219*c83a76b0SSuyog Pawar     /* encode prev intra pred mode flags  : context model based */
220*c83a76b0SSuyog Pawar     for(i = 0; i < num_parts; i++)
221*c83a76b0SSuyog Pawar     {
222*c83a76b0SSuyog Pawar         WORD32 prev_intra_pred_flag = ps_prev_mpm_rem_flags[i].b1_prev_intra_luma_pred_flag;
223*c83a76b0SSuyog Pawar         error |=
224*c83a76b0SSuyog Pawar             ihevce_cabac_encode_bin(ps_cabac, prev_intra_pred_flag, IHEVC_CAB_INTRA_LUMA_PRED_FLAG);
225*c83a76b0SSuyog Pawar         AEV_TRACE("prev_intra_pred_luma_flag", prev_intra_pred_flag, ps_cabac->u4_range);
226*c83a76b0SSuyog Pawar     }
227*c83a76b0SSuyog Pawar 
228*c83a76b0SSuyog Pawar     /* encode mpm_idx or rem_intra_pred_mode bypass bins */
229*c83a76b0SSuyog Pawar     for(i = 0; i < num_parts; i++)
230*c83a76b0SSuyog Pawar     {
231*c83a76b0SSuyog Pawar         if(ps_prev_mpm_rem_flags[i].b1_prev_intra_luma_pred_flag)
232*c83a76b0SSuyog Pawar         {
233*c83a76b0SSuyog Pawar             WORD32 mpm_idx = ps_prev_mpm_rem_flags[i].b2_mpm_idx;
234*c83a76b0SSuyog Pawar 
235*c83a76b0SSuyog Pawar             /* tunary bins for cmax = 2 */
236*c83a76b0SSuyog Pawar             WORD32 num_bins = mpm_idx ? 2 : 1;
237*c83a76b0SSuyog Pawar             UWORD32 bins = mpm_idx ? ((1 << 1) | (mpm_idx - 1)) : 0;
238*c83a76b0SSuyog Pawar 
239*c83a76b0SSuyog Pawar             ASSERT(mpm_idx < 3);
240*c83a76b0SSuyog Pawar 
241*c83a76b0SSuyog Pawar             error |= ihevce_cabac_encode_bypass_bins(ps_cabac, bins, num_bins);
242*c83a76b0SSuyog Pawar             AEV_TRACE("mpm_idx", mpm_idx, ps_cabac->u4_range);
243*c83a76b0SSuyog Pawar         }
244*c83a76b0SSuyog Pawar         else
245*c83a76b0SSuyog Pawar         {
246*c83a76b0SSuyog Pawar             WORD32 rem_intra_pred_mode = ps_prev_mpm_rem_flags[i].b5_rem_intra_pred_mode;
247*c83a76b0SSuyog Pawar             error |= ihevce_cabac_encode_bypass_bins(ps_cabac, rem_intra_pred_mode, 5);
248*c83a76b0SSuyog Pawar             AEV_TRACE("rem_intra_luma_pred_mode", rem_intra_pred_mode, ps_cabac->u4_range);
249*c83a76b0SSuyog Pawar         }
250*c83a76b0SSuyog Pawar     }
251*c83a76b0SSuyog Pawar 
252*c83a76b0SSuyog Pawar     /************************************************************************/
253*c83a76b0SSuyog Pawar     /* encode the chroma intra prediction mode as per Table 9-35            */
254*c83a76b0SSuyog Pawar     /* First bin is context model based prefix : 0 if chroma_mode==4 else 1 */
255*c83a76b0SSuyog Pawar     /* If chroma pred mode is not 4, suffix bins are coded as bypass bins   */
256*c83a76b0SSuyog Pawar     /************************************************************************/
257*c83a76b0SSuyog Pawar     {
258*c83a76b0SSuyog Pawar         WORD32 chroma_pred_mode = ps_enc_cu->b3_chroma_intra_pred_mode;
259*c83a76b0SSuyog Pawar         WORD32 prefix_bin = (chroma_pred_mode == 4) ? 0 : 1;
260*c83a76b0SSuyog Pawar 
261*c83a76b0SSuyog Pawar         /* encode prefix bin */
262*c83a76b0SSuyog Pawar         error |= ihevce_cabac_encode_bin(ps_cabac, prefix_bin, IHEVC_CAB_CHROMA_PRED_MODE);
263*c83a76b0SSuyog Pawar 
264*c83a76b0SSuyog Pawar         /* encode suffix bins */
265*c83a76b0SSuyog Pawar         if(prefix_bin)
266*c83a76b0SSuyog Pawar         {
267*c83a76b0SSuyog Pawar             error |= ihevce_cabac_encode_bypass_bins(ps_cabac, chroma_pred_mode, 2);
268*c83a76b0SSuyog Pawar         }
269*c83a76b0SSuyog Pawar         AEV_TRACE("intra_chroma_pred_mode", chroma_pred_mode, ps_cabac->u4_range);
270*c83a76b0SSuyog Pawar     }
271*c83a76b0SSuyog Pawar 
272*c83a76b0SSuyog Pawar     return (error);
273*c83a76b0SSuyog Pawar }
274*c83a76b0SSuyog Pawar 
275*c83a76b0SSuyog Pawar /**
276*c83a76b0SSuyog Pawar ******************************************************************************
277*c83a76b0SSuyog Pawar *
278*c83a76b0SSuyog Pawar *  @brief Entropy encoding of skip flag (Coding Unit syntax)
279*c83a76b0SSuyog Pawar *
280*c83a76b0SSuyog Pawar *  @par   Description
281*c83a76b0SSuyog Pawar *  context increment for skip flag is derived based on left and top skip flag
282*c83a76b0SSuyog Pawar *  as per section 9.3.3.1.1, Table 9-38
283*c83a76b0SSuyog Pawar *
284*c83a76b0SSuyog Pawar *  @param[inout]   ps_entropy_ctxt
285*c83a76b0SSuyog Pawar *  pointer to entropy context (handle)
286*c83a76b0SSuyog Pawar *
287*c83a76b0SSuyog Pawar *  @param[in]   ps_enc_cu
288*c83a76b0SSuyog Pawar *  pointer to inter cu whose skip flag is to be coded
289*c83a76b0SSuyog Pawar *
290*c83a76b0SSuyog Pawar *  @param[in]   top_avail
291*c83a76b0SSuyog Pawar *  top availabilty flag for current cu (boolean)
292*c83a76b0SSuyog Pawar *
293*c83a76b0SSuyog Pawar *  @param[in]   left_avail
294*c83a76b0SSuyog Pawar *  left availabilty flag for current cu (boolean)
295*c83a76b0SSuyog Pawar *
296*c83a76b0SSuyog Pawar *  @return      success or failure error code
297*c83a76b0SSuyog Pawar *
298*c83a76b0SSuyog Pawar ******************************************************************************
299*c83a76b0SSuyog Pawar */
ihevce_cabac_encode_skip_flag(entropy_context_t * ps_entropy_ctxt,cu_enc_loop_out_t * ps_enc_cu,WORD32 top_avail,WORD32 left_avail)300*c83a76b0SSuyog Pawar WORD32 ihevce_cabac_encode_skip_flag(
301*c83a76b0SSuyog Pawar     entropy_context_t *ps_entropy_ctxt,
302*c83a76b0SSuyog Pawar     cu_enc_loop_out_t *ps_enc_cu,
303*c83a76b0SSuyog Pawar     WORD32 top_avail,
304*c83a76b0SSuyog Pawar     WORD32 left_avail)
305*c83a76b0SSuyog Pawar 
306*c83a76b0SSuyog Pawar {
307*c83a76b0SSuyog Pawar     WORD32 error = IHEVCE_SUCCESS;
308*c83a76b0SSuyog Pawar     WORD32 skip_flag = ps_enc_cu->b1_skip_flag;
309*c83a76b0SSuyog Pawar     cab_ctxt_t *ps_cabac = &ps_entropy_ctxt->s_cabac_ctxt;
310*c83a76b0SSuyog Pawar 
311*c83a76b0SSuyog Pawar     /* CU top left co-ordinates w.r.t ctb */
312*c83a76b0SSuyog Pawar     WORD32 cu_x0 = ps_enc_cu->b3_cu_pos_x << 3;
313*c83a76b0SSuyog Pawar     WORD32 cu_y0 = ps_enc_cu->b3_cu_pos_y << 3;
314*c83a76b0SSuyog Pawar 
315*c83a76b0SSuyog Pawar     /* CU size in pels */
316*c83a76b0SSuyog Pawar     WORD32 cu_size = ps_enc_cu->b4_cu_size << 3;
317*c83a76b0SSuyog Pawar 
318*c83a76b0SSuyog Pawar     /* CU x co-ordinate w.r.t frame start           */
319*c83a76b0SSuyog Pawar     WORD32 ctb_x0_frm = (ps_entropy_ctxt->i4_ctb_x << ps_entropy_ctxt->i1_log2_ctb_size);
320*c83a76b0SSuyog Pawar 
321*c83a76b0SSuyog Pawar     WORD32 cu_x0_frm = cu_x0 + ctb_x0_frm;
322*c83a76b0SSuyog Pawar 
323*c83a76b0SSuyog Pawar     /* bit postion from where top skip flag is extracted; 1bit per 8 pel   */
324*c83a76b0SSuyog Pawar     WORD32 x_pos = ((cu_x0_frm >> 3) & 0x7);
325*c83a76b0SSuyog Pawar 
326*c83a76b0SSuyog Pawar     /* bit postion from where left skip flag is extracted; 1bit per 8 pel  */
327*c83a76b0SSuyog Pawar     WORD32 y_pos = ((cu_y0 >> 3) & 0x7);
328*c83a76b0SSuyog Pawar 
329*c83a76b0SSuyog Pawar     /* top and left skip flags computed based on nbr availability */
330*c83a76b0SSuyog Pawar     UWORD8 *pu1_top_skip_flags = ps_entropy_ctxt->pu1_skip_cu_top + (cu_x0_frm >> 6);
331*c83a76b0SSuyog Pawar     UWORD32 u4_skip_left_flags = ps_entropy_ctxt->u4_skip_cu_left;
332*c83a76b0SSuyog Pawar 
333*c83a76b0SSuyog Pawar     /* context incerements based on top and left neigbours */
334*c83a76b0SSuyog Pawar     UWORD32 ctxt_inc = 0;
335*c83a76b0SSuyog Pawar 
336*c83a76b0SSuyog Pawar     if(top_avail)
337*c83a76b0SSuyog Pawar     {
338*c83a76b0SSuyog Pawar         WORD32 val;
339*c83a76b0SSuyog Pawar         EXTRACT_BIT(val, pu1_top_skip_flags[0], x_pos);
340*c83a76b0SSuyog Pawar         ctxt_inc += val;
341*c83a76b0SSuyog Pawar     }
342*c83a76b0SSuyog Pawar 
343*c83a76b0SSuyog Pawar     if(left_avail)
344*c83a76b0SSuyog Pawar     {
345*c83a76b0SSuyog Pawar         WORD32 val;
346*c83a76b0SSuyog Pawar         EXTRACT_BIT(val, u4_skip_left_flags, y_pos);
347*c83a76b0SSuyog Pawar         ctxt_inc += val;
348*c83a76b0SSuyog Pawar     }
349*c83a76b0SSuyog Pawar 
350*c83a76b0SSuyog Pawar     if(CABAC_MODE_COMPUTE_BITS == ps_cabac->e_cabac_op_mode)
351*c83a76b0SSuyog Pawar     {
352*c83a76b0SSuyog Pawar         //ASSERT(ctxt_inc == ps_entropy_ctxt->i4_num_nbr_skip_cus);
353*c83a76b0SSuyog Pawar         ctxt_inc = ps_entropy_ctxt->i4_num_nbr_skip_cus;
354*c83a76b0SSuyog Pawar         ASSERT(ctxt_inc < 3);
355*c83a76b0SSuyog Pawar         ASSERT((WORD32)ctxt_inc <= (top_avail + left_avail));
356*c83a76b0SSuyog Pawar     }
357*c83a76b0SSuyog Pawar 
358*c83a76b0SSuyog Pawar     /* encode the skip flag */
359*c83a76b0SSuyog Pawar     error |= ihevce_cabac_encode_bin(ps_cabac, skip_flag, (IHEVC_CAB_SKIP_FLAG + ctxt_inc));
360*c83a76b0SSuyog Pawar 
361*c83a76b0SSuyog Pawar     AEV_TRACE("cu_skip_flag", skip_flag, ps_cabac->u4_range);
362*c83a76b0SSuyog Pawar 
363*c83a76b0SSuyog Pawar     if(CABAC_MODE_ENCODE_BITS == ps_cabac->e_cabac_op_mode)
364*c83a76b0SSuyog Pawar     {
365*c83a76b0SSuyog Pawar         /* update top and left skip flags only in encode mode */
366*c83a76b0SSuyog Pawar         if(skip_flag)
367*c83a76b0SSuyog Pawar         {
368*c83a76b0SSuyog Pawar             SET_BITS(pu1_top_skip_flags[0], x_pos, (cu_size >> 3));
369*c83a76b0SSuyog Pawar             SET_BITS(u4_skip_left_flags, y_pos, (cu_size >> 3));
370*c83a76b0SSuyog Pawar         }
371*c83a76b0SSuyog Pawar         else
372*c83a76b0SSuyog Pawar         {
373*c83a76b0SSuyog Pawar             CLEAR_BITS(pu1_top_skip_flags[0], x_pos, (cu_size >> 3));
374*c83a76b0SSuyog Pawar             CLEAR_BITS(u4_skip_left_flags, y_pos, (cu_size >> 3));
375*c83a76b0SSuyog Pawar         }
376*c83a76b0SSuyog Pawar 
377*c83a76b0SSuyog Pawar         ps_entropy_ctxt->u4_skip_cu_left = u4_skip_left_flags;
378*c83a76b0SSuyog Pawar     }
379*c83a76b0SSuyog Pawar 
380*c83a76b0SSuyog Pawar     return (error);
381*c83a76b0SSuyog Pawar }
382*c83a76b0SSuyog Pawar 
383*c83a76b0SSuyog Pawar /**
384*c83a76b0SSuyog Pawar ******************************************************************************
385*c83a76b0SSuyog Pawar *
386*c83a76b0SSuyog Pawar *  @brief Entropy encoding of partition mode (Coding Unit syntax)
387*c83a76b0SSuyog Pawar *
388*c83a76b0SSuyog Pawar *  @par   Description
389*c83a76b0SSuyog Pawar *  Binarization process and context modelling of partition mode is done as per
390*c83a76b0SSuyog Pawar *  section 9.3.2.6 (Table 9-34) and se
391*c83a76b0SSuyog Pawar *
392*c83a76b0SSuyog Pawar *  @param[inout]   ps_cabac
393*c83a76b0SSuyog Pawar *  pointer to cabac encoding context (handle)
394*c83a76b0SSuyog Pawar *
395*c83a76b0SSuyog Pawar *  @param[in]   intra
396*c83a76b0SSuyog Pawar *  boolean indicating if current cu is intra cu
397*c83a76b0SSuyog Pawar *
398*c83a76b0SSuyog Pawar *  @param[in]   is_mincu
399*c83a76b0SSuyog Pawar *  boolean indicating if current cu size is equal to mincu
400*c83a76b0SSuyog Pawar *
401*c83a76b0SSuyog Pawar *  @param[in]   amp_enabled
402*c83a76b0SSuyog Pawar *  flag to indicate if AMP(Assymetric motion partition) is enabled at sps level
403*c83a76b0SSuyog Pawar *
404*c83a76b0SSuyog Pawar *  @param[in]   cu_eq_8
405*c83a76b0SSuyog Pawar *  boolean indicating if current cu size is equal to 8
406*c83a76b0SSuyog Pawar *
407*c83a76b0SSuyog Pawar *  @param[in]   part_mode
408*c83a76b0SSuyog Pawar *  partition mode of current CU
409*c83a76b0SSuyog Pawar *
410*c83a76b0SSuyog Pawar *  @return      success or failure error code
411*c83a76b0SSuyog Pawar *
412*c83a76b0SSuyog Pawar ******************************************************************************
413*c83a76b0SSuyog Pawar */
ihevce_cabac_encode_part_mode(cab_ctxt_t * ps_cabac,WORD32 intra,WORD32 is_mincu,WORD32 amp_enabled,WORD32 cu_eq_8,WORD32 part_mode)414*c83a76b0SSuyog Pawar WORD32 ihevce_cabac_encode_part_mode(
415*c83a76b0SSuyog Pawar     cab_ctxt_t *ps_cabac,
416*c83a76b0SSuyog Pawar     WORD32 intra,
417*c83a76b0SSuyog Pawar     WORD32 is_mincu,
418*c83a76b0SSuyog Pawar     WORD32 amp_enabled,
419*c83a76b0SSuyog Pawar     WORD32 cu_eq_8,
420*c83a76b0SSuyog Pawar     WORD32 part_mode)
421*c83a76b0SSuyog Pawar {
422*c83a76b0SSuyog Pawar     /* Binarization depends on intra/inter, is_mincu, amp flag, cbsize == 8 */
423*c83a76b0SSuyog Pawar     WORD32 bins;
424*c83a76b0SSuyog Pawar     WORD32 bin_count, i;
425*c83a76b0SSuyog Pawar     WORD32 error = IHEVCE_SUCCESS;
426*c83a76b0SSuyog Pawar 
427*c83a76b0SSuyog Pawar     (void)is_mincu;
428*c83a76b0SSuyog Pawar     (void)amp_enabled;
429*c83a76b0SSuyog Pawar     (void)cu_eq_8;
430*c83a76b0SSuyog Pawar     if(intra)
431*c83a76b0SSuyog Pawar     {
432*c83a76b0SSuyog Pawar         /* sanity checks for intra part mode */
433*c83a76b0SSuyog Pawar         ASSERT(is_mincu);
434*c83a76b0SSuyog Pawar         ASSERT((part_mode == SIZE_NxN) || (part_mode == SIZE_2Nx2N));
435*c83a76b0SSuyog Pawar 
436*c83a76b0SSuyog Pawar         bins = (part_mode == SIZE_2Nx2N) ? 1 : 0;
437*c83a76b0SSuyog Pawar         error |= ihevce_cabac_encode_bin(ps_cabac, bins, IHEVC_CAB_PART_MODE);
438*c83a76b0SSuyog Pawar     }
439*c83a76b0SSuyog Pawar     else
440*c83a76b0SSuyog Pawar     {
441*c83a76b0SSuyog Pawar         /* sanity checks for inter part mode....Too many but good to have  */
442*c83a76b0SSuyog Pawar         ASSERT((amp_enabled == 0) || (amp_enabled == 1));
443*c83a76b0SSuyog Pawar         ASSERT((is_mincu == 0) || (is_mincu == 1));
444*c83a76b0SSuyog Pawar         ASSERT((cu_eq_8 == 0) || (cu_eq_8 == 1));
445*c83a76b0SSuyog Pawar         ASSERT((part_mode <= SIZE_nRx2N) && (part_mode >= SIZE_2Nx2N));
446*c83a76b0SSuyog Pawar         if(!amp_enabled)
447*c83a76b0SSuyog Pawar             ASSERT(part_mode <= SIZE_NxN);
448*c83a76b0SSuyog Pawar         if(!is_mincu)
449*c83a76b0SSuyog Pawar             ASSERT(part_mode != SIZE_NxN);
450*c83a76b0SSuyog Pawar         if(is_mincu)
451*c83a76b0SSuyog Pawar             ASSERT(part_mode <= SIZE_NxN);
452*c83a76b0SSuyog Pawar         if(cu_eq_8)
453*c83a76b0SSuyog Pawar             ASSERT(part_mode < SIZE_NxN);
454*c83a76b0SSuyog Pawar         if(cu_eq_8)
455*c83a76b0SSuyog Pawar             ASSERT(is_mincu);
456*c83a76b0SSuyog Pawar 
457*c83a76b0SSuyog Pawar         /* look up table for bins and number of bins for inter pred mode    */
458*c83a76b0SSuyog Pawar         if(!is_mincu)
459*c83a76b0SSuyog Pawar         {
460*c83a76b0SSuyog Pawar             bins = gu1_hevce_inter_part_mode_bins[amp_enabled][part_mode];
461*c83a76b0SSuyog Pawar         }
462*c83a76b0SSuyog Pawar         else
463*c83a76b0SSuyog Pawar         {
464*c83a76b0SSuyog Pawar             bins = gu1_hevce_inter_part_mode_bins_mincu[cu_eq_8][part_mode];
465*c83a76b0SSuyog Pawar         }
466*c83a76b0SSuyog Pawar 
467*c83a76b0SSuyog Pawar         bin_count = (bins >> 4) & 0xF;
468*c83a76b0SSuyog Pawar 
469*c83a76b0SSuyog Pawar         /* Encode the context model based bins, max of 3 */
470*c83a76b0SSuyog Pawar         for(i = 0; i < MIN(bin_count, 3); i++)
471*c83a76b0SSuyog Pawar         {
472*c83a76b0SSuyog Pawar             //TODO: HM-8.0-dev uses 0 context increment for bin2 (i===2) when amp is enabled
473*c83a76b0SSuyog Pawar             WORD32 ctxt_inc = IHEVC_CAB_PART_MODE + i;
474*c83a76b0SSuyog Pawar             WORD32 bin = (bins >> (3 - i)) & 0x1;
475*c83a76b0SSuyog Pawar             error |= ihevce_cabac_encode_bin(ps_cabac, bin, ctxt_inc);
476*c83a76b0SSuyog Pawar         }
477*c83a76b0SSuyog Pawar 
478*c83a76b0SSuyog Pawar         /* Encode the last bin as bypass bin for amp partitions */
479*c83a76b0SSuyog Pawar         if(bin_count == 4)
480*c83a76b0SSuyog Pawar         {
481*c83a76b0SSuyog Pawar             error |= ihevce_cabac_encode_bypass_bin(ps_cabac, (bins & 0x1));
482*c83a76b0SSuyog Pawar         }
483*c83a76b0SSuyog Pawar     }
484*c83a76b0SSuyog Pawar     AEV_TRACE("part_mode", part_mode, ps_cabac->u4_range);
485*c83a76b0SSuyog Pawar     return (error);
486*c83a76b0SSuyog Pawar }
487*c83a76b0SSuyog Pawar 
488*c83a76b0SSuyog Pawar /**
489*c83a76b0SSuyog Pawar ******************************************************************************
490*c83a76b0SSuyog Pawar *
491*c83a76b0SSuyog Pawar *  @brief Entropy encoding of merge_idx of inter prediction unit as per sec
492*c83a76b0SSuyog Pawar *  as per sec 9.3.2 Table9-32. (tunary binarization)
493*c83a76b0SSuyog Pawar *
494*c83a76b0SSuyog Pawar *  @par   Description
495*c83a76b0SSuyog Pawar *  trunacted unary binarization is done based on max merge candidates
496*c83a76b0SSuyog Pawar *  First bin is context modelled bin and the rest are coded as bypass
497*c83a76b0SSuyog Pawar *
498*c83a76b0SSuyog Pawar *  @param[inout]   ps_cabac
499*c83a76b0SSuyog Pawar *  pointer to cabac encoding context (handle)
500*c83a76b0SSuyog Pawar *
501*c83a76b0SSuyog Pawar *  @param[in]   merge_idx
502*c83a76b0SSuyog Pawar *  merge idx of the pu to be encoded;
503*c83a76b0SSuyog Pawar *
504*c83a76b0SSuyog Pawar *  @param[in]   max_merge_cand
505*c83a76b0SSuyog Pawar *  maximum merge candidates signalled in the slice header*
506*c83a76b0SSuyog Pawar *
507*c83a76b0SSuyog Pawar *  @return      success or failure error code
508*c83a76b0SSuyog Pawar *
509*c83a76b0SSuyog Pawar ******************************************************************************
510*c83a76b0SSuyog Pawar */
ihevce_cabac_encode_merge_idx(cab_ctxt_t * ps_cabac,WORD32 merge_idx,WORD32 max_merge_cand)511*c83a76b0SSuyog Pawar WORD32 ihevce_cabac_encode_merge_idx(cab_ctxt_t *ps_cabac, WORD32 merge_idx, WORD32 max_merge_cand)
512*c83a76b0SSuyog Pawar {
513*c83a76b0SSuyog Pawar     WORD32 ret = IHEVCE_SUCCESS;
514*c83a76b0SSuyog Pawar     WORD32 ctxt_inc = IHEVC_CAB_MERGE_IDX_EXT;
515*c83a76b0SSuyog Pawar 
516*c83a76b0SSuyog Pawar     /* sanity checks */
517*c83a76b0SSuyog Pawar     ASSERT((merge_idx >= 0) && (merge_idx < max_merge_cand));
518*c83a76b0SSuyog Pawar 
519*c83a76b0SSuyog Pawar     /* encode the merge idx only if required */
520*c83a76b0SSuyog Pawar     if(max_merge_cand > 1)
521*c83a76b0SSuyog Pawar     {
522*c83a76b0SSuyog Pawar         /* encode the context modelled first bin */
523*c83a76b0SSuyog Pawar         ret |= ihevce_cabac_encode_bin(ps_cabac, (merge_idx > 0), ctxt_inc);
524*c83a76b0SSuyog Pawar 
525*c83a76b0SSuyog Pawar         /* encode the remaining bins as bypass tunary */
526*c83a76b0SSuyog Pawar         if((max_merge_cand > 2) && (merge_idx > 0))
527*c83a76b0SSuyog Pawar         {
528*c83a76b0SSuyog Pawar             ret |=
529*c83a76b0SSuyog Pawar                 ihevce_cabac_encode_tunary_bypass(ps_cabac, (merge_idx - 1), (max_merge_cand - 2));
530*c83a76b0SSuyog Pawar         }
531*c83a76b0SSuyog Pawar 
532*c83a76b0SSuyog Pawar         AEV_TRACE("merge_idx", merge_idx, ps_cabac->u4_range);
533*c83a76b0SSuyog Pawar     }
534*c83a76b0SSuyog Pawar 
535*c83a76b0SSuyog Pawar     return (ret);
536*c83a76b0SSuyog Pawar }
537*c83a76b0SSuyog Pawar 
538*c83a76b0SSuyog Pawar /**
539*c83a76b0SSuyog Pawar ******************************************************************************
540*c83a76b0SSuyog Pawar *
541*c83a76b0SSuyog Pawar *  @brief Entropy encoding of inter_pred_idc for prediction unit of B slice as
542*c83a76b0SSuyog Pawar *   per sec 9.3.2.9 Table9-36
543*c83a76b0SSuyog Pawar *
544*c83a76b0SSuyog Pawar *  @par   Description
545*c83a76b0SSuyog Pawar *  Max of two context modelled bins coded for pu size > 8x4 or 4x8
546*c83a76b0SSuyog Pawar *  one context modelled bin coded for pu size = 8x4 or 4x8; bipred not allowed
547*c83a76b0SSuyog Pawar *  for 8x4 or 4x8.
548*c83a76b0SSuyog Pawar *
549*c83a76b0SSuyog Pawar *  @param[inout]   ps_cabac
550*c83a76b0SSuyog Pawar *  pointer to cabac encoding context (handle)
551*c83a76b0SSuyog Pawar *
552*c83a76b0SSuyog Pawar *  @param[in]   inter_pred_idc
553*c83a76b0SSuyog Pawar *  inter pred mode  to be encoded; shall be PRED_L0 or PRED_L1 or PRED_BI
554*c83a76b0SSuyog Pawar *
555*c83a76b0SSuyog Pawar *  @param[in]   cu_depth
556*c83a76b0SSuyog Pawar *  depth of the cu to which current pu belongs (required for context increment)
557*c83a76b0SSuyog Pawar *
558*c83a76b0SSuyog Pawar *  @param[in]   pu_w_plus_pu_h
559*c83a76b0SSuyog Pawar *  required to check if pu_w_plus_pu_h is 12 (8x4PU or 4x8PU)
560*c83a76b0SSuyog Pawar *
561*c83a76b0SSuyog Pawar *  @return      success or failure error code
562*c83a76b0SSuyog Pawar *
563*c83a76b0SSuyog Pawar ******************************************************************************
564*c83a76b0SSuyog Pawar */
ihevce_cabac_encode_inter_pred_idc(cab_ctxt_t * ps_cabac,WORD32 inter_pred_idc,WORD32 cu_depth,WORD32 pu_w_plus_pu_h)565*c83a76b0SSuyog Pawar WORD32 ihevce_cabac_encode_inter_pred_idc(
566*c83a76b0SSuyog Pawar     cab_ctxt_t *ps_cabac, WORD32 inter_pred_idc, WORD32 cu_depth, WORD32 pu_w_plus_pu_h)
567*c83a76b0SSuyog Pawar {
568*c83a76b0SSuyog Pawar     WORD32 ret = IHEVCE_SUCCESS;
569*c83a76b0SSuyog Pawar     WORD32 ctxt_inc;
570*c83a76b0SSuyog Pawar 
571*c83a76b0SSuyog Pawar     ASSERT(inter_pred_idc <= PRED_BI);
572*c83a76b0SSuyog Pawar 
573*c83a76b0SSuyog Pawar     /* check if PU is 8x4/4x8  */
574*c83a76b0SSuyog Pawar     if(pu_w_plus_pu_h == 12)
575*c83a76b0SSuyog Pawar     {
576*c83a76b0SSuyog Pawar         /* case of 8x4 or 4x8 where bi_pred is not allowed */
577*c83a76b0SSuyog Pawar         ASSERT((inter_pred_idc == PRED_L0) || (inter_pred_idc == PRED_L1));
578*c83a76b0SSuyog Pawar 
579*c83a76b0SSuyog Pawar         ctxt_inc = IHEVC_CAB_INTER_PRED_IDC + 4;
580*c83a76b0SSuyog Pawar         ret |= ihevce_cabac_encode_bin(ps_cabac, inter_pred_idc, ctxt_inc);
581*c83a76b0SSuyog Pawar     }
582*c83a76b0SSuyog Pawar     else
583*c83a76b0SSuyog Pawar     {
584*c83a76b0SSuyog Pawar         /* larger PUs can be encoded as bi_pred/l0/l1 inter_pred_idc */
585*c83a76b0SSuyog Pawar         WORD32 is_bipred = (inter_pred_idc == PRED_BI);
586*c83a76b0SSuyog Pawar 
587*c83a76b0SSuyog Pawar         ctxt_inc = IHEVC_CAB_INTER_PRED_IDC + cu_depth;
588*c83a76b0SSuyog Pawar         ret |= ihevce_cabac_encode_bin(ps_cabac, is_bipred, ctxt_inc);
589*c83a76b0SSuyog Pawar 
590*c83a76b0SSuyog Pawar         if(!is_bipred)
591*c83a76b0SSuyog Pawar         {
592*c83a76b0SSuyog Pawar             ctxt_inc = IHEVC_CAB_INTER_PRED_IDC + 4;
593*c83a76b0SSuyog Pawar             ret |= ihevce_cabac_encode_bin(ps_cabac, inter_pred_idc, ctxt_inc);
594*c83a76b0SSuyog Pawar         }
595*c83a76b0SSuyog Pawar     }
596*c83a76b0SSuyog Pawar 
597*c83a76b0SSuyog Pawar     AEV_TRACE("inter_pred_idc", inter_pred_idc, ps_cabac->u4_range);
598*c83a76b0SSuyog Pawar 
599*c83a76b0SSuyog Pawar     return (ret);
600*c83a76b0SSuyog Pawar }
601*c83a76b0SSuyog Pawar 
602*c83a76b0SSuyog Pawar /**
603*c83a76b0SSuyog Pawar ******************************************************************************
604*c83a76b0SSuyog Pawar *
605*c83a76b0SSuyog Pawar *  @brief Entropy encoding of refidx for prediction unit; Binarization done as
606*c83a76b0SSuyog Pawar *   tunary code as per sec 9.3.2 Table9-32
607*c83a76b0SSuyog Pawar *
608*c83a76b0SSuyog Pawar *  @par   Description
609*c83a76b0SSuyog Pawar *  First two bins are context modelled while the rest are coded as bypass
610*c83a76b0SSuyog Pawar *
611*c83a76b0SSuyog Pawar *  @param[inout]   ps_cabac
612*c83a76b0SSuyog Pawar *  pointer to cabac encoding context (handle)
613*c83a76b0SSuyog Pawar *
614*c83a76b0SSuyog Pawar *  @param[in]   ref_idx
615*c83a76b0SSuyog Pawar *  ref idx of partition unit
616*c83a76b0SSuyog Pawar *
617*c83a76b0SSuyog Pawar *  @param[in]   active_refs
618*c83a76b0SSuyog Pawar *  max number of active references signalled in slice header
619*c83a76b0SSuyog Pawar *
620*c83a76b0SSuyog Pawar *  @return      success or failure error code
621*c83a76b0SSuyog Pawar *
622*c83a76b0SSuyog Pawar ******************************************************************************
623*c83a76b0SSuyog Pawar */
ihevce_cabac_encode_refidx(cab_ctxt_t * ps_cabac,WORD32 ref_idx,WORD32 active_refs)624*c83a76b0SSuyog Pawar WORD32 ihevce_cabac_encode_refidx(cab_ctxt_t *ps_cabac, WORD32 ref_idx, WORD32 active_refs)
625*c83a76b0SSuyog Pawar {
626*c83a76b0SSuyog Pawar     /************************************************************/
627*c83a76b0SSuyog Pawar     /* encode ref_idx as tunary binarization Table 9-32         */
628*c83a76b0SSuyog Pawar     /* First 2 bin use context model and rest coded as  bypass  */
629*c83a76b0SSuyog Pawar     /************************************************************/
630*c83a76b0SSuyog Pawar     WORD32 ret = IHEVCE_SUCCESS;
631*c83a76b0SSuyog Pawar     WORD32 ctxt_inc = IHEVC_CAB_INTER_REF_IDX;
632*c83a76b0SSuyog Pawar 
633*c83a76b0SSuyog Pawar     /* sanity checks */
634*c83a76b0SSuyog Pawar     ASSERT((ref_idx >= 0) && (ref_idx < active_refs));
635*c83a76b0SSuyog Pawar 
636*c83a76b0SSuyog Pawar     /* encode the ref idx only if required */
637*c83a76b0SSuyog Pawar     if(active_refs > 1)
638*c83a76b0SSuyog Pawar     {
639*c83a76b0SSuyog Pawar         /* encode the context modelled first bin */
640*c83a76b0SSuyog Pawar         ret |= ihevce_cabac_encode_bin(ps_cabac, (ref_idx > 0), ctxt_inc);
641*c83a76b0SSuyog Pawar 
642*c83a76b0SSuyog Pawar         if((active_refs > 2) && (ref_idx > 0))
643*c83a76b0SSuyog Pawar         {
644*c83a76b0SSuyog Pawar             /* encode the context modelled second bin */
645*c83a76b0SSuyog Pawar             ctxt_inc++;
646*c83a76b0SSuyog Pawar             ret |= ihevce_cabac_encode_bin(ps_cabac, (ref_idx > 1), ctxt_inc);
647*c83a76b0SSuyog Pawar         }
648*c83a76b0SSuyog Pawar 
649*c83a76b0SSuyog Pawar         if((active_refs > 3) && (ref_idx > 1))
650*c83a76b0SSuyog Pawar         {
651*c83a76b0SSuyog Pawar             /* encode remaining bypass bins */
652*c83a76b0SSuyog Pawar             ret |= ihevce_cabac_encode_tunary_bypass(ps_cabac, (ref_idx - 2), (active_refs - 3));
653*c83a76b0SSuyog Pawar         }
654*c83a76b0SSuyog Pawar 
655*c83a76b0SSuyog Pawar         AEV_TRACE("ref_idx", ref_idx, ps_cabac->u4_range);
656*c83a76b0SSuyog Pawar     }
657*c83a76b0SSuyog Pawar 
658*c83a76b0SSuyog Pawar     return (ret);
659*c83a76b0SSuyog Pawar }
660*c83a76b0SSuyog Pawar 
661*c83a76b0SSuyog Pawar /**
662*c83a76b0SSuyog Pawar ******************************************************************************
663*c83a76b0SSuyog Pawar *
664*c83a76b0SSuyog Pawar *  @brief Entropy encoding of mvd for inter pu as per section 7.3.10.2
665*c83a76b0SSuyog Pawar *
666*c83a76b0SSuyog Pawar *  @par   Description
667*c83a76b0SSuyog Pawar *  syntax coded as per section 7.3.10.2 for mvdx and mvdy
668*c83a76b0SSuyog Pawar *  context modeling of abs_mvd_greater0 abs_mvd_greater1 done as per Table 9-32
669*c83a76b0SSuyog Pawar *  binazrization of abs_mvd_minus2 is done as done as EG1 code section 9.3.2.4
670*c83a76b0SSuyog Pawar *
671*c83a76b0SSuyog Pawar *  @param[inout]   ps_cabac
672*c83a76b0SSuyog Pawar *  pointer to cabac encoding context (handle)
673*c83a76b0SSuyog Pawar *
674*c83a76b0SSuyog Pawar *  @param[in]   ps_mvd
675*c83a76b0SSuyog Pawar *  pointer to mvd struct containing mvdx and mvdy
676*c83a76b0SSuyog Pawar *
677*c83a76b0SSuyog Pawar *  @return      success or failure error code
678*c83a76b0SSuyog Pawar *
679*c83a76b0SSuyog Pawar ******************************************************************************
680*c83a76b0SSuyog Pawar */
ihevce_cabac_encode_mvd(cab_ctxt_t * ps_cabac,mv_t * ps_mvd)681*c83a76b0SSuyog Pawar WORD32 ihevce_cabac_encode_mvd(cab_ctxt_t *ps_cabac, mv_t *ps_mvd)
682*c83a76b0SSuyog Pawar {
683*c83a76b0SSuyog Pawar     WORD32 ret = IHEVCE_SUCCESS;
684*c83a76b0SSuyog Pawar     WORD32 mvd_x = ps_mvd->i2_mvx;
685*c83a76b0SSuyog Pawar     WORD32 mvd_y = ps_mvd->i2_mvy;
686*c83a76b0SSuyog Pawar 
687*c83a76b0SSuyog Pawar     WORD32 abs_mvd_x = ABS(mvd_x);
688*c83a76b0SSuyog Pawar     WORD32 abs_mvd_y = ABS(mvd_y);
689*c83a76b0SSuyog Pawar 
690*c83a76b0SSuyog Pawar     WORD32 abs_mvd_x_gt0 = abs_mvd_x > 0;
691*c83a76b0SSuyog Pawar     WORD32 abs_mvd_y_gt0 = abs_mvd_y > 0;
692*c83a76b0SSuyog Pawar 
693*c83a76b0SSuyog Pawar     WORD32 abs_mvd_x_gt1 = abs_mvd_x > 1;
694*c83a76b0SSuyog Pawar     WORD32 abs_mvd_y_gt1 = abs_mvd_y > 1;
695*c83a76b0SSuyog Pawar 
696*c83a76b0SSuyog Pawar     WORD32 ctxt_inc = IHEVC_CAB_MVD_GRT0;
697*c83a76b0SSuyog Pawar 
698*c83a76b0SSuyog Pawar     /* encode absmvd_x > 0 */
699*c83a76b0SSuyog Pawar     ret |= ihevce_cabac_encode_bin(ps_cabac, abs_mvd_x_gt0, ctxt_inc);
700*c83a76b0SSuyog Pawar     AEV_TRACE("abs_mvd_greater0_flag[0]", abs_mvd_x_gt0, ps_cabac->u4_range);
701*c83a76b0SSuyog Pawar 
702*c83a76b0SSuyog Pawar     /* encode absmvd_y > 0 */
703*c83a76b0SSuyog Pawar     ret |= ihevce_cabac_encode_bin(ps_cabac, abs_mvd_y_gt0, ctxt_inc);
704*c83a76b0SSuyog Pawar     AEV_TRACE("abs_mvd_greater0_flag[1]", abs_mvd_y_gt0, ps_cabac->u4_range);
705*c83a76b0SSuyog Pawar 
706*c83a76b0SSuyog Pawar     ctxt_inc = IHEVC_CAB_MVD_GRT1;
707*c83a76b0SSuyog Pawar 
708*c83a76b0SSuyog Pawar     /* encode abs_mvd_x > 1 iff (abs_mvd_x > 0) */
709*c83a76b0SSuyog Pawar     if(abs_mvd_x_gt0)
710*c83a76b0SSuyog Pawar     {
711*c83a76b0SSuyog Pawar         ret |= ihevce_cabac_encode_bin(ps_cabac, abs_mvd_x_gt1, ctxt_inc);
712*c83a76b0SSuyog Pawar         AEV_TRACE("abs_mvd_greater1_flag[0]", abs_mvd_x_gt1, ps_cabac->u4_range);
713*c83a76b0SSuyog Pawar     }
714*c83a76b0SSuyog Pawar 
715*c83a76b0SSuyog Pawar     /* encode abs_mvd_y > 1 iff (abs_mvd_y > 0) */
716*c83a76b0SSuyog Pawar     if(abs_mvd_y_gt0)
717*c83a76b0SSuyog Pawar     {
718*c83a76b0SSuyog Pawar         ret |= ihevce_cabac_encode_bin(ps_cabac, abs_mvd_y_gt1, ctxt_inc);
719*c83a76b0SSuyog Pawar         AEV_TRACE("abs_mvd_greater1_flag[1]", abs_mvd_y_gt1, ps_cabac->u4_range);
720*c83a76b0SSuyog Pawar     }
721*c83a76b0SSuyog Pawar 
722*c83a76b0SSuyog Pawar     /* encode abs_mvd_x - 2 iff (abs_mvd_x > 1) */
723*c83a76b0SSuyog Pawar     if(abs_mvd_x_gt1)
724*c83a76b0SSuyog Pawar     {
725*c83a76b0SSuyog Pawar         ret |= ihevce_cabac_encode_egk(ps_cabac, (abs_mvd_x - 2), 1);
726*c83a76b0SSuyog Pawar         AEV_TRACE("abs_mvd_minus2[0]", (abs_mvd_x - 2), ps_cabac->u4_range);
727*c83a76b0SSuyog Pawar     }
728*c83a76b0SSuyog Pawar 
729*c83a76b0SSuyog Pawar     /* encode mvd_x sign iff (abs_mvd_x > 0) */
730*c83a76b0SSuyog Pawar     if(abs_mvd_x_gt0)
731*c83a76b0SSuyog Pawar     {
732*c83a76b0SSuyog Pawar         ret |= ihevce_cabac_encode_bypass_bin(ps_cabac, (mvd_x < 0));
733*c83a76b0SSuyog Pawar         AEV_TRACE("mvd_sign_flag[0]", (mvd_x < 0), ps_cabac->u4_range);
734*c83a76b0SSuyog Pawar     }
735*c83a76b0SSuyog Pawar 
736*c83a76b0SSuyog Pawar     /* encode abs_mvd_y - 2 iff (abs_mvd_y > 1) */
737*c83a76b0SSuyog Pawar     if(abs_mvd_y_gt1)
738*c83a76b0SSuyog Pawar     {
739*c83a76b0SSuyog Pawar         ret |= ihevce_cabac_encode_egk(ps_cabac, (abs_mvd_y - 2), 1);
740*c83a76b0SSuyog Pawar         AEV_TRACE("abs_mvd_minus2[1]", (abs_mvd_y - 2), ps_cabac->u4_range);
741*c83a76b0SSuyog Pawar     }
742*c83a76b0SSuyog Pawar 
743*c83a76b0SSuyog Pawar     /* encode mvd_y sign iff (abs_mvd_y > 0) */
744*c83a76b0SSuyog Pawar     if(abs_mvd_y_gt0)
745*c83a76b0SSuyog Pawar     {
746*c83a76b0SSuyog Pawar         ret |= ihevce_cabac_encode_bypass_bin(ps_cabac, (mvd_y < 0));
747*c83a76b0SSuyog Pawar         AEV_TRACE("mvd_sign_flag[1]", (mvd_y < 0), ps_cabac->u4_range);
748*c83a76b0SSuyog Pawar     }
749*c83a76b0SSuyog Pawar 
750*c83a76b0SSuyog Pawar     return ret;
751*c83a76b0SSuyog Pawar }
752*c83a76b0SSuyog Pawar 
753*c83a76b0SSuyog Pawar /**
754*c83a76b0SSuyog Pawar ******************************************************************************
755*c83a76b0SSuyog Pawar *
756*c83a76b0SSuyog Pawar *  @brief Entropy encoding of all syntax elements of inter PUs in a CU
757*c83a76b0SSuyog Pawar *
758*c83a76b0SSuyog Pawar *  @par   Description
759*c83a76b0SSuyog Pawar *  syntax coded as per section 7.3.10.1 for inter prediction unit
760*c83a76b0SSuyog Pawar *
761*c83a76b0SSuyog Pawar *  @param[inout]   ps_entropy_ctxt
762*c83a76b0SSuyog Pawar *  pointer to entropy context (handle)
763*c83a76b0SSuyog Pawar *
764*c83a76b0SSuyog Pawar *  @param[in]   ps_enc_cu
765*c83a76b0SSuyog Pawar *  pointer to current cu whose inter prediction units are to be encoded
766*c83a76b0SSuyog Pawar *
767*c83a76b0SSuyog Pawar *  @param[in]   cu_depth
768*c83a76b0SSuyog Pawar *  depth of the the current cu in coding tree
769*c83a76b0SSuyog Pawar *
770*c83a76b0SSuyog Pawar *  @return      success or failure error code
771*c83a76b0SSuyog Pawar *
772*c83a76b0SSuyog Pawar ******************************************************************************
773*c83a76b0SSuyog Pawar */
ihevce_cabac_encode_inter_pu(entropy_context_t * ps_entropy_ctxt,cu_enc_loop_out_t * ps_enc_cu,WORD32 cu_depth)774*c83a76b0SSuyog Pawar WORD32 ihevce_cabac_encode_inter_pu(
775*c83a76b0SSuyog Pawar     entropy_context_t *ps_entropy_ctxt, cu_enc_loop_out_t *ps_enc_cu, WORD32 cu_depth)
776*c83a76b0SSuyog Pawar {
777*c83a76b0SSuyog Pawar     WORD32 ret = IHEVCE_SUCCESS;
778*c83a76b0SSuyog Pawar 
779*c83a76b0SSuyog Pawar     slice_header_t *ps_slice_hdr = ps_entropy_ctxt->ps_slice_hdr;
780*c83a76b0SSuyog Pawar     cab_ctxt_t *ps_cabac = &ps_entropy_ctxt->s_cabac_ctxt;
781*c83a76b0SSuyog Pawar     pu_t *ps_pu = ps_enc_cu->ps_pu;
782*c83a76b0SSuyog Pawar 
783*c83a76b0SSuyog Pawar     WORD32 merge_idx = ps_pu->b3_merge_idx;
784*c83a76b0SSuyog Pawar     WORD32 max_merge_cand = ps_slice_hdr->i1_max_num_merge_cand;
785*c83a76b0SSuyog Pawar     WORD32 ctxt_inc;
786*c83a76b0SSuyog Pawar 
787*c83a76b0SSuyog Pawar     if(ps_enc_cu->b1_skip_flag)
788*c83a76b0SSuyog Pawar     {
789*c83a76b0SSuyog Pawar         WORD32 cu_size = ps_enc_cu->b4_cu_size << 3;
790*c83a76b0SSuyog Pawar         /*PIC_INFO : SKIP CU in frame*/
791*c83a76b0SSuyog Pawar         if(ps_cabac->e_cabac_op_mode == CABAC_MODE_ENCODE_BITS)
792*c83a76b0SSuyog Pawar         {
793*c83a76b0SSuyog Pawar             ps_entropy_ctxt->ps_pic_level_info->i8_total_skip_cu++;
794*c83a76b0SSuyog Pawar             ps_entropy_ctxt->ps_pic_level_info->i8_total_pu++;
795*c83a76b0SSuyog Pawar             if(cu_size == 64)
796*c83a76b0SSuyog Pawar                 ps_entropy_ctxt->ps_pic_level_info->i8_total_2nx2n_inter_pu[3]++;
797*c83a76b0SSuyog Pawar             else
798*c83a76b0SSuyog Pawar                 ps_entropy_ctxt->ps_pic_level_info->i8_total_2nx2n_inter_pu[cu_size >> 4]++;
799*c83a76b0SSuyog Pawar         }
800*c83a76b0SSuyog Pawar         /* encode the merge idx for skip cu and return */
801*c83a76b0SSuyog Pawar         ret |= ihevce_cabac_encode_merge_idx(ps_cabac, merge_idx, max_merge_cand);
802*c83a76b0SSuyog Pawar     }
803*c83a76b0SSuyog Pawar     else
804*c83a76b0SSuyog Pawar     {
805*c83a76b0SSuyog Pawar         /* MODE_INTER */
806*c83a76b0SSuyog Pawar         WORD32 part_mode = ps_enc_cu->b3_part_mode;
807*c83a76b0SSuyog Pawar         WORD32 num_parts, i;
808*c83a76b0SSuyog Pawar 
809*c83a76b0SSuyog Pawar         num_parts = (part_mode == SIZE_2Nx2N) ? 1 : ((part_mode == SIZE_NxN) ? 4 : 2);
810*c83a76b0SSuyog Pawar 
811*c83a76b0SSuyog Pawar         /*PIC_INFO : INTER CU in frame*/
812*c83a76b0SSuyog Pawar         if(ps_cabac->e_cabac_op_mode == CABAC_MODE_ENCODE_BITS)
813*c83a76b0SSuyog Pawar         {
814*c83a76b0SSuyog Pawar             WORD32 cu_size = ps_enc_cu->b4_cu_size << 3;
815*c83a76b0SSuyog Pawar             ps_entropy_ctxt->ps_pic_level_info->i8_total_inter_cu++;
816*c83a76b0SSuyog Pawar             ps_entropy_ctxt->ps_pic_level_info->i8_total_pu += num_parts;
817*c83a76b0SSuyog Pawar 
818*c83a76b0SSuyog Pawar             // clang-format off
819*c83a76b0SSuyog Pawar             if(PART_2Nx2N == part_mode)
820*c83a76b0SSuyog Pawar             {
821*c83a76b0SSuyog Pawar                 if(cu_size == 64)
822*c83a76b0SSuyog Pawar                     ps_entropy_ctxt->ps_pic_level_info->i8_total_2nx2n_inter_pu[3]++;
823*c83a76b0SSuyog Pawar                 else
824*c83a76b0SSuyog Pawar                     ps_entropy_ctxt->ps_pic_level_info->i8_total_2nx2n_inter_pu[cu_size >> 4]++;
825*c83a76b0SSuyog Pawar             }
826*c83a76b0SSuyog Pawar             else if((PART_2NxN == part_mode) || (PART_Nx2N == part_mode))
827*c83a76b0SSuyog Pawar             {
828*c83a76b0SSuyog Pawar                 if(cu_size == 64)
829*c83a76b0SSuyog Pawar                     ps_entropy_ctxt->ps_pic_level_info->i8_total_smp_inter_pu[3]++;
830*c83a76b0SSuyog Pawar                 else
831*c83a76b0SSuyog Pawar                     ps_entropy_ctxt->ps_pic_level_info->i8_total_smp_inter_pu[cu_size >> 4]++;
832*c83a76b0SSuyog Pawar             }
833*c83a76b0SSuyog Pawar             else if((PART_2NxnU == part_mode) || (PART_2NxnD == part_mode) ||
834*c83a76b0SSuyog Pawar                     (PART_nLx2N == part_mode) || (PART_nRx2N == part_mode))
835*c83a76b0SSuyog Pawar             {
836*c83a76b0SSuyog Pawar                 ps_entropy_ctxt->ps_pic_level_info->i8_total_amp_inter_pu[cu_size >> 5]++;
837*c83a76b0SSuyog Pawar             }
838*c83a76b0SSuyog Pawar             else
839*c83a76b0SSuyog Pawar             {
840*c83a76b0SSuyog Pawar                 ps_entropy_ctxt->ps_pic_level_info->i8_total_nxn_inter_pu[cu_size >> 5]++;
841*c83a76b0SSuyog Pawar             }
842*c83a76b0SSuyog Pawar             // clang-format on
843*c83a76b0SSuyog Pawar         }
844*c83a76b0SSuyog Pawar 
845*c83a76b0SSuyog Pawar         /* encode each pu partition */
846*c83a76b0SSuyog Pawar         for(i = 0; i < num_parts; i++)
847*c83a76b0SSuyog Pawar         {
848*c83a76b0SSuyog Pawar             /* encode the merge flag context modelled bin */
849*c83a76b0SSuyog Pawar             WORD32 merge_flag;
850*c83a76b0SSuyog Pawar             UWORD32 u4_bits_estimated_merge_flag = 0;
851*c83a76b0SSuyog Pawar             ps_pu = ps_enc_cu->ps_pu + i;
852*c83a76b0SSuyog Pawar 
853*c83a76b0SSuyog Pawar             /* encode the merge flag context modelled bin */
854*c83a76b0SSuyog Pawar             merge_flag = ps_pu->b1_merge_flag;
855*c83a76b0SSuyog Pawar             u4_bits_estimated_merge_flag = ps_cabac->u4_bits_estimated_q12;
856*c83a76b0SSuyog Pawar             ctxt_inc = IHEVC_CAB_MERGE_FLAG_EXT;
857*c83a76b0SSuyog Pawar             ret |= ihevce_cabac_encode_bin(ps_cabac, merge_flag, ctxt_inc);
858*c83a76b0SSuyog Pawar 
859*c83a76b0SSuyog Pawar             if(ps_cabac->e_cabac_op_mode == CABAC_MODE_ENCODE_BITS)
860*c83a76b0SSuyog Pawar             {
861*c83a76b0SSuyog Pawar                 // clang-format off
862*c83a76b0SSuyog Pawar                 /*PIC INFO : Populate merge flag */
863*c83a76b0SSuyog Pawar                 ps_entropy_ctxt->ps_pic_level_info->u8_bits_estimated_merge_flag =
864*c83a76b0SSuyog Pawar                     (ps_cabac->u4_bits_estimated_q12 -
865*c83a76b0SSuyog Pawar                         u4_bits_estimated_merge_flag);
866*c83a76b0SSuyog Pawar                 // clang-format on
867*c83a76b0SSuyog Pawar             }
868*c83a76b0SSuyog Pawar             AEV_TRACE("merge_flag", merge_flag, ps_cabac->u4_range);
869*c83a76b0SSuyog Pawar 
870*c83a76b0SSuyog Pawar             if(merge_flag)
871*c83a76b0SSuyog Pawar             {
872*c83a76b0SSuyog Pawar                 merge_idx = ps_pu->b3_merge_idx;
873*c83a76b0SSuyog Pawar                 if(ps_cabac->e_cabac_op_mode == CABAC_MODE_ENCODE_BITS)
874*c83a76b0SSuyog Pawar                     ps_entropy_ctxt->ps_pic_level_info->i8_total_merge_pu++;
875*c83a76b0SSuyog Pawar                 /* encode the merge idx for the pu */
876*c83a76b0SSuyog Pawar                 ret |= ihevce_cabac_encode_merge_idx(ps_cabac, merge_idx, max_merge_cand);
877*c83a76b0SSuyog Pawar             }
878*c83a76b0SSuyog Pawar             else
879*c83a76b0SSuyog Pawar             {
880*c83a76b0SSuyog Pawar                 /* encode the inter_pred_idc, ref_idx and mvd */
881*c83a76b0SSuyog Pawar                 WORD32 inter_pred_idc = ps_pu->b2_pred_mode;
882*c83a76b0SSuyog Pawar                 WORD32 ref_l0_active = ps_slice_hdr->i1_num_ref_idx_l0_active;
883*c83a76b0SSuyog Pawar                 WORD32 ref_l1_active = ps_slice_hdr->i1_num_ref_idx_l1_active;
884*c83a76b0SSuyog Pawar 
885*c83a76b0SSuyog Pawar                 /*PIC_INFO : L0 L1 BI ro r1.. in frame*/
886*c83a76b0SSuyog Pawar                 if(ps_cabac->e_cabac_op_mode == CABAC_MODE_ENCODE_BITS)
887*c83a76b0SSuyog Pawar                 {
888*c83a76b0SSuyog Pawar                     ps_entropy_ctxt->ps_pic_level_info->i8_total_non_skipped_inter_pu++;
889*c83a76b0SSuyog Pawar                     // clang-format off
890*c83a76b0SSuyog Pawar                     if(inter_pred_idc == PRED_L0)
891*c83a76b0SSuyog Pawar                     {
892*c83a76b0SSuyog Pawar                         ps_entropy_ctxt->ps_pic_level_info->i8_total_L0_mode++;
893*c83a76b0SSuyog Pawar                         ps_entropy_ctxt->ps_pic_level_info->i8_total_L0_ref_idx[ps_pu->mv.i1_l0_ref_idx]++;
894*c83a76b0SSuyog Pawar                     }
895*c83a76b0SSuyog Pawar                     else if(inter_pred_idc == PRED_L1)
896*c83a76b0SSuyog Pawar                     {
897*c83a76b0SSuyog Pawar                         ps_entropy_ctxt->ps_pic_level_info->i8_total_L1_mode++;
898*c83a76b0SSuyog Pawar                         ps_entropy_ctxt->ps_pic_level_info->i8_total_L1_ref_idx[ps_pu->mv.i1_l1_ref_idx]++;
899*c83a76b0SSuyog Pawar                     }
900*c83a76b0SSuyog Pawar                     else if(inter_pred_idc == PRED_BI)
901*c83a76b0SSuyog Pawar                     {
902*c83a76b0SSuyog Pawar                         ps_entropy_ctxt->ps_pic_level_info->i8_total_BI_mode++;
903*c83a76b0SSuyog Pawar                         if(inter_pred_idc != PRED_L1)
904*c83a76b0SSuyog Pawar                             ps_entropy_ctxt->ps_pic_level_info->i8_total_L0_ref_idx[ps_pu->mv.i1_l0_ref_idx]++;
905*c83a76b0SSuyog Pawar                         if(inter_pred_idc != PRED_L0)
906*c83a76b0SSuyog Pawar                             ps_entropy_ctxt->ps_pic_level_info->i8_total_L1_ref_idx[ps_pu->mv.i1_l1_ref_idx]++;
907*c83a76b0SSuyog Pawar                     }
908*c83a76b0SSuyog Pawar                     // clang-format on
909*c83a76b0SSuyog Pawar                 }
910*c83a76b0SSuyog Pawar                 if(ps_slice_hdr->i1_slice_type == BSLICE)
911*c83a76b0SSuyog Pawar                 {
912*c83a76b0SSuyog Pawar                     /* Encode inter_pred_idc as per sec 9.3.2.9 Table9-36 */
913*c83a76b0SSuyog Pawar                     WORD32 pu_w_plus_pu_h;
914*c83a76b0SSuyog Pawar                     WORD32 inter_pred_idc = ps_pu->b2_pred_mode;
915*c83a76b0SSuyog Pawar 
916*c83a76b0SSuyog Pawar                     /* required to check if w+h==12 case */
917*c83a76b0SSuyog Pawar                     pu_w_plus_pu_h = ((ps_pu->b4_wd + 1) << 2) + ((ps_pu->b4_ht + 1) << 2);
918*c83a76b0SSuyog Pawar 
919*c83a76b0SSuyog Pawar                     ret |= ihevce_cabac_encode_inter_pred_idc(
920*c83a76b0SSuyog Pawar                         ps_cabac, inter_pred_idc, cu_depth, pu_w_plus_pu_h);
921*c83a76b0SSuyog Pawar                 }
922*c83a76b0SSuyog Pawar                 else
923*c83a76b0SSuyog Pawar                 {
924*c83a76b0SSuyog Pawar                     ASSERT(inter_pred_idc == 0);
925*c83a76b0SSuyog Pawar                 }
926*c83a76b0SSuyog Pawar 
927*c83a76b0SSuyog Pawar                 /* Decode ref idx and mvd  for L0 (PRED_L0 or PRED_BI) */
928*c83a76b0SSuyog Pawar                 if(inter_pred_idc != PRED_L1)
929*c83a76b0SSuyog Pawar                 {
930*c83a76b0SSuyog Pawar                     UWORD32 u4_bits_estimated_prev_mvd_ref_id;
931*c83a76b0SSuyog Pawar                     /* encode L0 ref_idx  */
932*c83a76b0SSuyog Pawar                     WORD32 ref_idx_l0 = ps_pu->mv.i1_l0_ref_idx;
933*c83a76b0SSuyog Pawar 
934*c83a76b0SSuyog Pawar                     /*PIC INFO : Populate Ref Indx L0 Bits*/
935*c83a76b0SSuyog Pawar                     u4_bits_estimated_prev_mvd_ref_id = ps_cabac->u4_bits_estimated_q12;
936*c83a76b0SSuyog Pawar                     ret |= ihevce_cabac_encode_refidx(ps_cabac, ref_idx_l0, ref_l0_active);
937*c83a76b0SSuyog Pawar 
938*c83a76b0SSuyog Pawar                     if(ps_cabac->e_cabac_op_mode == CABAC_MODE_ENCODE_BITS)
939*c83a76b0SSuyog Pawar                     {
940*c83a76b0SSuyog Pawar                         // clang-format off
941*c83a76b0SSuyog Pawar                         ps_entropy_ctxt->ps_pic_level_info->u8_bits_estimated_ref_id +=
942*c83a76b0SSuyog Pawar                             (ps_cabac->u4_bits_estimated_q12 -
943*c83a76b0SSuyog Pawar                                 u4_bits_estimated_prev_mvd_ref_id);
944*c83a76b0SSuyog Pawar                         // clang-format on
945*c83a76b0SSuyog Pawar                     }
946*c83a76b0SSuyog Pawar                     /* Encode the mvd for L0 */
947*c83a76b0SSuyog Pawar                     /*PIC INFO : Populate MVD Bits*/
948*c83a76b0SSuyog Pawar                     u4_bits_estimated_prev_mvd_ref_id = ps_cabac->u4_bits_estimated_q12;
949*c83a76b0SSuyog Pawar 
950*c83a76b0SSuyog Pawar                     ret |= ihevce_cabac_encode_mvd(ps_cabac, &ps_pu->mv.s_l0_mv);
951*c83a76b0SSuyog Pawar 
952*c83a76b0SSuyog Pawar                     if(ps_cabac->e_cabac_op_mode == CABAC_MODE_ENCODE_BITS)
953*c83a76b0SSuyog Pawar                     {  // clang-format off
954*c83a76b0SSuyog Pawar                         ps_entropy_ctxt->ps_pic_level_info->u8_bits_estimated_mvd +=
955*c83a76b0SSuyog Pawar                             (ps_cabac->u4_bits_estimated_q12 -
956*c83a76b0SSuyog Pawar                                 u4_bits_estimated_prev_mvd_ref_id);
957*c83a76b0SSuyog Pawar                         // clang-format on
958*c83a76b0SSuyog Pawar                     }
959*c83a76b0SSuyog Pawar 
960*c83a76b0SSuyog Pawar                     /* Encode the mvp_l0_flag */
961*c83a76b0SSuyog Pawar                     ctxt_inc = IHEVC_CAB_MVP_L0L1;
962*c83a76b0SSuyog Pawar                     ret |= ihevce_cabac_encode_bin(ps_cabac, ps_pu->b1_l0_mvp_idx, ctxt_inc);
963*c83a76b0SSuyog Pawar 
964*c83a76b0SSuyog Pawar                     AEV_TRACE("mvp_l0/l1_flag", ps_pu->b1_l0_mvp_idx, ps_cabac->u4_range);
965*c83a76b0SSuyog Pawar                 }
966*c83a76b0SSuyog Pawar 
967*c83a76b0SSuyog Pawar                 /* Encode ref idx and MVD for L1  (PRED_L1 or PRED_BI) */
968*c83a76b0SSuyog Pawar                 if(inter_pred_idc != PRED_L0)
969*c83a76b0SSuyog Pawar                 {
970*c83a76b0SSuyog Pawar                     /* encode L1 ref_idx  */
971*c83a76b0SSuyog Pawar                     WORD32 ref_idx_l1 = ps_pu->mv.i1_l1_ref_idx;
972*c83a76b0SSuyog Pawar 
973*c83a76b0SSuyog Pawar                     UWORD32 u4_bits_estimated_prev_mvd_ref_id;
974*c83a76b0SSuyog Pawar                     /*PIC INFO : Populate Ref Indx L1 Bits*/
975*c83a76b0SSuyog Pawar                     u4_bits_estimated_prev_mvd_ref_id = ps_cabac->u4_bits_estimated_q12;
976*c83a76b0SSuyog Pawar 
977*c83a76b0SSuyog Pawar                     ret |= ihevce_cabac_encode_refidx(ps_cabac, ref_idx_l1, ref_l1_active);
978*c83a76b0SSuyog Pawar 
979*c83a76b0SSuyog Pawar                     if(ps_cabac->e_cabac_op_mode == CABAC_MODE_ENCODE_BITS)
980*c83a76b0SSuyog Pawar                     {  // clang-format off
981*c83a76b0SSuyog Pawar                         ps_entropy_ctxt->ps_pic_level_info->u8_bits_estimated_ref_id +=
982*c83a76b0SSuyog Pawar                             (ps_cabac->u4_bits_estimated_q12 -
983*c83a76b0SSuyog Pawar                                 u4_bits_estimated_prev_mvd_ref_id);
984*c83a76b0SSuyog Pawar                     }  // clang-format on
985*c83a76b0SSuyog Pawar 
986*c83a76b0SSuyog Pawar                     /* Check for zero mvd in case of bi_pred */
987*c83a76b0SSuyog Pawar                     if(ps_slice_hdr->i1_mvd_l1_zero_flag && inter_pred_idc == PRED_BI)
988*c83a76b0SSuyog Pawar                     {
989*c83a76b0SSuyog Pawar                         ASSERT(ps_pu->mv.s_l1_mv.i2_mvx == 0);
990*c83a76b0SSuyog Pawar                         ASSERT(ps_pu->mv.s_l1_mv.i2_mvy == 0);
991*c83a76b0SSuyog Pawar                     }
992*c83a76b0SSuyog Pawar                     else
993*c83a76b0SSuyog Pawar                     {
994*c83a76b0SSuyog Pawar                         /* Encode the mvd for L1 */
995*c83a76b0SSuyog Pawar                         /*PIC INFO : Populate MVD Bits*/
996*c83a76b0SSuyog Pawar                         u4_bits_estimated_prev_mvd_ref_id = ps_cabac->u4_bits_estimated_q12;
997*c83a76b0SSuyog Pawar 
998*c83a76b0SSuyog Pawar                         /* Encode the mvd for L1 */
999*c83a76b0SSuyog Pawar                         ret |= ihevce_cabac_encode_mvd(ps_cabac, &ps_pu->mv.s_l1_mv);
1000*c83a76b0SSuyog Pawar 
1001*c83a76b0SSuyog Pawar                         if(ps_cabac->e_cabac_op_mode == CABAC_MODE_ENCODE_BITS)
1002*c83a76b0SSuyog Pawar                         {
1003*c83a76b0SSuyog Pawar                             ps_entropy_ctxt->ps_pic_level_info->u8_bits_estimated_mvd +=
1004*c83a76b0SSuyog Pawar                                 (ps_cabac->u4_bits_estimated_q12 -
1005*c83a76b0SSuyog Pawar                                  u4_bits_estimated_prev_mvd_ref_id);
1006*c83a76b0SSuyog Pawar                         }
1007*c83a76b0SSuyog Pawar                     }
1008*c83a76b0SSuyog Pawar 
1009*c83a76b0SSuyog Pawar                     /* Encode the mvp_l1_flag */
1010*c83a76b0SSuyog Pawar                     ctxt_inc = IHEVC_CAB_MVP_L0L1;
1011*c83a76b0SSuyog Pawar                     ret |= ihevce_cabac_encode_bin(ps_cabac, ps_pu->b1_l1_mvp_idx, ctxt_inc);
1012*c83a76b0SSuyog Pawar 
1013*c83a76b0SSuyog Pawar                     AEV_TRACE("mvp_l0/l1_flag", ps_pu->b1_l1_mvp_idx, ps_cabac->u4_range);
1014*c83a76b0SSuyog Pawar                 }
1015*c83a76b0SSuyog Pawar             }
1016*c83a76b0SSuyog Pawar         }
1017*c83a76b0SSuyog Pawar     }
1018*c83a76b0SSuyog Pawar 
1019*c83a76b0SSuyog Pawar     return ret;
1020*c83a76b0SSuyog Pawar }
1021*c83a76b0SSuyog Pawar 
1022*c83a76b0SSuyog Pawar /**
1023*c83a76b0SSuyog Pawar ******************************************************************************
1024*c83a76b0SSuyog Pawar *
1025*c83a76b0SSuyog Pawar *  @brief Entropy encoding of coding unit (Coding Unit syntax)
1026*c83a76b0SSuyog Pawar *
1027*c83a76b0SSuyog Pawar *  @par   Description
1028*c83a76b0SSuyog Pawar *  Entropy encode of  coding unit (Coding Unit syntax) as per section:7.3.9.1
1029*c83a76b0SSuyog Pawar *  General Coding unit syntax
1030*c83a76b0SSuyog Pawar *
1031*c83a76b0SSuyog Pawar *  @param[inout]   ps_entropy_ctxt
1032*c83a76b0SSuyog Pawar *  pointer to entropy context (handle)
1033*c83a76b0SSuyog Pawar *
1034*c83a76b0SSuyog Pawar *  @param[in]   ps_enc_cu
1035*c83a76b0SSuyog Pawar *  pointer to current cu whose entropy encode is done
1036*c83a76b0SSuyog Pawar *
1037*c83a76b0SSuyog Pawar *  @param[in]   cu_depth
1038*c83a76b0SSuyog Pawar *  depth of the the current cu in coding tree
1039*c83a76b0SSuyog Pawar *
1040*c83a76b0SSuyog Pawar *  @param[in]   top_avail
1041*c83a76b0SSuyog Pawar *  top availabilty flag for current cu (boolean)
1042*c83a76b0SSuyog Pawar *
1043*c83a76b0SSuyog Pawar *  @param[in]   left_avail
1044*c83a76b0SSuyog Pawar *  left availabilty flag for current cu (boolean)
1045*c83a76b0SSuyog Pawar *
1046*c83a76b0SSuyog Pawar *  @return      success or failure error code
1047*c83a76b0SSuyog Pawar *
1048*c83a76b0SSuyog Pawar ******************************************************************************
1049*c83a76b0SSuyog Pawar */
ihevce_cabac_encode_coding_unit(entropy_context_t * ps_entropy_ctxt,cu_enc_loop_out_t * ps_enc_cu,WORD32 cu_depth,WORD32 top_avail,WORD32 left_avail)1050*c83a76b0SSuyog Pawar WORD32 ihevce_cabac_encode_coding_unit(
1051*c83a76b0SSuyog Pawar     entropy_context_t *ps_entropy_ctxt,
1052*c83a76b0SSuyog Pawar     cu_enc_loop_out_t *ps_enc_cu,
1053*c83a76b0SSuyog Pawar     WORD32 cu_depth,
1054*c83a76b0SSuyog Pawar     WORD32 top_avail,
1055*c83a76b0SSuyog Pawar     WORD32 left_avail)
1056*c83a76b0SSuyog Pawar {
1057*c83a76b0SSuyog Pawar     WORD32 ret = IHEVCE_SUCCESS;
1058*c83a76b0SSuyog Pawar     sps_t *ps_sps = ps_entropy_ctxt->ps_sps;
1059*c83a76b0SSuyog Pawar     pps_t *ps_pps = ps_entropy_ctxt->ps_pps;
1060*c83a76b0SSuyog Pawar     slice_header_t *ps_slice_hdr = ps_entropy_ctxt->ps_slice_hdr;
1061*c83a76b0SSuyog Pawar 
1062*c83a76b0SSuyog Pawar     WORD32 skip_flag = 0;
1063*c83a76b0SSuyog Pawar     WORD32 no_res_flag = 0;
1064*c83a76b0SSuyog Pawar 
1065*c83a76b0SSuyog Pawar     /* CU top left co-ordinates w.r.t ctb */
1066*c83a76b0SSuyog Pawar     WORD32 cu_x0 = ps_enc_cu->b3_cu_pos_x << 3;
1067*c83a76b0SSuyog Pawar     WORD32 cu_y0 = ps_enc_cu->b3_cu_pos_y << 3;
1068*c83a76b0SSuyog Pawar 
1069*c83a76b0SSuyog Pawar     /* CU size in pels */
1070*c83a76b0SSuyog Pawar     WORD32 cu_size = ps_enc_cu->b4_cu_size << 3;
1071*c83a76b0SSuyog Pawar     WORD32 log2_cb_size;
1072*c83a76b0SSuyog Pawar 
1073*c83a76b0SSuyog Pawar     cab_ctxt_t *ps_cabac = &ps_entropy_ctxt->s_cabac_ctxt;
1074*c83a76b0SSuyog Pawar 
1075*c83a76b0SSuyog Pawar     UWORD32 u4_header_bits_temp = ps_cabac->u4_bits_estimated_q12;
1076*c83a76b0SSuyog Pawar 
1077*c83a76b0SSuyog Pawar     (void)cu_depth;
1078*c83a76b0SSuyog Pawar     (void)top_avail;
1079*c83a76b0SSuyog Pawar     (void)left_avail;
1080*c83a76b0SSuyog Pawar     /* Sanity checks */
1081*c83a76b0SSuyog Pawar     ASSERT((cu_x0 + cu_size) <= (1 << ps_entropy_ctxt->i1_log2_ctb_size));
1082*c83a76b0SSuyog Pawar     ASSERT((cu_y0 + cu_size) <= (1 << ps_entropy_ctxt->i1_log2_ctb_size));
1083*c83a76b0SSuyog Pawar 
1084*c83a76b0SSuyog Pawar     /* code tq bypass flag */
1085*c83a76b0SSuyog Pawar     ASSERT(ps_pps->i1_transquant_bypass_enable_flag == 0);
1086*c83a76b0SSuyog Pawar 
1087*c83a76b0SSuyog Pawar     /* log2_cb_size based on cu size */
1088*c83a76b0SSuyog Pawar     GETRANGE(log2_cb_size, cu_size);
1089*c83a76b0SSuyog Pawar     log2_cb_size -= 1;
1090*c83a76b0SSuyog Pawar 
1091*c83a76b0SSuyog Pawar     if(ps_pps->i1_transquant_bypass_enable_flag)
1092*c83a76b0SSuyog Pawar     {
1093*c83a76b0SSuyog Pawar         ihevce_cabac_encode_bin(
1094*c83a76b0SSuyog Pawar             ps_cabac, ps_enc_cu->b1_tq_bypass_flag, IHEVC_CAB_CU_TQ_BYPASS_FLAG);
1095*c83a76b0SSuyog Pawar 
1096*c83a76b0SSuyog Pawar         AEV_TRACE("cu_transquant_bypass_flag", ps_enc_cu->b1_tq_bypass_flag, ps_cabac->u4_range);
1097*c83a76b0SSuyog Pawar     }
1098*c83a76b0SSuyog Pawar     /* code the skip flag for inter slices */
1099*c83a76b0SSuyog Pawar     if(ps_slice_hdr->i1_slice_type != ISLICE)
1100*c83a76b0SSuyog Pawar     {
1101*c83a76b0SSuyog Pawar         skip_flag = ps_enc_cu->b1_skip_flag;
1102*c83a76b0SSuyog Pawar 
1103*c83a76b0SSuyog Pawar         ret |= ihevce_cabac_encode_skip_flag(ps_entropy_ctxt, ps_enc_cu, top_avail, left_avail);
1104*c83a76b0SSuyog Pawar     }
1105*c83a76b0SSuyog Pawar     /*PIC_INFO : Total CU in frame based on cu size */
1106*c83a76b0SSuyog Pawar     if(ps_cabac->e_cabac_op_mode == CABAC_MODE_ENCODE_BITS)
1107*c83a76b0SSuyog Pawar     {
1108*c83a76b0SSuyog Pawar         // clang-format off
1109*c83a76b0SSuyog Pawar         if(cu_size == 64)
1110*c83a76b0SSuyog Pawar             ps_entropy_ctxt->ps_pic_level_info->i8_total_cu_based_on_size[3]++;
1111*c83a76b0SSuyog Pawar         else
1112*c83a76b0SSuyog Pawar             ps_entropy_ctxt->ps_pic_level_info->i8_total_cu_based_on_size[cu_size >> 4]++;
1113*c83a76b0SSuyog Pawar         // clang-format on
1114*c83a76b0SSuyog Pawar     }
1115*c83a76b0SSuyog Pawar     if(skip_flag)
1116*c83a76b0SSuyog Pawar     {
1117*c83a76b0SSuyog Pawar         /* encode merge idx for the skip cu */
1118*c83a76b0SSuyog Pawar         ret |= ihevce_cabac_encode_inter_pu(ps_entropy_ctxt, ps_enc_cu, cu_depth);
1119*c83a76b0SSuyog Pawar 
1120*c83a76b0SSuyog Pawar         if(ps_cabac->e_cabac_op_mode == CABAC_MODE_ENCODE_BITS)
1121*c83a76b0SSuyog Pawar         {
1122*c83a76b0SSuyog Pawar             /*PIC INFO: Populated non-coded TUs in CU*/
1123*c83a76b0SSuyog Pawar             ps_entropy_ctxt->ps_pic_level_info->i8_total_non_coded_tu +=
1124*c83a76b0SSuyog Pawar                 ps_enc_cu->u2_num_tus_in_cu;
1125*c83a76b0SSuyog Pawar             // clang-format off
1126*c83a76b0SSuyog Pawar             if(cu_size == 64)
1127*c83a76b0SSuyog Pawar                 ps_entropy_ctxt->ps_pic_level_info->i8_total_tu_based_on_size[3] +=
1128*c83a76b0SSuyog Pawar                     ps_enc_cu->u2_num_tus_in_cu;
1129*c83a76b0SSuyog Pawar             else if(cu_size == 32)
1130*c83a76b0SSuyog Pawar                 ps_entropy_ctxt->ps_pic_level_info->i8_total_tu_based_on_size[3] +=
1131*c83a76b0SSuyog Pawar                     ps_enc_cu->u2_num_tus_in_cu;
1132*c83a76b0SSuyog Pawar             else
1133*c83a76b0SSuyog Pawar                 ps_entropy_ctxt->ps_pic_level_info->i8_total_tu_based_on_size[cu_size >> 3] +=
1134*c83a76b0SSuyog Pawar                     ps_enc_cu->u2_num_tus_in_cu;
1135*c83a76b0SSuyog Pawar             // clang-format on
1136*c83a76b0SSuyog Pawar 
1137*c83a76b0SSuyog Pawar             /*PIC INFO: Populate cu header bits*/
1138*c83a76b0SSuyog Pawar             ps_entropy_ctxt->ps_pic_level_info->u8_bits_estimated_cu_hdr_bits +=
1139*c83a76b0SSuyog Pawar                 (ps_cabac->u4_bits_estimated_q12 - u4_header_bits_temp);
1140*c83a76b0SSuyog Pawar         }
1141*c83a76b0SSuyog Pawar     }
1142*c83a76b0SSuyog Pawar     else
1143*c83a76b0SSuyog Pawar     {
1144*c83a76b0SSuyog Pawar         WORD32 pred_mode = PRED_MODE_INTRA;
1145*c83a76b0SSuyog Pawar         WORD32 part_mode = ps_enc_cu->b3_part_mode;
1146*c83a76b0SSuyog Pawar         WORD32 pcm_flag = ps_enc_cu->b1_pcm_flag;
1147*c83a76b0SSuyog Pawar         WORD32 is_mincu;
1148*c83a76b0SSuyog Pawar         WORD32 is_intra;
1149*c83a76b0SSuyog Pawar 
1150*c83a76b0SSuyog Pawar         is_mincu = (cu_size == (1 << ps_sps->i1_log2_min_coding_block_size));
1151*c83a76b0SSuyog Pawar         /* encode pred mode flag for inter slice */
1152*c83a76b0SSuyog Pawar         if(ps_slice_hdr->i1_slice_type != ISLICE)
1153*c83a76b0SSuyog Pawar         {
1154*c83a76b0SSuyog Pawar             pred_mode = ps_enc_cu->b1_pred_mode_flag;
1155*c83a76b0SSuyog Pawar 
1156*c83a76b0SSuyog Pawar             ret |= ihevce_cabac_encode_bin(ps_cabac, pred_mode, IHEVC_CAB_PRED_MODE);
1157*c83a76b0SSuyog Pawar 
1158*c83a76b0SSuyog Pawar             AEV_TRACE("pred_mode_flag", pred_mode, ps_cabac->u4_range);
1159*c83a76b0SSuyog Pawar         }
1160*c83a76b0SSuyog Pawar         is_intra = (PRED_MODE_INTRA == pred_mode);
1161*c83a76b0SSuyog Pawar 
1162*c83a76b0SSuyog Pawar         /* encode partition mode for inter pred or smallest intra pred cu */
1163*c83a76b0SSuyog Pawar         if((!is_intra) || is_mincu)
1164*c83a76b0SSuyog Pawar         {
1165*c83a76b0SSuyog Pawar             WORD32 amp_enabled = ps_sps->i1_amp_enabled_flag;
1166*c83a76b0SSuyog Pawar             WORD32 cusize_8 = (cu_size == 8);
1167*c83a76b0SSuyog Pawar 
1168*c83a76b0SSuyog Pawar             ret |= ihevce_cabac_encode_part_mode(
1169*c83a76b0SSuyog Pawar                 ps_cabac, is_intra, is_mincu, amp_enabled, cusize_8, part_mode);
1170*c83a76b0SSuyog Pawar         }
1171*c83a76b0SSuyog Pawar         else
1172*c83a76b0SSuyog Pawar         {
1173*c83a76b0SSuyog Pawar             ASSERT(part_mode == SIZE_2Nx2N);
1174*c83a76b0SSuyog Pawar         }
1175*c83a76b0SSuyog Pawar 
1176*c83a76b0SSuyog Pawar         /* encode intra / inter pu modes of the current CU */
1177*c83a76b0SSuyog Pawar         if(is_intra)
1178*c83a76b0SSuyog Pawar         {
1179*c83a76b0SSuyog Pawar             /* NOTE: I_PCM not supported in encoder */
1180*c83a76b0SSuyog Pawar             ASSERT(0 == pcm_flag);
1181*c83a76b0SSuyog Pawar             ASSERT(0 == ps_sps->i1_pcm_enabled_flag);
1182*c83a76b0SSuyog Pawar 
1183*c83a76b0SSuyog Pawar             ret |= ihevce_cabac_encode_intra_pu(ps_entropy_ctxt, part_mode, ps_enc_cu);
1184*c83a76b0SSuyog Pawar         }
1185*c83a76b0SSuyog Pawar         else
1186*c83a76b0SSuyog Pawar         {
1187*c83a76b0SSuyog Pawar             ret |= ihevce_cabac_encode_inter_pu(ps_entropy_ctxt, ps_enc_cu, cu_depth);
1188*c83a76b0SSuyog Pawar         }
1189*c83a76b0SSuyog Pawar         /* encode no residue syntax flag and transform tree conditionally */
1190*c83a76b0SSuyog Pawar         if(!pcm_flag)
1191*c83a76b0SSuyog Pawar         {
1192*c83a76b0SSuyog Pawar             pu_t *ps_pu = &ps_enc_cu->ps_pu[0];
1193*c83a76b0SSuyog Pawar             WORD32 merge_cu;
1194*c83a76b0SSuyog Pawar             /* Encode residue syntax flag for inter cus not merged as 2Nx2N */
1195*c83a76b0SSuyog Pawar             if(!is_intra)
1196*c83a76b0SSuyog Pawar                 merge_cu = (part_mode == PART_2Nx2N) && ps_pu->b1_merge_flag;
1197*c83a76b0SSuyog Pawar 
1198*c83a76b0SSuyog Pawar             if(!is_intra && !merge_cu)
1199*c83a76b0SSuyog Pawar             {
1200*c83a76b0SSuyog Pawar                 no_res_flag = ps_enc_cu->b1_no_residual_syntax_flag;
1201*c83a76b0SSuyog Pawar 
1202*c83a76b0SSuyog Pawar #if 1 /* HACK FOR COMPLIANCE WITH HM REFERENCE DECODER */
1203*c83a76b0SSuyog Pawar                 /*********************************************************/
1204*c83a76b0SSuyog Pawar                 /* currently the HM decoder expects qtroot cbf instead of */
1205*c83a76b0SSuyog Pawar                 /* no_residue_flag which has opposite meaning             */
1206*c83a76b0SSuyog Pawar                 /* This will be fixed once the software / spec is fixed   */
1207*c83a76b0SSuyog Pawar                 /*********************************************************/
1208*c83a76b0SSuyog Pawar                 ret |= ihevce_cabac_encode_bin(ps_cabac, !no_res_flag, IHEVC_CAB_NORES_IDX);
1209*c83a76b0SSuyog Pawar 
1210*c83a76b0SSuyog Pawar                 AEV_TRACE("no_residual_syntax_flag (HACKY)", !no_res_flag, ps_cabac->u4_range);
1211*c83a76b0SSuyog Pawar #else
1212*c83a76b0SSuyog Pawar                 ret |= ihevce_cabac_encode_bin(ps_cabac, no_res_flag, IHEVC_CAB_NORES_IDX);
1213*c83a76b0SSuyog Pawar 
1214*c83a76b0SSuyog Pawar                 AEV_TRACE("no_residual_syntax_flag", no_res_flag, ps_cabac->u4_range);
1215*c83a76b0SSuyog Pawar #endif
1216*c83a76b0SSuyog Pawar             }
1217*c83a76b0SSuyog Pawar             /*initialize header bits*/
1218*c83a76b0SSuyog Pawar             ps_cabac->u4_header_bits_estimated_q12 = ps_cabac->u4_bits_estimated_q12;
1219*c83a76b0SSuyog Pawar 
1220*c83a76b0SSuyog Pawar             if(ps_cabac->e_cabac_op_mode == CABAC_MODE_ENCODE_BITS)
1221*c83a76b0SSuyog Pawar             {  // clang-format off
1222*c83a76b0SSuyog Pawar                 /*PIC INFO: Populate cu header bits*/
1223*c83a76b0SSuyog Pawar                 ps_entropy_ctxt->ps_pic_level_info->u8_bits_estimated_cu_hdr_bits +=
1224*c83a76b0SSuyog Pawar                     (ps_cabac->u4_bits_estimated_q12 - u4_header_bits_temp);
1225*c83a76b0SSuyog Pawar             }  // clang-format on
1226*c83a76b0SSuyog Pawar 
1227*c83a76b0SSuyog Pawar             ps_cabac->u4_true_tu_split_flag_q12 = 0;
1228*c83a76b0SSuyog Pawar             /* encode transform tree if no_residue_flag is 0 */
1229*c83a76b0SSuyog Pawar             if(!no_res_flag)
1230*c83a76b0SSuyog Pawar             {
1231*c83a76b0SSuyog Pawar                 ps_entropy_ctxt->i4_tu_idx = 0;
1232*c83a76b0SSuyog Pawar 
1233*c83a76b0SSuyog Pawar                 ret |= ihevce_encode_transform_tree(
1234*c83a76b0SSuyog Pawar                     ps_entropy_ctxt, cu_x0, cu_y0, log2_cb_size, 0, 0, ps_enc_cu);
1235*c83a76b0SSuyog Pawar             }
1236*c83a76b0SSuyog Pawar             else
1237*c83a76b0SSuyog Pawar             {
1238*c83a76b0SSuyog Pawar                 if(ps_cabac->e_cabac_op_mode == CABAC_MODE_ENCODE_BITS)
1239*c83a76b0SSuyog Pawar                 {
1240*c83a76b0SSuyog Pawar                     /*PIC INFO: Populated non-coded TUs in CU*/
1241*c83a76b0SSuyog Pawar                     ps_entropy_ctxt->ps_pic_level_info->i8_total_non_coded_tu +=
1242*c83a76b0SSuyog Pawar                         ps_enc_cu->u2_num_tus_in_cu;
1243*c83a76b0SSuyog Pawar                     // clang-format off
1244*c83a76b0SSuyog Pawar                     if(cu_size == 64)
1245*c83a76b0SSuyog Pawar                         ps_entropy_ctxt->ps_pic_level_info->i8_total_tu_based_on_size[3] +=
1246*c83a76b0SSuyog Pawar                             ps_enc_cu->u2_num_tus_in_cu;
1247*c83a76b0SSuyog Pawar                     else if(cu_size == 32)
1248*c83a76b0SSuyog Pawar                         ps_entropy_ctxt->ps_pic_level_info->i8_total_tu_based_on_size[3] +=
1249*c83a76b0SSuyog Pawar                             ps_enc_cu->u2_num_tus_in_cu;
1250*c83a76b0SSuyog Pawar                     else
1251*c83a76b0SSuyog Pawar                         ps_entropy_ctxt->ps_pic_level_info->i8_total_tu_based_on_size[cu_size >> 3] +=
1252*c83a76b0SSuyog Pawar                             ps_enc_cu->u2_num_tus_in_cu;
1253*c83a76b0SSuyog Pawar                     // clang-format on
1254*c83a76b0SSuyog Pawar                 }
1255*c83a76b0SSuyog Pawar             }
1256*c83a76b0SSuyog Pawar             ps_cabac->u4_cbf_bits_q12 = ps_cabac->u4_bits_estimated_q12 -
1257*c83a76b0SSuyog Pawar                                         ps_cabac->u4_header_bits_estimated_q12 -
1258*c83a76b0SSuyog Pawar                                         ps_cabac->u4_true_tu_split_flag_q12;
1259*c83a76b0SSuyog Pawar         }
1260*c83a76b0SSuyog Pawar     }
1261*c83a76b0SSuyog Pawar 
1262*c83a76b0SSuyog Pawar     /*duplicate the qp values for 8x8 CU array to maintain neighbour qp*/
1263*c83a76b0SSuyog Pawar     if(CABAC_MODE_ENCODE_BITS == ps_entropy_ctxt->s_cabac_ctxt.e_cabac_op_mode)
1264*c83a76b0SSuyog Pawar     {
1265*c83a76b0SSuyog Pawar         WORD32 i, j;
1266*c83a76b0SSuyog Pawar         WORD32 cur_cu_offset, cur_qp, qp_left, qp_top;
1267*c83a76b0SSuyog Pawar         WORD32 is_last_blk_in_qg;
1268*c83a76b0SSuyog Pawar         /* CU x co-ordinate w.r.t frame start           */
1269*c83a76b0SSuyog Pawar         WORD32 ctb_x0_frm = (ps_entropy_ctxt->i4_ctb_x << ps_entropy_ctxt->i1_log2_ctb_size);
1270*c83a76b0SSuyog Pawar 
1271*c83a76b0SSuyog Pawar         WORD32 cu_x0_frm = cu_x0 + ctb_x0_frm;
1272*c83a76b0SSuyog Pawar 
1273*c83a76b0SSuyog Pawar         /* CU y co-ordinate w.r.t frame start           */
1274*c83a76b0SSuyog Pawar         WORD32 ctb_y0_frm = (ps_entropy_ctxt->i4_ctb_y << ps_entropy_ctxt->i1_log2_ctb_size);
1275*c83a76b0SSuyog Pawar 
1276*c83a76b0SSuyog Pawar         WORD32 cu_y0_frm = cu_y0 + ctb_y0_frm;
1277*c83a76b0SSuyog Pawar 
1278*c83a76b0SSuyog Pawar         WORD32 pic_width = ps_sps->i2_pic_width_in_luma_samples;
1279*c83a76b0SSuyog Pawar         WORD32 pic_height = ps_sps->i2_pic_height_in_luma_samples;
1280*c83a76b0SSuyog Pawar 
1281*c83a76b0SSuyog Pawar         /* Added code for handling the QP neighbour population depending
1282*c83a76b0SSuyog Pawar             on the diff_cu_qp_delta_depth: Lokesh  */
1283*c83a76b0SSuyog Pawar         /* is_last_blk_in_qg variables is to find if the coding block is the last CU in the Quantization group
1284*c83a76b0SSuyog Pawar             3 - i1_diff_cu_qp_delta_depth is done as the cu_pos_x and cu_pos_y are in terms of 8x8 positions in the CTB: Lokesh*/
1285*c83a76b0SSuyog Pawar         WORD32 log2_min_cu_qp_delta_size =
1286*c83a76b0SSuyog Pawar             ps_entropy_ctxt->i1_log2_ctb_size - ps_entropy_ctxt->ps_pps->i1_diff_cu_qp_delta_depth;
1287*c83a76b0SSuyog Pawar         UWORD32 min_cu_qp_delta_size = 1 << log2_min_cu_qp_delta_size;
1288*c83a76b0SSuyog Pawar 
1289*c83a76b0SSuyog Pawar         WORD32 block_addr_align = 15 << (log2_min_cu_qp_delta_size - 3);
1290*c83a76b0SSuyog Pawar 
1291*c83a76b0SSuyog Pawar         ps_entropy_ctxt->i4_qg_pos_x = ps_enc_cu->b3_cu_pos_x & block_addr_align;
1292*c83a76b0SSuyog Pawar         ps_entropy_ctxt->i4_qg_pos_y = ps_enc_cu->b3_cu_pos_y & block_addr_align;
1293*c83a76b0SSuyog Pawar 
1294*c83a76b0SSuyog Pawar         /* Condition for detecting last cu in a qp group.                                       */
1295*c83a76b0SSuyog Pawar         /* Case 1: Current cu position + size exceed or meets the next qp group start location  */
1296*c83a76b0SSuyog Pawar         /* Case 2: Current cu position + size hits the incomplete ctb boundary in atleast one   */
1297*c83a76b0SSuyog Pawar         /*         direction and the qp grp limit in other direction                            */
1298*c83a76b0SSuyog Pawar 
1299*c83a76b0SSuyog Pawar         /* case 1 */
1300*c83a76b0SSuyog Pawar         is_last_blk_in_qg =
1301*c83a76b0SSuyog Pawar             ((cu_x0 + cu_size) >=
1302*c83a76b0SSuyog Pawar                  ((ps_entropy_ctxt->i4_qg_pos_x << 3) + (WORD32)min_cu_qp_delta_size) &&
1303*c83a76b0SSuyog Pawar              (cu_y0 + cu_size) >=
1304*c83a76b0SSuyog Pawar                  ((ps_entropy_ctxt->i4_qg_pos_y << 3) + (WORD32)min_cu_qp_delta_size));
1305*c83a76b0SSuyog Pawar 
1306*c83a76b0SSuyog Pawar         /* case 2 : x direction incomplete ctb */
1307*c83a76b0SSuyog Pawar         if((cu_x0_frm + cu_size) >= pic_width)
1308*c83a76b0SSuyog Pawar         {
1309*c83a76b0SSuyog Pawar             is_last_blk_in_qg |=
1310*c83a76b0SSuyog Pawar                 ((cu_y0 + cu_size) >=
1311*c83a76b0SSuyog Pawar                  ((ps_entropy_ctxt->i4_qg_pos_y << 3) + (WORD32)min_cu_qp_delta_size));
1312*c83a76b0SSuyog Pawar         }
1313*c83a76b0SSuyog Pawar 
1314*c83a76b0SSuyog Pawar         /* case 2 : y direction incomplete ctb */
1315*c83a76b0SSuyog Pawar         if((cu_y0_frm + cu_size) >= pic_height)
1316*c83a76b0SSuyog Pawar         {
1317*c83a76b0SSuyog Pawar             is_last_blk_in_qg |=
1318*c83a76b0SSuyog Pawar                 ((cu_x0 + cu_size) >=
1319*c83a76b0SSuyog Pawar                  ((ps_entropy_ctxt->i4_qg_pos_x << 3) + (WORD32)min_cu_qp_delta_size));
1320*c83a76b0SSuyog Pawar         }
1321*c83a76b0SSuyog Pawar 
1322*c83a76b0SSuyog Pawar         cur_cu_offset = ps_enc_cu->b3_cu_pos_x + (ps_enc_cu->b3_cu_pos_y * 8);
1323*c83a76b0SSuyog Pawar 
1324*c83a76b0SSuyog Pawar         if((ps_entropy_ctxt->i4_is_cu_cbf_zero || no_res_flag || skip_flag) &&
1325*c83a76b0SSuyog Pawar            ((ps_entropy_ctxt->i1_encode_qp_delta)))
1326*c83a76b0SSuyog Pawar         {
1327*c83a76b0SSuyog Pawar             {  // clang-format off
1328*c83a76b0SSuyog Pawar                 /*it should remember average of qp_top and qp_left*/
1329*c83a76b0SSuyog Pawar                 if(ps_entropy_ctxt->i4_qg_pos_x > 0)
1330*c83a76b0SSuyog Pawar                 {
1331*c83a76b0SSuyog Pawar                     qp_left =
1332*c83a76b0SSuyog Pawar                         ps_entropy_ctxt->ai4_8x8_cu_qp[(ps_entropy_ctxt->i4_qg_pos_x - 1) +
1333*c83a76b0SSuyog Pawar                                             (ps_entropy_ctxt->i4_qg_pos_y * 8)];
1334*c83a76b0SSuyog Pawar                 }
1335*c83a76b0SSuyog Pawar                 if(ps_entropy_ctxt->i4_qg_pos_y > 0)
1336*c83a76b0SSuyog Pawar                 {
1337*c83a76b0SSuyog Pawar                     qp_top =
1338*c83a76b0SSuyog Pawar                         ps_entropy_ctxt->ai4_8x8_cu_qp[ps_entropy_ctxt->i4_qg_pos_x +
1339*c83a76b0SSuyog Pawar                                             (ps_entropy_ctxt->i4_qg_pos_y - 1) *
1340*c83a76b0SSuyog Pawar                                                 8];
1341*c83a76b0SSuyog Pawar                 }  // clang-format on
1342*c83a76b0SSuyog Pawar                 if(ps_entropy_ctxt->i4_qg_pos_x == 0)
1343*c83a76b0SSuyog Pawar                 {
1344*c83a76b0SSuyog Pawar                     /*previous coded Qp*/
1345*c83a76b0SSuyog Pawar                     qp_left = ps_entropy_ctxt->i1_cur_qp;
1346*c83a76b0SSuyog Pawar                 }
1347*c83a76b0SSuyog Pawar                 if(ps_entropy_ctxt->i4_qg_pos_y == 0)
1348*c83a76b0SSuyog Pawar                 {
1349*c83a76b0SSuyog Pawar                     /*previous coded Qp*/
1350*c83a76b0SSuyog Pawar                     qp_top = ps_entropy_ctxt->i1_cur_qp;
1351*c83a76b0SSuyog Pawar                 }
1352*c83a76b0SSuyog Pawar                 cur_qp = (qp_top + qp_left + 1) >> 1;
1353*c83a76b0SSuyog Pawar                 /*In case of skip or zero cbf CU the previous qp used has to be updated*/
1354*c83a76b0SSuyog Pawar                 if(is_last_blk_in_qg)
1355*c83a76b0SSuyog Pawar                     ps_entropy_ctxt->i1_cur_qp = cur_qp;
1356*c83a76b0SSuyog Pawar             }
1357*c83a76b0SSuyog Pawar         }
1358*c83a76b0SSuyog Pawar         else
1359*c83a76b0SSuyog Pawar         {
1360*c83a76b0SSuyog Pawar             cur_qp = (WORD32)ps_enc_cu->ps_enc_tu->s_tu.b7_qp;
1361*c83a76b0SSuyog Pawar         }
1362*c83a76b0SSuyog Pawar 
1363*c83a76b0SSuyog Pawar         if(ps_cabac->e_cabac_op_mode == CABAC_MODE_ENCODE_BITS)
1364*c83a76b0SSuyog Pawar         {
1365*c83a76b0SSuyog Pawar             WORD32 temp = 0;
1366*c83a76b0SSuyog Pawar             /*PIC_INFO: Accumalate average qp, min qp and max qp*/
1367*c83a76b0SSuyog Pawar             ps_entropy_ctxt->ps_pic_level_info->i8_total_qp += cur_qp;
1368*c83a76b0SSuyog Pawar             if(cu_size == 64)
1369*c83a76b0SSuyog Pawar                 temp = 6;
1370*c83a76b0SSuyog Pawar             else if(cu_size == 32)
1371*c83a76b0SSuyog Pawar                 temp = 4;
1372*c83a76b0SSuyog Pawar             else if(cu_size == 16)
1373*c83a76b0SSuyog Pawar                 temp = 2;
1374*c83a76b0SSuyog Pawar             else if(cu_size == 8)
1375*c83a76b0SSuyog Pawar                 temp = 0;
1376*c83a76b0SSuyog Pawar 
1377*c83a76b0SSuyog Pawar             ps_entropy_ctxt->ps_pic_level_info->i8_total_qp_min_cu += (cur_qp * (1 << temp));
1378*c83a76b0SSuyog Pawar             if(cur_qp < ps_entropy_ctxt->ps_pic_level_info->i4_min_qp)
1379*c83a76b0SSuyog Pawar                 ps_entropy_ctxt->ps_pic_level_info->i4_min_qp = cur_qp;
1380*c83a76b0SSuyog Pawar             if(cur_qp > ps_entropy_ctxt->ps_pic_level_info->i4_max_qp)
1381*c83a76b0SSuyog Pawar                 ps_entropy_ctxt->ps_pic_level_info->i4_max_qp = cur_qp;
1382*c83a76b0SSuyog Pawar         }
1383*c83a76b0SSuyog Pawar 
1384*c83a76b0SSuyog Pawar         for(i = 0; i < (WORD32)ps_enc_cu->b4_cu_size; i++)
1385*c83a76b0SSuyog Pawar         {
1386*c83a76b0SSuyog Pawar             for(j = 0; j < (WORD32)ps_enc_cu->b4_cu_size; j++)
1387*c83a76b0SSuyog Pawar             {
1388*c83a76b0SSuyog Pawar                 ps_entropy_ctxt->ai4_8x8_cu_qp[cur_cu_offset + (i * 8) + j] = cur_qp;
1389*c83a76b0SSuyog Pawar             }
1390*c83a76b0SSuyog Pawar         }
1391*c83a76b0SSuyog Pawar         ps_entropy_ctxt->i4_is_cu_cbf_zero = 1;
1392*c83a76b0SSuyog Pawar     }
1393*c83a76b0SSuyog Pawar 
1394*c83a76b0SSuyog Pawar     return ret;
1395*c83a76b0SSuyog Pawar }
1396*c83a76b0SSuyog Pawar 
1397*c83a76b0SSuyog Pawar /**
1398*c83a76b0SSuyog Pawar ******************************************************************************
1399*c83a76b0SSuyog Pawar *
1400*c83a76b0SSuyog Pawar *  @brief Entropy encoding of SAO related syntax elements as per sec 7.3.8.3
1401*c83a76b0SSuyog Pawar *
1402*c83a76b0SSuyog Pawar *  @par   Description
1403*c83a76b0SSuyog Pawar *  Encoding of sao related syntax elements at ctb level.
1404*c83a76b0SSuyog Pawar *
1405*c83a76b0SSuyog Pawar *  @param[inout]   ps_entropy_ctxt
1406*c83a76b0SSuyog Pawar *  pointer to entropy context (handle)
1407*c83a76b0SSuyog Pawar *
1408*c83a76b0SSuyog Pawar *  @param[in]   ps_ctb_enc_loop_out
1409*c83a76b0SSuyog Pawar *  pointer to ctb level output structure from enc loop
1410*c83a76b0SSuyog Pawar *
1411*c83a76b0SSuyog Pawar *  @return      success or failure error code
1412*c83a76b0SSuyog Pawar *
1413*c83a76b0SSuyog Pawar ******************************************************************************
1414*c83a76b0SSuyog Pawar */
ihevce_cabac_encode_sao(entropy_context_t * ps_entropy_ctxt,ctb_enc_loop_out_t * ps_ctb_enc_loop_out)1415*c83a76b0SSuyog Pawar WORD32 ihevce_cabac_encode_sao(
1416*c83a76b0SSuyog Pawar     entropy_context_t *ps_entropy_ctxt, ctb_enc_loop_out_t *ps_ctb_enc_loop_out)
1417*c83a76b0SSuyog Pawar {
1418*c83a76b0SSuyog Pawar     WORD32 error = IHEVCE_SUCCESS;
1419*c83a76b0SSuyog Pawar     sao_enc_t *ps_sao;
1420*c83a76b0SSuyog Pawar     nbr_avail_flags_t *ps_ctb_nbr_avail_flags;
1421*c83a76b0SSuyog Pawar     slice_header_t *ps_slice_hdr = ps_entropy_ctxt->ps_slice_hdr;
1422*c83a76b0SSuyog Pawar     cab_ctxt_t *ps_cabac = &ps_entropy_ctxt->s_cabac_ctxt;
1423*c83a76b0SSuyog Pawar 
1424*c83a76b0SSuyog Pawar     UWORD8 u1_left_avail, u1_top_avail;
1425*c83a76b0SSuyog Pawar 
1426*c83a76b0SSuyog Pawar     ps_ctb_nbr_avail_flags = &ps_ctb_enc_loop_out->s_ctb_nbr_avail_flags;
1427*c83a76b0SSuyog Pawar 
1428*c83a76b0SSuyog Pawar     ps_sao = &ps_ctb_enc_loop_out->s_sao;
1429*c83a76b0SSuyog Pawar 
1430*c83a76b0SSuyog Pawar     ASSERT(ps_sao->b1_sao_merge_left_flag < 2);
1431*c83a76b0SSuyog Pawar 
1432*c83a76b0SSuyog Pawar     u1_left_avail = ps_ctb_nbr_avail_flags->u1_left_avail;
1433*c83a76b0SSuyog Pawar     u1_top_avail = ps_ctb_nbr_avail_flags->u1_top_avail;
1434*c83a76b0SSuyog Pawar 
1435*c83a76b0SSuyog Pawar     if(u1_left_avail == 1)
1436*c83a76b0SSuyog Pawar     {
1437*c83a76b0SSuyog Pawar         /*Encode the sao_merge_left_flag as FL as per table 9-32*/
1438*c83a76b0SSuyog Pawar         error |=
1439*c83a76b0SSuyog Pawar             ihevce_cabac_encode_bin(ps_cabac, ps_sao->b1_sao_merge_left_flag, IHEVC_CAB_SAO_MERGE);
1440*c83a76b0SSuyog Pawar 
1441*c83a76b0SSuyog Pawar         AEV_TRACE("sao_merge_flag", ps_sao->b1_sao_merge_left_flag, ps_cabac->u4_range);
1442*c83a76b0SSuyog Pawar     }
1443*c83a76b0SSuyog Pawar 
1444*c83a76b0SSuyog Pawar     if((u1_top_avail == 1) && (!ps_sao->b1_sao_merge_left_flag))
1445*c83a76b0SSuyog Pawar     {
1446*c83a76b0SSuyog Pawar         /*Encode the sao_merge_up_flag as FL as per table 9-32*/
1447*c83a76b0SSuyog Pawar         error |=
1448*c83a76b0SSuyog Pawar             ihevce_cabac_encode_bin(ps_cabac, ps_sao->b1_sao_merge_up_flag, IHEVC_CAB_SAO_MERGE);
1449*c83a76b0SSuyog Pawar 
1450*c83a76b0SSuyog Pawar         AEV_TRACE("sao_merge_flag", ps_sao->b1_sao_merge_up_flag, ps_cabac->u4_range);
1451*c83a76b0SSuyog Pawar     }
1452*c83a76b0SSuyog Pawar 
1453*c83a76b0SSuyog Pawar     if((!ps_sao->b1_sao_merge_left_flag) && (!ps_sao->b1_sao_merge_up_flag))
1454*c83a76b0SSuyog Pawar     {
1455*c83a76b0SSuyog Pawar         WORD32 c_idx;
1456*c83a76b0SSuyog Pawar         WORD32 sao_type_idx = ps_sao->b3_y_type_idx;
1457*c83a76b0SSuyog Pawar 
1458*c83a76b0SSuyog Pawar         /*Run a loop for y,cb and cr to encode the type idx for luma and chroma*/
1459*c83a76b0SSuyog Pawar         for(c_idx = 0; c_idx < 3; c_idx++)
1460*c83a76b0SSuyog Pawar         {
1461*c83a76b0SSuyog Pawar             if((ps_slice_hdr->i1_slice_sao_luma_flag && c_idx == 0) ||
1462*c83a76b0SSuyog Pawar                (ps_slice_hdr->i1_slice_sao_chroma_flag && c_idx > 0))
1463*c83a76b0SSuyog Pawar             {
1464*c83a76b0SSuyog Pawar                 WORD32 ctxt_bin;
1465*c83a76b0SSuyog Pawar 
1466*c83a76b0SSuyog Pawar                 /**************************************************************************/
1467*c83a76b0SSuyog Pawar                 /* encode the sao_type_idx as per Table 9-33                              */
1468*c83a76b0SSuyog Pawar                 /* First bin is context model based prefix : 1 if sao_type_idx > 0 else 0 */
1469*c83a76b0SSuyog Pawar                 /* Second bin is coded as bypass bin if sao_type_ide > 0                  */
1470*c83a76b0SSuyog Pawar                 /**************************************************************************/
1471*c83a76b0SSuyog Pawar 
1472*c83a76b0SSuyog Pawar                 if(c_idx < 2)
1473*c83a76b0SSuyog Pawar                 {
1474*c83a76b0SSuyog Pawar                     WORD32 sao_type_idx_temp;
1475*c83a76b0SSuyog Pawar 
1476*c83a76b0SSuyog Pawar                     ASSERT(ps_sao->b3_cb_type_idx == ps_sao->b3_cr_type_idx);
1477*c83a76b0SSuyog Pawar 
1478*c83a76b0SSuyog Pawar                     sao_type_idx = c_idx ? ps_sao->b3_cb_type_idx : ps_sao->b3_y_type_idx;
1479*c83a76b0SSuyog Pawar 
1480*c83a76b0SSuyog Pawar                     ctxt_bin = sao_type_idx ? 1 : 0;
1481*c83a76b0SSuyog Pawar 
1482*c83a76b0SSuyog Pawar                     if(sao_type_idx > 1)
1483*c83a76b0SSuyog Pawar                     {
1484*c83a76b0SSuyog Pawar                         sao_type_idx_temp = 2;
1485*c83a76b0SSuyog Pawar                     }
1486*c83a76b0SSuyog Pawar                     else
1487*c83a76b0SSuyog Pawar                     {
1488*c83a76b0SSuyog Pawar                         sao_type_idx_temp = sao_type_idx;
1489*c83a76b0SSuyog Pawar                     }
1490*c83a76b0SSuyog Pawar 
1491*c83a76b0SSuyog Pawar                     ASSERT(sao_type_idx_temp < 3);
1492*c83a76b0SSuyog Pawar 
1493*c83a76b0SSuyog Pawar                     /*Encode the first bin as context bin as per table 9-37*/
1494*c83a76b0SSuyog Pawar                     error |= ihevce_cabac_encode_bin(ps_cabac, ctxt_bin, IHEVC_CAB_SAO_TYPE);
1495*c83a76b0SSuyog Pawar 
1496*c83a76b0SSuyog Pawar                     if(sao_type_idx_temp)
1497*c83a76b0SSuyog Pawar                     {
1498*c83a76b0SSuyog Pawar                         /*Binarisation for sao_type_idx is TR(truncated rice) process as per
1499*c83a76b0SSuyog Pawar                             * table 9-32 with cMax=2 and cRiceParam=0
1500*c83a76b0SSuyog Pawar                             */
1501*c83a76b0SSuyog Pawar 
1502*c83a76b0SSuyog Pawar                         /* Encode the second bin as bypass bin as per below table*/
1503*c83a76b0SSuyog Pawar                         /*
1504*c83a76b0SSuyog Pawar                             |Symbol | Prefix |Prefix length |Prefix bins|
1505*c83a76b0SSuyog Pawar                             |   0   |    0   |     1        |     0     |
1506*c83a76b0SSuyog Pawar                             |   1   |    1   |     2        |     10    |
1507*c83a76b0SSuyog Pawar                             |   2   |    2   |     2        |     11    |
1508*c83a76b0SSuyog Pawar 
1509*c83a76b0SSuyog Pawar                             Since cRiceParam=0, there is no suffix code
1510*c83a76b0SSuyog Pawar                             */
1511*c83a76b0SSuyog Pawar 
1512*c83a76b0SSuyog Pawar                         error |= ihevce_cabac_encode_bypass_bin(ps_cabac, sao_type_idx_temp - 1);
1513*c83a76b0SSuyog Pawar                     }
1514*c83a76b0SSuyog Pawar                     AEV_TRACE("sao_type_idx", sao_type_idx_temp, ps_cabac->u4_range);
1515*c83a76b0SSuyog Pawar                 }
1516*c83a76b0SSuyog Pawar 
1517*c83a76b0SSuyog Pawar                 if(sao_type_idx != 0)
1518*c83a76b0SSuyog Pawar                 {
1519*c83a76b0SSuyog Pawar                     WORD32 i;
1520*c83a76b0SSuyog Pawar                     UWORD8 u1_bit_depth = ps_entropy_ctxt->ps_sps->i1_bit_depth_luma_minus8 + 8;
1521*c83a76b0SSuyog Pawar                     WORD8 *sao_offset;
1522*c83a76b0SSuyog Pawar                     WORD32 sao_band_position;
1523*c83a76b0SSuyog Pawar                     WORD32 c_max = (1 << (MIN(u1_bit_depth, 10) - 5)) -
1524*c83a76b0SSuyog Pawar                                    1;  //( 1 << (MIN(BIT_DEPTH, 10) - 5)) - 1;
1525*c83a76b0SSuyog Pawar 
1526*c83a76b0SSuyog Pawar                     if(c_idx == 0)
1527*c83a76b0SSuyog Pawar                     {
1528*c83a76b0SSuyog Pawar                         //sao_offset[0] = ps_sao->b4_y_offset_1;
1529*c83a76b0SSuyog Pawar                         //sao_offset[1] = ps_sao->b4_y_offset_2;
1530*c83a76b0SSuyog Pawar                         //sao_offset[2] = ps_sao->b4_y_offset_3;
1531*c83a76b0SSuyog Pawar                         //sao_offset[3] = ps_sao->b4_y_offset_4;
1532*c83a76b0SSuyog Pawar                         sao_offset = &ps_sao->u1_y_offset[1];
1533*c83a76b0SSuyog Pawar                         sao_band_position = ps_sao->b5_y_band_pos;
1534*c83a76b0SSuyog Pawar                     }
1535*c83a76b0SSuyog Pawar                     else if(c_idx == 1)
1536*c83a76b0SSuyog Pawar                     {
1537*c83a76b0SSuyog Pawar                         //sao_offset[0] = ps_sao->b4_cb_offset_1;
1538*c83a76b0SSuyog Pawar                         //sao_offset[1] = ps_sao->b4_cb_offset_2;
1539*c83a76b0SSuyog Pawar                         //sao_offset[2] = ps_sao->b4_cb_offset_3;
1540*c83a76b0SSuyog Pawar                         //sao_offset[3] = ps_sao->b4_cb_offset_4;
1541*c83a76b0SSuyog Pawar                         sao_offset = &ps_sao->u1_cb_offset[1];
1542*c83a76b0SSuyog Pawar                         sao_band_position = ps_sao->b5_cb_band_pos;
1543*c83a76b0SSuyog Pawar                     }
1544*c83a76b0SSuyog Pawar                     else
1545*c83a76b0SSuyog Pawar                     {
1546*c83a76b0SSuyog Pawar                         //sao_offset[0] = ps_sao->b4_cr_offset_1;
1547*c83a76b0SSuyog Pawar                         //sao_offset[1] = ps_sao->b4_cr_offset_2;
1548*c83a76b0SSuyog Pawar                         //sao_offset[2] = ps_sao->b4_cr_offset_3;
1549*c83a76b0SSuyog Pawar                         //sao_offset[3] = ps_sao->b4_cr_offset_4;
1550*c83a76b0SSuyog Pawar                         sao_offset = &ps_sao->u1_cr_offset[1];
1551*c83a76b0SSuyog Pawar                         sao_band_position = ps_sao->b5_cr_band_pos;
1552*c83a76b0SSuyog Pawar                     }
1553*c83a76b0SSuyog Pawar 
1554*c83a76b0SSuyog Pawar                     for(i = 0; i < 4; i++)
1555*c83a76b0SSuyog Pawar                     {
1556*c83a76b0SSuyog Pawar                         /*Encode the sao offset value as tunary bypass*/
1557*c83a76b0SSuyog Pawar                         error |=
1558*c83a76b0SSuyog Pawar                             ihevce_cabac_encode_tunary_bypass(ps_cabac, abs(sao_offset[i]), c_max);
1559*c83a76b0SSuyog Pawar 
1560*c83a76b0SSuyog Pawar                         AEV_TRACE("sao_offset_abs", abs(sao_offset[i]), ps_cabac->u4_range);
1561*c83a76b0SSuyog Pawar                     }
1562*c83a76b0SSuyog Pawar 
1563*c83a76b0SSuyog Pawar                     /*Band offset case*/
1564*c83a76b0SSuyog Pawar                     if(sao_type_idx == 1)
1565*c83a76b0SSuyog Pawar                     {
1566*c83a76b0SSuyog Pawar                         for(i = 0; i < 4; i++)
1567*c83a76b0SSuyog Pawar                         {
1568*c83a76b0SSuyog Pawar                             if(sao_offset[i] != 0)
1569*c83a76b0SSuyog Pawar                             {
1570*c83a76b0SSuyog Pawar                                 /*Encode the sao offset sign as FL as per table 9-32*/
1571*c83a76b0SSuyog Pawar                                 error |= ihevce_cabac_encode_bypass_bin(
1572*c83a76b0SSuyog Pawar                                     ps_cabac,
1573*c83a76b0SSuyog Pawar                                     (abs(sao_offset[i]) + sao_offset[i] == 0));  //,
1574*c83a76b0SSuyog Pawar                                 //IHEVC_CAB_SAO_MERGE
1575*c83a76b0SSuyog Pawar                                 //);
1576*c83a76b0SSuyog Pawar 
1577*c83a76b0SSuyog Pawar                                 AEV_TRACE(
1578*c83a76b0SSuyog Pawar                                     "sao_offset_sign",
1579*c83a76b0SSuyog Pawar                                     (abs(sao_offset[i]) + sao_offset[i] == 0),
1580*c83a76b0SSuyog Pawar                                     ps_cabac->u4_range);
1581*c83a76b0SSuyog Pawar                             }
1582*c83a76b0SSuyog Pawar                         }
1583*c83a76b0SSuyog Pawar 
1584*c83a76b0SSuyog Pawar                         /*Encode the sao band position as FL as per table 9-32*/
1585*c83a76b0SSuyog Pawar                         error |= ihevce_cabac_encode_bypass_bins(ps_cabac, sao_band_position, 5);
1586*c83a76b0SSuyog Pawar                         AEV_TRACE("sao_band_position", sao_band_position, ps_cabac->u4_range);
1587*c83a76b0SSuyog Pawar                     }
1588*c83a76b0SSuyog Pawar                     else
1589*c83a76b0SSuyog Pawar                     {
1590*c83a76b0SSuyog Pawar                         /*Encode the sao edge offset class for luma and chroma as FL as per table 9-32*/
1591*c83a76b0SSuyog Pawar                         if(c_idx == 0)
1592*c83a76b0SSuyog Pawar                         {
1593*c83a76b0SSuyog Pawar                             error |= ihevce_cabac_encode_bypass_bins(
1594*c83a76b0SSuyog Pawar                                 ps_cabac, (ps_sao->b3_y_type_idx - 2), 2);
1595*c83a76b0SSuyog Pawar                             AEV_TRACE(
1596*c83a76b0SSuyog Pawar                                 "sao_eo_class", (ps_sao->b3_y_type_idx - 2), ps_cabac->u4_range);
1597*c83a76b0SSuyog Pawar                         }
1598*c83a76b0SSuyog Pawar 
1599*c83a76b0SSuyog Pawar                         if(c_idx == 1)
1600*c83a76b0SSuyog Pawar                         {
1601*c83a76b0SSuyog Pawar                             ASSERT(ps_sao->b3_cb_type_idx == ps_sao->b3_cr_type_idx);
1602*c83a76b0SSuyog Pawar                             error |= ihevce_cabac_encode_bypass_bins(
1603*c83a76b0SSuyog Pawar                                 ps_cabac, (ps_sao->b3_cb_type_idx - 2), 2);
1604*c83a76b0SSuyog Pawar                             AEV_TRACE(
1605*c83a76b0SSuyog Pawar                                 "sao_eo_class", (ps_sao->b3_cb_type_idx - 2), ps_cabac->u4_range);
1606*c83a76b0SSuyog Pawar                         }
1607*c83a76b0SSuyog Pawar                     }
1608*c83a76b0SSuyog Pawar                 }
1609*c83a76b0SSuyog Pawar             }
1610*c83a76b0SSuyog Pawar         }
1611*c83a76b0SSuyog Pawar     }
1612*c83a76b0SSuyog Pawar 
1613*c83a76b0SSuyog Pawar     return (error);
1614*c83a76b0SSuyog Pawar }
1615*c83a76b0SSuyog Pawar 
1616*c83a76b0SSuyog Pawar /**
1617*c83a76b0SSuyog Pawar ******************************************************************************
1618*c83a76b0SSuyog Pawar *
1619*c83a76b0SSuyog Pawar *  @brief Encodes a coding quad tree (QuadTree syntax) as per section 7.3.8
1620*c83a76b0SSuyog Pawar *
1621*c83a76b0SSuyog Pawar *  @par   Description
1622*c83a76b0SSuyog Pawar *  Entropy encode of coding quad tree based on cu split flags of ctb as per
1623*c83a76b0SSuyog Pawar *  section:7.3.8
1624*c83a76b0SSuyog Pawar *
1625*c83a76b0SSuyog Pawar *  @param[inout]   ps_entropy_ctxt
1626*c83a76b0SSuyog Pawar *  pointer to entropy context (handle)
1627*c83a76b0SSuyog Pawar *
1628*c83a76b0SSuyog Pawar *  @param[in]      x0_frm
1629*c83a76b0SSuyog Pawar *  x co-ordinate of current cu node of coding tree
1630*c83a76b0SSuyog Pawar *
1631*c83a76b0SSuyog Pawar *  @param[in]      y0_frm
1632*c83a76b0SSuyog Pawar *  y co-ordinate of current cu node of coding tree
1633*c83a76b0SSuyog Pawar *
1634*c83a76b0SSuyog Pawar *  @param[in]      log2_cb_size
1635*c83a76b0SSuyog Pawar *  current cu node block size
1636*c83a76b0SSuyog Pawar *
1637*c83a76b0SSuyog Pawar *  @param[in]      ct_depth
1638*c83a76b0SSuyog Pawar *  depth of current cu node w.r.t ctb
1639*c83a76b0SSuyog Pawar *
1640*c83a76b0SSuyog Pawar *  @param[in]      ps_ctb
1641*c83a76b0SSuyog Pawar *  pointer to current ctb structure
1642*c83a76b0SSuyog Pawar *
1643*c83a76b0SSuyog Pawar *  @return      success or failure error code
1644*c83a76b0SSuyog Pawar *
1645*c83a76b0SSuyog Pawar ******************************************************************************
1646*c83a76b0SSuyog Pawar */
ihevce_encode_coding_quadtree(entropy_context_t * ps_entropy_ctxt,WORD32 x0_frm,WORD32 y0_frm,WORD32 log2_cb_size,WORD32 ct_depth,ctb_enc_loop_out_t * ps_ctb,ihevce_tile_params_t * ps_tile_params)1647*c83a76b0SSuyog Pawar WORD32 ihevce_encode_coding_quadtree(
1648*c83a76b0SSuyog Pawar     entropy_context_t *ps_entropy_ctxt,
1649*c83a76b0SSuyog Pawar     WORD32 x0_frm,
1650*c83a76b0SSuyog Pawar     WORD32 y0_frm,
1651*c83a76b0SSuyog Pawar     WORD32 log2_cb_size,
1652*c83a76b0SSuyog Pawar     WORD32 ct_depth,
1653*c83a76b0SSuyog Pawar     ctb_enc_loop_out_t *ps_ctb,
1654*c83a76b0SSuyog Pawar     ihevce_tile_params_t *ps_tile_params)
1655*c83a76b0SSuyog Pawar {
1656*c83a76b0SSuyog Pawar     WORD32 ret = IHEVCE_SUCCESS;
1657*c83a76b0SSuyog Pawar     sps_t *ps_sps = ps_entropy_ctxt->ps_sps;
1658*c83a76b0SSuyog Pawar     pps_t *ps_pps = ps_entropy_ctxt->ps_pps;
1659*c83a76b0SSuyog Pawar     WORD32 split_cu_flag;
1660*c83a76b0SSuyog Pawar     WORD32 cu_idx = ps_entropy_ctxt->i4_cu_idx;
1661*c83a76b0SSuyog Pawar     cu_enc_loop_out_t *ps_enc_cu = ps_ctb->ps_enc_cu + cu_idx;
1662*c83a76b0SSuyog Pawar 
1663*c83a76b0SSuyog Pawar     /* CU size in pels */
1664*c83a76b0SSuyog Pawar     WORD32 cu_size = ps_enc_cu->b4_cu_size << 3;
1665*c83a76b0SSuyog Pawar 
1666*c83a76b0SSuyog Pawar     WORD32 pic_width = ps_tile_params->i4_curr_tile_width;
1667*c83a76b0SSuyog Pawar     WORD32 pic_height = ps_tile_params->i4_curr_tile_height;
1668*c83a76b0SSuyog Pawar 
1669*c83a76b0SSuyog Pawar     WORD32 log2_min_cb_size = ps_sps->i1_log2_min_coding_block_size;
1670*c83a76b0SSuyog Pawar     WORD32 ctb_size = (1 << (log2_cb_size + ct_depth));
1671*c83a76b0SSuyog Pawar     cab_ctxt_t *ps_cabac = &ps_entropy_ctxt->s_cabac_ctxt;
1672*c83a76b0SSuyog Pawar 
1673*c83a76b0SSuyog Pawar     /* top row cu depth stored for frm_width (1byte per mincusize=8) */
1674*c83a76b0SSuyog Pawar     UWORD8 *pu1_cu_depth_top = ps_entropy_ctxt->pu1_cu_depth_top;
1675*c83a76b0SSuyog Pawar 
1676*c83a76b0SSuyog Pawar     /* left cu depth stored for one ctb column (1byte per mincusize=8) */
1677*c83a76b0SSuyog Pawar     UWORD8 *pu1_cu_depth_left = &ps_entropy_ctxt->au1_cu_depth_left[0];
1678*c83a76b0SSuyog Pawar 
1679*c83a76b0SSuyog Pawar     /* calculation of top and left nbr availability */
1680*c83a76b0SSuyog Pawar     WORD32 top_avail;
1681*c83a76b0SSuyog Pawar     WORD32 left_avail;
1682*c83a76b0SSuyog Pawar 
1683*c83a76b0SSuyog Pawar     /* top and left cu within ctb  or outside ctb boundary */
1684*c83a76b0SSuyog Pawar     left_avail = (x0_frm & (ctb_size - 1)) ? 1 : ps_ctb->s_ctb_nbr_avail_flags.u1_left_avail;
1685*c83a76b0SSuyog Pawar     top_avail = (y0_frm & (ctb_size - 1)) ? 1 : ps_ctb->s_ctb_nbr_avail_flags.u1_top_avail;
1686*c83a76b0SSuyog Pawar 
1687*c83a76b0SSuyog Pawar     /* Sanity checks */
1688*c83a76b0SSuyog Pawar     ASSERT(ct_depth <= 3);
1689*c83a76b0SSuyog Pawar     ASSERT((cu_idx >= 0) && (cu_idx < ps_ctb->u1_num_cus_in_ctb));
1690*c83a76b0SSuyog Pawar     ASSERT(cu_size >= (1 << log2_min_cb_size));
1691*c83a76b0SSuyog Pawar     ASSERT(((ps_enc_cu->b3_cu_pos_x << 3) + cu_size) <= (UWORD32)ctb_size);
1692*c83a76b0SSuyog Pawar     ASSERT(((ps_enc_cu->b3_cu_pos_y << 3) + cu_size) <= (UWORD32)ctb_size);
1693*c83a76b0SSuyog Pawar 
1694*c83a76b0SSuyog Pawar     /* Encode cu split flags based on following conditions; See section 7.3.8*/
1695*c83a76b0SSuyog Pawar     if(((x0_frm + (1 << log2_cb_size)) <= pic_width) &&
1696*c83a76b0SSuyog Pawar        ((y0_frm + (1 << log2_cb_size)) <= pic_height) && (log2_cb_size > log2_min_cb_size) &&
1697*c83a76b0SSuyog Pawar        (ps_entropy_ctxt->i1_ctb_num_pcm_blks == 0))
1698*c83a76b0SSuyog Pawar     {
1699*c83a76b0SSuyog Pawar         /* encode the split cu flag */
1700*c83a76b0SSuyog Pawar         WORD32 ctxt_inc = IHEVC_CAB_SPLIT_CU_FLAG;
1701*c83a76b0SSuyog Pawar         UWORD32 u4_bits_estimated_prev;
1702*c83a76b0SSuyog Pawar         /* Context increment for skip flag as per Table 9-38 */
1703*c83a76b0SSuyog Pawar         if(top_avail)
1704*c83a76b0SSuyog Pawar         {
1705*c83a76b0SSuyog Pawar             ctxt_inc += (pu1_cu_depth_top[x0_frm >> 3] > ct_depth);
1706*c83a76b0SSuyog Pawar         }
1707*c83a76b0SSuyog Pawar 
1708*c83a76b0SSuyog Pawar         if(left_avail)
1709*c83a76b0SSuyog Pawar         {
1710*c83a76b0SSuyog Pawar             ctxt_inc += (pu1_cu_depth_left[(y0_frm >> 3) & 0x7] > ct_depth);
1711*c83a76b0SSuyog Pawar         }
1712*c83a76b0SSuyog Pawar 
1713*c83a76b0SSuyog Pawar         /* split if actual cu size is smaller than target cu size */
1714*c83a76b0SSuyog Pawar         split_cu_flag = cu_size < (1 << log2_cb_size);
1715*c83a76b0SSuyog Pawar         u4_bits_estimated_prev = ps_cabac->u4_bits_estimated_q12;
1716*c83a76b0SSuyog Pawar         ret |= ihevce_cabac_encode_bin(ps_cabac, split_cu_flag, ctxt_inc);
1717*c83a76b0SSuyog Pawar 
1718*c83a76b0SSuyog Pawar         if(ps_cabac->e_cabac_op_mode == CABAC_MODE_ENCODE_BITS)
1719*c83a76b0SSuyog Pawar         {  // clang-format off
1720*c83a76b0SSuyog Pawar             /*PIC INFO : populate cu split flag*/
1721*c83a76b0SSuyog Pawar             ps_entropy_ctxt->ps_pic_level_info->u8_bits_estimated_split_cu_flag +=
1722*c83a76b0SSuyog Pawar                 (ps_cabac->u4_bits_estimated_q12 - u4_bits_estimated_prev);
1723*c83a76b0SSuyog Pawar         }  // clang-format on
1724*c83a76b0SSuyog Pawar 
1725*c83a76b0SSuyog Pawar         AEV_TRACE("split_cu_flag", split_cu_flag, ps_cabac->u4_range);
1726*c83a76b0SSuyog Pawar         if(split_cu_flag == 0)
1727*c83a76b0SSuyog Pawar         {
1728*c83a76b0SSuyog Pawar             AEV_TRACE("split_cu_flag : X0", (x0_frm >> 6) << 6, ps_cabac->u4_range);
1729*c83a76b0SSuyog Pawar             AEV_TRACE("split_cu_flag : Y0", (y0_frm >> 6) << 6, ps_cabac->u4_range);
1730*c83a76b0SSuyog Pawar         }
1731*c83a76b0SSuyog Pawar     }
1732*c83a76b0SSuyog Pawar     else
1733*c83a76b0SSuyog Pawar     {
1734*c83a76b0SSuyog Pawar         /*********************************************************************/
1735*c83a76b0SSuyog Pawar         /* split cu is implicitly derived as 1 in frame/slice boundary case  */
1736*c83a76b0SSuyog Pawar         /* else split cu is implicitly derived as 0 if mincu size is reached */
1737*c83a76b0SSuyog Pawar         /*********************************************************************/
1738*c83a76b0SSuyog Pawar         if(log2_cb_size > ps_sps->i1_log2_min_coding_block_size)
1739*c83a76b0SSuyog Pawar             split_cu_flag = 1;
1740*c83a76b0SSuyog Pawar         else
1741*c83a76b0SSuyog Pawar             split_cu_flag = 0;
1742*c83a76b0SSuyog Pawar     }
1743*c83a76b0SSuyog Pawar 
1744*c83a76b0SSuyog Pawar     /************************************************************************/
1745*c83a76b0SSuyog Pawar     /* Reset qp delata coded flag appropriately so as to signal qp rightly  */
1746*c83a76b0SSuyog Pawar     /* during transform coding                                              */
1747*c83a76b0SSuyog Pawar     /************************************************************************/
1748*c83a76b0SSuyog Pawar     if((ps_pps->i1_cu_qp_delta_enabled_flag) && (ct_depth <= (ps_pps->i1_diff_cu_qp_delta_depth)))
1749*c83a76b0SSuyog Pawar 
1750*c83a76b0SSuyog Pawar     {
1751*c83a76b0SSuyog Pawar         ps_entropy_ctxt->i1_encode_qp_delta = 1;
1752*c83a76b0SSuyog Pawar     }
1753*c83a76b0SSuyog Pawar     /*else
1754*c83a76b0SSuyog Pawar     {
1755*c83a76b0SSuyog Pawar         ps_entropy_ctxt->i1_encode_qp_delta = 0;
1756*c83a76b0SSuyog Pawar     }*/
1757*c83a76b0SSuyog Pawar 
1758*c83a76b0SSuyog Pawar     if(split_cu_flag)
1759*c83a76b0SSuyog Pawar     {
1760*c83a76b0SSuyog Pawar         /* recurse quad tree till a leaf node is reached */
1761*c83a76b0SSuyog Pawar         WORD32 x1_frm = x0_frm + ((1 << log2_cb_size) >> 1);
1762*c83a76b0SSuyog Pawar         WORD32 y1_frm = y0_frm + ((1 << log2_cb_size) >> 1);
1763*c83a76b0SSuyog Pawar 
1764*c83a76b0SSuyog Pawar         /* node0 of quad tree */
1765*c83a76b0SSuyog Pawar         ret |= ihevce_encode_coding_quadtree(
1766*c83a76b0SSuyog Pawar             ps_entropy_ctxt, x0_frm, y0_frm, log2_cb_size - 1, ct_depth + 1, ps_ctb, ps_tile_params);
1767*c83a76b0SSuyog Pawar 
1768*c83a76b0SSuyog Pawar         if(x1_frm < pic_width)
1769*c83a76b0SSuyog Pawar         { /* node1 of quad tree */
1770*c83a76b0SSuyog Pawar             ret |= ihevce_encode_coding_quadtree(
1771*c83a76b0SSuyog Pawar                 ps_entropy_ctxt,
1772*c83a76b0SSuyog Pawar                 x1_frm,
1773*c83a76b0SSuyog Pawar                 y0_frm,
1774*c83a76b0SSuyog Pawar                 log2_cb_size - 1,
1775*c83a76b0SSuyog Pawar                 ct_depth + 1,
1776*c83a76b0SSuyog Pawar                 ps_ctb,
1777*c83a76b0SSuyog Pawar                 ps_tile_params);
1778*c83a76b0SSuyog Pawar         }
1779*c83a76b0SSuyog Pawar 
1780*c83a76b0SSuyog Pawar         if(y1_frm < pic_height)
1781*c83a76b0SSuyog Pawar         {
1782*c83a76b0SSuyog Pawar             /* node2 of quad tree */
1783*c83a76b0SSuyog Pawar             ret |= ihevce_encode_coding_quadtree(
1784*c83a76b0SSuyog Pawar                 ps_entropy_ctxt,
1785*c83a76b0SSuyog Pawar                 x0_frm,
1786*c83a76b0SSuyog Pawar                 y1_frm,
1787*c83a76b0SSuyog Pawar                 log2_cb_size - 1,
1788*c83a76b0SSuyog Pawar                 ct_depth + 1,
1789*c83a76b0SSuyog Pawar                 ps_ctb,
1790*c83a76b0SSuyog Pawar                 ps_tile_params);
1791*c83a76b0SSuyog Pawar         }
1792*c83a76b0SSuyog Pawar 
1793*c83a76b0SSuyog Pawar         if((x1_frm < pic_width) && (y1_frm < pic_height))
1794*c83a76b0SSuyog Pawar         {
1795*c83a76b0SSuyog Pawar             /* node3 of quad tree */
1796*c83a76b0SSuyog Pawar             ret |= ihevce_encode_coding_quadtree(
1797*c83a76b0SSuyog Pawar                 ps_entropy_ctxt,
1798*c83a76b0SSuyog Pawar                 x1_frm,
1799*c83a76b0SSuyog Pawar                 y1_frm,
1800*c83a76b0SSuyog Pawar                 log2_cb_size - 1,
1801*c83a76b0SSuyog Pawar                 ct_depth + 1,
1802*c83a76b0SSuyog Pawar                 ps_ctb,
1803*c83a76b0SSuyog Pawar                 ps_tile_params);
1804*c83a76b0SSuyog Pawar         }
1805*c83a76b0SSuyog Pawar     }
1806*c83a76b0SSuyog Pawar     else
1807*c83a76b0SSuyog Pawar     {
1808*c83a76b0SSuyog Pawar         /* leaf node is reached! Encode the CU */
1809*c83a76b0SSuyog Pawar         WORD32 i;
1810*c83a76b0SSuyog Pawar 
1811*c83a76b0SSuyog Pawar         /* sanity checks */
1812*c83a76b0SSuyog Pawar         ASSERT(ps_entropy_ctxt->i1_ctb_num_pcm_blks == 0);
1813*c83a76b0SSuyog Pawar 
1814*c83a76b0SSuyog Pawar         if(ps_entropy_ctxt->i1_ctb_num_pcm_blks == 0)
1815*c83a76b0SSuyog Pawar         {
1816*c83a76b0SSuyog Pawar             UWORD32 u4_bits_eztimated = ps_entropy_ctxt->s_cabac_ctxt.u4_bits_estimated_q12;
1817*c83a76b0SSuyog Pawar             /* Encode a non-PCM CU */
1818*c83a76b0SSuyog Pawar             /*PCM INFO: populate total TUs*/
1819*c83a76b0SSuyog Pawar             if(ps_cabac->e_cabac_op_mode == CABAC_MODE_ENCODE_BITS)
1820*c83a76b0SSuyog Pawar             {
1821*c83a76b0SSuyog Pawar                 ps_entropy_ctxt->ps_pic_level_info->i8_total_tu += ps_enc_cu->u2_num_tus_in_cu;
1822*c83a76b0SSuyog Pawar             }
1823*c83a76b0SSuyog Pawar 
1824*c83a76b0SSuyog Pawar             ret |= ihevce_cabac_encode_coding_unit(
1825*c83a76b0SSuyog Pawar                 ps_entropy_ctxt, ps_enc_cu, ct_depth, top_avail, left_avail);
1826*c83a76b0SSuyog Pawar 
1827*c83a76b0SSuyog Pawar             if(ps_cabac->e_cabac_op_mode == CABAC_MODE_ENCODE_BITS)
1828*c83a76b0SSuyog Pawar             {
1829*c83a76b0SSuyog Pawar                 // clang-format off
1830*c83a76b0SSuyog Pawar                 if(PRED_MODE_INTRA == ps_enc_cu->b1_pred_mode_flag)
1831*c83a76b0SSuyog Pawar                 {
1832*c83a76b0SSuyog Pawar                     ps_entropy_ctxt->ps_pic_level_info->u8_bits_estimated_intra +=
1833*c83a76b0SSuyog Pawar                         (ps_entropy_ctxt->s_cabac_ctxt.u4_bits_estimated_q12 -
1834*c83a76b0SSuyog Pawar                             u4_bits_eztimated);
1835*c83a76b0SSuyog Pawar                 }
1836*c83a76b0SSuyog Pawar                 else
1837*c83a76b0SSuyog Pawar                 {
1838*c83a76b0SSuyog Pawar                     ps_entropy_ctxt->ps_pic_level_info->u8_bits_estimated_inter +=
1839*c83a76b0SSuyog Pawar                         (ps_entropy_ctxt->s_cabac_ctxt.u4_bits_estimated_q12 -
1840*c83a76b0SSuyog Pawar                             u4_bits_eztimated);
1841*c83a76b0SSuyog Pawar                 }
1842*c83a76b0SSuyog Pawar                 // clang-format on
1843*c83a76b0SSuyog Pawar             }
1844*c83a76b0SSuyog Pawar         }
1845*c83a76b0SSuyog Pawar         else
1846*c83a76b0SSuyog Pawar         {  //TODO: //PCM not supported in this encoder
1847*c83a76b0SSuyog Pawar         }
1848*c83a76b0SSuyog Pawar 
1849*c83a76b0SSuyog Pawar         /* update cu_idx, left and top arrays for cudepth  after encoding cu */
1850*c83a76b0SSuyog Pawar         ps_entropy_ctxt->i4_cu_idx++;
1851*c83a76b0SSuyog Pawar         for(i = 0; i < (cu_size >> 3); i++)
1852*c83a76b0SSuyog Pawar         {
1853*c83a76b0SSuyog Pawar             pu1_cu_depth_top[(x0_frm >> 3) + i] = ct_depth;
1854*c83a76b0SSuyog Pawar             pu1_cu_depth_left[((y0_frm >> 3) & 0x7) + i] = ct_depth;
1855*c83a76b0SSuyog Pawar         }
1856*c83a76b0SSuyog Pawar     }
1857*c83a76b0SSuyog Pawar 
1858*c83a76b0SSuyog Pawar     return ret;
1859*c83a76b0SSuyog Pawar }
1860*c83a76b0SSuyog Pawar 
1861*c83a76b0SSuyog Pawar /**
1862*c83a76b0SSuyog Pawar ******************************************************************************
1863*c83a76b0SSuyog Pawar *
1864*c83a76b0SSuyog Pawar *  @brief Encodes slice data (General Slice syntax) as per section 7.3.6.1
1865*c83a76b0SSuyog Pawar *
1866*c83a76b0SSuyog Pawar *  @par   Description
1867*c83a76b0SSuyog Pawar *  Entropy encode of all ctbs in a slice as per section 7.3.6.1
1868*c83a76b0SSuyog Pawar *
1869*c83a76b0SSuyog Pawar *  @param[inout]   ps_entropy_ctxt
1870*c83a76b0SSuyog Pawar *  pointer to entropy context (handle)
1871*c83a76b0SSuyog Pawar *
1872*c83a76b0SSuyog Pawar *  @return      success or failure error code
1873*c83a76b0SSuyog Pawar *
1874*c83a76b0SSuyog Pawar ******************************************************************************
1875*c83a76b0SSuyog Pawar */
ihevce_encode_slice_data(entropy_context_t * ps_entropy_ctxt,ihevce_tile_params_t * ps_tile_params,WORD32 * pi4_end_of_slice_flag)1876*c83a76b0SSuyog Pawar WORD32 ihevce_encode_slice_data(
1877*c83a76b0SSuyog Pawar     entropy_context_t *ps_entropy_ctxt,
1878*c83a76b0SSuyog Pawar     ihevce_tile_params_t *ps_tile_params,
1879*c83a76b0SSuyog Pawar     WORD32 *pi4_end_of_slice_flag)
1880*c83a76b0SSuyog Pawar {
1881*c83a76b0SSuyog Pawar     WORD32 ret = IHEVCE_SUCCESS;
1882*c83a76b0SSuyog Pawar     WORD32 end_of_slice_seg_flag = 0;
1883*c83a76b0SSuyog Pawar     sps_t *ps_sps = ps_entropy_ctxt->ps_sps;
1884*c83a76b0SSuyog Pawar     pps_t *ps_pps = ps_entropy_ctxt->ps_pps;
1885*c83a76b0SSuyog Pawar     slice_header_t *ps_slice_hdr = ps_entropy_ctxt->ps_slice_hdr;
1886*c83a76b0SSuyog Pawar 
1887*c83a76b0SSuyog Pawar     cab_ctxt_t *ps_cabac = &ps_entropy_ctxt->s_cabac_ctxt;
1888*c83a76b0SSuyog Pawar 
1889*c83a76b0SSuyog Pawar     /* State of previous CTB before it's terminate bin is encoded */
1890*c83a76b0SSuyog Pawar     cab_ctxt_t s_cabac_prev_ctb;
1891*c83a76b0SSuyog Pawar 
1892*c83a76b0SSuyog Pawar     /* State after current CTB's encoding is complete but before
1893*c83a76b0SSuyog Pawar     the termintate bin encoding */
1894*c83a76b0SSuyog Pawar     cab_ctxt_t s_cabac_after_ctb;
1895*c83a76b0SSuyog Pawar 
1896*c83a76b0SSuyog Pawar     /* Storing the last 4 bytes before adding terminate bin
1897*c83a76b0SSuyog Pawar     as these 4 bytes might get corrupted while encoding terminate bin */
1898*c83a76b0SSuyog Pawar     UWORD32 u4_prev_ctb_temp, u4_cur_ctb_temp;
1899*c83a76b0SSuyog Pawar     WORD8 i1_last_cu_qp = 0;
1900*c83a76b0SSuyog Pawar     bitstrm_t *ps_bit_strm = &ps_entropy_ctxt->s_bit_strm;
1901*c83a76b0SSuyog Pawar 
1902*c83a76b0SSuyog Pawar     WORD32 log2_ctb_size, ctb_size;
1903*c83a76b0SSuyog Pawar     //WORD32 pic_width  = ps_sps->i2_pic_width_in_luma_samples;
1904*c83a76b0SSuyog Pawar     //WORD32 pic_height = ps_sps->i2_pic_height_in_luma_samples;
1905*c83a76b0SSuyog Pawar     WORD32 pic_width = ps_tile_params->i4_curr_tile_width;
1906*c83a76b0SSuyog Pawar     WORD32 pic_height = ps_tile_params->i4_curr_tile_height;
1907*c83a76b0SSuyog Pawar     WORD32 num_ctb_in_row;
1908*c83a76b0SSuyog Pawar 
1909*c83a76b0SSuyog Pawar     WORD32 i4_curr_ctb_x, i4_curr_ctb_y;
1910*c83a76b0SSuyog Pawar     UWORD32 u4_slice_seg_hdr_size = (UWORD32)ps_entropy_ctxt->i4_slice_seg_len;
1911*c83a76b0SSuyog Pawar     UWORD32 u4_slice_start_offset = ps_bit_strm->u4_strm_buf_offset - u4_slice_seg_hdr_size;
1912*c83a76b0SSuyog Pawar 
1913*c83a76b0SSuyog Pawar     WORD32 ctb_slice_address = ps_slice_hdr->i2_slice_address;
1914*c83a76b0SSuyog Pawar     WORD32 slice_qp = ps_slice_hdr->i1_slice_qp_delta + ps_pps->i1_pic_init_qp;
1915*c83a76b0SSuyog Pawar     WORD32 cabac_init_idc;
1916*c83a76b0SSuyog Pawar     WORD32 x0_frm, y0_frm;
1917*c83a76b0SSuyog Pawar     ctb_enc_loop_out_t *ps_first_ctb;  // Points to first CTB of ctb-row
1918*c83a76b0SSuyog Pawar     ctb_enc_loop_out_t *ps_ctb;
1919*c83a76b0SSuyog Pawar     WORD32 ctb_ctr = 0;  //count ctb encoded in a ctb-row
1920*c83a76b0SSuyog Pawar 
1921*c83a76b0SSuyog Pawar     ihevce_sys_api_t *ps_sys_api = (ihevce_sys_api_t *)ps_entropy_ctxt->pv_sys_api;
1922*c83a76b0SSuyog Pawar 
1923*c83a76b0SSuyog Pawar     /* Structure to backup pic info in case we need to revert back to pervious
1924*c83a76b0SSuyog Pawar     CTB when i4_slice_segment_mode is 2 */
1925*c83a76b0SSuyog Pawar     s_pic_level_acc_info_t s_pic_level_info_backup;  // info before
1926*c83a76b0SSuyog Pawar 
1927*c83a76b0SSuyog Pawar     /* Initialize the CTB size from sps parameters */
1928*c83a76b0SSuyog Pawar     log2_ctb_size =
1929*c83a76b0SSuyog Pawar         ps_sps->i1_log2_min_coding_block_size + ps_sps->i1_log2_diff_max_min_coding_block_size;
1930*c83a76b0SSuyog Pawar 
1931*c83a76b0SSuyog Pawar     ctb_size = (1 << log2_ctb_size);
1932*c83a76b0SSuyog Pawar 
1933*c83a76b0SSuyog Pawar     /* sanity checks */
1934*c83a76b0SSuyog Pawar     ASSERT((log2_ctb_size >= 3) && (log2_ctb_size <= 6));
1935*c83a76b0SSuyog Pawar 
1936*c83a76b0SSuyog Pawar     ps_entropy_ctxt->i1_log2_ctb_size = (WORD8)log2_ctb_size;
1937*c83a76b0SSuyog Pawar 
1938*c83a76b0SSuyog Pawar     /* Initiallise before starting slice. For single slice case both
1939*c83a76b0SSuyog Pawar     x and y will be set to zero */
1940*c83a76b0SSuyog Pawar     ps_entropy_ctxt->i4_ctb_x = ps_entropy_ctxt->i4_next_slice_seg_x;
1941*c83a76b0SSuyog Pawar     ps_entropy_ctxt->i4_ctb_y = ps_entropy_ctxt->i4_next_slice_seg_y;
1942*c83a76b0SSuyog Pawar     num_ctb_in_row = (ps_sps->i2_pic_width_in_luma_samples + ctb_size - 1) >> log2_ctb_size;
1943*c83a76b0SSuyog Pawar 
1944*c83a76b0SSuyog Pawar     /* initialize the cabac init idc based on slice type */
1945*c83a76b0SSuyog Pawar     if(ps_slice_hdr->i1_slice_type == ISLICE)
1946*c83a76b0SSuyog Pawar     {
1947*c83a76b0SSuyog Pawar         cabac_init_idc = 0;
1948*c83a76b0SSuyog Pawar     }
1949*c83a76b0SSuyog Pawar     else if(ps_slice_hdr->i1_slice_type == PSLICE)
1950*c83a76b0SSuyog Pawar     {
1951*c83a76b0SSuyog Pawar         cabac_init_idc = ps_slice_hdr->i1_cabac_init_flag ? 2 : 1;
1952*c83a76b0SSuyog Pawar     }
1953*c83a76b0SSuyog Pawar     else
1954*c83a76b0SSuyog Pawar     {
1955*c83a76b0SSuyog Pawar         cabac_init_idc = ps_slice_hdr->i1_cabac_init_flag ? 1 : 2;
1956*c83a76b0SSuyog Pawar     }
1957*c83a76b0SSuyog Pawar     ps_cabac->i1_entropy_coding_sync_enabled_flag = ps_pps->i1_entropy_coding_sync_enabled_flag;
1958*c83a76b0SSuyog Pawar 
1959*c83a76b0SSuyog Pawar     /* Dependent slices should be ON only when slice segment mode is enabled */
1960*c83a76b0SSuyog Pawar     if(ps_slice_hdr->i1_dependent_slice_flag == 1)
1961*c83a76b0SSuyog Pawar     {
1962*c83a76b0SSuyog Pawar         ASSERT(
1963*c83a76b0SSuyog Pawar             (ps_entropy_ctxt->i4_slice_segment_mode == 1) ||
1964*c83a76b0SSuyog Pawar             (ps_entropy_ctxt->i4_slice_segment_mode == 2));
1965*c83a76b0SSuyog Pawar     }
1966*c83a76b0SSuyog Pawar 
1967*c83a76b0SSuyog Pawar     /* initialize the cabac engine. For dependent slice segments
1968*c83a76b0SSuyog Pawar     cabac context models will not be reset */
1969*c83a76b0SSuyog Pawar     if(ps_slice_hdr->i1_dependent_slice_flag == 1)
1970*c83a76b0SSuyog Pawar     {
1971*c83a76b0SSuyog Pawar         ret = ihevce_cabac_reset(ps_cabac, ps_bit_strm, CABAC_MODE_ENCODE_BITS);
1972*c83a76b0SSuyog Pawar     }
1973*c83a76b0SSuyog Pawar     else
1974*c83a76b0SSuyog Pawar     {
1975*c83a76b0SSuyog Pawar         ret = ihevce_cabac_init(
1976*c83a76b0SSuyog Pawar             ps_cabac,
1977*c83a76b0SSuyog Pawar             ps_bit_strm,
1978*c83a76b0SSuyog Pawar             CLIP3(slice_qp, 0, IHEVC_MAX_QP),
1979*c83a76b0SSuyog Pawar             cabac_init_idc,
1980*c83a76b0SSuyog Pawar             CABAC_MODE_ENCODE_BITS);
1981*c83a76b0SSuyog Pawar 
1982*c83a76b0SSuyog Pawar         /* initialize qp to slice start qp */
1983*c83a76b0SSuyog Pawar         ps_entropy_ctxt->i1_cur_qp = slice_qp;
1984*c83a76b0SSuyog Pawar     }
1985*c83a76b0SSuyog Pawar 
1986*c83a76b0SSuyog Pawar     /* initialize slice x and y offset in pels w.r.t top left conrner */
1987*c83a76b0SSuyog Pawar     x0_frm = ps_entropy_ctxt->i4_ctb_x << log2_ctb_size;
1988*c83a76b0SSuyog Pawar     y0_frm = ps_entropy_ctxt->i4_ctb_y << log2_ctb_size;
1989*c83a76b0SSuyog Pawar 
1990*c83a76b0SSuyog Pawar     /* Pointing ctb structure to the correct CTB in frame based on
1991*c83a76b0SSuyog Pawar     slice address */
1992*c83a76b0SSuyog Pawar     ps_first_ctb = ps_entropy_ctxt->ps_frm_ctb + ctb_slice_address;
1993*c83a76b0SSuyog Pawar     ps_ctb = ps_first_ctb - 1;
1994*c83a76b0SSuyog Pawar 
1995*c83a76b0SSuyog Pawar     //ps_entropy_ctxt->i4_ctb_slice_x = 0;
1996*c83a76b0SSuyog Pawar     //ps_entropy_ctxt->i4_ctb_slice_y = 0;
1997*c83a76b0SSuyog Pawar 
1998*c83a76b0SSuyog Pawar     /* Setting to NULL to detect if first CTB of slice itself
1999*c83a76b0SSuyog Pawar     exceeds the i4_slice_segment_max_length. Will be used only if
2000*c83a76b0SSuyog Pawar     i4_slice_segment_mode is non-zero */
2001*c83a76b0SSuyog Pawar     s_cabac_prev_ctb.pu1_strm_buffer = NULL;
2002*c83a76b0SSuyog Pawar 
2003*c83a76b0SSuyog Pawar     do
2004*c83a76b0SSuyog Pawar     {
2005*c83a76b0SSuyog Pawar         UWORD8 au1_cu_depth_top[8] = { 0 }, au1_cu_depth_left[8] = { 0 };
2006*c83a76b0SSuyog Pawar         UWORD8 u1_skip_cu_top = 0;
2007*c83a76b0SSuyog Pawar         UWORD32 u4_skip_cu_left = 0;
2008*c83a76b0SSuyog Pawar 
2009*c83a76b0SSuyog Pawar         /* By default assume that slice-segment is going to end after
2010*c83a76b0SSuyog Pawar         current CTB */
2011*c83a76b0SSuyog Pawar         end_of_slice_seg_flag = 1;
2012*c83a76b0SSuyog Pawar 
2013*c83a76b0SSuyog Pawar         i4_curr_ctb_x = ps_entropy_ctxt->i4_ctb_x;
2014*c83a76b0SSuyog Pawar         i4_curr_ctb_y = ps_entropy_ctxt->i4_ctb_y;
2015*c83a76b0SSuyog Pawar 
2016*c83a76b0SSuyog Pawar         if(1 == ps_tile_params->i4_tiles_enabled_flag)
2017*c83a76b0SSuyog Pawar         {
2018*c83a76b0SSuyog Pawar             ps_ctb = ps_first_ctb + ctb_ctr;
2019*c83a76b0SSuyog Pawar         }
2020*c83a76b0SSuyog Pawar         else
2021*c83a76b0SSuyog Pawar         {
2022*c83a76b0SSuyog Pawar             ps_ctb++;
2023*c83a76b0SSuyog Pawar         }
2024*c83a76b0SSuyog Pawar 
2025*c83a76b0SSuyog Pawar         /* Store some parameters. Will be used if current CTB's encoding
2026*c83a76b0SSuyog Pawar         has to be reverted in the event of overflow beyond i4_slice_segment_max_length */
2027*c83a76b0SSuyog Pawar         if(2 == ps_entropy_ctxt->i4_slice_segment_mode)
2028*c83a76b0SSuyog Pawar         {
2029*c83a76b0SSuyog Pawar             /* Store CU depths flag */
2030*c83a76b0SSuyog Pawar             memcpy(au1_cu_depth_top, &ps_entropy_ctxt->pu1_cu_depth_top[i4_curr_ctb_x * 8], 8);
2031*c83a76b0SSuyog Pawar             memcpy(au1_cu_depth_left, ps_entropy_ctxt->au1_cu_depth_left, 8);
2032*c83a76b0SSuyog Pawar 
2033*c83a76b0SSuyog Pawar             /* Store CU skip flags */
2034*c83a76b0SSuyog Pawar             u1_skip_cu_top = *(ps_entropy_ctxt->pu1_skip_cu_top + i4_curr_ctb_x);
2035*c83a76b0SSuyog Pawar             u4_skip_cu_left = ps_entropy_ctxt->u4_skip_cu_left;
2036*c83a76b0SSuyog Pawar 
2037*c83a76b0SSuyog Pawar             /* Backup current state of pic info */
2038*c83a76b0SSuyog Pawar             s_pic_level_info_backup = *(ps_entropy_ctxt->ps_pic_level_info);
2039*c83a76b0SSuyog Pawar         }
2040*c83a76b0SSuyog Pawar 
2041*c83a76b0SSuyog Pawar         /* Section:7.3.7 Coding tree unit syntax */
2042*c83a76b0SSuyog Pawar         /* coding_tree_unit() inlined here */
2043*c83a76b0SSuyog Pawar         ps_entropy_ctxt->i1_ctb_num_pcm_blks = 0;
2044*c83a76b0SSuyog Pawar 
2045*c83a76b0SSuyog Pawar         /* Simple Neigbour avail calculation */
2046*c83a76b0SSuyog Pawar         ps_ctb->s_ctb_nbr_avail_flags.u1_left_avail = (x0_frm > 0);
2047*c83a76b0SSuyog Pawar         ps_ctb->s_ctb_nbr_avail_flags.u1_top_avail = (y0_frm > 0);
2048*c83a76b0SSuyog Pawar 
2049*c83a76b0SSuyog Pawar         ps_entropy_ctxt->i4_cu_idx = 0;
2050*c83a76b0SSuyog Pawar 
2051*c83a76b0SSuyog Pawar         /* Encode SAO syntax as per section 7.3.8.3 */
2052*c83a76b0SSuyog Pawar         if(ps_sps->i1_sample_adaptive_offset_enabled_flag)
2053*c83a76b0SSuyog Pawar         {
2054*c83a76b0SSuyog Pawar             if((ps_slice_hdr->i1_slice_sao_luma_flag) || (ps_slice_hdr->i1_slice_sao_chroma_flag))
2055*c83a76b0SSuyog Pawar             {
2056*c83a76b0SSuyog Pawar                 /*PIC INFO: SAO encode biys*/
2057*c83a76b0SSuyog Pawar                 UWORD32 u4_bits_estimated_prev =
2058*c83a76b0SSuyog Pawar                     ps_entropy_ctxt->s_cabac_ctxt.u4_bits_estimated_q12;
2059*c83a76b0SSuyog Pawar 
2060*c83a76b0SSuyog Pawar                 ret |= ihevce_cabac_encode_sao(ps_entropy_ctxt, ps_ctb);
2061*c83a76b0SSuyog Pawar 
2062*c83a76b0SSuyog Pawar                 if(ps_cabac->e_cabac_op_mode == CABAC_MODE_ENCODE_BITS)
2063*c83a76b0SSuyog Pawar                 {
2064*c83a76b0SSuyog Pawar                     ps_entropy_ctxt->ps_pic_level_info->u8_bits_estimated_sao +=
2065*c83a76b0SSuyog Pawar                         (ps_entropy_ctxt->s_cabac_ctxt.u4_bits_estimated_q12 -
2066*c83a76b0SSuyog Pawar                          u4_bits_estimated_prev);
2067*c83a76b0SSuyog Pawar                 }
2068*c83a76b0SSuyog Pawar             }
2069*c83a76b0SSuyog Pawar         }
2070*c83a76b0SSuyog Pawar 
2071*c83a76b0SSuyog Pawar         ps_entropy_ctxt->s_cabac_ctxt.u4_bits_estimated_q12 = 0;
2072*c83a76b0SSuyog Pawar 
2073*c83a76b0SSuyog Pawar         if(ps_cabac->e_cabac_op_mode == CABAC_MODE_ENCODE_BITS)
2074*c83a76b0SSuyog Pawar         {
2075*c83a76b0SSuyog Pawar             /*PIC_INFO: Update total no.of CUS*/
2076*c83a76b0SSuyog Pawar             ps_entropy_ctxt->ps_pic_level_info->i8_total_cu += ps_ctb->u1_num_cus_in_ctb;
2077*c83a76b0SSuyog Pawar         }
2078*c83a76b0SSuyog Pawar         /* call recursive coding tree structure to encode all cus in ctb */
2079*c83a76b0SSuyog Pawar         ret |= ihevce_encode_coding_quadtree(
2080*c83a76b0SSuyog Pawar             ps_entropy_ctxt, x0_frm, y0_frm, log2_ctb_size, 0, ps_ctb, ps_tile_params);
2081*c83a76b0SSuyog Pawar 
2082*c83a76b0SSuyog Pawar         /* post ctb encode increments */
2083*c83a76b0SSuyog Pawar         ctb_ctr++;
2084*c83a76b0SSuyog Pawar         x0_frm += ctb_size;
2085*c83a76b0SSuyog Pawar         ps_entropy_ctxt->i4_ctb_x++;
2086*c83a76b0SSuyog Pawar         //ps_entropy_ctxt->i4_ctb_slice_x++;
2087*c83a76b0SSuyog Pawar 
2088*c83a76b0SSuyog Pawar         if(ps_pps->i1_entropy_coding_sync_enabled_flag && ps_entropy_ctxt->i4_ctb_x == 2)
2089*c83a76b0SSuyog Pawar         {
2090*c83a76b0SSuyog Pawar             /*backup cabac context at end of second CTB(top right neighbour for start of bottom row)*/
2091*c83a76b0SSuyog Pawar             ihevce_cabac_ctxt_backup(ps_cabac);
2092*c83a76b0SSuyog Pawar         }
2093*c83a76b0SSuyog Pawar 
2094*c83a76b0SSuyog Pawar         /* end of row check using x0_frm offset */
2095*c83a76b0SSuyog Pawar         if(x0_frm >= pic_width)
2096*c83a76b0SSuyog Pawar         {
2097*c83a76b0SSuyog Pawar             ctb_ctr = 0;
2098*c83a76b0SSuyog Pawar             ps_first_ctb += num_ctb_in_row;
2099*c83a76b0SSuyog Pawar             x0_frm = 0;
2100*c83a76b0SSuyog Pawar             y0_frm += ctb_size;
2101*c83a76b0SSuyog Pawar 
2102*c83a76b0SSuyog Pawar             ps_entropy_ctxt->i4_ctb_x = 0;
2103*c83a76b0SSuyog Pawar             ps_entropy_ctxt->i4_ctb_y++;
2104*c83a76b0SSuyog Pawar             //ps_entropy_ctxt->i4_ctb_slice_y++;
2105*c83a76b0SSuyog Pawar         }
2106*c83a76b0SSuyog Pawar 
2107*c83a76b0SSuyog Pawar         /* Detect end of slice. Which would mean end-of-slice-segment too */
2108*c83a76b0SSuyog Pawar         *pi4_end_of_slice_flag = (y0_frm >= pic_height);
2109*c83a76b0SSuyog Pawar 
2110*c83a76b0SSuyog Pawar         if(0 == ps_entropy_ctxt->i4_slice_segment_mode)
2111*c83a76b0SSuyog Pawar         {
2112*c83a76b0SSuyog Pawar             /* If slice ends then so does slice segment  */
2113*c83a76b0SSuyog Pawar             end_of_slice_seg_flag = *pi4_end_of_slice_flag;
2114*c83a76b0SSuyog Pawar 
2115*c83a76b0SSuyog Pawar             /*  encode terminate bin */
2116*c83a76b0SSuyog Pawar             ret |= ihevce_cabac_encode_terminate(ps_cabac, end_of_slice_seg_flag, 0);
2117*c83a76b0SSuyog Pawar         }
2118*c83a76b0SSuyog Pawar         else if(1 == ps_entropy_ctxt->i4_slice_segment_mode)
2119*c83a76b0SSuyog Pawar         {
2120*c83a76b0SSuyog Pawar             ps_entropy_ctxt->i4_slice_seg_len++;
2121*c83a76b0SSuyog Pawar             if((ps_entropy_ctxt->i4_slice_seg_len) >= ps_entropy_ctxt->i4_slice_segment_max_length)
2122*c83a76b0SSuyog Pawar             {
2123*c83a76b0SSuyog Pawar                 /* Store the address of CTB from where next slice segment will start */
2124*c83a76b0SSuyog Pawar                 ps_entropy_ctxt->i4_next_slice_seg_x = ps_entropy_ctxt->i4_ctb_x;
2125*c83a76b0SSuyog Pawar                 ps_entropy_ctxt->i4_next_slice_seg_y = ps_entropy_ctxt->i4_ctb_y;
2126*c83a76b0SSuyog Pawar             }
2127*c83a76b0SSuyog Pawar             else
2128*c83a76b0SSuyog Pawar             {
2129*c83a76b0SSuyog Pawar                 /* If slice ends then so does slice segment  */
2130*c83a76b0SSuyog Pawar                 end_of_slice_seg_flag = *pi4_end_of_slice_flag;
2131*c83a76b0SSuyog Pawar             }
2132*c83a76b0SSuyog Pawar 
2133*c83a76b0SSuyog Pawar             /*  encode terminate bin */
2134*c83a76b0SSuyog Pawar             ret |= ihevce_cabac_encode_terminate(ps_cabac, end_of_slice_seg_flag, 0);
2135*c83a76b0SSuyog Pawar         }
2136*c83a76b0SSuyog Pawar         else if(2 == ps_entropy_ctxt->i4_slice_segment_mode)
2137*c83a76b0SSuyog Pawar         {
2138*c83a76b0SSuyog Pawar             //WORD32 i4_slice_seg_len_prev = i4_slice_seg_len;
2139*c83a76b0SSuyog Pawar 
2140*c83a76b0SSuyog Pawar             /* Store some parameters. Will be used to revert back to this state if
2141*c83a76b0SSuyog Pawar             i4_slice_segment_max_length is not exceeded after encoding end-of-slice */
2142*c83a76b0SSuyog Pawar             s_cabac_after_ctb = *ps_cabac;
2143*c83a76b0SSuyog Pawar             u4_cur_ctb_temp =
2144*c83a76b0SSuyog Pawar                 *((UWORD32 *)(ps_cabac->pu1_strm_buffer + ps_cabac->u4_strm_buf_offset - 4));
2145*c83a76b0SSuyog Pawar 
2146*c83a76b0SSuyog Pawar             /*  encode terminate bin. For dependent slices, always simulate
2147*c83a76b0SSuyog Pawar             end-of-slice to check if i4_slice_segment_max_length is surpassed */
2148*c83a76b0SSuyog Pawar             ret |= ihevce_cabac_encode_terminate(ps_cabac, 1, 0);
2149*c83a76b0SSuyog Pawar 
2150*c83a76b0SSuyog Pawar             //i4_slice_seg_len_prev   = i4_slice_seg_len;
2151*c83a76b0SSuyog Pawar             ps_entropy_ctxt->i4_slice_seg_len =
2152*c83a76b0SSuyog Pawar                 (WORD32)(ps_cabac->u4_strm_buf_offset - u4_slice_start_offset);
2153*c83a76b0SSuyog Pawar 
2154*c83a76b0SSuyog Pawar             //ps_entropy_ctxt->i4_slice_seg_len = i4_slice_seg_len; //No need to update it.
2155*c83a76b0SSuyog Pawar 
2156*c83a76b0SSuyog Pawar             if(ps_entropy_ctxt->i4_slice_seg_len > ps_entropy_ctxt->i4_slice_segment_max_length)
2157*c83a76b0SSuyog Pawar             {
2158*c83a76b0SSuyog Pawar                 if(s_cabac_prev_ctb.pu1_strm_buffer == NULL)
2159*c83a76b0SSuyog Pawar                 {
2160*c83a76b0SSuyog Pawar                     /* Bytes in a single CTB has exceeded the i4_slice_segment_max_length
2161*c83a76b0SSuyog Pawar                     set by the user. Close the slice-segment and print a warning */
2162*c83a76b0SSuyog Pawar 
2163*c83a76b0SSuyog Pawar                     /* Store the address of CTB from where next slice segment will start */
2164*c83a76b0SSuyog Pawar                     ps_entropy_ctxt->i4_next_slice_seg_x = ps_entropy_ctxt->i4_ctb_x;
2165*c83a76b0SSuyog Pawar                     ps_entropy_ctxt->i4_next_slice_seg_y = ps_entropy_ctxt->i4_ctb_y;
2166*c83a76b0SSuyog Pawar 
2167*c83a76b0SSuyog Pawar                     ps_sys_api->ihevce_printf(
2168*c83a76b0SSuyog Pawar                         ps_sys_api->pv_cb_handle,
2169*c83a76b0SSuyog Pawar                         "IHEVCE_WARNING: CTB(%2d, %2d) encoded using %d bytes; "
2170*c83a76b0SSuyog Pawar                         "this exceeds max slice segment size %d as requested "
2171*c83a76b0SSuyog Pawar                         "by the user\n",
2172*c83a76b0SSuyog Pawar                         i4_curr_ctb_x,
2173*c83a76b0SSuyog Pawar                         i4_curr_ctb_y,
2174*c83a76b0SSuyog Pawar                         ps_entropy_ctxt->i4_slice_seg_len,
2175*c83a76b0SSuyog Pawar                         ps_entropy_ctxt->i4_slice_segment_max_length);
2176*c83a76b0SSuyog Pawar                 }
2177*c83a76b0SSuyog Pawar                 else /* Revert back to previous CTB's state and close current slice */
2178*c83a76b0SSuyog Pawar                 {
2179*c83a76b0SSuyog Pawar                     *ps_cabac = s_cabac_prev_ctb;
2180*c83a76b0SSuyog Pawar                     *((UWORD32 *)(ps_cabac->pu1_strm_buffer + ps_cabac->u4_strm_buf_offset - 4)) =
2181*c83a76b0SSuyog Pawar                         u4_prev_ctb_temp;
2182*c83a76b0SSuyog Pawar 
2183*c83a76b0SSuyog Pawar                     memcpy(
2184*c83a76b0SSuyog Pawar                         &ps_entropy_ctxt->pu1_cu_depth_top[i4_curr_ctb_x * 8], au1_cu_depth_top, 8);
2185*c83a76b0SSuyog Pawar                     memcpy(ps_entropy_ctxt->au1_cu_depth_left, au1_cu_depth_left, 8);
2186*c83a76b0SSuyog Pawar 
2187*c83a76b0SSuyog Pawar                     *(ps_entropy_ctxt->pu1_skip_cu_top + i4_curr_ctb_x) = u1_skip_cu_top;
2188*c83a76b0SSuyog Pawar                     ps_entropy_ctxt->u4_skip_cu_left = u4_skip_cu_left;
2189*c83a76b0SSuyog Pawar 
2190*c83a76b0SSuyog Pawar                     ps_entropy_ctxt->i1_cur_qp = i1_last_cu_qp;
2191*c83a76b0SSuyog Pawar 
2192*c83a76b0SSuyog Pawar                     /* Restore pic info */
2193*c83a76b0SSuyog Pawar                     *(ps_entropy_ctxt->ps_pic_level_info) = s_pic_level_info_backup;
2194*c83a76b0SSuyog Pawar 
2195*c83a76b0SSuyog Pawar                     /*  encode terminate bin with end-of-slice */
2196*c83a76b0SSuyog Pawar                     ret |= ihevce_cabac_encode_terminate(ps_cabac, 1, 0);
2197*c83a76b0SSuyog Pawar 
2198*c83a76b0SSuyog Pawar                     /* Store the address of CTB from where next slice segment will start */
2199*c83a76b0SSuyog Pawar                     ps_entropy_ctxt->i4_next_slice_seg_x = i4_curr_ctb_x;
2200*c83a76b0SSuyog Pawar                     ps_entropy_ctxt->i4_next_slice_seg_y = i4_curr_ctb_y;
2201*c83a76b0SSuyog Pawar 
2202*c83a76b0SSuyog Pawar                     /* As we are reverted back to the previous CTB, force end of slice to zero */
2203*c83a76b0SSuyog Pawar                     *pi4_end_of_slice_flag = 0;
2204*c83a76b0SSuyog Pawar                 }
2205*c83a76b0SSuyog Pawar             }
2206*c83a76b0SSuyog Pawar             else if(0 == *pi4_end_of_slice_flag)
2207*c83a76b0SSuyog Pawar             {
2208*c83a76b0SSuyog Pawar                 /* As this is not the end of slice, therefore revert back
2209*c83a76b0SSuyog Pawar                 the end-of-slice encoding and then add terminate bit */
2210*c83a76b0SSuyog Pawar 
2211*c83a76b0SSuyog Pawar                 /* Signal that this is not slice segment end */
2212*c83a76b0SSuyog Pawar                 end_of_slice_seg_flag = 0;
2213*c83a76b0SSuyog Pawar 
2214*c83a76b0SSuyog Pawar                 *ps_cabac = s_cabac_after_ctb;
2215*c83a76b0SSuyog Pawar                 *((UWORD32 *)(ps_cabac->pu1_strm_buffer + ps_cabac->u4_strm_buf_offset - 4)) =
2216*c83a76b0SSuyog Pawar                     u4_cur_ctb_temp;
2217*c83a76b0SSuyog Pawar 
2218*c83a76b0SSuyog Pawar                 /*  encode terminate bin */
2219*c83a76b0SSuyog Pawar                 ret |= ihevce_cabac_encode_terminate(ps_cabac, 0, 0);
2220*c83a76b0SSuyog Pawar             }
2221*c83a76b0SSuyog Pawar 
2222*c83a76b0SSuyog Pawar             /* Update variables storing previous CTB's state in order to be
2223*c83a76b0SSuyog Pawar             able to revert to previous CTB's state */
2224*c83a76b0SSuyog Pawar             s_cabac_prev_ctb = s_cabac_after_ctb;
2225*c83a76b0SSuyog Pawar             u4_prev_ctb_temp = u4_cur_ctb_temp;
2226*c83a76b0SSuyog Pawar 
2227*c83a76b0SSuyog Pawar             i1_last_cu_qp = ps_entropy_ctxt->i1_cur_qp;
2228*c83a76b0SSuyog Pawar         }
2229*c83a76b0SSuyog Pawar         else  //No other slice segment mode supported
2230*c83a76b0SSuyog Pawar         {
2231*c83a76b0SSuyog Pawar             ASSERT(0);
2232*c83a76b0SSuyog Pawar         }
2233*c83a76b0SSuyog Pawar 
2234*c83a76b0SSuyog Pawar         AEV_TRACE("end_of_slice_flag", end_of_slice_seg_flag, ps_cabac->u4_range);
2235*c83a76b0SSuyog Pawar 
2236*c83a76b0SSuyog Pawar         if((0 == ps_entropy_ctxt->i4_ctb_x) && (!end_of_slice_seg_flag) &&
2237*c83a76b0SSuyog Pawar            (ps_pps->i1_entropy_coding_sync_enabled_flag))
2238*c83a76b0SSuyog Pawar         {
2239*c83a76b0SSuyog Pawar             /* initialize qp to slice start qp */
2240*c83a76b0SSuyog Pawar             ps_entropy_ctxt->i1_cur_qp = slice_qp;
2241*c83a76b0SSuyog Pawar 
2242*c83a76b0SSuyog Pawar             /* flush and align to byte bounary for entropy sync every row */
2243*c83a76b0SSuyog Pawar             ret |= ihevce_cabac_encode_terminate(ps_cabac, 1, 1);
2244*c83a76b0SSuyog Pawar 
2245*c83a76b0SSuyog Pawar             /*This will be entered only during row end, tap bits generated in that row to cal entry point offset*/
2246*c83a76b0SSuyog Pawar             /*add error check to make sure row count doesnt exceed the size of array allocated*/
2247*c83a76b0SSuyog Pawar             ASSERT(ps_entropy_ctxt->i4_ctb_y < MAX_NUM_CTB_ROWS_FRM);
2248*c83a76b0SSuyog Pawar             ps_slice_hdr->pu4_entry_point_offset[ps_entropy_ctxt->i4_ctb_y] =
2249*c83a76b0SSuyog Pawar                 ps_cabac->u4_strm_buf_offset;
2250*c83a76b0SSuyog Pawar 
2251*c83a76b0SSuyog Pawar             /*init the cabac context with top right neighbour*/
2252*c83a76b0SSuyog Pawar             ret |= ihevce_cabac_ctxt_row_init(ps_cabac);
2253*c83a76b0SSuyog Pawar         }
2254*c83a76b0SSuyog Pawar 
2255*c83a76b0SSuyog Pawar     } while(!end_of_slice_seg_flag);
2256*c83a76b0SSuyog Pawar 
2257*c83a76b0SSuyog Pawar     if(end_of_slice_seg_flag && ps_pps->i1_entropy_coding_sync_enabled_flag)
2258*c83a76b0SSuyog Pawar     {
2259*c83a76b0SSuyog Pawar         ps_slice_hdr->pu4_entry_point_offset[ps_entropy_ctxt->i4_ctb_y] =
2260*c83a76b0SSuyog Pawar             ps_cabac->u4_strm_buf_offset;
2261*c83a76b0SSuyog Pawar     }
2262*c83a76b0SSuyog Pawar 
2263*c83a76b0SSuyog Pawar     return ret;
2264*c83a76b0SSuyog Pawar }
2265