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