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