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 * \file ihevce_plugin.c
     23 *
     24 * \brief
     25 *    This file contains wrapper utilities to use hevc encoder library
     26 *
     27 * \date
     28 *    15/04/2014
     29 *
     30 * \author
     31 *    Ittiam
     32 *
     33 * List of Functions
     34 *
     35 *
     36 ******************************************************************************
     37 */
     38 
     39 /*****************************************************************************/
     40 /* File Includes                                                             */
     41 /*****************************************************************************/
     42 /* System include files */
     43 #include <stdio.h>
     44 #include <string.h>
     45 #include <stdlib.h>
     46 #include <assert.h>
     47 #include <stdarg.h>
     48 
     49 /* User include files */
     50 #include "ihevc_typedefs.h"
     51 #include "itt_video_api.h"
     52 #include "ihevce_api.h"
     53 
     54 #include "rc_cntrl_param.h"
     55 #include "rc_frame_info_collector.h"
     56 #include "rc_look_ahead_params.h"
     57 
     58 #include "ihevc_defs.h"
     59 #include "ihevc_macros.h"
     60 #include "ihevc_debug.h"
     61 #include "ihevc_structs.h"
     62 #include "ihevc_platform_macros.h"
     63 #include "ihevc_deblk.h"
     64 #include "ihevc_itrans_recon.h"
     65 #include "ihevc_chroma_itrans_recon.h"
     66 #include "ihevc_chroma_intra_pred.h"
     67 #include "ihevc_intra_pred.h"
     68 #include "ihevc_inter_pred.h"
     69 #include "ihevc_mem_fns.h"
     70 #include "ihevc_padding.h"
     71 #include "ihevc_weighted_pred.h"
     72 #include "ihevc_sao.h"
     73 #include "ihevc_resi_trans.h"
     74 #include "ihevc_quant_iquant_ssd.h"
     75 
     76 #include "ihevce_defs.h"
     77 #include "ihevce_lap_enc_structs.h"
     78 #include "ihevce_plugin.h"
     79 #include "ihevce_plugin_priv.h"
     80 #include "ihevce_hle_interface.h"
     81 #include "ihevce_multi_thrd_structs.h"
     82 #include "ihevce_me_common_defs.h"
     83 #include "ihevce_error_codes.h"
     84 #include "ihevce_error_checks.h"
     85 #include "ihevce_function_selector.h"
     86 #include "ihevce_enc_structs.h"
     87 #include "ihevce_global_tables.h"
     88 
     89 #include "cast_types.h"
     90 #include "osal.h"
     91 #include "osal_defaults.h"
     92 
     93 /*****************************************************************************/
     94 /* Constant Macros                                                           */
     95 /*****************************************************************************/
     96 #define CREATE_TIME_ALLOCATION_INPUT 1
     97 #define CREATE_TIME_ALLOCATION_OUTPUT 0
     98 
     99 #define MAX_NUM_FRM_IN_GOP 600
    100 
    101 /*****************************************************************************/
    102 /* Extern variables                                                          */
    103 /*****************************************************************************/
    104 
    105 /*****************************************************************************/
    106 /* Function Definitions                                                      */
    107 /*****************************************************************************/
    108 
    109 /*!
    110 ******************************************************************************
    111 * \if Function name : mem_mngr_alloc \endif
    112 *
    113 * \brief
    114 *    Memory manager specific alloc function
    115 *
    116 * \param[in] pv_handle : handle to memory manager
    117 *                        (currently not required can be set to null)
    118 * \param[in] ps_memtab : memory descriptor pointer
    119 *
    120 * \return
    121 *    Memory pointer
    122 *
    123 * \author
    124 *  Ittiam
    125 *
    126 *****************************************************************************
    127 */
    128 void mem_mngr_alloc(void *pv_handle, ihevce_sys_api_t *ps_sys_api, iv_mem_rec_t *ps_memtab)
    129 {
    130 #ifndef X86_MINGW
    131     WORD32 error, mem_alignment;
    132 #endif
    133 
    134     (void)pv_handle;
    135 
    136 #ifdef X86_MINGW
    137     ps_memtab->pv_base = _aligned_malloc(ps_memtab->i4_mem_size, ps_memtab->i4_mem_alignment);
    138 #else
    139     mem_alignment = ps_memtab->i4_mem_alignment;
    140     mem_alignment = (mem_alignment >> 3) << 3;
    141     if(mem_alignment == 0)
    142     {
    143         error = posix_memalign(&ps_memtab->pv_base, sizeof(void *), ps_memtab->i4_mem_size);
    144     }
    145     else
    146     {
    147         error = posix_memalign(&ps_memtab->pv_base, mem_alignment, ps_memtab->i4_mem_size);
    148     }
    149     if(error != 0)
    150     {
    151         ps_sys_api->ihevce_printf(ps_sys_api->pv_cb_handle, "posix_memalign error %d\n", error);
    152     }
    153 #endif
    154 
    155     if(ps_memtab->pv_base == NULL)
    156     {
    157         ps_sys_api->ihevce_printf(
    158             ps_sys_api->pv_cb_handle, "IHEVCE ERROR: Unable to allocate memory\n");
    159         ASSERT(0);
    160     }
    161     return;
    162 }
    163 
    164 /*!
    165 ******************************************************************************
    166 * \if Function name : memory_alloc \endif
    167 *
    168 * \brief
    169 *    common memory allocate function should be used across all threads
    170 *
    171 * \param[in] pv_handle : handle to memory manager
    172 *                        (currently not required can be set to null)
    173 * \param[in] u4_size : size of memory required
    174 *
    175 * \return
    176 *    Memory pointer
    177 *
    178 * \author
    179 *  Ittiam
    180 *
    181 *****************************************************************************
    182 */
    183 void *memory_alloc(void *pv_handle, UWORD32 u4_size)
    184 {
    185     (void)pv_handle;
    186     return (malloc(u4_size));
    187 }
    188 
    189 /*!
    190 ******************************************************************************
    191 * \if Function name : mem_mngr_free \endif
    192 *
    193 * \brief
    194 *    Memory manager specific free function
    195 *
    196 * \param[in] pv_handle : handle to memory manager
    197 *                        (currently not required can be set to null)
    198 * \param[in] ps_memtab : memory descriptor pointer
    199 *
    200 * \return
    201 *    Memory pointer
    202 *
    203 * \author
    204 *  Ittiam
    205 *
    206 *****************************************************************************
    207 */
    208 void mem_mngr_free(void *pv_handle, iv_mem_rec_t *ps_memtab)
    209 {
    210     (void)pv_handle;
    211 #ifdef X86_MINGW
    212     _aligned_free(ps_memtab->pv_base);
    213 #else
    214     free(ps_memtab->pv_base);
    215 #endif
    216     return;
    217 }
    218 
    219 /*!
    220 ******************************************************************************
    221 * \if Function name : memory_free \endif
    222 *
    223 * \brief
    224 *    common memory free function should be used across all threads
    225 *
    226 * \param[in] pv_handle : handle to memory manager
    227 *                        (currently not required can be set to null)
    228 * \param[in] pv_mem : memory to be freed
    229 *
    230 * \return
    231 *    Memory pointer
    232 *
    233 * \author
    234 *  Ittiam
    235 *
    236 *****************************************************************************
    237 */
    238 void memory_free(void *pv_handle, void *pv_mem)
    239 {
    240     (void)pv_handle;
    241     free(pv_mem);
    242     return;
    243 }
    244 
    245 /*!
    246 ******************************************************************************
    247 * \if Function name : ihevce_set_def_params \endif
    248 *
    249 * \brief
    250 *    Set default values
    251 *
    252 * \param[in] Static params pointer
    253 *
    254 * \return
    255 *    status
    256 *
    257 * \author
    258 *  Ittiam
    259 *
    260 *****************************************************************************
    261 */
    262 IHEVCE_PLUGIN_STATUS_T ihevce_set_def_params(ihevce_static_cfg_params_t *ps_params)
    263 {
    264     WORD32 i, j;
    265     /* sanity checks */
    266     if(NULL == ps_params)
    267         return (IHEVCE_EFAIL);
    268 
    269     memset(ps_params, 0, sizeof(*ps_params));
    270 
    271     /* initialsie all the parameters to default values */
    272     ps_params->i4_size = sizeof(ihevce_static_cfg_params_t);
    273     ps_params->i4_save_recon = 0;
    274     ps_params->i4_log_dump_level = 0;
    275     ps_params->i4_enable_logo = 0;
    276     ps_params->i4_enable_csv_dump = 0;
    277 
    278     /* Control to free the entropy output buffers   */
    279     /* 1  for non_blocking mode */
    280     /* and 0 for blocking mode */
    281     ps_params->i4_outbuf_buf_free_control = 1;
    282 
    283     /* coding tools parameters */
    284     ps_params->s_coding_tools_prms.i4_size = sizeof(ihevce_coding_params_t);
    285     ps_params->s_coding_tools_prms.i4_cropping_mode = 1;
    286     ps_params->s_coding_tools_prms.i4_deblocking_type = 0;
    287     ps_params->s_coding_tools_prms.i4_enable_entropy_sync = 0;
    288     // New IDR/CDR Params
    289     ps_params->s_coding_tools_prms.i4_max_closed_gop_period = 0;
    290     ps_params->s_coding_tools_prms.i4_min_closed_gop_period = 0;
    291     ps_params->s_coding_tools_prms.i4_max_cra_open_gop_period = 60;
    292     ps_params->s_coding_tools_prms.i4_max_i_open_gop_period = 0;
    293     ps_params->s_coding_tools_prms.i4_max_reference_frames = -1;
    294     ps_params->s_coding_tools_prms.i4_max_temporal_layers = 0;
    295     ps_params->s_coding_tools_prms.i4_slice_type = 0;
    296     ps_params->s_coding_tools_prms.i4_use_default_sc_mtx = 0;
    297     ps_params->s_coding_tools_prms.i4_weighted_pred_enable = 0;
    298     ps_params->s_coding_tools_prms.i4_vqet = 0;
    299 
    300     ps_params->e_arch_type = ARCH_NA;
    301 
    302     /* config parameters */
    303     ps_params->s_config_prms.i4_size = sizeof(ihevce_config_prms_t);
    304     ps_params->s_config_prms.i4_cu_level_rc = 1;
    305     ps_params->s_config_prms.i4_init_vbv_fullness = 0;
    306     ps_params->s_config_prms.i4_max_frame_qp = 51;
    307     ps_params->s_config_prms.i4_max_log2_cu_size = 6;
    308     ps_params->s_config_prms.i4_max_log2_tu_size = 5;
    309     ps_params->s_config_prms.i4_max_search_range_horz = 512;
    310     ps_params->s_config_prms.i4_max_search_range_vert = 256;
    311     ps_params->s_config_prms.i4_max_tr_tree_depth_I = 1;
    312     ps_params->s_config_prms.i4_max_tr_tree_depth_nI = 3;
    313     ps_params->s_config_prms.i4_min_frame_qp = 1;
    314     ps_params->s_config_prms.i4_min_log2_cu_size = 3;
    315     ps_params->s_config_prms.i4_min_log2_tu_size = 2;
    316     ps_params->s_config_prms.i4_num_frms_to_encode = -1;
    317     ps_params->s_config_prms.i4_rate_factor = 500;
    318     ps_params->s_config_prms.i4_rate_control_mode = 2;
    319     ps_params->s_config_prms.i4_stuffing_enable = 0;
    320     ps_params->s_config_prms.i4_vbr_max_peak_rate_dur = 2000;
    321 
    322     /* LAP parameters */
    323     ps_params->s_lap_prms.i4_size = sizeof(ihevce_lap_params_t);
    324     ps_params->s_lap_prms.i4_deinterlacer_enable = 0;
    325     ps_params->s_lap_prms.i4_denoise_enable = 0;
    326     ps_params->s_lap_prms.i4_enable_wts_ofsts = 1;
    327     ps_params->s_lap_prms.i4_rc_look_ahead_pics = 0;
    328 
    329     /* Multi Thread parameters */
    330     ps_params->s_multi_thrd_prms.i4_size = sizeof(ihevce_static_multi_thread_params_t);
    331     ps_params->s_multi_thrd_prms.i4_max_num_cores = 1;
    332     ps_params->s_multi_thrd_prms.i4_memory_alloc_ctrl_flag = 0;
    333     ps_params->s_multi_thrd_prms.i4_num_proc_groups = 1;
    334     ps_params->s_multi_thrd_prms.ai4_num_cores_per_grp[0] = -1;
    335     ps_params->s_multi_thrd_prms.i4_use_thrd_affinity = -1;  //0;
    336     memset(&ps_params->s_multi_thrd_prms.au8_core_aff_mask[0], 0, sizeof(ULWORD64) * MAX_NUM_CORES);
    337 
    338     /* Output Streams parameters */
    339     ps_params->s_out_strm_prms.i4_size = sizeof(ihevce_out_strm_params_t);
    340     ps_params->s_out_strm_prms.i4_aud_enable_flags = 0;
    341     ps_params->s_out_strm_prms.i4_eos_enable_flags = 0;
    342     ps_params->s_out_strm_prms.i4_codec_profile = 1;
    343     ps_params->s_out_strm_prms.i4_codec_tier = 0;
    344     ps_params->s_out_strm_prms.i4_codec_type = 0;
    345     ps_params->s_out_strm_prms.i4_sei_buffer_period_flags = 0;
    346     ps_params->s_out_strm_prms.i4_sei_enable_flag = 0;
    347     ps_params->s_out_strm_prms.i4_sei_payload_enable_flag = 0;
    348     ps_params->s_out_strm_prms.i4_sei_pic_timing_flags = 0;
    349     ps_params->s_out_strm_prms.i4_sei_cll_enable = 0;
    350     ps_params->s_out_strm_prms.u2_sei_avg_cll = 0;
    351     ps_params->s_out_strm_prms.u2_sei_max_cll = 0;
    352     ps_params->s_out_strm_prms.i4_sei_recovery_point_flags = 0;
    353     ps_params->s_out_strm_prms.i4_sei_mastering_disp_colour_vol_flags = 0;
    354     ps_params->s_out_strm_prms.i4_decoded_pic_hash_sei_flag = 0;
    355     ps_params->s_out_strm_prms.i4_sps_at_cdr_enable = 1;
    356     ps_params->s_out_strm_prms.i4_vui_enable = 0;
    357     /*Set the interoperability flag to 0*/
    358     ps_params->s_out_strm_prms.i4_interop_flags = 0;
    359 
    360     /* Source parameters */
    361     ps_params->s_src_prms.i4_size = sizeof(ihevce_src_params_t);
    362     ps_params->s_src_prms.inp_chr_format = 1;
    363     ps_params->s_src_prms.i4_chr_format = 11;
    364     ps_params->s_src_prms.i4_field_pic = 0;
    365     ps_params->s_src_prms.i4_frm_rate_denom = 1000;
    366     ps_params->s_src_prms.i4_frm_rate_num = 30000;
    367     ps_params->s_src_prms.i4_height = 0;  //1080;
    368     ps_params->s_src_prms.i4_input_bit_depth = 8;
    369     ps_params->s_src_prms.i4_topfield_first = 1;
    370     ps_params->s_src_prms.i4_width = 0;  //1920;
    371     ps_params->s_src_prms.i4_orig_width = 0;
    372     ps_params->s_src_prms.i4_orig_height = 0;
    373 
    374     /* Target layer parameters */
    375     ps_params->s_tgt_lyr_prms.i4_size = sizeof(ihevce_tgt_layer_params_t);
    376     ps_params->s_tgt_lyr_prms.i4_enable_temporal_scalability = 0;
    377     ps_params->s_tgt_lyr_prms.i4_internal_bit_depth = 8;
    378     ps_params->s_tgt_lyr_prms.i4_mbr_quality_setting = IHEVCE_MBR_HIGH_QUALITY;
    379     ps_params->s_tgt_lyr_prms.i4_multi_res_layer_reuse = 0;
    380     ps_params->s_tgt_lyr_prms.i4_num_res_layers = 1;
    381     ps_params->s_tgt_lyr_prms.i4_mres_single_out = 0;
    382     ps_params->s_tgt_lyr_prms.i4_start_res_id = 0;
    383     ps_params->s_tgt_lyr_prms.pf_scale_chroma = NULL;
    384     ps_params->s_tgt_lyr_prms.pf_scale_luma = NULL;
    385     ps_params->s_tgt_lyr_prms.pv_scaler_handle = NULL;
    386 
    387     /* target parameters */
    388     for(i = 0; i < IHEVCE_MAX_NUM_RESOLUTIONS; i++)
    389     {
    390         ps_params->s_tgt_lyr_prms.as_tgt_params[i].i4_size = sizeof(ihevce_tgt_params_t);
    391         for(j = 0; j < IHEVCE_MAX_NUM_BITRATES; j++)
    392         {
    393             ps_params->s_tgt_lyr_prms.as_tgt_params[i].ai4_frame_qp[j] = 32;
    394             ps_params->s_tgt_lyr_prms.as_tgt_params[i].ai4_tgt_bitrate[j] = 5000000;
    395             ps_params->s_tgt_lyr_prms.as_tgt_params[i].ai4_peak_bitrate[j] = 10000000;
    396             ps_params->s_tgt_lyr_prms.as_tgt_params[i].ai4_max_vbv_buffer_size[j] = -1;
    397         }
    398         ps_params->s_tgt_lyr_prms.as_tgt_params[i].i4_codec_level = 156;
    399         ps_params->s_tgt_lyr_prms.as_tgt_params[i].i4_frm_rate_scale_factor = 1;
    400         ps_params->s_tgt_lyr_prms.as_tgt_params[i].i4_height = 0;
    401         ps_params->s_tgt_lyr_prms.as_tgt_params[i].i4_num_bitrate_instances = 1;
    402         ps_params->s_tgt_lyr_prms.as_tgt_params[i].i4_quality_preset = IHEVCE_QUALITY_P5;
    403         ps_params->s_tgt_lyr_prms.as_tgt_params[i].i4_width = 0;
    404     }
    405 
    406     /* SEI VUI parameters */
    407     ps_params->s_vui_sei_prms.u1_aspect_ratio_info_present_flag = 0;
    408     ps_params->s_vui_sei_prms.au1_aspect_ratio_idc[0] = 255;
    409     ps_params->s_vui_sei_prms.au2_sar_width[0] = 4;
    410     ps_params->s_vui_sei_prms.au2_sar_height[0] = 3;
    411     ps_params->s_vui_sei_prms.u1_overscan_info_present_flag = 0;
    412     ps_params->s_vui_sei_prms.u1_overscan_appropriate_flag = 0;
    413     ps_params->s_vui_sei_prms.u1_video_signal_type_present_flag = 1;
    414     ps_params->s_vui_sei_prms.u1_video_format = 5;
    415     ps_params->s_vui_sei_prms.u1_video_full_range_flag = 1;
    416     ps_params->s_vui_sei_prms.u1_colour_description_present_flag = 0;
    417     ps_params->s_vui_sei_prms.u1_colour_primaries = 2;
    418     ps_params->s_vui_sei_prms.u1_transfer_characteristics = 2;
    419     ps_params->s_vui_sei_prms.u1_matrix_coefficients = 2;
    420     ps_params->s_vui_sei_prms.u1_chroma_loc_info_present_flag = 0;
    421     ps_params->s_vui_sei_prms.u1_chroma_sample_loc_type_top_field = 0;
    422     ps_params->s_vui_sei_prms.u1_chroma_sample_loc_type_bottom_field = 0;
    423     ps_params->s_vui_sei_prms.u1_vui_hrd_parameters_present_flag = 0;
    424     ps_params->s_vui_sei_prms.u1_timing_info_present_flag = 0;
    425     ps_params->s_vui_sei_prms.u1_nal_hrd_parameters_present_flag = 0;
    426 
    427     /* Setting sysAPIs to NULL */
    428     memset(&ps_params->s_sys_api, 0, sizeof(ihevce_sys_api_t));
    429 
    430     /* Multi pass parameters */
    431     memset(&ps_params->s_pass_prms, 0, sizeof(ihevce_pass_prms_t));
    432     ps_params->s_pass_prms.i4_size = sizeof(ihevce_pass_prms_t);
    433 
    434     /* Tile parameters */
    435     ps_params->s_app_tile_params.i4_size = sizeof(ihevce_app_tile_params_t);
    436     ps_params->s_app_tile_params.i4_tiles_enabled_flag = 0;
    437     ps_params->s_app_tile_params.i4_uniform_spacing_flag = 1;
    438     ps_params->s_app_tile_params.i4_num_tile_cols = 1;
    439     ps_params->s_app_tile_params.i4_num_tile_rows = 1;
    440 
    441     ps_params->s_slice_params.i4_slice_segment_mode = 0;
    442     ps_params->s_slice_params.i4_slice_segment_argument = 1300;
    443 
    444     return (IHEVCE_EOK);
    445 }
    446 
    447 /*!
    448 ******************************************************************************
    449 * \if Function name : ihevce_cmds_error_report \endif
    450 *
    451 * \brief
    452 *    Call back from encoder to report errors
    453 *
    454 * \param[in]    pv_error_handling_cb_handle
    455 * \param[in]    i4_error_code
    456 * \param[in]    i4_cmd_type
    457 * \param[in]    i4_id
    458 *
    459 * \return
    460 *    None
    461 *
    462 * \author
    463 *  Ittiam
    464 *
    465 *****************************************************************************
    466 */
    467 IV_API_CALL_STATUS_T ihevce_cmds_error_report(
    468     void *pv_cb_handle, WORD32 i4_error_code, WORD32 i4_cmd_type, WORD32 i4_buf_id)
    469 {
    470     /*local variables*/
    471     plugin_ctxt_t *plugin_ctxt = (plugin_ctxt_t *)pv_cb_handle;
    472     ihevce_static_cfg_params_t *ps_static_cfg_params =
    473         ((ihevce_hle_ctxt_t *)plugin_ctxt->pv_hle_interface_ctxt)->ps_static_cfg_prms;
    474 
    475     if(i4_cmd_type == 0)
    476         ps_static_cfg_params->s_sys_api.ihevce_printf(
    477             ps_static_cfg_params->s_sys_api.pv_cb_handle,
    478             "PLUGIN ERROR: Asynchronous Buffer Error %d in Buffer Id %d",
    479             i4_error_code,
    480             i4_buf_id);
    481     else
    482         ps_static_cfg_params->s_sys_api.ihevce_printf(
    483             ps_static_cfg_params->s_sys_api.pv_cb_handle,
    484             "PLUGIN ERROR: Synchronous Buffer Error %d in Buffer Id %d",
    485             i4_error_code,
    486             i4_buf_id);
    487 
    488     return (IV_SUCCESS);
    489 }
    490 
    491 /*!
    492 ******************************************************************************
    493 * \if Function name : ihevce_strm_fill_done \endif
    494 *
    495 * \brief
    496 *    Call back from encoder when Bitstream is ready to consume
    497 *
    498 * \param[in]
    499 * \param[in]
    500 * \param[in]
    501 *
    502 * \return
    503 *    None
    504 *
    505 * \author
    506 *  Ittiam
    507 *
    508 *****************************************************************************
    509 */
    510 IV_API_CALL_STATUS_T
    511     ihevce_strm_fill_done(void *pv_ctxt, void *pv_curr_out, WORD32 i4_br_id, WORD32 i4_res_id)
    512 {
    513     /* local variables */
    514     plugin_ctxt_t *ps_ctxt = (plugin_ctxt_t *)pv_ctxt;
    515     app_ctxt_t *ps_app_ctxt = &ps_ctxt->s_app_ctxt;
    516     out_strm_prms_t *ps_out_strm_prms = &ps_app_ctxt->as_out_strm_prms[i4_res_id][i4_br_id];
    517     void *pv_app_out_strm_buf_mutex_hdl = ps_out_strm_prms->pv_app_out_strm_buf_mutex_hdl;
    518     void *pv_app_out_strm_buf_cond_var_hdl = ps_out_strm_prms->pv_app_out_strm_buf_cond_var_hdl;
    519     iv_output_data_buffs_t *ps_curr_out = (iv_output_data_buffs_t *)pv_curr_out;
    520     WORD32 end_flag = ps_curr_out->i4_end_flag;
    521     WORD32 osal_result;
    522 
    523     /* ------  output dump stream  -- */
    524     if((WORD32)IV_FAIL != ps_curr_out->i4_process_ret_sts)
    525     {
    526         if(0 != ps_curr_out->i4_bytes_generated)
    527         {
    528             /* accumulate the total bits generated */
    529             (ps_out_strm_prms->u8_total_bits) += ps_curr_out->i4_bytes_generated * 8;
    530             (ps_out_strm_prms->u4_num_frms_enc)++;
    531         }
    532     }
    533 
    534     /****** Lock the critical section ******/
    535     osal_result = osal_mutex_lock(pv_app_out_strm_buf_mutex_hdl);
    536     if(OSAL_SUCCESS != osal_result)
    537         return (IV_FAIL);
    538 
    539     /* Update the end flag to communicate with the o/p thread */
    540     ps_app_ctxt->ai4_out_strm_end_flag[i4_res_id][i4_br_id] = end_flag;
    541 
    542     /* set the produced status of the buffer */
    543     {
    544         WORD32 idx = ps_curr_out->i4_cb_buf_id;
    545 
    546         ps_ctxt->aaas_out_bufs[i4_res_id][i4_br_id][idx].i4_timestamp_low =
    547             ps_curr_out->i4_out_timestamp_low;
    548         ps_ctxt->aaas_out_bufs[i4_res_id][i4_br_id][idx].i4_timestamp_high =
    549             ps_curr_out->i4_out_timestamp_high;
    550         ps_ctxt->aaas_out_bufs[i4_res_id][i4_br_id][idx].i4_bytes_gen =
    551             ps_curr_out->i4_bytes_generated;
    552         ps_ctxt->aaas_out_bufs[i4_res_id][i4_br_id][idx].i4_is_key_frame = 0;
    553         ps_ctxt->aaas_out_bufs[i4_res_id][i4_br_id][idx].i4_end_flag = end_flag;
    554 
    555         if((IV_IDR_FRAME == ps_curr_out->i4_encoded_frame_type) ||
    556            (IV_I_FRAME == ps_curr_out->i4_encoded_frame_type))
    557         {
    558             ps_ctxt->aaas_out_bufs[i4_res_id][i4_br_id][idx].i4_is_key_frame = 1;
    559         }
    560 
    561         /* set the buffer as produced */
    562         ps_ctxt->aaas_out_bufs[i4_res_id][i4_br_id][idx].i4_is_prod = 1;
    563     }
    564 
    565     /****** Wake ******/
    566     osal_cond_var_signal(pv_app_out_strm_buf_cond_var_hdl);
    567 
    568     /****** Unlock the critical section ******/
    569     osal_result = osal_mutex_unlock(pv_app_out_strm_buf_mutex_hdl);
    570     if(OSAL_SUCCESS != osal_result)
    571         return (IV_FAIL);
    572 
    573     return (IV_SUCCESS);
    574 }
    575 
    576 /*!
    577 ******************************************************************************
    578 * \if Function name : ihevce_plugin_init \endif
    579 *
    580 * \brief
    581 *    Initialises the enocder context and threads
    582 *
    583 * \param[in] Static params pointer
    584 *
    585 * \return
    586 *    status
    587 *
    588 * \author
    589 *  Ittiam
    590 *
    591 *****************************************************************************
    592 */
    593 IHEVCE_PLUGIN_STATUS_T ihevce_init(ihevce_static_cfg_params_t *ps_params, void **ppv_ihevce_hdl)
    594 {
    595     /* local variables */
    596     plugin_ctxt_t *ps_ctxt;
    597     app_ctxt_t *ps_app_ctxt;
    598     ihevce_hle_ctxt_t *ps_interface_ctxt;
    599     ihevce_sys_api_t *ps_sys_api;
    600     osal_cb_funcs_t s_cb_funcs;
    601     WORD32 status = 0;
    602 
    603     /* sanity checks */
    604     if(NULL == ps_params)
    605         return (IHEVCE_EFAIL);
    606 
    607     if(NULL == ppv_ihevce_hdl)
    608         return (IHEVCE_EFAIL);
    609 
    610     /* set the handle to null by default */
    611     *ppv_ihevce_hdl = NULL;
    612 
    613     /* Initiallizing system apis */
    614     ps_sys_api = &ps_params->s_sys_api;
    615     ihevce_init_sys_api(NULL, ps_sys_api);
    616 
    617     /* --------------------------------------------------------------------- */
    618     /*                   Query and print Encoder version                     */
    619     /* --------------------------------------------------------------------- */
    620     ps_sys_api->ihevce_printf(
    621         ps_sys_api->pv_cb_handle, "Encoder version %s\n\n", ihevce_get_encoder_version());
    622 
    623     /* --------------------------------------------------------------------- */
    624     /*                    Plugin Handle create                               */
    625     /* --------------------------------------------------------------------- */
    626     ps_ctxt = (plugin_ctxt_t *)memory_alloc(NULL, sizeof(plugin_ctxt_t));
    627     if(NULL == ps_ctxt)
    628     {
    629         ps_sys_api->ihevce_printf(
    630             ps_sys_api->pv_cb_handle, "IHEVCE ERROR: Error in Plugin initialization\n");
    631         return (IHEVCE_EFAIL);
    632     }
    633     memset(ps_ctxt, 0, sizeof(plugin_ctxt_t));
    634 
    635     /* initialise memory call backs */
    636     ps_ctxt->ihevce_mem_alloc = memory_alloc;
    637     ps_ctxt->ihevce_mem_free = memory_free;
    638 
    639     ps_ctxt->u8_num_frames_encoded = 0;
    640 
    641     if((0 == ps_params->i4_res_id) && (0 == ps_params->i4_br_id))
    642     {
    643         /* --------------------------------------------------------------------- */
    644         /*                      OSAL Handle create                               */
    645         /* --------------------------------------------------------------------- */
    646         ps_ctxt->pv_osal_handle = memory_alloc(NULL, OSAL_HANDLE_SIZE);
    647 
    648         /* Initialize OSAL call back functions */
    649         s_cb_funcs.mmr_handle = NULL;
    650         s_cb_funcs.osal_alloc = memory_alloc;
    651         s_cb_funcs.osal_free = memory_free;
    652 
    653         status = osal_init(ps_ctxt->pv_osal_handle);
    654         if(OSAL_SUCCESS != status)
    655         {
    656             ps_sys_api->ihevce_printf(
    657                 ps_sys_api->pv_cb_handle, "IHEVCE ERROR: Error in OSAL initialization\n");
    658             return (IHEVCE_EFAIL);
    659         }
    660 
    661         status = osal_register_callbacks(ps_ctxt->pv_osal_handle, &s_cb_funcs);
    662         if(OSAL_SUCCESS != status)
    663         {
    664             ps_sys_api->ihevce_printf(
    665                 ps_sys_api->pv_cb_handle, "IHEVCE ERROR: Error in OSAL call back registration\n");
    666             return (IHEVCE_EFAIL);
    667         }
    668 
    669         /* --------------------------------------------------------------------- */
    670         /*                      Thread affinity  Initialization                  */
    671         /* --------------------------------------------------------------------- */
    672         if(ps_params->s_multi_thrd_prms.i4_use_thrd_affinity)
    673         {
    674             WORD32 i4_ctr;
    675 
    676             /* loop over all the cores */
    677             for(i4_ctr = 0; i4_ctr < ps_params->s_multi_thrd_prms.i4_max_num_cores; i4_ctr++)
    678             {
    679                 /* All cores are logical cores  */
    680                 ps_params->s_multi_thrd_prms.au8_core_aff_mask[i4_ctr] = ((ULWORD64)1 << i4_ctr);
    681             }
    682         }
    683 
    684         /* --------------------------------------------------------------------- */
    685         /*             Context Initialization                                    */
    686         /* --------------------------------------------------------------------- */
    687         ps_app_ctxt = &ps_ctxt->s_app_ctxt;
    688 
    689         ps_ctxt->ps_static_cfg_prms = (ihevce_static_cfg_params_t *)ps_ctxt->ihevce_mem_alloc(
    690             NULL, sizeof(ihevce_static_cfg_params_t));
    691         if(NULL == ps_ctxt->ps_static_cfg_prms)
    692         {
    693             ps_sys_api->ihevce_printf(
    694                 ps_sys_api->pv_cb_handle, "IHEVCE ERROR: Error in Plugin memory initialization\n");
    695             return (IHEVCE_EFAIL);
    696         }
    697 
    698         ps_params->apF_csv_file[0][0] = NULL;
    699 
    700         /* set the memory manager handle to NULL */
    701         ps_app_ctxt->pv_mem_mngr_handle = NULL;
    702 
    703         /* --------------------------------------------------------------------- */
    704         /*            Back up the static params passed by caller                 */
    705         /* --------------------------------------------------------------------- */
    706         memcpy(ps_ctxt->ps_static_cfg_prms, ps_params, sizeof(ihevce_static_cfg_params_t));
    707 
    708         ps_ctxt->ps_static_cfg_prms->s_src_prms.i4_orig_width =
    709             ps_ctxt->ps_static_cfg_prms->s_src_prms.i4_width;
    710         if(HEVCE_MIN_WIDTH > ps_ctxt->ps_static_cfg_prms->s_src_prms.i4_width)
    711         {
    712             ps_ctxt->ps_static_cfg_prms->s_src_prms.i4_width = HEVCE_MIN_WIDTH;
    713         }
    714 
    715         ps_ctxt->ps_static_cfg_prms->s_src_prms.i4_orig_height =
    716             ps_ctxt->ps_static_cfg_prms->s_src_prms.i4_height;
    717         if(HEVCE_MIN_HEIGHT > ps_ctxt->ps_static_cfg_prms->s_src_prms.i4_height)
    718         {
    719             ps_ctxt->ps_static_cfg_prms->s_src_prms.i4_height = HEVCE_MIN_HEIGHT;
    720         }
    721 
    722         /* setting tgt width and height same as src width and height */
    723         ps_ctxt->ps_static_cfg_prms->s_tgt_lyr_prms.as_tgt_params[0].i4_width =
    724             ps_ctxt->ps_static_cfg_prms->s_src_prms.i4_width;
    725         ps_ctxt->ps_static_cfg_prms->s_tgt_lyr_prms.as_tgt_params[0].i4_height =
    726             ps_ctxt->ps_static_cfg_prms->s_src_prms.i4_height;
    727 
    728         /* setting key frame interval */
    729         ps_ctxt->ps_static_cfg_prms->s_coding_tools_prms.i4_max_closed_gop_period =
    730             MIN(MAX_NUM_FRM_IN_GOP,
    731                 ps_ctxt->ps_static_cfg_prms->s_coding_tools_prms.i4_max_closed_gop_period);
    732         ps_ctxt->ps_static_cfg_prms->s_coding_tools_prms.i4_max_cra_open_gop_period =
    733             MIN(MAX_NUM_FRM_IN_GOP,
    734                 ps_ctxt->ps_static_cfg_prms->s_coding_tools_prms.i4_max_cra_open_gop_period);
    735         ps_ctxt->ps_static_cfg_prms->s_coding_tools_prms.i4_max_i_open_gop_period =
    736             MIN(MAX_NUM_FRM_IN_GOP,
    737                 ps_ctxt->ps_static_cfg_prms->s_coding_tools_prms.i4_max_i_open_gop_period);
    738 
    739         /* --------------------------------------------------------------------- */
    740         /*            High Level Encoder context init                            */
    741         /* --------------------------------------------------------------------- */
    742         ps_interface_ctxt =
    743             (ihevce_hle_ctxt_t *)ps_ctxt->ihevce_mem_alloc(NULL, sizeof(ihevce_hle_ctxt_t));
    744         if(NULL == ps_interface_ctxt)
    745         {
    746             ps_sys_api->ihevce_printf(
    747                 ps_sys_api->pv_cb_handle,
    748                 "IHEVCE ERROR: Error in Plugin HLE memory initialization\n");
    749             return (IHEVCE_EFAIL);
    750         }
    751         memset(ps_interface_ctxt, 0, sizeof(ihevce_hle_ctxt_t));
    752         ps_interface_ctxt->i4_size = sizeof(ihevce_hle_ctxt_t);
    753 
    754         ps_ctxt->pv_hle_interface_ctxt = ps_interface_ctxt;
    755 
    756         /* store the static config parameters pointer */
    757         ps_interface_ctxt->ps_static_cfg_prms = ps_ctxt->ps_static_cfg_prms;
    758 
    759         /* initialise the interface strucure parameters */
    760         ps_interface_ctxt->pv_inp_cb_handle = (void *)ps_ctxt;
    761         ps_interface_ctxt->pv_out_cb_handle = (void *)ps_ctxt;
    762         ps_interface_ctxt->pv_recon_cb_handle = (void *)ps_ctxt;
    763 
    764         ps_interface_ctxt->pv_osal_handle = ps_ctxt->pv_osal_handle;
    765         ps_interface_ctxt->ihevce_mem_alloc = mem_mngr_alloc;
    766         ps_interface_ctxt->ihevce_mem_free = mem_mngr_free;
    767         ps_interface_ctxt->i4_hle_init_done = 0;
    768         ps_interface_ctxt->pv_mem_mgr_hdl = ps_app_ctxt->pv_mem_mngr_handle;
    769 
    770         /* reigter the callbacks */
    771         ps_interface_ctxt->ihevce_output_strm_fill_done = ihevce_strm_fill_done;
    772         ps_interface_ctxt->ihevce_output_recon_fill_done = NULL;
    773         ps_interface_ctxt->ihevce_set_free_input_buff = NULL;
    774 
    775         /*Added for run time or create time creation*/
    776         ps_interface_ctxt->i4_create_time_input_allocation = (WORD32)CREATE_TIME_ALLOCATION_INPUT;
    777         ps_interface_ctxt->i4_create_time_output_allocation = (WORD32)CREATE_TIME_ALLOCATION_OUTPUT;
    778 
    779         ps_interface_ctxt->ihevce_cmds_error_report = ihevce_cmds_error_report;
    780         ps_interface_ctxt->pv_cmd_err_cb_handle = (void *)ps_ctxt;
    781 
    782         /* --------------------------------------------------------------------- */
    783         /*           High Level Encoder Instance Creation                        */
    784         /* --------------------------------------------------------------------- */
    785         status = ihevce_hle_interface_create(ps_interface_ctxt);
    786         if((WORD32)IV_FAIL == status)
    787         {
    788             ihevce_hle_interface_delete(ps_interface_ctxt);
    789 
    790             memory_free(NULL, ps_interface_ctxt);
    791 
    792             /* free static config memory */
    793             ps_ctxt->ihevce_mem_free(NULL, ps_ctxt->ps_static_cfg_prms);
    794 
    795             /* free osal handle */
    796             memory_free(NULL, ps_ctxt->pv_osal_handle);
    797 
    798             /* free plugin ctxt memory */
    799             memory_free(NULL, ps_ctxt);
    800 
    801             ps_sys_api->ihevce_printf(
    802                 ps_sys_api->pv_cb_handle, "IHEVCE ERROR: Error in Plugin HLE create failed\n");
    803             return (IHEVCE_EFAIL);
    804         }
    805 
    806         /* --------------------------------------------------------------------- */
    807         /*            Input Output and Command buffer allocation                 */
    808         /* --------------------------------------------------------------------- */
    809         {
    810             WORD32 ctr;
    811             WORD32 buf_size;
    812             UWORD8 *pu1_tmp_buf;
    813             WORD32 i4_res_id;
    814             WORD32 i4_br_id;
    815             WORD32 i4_num_resolutions;
    816             WORD32 ai4_num_bitrate_instances[IHEVCE_MAX_NUM_RESOLUTIONS] = { 1 };
    817             iv_input_bufs_req_t s_input_bufs_req;
    818             iv_res_layer_output_bufs_req_t s_res_layer_output_bufs_req;
    819             iv_res_layer_recon_bufs_req_t s_res_layer_recon_bufs_req;
    820 
    821             /* local array of pointers */
    822             void *apv_inp_luma_bufs[MAX_NUM_INP_DATA_BUFS];
    823             void *apv_inp_cb_bufs[MAX_NUM_INP_DATA_BUFS];
    824             void *apv_inp_cr_bufs[MAX_NUM_INP_DATA_BUFS];
    825             void *apv_inp_sync_bufs[MAX_NUM_INP_CTRL_SYNC_BUFS];
    826             void *apv_inp_async_bufs[MAX_NUM_INP_CTRL_ASYNC_BUFS];
    827             void *apv_out_data_bufs[IHEVCE_MAX_NUM_RESOLUTIONS][IHEVCE_MAX_NUM_BITRATES]
    828                                    [MAX_NUM_OUT_DATA_BUFS];
    829 
    830             /* get the number of resolutions */
    831             i4_num_resolutions = ps_ctxt->ps_static_cfg_prms->s_tgt_lyr_prms.i4_num_res_layers;
    832 
    833             /* set the size of the structure */
    834             s_input_bufs_req.i4_size = sizeof(iv_input_bufs_req_t);
    835             s_res_layer_output_bufs_req.i4_size = sizeof(iv_res_layer_output_bufs_req_t);
    836             s_res_layer_recon_bufs_req.i4_size = sizeof(iv_res_layer_recon_bufs_req_t);
    837 
    838             /* loop over num resolutions */
    839             for(i4_res_id = 0; i4_res_id < i4_num_resolutions; i4_res_id++)
    840             {
    841                 /* store the number of bitrates */
    842                 ai4_num_bitrate_instances[i4_res_id] =
    843                     ps_ctxt->ps_static_cfg_prms->s_tgt_lyr_prms.as_tgt_params[i4_res_id]
    844                         .i4_num_bitrate_instances;
    845 
    846                 /* loop over num bitrates */
    847                 for(i4_br_id = 0; i4_br_id < ai4_num_bitrate_instances[i4_res_id]; i4_br_id++)
    848                 {
    849                     s_res_layer_output_bufs_req.s_output_buf_req[i4_res_id][i4_br_id].i4_size =
    850                         sizeof(iv_output_bufs_req_t);
    851                 }
    852             }
    853 
    854             /* call Query I/O buffer */
    855             status = ihevce_query_io_buf_req(
    856                 ps_interface_ctxt,
    857                 &s_input_bufs_req,
    858                 &s_res_layer_output_bufs_req,
    859                 &s_res_layer_recon_bufs_req);
    860 
    861             /* check on the requirements against the MAX of application */
    862             /* should be present only for debug purpose                 */
    863 
    864             /* ---------------  Input data buffers init ---------------------- */
    865             /* allocate memory for input buffers  */
    866             if(ps_interface_ctxt->i4_create_time_input_allocation == 1)
    867             {
    868                 buf_size = s_input_bufs_req.i4_min_size_uv_buf + s_input_bufs_req.i4_min_size_y_buf;
    869                 ps_ctxt->s_memtab_inp_data_buf.i4_size = sizeof(iv_mem_rec_t);
    870                 ps_ctxt->s_memtab_inp_data_buf.i4_mem_alignment = 4;
    871                 ps_ctxt->s_memtab_inp_data_buf.i4_mem_size =
    872                     (s_input_bufs_req.i4_min_num_yuv_bufs + XTRA_INP_DATA_BUFS) * buf_size;
    873                 ps_ctxt->s_memtab_inp_data_buf.e_mem_type = IV_EXT_CACHEABLE_NUMA_NODE0_MEM;
    874 
    875                 mem_mngr_alloc(
    876                     ps_app_ctxt->pv_mem_mngr_handle, ps_sys_api, &ps_ctxt->s_memtab_inp_data_buf);
    877 
    878                 pu1_tmp_buf = (UWORD8 *)ps_ctxt->s_memtab_inp_data_buf.pv_base;
    879 
    880                 if(NULL == pu1_tmp_buf)
    881                 {
    882                     ps_sys_api->ihevce_printf(
    883                         ps_sys_api->pv_cb_handle, "IHEVCE ERROR: Error in allocate memory\n");
    884                     return (IHEVCE_EFAIL);
    885                 }
    886 
    887                 /* loop to initialise the buffer pointer */
    888                 for(ctr = 0; ctr < s_input_bufs_req.i4_min_num_yuv_bufs + XTRA_INP_DATA_BUFS; ctr++)
    889                 {
    890                     apv_inp_luma_bufs[ctr] = pu1_tmp_buf;
    891                     apv_inp_cb_bufs[ctr] = pu1_tmp_buf + s_input_bufs_req.i4_min_size_y_buf;
    892                     apv_inp_cr_bufs[ctr] = NULL; /* 420SP case */
    893 
    894                     /* increment the input buffer pointer to next buffer */
    895                     pu1_tmp_buf += buf_size;
    896                 }
    897             }
    898 
    899             /* ---------------  Output data buffers init ---------------------- */
    900 
    901             /* loop over num resolutions */
    902             for(i4_res_id = 0; i4_res_id < i4_num_resolutions; i4_res_id++)
    903             {
    904                 for(i4_br_id = 0; i4_br_id < ai4_num_bitrate_instances[i4_res_id]; i4_br_id++)
    905                 {
    906                     buf_size = s_res_layer_output_bufs_req.s_output_buf_req[i4_res_id][i4_br_id]
    907                                    .i4_min_size_bitstream_buf;
    908 
    909                     ps_ctxt->as_memtab_out_data_buf[i4_res_id][i4_br_id].i4_size =
    910                         sizeof(iv_mem_rec_t);
    911                     ps_ctxt->as_memtab_out_data_buf[i4_res_id][i4_br_id].i4_mem_alignment = 4;
    912 
    913                     if(!ps_interface_ctxt->i4_create_time_output_allocation)
    914                     {
    915                         ps_ctxt->as_memtab_out_data_buf[i4_res_id][i4_br_id].i4_mem_size =
    916                             (s_res_layer_output_bufs_req.s_output_buf_req[i4_res_id][i4_br_id]
    917                                  .i4_min_num_out_bufs +
    918                              XTRA_OUT_DATA_BUFS) *
    919                             buf_size;
    920                     }
    921                     else
    922                     {
    923                         ps_ctxt->as_memtab_out_data_buf[i4_res_id][i4_br_id].i4_mem_size =
    924                             (s_res_layer_output_bufs_req.s_output_buf_req[i4_res_id][i4_br_id]
    925                                  .i4_min_num_out_bufs) *
    926                             buf_size;
    927                     }
    928                     ps_ctxt->as_memtab_out_data_buf[i4_res_id][i4_br_id].e_mem_type =
    929                         IV_EXT_CACHEABLE_NUMA_NODE1_MEM;
    930 
    931                     mem_mngr_alloc(
    932                         ps_app_ctxt->pv_mem_mngr_handle,
    933                         ps_sys_api,
    934                         &ps_ctxt->as_memtab_out_data_buf[i4_res_id][i4_br_id]);
    935 
    936                     pu1_tmp_buf =
    937                         (UWORD8 *)ps_ctxt->as_memtab_out_data_buf[i4_res_id][i4_br_id].pv_base;
    938                     if(NULL == pu1_tmp_buf)
    939                     {
    940                         ps_sys_api->ihevce_printf(
    941                             ps_sys_api->pv_cb_handle, "IHEVCE ERROR: Error in allocate memory\n");
    942                         return (IHEVCE_EFAIL);
    943                     }
    944 
    945                     if(ps_interface_ctxt->i4_create_time_output_allocation == 1)
    946                     {
    947                         /* loop to initialise the buffer pointer */
    948                         for(ctr = 0;
    949                             ctr < s_res_layer_output_bufs_req.s_output_buf_req[i4_res_id][i4_br_id]
    950                                       .i4_min_num_out_bufs;
    951                             ctr++)
    952                         {
    953                             apv_out_data_bufs[i4_res_id][i4_br_id][ctr] = pu1_tmp_buf;
    954                             pu1_tmp_buf += buf_size;
    955                         }
    956                     }
    957                     else
    958                     {
    959                         WORD32 i4_num_out_bufs =
    960                             s_res_layer_output_bufs_req.s_output_buf_req[i4_res_id][i4_br_id]
    961                                 .i4_min_num_out_bufs +
    962                             XTRA_OUT_DATA_BUFS;
    963                         ps_ctxt->i4_num_out_bufs = i4_num_out_bufs;
    964                         ps_ctxt->ai4_free_out_buf_idx[i4_res_id][i4_br_id] = 0;
    965                         ps_ctxt->i4_prod_out_buf_idx = 0;
    966 
    967                         /* Assert to make sure ps_ctxt->aaas_out_bufs[i4_res_id][i4_br_id][] array
    968                         has more bufs than ps_ctxt->i4_num_out_bufs. Needed to identify
    969                         wrap-around case */
    970                         ASSERT(ps_ctxt->i4_num_out_bufs <= MAX_NUM_OUT_DATA_BUFS);
    971 
    972                         /* loop to initialise the buffer pointer */
    973                         for(ctr = 0; ctr < i4_num_out_bufs; ctr++)
    974                         {
    975                             ps_ctxt->aaas_out_bufs[i4_res_id][i4_br_id][ctr].i4_idx = ctr;
    976                             ps_ctxt->aaas_out_bufs[i4_res_id][i4_br_id][ctr].i4_is_free = 1;
    977                             ps_ctxt->aaas_out_bufs[i4_res_id][i4_br_id][ctr].i4_is_prod = 0;
    978                             ps_ctxt->aaas_out_bufs[i4_res_id][i4_br_id][ctr].i4_bytes_gen = 0;
    979                             ps_ctxt->aaas_out_bufs[i4_res_id][i4_br_id][ctr].pu1_buf = pu1_tmp_buf;
    980                             ps_ctxt->aaas_out_bufs[i4_res_id][i4_br_id][ctr].i4_buf_size = buf_size;
    981                             pu1_tmp_buf += buf_size;
    982                         }
    983                     }
    984 
    985                     /* create mutex for controlling the out strm buf b/w appln and encoder */
    986                     ps_app_ctxt->as_out_strm_prms[i4_res_id][i4_br_id]
    987                         .pv_app_out_strm_buf_mutex_hdl = osal_mutex_create(ps_ctxt->pv_osal_handle);
    988                     if(NULL == ps_app_ctxt->as_out_strm_prms[i4_res_id][i4_br_id]
    989                                    .pv_app_out_strm_buf_mutex_hdl)
    990                     {
    991                         ps_sys_api->ihevce_printf(
    992                             ps_sys_api->pv_cb_handle,
    993                             "IHEVCE ERROR: Error in Plugin initialization\n");
    994                         return (IHEVCE_EFAIL);
    995                     }
    996 
    997                     /* create mutex for controlling the out strm buf b/w appln and encoder */
    998                     ps_app_ctxt->as_out_strm_prms[i4_res_id][i4_br_id]
    999                         .pv_app_out_strm_buf_cond_var_hdl =
   1000                         osal_cond_var_create(ps_ctxt->pv_osal_handle);
   1001                     if(NULL == ps_app_ctxt->as_out_strm_prms[i4_res_id][i4_br_id]
   1002                                    .pv_app_out_strm_buf_cond_var_hdl)
   1003                     {
   1004                         ps_sys_api->ihevce_printf(
   1005                             ps_sys_api->pv_cb_handle,
   1006                             "IHEVCE ERROR: Error in Plugin initialization\n");
   1007                         return (IHEVCE_EFAIL);
   1008                     }
   1009                 }
   1010             }
   1011 
   1012             if(ps_interface_ctxt->i4_create_time_input_allocation == 1)
   1013             {
   1014                 /* ------------- Input sync command buffers init -------------------- */
   1015                 buf_size = s_input_bufs_req.i4_min_size_synch_ctrl_bufs;
   1016 
   1017                 ps_ctxt->s_memtab_inp_sync_ctrl_buf.i4_size = sizeof(iv_mem_rec_t);
   1018                 ps_ctxt->s_memtab_inp_sync_ctrl_buf.i4_mem_alignment = 4;
   1019                 ps_ctxt->s_memtab_inp_sync_ctrl_buf.i4_mem_size =
   1020                     (s_input_bufs_req.i4_min_num_yuv_bufs + XTRA_INP_DATA_BUFS) * buf_size;
   1021                 ps_ctxt->s_memtab_inp_sync_ctrl_buf.e_mem_type = IV_EXT_CACHEABLE_NUMA_NODE0_MEM;
   1022 
   1023                 mem_mngr_alloc(
   1024                     ps_app_ctxt->pv_mem_mngr_handle,
   1025                     ps_sys_api,
   1026                     &ps_ctxt->s_memtab_inp_sync_ctrl_buf);
   1027 
   1028                 pu1_tmp_buf = (UWORD8 *)ps_ctxt->s_memtab_inp_sync_ctrl_buf.pv_base;
   1029 
   1030                 if(NULL == pu1_tmp_buf)
   1031                 {
   1032                     ps_sys_api->ihevce_printf(
   1033                         ps_sys_api->pv_cb_handle, "IHEVCE ERROR: Error in allocate memory\n");
   1034                     return (IHEVCE_EFAIL);
   1035                 }
   1036 
   1037                 /* loop to initialise the buffer pointer */
   1038                 for(ctr = 0; ctr < s_input_bufs_req.i4_min_num_yuv_bufs + XTRA_INP_DATA_BUFS; ctr++)
   1039                 {
   1040                     apv_inp_sync_bufs[ctr] = pu1_tmp_buf;
   1041                     pu1_tmp_buf += buf_size;
   1042                 }
   1043             }
   1044 
   1045             /* ------------- Input async command buffers init -------------------- */
   1046             buf_size = s_input_bufs_req.i4_min_size_asynch_ctrl_bufs;
   1047 
   1048             /* allocate memory for output status buffer */
   1049             ps_ctxt->pu1_inp_async_ctrl_buf = (UWORD8 *)ps_ctxt->ihevce_mem_alloc(
   1050                 NULL, s_input_bufs_req.i4_min_num_asynch_ctrl_bufs * buf_size);
   1051             if(ps_ctxt->pu1_inp_async_ctrl_buf == NULL)
   1052             {
   1053                 ps_sys_api->ihevce_printf(
   1054                     ps_sys_api->pv_cb_handle,
   1055                     "IHEVCE ERROR: Error in Plugin memory initialization\n");
   1056                 return (IHEVCE_EFAIL);
   1057             }
   1058 
   1059             pu1_tmp_buf = ps_ctxt->pu1_inp_async_ctrl_buf;
   1060 
   1061             /* loop to initialise the buffer pointer */
   1062             for(ctr = 0; ctr < s_input_bufs_req.i4_min_num_asynch_ctrl_bufs; ctr++)
   1063             {
   1064                 apv_inp_async_bufs[ctr] = pu1_tmp_buf;
   1065                 pu1_tmp_buf += buf_size;
   1066             }
   1067 
   1068             /* Create IO ports for the buffer allocated */
   1069             {
   1070                 iv_input_data_ctrl_buffs_desc_t s_inp_desc;
   1071                 iv_input_asynch_ctrl_buffs_desc_t s_inp_ctrl_desc;
   1072                 iv_res_layer_output_data_buffs_desc_t s_mres_out_desc;
   1073                 iv_res_layer_recon_data_buffs_desc_t s_mres_recon_desc;
   1074 
   1075                 /* set the parameters of the input data control desc */
   1076                 s_inp_desc.i4_size = sizeof(iv_input_data_ctrl_buffs_desc_t);
   1077                 s_inp_desc.i4_num_synch_ctrl_bufs = s_input_bufs_req.i4_min_num_synch_ctrl_bufs;
   1078                 s_inp_desc.i4_num_yuv_bufs =
   1079                     s_input_bufs_req.i4_min_num_yuv_bufs + XTRA_INP_DATA_BUFS;
   1080                 s_inp_desc.i4_size_y_buf = s_input_bufs_req.i4_min_size_y_buf;
   1081                 s_inp_desc.i4_size_uv_buf = s_input_bufs_req.i4_min_size_uv_buf;
   1082                 s_inp_desc.i4_size_synch_ctrl_bufs = s_input_bufs_req.i4_min_size_synch_ctrl_bufs;
   1083                 s_inp_desc.ppv_synch_ctrl_bufs = &apv_inp_sync_bufs[0];
   1084                 s_inp_desc.ppv_y_buf = &apv_inp_luma_bufs[0];
   1085                 s_inp_desc.ppv_u_buf = &apv_inp_cb_bufs[0];
   1086                 s_inp_desc.ppv_v_buf = &apv_inp_cr_bufs[0];
   1087 
   1088                 /* set the parameters of the input async control desc */
   1089                 s_inp_ctrl_desc.i4_size = sizeof(iv_input_asynch_ctrl_buffs_desc_t);
   1090                 s_inp_ctrl_desc.i4_num_asynch_ctrl_bufs =
   1091                     s_input_bufs_req.i4_min_num_asynch_ctrl_bufs;
   1092                 s_inp_ctrl_desc.i4_size_asynch_ctrl_bufs =
   1093                     s_input_bufs_req.i4_min_size_asynch_ctrl_bufs;
   1094                 s_inp_ctrl_desc.ppv_asynch_ctrl_bufs = &apv_inp_async_bufs[0];
   1095 
   1096                 for(i4_res_id = 0; i4_res_id < i4_num_resolutions; i4_res_id++)
   1097                 {
   1098                     /* set the parameters of the output data desc */
   1099                     for(i4_br_id = 0; i4_br_id < ai4_num_bitrate_instances[i4_res_id]; i4_br_id++)
   1100                     {
   1101                         s_mres_out_desc.s_output_data_buffs[i4_res_id][i4_br_id].i4_size =
   1102                             sizeof(iv_output_data_buffs_desc_t);
   1103 
   1104                         if(!ps_interface_ctxt->i4_create_time_output_allocation)
   1105                         {
   1106                             s_mres_out_desc.s_output_data_buffs[i4_res_id][i4_br_id]
   1107                                 .i4_num_bitstream_bufs =
   1108                                 s_res_layer_output_bufs_req.s_output_buf_req[i4_res_id][i4_br_id]
   1109                                     .i4_min_num_out_bufs +
   1110                                 XTRA_OUT_DATA_BUFS;
   1111                         }
   1112                         else
   1113                         {
   1114                             s_mres_out_desc.s_output_data_buffs[i4_res_id][i4_br_id]
   1115                                 .i4_num_bitstream_bufs =
   1116                                 s_res_layer_output_bufs_req.s_output_buf_req[i4_res_id][i4_br_id]
   1117                                     .i4_min_num_out_bufs;
   1118                         }
   1119 
   1120                         s_mres_out_desc.s_output_data_buffs[i4_res_id][i4_br_id]
   1121                             .i4_size_bitstream_buf =
   1122                             s_res_layer_output_bufs_req.s_output_buf_req[i4_res_id][i4_br_id]
   1123                                 .i4_min_size_bitstream_buf;
   1124                         s_mres_out_desc.s_output_data_buffs[i4_res_id][i4_br_id].ppv_bitstream_bufs =
   1125                             &apv_out_data_bufs[i4_res_id][i4_br_id][0];
   1126                     }
   1127                 }
   1128 
   1129                 s_mres_recon_desc.i4_size = sizeof(iv_res_layer_recon_data_buffs_desc_t);
   1130                 /* call create I/O ports */
   1131                 status = ihevce_create_ports(
   1132                     ps_interface_ctxt,
   1133                     &s_inp_desc,
   1134                     &s_inp_ctrl_desc,
   1135                     &s_mres_out_desc,
   1136                     &s_mres_recon_desc);
   1137             }
   1138         }
   1139 
   1140         /* --------------------------------------------------------------------- */
   1141         /*            Create a High level encoder  thread                        */
   1142         /* --------------------------------------------------------------------- */
   1143         {
   1144             osal_thread_attr_t s_thread_attr = OSAL_DEFAULT_THREAD_ATTR;
   1145 
   1146             /* Initialize application thread attributes */
   1147             s_thread_attr.exit_code = 0;
   1148             s_thread_attr.name = 0;
   1149             s_thread_attr.priority_map_flag = 1;
   1150             s_thread_attr.priority = OSAL_PRIORITY_DEFAULT;
   1151             s_thread_attr.stack_addr = 0;
   1152             s_thread_attr.stack_size = THREAD_STACK_SIZE;
   1153             s_thread_attr.thread_func = ihevce_hle_interface_thrd;
   1154             s_thread_attr.thread_param = (void *)(ps_interface_ctxt);
   1155             s_thread_attr.core_affinity_mask = 0;
   1156             s_thread_attr.group_num = 0;
   1157 
   1158             /* Create High level encoder thread */
   1159             ps_ctxt->pv_hle_thread_hdl =
   1160                 osal_thread_create(ps_ctxt->pv_osal_handle, &s_thread_attr);
   1161             if(NULL == ps_ctxt->pv_hle_thread_hdl)
   1162             {
   1163                 return IHEVCE_EFAIL;
   1164             }
   1165         }
   1166 
   1167         /* --------------------------------------------------------------------- */
   1168         /*                 Wait until HLE init is done                           */
   1169         /* --------------------------------------------------------------------- */
   1170         {
   1171             volatile WORD32 hle_init_done;
   1172             volatile WORD32 *pi4_hle_init_done;
   1173 
   1174             pi4_hle_init_done = (volatile WORD32 *)&ps_interface_ctxt->i4_hle_init_done;
   1175 
   1176             do
   1177             {
   1178                 hle_init_done = *pi4_hle_init_done;
   1179 
   1180             } while(0 == hle_init_done);
   1181         }
   1182 
   1183         /* reset flush mode */
   1184         ps_ctxt->i4_flush_mode_on = 0;
   1185 
   1186         {
   1187             WORD32 i4_res_id;
   1188             WORD32 i4_br_id;
   1189             for(i4_res_id = 0; i4_res_id < IHEVCE_MAX_NUM_RESOLUTIONS; i4_res_id++)
   1190             {
   1191                 for(i4_br_id = 0; i4_br_id < IHEVCE_MAX_NUM_BITRATES; i4_br_id++)
   1192                 {
   1193                     /* reset out end flag */
   1194                     ps_ctxt->ai4_out_end_flag[i4_res_id][i4_br_id] = 0;
   1195                 }
   1196             }
   1197         }
   1198 
   1199         /* reset the field id */
   1200         ps_ctxt->i4_field_id = 0;
   1201 
   1202         /* based on number of B pics set the DTS value */
   1203         ps_ctxt->i8_dts = -1;
   1204 
   1205         if(0 != ps_ctxt->ps_static_cfg_prms->s_coding_tools_prms.i4_max_temporal_layers)
   1206         {
   1207             ps_ctxt->i8_dts =
   1208                 (-1) *
   1209                 (1 << ps_ctxt->ps_static_cfg_prms->s_coding_tools_prms.i4_max_temporal_layers);
   1210         }
   1211 
   1212         /* initialsie the buffer stride */
   1213         {
   1214             WORD32 max_cu_size;
   1215 
   1216             max_cu_size = (1 << ps_ctxt->ps_static_cfg_prms->s_config_prms.i4_max_log2_cu_size);
   1217             ps_ctxt->i4_frm_stride =
   1218                 ps_ctxt->ps_static_cfg_prms->s_src_prms.i4_width +
   1219                 SET_CTB_ALIGN(ps_ctxt->ps_static_cfg_prms->s_src_prms.i4_width, max_cu_size);
   1220         }
   1221     }
   1222     else
   1223     {
   1224         /* free plugin ctxt memory */
   1225         memory_free(NULL, ps_ctxt);
   1226 
   1227         return (IHEVCE_EFAIL);
   1228     }
   1229 
   1230     /* reset the place holders of old bitrate */
   1231     memset(&ps_ctxt->ai4_old_bitrate[0][0], 0, sizeof(ps_ctxt->ai4_old_bitrate));
   1232 
   1233     ps_ctxt->ai4_old_bitrate[0][0] = ps_params->s_tgt_lyr_prms.as_tgt_params[0].ai4_tgt_bitrate[0];
   1234 
   1235     /* store the plugin handle before returning */
   1236     *ppv_ihevce_hdl = (void *)ps_ctxt;
   1237 
   1238     return (IHEVCE_EOK);
   1239 }
   1240 
   1241 static IHEVCE_PLUGIN_STATUS_T
   1242     ihevce_receive_out_buffer(plugin_ctxt_t *ps_ctxt, ihevce_out_buf_t *ps_out)
   1243 {
   1244     app_ctxt_t *ps_app_ctxt = &ps_ctxt->s_app_ctxt;
   1245     WORD32 i4_res_id, i4_br_id;
   1246     WORD32 i4_num_resolutions;
   1247     WORD32 ai4_num_bitrate_instances[IHEVCE_MAX_NUM_RESOLUTIONS] = { 1 };
   1248 
   1249     i4_num_resolutions = ps_ctxt->ps_static_cfg_prms->s_tgt_lyr_prms.i4_num_res_layers;
   1250     for(i4_res_id = 0; i4_res_id < i4_num_resolutions; i4_res_id++)
   1251     {
   1252         ai4_num_bitrate_instances[i4_res_id] =
   1253             ps_ctxt->ps_static_cfg_prms->s_tgt_lyr_prms.as_tgt_params[i4_res_id]
   1254                 .i4_num_bitrate_instances;
   1255     }
   1256     /* default init */
   1257     ps_out->pu1_output_buf = NULL;
   1258     ps_out->i4_bytes_generated = 0;
   1259 
   1260     /* ---------------- if any output buffer is available return the buffer back ------------- */
   1261     while(1)
   1262     {
   1263         WORD32 osal_result;
   1264         WORD32 buf_present = 0;
   1265         WORD32 i4_is_prod = 1;
   1266         WORD32 i4_atleast_one_br_prod = 0;
   1267         /****** Lock the critical section ******/
   1268         osal_result =
   1269             osal_mutex_lock(ps_app_ctxt->as_out_strm_prms[0][0].pv_app_out_strm_buf_mutex_hdl);
   1270 
   1271         if(OSAL_SUCCESS != osal_result)
   1272             return IHEVCE_EFAIL;
   1273 
   1274         /* wait until entropy sends an output */
   1275         while(1)
   1276         {
   1277             i4_is_prod = 1;
   1278             for(i4_res_id = 0; i4_res_id < i4_num_resolutions; i4_res_id++)
   1279             {
   1280                 for(i4_br_id = 0; i4_br_id < ai4_num_bitrate_instances[i4_res_id]; i4_br_id++)
   1281                 {
   1282                     i4_is_prod &=
   1283                         ps_ctxt->aaas_out_bufs[i4_res_id][i4_br_id][ps_ctxt->i4_prod_out_buf_idx]
   1284                             .i4_is_prod;
   1285                     i4_atleast_one_br_prod |=
   1286                         ps_ctxt->aaas_out_bufs[i4_res_id][i4_br_id][ps_ctxt->i4_prod_out_buf_idx]
   1287                             .i4_is_prod;
   1288                 }
   1289             }
   1290             if(!i4_is_prod)
   1291             {
   1292                 for(i4_res_id = 0; i4_res_id < i4_num_resolutions; i4_res_id++)
   1293                 {
   1294                     for(i4_br_id = 0; i4_br_id < ai4_num_bitrate_instances[i4_res_id]; i4_br_id++)
   1295                     {
   1296                         osal_cond_var_wait(
   1297                             ps_app_ctxt->as_out_strm_prms[i4_res_id][i4_br_id]
   1298                                 .pv_app_out_strm_buf_cond_var_hdl,
   1299                             ps_app_ctxt->as_out_strm_prms[i4_res_id][i4_br_id]
   1300                                 .pv_app_out_strm_buf_mutex_hdl);
   1301                     }
   1302                 }
   1303             }
   1304             else
   1305             {
   1306                 break;
   1307             }
   1308         }
   1309 
   1310         ASSERT(i4_is_prod == 1);
   1311 
   1312         /* check if the current buffer for all bitrates and resolutions have been produced */
   1313         if(1 == i4_is_prod)
   1314         {
   1315             buf_present = 1;
   1316 
   1317             for(i4_res_id = 0; i4_res_id < i4_num_resolutions; i4_res_id++)
   1318             {
   1319                 for(i4_br_id = 0; i4_br_id < ai4_num_bitrate_instances[i4_res_id]; i4_br_id++)
   1320                 {
   1321                     /* set the buffer to free status */
   1322                     ps_ctxt->aaas_out_bufs[i4_res_id][i4_br_id][ps_ctxt->i4_prod_out_buf_idx]
   1323                         .i4_is_free = 1;
   1324                     if((0 == i4_res_id) && (0 == i4_br_id))
   1325                     {
   1326                         ps_out->i4_bytes_generated =
   1327                             ps_ctxt->aaas_out_bufs[0][0][ps_ctxt->i4_prod_out_buf_idx].i4_bytes_gen;
   1328                         ps_out->pu1_output_buf =
   1329                             ps_ctxt->aaas_out_bufs[0][0][ps_ctxt->i4_prod_out_buf_idx].pu1_buf;
   1330                     }
   1331                 }
   1332             }
   1333 
   1334             /* copy the contents to output buffer */
   1335             ps_out->i4_is_key_frame =
   1336                 ps_ctxt->aaas_out_bufs[0][0][ps_ctxt->i4_prod_out_buf_idx].i4_is_key_frame;
   1337             ps_out->u8_pts =
   1338                 ps_ctxt->aaas_out_bufs[0][0][ps_ctxt->i4_prod_out_buf_idx].i4_timestamp_low;
   1339             ps_out->u8_pts =
   1340                 ps_out->u8_pts |
   1341                 ((ULWORD64)(
   1342                      ps_ctxt->aaas_out_bufs[0][0][ps_ctxt->i4_prod_out_buf_idx].i4_timestamp_high)
   1343                  << 32);
   1344             ps_out->i4_end_flag =
   1345                 ps_ctxt->aaas_out_bufs[0][0][ps_ctxt->i4_prod_out_buf_idx].i4_end_flag;
   1346             ps_out->i8_dts = ps_ctxt->i8_dts;
   1347 
   1348             /* increment the DTS */
   1349             ps_ctxt->i8_dts++;
   1350         }
   1351 
   1352         /* check for buffer present */
   1353         if(1 == buf_present)
   1354         {
   1355             ps_ctxt->i4_prod_out_buf_idx++;
   1356 
   1357             /* wrap around case */
   1358             if(ps_ctxt->i4_prod_out_buf_idx == ps_ctxt->i4_num_out_bufs)
   1359             {
   1360                 ps_ctxt->i4_prod_out_buf_idx = 0;
   1361             }
   1362 
   1363             /****** Unlock the critical section ******/
   1364             osal_result = osal_mutex_unlock(
   1365                 ps_app_ctxt->as_out_strm_prms[0][0].pv_app_out_strm_buf_mutex_hdl);
   1366             if(OSAL_SUCCESS != osal_result)
   1367                 return IHEVCE_EFAIL;
   1368 
   1369             /* break while 1 loop */
   1370             break;
   1371         }
   1372         else
   1373         {
   1374             /* in steady state*/
   1375             if(0 == ps_ctxt->i4_flush_mode_on)
   1376             {
   1377                 /****** Unlock the critical section ******/
   1378                 osal_result = osal_mutex_unlock(
   1379                     ps_app_ctxt->as_out_strm_prms[0][0].pv_app_out_strm_buf_mutex_hdl);
   1380                 if(OSAL_SUCCESS != osal_result)
   1381                     return IHEVCE_EFAIL;
   1382                 if(!i4_atleast_one_br_prod) /*** If atleast one bitrate is produced do not break from loop **/
   1383                 { /*** Continue in while loop and Wait for next bitrate ***/
   1384                     /* break while 1 loop */
   1385                     break;
   1386                 }
   1387             }
   1388             else
   1389             {
   1390                 /* In flush mode is ON then this function must return output
   1391                 buffers. Otherwise assume that encoding is over and return fail */
   1392                 /****** Unlock the critical section ******/
   1393                 osal_result = osal_mutex_unlock(
   1394                     ps_app_ctxt->as_out_strm_prms[0][0].pv_app_out_strm_buf_mutex_hdl);
   1395                 if(OSAL_SUCCESS != osal_result)
   1396                     return IHEVCE_EFAIL;
   1397             }
   1398         }
   1399     }
   1400 
   1401     return IHEVCE_EOK;
   1402 }
   1403 
   1404 static IHEVCE_PLUGIN_STATUS_T
   1405     ihevce_queue_out_buffer(plugin_ctxt_t *ps_ctxt, WORD32 i4_res_id, WORD32 i4_br_id)
   1406 {
   1407     app_ctxt_t *ps_app_ctxt = &ps_ctxt->s_app_ctxt;
   1408     ihevce_hle_ctxt_t *ps_interface_ctxt = (ihevce_hle_ctxt_t *)ps_ctxt->pv_hle_interface_ctxt;
   1409 
   1410     /* --------------------------------------------------------------------- */
   1411     /*           Free Output buffer Queuing                                  */
   1412     /* --------------------------------------------------------------------- */
   1413     /* ------- Que in free output buffer if end flag is not set ------ */
   1414     if(0 == ps_ctxt->ai4_out_end_flag[i4_res_id][i4_br_id])
   1415     {
   1416         WORD32 osal_result;
   1417         iv_output_data_buffs_t *ps_curr_out;
   1418         WORD32 buf_id_strm;
   1419         WORD32 free_idx;
   1420 
   1421         free_idx = ps_ctxt->ai4_free_out_buf_idx[i4_res_id][i4_br_id];
   1422 
   1423         if(1 == ps_ctxt->aaas_out_bufs[i4_res_id][i4_br_id][free_idx].i4_is_free)
   1424         {
   1425             /* ---------- get a free desc. from output Q ------ */
   1426             ps_curr_out = (iv_output_data_buffs_t *)ihevce_q_get_free_out_strm_buff(
   1427                 ps_interface_ctxt, &buf_id_strm, BUFF_QUE_NON_BLOCKING_MODE, i4_br_id, i4_res_id);
   1428 
   1429             /* if a free buffer is available */
   1430             if(NULL != ps_curr_out)
   1431             {
   1432                 /****** Lock the critical section ******/
   1433                 osal_result = osal_mutex_lock(ps_app_ctxt->as_out_strm_prms[i4_res_id][i4_br_id]
   1434                                                   .pv_app_out_strm_buf_mutex_hdl);
   1435 
   1436                 if(OSAL_SUCCESS != osal_result)
   1437                     return IHEVCE_EFAIL;
   1438 
   1439                 if(1 == ps_app_ctxt->ai4_out_strm_end_flag[i4_res_id][i4_br_id])
   1440                 {
   1441                     ps_curr_out->i4_is_last_buf = 1;
   1442                     ps_ctxt->ai4_out_end_flag[i4_res_id][i4_br_id] = 1;
   1443                 }
   1444                 else
   1445                 {
   1446                     ps_curr_out->i4_is_last_buf = 0;
   1447                 }
   1448                 ASSERT(ps_ctxt->aaas_out_bufs[i4_res_id][i4_br_id][free_idx].i4_is_free == 1);
   1449                 ASSERT(free_idx == ps_ctxt->aaas_out_bufs[i4_res_id][i4_br_id][free_idx].i4_idx);
   1450 
   1451                 ps_curr_out->pv_bitstream_bufs =
   1452                     (void *)ps_ctxt->aaas_out_bufs[i4_res_id][i4_br_id][free_idx].pu1_buf;
   1453                 ps_curr_out->i4_cb_buf_id =
   1454                     ps_ctxt->aaas_out_bufs[i4_res_id][i4_br_id][free_idx].i4_idx;
   1455                 ps_ctxt->aaas_out_bufs[i4_res_id][i4_br_id][free_idx].i4_is_free = 0;
   1456                 ps_ctxt->aaas_out_bufs[i4_res_id][i4_br_id][free_idx].i4_is_prod = 0;
   1457                 ps_ctxt->aaas_out_bufs[i4_res_id][i4_br_id][free_idx].i4_bytes_gen = 0;
   1458 
   1459                 ps_ctxt->ai4_free_out_buf_idx[i4_res_id][i4_br_id]++;
   1460 
   1461                 /* wrap around case */
   1462                 if(ps_ctxt->ai4_free_out_buf_idx[i4_res_id][i4_br_id] == ps_ctxt->i4_num_out_bufs)
   1463                 {
   1464                     ps_ctxt->ai4_free_out_buf_idx[i4_res_id][i4_br_id] = 0;
   1465                 }
   1466 
   1467                 /****** Unlock the critical section ******/
   1468                 osal_result = osal_mutex_unlock(ps_app_ctxt->as_out_strm_prms[i4_res_id][i4_br_id]
   1469                                                     .pv_app_out_strm_buf_mutex_hdl);
   1470                 if(OSAL_SUCCESS != osal_result)
   1471                     return IHEVCE_EFAIL;
   1472 
   1473                 /* ---------- set the buffer as produced ---------- */
   1474                 ihevce_q_set_out_strm_buff_prod(
   1475                     ps_interface_ctxt, buf_id_strm, i4_br_id, i4_res_id);
   1476             }
   1477         }
   1478     }
   1479     return IHEVCE_EOK;
   1480 }
   1481 
   1482 /*!
   1483 ******************************************************************************
   1484 * \if Function name : ihevce_close \endif
   1485 *
   1486 * \brief
   1487 *    De-Initialises the enocder context and threads
   1488 *
   1489 * \param[in] Static params pointer
   1490 *
   1491 * \return
   1492 *    status
   1493 *
   1494 * \author
   1495 *  Ittiam
   1496 *
   1497 *****************************************************************************
   1498 */
   1499 IHEVCE_PLUGIN_STATUS_T ihevce_close(void *pv_ihevce_hdl)
   1500 {
   1501     /* local variables */
   1502     plugin_ctxt_t *ps_ctxt;
   1503     app_ctxt_t *ps_app_ctxt;
   1504     ihevce_hle_ctxt_t *ps_interface_ctxt;
   1505     WORD32 i4_num_resolutions;
   1506     WORD32 i4_res_id;
   1507     WORD32 i4_br_id;
   1508     WORD32 ai4_num_bitrate_instances[IHEVCE_MAX_NUM_RESOLUTIONS] = { 1 };
   1509     ihevce_sys_api_t *ps_sys_api;
   1510 
   1511     /* sanity checks */
   1512     if(NULL == pv_ihevce_hdl)
   1513         return (IHEVCE_EFAIL);
   1514 
   1515     /* derive local variables */
   1516     ps_ctxt = (plugin_ctxt_t *)pv_ihevce_hdl;
   1517 
   1518     ps_sys_api = &ps_ctxt->ps_static_cfg_prms->s_sys_api;
   1519 
   1520     if((0 == ps_ctxt->ps_static_cfg_prms->i4_res_id) &&
   1521        (0 == ps_ctxt->ps_static_cfg_prms->i4_br_id))
   1522     {
   1523         ps_interface_ctxt = (ihevce_hle_ctxt_t *)ps_ctxt->pv_hle_interface_ctxt;
   1524         ps_app_ctxt = &ps_ctxt->s_app_ctxt;
   1525         i4_num_resolutions = ps_ctxt->ps_static_cfg_prms->s_tgt_lyr_prms.i4_num_res_layers;
   1526 
   1527         if(1 != ps_ctxt->i4_flush_mode_on)
   1528         {
   1529             for(i4_res_id = 0; i4_res_id < i4_num_resolutions; i4_res_id++)
   1530             {
   1531                 ai4_num_bitrate_instances[i4_res_id] =
   1532                     ps_ctxt->ps_static_cfg_prms->s_tgt_lyr_prms.as_tgt_params[i4_res_id]
   1533                         .i4_num_bitrate_instances;
   1534                 for(i4_br_id = 0; i4_br_id < ai4_num_bitrate_instances[i4_res_id]; i4_br_id++)
   1535                 {
   1536                     /* ------- Que in free output buffer if end flag is not set ------ */
   1537                     ihevce_queue_out_buffer(ps_ctxt, i4_res_id, i4_br_id);
   1538                 }
   1539             }
   1540             /* --------------------------------------------------------------------- */
   1541             /*            Input Processing                                           */
   1542             /* --------------------------------------------------------------------- */
   1543             {
   1544                 WORD32 buf_id;
   1545 
   1546                 iv_input_data_ctrl_buffs_t *ps_curr_inp;
   1547                 WORD32 *pi4_ctrl_ptr;
   1548 
   1549                 /* ---------- get a free buffer from input Q ------ */
   1550                 ps_curr_inp = (iv_input_data_ctrl_buffs_t *)ihevce_q_get_free_inp_data_buff(
   1551                     ps_interface_ctxt, &buf_id, BUFF_QUE_BLOCKING_MODE);
   1552 
   1553                 if(NULL != ps_curr_inp)
   1554                 {
   1555                     /* flush mode command */
   1556 
   1557                     ps_curr_inp->i4_buf_id = buf_id;
   1558 
   1559                     /* set the input status to invalid flag */
   1560                     ps_curr_inp->i4_inp_frm_data_valid_flag = 0;
   1561 
   1562                     pi4_ctrl_ptr = (WORD32 *)ps_curr_inp->pv_synch_ctrl_bufs;
   1563 
   1564                     *pi4_ctrl_ptr = IHEVCE_SYNCH_API_FLUSH_TAG;
   1565                     *(pi4_ctrl_ptr + 1) = 0;
   1566                     *(pi4_ctrl_ptr + 2) = IHEVCE_SYNCH_API_END_TAG;
   1567 
   1568                     ps_curr_inp->i4_cmd_buf_size = 4 * 3; /* 4 bytes */
   1569 
   1570                     /* ---------- set the buffer as produced ---------- */
   1571                     ihevce_q_set_inp_data_buff_prod(ps_interface_ctxt, buf_id);
   1572                 }
   1573                 else
   1574                 {
   1575                     /* Enable flush-mode and internal-flush once limit according to
   1576                     Eval-version is reached */
   1577                     ps_ctxt->i4_flush_mode_on = 1;
   1578                 }
   1579             }
   1580         }
   1581 
   1582         /* --------------------------------------------------------------------- */
   1583         /*            Wait and destroy Processing threads                        */
   1584         /* --------------------------------------------------------------------- */
   1585 
   1586         /* Wait for High level encoder thread to complete */
   1587         osal_thread_wait(ps_ctxt->pv_hle_thread_hdl);
   1588 
   1589         /* Destroy Hle thread */
   1590         osal_thread_destroy(ps_ctxt->pv_hle_thread_hdl);
   1591 
   1592         /* --------------------------------------------------------------------- */
   1593         /*            Input Output and Command buffers free                      */
   1594         /* --------------------------------------------------------------------- */
   1595 
   1596         /* free output data and control buffer */
   1597 
   1598         for(i4_res_id = 0; i4_res_id < i4_num_resolutions; i4_res_id++)
   1599         {
   1600             ai4_num_bitrate_instances[i4_res_id] =
   1601                 ps_ctxt->ps_static_cfg_prms->s_tgt_lyr_prms.as_tgt_params[i4_res_id]
   1602                     .i4_num_bitrate_instances;
   1603 
   1604             for(i4_br_id = 0; i4_br_id < ai4_num_bitrate_instances[i4_res_id]; i4_br_id++)
   1605             {
   1606                 mem_mngr_free(
   1607                     ps_app_ctxt->pv_mem_mngr_handle,
   1608                     &ps_ctxt->as_memtab_out_data_buf[i4_res_id][i4_br_id]);
   1609 
   1610                 /* free mutex of out strm buf b/w appln and encoder */
   1611                 osal_mutex_destroy(ps_app_ctxt->as_out_strm_prms[i4_res_id][i4_br_id]
   1612                                        .pv_app_out_strm_buf_mutex_hdl);
   1613 
   1614                 osal_cond_var_destroy(ps_app_ctxt->as_out_strm_prms[i4_res_id][i4_br_id]
   1615                                           .pv_app_out_strm_buf_cond_var_hdl);
   1616             }
   1617         }
   1618 
   1619         ps_ctxt->ihevce_mem_free(NULL, ps_ctxt->pu1_out_ctrl_buf);
   1620         ps_ctxt->ihevce_mem_free(NULL, ps_ctxt->pu1_inp_async_ctrl_buf);
   1621 
   1622         /* free input data and control buffer */
   1623         if(ps_interface_ctxt->i4_create_time_input_allocation == 1)
   1624         {
   1625             mem_mngr_free(ps_app_ctxt->pv_mem_mngr_handle, &ps_ctxt->s_memtab_inp_data_buf);
   1626             mem_mngr_free(ps_app_ctxt->pv_mem_mngr_handle, &ps_ctxt->s_memtab_inp_sync_ctrl_buf);
   1627         }
   1628 
   1629         /* --------------------------------------------------------------------- */
   1630         /*               Encoder Instance Deletion                               */
   1631         /* --------------------------------------------------------------------- */
   1632         ihevce_hle_interface_delete(ps_interface_ctxt);
   1633 
   1634         /* free the high level encoder context memory */
   1635         ps_ctxt->ihevce_mem_free(NULL, ps_ctxt->pv_hle_interface_ctxt);
   1636 
   1637         if(ps_ctxt->ps_static_cfg_prms->i4_enable_csv_dump)
   1638         {
   1639             ps_sys_api->s_file_io_api.ihevce_fclose(
   1640                 (void *)ps_sys_api->pv_cb_handle, ps_ctxt->ps_static_cfg_prms->apF_csv_file[0][0]);
   1641         }
   1642 
   1643         /* free static config memory */
   1644         ps_ctxt->ihevce_mem_free(NULL, ps_ctxt->ps_static_cfg_prms);
   1645 
   1646         /* free osal handle */
   1647         memory_free(NULL, ps_ctxt->pv_osal_handle);
   1648 
   1649         /* free plugin ctxt memory */
   1650         memory_free(NULL, pv_ihevce_hdl);
   1651     }
   1652     else
   1653     {
   1654         return (IHEVCE_EFAIL);
   1655     }
   1656 
   1657     return (IHEVCE_EOK);
   1658 }
   1659 
   1660 /*!
   1661 ******************************************************************************
   1662 * \if Function name : ihevce_copy_inp_8bit \endif
   1663 *
   1664 * \brief
   1665 *    Input copy function for 8 bit input
   1666 *
   1667 * \param[in] Source and desdtination buffer descriptors
   1668 *
   1669 * \return
   1670 *    None
   1671 *
   1672 * \author
   1673 *  Ittiam
   1674 *
   1675 *****************************************************************************
   1676 */
   1677 IV_API_CALL_STATUS_T ihevce_copy_inp_8bit(
   1678     iv_input_data_ctrl_buffs_t *ps_curr_inp,
   1679     ihevce_inp_buf_t *ps_inp,
   1680     WORD32 chroma_format,
   1681     WORD32 i4_orig_wd,
   1682     WORD32 i4_orig_ht)
   1683 {
   1684     UWORD8 *pu1_src, *pu1_dst;
   1685     WORD32 src_strd, dst_strd;
   1686     WORD32 frm_height = i4_orig_ht;
   1687     WORD32 frm_width = i4_orig_wd;
   1688     WORD32 buf_height = ps_curr_inp->s_input_buf.i4_y_ht;
   1689     WORD32 buf_width = ps_curr_inp->s_input_buf.i4_y_wd;
   1690     WORD32 rows, cols;
   1691 
   1692     pu1_src = (UWORD8 *)ps_inp->apv_inp_planes[0];
   1693     src_strd = ps_inp->ai4_inp_strd[0];
   1694     pu1_dst = (UWORD8 *)ps_curr_inp->s_input_buf.pv_y_buf;
   1695     dst_strd = ps_curr_inp->s_input_buf.i4_y_strd;
   1696 
   1697     if((ps_inp->ai4_inp_size[0] < (src_strd * frm_height)) || (ps_inp->ai4_inp_size[0] <= 0) ||
   1698        (ps_inp->apv_inp_planes[0] == NULL))
   1699     {
   1700         return (IV_FAIL);
   1701     }
   1702     /* copy the input luma data into internal buffer */
   1703     for(rows = 0; rows < frm_height; rows++)
   1704     {
   1705         memcpy(pu1_dst, pu1_src, frm_width);
   1706         if(buf_width > frm_width)
   1707         {
   1708             memset(pu1_dst + frm_width, 0x0, buf_width - frm_width);
   1709         }
   1710         pu1_src += src_strd;
   1711         pu1_dst += dst_strd;
   1712     }
   1713     while(rows < buf_height)
   1714     {
   1715         memset(pu1_dst, 0x0, buf_width);
   1716         pu1_dst += dst_strd;
   1717         rows++;
   1718     }
   1719 
   1720     if(IV_YUV_420P == chroma_format)
   1721     {
   1722         UWORD8 *pu1_src_u, *pu1_src_v;
   1723         WORD32 src_strd_u, src_strd_v;
   1724 
   1725         pu1_src_u = (UWORD8 *)ps_inp->apv_inp_planes[1];
   1726         src_strd_u = ps_inp->ai4_inp_strd[1];
   1727         pu1_src_v = (UWORD8 *)ps_inp->apv_inp_planes[2];
   1728         src_strd_v = ps_inp->ai4_inp_strd[2];
   1729         pu1_dst = (UWORD8 *)ps_curr_inp->s_input_buf.pv_u_buf;
   1730         dst_strd = ps_curr_inp->s_input_buf.i4_uv_strd;
   1731 
   1732         frm_width = i4_orig_wd >> 1;
   1733         frm_height = i4_orig_ht >> 1;
   1734         buf_width = ps_curr_inp->s_input_buf.i4_uv_wd;
   1735         buf_height = ps_curr_inp->s_input_buf.i4_uv_ht;
   1736 
   1737         if((ps_inp->ai4_inp_size[1] < (ps_inp->ai4_inp_strd[1] * frm_height)) ||
   1738            (ps_inp->ai4_inp_size[1] <= 0) || (pu1_src_u == NULL))
   1739         {
   1740             return (IV_FAIL);
   1741         }
   1742         if((ps_inp->ai4_inp_size[2] < (ps_inp->ai4_inp_strd[2] * frm_height)) ||
   1743            (ps_inp->ai4_inp_size[2] <= 0) || (pu1_src_v == NULL))
   1744         {
   1745             return (IV_FAIL);
   1746         }
   1747 
   1748         /* copy the input chroma data in pixel interleaved format */
   1749         for(rows = 0; rows < frm_height; rows++)
   1750         {
   1751             for(cols = 0; cols < frm_width; cols++)
   1752             {
   1753                 /* U V alternate */
   1754                 pu1_dst[(cols << 1)] = pu1_src_u[cols];
   1755                 pu1_dst[(cols << 1) + 1] = pu1_src_v[cols];
   1756             }
   1757             if(buf_width > (cols << 1))
   1758             {
   1759                 memset(&pu1_dst[(cols << 1)], 0x80, buf_width - (cols << 1));
   1760             }
   1761 
   1762             pu1_src_u += src_strd_u;
   1763             pu1_src_v += src_strd_v;
   1764             pu1_dst += dst_strd;
   1765         }
   1766         while(rows < buf_height)
   1767         {
   1768             memset(pu1_dst, 0x80, buf_width);
   1769 
   1770             pu1_dst += dst_strd;
   1771             rows++;
   1772         }
   1773     }
   1774     else if(IV_YUV_420SP_UV == chroma_format)
   1775     {
   1776         pu1_src = (UWORD8 *)ps_inp->apv_inp_planes[1];
   1777         src_strd = ps_inp->ai4_inp_strd[1];
   1778         pu1_dst = (UWORD8 *)ps_curr_inp->s_input_buf.pv_u_buf;
   1779         dst_strd = ps_curr_inp->s_input_buf.i4_uv_strd;
   1780 
   1781         frm_width = i4_orig_wd;
   1782         frm_height = i4_orig_ht >> 1;
   1783         buf_width = ps_curr_inp->s_input_buf.i4_uv_wd;
   1784         buf_height = ps_curr_inp->s_input_buf.i4_uv_ht;
   1785 
   1786         if((ps_inp->ai4_inp_size[1] < (ps_inp->ai4_inp_strd[1] * frm_height)) ||
   1787            (ps_inp->ai4_inp_size[1] <= 0) || (pu1_src == NULL))
   1788         {
   1789             return (IV_FAIL);
   1790         }
   1791 
   1792         /* copy the input luma data into internal buffer */
   1793         for(rows = 0; rows < frm_height; rows++)
   1794         {
   1795             memcpy(pu1_dst, pu1_src, frm_width);
   1796             if(buf_width > frm_width)
   1797             {
   1798                 memset(pu1_dst + frm_width, 0x80, buf_width - frm_width);
   1799             }
   1800             pu1_src += src_strd;
   1801             pu1_dst += dst_strd;
   1802         }
   1803         while(rows < buf_height)
   1804         {
   1805             memset(pu1_dst, 0x80, buf_width);
   1806             pu1_dst += dst_strd;
   1807             rows++;
   1808         }
   1809     }
   1810     return (IV_SUCCESS);
   1811 }
   1812 
   1813 /*!
   1814 ******************************************************************************
   1815 * \if Function name : ihevce_encode_header \endif
   1816 *
   1817 * \brief
   1818 *    Receive sps, pps and vps of the encoded sequence
   1819 *
   1820 * \param[in] Plugin handle, Output buffer
   1821 *
   1822 * \return
   1823 *    Success or Failure
   1824 *
   1825 * \author
   1826 *  Ittiam
   1827 *
   1828 *****************************************************************************
   1829 */
   1830 IHEVCE_PLUGIN_STATUS_T ihevce_encode_header(void *pv_ihevce_hdl, ihevce_out_buf_t *ps_out)
   1831 {
   1832     plugin_ctxt_t *ps_ctxt = (plugin_ctxt_t *)pv_ihevce_hdl;
   1833     ihevce_hle_ctxt_t *ps_interface_ctxt;
   1834 
   1835     /* sanity checks */
   1836     if(NULL == pv_ihevce_hdl)
   1837         return (IHEVCE_EFAIL);
   1838 
   1839     if(NULL == ps_out)
   1840         return (IHEVCE_EFAIL);
   1841 
   1842     if((0 == ps_ctxt->ps_static_cfg_prms->i4_res_id) &&
   1843        (0 == ps_ctxt->ps_static_cfg_prms->i4_br_id))
   1844     {
   1845         WORD32 status;
   1846 
   1847         /* ------- Que in free output buffer if end flag is not set ------ */
   1848         ihevce_queue_out_buffer(ps_ctxt, 0, 0);
   1849 
   1850         /* ------- API call to encoder header ------- */
   1851         ps_interface_ctxt = (ihevce_hle_ctxt_t *)ps_ctxt->pv_hle_interface_ctxt;
   1852         status = ihevce_entropy_encode_header(ps_interface_ctxt, 0, 0);
   1853         if(status)
   1854             return IHEVCE_EFAIL;
   1855 
   1856         /* ------- receive header ------- */
   1857         ihevce_receive_out_buffer(ps_ctxt, ps_out);
   1858     }
   1859     else
   1860     {
   1861         return (IHEVCE_EFAIL);
   1862     }
   1863 
   1864     return (IHEVCE_EOK);
   1865 }
   1866 
   1867 /*!
   1868 ******************************************************************************
   1869 * \if Function name : ihevce_encode \endif
   1870 *
   1871 * \brief
   1872 *    Frame level processing function
   1873 *
   1874 * \param[in] Plugin handle, Input buffer, Output buffer
   1875 *
   1876 * \return
   1877 *    Success or Failure
   1878 *
   1879 * \author
   1880 *  Ittiam
   1881 *
   1882 *****************************************************************************
   1883 */
   1884 IHEVCE_PLUGIN_STATUS_T
   1885     ihevce_encode(void *pv_ihevce_hdl, ihevce_inp_buf_t *ps_inp, ihevce_out_buf_t *ps_out)
   1886 {
   1887     /* local variables */
   1888     plugin_ctxt_t *ps_ctxt;
   1889     app_ctxt_t *ps_app_ctxt;
   1890     ihevce_hle_ctxt_t *ps_interface_ctxt;
   1891 
   1892     WORD32 i4_res_id, i4_br_id;
   1893     WORD32 i4_num_resolutions;
   1894     WORD32 ai4_num_bitrate_instances[IHEVCE_MAX_NUM_RESOLUTIONS] = { 1 };
   1895     UWORD32 u4_latency = 0;
   1896 
   1897     /* sanity checks */
   1898     if(NULL == pv_ihevce_hdl)
   1899         return (IHEVCE_EFAIL);
   1900 
   1901     if(NULL == ps_out)
   1902         return (IHEVCE_EFAIL);
   1903 
   1904     /* derive local variables */
   1905     ps_ctxt = (plugin_ctxt_t *)pv_ihevce_hdl;
   1906     if((0 == ps_ctxt->ps_static_cfg_prms->i4_res_id) &&
   1907        (0 == ps_ctxt->ps_static_cfg_prms->i4_br_id))
   1908     {
   1909         ps_interface_ctxt = (ihevce_hle_ctxt_t *)ps_ctxt->pv_hle_interface_ctxt;
   1910         ps_app_ctxt = &ps_ctxt->s_app_ctxt;
   1911         i4_num_resolutions = ps_ctxt->ps_static_cfg_prms->s_tgt_lyr_prms.i4_num_res_layers;
   1912 
   1913         if(ps_ctxt->ps_static_cfg_prms->s_coding_tools_prms.i4_max_temporal_layers)
   1914         {
   1915             u4_latency +=
   1916                 (1 << ps_ctxt->ps_static_cfg_prms->s_coding_tools_prms.i4_max_temporal_layers);
   1917         }
   1918 
   1919         u4_latency += ps_ctxt->ps_static_cfg_prms->s_lap_prms.i4_rc_look_ahead_pics;
   1920 
   1921         /* Once the internal-flush-flag has been set and codec has issued
   1922         end flag, exit encoding by returning IHEVCE_EFAIL */
   1923         if(ps_ctxt->i4_internal_flush)
   1924         {
   1925             if(1 == ps_app_ctxt->ai4_out_strm_end_flag[0][0])
   1926                 return (IHEVCE_EFAIL);
   1927         }
   1928 
   1929         for(i4_res_id = 0; i4_res_id < i4_num_resolutions; i4_res_id++)
   1930         {
   1931             ai4_num_bitrate_instances[i4_res_id] =
   1932                 ps_ctxt->ps_static_cfg_prms->s_tgt_lyr_prms.as_tgt_params[i4_res_id]
   1933                     .i4_num_bitrate_instances;
   1934             for(i4_br_id = 0; i4_br_id < ai4_num_bitrate_instances[i4_res_id]; i4_br_id++)
   1935             {
   1936                 /* ------- Que in free output buffer if end flag is not set ------ */
   1937                 ihevce_queue_out_buffer(ps_ctxt, i4_res_id, i4_br_id);
   1938             }
   1939         }
   1940 
   1941         /* --------------------------------------------------------------------- */
   1942         /*            Input Processing                                           */
   1943         /* --------------------------------------------------------------------- */
   1944         if(0 == ps_ctxt->i4_flush_mode_on)
   1945         {
   1946             WORD32 frm_stride;
   1947             WORD32 frm_width;
   1948             WORD32 frm_height;
   1949             WORD32 buf_id;
   1950 
   1951             iv_input_data_ctrl_buffs_t *ps_curr_inp;
   1952             WORD32 *pi4_ctrl_ptr;
   1953 
   1954             frm_width = ps_ctxt->ps_static_cfg_prms->s_src_prms.i4_width;
   1955             frm_height = ps_ctxt->ps_static_cfg_prms->s_src_prms.i4_height;
   1956             frm_stride = ps_ctxt->i4_frm_stride;
   1957 
   1958             /* ---------- get a free buffer from input Q ------ */
   1959             ps_curr_inp = (iv_input_data_ctrl_buffs_t *)ihevce_q_get_free_inp_data_buff(
   1960                 ps_interface_ctxt, &buf_id, BUFF_QUE_BLOCKING_MODE);
   1961 
   1962             if(NULL != ps_curr_inp)
   1963             {
   1964                 /* if input buffer is not NULL */
   1965                 if(NULL != ps_inp)
   1966                 {
   1967                     WORD32 result;
   1968 
   1969                     pi4_ctrl_ptr = (WORD32 *)ps_curr_inp->pv_synch_ctrl_bufs;
   1970 
   1971                     /* ---------- set ip params ---------- */
   1972                     ps_curr_inp->s_input_buf.i4_size = sizeof(iv_yuv_buf_t);
   1973                     ps_curr_inp->s_input_buf.i4_y_wd = frm_width;
   1974                     ps_curr_inp->s_input_buf.i4_y_ht = frm_height;
   1975                     ps_curr_inp->s_input_buf.i4_y_strd = frm_stride;
   1976                     ps_curr_inp->s_input_buf.i4_uv_wd = frm_width;
   1977                     ps_curr_inp->s_input_buf.i4_uv_ht =
   1978                         frm_height >>
   1979                         ((ps_ctxt->ps_static_cfg_prms->s_src_prms.inp_chr_format == 13) ? 0 : 1);
   1980                     ps_curr_inp->s_input_buf.i4_uv_strd = frm_stride;
   1981 
   1982                     ps_curr_inp->i4_buf_id = buf_id;
   1983                     ps_curr_inp->i4_inp_frm_data_valid_flag = 1;
   1984                     ps_curr_inp->i4_topfield_first = 1; /* set to default */
   1985                     ps_curr_inp->i4_bottom_field = ps_ctxt->i4_field_id;
   1986                     ps_curr_inp->i4_inp_timestamp_low = (WORD32)(ps_inp->u8_pts & 0xFFFFFFFF);
   1987                     ps_curr_inp->i4_inp_timestamp_high = (WORD32)(ps_inp->u8_pts >> 32);
   1988 
   1989                     /* toggle field id */
   1990                     ps_ctxt->i4_field_id = !ps_ctxt->i4_field_id;
   1991 
   1992                     /* set the cmd to NA */
   1993                     *pi4_ctrl_ptr = IHEVCE_SYNCH_API_END_TAG;
   1994 
   1995                     ps_curr_inp->i4_cmd_buf_size = 4; /* 4 bytes */
   1996 
   1997                     /* call the input copy function */
   1998                     result = ihevce_copy_inp_8bit(
   1999                         ps_curr_inp,
   2000                         ps_inp,
   2001                         ps_ctxt->ps_static_cfg_prms->s_src_prms.inp_chr_format,
   2002                         ps_ctxt->ps_static_cfg_prms->s_src_prms.i4_orig_width,
   2003                         ps_ctxt->ps_static_cfg_prms->s_src_prms.i4_orig_height);
   2004 
   2005                     if(IV_SUCCESS != result)
   2006                         return (IHEVCE_EFAIL);
   2007 
   2008                     if(3 != ps_ctxt->ps_static_cfg_prms->s_config_prms.i4_rate_control_mode)
   2009                     {
   2010                         /* Dynamic Change in bitrate not supported for multi res/MBR */
   2011                         /*** Check for change in bitrate command ***/
   2012                         if(ps_ctxt->ai4_old_bitrate[0][0] != ps_inp->i4_curr_bitrate)
   2013                         {
   2014                             WORD32 buf_id;
   2015                             WORD32 *pi4_cmd_buf;
   2016                             iv_input_ctrl_buffs_t *ps_ctrl_buf;
   2017                             ihevce_dyn_config_prms_t *ps_dyn_br;
   2018                             WORD32 codec_level_index = ihevce_get_level_index(
   2019                                 ps_ctxt->ps_static_cfg_prms->s_tgt_lyr_prms.as_tgt_params[0]
   2020                                     .i4_codec_level);
   2021                             WORD32 max_bitrate =
   2022                                 g_as_level_data[codec_level_index].i4_max_bit_rate
   2023                                     [ps_ctxt->ps_static_cfg_prms->s_out_strm_prms.i4_codec_tier] *
   2024                                 1000;
   2025 
   2026                             /* ---------- get a free buffer from command Q ------ */
   2027                             ps_ctrl_buf = (iv_input_ctrl_buffs_t *)ihevce_q_get_free_inp_ctrl_buff(
   2028                                 ps_interface_ctxt, &buf_id, BUFF_QUE_BLOCKING_MODE);
   2029                             /* store the buffer id */
   2030                             ps_ctrl_buf->i4_buf_id = buf_id;
   2031 
   2032                             /* get the buffer pointer */
   2033                             pi4_cmd_buf = (WORD32 *)ps_ctrl_buf->pv_asynch_ctrl_bufs;
   2034 
   2035                             /* store the set default command, encoder should use create time prms */
   2036                             *pi4_cmd_buf = IHEVCE_ASYNCH_API_SETBITRATE_TAG;
   2037                             *(pi4_cmd_buf + 1) = sizeof(ihevce_dyn_config_prms_t);
   2038 
   2039                             ps_dyn_br = (ihevce_dyn_config_prms_t *)(pi4_cmd_buf + 2);
   2040                             ps_dyn_br->i4_size = sizeof(ihevce_dyn_config_prms_t);
   2041                             ps_dyn_br->i4_tgt_br_id = 0;
   2042                             ps_dyn_br->i4_tgt_res_id = 0;
   2043                             ps_dyn_br->i4_new_tgt_bitrate =
   2044                                 MIN(ps_inp->i4_curr_bitrate, max_bitrate);
   2045                             ps_dyn_br->i4_new_peak_bitrate =
   2046                                 MIN((ps_dyn_br->i4_new_tgt_bitrate << 1), max_bitrate);
   2047 
   2048                             pi4_cmd_buf += 2;
   2049                             pi4_cmd_buf += (sizeof(ihevce_dyn_config_prms_t) >> 2);
   2050 
   2051                             *(pi4_cmd_buf) = IHEVCE_ASYNCH_API_END_TAG;
   2052 
   2053                             /* ---------- set the buffer as produced ---------- */
   2054                             ihevce_q_set_inp_ctrl_buff_prod(ps_interface_ctxt, buf_id);
   2055 
   2056                             ps_ctxt->ai4_old_bitrate[0][0] = ps_inp->i4_curr_bitrate;
   2057                         }
   2058                     }
   2059 
   2060                     ps_ctxt->u8_num_frames_queued++;
   2061                 }
   2062                 else
   2063                 { /* flush mode command */
   2064 
   2065                     ps_curr_inp->i4_buf_id = buf_id;
   2066 
   2067                     /* set the input status to invalid flag */
   2068                     ps_curr_inp->i4_inp_frm_data_valid_flag = 0;
   2069 
   2070                     pi4_ctrl_ptr = (WORD32 *)ps_curr_inp->pv_synch_ctrl_bufs;
   2071 
   2072                     *pi4_ctrl_ptr = IHEVCE_SYNCH_API_FLUSH_TAG;
   2073                     *(pi4_ctrl_ptr + 1) = 0;
   2074                     *(pi4_ctrl_ptr + 2) = IHEVCE_SYNCH_API_END_TAG;
   2075 
   2076                     ps_curr_inp->i4_cmd_buf_size = 4 * 3; /* 4 bytes */
   2077                 }
   2078 
   2079                 /* ---------- set the buffer as produced ---------- */
   2080                 ihevce_q_set_inp_data_buff_prod(ps_interface_ctxt, buf_id);
   2081                 ps_ctxt->u8_num_frames_encoded++;
   2082             }
   2083             else
   2084             {
   2085                 /* Enable flush-mode and internal-flush once limit according to
   2086                 Eval-version is reached */
   2087                 ps_ctxt->i4_flush_mode_on = 1;
   2088                 ps_ctxt->i4_internal_flush = 1;
   2089             }
   2090         }
   2091 
   2092         /* set encoder in flush mode if input buffer is NULL */
   2093         if(0 == ps_ctxt->i4_flush_mode_on)
   2094         {
   2095             if(NULL == ps_inp)
   2096             {
   2097                 ps_ctxt->i4_flush_mode_on = 1;
   2098             }
   2099         }
   2100 
   2101         if((u4_latency < ps_ctxt->u8_num_frames_queued) || (1 == ps_ctxt->i4_flush_mode_on))
   2102         {
   2103             /* --------------------------------------------------------------------- */
   2104             /*            Output Processing                                          */
   2105             /* --------------------------------------------------------------------- */
   2106             ihevce_receive_out_buffer(ps_ctxt, ps_out);
   2107         }
   2108     }
   2109     else  //Other bitrate and resolution instances
   2110     {
   2111         return IHEVCE_EFAIL;
   2112     }
   2113     return (IHEVCE_EOK);
   2114 }
   2115 
   2116