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_entropy_interface.c
23*c83a76b0SSuyog Pawar *
24*c83a76b0SSuyog Pawar * @brief
25*c83a76b0SSuyog Pawar * This file contains function definitions for entropy interface related to
26*c83a76b0SSuyog Pawar * memory init and process apis
27*c83a76b0SSuyog Pawar *
28*c83a76b0SSuyog Pawar * @author
29*c83a76b0SSuyog Pawar * Ittiam
30*c83a76b0SSuyog Pawar *
31*c83a76b0SSuyog Pawar * List of Functions
32*c83a76b0SSuyog Pawar * ihevce_entropy_get_num_mem_recs()
33*c83a76b0SSuyog Pawar * ihevce_entropy_size_of_out_buffer()
34*c83a76b0SSuyog Pawar * ihevce_entropy_get_mem_recs()
35*c83a76b0SSuyog Pawar * ihevce_entropy_init()
36*c83a76b0SSuyog Pawar * ihevce_entropy_encode_frame()
37*c83a76b0SSuyog Pawar *
38*c83a76b0SSuyog Pawar ******************************************************************************
39*c83a76b0SSuyog Pawar */
40*c83a76b0SSuyog Pawar
41*c83a76b0SSuyog Pawar /*****************************************************************************/
42*c83a76b0SSuyog Pawar /* File Includes */
43*c83a76b0SSuyog Pawar /*****************************************************************************/
44*c83a76b0SSuyog Pawar /* System include files */
45*c83a76b0SSuyog Pawar #include <stdio.h>
46*c83a76b0SSuyog Pawar #include <string.h>
47*c83a76b0SSuyog Pawar #include <stdlib.h>
48*c83a76b0SSuyog Pawar #include <assert.h>
49*c83a76b0SSuyog Pawar #include <stdarg.h>
50*c83a76b0SSuyog Pawar #include <math.h>
51*c83a76b0SSuyog Pawar
52*c83a76b0SSuyog Pawar /* User include files */
53*c83a76b0SSuyog Pawar #include "ihevc_typedefs.h"
54*c83a76b0SSuyog Pawar #include "itt_video_api.h"
55*c83a76b0SSuyog Pawar #include "ihevce_api.h"
56*c83a76b0SSuyog Pawar
57*c83a76b0SSuyog Pawar #include "rc_cntrl_param.h"
58*c83a76b0SSuyog Pawar #include "rc_frame_info_collector.h"
59*c83a76b0SSuyog Pawar #include "rc_look_ahead_params.h"
60*c83a76b0SSuyog Pawar
61*c83a76b0SSuyog Pawar #include "ihevc_defs.h"
62*c83a76b0SSuyog Pawar #include "ihevc_macros.h"
63*c83a76b0SSuyog Pawar #include "ihevc_debug.h"
64*c83a76b0SSuyog Pawar #include "ihevc_structs.h"
65*c83a76b0SSuyog Pawar #include "ihevc_platform_macros.h"
66*c83a76b0SSuyog Pawar #include "ihevc_deblk.h"
67*c83a76b0SSuyog Pawar #include "ihevc_itrans_recon.h"
68*c83a76b0SSuyog Pawar #include "ihevc_chroma_itrans_recon.h"
69*c83a76b0SSuyog Pawar #include "ihevc_chroma_intra_pred.h"
70*c83a76b0SSuyog Pawar #include "ihevc_intra_pred.h"
71*c83a76b0SSuyog Pawar #include "ihevc_inter_pred.h"
72*c83a76b0SSuyog Pawar #include "ihevc_mem_fns.h"
73*c83a76b0SSuyog Pawar #include "ihevc_padding.h"
74*c83a76b0SSuyog Pawar #include "ihevc_weighted_pred.h"
75*c83a76b0SSuyog Pawar #include "ihevc_sao.h"
76*c83a76b0SSuyog Pawar #include "ihevc_resi_trans.h"
77*c83a76b0SSuyog Pawar #include "ihevc_quant_iquant_ssd.h"
78*c83a76b0SSuyog Pawar #include "ihevc_cabac_tables.h"
79*c83a76b0SSuyog Pawar #include "ihevc_trans_tables.h"
80*c83a76b0SSuyog Pawar #include "ihevc_trans_macros.h"
81*c83a76b0SSuyog Pawar
82*c83a76b0SSuyog Pawar #include "ihevce_defs.h"
83*c83a76b0SSuyog Pawar #include "ihevce_lap_enc_structs.h"
84*c83a76b0SSuyog Pawar #include "ihevce_multi_thrd_structs.h"
85*c83a76b0SSuyog Pawar #include "ihevce_multi_thrd_funcs.h"
86*c83a76b0SSuyog Pawar #include "ihevce_me_common_defs.h"
87*c83a76b0SSuyog Pawar #include "ihevce_had_satd.h"
88*c83a76b0SSuyog Pawar #include "ihevce_error_codes.h"
89*c83a76b0SSuyog Pawar #include "ihevce_error_checks.h"
90*c83a76b0SSuyog Pawar #include "ihevce_bitstream.h"
91*c83a76b0SSuyog Pawar #include "ihevce_cabac.h"
92*c83a76b0SSuyog Pawar #include "ihevce_rdoq_macros.h"
93*c83a76b0SSuyog Pawar #include "ihevce_function_selector.h"
94*c83a76b0SSuyog Pawar #include "ihevce_enc_structs.h"
95*c83a76b0SSuyog Pawar #include "ihevce_global_tables.h"
96*c83a76b0SSuyog Pawar #include "ihevce_entropy_structs.h"
97*c83a76b0SSuyog Pawar #include "ihevce_entropy_interface.h"
98*c83a76b0SSuyog Pawar #include "ihevce_encode_header.h"
99*c83a76b0SSuyog Pawar #include "ihevce_encode_header_sei_vui.h"
100*c83a76b0SSuyog Pawar #include "ihevce_trace.h"
101*c83a76b0SSuyog Pawar
102*c83a76b0SSuyog Pawar #include "cast_types.h"
103*c83a76b0SSuyog Pawar #include "osal.h"
104*c83a76b0SSuyog Pawar #include "osal_defaults.h"
105*c83a76b0SSuyog Pawar
106*c83a76b0SSuyog Pawar /*****************************************************************************/
107*c83a76b0SSuyog Pawar /* Function Definitions */
108*c83a76b0SSuyog Pawar /*****************************************************************************/
109*c83a76b0SSuyog Pawar
110*c83a76b0SSuyog Pawar /**
111*c83a76b0SSuyog Pawar ******************************************************************************
112*c83a76b0SSuyog Pawar *
113*c83a76b0SSuyog Pawar * @brief Number of memory records are returned for entropy module
114*c83a76b0SSuyog Pawar *
115*c83a76b0SSuyog Pawar * @par Description
116*c83a76b0SSuyog Pawar *
117*c83a76b0SSuyog Pawar * @return number of memory records
118*c83a76b0SSuyog Pawar *
119*c83a76b0SSuyog Pawar ******************************************************************************
120*c83a76b0SSuyog Pawar */
ihevce_entropy_get_num_mem_recs(void)121*c83a76b0SSuyog Pawar WORD32 ihevce_entropy_get_num_mem_recs(void)
122*c83a76b0SSuyog Pawar {
123*c83a76b0SSuyog Pawar return (NUM_ENTROPY_MEM_RECS);
124*c83a76b0SSuyog Pawar }
125*c83a76b0SSuyog Pawar
126*c83a76b0SSuyog Pawar /**
127*c83a76b0SSuyog Pawar ******************************************************************************
128*c83a76b0SSuyog Pawar *
129*c83a76b0SSuyog Pawar * @brief Estimated bitstream buffer size basing on input dimensions
130*c83a76b0SSuyog Pawar *
131*c83a76b0SSuyog Pawar * @par Description
132*c83a76b0SSuyog Pawar *
133*c83a76b0SSuyog Pawar * @return bitstream buffer size
134*c83a76b0SSuyog Pawar *
135*c83a76b0SSuyog Pawar ******************************************************************************
136*c83a76b0SSuyog Pawar */
ihevce_entropy_size_of_out_buffer(frm_proc_ent_cod_ctxt_t * ps_curr_inp)137*c83a76b0SSuyog Pawar WORD32 ihevce_entropy_size_of_out_buffer(frm_proc_ent_cod_ctxt_t *ps_curr_inp)
138*c83a76b0SSuyog Pawar {
139*c83a76b0SSuyog Pawar WORD32 i4_size;
140*c83a76b0SSuyog Pawar
141*c83a76b0SSuyog Pawar i4_size = (WORD32)(
142*c83a76b0SSuyog Pawar ps_curr_inp->ps_sps->i2_pic_height_in_luma_samples *
143*c83a76b0SSuyog Pawar ps_curr_inp->ps_sps->i2_pic_width_in_luma_samples);
144*c83a76b0SSuyog Pawar
145*c83a76b0SSuyog Pawar return (i4_size);
146*c83a76b0SSuyog Pawar }
147*c83a76b0SSuyog Pawar
148*c83a76b0SSuyog Pawar /**
149*c83a76b0SSuyog Pawar ******************************************************************************
150*c83a76b0SSuyog Pawar *
151*c83a76b0SSuyog Pawar * @brief Populates Memory requirements of the entropy module
152*c83a76b0SSuyog Pawar *
153*c83a76b0SSuyog Pawar * @par Description
154*c83a76b0SSuyog Pawar *
155*c83a76b0SSuyog Pawar * @param[inout] ps_mem_tab
156*c83a76b0SSuyog Pawar * pointer to memory descriptors table
157*c83a76b0SSuyog Pawar *
158*c83a76b0SSuyog Pawar * @param[in] ps_init_prms
159*c83a76b0SSuyog Pawar * Create time static parameters
160*c83a76b0SSuyog Pawar *
161*c83a76b0SSuyog Pawar * @param[in] i4_mem_space
162*c83a76b0SSuyog Pawar * memspace in whihc memory request should be done
163*c83a76b0SSuyog Pawar *
164*c83a76b0SSuyog Pawar * @return number of memory requirements filled
165*c83a76b0SSuyog Pawar *
166*c83a76b0SSuyog Pawar ******************************************************************************
167*c83a76b0SSuyog Pawar */
ihevce_entropy_get_mem_recs(iv_mem_rec_t * ps_mem_tab,ihevce_static_cfg_params_t * ps_init_prms,WORD32 i4_mem_space,WORD32 i4_resolution_id)168*c83a76b0SSuyog Pawar WORD32 ihevce_entropy_get_mem_recs(
169*c83a76b0SSuyog Pawar iv_mem_rec_t *ps_mem_tab,
170*c83a76b0SSuyog Pawar ihevce_static_cfg_params_t *ps_init_prms,
171*c83a76b0SSuyog Pawar WORD32 i4_mem_space,
172*c83a76b0SSuyog Pawar WORD32 i4_resolution_id)
173*c83a76b0SSuyog Pawar {
174*c83a76b0SSuyog Pawar /* memories should be requested assuming worst case requirememnts */
175*c83a76b0SSuyog Pawar WORD32 max_width = ps_init_prms->s_tgt_lyr_prms.as_tgt_params[i4_resolution_id].i4_width;
176*c83a76b0SSuyog Pawar WORD32 max_height = ps_init_prms->s_tgt_lyr_prms.as_tgt_params[i4_resolution_id].i4_height;
177*c83a76b0SSuyog Pawar WORD32 max_align_width = ALIGN64(max_width);
178*c83a76b0SSuyog Pawar WORD32 max_align_height = ALIGN64(max_height);
179*c83a76b0SSuyog Pawar
180*c83a76b0SSuyog Pawar /* Module context structure */
181*c83a76b0SSuyog Pawar ps_mem_tab[ENTROPY_CTXT].i4_mem_size = sizeof(entropy_context_t);
182*c83a76b0SSuyog Pawar ps_mem_tab[ENTROPY_CTXT].e_mem_type = (IV_MEM_TYPE_T)i4_mem_space;
183*c83a76b0SSuyog Pawar ps_mem_tab[ENTROPY_CTXT].i4_mem_alignment = 64;
184*c83a76b0SSuyog Pawar
185*c83a76b0SSuyog Pawar /* top row cu skip flags (1 bit per 8x8CU) */
186*c83a76b0SSuyog Pawar ps_mem_tab[ENTROPY_TOP_SKIP_FLAGS].i4_mem_size = max_align_width >> 6;
187*c83a76b0SSuyog Pawar ps_mem_tab[ENTROPY_TOP_SKIP_FLAGS].e_mem_type = (IV_MEM_TYPE_T)i4_mem_space;
188*c83a76b0SSuyog Pawar ps_mem_tab[ENTROPY_TOP_SKIP_FLAGS].i4_mem_alignment = 64;
189*c83a76b0SSuyog Pawar
190*c83a76b0SSuyog Pawar /* top row CU Depth (1 byte per 8x8CU) */
191*c83a76b0SSuyog Pawar ps_mem_tab[ENTROPY_TOP_CU_DEPTH].i4_mem_size = (max_align_width >> 3);
192*c83a76b0SSuyog Pawar ps_mem_tab[ENTROPY_TOP_CU_DEPTH].e_mem_type = (IV_MEM_TYPE_T)i4_mem_space;
193*c83a76b0SSuyog Pawar ps_mem_tab[ENTROPY_TOP_CU_DEPTH].i4_mem_alignment = 64;
194*c83a76b0SSuyog Pawar
195*c83a76b0SSuyog Pawar /* Dummy_buffer to handle first pass MBR case*/
196*c83a76b0SSuyog Pawar ps_mem_tab[ENTROPY_DUMMY_OUT_BUF].i4_mem_size = (max_align_width * max_align_height * 2);
197*c83a76b0SSuyog Pawar ps_mem_tab[ENTROPY_DUMMY_OUT_BUF].e_mem_type = (IV_MEM_TYPE_T)i4_mem_space;
198*c83a76b0SSuyog Pawar ps_mem_tab[ENTROPY_DUMMY_OUT_BUF].i4_mem_alignment = 64;
199*c83a76b0SSuyog Pawar
200*c83a76b0SSuyog Pawar return (NUM_ENTROPY_MEM_RECS);
201*c83a76b0SSuyog Pawar }
202*c83a76b0SSuyog Pawar
203*c83a76b0SSuyog Pawar /**
204*c83a76b0SSuyog Pawar ******************************************************************************
205*c83a76b0SSuyog Pawar *
206*c83a76b0SSuyog Pawar * @brief Intialization of entropy module
207*c83a76b0SSuyog Pawar *
208*c83a76b0SSuyog Pawar * @par Description
209*c83a76b0SSuyog Pawar * pointers of the memory requests done in ihevce_entropy_get_mem_recs() are
210*c83a76b0SSuyog Pawar * used to initialized the entropy module and the handle is returned
211*c83a76b0SSuyog Pawar *
212*c83a76b0SSuyog Pawar * @param[inout] ps_mem_tab
213*c83a76b0SSuyog Pawar * pointer to memory descriptors table
214*c83a76b0SSuyog Pawar *
215*c83a76b0SSuyog Pawar * @param[in] ps_init_prms
216*c83a76b0SSuyog Pawar * Create time static parameters
217*c83a76b0SSuyog Pawar *
218*c83a76b0SSuyog Pawar * @return
219*c83a76b0SSuyog Pawar * Handle of the entropy module returned as void ptr
220*c83a76b0SSuyog Pawar *
221*c83a76b0SSuyog Pawar ******************************************************************************
222*c83a76b0SSuyog Pawar */
ihevce_entropy_init(iv_mem_rec_t * ps_mem_tab,ihevce_static_cfg_params_t * ps_init_prms,void * pv_tile_params_base,WORD32 i4_res_id)223*c83a76b0SSuyog Pawar void *ihevce_entropy_init(
224*c83a76b0SSuyog Pawar iv_mem_rec_t *ps_mem_tab,
225*c83a76b0SSuyog Pawar ihevce_static_cfg_params_t *ps_init_prms,
226*c83a76b0SSuyog Pawar void *pv_tile_params_base,
227*c83a76b0SSuyog Pawar WORD32 i4_res_id)
228*c83a76b0SSuyog Pawar {
229*c83a76b0SSuyog Pawar entropy_context_t *ps_entropy_ctxt;
230*c83a76b0SSuyog Pawar
231*c83a76b0SSuyog Pawar /* Entropy state structure */
232*c83a76b0SSuyog Pawar ps_entropy_ctxt = (entropy_context_t *)ps_mem_tab[ENTROPY_CTXT].pv_base;
233*c83a76b0SSuyog Pawar memset(ps_entropy_ctxt, 0, sizeof(entropy_context_t));
234*c83a76b0SSuyog Pawar
235*c83a76b0SSuyog Pawar ps_entropy_ctxt->pu1_skip_cu_top = (UWORD8 *)ps_mem_tab[ENTROPY_TOP_SKIP_FLAGS].pv_base;
236*c83a76b0SSuyog Pawar ps_entropy_ctxt->pu1_cu_depth_top = (UWORD8 *)ps_mem_tab[ENTROPY_TOP_CU_DEPTH].pv_base;
237*c83a76b0SSuyog Pawar ps_entropy_ctxt->pv_dummy_out_buf = ps_mem_tab[ENTROPY_DUMMY_OUT_BUF].pv_base;
238*c83a76b0SSuyog Pawar ps_entropy_ctxt->i4_bitstream_buf_size = ps_mem_tab[ENTROPY_DUMMY_OUT_BUF].i4_mem_size;
239*c83a76b0SSuyog Pawar
240*c83a76b0SSuyog Pawar /* perform all one time initialisation here */
241*c83a76b0SSuyog Pawar /*************************************************************************/
242*c83a76b0SSuyog Pawar /* Note pu1_cbf_cb, pu1_cbf_cr initialization are done with array idx 1 */
243*c83a76b0SSuyog Pawar /* This is because these flags are accessed as pu1_cbf_cb[tfr_depth - 1] */
244*c83a76b0SSuyog Pawar /* without cheking for tfr_depth= 0 */
245*c83a76b0SSuyog Pawar /*************************************************************************/
246*c83a76b0SSuyog Pawar ps_entropy_ctxt->apu1_cbf_cb[0] = &ps_entropy_ctxt->au1_cbf_cb[0][1];
247*c83a76b0SSuyog Pawar ps_entropy_ctxt->apu1_cbf_cr[0] = &ps_entropy_ctxt->au1_cbf_cr[0][1];
248*c83a76b0SSuyog Pawar ps_entropy_ctxt->apu1_cbf_cb[1] = &ps_entropy_ctxt->au1_cbf_cb[1][1];
249*c83a76b0SSuyog Pawar ps_entropy_ctxt->apu1_cbf_cr[1] = &ps_entropy_ctxt->au1_cbf_cr[1][1];
250*c83a76b0SSuyog Pawar
251*c83a76b0SSuyog Pawar memset(ps_entropy_ctxt->au1_cbf_cb, 0, (MAX_TFR_DEPTH + 1) * 2 * sizeof(UWORD8));
252*c83a76b0SSuyog Pawar
253*c83a76b0SSuyog Pawar /* register codec level */
254*c83a76b0SSuyog Pawar ps_entropy_ctxt->i4_codec_level =
255*c83a76b0SSuyog Pawar ps_init_prms->s_tgt_lyr_prms.as_tgt_params[i4_res_id].i4_codec_level;
256*c83a76b0SSuyog Pawar
257*c83a76b0SSuyog Pawar /* Flag to enable/disable insertion of SPS, VPS & PPS at every CRA frame */
258*c83a76b0SSuyog Pawar ps_entropy_ctxt->i4_sps_at_cdr_enable = ps_init_prms->s_out_strm_prms.i4_sps_at_cdr_enable;
259*c83a76b0SSuyog Pawar
260*c83a76b0SSuyog Pawar /* Store Tile params base into entropy context */
261*c83a76b0SSuyog Pawar ps_entropy_ctxt->pv_tile_params_base = pv_tile_params_base;
262*c83a76b0SSuyog Pawar
263*c83a76b0SSuyog Pawar ps_entropy_ctxt->pv_sys_api = (void *)&ps_init_prms->s_sys_api;
264*c83a76b0SSuyog Pawar
265*c83a76b0SSuyog Pawar ps_entropy_ctxt->i4_slice_segment_mode = ps_init_prms->s_slice_params.i4_slice_segment_mode;
266*c83a76b0SSuyog Pawar
267*c83a76b0SSuyog Pawar /* Set slice segment length */
268*c83a76b0SSuyog Pawar if((ps_entropy_ctxt->i4_slice_segment_mode == 1) ||
269*c83a76b0SSuyog Pawar (ps_entropy_ctxt->i4_slice_segment_mode == 2))
270*c83a76b0SSuyog Pawar {
271*c83a76b0SSuyog Pawar ps_entropy_ctxt->i4_slice_segment_max_length =
272*c83a76b0SSuyog Pawar ps_init_prms->s_slice_params.i4_slice_segment_argument;
273*c83a76b0SSuyog Pawar }
274*c83a76b0SSuyog Pawar else
275*c83a76b0SSuyog Pawar {
276*c83a76b0SSuyog Pawar ps_entropy_ctxt->i4_slice_segment_max_length = 0;
277*c83a76b0SSuyog Pawar }
278*c83a76b0SSuyog Pawar
279*c83a76b0SSuyog Pawar /* return the handle to caller */
280*c83a76b0SSuyog Pawar return ((void *)ps_entropy_ctxt);
281*c83a76b0SSuyog Pawar }
282*c83a76b0SSuyog Pawar
283*c83a76b0SSuyog Pawar /**
284*c83a76b0SSuyog Pawar ******************************************************************************
285*c83a76b0SSuyog Pawar *
286*c83a76b0SSuyog Pawar * @brief entry point for entropy coding of a frame
287*c83a76b0SSuyog Pawar *
288*c83a76b0SSuyog Pawar * @par Description
289*c83a76b0SSuyog Pawar * This function generates nal headers like SPS/PPS/slice header and call the
290*c83a76b0SSuyog Pawar * slice data entropy coding function
291*c83a76b0SSuyog Pawar *
292*c83a76b0SSuyog Pawar * @param[in] ps_enc_ctxt
293*c83a76b0SSuyog Pawar * pointer to encoder context (handle)
294*c83a76b0SSuyog Pawar *
295*c83a76b0SSuyog Pawar * @param[out] ps_curr_out
296*c83a76b0SSuyog Pawar * pointer to output data buffer context where bitstream is generated
297*c83a76b0SSuyog Pawar *
298*c83a76b0SSuyog Pawar * @param[out] ps_curr_inp
299*c83a76b0SSuyog Pawar * pointer to entropy input params context
300*c83a76b0SSuyog Pawar *
301*c83a76b0SSuyog Pawar * @return success or failure error code
302*c83a76b0SSuyog Pawar *
303*c83a76b0SSuyog Pawar ******************************************************************************
304*c83a76b0SSuyog Pawar */
ihevce_entropy_encode_frame(void * pv_entropy_hdl,iv_output_data_buffs_t * ps_curr_out,frm_proc_ent_cod_ctxt_t * ps_curr_inp,WORD32 i4_out_buf_size)305*c83a76b0SSuyog Pawar WORD32 ihevce_entropy_encode_frame(
306*c83a76b0SSuyog Pawar void *pv_entropy_hdl,
307*c83a76b0SSuyog Pawar iv_output_data_buffs_t *ps_curr_out,
308*c83a76b0SSuyog Pawar frm_proc_ent_cod_ctxt_t *ps_curr_inp,
309*c83a76b0SSuyog Pawar WORD32 i4_out_buf_size)
310*c83a76b0SSuyog Pawar {
311*c83a76b0SSuyog Pawar WORD32 ret = IHEVCE_SUCCESS;
312*c83a76b0SSuyog Pawar WORD32 tile_ctr, total_tiles = 1;
313*c83a76b0SSuyog Pawar entropy_context_t *ps_entropy_ctxt = (entropy_context_t *)pv_entropy_hdl;
314*c83a76b0SSuyog Pawar
315*c83a76b0SSuyog Pawar /* current frame slice type and nal type */
316*c83a76b0SSuyog Pawar WORD32 slice_type = ps_curr_inp->s_slice_hdr.i1_slice_type;
317*c83a76b0SSuyog Pawar
318*c83a76b0SSuyog Pawar /* current frame slice type and nal type */
319*c83a76b0SSuyog Pawar WORD32 nal_type = ps_curr_inp->i4_slice_nal_type;
320*c83a76b0SSuyog Pawar
321*c83a76b0SSuyog Pawar /* read vps, sps and pps from input params */
322*c83a76b0SSuyog Pawar vps_t *ps_vps = ps_curr_inp->ps_vps;
323*c83a76b0SSuyog Pawar sps_t *ps_sps = ps_curr_inp->ps_sps;
324*c83a76b0SSuyog Pawar pps_t *ps_pps = ps_curr_inp->ps_pps;
325*c83a76b0SSuyog Pawar #ifndef DISABLE_SEI
326*c83a76b0SSuyog Pawar sei_params_t *ps_sei = &ps_curr_inp->s_sei;
327*c83a76b0SSuyog Pawar #endif
328*c83a76b0SSuyog Pawar ihevce_tile_params_t *ps_tile_params_base;
329*c83a76b0SSuyog Pawar WORD32 out_buf_size = i4_out_buf_size;
330*c83a76b0SSuyog Pawar
331*c83a76b0SSuyog Pawar /* Headers are repeated once per IDR. Should be changed to every CRA */
332*c83a76b0SSuyog Pawar WORD32 insert_vps_sps_pps =
333*c83a76b0SSuyog Pawar ((slice_type == ISLICE) &&
334*c83a76b0SSuyog Pawar (((NAL_IDR_N_LP == nal_type) || (NAL_CRA == nal_type)) || (NAL_IDR_W_LP == nal_type)));
335*c83a76b0SSuyog Pawar
336*c83a76b0SSuyog Pawar WORD32 insert_per_cra =
337*c83a76b0SSuyog Pawar ((slice_type == ISLICE) &&
338*c83a76b0SSuyog Pawar (((NAL_IDR_N_LP == nal_type) || (NAL_CRA == nal_type)) || (NAL_IDR_W_LP == nal_type)));
339*c83a76b0SSuyog Pawar bitstrm_t *ps_bitstrm = &ps_entropy_ctxt->s_bit_strm;
340*c83a76b0SSuyog Pawar
341*c83a76b0SSuyog Pawar ULWORD64 u8_bits_slice_header_prev;
342*c83a76b0SSuyog Pawar
343*c83a76b0SSuyog Pawar WORD32 i4_slice_segment_max_length_bckp;
344*c83a76b0SSuyog Pawar WORD32 i4_max_num_slices;
345*c83a76b0SSuyog Pawar
346*c83a76b0SSuyog Pawar ihevce_sys_api_t *ps_sys_api = (ihevce_sys_api_t *)ps_entropy_ctxt->pv_sys_api;
347*c83a76b0SSuyog Pawar
348*c83a76b0SSuyog Pawar #if POPULATE_NAL_OFFSET
349*c83a76b0SSuyog Pawar ULWORD64 u8_bitstream_base = (ULWORD64)ps_curr_out->pv_bitstream_bufs;
350*c83a76b0SSuyog Pawar #endif
351*c83a76b0SSuyog Pawar if(0 == ps_entropy_ctxt->i4_sps_at_cdr_enable)
352*c83a76b0SSuyog Pawar {
353*c83a76b0SSuyog Pawar insert_vps_sps_pps =
354*c83a76b0SSuyog Pawar ((slice_type == ISLICE) && ((NAL_IDR_N_LP == nal_type) || (NAL_IDR_W_LP == nal_type)));
355*c83a76b0SSuyog Pawar }
356*c83a76b0SSuyog Pawar /* intialize vps, sps, pps, sei and slice header in entropy context */
357*c83a76b0SSuyog Pawar ps_entropy_ctxt->ps_vps = ps_vps;
358*c83a76b0SSuyog Pawar ps_entropy_ctxt->ps_sps = ps_sps;
359*c83a76b0SSuyog Pawar ps_entropy_ctxt->ps_pps = ps_pps;
360*c83a76b0SSuyog Pawar #ifndef DISABLE_SEI
361*c83a76b0SSuyog Pawar ps_entropy_ctxt->ps_sei = ps_sei;
362*c83a76b0SSuyog Pawar #endif
363*c83a76b0SSuyog Pawar ps_entropy_ctxt->ps_slice_hdr = &ps_curr_inp->s_slice_hdr;
364*c83a76b0SSuyog Pawar ps_entropy_ctxt->i4_is_cu_cbf_zero = 1;
365*c83a76b0SSuyog Pawar
366*c83a76b0SSuyog Pawar ps_entropy_ctxt->ps_pic_level_info = &ps_curr_inp->s_pic_level_info;
367*c83a76b0SSuyog Pawar
368*c83a76b0SSuyog Pawar /* intialize the frame level ctb pointer for current slice */
369*c83a76b0SSuyog Pawar ps_entropy_ctxt->ps_frm_ctb = ps_curr_inp->ps_frm_ctb_data;
370*c83a76b0SSuyog Pawar
371*c83a76b0SSuyog Pawar /* Initiallizing to indicate the start of frame */
372*c83a76b0SSuyog Pawar ps_entropy_ctxt->i4_next_slice_seg_x = 0;
373*c83a76b0SSuyog Pawar ps_entropy_ctxt->i4_next_slice_seg_y = 0;
374*c83a76b0SSuyog Pawar
375*c83a76b0SSuyog Pawar /* enable the residue encode flag */
376*c83a76b0SSuyog Pawar ps_entropy_ctxt->i4_enable_res_encode = 1;
377*c83a76b0SSuyog Pawar
378*c83a76b0SSuyog Pawar /* Initialize the bitstream engine */
379*c83a76b0SSuyog Pawar ret |= ihevce_bitstrm_init(ps_bitstrm, (UWORD8 *)ps_curr_out->pv_bitstream_bufs, out_buf_size);
380*c83a76b0SSuyog Pawar
381*c83a76b0SSuyog Pawar /* Reset Bitstream NAL counter */
382*c83a76b0SSuyog Pawar ps_bitstrm->i4_num_nal = 0;
383*c83a76b0SSuyog Pawar
384*c83a76b0SSuyog Pawar /*PIC INFO: Store the Bits before slice header is encoded*/
385*c83a76b0SSuyog Pawar u8_bits_slice_header_prev = (ps_bitstrm->u4_strm_buf_offset * 8);
386*c83a76b0SSuyog Pawar
387*c83a76b0SSuyog Pawar /* generate AUD if enabled from the application */
388*c83a76b0SSuyog Pawar if(1 == ps_curr_inp->i1_aud_present_flag)
389*c83a76b0SSuyog Pawar {
390*c83a76b0SSuyog Pawar UWORD8 u1_pic_type;
391*c83a76b0SSuyog Pawar
392*c83a76b0SSuyog Pawar switch(slice_type)
393*c83a76b0SSuyog Pawar {
394*c83a76b0SSuyog Pawar case ISLICE:
395*c83a76b0SSuyog Pawar u1_pic_type = 0;
396*c83a76b0SSuyog Pawar break;
397*c83a76b0SSuyog Pawar case PSLICE:
398*c83a76b0SSuyog Pawar u1_pic_type = 1;
399*c83a76b0SSuyog Pawar break;
400*c83a76b0SSuyog Pawar default:
401*c83a76b0SSuyog Pawar u1_pic_type = 2;
402*c83a76b0SSuyog Pawar break;
403*c83a76b0SSuyog Pawar }
404*c83a76b0SSuyog Pawar
405*c83a76b0SSuyog Pawar ret |= ihevce_generate_aud(ps_bitstrm, u1_pic_type);
406*c83a76b0SSuyog Pawar }
407*c83a76b0SSuyog Pawar
408*c83a76b0SSuyog Pawar if(insert_vps_sps_pps)
409*c83a76b0SSuyog Pawar {
410*c83a76b0SSuyog Pawar /* generate vps */
411*c83a76b0SSuyog Pawar ret |= ihevce_generate_vps(ps_bitstrm, ps_entropy_ctxt->ps_vps);
412*c83a76b0SSuyog Pawar
413*c83a76b0SSuyog Pawar /* generate sps */
414*c83a76b0SSuyog Pawar ret |= ihevce_generate_sps(ps_bitstrm, ps_entropy_ctxt->ps_sps);
415*c83a76b0SSuyog Pawar
416*c83a76b0SSuyog Pawar /* generate pps */
417*c83a76b0SSuyog Pawar ret |= ihevce_generate_pps(ps_bitstrm, ps_entropy_ctxt->ps_pps);
418*c83a76b0SSuyog Pawar }
419*c83a76b0SSuyog Pawar
420*c83a76b0SSuyog Pawar #ifndef DISABLE_SEI
421*c83a76b0SSuyog Pawar /* generate sei */
422*c83a76b0SSuyog Pawar if(1 == ps_entropy_ctxt->ps_sei->i1_sei_parameters_present_flag)
423*c83a76b0SSuyog Pawar {
424*c83a76b0SSuyog Pawar WORD32 i4_insert_prefix_sei =
425*c83a76b0SSuyog Pawar ps_entropy_ctxt->ps_sei->i1_buf_period_params_present_flag ||
426*c83a76b0SSuyog Pawar ps_entropy_ctxt->ps_sei->i1_pic_timing_params_present_flag ||
427*c83a76b0SSuyog Pawar ps_entropy_ctxt->ps_sei->i1_recovery_point_params_present_flag ||
428*c83a76b0SSuyog Pawar ps_entropy_ctxt->ps_sei->i4_sei_mastering_disp_colour_vol_params_present_flags ||
429*c83a76b0SSuyog Pawar ps_curr_inp->u4_num_sei_payload || ps_curr_inp->s_sei.i1_sei_cll_enable;
430*c83a76b0SSuyog Pawar
431*c83a76b0SSuyog Pawar if(i4_insert_prefix_sei)
432*c83a76b0SSuyog Pawar {
433*c83a76b0SSuyog Pawar ret |= ihevce_generate_sei(
434*c83a76b0SSuyog Pawar ps_bitstrm,
435*c83a76b0SSuyog Pawar ps_entropy_ctxt->ps_sei,
436*c83a76b0SSuyog Pawar &ps_entropy_ctxt->ps_sps->s_vui_parameters,
437*c83a76b0SSuyog Pawar insert_per_cra,
438*c83a76b0SSuyog Pawar NAL_PREFIX_SEI,
439*c83a76b0SSuyog Pawar ps_curr_inp->u4_num_sei_payload,
440*c83a76b0SSuyog Pawar &ps_curr_inp->as_sei_payload[0]);
441*c83a76b0SSuyog Pawar }
442*c83a76b0SSuyog Pawar }
443*c83a76b0SSuyog Pawar #endif
444*c83a76b0SSuyog Pawar
445*c83a76b0SSuyog Pawar /*PIC INFO: Populate slice header bits */
446*c83a76b0SSuyog Pawar ps_entropy_ctxt->ps_pic_level_info->u8_bits_estimated_slice_header +=
447*c83a76b0SSuyog Pawar (ps_bitstrm->u4_strm_buf_offset * 8) - u8_bits_slice_header_prev;
448*c83a76b0SSuyog Pawar
449*c83a76b0SSuyog Pawar ps_tile_params_base = (ihevce_tile_params_t *)ps_entropy_ctxt->pv_tile_params_base;
450*c83a76b0SSuyog Pawar
451*c83a76b0SSuyog Pawar ps_curr_out->i4_bytes_generated = 0; //Init
452*c83a76b0SSuyog Pawar
453*c83a76b0SSuyog Pawar /* ------------------- Initialize non-VCL prefix NAL Size/offsets --------------------*/
454*c83a76b0SSuyog Pawar {
455*c83a76b0SSuyog Pawar WORD32 num_non_vcl_prefix_nals = ps_bitstrm->i4_num_nal;
456*c83a76b0SSuyog Pawar WORD32 ctr = 0;
457*c83a76b0SSuyog Pawar
458*c83a76b0SSuyog Pawar ASSERT(num_non_vcl_prefix_nals <= MAX_NUM_PREFIX_NALS_PER_AU);
459*c83a76b0SSuyog Pawar
460*c83a76b0SSuyog Pawar ps_curr_out->i4_num_non_vcl_prefix_nals = num_non_vcl_prefix_nals;
461*c83a76b0SSuyog Pawar for(ctr = 0; ctr < MIN(num_non_vcl_prefix_nals, MAX_NUM_PREFIX_NALS_PER_AU); ctr++)
462*c83a76b0SSuyog Pawar {
463*c83a76b0SSuyog Pawar /* NAL offset is derive by subtracting Bistream base from NAL start pointer */
464*c83a76b0SSuyog Pawar ULWORD64 u8_cur_nal_start = (ULWORD64)ps_bitstrm->apu1_nal_start[ctr];
465*c83a76b0SSuyog Pawar
466*c83a76b0SSuyog Pawar #if POPULATE_NAL_SIZE
467*c83a76b0SSuyog Pawar
468*c83a76b0SSuyog Pawar /* ----------Populate NAL Size -------------*/
469*c83a76b0SSuyog Pawar if((ctr + 1) < num_non_vcl_prefix_nals)
470*c83a76b0SSuyog Pawar {
471*c83a76b0SSuyog Pawar ULWORD64 u8_next_nal_start = (ULWORD64)ps_bitstrm->apu1_nal_start[ctr + 1];
472*c83a76b0SSuyog Pawar ps_curr_out->ai4_size_non_vcl_prefix_nals[ctr] =
473*c83a76b0SSuyog Pawar (UWORD32)(u8_next_nal_start - u8_cur_nal_start);
474*c83a76b0SSuyog Pawar }
475*c83a76b0SSuyog Pawar else
476*c83a76b0SSuyog Pawar {
477*c83a76b0SSuyog Pawar ULWORD64 u8_next_nal_start =
478*c83a76b0SSuyog Pawar (ULWORD64)ps_bitstrm->pu1_strm_buffer + ps_bitstrm->u4_strm_buf_offset;
479*c83a76b0SSuyog Pawar ps_curr_out->ai4_size_non_vcl_prefix_nals[ctr] =
480*c83a76b0SSuyog Pawar (UWORD32)(u8_next_nal_start - u8_cur_nal_start);
481*c83a76b0SSuyog Pawar }
482*c83a76b0SSuyog Pawar ASSERT(ps_curr_out->ai4_size_non_vcl_prefix_nals[ctr] > 0);
483*c83a76b0SSuyog Pawar
484*c83a76b0SSuyog Pawar #elif POPULATE_NAL_OFFSET
485*c83a76b0SSuyog Pawar
486*c83a76b0SSuyog Pawar /* ----------Populate NAL Offset -------------*/
487*c83a76b0SSuyog Pawar
488*c83a76b0SSuyog Pawar ASSERT(u8_cur_nal_start >= u8_bitstream_base);
489*c83a76b0SSuyog Pawar ps_curr_out->ai4_off_non_vcl_prefix_nals[ctr] =
490*c83a76b0SSuyog Pawar (UWORD32)(u8_cur_nal_start - u8_bitstream_base);
491*c83a76b0SSuyog Pawar
492*c83a76b0SSuyog Pawar if(ctr)
493*c83a76b0SSuyog Pawar {
494*c83a76b0SSuyog Pawar /* sanity check on increasing NAL offsets */
495*c83a76b0SSuyog Pawar ASSERT(
496*c83a76b0SSuyog Pawar ps_curr_out->ai4_off_non_vcl_prefix_nals[ctr] >
497*c83a76b0SSuyog Pawar ps_curr_out->ai4_off_non_vcl_prefix_nals[ctr - 1]);
498*c83a76b0SSuyog Pawar }
499*c83a76b0SSuyog Pawar #endif /* POPULATE_NAL_SIZE */
500*c83a76b0SSuyog Pawar }
501*c83a76b0SSuyog Pawar }
502*c83a76b0SSuyog Pawar
503*c83a76b0SSuyog Pawar total_tiles = ps_tile_params_base->i4_num_tiles;
504*c83a76b0SSuyog Pawar
505*c83a76b0SSuyog Pawar /* frame level NUM slices related params initialisations */
506*c83a76b0SSuyog Pawar {
507*c83a76b0SSuyog Pawar WORD32 codec_level_index = ihevce_get_level_index(ps_entropy_ctxt->i4_codec_level);
508*c83a76b0SSuyog Pawar
509*c83a76b0SSuyog Pawar i4_max_num_slices = g_as_level_data[codec_level_index].i4_max_slices_per_picture;
510*c83a76b0SSuyog Pawar ps_entropy_ctxt->i4_num_slice_seg = 0;
511*c83a76b0SSuyog Pawar }
512*c83a76b0SSuyog Pawar
513*c83a76b0SSuyog Pawar /* back up slice arg length before pic encoding */
514*c83a76b0SSuyog Pawar i4_slice_segment_max_length_bckp = ps_entropy_ctxt->i4_slice_segment_max_length;
515*c83a76b0SSuyog Pawar
516*c83a76b0SSuyog Pawar for(tile_ctr = 0; tile_ctr < total_tiles; tile_ctr++)
517*c83a76b0SSuyog Pawar {
518*c83a76b0SSuyog Pawar WORD32 i4_end_of_slice = 0;
519*c83a76b0SSuyog Pawar
520*c83a76b0SSuyog Pawar /* Loop over all the slice segments */
521*c83a76b0SSuyog Pawar while(0 == i4_end_of_slice)
522*c83a76b0SSuyog Pawar {
523*c83a76b0SSuyog Pawar WORD32 i4_bytes_generated, i4_slice_header_bits;
524*c83a76b0SSuyog Pawar
525*c83a76b0SSuyog Pawar /*PIC INFO: Store the Bits before slice header is encoded*/
526*c83a76b0SSuyog Pawar u8_bits_slice_header_prev = (ps_bitstrm->u4_strm_buf_offset * 8);
527*c83a76b0SSuyog Pawar
528*c83a76b0SSuyog Pawar /* generate slice header */
529*c83a76b0SSuyog Pawar ret |= ihevce_generate_slice_header(
530*c83a76b0SSuyog Pawar ps_bitstrm,
531*c83a76b0SSuyog Pawar nal_type,
532*c83a76b0SSuyog Pawar ps_entropy_ctxt->ps_slice_hdr,
533*c83a76b0SSuyog Pawar ps_entropy_ctxt->ps_pps,
534*c83a76b0SSuyog Pawar ps_entropy_ctxt->ps_sps,
535*c83a76b0SSuyog Pawar &ps_entropy_ctxt->s_dup_bit_strm_ent_offset,
536*c83a76b0SSuyog Pawar &ps_entropy_ctxt->s_cabac_ctxt.u4_first_slice_start_offset,
537*c83a76b0SSuyog Pawar (ps_tile_params_base + tile_ctr),
538*c83a76b0SSuyog Pawar ps_entropy_ctxt->i4_next_slice_seg_x,
539*c83a76b0SSuyog Pawar ps_entropy_ctxt->i4_next_slice_seg_y);
540*c83a76b0SSuyog Pawar
541*c83a76b0SSuyog Pawar i4_slice_header_bits =
542*c83a76b0SSuyog Pawar (ps_bitstrm->u4_strm_buf_offset * 8) - (WORD32)u8_bits_slice_header_prev;
543*c83a76b0SSuyog Pawar
544*c83a76b0SSuyog Pawar /* Update slice segment length with bytes in slice header */
545*c83a76b0SSuyog Pawar if(2 == ps_entropy_ctxt->i4_slice_segment_mode)
546*c83a76b0SSuyog Pawar {
547*c83a76b0SSuyog Pawar ps_entropy_ctxt->i4_slice_seg_len = (i4_slice_header_bits / 8);
548*c83a76b0SSuyog Pawar }
549*c83a76b0SSuyog Pawar else //Initiallize to zero
550*c83a76b0SSuyog Pawar {
551*c83a76b0SSuyog Pawar ps_entropy_ctxt->i4_slice_seg_len = 0;
552*c83a76b0SSuyog Pawar }
553*c83a76b0SSuyog Pawar
554*c83a76b0SSuyog Pawar /*PIC INFO: Populate slice header bits */
555*c83a76b0SSuyog Pawar ps_entropy_ctxt->ps_pic_level_info->u8_bits_estimated_slice_header +=
556*c83a76b0SSuyog Pawar i4_slice_header_bits;
557*c83a76b0SSuyog Pawar
558*c83a76b0SSuyog Pawar /* check if number of slices generated in is MAX -1 as per codec_level */
559*c83a76b0SSuyog Pawar if(ps_entropy_ctxt->i4_num_slice_seg == (i4_max_num_slices - 1))
560*c83a76b0SSuyog Pawar {
561*c83a76b0SSuyog Pawar /* i4_slice_segment_max_length is set to a huge positive value */
562*c83a76b0SSuyog Pawar /* so that remaining CTBS in the picture gets encoded as a single slice */
563*c83a76b0SSuyog Pawar ps_entropy_ctxt->i4_slice_segment_max_length = 0x7FFFFFFF;
564*c83a76b0SSuyog Pawar }
565*c83a76b0SSuyog Pawar
566*c83a76b0SSuyog Pawar /* encode the slice data */
567*c83a76b0SSuyog Pawar ret |= ihevce_encode_slice_data(
568*c83a76b0SSuyog Pawar ps_entropy_ctxt, (ps_tile_params_base + tile_ctr), &i4_end_of_slice);
569*c83a76b0SSuyog Pawar
570*c83a76b0SSuyog Pawar /* increment the number of slices generated */
571*c83a76b0SSuyog Pawar ps_entropy_ctxt->i4_num_slice_seg++;
572*c83a76b0SSuyog Pawar
573*c83a76b0SSuyog Pawar if(1 == ps_pps->i1_entropy_coding_sync_enabled_flag)
574*c83a76b0SSuyog Pawar {
575*c83a76b0SSuyog Pawar /*after encoding is done each slice offset is available. Enter these offset in slice header*/
576*c83a76b0SSuyog Pawar ihevce_insert_entry_offset_slice_header(
577*c83a76b0SSuyog Pawar &ps_entropy_ctxt->s_dup_bit_strm_ent_offset,
578*c83a76b0SSuyog Pawar ps_entropy_ctxt->ps_slice_hdr,
579*c83a76b0SSuyog Pawar ps_entropy_ctxt->ps_pps,
580*c83a76b0SSuyog Pawar ps_entropy_ctxt->s_cabac_ctxt.u4_first_slice_start_offset);
581*c83a76b0SSuyog Pawar }
582*c83a76b0SSuyog Pawar
583*c83a76b0SSuyog Pawar /* compute the bytes generated and return */
584*c83a76b0SSuyog Pawar if(1 == ps_pps->i1_entropy_coding_sync_enabled_flag)
585*c83a76b0SSuyog Pawar {
586*c83a76b0SSuyog Pawar i4_bytes_generated = ps_entropy_ctxt->s_dup_bit_strm_ent_offset.u4_strm_buf_offset;
587*c83a76b0SSuyog Pawar }
588*c83a76b0SSuyog Pawar else
589*c83a76b0SSuyog Pawar {
590*c83a76b0SSuyog Pawar i4_bytes_generated = ps_entropy_ctxt->s_cabac_ctxt.u4_strm_buf_offset;
591*c83a76b0SSuyog Pawar }
592*c83a76b0SSuyog Pawar
593*c83a76b0SSuyog Pawar /* Updating bytes generated and Updating strm_buffer pointer */
594*c83a76b0SSuyog Pawar ps_curr_out->i4_bytes_generated += i4_bytes_generated;
595*c83a76b0SSuyog Pawar
596*c83a76b0SSuyog Pawar /* Re-Initialize the bitstream engine after each tile or slice */
597*c83a76b0SSuyog Pawar ihevce_bitstrm_init(
598*c83a76b0SSuyog Pawar ps_bitstrm, (ps_bitstrm->pu1_strm_buffer + i4_bytes_generated), out_buf_size);
599*c83a76b0SSuyog Pawar }
600*c83a76b0SSuyog Pawar }
601*c83a76b0SSuyog Pawar
602*c83a76b0SSuyog Pawar /* Max slices related warning prints based on last slice status */
603*c83a76b0SSuyog Pawar if(ps_entropy_ctxt->i4_num_slice_seg == i4_max_num_slices)
604*c83a76b0SSuyog Pawar {
605*c83a76b0SSuyog Pawar if(ps_entropy_ctxt->i4_slice_seg_len >= i4_slice_segment_max_length_bckp)
606*c83a76b0SSuyog Pawar {
607*c83a76b0SSuyog Pawar if(1 == ps_entropy_ctxt->i4_slice_segment_mode)
608*c83a76b0SSuyog Pawar {
609*c83a76b0SSuyog Pawar ps_sys_api->ihevce_printf(
610*c83a76b0SSuyog Pawar ps_sys_api->pv_cb_handle,
611*c83a76b0SSuyog Pawar "IHEVCE_WARNING: Last slice contains %d CTBs exceeds %d (Max limit of CTBs "
612*c83a76b0SSuyog Pawar "configured). As per codec_level max number of slices per frame is %d\n",
613*c83a76b0SSuyog Pawar ps_entropy_ctxt->i4_slice_seg_len,
614*c83a76b0SSuyog Pawar i4_slice_segment_max_length_bckp,
615*c83a76b0SSuyog Pawar i4_max_num_slices);
616*c83a76b0SSuyog Pawar }
617*c83a76b0SSuyog Pawar else if(2 == ps_entropy_ctxt->i4_slice_segment_mode)
618*c83a76b0SSuyog Pawar {
619*c83a76b0SSuyog Pawar ps_sys_api->ihevce_printf(
620*c83a76b0SSuyog Pawar ps_sys_api->pv_cb_handle,
621*c83a76b0SSuyog Pawar "IHEVCE_WARNING: Last slice contains %d Bytes exceeds %d (Max limit of Bytes "
622*c83a76b0SSuyog Pawar "configured). As per codec_level max number of slices per frame is %d\n",
623*c83a76b0SSuyog Pawar ps_entropy_ctxt->i4_slice_seg_len,
624*c83a76b0SSuyog Pawar i4_slice_segment_max_length_bckp,
625*c83a76b0SSuyog Pawar i4_max_num_slices);
626*c83a76b0SSuyog Pawar }
627*c83a76b0SSuyog Pawar }
628*c83a76b0SSuyog Pawar }
629*c83a76b0SSuyog Pawar
630*c83a76b0SSuyog Pawar /* restore slice arg length after pic encoding */
631*c83a76b0SSuyog Pawar ps_entropy_ctxt->i4_slice_segment_max_length = i4_slice_segment_max_length_bckp;
632*c83a76b0SSuyog Pawar
633*c83a76b0SSuyog Pawar /* ---------------------- Initialize VCL NAL Size/offsets ---------------------------*/
634*c83a76b0SSuyog Pawar {
635*c83a76b0SSuyog Pawar WORD32 vcl_start = ps_curr_out->i4_num_non_vcl_prefix_nals;
636*c83a76b0SSuyog Pawar WORD32 num_vcl_nals = ps_bitstrm->i4_num_nal - vcl_start;
637*c83a76b0SSuyog Pawar WORD32 ctr = 0;
638*c83a76b0SSuyog Pawar
639*c83a76b0SSuyog Pawar ASSERT(num_vcl_nals > 0);
640*c83a76b0SSuyog Pawar ASSERT(num_vcl_nals <= MAX_NUM_VCL_NALS_PER_AU);
641*c83a76b0SSuyog Pawar
642*c83a76b0SSuyog Pawar ps_curr_out->i4_num_vcl_nals = num_vcl_nals;
643*c83a76b0SSuyog Pawar for(ctr = 0; ctr < MIN(num_vcl_nals, MAX_NUM_VCL_NALS_PER_AU); ctr++)
644*c83a76b0SSuyog Pawar {
645*c83a76b0SSuyog Pawar /* NAL offset is derive by subtracting Bistream base from NAL start pointer */
646*c83a76b0SSuyog Pawar ULWORD64 u8_cur_nal_start = (ULWORD64)ps_bitstrm->apu1_nal_start[ctr + vcl_start];
647*c83a76b0SSuyog Pawar
648*c83a76b0SSuyog Pawar #if POPULATE_NAL_SIZE
649*c83a76b0SSuyog Pawar
650*c83a76b0SSuyog Pawar /* ----------Populate NAL Size -------------*/
651*c83a76b0SSuyog Pawar if((ctr + 1) < num_vcl_nals)
652*c83a76b0SSuyog Pawar {
653*c83a76b0SSuyog Pawar ULWORD64 u8_next_nal_start =
654*c83a76b0SSuyog Pawar (ULWORD64)ps_bitstrm->apu1_nal_start[ctr + vcl_start + 1];
655*c83a76b0SSuyog Pawar ps_curr_out->ai4_size_vcl_nals[ctr] =
656*c83a76b0SSuyog Pawar (UWORD32)(u8_next_nal_start - u8_cur_nal_start);
657*c83a76b0SSuyog Pawar }
658*c83a76b0SSuyog Pawar else
659*c83a76b0SSuyog Pawar {
660*c83a76b0SSuyog Pawar ULWORD64 u8_next_nal_start =
661*c83a76b0SSuyog Pawar (ULWORD64)ps_bitstrm->pu1_strm_buffer + ps_bitstrm->u4_strm_buf_offset;
662*c83a76b0SSuyog Pawar ps_curr_out->ai4_size_vcl_nals[ctr] =
663*c83a76b0SSuyog Pawar (UWORD32)(u8_next_nal_start - u8_cur_nal_start);
664*c83a76b0SSuyog Pawar }
665*c83a76b0SSuyog Pawar ASSERT(ps_curr_out->ai4_size_vcl_nals[ctr] > 0);
666*c83a76b0SSuyog Pawar
667*c83a76b0SSuyog Pawar #elif POPULATE_NAL_OFFSET
668*c83a76b0SSuyog Pawar
669*c83a76b0SSuyog Pawar /* ----------Populate NAL Offset -------------*/
670*c83a76b0SSuyog Pawar
671*c83a76b0SSuyog Pawar ASSERT(u8_cur_nal_start >= u8_bitstream_base);
672*c83a76b0SSuyog Pawar ps_curr_out->ai4_off_vcl_nals[ctr] = (UWORD32)(u8_cur_nal_start - u8_bitstream_base);
673*c83a76b0SSuyog Pawar
674*c83a76b0SSuyog Pawar if(ctr)
675*c83a76b0SSuyog Pawar {
676*c83a76b0SSuyog Pawar /* sanity check on increasing NAL offsets */
677*c83a76b0SSuyog Pawar ASSERT(ps_curr_out->ai4_off_vcl_nals[ctr] > ps_curr_out->ai4_off_vcl_nals[ctr - 1]);
678*c83a76b0SSuyog Pawar }
679*c83a76b0SSuyog Pawar #endif /* POPULATE_NAL_SIZE */
680*c83a76b0SSuyog Pawar }
681*c83a76b0SSuyog Pawar }
682*c83a76b0SSuyog Pawar
683*c83a76b0SSuyog Pawar #ifndef DISABLE_SEI
684*c83a76b0SSuyog Pawar /* generate suffix sei */
685*c83a76b0SSuyog Pawar if(1 == ps_entropy_ctxt->ps_sei->i1_sei_parameters_present_flag)
686*c83a76b0SSuyog Pawar {
687*c83a76b0SSuyog Pawar /* Insert hash SEI */
688*c83a76b0SSuyog Pawar if(0 != ps_entropy_ctxt->ps_sei->i1_decoded_pic_hash_sei_flag)
689*c83a76b0SSuyog Pawar {
690*c83a76b0SSuyog Pawar ret |= ihevce_generate_sei(
691*c83a76b0SSuyog Pawar ps_bitstrm,
692*c83a76b0SSuyog Pawar ps_entropy_ctxt->ps_sei,
693*c83a76b0SSuyog Pawar &ps_entropy_ctxt->ps_sps->s_vui_parameters,
694*c83a76b0SSuyog Pawar insert_per_cra,
695*c83a76b0SSuyog Pawar NAL_SUFFIX_SEI,
696*c83a76b0SSuyog Pawar ps_curr_inp->u4_num_sei_payload,
697*c83a76b0SSuyog Pawar &ps_curr_inp->as_sei_payload[0]);
698*c83a76b0SSuyog Pawar }
699*c83a76b0SSuyog Pawar
700*c83a76b0SSuyog Pawar /* Updating bytes generated */
701*c83a76b0SSuyog Pawar ps_curr_out->i4_bytes_generated += ps_bitstrm->u4_strm_buf_offset;
702*c83a76b0SSuyog Pawar }
703*c83a76b0SSuyog Pawar #endif
704*c83a76b0SSuyog Pawar
705*c83a76b0SSuyog Pawar /* generate end of sequence nal */
706*c83a76b0SSuyog Pawar if((1 == ps_curr_inp->i1_eos_present_flag) && (ps_curr_inp->i4_is_end_of_idr_gop == 1))
707*c83a76b0SSuyog Pawar {
708*c83a76b0SSuyog Pawar ret |= ihevce_generate_eos(ps_bitstrm);
709*c83a76b0SSuyog Pawar /* Updating bytes generated */
710*c83a76b0SSuyog Pawar ps_curr_out->i4_bytes_generated += ps_bitstrm->u4_strm_buf_offset;
711*c83a76b0SSuyog Pawar }
712*c83a76b0SSuyog Pawar
713*c83a76b0SSuyog Pawar /* ------------------- Initialize non-VCL suffix NAL Size/offsets -----------------------*/
714*c83a76b0SSuyog Pawar {
715*c83a76b0SSuyog Pawar WORD32 non_vcl_suffix_start =
716*c83a76b0SSuyog Pawar ps_curr_out->i4_num_non_vcl_prefix_nals + ps_curr_out->i4_num_vcl_nals;
717*c83a76b0SSuyog Pawar WORD32 num_non_vcl_suffix_nals = ps_bitstrm->i4_num_nal - non_vcl_suffix_start;
718*c83a76b0SSuyog Pawar WORD32 ctr = 0;
719*c83a76b0SSuyog Pawar
720*c83a76b0SSuyog Pawar ASSERT(num_non_vcl_suffix_nals >= 0);
721*c83a76b0SSuyog Pawar ASSERT(num_non_vcl_suffix_nals <= MAX_NUM_SUFFIX_NALS_PER_AU);
722*c83a76b0SSuyog Pawar
723*c83a76b0SSuyog Pawar ps_curr_out->i4_num_non_vcl_suffix_nals = num_non_vcl_suffix_nals;
724*c83a76b0SSuyog Pawar for(ctr = 0; ctr < MIN(num_non_vcl_suffix_nals, MAX_NUM_SUFFIX_NALS_PER_AU); ctr++)
725*c83a76b0SSuyog Pawar {
726*c83a76b0SSuyog Pawar /* NAL offset is derive by subtracting Bistream base from NAL start pointer */
727*c83a76b0SSuyog Pawar ULWORD64 u8_cur_nal_start =
728*c83a76b0SSuyog Pawar (ULWORD64)ps_bitstrm->apu1_nal_start[ctr + non_vcl_suffix_start];
729*c83a76b0SSuyog Pawar
730*c83a76b0SSuyog Pawar #if POPULATE_NAL_SIZE
731*c83a76b0SSuyog Pawar
732*c83a76b0SSuyog Pawar /* ----------Populate NAL Size -------------*/
733*c83a76b0SSuyog Pawar if((ctr + 1) < num_non_vcl_suffix_nals)
734*c83a76b0SSuyog Pawar {
735*c83a76b0SSuyog Pawar ULWORD64 u8_next_nal_start =
736*c83a76b0SSuyog Pawar (ULWORD64)ps_bitstrm->apu1_nal_start[ctr + non_vcl_suffix_start + 1];
737*c83a76b0SSuyog Pawar ps_curr_out->ai4_size_non_vcl_suffix_nals[ctr] =
738*c83a76b0SSuyog Pawar (UWORD32)(u8_next_nal_start - u8_cur_nal_start);
739*c83a76b0SSuyog Pawar }
740*c83a76b0SSuyog Pawar else
741*c83a76b0SSuyog Pawar {
742*c83a76b0SSuyog Pawar ULWORD64 u8_next_nal_start =
743*c83a76b0SSuyog Pawar (ULWORD64)ps_bitstrm->pu1_strm_buffer + ps_bitstrm->u4_strm_buf_offset;
744*c83a76b0SSuyog Pawar ps_curr_out->ai4_size_non_vcl_suffix_nals[ctr] =
745*c83a76b0SSuyog Pawar (UWORD32)(u8_next_nal_start - u8_cur_nal_start);
746*c83a76b0SSuyog Pawar }
747*c83a76b0SSuyog Pawar ASSERT(ps_curr_out->ai4_size_non_vcl_suffix_nals[ctr] > 0);
748*c83a76b0SSuyog Pawar
749*c83a76b0SSuyog Pawar #elif POPULATE_NAL_OFFSET
750*c83a76b0SSuyog Pawar
751*c83a76b0SSuyog Pawar /* ----------Populate NAL Offset -------------*/
752*c83a76b0SSuyog Pawar
753*c83a76b0SSuyog Pawar ASSERT(u8_cur_nal_start >= u8_bitstream_base);
754*c83a76b0SSuyog Pawar ps_curr_out->ai4_off_non_vcl_suffix_nals[ctr] =
755*c83a76b0SSuyog Pawar (UWORD32)(u8_cur_nal_start - u8_bitstream_base);
756*c83a76b0SSuyog Pawar
757*c83a76b0SSuyog Pawar if(ctr)
758*c83a76b0SSuyog Pawar {
759*c83a76b0SSuyog Pawar /* sanity check on increasing NAL offsets */
760*c83a76b0SSuyog Pawar ASSERT(
761*c83a76b0SSuyog Pawar ps_curr_out->ai4_off_non_vcl_suffix_nals[ctr] >
762*c83a76b0SSuyog Pawar ps_curr_out->ai4_off_non_vcl_suffix_nals[ctr - 1]);
763*c83a76b0SSuyog Pawar }
764*c83a76b0SSuyog Pawar #endif /* POPULATE_NAL_SIZE */
765*c83a76b0SSuyog Pawar }
766*c83a76b0SSuyog Pawar }
767*c83a76b0SSuyog Pawar
768*c83a76b0SSuyog Pawar /*PIC INFO: Populatinf Ref POC, weights and offset*/
769*c83a76b0SSuyog Pawar {
770*c83a76b0SSuyog Pawar WORD32 i;
771*c83a76b0SSuyog Pawar ps_entropy_ctxt->ps_pic_level_info->i1_num_ref_idx_l0_active =
772*c83a76b0SSuyog Pawar ps_entropy_ctxt->ps_slice_hdr->i1_num_ref_idx_l0_active;
773*c83a76b0SSuyog Pawar ps_entropy_ctxt->ps_pic_level_info->i1_num_ref_idx_l1_active =
774*c83a76b0SSuyog Pawar ps_entropy_ctxt->ps_slice_hdr->i1_num_ref_idx_l1_active;
775*c83a76b0SSuyog Pawar for(i = 0; i < ps_entropy_ctxt->ps_slice_hdr->i1_num_ref_idx_l0_active; i++)
776*c83a76b0SSuyog Pawar {
777*c83a76b0SSuyog Pawar ps_entropy_ctxt->ps_pic_level_info->i4_ref_poc_l0[i] =
778*c83a76b0SSuyog Pawar ps_entropy_ctxt->ps_slice_hdr->s_rplm.i4_ref_poc_l0[i];
779*c83a76b0SSuyog Pawar ps_entropy_ctxt->ps_pic_level_info->i1_list_entry_l0[i] =
780*c83a76b0SSuyog Pawar ps_entropy_ctxt->ps_slice_hdr->s_rplm.i1_list_entry_l0[i];
781*c83a76b0SSuyog Pawar ps_entropy_ctxt->ps_pic_level_info->i2_luma_weight_l0[i] =
782*c83a76b0SSuyog Pawar (DOUBLE)ps_entropy_ctxt->ps_slice_hdr->s_wt_ofst.i2_luma_weight_l0[i] /
783*c83a76b0SSuyog Pawar (1 << ps_entropy_ctxt->ps_slice_hdr->s_wt_ofst.i1_luma_log2_weight_denom);
784*c83a76b0SSuyog Pawar ps_entropy_ctxt->ps_pic_level_info->i2_luma_offset_l0[i] =
785*c83a76b0SSuyog Pawar ps_entropy_ctxt->ps_slice_hdr->s_wt_ofst.i2_luma_offset_l0[i];
786*c83a76b0SSuyog Pawar }
787*c83a76b0SSuyog Pawar for(i = 0; i < ps_entropy_ctxt->ps_slice_hdr->i1_num_ref_idx_l1_active; i++)
788*c83a76b0SSuyog Pawar {
789*c83a76b0SSuyog Pawar ps_entropy_ctxt->ps_pic_level_info->i4_ref_poc_l1[i] =
790*c83a76b0SSuyog Pawar ps_entropy_ctxt->ps_slice_hdr->s_rplm.i4_ref_poc_l1[i];
791*c83a76b0SSuyog Pawar ps_entropy_ctxt->ps_pic_level_info->i1_list_entry_l1[i] =
792*c83a76b0SSuyog Pawar ps_entropy_ctxt->ps_slice_hdr->s_rplm.i1_list_entry_l1[i];
793*c83a76b0SSuyog Pawar ps_entropy_ctxt->ps_pic_level_info->i2_luma_weight_l1[i] =
794*c83a76b0SSuyog Pawar (DOUBLE)ps_entropy_ctxt->ps_slice_hdr->s_wt_ofst.i2_luma_weight_l1[i] /
795*c83a76b0SSuyog Pawar (1 << ps_entropy_ctxt->ps_slice_hdr->s_wt_ofst.i1_luma_log2_weight_denom);
796*c83a76b0SSuyog Pawar ps_entropy_ctxt->ps_pic_level_info->i2_luma_offset_l1[i] =
797*c83a76b0SSuyog Pawar ps_entropy_ctxt->ps_slice_hdr->s_wt_ofst.i2_luma_offset_l1[i];
798*c83a76b0SSuyog Pawar }
799*c83a76b0SSuyog Pawar }
800*c83a76b0SSuyog Pawar
801*c83a76b0SSuyog Pawar /* attach the time stamp of the input to output */
802*c83a76b0SSuyog Pawar ps_curr_out->i4_out_timestamp_low = ps_curr_inp->i4_inp_timestamp_low;
803*c83a76b0SSuyog Pawar
804*c83a76b0SSuyog Pawar ps_curr_out->i4_out_timestamp_high = ps_curr_inp->i4_inp_timestamp_high;
805*c83a76b0SSuyog Pawar
806*c83a76b0SSuyog Pawar /*attach the app frame info of this buffer */
807*c83a76b0SSuyog Pawar ps_curr_out->pv_app_frm_ctxt = ps_curr_inp->pv_app_frm_ctxt;
808*c83a76b0SSuyog Pawar
809*c83a76b0SSuyog Pawar /* frame never skipped for now */
810*c83a76b0SSuyog Pawar ps_curr_out->i4_frame_skipped = 0;
811*c83a76b0SSuyog Pawar
812*c83a76b0SSuyog Pawar /* update error code and return */
813*c83a76b0SSuyog Pawar ps_curr_out->i4_process_error_code = ret;
814*c83a76b0SSuyog Pawar
815*c83a76b0SSuyog Pawar switch(slice_type)
816*c83a76b0SSuyog Pawar {
817*c83a76b0SSuyog Pawar case ISLICE:
818*c83a76b0SSuyog Pawar if((nal_type == NAL_IDR_N_LP) || (NAL_IDR_W_LP == nal_type))
819*c83a76b0SSuyog Pawar {
820*c83a76b0SSuyog Pawar ps_curr_out->i4_encoded_frame_type = IV_IDR_FRAME;
821*c83a76b0SSuyog Pawar }
822*c83a76b0SSuyog Pawar else
823*c83a76b0SSuyog Pawar {
824*c83a76b0SSuyog Pawar ps_curr_out->i4_encoded_frame_type = IV_I_FRAME;
825*c83a76b0SSuyog Pawar }
826*c83a76b0SSuyog Pawar break;
827*c83a76b0SSuyog Pawar case PSLICE:
828*c83a76b0SSuyog Pawar ps_curr_out->i4_encoded_frame_type = IV_P_FRAME;
829*c83a76b0SSuyog Pawar break;
830*c83a76b0SSuyog Pawar case BSLICE:
831*c83a76b0SSuyog Pawar ps_curr_out->i4_encoded_frame_type = IV_B_FRAME;
832*c83a76b0SSuyog Pawar break;
833*c83a76b0SSuyog Pawar }
834*c83a76b0SSuyog Pawar
835*c83a76b0SSuyog Pawar if(IHEVCE_SUCCESS == ret)
836*c83a76b0SSuyog Pawar {
837*c83a76b0SSuyog Pawar ps_curr_out->i4_process_ret_sts = IV_SUCCESS;
838*c83a76b0SSuyog Pawar }
839*c83a76b0SSuyog Pawar else
840*c83a76b0SSuyog Pawar {
841*c83a76b0SSuyog Pawar ps_curr_out->i4_process_ret_sts = IV_FAIL;
842*c83a76b0SSuyog Pawar }
843*c83a76b0SSuyog Pawar
844*c83a76b0SSuyog Pawar return (ret);
845*c83a76b0SSuyog Pawar }
846