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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 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 */ 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 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 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 */ 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 */ 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 */ 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 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