C++程序  |  2267行  |  85.9 KB

/******************************************************************************
 *
 * Copyright (C) 2018 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at:
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 *****************************************************************************
 * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
*/

/*!
******************************************************************************
* \file ihevce_hle_interface.c
*
* \brief
*    This file contains all the functions related High level enocder
*    Interface layer
*
* \date
*    18/09/2012
*
* \author
*    Ittiam
*
* List of Functions
*    <TODO: TO BE ADDED>
*
******************************************************************************
*/

/*****************************************************************************/
/* File Includes                                                             */
/*****************************************************************************/
/* System include files */
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <assert.h>
#include <stdarg.h>
#include <math.h>
#include <time.h>

/* User include files */
#include "ihevc_typedefs.h"
#include "itt_video_api.h"
#include "ihevce_api.h"

#include "rc_cntrl_param.h"
#include "rc_frame_info_collector.h"
#include "rc_look_ahead_params.h"

#include "ihevc_defs.h"
#include "ihevc_macros.h"
#include "ihevc_debug.h"
#include "ihevc_structs.h"
#include "ihevc_platform_macros.h"
#include "ihevc_deblk.h"
#include "ihevc_itrans_recon.h"
#include "ihevc_chroma_itrans_recon.h"
#include "ihevc_chroma_intra_pred.h"
#include "ihevc_intra_pred.h"
#include "ihevc_inter_pred.h"
#include "ihevc_mem_fns.h"
#include "ihevc_padding.h"
#include "ihevc_weighted_pred.h"
#include "ihevc_sao.h"
#include "ihevc_resi_trans.h"
#include "ihevc_quant_iquant_ssd.h"
#include "ihevc_cabac_tables.h"
#include "ihevc_trans_tables.h"
#include "ihevc_trans_macros.h"

#include "ihevce_defs.h"
#include "ihevce_hle_interface.h"
#include "ihevce_hle_q_func.h"
#include "ihevce_buffer_que_interface.h"
#include "ihevce_lap_enc_structs.h"
#include "ihevce_multi_thrd_structs.h"
#include "ihevce_multi_thrd_funcs.h"
#include "ihevce_me_common_defs.h"
#include "ihevce_had_satd.h"
#include "ihevce_error_codes.h"
#include "ihevce_error_checks.h"
#include "ihevce_bitstream.h"
#include "ihevce_cabac.h"
#include "ihevce_rdoq_macros.h"
#include "ihevce_function_selector.h"
#include "ihevce_enc_structs.h"
#include "ihevce_cmn_utils_instr_set_router.h"
#include "ihevce_memory_init.h"
#include "ihevce_lap_interface.h"
#include "ihevce_entropy_cod.h"
#include "ihevce_entropy_structs.h"
#include "ihevce_frame_process_utils.h"
#include "ihevce_frame_process.h"
#include "ihevce_profile.h"
#include "ihevce_global_tables.h"
#include "ihevce_dep_mngr_interface.h"
#include "ihevce_common_utils.h"
#include "hme_datatype.h"
#include "hme_interface.h"
#include "hme_common_defs.h"
#include "hme_defs.h"
#include "ihevce_coarse_me_pass.h"
#include "ihevce_me_pass.h"
#include "ihevce_enc_loop_structs.h"
#include "ihevce_enc_loop_pass.h"

#include "cast_types.h"
#include "osal.h"
#include "osal_defaults.h"

/*****************************************************************************/
/* Function Definitions                                                      */
/*****************************************************************************/
/*!
******************************************************************************
* \if Function name : ihevce_context_reset \endif
*
* \brief
*    Encoder reset function
*
* \param[in] Encoder context pointer
*
* \return
*    None
*
* \author
*  Ittiam
*
*****************************************************************************
*/
void ihevce_context_reset(enc_ctxt_t *ps_enc_ctxt)
{
    ps_enc_ctxt->i4_end_flag = 0;

    /* set the queue related pointer and buffer to default value */
    ps_enc_ctxt->s_enc_ques.pv_q_mutex_hdl = NULL;

    /* Reset the i/o queues created status to 0 */
    ps_enc_ctxt->i4_io_queues_created = 0;

    /* reset the frame limit flag to 0 */
    ps_enc_ctxt->i4_frame_limit_reached = 0;

    return;
}

/*!
******************************************************************************
* \if Function name : ihevce_hle_interface_create \endif
*
* \brief
*    High level Encoder create function
*
* \param[in]  High level enocder interface context pointer
*
* \return
*    success or fail
*
* \author
*  Ittiam
*
*****************************************************************************
*/
IV_API_CALL_STATUS_T ihevce_hle_interface_create(ihevce_hle_ctxt_t *ps_hle_ctxt)
{
    /* local variables */
    enc_ctxt_t *ps_enc_ctxt;
    iv_mem_rec_t s_memtab;
    ihevce_static_cfg_params_t *ps_enc_static_cfg_params;
    WORD32 i4_num_resolutions = ps_hle_ctxt->ps_static_cfg_prms->s_tgt_lyr_prms.i4_num_res_layers;
    WORD32 i4_look_ahead_frames_in_first_pass = -1;
    WORD32 i4_total_cores = 0, ctr, i4_mres_flag = 0;
    ihevce_sys_api_t *ps_sys_api = &ps_hle_ctxt->ps_static_cfg_prms->s_sys_api;

    WORD32 status = 0;
    WORD32 i;
    WORD32 *pi4_active_res_id = NULL;

    /* OSAL Init */
    status = ihevce_osal_init((void *)ps_hle_ctxt);

    if(status != 0)
        return (IV_FAIL);

    /* --------------------------------------------------------------------- */
    /*              High Level Encoder Init                                  */
    /* --------------------------------------------------------------------- */

    if(i4_num_resolutions > 1)
        i4_mres_flag = 1;
    /* set no error in the output */
    ps_hle_ctxt->i4_error_code = 0;

    /* Error checks on the static parameters passed */
    ps_hle_ctxt->i4_error_code = ihevce_hle_validate_static_params(ps_hle_ctxt->ps_static_cfg_prms);

    /*memory for static cfg params for encoder, which can be overwritten if encoder wants
        encoder should use this for all its usage*/
    s_memtab.i4_size = sizeof(iv_mem_rec_t);
    s_memtab.i4_mem_alignment = 4;
    s_memtab.i4_mem_size = sizeof(ihevce_static_cfg_params_t);
    s_memtab.e_mem_type = IV_EXT_CACHEABLE_NORMAL_MEM;

    ps_hle_ctxt->ihevce_mem_alloc(
        ps_hle_ctxt->pv_mem_mgr_hdl, &ps_hle_ctxt->ps_static_cfg_prms->s_sys_api, &s_memtab);
    if(s_memtab.pv_base == NULL)
    {
        return (IV_FAIL);
    }
    ps_enc_static_cfg_params = (ihevce_static_cfg_params_t *)s_memtab.pv_base;
    memcpy(
        ps_enc_static_cfg_params,
        ps_hle_ctxt->ps_static_cfg_prms,
        (sizeof(ihevce_static_cfg_params_t)));

    i4_total_cores = ps_enc_static_cfg_params->s_multi_thrd_prms.i4_max_num_cores;

    /* check for validity of memory control flag (only 0,1,2 modes are allowed) */
    if((ps_enc_static_cfg_params->s_multi_thrd_prms.i4_memory_alloc_ctrl_flag > 2) ||
       (ps_enc_static_cfg_params->s_multi_thrd_prms.i4_memory_alloc_ctrl_flag < 0))
    {
        ps_hle_ctxt->i4_error_code = IHEVCE_INVALID_MEM_CTRL_FLAG;
    }

    if((i4_mres_flag == 1) &&
       (ps_enc_static_cfg_params->s_multi_thrd_prms.i4_use_thrd_affinity == 1))
    {
        ps_sys_api->ihevce_printf(
            ps_sys_api->pv_cb_handle,
            "\nIHEVCE WARNING: Enabling thread affinity in multiresolution encoding will affect "
            "performance\n");
    }
    if((ps_enc_static_cfg_params->s_tgt_lyr_prms.as_tgt_params[0].i4_quality_preset ==
        IHEVCE_QUALITY_P6) &&
       (ps_enc_static_cfg_params->s_config_prms.i4_cu_level_rc))
    {
        ps_sys_api->ihevce_printf(
            ps_sys_api->pv_cb_handle,
            "\nIHEVCE WARNING: Disabling CU level QP modulation for P6 preset\n");
        ps_enc_static_cfg_params->s_config_prms.i4_cu_level_rc = 0;
    }
    if((ps_enc_static_cfg_params->s_tgt_lyr_prms.as_tgt_params[0].i4_quality_preset ==
        IHEVCE_QUALITY_P7) &&
       (ps_enc_static_cfg_params->s_config_prms.i4_cu_level_rc))
    {
        ps_sys_api->ihevce_printf(
            ps_sys_api->pv_cb_handle,
            "\nIHEVCE WARNING: Disabling CU level QP modulation for P7 preset\n");
        ps_enc_static_cfg_params->s_config_prms.i4_cu_level_rc = 0;
    }

    if(0 != ps_hle_ctxt->i4_error_code)
    {
        ps_hle_ctxt->ihevce_mem_free(ps_hle_ctxt->pv_mem_mgr_hdl, &s_memtab);
        return (IV_FAIL);
    }
    ps_hle_ctxt->ai4_num_core_per_res[0] = i4_total_cores;

    if(1 == ps_enc_static_cfg_params->s_tgt_lyr_prms.i4_mres_single_out)
    {
        /*    Memory Allocation of pi4_active_res_id */
        s_memtab.i4_size = sizeof(iv_mem_rec_t);
        s_memtab.i4_mem_alignment = 4;
        s_memtab.i4_mem_size = sizeof(WORD32) * (IHEVCE_MAX_NUM_RESOLUTIONS + 1);
        s_memtab.e_mem_type = IV_EXT_CACHEABLE_NORMAL_MEM;

        ps_hle_ctxt->ihevce_mem_alloc(
            ps_hle_ctxt->pv_mem_mgr_hdl, &ps_enc_static_cfg_params->s_sys_api, &s_memtab);
        if(s_memtab.pv_base == NULL)
        {
            return (IV_FAIL);
        }

        pi4_active_res_id = (WORD32 *)s_memtab.pv_base;
    }
    /* --------------------------------------------------------------------- */
    /*    Context and Memory Initialization of Encoder ctxt                  */
    /* --------------------------------------------------------------------- */
    for(ctr = 0; ctr < i4_num_resolutions; ctr++)
    {
        WORD32 i4_br_id;
        s_memtab.i4_size = sizeof(iv_mem_rec_t);
        s_memtab.i4_mem_alignment = 4;
        s_memtab.i4_mem_size = sizeof(enc_ctxt_t);
        s_memtab.e_mem_type = IV_EXT_CACHEABLE_NORMAL_MEM;

        ps_hle_ctxt->ihevce_mem_alloc(
            ps_hle_ctxt->pv_mem_mgr_hdl, &ps_enc_static_cfg_params->s_sys_api, &s_memtab);
        if(s_memtab.pv_base == NULL)
        {
            return (IV_FAIL);
        }

        ps_enc_ctxt = (enc_ctxt_t *)s_memtab.pv_base;

        ps_enc_ctxt->ps_stat_prms = ps_enc_static_cfg_params;

        /* check of number of cores to decide the num threads active */
        ps_enc_ctxt->s_multi_thrd.i4_all_thrds_active_flag = 1;

        if(1 == ps_enc_static_cfg_params->s_tgt_lyr_prms.i4_mres_single_out)
        {
            pi4_active_res_id[ctr] = 0;
            ps_enc_ctxt->s_multi_thrd.pi4_active_res_id = pi4_active_res_id;
        }

        /*store num bit-rate instances in the encoder context */
        ps_enc_ctxt->i4_num_bitrates =
            ps_enc_static_cfg_params->s_tgt_lyr_prms.as_tgt_params[ctr].i4_num_bitrate_instances;

        if(1 == ps_enc_static_cfg_params->s_config_prms.i4_rate_control_mode)
        {
            LWORD64 i8_peak_bitrate;
            for(i4_br_id = 0; i4_br_id < ps_enc_ctxt->i4_num_bitrates; i4_br_id++)
            {
                i8_peak_bitrate =
                    (ULWORD64)(ps_enc_static_cfg_params->s_tgt_lyr_prms.as_tgt_params[ctr]
                                   .ai4_peak_bitrate[i4_br_id]);

                ps_enc_static_cfg_params->s_tgt_lyr_prms.as_tgt_params[ctr]
                    .ai4_tgt_bitrate[i4_br_id] = (WORD32)(
                    (i8_peak_bitrate * ps_enc_static_cfg_params->s_config_prms.i4_rate_factor) /
                    1000);
            }
        }

        if(BLU_RAY_SUPPORT == ps_enc_static_cfg_params->s_out_strm_prms.i4_interop_flags)
        {
            ps_enc_ctxt->i4_blu_ray_spec = 1;
        }
        else
        {
            ps_enc_ctxt->i4_blu_ray_spec = 0;
        }

        /* if all threads are required to be active */
        if(1 == ps_enc_ctxt->s_multi_thrd.i4_all_thrds_active_flag)
        {
            /* store the number of threads to be created as passed by app with HT flag */
            ps_enc_ctxt->s_multi_thrd.i4_num_enc_proc_thrds =
                ps_hle_ctxt->ai4_num_core_per_res[ctr];

            /* pre enc threads are doubled if HT is ON */
            ps_enc_ctxt->s_multi_thrd.i4_num_pre_enc_proc_thrds =
                ps_hle_ctxt->ai4_num_core_per_res[ctr];
        }
        else
        {
            // TODO: distribute threads across stages
        }

        /*Keep track of resolution id, this is used to differentiate from other encoder instance*/
        ps_enc_ctxt->i4_resolution_id = ctr;
        /* store hle ctxt in enc ctxt */
        ps_enc_ctxt->pv_hle_ctxt = (void *)ps_hle_ctxt;
        ps_enc_ctxt->pv_rc_mutex_lock_hdl = NULL;
        ps_enc_ctxt->s_multi_thrd.pv_sub_pic_rc_mutex_lock_hdl = NULL;
        ps_enc_ctxt->s_multi_thrd.pv_sub_pic_rc_for_qp_update_mutex_lock_hdl = NULL;
        ps_enc_ctxt->i4_look_ahead_frames_in_first_pass = i4_look_ahead_frames_in_first_pass;

        ps_enc_ctxt->ai4_is_past_pic_complex[0] = 0;
        ps_enc_ctxt->ai4_is_past_pic_complex[1] = 0;
        ps_enc_ctxt->i4_is_I_reset_done = 1;
        ps_enc_ctxt->i4_past_RC_reset_count = 0;
        ps_enc_ctxt->i4_future_RC_reset = 0;
        ps_enc_ctxt->i4_past_RC_scd_reset_count = 0;
        ps_enc_ctxt->i4_future_RC_scd_reset = 0;
        ps_enc_ctxt->i4_active_scene_num = -1;
        for(i = 0; i < IHEVCE_MAX_NUM_BITRATES; i++)
        {
            ps_enc_ctxt->ai4_rc_query[i] = 0;
        }
        ps_enc_ctxt->i4_active_enc_frame_id = 0;
        ps_enc_ctxt->u1_is_popcnt_available = 1;

#ifndef ARM
        ps_enc_ctxt->e_arch_type = ARCH_X86_GENERIC;
        ps_enc_ctxt->u1_is_popcnt_available = 0;
#else
        if(ps_enc_static_cfg_params->e_arch_type == ARCH_NA)
            ps_enc_ctxt->e_arch_type = ihevce_default_arch();
        else
            ps_enc_ctxt->e_arch_type = ps_enc_static_cfg_params->e_arch_type;
        ps_enc_ctxt->u1_is_popcnt_available = 0;
#endif

        {
            ps_enc_static_cfg_params->e_arch_type = ps_enc_ctxt->e_arch_type;

            ihevce_init_function_ptr(ps_enc_ctxt, ps_enc_ctxt->e_arch_type);
        }

        ihevce_mem_manager_init(ps_enc_ctxt, ps_hle_ctxt);

        if(0 != ps_hle_ctxt->i4_error_code)
        {
            return (IV_FAIL);
        }

        /* mutex lock for RC calls */
        ps_enc_ctxt->pv_rc_mutex_lock_hdl = osal_mutex_create(ps_hle_ctxt->pv_osal_handle);
        if(NULL == ps_enc_ctxt->pv_rc_mutex_lock_hdl)
        {
            return IV_FAIL;
        }

        /* mutex lock for Sub pic RC calls */
        ps_enc_ctxt->s_multi_thrd.pv_sub_pic_rc_mutex_lock_hdl =
            osal_mutex_create(ps_hle_ctxt->pv_osal_handle);
        if(NULL == ps_enc_ctxt->s_multi_thrd.pv_sub_pic_rc_mutex_lock_hdl)
        {
            return IV_FAIL;
        }

        ps_enc_ctxt->s_multi_thrd.pv_sub_pic_rc_for_qp_update_mutex_lock_hdl =
            osal_mutex_create(ps_hle_ctxt->pv_osal_handle);
        if(NULL == ps_enc_ctxt->s_multi_thrd.pv_sub_pic_rc_for_qp_update_mutex_lock_hdl)
        {
            return IV_FAIL;
        }

        /* reset the encoder context */
        ihevce_context_reset(ps_enc_ctxt);

        /* register the Encoder context in HLE interface ctxt */
        ps_hle_ctxt->apv_enc_hdl[ctr] = ps_enc_ctxt;
    }
    /* init profile */
    PROFILE_INIT(&ps_hle_ctxt->profile_hle);
    for(ctr = 0; ctr < i4_num_resolutions; ctr++)
    {
        WORD32 i4_br_id;

        PROFILE_INIT(&ps_hle_ctxt->profile_pre_enc[ctr]);
        for(i4_br_id = 0; i4_br_id < ps_enc_ctxt->i4_num_bitrates; i4_br_id++)
        {
            PROFILE_INIT(&ps_hle_ctxt->profile_enc[ctr][i4_br_id]);
            PROFILE_INIT(&ps_hle_ctxt->profile_entropy[ctr][i4_br_id]);
        }
    }
    if(1 == ps_enc_static_cfg_params->s_tgt_lyr_prms.i4_mres_single_out)
        pi4_active_res_id[i4_num_resolutions] = 0;

    return (IV_SUCCESS);
}

/*!
******************************************************************************
* \if Function name : ihevce_query_io_buf_req \endif
*
* \brief
*    High level Encoder IO buffers query function
*
* \param[in] High level encoder interface context pointer
* \param[out] Input buffer requirment stucture pointer.
* \param[out] Output buffer requirment stucture pointer.
*
* \return
*    success or fail
*
* \author
*  Ittiam
*
*****************************************************************************
*/
IV_API_CALL_STATUS_T ihevce_query_io_buf_req(
    ihevce_hle_ctxt_t *ps_hle_ctxt,
    iv_input_bufs_req_t *ps_input_bufs_req,
    iv_res_layer_output_bufs_req_t *ps_res_layer_output_bufs_req,
    iv_res_layer_recon_bufs_req_t *ps_res_layer_recon_bufs_req)
{
    /* local variables */
    enc_ctxt_t *ps_enc_ctxt;
    ihevce_src_params_t *ps_src_prms;
    WORD32 ctb_align_pic_wd;
    WORD32 ctb_align_pic_ht, i4_resolution_id = 0, i4_num_resolutions, i4_num_bitrate_instances;
    WORD32 i4_resolution_id_ctr, br_ctr;

    ps_enc_ctxt = (enc_ctxt_t *)ps_hle_ctxt->apv_enc_hdl[i4_resolution_id];
    ps_src_prms = &ps_hle_ctxt->ps_static_cfg_prms->s_src_prms;
    i4_num_resolutions = ps_hle_ctxt->ps_static_cfg_prms->s_tgt_lyr_prms.i4_num_res_layers;
    /* set no error in the output */
    ps_hle_ctxt->i4_error_code = 0;

    /* ------- populate the Input buffer requirements -------- */
    /* get the number of buffers required for LAP */
    ps_input_bufs_req->i4_min_num_yuv_bufs =
        ihevce_lap_get_num_ip_bufs(&ps_enc_ctxt->s_lap_stat_prms);

    ps_input_bufs_req->i4_min_num_synch_ctrl_bufs = ps_input_bufs_req->i4_min_num_yuv_bufs;

    ps_input_bufs_req->i4_min_num_asynch_ctrl_bufs = NUM_AYSNC_CMD_BUFS;

    /* buffer sizes are populated based on create time parameters */
    ctb_align_pic_wd =
        ps_src_prms->i4_width +
        SET_CTB_ALIGN(ps_src_prms->i4_width, ps_enc_ctxt->s_frm_ctb_prms.i4_ctb_size);

    ctb_align_pic_ht =
        ps_src_prms->i4_height +
        SET_CTB_ALIGN(ps_src_prms->i4_height, ps_enc_ctxt->s_frm_ctb_prms.i4_ctb_size);

    if(ps_src_prms->i4_input_bit_depth > 8)
    {
        ps_input_bufs_req->i4_min_size_y_buf = ctb_align_pic_wd * ctb_align_pic_ht * 2;

        ps_input_bufs_req->i4_min_size_uv_buf = ps_input_bufs_req->i4_min_size_y_buf >> 1;
    }
    else
    {
        ps_input_bufs_req->i4_min_size_y_buf = ctb_align_pic_wd * ctb_align_pic_ht;

        ps_input_bufs_req->i4_min_size_uv_buf = (ctb_align_pic_wd * ctb_align_pic_ht) >> 1;
    }

    ps_input_bufs_req->i4_min_size_uv_buf <<=
        ((ps_src_prms->i4_chr_format == IV_YUV_422SP_UV) ? 1 : 0);

    ps_input_bufs_req->i4_yuv_format = ps_src_prms->i4_chr_format;

    ps_input_bufs_req->i4_min_size_synch_ctrl_bufs =
        ((MAX_SEI_PAYLOAD_PER_TLV + 16) * MAX_NUMBER_OF_SEI_PAYLOAD) + 16;

    ps_input_bufs_req->i4_min_size_asynch_ctrl_bufs =
        ((MAX_SEI_PAYLOAD_PER_TLV + 16) * (MAX_NUMBER_OF_SEI_PAYLOAD - 6)) + 16;

    for(i4_resolution_id_ctr = 0; i4_resolution_id_ctr < i4_num_resolutions; i4_resolution_id_ctr++)
    {
        ps_enc_ctxt = (enc_ctxt_t *)ps_hle_ctxt->apv_enc_hdl[i4_resolution_id_ctr];

        i4_num_bitrate_instances = ps_enc_ctxt->s_runtime_tgt_params.i4_num_bitrate_instances;

        /* buffer sizes are populated based on create time parameters */
        ctb_align_pic_wd = ps_enc_ctxt->s_runtime_tgt_params.i4_width +
                           SET_CTB_ALIGN(
                               ps_enc_ctxt->s_runtime_tgt_params.i4_width,
                               ps_enc_ctxt->s_frm_ctb_prms.i4_ctb_size);

        ctb_align_pic_ht = ps_enc_ctxt->s_runtime_tgt_params.i4_height +
                           SET_CTB_ALIGN(
                               ps_enc_ctxt->s_runtime_tgt_params.i4_height,
                               ps_enc_ctxt->s_frm_ctb_prms.i4_ctb_size);

        for(br_ctr = 0; br_ctr < i4_num_bitrate_instances; br_ctr++)
        {
            /* ------- populate the Output buffer requirements -------- */
            ps_res_layer_output_bufs_req->s_output_buf_req[i4_resolution_id_ctr][br_ctr]
                .i4_min_num_out_bufs = NUM_OUTPUT_BUFS;

            ps_res_layer_output_bufs_req->s_output_buf_req[i4_resolution_id_ctr][br_ctr]
                .i4_min_size_bitstream_buf = (ctb_align_pic_wd * ctb_align_pic_ht);

            if((ps_hle_ctxt->ps_static_cfg_prms->s_tgt_lyr_prms.i4_internal_bit_depth == 12) ||
               ((ps_hle_ctxt->ps_static_cfg_prms->s_tgt_lyr_prms.i4_internal_bit_depth > 8) &&
                (ps_src_prms->i4_chr_format == IV_YUV_422SP_UV)))
            {
                ps_res_layer_output_bufs_req->s_output_buf_req[i4_resolution_id_ctr][br_ctr]
                    .i4_min_size_bitstream_buf *= 2;
            }

            if((ps_hle_ctxt->ps_static_cfg_prms->s_tgt_lyr_prms.i4_internal_bit_depth == 10) &&
               (ps_src_prms->i4_chr_format == IV_YUV_420SP_UV))
            {
                ps_res_layer_output_bufs_req->s_output_buf_req[i4_resolution_id_ctr][br_ctr]
                    .i4_min_size_bitstream_buf *= 3;
                ps_res_layer_output_bufs_req->s_output_buf_req[i4_resolution_id_ctr][br_ctr]
                    .i4_min_size_bitstream_buf >>= 1;
            }

            //recon_dump
            /* ------- populate the Recon buffer requirements -------- */
            if(ps_enc_ctxt->ps_stat_prms->i4_save_recon == 0)
            {
                ps_res_layer_recon_bufs_req->s_recon_buf_req[i4_resolution_id_ctr][br_ctr]
                    .i4_min_num_recon_bufs = 0;

                ps_res_layer_recon_bufs_req->s_recon_buf_req[i4_resolution_id_ctr][br_ctr]
                    .i4_min_size_y_buf = 0;

                ps_res_layer_recon_bufs_req->s_recon_buf_req[i4_resolution_id_ctr][br_ctr]
                    .i4_min_size_uv_buf = 0;
            }
            else
            {
                ps_res_layer_recon_bufs_req->s_recon_buf_req[i4_resolution_id_ctr][br_ctr]
                    .i4_min_num_recon_bufs = 2 * HEVCE_MAX_REF_PICS + 1;

                ps_res_layer_recon_bufs_req->s_recon_buf_req[i4_resolution_id_ctr][br_ctr]
                    .i4_min_size_y_buf =
                    ctb_align_pic_wd * ctb_align_pic_ht *
                    ((ps_hle_ctxt->ps_static_cfg_prms->s_tgt_lyr_prms.i4_internal_bit_depth > 8)
                         ? 2
                         : 1);

                ps_res_layer_recon_bufs_req->s_recon_buf_req[i4_resolution_id_ctr][br_ctr]
                    .i4_min_size_uv_buf =
                    (ps_res_layer_recon_bufs_req->s_recon_buf_req[i4_resolution_id_ctr][br_ctr]
                         .i4_min_size_y_buf >>
                     1);
                ps_res_layer_recon_bufs_req->s_recon_buf_req[i4_resolution_id_ctr][br_ctr]
                    .i4_min_size_uv_buf <<=
                    ((ps_src_prms->i4_chr_format == IV_YUV_422SP_UV) ? 1 : 0);
            }
        }
    }

    return (IV_SUCCESS);
}

/*!
******************************************************************************
* \if Function name : ihevce_create_ports \endif
*
* \brief
*    High level Encoder IO ports Create function
*
* \param[in] High level encoder interface context pointer
* \param[in] Input data buffer descriptor
* \param[in] Input control buffer descriptor
* \param[in] Output data buffer descriptor
* \param[in] Output control status buffer descriptor
* \param[out] Pointer to store the ID for Input data Que
* \param[out] Pointer to store the ID for Input control Que
* \param[out] Pointer to store the ID for Output data Que
* \param[out] Pointer to store the ID for Output control status Que
*
* \return
*  success or fail
*
* \author
*  Ittiam
*
*****************************************************************************
*/
IV_API_CALL_STATUS_T ihevce_create_ports(
    ihevce_hle_ctxt_t *ps_hle_ctxt,
    iv_input_data_ctrl_buffs_desc_t *ps_input_data_ctrl_buffs_desc,
    iv_input_asynch_ctrl_buffs_desc_t *ps_input_asynch_ctrl_buffs_desc,
    iv_res_layer_output_data_buffs_desc_t *ps_mres_output_data_buffs_desc,
    iv_res_layer_recon_data_buffs_desc_t *ps_mres_recon_data_buffs_desc)
{
    /* local varaibles */
    enc_ctxt_t *ps_enc_ctxt;
    WORD32 res_ctr,
        i4_num_resolutions = ps_hle_ctxt->ps_static_cfg_prms->s_tgt_lyr_prms.i4_num_res_layers;
    void *pv_q_mutex_hdl = NULL;

    /* set no error in the output */
    ps_hle_ctxt->i4_error_code = 0;

    for(res_ctr = 0; res_ctr < i4_num_resolutions; res_ctr++)
    {
        ps_enc_ctxt = (enc_ctxt_t *)ps_hle_ctxt->apv_enc_hdl[res_ctr];
        /* check on buffer sizes provided by applciation needs to be checked */

        /* call the memory manager que init function , pass the op data , status, recon for the first bitrate, internally we will increment*/
        ihevce_mem_manager_que_init(
            ps_enc_ctxt,
            ps_hle_ctxt,
            ps_input_data_ctrl_buffs_desc,
            ps_input_asynch_ctrl_buffs_desc,
            &ps_mres_output_data_buffs_desc->s_output_data_buffs[res_ctr][0],
            &ps_mres_recon_data_buffs_desc->s_recon_data_buffs[res_ctr][0]);

        /* set the number of Queues */
        ps_enc_ctxt->s_enc_ques.i4_num_queues = IHEVCE_MAX_NUM_QUEUES;

        /* allocate a mutex to take care of handling multiple threads accesing Queues */
        /*my understanding, this is common semaphore for all the queue. Since main input is still
        common across all instance fo encoder. Hence common semaphore is a must*/
        if(0 == res_ctr)
        {
            ps_enc_ctxt->s_enc_ques.pv_q_mutex_hdl = osal_mutex_create(ps_hle_ctxt->pv_osal_handle);
            /* store it in local variable for allocating it to other instances */
            pv_q_mutex_hdl = ps_enc_ctxt->s_enc_ques.pv_q_mutex_hdl;
            if(NULL == pv_q_mutex_hdl)
            {
                return IV_FAIL;
            }
        }
        else
        {
            ps_enc_ctxt->s_enc_ques.pv_q_mutex_hdl = pv_q_mutex_hdl;
        }

        /* Set the i/o queues created status to 1 */
        ps_enc_ctxt->i4_io_queues_created = 1;
    }
    return (IV_SUCCESS);
}

/*!
******************************************************************************
* \if Function name : ihevce_hle_interface_thrd \endif
*
* \brief
*    High level encoder thread interface function
*
* \param[in] High level interface context pointer
*
* \return
*    None
*
* \author
*  Ittiam
*
*****************************************************************************
*/
WORD32 ihevce_hle_interface_thrd(void *pv_proc_intf_ctxt)
{
    /* local variables */
    WORD32 ctr, res_ctr;
    ihevce_hle_ctxt_t *ps_hle_ctxt;
    enc_ctxt_t *ps_enc_ctxt;
    /* enc ctxt to store 0th instance's params which are required by all instances */
    enc_ctxt_t *ps_enc_ctxt_base;
    void *pv_lap_sem_hdl;
    void *pv_enc_frame_process_sem_hdl;
    void *pv_pre_enc_frame_process_sem_hdl;
    void *apv_ent_coding_sem_hdl[IHEVCE_MAX_NUM_BITRATES];
    void *pv_ent_common_mres_sem_hdl = NULL;
    void *pv_out_common_mres_sem_hdl = NULL;

    void *pv_inp_data_sem_hdl;
    void *pv_lap_inp_data_sem_hdl;
    void *pv_preenc_inp_data_sem_hdl;
    void *pv_inp_ctrl_sem_hdl;
    void *apv_out_stream_sem_hdl[IHEVCE_MAX_NUM_BITRATES];
    void *apv_out_recon_sem_hdl[IHEVCE_MAX_NUM_BITRATES];
    void *pv_out_ctrl_sts_sem_hdl;

    lap_intface_t *ps_lap_interface_ctxt;
    iv_mem_rec_t s_memtab;
    WORD32 i4_num_bit_rate_instances[IHEVCE_MAX_NUM_RESOLUTIONS], i4_num_resolutions;
    WORD32 i;  //loop variable
    WORD32 ai4_proc_count[MAX_NUMBER_PROC_GRPS] = { 0 }, i4_proc_grp_count;
    WORD32 i4_acc_proc_num = 0;

    /* Frame Encode processing threads & semaphores */
    void *apv_enc_frm_proc_hdls[IHEVCE_MAX_NUM_RESOLUTIONS][MAX_NUM_FRM_PROC_THRDS_ENC];
    frm_proc_thrd_ctxt_t
        *aps_enc_frm_proc_thrd_ctxt[IHEVCE_MAX_NUM_RESOLUTIONS][MAX_NUM_FRM_PROC_THRDS_ENC];

    /* Pre Frame Encode processing threads & semaphores */
    void *apv_pre_enc_frm_proc_hdls[IHEVCE_MAX_NUM_RESOLUTIONS][MAX_NUM_FRM_PROC_THRDS_PRE_ENC];
    frm_proc_thrd_ctxt_t
        *aps_pre_enc_frm_proc_thrd_ctxt[IHEVCE_MAX_NUM_RESOLUTIONS][MAX_NUM_FRM_PROC_THRDS_PRE_ENC];

    void *apv_entropy_thrd_hdls[IHEVCE_MAX_NUM_RESOLUTIONS][NUM_ENTROPY_THREADS];
    frm_proc_thrd_ctxt_t *aps_entropy_thrd_ctxt[IHEVCE_MAX_NUM_RESOLUTIONS][NUM_ENTROPY_THREADS];

    ps_hle_ctxt = (ihevce_hle_ctxt_t *)pv_proc_intf_ctxt;
    ps_enc_ctxt_base = (enc_ctxt_t *)ps_hle_ctxt->apv_enc_hdl[0];
    /* profile start */
    PROFILE_START(&ps_hle_ctxt->profile_hle);
    /* store default values of mem tab */
    s_memtab.i4_size = sizeof(iv_mem_rec_t);
    s_memtab.i4_mem_alignment = 4;

    i4_num_resolutions = ps_enc_ctxt_base->ps_stat_prms->s_tgt_lyr_prms.i4_num_res_layers;
    memset(
        apv_entropy_thrd_hdls,
        0,
        IHEVCE_MAX_NUM_RESOLUTIONS * NUM_ENTROPY_THREADS * sizeof(void *));
    memset(
        apv_entropy_thrd_hdls,
        0,
        IHEVCE_MAX_NUM_RESOLUTIONS * NUM_ENTROPY_THREADS * sizeof(void *));
    for(res_ctr = 0; res_ctr < i4_num_resolutions; res_ctr++)
    {
        i4_num_bit_rate_instances[res_ctr] =
            ps_enc_ctxt_base->ps_stat_prms->s_tgt_lyr_prms.as_tgt_params[res_ctr]
                .i4_num_bitrate_instances;
    }
    /* --------------------------------------------------------------------- */
    /*        Init number of threads for each stage                          */
    /* --------------------------------------------------------------------- */

    {
        for(res_ctr = 0; res_ctr < i4_num_resolutions; res_ctr++)
        {
            ps_enc_ctxt = (enc_ctxt_t *)ps_hle_ctxt->apv_enc_hdl[res_ctr];
            /* all the threads created will be made active */
            ps_enc_ctxt->s_multi_thrd.i4_num_active_enc_thrds =
                ps_enc_ctxt->s_multi_thrd.i4_num_enc_proc_thrds;

            ps_enc_ctxt->s_multi_thrd.i4_num_active_pre_enc_thrds =
                ps_enc_ctxt->s_multi_thrd.i4_num_pre_enc_proc_thrds;
        }
    }

    /* --------------------------------------------------------------------- */
    /*            Multiple processing Threads Semaphores init                */
    /* --------------------------------------------------------------------- */
    for(res_ctr = 0; res_ctr < i4_num_resolutions; res_ctr++)
    {
        osal_sem_attr_t attr = OSAL_DEFAULT_SEM_ATTR;

        ps_enc_ctxt = (enc_ctxt_t *)ps_hle_ctxt->apv_enc_hdl[res_ctr];

        attr.value = SEM_START_VALUE;

        /* Create Semaphore handle for LAP thread   */
        if(0 == ps_enc_ctxt->i4_resolution_id)
        {
            pv_lap_sem_hdl = osal_sem_create(ps_hle_ctxt->pv_osal_handle, &attr);
            if(NULL == pv_lap_sem_hdl)
            {
                return IV_FAIL;
            }
        }
        else
        {
            /*NOTE: Tile workspace assigned this to null. Confirm this*/
            pv_lap_sem_hdl = ps_enc_ctxt_base->s_thrd_sem_ctxt.pv_lap_sem_handle;
        }
        /* Create Semaphore for encode frame process thread */
        pv_enc_frame_process_sem_hdl = osal_sem_create(ps_hle_ctxt->pv_osal_handle, &attr);
        if(NULL == pv_enc_frame_process_sem_hdl)
        {
            return IV_FAIL;
        }

        /* Create Semaphore for pre_encode frame process thread */
        pv_pre_enc_frame_process_sem_hdl = osal_sem_create(ps_hle_ctxt->pv_osal_handle, &attr);
        if(NULL == pv_pre_enc_frame_process_sem_hdl)
        {
            return IV_FAIL;
        }

        /* Create Semaphore for input frame data q function */
        if(0 == ps_enc_ctxt->i4_resolution_id)
        {
            pv_inp_data_sem_hdl = osal_sem_create(ps_hle_ctxt->pv_osal_handle, &attr);
            if(NULL == pv_inp_data_sem_hdl)
            {
                return IV_FAIL;
            }
        }
        else
        {
            pv_inp_data_sem_hdl = ps_enc_ctxt_base->s_thrd_sem_ctxt.pv_inp_data_sem_handle;
        }

        /*creating new input queue owned by encoder*/
        /* Create Semaphore for input frame data q function */
        pv_lap_inp_data_sem_hdl = osal_sem_create(ps_hle_ctxt->pv_osal_handle, &attr);
        if(NULL == pv_lap_inp_data_sem_hdl)
        {
            return IV_FAIL;
        }

        /* Create Semaphore for input frame data q function */
        pv_preenc_inp_data_sem_hdl = osal_sem_create(ps_hle_ctxt->pv_osal_handle, &attr);
        if(NULL == pv_preenc_inp_data_sem_hdl)
        {
            return IV_FAIL;
        }

        /* Create Semaphore for input conrol data q function */
        if(0 == ps_enc_ctxt->i4_resolution_id)
        {
            pv_inp_ctrl_sem_hdl = osal_sem_create(ps_hle_ctxt->pv_osal_handle, &attr);
            if(NULL == pv_inp_ctrl_sem_hdl)
            {
                return IV_FAIL;
            }
        }
        else
        { /*Inp ctrl queue is same for all resolutions between app and lap*/
            pv_inp_ctrl_sem_hdl = ps_enc_ctxt_base->s_thrd_sem_ctxt.pv_inp_ctrl_sem_handle;
        }

        /* Create Semaphore for output control status data q function */
        pv_out_ctrl_sts_sem_hdl = osal_sem_create(ps_hle_ctxt->pv_osal_handle, &attr);
        if(NULL == pv_out_ctrl_sts_sem_hdl)
        {
            return IV_FAIL;
        }

        /* Multi res single output case singel output queue is used for all output resolutions */
        if(1 == ps_enc_ctxt_base->ps_stat_prms->s_tgt_lyr_prms.i4_mres_single_out)
        {
            ps_enc_ctxt->s_enc_ques.apv_q_hdl[IHEVCE_OUTPUT_DATA_Q] =
                ps_enc_ctxt_base->s_enc_ques.apv_q_hdl[IHEVCE_OUTPUT_DATA_Q];
            if(0 == ps_enc_ctxt->i4_resolution_id)
            {
                /* Create Semaphore for enropy coding thread   */
                pv_ent_common_mres_sem_hdl = osal_sem_create(ps_hle_ctxt->pv_osal_handle, &attr);
                if(NULL == pv_ent_common_mres_sem_hdl)
                {
                    return IV_FAIL;
                }

                /* Create Semaphore for output stream data q function */
                pv_out_common_mres_sem_hdl = osal_sem_create(ps_hle_ctxt->pv_osal_handle, &attr);
                if(NULL == pv_out_common_mres_sem_hdl)
                {
                    return IV_FAIL;
                }
            }
            ps_enc_ctxt->s_thrd_sem_ctxt.pv_ent_common_mres_sem_hdl = pv_ent_common_mres_sem_hdl;
            ps_enc_ctxt->s_thrd_sem_ctxt.pv_out_common_mres_sem_hdl = pv_out_common_mres_sem_hdl;
        }

        /*create entropy and output semaphores for each thread.
        Each thread will correspond to each bit-rate instance running */
        for(i = 0; i < i4_num_bit_rate_instances[res_ctr]; i++)
        {
            /* Create Semaphore for enropy coding thread   */
            apv_ent_coding_sem_hdl[i] = osal_sem_create(ps_hle_ctxt->pv_osal_handle, &attr);
            if(NULL == apv_ent_coding_sem_hdl[i])
            {
                return IV_FAIL;
            }

            /* Create Semaphore for output stream data q function */
            apv_out_stream_sem_hdl[i] = osal_sem_create(ps_hle_ctxt->pv_osal_handle, &attr);
            if(NULL == apv_out_stream_sem_hdl[i])
            {
                return IV_FAIL;
            }

            /* Create Semaphore for output recon data q function */
            apv_out_recon_sem_hdl[i] = osal_sem_create(ps_hle_ctxt->pv_osal_handle, &attr);
            if(NULL == apv_out_recon_sem_hdl[i])
            {
                return IV_FAIL;
            }
        }

        /* update the semaphore handles and the thread creates status */

        ps_enc_ctxt->s_thrd_sem_ctxt.pv_enc_frm_proc_sem_handle = pv_enc_frame_process_sem_hdl;
        ps_enc_ctxt->s_thrd_sem_ctxt.pv_pre_enc_frm_proc_sem_handle =
            pv_pre_enc_frame_process_sem_hdl;
        ps_enc_ctxt->s_thrd_sem_ctxt.pv_lap_sem_handle = pv_lap_sem_hdl;
        ps_enc_ctxt->s_thrd_sem_ctxt.pv_inp_data_sem_handle = pv_inp_data_sem_hdl;
        ps_enc_ctxt->s_thrd_sem_ctxt.pv_lap_inp_data_sem_hdl = pv_lap_inp_data_sem_hdl;
        ps_enc_ctxt->s_thrd_sem_ctxt.pv_preenc_inp_data_sem_hdl = pv_preenc_inp_data_sem_hdl;
        ps_enc_ctxt->s_thrd_sem_ctxt.pv_inp_ctrl_sem_handle = pv_inp_ctrl_sem_hdl;
        ps_enc_ctxt->s_thrd_sem_ctxt.pv_out_ctrl_sem_handle = pv_out_ctrl_sts_sem_hdl;
        for(i = 0; i < i4_num_bit_rate_instances[res_ctr]; i++)
        {
            ps_enc_ctxt->s_thrd_sem_ctxt.apv_ent_cod_sem_handle[i] = apv_ent_coding_sem_hdl[i];
            ps_enc_ctxt->s_thrd_sem_ctxt.apv_out_strm_sem_handle[i] = apv_out_stream_sem_hdl[i];
            ps_enc_ctxt->s_thrd_sem_ctxt.apv_out_recon_sem_handle[i] = apv_out_recon_sem_hdl[i];
        }
    }

    /* --------------------------------------------------------------------- */
    /*            Multiple processing Threads Mutex init                     */
    /* --------------------------------------------------------------------- */
    for(res_ctr = 0; res_ctr < i4_num_resolutions; res_ctr++)
    {
        ps_enc_ctxt = (enc_ctxt_t *)ps_hle_ctxt->apv_enc_hdl[res_ctr];

        /* create a mutex lock for Job Queue access accross slave threads of encode frame processing */
        ps_enc_ctxt->s_multi_thrd.pv_job_q_mutex_hdl_enc_grp_me =
            osal_mutex_create(ps_hle_ctxt->pv_osal_handle);
        if(NULL == ps_enc_ctxt->s_multi_thrd.pv_job_q_mutex_hdl_enc_grp_me)
        {
            return IV_FAIL;
        }

        /* create a mutex lock for Job Queue access accross slave threads of encode frame processing */
        ps_enc_ctxt->s_multi_thrd.pv_job_q_mutex_hdl_enc_grp_enc_loop =
            osal_mutex_create(ps_hle_ctxt->pv_osal_handle);
        if(NULL == ps_enc_ctxt->s_multi_thrd.pv_job_q_mutex_hdl_enc_grp_enc_loop)
        {
            return IV_FAIL;
        }

        /* create mutex for enc thread group */
        for(i = 0; i < MAX_NUM_ME_PARALLEL; i++)
        {
            ps_enc_ctxt->s_multi_thrd.apv_mutex_handle[i] =
                osal_mutex_create(ps_hle_ctxt->pv_osal_handle);
            if(NULL == ps_enc_ctxt->s_multi_thrd.apv_mutex_handle[i])
            {
                return IV_FAIL;
            }

            ps_enc_ctxt->s_multi_thrd.apv_mutex_handle_me_end[i] =
                osal_mutex_create(ps_hle_ctxt->pv_osal_handle);
            if(NULL == ps_enc_ctxt->s_multi_thrd.apv_mutex_handle_me_end[i])
            {
                return IV_FAIL;
            }
        }

        for(i = 0; i < MAX_NUM_ENC_LOOP_PARALLEL; i++)
        {
            ps_enc_ctxt->s_multi_thrd.apv_post_enc_mutex_handle[i] =
                osal_mutex_create(ps_hle_ctxt->pv_osal_handle);
            if(NULL == ps_enc_ctxt->s_multi_thrd.apv_post_enc_mutex_handle[i])
            {
                return IV_FAIL;
            }

            ps_enc_ctxt->s_multi_thrd.apv_mutex_handle_frame_init[i] =
                osal_mutex_create(ps_hle_ctxt->pv_osal_handle);
            if(NULL == ps_enc_ctxt->s_multi_thrd.apv_mutex_handle_frame_init[i])
            {
                return IV_FAIL;
            }
        }

        /*initialize mutex for pre-enc group */
        ps_enc_ctxt->s_multi_thrd.pv_mutex_hdl_pre_enc_init =
            osal_mutex_create(ps_hle_ctxt->pv_osal_handle);

        ps_enc_ctxt->s_multi_thrd.pv_mutex_hdl_pre_enc_decomp_deinit =
            osal_mutex_create(ps_hle_ctxt->pv_osal_handle);

        ps_enc_ctxt->s_multi_thrd.pv_mutex_hdl_pre_enc_hme_init =
            osal_mutex_create(ps_hle_ctxt->pv_osal_handle);

        ps_enc_ctxt->s_multi_thrd.pv_mutex_hdl_pre_enc_hme_deinit =
            osal_mutex_create(ps_hle_ctxt->pv_osal_handle);

        ps_enc_ctxt->s_multi_thrd.pv_mutex_hdl_pre_enc_deinit =
            osal_mutex_create(ps_hle_ctxt->pv_osal_handle);

        ps_enc_ctxt->s_multi_thrd.pv_mutex_hdl_l0_ipe_init =
            osal_mutex_create(ps_hle_ctxt->pv_osal_handle);

        ps_enc_ctxt->s_multi_thrd.pv_job_q_mutex_hdl_pre_enc_decomp =
            osal_mutex_create(ps_hle_ctxt->pv_osal_handle);

        ps_enc_ctxt->s_multi_thrd.pv_job_q_mutex_hdl_pre_enc_hme =
            osal_mutex_create(ps_hle_ctxt->pv_osal_handle);

        ps_enc_ctxt->s_multi_thrd.pv_job_q_mutex_hdl_pre_enc_l0ipe =
            osal_mutex_create(ps_hle_ctxt->pv_osal_handle);

        if(NULL == ps_enc_ctxt->s_multi_thrd.pv_mutex_hdl_pre_enc_init ||
           NULL == ps_enc_ctxt->s_multi_thrd.pv_mutex_hdl_pre_enc_decomp_deinit ||
           NULL == ps_enc_ctxt->s_multi_thrd.pv_mutex_hdl_pre_enc_hme_init ||
           NULL == ps_enc_ctxt->s_multi_thrd.pv_mutex_hdl_pre_enc_hme_deinit ||
           NULL == ps_enc_ctxt->s_multi_thrd.pv_mutex_hdl_pre_enc_deinit ||
           NULL == ps_enc_ctxt->s_multi_thrd.pv_mutex_hdl_l0_ipe_init ||
           NULL == ps_enc_ctxt->s_multi_thrd.pv_job_q_mutex_hdl_pre_enc_decomp ||
           NULL == ps_enc_ctxt->s_multi_thrd.pv_job_q_mutex_hdl_pre_enc_hme ||
           NULL == ps_enc_ctxt->s_multi_thrd.pv_job_q_mutex_hdl_pre_enc_l0ipe)
        {
            return IV_FAIL;
        }
    }

    /* --------------------------------------------------------------------- */
    /*            Multiple processing Threads Context init                   */
    /* --------------------------------------------------------------------- */

    for(res_ctr = 0; res_ctr < i4_num_resolutions; res_ctr++)
    {
        ps_enc_ctxt = (enc_ctxt_t *)ps_hle_ctxt->apv_enc_hdl[res_ctr];
        ps_enc_ctxt_base = (enc_ctxt_t *)ps_hle_ctxt->apv_enc_hdl[0];

        /*initialize multi-thread context for enc group*/
        ps_enc_ctxt->s_multi_thrd.i4_is_recon_free_done = 0;
        ps_enc_ctxt->s_multi_thrd.me_end_flag = 0;
        ps_enc_ctxt->s_multi_thrd.enc_end_flag = 0;
        ps_enc_ctxt->s_multi_thrd.i4_idx_dvsr_p = 0;
        ps_enc_ctxt->s_multi_thrd.i4_last_inp_buf = 0;

        {
            /* For all the ME frames in Parallel */
            WORD32 i4_frm_idx;

            for(i4_frm_idx = 0; i4_frm_idx < MAX_NUM_ME_PARALLEL; i4_frm_idx++)
            {
                ps_enc_ctxt->s_multi_thrd.me_num_thrds_exited[i4_frm_idx] = 0;
                ps_enc_ctxt->s_multi_thrd.ai4_me_master_done_flag[i4_frm_idx] = 0;
                ps_enc_ctxt->s_multi_thrd.ai4_me_enc_buff_prod_flag[i4_frm_idx] = 0;
            }
        }

        {
            WORD32 i4_frm_idx;
            ps_enc_ctxt->s_multi_thrd.num_thrds_done = 0;
            ps_enc_ctxt->s_multi_thrd.num_thrds_exited_for_reenc = 0;
            for(i4_frm_idx = 0; i4_frm_idx < MAX_NUM_ENC_LOOP_PARALLEL; i4_frm_idx++)
            {
                ps_enc_ctxt->s_multi_thrd.num_thrds_exited[i4_frm_idx] = 0;

                ps_enc_ctxt->s_multi_thrd.enc_master_done_frame_init[i4_frm_idx] = 0;

                for(i = 0; i < i4_num_bit_rate_instances[res_ctr]; i++)
                {
                    /*reset the entropy buffer produced status */
                    ps_enc_ctxt->s_multi_thrd.ai4_produce_outbuf[i4_frm_idx][i] = 1;
                    ps_enc_ctxt->s_multi_thrd.ps_frm_recon[i4_frm_idx][i] = NULL;

                    ps_enc_ctxt->s_multi_thrd.ps_curr_out_enc_grp[i4_frm_idx][i] = NULL;
                }
            }
        }
        ps_enc_ctxt->s_multi_thrd.i4_seq_mode_enabled_flag = 0;

        /* Set prev_frame_done = 1 to indicate that all the threads are in same frame*/
        for(i = 0; i < ps_enc_ctxt->s_multi_thrd.i4_num_enc_loop_frm_pllel; i++)
        {
            ihevce_dmgr_set_done_frm_frm_sync(
                ps_enc_ctxt->s_multi_thrd.apv_dep_mngr_prev_frame_done[i]);
        }
        /* Set prev_frame_done = 1 to indicate that all the threads are in same frame*/
        ihevce_dmgr_set_done_frm_frm_sync(
            ps_enc_ctxt->s_multi_thrd.pv_dep_mngr_prev_frame_enc_done_for_reenc);
        /*to enable the dependency manager to wait when first reached*/
        ihevce_dmgr_set_prev_done_frm_frm_sync(
            ps_enc_ctxt->s_multi_thrd.pv_dep_mngr_prev_frame_enc_done_for_reenc);
        for(i = 0; i < ps_enc_ctxt->s_multi_thrd.i4_num_me_frm_pllel; i++)
        {
            ihevce_dmgr_set_done_frm_frm_sync(
                ps_enc_ctxt->s_multi_thrd.apv_dep_mngr_prev_frame_me_done[i]);
        }

        /* reset the completed status & start proc flags of slave encode frame processing threads */
        for(ctr = 0; ctr < ps_enc_ctxt->s_multi_thrd.i4_num_enc_proc_thrds; ctr++)
        {
            ps_enc_ctxt->s_multi_thrd.ai4_enc_frm_proc_start[ctr] = 0;
        }

        /* initialize multi-thread context for pre enc group */

        ps_enc_ctxt->s_multi_thrd.i4_ctrl_blocking_mode = BUFF_QUE_BLOCKING_MODE;

        //for (ctr=0; ctr< PING_PONG_BUF; ctr++)
        for(ctr = 0; ctr < MAX_PRE_ENC_STAGGER + NUM_BUFS_DECOMP_HME; ctr++)
        {
            ps_enc_ctxt->s_multi_thrd.ai4_pre_enc_init_done[ctr] = 0;
            ps_enc_ctxt->s_multi_thrd.ai4_pre_enc_hme_init_done[ctr] = 0;
            ps_enc_ctxt->s_multi_thrd.ai4_pre_enc_deinit_done[ctr] = 1;
            ps_enc_ctxt->s_multi_thrd.ai4_num_thrds_processed_decomp[ctr] = 0;
            ps_enc_ctxt->s_multi_thrd.ai4_num_thrds_processed_coarse_me[ctr] = 0;
            ps_enc_ctxt->s_multi_thrd.ai4_num_thrds_processed_pre_enc[ctr] = 0;

            ps_enc_ctxt->s_multi_thrd.ai4_num_thrds_processed_L0_ipe_qp_init[ctr] = 0;
            ps_enc_ctxt->s_multi_thrd.ai4_decomp_coarse_me_complete_flag[ctr] = 1;
            ps_enc_ctxt->s_multi_thrd.ai4_end_flag_pre_enc[ctr] = 0;
        }

        /* Set prev_frame_done = 1 to indicate that all the threads are in same frame*/
        ihevce_dmgr_set_done_frm_frm_sync(
            ps_enc_ctxt->s_multi_thrd.pv_dep_mngr_prev_frame_pre_enc_l1);

        ihevce_dmgr_set_done_frm_frm_sync(
            ps_enc_ctxt->s_multi_thrd.pv_dep_mngr_prev_frame_pre_enc_coarse_me);

        ihevce_dmgr_set_done_frm_frm_sync(
            ps_enc_ctxt->s_multi_thrd.pv_dep_mngr_prev_frame_pre_enc_l0);

        {
            /**init idx for handling delay between pre-me and l0-ipe*/
            ps_enc_ctxt->s_multi_thrd.i4_delay_pre_me_btw_l0_ipe = 0;
            ps_enc_ctxt->s_multi_thrd.i4_max_delay_pre_me_btw_l0_ipe =
                MAX_PRE_ENC_STAGGER + NUM_BUFS_DECOMP_HME - 1;
            if(ps_enc_ctxt->s_lap_stat_prms.s_lap_params.i4_rc_look_ahead_pics)
            {
                ps_enc_ctxt->s_multi_thrd.i4_delay_pre_me_btw_l0_ipe +=
                    MIN_L1_L0_STAGGER_NON_SEQ +
                    ps_enc_ctxt->s_lap_stat_prms.s_lap_params.i4_rc_look_ahead_pics;
            }
            ps_enc_ctxt->s_multi_thrd.i4_qp_update_l0_ipe = -1;
        }
    }

    /** Get Number of Processor Groups **/
    i4_proc_grp_count = ps_enc_ctxt_base->ps_stat_prms->s_multi_thrd_prms.i4_num_proc_groups;
    /*** Enc threads are allocated based on the assumption that there can be only 2 processor groups **/
    ASSERT(i4_proc_grp_count <= MAX_NUMBER_PROC_GRPS);
    /** Get Number of logical processors in Each Group **/
    for(ctr = 0; ctr < i4_proc_grp_count; ctr++)
    {
        ai4_proc_count[ctr] =
            ps_enc_ctxt_base->ps_stat_prms->s_multi_thrd_prms.ai4_num_cores_per_grp[ctr];
    }

    /* --------------------------------------------------------------------- */
    /*            Create a LAP thread                                        */
    /* --------------------------------------------------------------------- */
    /* LAP thread will run on  0th resolution instance context */
    {
        s_memtab.e_mem_type = IV_EXT_CACHEABLE_NORMAL_MEM;
        s_memtab.i4_mem_size = sizeof(lap_intface_t);

        /* initialise the interface strucure parameters */
        ps_hle_ctxt->ihevce_mem_alloc(
            ps_hle_ctxt->pv_mem_mgr_hdl, &ps_enc_ctxt_base->ps_stat_prms->s_sys_api, &s_memtab);
        if(s_memtab.pv_base == NULL)
        {
            return (IV_FAIL);
        }

        ps_lap_interface_ctxt = (lap_intface_t *)s_memtab.pv_base;

        /* populate the params */
        ps_lap_interface_ctxt->pv_hle_ctxt = ps_hle_ctxt;
        ps_enc_ctxt = (enc_ctxt_t *)ps_hle_ctxt->apv_enc_hdl[0];
        ps_lap_interface_ctxt->pv_lap_module_ctxt = ps_enc_ctxt->s_module_ctxt.pv_lap_ctxt;
        ps_lap_interface_ctxt->i4_ctrl_in_que_id = IHEVCE_INPUT_ASYNCH_CTRL_Q;
        ps_lap_interface_ctxt->i4_ctrl_out_que_id = IHEVCE_OUTPUT_STATUS_Q;
        ps_lap_interface_ctxt->i4_ctrl_cmd_buf_size = ENC_COMMAND_BUFF_SIZE;
        ps_lap_interface_ctxt->i4_ctrl_in_que_blocking_mode = BUFF_QUE_BLOCKING_MODE;
        ps_lap_interface_ctxt->ps_sys_api = &ps_enc_ctxt_base->ps_stat_prms->s_sys_api;
        ps_enc_ctxt_base->pv_lap_interface_ctxt = (void *)ps_lap_interface_ctxt;
        ps_lap_interface_ctxt->ihevce_dyn_bitrate_cb = ihevce_dyn_bitrate;
    }

    /* --------------------------------------------------------------------- */
    /*          Create Entropy Coding threads                             */
    /* --------------------------------------------------------------------- */
    /*Create entropy thread for each encoder instance*/
    for(res_ctr = 0; res_ctr < i4_num_resolutions; res_ctr++)
    {
        osal_thread_attr_t s_thread_attr = OSAL_DEFAULT_THREAD_ATTR;
        WORD32 i4_num_entropy_threads;

        /* derive encoder ctxt from hle handle */
        ps_enc_ctxt = (enc_ctxt_t *)ps_hle_ctxt->apv_enc_hdl[res_ctr];

        i4_num_entropy_threads =
            ps_enc_ctxt_base->ps_stat_prms->s_tgt_lyr_prms.as_tgt_params[res_ctr]
                .i4_num_bitrate_instances;

        /* initialise the interface strucure parameters */
        for(ctr = 0; ctr < i4_num_entropy_threads; ctr++)
        {
            s_memtab.e_mem_type = IV_EXT_CACHEABLE_NORMAL_MEM;
            s_memtab.i4_mem_size = sizeof(frm_proc_thrd_ctxt_t);

            ps_hle_ctxt->ihevce_mem_alloc(
                ps_hle_ctxt->pv_mem_mgr_hdl, &ps_enc_ctxt_base->ps_stat_prms->s_sys_api, &s_memtab);
            if(s_memtab.pv_base == NULL)
            {
                return (IV_FAIL);
            }

            aps_entropy_thrd_ctxt[res_ctr][ctr] = (frm_proc_thrd_ctxt_t *)s_memtab.pv_base;

            /* initialise the interface strucure parameters */
            aps_entropy_thrd_ctxt[res_ctr][ctr]->i4_thrd_id = ctr;
            aps_entropy_thrd_ctxt[res_ctr][ctr]->ps_hle_ctxt = ps_hle_ctxt;
            aps_entropy_thrd_ctxt[res_ctr][ctr]->pv_enc_ctxt = (void *)ps_enc_ctxt;

            /* Initialize application thread attributes */
            s_thread_attr.exit_code = 0;
            s_thread_attr.name = 0;
            s_thread_attr.priority_map_flag = 1;
            s_thread_attr.priority = OSAL_PRIORITY_DEFAULT;
            s_thread_attr.stack_addr = 0;
            s_thread_attr.stack_size = THREAD_STACK_SIZE;
            s_thread_attr.thread_func = ihevce_ent_coding_thrd;
            s_thread_attr.thread_param =
                (void *)(aps_entropy_thrd_ctxt[res_ctr]
                                              [ctr]);  //encioder and hle context are derived from this
            s_thread_attr.core_affinity_mask = 0;
            if(ps_enc_ctxt_base->ps_stat_prms->s_multi_thrd_prms.i4_num_proc_groups > 1)
            {
                /* Run ENTROPY thread on last group if there are more than one processor group */
                s_thread_attr.group_num =
                    ps_hle_ctxt->ps_static_cfg_prms->s_multi_thrd_prms.i4_num_proc_groups - 1;
            }
            else
            {
                s_thread_attr.group_num = 0;
            }

            /* Create entropy coding thread */
            apv_entropy_thrd_hdls[res_ctr][ctr] =
                osal_thread_create(ps_hle_ctxt->pv_osal_handle, &s_thread_attr);
            if(NULL == apv_entropy_thrd_hdls[res_ctr][ctr])
            {
                return IV_FAIL;
            }
        }
    }

    /* --------------------------------------------------------------------- */
    /*     Create all Slave Encode Frame processing threads                  */
    /* - -------------------------------------------------------------------- */
    for(res_ctr = 0; res_ctr < i4_num_resolutions; res_ctr++)
    {
        WORD32 enc_ctr = 0;
        WORD32 i4_loop_count;
        WORD32 i4_curr_grp_num = 0;
        ps_enc_ctxt = (enc_ctxt_t *)ps_hle_ctxt->apv_enc_hdl[res_ctr];

        i4_acc_proc_num = 0;
        /* Calculate the start core number of enc threads for current resolution */
        for(i4_loop_count = 0; i4_loop_count < res_ctr; i4_loop_count++)
        {
            /* Add number of cores taken by each resolution till the curr resolution */
            enc_ctr += ps_hle_ctxt->ai4_num_core_per_res[i4_loop_count];
        }
        if(ps_enc_ctxt_base->ps_stat_prms->s_multi_thrd_prms.i4_num_proc_groups > 1)
        {
            /* Select the group number for each res based on processors present in each group */
            for(i4_loop_count = 0;
                i4_loop_count <
                ps_enc_ctxt_base->ps_stat_prms->s_multi_thrd_prms.i4_num_proc_groups;
                i4_loop_count++)
            {
                i4_acc_proc_num += ai4_proc_count[i4_loop_count];
                if(enc_ctr >= i4_acc_proc_num)
                {
                    /* if enc_ctr is greater than proc count for first group,
                    then increment group count.This group number will be starting grp num for
                    that resolution */
                    i4_curr_grp_num++;
                }
                else
                    break;
            }
        }

        for(ctr = 0; ctr < ps_enc_ctxt->s_multi_thrd.i4_num_enc_proc_thrds; ctr++)
        {
            osal_thread_attr_t s_thread_attr = OSAL_DEFAULT_THREAD_ATTR;

            s_memtab.e_mem_type = IV_EXT_CACHEABLE_NORMAL_MEM;
            s_memtab.i4_mem_size = sizeof(frm_proc_thrd_ctxt_t);

            ps_hle_ctxt->ihevce_mem_alloc(
                ps_hle_ctxt->pv_mem_mgr_hdl, &ps_enc_ctxt_base->ps_stat_prms->s_sys_api, &s_memtab);
            if(s_memtab.pv_base == NULL)
            {
                return (IV_FAIL);
            }

            aps_enc_frm_proc_thrd_ctxt[res_ctr][ctr] = (frm_proc_thrd_ctxt_t *)s_memtab.pv_base;

            /* initialise the interface strucure parameters */
            aps_enc_frm_proc_thrd_ctxt[res_ctr][ctr]->i4_thrd_id = ctr;

            aps_enc_frm_proc_thrd_ctxt[res_ctr][ctr]->ps_hle_ctxt = ps_hle_ctxt;

            ps_enc_ctxt = (enc_ctxt_t *)ps_hle_ctxt->apv_enc_hdl[res_ctr];

            aps_enc_frm_proc_thrd_ctxt[res_ctr][ctr]->pv_enc_ctxt = (void *)ps_enc_ctxt;

            /* Initialize application thread attributes */
            s_thread_attr.exit_code = 0;
            s_thread_attr.name = 0;
            s_thread_attr.priority_map_flag = 1;
            s_thread_attr.priority = OSAL_PRIORITY_DEFAULT;
            s_thread_attr.stack_addr = 0;
            s_thread_attr.stack_size = THREAD_STACK_SIZE;
            s_thread_attr.thread_func = ihevce_enc_frm_proc_slave_thrd;
            s_thread_attr.thread_param = (void *)(aps_enc_frm_proc_thrd_ctxt[res_ctr][ctr]);
            s_thread_attr.group_num = i4_curr_grp_num;
            if(1 == ps_enc_ctxt_base->ps_stat_prms->s_multi_thrd_prms.i4_use_thrd_affinity)
            {
                ihevce_static_multi_thread_params_t *ps_multi_thrd_prms =
                    &ps_enc_ctxt_base->ps_stat_prms->s_multi_thrd_prms;

                s_thread_attr.core_affinity_mask = ps_multi_thrd_prms->au8_core_aff_mask[enc_ctr];
                if((enc_ctr >= i4_acc_proc_num) &&
                   (ps_enc_ctxt_base->ps_stat_prms->s_multi_thrd_prms.i4_num_proc_groups > 1))
                {
                    /*** When the cores in the Group0 is exhausted start enc threads in the next Processor Group ***/
                    s_thread_attr.group_num++;
                    i4_curr_grp_num++;
                    /* This takes care of the condition that differnt proc groups can have diff number of cores */
                    i4_acc_proc_num += ai4_proc_count[i4_curr_grp_num];
                }
            }
            else
            {
                s_thread_attr.core_affinity_mask = 0;
                if((enc_ctr >= i4_acc_proc_num) &&
                   (ps_enc_ctxt_base->ps_stat_prms->s_multi_thrd_prms.i4_num_proc_groups > 1))
                {
                    /*** When the cores in the Group0 is exhausted start enc threads in the next Processor Group ***/
                    s_thread_attr.group_num++;
                    i4_curr_grp_num++;
                    /* This takes care of the condition that differnt proc groups can have diff number of cores */
                    i4_acc_proc_num += ai4_proc_count[i4_curr_grp_num];
                }
            }

            /* Create frame processing thread */
            apv_enc_frm_proc_hdls[res_ctr][ctr] =
                osal_thread_create(ps_hle_ctxt->pv_osal_handle, &s_thread_attr);
            if(NULL == apv_enc_frm_proc_hdls[res_ctr][ctr])
            {
                return IV_FAIL;
            }
            enc_ctr++;
        }
    }

    /* --------------------------------------------------------------------- */
    /*     Create all Pre - Encode Frame processing threads                  */
    /* --------------------------------------------------------------------- */
    for(res_ctr = 0; res_ctr < i4_num_resolutions; res_ctr++)
    {
        WORD32 pre_enc_ctr = 0;
        WORD32 i4_loop_count;
        WORD32 i4_curr_grp_num = 0;
        ps_enc_ctxt = (enc_ctxt_t *)ps_hle_ctxt->apv_enc_hdl[res_ctr];

        i4_acc_proc_num = 0;

        for(i4_loop_count = 0; i4_loop_count < res_ctr; i4_loop_count++)
            pre_enc_ctr += ps_hle_ctxt->ai4_num_core_per_res[i4_loop_count];
        if(ps_enc_ctxt->s_multi_thrd.i4_all_thrds_active_flag)
        {
            /* If its sequential mode of operation enc and pre-enc threads to be given same core affinity mask */
            pre_enc_ctr -= ps_enc_ctxt->s_multi_thrd.i4_num_enc_proc_thrds;
        }

        if(ps_enc_ctxt_base->ps_stat_prms->s_multi_thrd_prms.i4_num_proc_groups > 1)
        {
            /* Select the group number for each res based on processors present in each group */
            for(i4_loop_count = 0;
                i4_loop_count <
                ps_enc_ctxt_base->ps_stat_prms->s_multi_thrd_prms.i4_num_proc_groups;
                i4_loop_count++)
            {
                i4_acc_proc_num += ai4_proc_count[i4_loop_count];
                if((pre_enc_ctr + ps_enc_ctxt->s_multi_thrd.i4_num_enc_proc_thrds) >=
                   i4_acc_proc_num)
                {
                    /* if pre_enc_ctr is greater than proc count for first group,
                    then increment group count.This group number will be starting grp num for
                    that resolution */
                    i4_curr_grp_num++;
                }
                else
                    break;
            }
        }

        for(ctr = 0; ctr < ps_enc_ctxt->s_multi_thrd.i4_num_pre_enc_proc_thrds; ctr++)
        {
            osal_thread_attr_t s_thread_attr = OSAL_DEFAULT_THREAD_ATTR;

            s_memtab.e_mem_type = IV_EXT_CACHEABLE_NORMAL_MEM;
            s_memtab.i4_mem_size = sizeof(frm_proc_thrd_ctxt_t);

            ps_hle_ctxt->ihevce_mem_alloc(
                ps_hle_ctxt->pv_mem_mgr_hdl, &ps_enc_ctxt_base->ps_stat_prms->s_sys_api, &s_memtab);
            if(s_memtab.pv_base == NULL)
            {
                return (IV_FAIL);
            }

            aps_pre_enc_frm_proc_thrd_ctxt[res_ctr][ctr] = (frm_proc_thrd_ctxt_t *)s_memtab.pv_base;

            /* initialise the interface strucure parameters */
            aps_pre_enc_frm_proc_thrd_ctxt[res_ctr][ctr]->i4_thrd_id = ctr;

            aps_pre_enc_frm_proc_thrd_ctxt[res_ctr][ctr]->ps_hle_ctxt = ps_hle_ctxt;
            ps_enc_ctxt = (enc_ctxt_t *)ps_hle_ctxt->apv_enc_hdl[res_ctr];
            aps_pre_enc_frm_proc_thrd_ctxt[res_ctr][ctr]->pv_enc_ctxt = (void *)ps_enc_ctxt;

            /* Initialize application thread attributes */
            s_thread_attr.exit_code = 0;
            s_thread_attr.name = 0;
            s_thread_attr.priority_map_flag = 1;
            s_thread_attr.priority = OSAL_PRIORITY_DEFAULT;
            s_thread_attr.stack_addr = 0;
            s_thread_attr.stack_size = THREAD_STACK_SIZE;
            s_thread_attr.thread_func = ihevce_pre_enc_process_frame_thrd;
            s_thread_attr.thread_param = (void *)(aps_pre_enc_frm_proc_thrd_ctxt[res_ctr][ctr]);
            s_thread_attr.group_num = i4_curr_grp_num;

            if(1 == ps_enc_ctxt_base->ps_stat_prms->s_multi_thrd_prms.i4_use_thrd_affinity)
            {
                ihevce_static_multi_thread_params_t *ps_multi_thrd_prms =
                    &ps_enc_ctxt_base->ps_stat_prms->s_multi_thrd_prms;

                s_thread_attr.core_affinity_mask =
                    ps_multi_thrd_prms->au8_core_aff_mask
                        [pre_enc_ctr + ps_enc_ctxt->s_multi_thrd.i4_num_enc_proc_thrds];
                if(((pre_enc_ctr + ps_enc_ctxt->s_multi_thrd.i4_num_enc_proc_thrds) >=
                    i4_acc_proc_num) &&
                   (ps_enc_ctxt_base->ps_stat_prms->s_multi_thrd_prms.i4_num_proc_groups > 1))
                {
                    /*** When the cores in the Group0 is exhausted start enc threads in the next Processor Group ***/
                    s_thread_attr.group_num++;
                    i4_curr_grp_num++;
                    /* This takes care of the condition that differnt proc groups can have diff number of cores */
                    i4_acc_proc_num += ai4_proc_count[i4_curr_grp_num];
                }
            }
            else
            {
                s_thread_attr.core_affinity_mask = 0;

                if(((pre_enc_ctr + ps_enc_ctxt->s_multi_thrd.i4_num_enc_proc_thrds) >=
                    i4_acc_proc_num) &&
                   (ps_enc_ctxt_base->ps_stat_prms->s_multi_thrd_prms.i4_num_proc_groups > 1))
                {
                    /*** When the cores in the Group0 is exhausted start enc threads in the next Processor Group ***/
                    s_thread_attr.group_num++;
                    i4_curr_grp_num++;
                    /* This takes care of the condition that differnt proc groups can have diff number of cores */
                    i4_acc_proc_num += ai4_proc_count[i4_curr_grp_num];
                }
            }

            /* Create frame processing thread */
            apv_pre_enc_frm_proc_hdls[res_ctr][ctr] =
                osal_thread_create(ps_hle_ctxt->pv_osal_handle, &s_thread_attr);
            if(NULL == apv_pre_enc_frm_proc_hdls[res_ctr][ctr])
            {
                return IV_FAIL;
            }
            pre_enc_ctr++;
        }
    }

    /* Set the threads init done Flag */
    ps_hle_ctxt->i4_hle_init_done = 1;

    /* --------------------------------------------------------------------- */
    /*            Wait and destroy Processing threads                        */
    /* --------------------------------------------------------------------- */

    /* --------------------------------------------------------------------- */
    /*           Frame process Pre - Encode threads destroy                  */
    /* --------------------------------------------------------------------- */
    for(res_ctr = 0; res_ctr < i4_num_resolutions; res_ctr++)
    {
        ps_enc_ctxt = (enc_ctxt_t *)ps_hle_ctxt->apv_enc_hdl[res_ctr];

        for(ctr = 0; ctr < ps_enc_ctxt->s_multi_thrd.i4_num_pre_enc_proc_thrds; ctr++)
        {
            /* Wait for thread to complete */
            osal_thread_wait(apv_pre_enc_frm_proc_hdls[res_ctr][ctr]);

            /* Destroy thread */
            osal_thread_destroy(apv_pre_enc_frm_proc_hdls[res_ctr][ctr]);

            s_memtab.i4_mem_size = sizeof(frm_proc_thrd_ctxt_t);
            s_memtab.e_mem_type = IV_EXT_CACHEABLE_NORMAL_MEM;
            s_memtab.pv_base = (void *)aps_pre_enc_frm_proc_thrd_ctxt[res_ctr][ctr];

            /* free the ctxt memory */
            ps_hle_ctxt->ihevce_mem_free(ps_hle_ctxt->pv_mem_mgr_hdl, &s_memtab);
        }
    }

    /* --------------------------------------------------------------------- */
    /*           Frame process Encode slave threads destroy                  */
    /* --------------------------------------------------------------------- */
    for(res_ctr = 0; res_ctr < i4_num_resolutions; res_ctr++)
    {
        ps_enc_ctxt = (enc_ctxt_t *)ps_hle_ctxt->apv_enc_hdl[res_ctr];

        for(ctr = 0; ctr < ps_enc_ctxt->s_multi_thrd.i4_num_enc_proc_thrds; ctr++)
        {
            /* Wait for thread to complete */
            osal_thread_wait(apv_enc_frm_proc_hdls[res_ctr][ctr]);

            /* Destroy thread */
            osal_thread_destroy(apv_enc_frm_proc_hdls[res_ctr][ctr]);

            s_memtab.i4_mem_size = sizeof(frm_proc_thrd_ctxt_t);
            s_memtab.e_mem_type = IV_EXT_CACHEABLE_NORMAL_MEM;
            s_memtab.pv_base = (void *)aps_enc_frm_proc_thrd_ctxt[res_ctr][ctr];

            /* free the ctxt memory */
            ps_hle_ctxt->ihevce_mem_free(ps_hle_ctxt->pv_mem_mgr_hdl, &s_memtab);
        }
    }

    /* --------------------------------------------------------------------- */
    /*           Entropy threads destroy                                     */
    /* --------------------------------------------------------------------- */
    for(res_ctr = 0; res_ctr < i4_num_resolutions; res_ctr++)
    {
        WORD32 i4_num_bitrates =
            ps_enc_ctxt_base->ps_stat_prms->s_tgt_lyr_prms.as_tgt_params[res_ctr]
                .i4_num_bitrate_instances;

        for(ctr = 0; ctr < i4_num_bitrates; ctr++)
        {
            /* Wait for Entropy Coding thread to complete */
            osal_thread_wait(apv_entropy_thrd_hdls[res_ctr][ctr]);

            /* Destroy Entropy Coding thread */
            osal_thread_destroy(apv_entropy_thrd_hdls[res_ctr][ctr]);

            //semaphore will come here

            s_memtab.i4_mem_size = sizeof(frm_proc_thrd_ctxt_t);
            s_memtab.e_mem_type = IV_EXT_CACHEABLE_NORMAL_MEM;
            s_memtab.pv_base = (void *)aps_entropy_thrd_ctxt[res_ctr][ctr];

            /* free the ctxt memory */
            ps_hle_ctxt->ihevce_mem_free(ps_hle_ctxt->pv_mem_mgr_hdl, &s_memtab);
        }
    }

    s_memtab.i4_mem_size = sizeof(lap_intface_t);
    s_memtab.e_mem_type = IV_EXT_CACHEABLE_NORMAL_MEM;
    s_memtab.pv_base = (void *)ps_lap_interface_ctxt;
    ps_hle_ctxt->ihevce_mem_free(ps_hle_ctxt->pv_mem_mgr_hdl, &s_memtab);
    /* profile stop */
    PROFILE_STOP(&ps_hle_ctxt->profile_hle, NULL);
    return (0);
}

/*!
******************************************************************************
* \if Function name : ihevce_q_get_free_inp_data_buff \endif
*
* \brief
*    Gets a free buffer from the que requested
*
* \param[in] high level encoder context pointer
* \param[in] pointer to return the buffer id
* \param[in] blocking mode / non blocking mode
*
* \return
*    None
*
* \author
*  Ittiam
*
*****************************************************************************
*/
void *ihevce_q_get_free_inp_data_buff(
    ihevce_hle_ctxt_t *ps_hle_ctxt, WORD32 *pi4_buff_id, WORD32 i4_blocking_mode)
{
    void *pv_ptr;
    enc_ctxt_t *ps_enc_ctxt;
    WORD32 i4_resolution_id = 0;

    ps_enc_ctxt = (enc_ctxt_t *)ps_hle_ctxt->apv_enc_hdl[i4_resolution_id];
    if(ps_enc_ctxt->i4_frame_limit_reached == 1)
    {
        return (NULL);
    }
    /*Input buffer is same for all enc handles*/
    pv_ptr = ihevce_q_get_free_buff(
        ps_hle_ctxt->apv_enc_hdl[0], IHEVCE_INPUT_DATA_CTRL_Q, pi4_buff_id, i4_blocking_mode);

    return (pv_ptr);
}

/*!
******************************************************************************
* \if Function name : ihevce_q_get_free_inp_ctrl_buff \endif
*
* \brief
*    Gets a free buffer from the que requested
*
* \param[in] high level encoder context pointer
* \param[in] pointer to return the buffer id
* \param[in] blocking mode / non blocking mode
*
* \return
*    None
*
* \author
*  Ittiam
*
*****************************************************************************
*/
void *ihevce_q_get_free_inp_ctrl_buff(
    ihevce_hle_ctxt_t *ps_hle_ctxt, WORD32 *pi4_buff_id, WORD32 i4_blocking_mode)
{
    void *pv_ptr;

    /*Input buffer is same for all enc handles*/
    pv_ptr = ihevce_q_get_free_buff(
        ps_hle_ctxt->apv_enc_hdl[0], IHEVCE_INPUT_ASYNCH_CTRL_Q, pi4_buff_id, i4_blocking_mode);

    return (pv_ptr);
}

/*!
******************************************************************************
* \if Function name : ihevce_q_get_free_out_strm_buff \endif
*
* \brief
*    Gets a free buffer from the que requested
*
* \param[in] high level encoder context pointer
* \param[in] pointer to return the buffer id
* \param[in] blocking mode / non blocking mode
*
* \return
*    None
*
* \author
*  Ittiam
*
*****************************************************************************
*/
void *ihevce_q_get_free_out_strm_buff(
    ihevce_hle_ctxt_t *ps_hle_ctxt,
    WORD32 *pi4_buff_id,
    WORD32 i4_blocking_mode,
    WORD32 i4_bitrate_instance,
    WORD32 i4_res_instance)
{
    void *pv_ptr;

    pv_ptr = ihevce_q_get_free_buff(
        ps_hle_ctxt->apv_enc_hdl[i4_res_instance],
        (IHEVCE_OUTPUT_DATA_Q + i4_bitrate_instance),
        pi4_buff_id,
        i4_blocking_mode);
    return (pv_ptr);
}

/*!
******************************************************************************
* \if Function name : ihevce_q_get_free_out_recon_buff \endif
*
* \brief
*    Gets a free buffer from the que requested
*
* \param[in] high level encoder context pointer
* \param[in] pointer to return the buffer id
* \param[in] blocking mode / non blocking mode
*
* \return
*    None
*
* \author
*  Ittiam
*
*****************************************************************************
*/
void *ihevce_q_get_free_out_recon_buff(
    ihevce_hle_ctxt_t *ps_hle_ctxt,
    WORD32 *pi4_buff_id,
    WORD32 i4_blocking_mode,
    WORD32 i4_bitrate_instance,
    WORD32 i4_res_instance)
{
    void *pv_ptr;

    pv_ptr = ihevce_q_get_free_buff(
        ps_hle_ctxt->apv_enc_hdl[i4_res_instance],
        (IHEVCE_RECON_DATA_Q + i4_bitrate_instance),
        pi4_buff_id,
        i4_blocking_mode);
    return (pv_ptr);
}

/*!
******************************************************************************
* \if Function name : ihevce_q_set_inp_data_buff_prod \endif
*
* \brief
*    Sets the input data buffer as produced in the que requested
*
* \param[in] high level encoder context pointer
* \param[in] buffer id which needs to be set as produced
*
* \return
*    None
*
* \author
*  Ittiam
*
*****************************************************************************
*/
IV_API_CALL_STATUS_T
    ihevce_q_set_inp_data_buff_prod(ihevce_hle_ctxt_t *ps_hle_ctxt, WORD32 i4_buff_id)
{
    IV_API_CALL_STATUS_T ret_status;

    ret_status =
        ihevce_q_set_buff_prod(ps_hle_ctxt->apv_enc_hdl[0], IHEVCE_INPUT_DATA_CTRL_Q, i4_buff_id);

    return (ret_status);
}

/*!
******************************************************************************
* \if Function name : ihevce_q_set_inp_ctrl_buff_prod \endif
*
* \brief
*    Sets the input data buffer as produced in the que requested
*
* \param[in] high level encoder context pointer
* \param[in] buffer id which needs to be set as produced
*
* \return
*    None
*
* \author
*  Ittiam
*
*****************************************************************************
*/
IV_API_CALL_STATUS_T
    ihevce_q_set_inp_ctrl_buff_prod(ihevce_hle_ctxt_t *ps_hle_ctxt, WORD32 i4_buff_id)

{
    IV_API_CALL_STATUS_T ret_status;

    ret_status =
        ihevce_q_set_buff_prod(ps_hle_ctxt->apv_enc_hdl[0], IHEVCE_INPUT_ASYNCH_CTRL_Q, i4_buff_id);

    return (ret_status);
}

/*!
******************************************************************************
* \if Function name : ihevce_q_set_out_strm_buff_prod \endif
*
* \brief
*    Sets the Output stream buffer as produced in the que requested
*
* \param[in] high level encoder context pointer
* \param[in] buffer id which needs to be set as produced
*
* \return
*    None
*
* \author
*  Ittiam
*
*****************************************************************************
*/
IV_API_CALL_STATUS_T ihevce_q_set_out_strm_buff_prod(
    ihevce_hle_ctxt_t *ps_hle_ctxt,
    WORD32 i4_buff_id,
    WORD32 i4_bitrate_instance_id,
    WORD32 i4_resolution_id)
{
    IV_API_CALL_STATUS_T ret_status;

    ret_status = ihevce_q_set_buff_prod(
        ps_hle_ctxt->apv_enc_hdl[i4_resolution_id],
        (IHEVCE_OUTPUT_DATA_Q + i4_bitrate_instance_id),
        i4_buff_id);

    return (ret_status);
}

/*!
******************************************************************************
* \if Function name : ihevce_q_set_out_recon_buff_prod \endif
*
* \brief
*    Sets the Output recon buffer as produced in the que requested
*
* \param[in] high level encoder context pointer
* \param[in] buffer id which needs to be set as produced
*
* \return
*    None
*
* \author
*  Ittiam
*
*****************************************************************************
*/
IV_API_CALL_STATUS_T ihevce_q_set_out_recon_buff_prod(
    ihevce_hle_ctxt_t *ps_hle_ctxt,
    WORD32 i4_buff_id,
    WORD32 i4_bitrate_instance_id,
    WORD32 i4_resolution_id)
{
    IV_API_CALL_STATUS_T ret_status;

    ret_status = ihevce_q_set_buff_prod(
        ps_hle_ctxt->apv_enc_hdl[i4_resolution_id],
        (IHEVCE_RECON_DATA_Q + i4_bitrate_instance_id),
        i4_buff_id);

    return (ret_status);
}

//recon_dump
/*!
******************************************************************************
* \if Function name : ihevce_q_get_filled_recon_buff \endif
*
* \brief
*    Gets a next filled recon buffer from the que requested
*
* \param[in] high level encoder context pointer
* \param[in] pointer to return the buffer id
* \param[in] blocking mode / non blocking mode
*
* \return
*    None
*
* \author
*  Ittiam
*
*****************************************************************************
*/
void *ihevce_q_get_filled_recon_buff(
    ihevce_hle_ctxt_t *ps_hle_ctxt,
    WORD32 *pi4_buff_id,
    WORD32 i4_blocking_mode,
    WORD32 i4_bitrate_instance_id,
    WORD32 i4_resolution_id)
{
    void *pv_ptr;

    pv_ptr = ihevce_q_get_filled_buff(
        ps_hle_ctxt->apv_enc_hdl[i4_resolution_id],
        IHEVCE_RECON_DATA_Q + i4_bitrate_instance_id,
        pi4_buff_id,
        i4_blocking_mode);

    return (pv_ptr);
}

/*!
******************************************************************************
* \if Function name : ihevce_q_get_filled_ctrl_sts_buff \endif
*
* \brief
*    Gets a next filled control status buffer from the que requested
*
* \param[in] high level encoder context pointer
* \param[in] pointer to return the buffer id
* \param[in] blocking mode / non blocking mode
*
* \return
*    None
*
* \author
*  Ittiam
*
*****************************************************************************
*/
void *ihevce_q_get_filled_ctrl_sts_buff(
    ihevce_hle_ctxt_t *ps_hle_ctxt, WORD32 *pi4_buff_id, WORD32 i4_blocking_mode)
{
    void *pv_ptr;
    pv_ptr = ihevce_q_get_filled_buff(
        ps_hle_ctxt->apv_enc_hdl[0], IHEVCE_OUTPUT_STATUS_Q, pi4_buff_id, i4_blocking_mode);

    return (pv_ptr);
}

//recon_dump
/*!
******************************************************************************
* \if Function name : ihevce_q_rel_recon_buf \endif
*
* \brief
*    Frees the recon buffer in the recon buffer que
*
* \param[in] high level encoder context pointer
* \param[in] buffer id which needs to be freed
*
* \return
*    None
*
* \author
*  Ittiam
*
*****************************************************************************
*/
IV_API_CALL_STATUS_T ihevce_q_rel_recon_buf(
    ihevce_hle_ctxt_t *ps_hle_ctxt,
    WORD32 i4_buff_id,
    WORD32 i4_bitrate_instance_id,
    WORD32 i4_resolution_id)
{
    IV_API_CALL_STATUS_T ret_status;

    ret_status = ihevce_q_rel_buf(
        ps_hle_ctxt->apv_enc_hdl[i4_resolution_id],
        IHEVCE_RECON_DATA_Q + i4_bitrate_instance_id,
        i4_buff_id);

    return (ret_status);
}

/*!
******************************************************************************
* \if Function name : ihevce_q_rel_ctrl_sts_buf \endif
*
* \brief
*    Frees the output control sttus buffer in buffer que
*
* \param[in] high level encoder context pointer
* \param[in] buffer id which needs to be freed
*
* \return
*    None
*
* \author
*  Ittiam
*
*****************************************************************************
*/
IV_API_CALL_STATUS_T ihevce_q_rel_ctrl_sts_buf(ihevce_hle_ctxt_t *ps_hle_ctxt, WORD32 i4_buff_id)
{
    IV_API_CALL_STATUS_T ret_status;

    ret_status = ihevce_q_rel_buf(ps_hle_ctxt->apv_enc_hdl[0], IHEVCE_OUTPUT_STATUS_Q, i4_buff_id);

    return (ret_status);
}

/*!
******************************************************************************
* \if Function name : ihevce_hle_interface_delete \endif
*
* \brief
*    High leve encoder delete interface
*
* \param[in] high level encoder interface context pointer
*
* \return
*    None
*
* \author
*  Ittiam
*
*****************************************************************************
*/
IV_API_CALL_STATUS_T ihevce_hle_interface_delete(ihevce_hle_ctxt_t *ps_hle_ctxt)
{
    /* local varaibles */
    enc_ctxt_t *ps_enc_ctxt;
    iv_mem_rec_t s_memtab;
    WORD32 ctr = 0, i, res_ctr, i4_num_resolutions;
    WORD32 ai4_num_bitrate_instances[IHEVCE_MAX_NUM_RESOLUTIONS] = { 1 };

    i4_num_resolutions = ps_hle_ctxt->ps_static_cfg_prms->s_tgt_lyr_prms.i4_num_res_layers;
    for(ctr = 0; ctr < i4_num_resolutions; ctr++)
    {
        ai4_num_bitrate_instances[ctr] =
            ps_hle_ctxt->ps_static_cfg_prms->s_tgt_lyr_prms.as_tgt_params[ctr]
                .i4_num_bitrate_instances;
    }

    for(res_ctr = 0; res_ctr < i4_num_resolutions && ps_hle_ctxt->apv_enc_hdl[res_ctr]; res_ctr++)
    {
        ps_enc_ctxt = (enc_ctxt_t *)ps_hle_ctxt->apv_enc_hdl[res_ctr];

        if(res_ctr == 0)
        {
            osal_sem_destroy(ps_enc_ctxt->s_thrd_sem_ctxt.pv_lap_sem_handle);
            osal_sem_destroy(ps_enc_ctxt->s_thrd_sem_ctxt.pv_inp_data_sem_handle);
            osal_sem_destroy(ps_enc_ctxt->s_thrd_sem_ctxt.pv_inp_ctrl_sem_handle);
            if(1 == ps_hle_ctxt->ps_static_cfg_prms->s_tgt_lyr_prms.i4_mres_single_out)
            {
                osal_sem_destroy(ps_enc_ctxt->s_thrd_sem_ctxt.pv_ent_common_mres_sem_hdl);
                osal_sem_destroy(ps_enc_ctxt->s_thrd_sem_ctxt.pv_out_common_mres_sem_hdl);
            }
        }

        osal_sem_destroy(ps_enc_ctxt->s_thrd_sem_ctxt.pv_lap_inp_data_sem_hdl);
        osal_sem_destroy(ps_enc_ctxt->s_thrd_sem_ctxt.pv_preenc_inp_data_sem_hdl);

        osal_sem_destroy(ps_enc_ctxt->s_thrd_sem_ctxt.pv_enc_frm_proc_sem_handle);
        osal_sem_destroy(ps_enc_ctxt->s_thrd_sem_ctxt.pv_pre_enc_frm_proc_sem_handle);

        osal_sem_destroy(ps_enc_ctxt->s_thrd_sem_ctxt.pv_out_ctrl_sem_handle);

        for(i = 0; i < ps_hle_ctxt->ps_static_cfg_prms->s_tgt_lyr_prms.as_tgt_params[res_ctr]
                           .i4_num_bitrate_instances;
            i++)
        {
            osal_sem_destroy(ps_enc_ctxt->s_thrd_sem_ctxt.apv_ent_cod_sem_handle[i]);
            osal_sem_destroy(ps_enc_ctxt->s_thrd_sem_ctxt.apv_out_strm_sem_handle[i]);
            osal_sem_destroy(ps_enc_ctxt->s_thrd_sem_ctxt.apv_out_recon_sem_handle[i]);
        }

        /* destroy the mutex  allocated for job queue usage encode group */
        osal_mutex_destroy(ps_enc_ctxt->s_multi_thrd.pv_job_q_mutex_hdl_enc_grp_me);

        /* destroy the mutex  allocated for job queue usage encode group */
        osal_mutex_destroy(ps_enc_ctxt->s_multi_thrd.pv_job_q_mutex_hdl_enc_grp_enc_loop);

        /* destroy the mutexes allocated for enc thread group */
        for(i = 0; i < MAX_NUM_ME_PARALLEL; i++)
        {
            osal_mutex_destroy(ps_enc_ctxt->s_multi_thrd.apv_mutex_handle[i]);

            osal_mutex_destroy(ps_enc_ctxt->s_multi_thrd.apv_mutex_handle_me_end[i]);
        }

        for(i = 0; i < MAX_NUM_ENC_LOOP_PARALLEL; i++)
        {
            osal_mutex_destroy(ps_enc_ctxt->s_multi_thrd.apv_mutex_handle_frame_init[i]);

            osal_mutex_destroy(ps_enc_ctxt->s_multi_thrd.apv_post_enc_mutex_handle[i]);
        }

        /* destroy the mutex  allocated for job queue, init and de-init
        usage pre enocde group */
        osal_mutex_destroy(ps_enc_ctxt->s_multi_thrd.pv_job_q_mutex_hdl_pre_enc_decomp);
        osal_mutex_destroy(ps_enc_ctxt->s_multi_thrd.pv_job_q_mutex_hdl_pre_enc_hme);
        osal_mutex_destroy(ps_enc_ctxt->s_multi_thrd.pv_job_q_mutex_hdl_pre_enc_l0ipe);
        osal_mutex_destroy(ps_enc_ctxt->s_multi_thrd.pv_mutex_hdl_pre_enc_init);
        osal_mutex_destroy(ps_enc_ctxt->s_multi_thrd.pv_mutex_hdl_pre_enc_decomp_deinit);
        osal_mutex_destroy(ps_enc_ctxt->s_multi_thrd.pv_mutex_hdl_pre_enc_hme_init);
        osal_mutex_destroy(ps_enc_ctxt->s_multi_thrd.pv_mutex_hdl_pre_enc_hme_deinit);
        osal_mutex_destroy(ps_enc_ctxt->s_multi_thrd.pv_mutex_hdl_l0_ipe_init);
        osal_mutex_destroy(ps_enc_ctxt->s_multi_thrd.pv_mutex_hdl_pre_enc_deinit);

        /* destroy the EncLoop Module */
        /* Note : Only Destroys the resources allocated in the module like */
        /* semaphore,etc. Memory free is done separately using memtabs     */
        ihevce_enc_loop_delete(ps_enc_ctxt->s_module_ctxt.pv_enc_loop_ctxt);

        /* destroy the Coarse ME Module */
        /* Note : Only Destroys the resources allocated in the module like */
        /* semaphore,etc. Memory free is done separately using memtabs     */
        ihevce_coarse_me_delete(
            ps_enc_ctxt->s_module_ctxt.pv_coarse_me_ctxt,
            ps_hle_ctxt->ps_static_cfg_prms,
            ps_enc_ctxt->i4_resolution_id);
        /* destroy semaphores for all the threads in pre-enc and enc */
        for(ctr = 0; ctr < ps_enc_ctxt->s_multi_thrd.i4_num_enc_proc_thrds; ctr++)
        {
            osal_sem_destroy(ps_enc_ctxt->s_multi_thrd.apv_enc_thrd_sem_handle[ctr]);
        }

        for(ctr = 0; ctr < ps_enc_ctxt->s_multi_thrd.i4_num_pre_enc_proc_thrds; ctr++)
        {
            osal_sem_destroy(ps_enc_ctxt->s_multi_thrd.apv_pre_enc_thrd_sem_handle[ctr]);
        }

        /* destroy the ME-EncLoop Dep Mngr */
        /* Note : Only Destroys the resources allocated in the module like */
        /* semaphore,etc. Memory free is done separately using memtabs     */
        for(ctr = 0; ctr < NUM_ME_ENC_BUFS; ctr++)
        {
            ihevce_dmgr_del(ps_enc_ctxt->s_multi_thrd.apv_dep_mngr_encloop_dep_me[ctr]);
        }
        /* destroy the Prev. frame EncLoop Done Dep Mngr */
        /* Note : Only Destroys the resources allocated in the module like */
        /* semaphore,etc. Memory free is done separately using memtabs     */
        for(i = 0; i < ps_enc_ctxt->s_multi_thrd.i4_num_enc_loop_frm_pllel; i++)
        {
            ihevce_dmgr_del(ps_enc_ctxt->s_multi_thrd.apv_dep_mngr_prev_frame_done[i]);
        }
        /* destroy the Prev. frame EncLoop Done for re-encode Dep Mngr */
        ihevce_dmgr_del(ps_enc_ctxt->s_multi_thrd.pv_dep_mngr_prev_frame_enc_done_for_reenc);

        /* destroy the Prev. frame ME Done Dep Mngr */
        /* Note : Only Destroys the resources allocated in the module like */
        /* semaphore,etc. Memory free is done separately using memtabs     */
        for(i = 0; i < ps_enc_ctxt->s_multi_thrd.i4_num_me_frm_pllel; i++)
        {
            ihevce_dmgr_del(ps_enc_ctxt->s_multi_thrd.apv_dep_mngr_prev_frame_me_done[i]);
        }

        /* destroy the Prev. frame PreEnc L1 Done Dep Mngr */
        /* Note : Only Destroys the resources allocated in the module like */
        /* semaphore,etc. Memory free is done separately using memtabs     */
        ihevce_dmgr_del(ps_enc_ctxt->s_multi_thrd.pv_dep_mngr_prev_frame_pre_enc_l1);

        /* destroy the Prev. frame PreEnc HME Done Dep Mngr */
        /* Note : Only Destroys the resources allocated in the module like */
        /* semaphore,etc. Memory free is done separately using memtabs     */
        ihevce_dmgr_del(ps_enc_ctxt->s_multi_thrd.pv_dep_mngr_prev_frame_pre_enc_coarse_me);

        /* destroy the Prev. frame PreEnc L0 Done Dep Mngr */
        /* Note : Only Destroys the resources allocated in the module like */
        /* semaphore,etc. Memory free is done separately using memtabs     */
        ihevce_dmgr_del(ps_enc_ctxt->s_multi_thrd.pv_dep_mngr_prev_frame_pre_enc_l0);

        /* destroy the ME-Prev Recon  Dep Mngr    */
        /* Note : Only Destroys the resources allocated in the module like */
        /* semaphore,etc. Memory free is done separately using memtabs     */
        for(ctr = 0; ctr < ps_enc_ctxt->ai4_num_buf_recon_q[0]; ctr++)
        {
            ihevce_dmgr_del(ps_enc_ctxt->pps_recon_buf_q[0][ctr]->pv_dep_mngr_recon);
        }

        /* destroy all the mutex created */
        if(res_ctr == 0)
        {
            if(NULL != ps_enc_ctxt->s_enc_ques.pv_q_mutex_hdl)
            {
                osal_mutex_destroy(ps_enc_ctxt->s_enc_ques.pv_q_mutex_hdl);
            }
        }

        if(NULL != ps_enc_ctxt->pv_rc_mutex_lock_hdl)
        {
            osal_mutex_destroy(ps_enc_ctxt->pv_rc_mutex_lock_hdl);
        }

        if(NULL != ps_enc_ctxt->s_multi_thrd.pv_sub_pic_rc_mutex_lock_hdl)
        {
            osal_mutex_destroy(ps_enc_ctxt->s_multi_thrd.pv_sub_pic_rc_mutex_lock_hdl);
        }

        if(NULL != ps_enc_ctxt->s_multi_thrd.pv_sub_pic_rc_for_qp_update_mutex_lock_hdl)
        {
            osal_mutex_destroy(
                ps_enc_ctxt->s_multi_thrd.pv_sub_pic_rc_for_qp_update_mutex_lock_hdl);
        }

        /* call the memrory free function */
        ihevce_mem_manager_free(ps_enc_ctxt, ps_hle_ctxt);
        if((1 == ps_hle_ctxt->ps_static_cfg_prms->s_tgt_lyr_prms.i4_mres_single_out) &&
           (res_ctr == 0))
        {
            s_memtab.i4_mem_size = sizeof(WORD32) * IHEVCE_MAX_NUM_RESOLUTIONS;
            s_memtab.i4_mem_alignment = 4;
            s_memtab.i4_size = sizeof(iv_mem_rec_t);
            s_memtab.e_mem_type = IV_EXT_CACHEABLE_NORMAL_MEM;
            s_memtab.pv_base = ps_enc_ctxt->s_multi_thrd.pi4_active_res_id;
            /* free active_res_id memory */
            ps_hle_ctxt->ihevce_mem_free(ps_hle_ctxt->pv_mem_mgr_hdl, &s_memtab);
        }
        if(res_ctr == (i4_num_resolutions - 1))
        {
            s_memtab.i4_mem_size = sizeof(ihevce_static_cfg_params_t);
            s_memtab.i4_mem_alignment = 4;
            s_memtab.i4_size = sizeof(iv_mem_rec_t);
            s_memtab.e_mem_type = IV_EXT_CACHEABLE_NORMAL_MEM;
            s_memtab.pv_base = ps_enc_ctxt->ps_stat_prms;

            /* free the encoder context pointer */
            ps_hle_ctxt->ihevce_mem_free(ps_hle_ctxt->pv_mem_mgr_hdl, &s_memtab);
        }
        s_memtab.i4_mem_size = sizeof(enc_ctxt_t);
        s_memtab.i4_mem_alignment = 4;
        s_memtab.i4_size = sizeof(iv_mem_rec_t);
        s_memtab.e_mem_type = IV_EXT_CACHEABLE_NORMAL_MEM;
        s_memtab.pv_base = ps_enc_ctxt;

        /* free the encoder context pointer */
        ps_hle_ctxt->ihevce_mem_free(ps_hle_ctxt->pv_mem_mgr_hdl, &s_memtab);

        /* reset the encoder handle to NULL */
        ps_hle_ctxt->apv_enc_hdl[res_ctr] = NULL;
    }
    /* profile end */
    PROFILE_END(&ps_hle_ctxt->profile_hle, "hle interface thread active time");
    for(res_ctr = 0; res_ctr < i4_num_resolutions; res_ctr++)
    {
        WORD32 i4_br_id;

        PROFILE_END(&ps_hle_ctxt->profile_pre_enc[res_ctr], "pre enc process");
        for(i4_br_id = 0; i4_br_id < ai4_num_bitrate_instances[res_ctr]; i4_br_id++)
        {
            PROFILE_END(&ps_hle_ctxt->profile_enc[res_ctr][i4_br_id], "enc process");
            PROFILE_END(&ps_hle_ctxt->profile_entropy[res_ctr][i4_br_id], "entropy process");
        }
    }

    /* OSAL Delete */
    ihevce_osal_delete((void *)ps_hle_ctxt);

    return (IV_SUCCESS);
}