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