xref: /aosp_15_r20/external/libhevc/encoder/ihevce_hle_interface.c (revision c83a76b084498d55f252f48b2e3786804cdf24b7)
1 /******************************************************************************
2  *
3  * Copyright (C) 2018 The Android Open Source Project
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at:
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  *****************************************************************************
18  * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
19 */
20 
21 /*!
22 ******************************************************************************
23 * \file ihevce_hle_interface.c
24 *
25 * \brief
26 *    This file contains all the functions related High level encoder
27 *    Interface layer
28 *
29 * \date
30 *    18/09/2012
31 *
32 * \author
33 *    Ittiam
34 *
35 * List of Functions
36 *    <TODO: TO BE ADDED>
37 *
38 ******************************************************************************
39 */
40 
41 /*****************************************************************************/
42 /* File Includes                                                             */
43 /*****************************************************************************/
44 /* System include files */
45 #include <stdio.h>
46 #include <string.h>
47 #include <stdlib.h>
48 #include <assert.h>
49 #include <stdarg.h>
50 #include <math.h>
51 #include <time.h>
52 
53 /* User include files */
54 #include "ihevc_typedefs.h"
55 #include "itt_video_api.h"
56 #include "ihevce_api.h"
57 
58 #include "rc_cntrl_param.h"
59 #include "rc_frame_info_collector.h"
60 #include "rc_look_ahead_params.h"
61 
62 #include "ihevc_defs.h"
63 #include "ihevc_macros.h"
64 #include "ihevc_debug.h"
65 #include "ihevc_structs.h"
66 #include "ihevc_platform_macros.h"
67 #include "ihevc_deblk.h"
68 #include "ihevc_itrans_recon.h"
69 #include "ihevc_chroma_itrans_recon.h"
70 #include "ihevc_chroma_intra_pred.h"
71 #include "ihevc_intra_pred.h"
72 #include "ihevc_inter_pred.h"
73 #include "ihevc_mem_fns.h"
74 #include "ihevc_padding.h"
75 #include "ihevc_weighted_pred.h"
76 #include "ihevc_sao.h"
77 #include "ihevc_resi_trans.h"
78 #include "ihevc_quant_iquant_ssd.h"
79 #include "ihevc_cabac_tables.h"
80 #include "ihevc_trans_tables.h"
81 #include "ihevc_trans_macros.h"
82 
83 #include "ihevce_defs.h"
84 #include "ihevce_hle_interface.h"
85 #include "ihevce_hle_q_func.h"
86 #include "ihevce_buffer_que_interface.h"
87 #include "ihevce_lap_enc_structs.h"
88 #include "ihevce_multi_thrd_structs.h"
89 #include "ihevce_multi_thrd_funcs.h"
90 #include "ihevce_me_common_defs.h"
91 #include "ihevce_had_satd.h"
92 #include "ihevce_error_codes.h"
93 #include "ihevce_error_checks.h"
94 #include "ihevce_bitstream.h"
95 #include "ihevce_cabac.h"
96 #include "ihevce_rdoq_macros.h"
97 #include "ihevce_function_selector.h"
98 #include "ihevce_enc_structs.h"
99 #include "ihevce_cmn_utils_instr_set_router.h"
100 #include "ihevce_memory_init.h"
101 #include "ihevce_lap_interface.h"
102 #include "ihevce_entropy_cod.h"
103 #include "ihevce_entropy_structs.h"
104 #include "ihevce_frame_process_utils.h"
105 #include "ihevce_frame_process.h"
106 #include "ihevce_profile.h"
107 #include "ihevce_global_tables.h"
108 #include "ihevce_dep_mngr_interface.h"
109 #include "ihevce_common_utils.h"
110 #include "hme_datatype.h"
111 #include "hme_interface.h"
112 #include "hme_common_defs.h"
113 #include "hme_defs.h"
114 #include "ihevce_coarse_me_pass.h"
115 #include "ihevce_me_pass.h"
116 #include "ihevce_enc_loop_structs.h"
117 #include "ihevce_enc_loop_pass.h"
118 
119 #include "cast_types.h"
120 #include "osal.h"
121 #include "osal_defaults.h"
122 
123 /*****************************************************************************/
124 /* Function Definitions                                                      */
125 /*****************************************************************************/
126 /*!
127 ******************************************************************************
128 * \if Function name : ihevce_context_reset \endif
129 *
130 * \brief
131 *    Encoder reset function
132 *
133 * \param[in] Encoder context pointer
134 *
135 * \return
136 *    None
137 *
138 * \author
139 *  Ittiam
140 *
141 *****************************************************************************
142 */
ihevce_context_reset(enc_ctxt_t * ps_enc_ctxt)143 void ihevce_context_reset(enc_ctxt_t *ps_enc_ctxt)
144 {
145     ps_enc_ctxt->i4_end_flag = 0;
146 
147     /* set the queue related pointer and buffer to default value */
148     ps_enc_ctxt->s_enc_ques.pv_q_mutex_hdl = NULL;
149 
150     /* Reset the i/o queues created status to 0 */
151     ps_enc_ctxt->i4_io_queues_created = 0;
152 
153     /* reset the frame limit flag to 0 */
154     ps_enc_ctxt->i4_frame_limit_reached = 0;
155 
156     return;
157 }
158 
159 /*!
160 ******************************************************************************
161 * \if Function name : ihevce_hle_interface_create \endif
162 *
163 * \brief
164 *    High level Encoder create function
165 *
166 * \param[in]  High level encoder interface context pointer
167 *
168 * \return
169 *    success or fail
170 *
171 * \author
172 *  Ittiam
173 *
174 *****************************************************************************
175 */
ihevce_hle_interface_create(ihevce_hle_ctxt_t * ps_hle_ctxt)176 IV_API_CALL_STATUS_T ihevce_hle_interface_create(ihevce_hle_ctxt_t *ps_hle_ctxt)
177 {
178     /* local variables */
179     enc_ctxt_t *ps_enc_ctxt;
180     iv_mem_rec_t s_memtab;
181     ihevce_static_cfg_params_t *ps_enc_static_cfg_params;
182     WORD32 i4_num_resolutions = ps_hle_ctxt->ps_static_cfg_prms->s_tgt_lyr_prms.i4_num_res_layers;
183     WORD32 i4_look_ahead_frames_in_first_pass = -1;
184     WORD32 i4_total_cores = 0, ctr, i4_mres_flag = 0;
185     ihevce_sys_api_t *ps_sys_api = &ps_hle_ctxt->ps_static_cfg_prms->s_sys_api;
186 
187     WORD32 status = 0;
188     WORD32 i;
189     WORD32 *pi4_active_res_id = NULL;
190 
191     /* OSAL Init */
192     status = ihevce_osal_init((void *)ps_hle_ctxt);
193 
194     if(status != 0)
195         return (IV_FAIL);
196 
197     /* --------------------------------------------------------------------- */
198     /*              High Level Encoder Init                                  */
199     /* --------------------------------------------------------------------- */
200 
201     if(i4_num_resolutions > 1)
202         i4_mres_flag = 1;
203     /* set no error in the output */
204     ps_hle_ctxt->i4_error_code = 0;
205 
206     /* Error checks on the static parameters passed */
207     ps_hle_ctxt->i4_error_code = ihevce_hle_validate_static_params(ps_hle_ctxt->ps_static_cfg_prms);
208 
209     /*memory for static cfg params for encoder, which can be overwritten if encoder wants
210         encoder should use this for all its usage*/
211     s_memtab.i4_size = sizeof(iv_mem_rec_t);
212     s_memtab.i4_mem_alignment = 4;
213     s_memtab.i4_mem_size = sizeof(ihevce_static_cfg_params_t);
214     s_memtab.e_mem_type = IV_EXT_CACHEABLE_NORMAL_MEM;
215 
216     ps_hle_ctxt->ihevce_mem_alloc(
217         ps_hle_ctxt->pv_mem_mgr_hdl, &ps_hle_ctxt->ps_static_cfg_prms->s_sys_api, &s_memtab);
218     if(s_memtab.pv_base == NULL)
219     {
220         return (IV_FAIL);
221     }
222     ps_enc_static_cfg_params = (ihevce_static_cfg_params_t *)s_memtab.pv_base;
223     memcpy(
224         ps_enc_static_cfg_params,
225         ps_hle_ctxt->ps_static_cfg_prms,
226         (sizeof(ihevce_static_cfg_params_t)));
227 
228     i4_total_cores = ps_enc_static_cfg_params->s_multi_thrd_prms.i4_max_num_cores;
229 
230     /* check for validity of memory control flag (only 0,1,2 modes are allowed) */
231     if((ps_enc_static_cfg_params->s_multi_thrd_prms.i4_memory_alloc_ctrl_flag > 2) ||
232        (ps_enc_static_cfg_params->s_multi_thrd_prms.i4_memory_alloc_ctrl_flag < 0))
233     {
234         ps_hle_ctxt->i4_error_code = IHEVCE_INVALID_MEM_CTRL_FLAG;
235     }
236 
237     if((i4_mres_flag == 1) &&
238        (ps_enc_static_cfg_params->s_multi_thrd_prms.i4_use_thrd_affinity == 1))
239     {
240         ps_sys_api->ihevce_printf(
241             ps_sys_api->pv_cb_handle,
242             "\nIHEVCE WARNING: Enabling thread affinity in multiresolution encoding will affect "
243             "performance\n");
244     }
245     if((ps_enc_static_cfg_params->s_tgt_lyr_prms.as_tgt_params[0].i4_quality_preset ==
246         IHEVCE_QUALITY_P6) &&
247        (ps_enc_static_cfg_params->s_config_prms.i4_cu_level_rc))
248     {
249         ps_sys_api->ihevce_printf(
250             ps_sys_api->pv_cb_handle,
251             "\nIHEVCE WARNING: Disabling CU level QP modulation for P6 preset\n");
252         ps_enc_static_cfg_params->s_config_prms.i4_cu_level_rc = 0;
253     }
254     if((ps_enc_static_cfg_params->s_tgt_lyr_prms.as_tgt_params[0].i4_quality_preset ==
255         IHEVCE_QUALITY_P7) &&
256        (ps_enc_static_cfg_params->s_config_prms.i4_cu_level_rc))
257     {
258         ps_sys_api->ihevce_printf(
259             ps_sys_api->pv_cb_handle,
260             "\nIHEVCE WARNING: Disabling CU level QP modulation for P7 preset\n");
261         ps_enc_static_cfg_params->s_config_prms.i4_cu_level_rc = 0;
262     }
263 
264     if(0 != ps_hle_ctxt->i4_error_code)
265     {
266         ps_hle_ctxt->ihevce_mem_free(ps_hle_ctxt->pv_mem_mgr_hdl, &s_memtab);
267         return (IV_FAIL);
268     }
269     ps_hle_ctxt->ai4_num_core_per_res[0] = i4_total_cores;
270 
271     if(1 == ps_enc_static_cfg_params->s_tgt_lyr_prms.i4_mres_single_out)
272     {
273         /*    Memory Allocation of pi4_active_res_id */
274         s_memtab.i4_size = sizeof(iv_mem_rec_t);
275         s_memtab.i4_mem_alignment = 4;
276         s_memtab.i4_mem_size = sizeof(WORD32) * (IHEVCE_MAX_NUM_RESOLUTIONS + 1);
277         s_memtab.e_mem_type = IV_EXT_CACHEABLE_NORMAL_MEM;
278 
279         ps_hle_ctxt->ihevce_mem_alloc(
280             ps_hle_ctxt->pv_mem_mgr_hdl, &ps_enc_static_cfg_params->s_sys_api, &s_memtab);
281         if(s_memtab.pv_base == NULL)
282         {
283             return (IV_FAIL);
284         }
285 
286         pi4_active_res_id = (WORD32 *)s_memtab.pv_base;
287     }
288     /* --------------------------------------------------------------------- */
289     /*    Context and Memory Initialization of Encoder ctxt                  */
290     /* --------------------------------------------------------------------- */
291     for(ctr = 0; ctr < i4_num_resolutions; ctr++)
292     {
293         WORD32 i4_br_id;
294         s_memtab.i4_size = sizeof(iv_mem_rec_t);
295         s_memtab.i4_mem_alignment = 4;
296         s_memtab.i4_mem_size = sizeof(enc_ctxt_t);
297         s_memtab.e_mem_type = IV_EXT_CACHEABLE_NORMAL_MEM;
298 
299         ps_hle_ctxt->ihevce_mem_alloc(
300             ps_hle_ctxt->pv_mem_mgr_hdl, &ps_enc_static_cfg_params->s_sys_api, &s_memtab);
301         if(s_memtab.pv_base == NULL)
302         {
303             return (IV_FAIL);
304         }
305 
306         ps_enc_ctxt = (enc_ctxt_t *)s_memtab.pv_base;
307 
308         ps_enc_ctxt->ps_stat_prms = ps_enc_static_cfg_params;
309 
310         /* check of number of cores to decide the num threads active */
311         ps_enc_ctxt->s_multi_thrd.i4_all_thrds_active_flag = 1;
312 
313         if(1 == ps_enc_static_cfg_params->s_tgt_lyr_prms.i4_mres_single_out)
314         {
315             pi4_active_res_id[ctr] = 0;
316             ps_enc_ctxt->s_multi_thrd.pi4_active_res_id = pi4_active_res_id;
317         }
318 
319         /*store num bit-rate instances in the encoder context */
320         ps_enc_ctxt->i4_num_bitrates =
321             ps_enc_static_cfg_params->s_tgt_lyr_prms.as_tgt_params[ctr].i4_num_bitrate_instances;
322         if(BLU_RAY_SUPPORT == ps_enc_static_cfg_params->s_out_strm_prms.i4_interop_flags)
323         {
324             ps_enc_ctxt->i4_blu_ray_spec = 1;
325         }
326         else
327         {
328             ps_enc_ctxt->i4_blu_ray_spec = 0;
329         }
330 
331         /* if all threads are required to be active */
332         if(1 == ps_enc_ctxt->s_multi_thrd.i4_all_thrds_active_flag)
333         {
334             /* store the number of threads to be created as passed by app with HT flag */
335             ps_enc_ctxt->s_multi_thrd.i4_num_enc_proc_thrds =
336                 ps_hle_ctxt->ai4_num_core_per_res[ctr];
337 
338             /* pre enc threads are doubled if HT is ON */
339             ps_enc_ctxt->s_multi_thrd.i4_num_pre_enc_proc_thrds =
340                 ps_hle_ctxt->ai4_num_core_per_res[ctr];
341         }
342         else
343         {
344             // TODO: distribute threads across stages
345         }
346 
347         /*Keep track of resolution id, this is used to differentiate from other encoder instance*/
348         ps_enc_ctxt->i4_resolution_id = ctr;
349         /* store hle ctxt in enc ctxt */
350         ps_enc_ctxt->pv_hle_ctxt = (void *)ps_hle_ctxt;
351         ps_enc_ctxt->pv_rc_mutex_lock_hdl = NULL;
352         ps_enc_ctxt->s_multi_thrd.pv_sub_pic_rc_mutex_lock_hdl = NULL;
353         ps_enc_ctxt->s_multi_thrd.pv_sub_pic_rc_for_qp_update_mutex_lock_hdl = NULL;
354         ps_enc_ctxt->i4_look_ahead_frames_in_first_pass = i4_look_ahead_frames_in_first_pass;
355 
356         ps_enc_ctxt->ai4_is_past_pic_complex[0] = 0;
357         ps_enc_ctxt->ai4_is_past_pic_complex[1] = 0;
358         ps_enc_ctxt->i4_is_I_reset_done = 1;
359         ps_enc_ctxt->i4_past_RC_reset_count = 0;
360         ps_enc_ctxt->i4_future_RC_reset = 0;
361         ps_enc_ctxt->i4_past_RC_scd_reset_count = 0;
362         ps_enc_ctxt->i4_future_RC_scd_reset = 0;
363         ps_enc_ctxt->i4_active_scene_num = -1;
364         for(i = 0; i < IHEVCE_MAX_NUM_BITRATES; i++)
365         {
366             ps_enc_ctxt->ai4_rc_query[i] = 0;
367         }
368         ps_enc_ctxt->i4_active_enc_frame_id = 0;
369         ps_enc_ctxt->u1_is_popcnt_available = 1;
370 
371 #ifndef ARM
372         ps_enc_ctxt->e_arch_type = ARCH_X86_GENERIC;
373         ps_enc_ctxt->u1_is_popcnt_available = 0;
374 #else
375         if(ps_enc_static_cfg_params->e_arch_type == ARCH_NA)
376             ps_enc_ctxt->e_arch_type = ihevce_default_arch();
377         else
378             ps_enc_ctxt->e_arch_type = ps_enc_static_cfg_params->e_arch_type;
379         ps_enc_ctxt->u1_is_popcnt_available = 0;
380 #endif
381 
382         {
383             ps_enc_static_cfg_params->e_arch_type = ps_enc_ctxt->e_arch_type;
384 
385             ihevce_init_function_ptr(ps_enc_ctxt, ps_enc_ctxt->e_arch_type);
386         }
387 
388         ihevce_mem_manager_init(ps_enc_ctxt, ps_hle_ctxt);
389 
390         if(0 != ps_hle_ctxt->i4_error_code)
391         {
392             return (IV_FAIL);
393         }
394 
395         /* mutex lock for RC calls */
396         ps_enc_ctxt->pv_rc_mutex_lock_hdl = osal_mutex_create(ps_hle_ctxt->pv_osal_handle);
397         if(NULL == ps_enc_ctxt->pv_rc_mutex_lock_hdl)
398         {
399             return IV_FAIL;
400         }
401 
402         /* mutex lock for Sub pic RC calls */
403         ps_enc_ctxt->s_multi_thrd.pv_sub_pic_rc_mutex_lock_hdl =
404             osal_mutex_create(ps_hle_ctxt->pv_osal_handle);
405         if(NULL == ps_enc_ctxt->s_multi_thrd.pv_sub_pic_rc_mutex_lock_hdl)
406         {
407             return IV_FAIL;
408         }
409 
410         ps_enc_ctxt->s_multi_thrd.pv_sub_pic_rc_for_qp_update_mutex_lock_hdl =
411             osal_mutex_create(ps_hle_ctxt->pv_osal_handle);
412         if(NULL == ps_enc_ctxt->s_multi_thrd.pv_sub_pic_rc_for_qp_update_mutex_lock_hdl)
413         {
414             return IV_FAIL;
415         }
416 
417         /* reset the encoder context */
418         ihevce_context_reset(ps_enc_ctxt);
419 
420         /* register the Encoder context in HLE interface ctxt */
421         ps_hle_ctxt->apv_enc_hdl[ctr] = ps_enc_ctxt;
422     }
423     /* init profile */
424     PROFILE_INIT(&ps_hle_ctxt->profile_hle);
425     for(ctr = 0; ctr < i4_num_resolutions; ctr++)
426     {
427         WORD32 i4_br_id;
428 
429         PROFILE_INIT(&ps_hle_ctxt->profile_enc_me[ctr]);
430         PROFILE_INIT(&ps_hle_ctxt->profile_pre_enc_l1l2[ctr]);
431         PROFILE_INIT(&ps_hle_ctxt->profile_pre_enc_l0ipe[ctr]);
432         for(i4_br_id = 0; i4_br_id < ps_enc_ctxt->i4_num_bitrates; i4_br_id++)
433         {
434             PROFILE_INIT(&ps_hle_ctxt->profile_enc[ctr][i4_br_id]);
435             PROFILE_INIT(&ps_hle_ctxt->profile_entropy[ctr][i4_br_id]);
436         }
437     }
438     if(1 == ps_enc_static_cfg_params->s_tgt_lyr_prms.i4_mres_single_out)
439         pi4_active_res_id[i4_num_resolutions] = 0;
440 
441     return (IV_SUCCESS);
442 }
443 
444 /*!
445 ******************************************************************************
446 * \if Function name : ihevce_query_io_buf_req \endif
447 *
448 * \brief
449 *    High level Encoder IO buffers query function
450 *
451 * \param[in] High level encoder interface context pointer
452 * \param[out] Input buffer requirment stucture pointer.
453 * \param[out] Output buffer requirment stucture pointer.
454 *
455 * \return
456 *    success or fail
457 *
458 * \author
459 *  Ittiam
460 *
461 *****************************************************************************
462 */
ihevce_query_io_buf_req(ihevce_hle_ctxt_t * ps_hle_ctxt,iv_input_bufs_req_t * ps_input_bufs_req,iv_res_layer_output_bufs_req_t * ps_res_layer_output_bufs_req,iv_res_layer_recon_bufs_req_t * ps_res_layer_recon_bufs_req)463 IV_API_CALL_STATUS_T ihevce_query_io_buf_req(
464     ihevce_hle_ctxt_t *ps_hle_ctxt,
465     iv_input_bufs_req_t *ps_input_bufs_req,
466     iv_res_layer_output_bufs_req_t *ps_res_layer_output_bufs_req,
467     iv_res_layer_recon_bufs_req_t *ps_res_layer_recon_bufs_req)
468 {
469     /* local variables */
470     enc_ctxt_t *ps_enc_ctxt;
471     ihevce_src_params_t *ps_src_prms;
472     WORD32 ctb_align_pic_wd;
473     WORD32 ctb_align_pic_ht, i4_resolution_id = 0, i4_num_resolutions, i4_num_bitrate_instances;
474     WORD32 i4_resolution_id_ctr, br_ctr;
475 
476     ps_enc_ctxt = (enc_ctxt_t *)ps_hle_ctxt->apv_enc_hdl[i4_resolution_id];
477     ps_src_prms = &ps_hle_ctxt->ps_static_cfg_prms->s_src_prms;
478     i4_num_resolutions = ps_hle_ctxt->ps_static_cfg_prms->s_tgt_lyr_prms.i4_num_res_layers;
479     /* set no error in the output */
480     ps_hle_ctxt->i4_error_code = 0;
481 
482     /* ------- populate the Input buffer requirements -------- */
483     /* get the number of buffers required for LAP */
484     ps_input_bufs_req->i4_min_num_yuv_bufs =
485         ihevce_lap_get_num_ip_bufs(&ps_enc_ctxt->s_lap_stat_prms);
486 
487     ps_input_bufs_req->i4_min_num_synch_ctrl_bufs = ps_input_bufs_req->i4_min_num_yuv_bufs;
488 
489     ps_input_bufs_req->i4_min_num_asynch_ctrl_bufs = NUM_AYSNC_CMD_BUFS;
490 
491     /* buffer sizes are populated based on create time parameters */
492     ctb_align_pic_wd =
493         ps_src_prms->i4_width +
494         SET_CTB_ALIGN(ps_src_prms->i4_width, ps_enc_ctxt->s_frm_ctb_prms.i4_ctb_size);
495 
496     ctb_align_pic_ht =
497         ps_src_prms->i4_height +
498         SET_CTB_ALIGN(ps_src_prms->i4_height, ps_enc_ctxt->s_frm_ctb_prms.i4_ctb_size);
499 
500     if(ps_src_prms->i4_input_bit_depth > 8)
501     {
502         ps_input_bufs_req->i4_min_size_y_buf = ctb_align_pic_wd * ctb_align_pic_ht * 2;
503 
504         ps_input_bufs_req->i4_min_size_uv_buf = ps_input_bufs_req->i4_min_size_y_buf >> 1;
505     }
506     else
507     {
508         ps_input_bufs_req->i4_min_size_y_buf = ctb_align_pic_wd * ctb_align_pic_ht;
509 
510         ps_input_bufs_req->i4_min_size_uv_buf = (ctb_align_pic_wd * ctb_align_pic_ht) >> 1;
511     }
512 
513     ps_input_bufs_req->i4_min_size_uv_buf <<=
514         ((ps_src_prms->i4_chr_format == IV_YUV_422SP_UV) ? 1 : 0);
515 
516     ps_input_bufs_req->i4_yuv_format = ps_src_prms->i4_chr_format;
517 
518 #ifndef DISABLE_SEI
519     ps_input_bufs_req->i4_min_size_synch_ctrl_bufs =
520         ((MAX_SEI_PAYLOAD_PER_TLV + 16) * MAX_NUMBER_OF_SEI_PAYLOAD) + 16;
521 
522     ps_input_bufs_req->i4_min_size_asynch_ctrl_bufs =
523         ((MAX_SEI_PAYLOAD_PER_TLV + 16) * (MAX_NUMBER_OF_SEI_PAYLOAD - 6)) + 16;
524 #else
525     ps_input_bufs_req->i4_min_size_synch_ctrl_bufs = 16;
526     ps_input_bufs_req->i4_min_size_asynch_ctrl_bufs = 16;
527 #endif
528 
529     for(i4_resolution_id_ctr = 0; i4_resolution_id_ctr < i4_num_resolutions; i4_resolution_id_ctr++)
530     {
531         ps_enc_ctxt = (enc_ctxt_t *)ps_hle_ctxt->apv_enc_hdl[i4_resolution_id_ctr];
532 
533         i4_num_bitrate_instances = ps_enc_ctxt->s_runtime_tgt_params.i4_num_bitrate_instances;
534 
535         /* buffer sizes are populated based on create time parameters */
536         ctb_align_pic_wd = ps_enc_ctxt->s_runtime_tgt_params.i4_width +
537                            SET_CTB_ALIGN(
538                                ps_enc_ctxt->s_runtime_tgt_params.i4_width,
539                                ps_enc_ctxt->s_frm_ctb_prms.i4_ctb_size);
540 
541         ctb_align_pic_ht = ps_enc_ctxt->s_runtime_tgt_params.i4_height +
542                            SET_CTB_ALIGN(
543                                ps_enc_ctxt->s_runtime_tgt_params.i4_height,
544                                ps_enc_ctxt->s_frm_ctb_prms.i4_ctb_size);
545 
546         for(br_ctr = 0; br_ctr < i4_num_bitrate_instances; br_ctr++)
547         {
548             /* ------- populate the Output buffer requirements -------- */
549             ps_res_layer_output_bufs_req->s_output_buf_req[i4_resolution_id_ctr][br_ctr]
550                 .i4_min_num_out_bufs = NUM_OUTPUT_BUFS;
551 
552             ps_res_layer_output_bufs_req->s_output_buf_req[i4_resolution_id_ctr][br_ctr]
553                 .i4_min_size_bitstream_buf = (ctb_align_pic_wd * ctb_align_pic_ht);
554 
555             if((ps_hle_ctxt->ps_static_cfg_prms->s_tgt_lyr_prms.i4_internal_bit_depth == 12) ||
556                ((ps_hle_ctxt->ps_static_cfg_prms->s_tgt_lyr_prms.i4_internal_bit_depth > 8) &&
557                 (ps_src_prms->i4_chr_format == IV_YUV_422SP_UV)))
558             {
559                 ps_res_layer_output_bufs_req->s_output_buf_req[i4_resolution_id_ctr][br_ctr]
560                     .i4_min_size_bitstream_buf *= 2;
561             }
562 
563             if((ps_hle_ctxt->ps_static_cfg_prms->s_tgt_lyr_prms.i4_internal_bit_depth == 10) &&
564                (ps_src_prms->i4_chr_format == IV_YUV_420SP_UV))
565             {
566                 ps_res_layer_output_bufs_req->s_output_buf_req[i4_resolution_id_ctr][br_ctr]
567                     .i4_min_size_bitstream_buf *= 3;
568                 ps_res_layer_output_bufs_req->s_output_buf_req[i4_resolution_id_ctr][br_ctr]
569                     .i4_min_size_bitstream_buf >>= 1;
570             }
571 
572             //recon_dump
573             /* ------- populate the Recon buffer requirements -------- */
574             if(ps_enc_ctxt->ps_stat_prms->i4_save_recon == 0)
575             {
576                 ps_res_layer_recon_bufs_req->s_recon_buf_req[i4_resolution_id_ctr][br_ctr]
577                     .i4_min_num_recon_bufs = 0;
578 
579                 ps_res_layer_recon_bufs_req->s_recon_buf_req[i4_resolution_id_ctr][br_ctr]
580                     .i4_min_size_y_buf = 0;
581 
582                 ps_res_layer_recon_bufs_req->s_recon_buf_req[i4_resolution_id_ctr][br_ctr]
583                     .i4_min_size_uv_buf = 0;
584             }
585             else
586             {
587                 ps_res_layer_recon_bufs_req->s_recon_buf_req[i4_resolution_id_ctr][br_ctr]
588                     .i4_min_num_recon_bufs = 2 * HEVCE_MAX_REF_PICS + 1;
589 
590                 ps_res_layer_recon_bufs_req->s_recon_buf_req[i4_resolution_id_ctr][br_ctr]
591                     .i4_min_size_y_buf =
592                     ctb_align_pic_wd * ctb_align_pic_ht *
593                     ((ps_hle_ctxt->ps_static_cfg_prms->s_tgt_lyr_prms.i4_internal_bit_depth > 8)
594                          ? 2
595                          : 1);
596 
597                 ps_res_layer_recon_bufs_req->s_recon_buf_req[i4_resolution_id_ctr][br_ctr]
598                     .i4_min_size_uv_buf =
599                     (ps_res_layer_recon_bufs_req->s_recon_buf_req[i4_resolution_id_ctr][br_ctr]
600                          .i4_min_size_y_buf >>
601                      1);
602                 ps_res_layer_recon_bufs_req->s_recon_buf_req[i4_resolution_id_ctr][br_ctr]
603                     .i4_min_size_uv_buf <<=
604                     ((ps_src_prms->i4_chr_format == IV_YUV_422SP_UV) ? 1 : 0);
605             }
606         }
607     }
608 
609     return (IV_SUCCESS);
610 }
611 
612 /*!
613 ******************************************************************************
614 * \if Function name : ihevce_create_ports \endif
615 *
616 * \brief
617 *    High level Encoder IO ports Create function
618 *
619 * \param[in] High level encoder interface context pointer
620 * \param[in] Input data buffer descriptor
621 * \param[in] Input control buffer descriptor
622 * \param[in] Output data buffer descriptor
623 * \param[in] Output control status buffer descriptor
624 * \param[out] Pointer to store the ID for Input data Que
625 * \param[out] Pointer to store the ID for Input control Que
626 * \param[out] Pointer to store the ID for Output data Que
627 * \param[out] Pointer to store the ID for Output control status Que
628 *
629 * \return
630 *  success or fail
631 *
632 * \author
633 *  Ittiam
634 *
635 *****************************************************************************
636 */
ihevce_create_ports(ihevce_hle_ctxt_t * ps_hle_ctxt,iv_input_data_ctrl_buffs_desc_t * ps_input_data_ctrl_buffs_desc,iv_input_asynch_ctrl_buffs_desc_t * ps_input_asynch_ctrl_buffs_desc,iv_res_layer_output_data_buffs_desc_t * ps_mres_output_data_buffs_desc,iv_res_layer_recon_data_buffs_desc_t * ps_mres_recon_data_buffs_desc)637 IV_API_CALL_STATUS_T ihevce_create_ports(
638     ihevce_hle_ctxt_t *ps_hle_ctxt,
639     iv_input_data_ctrl_buffs_desc_t *ps_input_data_ctrl_buffs_desc,
640     iv_input_asynch_ctrl_buffs_desc_t *ps_input_asynch_ctrl_buffs_desc,
641     iv_res_layer_output_data_buffs_desc_t *ps_mres_output_data_buffs_desc,
642     iv_res_layer_recon_data_buffs_desc_t *ps_mres_recon_data_buffs_desc)
643 {
644     /* local varaibles */
645     enc_ctxt_t *ps_enc_ctxt;
646     WORD32 res_ctr,
647         i4_num_resolutions = ps_hle_ctxt->ps_static_cfg_prms->s_tgt_lyr_prms.i4_num_res_layers;
648     void *pv_q_mutex_hdl = NULL;
649 
650     /* set no error in the output */
651     ps_hle_ctxt->i4_error_code = 0;
652 
653     for(res_ctr = 0; res_ctr < i4_num_resolutions; res_ctr++)
654     {
655         ps_enc_ctxt = (enc_ctxt_t *)ps_hle_ctxt->apv_enc_hdl[res_ctr];
656         /* check on buffer sizes provided by applciation needs to be checked */
657 
658         /* call the memory manager que init function , pass the op data , status, recon for the first bitrate, internally we will increment*/
659         ihevce_mem_manager_que_init(
660             ps_enc_ctxt,
661             ps_hle_ctxt,
662             ps_input_data_ctrl_buffs_desc,
663             ps_input_asynch_ctrl_buffs_desc,
664             &ps_mres_output_data_buffs_desc->s_output_data_buffs[res_ctr][0],
665             &ps_mres_recon_data_buffs_desc->s_recon_data_buffs[res_ctr][0]);
666 
667         /* set the number of Queues */
668         ps_enc_ctxt->s_enc_ques.i4_num_queues = IHEVCE_MAX_NUM_QUEUES;
669 
670         /* allocate a mutex to take care of handling multiple threads accesing Queues */
671         /*my understanding, this is common semaphore for all the queue. Since main input is still
672         common across all instance fo encoder. Hence common semaphore is a must*/
673         if(0 == res_ctr)
674         {
675             ps_enc_ctxt->s_enc_ques.pv_q_mutex_hdl = osal_mutex_create(ps_hle_ctxt->pv_osal_handle);
676             /* store it in local variable for allocating it to other instances */
677             pv_q_mutex_hdl = ps_enc_ctxt->s_enc_ques.pv_q_mutex_hdl;
678             if(NULL == pv_q_mutex_hdl)
679             {
680                 return IV_FAIL;
681             }
682         }
683         else
684         {
685             ps_enc_ctxt->s_enc_ques.pv_q_mutex_hdl = pv_q_mutex_hdl;
686         }
687 
688         /* Set the i/o queues created status to 1 */
689         ps_enc_ctxt->i4_io_queues_created = 1;
690     }
691     return (IV_SUCCESS);
692 }
693 
694 /*!
695 ******************************************************************************
696 * \if Function name : ihevce_hle_interface_thrd \endif
697 *
698 * \brief
699 *    High level encoder thread interface function
700 *
701 * \param[in] High level interface context pointer
702 *
703 * \return
704 *    None
705 *
706 * \author
707 *  Ittiam
708 *
709 *****************************************************************************
710 */
ihevce_hle_interface_thrd(void * pv_proc_intf_ctxt)711 WORD32 ihevce_hle_interface_thrd(void *pv_proc_intf_ctxt)
712 {
713     /* local variables */
714     WORD32 ctr, res_ctr;
715     ihevce_hle_ctxt_t *ps_hle_ctxt;
716     enc_ctxt_t *ps_enc_ctxt;
717     /* enc ctxt to store 0th instance's params which are required by all instances */
718     enc_ctxt_t *ps_enc_ctxt_base;
719     void *pv_lap_sem_hdl;
720     void *pv_enc_frame_process_sem_hdl;
721     void *pv_pre_enc_frame_process_sem_hdl;
722     void *apv_ent_coding_sem_hdl[IHEVCE_MAX_NUM_BITRATES];
723     void *pv_ent_common_mres_sem_hdl = NULL;
724     void *pv_out_common_mres_sem_hdl = NULL;
725 
726     void *pv_inp_data_sem_hdl;
727     void *pv_lap_inp_data_sem_hdl;
728     void *pv_preenc_inp_data_sem_hdl;
729     void *pv_inp_ctrl_sem_hdl;
730     void *apv_out_stream_sem_hdl[IHEVCE_MAX_NUM_BITRATES];
731     void *apv_out_recon_sem_hdl[IHEVCE_MAX_NUM_BITRATES];
732     void *pv_out_ctrl_sts_sem_hdl;
733 
734     lap_intface_t *ps_lap_interface_ctxt;
735     iv_mem_rec_t s_memtab;
736     WORD32 i4_num_bit_rate_instances[IHEVCE_MAX_NUM_RESOLUTIONS], i4_num_resolutions;
737     WORD32 i;  //loop variable
738     WORD32 ai4_proc_count[MAX_NUMBER_PROC_GRPS] = { 0 }, i4_proc_grp_count;
739     WORD32 i4_acc_proc_num = 0;
740 
741     /* Frame Encode processing threads & semaphores */
742     void *apv_enc_frm_proc_hdls[IHEVCE_MAX_NUM_RESOLUTIONS][MAX_NUM_FRM_PROC_THRDS_ENC];
743     frm_proc_thrd_ctxt_t
744         *aps_enc_frm_proc_thrd_ctxt[IHEVCE_MAX_NUM_RESOLUTIONS][MAX_NUM_FRM_PROC_THRDS_ENC];
745 
746     /* Pre Frame Encode processing threads & semaphores */
747     void *apv_pre_enc_frm_proc_hdls[IHEVCE_MAX_NUM_RESOLUTIONS][MAX_NUM_FRM_PROC_THRDS_PRE_ENC];
748     frm_proc_thrd_ctxt_t
749         *aps_pre_enc_frm_proc_thrd_ctxt[IHEVCE_MAX_NUM_RESOLUTIONS][MAX_NUM_FRM_PROC_THRDS_PRE_ENC];
750 
751     void *apv_entropy_thrd_hdls[IHEVCE_MAX_NUM_RESOLUTIONS][NUM_ENTROPY_THREADS];
752     frm_proc_thrd_ctxt_t *aps_entropy_thrd_ctxt[IHEVCE_MAX_NUM_RESOLUTIONS][NUM_ENTROPY_THREADS];
753 
754     ps_hle_ctxt = (ihevce_hle_ctxt_t *)pv_proc_intf_ctxt;
755     ps_enc_ctxt_base = (enc_ctxt_t *)ps_hle_ctxt->apv_enc_hdl[0];
756     /* profile start */
757     PROFILE_START(&ps_hle_ctxt->profile_hle);
758     /* store default values of mem tab */
759     s_memtab.i4_size = sizeof(iv_mem_rec_t);
760     s_memtab.i4_mem_alignment = 4;
761 
762     i4_num_resolutions = ps_enc_ctxt_base->ps_stat_prms->s_tgt_lyr_prms.i4_num_res_layers;
763     memset(
764         apv_entropy_thrd_hdls,
765         0,
766         IHEVCE_MAX_NUM_RESOLUTIONS * NUM_ENTROPY_THREADS * sizeof(void *));
767     memset(
768         apv_entropy_thrd_hdls,
769         0,
770         IHEVCE_MAX_NUM_RESOLUTIONS * NUM_ENTROPY_THREADS * sizeof(void *));
771     for(res_ctr = 0; res_ctr < i4_num_resolutions; res_ctr++)
772     {
773         i4_num_bit_rate_instances[res_ctr] =
774             ps_enc_ctxt_base->ps_stat_prms->s_tgt_lyr_prms.as_tgt_params[res_ctr]
775                 .i4_num_bitrate_instances;
776     }
777     /* --------------------------------------------------------------------- */
778     /*        Init number of threads for each stage                          */
779     /* --------------------------------------------------------------------- */
780 
781     {
782         for(res_ctr = 0; res_ctr < i4_num_resolutions; res_ctr++)
783         {
784             ps_enc_ctxt = (enc_ctxt_t *)ps_hle_ctxt->apv_enc_hdl[res_ctr];
785             /* all the threads created will be made active */
786             ps_enc_ctxt->s_multi_thrd.i4_num_active_enc_thrds =
787                 ps_enc_ctxt->s_multi_thrd.i4_num_enc_proc_thrds;
788 
789             ps_enc_ctxt->s_multi_thrd.i4_num_active_pre_enc_thrds =
790                 ps_enc_ctxt->s_multi_thrd.i4_num_pre_enc_proc_thrds;
791         }
792     }
793 
794     /* --------------------------------------------------------------------- */
795     /*            Multiple processing Threads Semaphores init                */
796     /* --------------------------------------------------------------------- */
797     for(res_ctr = 0; res_ctr < i4_num_resolutions; res_ctr++)
798     {
799         osal_sem_attr_t attr = OSAL_DEFAULT_SEM_ATTR;
800 
801         ps_enc_ctxt = (enc_ctxt_t *)ps_hle_ctxt->apv_enc_hdl[res_ctr];
802 
803         attr.value = SEM_START_VALUE;
804 
805         /* Create Semaphore handle for LAP thread   */
806         if(0 == ps_enc_ctxt->i4_resolution_id)
807         {
808             pv_lap_sem_hdl = osal_sem_create(ps_hle_ctxt->pv_osal_handle, &attr);
809             if(NULL == pv_lap_sem_hdl)
810             {
811                 return IV_FAIL;
812             }
813         }
814         else
815         {
816             /*NOTE: Tile workspace assigned this to null. Confirm this*/
817             pv_lap_sem_hdl = ps_enc_ctxt_base->s_thrd_sem_ctxt.pv_lap_sem_handle;
818         }
819         /* Create Semaphore for encode frame process thread */
820         pv_enc_frame_process_sem_hdl = osal_sem_create(ps_hle_ctxt->pv_osal_handle, &attr);
821         if(NULL == pv_enc_frame_process_sem_hdl)
822         {
823             return IV_FAIL;
824         }
825 
826         /* Create Semaphore for pre_encode frame process thread */
827         pv_pre_enc_frame_process_sem_hdl = osal_sem_create(ps_hle_ctxt->pv_osal_handle, &attr);
828         if(NULL == pv_pre_enc_frame_process_sem_hdl)
829         {
830             return IV_FAIL;
831         }
832 
833         /* Create Semaphore for input frame data q function */
834         if(0 == ps_enc_ctxt->i4_resolution_id)
835         {
836             pv_inp_data_sem_hdl = osal_sem_create(ps_hle_ctxt->pv_osal_handle, &attr);
837             if(NULL == pv_inp_data_sem_hdl)
838             {
839                 return IV_FAIL;
840             }
841         }
842         else
843         {
844             pv_inp_data_sem_hdl = ps_enc_ctxt_base->s_thrd_sem_ctxt.pv_inp_data_sem_handle;
845         }
846 
847         /*creating new input queue owned by encoder*/
848         /* Create Semaphore for input frame data q function */
849         pv_lap_inp_data_sem_hdl = osal_sem_create(ps_hle_ctxt->pv_osal_handle, &attr);
850         if(NULL == pv_lap_inp_data_sem_hdl)
851         {
852             return IV_FAIL;
853         }
854 
855         /* Create Semaphore for input frame data q function */
856         pv_preenc_inp_data_sem_hdl = osal_sem_create(ps_hle_ctxt->pv_osal_handle, &attr);
857         if(NULL == pv_preenc_inp_data_sem_hdl)
858         {
859             return IV_FAIL;
860         }
861 
862         /* Create Semaphore for input conrol data q function */
863         if(0 == ps_enc_ctxt->i4_resolution_id)
864         {
865             pv_inp_ctrl_sem_hdl = osal_sem_create(ps_hle_ctxt->pv_osal_handle, &attr);
866             if(NULL == pv_inp_ctrl_sem_hdl)
867             {
868                 return IV_FAIL;
869             }
870         }
871         else
872         { /*Inp ctrl queue is same for all resolutions between app and lap*/
873             pv_inp_ctrl_sem_hdl = ps_enc_ctxt_base->s_thrd_sem_ctxt.pv_inp_ctrl_sem_handle;
874         }
875 
876         /* Create Semaphore for output control status data q function */
877         pv_out_ctrl_sts_sem_hdl = osal_sem_create(ps_hle_ctxt->pv_osal_handle, &attr);
878         if(NULL == pv_out_ctrl_sts_sem_hdl)
879         {
880             return IV_FAIL;
881         }
882 
883         /* Multi res single output case singel output queue is used for all output resolutions */
884         if(1 == ps_enc_ctxt_base->ps_stat_prms->s_tgt_lyr_prms.i4_mres_single_out)
885         {
886             ps_enc_ctxt->s_enc_ques.apv_q_hdl[IHEVCE_OUTPUT_DATA_Q] =
887                 ps_enc_ctxt_base->s_enc_ques.apv_q_hdl[IHEVCE_OUTPUT_DATA_Q];
888             if(0 == ps_enc_ctxt->i4_resolution_id)
889             {
890                 /* Create Semaphore for enropy coding thread   */
891                 pv_ent_common_mres_sem_hdl = osal_sem_create(ps_hle_ctxt->pv_osal_handle, &attr);
892                 if(NULL == pv_ent_common_mres_sem_hdl)
893                 {
894                     return IV_FAIL;
895                 }
896 
897                 /* Create Semaphore for output stream data q function */
898                 pv_out_common_mres_sem_hdl = osal_sem_create(ps_hle_ctxt->pv_osal_handle, &attr);
899                 if(NULL == pv_out_common_mres_sem_hdl)
900                 {
901                     return IV_FAIL;
902                 }
903             }
904             ps_enc_ctxt->s_thrd_sem_ctxt.pv_ent_common_mres_sem_hdl = pv_ent_common_mres_sem_hdl;
905             ps_enc_ctxt->s_thrd_sem_ctxt.pv_out_common_mres_sem_hdl = pv_out_common_mres_sem_hdl;
906         }
907 
908         /*create entropy and output semaphores for each thread.
909         Each thread will correspond to each bit-rate instance running */
910         for(i = 0; i < i4_num_bit_rate_instances[res_ctr]; i++)
911         {
912             /* Create Semaphore for enropy coding thread   */
913             apv_ent_coding_sem_hdl[i] = osal_sem_create(ps_hle_ctxt->pv_osal_handle, &attr);
914             if(NULL == apv_ent_coding_sem_hdl[i])
915             {
916                 return IV_FAIL;
917             }
918 
919             /* Create Semaphore for output stream data q function */
920             apv_out_stream_sem_hdl[i] = osal_sem_create(ps_hle_ctxt->pv_osal_handle, &attr);
921             if(NULL == apv_out_stream_sem_hdl[i])
922             {
923                 return IV_FAIL;
924             }
925 
926             /* Create Semaphore for output recon data q function */
927             apv_out_recon_sem_hdl[i] = osal_sem_create(ps_hle_ctxt->pv_osal_handle, &attr);
928             if(NULL == apv_out_recon_sem_hdl[i])
929             {
930                 return IV_FAIL;
931             }
932         }
933 
934         /* update the semaphore handles and the thread creates status */
935 
936         ps_enc_ctxt->s_thrd_sem_ctxt.pv_enc_frm_proc_sem_handle = pv_enc_frame_process_sem_hdl;
937         ps_enc_ctxt->s_thrd_sem_ctxt.pv_pre_enc_frm_proc_sem_handle =
938             pv_pre_enc_frame_process_sem_hdl;
939         ps_enc_ctxt->s_thrd_sem_ctxt.pv_lap_sem_handle = pv_lap_sem_hdl;
940         ps_enc_ctxt->s_thrd_sem_ctxt.pv_inp_data_sem_handle = pv_inp_data_sem_hdl;
941         ps_enc_ctxt->s_thrd_sem_ctxt.pv_lap_inp_data_sem_hdl = pv_lap_inp_data_sem_hdl;
942         ps_enc_ctxt->s_thrd_sem_ctxt.pv_preenc_inp_data_sem_hdl = pv_preenc_inp_data_sem_hdl;
943         ps_enc_ctxt->s_thrd_sem_ctxt.pv_inp_ctrl_sem_handle = pv_inp_ctrl_sem_hdl;
944         ps_enc_ctxt->s_thrd_sem_ctxt.pv_out_ctrl_sem_handle = pv_out_ctrl_sts_sem_hdl;
945         for(i = 0; i < i4_num_bit_rate_instances[res_ctr]; i++)
946         {
947             ps_enc_ctxt->s_thrd_sem_ctxt.apv_ent_cod_sem_handle[i] = apv_ent_coding_sem_hdl[i];
948             ps_enc_ctxt->s_thrd_sem_ctxt.apv_out_strm_sem_handle[i] = apv_out_stream_sem_hdl[i];
949             ps_enc_ctxt->s_thrd_sem_ctxt.apv_out_recon_sem_handle[i] = apv_out_recon_sem_hdl[i];
950         }
951     }
952 
953     /* --------------------------------------------------------------------- */
954     /*            Multiple processing Threads Mutex init                     */
955     /* --------------------------------------------------------------------- */
956     for(res_ctr = 0; res_ctr < i4_num_resolutions; res_ctr++)
957     {
958         ps_enc_ctxt = (enc_ctxt_t *)ps_hle_ctxt->apv_enc_hdl[res_ctr];
959 
960         /* create a mutex lock for Job Queue access accross slave threads of encode frame processing */
961         ps_enc_ctxt->s_multi_thrd.pv_job_q_mutex_hdl_enc_grp_me =
962             osal_mutex_create(ps_hle_ctxt->pv_osal_handle);
963         if(NULL == ps_enc_ctxt->s_multi_thrd.pv_job_q_mutex_hdl_enc_grp_me)
964         {
965             return IV_FAIL;
966         }
967 
968         /* create a mutex lock for Job Queue access accross slave threads of encode frame processing */
969         ps_enc_ctxt->s_multi_thrd.pv_job_q_mutex_hdl_enc_grp_enc_loop =
970             osal_mutex_create(ps_hle_ctxt->pv_osal_handle);
971         if(NULL == ps_enc_ctxt->s_multi_thrd.pv_job_q_mutex_hdl_enc_grp_enc_loop)
972         {
973             return IV_FAIL;
974         }
975 
976         /* create mutex for enc thread group */
977         for(i = 0; i < MAX_NUM_ME_PARALLEL; i++)
978         {
979             ps_enc_ctxt->s_multi_thrd.apv_mutex_handle[i] =
980                 osal_mutex_create(ps_hle_ctxt->pv_osal_handle);
981             if(NULL == ps_enc_ctxt->s_multi_thrd.apv_mutex_handle[i])
982             {
983                 return IV_FAIL;
984             }
985 
986             ps_enc_ctxt->s_multi_thrd.apv_mutex_handle_me_end[i] =
987                 osal_mutex_create(ps_hle_ctxt->pv_osal_handle);
988             if(NULL == ps_enc_ctxt->s_multi_thrd.apv_mutex_handle_me_end[i])
989             {
990                 return IV_FAIL;
991             }
992         }
993 
994         for(i = 0; i < MAX_NUM_ENC_LOOP_PARALLEL; i++)
995         {
996             ps_enc_ctxt->s_multi_thrd.apv_post_enc_mutex_handle[i] =
997                 osal_mutex_create(ps_hle_ctxt->pv_osal_handle);
998             if(NULL == ps_enc_ctxt->s_multi_thrd.apv_post_enc_mutex_handle[i])
999             {
1000                 return IV_FAIL;
1001             }
1002 
1003             ps_enc_ctxt->s_multi_thrd.apv_mutex_handle_frame_init[i] =
1004                 osal_mutex_create(ps_hle_ctxt->pv_osal_handle);
1005             if(NULL == ps_enc_ctxt->s_multi_thrd.apv_mutex_handle_frame_init[i])
1006             {
1007                 return IV_FAIL;
1008             }
1009         }
1010 
1011         /*initialize mutex for pre-enc group */
1012         ps_enc_ctxt->s_multi_thrd.pv_mutex_hdl_pre_enc_init =
1013             osal_mutex_create(ps_hle_ctxt->pv_osal_handle);
1014 
1015         ps_enc_ctxt->s_multi_thrd.pv_mutex_hdl_pre_enc_decomp_deinit =
1016             osal_mutex_create(ps_hle_ctxt->pv_osal_handle);
1017 
1018         ps_enc_ctxt->s_multi_thrd.pv_mutex_hdl_pre_enc_hme_init =
1019             osal_mutex_create(ps_hle_ctxt->pv_osal_handle);
1020 
1021         ps_enc_ctxt->s_multi_thrd.pv_mutex_hdl_pre_enc_hme_deinit =
1022             osal_mutex_create(ps_hle_ctxt->pv_osal_handle);
1023 
1024         ps_enc_ctxt->s_multi_thrd.pv_mutex_hdl_pre_enc_deinit =
1025             osal_mutex_create(ps_hle_ctxt->pv_osal_handle);
1026 
1027         ps_enc_ctxt->s_multi_thrd.pv_mutex_hdl_l0_ipe_init =
1028             osal_mutex_create(ps_hle_ctxt->pv_osal_handle);
1029 
1030         ps_enc_ctxt->s_multi_thrd.pv_job_q_mutex_hdl_pre_enc_decomp =
1031             osal_mutex_create(ps_hle_ctxt->pv_osal_handle);
1032 
1033         ps_enc_ctxt->s_multi_thrd.pv_job_q_mutex_hdl_pre_enc_hme =
1034             osal_mutex_create(ps_hle_ctxt->pv_osal_handle);
1035 
1036         ps_enc_ctxt->s_multi_thrd.pv_job_q_mutex_hdl_pre_enc_l0ipe =
1037             osal_mutex_create(ps_hle_ctxt->pv_osal_handle);
1038 
1039         if(NULL == ps_enc_ctxt->s_multi_thrd.pv_mutex_hdl_pre_enc_init ||
1040            NULL == ps_enc_ctxt->s_multi_thrd.pv_mutex_hdl_pre_enc_decomp_deinit ||
1041            NULL == ps_enc_ctxt->s_multi_thrd.pv_mutex_hdl_pre_enc_hme_init ||
1042            NULL == ps_enc_ctxt->s_multi_thrd.pv_mutex_hdl_pre_enc_hme_deinit ||
1043            NULL == ps_enc_ctxt->s_multi_thrd.pv_mutex_hdl_pre_enc_deinit ||
1044            NULL == ps_enc_ctxt->s_multi_thrd.pv_mutex_hdl_l0_ipe_init ||
1045            NULL == ps_enc_ctxt->s_multi_thrd.pv_job_q_mutex_hdl_pre_enc_decomp ||
1046            NULL == ps_enc_ctxt->s_multi_thrd.pv_job_q_mutex_hdl_pre_enc_hme ||
1047            NULL == ps_enc_ctxt->s_multi_thrd.pv_job_q_mutex_hdl_pre_enc_l0ipe)
1048         {
1049             return IV_FAIL;
1050         }
1051     }
1052 
1053     /* --------------------------------------------------------------------- */
1054     /*            Multiple processing Threads Context init                   */
1055     /* --------------------------------------------------------------------- */
1056 
1057     for(res_ctr = 0; res_ctr < i4_num_resolutions; res_ctr++)
1058     {
1059         ps_enc_ctxt = (enc_ctxt_t *)ps_hle_ctxt->apv_enc_hdl[res_ctr];
1060         ps_enc_ctxt_base = (enc_ctxt_t *)ps_hle_ctxt->apv_enc_hdl[0];
1061 
1062         /*initialize multi-thread context for enc group*/
1063         ps_enc_ctxt->s_multi_thrd.i4_is_recon_free_done = 0;
1064         ps_enc_ctxt->s_multi_thrd.i4_idx_dvsr_p = 0;
1065         ps_enc_ctxt->s_multi_thrd.i4_last_inp_buf = 0;
1066 
1067         {
1068             /* For all the ME frames in Parallel */
1069             WORD32 i4_frm_idx;
1070 
1071             for(i4_frm_idx = 0; i4_frm_idx < MAX_NUM_ME_PARALLEL; i4_frm_idx++)
1072             {
1073                 ps_enc_ctxt->s_multi_thrd.me_num_thrds_exited[i4_frm_idx] = 0;
1074                 ps_enc_ctxt->s_multi_thrd.ai4_me_master_done_flag[i4_frm_idx] = 0;
1075                 ps_enc_ctxt->s_multi_thrd.ai4_me_enc_buff_prod_flag[i4_frm_idx] = 0;
1076             }
1077         }
1078 
1079         {
1080             WORD32 i4_frm_idx;
1081             ps_enc_ctxt->s_multi_thrd.num_thrds_done = 0;
1082             ps_enc_ctxt->s_multi_thrd.num_thrds_exited_for_reenc = 0;
1083             for(i4_frm_idx = 0; i4_frm_idx < MAX_NUM_ENC_LOOP_PARALLEL; i4_frm_idx++)
1084             {
1085                 ps_enc_ctxt->s_multi_thrd.num_thrds_exited[i4_frm_idx] = 0;
1086 
1087                 ps_enc_ctxt->s_multi_thrd.enc_master_done_frame_init[i4_frm_idx] = 0;
1088 
1089                 for(i = 0; i < i4_num_bit_rate_instances[res_ctr]; i++)
1090                 {
1091                     /*reset the entropy buffer produced status */
1092                     ps_enc_ctxt->s_multi_thrd.ai4_produce_outbuf[i4_frm_idx][i] = 1;
1093                     ps_enc_ctxt->s_multi_thrd.ps_frm_recon[i4_frm_idx][i] = NULL;
1094 
1095                     ps_enc_ctxt->s_multi_thrd.ps_curr_out_enc_grp[i4_frm_idx][i] = NULL;
1096                 }
1097             }
1098         }
1099         ps_enc_ctxt->s_multi_thrd.i4_seq_mode_enabled_flag = 0;
1100 
1101         /* Set prev_frame_done = 1 to indicate that all the threads are in same frame*/
1102         for(i = 0; i < ps_enc_ctxt->s_multi_thrd.i4_num_enc_loop_frm_pllel; i++)
1103         {
1104             ihevce_dmgr_set_done_frm_frm_sync(
1105                 ps_enc_ctxt->s_multi_thrd.apv_dep_mngr_prev_frame_done[i]);
1106         }
1107         /* Set prev_frame_done = 1 to indicate that all the threads are in same frame*/
1108         ihevce_dmgr_set_done_frm_frm_sync(
1109             ps_enc_ctxt->s_multi_thrd.pv_dep_mngr_prev_frame_enc_done_for_reenc);
1110         /*to enable the dependency manager to wait when first reached*/
1111         ihevce_dmgr_set_prev_done_frm_frm_sync(
1112             ps_enc_ctxt->s_multi_thrd.pv_dep_mngr_prev_frame_enc_done_for_reenc);
1113         for(i = 0; i < ps_enc_ctxt->s_multi_thrd.i4_num_me_frm_pllel; i++)
1114         {
1115             ihevce_dmgr_set_done_frm_frm_sync(
1116                 ps_enc_ctxt->s_multi_thrd.apv_dep_mngr_prev_frame_me_done[i]);
1117         }
1118 
1119         /* initialize multi-thread context for pre enc group */
1120 
1121         ps_enc_ctxt->s_multi_thrd.i4_ctrl_blocking_mode = BUFF_QUE_BLOCKING_MODE;
1122 
1123         for(ctr = 0; ctr < MAX_PRE_ENC_STAGGER + NUM_BUFS_DECOMP_HME; ctr++)
1124         {
1125             ps_enc_ctxt->s_multi_thrd.ai4_pre_enc_init_done[ctr] = 0;
1126             ps_enc_ctxt->s_multi_thrd.ai4_pre_enc_hme_init_done[ctr] = 0;
1127             ps_enc_ctxt->s_multi_thrd.ai4_pre_enc_deinit_done[ctr] = 1;
1128             ps_enc_ctxt->s_multi_thrd.ai4_num_thrds_processed_decomp[ctr] = 0;
1129             ps_enc_ctxt->s_multi_thrd.ai4_num_thrds_processed_coarse_me[ctr] = 0;
1130             ps_enc_ctxt->s_multi_thrd.ai4_num_thrds_processed_pre_enc[ctr] = 0;
1131 
1132             ps_enc_ctxt->s_multi_thrd.ai4_num_thrds_processed_L0_ipe_qp_init[ctr] = 0;
1133             ps_enc_ctxt->s_multi_thrd.ai4_decomp_coarse_me_complete_flag[ctr] = 1;
1134             ps_enc_ctxt->s_multi_thrd.ai4_end_flag_pre_enc[ctr] = 0;
1135         }
1136 
1137         /* Set prev_frame_done = 1 to indicate that all the threads are in same frame*/
1138         ihevce_dmgr_set_done_frm_frm_sync(
1139             ps_enc_ctxt->s_multi_thrd.pv_dep_mngr_prev_frame_pre_enc_l1);
1140 
1141         ihevce_dmgr_set_done_frm_frm_sync(
1142             ps_enc_ctxt->s_multi_thrd.pv_dep_mngr_prev_frame_pre_enc_coarse_me);
1143 
1144         ihevce_dmgr_set_done_frm_frm_sync(
1145             ps_enc_ctxt->s_multi_thrd.pv_dep_mngr_prev_frame_pre_enc_l0);
1146 
1147         {
1148             /**init idx for handling delay between pre-me and l0-ipe*/
1149             ps_enc_ctxt->s_multi_thrd.i4_delay_pre_me_btw_l0_ipe = 0;
1150             ps_enc_ctxt->s_multi_thrd.i4_max_delay_pre_me_btw_l0_ipe =
1151                 MIN_L1_L0_STAGGER_NON_SEQ +
1152                 ps_enc_ctxt->s_lap_stat_prms.s_lap_params.i4_rc_look_ahead_pics + 1;
1153             if(ps_enc_ctxt->s_lap_stat_prms.s_lap_params.i4_rc_look_ahead_pics)
1154             {
1155                 ps_enc_ctxt->s_multi_thrd.i4_delay_pre_me_btw_l0_ipe =
1156                     MIN_L1_L0_STAGGER_NON_SEQ +
1157                     ps_enc_ctxt->s_lap_stat_prms.s_lap_params.i4_rc_look_ahead_pics;
1158             }
1159             ps_enc_ctxt->s_multi_thrd.i4_qp_update_l0_ipe = -1;
1160         }
1161     }
1162 
1163     /** Get Number of Processor Groups **/
1164     i4_proc_grp_count = ps_enc_ctxt_base->ps_stat_prms->s_multi_thrd_prms.i4_num_proc_groups;
1165     /*** Enc threads are allocated based on the assumption that there can be only 2 processor groups **/
1166     ASSERT(i4_proc_grp_count <= MAX_NUMBER_PROC_GRPS);
1167     /** Get Number of logical processors in Each Group **/
1168     for(ctr = 0; ctr < i4_proc_grp_count; ctr++)
1169     {
1170         ai4_proc_count[ctr] =
1171             ps_enc_ctxt_base->ps_stat_prms->s_multi_thrd_prms.ai4_num_cores_per_grp[ctr];
1172     }
1173 
1174     /* --------------------------------------------------------------------- */
1175     /*            Create a LAP thread                                        */
1176     /* --------------------------------------------------------------------- */
1177     /* LAP thread will run on  0th resolution instance context */
1178     {
1179         s_memtab.e_mem_type = IV_EXT_CACHEABLE_NORMAL_MEM;
1180         s_memtab.i4_mem_size = sizeof(lap_intface_t);
1181 
1182         /* initialise the interface strucure parameters */
1183         ps_hle_ctxt->ihevce_mem_alloc(
1184             ps_hle_ctxt->pv_mem_mgr_hdl, &ps_enc_ctxt_base->ps_stat_prms->s_sys_api, &s_memtab);
1185         if(s_memtab.pv_base == NULL)
1186         {
1187             return (IV_FAIL);
1188         }
1189 
1190         ps_lap_interface_ctxt = (lap_intface_t *)s_memtab.pv_base;
1191 
1192         /* populate the params */
1193         ps_lap_interface_ctxt->pv_hle_ctxt = ps_hle_ctxt;
1194         ps_enc_ctxt = (enc_ctxt_t *)ps_hle_ctxt->apv_enc_hdl[0];
1195         ps_lap_interface_ctxt->pv_lap_module_ctxt = ps_enc_ctxt->s_module_ctxt.pv_lap_ctxt;
1196         ps_lap_interface_ctxt->i4_ctrl_in_que_id = IHEVCE_INPUT_ASYNCH_CTRL_Q;
1197         ps_lap_interface_ctxt->i4_ctrl_out_que_id = IHEVCE_OUTPUT_STATUS_Q;
1198         ps_lap_interface_ctxt->i4_ctrl_cmd_buf_size = ENC_COMMAND_BUFF_SIZE;
1199         ps_lap_interface_ctxt->i4_ctrl_in_que_blocking_mode = BUFF_QUE_BLOCKING_MODE;
1200         ps_lap_interface_ctxt->ps_sys_api = &ps_enc_ctxt_base->ps_stat_prms->s_sys_api;
1201         ps_enc_ctxt_base->pv_lap_interface_ctxt = (void *)ps_lap_interface_ctxt;
1202         ps_lap_interface_ctxt->ihevce_dyn_bitrate_cb = ihevce_dyn_bitrate;
1203     }
1204 
1205     /* --------------------------------------------------------------------- */
1206     /*          Create Entropy Coding threads                             */
1207     /* --------------------------------------------------------------------- */
1208     /*Create entropy thread for each encoder instance*/
1209     for(res_ctr = 0; res_ctr < i4_num_resolutions; res_ctr++)
1210     {
1211         osal_thread_attr_t s_thread_attr = OSAL_DEFAULT_THREAD_ATTR;
1212         WORD32 i4_num_entropy_threads;
1213 
1214         /* derive encoder ctxt from hle handle */
1215         ps_enc_ctxt = (enc_ctxt_t *)ps_hle_ctxt->apv_enc_hdl[res_ctr];
1216 
1217         i4_num_entropy_threads =
1218             ps_enc_ctxt_base->ps_stat_prms->s_tgt_lyr_prms.as_tgt_params[res_ctr]
1219                 .i4_num_bitrate_instances;
1220 
1221         /* initialise the interface strucure parameters */
1222         for(ctr = 0; ctr < i4_num_entropy_threads; ctr++)
1223         {
1224             s_memtab.e_mem_type = IV_EXT_CACHEABLE_NORMAL_MEM;
1225             s_memtab.i4_mem_size = sizeof(frm_proc_thrd_ctxt_t);
1226 
1227             ps_hle_ctxt->ihevce_mem_alloc(
1228                 ps_hle_ctxt->pv_mem_mgr_hdl, &ps_enc_ctxt_base->ps_stat_prms->s_sys_api, &s_memtab);
1229             if(s_memtab.pv_base == NULL)
1230             {
1231                 return (IV_FAIL);
1232             }
1233 
1234             aps_entropy_thrd_ctxt[res_ctr][ctr] = (frm_proc_thrd_ctxt_t *)s_memtab.pv_base;
1235 
1236             /* initialise the interface strucure parameters */
1237             aps_entropy_thrd_ctxt[res_ctr][ctr]->i4_thrd_id = ctr;
1238             aps_entropy_thrd_ctxt[res_ctr][ctr]->ps_hle_ctxt = ps_hle_ctxt;
1239             aps_entropy_thrd_ctxt[res_ctr][ctr]->pv_enc_ctxt = (void *)ps_enc_ctxt;
1240 
1241             /* Initialize application thread attributes */
1242             s_thread_attr.exit_code = 0;
1243             s_thread_attr.name = 0;
1244             s_thread_attr.priority_map_flag = 1;
1245             s_thread_attr.priority = OSAL_PRIORITY_DEFAULT;
1246             s_thread_attr.stack_addr = 0;
1247             s_thread_attr.stack_size = THREAD_STACK_SIZE;
1248             s_thread_attr.thread_func = ihevce_ent_coding_thrd;
1249             s_thread_attr.thread_param =
1250                 (void *)(aps_entropy_thrd_ctxt[res_ctr]
1251                                               [ctr]);  //encioder and hle context are derived from this
1252             s_thread_attr.core_affinity_mask = 0;
1253             if(ps_enc_ctxt_base->ps_stat_prms->s_multi_thrd_prms.i4_num_proc_groups > 1)
1254             {
1255                 /* Run ENTROPY thread on last group if there are more than one processor group */
1256                 s_thread_attr.group_num =
1257                     ps_hle_ctxt->ps_static_cfg_prms->s_multi_thrd_prms.i4_num_proc_groups - 1;
1258             }
1259             else
1260             {
1261                 s_thread_attr.group_num = 0;
1262             }
1263 
1264             /* Create entropy coding thread */
1265             apv_entropy_thrd_hdls[res_ctr][ctr] =
1266                 osal_thread_create(ps_hle_ctxt->pv_osal_handle, &s_thread_attr);
1267             if(NULL == apv_entropy_thrd_hdls[res_ctr][ctr])
1268             {
1269                 return IV_FAIL;
1270             }
1271         }
1272     }
1273 
1274     /* --------------------------------------------------------------------- */
1275     /*     Create all Slave Encode Frame processing threads                  */
1276     /* - -------------------------------------------------------------------- */
1277     for(res_ctr = 0; res_ctr < i4_num_resolutions; res_ctr++)
1278     {
1279         WORD32 enc_ctr = 0;
1280         WORD32 i4_loop_count;
1281         WORD32 i4_curr_grp_num = 0;
1282         ps_enc_ctxt = (enc_ctxt_t *)ps_hle_ctxt->apv_enc_hdl[res_ctr];
1283 
1284         i4_acc_proc_num = 0;
1285         /* Calculate the start core number of enc threads for current resolution */
1286         for(i4_loop_count = 0; i4_loop_count < res_ctr; i4_loop_count++)
1287         {
1288             /* Add number of cores taken by each resolution till the curr resolution */
1289             enc_ctr += ps_hle_ctxt->ai4_num_core_per_res[i4_loop_count];
1290         }
1291         if(ps_enc_ctxt_base->ps_stat_prms->s_multi_thrd_prms.i4_num_proc_groups > 1)
1292         {
1293             /* Select the group number for each res based on processors present in each group */
1294             for(i4_loop_count = 0;
1295                 i4_loop_count <
1296                 ps_enc_ctxt_base->ps_stat_prms->s_multi_thrd_prms.i4_num_proc_groups;
1297                 i4_loop_count++)
1298             {
1299                 i4_acc_proc_num += ai4_proc_count[i4_loop_count];
1300                 if(enc_ctr >= i4_acc_proc_num)
1301                 {
1302                     /* if enc_ctr is greater than proc count for first group,
1303                     then increment group count.This group number will be starting grp num for
1304                     that resolution */
1305                     i4_curr_grp_num++;
1306                 }
1307                 else
1308                     break;
1309             }
1310         }
1311 
1312         for(ctr = 0; ctr < ps_enc_ctxt->s_multi_thrd.i4_num_enc_proc_thrds; ctr++)
1313         {
1314             osal_thread_attr_t s_thread_attr = OSAL_DEFAULT_THREAD_ATTR;
1315 
1316             s_memtab.e_mem_type = IV_EXT_CACHEABLE_NORMAL_MEM;
1317             s_memtab.i4_mem_size = sizeof(frm_proc_thrd_ctxt_t);
1318 
1319             ps_hle_ctxt->ihevce_mem_alloc(
1320                 ps_hle_ctxt->pv_mem_mgr_hdl, &ps_enc_ctxt_base->ps_stat_prms->s_sys_api, &s_memtab);
1321             if(s_memtab.pv_base == NULL)
1322             {
1323                 return (IV_FAIL);
1324             }
1325 
1326             aps_enc_frm_proc_thrd_ctxt[res_ctr][ctr] = (frm_proc_thrd_ctxt_t *)s_memtab.pv_base;
1327 
1328             /* initialise the interface strucure parameters */
1329             aps_enc_frm_proc_thrd_ctxt[res_ctr][ctr]->i4_thrd_id = ctr;
1330 
1331             aps_enc_frm_proc_thrd_ctxt[res_ctr][ctr]->ps_hle_ctxt = ps_hle_ctxt;
1332 
1333             ps_enc_ctxt = (enc_ctxt_t *)ps_hle_ctxt->apv_enc_hdl[res_ctr];
1334 
1335             aps_enc_frm_proc_thrd_ctxt[res_ctr][ctr]->pv_enc_ctxt = (void *)ps_enc_ctxt;
1336 
1337             /* Initialize application thread attributes */
1338             s_thread_attr.exit_code = 0;
1339             s_thread_attr.name = 0;
1340             s_thread_attr.priority_map_flag = 1;
1341             s_thread_attr.priority = OSAL_PRIORITY_DEFAULT;
1342             s_thread_attr.stack_addr = 0;
1343             s_thread_attr.stack_size = THREAD_STACK_SIZE;
1344             s_thread_attr.thread_func = ihevce_enc_frm_proc_slave_thrd;
1345             s_thread_attr.thread_param = (void *)(aps_enc_frm_proc_thrd_ctxt[res_ctr][ctr]);
1346             s_thread_attr.group_num = i4_curr_grp_num;
1347             if(1 == ps_enc_ctxt_base->ps_stat_prms->s_multi_thrd_prms.i4_use_thrd_affinity)
1348             {
1349                 ihevce_static_multi_thread_params_t *ps_multi_thrd_prms =
1350                     &ps_enc_ctxt_base->ps_stat_prms->s_multi_thrd_prms;
1351 
1352                 s_thread_attr.core_affinity_mask = ps_multi_thrd_prms->au8_core_aff_mask[enc_ctr];
1353                 if((enc_ctr >= i4_acc_proc_num) &&
1354                    (ps_enc_ctxt_base->ps_stat_prms->s_multi_thrd_prms.i4_num_proc_groups > 1))
1355                 {
1356                     /*** When the cores in the Group0 is exhausted start enc threads in the next Processor Group ***/
1357                     s_thread_attr.group_num++;
1358                     i4_curr_grp_num++;
1359                     /* This takes care of the condition that differnt proc groups can have diff number of cores */
1360                     i4_acc_proc_num += ai4_proc_count[i4_curr_grp_num];
1361                 }
1362             }
1363             else
1364             {
1365                 s_thread_attr.core_affinity_mask = 0;
1366                 if((enc_ctr >= i4_acc_proc_num) &&
1367                    (ps_enc_ctxt_base->ps_stat_prms->s_multi_thrd_prms.i4_num_proc_groups > 1))
1368                 {
1369                     /*** When the cores in the Group0 is exhausted start enc threads in the next Processor Group ***/
1370                     s_thread_attr.group_num++;
1371                     i4_curr_grp_num++;
1372                     /* This takes care of the condition that differnt proc groups can have diff number of cores */
1373                     i4_acc_proc_num += ai4_proc_count[i4_curr_grp_num];
1374                 }
1375             }
1376 
1377             /* Create frame processing thread */
1378             apv_enc_frm_proc_hdls[res_ctr][ctr] =
1379                 osal_thread_create(ps_hle_ctxt->pv_osal_handle, &s_thread_attr);
1380             if(NULL == apv_enc_frm_proc_hdls[res_ctr][ctr])
1381             {
1382                 return IV_FAIL;
1383             }
1384             enc_ctr++;
1385         }
1386     }
1387 
1388     /* --------------------------------------------------------------------- */
1389     /*     Create all Pre - Encode Frame processing threads                  */
1390     /* --------------------------------------------------------------------- */
1391     for(res_ctr = 0; res_ctr < i4_num_resolutions; res_ctr++)
1392     {
1393         WORD32 pre_enc_ctr = 0;
1394         WORD32 i4_loop_count;
1395         WORD32 i4_curr_grp_num = 0;
1396         ps_enc_ctxt = (enc_ctxt_t *)ps_hle_ctxt->apv_enc_hdl[res_ctr];
1397 
1398         i4_acc_proc_num = 0;
1399 
1400         for(i4_loop_count = 0; i4_loop_count < res_ctr; i4_loop_count++)
1401             pre_enc_ctr += ps_hle_ctxt->ai4_num_core_per_res[i4_loop_count];
1402         if(ps_enc_ctxt->s_multi_thrd.i4_all_thrds_active_flag)
1403         {
1404             /* If its sequential mode of operation enc and pre-enc threads to be given same core affinity mask */
1405             pre_enc_ctr -= ps_enc_ctxt->s_multi_thrd.i4_num_enc_proc_thrds;
1406         }
1407 
1408         if(ps_enc_ctxt_base->ps_stat_prms->s_multi_thrd_prms.i4_num_proc_groups > 1)
1409         {
1410             /* Select the group number for each res based on processors present in each group */
1411             for(i4_loop_count = 0;
1412                 i4_loop_count <
1413                 ps_enc_ctxt_base->ps_stat_prms->s_multi_thrd_prms.i4_num_proc_groups;
1414                 i4_loop_count++)
1415             {
1416                 i4_acc_proc_num += ai4_proc_count[i4_loop_count];
1417                 if((pre_enc_ctr + ps_enc_ctxt->s_multi_thrd.i4_num_enc_proc_thrds) >=
1418                    i4_acc_proc_num)
1419                 {
1420                     /* if pre_enc_ctr is greater than proc count for first group,
1421                     then increment group count.This group number will be starting grp num for
1422                     that resolution */
1423                     i4_curr_grp_num++;
1424                 }
1425                 else
1426                     break;
1427             }
1428         }
1429 
1430         for(ctr = 0; ctr < ps_enc_ctxt->s_multi_thrd.i4_num_pre_enc_proc_thrds; ctr++)
1431         {
1432             osal_thread_attr_t s_thread_attr = OSAL_DEFAULT_THREAD_ATTR;
1433 
1434             s_memtab.e_mem_type = IV_EXT_CACHEABLE_NORMAL_MEM;
1435             s_memtab.i4_mem_size = sizeof(frm_proc_thrd_ctxt_t);
1436 
1437             ps_hle_ctxt->ihevce_mem_alloc(
1438                 ps_hle_ctxt->pv_mem_mgr_hdl, &ps_enc_ctxt_base->ps_stat_prms->s_sys_api, &s_memtab);
1439             if(s_memtab.pv_base == NULL)
1440             {
1441                 return (IV_FAIL);
1442             }
1443 
1444             aps_pre_enc_frm_proc_thrd_ctxt[res_ctr][ctr] = (frm_proc_thrd_ctxt_t *)s_memtab.pv_base;
1445 
1446             /* initialise the interface strucure parameters */
1447             aps_pre_enc_frm_proc_thrd_ctxt[res_ctr][ctr]->i4_thrd_id = ctr;
1448 
1449             aps_pre_enc_frm_proc_thrd_ctxt[res_ctr][ctr]->ps_hle_ctxt = ps_hle_ctxt;
1450             ps_enc_ctxt = (enc_ctxt_t *)ps_hle_ctxt->apv_enc_hdl[res_ctr];
1451             aps_pre_enc_frm_proc_thrd_ctxt[res_ctr][ctr]->pv_enc_ctxt = (void *)ps_enc_ctxt;
1452 
1453             /* Initialize application thread attributes */
1454             s_thread_attr.exit_code = 0;
1455             s_thread_attr.name = 0;
1456             s_thread_attr.priority_map_flag = 1;
1457             s_thread_attr.priority = OSAL_PRIORITY_DEFAULT;
1458             s_thread_attr.stack_addr = 0;
1459             s_thread_attr.stack_size = THREAD_STACK_SIZE;
1460             s_thread_attr.thread_func = ihevce_pre_enc_process_frame_thrd;
1461             s_thread_attr.thread_param = (void *)(aps_pre_enc_frm_proc_thrd_ctxt[res_ctr][ctr]);
1462             s_thread_attr.group_num = i4_curr_grp_num;
1463 
1464             if(1 == ps_enc_ctxt_base->ps_stat_prms->s_multi_thrd_prms.i4_use_thrd_affinity)
1465             {
1466                 ihevce_static_multi_thread_params_t *ps_multi_thrd_prms =
1467                     &ps_enc_ctxt_base->ps_stat_prms->s_multi_thrd_prms;
1468 
1469                 s_thread_attr.core_affinity_mask =
1470                     ps_multi_thrd_prms->au8_core_aff_mask
1471                         [pre_enc_ctr + ps_enc_ctxt->s_multi_thrd.i4_num_enc_proc_thrds];
1472                 if(((pre_enc_ctr + ps_enc_ctxt->s_multi_thrd.i4_num_enc_proc_thrds) >=
1473                     i4_acc_proc_num) &&
1474                    (ps_enc_ctxt_base->ps_stat_prms->s_multi_thrd_prms.i4_num_proc_groups > 1))
1475                 {
1476                     /*** When the cores in the Group0 is exhausted start enc threads in the next Processor Group ***/
1477                     s_thread_attr.group_num++;
1478                     i4_curr_grp_num++;
1479                     /* This takes care of the condition that differnt proc groups can have diff number of cores */
1480                     i4_acc_proc_num += ai4_proc_count[i4_curr_grp_num];
1481                 }
1482             }
1483             else
1484             {
1485                 s_thread_attr.core_affinity_mask = 0;
1486 
1487                 if(((pre_enc_ctr + ps_enc_ctxt->s_multi_thrd.i4_num_enc_proc_thrds) >=
1488                     i4_acc_proc_num) &&
1489                    (ps_enc_ctxt_base->ps_stat_prms->s_multi_thrd_prms.i4_num_proc_groups > 1))
1490                 {
1491                     /*** When the cores in the Group0 is exhausted start enc threads in the next Processor Group ***/
1492                     s_thread_attr.group_num++;
1493                     i4_curr_grp_num++;
1494                     /* This takes care of the condition that differnt proc groups can have diff number of cores */
1495                     i4_acc_proc_num += ai4_proc_count[i4_curr_grp_num];
1496                 }
1497             }
1498 
1499             /* Create frame processing thread */
1500             apv_pre_enc_frm_proc_hdls[res_ctr][ctr] =
1501                 osal_thread_create(ps_hle_ctxt->pv_osal_handle, &s_thread_attr);
1502             if(NULL == apv_pre_enc_frm_proc_hdls[res_ctr][ctr])
1503             {
1504                 return IV_FAIL;
1505             }
1506             pre_enc_ctr++;
1507         }
1508     }
1509 
1510     /* Set the threads init done Flag */
1511     ps_hle_ctxt->i4_hle_init_done = 1;
1512 
1513     /* --------------------------------------------------------------------- */
1514     /*            Wait and destroy Processing threads                        */
1515     /* --------------------------------------------------------------------- */
1516 
1517     /* --------------------------------------------------------------------- */
1518     /*           Frame process Pre - Encode threads destroy                  */
1519     /* --------------------------------------------------------------------- */
1520     for(res_ctr = 0; res_ctr < i4_num_resolutions; res_ctr++)
1521     {
1522         ps_enc_ctxt = (enc_ctxt_t *)ps_hle_ctxt->apv_enc_hdl[res_ctr];
1523 
1524         for(ctr = 0; ctr < ps_enc_ctxt->s_multi_thrd.i4_num_pre_enc_proc_thrds; ctr++)
1525         {
1526             /* Wait for thread to complete */
1527             osal_thread_wait(apv_pre_enc_frm_proc_hdls[res_ctr][ctr]);
1528 
1529             /* Destroy thread */
1530             osal_thread_destroy(apv_pre_enc_frm_proc_hdls[res_ctr][ctr]);
1531 
1532             s_memtab.i4_mem_size = sizeof(frm_proc_thrd_ctxt_t);
1533             s_memtab.e_mem_type = IV_EXT_CACHEABLE_NORMAL_MEM;
1534             s_memtab.pv_base = (void *)aps_pre_enc_frm_proc_thrd_ctxt[res_ctr][ctr];
1535 
1536             /* free the ctxt memory */
1537             ps_hle_ctxt->ihevce_mem_free(ps_hle_ctxt->pv_mem_mgr_hdl, &s_memtab);
1538         }
1539     }
1540 
1541     /* --------------------------------------------------------------------- */
1542     /*           Frame process Encode slave threads destroy                  */
1543     /* --------------------------------------------------------------------- */
1544     for(res_ctr = 0; res_ctr < i4_num_resolutions; res_ctr++)
1545     {
1546         ps_enc_ctxt = (enc_ctxt_t *)ps_hle_ctxt->apv_enc_hdl[res_ctr];
1547 
1548         for(ctr = 0; ctr < ps_enc_ctxt->s_multi_thrd.i4_num_enc_proc_thrds; ctr++)
1549         {
1550             /* Wait for thread to complete */
1551             osal_thread_wait(apv_enc_frm_proc_hdls[res_ctr][ctr]);
1552 
1553             /* Destroy thread */
1554             osal_thread_destroy(apv_enc_frm_proc_hdls[res_ctr][ctr]);
1555 
1556             s_memtab.i4_mem_size = sizeof(frm_proc_thrd_ctxt_t);
1557             s_memtab.e_mem_type = IV_EXT_CACHEABLE_NORMAL_MEM;
1558             s_memtab.pv_base = (void *)aps_enc_frm_proc_thrd_ctxt[res_ctr][ctr];
1559 
1560             /* free the ctxt memory */
1561             ps_hle_ctxt->ihevce_mem_free(ps_hle_ctxt->pv_mem_mgr_hdl, &s_memtab);
1562         }
1563     }
1564 
1565     /* --------------------------------------------------------------------- */
1566     /*           Entropy threads destroy                                     */
1567     /* --------------------------------------------------------------------- */
1568     for(res_ctr = 0; res_ctr < i4_num_resolutions; res_ctr++)
1569     {
1570         WORD32 i4_num_bitrates =
1571             ps_enc_ctxt_base->ps_stat_prms->s_tgt_lyr_prms.as_tgt_params[res_ctr]
1572                 .i4_num_bitrate_instances;
1573 
1574         for(ctr = 0; ctr < i4_num_bitrates; ctr++)
1575         {
1576             /* Wait for Entropy Coding thread to complete */
1577             osal_thread_wait(apv_entropy_thrd_hdls[res_ctr][ctr]);
1578 
1579             /* Destroy Entropy Coding thread */
1580             osal_thread_destroy(apv_entropy_thrd_hdls[res_ctr][ctr]);
1581 
1582             //semaphore will come here
1583 
1584             s_memtab.i4_mem_size = sizeof(frm_proc_thrd_ctxt_t);
1585             s_memtab.e_mem_type = IV_EXT_CACHEABLE_NORMAL_MEM;
1586             s_memtab.pv_base = (void *)aps_entropy_thrd_ctxt[res_ctr][ctr];
1587 
1588             /* free the ctxt memory */
1589             ps_hle_ctxt->ihevce_mem_free(ps_hle_ctxt->pv_mem_mgr_hdl, &s_memtab);
1590         }
1591     }
1592 
1593     s_memtab.i4_mem_size = sizeof(lap_intface_t);
1594     s_memtab.e_mem_type = IV_EXT_CACHEABLE_NORMAL_MEM;
1595     s_memtab.pv_base = (void *)ps_lap_interface_ctxt;
1596     ps_hle_ctxt->ihevce_mem_free(ps_hle_ctxt->pv_mem_mgr_hdl, &s_memtab);
1597     /* profile stop */
1598     PROFILE_STOP(&ps_hle_ctxt->profile_hle, NULL);
1599     return (0);
1600 }
1601 
1602 /*!
1603 ******************************************************************************
1604 * \if Function name : ihevce_q_get_free_inp_data_buff \endif
1605 *
1606 * \brief
1607 *    Gets a free buffer from the que requested
1608 *
1609 * \param[in] high level encoder context pointer
1610 * \param[in] pointer to return the buffer id
1611 * \param[in] blocking mode / non blocking mode
1612 *
1613 * \return
1614 *    None
1615 *
1616 * \author
1617 *  Ittiam
1618 *
1619 *****************************************************************************
1620 */
ihevce_q_get_free_inp_data_buff(ihevce_hle_ctxt_t * ps_hle_ctxt,WORD32 * pi4_buff_id,WORD32 i4_blocking_mode)1621 void *ihevce_q_get_free_inp_data_buff(
1622     ihevce_hle_ctxt_t *ps_hle_ctxt, WORD32 *pi4_buff_id, WORD32 i4_blocking_mode)
1623 {
1624     void *pv_ptr;
1625     enc_ctxt_t *ps_enc_ctxt;
1626     WORD32 i4_resolution_id = 0;
1627 
1628     ps_enc_ctxt = (enc_ctxt_t *)ps_hle_ctxt->apv_enc_hdl[i4_resolution_id];
1629     if(ps_enc_ctxt->i4_frame_limit_reached == 1)
1630     {
1631         return (NULL);
1632     }
1633     /*Input buffer is same for all enc handles*/
1634     pv_ptr = ihevce_q_get_free_buff(
1635         ps_hle_ctxt->apv_enc_hdl[0], IHEVCE_INPUT_DATA_CTRL_Q, pi4_buff_id, i4_blocking_mode);
1636 
1637     return (pv_ptr);
1638 }
1639 
1640 /*!
1641 ******************************************************************************
1642 * \if Function name : ihevce_q_get_free_inp_ctrl_buff \endif
1643 *
1644 * \brief
1645 *    Gets a free buffer from the que requested
1646 *
1647 * \param[in] high level encoder context pointer
1648 * \param[in] pointer to return the buffer id
1649 * \param[in] blocking mode / non blocking mode
1650 *
1651 * \return
1652 *    None
1653 *
1654 * \author
1655 *  Ittiam
1656 *
1657 *****************************************************************************
1658 */
ihevce_q_get_free_inp_ctrl_buff(ihevce_hle_ctxt_t * ps_hle_ctxt,WORD32 * pi4_buff_id,WORD32 i4_blocking_mode)1659 void *ihevce_q_get_free_inp_ctrl_buff(
1660     ihevce_hle_ctxt_t *ps_hle_ctxt, WORD32 *pi4_buff_id, WORD32 i4_blocking_mode)
1661 {
1662     void *pv_ptr;
1663 
1664     /*Input buffer is same for all enc handles*/
1665     pv_ptr = ihevce_q_get_free_buff(
1666         ps_hle_ctxt->apv_enc_hdl[0], IHEVCE_INPUT_ASYNCH_CTRL_Q, pi4_buff_id, i4_blocking_mode);
1667 
1668     return (pv_ptr);
1669 }
1670 
1671 /*!
1672 ******************************************************************************
1673 * \if Function name : ihevce_q_get_free_out_strm_buff \endif
1674 *
1675 * \brief
1676 *    Gets a free buffer from the que requested
1677 *
1678 * \param[in] high level encoder context pointer
1679 * \param[in] pointer to return the buffer id
1680 * \param[in] blocking mode / non blocking mode
1681 *
1682 * \return
1683 *    None
1684 *
1685 * \author
1686 *  Ittiam
1687 *
1688 *****************************************************************************
1689 */
ihevce_q_get_free_out_strm_buff(ihevce_hle_ctxt_t * ps_hle_ctxt,WORD32 * pi4_buff_id,WORD32 i4_blocking_mode,WORD32 i4_bitrate_instance,WORD32 i4_res_instance)1690 void *ihevce_q_get_free_out_strm_buff(
1691     ihevce_hle_ctxt_t *ps_hle_ctxt,
1692     WORD32 *pi4_buff_id,
1693     WORD32 i4_blocking_mode,
1694     WORD32 i4_bitrate_instance,
1695     WORD32 i4_res_instance)
1696 {
1697     void *pv_ptr;
1698 
1699     pv_ptr = ihevce_q_get_free_buff(
1700         ps_hle_ctxt->apv_enc_hdl[i4_res_instance],
1701         (IHEVCE_OUTPUT_DATA_Q + i4_bitrate_instance),
1702         pi4_buff_id,
1703         i4_blocking_mode);
1704     return (pv_ptr);
1705 }
1706 
1707 /*!
1708 ******************************************************************************
1709 * \if Function name : ihevce_q_get_free_out_recon_buff \endif
1710 *
1711 * \brief
1712 *    Gets a free buffer from the que requested
1713 *
1714 * \param[in] high level encoder context pointer
1715 * \param[in] pointer to return the buffer id
1716 * \param[in] blocking mode / non blocking mode
1717 *
1718 * \return
1719 *    None
1720 *
1721 * \author
1722 *  Ittiam
1723 *
1724 *****************************************************************************
1725 */
ihevce_q_get_free_out_recon_buff(ihevce_hle_ctxt_t * ps_hle_ctxt,WORD32 * pi4_buff_id,WORD32 i4_blocking_mode,WORD32 i4_bitrate_instance,WORD32 i4_res_instance)1726 void *ihevce_q_get_free_out_recon_buff(
1727     ihevce_hle_ctxt_t *ps_hle_ctxt,
1728     WORD32 *pi4_buff_id,
1729     WORD32 i4_blocking_mode,
1730     WORD32 i4_bitrate_instance,
1731     WORD32 i4_res_instance)
1732 {
1733     void *pv_ptr;
1734 
1735     pv_ptr = ihevce_q_get_free_buff(
1736         ps_hle_ctxt->apv_enc_hdl[i4_res_instance],
1737         (IHEVCE_RECON_DATA_Q + i4_bitrate_instance),
1738         pi4_buff_id,
1739         i4_blocking_mode);
1740     return (pv_ptr);
1741 }
1742 
1743 /*!
1744 ******************************************************************************
1745 * \if Function name : ihevce_q_set_inp_data_buff_prod \endif
1746 *
1747 * \brief
1748 *    Sets the input data buffer as produced in the que requested
1749 *
1750 * \param[in] high level encoder context pointer
1751 * \param[in] buffer id which needs to be set as produced
1752 *
1753 * \return
1754 *    None
1755 *
1756 * \author
1757 *  Ittiam
1758 *
1759 *****************************************************************************
1760 */
1761 IV_API_CALL_STATUS_T
ihevce_q_set_inp_data_buff_prod(ihevce_hle_ctxt_t * ps_hle_ctxt,WORD32 i4_buff_id)1762     ihevce_q_set_inp_data_buff_prod(ihevce_hle_ctxt_t *ps_hle_ctxt, WORD32 i4_buff_id)
1763 {
1764     IV_API_CALL_STATUS_T ret_status;
1765 
1766     ret_status =
1767         ihevce_q_set_buff_prod(ps_hle_ctxt->apv_enc_hdl[0], IHEVCE_INPUT_DATA_CTRL_Q, i4_buff_id);
1768 
1769     return (ret_status);
1770 }
1771 
1772 /*!
1773 ******************************************************************************
1774 * \if Function name : ihevce_q_set_inp_ctrl_buff_prod \endif
1775 *
1776 * \brief
1777 *    Sets the input data buffer as produced in the que requested
1778 *
1779 * \param[in] high level encoder context pointer
1780 * \param[in] buffer id which needs to be set as produced
1781 *
1782 * \return
1783 *    None
1784 *
1785 * \author
1786 *  Ittiam
1787 *
1788 *****************************************************************************
1789 */
1790 IV_API_CALL_STATUS_T
ihevce_q_set_inp_ctrl_buff_prod(ihevce_hle_ctxt_t * ps_hle_ctxt,WORD32 i4_buff_id)1791     ihevce_q_set_inp_ctrl_buff_prod(ihevce_hle_ctxt_t *ps_hle_ctxt, WORD32 i4_buff_id)
1792 
1793 {
1794     IV_API_CALL_STATUS_T ret_status;
1795 
1796     ret_status =
1797         ihevce_q_set_buff_prod(ps_hle_ctxt->apv_enc_hdl[0], IHEVCE_INPUT_ASYNCH_CTRL_Q, i4_buff_id);
1798 
1799     return (ret_status);
1800 }
1801 
1802 /*!
1803 ******************************************************************************
1804 * \if Function name : ihevce_q_set_out_strm_buff_prod \endif
1805 *
1806 * \brief
1807 *    Sets the Output stream buffer as produced in the que requested
1808 *
1809 * \param[in] high level encoder context pointer
1810 * \param[in] buffer id which needs to be set as produced
1811 *
1812 * \return
1813 *    None
1814 *
1815 * \author
1816 *  Ittiam
1817 *
1818 *****************************************************************************
1819 */
ihevce_q_set_out_strm_buff_prod(ihevce_hle_ctxt_t * ps_hle_ctxt,WORD32 i4_buff_id,WORD32 i4_bitrate_instance_id,WORD32 i4_resolution_id)1820 IV_API_CALL_STATUS_T ihevce_q_set_out_strm_buff_prod(
1821     ihevce_hle_ctxt_t *ps_hle_ctxt,
1822     WORD32 i4_buff_id,
1823     WORD32 i4_bitrate_instance_id,
1824     WORD32 i4_resolution_id)
1825 {
1826     IV_API_CALL_STATUS_T ret_status;
1827 
1828     ret_status = ihevce_q_set_buff_prod(
1829         ps_hle_ctxt->apv_enc_hdl[i4_resolution_id],
1830         (IHEVCE_OUTPUT_DATA_Q + i4_bitrate_instance_id),
1831         i4_buff_id);
1832 
1833     return (ret_status);
1834 }
1835 
1836 /*!
1837 ******************************************************************************
1838 * \if Function name : ihevce_q_set_out_recon_buff_prod \endif
1839 *
1840 * \brief
1841 *    Sets the Output recon buffer as produced in the que requested
1842 *
1843 * \param[in] high level encoder context pointer
1844 * \param[in] buffer id which needs to be set as produced
1845 *
1846 * \return
1847 *    None
1848 *
1849 * \author
1850 *  Ittiam
1851 *
1852 *****************************************************************************
1853 */
ihevce_q_set_out_recon_buff_prod(ihevce_hle_ctxt_t * ps_hle_ctxt,WORD32 i4_buff_id,WORD32 i4_bitrate_instance_id,WORD32 i4_resolution_id)1854 IV_API_CALL_STATUS_T ihevce_q_set_out_recon_buff_prod(
1855     ihevce_hle_ctxt_t *ps_hle_ctxt,
1856     WORD32 i4_buff_id,
1857     WORD32 i4_bitrate_instance_id,
1858     WORD32 i4_resolution_id)
1859 {
1860     IV_API_CALL_STATUS_T ret_status;
1861 
1862     ret_status = ihevce_q_set_buff_prod(
1863         ps_hle_ctxt->apv_enc_hdl[i4_resolution_id],
1864         (IHEVCE_RECON_DATA_Q + i4_bitrate_instance_id),
1865         i4_buff_id);
1866 
1867     return (ret_status);
1868 }
1869 
1870 //recon_dump
1871 /*!
1872 ******************************************************************************
1873 * \if Function name : ihevce_q_get_filled_recon_buff \endif
1874 *
1875 * \brief
1876 *    Gets a next filled recon buffer from the que requested
1877 *
1878 * \param[in] high level encoder context pointer
1879 * \param[in] pointer to return the buffer id
1880 * \param[in] blocking mode / non blocking mode
1881 *
1882 * \return
1883 *    None
1884 *
1885 * \author
1886 *  Ittiam
1887 *
1888 *****************************************************************************
1889 */
ihevce_q_get_filled_recon_buff(ihevce_hle_ctxt_t * ps_hle_ctxt,WORD32 * pi4_buff_id,WORD32 i4_blocking_mode,WORD32 i4_bitrate_instance_id,WORD32 i4_resolution_id)1890 void *ihevce_q_get_filled_recon_buff(
1891     ihevce_hle_ctxt_t *ps_hle_ctxt,
1892     WORD32 *pi4_buff_id,
1893     WORD32 i4_blocking_mode,
1894     WORD32 i4_bitrate_instance_id,
1895     WORD32 i4_resolution_id)
1896 {
1897     void *pv_ptr;
1898 
1899     pv_ptr = ihevce_q_get_filled_buff(
1900         ps_hle_ctxt->apv_enc_hdl[i4_resolution_id],
1901         IHEVCE_RECON_DATA_Q + i4_bitrate_instance_id,
1902         pi4_buff_id,
1903         i4_blocking_mode);
1904 
1905     return (pv_ptr);
1906 }
1907 
1908 /*!
1909 ******************************************************************************
1910 * \if Function name : ihevce_q_get_filled_ctrl_sts_buff \endif
1911 *
1912 * \brief
1913 *    Gets a next filled control status buffer from the que requested
1914 *
1915 * \param[in] high level encoder context pointer
1916 * \param[in] pointer to return the buffer id
1917 * \param[in] blocking mode / non blocking mode
1918 *
1919 * \return
1920 *    None
1921 *
1922 * \author
1923 *  Ittiam
1924 *
1925 *****************************************************************************
1926 */
ihevce_q_get_filled_ctrl_sts_buff(ihevce_hle_ctxt_t * ps_hle_ctxt,WORD32 * pi4_buff_id,WORD32 i4_blocking_mode)1927 void *ihevce_q_get_filled_ctrl_sts_buff(
1928     ihevce_hle_ctxt_t *ps_hle_ctxt, WORD32 *pi4_buff_id, WORD32 i4_blocking_mode)
1929 {
1930     void *pv_ptr;
1931     pv_ptr = ihevce_q_get_filled_buff(
1932         ps_hle_ctxt->apv_enc_hdl[0], IHEVCE_OUTPUT_STATUS_Q, pi4_buff_id, i4_blocking_mode);
1933 
1934     return (pv_ptr);
1935 }
1936 
1937 //recon_dump
1938 /*!
1939 ******************************************************************************
1940 * \if Function name : ihevce_q_rel_recon_buf \endif
1941 *
1942 * \brief
1943 *    Frees the recon buffer in the recon buffer que
1944 *
1945 * \param[in] high level encoder context pointer
1946 * \param[in] buffer id which needs to be freed
1947 *
1948 * \return
1949 *    None
1950 *
1951 * \author
1952 *  Ittiam
1953 *
1954 *****************************************************************************
1955 */
ihevce_q_rel_recon_buf(ihevce_hle_ctxt_t * ps_hle_ctxt,WORD32 i4_buff_id,WORD32 i4_bitrate_instance_id,WORD32 i4_resolution_id)1956 IV_API_CALL_STATUS_T ihevce_q_rel_recon_buf(
1957     ihevce_hle_ctxt_t *ps_hle_ctxt,
1958     WORD32 i4_buff_id,
1959     WORD32 i4_bitrate_instance_id,
1960     WORD32 i4_resolution_id)
1961 {
1962     IV_API_CALL_STATUS_T ret_status;
1963 
1964     ret_status = ihevce_q_rel_buf(
1965         ps_hle_ctxt->apv_enc_hdl[i4_resolution_id],
1966         IHEVCE_RECON_DATA_Q + i4_bitrate_instance_id,
1967         i4_buff_id);
1968 
1969     return (ret_status);
1970 }
1971 
1972 /*!
1973 ******************************************************************************
1974 * \if Function name : ihevce_q_rel_ctrl_sts_buf \endif
1975 *
1976 * \brief
1977 *    Frees the output control sttus buffer in buffer que
1978 *
1979 * \param[in] high level encoder context pointer
1980 * \param[in] buffer id which needs to be freed
1981 *
1982 * \return
1983 *    None
1984 *
1985 * \author
1986 *  Ittiam
1987 *
1988 *****************************************************************************
1989 */
ihevce_q_rel_ctrl_sts_buf(ihevce_hle_ctxt_t * ps_hle_ctxt,WORD32 i4_buff_id)1990 IV_API_CALL_STATUS_T ihevce_q_rel_ctrl_sts_buf(ihevce_hle_ctxt_t *ps_hle_ctxt, WORD32 i4_buff_id)
1991 {
1992     IV_API_CALL_STATUS_T ret_status;
1993 
1994     ret_status = ihevce_q_rel_buf(ps_hle_ctxt->apv_enc_hdl[0], IHEVCE_OUTPUT_STATUS_Q, i4_buff_id);
1995 
1996     return (ret_status);
1997 }
1998 
1999 /*!
2000 ******************************************************************************
2001 * \if Function name : ihevce_hle_interface_delete \endif
2002 *
2003 * \brief
2004 *    High leve encoder delete interface
2005 *
2006 * \param[in] high level encoder interface context pointer
2007 *
2008 * \return
2009 *    None
2010 *
2011 * \author
2012 *  Ittiam
2013 *
2014 *****************************************************************************
2015 */
ihevce_hle_interface_delete(ihevce_hle_ctxt_t * ps_hle_ctxt)2016 IV_API_CALL_STATUS_T ihevce_hle_interface_delete(ihevce_hle_ctxt_t *ps_hle_ctxt)
2017 {
2018     /* local varaibles */
2019     enc_ctxt_t *ps_enc_ctxt;
2020     iv_mem_rec_t s_memtab;
2021     WORD32 ctr = 0, i, res_ctr, i4_num_resolutions;
2022     WORD32 ai4_num_bitrate_instances[IHEVCE_MAX_NUM_RESOLUTIONS] = { 1 };
2023 
2024     i4_num_resolutions = ps_hle_ctxt->ps_static_cfg_prms->s_tgt_lyr_prms.i4_num_res_layers;
2025     for(ctr = 0; ctr < i4_num_resolutions; ctr++)
2026     {
2027         ai4_num_bitrate_instances[ctr] =
2028             ps_hle_ctxt->ps_static_cfg_prms->s_tgt_lyr_prms.as_tgt_params[ctr]
2029                 .i4_num_bitrate_instances;
2030     }
2031 
2032     for(res_ctr = 0; res_ctr < i4_num_resolutions && ps_hle_ctxt->apv_enc_hdl[res_ctr]; res_ctr++)
2033     {
2034         ps_enc_ctxt = (enc_ctxt_t *)ps_hle_ctxt->apv_enc_hdl[res_ctr];
2035 
2036         if(res_ctr == 0)
2037         {
2038             osal_sem_destroy(ps_enc_ctxt->s_thrd_sem_ctxt.pv_lap_sem_handle);
2039             osal_sem_destroy(ps_enc_ctxt->s_thrd_sem_ctxt.pv_inp_data_sem_handle);
2040             osal_sem_destroy(ps_enc_ctxt->s_thrd_sem_ctxt.pv_inp_ctrl_sem_handle);
2041             if(1 == ps_hle_ctxt->ps_static_cfg_prms->s_tgt_lyr_prms.i4_mres_single_out)
2042             {
2043                 osal_sem_destroy(ps_enc_ctxt->s_thrd_sem_ctxt.pv_ent_common_mres_sem_hdl);
2044                 osal_sem_destroy(ps_enc_ctxt->s_thrd_sem_ctxt.pv_out_common_mres_sem_hdl);
2045             }
2046         }
2047 
2048         osal_sem_destroy(ps_enc_ctxt->s_thrd_sem_ctxt.pv_lap_inp_data_sem_hdl);
2049         osal_sem_destroy(ps_enc_ctxt->s_thrd_sem_ctxt.pv_preenc_inp_data_sem_hdl);
2050 
2051         osal_sem_destroy(ps_enc_ctxt->s_thrd_sem_ctxt.pv_enc_frm_proc_sem_handle);
2052         osal_sem_destroy(ps_enc_ctxt->s_thrd_sem_ctxt.pv_pre_enc_frm_proc_sem_handle);
2053 
2054         osal_sem_destroy(ps_enc_ctxt->s_thrd_sem_ctxt.pv_out_ctrl_sem_handle);
2055 
2056         for(i = 0; i < ps_hle_ctxt->ps_static_cfg_prms->s_tgt_lyr_prms.as_tgt_params[res_ctr]
2057                            .i4_num_bitrate_instances;
2058             i++)
2059         {
2060             osal_sem_destroy(ps_enc_ctxt->s_thrd_sem_ctxt.apv_ent_cod_sem_handle[i]);
2061             osal_sem_destroy(ps_enc_ctxt->s_thrd_sem_ctxt.apv_out_strm_sem_handle[i]);
2062             osal_sem_destroy(ps_enc_ctxt->s_thrd_sem_ctxt.apv_out_recon_sem_handle[i]);
2063         }
2064 
2065         /* destroy the mutex  allocated for job queue usage encode group */
2066         osal_mutex_destroy(ps_enc_ctxt->s_multi_thrd.pv_job_q_mutex_hdl_enc_grp_me);
2067 
2068         /* destroy the mutex  allocated for job queue usage encode group */
2069         osal_mutex_destroy(ps_enc_ctxt->s_multi_thrd.pv_job_q_mutex_hdl_enc_grp_enc_loop);
2070 
2071         /* destroy the mutexes allocated for enc thread group */
2072         for(i = 0; i < MAX_NUM_ME_PARALLEL; i++)
2073         {
2074             osal_mutex_destroy(ps_enc_ctxt->s_multi_thrd.apv_mutex_handle[i]);
2075 
2076             osal_mutex_destroy(ps_enc_ctxt->s_multi_thrd.apv_mutex_handle_me_end[i]);
2077         }
2078 
2079         for(i = 0; i < MAX_NUM_ENC_LOOP_PARALLEL; i++)
2080         {
2081             osal_mutex_destroy(ps_enc_ctxt->s_multi_thrd.apv_mutex_handle_frame_init[i]);
2082 
2083             osal_mutex_destroy(ps_enc_ctxt->s_multi_thrd.apv_post_enc_mutex_handle[i]);
2084         }
2085 
2086         /* destroy the mutex  allocated for job queue, init and de-init
2087         usage pre enocde group */
2088         osal_mutex_destroy(ps_enc_ctxt->s_multi_thrd.pv_job_q_mutex_hdl_pre_enc_decomp);
2089         osal_mutex_destroy(ps_enc_ctxt->s_multi_thrd.pv_job_q_mutex_hdl_pre_enc_hme);
2090         osal_mutex_destroy(ps_enc_ctxt->s_multi_thrd.pv_job_q_mutex_hdl_pre_enc_l0ipe);
2091         osal_mutex_destroy(ps_enc_ctxt->s_multi_thrd.pv_mutex_hdl_pre_enc_init);
2092         osal_mutex_destroy(ps_enc_ctxt->s_multi_thrd.pv_mutex_hdl_pre_enc_decomp_deinit);
2093         osal_mutex_destroy(ps_enc_ctxt->s_multi_thrd.pv_mutex_hdl_pre_enc_hme_init);
2094         osal_mutex_destroy(ps_enc_ctxt->s_multi_thrd.pv_mutex_hdl_pre_enc_hme_deinit);
2095         osal_mutex_destroy(ps_enc_ctxt->s_multi_thrd.pv_mutex_hdl_l0_ipe_init);
2096         osal_mutex_destroy(ps_enc_ctxt->s_multi_thrd.pv_mutex_hdl_pre_enc_deinit);
2097 
2098         /* destroy the EncLoop Module */
2099         /* Note : Only Destroys the resources allocated in the module like */
2100         /* semaphore,etc. Memory free is done separately using memtabs     */
2101         ihevce_enc_loop_delete(ps_enc_ctxt->s_module_ctxt.pv_enc_loop_ctxt);
2102 
2103         /* destroy the Coarse ME Module */
2104         /* Note : Only Destroys the resources allocated in the module like */
2105         /* semaphore,etc. Memory free is done separately using memtabs     */
2106         ihevce_coarse_me_delete(
2107             ps_enc_ctxt->s_module_ctxt.pv_coarse_me_ctxt,
2108             ps_hle_ctxt->ps_static_cfg_prms,
2109             ps_enc_ctxt->i4_resolution_id);
2110         /* destroy semaphores for all the threads in pre-enc and enc */
2111         for(ctr = 0; ctr < ps_enc_ctxt->s_multi_thrd.i4_num_enc_proc_thrds; ctr++)
2112         {
2113             osal_sem_destroy(ps_enc_ctxt->s_multi_thrd.apv_enc_thrd_sem_handle[ctr]);
2114         }
2115 
2116         for(ctr = 0; ctr < ps_enc_ctxt->s_multi_thrd.i4_num_pre_enc_proc_thrds; ctr++)
2117         {
2118             osal_sem_destroy(ps_enc_ctxt->s_multi_thrd.apv_pre_enc_thrd_sem_handle[ctr]);
2119         }
2120 
2121         /* destroy the ME-EncLoop Dep Mngr */
2122         /* Note : Only Destroys the resources allocated in the module like */
2123         /* semaphore,etc. Memory free is done separately using memtabs     */
2124         for(ctr = 0; ctr < NUM_ME_ENC_BUFS; ctr++)
2125         {
2126             ihevce_dmgr_del(ps_enc_ctxt->s_multi_thrd.apv_dep_mngr_encloop_dep_me[ctr]);
2127         }
2128         /* destroy the Prev. frame EncLoop Done Dep Mngr */
2129         /* Note : Only Destroys the resources allocated in the module like */
2130         /* semaphore,etc. Memory free is done separately using memtabs     */
2131         for(i = 0; i < ps_enc_ctxt->s_multi_thrd.i4_num_enc_loop_frm_pllel; i++)
2132         {
2133             ihevce_dmgr_del(ps_enc_ctxt->s_multi_thrd.apv_dep_mngr_prev_frame_done[i]);
2134         }
2135         /* destroy the Prev. frame EncLoop Done for re-encode Dep Mngr */
2136         ihevce_dmgr_del(ps_enc_ctxt->s_multi_thrd.pv_dep_mngr_prev_frame_enc_done_for_reenc);
2137 
2138         /* destroy the Prev. frame ME Done Dep Mngr */
2139         /* Note : Only Destroys the resources allocated in the module like */
2140         /* semaphore,etc. Memory free is done separately using memtabs     */
2141         for(i = 0; i < ps_enc_ctxt->s_multi_thrd.i4_num_me_frm_pllel; i++)
2142         {
2143             ihevce_dmgr_del(ps_enc_ctxt->s_multi_thrd.apv_dep_mngr_prev_frame_me_done[i]);
2144         }
2145 
2146         /* destroy the Prev. frame PreEnc L1 Done Dep Mngr */
2147         /* Note : Only Destroys the resources allocated in the module like */
2148         /* semaphore,etc. Memory free is done separately using memtabs     */
2149         ihevce_dmgr_del(ps_enc_ctxt->s_multi_thrd.pv_dep_mngr_prev_frame_pre_enc_l1);
2150 
2151         /* destroy the Prev. frame PreEnc HME Done Dep Mngr */
2152         /* Note : Only Destroys the resources allocated in the module like */
2153         /* semaphore,etc. Memory free is done separately using memtabs     */
2154         ihevce_dmgr_del(ps_enc_ctxt->s_multi_thrd.pv_dep_mngr_prev_frame_pre_enc_coarse_me);
2155 
2156         /* destroy the Prev. frame PreEnc L0 Done Dep Mngr */
2157         /* Note : Only Destroys the resources allocated in the module like */
2158         /* semaphore,etc. Memory free is done separately using memtabs     */
2159         ihevce_dmgr_del(ps_enc_ctxt->s_multi_thrd.pv_dep_mngr_prev_frame_pre_enc_l0);
2160 
2161         /* destroy the ME-Prev Recon  Dep Mngr    */
2162         /* Note : Only Destroys the resources allocated in the module like */
2163         /* semaphore,etc. Memory free is done separately using memtabs     */
2164         for(ctr = 0; ctr < ps_enc_ctxt->ai4_num_buf_recon_q[0]; ctr++)
2165         {
2166             ihevce_dmgr_del(ps_enc_ctxt->pps_recon_buf_q[0][ctr]->pv_dep_mngr_recon);
2167         }
2168 
2169         /* destroy all the mutex created */
2170         if(res_ctr == 0)
2171         {
2172             if(NULL != ps_enc_ctxt->s_enc_ques.pv_q_mutex_hdl)
2173             {
2174                 osal_mutex_destroy(ps_enc_ctxt->s_enc_ques.pv_q_mutex_hdl);
2175             }
2176         }
2177 
2178         if(NULL != ps_enc_ctxt->pv_rc_mutex_lock_hdl)
2179         {
2180             osal_mutex_destroy(ps_enc_ctxt->pv_rc_mutex_lock_hdl);
2181         }
2182 
2183         if(NULL != ps_enc_ctxt->s_multi_thrd.pv_sub_pic_rc_mutex_lock_hdl)
2184         {
2185             osal_mutex_destroy(ps_enc_ctxt->s_multi_thrd.pv_sub_pic_rc_mutex_lock_hdl);
2186         }
2187 
2188         if(NULL != ps_enc_ctxt->s_multi_thrd.pv_sub_pic_rc_for_qp_update_mutex_lock_hdl)
2189         {
2190             osal_mutex_destroy(
2191                 ps_enc_ctxt->s_multi_thrd.pv_sub_pic_rc_for_qp_update_mutex_lock_hdl);
2192         }
2193 
2194         /* call the memrory free function */
2195         ihevce_mem_manager_free(ps_enc_ctxt, ps_hle_ctxt);
2196         if((1 == ps_hle_ctxt->ps_static_cfg_prms->s_tgt_lyr_prms.i4_mres_single_out) &&
2197            (res_ctr == 0))
2198         {
2199             s_memtab.i4_mem_size = sizeof(WORD32) * IHEVCE_MAX_NUM_RESOLUTIONS;
2200             s_memtab.i4_mem_alignment = 4;
2201             s_memtab.i4_size = sizeof(iv_mem_rec_t);
2202             s_memtab.e_mem_type = IV_EXT_CACHEABLE_NORMAL_MEM;
2203             s_memtab.pv_base = ps_enc_ctxt->s_multi_thrd.pi4_active_res_id;
2204             /* free active_res_id memory */
2205             ps_hle_ctxt->ihevce_mem_free(ps_hle_ctxt->pv_mem_mgr_hdl, &s_memtab);
2206         }
2207         if(res_ctr == (i4_num_resolutions - 1))
2208         {
2209             s_memtab.i4_mem_size = sizeof(ihevce_static_cfg_params_t);
2210             s_memtab.i4_mem_alignment = 4;
2211             s_memtab.i4_size = sizeof(iv_mem_rec_t);
2212             s_memtab.e_mem_type = IV_EXT_CACHEABLE_NORMAL_MEM;
2213             s_memtab.pv_base = ps_enc_ctxt->ps_stat_prms;
2214 
2215             /* free the encoder context pointer */
2216             ps_hle_ctxt->ihevce_mem_free(ps_hle_ctxt->pv_mem_mgr_hdl, &s_memtab);
2217         }
2218         s_memtab.i4_mem_size = sizeof(enc_ctxt_t);
2219         s_memtab.i4_mem_alignment = 4;
2220         s_memtab.i4_size = sizeof(iv_mem_rec_t);
2221         s_memtab.e_mem_type = IV_EXT_CACHEABLE_NORMAL_MEM;
2222         s_memtab.pv_base = ps_enc_ctxt;
2223 
2224         /* free the encoder context pointer */
2225         ps_hle_ctxt->ihevce_mem_free(ps_hle_ctxt->pv_mem_mgr_hdl, &s_memtab);
2226 
2227         /* reset the encoder handle to NULL */
2228         ps_hle_ctxt->apv_enc_hdl[res_ctr] = NULL;
2229     }
2230     /* profile end */
2231     PROFILE_END(&ps_hle_ctxt->profile_hle, "hle interface thread active time");
2232     for(res_ctr = 0; res_ctr < i4_num_resolutions; res_ctr++)
2233     {
2234         WORD32 i4_br_id;
2235 
2236         PROFILE_END(&ps_hle_ctxt->profile_pre_enc_l1l2[res_ctr], "pre enc l1l2 process");
2237         PROFILE_END(&ps_hle_ctxt->profile_pre_enc_l0ipe[res_ctr], "pre enc l0 ipe process");
2238         PROFILE_END(&ps_hle_ctxt->profile_enc_me[res_ctr], "enc me process");
2239         for(i4_br_id = 0; i4_br_id < ai4_num_bitrate_instances[res_ctr]; i4_br_id++)
2240         {
2241             PROFILE_END(&ps_hle_ctxt->profile_enc[res_ctr][i4_br_id], "enc loop process");
2242             PROFILE_END(&ps_hle_ctxt->profile_entropy[res_ctr][i4_br_id], "entropy process");
2243         }
2244     }
2245 
2246     /* OSAL Delete */
2247     ihevce_osal_delete((void *)ps_hle_ctxt);
2248 
2249     return (IV_SUCCESS);
2250 }
2251