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 enocder
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 enocder 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 ps_input_bufs_req->i4_min_size_synch_ctrl_bufs =
519 ((MAX_SEI_PAYLOAD_PER_TLV + 16) * MAX_NUMBER_OF_SEI_PAYLOAD) + 16;
520
521 ps_input_bufs_req->i4_min_size_asynch_ctrl_bufs =
522 ((MAX_SEI_PAYLOAD_PER_TLV + 16) * (MAX_NUMBER_OF_SEI_PAYLOAD - 6)) + 16;
523
524 for(i4_resolution_id_ctr = 0; i4_resolution_id_ctr < i4_num_resolutions; i4_resolution_id_ctr++)
525 {
526 ps_enc_ctxt = (enc_ctxt_t *)ps_hle_ctxt->apv_enc_hdl[i4_resolution_id_ctr];
527
528 i4_num_bitrate_instances = ps_enc_ctxt->s_runtime_tgt_params.i4_num_bitrate_instances;
529
530 /* buffer sizes are populated based on create time parameters */
531 ctb_align_pic_wd = ps_enc_ctxt->s_runtime_tgt_params.i4_width +
532 SET_CTB_ALIGN(
533 ps_enc_ctxt->s_runtime_tgt_params.i4_width,
534 ps_enc_ctxt->s_frm_ctb_prms.i4_ctb_size);
535
536 ctb_align_pic_ht = ps_enc_ctxt->s_runtime_tgt_params.i4_height +
537 SET_CTB_ALIGN(
538 ps_enc_ctxt->s_runtime_tgt_params.i4_height,
539 ps_enc_ctxt->s_frm_ctb_prms.i4_ctb_size);
540
541 for(br_ctr = 0; br_ctr < i4_num_bitrate_instances; br_ctr++)
542 {
543 /* ------- populate the Output buffer requirements -------- */
544 ps_res_layer_output_bufs_req->s_output_buf_req[i4_resolution_id_ctr][br_ctr]
545 .i4_min_num_out_bufs = NUM_OUTPUT_BUFS;
546
547 ps_res_layer_output_bufs_req->s_output_buf_req[i4_resolution_id_ctr][br_ctr]
548 .i4_min_size_bitstream_buf = (ctb_align_pic_wd * ctb_align_pic_ht);
549
550 if((ps_hle_ctxt->ps_static_cfg_prms->s_tgt_lyr_prms.i4_internal_bit_depth == 12) ||
551 ((ps_hle_ctxt->ps_static_cfg_prms->s_tgt_lyr_prms.i4_internal_bit_depth > 8) &&
552 (ps_src_prms->i4_chr_format == IV_YUV_422SP_UV)))
553 {
554 ps_res_layer_output_bufs_req->s_output_buf_req[i4_resolution_id_ctr][br_ctr]
555 .i4_min_size_bitstream_buf *= 2;
556 }
557
558 if((ps_hle_ctxt->ps_static_cfg_prms->s_tgt_lyr_prms.i4_internal_bit_depth == 10) &&
559 (ps_src_prms->i4_chr_format == IV_YUV_420SP_UV))
560 {
561 ps_res_layer_output_bufs_req->s_output_buf_req[i4_resolution_id_ctr][br_ctr]
562 .i4_min_size_bitstream_buf *= 3;
563 ps_res_layer_output_bufs_req->s_output_buf_req[i4_resolution_id_ctr][br_ctr]
564 .i4_min_size_bitstream_buf >>= 1;
565 }
566
567 //recon_dump
568 /* ------- populate the Recon buffer requirements -------- */
569 if(ps_enc_ctxt->ps_stat_prms->i4_save_recon == 0)
570 {
571 ps_res_layer_recon_bufs_req->s_recon_buf_req[i4_resolution_id_ctr][br_ctr]
572 .i4_min_num_recon_bufs = 0;
573
574 ps_res_layer_recon_bufs_req->s_recon_buf_req[i4_resolution_id_ctr][br_ctr]
575 .i4_min_size_y_buf = 0;
576
577 ps_res_layer_recon_bufs_req->s_recon_buf_req[i4_resolution_id_ctr][br_ctr]
578 .i4_min_size_uv_buf = 0;
579 }
580 else
581 {
582 ps_res_layer_recon_bufs_req->s_recon_buf_req[i4_resolution_id_ctr][br_ctr]
583 .i4_min_num_recon_bufs = 2 * HEVCE_MAX_REF_PICS + 1;
584
585 ps_res_layer_recon_bufs_req->s_recon_buf_req[i4_resolution_id_ctr][br_ctr]
586 .i4_min_size_y_buf =
587 ctb_align_pic_wd * ctb_align_pic_ht *
588 ((ps_hle_ctxt->ps_static_cfg_prms->s_tgt_lyr_prms.i4_internal_bit_depth > 8)
589 ? 2
590 : 1);
591
592 ps_res_layer_recon_bufs_req->s_recon_buf_req[i4_resolution_id_ctr][br_ctr]
593 .i4_min_size_uv_buf =
594 (ps_res_layer_recon_bufs_req->s_recon_buf_req[i4_resolution_id_ctr][br_ctr]
595 .i4_min_size_y_buf >>
596 1);
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_src_prms->i4_chr_format == IV_YUV_422SP_UV) ? 1 : 0);
600 }
601 }
602 }
603
604 return (IV_SUCCESS);
605 }
606
607 /*!
608 ******************************************************************************
609 * \if Function name : ihevce_create_ports \endif
610 *
611 * \brief
612 * High level Encoder IO ports Create function
613 *
614 * \param[in] High level encoder interface context pointer
615 * \param[in] Input data buffer descriptor
616 * \param[in] Input control buffer descriptor
617 * \param[in] Output data buffer descriptor
618 * \param[in] Output control status buffer descriptor
619 * \param[out] Pointer to store the ID for Input data Que
620 * \param[out] Pointer to store the ID for Input control Que
621 * \param[out] Pointer to store the ID for Output data Que
622 * \param[out] Pointer to store the ID for Output control status Que
623 *
624 * \return
625 * success or fail
626 *
627 * \author
628 * Ittiam
629 *
630 *****************************************************************************
631 */
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)632 IV_API_CALL_STATUS_T ihevce_create_ports(
633 ihevce_hle_ctxt_t *ps_hle_ctxt,
634 iv_input_data_ctrl_buffs_desc_t *ps_input_data_ctrl_buffs_desc,
635 iv_input_asynch_ctrl_buffs_desc_t *ps_input_asynch_ctrl_buffs_desc,
636 iv_res_layer_output_data_buffs_desc_t *ps_mres_output_data_buffs_desc,
637 iv_res_layer_recon_data_buffs_desc_t *ps_mres_recon_data_buffs_desc)
638 {
639 /* local varaibles */
640 enc_ctxt_t *ps_enc_ctxt;
641 WORD32 res_ctr,
642 i4_num_resolutions = ps_hle_ctxt->ps_static_cfg_prms->s_tgt_lyr_prms.i4_num_res_layers;
643 void *pv_q_mutex_hdl = NULL;
644
645 /* set no error in the output */
646 ps_hle_ctxt->i4_error_code = 0;
647
648 for(res_ctr = 0; res_ctr < i4_num_resolutions; res_ctr++)
649 {
650 ps_enc_ctxt = (enc_ctxt_t *)ps_hle_ctxt->apv_enc_hdl[res_ctr];
651 /* check on buffer sizes provided by applciation needs to be checked */
652
653 /* call the memory manager que init function , pass the op data , status, recon for the first bitrate, internally we will increment*/
654 ihevce_mem_manager_que_init(
655 ps_enc_ctxt,
656 ps_hle_ctxt,
657 ps_input_data_ctrl_buffs_desc,
658 ps_input_asynch_ctrl_buffs_desc,
659 &ps_mres_output_data_buffs_desc->s_output_data_buffs[res_ctr][0],
660 &ps_mres_recon_data_buffs_desc->s_recon_data_buffs[res_ctr][0]);
661
662 /* set the number of Queues */
663 ps_enc_ctxt->s_enc_ques.i4_num_queues = IHEVCE_MAX_NUM_QUEUES;
664
665 /* allocate a mutex to take care of handling multiple threads accesing Queues */
666 /*my understanding, this is common semaphore for all the queue. Since main input is still
667 common across all instance fo encoder. Hence common semaphore is a must*/
668 if(0 == res_ctr)
669 {
670 ps_enc_ctxt->s_enc_ques.pv_q_mutex_hdl = osal_mutex_create(ps_hle_ctxt->pv_osal_handle);
671 /* store it in local variable for allocating it to other instances */
672 pv_q_mutex_hdl = ps_enc_ctxt->s_enc_ques.pv_q_mutex_hdl;
673 if(NULL == pv_q_mutex_hdl)
674 {
675 return IV_FAIL;
676 }
677 }
678 else
679 {
680 ps_enc_ctxt->s_enc_ques.pv_q_mutex_hdl = pv_q_mutex_hdl;
681 }
682
683 /* Set the i/o queues created status to 1 */
684 ps_enc_ctxt->i4_io_queues_created = 1;
685 }
686 return (IV_SUCCESS);
687 }
688
689 /*!
690 ******************************************************************************
691 * \if Function name : ihevce_hle_interface_thrd \endif
692 *
693 * \brief
694 * High level encoder thread interface function
695 *
696 * \param[in] High level interface context pointer
697 *
698 * \return
699 * None
700 *
701 * \author
702 * Ittiam
703 *
704 *****************************************************************************
705 */
ihevce_hle_interface_thrd(void * pv_proc_intf_ctxt)706 WORD32 ihevce_hle_interface_thrd(void *pv_proc_intf_ctxt)
707 {
708 /* local variables */
709 WORD32 ctr, res_ctr;
710 ihevce_hle_ctxt_t *ps_hle_ctxt;
711 enc_ctxt_t *ps_enc_ctxt;
712 /* enc ctxt to store 0th instance's params which are required by all instances */
713 enc_ctxt_t *ps_enc_ctxt_base;
714 void *pv_lap_sem_hdl;
715 void *pv_enc_frame_process_sem_hdl;
716 void *pv_pre_enc_frame_process_sem_hdl;
717 void *apv_ent_coding_sem_hdl[IHEVCE_MAX_NUM_BITRATES];
718 void *pv_ent_common_mres_sem_hdl = NULL;
719 void *pv_out_common_mres_sem_hdl = NULL;
720
721 void *pv_inp_data_sem_hdl;
722 void *pv_lap_inp_data_sem_hdl;
723 void *pv_preenc_inp_data_sem_hdl;
724 void *pv_inp_ctrl_sem_hdl;
725 void *apv_out_stream_sem_hdl[IHEVCE_MAX_NUM_BITRATES];
726 void *apv_out_recon_sem_hdl[IHEVCE_MAX_NUM_BITRATES];
727 void *pv_out_ctrl_sts_sem_hdl;
728
729 lap_intface_t *ps_lap_interface_ctxt;
730 iv_mem_rec_t s_memtab;
731 WORD32 i4_num_bit_rate_instances[IHEVCE_MAX_NUM_RESOLUTIONS], i4_num_resolutions;
732 WORD32 i; //loop variable
733 WORD32 ai4_proc_count[MAX_NUMBER_PROC_GRPS] = { 0 }, i4_proc_grp_count;
734 WORD32 i4_acc_proc_num = 0;
735
736 /* Frame Encode processing threads & semaphores */
737 void *apv_enc_frm_proc_hdls[IHEVCE_MAX_NUM_RESOLUTIONS][MAX_NUM_FRM_PROC_THRDS_ENC];
738 frm_proc_thrd_ctxt_t
739 *aps_enc_frm_proc_thrd_ctxt[IHEVCE_MAX_NUM_RESOLUTIONS][MAX_NUM_FRM_PROC_THRDS_ENC];
740
741 /* Pre Frame Encode processing threads & semaphores */
742 void *apv_pre_enc_frm_proc_hdls[IHEVCE_MAX_NUM_RESOLUTIONS][MAX_NUM_FRM_PROC_THRDS_PRE_ENC];
743 frm_proc_thrd_ctxt_t
744 *aps_pre_enc_frm_proc_thrd_ctxt[IHEVCE_MAX_NUM_RESOLUTIONS][MAX_NUM_FRM_PROC_THRDS_PRE_ENC];
745
746 void *apv_entropy_thrd_hdls[IHEVCE_MAX_NUM_RESOLUTIONS][NUM_ENTROPY_THREADS];
747 frm_proc_thrd_ctxt_t *aps_entropy_thrd_ctxt[IHEVCE_MAX_NUM_RESOLUTIONS][NUM_ENTROPY_THREADS];
748
749 ps_hle_ctxt = (ihevce_hle_ctxt_t *)pv_proc_intf_ctxt;
750 ps_enc_ctxt_base = (enc_ctxt_t *)ps_hle_ctxt->apv_enc_hdl[0];
751 /* profile start */
752 PROFILE_START(&ps_hle_ctxt->profile_hle);
753 /* store default values of mem tab */
754 s_memtab.i4_size = sizeof(iv_mem_rec_t);
755 s_memtab.i4_mem_alignment = 4;
756
757 i4_num_resolutions = ps_enc_ctxt_base->ps_stat_prms->s_tgt_lyr_prms.i4_num_res_layers;
758 memset(
759 apv_entropy_thrd_hdls,
760 0,
761 IHEVCE_MAX_NUM_RESOLUTIONS * NUM_ENTROPY_THREADS * sizeof(void *));
762 memset(
763 apv_entropy_thrd_hdls,
764 0,
765 IHEVCE_MAX_NUM_RESOLUTIONS * NUM_ENTROPY_THREADS * sizeof(void *));
766 for(res_ctr = 0; res_ctr < i4_num_resolutions; res_ctr++)
767 {
768 i4_num_bit_rate_instances[res_ctr] =
769 ps_enc_ctxt_base->ps_stat_prms->s_tgt_lyr_prms.as_tgt_params[res_ctr]
770 .i4_num_bitrate_instances;
771 }
772 /* --------------------------------------------------------------------- */
773 /* Init number of threads for each stage */
774 /* --------------------------------------------------------------------- */
775
776 {
777 for(res_ctr = 0; res_ctr < i4_num_resolutions; res_ctr++)
778 {
779 ps_enc_ctxt = (enc_ctxt_t *)ps_hle_ctxt->apv_enc_hdl[res_ctr];
780 /* all the threads created will be made active */
781 ps_enc_ctxt->s_multi_thrd.i4_num_active_enc_thrds =
782 ps_enc_ctxt->s_multi_thrd.i4_num_enc_proc_thrds;
783
784 ps_enc_ctxt->s_multi_thrd.i4_num_active_pre_enc_thrds =
785 ps_enc_ctxt->s_multi_thrd.i4_num_pre_enc_proc_thrds;
786 }
787 }
788
789 /* --------------------------------------------------------------------- */
790 /* Multiple processing Threads Semaphores init */
791 /* --------------------------------------------------------------------- */
792 for(res_ctr = 0; res_ctr < i4_num_resolutions; res_ctr++)
793 {
794 osal_sem_attr_t attr = OSAL_DEFAULT_SEM_ATTR;
795
796 ps_enc_ctxt = (enc_ctxt_t *)ps_hle_ctxt->apv_enc_hdl[res_ctr];
797
798 attr.value = SEM_START_VALUE;
799
800 /* Create Semaphore handle for LAP thread */
801 if(0 == ps_enc_ctxt->i4_resolution_id)
802 {
803 pv_lap_sem_hdl = osal_sem_create(ps_hle_ctxt->pv_osal_handle, &attr);
804 if(NULL == pv_lap_sem_hdl)
805 {
806 return IV_FAIL;
807 }
808 }
809 else
810 {
811 /*NOTE: Tile workspace assigned this to null. Confirm this*/
812 pv_lap_sem_hdl = ps_enc_ctxt_base->s_thrd_sem_ctxt.pv_lap_sem_handle;
813 }
814 /* Create Semaphore for encode frame process thread */
815 pv_enc_frame_process_sem_hdl = osal_sem_create(ps_hle_ctxt->pv_osal_handle, &attr);
816 if(NULL == pv_enc_frame_process_sem_hdl)
817 {
818 return IV_FAIL;
819 }
820
821 /* Create Semaphore for pre_encode frame process thread */
822 pv_pre_enc_frame_process_sem_hdl = osal_sem_create(ps_hle_ctxt->pv_osal_handle, &attr);
823 if(NULL == pv_pre_enc_frame_process_sem_hdl)
824 {
825 return IV_FAIL;
826 }
827
828 /* Create Semaphore for input frame data q function */
829 if(0 == ps_enc_ctxt->i4_resolution_id)
830 {
831 pv_inp_data_sem_hdl = osal_sem_create(ps_hle_ctxt->pv_osal_handle, &attr);
832 if(NULL == pv_inp_data_sem_hdl)
833 {
834 return IV_FAIL;
835 }
836 }
837 else
838 {
839 pv_inp_data_sem_hdl = ps_enc_ctxt_base->s_thrd_sem_ctxt.pv_inp_data_sem_handle;
840 }
841
842 /*creating new input queue owned by encoder*/
843 /* Create Semaphore for input frame data q function */
844 pv_lap_inp_data_sem_hdl = osal_sem_create(ps_hle_ctxt->pv_osal_handle, &attr);
845 if(NULL == pv_lap_inp_data_sem_hdl)
846 {
847 return IV_FAIL;
848 }
849
850 /* Create Semaphore for input frame data q function */
851 pv_preenc_inp_data_sem_hdl = osal_sem_create(ps_hle_ctxt->pv_osal_handle, &attr);
852 if(NULL == pv_preenc_inp_data_sem_hdl)
853 {
854 return IV_FAIL;
855 }
856
857 /* Create Semaphore for input conrol data q function */
858 if(0 == ps_enc_ctxt->i4_resolution_id)
859 {
860 pv_inp_ctrl_sem_hdl = osal_sem_create(ps_hle_ctxt->pv_osal_handle, &attr);
861 if(NULL == pv_inp_ctrl_sem_hdl)
862 {
863 return IV_FAIL;
864 }
865 }
866 else
867 { /*Inp ctrl queue is same for all resolutions between app and lap*/
868 pv_inp_ctrl_sem_hdl = ps_enc_ctxt_base->s_thrd_sem_ctxt.pv_inp_ctrl_sem_handle;
869 }
870
871 /* Create Semaphore for output control status data q function */
872 pv_out_ctrl_sts_sem_hdl = osal_sem_create(ps_hle_ctxt->pv_osal_handle, &attr);
873 if(NULL == pv_out_ctrl_sts_sem_hdl)
874 {
875 return IV_FAIL;
876 }
877
878 /* Multi res single output case singel output queue is used for all output resolutions */
879 if(1 == ps_enc_ctxt_base->ps_stat_prms->s_tgt_lyr_prms.i4_mres_single_out)
880 {
881 ps_enc_ctxt->s_enc_ques.apv_q_hdl[IHEVCE_OUTPUT_DATA_Q] =
882 ps_enc_ctxt_base->s_enc_ques.apv_q_hdl[IHEVCE_OUTPUT_DATA_Q];
883 if(0 == ps_enc_ctxt->i4_resolution_id)
884 {
885 /* Create Semaphore for enropy coding thread */
886 pv_ent_common_mres_sem_hdl = osal_sem_create(ps_hle_ctxt->pv_osal_handle, &attr);
887 if(NULL == pv_ent_common_mres_sem_hdl)
888 {
889 return IV_FAIL;
890 }
891
892 /* Create Semaphore for output stream data q function */
893 pv_out_common_mres_sem_hdl = osal_sem_create(ps_hle_ctxt->pv_osal_handle, &attr);
894 if(NULL == pv_out_common_mres_sem_hdl)
895 {
896 return IV_FAIL;
897 }
898 }
899 ps_enc_ctxt->s_thrd_sem_ctxt.pv_ent_common_mres_sem_hdl = pv_ent_common_mres_sem_hdl;
900 ps_enc_ctxt->s_thrd_sem_ctxt.pv_out_common_mres_sem_hdl = pv_out_common_mres_sem_hdl;
901 }
902
903 /*create entropy and output semaphores for each thread.
904 Each thread will correspond to each bit-rate instance running */
905 for(i = 0; i < i4_num_bit_rate_instances[res_ctr]; i++)
906 {
907 /* Create Semaphore for enropy coding thread */
908 apv_ent_coding_sem_hdl[i] = osal_sem_create(ps_hle_ctxt->pv_osal_handle, &attr);
909 if(NULL == apv_ent_coding_sem_hdl[i])
910 {
911 return IV_FAIL;
912 }
913
914 /* Create Semaphore for output stream data q function */
915 apv_out_stream_sem_hdl[i] = osal_sem_create(ps_hle_ctxt->pv_osal_handle, &attr);
916 if(NULL == apv_out_stream_sem_hdl[i])
917 {
918 return IV_FAIL;
919 }
920
921 /* Create Semaphore for output recon data q function */
922 apv_out_recon_sem_hdl[i] = osal_sem_create(ps_hle_ctxt->pv_osal_handle, &attr);
923 if(NULL == apv_out_recon_sem_hdl[i])
924 {
925 return IV_FAIL;
926 }
927 }
928
929 /* update the semaphore handles and the thread creates status */
930
931 ps_enc_ctxt->s_thrd_sem_ctxt.pv_enc_frm_proc_sem_handle = pv_enc_frame_process_sem_hdl;
932 ps_enc_ctxt->s_thrd_sem_ctxt.pv_pre_enc_frm_proc_sem_handle =
933 pv_pre_enc_frame_process_sem_hdl;
934 ps_enc_ctxt->s_thrd_sem_ctxt.pv_lap_sem_handle = pv_lap_sem_hdl;
935 ps_enc_ctxt->s_thrd_sem_ctxt.pv_inp_data_sem_handle = pv_inp_data_sem_hdl;
936 ps_enc_ctxt->s_thrd_sem_ctxt.pv_lap_inp_data_sem_hdl = pv_lap_inp_data_sem_hdl;
937 ps_enc_ctxt->s_thrd_sem_ctxt.pv_preenc_inp_data_sem_hdl = pv_preenc_inp_data_sem_hdl;
938 ps_enc_ctxt->s_thrd_sem_ctxt.pv_inp_ctrl_sem_handle = pv_inp_ctrl_sem_hdl;
939 ps_enc_ctxt->s_thrd_sem_ctxt.pv_out_ctrl_sem_handle = pv_out_ctrl_sts_sem_hdl;
940 for(i = 0; i < i4_num_bit_rate_instances[res_ctr]; i++)
941 {
942 ps_enc_ctxt->s_thrd_sem_ctxt.apv_ent_cod_sem_handle[i] = apv_ent_coding_sem_hdl[i];
943 ps_enc_ctxt->s_thrd_sem_ctxt.apv_out_strm_sem_handle[i] = apv_out_stream_sem_hdl[i];
944 ps_enc_ctxt->s_thrd_sem_ctxt.apv_out_recon_sem_handle[i] = apv_out_recon_sem_hdl[i];
945 }
946 }
947
948 /* --------------------------------------------------------------------- */
949 /* Multiple processing Threads Mutex init */
950 /* --------------------------------------------------------------------- */
951 for(res_ctr = 0; res_ctr < i4_num_resolutions; res_ctr++)
952 {
953 ps_enc_ctxt = (enc_ctxt_t *)ps_hle_ctxt->apv_enc_hdl[res_ctr];
954
955 /* create a mutex lock for Job Queue access accross slave threads of encode frame processing */
956 ps_enc_ctxt->s_multi_thrd.pv_job_q_mutex_hdl_enc_grp_me =
957 osal_mutex_create(ps_hle_ctxt->pv_osal_handle);
958 if(NULL == ps_enc_ctxt->s_multi_thrd.pv_job_q_mutex_hdl_enc_grp_me)
959 {
960 return IV_FAIL;
961 }
962
963 /* create a mutex lock for Job Queue access accross slave threads of encode frame processing */
964 ps_enc_ctxt->s_multi_thrd.pv_job_q_mutex_hdl_enc_grp_enc_loop =
965 osal_mutex_create(ps_hle_ctxt->pv_osal_handle);
966 if(NULL == ps_enc_ctxt->s_multi_thrd.pv_job_q_mutex_hdl_enc_grp_enc_loop)
967 {
968 return IV_FAIL;
969 }
970
971 /* create mutex for enc thread group */
972 for(i = 0; i < MAX_NUM_ME_PARALLEL; i++)
973 {
974 ps_enc_ctxt->s_multi_thrd.apv_mutex_handle[i] =
975 osal_mutex_create(ps_hle_ctxt->pv_osal_handle);
976 if(NULL == ps_enc_ctxt->s_multi_thrd.apv_mutex_handle[i])
977 {
978 return IV_FAIL;
979 }
980
981 ps_enc_ctxt->s_multi_thrd.apv_mutex_handle_me_end[i] =
982 osal_mutex_create(ps_hle_ctxt->pv_osal_handle);
983 if(NULL == ps_enc_ctxt->s_multi_thrd.apv_mutex_handle_me_end[i])
984 {
985 return IV_FAIL;
986 }
987 }
988
989 for(i = 0; i < MAX_NUM_ENC_LOOP_PARALLEL; i++)
990 {
991 ps_enc_ctxt->s_multi_thrd.apv_post_enc_mutex_handle[i] =
992 osal_mutex_create(ps_hle_ctxt->pv_osal_handle);
993 if(NULL == ps_enc_ctxt->s_multi_thrd.apv_post_enc_mutex_handle[i])
994 {
995 return IV_FAIL;
996 }
997
998 ps_enc_ctxt->s_multi_thrd.apv_mutex_handle_frame_init[i] =
999 osal_mutex_create(ps_hle_ctxt->pv_osal_handle);
1000 if(NULL == ps_enc_ctxt->s_multi_thrd.apv_mutex_handle_frame_init[i])
1001 {
1002 return IV_FAIL;
1003 }
1004 }
1005
1006 /*initialize mutex for pre-enc group */
1007 ps_enc_ctxt->s_multi_thrd.pv_mutex_hdl_pre_enc_init =
1008 osal_mutex_create(ps_hle_ctxt->pv_osal_handle);
1009
1010 ps_enc_ctxt->s_multi_thrd.pv_mutex_hdl_pre_enc_decomp_deinit =
1011 osal_mutex_create(ps_hle_ctxt->pv_osal_handle);
1012
1013 ps_enc_ctxt->s_multi_thrd.pv_mutex_hdl_pre_enc_hme_init =
1014 osal_mutex_create(ps_hle_ctxt->pv_osal_handle);
1015
1016 ps_enc_ctxt->s_multi_thrd.pv_mutex_hdl_pre_enc_hme_deinit =
1017 osal_mutex_create(ps_hle_ctxt->pv_osal_handle);
1018
1019 ps_enc_ctxt->s_multi_thrd.pv_mutex_hdl_pre_enc_deinit =
1020 osal_mutex_create(ps_hle_ctxt->pv_osal_handle);
1021
1022 ps_enc_ctxt->s_multi_thrd.pv_mutex_hdl_l0_ipe_init =
1023 osal_mutex_create(ps_hle_ctxt->pv_osal_handle);
1024
1025 ps_enc_ctxt->s_multi_thrd.pv_job_q_mutex_hdl_pre_enc_decomp =
1026 osal_mutex_create(ps_hle_ctxt->pv_osal_handle);
1027
1028 ps_enc_ctxt->s_multi_thrd.pv_job_q_mutex_hdl_pre_enc_hme =
1029 osal_mutex_create(ps_hle_ctxt->pv_osal_handle);
1030
1031 ps_enc_ctxt->s_multi_thrd.pv_job_q_mutex_hdl_pre_enc_l0ipe =
1032 osal_mutex_create(ps_hle_ctxt->pv_osal_handle);
1033
1034 if(NULL == ps_enc_ctxt->s_multi_thrd.pv_mutex_hdl_pre_enc_init ||
1035 NULL == ps_enc_ctxt->s_multi_thrd.pv_mutex_hdl_pre_enc_decomp_deinit ||
1036 NULL == ps_enc_ctxt->s_multi_thrd.pv_mutex_hdl_pre_enc_hme_init ||
1037 NULL == ps_enc_ctxt->s_multi_thrd.pv_mutex_hdl_pre_enc_hme_deinit ||
1038 NULL == ps_enc_ctxt->s_multi_thrd.pv_mutex_hdl_pre_enc_deinit ||
1039 NULL == ps_enc_ctxt->s_multi_thrd.pv_mutex_hdl_l0_ipe_init ||
1040 NULL == ps_enc_ctxt->s_multi_thrd.pv_job_q_mutex_hdl_pre_enc_decomp ||
1041 NULL == ps_enc_ctxt->s_multi_thrd.pv_job_q_mutex_hdl_pre_enc_hme ||
1042 NULL == ps_enc_ctxt->s_multi_thrd.pv_job_q_mutex_hdl_pre_enc_l0ipe)
1043 {
1044 return IV_FAIL;
1045 }
1046 }
1047
1048 /* --------------------------------------------------------------------- */
1049 /* Multiple processing Threads Context init */
1050 /* --------------------------------------------------------------------- */
1051
1052 for(res_ctr = 0; res_ctr < i4_num_resolutions; res_ctr++)
1053 {
1054 ps_enc_ctxt = (enc_ctxt_t *)ps_hle_ctxt->apv_enc_hdl[res_ctr];
1055 ps_enc_ctxt_base = (enc_ctxt_t *)ps_hle_ctxt->apv_enc_hdl[0];
1056
1057 /*initialize multi-thread context for enc group*/
1058 ps_enc_ctxt->s_multi_thrd.i4_is_recon_free_done = 0;
1059 ps_enc_ctxt->s_multi_thrd.i4_idx_dvsr_p = 0;
1060 ps_enc_ctxt->s_multi_thrd.i4_last_inp_buf = 0;
1061
1062 {
1063 /* For all the ME frames in Parallel */
1064 WORD32 i4_frm_idx;
1065
1066 for(i4_frm_idx = 0; i4_frm_idx < MAX_NUM_ME_PARALLEL; i4_frm_idx++)
1067 {
1068 ps_enc_ctxt->s_multi_thrd.me_num_thrds_exited[i4_frm_idx] = 0;
1069 ps_enc_ctxt->s_multi_thrd.ai4_me_master_done_flag[i4_frm_idx] = 0;
1070 ps_enc_ctxt->s_multi_thrd.ai4_me_enc_buff_prod_flag[i4_frm_idx] = 0;
1071 }
1072 }
1073
1074 {
1075 WORD32 i4_frm_idx;
1076 ps_enc_ctxt->s_multi_thrd.num_thrds_done = 0;
1077 ps_enc_ctxt->s_multi_thrd.num_thrds_exited_for_reenc = 0;
1078 for(i4_frm_idx = 0; i4_frm_idx < MAX_NUM_ENC_LOOP_PARALLEL; i4_frm_idx++)
1079 {
1080 ps_enc_ctxt->s_multi_thrd.num_thrds_exited[i4_frm_idx] = 0;
1081
1082 ps_enc_ctxt->s_multi_thrd.enc_master_done_frame_init[i4_frm_idx] = 0;
1083
1084 for(i = 0; i < i4_num_bit_rate_instances[res_ctr]; i++)
1085 {
1086 /*reset the entropy buffer produced status */
1087 ps_enc_ctxt->s_multi_thrd.ai4_produce_outbuf[i4_frm_idx][i] = 1;
1088 ps_enc_ctxt->s_multi_thrd.ps_frm_recon[i4_frm_idx][i] = NULL;
1089
1090 ps_enc_ctxt->s_multi_thrd.ps_curr_out_enc_grp[i4_frm_idx][i] = NULL;
1091 }
1092 }
1093 }
1094 ps_enc_ctxt->s_multi_thrd.i4_seq_mode_enabled_flag = 0;
1095
1096 /* Set prev_frame_done = 1 to indicate that all the threads are in same frame*/
1097 for(i = 0; i < ps_enc_ctxt->s_multi_thrd.i4_num_enc_loop_frm_pllel; i++)
1098 {
1099 ihevce_dmgr_set_done_frm_frm_sync(
1100 ps_enc_ctxt->s_multi_thrd.apv_dep_mngr_prev_frame_done[i]);
1101 }
1102 /* Set prev_frame_done = 1 to indicate that all the threads are in same frame*/
1103 ihevce_dmgr_set_done_frm_frm_sync(
1104 ps_enc_ctxt->s_multi_thrd.pv_dep_mngr_prev_frame_enc_done_for_reenc);
1105 /*to enable the dependency manager to wait when first reached*/
1106 ihevce_dmgr_set_prev_done_frm_frm_sync(
1107 ps_enc_ctxt->s_multi_thrd.pv_dep_mngr_prev_frame_enc_done_for_reenc);
1108 for(i = 0; i < ps_enc_ctxt->s_multi_thrd.i4_num_me_frm_pllel; i++)
1109 {
1110 ihevce_dmgr_set_done_frm_frm_sync(
1111 ps_enc_ctxt->s_multi_thrd.apv_dep_mngr_prev_frame_me_done[i]);
1112 }
1113
1114 /* initialize multi-thread context for pre enc group */
1115
1116 ps_enc_ctxt->s_multi_thrd.i4_ctrl_blocking_mode = BUFF_QUE_BLOCKING_MODE;
1117
1118 for(ctr = 0; ctr < MAX_PRE_ENC_STAGGER + NUM_BUFS_DECOMP_HME; ctr++)
1119 {
1120 ps_enc_ctxt->s_multi_thrd.ai4_pre_enc_init_done[ctr] = 0;
1121 ps_enc_ctxt->s_multi_thrd.ai4_pre_enc_hme_init_done[ctr] = 0;
1122 ps_enc_ctxt->s_multi_thrd.ai4_pre_enc_deinit_done[ctr] = 1;
1123 ps_enc_ctxt->s_multi_thrd.ai4_num_thrds_processed_decomp[ctr] = 0;
1124 ps_enc_ctxt->s_multi_thrd.ai4_num_thrds_processed_coarse_me[ctr] = 0;
1125 ps_enc_ctxt->s_multi_thrd.ai4_num_thrds_processed_pre_enc[ctr] = 0;
1126
1127 ps_enc_ctxt->s_multi_thrd.ai4_num_thrds_processed_L0_ipe_qp_init[ctr] = 0;
1128 ps_enc_ctxt->s_multi_thrd.ai4_decomp_coarse_me_complete_flag[ctr] = 1;
1129 ps_enc_ctxt->s_multi_thrd.ai4_end_flag_pre_enc[ctr] = 0;
1130 }
1131
1132 /* Set prev_frame_done = 1 to indicate that all the threads are in same frame*/
1133 ihevce_dmgr_set_done_frm_frm_sync(
1134 ps_enc_ctxt->s_multi_thrd.pv_dep_mngr_prev_frame_pre_enc_l1);
1135
1136 ihevce_dmgr_set_done_frm_frm_sync(
1137 ps_enc_ctxt->s_multi_thrd.pv_dep_mngr_prev_frame_pre_enc_coarse_me);
1138
1139 ihevce_dmgr_set_done_frm_frm_sync(
1140 ps_enc_ctxt->s_multi_thrd.pv_dep_mngr_prev_frame_pre_enc_l0);
1141
1142 {
1143 /**init idx for handling delay between pre-me and l0-ipe*/
1144 ps_enc_ctxt->s_multi_thrd.i4_delay_pre_me_btw_l0_ipe = 0;
1145 ps_enc_ctxt->s_multi_thrd.i4_max_delay_pre_me_btw_l0_ipe =
1146 MIN_L1_L0_STAGGER_NON_SEQ +
1147 ps_enc_ctxt->s_lap_stat_prms.s_lap_params.i4_rc_look_ahead_pics + 1;
1148 if(ps_enc_ctxt->s_lap_stat_prms.s_lap_params.i4_rc_look_ahead_pics)
1149 {
1150 ps_enc_ctxt->s_multi_thrd.i4_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;
1153 }
1154 ps_enc_ctxt->s_multi_thrd.i4_qp_update_l0_ipe = -1;
1155 }
1156 }
1157
1158 /** Get Number of Processor Groups **/
1159 i4_proc_grp_count = ps_enc_ctxt_base->ps_stat_prms->s_multi_thrd_prms.i4_num_proc_groups;
1160 /*** Enc threads are allocated based on the assumption that there can be only 2 processor groups **/
1161 ASSERT(i4_proc_grp_count <= MAX_NUMBER_PROC_GRPS);
1162 /** Get Number of logical processors in Each Group **/
1163 for(ctr = 0; ctr < i4_proc_grp_count; ctr++)
1164 {
1165 ai4_proc_count[ctr] =
1166 ps_enc_ctxt_base->ps_stat_prms->s_multi_thrd_prms.ai4_num_cores_per_grp[ctr];
1167 }
1168
1169 /* --------------------------------------------------------------------- */
1170 /* Create a LAP thread */
1171 /* --------------------------------------------------------------------- */
1172 /* LAP thread will run on 0th resolution instance context */
1173 {
1174 s_memtab.e_mem_type = IV_EXT_CACHEABLE_NORMAL_MEM;
1175 s_memtab.i4_mem_size = sizeof(lap_intface_t);
1176
1177 /* initialise the interface strucure parameters */
1178 ps_hle_ctxt->ihevce_mem_alloc(
1179 ps_hle_ctxt->pv_mem_mgr_hdl, &ps_enc_ctxt_base->ps_stat_prms->s_sys_api, &s_memtab);
1180 if(s_memtab.pv_base == NULL)
1181 {
1182 return (IV_FAIL);
1183 }
1184
1185 ps_lap_interface_ctxt = (lap_intface_t *)s_memtab.pv_base;
1186
1187 /* populate the params */
1188 ps_lap_interface_ctxt->pv_hle_ctxt = ps_hle_ctxt;
1189 ps_enc_ctxt = (enc_ctxt_t *)ps_hle_ctxt->apv_enc_hdl[0];
1190 ps_lap_interface_ctxt->pv_lap_module_ctxt = ps_enc_ctxt->s_module_ctxt.pv_lap_ctxt;
1191 ps_lap_interface_ctxt->i4_ctrl_in_que_id = IHEVCE_INPUT_ASYNCH_CTRL_Q;
1192 ps_lap_interface_ctxt->i4_ctrl_out_que_id = IHEVCE_OUTPUT_STATUS_Q;
1193 ps_lap_interface_ctxt->i4_ctrl_cmd_buf_size = ENC_COMMAND_BUFF_SIZE;
1194 ps_lap_interface_ctxt->i4_ctrl_in_que_blocking_mode = BUFF_QUE_BLOCKING_MODE;
1195 ps_lap_interface_ctxt->ps_sys_api = &ps_enc_ctxt_base->ps_stat_prms->s_sys_api;
1196 ps_enc_ctxt_base->pv_lap_interface_ctxt = (void *)ps_lap_interface_ctxt;
1197 ps_lap_interface_ctxt->ihevce_dyn_bitrate_cb = ihevce_dyn_bitrate;
1198 }
1199
1200 /* --------------------------------------------------------------------- */
1201 /* Create Entropy Coding threads */
1202 /* --------------------------------------------------------------------- */
1203 /*Create entropy thread for each encoder instance*/
1204 for(res_ctr = 0; res_ctr < i4_num_resolutions; res_ctr++)
1205 {
1206 osal_thread_attr_t s_thread_attr = OSAL_DEFAULT_THREAD_ATTR;
1207 WORD32 i4_num_entropy_threads;
1208
1209 /* derive encoder ctxt from hle handle */
1210 ps_enc_ctxt = (enc_ctxt_t *)ps_hle_ctxt->apv_enc_hdl[res_ctr];
1211
1212 i4_num_entropy_threads =
1213 ps_enc_ctxt_base->ps_stat_prms->s_tgt_lyr_prms.as_tgt_params[res_ctr]
1214 .i4_num_bitrate_instances;
1215
1216 /* initialise the interface strucure parameters */
1217 for(ctr = 0; ctr < i4_num_entropy_threads; ctr++)
1218 {
1219 s_memtab.e_mem_type = IV_EXT_CACHEABLE_NORMAL_MEM;
1220 s_memtab.i4_mem_size = sizeof(frm_proc_thrd_ctxt_t);
1221
1222 ps_hle_ctxt->ihevce_mem_alloc(
1223 ps_hle_ctxt->pv_mem_mgr_hdl, &ps_enc_ctxt_base->ps_stat_prms->s_sys_api, &s_memtab);
1224 if(s_memtab.pv_base == NULL)
1225 {
1226 return (IV_FAIL);
1227 }
1228
1229 aps_entropy_thrd_ctxt[res_ctr][ctr] = (frm_proc_thrd_ctxt_t *)s_memtab.pv_base;
1230
1231 /* initialise the interface strucure parameters */
1232 aps_entropy_thrd_ctxt[res_ctr][ctr]->i4_thrd_id = ctr;
1233 aps_entropy_thrd_ctxt[res_ctr][ctr]->ps_hle_ctxt = ps_hle_ctxt;
1234 aps_entropy_thrd_ctxt[res_ctr][ctr]->pv_enc_ctxt = (void *)ps_enc_ctxt;
1235
1236 /* Initialize application thread attributes */
1237 s_thread_attr.exit_code = 0;
1238 s_thread_attr.name = 0;
1239 s_thread_attr.priority_map_flag = 1;
1240 s_thread_attr.priority = OSAL_PRIORITY_DEFAULT;
1241 s_thread_attr.stack_addr = 0;
1242 s_thread_attr.stack_size = THREAD_STACK_SIZE;
1243 s_thread_attr.thread_func = ihevce_ent_coding_thrd;
1244 s_thread_attr.thread_param =
1245 (void *)(aps_entropy_thrd_ctxt[res_ctr]
1246 [ctr]); //encioder and hle context are derived from this
1247 s_thread_attr.core_affinity_mask = 0;
1248 if(ps_enc_ctxt_base->ps_stat_prms->s_multi_thrd_prms.i4_num_proc_groups > 1)
1249 {
1250 /* Run ENTROPY thread on last group if there are more than one processor group */
1251 s_thread_attr.group_num =
1252 ps_hle_ctxt->ps_static_cfg_prms->s_multi_thrd_prms.i4_num_proc_groups - 1;
1253 }
1254 else
1255 {
1256 s_thread_attr.group_num = 0;
1257 }
1258
1259 /* Create entropy coding thread */
1260 apv_entropy_thrd_hdls[res_ctr][ctr] =
1261 osal_thread_create(ps_hle_ctxt->pv_osal_handle, &s_thread_attr);
1262 if(NULL == apv_entropy_thrd_hdls[res_ctr][ctr])
1263 {
1264 return IV_FAIL;
1265 }
1266 }
1267 }
1268
1269 /* --------------------------------------------------------------------- */
1270 /* Create all Slave Encode Frame processing threads */
1271 /* - -------------------------------------------------------------------- */
1272 for(res_ctr = 0; res_ctr < i4_num_resolutions; res_ctr++)
1273 {
1274 WORD32 enc_ctr = 0;
1275 WORD32 i4_loop_count;
1276 WORD32 i4_curr_grp_num = 0;
1277 ps_enc_ctxt = (enc_ctxt_t *)ps_hle_ctxt->apv_enc_hdl[res_ctr];
1278
1279 i4_acc_proc_num = 0;
1280 /* Calculate the start core number of enc threads for current resolution */
1281 for(i4_loop_count = 0; i4_loop_count < res_ctr; i4_loop_count++)
1282 {
1283 /* Add number of cores taken by each resolution till the curr resolution */
1284 enc_ctr += ps_hle_ctxt->ai4_num_core_per_res[i4_loop_count];
1285 }
1286 if(ps_enc_ctxt_base->ps_stat_prms->s_multi_thrd_prms.i4_num_proc_groups > 1)
1287 {
1288 /* Select the group number for each res based on processors present in each group */
1289 for(i4_loop_count = 0;
1290 i4_loop_count <
1291 ps_enc_ctxt_base->ps_stat_prms->s_multi_thrd_prms.i4_num_proc_groups;
1292 i4_loop_count++)
1293 {
1294 i4_acc_proc_num += ai4_proc_count[i4_loop_count];
1295 if(enc_ctr >= i4_acc_proc_num)
1296 {
1297 /* if enc_ctr is greater than proc count for first group,
1298 then increment group count.This group number will be starting grp num for
1299 that resolution */
1300 i4_curr_grp_num++;
1301 }
1302 else
1303 break;
1304 }
1305 }
1306
1307 for(ctr = 0; ctr < ps_enc_ctxt->s_multi_thrd.i4_num_enc_proc_thrds; ctr++)
1308 {
1309 osal_thread_attr_t s_thread_attr = OSAL_DEFAULT_THREAD_ATTR;
1310
1311 s_memtab.e_mem_type = IV_EXT_CACHEABLE_NORMAL_MEM;
1312 s_memtab.i4_mem_size = sizeof(frm_proc_thrd_ctxt_t);
1313
1314 ps_hle_ctxt->ihevce_mem_alloc(
1315 ps_hle_ctxt->pv_mem_mgr_hdl, &ps_enc_ctxt_base->ps_stat_prms->s_sys_api, &s_memtab);
1316 if(s_memtab.pv_base == NULL)
1317 {
1318 return (IV_FAIL);
1319 }
1320
1321 aps_enc_frm_proc_thrd_ctxt[res_ctr][ctr] = (frm_proc_thrd_ctxt_t *)s_memtab.pv_base;
1322
1323 /* initialise the interface strucure parameters */
1324 aps_enc_frm_proc_thrd_ctxt[res_ctr][ctr]->i4_thrd_id = ctr;
1325
1326 aps_enc_frm_proc_thrd_ctxt[res_ctr][ctr]->ps_hle_ctxt = ps_hle_ctxt;
1327
1328 ps_enc_ctxt = (enc_ctxt_t *)ps_hle_ctxt->apv_enc_hdl[res_ctr];
1329
1330 aps_enc_frm_proc_thrd_ctxt[res_ctr][ctr]->pv_enc_ctxt = (void *)ps_enc_ctxt;
1331
1332 /* Initialize application thread attributes */
1333 s_thread_attr.exit_code = 0;
1334 s_thread_attr.name = 0;
1335 s_thread_attr.priority_map_flag = 1;
1336 s_thread_attr.priority = OSAL_PRIORITY_DEFAULT;
1337 s_thread_attr.stack_addr = 0;
1338 s_thread_attr.stack_size = THREAD_STACK_SIZE;
1339 s_thread_attr.thread_func = ihevce_enc_frm_proc_slave_thrd;
1340 s_thread_attr.thread_param = (void *)(aps_enc_frm_proc_thrd_ctxt[res_ctr][ctr]);
1341 s_thread_attr.group_num = i4_curr_grp_num;
1342 if(1 == ps_enc_ctxt_base->ps_stat_prms->s_multi_thrd_prms.i4_use_thrd_affinity)
1343 {
1344 ihevce_static_multi_thread_params_t *ps_multi_thrd_prms =
1345 &ps_enc_ctxt_base->ps_stat_prms->s_multi_thrd_prms;
1346
1347 s_thread_attr.core_affinity_mask = ps_multi_thrd_prms->au8_core_aff_mask[enc_ctr];
1348 if((enc_ctr >= i4_acc_proc_num) &&
1349 (ps_enc_ctxt_base->ps_stat_prms->s_multi_thrd_prms.i4_num_proc_groups > 1))
1350 {
1351 /*** When the cores in the Group0 is exhausted start enc threads in the next Processor Group ***/
1352 s_thread_attr.group_num++;
1353 i4_curr_grp_num++;
1354 /* This takes care of the condition that differnt proc groups can have diff number of cores */
1355 i4_acc_proc_num += ai4_proc_count[i4_curr_grp_num];
1356 }
1357 }
1358 else
1359 {
1360 s_thread_attr.core_affinity_mask = 0;
1361 if((enc_ctr >= i4_acc_proc_num) &&
1362 (ps_enc_ctxt_base->ps_stat_prms->s_multi_thrd_prms.i4_num_proc_groups > 1))
1363 {
1364 /*** When the cores in the Group0 is exhausted start enc threads in the next Processor Group ***/
1365 s_thread_attr.group_num++;
1366 i4_curr_grp_num++;
1367 /* This takes care of the condition that differnt proc groups can have diff number of cores */
1368 i4_acc_proc_num += ai4_proc_count[i4_curr_grp_num];
1369 }
1370 }
1371
1372 /* Create frame processing thread */
1373 apv_enc_frm_proc_hdls[res_ctr][ctr] =
1374 osal_thread_create(ps_hle_ctxt->pv_osal_handle, &s_thread_attr);
1375 if(NULL == apv_enc_frm_proc_hdls[res_ctr][ctr])
1376 {
1377 return IV_FAIL;
1378 }
1379 enc_ctr++;
1380 }
1381 }
1382
1383 /* --------------------------------------------------------------------- */
1384 /* Create all Pre - Encode Frame processing threads */
1385 /* --------------------------------------------------------------------- */
1386 for(res_ctr = 0; res_ctr < i4_num_resolutions; res_ctr++)
1387 {
1388 WORD32 pre_enc_ctr = 0;
1389 WORD32 i4_loop_count;
1390 WORD32 i4_curr_grp_num = 0;
1391 ps_enc_ctxt = (enc_ctxt_t *)ps_hle_ctxt->apv_enc_hdl[res_ctr];
1392
1393 i4_acc_proc_num = 0;
1394
1395 for(i4_loop_count = 0; i4_loop_count < res_ctr; i4_loop_count++)
1396 pre_enc_ctr += ps_hle_ctxt->ai4_num_core_per_res[i4_loop_count];
1397 if(ps_enc_ctxt->s_multi_thrd.i4_all_thrds_active_flag)
1398 {
1399 /* If its sequential mode of operation enc and pre-enc threads to be given same core affinity mask */
1400 pre_enc_ctr -= ps_enc_ctxt->s_multi_thrd.i4_num_enc_proc_thrds;
1401 }
1402
1403 if(ps_enc_ctxt_base->ps_stat_prms->s_multi_thrd_prms.i4_num_proc_groups > 1)
1404 {
1405 /* Select the group number for each res based on processors present in each group */
1406 for(i4_loop_count = 0;
1407 i4_loop_count <
1408 ps_enc_ctxt_base->ps_stat_prms->s_multi_thrd_prms.i4_num_proc_groups;
1409 i4_loop_count++)
1410 {
1411 i4_acc_proc_num += ai4_proc_count[i4_loop_count];
1412 if((pre_enc_ctr + ps_enc_ctxt->s_multi_thrd.i4_num_enc_proc_thrds) >=
1413 i4_acc_proc_num)
1414 {
1415 /* if pre_enc_ctr is greater than proc count for first group,
1416 then increment group count.This group number will be starting grp num for
1417 that resolution */
1418 i4_curr_grp_num++;
1419 }
1420 else
1421 break;
1422 }
1423 }
1424
1425 for(ctr = 0; ctr < ps_enc_ctxt->s_multi_thrd.i4_num_pre_enc_proc_thrds; ctr++)
1426 {
1427 osal_thread_attr_t s_thread_attr = OSAL_DEFAULT_THREAD_ATTR;
1428
1429 s_memtab.e_mem_type = IV_EXT_CACHEABLE_NORMAL_MEM;
1430 s_memtab.i4_mem_size = sizeof(frm_proc_thrd_ctxt_t);
1431
1432 ps_hle_ctxt->ihevce_mem_alloc(
1433 ps_hle_ctxt->pv_mem_mgr_hdl, &ps_enc_ctxt_base->ps_stat_prms->s_sys_api, &s_memtab);
1434 if(s_memtab.pv_base == NULL)
1435 {
1436 return (IV_FAIL);
1437 }
1438
1439 aps_pre_enc_frm_proc_thrd_ctxt[res_ctr][ctr] = (frm_proc_thrd_ctxt_t *)s_memtab.pv_base;
1440
1441 /* initialise the interface strucure parameters */
1442 aps_pre_enc_frm_proc_thrd_ctxt[res_ctr][ctr]->i4_thrd_id = ctr;
1443
1444 aps_pre_enc_frm_proc_thrd_ctxt[res_ctr][ctr]->ps_hle_ctxt = ps_hle_ctxt;
1445 ps_enc_ctxt = (enc_ctxt_t *)ps_hle_ctxt->apv_enc_hdl[res_ctr];
1446 aps_pre_enc_frm_proc_thrd_ctxt[res_ctr][ctr]->pv_enc_ctxt = (void *)ps_enc_ctxt;
1447
1448 /* Initialize application thread attributes */
1449 s_thread_attr.exit_code = 0;
1450 s_thread_attr.name = 0;
1451 s_thread_attr.priority_map_flag = 1;
1452 s_thread_attr.priority = OSAL_PRIORITY_DEFAULT;
1453 s_thread_attr.stack_addr = 0;
1454 s_thread_attr.stack_size = THREAD_STACK_SIZE;
1455 s_thread_attr.thread_func = ihevce_pre_enc_process_frame_thrd;
1456 s_thread_attr.thread_param = (void *)(aps_pre_enc_frm_proc_thrd_ctxt[res_ctr][ctr]);
1457 s_thread_attr.group_num = i4_curr_grp_num;
1458
1459 if(1 == ps_enc_ctxt_base->ps_stat_prms->s_multi_thrd_prms.i4_use_thrd_affinity)
1460 {
1461 ihevce_static_multi_thread_params_t *ps_multi_thrd_prms =
1462 &ps_enc_ctxt_base->ps_stat_prms->s_multi_thrd_prms;
1463
1464 s_thread_attr.core_affinity_mask =
1465 ps_multi_thrd_prms->au8_core_aff_mask
1466 [pre_enc_ctr + ps_enc_ctxt->s_multi_thrd.i4_num_enc_proc_thrds];
1467 if(((pre_enc_ctr + ps_enc_ctxt->s_multi_thrd.i4_num_enc_proc_thrds) >=
1468 i4_acc_proc_num) &&
1469 (ps_enc_ctxt_base->ps_stat_prms->s_multi_thrd_prms.i4_num_proc_groups > 1))
1470 {
1471 /*** When the cores in the Group0 is exhausted start enc threads in the next Processor Group ***/
1472 s_thread_attr.group_num++;
1473 i4_curr_grp_num++;
1474 /* This takes care of the condition that differnt proc groups can have diff number of cores */
1475 i4_acc_proc_num += ai4_proc_count[i4_curr_grp_num];
1476 }
1477 }
1478 else
1479 {
1480 s_thread_attr.core_affinity_mask = 0;
1481
1482 if(((pre_enc_ctr + ps_enc_ctxt->s_multi_thrd.i4_num_enc_proc_thrds) >=
1483 i4_acc_proc_num) &&
1484 (ps_enc_ctxt_base->ps_stat_prms->s_multi_thrd_prms.i4_num_proc_groups > 1))
1485 {
1486 /*** When the cores in the Group0 is exhausted start enc threads in the next Processor Group ***/
1487 s_thread_attr.group_num++;
1488 i4_curr_grp_num++;
1489 /* This takes care of the condition that differnt proc groups can have diff number of cores */
1490 i4_acc_proc_num += ai4_proc_count[i4_curr_grp_num];
1491 }
1492 }
1493
1494 /* Create frame processing thread */
1495 apv_pre_enc_frm_proc_hdls[res_ctr][ctr] =
1496 osal_thread_create(ps_hle_ctxt->pv_osal_handle, &s_thread_attr);
1497 if(NULL == apv_pre_enc_frm_proc_hdls[res_ctr][ctr])
1498 {
1499 return IV_FAIL;
1500 }
1501 pre_enc_ctr++;
1502 }
1503 }
1504
1505 /* Set the threads init done Flag */
1506 ps_hle_ctxt->i4_hle_init_done = 1;
1507
1508 /* --------------------------------------------------------------------- */
1509 /* Wait and destroy Processing threads */
1510 /* --------------------------------------------------------------------- */
1511
1512 /* --------------------------------------------------------------------- */
1513 /* Frame process Pre - Encode threads destroy */
1514 /* --------------------------------------------------------------------- */
1515 for(res_ctr = 0; res_ctr < i4_num_resolutions; res_ctr++)
1516 {
1517 ps_enc_ctxt = (enc_ctxt_t *)ps_hle_ctxt->apv_enc_hdl[res_ctr];
1518
1519 for(ctr = 0; ctr < ps_enc_ctxt->s_multi_thrd.i4_num_pre_enc_proc_thrds; ctr++)
1520 {
1521 /* Wait for thread to complete */
1522 osal_thread_wait(apv_pre_enc_frm_proc_hdls[res_ctr][ctr]);
1523
1524 /* Destroy thread */
1525 osal_thread_destroy(apv_pre_enc_frm_proc_hdls[res_ctr][ctr]);
1526
1527 s_memtab.i4_mem_size = sizeof(frm_proc_thrd_ctxt_t);
1528 s_memtab.e_mem_type = IV_EXT_CACHEABLE_NORMAL_MEM;
1529 s_memtab.pv_base = (void *)aps_pre_enc_frm_proc_thrd_ctxt[res_ctr][ctr];
1530
1531 /* free the ctxt memory */
1532 ps_hle_ctxt->ihevce_mem_free(ps_hle_ctxt->pv_mem_mgr_hdl, &s_memtab);
1533 }
1534 }
1535
1536 /* --------------------------------------------------------------------- */
1537 /* Frame process Encode slave threads destroy */
1538 /* --------------------------------------------------------------------- */
1539 for(res_ctr = 0; res_ctr < i4_num_resolutions; res_ctr++)
1540 {
1541 ps_enc_ctxt = (enc_ctxt_t *)ps_hle_ctxt->apv_enc_hdl[res_ctr];
1542
1543 for(ctr = 0; ctr < ps_enc_ctxt->s_multi_thrd.i4_num_enc_proc_thrds; ctr++)
1544 {
1545 /* Wait for thread to complete */
1546 osal_thread_wait(apv_enc_frm_proc_hdls[res_ctr][ctr]);
1547
1548 /* Destroy thread */
1549 osal_thread_destroy(apv_enc_frm_proc_hdls[res_ctr][ctr]);
1550
1551 s_memtab.i4_mem_size = sizeof(frm_proc_thrd_ctxt_t);
1552 s_memtab.e_mem_type = IV_EXT_CACHEABLE_NORMAL_MEM;
1553 s_memtab.pv_base = (void *)aps_enc_frm_proc_thrd_ctxt[res_ctr][ctr];
1554
1555 /* free the ctxt memory */
1556 ps_hle_ctxt->ihevce_mem_free(ps_hle_ctxt->pv_mem_mgr_hdl, &s_memtab);
1557 }
1558 }
1559
1560 /* --------------------------------------------------------------------- */
1561 /* Entropy threads destroy */
1562 /* --------------------------------------------------------------------- */
1563 for(res_ctr = 0; res_ctr < i4_num_resolutions; res_ctr++)
1564 {
1565 WORD32 i4_num_bitrates =
1566 ps_enc_ctxt_base->ps_stat_prms->s_tgt_lyr_prms.as_tgt_params[res_ctr]
1567 .i4_num_bitrate_instances;
1568
1569 for(ctr = 0; ctr < i4_num_bitrates; ctr++)
1570 {
1571 /* Wait for Entropy Coding thread to complete */
1572 osal_thread_wait(apv_entropy_thrd_hdls[res_ctr][ctr]);
1573
1574 /* Destroy Entropy Coding thread */
1575 osal_thread_destroy(apv_entropy_thrd_hdls[res_ctr][ctr]);
1576
1577 //semaphore will come here
1578
1579 s_memtab.i4_mem_size = sizeof(frm_proc_thrd_ctxt_t);
1580 s_memtab.e_mem_type = IV_EXT_CACHEABLE_NORMAL_MEM;
1581 s_memtab.pv_base = (void *)aps_entropy_thrd_ctxt[res_ctr][ctr];
1582
1583 /* free the ctxt memory */
1584 ps_hle_ctxt->ihevce_mem_free(ps_hle_ctxt->pv_mem_mgr_hdl, &s_memtab);
1585 }
1586 }
1587
1588 s_memtab.i4_mem_size = sizeof(lap_intface_t);
1589 s_memtab.e_mem_type = IV_EXT_CACHEABLE_NORMAL_MEM;
1590 s_memtab.pv_base = (void *)ps_lap_interface_ctxt;
1591 ps_hle_ctxt->ihevce_mem_free(ps_hle_ctxt->pv_mem_mgr_hdl, &s_memtab);
1592 /* profile stop */
1593 PROFILE_STOP(&ps_hle_ctxt->profile_hle, NULL);
1594 return (0);
1595 }
1596
1597 /*!
1598 ******************************************************************************
1599 * \if Function name : ihevce_q_get_free_inp_data_buff \endif
1600 *
1601 * \brief
1602 * Gets a free buffer from the que requested
1603 *
1604 * \param[in] high level encoder context pointer
1605 * \param[in] pointer to return the buffer id
1606 * \param[in] blocking mode / non blocking mode
1607 *
1608 * \return
1609 * None
1610 *
1611 * \author
1612 * Ittiam
1613 *
1614 *****************************************************************************
1615 */
ihevce_q_get_free_inp_data_buff(ihevce_hle_ctxt_t * ps_hle_ctxt,WORD32 * pi4_buff_id,WORD32 i4_blocking_mode)1616 void *ihevce_q_get_free_inp_data_buff(
1617 ihevce_hle_ctxt_t *ps_hle_ctxt, WORD32 *pi4_buff_id, WORD32 i4_blocking_mode)
1618 {
1619 void *pv_ptr;
1620 enc_ctxt_t *ps_enc_ctxt;
1621 WORD32 i4_resolution_id = 0;
1622
1623 ps_enc_ctxt = (enc_ctxt_t *)ps_hle_ctxt->apv_enc_hdl[i4_resolution_id];
1624 if(ps_enc_ctxt->i4_frame_limit_reached == 1)
1625 {
1626 return (NULL);
1627 }
1628 /*Input buffer is same for all enc handles*/
1629 pv_ptr = ihevce_q_get_free_buff(
1630 ps_hle_ctxt->apv_enc_hdl[0], IHEVCE_INPUT_DATA_CTRL_Q, pi4_buff_id, i4_blocking_mode);
1631
1632 return (pv_ptr);
1633 }
1634
1635 /*!
1636 ******************************************************************************
1637 * \if Function name : ihevce_q_get_free_inp_ctrl_buff \endif
1638 *
1639 * \brief
1640 * Gets a free buffer from the que requested
1641 *
1642 * \param[in] high level encoder context pointer
1643 * \param[in] pointer to return the buffer id
1644 * \param[in] blocking mode / non blocking mode
1645 *
1646 * \return
1647 * None
1648 *
1649 * \author
1650 * Ittiam
1651 *
1652 *****************************************************************************
1653 */
ihevce_q_get_free_inp_ctrl_buff(ihevce_hle_ctxt_t * ps_hle_ctxt,WORD32 * pi4_buff_id,WORD32 i4_blocking_mode)1654 void *ihevce_q_get_free_inp_ctrl_buff(
1655 ihevce_hle_ctxt_t *ps_hle_ctxt, WORD32 *pi4_buff_id, WORD32 i4_blocking_mode)
1656 {
1657 void *pv_ptr;
1658
1659 /*Input buffer is same for all enc handles*/
1660 pv_ptr = ihevce_q_get_free_buff(
1661 ps_hle_ctxt->apv_enc_hdl[0], IHEVCE_INPUT_ASYNCH_CTRL_Q, pi4_buff_id, i4_blocking_mode);
1662
1663 return (pv_ptr);
1664 }
1665
1666 /*!
1667 ******************************************************************************
1668 * \if Function name : ihevce_q_get_free_out_strm_buff \endif
1669 *
1670 * \brief
1671 * Gets a free buffer from the que requested
1672 *
1673 * \param[in] high level encoder context pointer
1674 * \param[in] pointer to return the buffer id
1675 * \param[in] blocking mode / non blocking mode
1676 *
1677 * \return
1678 * None
1679 *
1680 * \author
1681 * Ittiam
1682 *
1683 *****************************************************************************
1684 */
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)1685 void *ihevce_q_get_free_out_strm_buff(
1686 ihevce_hle_ctxt_t *ps_hle_ctxt,
1687 WORD32 *pi4_buff_id,
1688 WORD32 i4_blocking_mode,
1689 WORD32 i4_bitrate_instance,
1690 WORD32 i4_res_instance)
1691 {
1692 void *pv_ptr;
1693
1694 pv_ptr = ihevce_q_get_free_buff(
1695 ps_hle_ctxt->apv_enc_hdl[i4_res_instance],
1696 (IHEVCE_OUTPUT_DATA_Q + i4_bitrate_instance),
1697 pi4_buff_id,
1698 i4_blocking_mode);
1699 return (pv_ptr);
1700 }
1701
1702 /*!
1703 ******************************************************************************
1704 * \if Function name : ihevce_q_get_free_out_recon_buff \endif
1705 *
1706 * \brief
1707 * Gets a free buffer from the que requested
1708 *
1709 * \param[in] high level encoder context pointer
1710 * \param[in] pointer to return the buffer id
1711 * \param[in] blocking mode / non blocking mode
1712 *
1713 * \return
1714 * None
1715 *
1716 * \author
1717 * Ittiam
1718 *
1719 *****************************************************************************
1720 */
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)1721 void *ihevce_q_get_free_out_recon_buff(
1722 ihevce_hle_ctxt_t *ps_hle_ctxt,
1723 WORD32 *pi4_buff_id,
1724 WORD32 i4_blocking_mode,
1725 WORD32 i4_bitrate_instance,
1726 WORD32 i4_res_instance)
1727 {
1728 void *pv_ptr;
1729
1730 pv_ptr = ihevce_q_get_free_buff(
1731 ps_hle_ctxt->apv_enc_hdl[i4_res_instance],
1732 (IHEVCE_RECON_DATA_Q + i4_bitrate_instance),
1733 pi4_buff_id,
1734 i4_blocking_mode);
1735 return (pv_ptr);
1736 }
1737
1738 /*!
1739 ******************************************************************************
1740 * \if Function name : ihevce_q_set_inp_data_buff_prod \endif
1741 *
1742 * \brief
1743 * Sets the input data buffer as produced in the que requested
1744 *
1745 * \param[in] high level encoder context pointer
1746 * \param[in] buffer id which needs to be set as produced
1747 *
1748 * \return
1749 * None
1750 *
1751 * \author
1752 * Ittiam
1753 *
1754 *****************************************************************************
1755 */
1756 IV_API_CALL_STATUS_T
ihevce_q_set_inp_data_buff_prod(ihevce_hle_ctxt_t * ps_hle_ctxt,WORD32 i4_buff_id)1757 ihevce_q_set_inp_data_buff_prod(ihevce_hle_ctxt_t *ps_hle_ctxt, WORD32 i4_buff_id)
1758 {
1759 IV_API_CALL_STATUS_T ret_status;
1760
1761 ret_status =
1762 ihevce_q_set_buff_prod(ps_hle_ctxt->apv_enc_hdl[0], IHEVCE_INPUT_DATA_CTRL_Q, i4_buff_id);
1763
1764 return (ret_status);
1765 }
1766
1767 /*!
1768 ******************************************************************************
1769 * \if Function name : ihevce_q_set_inp_ctrl_buff_prod \endif
1770 *
1771 * \brief
1772 * Sets the input data buffer as produced in the que requested
1773 *
1774 * \param[in] high level encoder context pointer
1775 * \param[in] buffer id which needs to be set as produced
1776 *
1777 * \return
1778 * None
1779 *
1780 * \author
1781 * Ittiam
1782 *
1783 *****************************************************************************
1784 */
1785 IV_API_CALL_STATUS_T
ihevce_q_set_inp_ctrl_buff_prod(ihevce_hle_ctxt_t * ps_hle_ctxt,WORD32 i4_buff_id)1786 ihevce_q_set_inp_ctrl_buff_prod(ihevce_hle_ctxt_t *ps_hle_ctxt, WORD32 i4_buff_id)
1787
1788 {
1789 IV_API_CALL_STATUS_T ret_status;
1790
1791 ret_status =
1792 ihevce_q_set_buff_prod(ps_hle_ctxt->apv_enc_hdl[0], IHEVCE_INPUT_ASYNCH_CTRL_Q, i4_buff_id);
1793
1794 return (ret_status);
1795 }
1796
1797 /*!
1798 ******************************************************************************
1799 * \if Function name : ihevce_q_set_out_strm_buff_prod \endif
1800 *
1801 * \brief
1802 * Sets the Output stream buffer as produced in the que requested
1803 *
1804 * \param[in] high level encoder context pointer
1805 * \param[in] buffer id which needs to be set as produced
1806 *
1807 * \return
1808 * None
1809 *
1810 * \author
1811 * Ittiam
1812 *
1813 *****************************************************************************
1814 */
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)1815 IV_API_CALL_STATUS_T ihevce_q_set_out_strm_buff_prod(
1816 ihevce_hle_ctxt_t *ps_hle_ctxt,
1817 WORD32 i4_buff_id,
1818 WORD32 i4_bitrate_instance_id,
1819 WORD32 i4_resolution_id)
1820 {
1821 IV_API_CALL_STATUS_T ret_status;
1822
1823 ret_status = ihevce_q_set_buff_prod(
1824 ps_hle_ctxt->apv_enc_hdl[i4_resolution_id],
1825 (IHEVCE_OUTPUT_DATA_Q + i4_bitrate_instance_id),
1826 i4_buff_id);
1827
1828 return (ret_status);
1829 }
1830
1831 /*!
1832 ******************************************************************************
1833 * \if Function name : ihevce_q_set_out_recon_buff_prod \endif
1834 *
1835 * \brief
1836 * Sets the Output recon buffer as produced in the que requested
1837 *
1838 * \param[in] high level encoder context pointer
1839 * \param[in] buffer id which needs to be set as produced
1840 *
1841 * \return
1842 * None
1843 *
1844 * \author
1845 * Ittiam
1846 *
1847 *****************************************************************************
1848 */
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)1849 IV_API_CALL_STATUS_T ihevce_q_set_out_recon_buff_prod(
1850 ihevce_hle_ctxt_t *ps_hle_ctxt,
1851 WORD32 i4_buff_id,
1852 WORD32 i4_bitrate_instance_id,
1853 WORD32 i4_resolution_id)
1854 {
1855 IV_API_CALL_STATUS_T ret_status;
1856
1857 ret_status = ihevce_q_set_buff_prod(
1858 ps_hle_ctxt->apv_enc_hdl[i4_resolution_id],
1859 (IHEVCE_RECON_DATA_Q + i4_bitrate_instance_id),
1860 i4_buff_id);
1861
1862 return (ret_status);
1863 }
1864
1865 //recon_dump
1866 /*!
1867 ******************************************************************************
1868 * \if Function name : ihevce_q_get_filled_recon_buff \endif
1869 *
1870 * \brief
1871 * Gets a next filled recon buffer from the que requested
1872 *
1873 * \param[in] high level encoder context pointer
1874 * \param[in] pointer to return the buffer id
1875 * \param[in] blocking mode / non blocking mode
1876 *
1877 * \return
1878 * None
1879 *
1880 * \author
1881 * Ittiam
1882 *
1883 *****************************************************************************
1884 */
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)1885 void *ihevce_q_get_filled_recon_buff(
1886 ihevce_hle_ctxt_t *ps_hle_ctxt,
1887 WORD32 *pi4_buff_id,
1888 WORD32 i4_blocking_mode,
1889 WORD32 i4_bitrate_instance_id,
1890 WORD32 i4_resolution_id)
1891 {
1892 void *pv_ptr;
1893
1894 pv_ptr = ihevce_q_get_filled_buff(
1895 ps_hle_ctxt->apv_enc_hdl[i4_resolution_id],
1896 IHEVCE_RECON_DATA_Q + i4_bitrate_instance_id,
1897 pi4_buff_id,
1898 i4_blocking_mode);
1899
1900 return (pv_ptr);
1901 }
1902
1903 /*!
1904 ******************************************************************************
1905 * \if Function name : ihevce_q_get_filled_ctrl_sts_buff \endif
1906 *
1907 * \brief
1908 * Gets a next filled control status buffer from the que requested
1909 *
1910 * \param[in] high level encoder context pointer
1911 * \param[in] pointer to return the buffer id
1912 * \param[in] blocking mode / non blocking mode
1913 *
1914 * \return
1915 * None
1916 *
1917 * \author
1918 * Ittiam
1919 *
1920 *****************************************************************************
1921 */
ihevce_q_get_filled_ctrl_sts_buff(ihevce_hle_ctxt_t * ps_hle_ctxt,WORD32 * pi4_buff_id,WORD32 i4_blocking_mode)1922 void *ihevce_q_get_filled_ctrl_sts_buff(
1923 ihevce_hle_ctxt_t *ps_hle_ctxt, WORD32 *pi4_buff_id, WORD32 i4_blocking_mode)
1924 {
1925 void *pv_ptr;
1926 pv_ptr = ihevce_q_get_filled_buff(
1927 ps_hle_ctxt->apv_enc_hdl[0], IHEVCE_OUTPUT_STATUS_Q, pi4_buff_id, i4_blocking_mode);
1928
1929 return (pv_ptr);
1930 }
1931
1932 //recon_dump
1933 /*!
1934 ******************************************************************************
1935 * \if Function name : ihevce_q_rel_recon_buf \endif
1936 *
1937 * \brief
1938 * Frees the recon buffer in the recon buffer que
1939 *
1940 * \param[in] high level encoder context pointer
1941 * \param[in] buffer id which needs to be freed
1942 *
1943 * \return
1944 * None
1945 *
1946 * \author
1947 * Ittiam
1948 *
1949 *****************************************************************************
1950 */
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)1951 IV_API_CALL_STATUS_T ihevce_q_rel_recon_buf(
1952 ihevce_hle_ctxt_t *ps_hle_ctxt,
1953 WORD32 i4_buff_id,
1954 WORD32 i4_bitrate_instance_id,
1955 WORD32 i4_resolution_id)
1956 {
1957 IV_API_CALL_STATUS_T ret_status;
1958
1959 ret_status = ihevce_q_rel_buf(
1960 ps_hle_ctxt->apv_enc_hdl[i4_resolution_id],
1961 IHEVCE_RECON_DATA_Q + i4_bitrate_instance_id,
1962 i4_buff_id);
1963
1964 return (ret_status);
1965 }
1966
1967 /*!
1968 ******************************************************************************
1969 * \if Function name : ihevce_q_rel_ctrl_sts_buf \endif
1970 *
1971 * \brief
1972 * Frees the output control sttus buffer in buffer que
1973 *
1974 * \param[in] high level encoder context pointer
1975 * \param[in] buffer id which needs to be freed
1976 *
1977 * \return
1978 * None
1979 *
1980 * \author
1981 * Ittiam
1982 *
1983 *****************************************************************************
1984 */
ihevce_q_rel_ctrl_sts_buf(ihevce_hle_ctxt_t * ps_hle_ctxt,WORD32 i4_buff_id)1985 IV_API_CALL_STATUS_T ihevce_q_rel_ctrl_sts_buf(ihevce_hle_ctxt_t *ps_hle_ctxt, WORD32 i4_buff_id)
1986 {
1987 IV_API_CALL_STATUS_T ret_status;
1988
1989 ret_status = ihevce_q_rel_buf(ps_hle_ctxt->apv_enc_hdl[0], IHEVCE_OUTPUT_STATUS_Q, i4_buff_id);
1990
1991 return (ret_status);
1992 }
1993
1994 /*!
1995 ******************************************************************************
1996 * \if Function name : ihevce_hle_interface_delete \endif
1997 *
1998 * \brief
1999 * High leve encoder delete interface
2000 *
2001 * \param[in] high level encoder interface context pointer
2002 *
2003 * \return
2004 * None
2005 *
2006 * \author
2007 * Ittiam
2008 *
2009 *****************************************************************************
2010 */
ihevce_hle_interface_delete(ihevce_hle_ctxt_t * ps_hle_ctxt)2011 IV_API_CALL_STATUS_T ihevce_hle_interface_delete(ihevce_hle_ctxt_t *ps_hle_ctxt)
2012 {
2013 /* local varaibles */
2014 enc_ctxt_t *ps_enc_ctxt;
2015 iv_mem_rec_t s_memtab;
2016 WORD32 ctr = 0, i, res_ctr, i4_num_resolutions;
2017 WORD32 ai4_num_bitrate_instances[IHEVCE_MAX_NUM_RESOLUTIONS] = { 1 };
2018
2019 i4_num_resolutions = ps_hle_ctxt->ps_static_cfg_prms->s_tgt_lyr_prms.i4_num_res_layers;
2020 for(ctr = 0; ctr < i4_num_resolutions; ctr++)
2021 {
2022 ai4_num_bitrate_instances[ctr] =
2023 ps_hle_ctxt->ps_static_cfg_prms->s_tgt_lyr_prms.as_tgt_params[ctr]
2024 .i4_num_bitrate_instances;
2025 }
2026
2027 for(res_ctr = 0; res_ctr < i4_num_resolutions && ps_hle_ctxt->apv_enc_hdl[res_ctr]; res_ctr++)
2028 {
2029 ps_enc_ctxt = (enc_ctxt_t *)ps_hle_ctxt->apv_enc_hdl[res_ctr];
2030
2031 if(res_ctr == 0)
2032 {
2033 osal_sem_destroy(ps_enc_ctxt->s_thrd_sem_ctxt.pv_lap_sem_handle);
2034 osal_sem_destroy(ps_enc_ctxt->s_thrd_sem_ctxt.pv_inp_data_sem_handle);
2035 osal_sem_destroy(ps_enc_ctxt->s_thrd_sem_ctxt.pv_inp_ctrl_sem_handle);
2036 if(1 == ps_hle_ctxt->ps_static_cfg_prms->s_tgt_lyr_prms.i4_mres_single_out)
2037 {
2038 osal_sem_destroy(ps_enc_ctxt->s_thrd_sem_ctxt.pv_ent_common_mres_sem_hdl);
2039 osal_sem_destroy(ps_enc_ctxt->s_thrd_sem_ctxt.pv_out_common_mres_sem_hdl);
2040 }
2041 }
2042
2043 osal_sem_destroy(ps_enc_ctxt->s_thrd_sem_ctxt.pv_lap_inp_data_sem_hdl);
2044 osal_sem_destroy(ps_enc_ctxt->s_thrd_sem_ctxt.pv_preenc_inp_data_sem_hdl);
2045
2046 osal_sem_destroy(ps_enc_ctxt->s_thrd_sem_ctxt.pv_enc_frm_proc_sem_handle);
2047 osal_sem_destroy(ps_enc_ctxt->s_thrd_sem_ctxt.pv_pre_enc_frm_proc_sem_handle);
2048
2049 osal_sem_destroy(ps_enc_ctxt->s_thrd_sem_ctxt.pv_out_ctrl_sem_handle);
2050
2051 for(i = 0; i < ps_hle_ctxt->ps_static_cfg_prms->s_tgt_lyr_prms.as_tgt_params[res_ctr]
2052 .i4_num_bitrate_instances;
2053 i++)
2054 {
2055 osal_sem_destroy(ps_enc_ctxt->s_thrd_sem_ctxt.apv_ent_cod_sem_handle[i]);
2056 osal_sem_destroy(ps_enc_ctxt->s_thrd_sem_ctxt.apv_out_strm_sem_handle[i]);
2057 osal_sem_destroy(ps_enc_ctxt->s_thrd_sem_ctxt.apv_out_recon_sem_handle[i]);
2058 }
2059
2060 /* destroy the mutex allocated for job queue usage encode group */
2061 osal_mutex_destroy(ps_enc_ctxt->s_multi_thrd.pv_job_q_mutex_hdl_enc_grp_me);
2062
2063 /* destroy the mutex allocated for job queue usage encode group */
2064 osal_mutex_destroy(ps_enc_ctxt->s_multi_thrd.pv_job_q_mutex_hdl_enc_grp_enc_loop);
2065
2066 /* destroy the mutexes allocated for enc thread group */
2067 for(i = 0; i < MAX_NUM_ME_PARALLEL; i++)
2068 {
2069 osal_mutex_destroy(ps_enc_ctxt->s_multi_thrd.apv_mutex_handle[i]);
2070
2071 osal_mutex_destroy(ps_enc_ctxt->s_multi_thrd.apv_mutex_handle_me_end[i]);
2072 }
2073
2074 for(i = 0; i < MAX_NUM_ENC_LOOP_PARALLEL; i++)
2075 {
2076 osal_mutex_destroy(ps_enc_ctxt->s_multi_thrd.apv_mutex_handle_frame_init[i]);
2077
2078 osal_mutex_destroy(ps_enc_ctxt->s_multi_thrd.apv_post_enc_mutex_handle[i]);
2079 }
2080
2081 /* destroy the mutex allocated for job queue, init and de-init
2082 usage pre enocde group */
2083 osal_mutex_destroy(ps_enc_ctxt->s_multi_thrd.pv_job_q_mutex_hdl_pre_enc_decomp);
2084 osal_mutex_destroy(ps_enc_ctxt->s_multi_thrd.pv_job_q_mutex_hdl_pre_enc_hme);
2085 osal_mutex_destroy(ps_enc_ctxt->s_multi_thrd.pv_job_q_mutex_hdl_pre_enc_l0ipe);
2086 osal_mutex_destroy(ps_enc_ctxt->s_multi_thrd.pv_mutex_hdl_pre_enc_init);
2087 osal_mutex_destroy(ps_enc_ctxt->s_multi_thrd.pv_mutex_hdl_pre_enc_decomp_deinit);
2088 osal_mutex_destroy(ps_enc_ctxt->s_multi_thrd.pv_mutex_hdl_pre_enc_hme_init);
2089 osal_mutex_destroy(ps_enc_ctxt->s_multi_thrd.pv_mutex_hdl_pre_enc_hme_deinit);
2090 osal_mutex_destroy(ps_enc_ctxt->s_multi_thrd.pv_mutex_hdl_l0_ipe_init);
2091 osal_mutex_destroy(ps_enc_ctxt->s_multi_thrd.pv_mutex_hdl_pre_enc_deinit);
2092
2093 /* destroy the EncLoop Module */
2094 /* Note : Only Destroys the resources allocated in the module like */
2095 /* semaphore,etc. Memory free is done separately using memtabs */
2096 ihevce_enc_loop_delete(ps_enc_ctxt->s_module_ctxt.pv_enc_loop_ctxt);
2097
2098 /* destroy the Coarse ME Module */
2099 /* Note : Only Destroys the resources allocated in the module like */
2100 /* semaphore,etc. Memory free is done separately using memtabs */
2101 ihevce_coarse_me_delete(
2102 ps_enc_ctxt->s_module_ctxt.pv_coarse_me_ctxt,
2103 ps_hle_ctxt->ps_static_cfg_prms,
2104 ps_enc_ctxt->i4_resolution_id);
2105 /* destroy semaphores for all the threads in pre-enc and enc */
2106 for(ctr = 0; ctr < ps_enc_ctxt->s_multi_thrd.i4_num_enc_proc_thrds; ctr++)
2107 {
2108 osal_sem_destroy(ps_enc_ctxt->s_multi_thrd.apv_enc_thrd_sem_handle[ctr]);
2109 }
2110
2111 for(ctr = 0; ctr < ps_enc_ctxt->s_multi_thrd.i4_num_pre_enc_proc_thrds; ctr++)
2112 {
2113 osal_sem_destroy(ps_enc_ctxt->s_multi_thrd.apv_pre_enc_thrd_sem_handle[ctr]);
2114 }
2115
2116 /* destroy the ME-EncLoop Dep Mngr */
2117 /* Note : Only Destroys the resources allocated in the module like */
2118 /* semaphore,etc. Memory free is done separately using memtabs */
2119 for(ctr = 0; ctr < NUM_ME_ENC_BUFS; ctr++)
2120 {
2121 ihevce_dmgr_del(ps_enc_ctxt->s_multi_thrd.apv_dep_mngr_encloop_dep_me[ctr]);
2122 }
2123 /* destroy the Prev. frame EncLoop Done Dep Mngr */
2124 /* Note : Only Destroys the resources allocated in the module like */
2125 /* semaphore,etc. Memory free is done separately using memtabs */
2126 for(i = 0; i < ps_enc_ctxt->s_multi_thrd.i4_num_enc_loop_frm_pllel; i++)
2127 {
2128 ihevce_dmgr_del(ps_enc_ctxt->s_multi_thrd.apv_dep_mngr_prev_frame_done[i]);
2129 }
2130 /* destroy the Prev. frame EncLoop Done for re-encode Dep Mngr */
2131 ihevce_dmgr_del(ps_enc_ctxt->s_multi_thrd.pv_dep_mngr_prev_frame_enc_done_for_reenc);
2132
2133 /* destroy the Prev. frame ME Done Dep Mngr */
2134 /* Note : Only Destroys the resources allocated in the module like */
2135 /* semaphore,etc. Memory free is done separately using memtabs */
2136 for(i = 0; i < ps_enc_ctxt->s_multi_thrd.i4_num_me_frm_pllel; i++)
2137 {
2138 ihevce_dmgr_del(ps_enc_ctxt->s_multi_thrd.apv_dep_mngr_prev_frame_me_done[i]);
2139 }
2140
2141 /* destroy the Prev. frame PreEnc L1 Done Dep Mngr */
2142 /* Note : Only Destroys the resources allocated in the module like */
2143 /* semaphore,etc. Memory free is done separately using memtabs */
2144 ihevce_dmgr_del(ps_enc_ctxt->s_multi_thrd.pv_dep_mngr_prev_frame_pre_enc_l1);
2145
2146 /* destroy the Prev. frame PreEnc HME 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_coarse_me);
2150
2151 /* destroy the Prev. frame PreEnc L0 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_l0);
2155
2156 /* destroy the ME-Prev Recon Dep Mngr */
2157 /* Note : Only Destroys the resources allocated in the module like */
2158 /* semaphore,etc. Memory free is done separately using memtabs */
2159 for(ctr = 0; ctr < ps_enc_ctxt->ai4_num_buf_recon_q[0]; ctr++)
2160 {
2161 ihevce_dmgr_del(ps_enc_ctxt->pps_recon_buf_q[0][ctr]->pv_dep_mngr_recon);
2162 }
2163
2164 /* destroy all the mutex created */
2165 if(res_ctr == 0)
2166 {
2167 if(NULL != ps_enc_ctxt->s_enc_ques.pv_q_mutex_hdl)
2168 {
2169 osal_mutex_destroy(ps_enc_ctxt->s_enc_ques.pv_q_mutex_hdl);
2170 }
2171 }
2172
2173 if(NULL != ps_enc_ctxt->pv_rc_mutex_lock_hdl)
2174 {
2175 osal_mutex_destroy(ps_enc_ctxt->pv_rc_mutex_lock_hdl);
2176 }
2177
2178 if(NULL != ps_enc_ctxt->s_multi_thrd.pv_sub_pic_rc_mutex_lock_hdl)
2179 {
2180 osal_mutex_destroy(ps_enc_ctxt->s_multi_thrd.pv_sub_pic_rc_mutex_lock_hdl);
2181 }
2182
2183 if(NULL != ps_enc_ctxt->s_multi_thrd.pv_sub_pic_rc_for_qp_update_mutex_lock_hdl)
2184 {
2185 osal_mutex_destroy(
2186 ps_enc_ctxt->s_multi_thrd.pv_sub_pic_rc_for_qp_update_mutex_lock_hdl);
2187 }
2188
2189 /* call the memrory free function */
2190 ihevce_mem_manager_free(ps_enc_ctxt, ps_hle_ctxt);
2191 if((1 == ps_hle_ctxt->ps_static_cfg_prms->s_tgt_lyr_prms.i4_mres_single_out) &&
2192 (res_ctr == 0))
2193 {
2194 s_memtab.i4_mem_size = sizeof(WORD32) * IHEVCE_MAX_NUM_RESOLUTIONS;
2195 s_memtab.i4_mem_alignment = 4;
2196 s_memtab.i4_size = sizeof(iv_mem_rec_t);
2197 s_memtab.e_mem_type = IV_EXT_CACHEABLE_NORMAL_MEM;
2198 s_memtab.pv_base = ps_enc_ctxt->s_multi_thrd.pi4_active_res_id;
2199 /* free active_res_id memory */
2200 ps_hle_ctxt->ihevce_mem_free(ps_hle_ctxt->pv_mem_mgr_hdl, &s_memtab);
2201 }
2202 if(res_ctr == (i4_num_resolutions - 1))
2203 {
2204 s_memtab.i4_mem_size = sizeof(ihevce_static_cfg_params_t);
2205 s_memtab.i4_mem_alignment = 4;
2206 s_memtab.i4_size = sizeof(iv_mem_rec_t);
2207 s_memtab.e_mem_type = IV_EXT_CACHEABLE_NORMAL_MEM;
2208 s_memtab.pv_base = ps_enc_ctxt->ps_stat_prms;
2209
2210 /* free the encoder context pointer */
2211 ps_hle_ctxt->ihevce_mem_free(ps_hle_ctxt->pv_mem_mgr_hdl, &s_memtab);
2212 }
2213 s_memtab.i4_mem_size = sizeof(enc_ctxt_t);
2214 s_memtab.i4_mem_alignment = 4;
2215 s_memtab.i4_size = sizeof(iv_mem_rec_t);
2216 s_memtab.e_mem_type = IV_EXT_CACHEABLE_NORMAL_MEM;
2217 s_memtab.pv_base = ps_enc_ctxt;
2218
2219 /* free the encoder context pointer */
2220 ps_hle_ctxt->ihevce_mem_free(ps_hle_ctxt->pv_mem_mgr_hdl, &s_memtab);
2221
2222 /* reset the encoder handle to NULL */
2223 ps_hle_ctxt->apv_enc_hdl[res_ctr] = NULL;
2224 }
2225 /* profile end */
2226 PROFILE_END(&ps_hle_ctxt->profile_hle, "hle interface thread active time");
2227 for(res_ctr = 0; res_ctr < i4_num_resolutions; res_ctr++)
2228 {
2229 WORD32 i4_br_id;
2230
2231 PROFILE_END(&ps_hle_ctxt->profile_pre_enc_l1l2[res_ctr], "pre enc l1l2 process");
2232 PROFILE_END(&ps_hle_ctxt->profile_pre_enc_l0ipe[res_ctr], "pre enc l0 ipe process");
2233 PROFILE_END(&ps_hle_ctxt->profile_enc_me[res_ctr], "enc me process");
2234 for(i4_br_id = 0; i4_br_id < ai4_num_bitrate_instances[res_ctr]; i4_br_id++)
2235 {
2236 PROFILE_END(&ps_hle_ctxt->profile_enc[res_ctr][i4_br_id], "enc loop process");
2237 PROFILE_END(&ps_hle_ctxt->profile_entropy[res_ctr][i4_br_id], "entropy process");
2238 }
2239 }
2240
2241 /* OSAL Delete */
2242 ihevce_osal_delete((void *)ps_hle_ctxt);
2243
2244 return (IV_SUCCESS);
2245 }
2246