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