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 ******************************************************************************
23 * \file ihevce_hle_interface.c
24 *
25 * \brief
26 * This file contains all the functions related High level encoder
27 * Interface layer
28 *
29 * \date
30 * 18/09/2012
31 *
32 * \author
33 * Ittiam
34 *
35 * List of Functions
36 * <TODO: TO BE ADDED>
37 *
38 ******************************************************************************
39 */
40
41 /*****************************************************************************/
42 /* File Includes */
43 /*****************************************************************************/
44 /* System include files */
45 #include <stdio.h>
46 #include <string.h>
47 #include <stdlib.h>
48 #include <assert.h>
49 #include <stdarg.h>
50 #include <math.h>
51 #include <time.h>
52
53 /* User include files */
54 #include "ihevc_typedefs.h"
55 #include "itt_video_api.h"
56 #include "ihevce_api.h"
57
58 #include "rc_cntrl_param.h"
59 #include "rc_frame_info_collector.h"
60 #include "rc_look_ahead_params.h"
61
62 #include "ihevc_defs.h"
63 #include "ihevc_macros.h"
64 #include "ihevc_debug.h"
65 #include "ihevc_structs.h"
66 #include "ihevc_platform_macros.h"
67 #include "ihevc_deblk.h"
68 #include "ihevc_itrans_recon.h"
69 #include "ihevc_chroma_itrans_recon.h"
70 #include "ihevc_chroma_intra_pred.h"
71 #include "ihevc_intra_pred.h"
72 #include "ihevc_inter_pred.h"
73 #include "ihevc_mem_fns.h"
74 #include "ihevc_padding.h"
75 #include "ihevc_weighted_pred.h"
76 #include "ihevc_sao.h"
77 #include "ihevc_resi_trans.h"
78 #include "ihevc_quant_iquant_ssd.h"
79 #include "ihevc_cabac_tables.h"
80 #include "ihevc_trans_tables.h"
81 #include "ihevc_trans_macros.h"
82
83 #include "ihevce_defs.h"
84 #include "ihevce_hle_interface.h"
85 #include "ihevce_hle_q_func.h"
86 #include "ihevce_buffer_que_interface.h"
87 #include "ihevce_lap_enc_structs.h"
88 #include "ihevce_multi_thrd_structs.h"
89 #include "ihevce_multi_thrd_funcs.h"
90 #include "ihevce_me_common_defs.h"
91 #include "ihevce_had_satd.h"
92 #include "ihevce_error_codes.h"
93 #include "ihevce_error_checks.h"
94 #include "ihevce_bitstream.h"
95 #include "ihevce_cabac.h"
96 #include "ihevce_rdoq_macros.h"
97 #include "ihevce_function_selector.h"
98 #include "ihevce_enc_structs.h"
99 #include "ihevce_cmn_utils_instr_set_router.h"
100 #include "ihevce_memory_init.h"
101 #include "ihevce_lap_interface.h"
102 #include "ihevce_entropy_cod.h"
103 #include "ihevce_entropy_structs.h"
104 #include "ihevce_frame_process_utils.h"
105 #include "ihevce_frame_process.h"
106 #include "ihevce_profile.h"
107 #include "ihevce_global_tables.h"
108 #include "ihevce_dep_mngr_interface.h"
109 #include "ihevce_common_utils.h"
110 #include "hme_datatype.h"
111 #include "hme_interface.h"
112 #include "hme_common_defs.h"
113 #include "hme_defs.h"
114 #include "ihevce_coarse_me_pass.h"
115 #include "ihevce_me_pass.h"
116 #include "ihevce_enc_loop_structs.h"
117 #include "ihevce_enc_loop_pass.h"
118
119 #include "cast_types.h"
120 #include "osal.h"
121 #include "osal_defaults.h"
122
123 /*****************************************************************************/
124 /* Function Definitions */
125 /*****************************************************************************/
126 /*!
127 ******************************************************************************
128 * \if Function name : ihevce_context_reset \endif
129 *
130 * \brief
131 * Encoder reset function
132 *
133 * \param[in] Encoder context pointer
134 *
135 * \return
136 * None
137 *
138 * \author
139 * Ittiam
140 *
141 *****************************************************************************
142 */
ihevce_context_reset(enc_ctxt_t * ps_enc_ctxt)143 void ihevce_context_reset(enc_ctxt_t *ps_enc_ctxt)
144 {
145 ps_enc_ctxt->i4_end_flag = 0;
146
147 /* set the queue related pointer and buffer to default value */
148 ps_enc_ctxt->s_enc_ques.pv_q_mutex_hdl = NULL;
149
150 /* Reset the i/o queues created status to 0 */
151 ps_enc_ctxt->i4_io_queues_created = 0;
152
153 /* reset the frame limit flag to 0 */
154 ps_enc_ctxt->i4_frame_limit_reached = 0;
155
156 return;
157 }
158
159 /*!
160 ******************************************************************************
161 * \if Function name : ihevce_hle_interface_create \endif
162 *
163 * \brief
164 * High level Encoder create function
165 *
166 * \param[in] High level encoder interface context pointer
167 *
168 * \return
169 * success or fail
170 *
171 * \author
172 * Ittiam
173 *
174 *****************************************************************************
175 */
ihevce_hle_interface_create(ihevce_hle_ctxt_t * ps_hle_ctxt)176 IV_API_CALL_STATUS_T ihevce_hle_interface_create(ihevce_hle_ctxt_t *ps_hle_ctxt)
177 {
178 /* local variables */
179 enc_ctxt_t *ps_enc_ctxt;
180 iv_mem_rec_t s_memtab;
181 ihevce_static_cfg_params_t *ps_enc_static_cfg_params;
182 WORD32 i4_num_resolutions = ps_hle_ctxt->ps_static_cfg_prms->s_tgt_lyr_prms.i4_num_res_layers;
183 WORD32 i4_look_ahead_frames_in_first_pass = -1;
184 WORD32 i4_total_cores = 0, ctr, i4_mres_flag = 0;
185 ihevce_sys_api_t *ps_sys_api = &ps_hle_ctxt->ps_static_cfg_prms->s_sys_api;
186
187 WORD32 status = 0;
188 WORD32 i;
189 WORD32 *pi4_active_res_id = NULL;
190
191 /* OSAL Init */
192 status = ihevce_osal_init((void *)ps_hle_ctxt);
193
194 if(status != 0)
195 return (IV_FAIL);
196
197 /* --------------------------------------------------------------------- */
198 /* High Level Encoder Init */
199 /* --------------------------------------------------------------------- */
200
201 if(i4_num_resolutions > 1)
202 i4_mres_flag = 1;
203 /* set no error in the output */
204 ps_hle_ctxt->i4_error_code = 0;
205
206 /* Error checks on the static parameters passed */
207 ps_hle_ctxt->i4_error_code = ihevce_hle_validate_static_params(ps_hle_ctxt->ps_static_cfg_prms);
208
209 /*memory for static cfg params for encoder, which can be overwritten if encoder wants
210 encoder should use this for all its usage*/
211 s_memtab.i4_size = sizeof(iv_mem_rec_t);
212 s_memtab.i4_mem_alignment = 4;
213 s_memtab.i4_mem_size = sizeof(ihevce_static_cfg_params_t);
214 s_memtab.e_mem_type = IV_EXT_CACHEABLE_NORMAL_MEM;
215
216 ps_hle_ctxt->ihevce_mem_alloc(
217 ps_hle_ctxt->pv_mem_mgr_hdl, &ps_hle_ctxt->ps_static_cfg_prms->s_sys_api, &s_memtab);
218 if(s_memtab.pv_base == NULL)
219 {
220 return (IV_FAIL);
221 }
222 ps_enc_static_cfg_params = (ihevce_static_cfg_params_t *)s_memtab.pv_base;
223 memcpy(
224 ps_enc_static_cfg_params,
225 ps_hle_ctxt->ps_static_cfg_prms,
226 (sizeof(ihevce_static_cfg_params_t)));
227
228 i4_total_cores = ps_enc_static_cfg_params->s_multi_thrd_prms.i4_max_num_cores;
229
230 /* check for validity of memory control flag (only 0,1,2 modes are allowed) */
231 if((ps_enc_static_cfg_params->s_multi_thrd_prms.i4_memory_alloc_ctrl_flag > 2) ||
232 (ps_enc_static_cfg_params->s_multi_thrd_prms.i4_memory_alloc_ctrl_flag < 0))
233 {
234 ps_hle_ctxt->i4_error_code = IHEVCE_INVALID_MEM_CTRL_FLAG;
235 }
236
237 if((i4_mres_flag == 1) &&
238 (ps_enc_static_cfg_params->s_multi_thrd_prms.i4_use_thrd_affinity == 1))
239 {
240 ps_sys_api->ihevce_printf(
241 ps_sys_api->pv_cb_handle,
242 "\nIHEVCE WARNING: Enabling thread affinity in multiresolution encoding will affect "
243 "performance\n");
244 }
245 if((ps_enc_static_cfg_params->s_tgt_lyr_prms.as_tgt_params[0].i4_quality_preset ==
246 IHEVCE_QUALITY_P6) &&
247 (ps_enc_static_cfg_params->s_config_prms.i4_cu_level_rc))
248 {
249 ps_sys_api->ihevce_printf(
250 ps_sys_api->pv_cb_handle,
251 "\nIHEVCE WARNING: Disabling CU level QP modulation for P6 preset\n");
252 ps_enc_static_cfg_params->s_config_prms.i4_cu_level_rc = 0;
253 }
254 if((ps_enc_static_cfg_params->s_tgt_lyr_prms.as_tgt_params[0].i4_quality_preset ==
255 IHEVCE_QUALITY_P7) &&
256 (ps_enc_static_cfg_params->s_config_prms.i4_cu_level_rc))
257 {
258 ps_sys_api->ihevce_printf(
259 ps_sys_api->pv_cb_handle,
260 "\nIHEVCE WARNING: Disabling CU level QP modulation for P7 preset\n");
261 ps_enc_static_cfg_params->s_config_prms.i4_cu_level_rc = 0;
262 }
263
264 if(0 != ps_hle_ctxt->i4_error_code)
265 {
266 ps_hle_ctxt->ihevce_mem_free(ps_hle_ctxt->pv_mem_mgr_hdl, &s_memtab);
267 return (IV_FAIL);
268 }
269 ps_hle_ctxt->ai4_num_core_per_res[0] = i4_total_cores;
270
271 if(1 == ps_enc_static_cfg_params->s_tgt_lyr_prms.i4_mres_single_out)
272 {
273 /* Memory Allocation of pi4_active_res_id */
274 s_memtab.i4_size = sizeof(iv_mem_rec_t);
275 s_memtab.i4_mem_alignment = 4;
276 s_memtab.i4_mem_size = sizeof(WORD32) * (IHEVCE_MAX_NUM_RESOLUTIONS + 1);
277 s_memtab.e_mem_type = IV_EXT_CACHEABLE_NORMAL_MEM;
278
279 ps_hle_ctxt->ihevce_mem_alloc(
280 ps_hle_ctxt->pv_mem_mgr_hdl, &ps_enc_static_cfg_params->s_sys_api, &s_memtab);
281 if(s_memtab.pv_base == NULL)
282 {
283 return (IV_FAIL);
284 }
285
286 pi4_active_res_id = (WORD32 *)s_memtab.pv_base;
287 }
288 /* --------------------------------------------------------------------- */
289 /* Context and Memory Initialization of Encoder ctxt */
290 /* --------------------------------------------------------------------- */
291 for(ctr = 0; ctr < i4_num_resolutions; ctr++)
292 {
293 WORD32 i4_br_id;
294 s_memtab.i4_size = sizeof(iv_mem_rec_t);
295 s_memtab.i4_mem_alignment = 4;
296 s_memtab.i4_mem_size = sizeof(enc_ctxt_t);
297 s_memtab.e_mem_type = IV_EXT_CACHEABLE_NORMAL_MEM;
298
299 ps_hle_ctxt->ihevce_mem_alloc(
300 ps_hle_ctxt->pv_mem_mgr_hdl, &ps_enc_static_cfg_params->s_sys_api, &s_memtab);
301 if(s_memtab.pv_base == NULL)
302 {
303 return (IV_FAIL);
304 }
305
306 ps_enc_ctxt = (enc_ctxt_t *)s_memtab.pv_base;
307
308 ps_enc_ctxt->ps_stat_prms = ps_enc_static_cfg_params;
309
310 /* check of number of cores to decide the num threads active */
311 ps_enc_ctxt->s_multi_thrd.i4_all_thrds_active_flag = 1;
312
313 if(1 == ps_enc_static_cfg_params->s_tgt_lyr_prms.i4_mres_single_out)
314 {
315 pi4_active_res_id[ctr] = 0;
316 ps_enc_ctxt->s_multi_thrd.pi4_active_res_id = pi4_active_res_id;
317 }
318
319 /*store num bit-rate instances in the encoder context */
320 ps_enc_ctxt->i4_num_bitrates =
321 ps_enc_static_cfg_params->s_tgt_lyr_prms.as_tgt_params[ctr].i4_num_bitrate_instances;
322 if(BLU_RAY_SUPPORT == ps_enc_static_cfg_params->s_out_strm_prms.i4_interop_flags)
323 {
324 ps_enc_ctxt->i4_blu_ray_spec = 1;
325 }
326 else
327 {
328 ps_enc_ctxt->i4_blu_ray_spec = 0;
329 }
330
331 /* if all threads are required to be active */
332 if(1 == ps_enc_ctxt->s_multi_thrd.i4_all_thrds_active_flag)
333 {
334 /* store the number of threads to be created as passed by app with HT flag */
335 ps_enc_ctxt->s_multi_thrd.i4_num_enc_proc_thrds =
336 ps_hle_ctxt->ai4_num_core_per_res[ctr];
337
338 /* pre enc threads are doubled if HT is ON */
339 ps_enc_ctxt->s_multi_thrd.i4_num_pre_enc_proc_thrds =
340 ps_hle_ctxt->ai4_num_core_per_res[ctr];
341 }
342 else
343 {
344 // TODO: distribute threads across stages
345 }
346
347 /*Keep track of resolution id, this is used to differentiate from other encoder instance*/
348 ps_enc_ctxt->i4_resolution_id = ctr;
349 /* store hle ctxt in enc ctxt */
350 ps_enc_ctxt->pv_hle_ctxt = (void *)ps_hle_ctxt;
351 ps_enc_ctxt->pv_rc_mutex_lock_hdl = NULL;
352 ps_enc_ctxt->s_multi_thrd.pv_sub_pic_rc_mutex_lock_hdl = NULL;
353 ps_enc_ctxt->s_multi_thrd.pv_sub_pic_rc_for_qp_update_mutex_lock_hdl = NULL;
354 ps_enc_ctxt->i4_look_ahead_frames_in_first_pass = i4_look_ahead_frames_in_first_pass;
355
356 ps_enc_ctxt->ai4_is_past_pic_complex[0] = 0;
357 ps_enc_ctxt->ai4_is_past_pic_complex[1] = 0;
358 ps_enc_ctxt->i4_is_I_reset_done = 1;
359 ps_enc_ctxt->i4_past_RC_reset_count = 0;
360 ps_enc_ctxt->i4_future_RC_reset = 0;
361 ps_enc_ctxt->i4_past_RC_scd_reset_count = 0;
362 ps_enc_ctxt->i4_future_RC_scd_reset = 0;
363 ps_enc_ctxt->i4_active_scene_num = -1;
364 for(i = 0; i < IHEVCE_MAX_NUM_BITRATES; i++)
365 {
366 ps_enc_ctxt->ai4_rc_query[i] = 0;
367 }
368 ps_enc_ctxt->i4_active_enc_frame_id = 0;
369 ps_enc_ctxt->u1_is_popcnt_available = 1;
370
371 #ifndef ARM
372 ps_enc_ctxt->e_arch_type = ARCH_X86_GENERIC;
373 ps_enc_ctxt->u1_is_popcnt_available = 0;
374 #else
375 if(ps_enc_static_cfg_params->e_arch_type == ARCH_NA)
376 ps_enc_ctxt->e_arch_type = ihevce_default_arch();
377 else
378 ps_enc_ctxt->e_arch_type = ps_enc_static_cfg_params->e_arch_type;
379 ps_enc_ctxt->u1_is_popcnt_available = 0;
380 #endif
381
382 {
383 ps_enc_static_cfg_params->e_arch_type = ps_enc_ctxt->e_arch_type;
384
385 ihevce_init_function_ptr(ps_enc_ctxt, ps_enc_ctxt->e_arch_type);
386 }
387
388 ihevce_mem_manager_init(ps_enc_ctxt, ps_hle_ctxt);
389
390 if(0 != ps_hle_ctxt->i4_error_code)
391 {
392 return (IV_FAIL);
393 }
394
395 /* mutex lock for RC calls */
396 ps_enc_ctxt->pv_rc_mutex_lock_hdl = osal_mutex_create(ps_hle_ctxt->pv_osal_handle);
397 if(NULL == ps_enc_ctxt->pv_rc_mutex_lock_hdl)
398 {
399 return IV_FAIL;
400 }
401
402 /* mutex lock for Sub pic RC calls */
403 ps_enc_ctxt->s_multi_thrd.pv_sub_pic_rc_mutex_lock_hdl =
404 osal_mutex_create(ps_hle_ctxt->pv_osal_handle);
405 if(NULL == ps_enc_ctxt->s_multi_thrd.pv_sub_pic_rc_mutex_lock_hdl)
406 {
407 return IV_FAIL;
408 }
409
410 ps_enc_ctxt->s_multi_thrd.pv_sub_pic_rc_for_qp_update_mutex_lock_hdl =
411 osal_mutex_create(ps_hle_ctxt->pv_osal_handle);
412 if(NULL == ps_enc_ctxt->s_multi_thrd.pv_sub_pic_rc_for_qp_update_mutex_lock_hdl)
413 {
414 return IV_FAIL;
415 }
416
417 /* reset the encoder context */
418 ihevce_context_reset(ps_enc_ctxt);
419
420 /* register the Encoder context in HLE interface ctxt */
421 ps_hle_ctxt->apv_enc_hdl[ctr] = ps_enc_ctxt;
422 }
423 /* init profile */
424 PROFILE_INIT(&ps_hle_ctxt->profile_hle);
425 for(ctr = 0; ctr < i4_num_resolutions; ctr++)
426 {
427 WORD32 i4_br_id;
428
429 PROFILE_INIT(&ps_hle_ctxt->profile_enc_me[ctr]);
430 PROFILE_INIT(&ps_hle_ctxt->profile_pre_enc_l1l2[ctr]);
431 PROFILE_INIT(&ps_hle_ctxt->profile_pre_enc_l0ipe[ctr]);
432 for(i4_br_id = 0; i4_br_id < ps_enc_ctxt->i4_num_bitrates; i4_br_id++)
433 {
434 PROFILE_INIT(&ps_hle_ctxt->profile_enc[ctr][i4_br_id]);
435 PROFILE_INIT(&ps_hle_ctxt->profile_entropy[ctr][i4_br_id]);
436 }
437 }
438 if(1 == ps_enc_static_cfg_params->s_tgt_lyr_prms.i4_mres_single_out)
439 pi4_active_res_id[i4_num_resolutions] = 0;
440
441 return (IV_SUCCESS);
442 }
443
444 /*!
445 ******************************************************************************
446 * \if Function name : ihevce_query_io_buf_req \endif
447 *
448 * \brief
449 * High level Encoder IO buffers query function
450 *
451 * \param[in] High level encoder interface context pointer
452 * \param[out] Input buffer requirment stucture pointer.
453 * \param[out] Output buffer requirment stucture pointer.
454 *
455 * \return
456 * success or fail
457 *
458 * \author
459 * Ittiam
460 *
461 *****************************************************************************
462 */
ihevce_query_io_buf_req(ihevce_hle_ctxt_t * ps_hle_ctxt,iv_input_bufs_req_t * ps_input_bufs_req,iv_res_layer_output_bufs_req_t * ps_res_layer_output_bufs_req,iv_res_layer_recon_bufs_req_t * ps_res_layer_recon_bufs_req)463 IV_API_CALL_STATUS_T ihevce_query_io_buf_req(
464 ihevce_hle_ctxt_t *ps_hle_ctxt,
465 iv_input_bufs_req_t *ps_input_bufs_req,
466 iv_res_layer_output_bufs_req_t *ps_res_layer_output_bufs_req,
467 iv_res_layer_recon_bufs_req_t *ps_res_layer_recon_bufs_req)
468 {
469 /* local variables */
470 enc_ctxt_t *ps_enc_ctxt;
471 ihevce_src_params_t *ps_src_prms;
472 WORD32 ctb_align_pic_wd;
473 WORD32 ctb_align_pic_ht, i4_resolution_id = 0, i4_num_resolutions, i4_num_bitrate_instances;
474 WORD32 i4_resolution_id_ctr, br_ctr;
475
476 ps_enc_ctxt = (enc_ctxt_t *)ps_hle_ctxt->apv_enc_hdl[i4_resolution_id];
477 ps_src_prms = &ps_hle_ctxt->ps_static_cfg_prms->s_src_prms;
478 i4_num_resolutions = ps_hle_ctxt->ps_static_cfg_prms->s_tgt_lyr_prms.i4_num_res_layers;
479 /* set no error in the output */
480 ps_hle_ctxt->i4_error_code = 0;
481
482 /* ------- populate the Input buffer requirements -------- */
483 /* get the number of buffers required for LAP */
484 ps_input_bufs_req->i4_min_num_yuv_bufs =
485 ihevce_lap_get_num_ip_bufs(&ps_enc_ctxt->s_lap_stat_prms);
486
487 ps_input_bufs_req->i4_min_num_synch_ctrl_bufs = ps_input_bufs_req->i4_min_num_yuv_bufs;
488
489 ps_input_bufs_req->i4_min_num_asynch_ctrl_bufs = NUM_AYSNC_CMD_BUFS;
490
491 /* buffer sizes are populated based on create time parameters */
492 ctb_align_pic_wd =
493 ps_src_prms->i4_width +
494 SET_CTB_ALIGN(ps_src_prms->i4_width, ps_enc_ctxt->s_frm_ctb_prms.i4_ctb_size);
495
496 ctb_align_pic_ht =
497 ps_src_prms->i4_height +
498 SET_CTB_ALIGN(ps_src_prms->i4_height, ps_enc_ctxt->s_frm_ctb_prms.i4_ctb_size);
499
500 if(ps_src_prms->i4_input_bit_depth > 8)
501 {
502 ps_input_bufs_req->i4_min_size_y_buf = ctb_align_pic_wd * ctb_align_pic_ht * 2;
503
504 ps_input_bufs_req->i4_min_size_uv_buf = ps_input_bufs_req->i4_min_size_y_buf >> 1;
505 }
506 else
507 {
508 ps_input_bufs_req->i4_min_size_y_buf = ctb_align_pic_wd * ctb_align_pic_ht;
509
510 ps_input_bufs_req->i4_min_size_uv_buf = (ctb_align_pic_wd * ctb_align_pic_ht) >> 1;
511 }
512
513 ps_input_bufs_req->i4_min_size_uv_buf <<=
514 ((ps_src_prms->i4_chr_format == IV_YUV_422SP_UV) ? 1 : 0);
515
516 ps_input_bufs_req->i4_yuv_format = ps_src_prms->i4_chr_format;
517
518 #ifndef DISABLE_SEI
519 ps_input_bufs_req->i4_min_size_synch_ctrl_bufs =
520 ((MAX_SEI_PAYLOAD_PER_TLV + 16) * MAX_NUMBER_OF_SEI_PAYLOAD) + 16;
521
522 ps_input_bufs_req->i4_min_size_asynch_ctrl_bufs =
523 ((MAX_SEI_PAYLOAD_PER_TLV + 16) * (MAX_NUMBER_OF_SEI_PAYLOAD - 6)) + 16;
524 #else
525 ps_input_bufs_req->i4_min_size_synch_ctrl_bufs = 16;
526 ps_input_bufs_req->i4_min_size_asynch_ctrl_bufs = 16;
527 #endif
528
529 for(i4_resolution_id_ctr = 0; i4_resolution_id_ctr < i4_num_resolutions; i4_resolution_id_ctr++)
530 {
531 ps_enc_ctxt = (enc_ctxt_t *)ps_hle_ctxt->apv_enc_hdl[i4_resolution_id_ctr];
532
533 i4_num_bitrate_instances = ps_enc_ctxt->s_runtime_tgt_params.i4_num_bitrate_instances;
534
535 /* buffer sizes are populated based on create time parameters */
536 ctb_align_pic_wd = ps_enc_ctxt->s_runtime_tgt_params.i4_width +
537 SET_CTB_ALIGN(
538 ps_enc_ctxt->s_runtime_tgt_params.i4_width,
539 ps_enc_ctxt->s_frm_ctb_prms.i4_ctb_size);
540
541 ctb_align_pic_ht = ps_enc_ctxt->s_runtime_tgt_params.i4_height +
542 SET_CTB_ALIGN(
543 ps_enc_ctxt->s_runtime_tgt_params.i4_height,
544 ps_enc_ctxt->s_frm_ctb_prms.i4_ctb_size);
545
546 for(br_ctr = 0; br_ctr < i4_num_bitrate_instances; br_ctr++)
547 {
548 /* ------- populate the Output buffer requirements -------- */
549 ps_res_layer_output_bufs_req->s_output_buf_req[i4_resolution_id_ctr][br_ctr]
550 .i4_min_num_out_bufs = NUM_OUTPUT_BUFS;
551
552 ps_res_layer_output_bufs_req->s_output_buf_req[i4_resolution_id_ctr][br_ctr]
553 .i4_min_size_bitstream_buf = (ctb_align_pic_wd * ctb_align_pic_ht);
554
555 if((ps_hle_ctxt->ps_static_cfg_prms->s_tgt_lyr_prms.i4_internal_bit_depth == 12) ||
556 ((ps_hle_ctxt->ps_static_cfg_prms->s_tgt_lyr_prms.i4_internal_bit_depth > 8) &&
557 (ps_src_prms->i4_chr_format == IV_YUV_422SP_UV)))
558 {
559 ps_res_layer_output_bufs_req->s_output_buf_req[i4_resolution_id_ctr][br_ctr]
560 .i4_min_size_bitstream_buf *= 2;
561 }
562
563 if((ps_hle_ctxt->ps_static_cfg_prms->s_tgt_lyr_prms.i4_internal_bit_depth == 10) &&
564 (ps_src_prms->i4_chr_format == IV_YUV_420SP_UV))
565 {
566 ps_res_layer_output_bufs_req->s_output_buf_req[i4_resolution_id_ctr][br_ctr]
567 .i4_min_size_bitstream_buf *= 3;
568 ps_res_layer_output_bufs_req->s_output_buf_req[i4_resolution_id_ctr][br_ctr]
569 .i4_min_size_bitstream_buf >>= 1;
570 }
571
572 //recon_dump
573 /* ------- populate the Recon buffer requirements -------- */
574 if(ps_enc_ctxt->ps_stat_prms->i4_save_recon == 0)
575 {
576 ps_res_layer_recon_bufs_req->s_recon_buf_req[i4_resolution_id_ctr][br_ctr]
577 .i4_min_num_recon_bufs = 0;
578
579 ps_res_layer_recon_bufs_req->s_recon_buf_req[i4_resolution_id_ctr][br_ctr]
580 .i4_min_size_y_buf = 0;
581
582 ps_res_layer_recon_bufs_req->s_recon_buf_req[i4_resolution_id_ctr][br_ctr]
583 .i4_min_size_uv_buf = 0;
584 }
585 else
586 {
587 ps_res_layer_recon_bufs_req->s_recon_buf_req[i4_resolution_id_ctr][br_ctr]
588 .i4_min_num_recon_bufs = 2 * HEVCE_MAX_REF_PICS + 1;
589
590 ps_res_layer_recon_bufs_req->s_recon_buf_req[i4_resolution_id_ctr][br_ctr]
591 .i4_min_size_y_buf =
592 ctb_align_pic_wd * ctb_align_pic_ht *
593 ((ps_hle_ctxt->ps_static_cfg_prms->s_tgt_lyr_prms.i4_internal_bit_depth > 8)
594 ? 2
595 : 1);
596
597 ps_res_layer_recon_bufs_req->s_recon_buf_req[i4_resolution_id_ctr][br_ctr]
598 .i4_min_size_uv_buf =
599 (ps_res_layer_recon_bufs_req->s_recon_buf_req[i4_resolution_id_ctr][br_ctr]
600 .i4_min_size_y_buf >>
601 1);
602 ps_res_layer_recon_bufs_req->s_recon_buf_req[i4_resolution_id_ctr][br_ctr]
603 .i4_min_size_uv_buf <<=
604 ((ps_src_prms->i4_chr_format == IV_YUV_422SP_UV) ? 1 : 0);
605 }
606 }
607 }
608
609 return (IV_SUCCESS);
610 }
611
612 /*!
613 ******************************************************************************
614 * \if Function name : ihevce_create_ports \endif
615 *
616 * \brief
617 * High level Encoder IO ports Create function
618 *
619 * \param[in] High level encoder interface context pointer
620 * \param[in] Input data buffer descriptor
621 * \param[in] Input control buffer descriptor
622 * \param[in] Output data buffer descriptor
623 * \param[in] Output control status buffer descriptor
624 * \param[out] Pointer to store the ID for Input data Que
625 * \param[out] Pointer to store the ID for Input control Que
626 * \param[out] Pointer to store the ID for Output data Que
627 * \param[out] Pointer to store the ID for Output control status Que
628 *
629 * \return
630 * success or fail
631 *
632 * \author
633 * Ittiam
634 *
635 *****************************************************************************
636 */
ihevce_create_ports(ihevce_hle_ctxt_t * ps_hle_ctxt,iv_input_data_ctrl_buffs_desc_t * ps_input_data_ctrl_buffs_desc,iv_input_asynch_ctrl_buffs_desc_t * ps_input_asynch_ctrl_buffs_desc,iv_res_layer_output_data_buffs_desc_t * ps_mres_output_data_buffs_desc,iv_res_layer_recon_data_buffs_desc_t * ps_mres_recon_data_buffs_desc)637 IV_API_CALL_STATUS_T ihevce_create_ports(
638 ihevce_hle_ctxt_t *ps_hle_ctxt,
639 iv_input_data_ctrl_buffs_desc_t *ps_input_data_ctrl_buffs_desc,
640 iv_input_asynch_ctrl_buffs_desc_t *ps_input_asynch_ctrl_buffs_desc,
641 iv_res_layer_output_data_buffs_desc_t *ps_mres_output_data_buffs_desc,
642 iv_res_layer_recon_data_buffs_desc_t *ps_mres_recon_data_buffs_desc)
643 {
644 /* local varaibles */
645 enc_ctxt_t *ps_enc_ctxt;
646 WORD32 res_ctr,
647 i4_num_resolutions = ps_hle_ctxt->ps_static_cfg_prms->s_tgt_lyr_prms.i4_num_res_layers;
648 void *pv_q_mutex_hdl = NULL;
649
650 /* set no error in the output */
651 ps_hle_ctxt->i4_error_code = 0;
652
653 for(res_ctr = 0; res_ctr < i4_num_resolutions; res_ctr++)
654 {
655 ps_enc_ctxt = (enc_ctxt_t *)ps_hle_ctxt->apv_enc_hdl[res_ctr];
656 /* check on buffer sizes provided by applciation needs to be checked */
657
658 /* call the memory manager que init function , pass the op data , status, recon for the first bitrate, internally we will increment*/
659 ihevce_mem_manager_que_init(
660 ps_enc_ctxt,
661 ps_hle_ctxt,
662 ps_input_data_ctrl_buffs_desc,
663 ps_input_asynch_ctrl_buffs_desc,
664 &ps_mres_output_data_buffs_desc->s_output_data_buffs[res_ctr][0],
665 &ps_mres_recon_data_buffs_desc->s_recon_data_buffs[res_ctr][0]);
666
667 /* set the number of Queues */
668 ps_enc_ctxt->s_enc_ques.i4_num_queues = IHEVCE_MAX_NUM_QUEUES;
669
670 /* allocate a mutex to take care of handling multiple threads accesing Queues */
671 /*my understanding, this is common semaphore for all the queue. Since main input is still
672 common across all instance fo encoder. Hence common semaphore is a must*/
673 if(0 == res_ctr)
674 {
675 ps_enc_ctxt->s_enc_ques.pv_q_mutex_hdl = osal_mutex_create(ps_hle_ctxt->pv_osal_handle);
676 /* store it in local variable for allocating it to other instances */
677 pv_q_mutex_hdl = ps_enc_ctxt->s_enc_ques.pv_q_mutex_hdl;
678 if(NULL == pv_q_mutex_hdl)
679 {
680 return IV_FAIL;
681 }
682 }
683 else
684 {
685 ps_enc_ctxt->s_enc_ques.pv_q_mutex_hdl = pv_q_mutex_hdl;
686 }
687
688 /* Set the i/o queues created status to 1 */
689 ps_enc_ctxt->i4_io_queues_created = 1;
690 }
691 return (IV_SUCCESS);
692 }
693
694 /*!
695 ******************************************************************************
696 * \if Function name : ihevce_hle_interface_thrd \endif
697 *
698 * \brief
699 * High level encoder thread interface function
700 *
701 * \param[in] High level interface context pointer
702 *
703 * \return
704 * None
705 *
706 * \author
707 * Ittiam
708 *
709 *****************************************************************************
710 */
ihevce_hle_interface_thrd(void * pv_proc_intf_ctxt)711 WORD32 ihevce_hle_interface_thrd(void *pv_proc_intf_ctxt)
712 {
713 /* local variables */
714 WORD32 ctr, res_ctr;
715 ihevce_hle_ctxt_t *ps_hle_ctxt;
716 enc_ctxt_t *ps_enc_ctxt;
717 /* enc ctxt to store 0th instance's params which are required by all instances */
718 enc_ctxt_t *ps_enc_ctxt_base;
719 void *pv_lap_sem_hdl;
720 void *pv_enc_frame_process_sem_hdl;
721 void *pv_pre_enc_frame_process_sem_hdl;
722 void *apv_ent_coding_sem_hdl[IHEVCE_MAX_NUM_BITRATES];
723 void *pv_ent_common_mres_sem_hdl = NULL;
724 void *pv_out_common_mres_sem_hdl = NULL;
725
726 void *pv_inp_data_sem_hdl;
727 void *pv_lap_inp_data_sem_hdl;
728 void *pv_preenc_inp_data_sem_hdl;
729 void *pv_inp_ctrl_sem_hdl;
730 void *apv_out_stream_sem_hdl[IHEVCE_MAX_NUM_BITRATES];
731 void *apv_out_recon_sem_hdl[IHEVCE_MAX_NUM_BITRATES];
732 void *pv_out_ctrl_sts_sem_hdl;
733
734 lap_intface_t *ps_lap_interface_ctxt;
735 iv_mem_rec_t s_memtab;
736 WORD32 i4_num_bit_rate_instances[IHEVCE_MAX_NUM_RESOLUTIONS], i4_num_resolutions;
737 WORD32 i; //loop variable
738 WORD32 ai4_proc_count[MAX_NUMBER_PROC_GRPS] = { 0 }, i4_proc_grp_count;
739 WORD32 i4_acc_proc_num = 0;
740
741 /* Frame Encode processing threads & semaphores */
742 void *apv_enc_frm_proc_hdls[IHEVCE_MAX_NUM_RESOLUTIONS][MAX_NUM_FRM_PROC_THRDS_ENC];
743 frm_proc_thrd_ctxt_t
744 *aps_enc_frm_proc_thrd_ctxt[IHEVCE_MAX_NUM_RESOLUTIONS][MAX_NUM_FRM_PROC_THRDS_ENC];
745
746 /* Pre Frame Encode processing threads & semaphores */
747 void *apv_pre_enc_frm_proc_hdls[IHEVCE_MAX_NUM_RESOLUTIONS][MAX_NUM_FRM_PROC_THRDS_PRE_ENC];
748 frm_proc_thrd_ctxt_t
749 *aps_pre_enc_frm_proc_thrd_ctxt[IHEVCE_MAX_NUM_RESOLUTIONS][MAX_NUM_FRM_PROC_THRDS_PRE_ENC];
750
751 void *apv_entropy_thrd_hdls[IHEVCE_MAX_NUM_RESOLUTIONS][NUM_ENTROPY_THREADS];
752 frm_proc_thrd_ctxt_t *aps_entropy_thrd_ctxt[IHEVCE_MAX_NUM_RESOLUTIONS][NUM_ENTROPY_THREADS];
753
754 ps_hle_ctxt = (ihevce_hle_ctxt_t *)pv_proc_intf_ctxt;
755 ps_enc_ctxt_base = (enc_ctxt_t *)ps_hle_ctxt->apv_enc_hdl[0];
756 /* profile start */
757 PROFILE_START(&ps_hle_ctxt->profile_hle);
758 /* store default values of mem tab */
759 s_memtab.i4_size = sizeof(iv_mem_rec_t);
760 s_memtab.i4_mem_alignment = 4;
761
762 i4_num_resolutions = ps_enc_ctxt_base->ps_stat_prms->s_tgt_lyr_prms.i4_num_res_layers;
763 memset(
764 apv_entropy_thrd_hdls,
765 0,
766 IHEVCE_MAX_NUM_RESOLUTIONS * NUM_ENTROPY_THREADS * sizeof(void *));
767 memset(
768 apv_entropy_thrd_hdls,
769 0,
770 IHEVCE_MAX_NUM_RESOLUTIONS * NUM_ENTROPY_THREADS * sizeof(void *));
771 for(res_ctr = 0; res_ctr < i4_num_resolutions; res_ctr++)
772 {
773 i4_num_bit_rate_instances[res_ctr] =
774 ps_enc_ctxt_base->ps_stat_prms->s_tgt_lyr_prms.as_tgt_params[res_ctr]
775 .i4_num_bitrate_instances;
776 }
777 /* --------------------------------------------------------------------- */
778 /* Init number of threads for each stage */
779 /* --------------------------------------------------------------------- */
780
781 {
782 for(res_ctr = 0; res_ctr < i4_num_resolutions; res_ctr++)
783 {
784 ps_enc_ctxt = (enc_ctxt_t *)ps_hle_ctxt->apv_enc_hdl[res_ctr];
785 /* all the threads created will be made active */
786 ps_enc_ctxt->s_multi_thrd.i4_num_active_enc_thrds =
787 ps_enc_ctxt->s_multi_thrd.i4_num_enc_proc_thrds;
788
789 ps_enc_ctxt->s_multi_thrd.i4_num_active_pre_enc_thrds =
790 ps_enc_ctxt->s_multi_thrd.i4_num_pre_enc_proc_thrds;
791 }
792 }
793
794 /* --------------------------------------------------------------------- */
795 /* Multiple processing Threads Semaphores init */
796 /* --------------------------------------------------------------------- */
797 for(res_ctr = 0; res_ctr < i4_num_resolutions; res_ctr++)
798 {
799 osal_sem_attr_t attr = OSAL_DEFAULT_SEM_ATTR;
800
801 ps_enc_ctxt = (enc_ctxt_t *)ps_hle_ctxt->apv_enc_hdl[res_ctr];
802
803 attr.value = SEM_START_VALUE;
804
805 /* Create Semaphore handle for LAP thread */
806 if(0 == ps_enc_ctxt->i4_resolution_id)
807 {
808 pv_lap_sem_hdl = osal_sem_create(ps_hle_ctxt->pv_osal_handle, &attr);
809 if(NULL == pv_lap_sem_hdl)
810 {
811 return IV_FAIL;
812 }
813 }
814 else
815 {
816 /*NOTE: Tile workspace assigned this to null. Confirm this*/
817 pv_lap_sem_hdl = ps_enc_ctxt_base->s_thrd_sem_ctxt.pv_lap_sem_handle;
818 }
819 /* Create Semaphore for encode frame process thread */
820 pv_enc_frame_process_sem_hdl = osal_sem_create(ps_hle_ctxt->pv_osal_handle, &attr);
821 if(NULL == pv_enc_frame_process_sem_hdl)
822 {
823 return IV_FAIL;
824 }
825
826 /* Create Semaphore for pre_encode frame process thread */
827 pv_pre_enc_frame_process_sem_hdl = osal_sem_create(ps_hle_ctxt->pv_osal_handle, &attr);
828 if(NULL == pv_pre_enc_frame_process_sem_hdl)
829 {
830 return IV_FAIL;
831 }
832
833 /* Create Semaphore for input frame data q function */
834 if(0 == ps_enc_ctxt->i4_resolution_id)
835 {
836 pv_inp_data_sem_hdl = osal_sem_create(ps_hle_ctxt->pv_osal_handle, &attr);
837 if(NULL == pv_inp_data_sem_hdl)
838 {
839 return IV_FAIL;
840 }
841 }
842 else
843 {
844 pv_inp_data_sem_hdl = ps_enc_ctxt_base->s_thrd_sem_ctxt.pv_inp_data_sem_handle;
845 }
846
847 /*creating new input queue owned by encoder*/
848 /* Create Semaphore for input frame data q function */
849 pv_lap_inp_data_sem_hdl = osal_sem_create(ps_hle_ctxt->pv_osal_handle, &attr);
850 if(NULL == pv_lap_inp_data_sem_hdl)
851 {
852 return IV_FAIL;
853 }
854
855 /* Create Semaphore for input frame data q function */
856 pv_preenc_inp_data_sem_hdl = osal_sem_create(ps_hle_ctxt->pv_osal_handle, &attr);
857 if(NULL == pv_preenc_inp_data_sem_hdl)
858 {
859 return IV_FAIL;
860 }
861
862 /* Create Semaphore for input conrol data q function */
863 if(0 == ps_enc_ctxt->i4_resolution_id)
864 {
865 pv_inp_ctrl_sem_hdl = osal_sem_create(ps_hle_ctxt->pv_osal_handle, &attr);
866 if(NULL == pv_inp_ctrl_sem_hdl)
867 {
868 return IV_FAIL;
869 }
870 }
871 else
872 { /*Inp ctrl queue is same for all resolutions between app and lap*/
873 pv_inp_ctrl_sem_hdl = ps_enc_ctxt_base->s_thrd_sem_ctxt.pv_inp_ctrl_sem_handle;
874 }
875
876 /* Create Semaphore for output control status data q function */
877 pv_out_ctrl_sts_sem_hdl = osal_sem_create(ps_hle_ctxt->pv_osal_handle, &attr);
878 if(NULL == pv_out_ctrl_sts_sem_hdl)
879 {
880 return IV_FAIL;
881 }
882
883 /* Multi res single output case singel output queue is used for all output resolutions */
884 if(1 == ps_enc_ctxt_base->ps_stat_prms->s_tgt_lyr_prms.i4_mres_single_out)
885 {
886 ps_enc_ctxt->s_enc_ques.apv_q_hdl[IHEVCE_OUTPUT_DATA_Q] =
887 ps_enc_ctxt_base->s_enc_ques.apv_q_hdl[IHEVCE_OUTPUT_DATA_Q];
888 if(0 == ps_enc_ctxt->i4_resolution_id)
889 {
890 /* Create Semaphore for enropy coding thread */
891 pv_ent_common_mres_sem_hdl = osal_sem_create(ps_hle_ctxt->pv_osal_handle, &attr);
892 if(NULL == pv_ent_common_mres_sem_hdl)
893 {
894 return IV_FAIL;
895 }
896
897 /* Create Semaphore for output stream data q function */
898 pv_out_common_mres_sem_hdl = osal_sem_create(ps_hle_ctxt->pv_osal_handle, &attr);
899 if(NULL == pv_out_common_mres_sem_hdl)
900 {
901 return IV_FAIL;
902 }
903 }
904 ps_enc_ctxt->s_thrd_sem_ctxt.pv_ent_common_mres_sem_hdl = pv_ent_common_mres_sem_hdl;
905 ps_enc_ctxt->s_thrd_sem_ctxt.pv_out_common_mres_sem_hdl = pv_out_common_mres_sem_hdl;
906 }
907
908 /*create entropy and output semaphores for each thread.
909 Each thread will correspond to each bit-rate instance running */
910 for(i = 0; i < i4_num_bit_rate_instances[res_ctr]; i++)
911 {
912 /* Create Semaphore for enropy coding thread */
913 apv_ent_coding_sem_hdl[i] = osal_sem_create(ps_hle_ctxt->pv_osal_handle, &attr);
914 if(NULL == apv_ent_coding_sem_hdl[i])
915 {
916 return IV_FAIL;
917 }
918
919 /* Create Semaphore for output stream data q function */
920 apv_out_stream_sem_hdl[i] = osal_sem_create(ps_hle_ctxt->pv_osal_handle, &attr);
921 if(NULL == apv_out_stream_sem_hdl[i])
922 {
923 return IV_FAIL;
924 }
925
926 /* Create Semaphore for output recon data q function */
927 apv_out_recon_sem_hdl[i] = osal_sem_create(ps_hle_ctxt->pv_osal_handle, &attr);
928 if(NULL == apv_out_recon_sem_hdl[i])
929 {
930 return IV_FAIL;
931 }
932 }
933
934 /* update the semaphore handles and the thread creates status */
935
936 ps_enc_ctxt->s_thrd_sem_ctxt.pv_enc_frm_proc_sem_handle = pv_enc_frame_process_sem_hdl;
937 ps_enc_ctxt->s_thrd_sem_ctxt.pv_pre_enc_frm_proc_sem_handle =
938 pv_pre_enc_frame_process_sem_hdl;
939 ps_enc_ctxt->s_thrd_sem_ctxt.pv_lap_sem_handle = pv_lap_sem_hdl;
940 ps_enc_ctxt->s_thrd_sem_ctxt.pv_inp_data_sem_handle = pv_inp_data_sem_hdl;
941 ps_enc_ctxt->s_thrd_sem_ctxt.pv_lap_inp_data_sem_hdl = pv_lap_inp_data_sem_hdl;
942 ps_enc_ctxt->s_thrd_sem_ctxt.pv_preenc_inp_data_sem_hdl = pv_preenc_inp_data_sem_hdl;
943 ps_enc_ctxt->s_thrd_sem_ctxt.pv_inp_ctrl_sem_handle = pv_inp_ctrl_sem_hdl;
944 ps_enc_ctxt->s_thrd_sem_ctxt.pv_out_ctrl_sem_handle = pv_out_ctrl_sts_sem_hdl;
945 for(i = 0; i < i4_num_bit_rate_instances[res_ctr]; i++)
946 {
947 ps_enc_ctxt->s_thrd_sem_ctxt.apv_ent_cod_sem_handle[i] = apv_ent_coding_sem_hdl[i];
948 ps_enc_ctxt->s_thrd_sem_ctxt.apv_out_strm_sem_handle[i] = apv_out_stream_sem_hdl[i];
949 ps_enc_ctxt->s_thrd_sem_ctxt.apv_out_recon_sem_handle[i] = apv_out_recon_sem_hdl[i];
950 }
951 }
952
953 /* --------------------------------------------------------------------- */
954 /* Multiple processing Threads Mutex init */
955 /* --------------------------------------------------------------------- */
956 for(res_ctr = 0; res_ctr < i4_num_resolutions; res_ctr++)
957 {
958 ps_enc_ctxt = (enc_ctxt_t *)ps_hle_ctxt->apv_enc_hdl[res_ctr];
959
960 /* create a mutex lock for Job Queue access accross slave threads of encode frame processing */
961 ps_enc_ctxt->s_multi_thrd.pv_job_q_mutex_hdl_enc_grp_me =
962 osal_mutex_create(ps_hle_ctxt->pv_osal_handle);
963 if(NULL == ps_enc_ctxt->s_multi_thrd.pv_job_q_mutex_hdl_enc_grp_me)
964 {
965 return IV_FAIL;
966 }
967
968 /* create a mutex lock for Job Queue access accross slave threads of encode frame processing */
969 ps_enc_ctxt->s_multi_thrd.pv_job_q_mutex_hdl_enc_grp_enc_loop =
970 osal_mutex_create(ps_hle_ctxt->pv_osal_handle);
971 if(NULL == ps_enc_ctxt->s_multi_thrd.pv_job_q_mutex_hdl_enc_grp_enc_loop)
972 {
973 return IV_FAIL;
974 }
975
976 /* create mutex for enc thread group */
977 for(i = 0; i < MAX_NUM_ME_PARALLEL; i++)
978 {
979 ps_enc_ctxt->s_multi_thrd.apv_mutex_handle[i] =
980 osal_mutex_create(ps_hle_ctxt->pv_osal_handle);
981 if(NULL == ps_enc_ctxt->s_multi_thrd.apv_mutex_handle[i])
982 {
983 return IV_FAIL;
984 }
985
986 ps_enc_ctxt->s_multi_thrd.apv_mutex_handle_me_end[i] =
987 osal_mutex_create(ps_hle_ctxt->pv_osal_handle);
988 if(NULL == ps_enc_ctxt->s_multi_thrd.apv_mutex_handle_me_end[i])
989 {
990 return IV_FAIL;
991 }
992 }
993
994 for(i = 0; i < MAX_NUM_ENC_LOOP_PARALLEL; i++)
995 {
996 ps_enc_ctxt->s_multi_thrd.apv_post_enc_mutex_handle[i] =
997 osal_mutex_create(ps_hle_ctxt->pv_osal_handle);
998 if(NULL == ps_enc_ctxt->s_multi_thrd.apv_post_enc_mutex_handle[i])
999 {
1000 return IV_FAIL;
1001 }
1002
1003 ps_enc_ctxt->s_multi_thrd.apv_mutex_handle_frame_init[i] =
1004 osal_mutex_create(ps_hle_ctxt->pv_osal_handle);
1005 if(NULL == ps_enc_ctxt->s_multi_thrd.apv_mutex_handle_frame_init[i])
1006 {
1007 return IV_FAIL;
1008 }
1009 }
1010
1011 /*initialize mutex for pre-enc group */
1012 ps_enc_ctxt->s_multi_thrd.pv_mutex_hdl_pre_enc_init =
1013 osal_mutex_create(ps_hle_ctxt->pv_osal_handle);
1014
1015 ps_enc_ctxt->s_multi_thrd.pv_mutex_hdl_pre_enc_decomp_deinit =
1016 osal_mutex_create(ps_hle_ctxt->pv_osal_handle);
1017
1018 ps_enc_ctxt->s_multi_thrd.pv_mutex_hdl_pre_enc_hme_init =
1019 osal_mutex_create(ps_hle_ctxt->pv_osal_handle);
1020
1021 ps_enc_ctxt->s_multi_thrd.pv_mutex_hdl_pre_enc_hme_deinit =
1022 osal_mutex_create(ps_hle_ctxt->pv_osal_handle);
1023
1024 ps_enc_ctxt->s_multi_thrd.pv_mutex_hdl_pre_enc_deinit =
1025 osal_mutex_create(ps_hle_ctxt->pv_osal_handle);
1026
1027 ps_enc_ctxt->s_multi_thrd.pv_mutex_hdl_l0_ipe_init =
1028 osal_mutex_create(ps_hle_ctxt->pv_osal_handle);
1029
1030 ps_enc_ctxt->s_multi_thrd.pv_job_q_mutex_hdl_pre_enc_decomp =
1031 osal_mutex_create(ps_hle_ctxt->pv_osal_handle);
1032
1033 ps_enc_ctxt->s_multi_thrd.pv_job_q_mutex_hdl_pre_enc_hme =
1034 osal_mutex_create(ps_hle_ctxt->pv_osal_handle);
1035
1036 ps_enc_ctxt->s_multi_thrd.pv_job_q_mutex_hdl_pre_enc_l0ipe =
1037 osal_mutex_create(ps_hle_ctxt->pv_osal_handle);
1038
1039 if(NULL == ps_enc_ctxt->s_multi_thrd.pv_mutex_hdl_pre_enc_init ||
1040 NULL == ps_enc_ctxt->s_multi_thrd.pv_mutex_hdl_pre_enc_decomp_deinit ||
1041 NULL == ps_enc_ctxt->s_multi_thrd.pv_mutex_hdl_pre_enc_hme_init ||
1042 NULL == ps_enc_ctxt->s_multi_thrd.pv_mutex_hdl_pre_enc_hme_deinit ||
1043 NULL == ps_enc_ctxt->s_multi_thrd.pv_mutex_hdl_pre_enc_deinit ||
1044 NULL == ps_enc_ctxt->s_multi_thrd.pv_mutex_hdl_l0_ipe_init ||
1045 NULL == ps_enc_ctxt->s_multi_thrd.pv_job_q_mutex_hdl_pre_enc_decomp ||
1046 NULL == ps_enc_ctxt->s_multi_thrd.pv_job_q_mutex_hdl_pre_enc_hme ||
1047 NULL == ps_enc_ctxt->s_multi_thrd.pv_job_q_mutex_hdl_pre_enc_l0ipe)
1048 {
1049 return IV_FAIL;
1050 }
1051 }
1052
1053 /* --------------------------------------------------------------------- */
1054 /* Multiple processing Threads Context init */
1055 /* --------------------------------------------------------------------- */
1056
1057 for(res_ctr = 0; res_ctr < i4_num_resolutions; res_ctr++)
1058 {
1059 ps_enc_ctxt = (enc_ctxt_t *)ps_hle_ctxt->apv_enc_hdl[res_ctr];
1060 ps_enc_ctxt_base = (enc_ctxt_t *)ps_hle_ctxt->apv_enc_hdl[0];
1061
1062 /*initialize multi-thread context for enc group*/
1063 ps_enc_ctxt->s_multi_thrd.i4_is_recon_free_done = 0;
1064 ps_enc_ctxt->s_multi_thrd.i4_idx_dvsr_p = 0;
1065 ps_enc_ctxt->s_multi_thrd.i4_last_inp_buf = 0;
1066
1067 {
1068 /* For all the ME frames in Parallel */
1069 WORD32 i4_frm_idx;
1070
1071 for(i4_frm_idx = 0; i4_frm_idx < MAX_NUM_ME_PARALLEL; i4_frm_idx++)
1072 {
1073 ps_enc_ctxt->s_multi_thrd.me_num_thrds_exited[i4_frm_idx] = 0;
1074 ps_enc_ctxt->s_multi_thrd.ai4_me_master_done_flag[i4_frm_idx] = 0;
1075 ps_enc_ctxt->s_multi_thrd.ai4_me_enc_buff_prod_flag[i4_frm_idx] = 0;
1076 }
1077 }
1078
1079 {
1080 WORD32 i4_frm_idx;
1081 ps_enc_ctxt->s_multi_thrd.num_thrds_done = 0;
1082 ps_enc_ctxt->s_multi_thrd.num_thrds_exited_for_reenc = 0;
1083 for(i4_frm_idx = 0; i4_frm_idx < MAX_NUM_ENC_LOOP_PARALLEL; i4_frm_idx++)
1084 {
1085 ps_enc_ctxt->s_multi_thrd.num_thrds_exited[i4_frm_idx] = 0;
1086
1087 ps_enc_ctxt->s_multi_thrd.enc_master_done_frame_init[i4_frm_idx] = 0;
1088
1089 for(i = 0; i < i4_num_bit_rate_instances[res_ctr]; i++)
1090 {
1091 /*reset the entropy buffer produced status */
1092 ps_enc_ctxt->s_multi_thrd.ai4_produce_outbuf[i4_frm_idx][i] = 1;
1093 ps_enc_ctxt->s_multi_thrd.ps_frm_recon[i4_frm_idx][i] = NULL;
1094
1095 ps_enc_ctxt->s_multi_thrd.ps_curr_out_enc_grp[i4_frm_idx][i] = NULL;
1096 }
1097 }
1098 }
1099 ps_enc_ctxt->s_multi_thrd.i4_seq_mode_enabled_flag = 0;
1100
1101 /* Set prev_frame_done = 1 to indicate that all the threads are in same frame*/
1102 for(i = 0; i < ps_enc_ctxt->s_multi_thrd.i4_num_enc_loop_frm_pllel; i++)
1103 {
1104 ihevce_dmgr_set_done_frm_frm_sync(
1105 ps_enc_ctxt->s_multi_thrd.apv_dep_mngr_prev_frame_done[i]);
1106 }
1107 /* Set prev_frame_done = 1 to indicate that all the threads are in same frame*/
1108 ihevce_dmgr_set_done_frm_frm_sync(
1109 ps_enc_ctxt->s_multi_thrd.pv_dep_mngr_prev_frame_enc_done_for_reenc);
1110 /*to enable the dependency manager to wait when first reached*/
1111 ihevce_dmgr_set_prev_done_frm_frm_sync(
1112 ps_enc_ctxt->s_multi_thrd.pv_dep_mngr_prev_frame_enc_done_for_reenc);
1113 for(i = 0; i < ps_enc_ctxt->s_multi_thrd.i4_num_me_frm_pllel; i++)
1114 {
1115 ihevce_dmgr_set_done_frm_frm_sync(
1116 ps_enc_ctxt->s_multi_thrd.apv_dep_mngr_prev_frame_me_done[i]);
1117 }
1118
1119 /* initialize multi-thread context for pre enc group */
1120
1121 ps_enc_ctxt->s_multi_thrd.i4_ctrl_blocking_mode = BUFF_QUE_BLOCKING_MODE;
1122
1123 for(ctr = 0; ctr < MAX_PRE_ENC_STAGGER + NUM_BUFS_DECOMP_HME; ctr++)
1124 {
1125 ps_enc_ctxt->s_multi_thrd.ai4_pre_enc_init_done[ctr] = 0;
1126 ps_enc_ctxt->s_multi_thrd.ai4_pre_enc_hme_init_done[ctr] = 0;
1127 ps_enc_ctxt->s_multi_thrd.ai4_pre_enc_deinit_done[ctr] = 1;
1128 ps_enc_ctxt->s_multi_thrd.ai4_num_thrds_processed_decomp[ctr] = 0;
1129 ps_enc_ctxt->s_multi_thrd.ai4_num_thrds_processed_coarse_me[ctr] = 0;
1130 ps_enc_ctxt->s_multi_thrd.ai4_num_thrds_processed_pre_enc[ctr] = 0;
1131
1132 ps_enc_ctxt->s_multi_thrd.ai4_num_thrds_processed_L0_ipe_qp_init[ctr] = 0;
1133 ps_enc_ctxt->s_multi_thrd.ai4_decomp_coarse_me_complete_flag[ctr] = 1;
1134 ps_enc_ctxt->s_multi_thrd.ai4_end_flag_pre_enc[ctr] = 0;
1135 }
1136
1137 /* Set prev_frame_done = 1 to indicate that all the threads are in same frame*/
1138 ihevce_dmgr_set_done_frm_frm_sync(
1139 ps_enc_ctxt->s_multi_thrd.pv_dep_mngr_prev_frame_pre_enc_l1);
1140
1141 ihevce_dmgr_set_done_frm_frm_sync(
1142 ps_enc_ctxt->s_multi_thrd.pv_dep_mngr_prev_frame_pre_enc_coarse_me);
1143
1144 ihevce_dmgr_set_done_frm_frm_sync(
1145 ps_enc_ctxt->s_multi_thrd.pv_dep_mngr_prev_frame_pre_enc_l0);
1146
1147 {
1148 /**init idx for handling delay between pre-me and l0-ipe*/
1149 ps_enc_ctxt->s_multi_thrd.i4_delay_pre_me_btw_l0_ipe = 0;
1150 ps_enc_ctxt->s_multi_thrd.i4_max_delay_pre_me_btw_l0_ipe =
1151 MIN_L1_L0_STAGGER_NON_SEQ +
1152 ps_enc_ctxt->s_lap_stat_prms.s_lap_params.i4_rc_look_ahead_pics + 1;
1153 if(ps_enc_ctxt->s_lap_stat_prms.s_lap_params.i4_rc_look_ahead_pics)
1154 {
1155 ps_enc_ctxt->s_multi_thrd.i4_delay_pre_me_btw_l0_ipe =
1156 MIN_L1_L0_STAGGER_NON_SEQ +
1157 ps_enc_ctxt->s_lap_stat_prms.s_lap_params.i4_rc_look_ahead_pics;
1158 }
1159 ps_enc_ctxt->s_multi_thrd.i4_qp_update_l0_ipe = -1;
1160 }
1161 }
1162
1163 /** Get Number of Processor Groups **/
1164 i4_proc_grp_count = ps_enc_ctxt_base->ps_stat_prms->s_multi_thrd_prms.i4_num_proc_groups;
1165 /*** Enc threads are allocated based on the assumption that there can be only 2 processor groups **/
1166 ASSERT(i4_proc_grp_count <= MAX_NUMBER_PROC_GRPS);
1167 /** Get Number of logical processors in Each Group **/
1168 for(ctr = 0; ctr < i4_proc_grp_count; ctr++)
1169 {
1170 ai4_proc_count[ctr] =
1171 ps_enc_ctxt_base->ps_stat_prms->s_multi_thrd_prms.ai4_num_cores_per_grp[ctr];
1172 }
1173
1174 /* --------------------------------------------------------------------- */
1175 /* Create a LAP thread */
1176 /* --------------------------------------------------------------------- */
1177 /* LAP thread will run on 0th resolution instance context */
1178 {
1179 s_memtab.e_mem_type = IV_EXT_CACHEABLE_NORMAL_MEM;
1180 s_memtab.i4_mem_size = sizeof(lap_intface_t);
1181
1182 /* initialise the interface strucure parameters */
1183 ps_hle_ctxt->ihevce_mem_alloc(
1184 ps_hle_ctxt->pv_mem_mgr_hdl, &ps_enc_ctxt_base->ps_stat_prms->s_sys_api, &s_memtab);
1185 if(s_memtab.pv_base == NULL)
1186 {
1187 return (IV_FAIL);
1188 }
1189
1190 ps_lap_interface_ctxt = (lap_intface_t *)s_memtab.pv_base;
1191
1192 /* populate the params */
1193 ps_lap_interface_ctxt->pv_hle_ctxt = ps_hle_ctxt;
1194 ps_enc_ctxt = (enc_ctxt_t *)ps_hle_ctxt->apv_enc_hdl[0];
1195 ps_lap_interface_ctxt->pv_lap_module_ctxt = ps_enc_ctxt->s_module_ctxt.pv_lap_ctxt;
1196 ps_lap_interface_ctxt->i4_ctrl_in_que_id = IHEVCE_INPUT_ASYNCH_CTRL_Q;
1197 ps_lap_interface_ctxt->i4_ctrl_out_que_id = IHEVCE_OUTPUT_STATUS_Q;
1198 ps_lap_interface_ctxt->i4_ctrl_cmd_buf_size = ENC_COMMAND_BUFF_SIZE;
1199 ps_lap_interface_ctxt->i4_ctrl_in_que_blocking_mode = BUFF_QUE_BLOCKING_MODE;
1200 ps_lap_interface_ctxt->ps_sys_api = &ps_enc_ctxt_base->ps_stat_prms->s_sys_api;
1201 ps_enc_ctxt_base->pv_lap_interface_ctxt = (void *)ps_lap_interface_ctxt;
1202 ps_lap_interface_ctxt->ihevce_dyn_bitrate_cb = ihevce_dyn_bitrate;
1203 }
1204
1205 /* --------------------------------------------------------------------- */
1206 /* Create Entropy Coding threads */
1207 /* --------------------------------------------------------------------- */
1208 /*Create entropy thread for each encoder instance*/
1209 for(res_ctr = 0; res_ctr < i4_num_resolutions; res_ctr++)
1210 {
1211 osal_thread_attr_t s_thread_attr = OSAL_DEFAULT_THREAD_ATTR;
1212 WORD32 i4_num_entropy_threads;
1213
1214 /* derive encoder ctxt from hle handle */
1215 ps_enc_ctxt = (enc_ctxt_t *)ps_hle_ctxt->apv_enc_hdl[res_ctr];
1216
1217 i4_num_entropy_threads =
1218 ps_enc_ctxt_base->ps_stat_prms->s_tgt_lyr_prms.as_tgt_params[res_ctr]
1219 .i4_num_bitrate_instances;
1220
1221 /* initialise the interface strucure parameters */
1222 for(ctr = 0; ctr < i4_num_entropy_threads; ctr++)
1223 {
1224 s_memtab.e_mem_type = IV_EXT_CACHEABLE_NORMAL_MEM;
1225 s_memtab.i4_mem_size = sizeof(frm_proc_thrd_ctxt_t);
1226
1227 ps_hle_ctxt->ihevce_mem_alloc(
1228 ps_hle_ctxt->pv_mem_mgr_hdl, &ps_enc_ctxt_base->ps_stat_prms->s_sys_api, &s_memtab);
1229 if(s_memtab.pv_base == NULL)
1230 {
1231 return (IV_FAIL);
1232 }
1233
1234 aps_entropy_thrd_ctxt[res_ctr][ctr] = (frm_proc_thrd_ctxt_t *)s_memtab.pv_base;
1235
1236 /* initialise the interface strucure parameters */
1237 aps_entropy_thrd_ctxt[res_ctr][ctr]->i4_thrd_id = ctr;
1238 aps_entropy_thrd_ctxt[res_ctr][ctr]->ps_hle_ctxt = ps_hle_ctxt;
1239 aps_entropy_thrd_ctxt[res_ctr][ctr]->pv_enc_ctxt = (void *)ps_enc_ctxt;
1240
1241 /* Initialize application thread attributes */
1242 s_thread_attr.exit_code = 0;
1243 s_thread_attr.name = 0;
1244 s_thread_attr.priority_map_flag = 1;
1245 s_thread_attr.priority = OSAL_PRIORITY_DEFAULT;
1246 s_thread_attr.stack_addr = 0;
1247 s_thread_attr.stack_size = THREAD_STACK_SIZE;
1248 s_thread_attr.thread_func = ihevce_ent_coding_thrd;
1249 s_thread_attr.thread_param =
1250 (void *)(aps_entropy_thrd_ctxt[res_ctr]
1251 [ctr]); //encioder and hle context are derived from this
1252 s_thread_attr.core_affinity_mask = 0;
1253 if(ps_enc_ctxt_base->ps_stat_prms->s_multi_thrd_prms.i4_num_proc_groups > 1)
1254 {
1255 /* Run ENTROPY thread on last group if there are more than one processor group */
1256 s_thread_attr.group_num =
1257 ps_hle_ctxt->ps_static_cfg_prms->s_multi_thrd_prms.i4_num_proc_groups - 1;
1258 }
1259 else
1260 {
1261 s_thread_attr.group_num = 0;
1262 }
1263
1264 /* Create entropy coding thread */
1265 apv_entropy_thrd_hdls[res_ctr][ctr] =
1266 osal_thread_create(ps_hle_ctxt->pv_osal_handle, &s_thread_attr);
1267 if(NULL == apv_entropy_thrd_hdls[res_ctr][ctr])
1268 {
1269 return IV_FAIL;
1270 }
1271 }
1272 }
1273
1274 /* --------------------------------------------------------------------- */
1275 /* Create all Slave Encode Frame processing threads */
1276 /* - -------------------------------------------------------------------- */
1277 for(res_ctr = 0; res_ctr < i4_num_resolutions; res_ctr++)
1278 {
1279 WORD32 enc_ctr = 0;
1280 WORD32 i4_loop_count;
1281 WORD32 i4_curr_grp_num = 0;
1282 ps_enc_ctxt = (enc_ctxt_t *)ps_hle_ctxt->apv_enc_hdl[res_ctr];
1283
1284 i4_acc_proc_num = 0;
1285 /* Calculate the start core number of enc threads for current resolution */
1286 for(i4_loop_count = 0; i4_loop_count < res_ctr; i4_loop_count++)
1287 {
1288 /* Add number of cores taken by each resolution till the curr resolution */
1289 enc_ctr += ps_hle_ctxt->ai4_num_core_per_res[i4_loop_count];
1290 }
1291 if(ps_enc_ctxt_base->ps_stat_prms->s_multi_thrd_prms.i4_num_proc_groups > 1)
1292 {
1293 /* Select the group number for each res based on processors present in each group */
1294 for(i4_loop_count = 0;
1295 i4_loop_count <
1296 ps_enc_ctxt_base->ps_stat_prms->s_multi_thrd_prms.i4_num_proc_groups;
1297 i4_loop_count++)
1298 {
1299 i4_acc_proc_num += ai4_proc_count[i4_loop_count];
1300 if(enc_ctr >= i4_acc_proc_num)
1301 {
1302 /* if enc_ctr is greater than proc count for first group,
1303 then increment group count.This group number will be starting grp num for
1304 that resolution */
1305 i4_curr_grp_num++;
1306 }
1307 else
1308 break;
1309 }
1310 }
1311
1312 for(ctr = 0; ctr < ps_enc_ctxt->s_multi_thrd.i4_num_enc_proc_thrds; ctr++)
1313 {
1314 osal_thread_attr_t s_thread_attr = OSAL_DEFAULT_THREAD_ATTR;
1315
1316 s_memtab.e_mem_type = IV_EXT_CACHEABLE_NORMAL_MEM;
1317 s_memtab.i4_mem_size = sizeof(frm_proc_thrd_ctxt_t);
1318
1319 ps_hle_ctxt->ihevce_mem_alloc(
1320 ps_hle_ctxt->pv_mem_mgr_hdl, &ps_enc_ctxt_base->ps_stat_prms->s_sys_api, &s_memtab);
1321 if(s_memtab.pv_base == NULL)
1322 {
1323 return (IV_FAIL);
1324 }
1325
1326 aps_enc_frm_proc_thrd_ctxt[res_ctr][ctr] = (frm_proc_thrd_ctxt_t *)s_memtab.pv_base;
1327
1328 /* initialise the interface strucure parameters */
1329 aps_enc_frm_proc_thrd_ctxt[res_ctr][ctr]->i4_thrd_id = ctr;
1330
1331 aps_enc_frm_proc_thrd_ctxt[res_ctr][ctr]->ps_hle_ctxt = ps_hle_ctxt;
1332
1333 ps_enc_ctxt = (enc_ctxt_t *)ps_hle_ctxt->apv_enc_hdl[res_ctr];
1334
1335 aps_enc_frm_proc_thrd_ctxt[res_ctr][ctr]->pv_enc_ctxt = (void *)ps_enc_ctxt;
1336
1337 /* Initialize application thread attributes */
1338 s_thread_attr.exit_code = 0;
1339 s_thread_attr.name = 0;
1340 s_thread_attr.priority_map_flag = 1;
1341 s_thread_attr.priority = OSAL_PRIORITY_DEFAULT;
1342 s_thread_attr.stack_addr = 0;
1343 s_thread_attr.stack_size = THREAD_STACK_SIZE;
1344 s_thread_attr.thread_func = ihevce_enc_frm_proc_slave_thrd;
1345 s_thread_attr.thread_param = (void *)(aps_enc_frm_proc_thrd_ctxt[res_ctr][ctr]);
1346 s_thread_attr.group_num = i4_curr_grp_num;
1347 if(1 == ps_enc_ctxt_base->ps_stat_prms->s_multi_thrd_prms.i4_use_thrd_affinity)
1348 {
1349 ihevce_static_multi_thread_params_t *ps_multi_thrd_prms =
1350 &ps_enc_ctxt_base->ps_stat_prms->s_multi_thrd_prms;
1351
1352 s_thread_attr.core_affinity_mask = ps_multi_thrd_prms->au8_core_aff_mask[enc_ctr];
1353 if((enc_ctr >= i4_acc_proc_num) &&
1354 (ps_enc_ctxt_base->ps_stat_prms->s_multi_thrd_prms.i4_num_proc_groups > 1))
1355 {
1356 /*** When the cores in the Group0 is exhausted start enc threads in the next Processor Group ***/
1357 s_thread_attr.group_num++;
1358 i4_curr_grp_num++;
1359 /* This takes care of the condition that differnt proc groups can have diff number of cores */
1360 i4_acc_proc_num += ai4_proc_count[i4_curr_grp_num];
1361 }
1362 }
1363 else
1364 {
1365 s_thread_attr.core_affinity_mask = 0;
1366 if((enc_ctr >= i4_acc_proc_num) &&
1367 (ps_enc_ctxt_base->ps_stat_prms->s_multi_thrd_prms.i4_num_proc_groups > 1))
1368 {
1369 /*** When the cores in the Group0 is exhausted start enc threads in the next Processor Group ***/
1370 s_thread_attr.group_num++;
1371 i4_curr_grp_num++;
1372 /* This takes care of the condition that differnt proc groups can have diff number of cores */
1373 i4_acc_proc_num += ai4_proc_count[i4_curr_grp_num];
1374 }
1375 }
1376
1377 /* Create frame processing thread */
1378 apv_enc_frm_proc_hdls[res_ctr][ctr] =
1379 osal_thread_create(ps_hle_ctxt->pv_osal_handle, &s_thread_attr);
1380 if(NULL == apv_enc_frm_proc_hdls[res_ctr][ctr])
1381 {
1382 return IV_FAIL;
1383 }
1384 enc_ctr++;
1385 }
1386 }
1387
1388 /* --------------------------------------------------------------------- */
1389 /* Create all Pre - Encode Frame processing threads */
1390 /* --------------------------------------------------------------------- */
1391 for(res_ctr = 0; res_ctr < i4_num_resolutions; res_ctr++)
1392 {
1393 WORD32 pre_enc_ctr = 0;
1394 WORD32 i4_loop_count;
1395 WORD32 i4_curr_grp_num = 0;
1396 ps_enc_ctxt = (enc_ctxt_t *)ps_hle_ctxt->apv_enc_hdl[res_ctr];
1397
1398 i4_acc_proc_num = 0;
1399
1400 for(i4_loop_count = 0; i4_loop_count < res_ctr; i4_loop_count++)
1401 pre_enc_ctr += ps_hle_ctxt->ai4_num_core_per_res[i4_loop_count];
1402 if(ps_enc_ctxt->s_multi_thrd.i4_all_thrds_active_flag)
1403 {
1404 /* If its sequential mode of operation enc and pre-enc threads to be given same core affinity mask */
1405 pre_enc_ctr -= ps_enc_ctxt->s_multi_thrd.i4_num_enc_proc_thrds;
1406 }
1407
1408 if(ps_enc_ctxt_base->ps_stat_prms->s_multi_thrd_prms.i4_num_proc_groups > 1)
1409 {
1410 /* Select the group number for each res based on processors present in each group */
1411 for(i4_loop_count = 0;
1412 i4_loop_count <
1413 ps_enc_ctxt_base->ps_stat_prms->s_multi_thrd_prms.i4_num_proc_groups;
1414 i4_loop_count++)
1415 {
1416 i4_acc_proc_num += ai4_proc_count[i4_loop_count];
1417 if((pre_enc_ctr + ps_enc_ctxt->s_multi_thrd.i4_num_enc_proc_thrds) >=
1418 i4_acc_proc_num)
1419 {
1420 /* if pre_enc_ctr is greater than proc count for first group,
1421 then increment group count.This group number will be starting grp num for
1422 that resolution */
1423 i4_curr_grp_num++;
1424 }
1425 else
1426 break;
1427 }
1428 }
1429
1430 for(ctr = 0; ctr < ps_enc_ctxt->s_multi_thrd.i4_num_pre_enc_proc_thrds; ctr++)
1431 {
1432 osal_thread_attr_t s_thread_attr = OSAL_DEFAULT_THREAD_ATTR;
1433
1434 s_memtab.e_mem_type = IV_EXT_CACHEABLE_NORMAL_MEM;
1435 s_memtab.i4_mem_size = sizeof(frm_proc_thrd_ctxt_t);
1436
1437 ps_hle_ctxt->ihevce_mem_alloc(
1438 ps_hle_ctxt->pv_mem_mgr_hdl, &ps_enc_ctxt_base->ps_stat_prms->s_sys_api, &s_memtab);
1439 if(s_memtab.pv_base == NULL)
1440 {
1441 return (IV_FAIL);
1442 }
1443
1444 aps_pre_enc_frm_proc_thrd_ctxt[res_ctr][ctr] = (frm_proc_thrd_ctxt_t *)s_memtab.pv_base;
1445
1446 /* initialise the interface strucure parameters */
1447 aps_pre_enc_frm_proc_thrd_ctxt[res_ctr][ctr]->i4_thrd_id = ctr;
1448
1449 aps_pre_enc_frm_proc_thrd_ctxt[res_ctr][ctr]->ps_hle_ctxt = ps_hle_ctxt;
1450 ps_enc_ctxt = (enc_ctxt_t *)ps_hle_ctxt->apv_enc_hdl[res_ctr];
1451 aps_pre_enc_frm_proc_thrd_ctxt[res_ctr][ctr]->pv_enc_ctxt = (void *)ps_enc_ctxt;
1452
1453 /* Initialize application thread attributes */
1454 s_thread_attr.exit_code = 0;
1455 s_thread_attr.name = 0;
1456 s_thread_attr.priority_map_flag = 1;
1457 s_thread_attr.priority = OSAL_PRIORITY_DEFAULT;
1458 s_thread_attr.stack_addr = 0;
1459 s_thread_attr.stack_size = THREAD_STACK_SIZE;
1460 s_thread_attr.thread_func = ihevce_pre_enc_process_frame_thrd;
1461 s_thread_attr.thread_param = (void *)(aps_pre_enc_frm_proc_thrd_ctxt[res_ctr][ctr]);
1462 s_thread_attr.group_num = i4_curr_grp_num;
1463
1464 if(1 == ps_enc_ctxt_base->ps_stat_prms->s_multi_thrd_prms.i4_use_thrd_affinity)
1465 {
1466 ihevce_static_multi_thread_params_t *ps_multi_thrd_prms =
1467 &ps_enc_ctxt_base->ps_stat_prms->s_multi_thrd_prms;
1468
1469 s_thread_attr.core_affinity_mask =
1470 ps_multi_thrd_prms->au8_core_aff_mask
1471 [pre_enc_ctr + ps_enc_ctxt->s_multi_thrd.i4_num_enc_proc_thrds];
1472 if(((pre_enc_ctr + ps_enc_ctxt->s_multi_thrd.i4_num_enc_proc_thrds) >=
1473 i4_acc_proc_num) &&
1474 (ps_enc_ctxt_base->ps_stat_prms->s_multi_thrd_prms.i4_num_proc_groups > 1))
1475 {
1476 /*** When the cores in the Group0 is exhausted start enc threads in the next Processor Group ***/
1477 s_thread_attr.group_num++;
1478 i4_curr_grp_num++;
1479 /* This takes care of the condition that differnt proc groups can have diff number of cores */
1480 i4_acc_proc_num += ai4_proc_count[i4_curr_grp_num];
1481 }
1482 }
1483 else
1484 {
1485 s_thread_attr.core_affinity_mask = 0;
1486
1487 if(((pre_enc_ctr + ps_enc_ctxt->s_multi_thrd.i4_num_enc_proc_thrds) >=
1488 i4_acc_proc_num) &&
1489 (ps_enc_ctxt_base->ps_stat_prms->s_multi_thrd_prms.i4_num_proc_groups > 1))
1490 {
1491 /*** When the cores in the Group0 is exhausted start enc threads in the next Processor Group ***/
1492 s_thread_attr.group_num++;
1493 i4_curr_grp_num++;
1494 /* This takes care of the condition that differnt proc groups can have diff number of cores */
1495 i4_acc_proc_num += ai4_proc_count[i4_curr_grp_num];
1496 }
1497 }
1498
1499 /* Create frame processing thread */
1500 apv_pre_enc_frm_proc_hdls[res_ctr][ctr] =
1501 osal_thread_create(ps_hle_ctxt->pv_osal_handle, &s_thread_attr);
1502 if(NULL == apv_pre_enc_frm_proc_hdls[res_ctr][ctr])
1503 {
1504 return IV_FAIL;
1505 }
1506 pre_enc_ctr++;
1507 }
1508 }
1509
1510 /* Set the threads init done Flag */
1511 ps_hle_ctxt->i4_hle_init_done = 1;
1512
1513 /* --------------------------------------------------------------------- */
1514 /* Wait and destroy Processing threads */
1515 /* --------------------------------------------------------------------- */
1516
1517 /* --------------------------------------------------------------------- */
1518 /* Frame process Pre - Encode threads destroy */
1519 /* --------------------------------------------------------------------- */
1520 for(res_ctr = 0; res_ctr < i4_num_resolutions; res_ctr++)
1521 {
1522 ps_enc_ctxt = (enc_ctxt_t *)ps_hle_ctxt->apv_enc_hdl[res_ctr];
1523
1524 for(ctr = 0; ctr < ps_enc_ctxt->s_multi_thrd.i4_num_pre_enc_proc_thrds; ctr++)
1525 {
1526 /* Wait for thread to complete */
1527 osal_thread_wait(apv_pre_enc_frm_proc_hdls[res_ctr][ctr]);
1528
1529 /* Destroy thread */
1530 osal_thread_destroy(apv_pre_enc_frm_proc_hdls[res_ctr][ctr]);
1531
1532 s_memtab.i4_mem_size = sizeof(frm_proc_thrd_ctxt_t);
1533 s_memtab.e_mem_type = IV_EXT_CACHEABLE_NORMAL_MEM;
1534 s_memtab.pv_base = (void *)aps_pre_enc_frm_proc_thrd_ctxt[res_ctr][ctr];
1535
1536 /* free the ctxt memory */
1537 ps_hle_ctxt->ihevce_mem_free(ps_hle_ctxt->pv_mem_mgr_hdl, &s_memtab);
1538 }
1539 }
1540
1541 /* --------------------------------------------------------------------- */
1542 /* Frame process Encode slave threads destroy */
1543 /* --------------------------------------------------------------------- */
1544 for(res_ctr = 0; res_ctr < i4_num_resolutions; res_ctr++)
1545 {
1546 ps_enc_ctxt = (enc_ctxt_t *)ps_hle_ctxt->apv_enc_hdl[res_ctr];
1547
1548 for(ctr = 0; ctr < ps_enc_ctxt->s_multi_thrd.i4_num_enc_proc_thrds; ctr++)
1549 {
1550 /* Wait for thread to complete */
1551 osal_thread_wait(apv_enc_frm_proc_hdls[res_ctr][ctr]);
1552
1553 /* Destroy thread */
1554 osal_thread_destroy(apv_enc_frm_proc_hdls[res_ctr][ctr]);
1555
1556 s_memtab.i4_mem_size = sizeof(frm_proc_thrd_ctxt_t);
1557 s_memtab.e_mem_type = IV_EXT_CACHEABLE_NORMAL_MEM;
1558 s_memtab.pv_base = (void *)aps_enc_frm_proc_thrd_ctxt[res_ctr][ctr];
1559
1560 /* free the ctxt memory */
1561 ps_hle_ctxt->ihevce_mem_free(ps_hle_ctxt->pv_mem_mgr_hdl, &s_memtab);
1562 }
1563 }
1564
1565 /* --------------------------------------------------------------------- */
1566 /* Entropy threads destroy */
1567 /* --------------------------------------------------------------------- */
1568 for(res_ctr = 0; res_ctr < i4_num_resolutions; res_ctr++)
1569 {
1570 WORD32 i4_num_bitrates =
1571 ps_enc_ctxt_base->ps_stat_prms->s_tgt_lyr_prms.as_tgt_params[res_ctr]
1572 .i4_num_bitrate_instances;
1573
1574 for(ctr = 0; ctr < i4_num_bitrates; ctr++)
1575 {
1576 /* Wait for Entropy Coding thread to complete */
1577 osal_thread_wait(apv_entropy_thrd_hdls[res_ctr][ctr]);
1578
1579 /* Destroy Entropy Coding thread */
1580 osal_thread_destroy(apv_entropy_thrd_hdls[res_ctr][ctr]);
1581
1582 //semaphore will come here
1583
1584 s_memtab.i4_mem_size = sizeof(frm_proc_thrd_ctxt_t);
1585 s_memtab.e_mem_type = IV_EXT_CACHEABLE_NORMAL_MEM;
1586 s_memtab.pv_base = (void *)aps_entropy_thrd_ctxt[res_ctr][ctr];
1587
1588 /* free the ctxt memory */
1589 ps_hle_ctxt->ihevce_mem_free(ps_hle_ctxt->pv_mem_mgr_hdl, &s_memtab);
1590 }
1591 }
1592
1593 s_memtab.i4_mem_size = sizeof(lap_intface_t);
1594 s_memtab.e_mem_type = IV_EXT_CACHEABLE_NORMAL_MEM;
1595 s_memtab.pv_base = (void *)ps_lap_interface_ctxt;
1596 ps_hle_ctxt->ihevce_mem_free(ps_hle_ctxt->pv_mem_mgr_hdl, &s_memtab);
1597 /* profile stop */
1598 PROFILE_STOP(&ps_hle_ctxt->profile_hle, NULL);
1599 return (0);
1600 }
1601
1602 /*!
1603 ******************************************************************************
1604 * \if Function name : ihevce_q_get_free_inp_data_buff \endif
1605 *
1606 * \brief
1607 * Gets a free buffer from the que requested
1608 *
1609 * \param[in] high level encoder context pointer
1610 * \param[in] pointer to return the buffer id
1611 * \param[in] blocking mode / non blocking mode
1612 *
1613 * \return
1614 * None
1615 *
1616 * \author
1617 * Ittiam
1618 *
1619 *****************************************************************************
1620 */
ihevce_q_get_free_inp_data_buff(ihevce_hle_ctxt_t * ps_hle_ctxt,WORD32 * pi4_buff_id,WORD32 i4_blocking_mode)1621 void *ihevce_q_get_free_inp_data_buff(
1622 ihevce_hle_ctxt_t *ps_hle_ctxt, WORD32 *pi4_buff_id, WORD32 i4_blocking_mode)
1623 {
1624 void *pv_ptr;
1625 enc_ctxt_t *ps_enc_ctxt;
1626 WORD32 i4_resolution_id = 0;
1627
1628 ps_enc_ctxt = (enc_ctxt_t *)ps_hle_ctxt->apv_enc_hdl[i4_resolution_id];
1629 if(ps_enc_ctxt->i4_frame_limit_reached == 1)
1630 {
1631 return (NULL);
1632 }
1633 /*Input buffer is same for all enc handles*/
1634 pv_ptr = ihevce_q_get_free_buff(
1635 ps_hle_ctxt->apv_enc_hdl[0], IHEVCE_INPUT_DATA_CTRL_Q, pi4_buff_id, i4_blocking_mode);
1636
1637 return (pv_ptr);
1638 }
1639
1640 /*!
1641 ******************************************************************************
1642 * \if Function name : ihevce_q_get_free_inp_ctrl_buff \endif
1643 *
1644 * \brief
1645 * Gets a free buffer from the que requested
1646 *
1647 * \param[in] high level encoder context pointer
1648 * \param[in] pointer to return the buffer id
1649 * \param[in] blocking mode / non blocking mode
1650 *
1651 * \return
1652 * None
1653 *
1654 * \author
1655 * Ittiam
1656 *
1657 *****************************************************************************
1658 */
ihevce_q_get_free_inp_ctrl_buff(ihevce_hle_ctxt_t * ps_hle_ctxt,WORD32 * pi4_buff_id,WORD32 i4_blocking_mode)1659 void *ihevce_q_get_free_inp_ctrl_buff(
1660 ihevce_hle_ctxt_t *ps_hle_ctxt, WORD32 *pi4_buff_id, WORD32 i4_blocking_mode)
1661 {
1662 void *pv_ptr;
1663
1664 /*Input buffer is same for all enc handles*/
1665 pv_ptr = ihevce_q_get_free_buff(
1666 ps_hle_ctxt->apv_enc_hdl[0], IHEVCE_INPUT_ASYNCH_CTRL_Q, pi4_buff_id, i4_blocking_mode);
1667
1668 return (pv_ptr);
1669 }
1670
1671 /*!
1672 ******************************************************************************
1673 * \if Function name : ihevce_q_get_free_out_strm_buff \endif
1674 *
1675 * \brief
1676 * Gets a free buffer from the que requested
1677 *
1678 * \param[in] high level encoder context pointer
1679 * \param[in] pointer to return the buffer id
1680 * \param[in] blocking mode / non blocking mode
1681 *
1682 * \return
1683 * None
1684 *
1685 * \author
1686 * Ittiam
1687 *
1688 *****************************************************************************
1689 */
ihevce_q_get_free_out_strm_buff(ihevce_hle_ctxt_t * ps_hle_ctxt,WORD32 * pi4_buff_id,WORD32 i4_blocking_mode,WORD32 i4_bitrate_instance,WORD32 i4_res_instance)1690 void *ihevce_q_get_free_out_strm_buff(
1691 ihevce_hle_ctxt_t *ps_hle_ctxt,
1692 WORD32 *pi4_buff_id,
1693 WORD32 i4_blocking_mode,
1694 WORD32 i4_bitrate_instance,
1695 WORD32 i4_res_instance)
1696 {
1697 void *pv_ptr;
1698
1699 pv_ptr = ihevce_q_get_free_buff(
1700 ps_hle_ctxt->apv_enc_hdl[i4_res_instance],
1701 (IHEVCE_OUTPUT_DATA_Q + i4_bitrate_instance),
1702 pi4_buff_id,
1703 i4_blocking_mode);
1704 return (pv_ptr);
1705 }
1706
1707 /*!
1708 ******************************************************************************
1709 * \if Function name : ihevce_q_get_free_out_recon_buff \endif
1710 *
1711 * \brief
1712 * Gets a free buffer from the que requested
1713 *
1714 * \param[in] high level encoder context pointer
1715 * \param[in] pointer to return the buffer id
1716 * \param[in] blocking mode / non blocking mode
1717 *
1718 * \return
1719 * None
1720 *
1721 * \author
1722 * Ittiam
1723 *
1724 *****************************************************************************
1725 */
ihevce_q_get_free_out_recon_buff(ihevce_hle_ctxt_t * ps_hle_ctxt,WORD32 * pi4_buff_id,WORD32 i4_blocking_mode,WORD32 i4_bitrate_instance,WORD32 i4_res_instance)1726 void *ihevce_q_get_free_out_recon_buff(
1727 ihevce_hle_ctxt_t *ps_hle_ctxt,
1728 WORD32 *pi4_buff_id,
1729 WORD32 i4_blocking_mode,
1730 WORD32 i4_bitrate_instance,
1731 WORD32 i4_res_instance)
1732 {
1733 void *pv_ptr;
1734
1735 pv_ptr = ihevce_q_get_free_buff(
1736 ps_hle_ctxt->apv_enc_hdl[i4_res_instance],
1737 (IHEVCE_RECON_DATA_Q + i4_bitrate_instance),
1738 pi4_buff_id,
1739 i4_blocking_mode);
1740 return (pv_ptr);
1741 }
1742
1743 /*!
1744 ******************************************************************************
1745 * \if Function name : ihevce_q_set_inp_data_buff_prod \endif
1746 *
1747 * \brief
1748 * Sets the input data buffer as produced in the que requested
1749 *
1750 * \param[in] high level encoder context pointer
1751 * \param[in] buffer id which needs to be set as produced
1752 *
1753 * \return
1754 * None
1755 *
1756 * \author
1757 * Ittiam
1758 *
1759 *****************************************************************************
1760 */
1761 IV_API_CALL_STATUS_T
ihevce_q_set_inp_data_buff_prod(ihevce_hle_ctxt_t * ps_hle_ctxt,WORD32 i4_buff_id)1762 ihevce_q_set_inp_data_buff_prod(ihevce_hle_ctxt_t *ps_hle_ctxt, WORD32 i4_buff_id)
1763 {
1764 IV_API_CALL_STATUS_T ret_status;
1765
1766 ret_status =
1767 ihevce_q_set_buff_prod(ps_hle_ctxt->apv_enc_hdl[0], IHEVCE_INPUT_DATA_CTRL_Q, i4_buff_id);
1768
1769 return (ret_status);
1770 }
1771
1772 /*!
1773 ******************************************************************************
1774 * \if Function name : ihevce_q_set_inp_ctrl_buff_prod \endif
1775 *
1776 * \brief
1777 * Sets the input data buffer as produced in the que requested
1778 *
1779 * \param[in] high level encoder context pointer
1780 * \param[in] buffer id which needs to be set as produced
1781 *
1782 * \return
1783 * None
1784 *
1785 * \author
1786 * Ittiam
1787 *
1788 *****************************************************************************
1789 */
1790 IV_API_CALL_STATUS_T
ihevce_q_set_inp_ctrl_buff_prod(ihevce_hle_ctxt_t * ps_hle_ctxt,WORD32 i4_buff_id)1791 ihevce_q_set_inp_ctrl_buff_prod(ihevce_hle_ctxt_t *ps_hle_ctxt, WORD32 i4_buff_id)
1792
1793 {
1794 IV_API_CALL_STATUS_T ret_status;
1795
1796 ret_status =
1797 ihevce_q_set_buff_prod(ps_hle_ctxt->apv_enc_hdl[0], IHEVCE_INPUT_ASYNCH_CTRL_Q, i4_buff_id);
1798
1799 return (ret_status);
1800 }
1801
1802 /*!
1803 ******************************************************************************
1804 * \if Function name : ihevce_q_set_out_strm_buff_prod \endif
1805 *
1806 * \brief
1807 * Sets the Output stream buffer as produced in the que requested
1808 *
1809 * \param[in] high level encoder context pointer
1810 * \param[in] buffer id which needs to be set as produced
1811 *
1812 * \return
1813 * None
1814 *
1815 * \author
1816 * Ittiam
1817 *
1818 *****************************************************************************
1819 */
ihevce_q_set_out_strm_buff_prod(ihevce_hle_ctxt_t * ps_hle_ctxt,WORD32 i4_buff_id,WORD32 i4_bitrate_instance_id,WORD32 i4_resolution_id)1820 IV_API_CALL_STATUS_T ihevce_q_set_out_strm_buff_prod(
1821 ihevce_hle_ctxt_t *ps_hle_ctxt,
1822 WORD32 i4_buff_id,
1823 WORD32 i4_bitrate_instance_id,
1824 WORD32 i4_resolution_id)
1825 {
1826 IV_API_CALL_STATUS_T ret_status;
1827
1828 ret_status = ihevce_q_set_buff_prod(
1829 ps_hle_ctxt->apv_enc_hdl[i4_resolution_id],
1830 (IHEVCE_OUTPUT_DATA_Q + i4_bitrate_instance_id),
1831 i4_buff_id);
1832
1833 return (ret_status);
1834 }
1835
1836 /*!
1837 ******************************************************************************
1838 * \if Function name : ihevce_q_set_out_recon_buff_prod \endif
1839 *
1840 * \brief
1841 * Sets the Output recon buffer as produced in the que requested
1842 *
1843 * \param[in] high level encoder context pointer
1844 * \param[in] buffer id which needs to be set as produced
1845 *
1846 * \return
1847 * None
1848 *
1849 * \author
1850 * Ittiam
1851 *
1852 *****************************************************************************
1853 */
ihevce_q_set_out_recon_buff_prod(ihevce_hle_ctxt_t * ps_hle_ctxt,WORD32 i4_buff_id,WORD32 i4_bitrate_instance_id,WORD32 i4_resolution_id)1854 IV_API_CALL_STATUS_T ihevce_q_set_out_recon_buff_prod(
1855 ihevce_hle_ctxt_t *ps_hle_ctxt,
1856 WORD32 i4_buff_id,
1857 WORD32 i4_bitrate_instance_id,
1858 WORD32 i4_resolution_id)
1859 {
1860 IV_API_CALL_STATUS_T ret_status;
1861
1862 ret_status = ihevce_q_set_buff_prod(
1863 ps_hle_ctxt->apv_enc_hdl[i4_resolution_id],
1864 (IHEVCE_RECON_DATA_Q + i4_bitrate_instance_id),
1865 i4_buff_id);
1866
1867 return (ret_status);
1868 }
1869
1870 //recon_dump
1871 /*!
1872 ******************************************************************************
1873 * \if Function name : ihevce_q_get_filled_recon_buff \endif
1874 *
1875 * \brief
1876 * Gets a next filled recon buffer from the que requested
1877 *
1878 * \param[in] high level encoder context pointer
1879 * \param[in] pointer to return the buffer id
1880 * \param[in] blocking mode / non blocking mode
1881 *
1882 * \return
1883 * None
1884 *
1885 * \author
1886 * Ittiam
1887 *
1888 *****************************************************************************
1889 */
ihevce_q_get_filled_recon_buff(ihevce_hle_ctxt_t * ps_hle_ctxt,WORD32 * pi4_buff_id,WORD32 i4_blocking_mode,WORD32 i4_bitrate_instance_id,WORD32 i4_resolution_id)1890 void *ihevce_q_get_filled_recon_buff(
1891 ihevce_hle_ctxt_t *ps_hle_ctxt,
1892 WORD32 *pi4_buff_id,
1893 WORD32 i4_blocking_mode,
1894 WORD32 i4_bitrate_instance_id,
1895 WORD32 i4_resolution_id)
1896 {
1897 void *pv_ptr;
1898
1899 pv_ptr = ihevce_q_get_filled_buff(
1900 ps_hle_ctxt->apv_enc_hdl[i4_resolution_id],
1901 IHEVCE_RECON_DATA_Q + i4_bitrate_instance_id,
1902 pi4_buff_id,
1903 i4_blocking_mode);
1904
1905 return (pv_ptr);
1906 }
1907
1908 /*!
1909 ******************************************************************************
1910 * \if Function name : ihevce_q_get_filled_ctrl_sts_buff \endif
1911 *
1912 * \brief
1913 * Gets a next filled control status buffer from the que requested
1914 *
1915 * \param[in] high level encoder context pointer
1916 * \param[in] pointer to return the buffer id
1917 * \param[in] blocking mode / non blocking mode
1918 *
1919 * \return
1920 * None
1921 *
1922 * \author
1923 * Ittiam
1924 *
1925 *****************************************************************************
1926 */
ihevce_q_get_filled_ctrl_sts_buff(ihevce_hle_ctxt_t * ps_hle_ctxt,WORD32 * pi4_buff_id,WORD32 i4_blocking_mode)1927 void *ihevce_q_get_filled_ctrl_sts_buff(
1928 ihevce_hle_ctxt_t *ps_hle_ctxt, WORD32 *pi4_buff_id, WORD32 i4_blocking_mode)
1929 {
1930 void *pv_ptr;
1931 pv_ptr = ihevce_q_get_filled_buff(
1932 ps_hle_ctxt->apv_enc_hdl[0], IHEVCE_OUTPUT_STATUS_Q, pi4_buff_id, i4_blocking_mode);
1933
1934 return (pv_ptr);
1935 }
1936
1937 //recon_dump
1938 /*!
1939 ******************************************************************************
1940 * \if Function name : ihevce_q_rel_recon_buf \endif
1941 *
1942 * \brief
1943 * Frees the recon buffer in the recon buffer que
1944 *
1945 * \param[in] high level encoder context pointer
1946 * \param[in] buffer id which needs to be freed
1947 *
1948 * \return
1949 * None
1950 *
1951 * \author
1952 * Ittiam
1953 *
1954 *****************************************************************************
1955 */
ihevce_q_rel_recon_buf(ihevce_hle_ctxt_t * ps_hle_ctxt,WORD32 i4_buff_id,WORD32 i4_bitrate_instance_id,WORD32 i4_resolution_id)1956 IV_API_CALL_STATUS_T ihevce_q_rel_recon_buf(
1957 ihevce_hle_ctxt_t *ps_hle_ctxt,
1958 WORD32 i4_buff_id,
1959 WORD32 i4_bitrate_instance_id,
1960 WORD32 i4_resolution_id)
1961 {
1962 IV_API_CALL_STATUS_T ret_status;
1963
1964 ret_status = ihevce_q_rel_buf(
1965 ps_hle_ctxt->apv_enc_hdl[i4_resolution_id],
1966 IHEVCE_RECON_DATA_Q + i4_bitrate_instance_id,
1967 i4_buff_id);
1968
1969 return (ret_status);
1970 }
1971
1972 /*!
1973 ******************************************************************************
1974 * \if Function name : ihevce_q_rel_ctrl_sts_buf \endif
1975 *
1976 * \brief
1977 * Frees the output control sttus buffer in buffer que
1978 *
1979 * \param[in] high level encoder context pointer
1980 * \param[in] buffer id which needs to be freed
1981 *
1982 * \return
1983 * None
1984 *
1985 * \author
1986 * Ittiam
1987 *
1988 *****************************************************************************
1989 */
ihevce_q_rel_ctrl_sts_buf(ihevce_hle_ctxt_t * ps_hle_ctxt,WORD32 i4_buff_id)1990 IV_API_CALL_STATUS_T ihevce_q_rel_ctrl_sts_buf(ihevce_hle_ctxt_t *ps_hle_ctxt, WORD32 i4_buff_id)
1991 {
1992 IV_API_CALL_STATUS_T ret_status;
1993
1994 ret_status = ihevce_q_rel_buf(ps_hle_ctxt->apv_enc_hdl[0], IHEVCE_OUTPUT_STATUS_Q, i4_buff_id);
1995
1996 return (ret_status);
1997 }
1998
1999 /*!
2000 ******************************************************************************
2001 * \if Function name : ihevce_hle_interface_delete \endif
2002 *
2003 * \brief
2004 * High leve encoder delete interface
2005 *
2006 * \param[in] high level encoder interface context pointer
2007 *
2008 * \return
2009 * None
2010 *
2011 * \author
2012 * Ittiam
2013 *
2014 *****************************************************************************
2015 */
ihevce_hle_interface_delete(ihevce_hle_ctxt_t * ps_hle_ctxt)2016 IV_API_CALL_STATUS_T ihevce_hle_interface_delete(ihevce_hle_ctxt_t *ps_hle_ctxt)
2017 {
2018 /* local varaibles */
2019 enc_ctxt_t *ps_enc_ctxt;
2020 iv_mem_rec_t s_memtab;
2021 WORD32 ctr = 0, i, res_ctr, i4_num_resolutions;
2022 WORD32 ai4_num_bitrate_instances[IHEVCE_MAX_NUM_RESOLUTIONS] = { 1 };
2023
2024 i4_num_resolutions = ps_hle_ctxt->ps_static_cfg_prms->s_tgt_lyr_prms.i4_num_res_layers;
2025 for(ctr = 0; ctr < i4_num_resolutions; ctr++)
2026 {
2027 ai4_num_bitrate_instances[ctr] =
2028 ps_hle_ctxt->ps_static_cfg_prms->s_tgt_lyr_prms.as_tgt_params[ctr]
2029 .i4_num_bitrate_instances;
2030 }
2031
2032 for(res_ctr = 0; res_ctr < i4_num_resolutions && ps_hle_ctxt->apv_enc_hdl[res_ctr]; res_ctr++)
2033 {
2034 ps_enc_ctxt = (enc_ctxt_t *)ps_hle_ctxt->apv_enc_hdl[res_ctr];
2035
2036 if(res_ctr == 0)
2037 {
2038 osal_sem_destroy(ps_enc_ctxt->s_thrd_sem_ctxt.pv_lap_sem_handle);
2039 osal_sem_destroy(ps_enc_ctxt->s_thrd_sem_ctxt.pv_inp_data_sem_handle);
2040 osal_sem_destroy(ps_enc_ctxt->s_thrd_sem_ctxt.pv_inp_ctrl_sem_handle);
2041 if(1 == ps_hle_ctxt->ps_static_cfg_prms->s_tgt_lyr_prms.i4_mres_single_out)
2042 {
2043 osal_sem_destroy(ps_enc_ctxt->s_thrd_sem_ctxt.pv_ent_common_mres_sem_hdl);
2044 osal_sem_destroy(ps_enc_ctxt->s_thrd_sem_ctxt.pv_out_common_mres_sem_hdl);
2045 }
2046 }
2047
2048 osal_sem_destroy(ps_enc_ctxt->s_thrd_sem_ctxt.pv_lap_inp_data_sem_hdl);
2049 osal_sem_destroy(ps_enc_ctxt->s_thrd_sem_ctxt.pv_preenc_inp_data_sem_hdl);
2050
2051 osal_sem_destroy(ps_enc_ctxt->s_thrd_sem_ctxt.pv_enc_frm_proc_sem_handle);
2052 osal_sem_destroy(ps_enc_ctxt->s_thrd_sem_ctxt.pv_pre_enc_frm_proc_sem_handle);
2053
2054 osal_sem_destroy(ps_enc_ctxt->s_thrd_sem_ctxt.pv_out_ctrl_sem_handle);
2055
2056 for(i = 0; i < ps_hle_ctxt->ps_static_cfg_prms->s_tgt_lyr_prms.as_tgt_params[res_ctr]
2057 .i4_num_bitrate_instances;
2058 i++)
2059 {
2060 osal_sem_destroy(ps_enc_ctxt->s_thrd_sem_ctxt.apv_ent_cod_sem_handle[i]);
2061 osal_sem_destroy(ps_enc_ctxt->s_thrd_sem_ctxt.apv_out_strm_sem_handle[i]);
2062 osal_sem_destroy(ps_enc_ctxt->s_thrd_sem_ctxt.apv_out_recon_sem_handle[i]);
2063 }
2064
2065 /* destroy the mutex allocated for job queue usage encode group */
2066 osal_mutex_destroy(ps_enc_ctxt->s_multi_thrd.pv_job_q_mutex_hdl_enc_grp_me);
2067
2068 /* destroy the mutex allocated for job queue usage encode group */
2069 osal_mutex_destroy(ps_enc_ctxt->s_multi_thrd.pv_job_q_mutex_hdl_enc_grp_enc_loop);
2070
2071 /* destroy the mutexes allocated for enc thread group */
2072 for(i = 0; i < MAX_NUM_ME_PARALLEL; i++)
2073 {
2074 osal_mutex_destroy(ps_enc_ctxt->s_multi_thrd.apv_mutex_handle[i]);
2075
2076 osal_mutex_destroy(ps_enc_ctxt->s_multi_thrd.apv_mutex_handle_me_end[i]);
2077 }
2078
2079 for(i = 0; i < MAX_NUM_ENC_LOOP_PARALLEL; i++)
2080 {
2081 osal_mutex_destroy(ps_enc_ctxt->s_multi_thrd.apv_mutex_handle_frame_init[i]);
2082
2083 osal_mutex_destroy(ps_enc_ctxt->s_multi_thrd.apv_post_enc_mutex_handle[i]);
2084 }
2085
2086 /* destroy the mutex allocated for job queue, init and de-init
2087 usage pre enocde group */
2088 osal_mutex_destroy(ps_enc_ctxt->s_multi_thrd.pv_job_q_mutex_hdl_pre_enc_decomp);
2089 osal_mutex_destroy(ps_enc_ctxt->s_multi_thrd.pv_job_q_mutex_hdl_pre_enc_hme);
2090 osal_mutex_destroy(ps_enc_ctxt->s_multi_thrd.pv_job_q_mutex_hdl_pre_enc_l0ipe);
2091 osal_mutex_destroy(ps_enc_ctxt->s_multi_thrd.pv_mutex_hdl_pre_enc_init);
2092 osal_mutex_destroy(ps_enc_ctxt->s_multi_thrd.pv_mutex_hdl_pre_enc_decomp_deinit);
2093 osal_mutex_destroy(ps_enc_ctxt->s_multi_thrd.pv_mutex_hdl_pre_enc_hme_init);
2094 osal_mutex_destroy(ps_enc_ctxt->s_multi_thrd.pv_mutex_hdl_pre_enc_hme_deinit);
2095 osal_mutex_destroy(ps_enc_ctxt->s_multi_thrd.pv_mutex_hdl_l0_ipe_init);
2096 osal_mutex_destroy(ps_enc_ctxt->s_multi_thrd.pv_mutex_hdl_pre_enc_deinit);
2097
2098 /* destroy the EncLoop Module */
2099 /* Note : Only Destroys the resources allocated in the module like */
2100 /* semaphore,etc. Memory free is done separately using memtabs */
2101 ihevce_enc_loop_delete(ps_enc_ctxt->s_module_ctxt.pv_enc_loop_ctxt);
2102
2103 /* destroy the Coarse ME Module */
2104 /* Note : Only Destroys the resources allocated in the module like */
2105 /* semaphore,etc. Memory free is done separately using memtabs */
2106 ihevce_coarse_me_delete(
2107 ps_enc_ctxt->s_module_ctxt.pv_coarse_me_ctxt,
2108 ps_hle_ctxt->ps_static_cfg_prms,
2109 ps_enc_ctxt->i4_resolution_id);
2110 /* destroy semaphores for all the threads in pre-enc and enc */
2111 for(ctr = 0; ctr < ps_enc_ctxt->s_multi_thrd.i4_num_enc_proc_thrds; ctr++)
2112 {
2113 osal_sem_destroy(ps_enc_ctxt->s_multi_thrd.apv_enc_thrd_sem_handle[ctr]);
2114 }
2115
2116 for(ctr = 0; ctr < ps_enc_ctxt->s_multi_thrd.i4_num_pre_enc_proc_thrds; ctr++)
2117 {
2118 osal_sem_destroy(ps_enc_ctxt->s_multi_thrd.apv_pre_enc_thrd_sem_handle[ctr]);
2119 }
2120
2121 /* destroy the ME-EncLoop Dep Mngr */
2122 /* Note : Only Destroys the resources allocated in the module like */
2123 /* semaphore,etc. Memory free is done separately using memtabs */
2124 for(ctr = 0; ctr < NUM_ME_ENC_BUFS; ctr++)
2125 {
2126 ihevce_dmgr_del(ps_enc_ctxt->s_multi_thrd.apv_dep_mngr_encloop_dep_me[ctr]);
2127 }
2128 /* destroy the Prev. frame EncLoop Done Dep Mngr */
2129 /* Note : Only Destroys the resources allocated in the module like */
2130 /* semaphore,etc. Memory free is done separately using memtabs */
2131 for(i = 0; i < ps_enc_ctxt->s_multi_thrd.i4_num_enc_loop_frm_pllel; i++)
2132 {
2133 ihevce_dmgr_del(ps_enc_ctxt->s_multi_thrd.apv_dep_mngr_prev_frame_done[i]);
2134 }
2135 /* destroy the Prev. frame EncLoop Done for re-encode Dep Mngr */
2136 ihevce_dmgr_del(ps_enc_ctxt->s_multi_thrd.pv_dep_mngr_prev_frame_enc_done_for_reenc);
2137
2138 /* destroy the Prev. frame ME Done Dep Mngr */
2139 /* Note : Only Destroys the resources allocated in the module like */
2140 /* semaphore,etc. Memory free is done separately using memtabs */
2141 for(i = 0; i < ps_enc_ctxt->s_multi_thrd.i4_num_me_frm_pllel; i++)
2142 {
2143 ihevce_dmgr_del(ps_enc_ctxt->s_multi_thrd.apv_dep_mngr_prev_frame_me_done[i]);
2144 }
2145
2146 /* destroy the Prev. frame PreEnc L1 Done Dep Mngr */
2147 /* Note : Only Destroys the resources allocated in the module like */
2148 /* semaphore,etc. Memory free is done separately using memtabs */
2149 ihevce_dmgr_del(ps_enc_ctxt->s_multi_thrd.pv_dep_mngr_prev_frame_pre_enc_l1);
2150
2151 /* destroy the Prev. frame PreEnc HME Done Dep Mngr */
2152 /* Note : Only Destroys the resources allocated in the module like */
2153 /* semaphore,etc. Memory free is done separately using memtabs */
2154 ihevce_dmgr_del(ps_enc_ctxt->s_multi_thrd.pv_dep_mngr_prev_frame_pre_enc_coarse_me);
2155
2156 /* destroy the Prev. frame PreEnc L0 Done Dep Mngr */
2157 /* Note : Only Destroys the resources allocated in the module like */
2158 /* semaphore,etc. Memory free is done separately using memtabs */
2159 ihevce_dmgr_del(ps_enc_ctxt->s_multi_thrd.pv_dep_mngr_prev_frame_pre_enc_l0);
2160
2161 /* destroy the ME-Prev Recon Dep Mngr */
2162 /* Note : Only Destroys the resources allocated in the module like */
2163 /* semaphore,etc. Memory free is done separately using memtabs */
2164 for(ctr = 0; ctr < ps_enc_ctxt->ai4_num_buf_recon_q[0]; ctr++)
2165 {
2166 ihevce_dmgr_del(ps_enc_ctxt->pps_recon_buf_q[0][ctr]->pv_dep_mngr_recon);
2167 }
2168
2169 /* destroy all the mutex created */
2170 if(res_ctr == 0)
2171 {
2172 if(NULL != ps_enc_ctxt->s_enc_ques.pv_q_mutex_hdl)
2173 {
2174 osal_mutex_destroy(ps_enc_ctxt->s_enc_ques.pv_q_mutex_hdl);
2175 }
2176 }
2177
2178 if(NULL != ps_enc_ctxt->pv_rc_mutex_lock_hdl)
2179 {
2180 osal_mutex_destroy(ps_enc_ctxt->pv_rc_mutex_lock_hdl);
2181 }
2182
2183 if(NULL != ps_enc_ctxt->s_multi_thrd.pv_sub_pic_rc_mutex_lock_hdl)
2184 {
2185 osal_mutex_destroy(ps_enc_ctxt->s_multi_thrd.pv_sub_pic_rc_mutex_lock_hdl);
2186 }
2187
2188 if(NULL != ps_enc_ctxt->s_multi_thrd.pv_sub_pic_rc_for_qp_update_mutex_lock_hdl)
2189 {
2190 osal_mutex_destroy(
2191 ps_enc_ctxt->s_multi_thrd.pv_sub_pic_rc_for_qp_update_mutex_lock_hdl);
2192 }
2193
2194 /* call the memrory free function */
2195 ihevce_mem_manager_free(ps_enc_ctxt, ps_hle_ctxt);
2196 if((1 == ps_hle_ctxt->ps_static_cfg_prms->s_tgt_lyr_prms.i4_mres_single_out) &&
2197 (res_ctr == 0))
2198 {
2199 s_memtab.i4_mem_size = sizeof(WORD32) * IHEVCE_MAX_NUM_RESOLUTIONS;
2200 s_memtab.i4_mem_alignment = 4;
2201 s_memtab.i4_size = sizeof(iv_mem_rec_t);
2202 s_memtab.e_mem_type = IV_EXT_CACHEABLE_NORMAL_MEM;
2203 s_memtab.pv_base = ps_enc_ctxt->s_multi_thrd.pi4_active_res_id;
2204 /* free active_res_id memory */
2205 ps_hle_ctxt->ihevce_mem_free(ps_hle_ctxt->pv_mem_mgr_hdl, &s_memtab);
2206 }
2207 if(res_ctr == (i4_num_resolutions - 1))
2208 {
2209 s_memtab.i4_mem_size = sizeof(ihevce_static_cfg_params_t);
2210 s_memtab.i4_mem_alignment = 4;
2211 s_memtab.i4_size = sizeof(iv_mem_rec_t);
2212 s_memtab.e_mem_type = IV_EXT_CACHEABLE_NORMAL_MEM;
2213 s_memtab.pv_base = ps_enc_ctxt->ps_stat_prms;
2214
2215 /* free the encoder context pointer */
2216 ps_hle_ctxt->ihevce_mem_free(ps_hle_ctxt->pv_mem_mgr_hdl, &s_memtab);
2217 }
2218 s_memtab.i4_mem_size = sizeof(enc_ctxt_t);
2219 s_memtab.i4_mem_alignment = 4;
2220 s_memtab.i4_size = sizeof(iv_mem_rec_t);
2221 s_memtab.e_mem_type = IV_EXT_CACHEABLE_NORMAL_MEM;
2222 s_memtab.pv_base = ps_enc_ctxt;
2223
2224 /* free the encoder context pointer */
2225 ps_hle_ctxt->ihevce_mem_free(ps_hle_ctxt->pv_mem_mgr_hdl, &s_memtab);
2226
2227 /* reset the encoder handle to NULL */
2228 ps_hle_ctxt->apv_enc_hdl[res_ctr] = NULL;
2229 }
2230 /* profile end */
2231 PROFILE_END(&ps_hle_ctxt->profile_hle, "hle interface thread active time");
2232 for(res_ctr = 0; res_ctr < i4_num_resolutions; res_ctr++)
2233 {
2234 WORD32 i4_br_id;
2235
2236 PROFILE_END(&ps_hle_ctxt->profile_pre_enc_l1l2[res_ctr], "pre enc l1l2 process");
2237 PROFILE_END(&ps_hle_ctxt->profile_pre_enc_l0ipe[res_ctr], "pre enc l0 ipe process");
2238 PROFILE_END(&ps_hle_ctxt->profile_enc_me[res_ctr], "enc me process");
2239 for(i4_br_id = 0; i4_br_id < ai4_num_bitrate_instances[res_ctr]; i4_br_id++)
2240 {
2241 PROFILE_END(&ps_hle_ctxt->profile_enc[res_ctr][i4_br_id], "enc loop process");
2242 PROFILE_END(&ps_hle_ctxt->profile_entropy[res_ctr][i4_br_id], "entropy process");
2243 }
2244 }
2245
2246 /* OSAL Delete */
2247 ihevce_osal_delete((void *)ps_hle_ctxt);
2248
2249 return (IV_SUCCESS);
2250 }
2251