• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /******************************************************************************
2  *
3  * Copyright (C) 2018 The Android Open Source Project
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at:
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  *****************************************************************************
18  * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
19 */
20 /*!
21 ******************************************************************************
22 * \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 */
mem_mngr_alloc(void * pv_handle,ihevce_sys_api_t * ps_sys_api,iv_mem_rec_t * ps_memtab)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 */
memory_alloc(void * pv_handle,UWORD32 u4_size)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 */
mem_mngr_free(void * pv_handle,iv_mem_rec_t * ps_memtab)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 */
memory_free(void * pv_handle,void * pv_mem)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 */
ihevce_set_def_params(ihevce_static_cfg_params_t * ps_params)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 */
ihevce_cmds_error_report(void * pv_cb_handle,WORD32 i4_error_code,WORD32 i4_cmd_type,WORD32 i4_buf_id)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
ihevce_strm_fill_done(void * pv_ctxt,void * pv_curr_out,WORD32 i4_br_id,WORD32 i4_res_id)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 */
ihevce_init(ihevce_static_cfg_params_t * ps_params,void ** ppv_ihevce_hdl)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
ihevce_receive_out_buffer(plugin_ctxt_t * ps_ctxt,ihevce_out_buf_t * ps_out)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
ihevce_queue_out_buffer(plugin_ctxt_t * ps_ctxt,WORD32 i4_res_id,WORD32 i4_br_id)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 */
ihevce_close(void * pv_ihevce_hdl)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 */
ihevce_copy_inp_8bit(iv_input_data_ctrl_buffs_t * ps_curr_inp,ihevce_inp_buf_t * ps_inp,WORD32 chroma_format,WORD32 i4_orig_wd,WORD32 i4_orig_ht)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 */
ihevce_encode_header(void * pv_ihevce_hdl,ihevce_out_buf_t * ps_out)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
ihevce_encode(void * pv_ihevce_hdl,ihevce_inp_buf_t * ps_inp,ihevce_out_buf_t * ps_out)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