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