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