Home | History | Annotate | Download | only in encoder
      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 */
    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 */
    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 */
    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 */
    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 */
    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 */
   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 */
   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 */
   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 */
   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
   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
   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 */
   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 */
   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 */
   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 */
   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 */
   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 */
   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 */
   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