Coverage Report

Created: 2026-02-14 06:43

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libhevc/encoder/ihevce_plugin.c
Line
Count
Source
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
182
#define CREATE_TIME_ALLOCATION_INPUT 1
97
182
#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
*/
130
void mem_mngr_alloc(void *pv_handle, ihevce_sys_api_t *ps_sys_api, iv_mem_rec_t *ps_memtab)
131
172k
{
132
172k
#ifndef X86_MINGW
133
172k
    WORD32 error, mem_alignment;
134
172k
#endif
135
136
172k
    (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
172k
    mem_alignment = ps_memtab->i4_mem_alignment;
142
172k
    mem_alignment = (mem_alignment >> 3) << 3;
143
172k
    if(mem_alignment == 0)
144
111k
    {
145
111k
        error = posix_memalign(&ps_memtab->pv_base, sizeof(void *), ps_memtab->i4_mem_size);
146
111k
    }
147
61.3k
    else
148
61.3k
    {
149
61.3k
        error = posix_memalign(&ps_memtab->pv_base, mem_alignment, ps_memtab->i4_mem_size);
150
61.3k
    }
151
172k
    if(error != 0)
152
0
    {
153
0
        ps_sys_api->ihevce_printf(ps_sys_api->pv_cb_handle, "posix_memalign error %d\n", error);
154
0
    }
155
172k
#endif
156
157
172k
    if(ps_memtab->pv_base == NULL)
158
0
    {
159
0
        ps_sys_api->ihevce_printf(
160
0
            ps_sys_api->pv_cb_handle, "IHEVCE ERROR: Unable to allocate memory\n");
161
0
        ASSERT(0);
162
0
    }
163
172k
    else
164
172k
    {
165
172k
        memset(ps_memtab->pv_base, 0, ps_memtab->i4_mem_size);
166
172k
    }
167
172k
    return;
168
172k
}
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
*/
191
void *memory_alloc(void *pv_handle, UWORD32 u4_size)
192
1.45k
{
193
1.45k
    (void)pv_handle;
194
1.45k
    void *pv_buf = malloc(u4_size);
195
1.45k
    if(pv_buf)
196
1.45k
    {
197
1.45k
        memset(pv_buf, 0, u4_size);
198
1.45k
    }
199
1.45k
    return (pv_buf);
200
1.45k
}
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
*/
221
void mem_mngr_free(void *pv_handle, iv_mem_rec_t *ps_memtab)
222
172k
{
223
172k
    (void)pv_handle;
224
#ifdef X86_MINGW
225
    _aligned_free(ps_memtab->pv_base);
226
#else
227
172k
    free(ps_memtab->pv_base);
228
172k
#endif
229
172k
    return;
230
172k
}
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
*/
251
void memory_free(void *pv_handle, void *pv_mem)
252
1.63k
{
253
1.63k
    (void)pv_handle;
254
1.63k
    free(pv_mem);
255
1.63k
    return;
256
1.63k
}
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
*/
275
IHEVCE_PLUGIN_STATUS_T ihevce_set_def_params(ihevce_static_cfg_params_t *ps_params)
276
182
{
277
182
    WORD32 i, j;
278
    /* sanity checks */
279
182
    if(NULL == ps_params)
280
0
        return (IHEVCE_EFAIL);
281
282
182
    memset(ps_params, 0, sizeof(*ps_params));
283
284
    /* initialsie all the parameters to default values */
285
182
    ps_params->i4_size = sizeof(ihevce_static_cfg_params_t);
286
182
    ps_params->i4_save_recon = 0;
287
182
    ps_params->i4_log_dump_level = 0;
288
182
    ps_params->i4_enable_logo = 0;
289
182
    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
182
    ps_params->i4_outbuf_buf_free_control = 1;
295
296
    /* coding tools parameters */
297
182
    ps_params->s_coding_tools_prms.i4_size = sizeof(ihevce_coding_params_t);
298
182
    ps_params->s_coding_tools_prms.i4_cropping_mode = 1;
299
182
    ps_params->s_coding_tools_prms.i4_deblocking_type = 0;
300
182
    ps_params->s_coding_tools_prms.i4_enable_entropy_sync = 0;
301
    // New IDR/CDR Params
302
182
    ps_params->s_coding_tools_prms.i4_max_closed_gop_period = 0;
303
182
    ps_params->s_coding_tools_prms.i4_min_closed_gop_period = 0;
304
182
    ps_params->s_coding_tools_prms.i4_max_cra_open_gop_period = 60;
305
182
    ps_params->s_coding_tools_prms.i4_max_i_open_gop_period = 0;
306
182
    ps_params->s_coding_tools_prms.i4_max_reference_frames = -1;
307
182
    ps_params->s_coding_tools_prms.i4_max_temporal_layers = 0;
308
182
    ps_params->s_coding_tools_prms.i4_slice_type = 0;
309
182
    ps_params->s_coding_tools_prms.i4_use_default_sc_mtx = 0;
310
182
    ps_params->s_coding_tools_prms.i4_weighted_pred_enable = 0;
311
182
    ps_params->s_coding_tools_prms.i4_vqet = 0;
312
313
182
    ps_params->e_arch_type = ARCH_NA;
314
315
    /* config parameters */
316
182
    ps_params->s_config_prms.i4_size = sizeof(ihevce_config_prms_t);
317
182
    ps_params->s_config_prms.i4_cu_level_rc = 1;
318
182
    ps_params->s_config_prms.i4_init_vbv_fullness = 0;
319
182
    ps_params->s_config_prms.i4_max_frame_qp = 51;
320
182
    ps_params->s_config_prms.i4_max_log2_cu_size = 6;
321
182
    ps_params->s_config_prms.i4_max_log2_tu_size = 5;
322
182
    ps_params->s_config_prms.i4_max_search_range_horz = 512;
323
182
    ps_params->s_config_prms.i4_max_search_range_vert = 256;
324
182
    ps_params->s_config_prms.i4_max_tr_tree_depth_I = 1;
325
182
    ps_params->s_config_prms.i4_max_tr_tree_depth_nI = 3;
326
182
    ps_params->s_config_prms.i4_min_frame_qp = 1;
327
182
    ps_params->s_config_prms.i4_min_log2_cu_size = 3;
328
182
    ps_params->s_config_prms.i4_min_log2_tu_size = 2;
329
182
    ps_params->s_config_prms.i4_num_frms_to_encode = -1;
330
182
    ps_params->s_config_prms.i4_rate_control_mode = 2;
331
182
    ps_params->s_config_prms.i4_stuffing_enable = 0;
332
182
    ps_params->s_config_prms.i4_vbr_max_peak_rate_dur = 2000;
333
334
    /* LAP parameters */
335
182
    ps_params->s_lap_prms.i4_size = sizeof(ihevce_lap_params_t);
336
182
    ps_params->s_lap_prms.i4_deinterlacer_enable = 0;
337
182
    ps_params->s_lap_prms.i4_denoise_enable = 0;
338
182
    ps_params->s_lap_prms.i4_enable_wts_ofsts = 1;
339
182
    ps_params->s_lap_prms.i4_rc_look_ahead_pics = 0;
340
341
    /* Multi Thread parameters */
342
182
    ps_params->s_multi_thrd_prms.i4_size = sizeof(ihevce_static_multi_thread_params_t);
343
182
    ps_params->s_multi_thrd_prms.i4_max_num_cores = 1;
344
182
    ps_params->s_multi_thrd_prms.i4_memory_alloc_ctrl_flag = 0;
345
182
    ps_params->s_multi_thrd_prms.i4_num_proc_groups = 1;
346
182
    ps_params->s_multi_thrd_prms.ai4_num_cores_per_grp[0] = -1;
347
182
    ps_params->s_multi_thrd_prms.i4_use_thrd_affinity = -1;  //0;
348
182
    memset(&ps_params->s_multi_thrd_prms.au8_core_aff_mask[0], 0, sizeof(ULWORD64) * MAX_NUM_CORES);
349
350
    /* Output Streams parameters */
351
182
    ps_params->s_out_strm_prms.i4_size = sizeof(ihevce_out_strm_params_t);
352
182
    ps_params->s_out_strm_prms.i4_aud_enable_flags = 0;
353
182
    ps_params->s_out_strm_prms.i4_eos_enable_flags = 0;
354
182
    ps_params->s_out_strm_prms.i4_codec_profile = 1;
355
182
    ps_params->s_out_strm_prms.i4_codec_tier = 0;
356
182
    ps_params->s_out_strm_prms.i4_codec_type = 0;
357
182
#ifndef DISABLE_SEI
358
182
    ps_params->s_out_strm_prms.i4_sei_buffer_period_flags = 0;
359
182
    ps_params->s_out_strm_prms.i4_sei_enable_flag = 0;
360
182
    ps_params->s_out_strm_prms.i4_sei_payload_enable_flag = 0;
361
182
    ps_params->s_out_strm_prms.i4_sei_pic_timing_flags = 0;
362
182
    ps_params->s_out_strm_prms.i4_sei_cll_enable = 0;
363
182
    ps_params->s_out_strm_prms.u2_sei_avg_cll = 0;
364
182
    ps_params->s_out_strm_prms.u2_sei_max_cll = 0;
365
182
    ps_params->s_out_strm_prms.i4_sei_recovery_point_flags = 0;
366
182
    ps_params->s_out_strm_prms.i4_sei_mastering_disp_colour_vol_flags = 0;
367
182
    ps_params->s_out_strm_prms.i4_decoded_pic_hash_sei_flag = 0;
368
182
#endif
369
182
    ps_params->s_out_strm_prms.i4_sps_at_cdr_enable = 1;
370
182
    ps_params->s_out_strm_prms.i4_vui_enable = 0;
371
    /*Set the interoperability flag to 0*/
372
182
    ps_params->s_out_strm_prms.i4_interop_flags = 0;
373
374
    /* Source parameters */
375
182
    ps_params->s_src_prms.i4_size = sizeof(ihevce_src_params_t);
376
182
    ps_params->s_src_prms.inp_chr_format = 1;
377
182
    ps_params->s_src_prms.i4_chr_format = 11;
378
182
    ps_params->s_src_prms.i4_field_pic = 0;
379
182
    ps_params->s_src_prms.i4_frm_rate_denom = 1000;
380
182
    ps_params->s_src_prms.i4_frm_rate_num = 30000;
381
182
    ps_params->s_src_prms.i4_height = 0;  //1080;
382
182
    ps_params->s_src_prms.i4_input_bit_depth = 8;
383
182
    ps_params->s_src_prms.i4_topfield_first = 1;
384
182
    ps_params->s_src_prms.i4_width = 0;  //1920;
385
182
    ps_params->s_src_prms.i4_orig_width = 0;
386
182
    ps_params->s_src_prms.i4_orig_height = 0;
387
388
    /* Target layer parameters */
389
182
    ps_params->s_tgt_lyr_prms.i4_size = sizeof(ihevce_tgt_layer_params_t);
390
182
    ps_params->s_tgt_lyr_prms.i4_enable_temporal_scalability = 0;
391
182
    ps_params->s_tgt_lyr_prms.i4_internal_bit_depth = 8;
392
182
    ps_params->s_tgt_lyr_prms.i4_mbr_quality_setting = IHEVCE_MBR_HIGH_QUALITY;
393
182
    ps_params->s_tgt_lyr_prms.i4_multi_res_layer_reuse = 0;
394
182
    ps_params->s_tgt_lyr_prms.i4_num_res_layers = 1;
395
182
    ps_params->s_tgt_lyr_prms.i4_mres_single_out = 0;
396
182
    ps_params->s_tgt_lyr_prms.i4_start_res_id = 0;
397
182
    ps_params->s_tgt_lyr_prms.pf_scale_chroma = NULL;
398
182
    ps_params->s_tgt_lyr_prms.pf_scale_luma = NULL;
399
182
    ps_params->s_tgt_lyr_prms.pv_scaler_handle = NULL;
400
401
    /* target parameters */
402
364
    for(i = 0; i < IHEVCE_MAX_NUM_RESOLUTIONS; i++)
403
182
    {
404
182
        ps_params->s_tgt_lyr_prms.as_tgt_params[i].i4_size = sizeof(ihevce_tgt_params_t);
405
364
        for(j = 0; j < IHEVCE_MAX_NUM_BITRATES; j++)
406
182
        {
407
182
            ps_params->s_tgt_lyr_prms.as_tgt_params[i].ai4_frame_qp[j] = 32;
408
182
            ps_params->s_tgt_lyr_prms.as_tgt_params[i].ai4_tgt_bitrate[j] = 5000000;
409
182
            ps_params->s_tgt_lyr_prms.as_tgt_params[i].ai4_peak_bitrate[j] = 10000000;
410
182
            ps_params->s_tgt_lyr_prms.as_tgt_params[i].ai4_max_vbv_buffer_size[j] = -1;
411
182
        }
412
182
        ps_params->s_tgt_lyr_prms.as_tgt_params[i].i4_codec_level = 156;
413
182
        ps_params->s_tgt_lyr_prms.as_tgt_params[i].i4_frm_rate_scale_factor = 1;
414
182
        ps_params->s_tgt_lyr_prms.as_tgt_params[i].i4_height = 0;
415
182
        ps_params->s_tgt_lyr_prms.as_tgt_params[i].i4_num_bitrate_instances = 1;
416
182
        ps_params->s_tgt_lyr_prms.as_tgt_params[i].i4_quality_preset = IHEVCE_QUALITY_P5;
417
182
        ps_params->s_tgt_lyr_prms.as_tgt_params[i].i4_width = 0;
418
182
    }
419
420
    /* SEI VUI parameters */
421
182
    ps_params->s_vui_sei_prms.u1_aspect_ratio_info_present_flag = 0;
422
182
    ps_params->s_vui_sei_prms.au1_aspect_ratio_idc[0] = 255;
423
182
    ps_params->s_vui_sei_prms.au2_sar_width[0] = 4;
424
182
    ps_params->s_vui_sei_prms.au2_sar_height[0] = 3;
425
182
    ps_params->s_vui_sei_prms.u1_overscan_info_present_flag = 0;
426
182
    ps_params->s_vui_sei_prms.u1_overscan_appropriate_flag = 0;
427
182
    ps_params->s_vui_sei_prms.u1_video_signal_type_present_flag = 1;
428
182
    ps_params->s_vui_sei_prms.u1_video_format = 5;
429
182
    ps_params->s_vui_sei_prms.u1_video_full_range_flag = 1;
430
182
    ps_params->s_vui_sei_prms.u1_colour_description_present_flag = 0;
431
182
    ps_params->s_vui_sei_prms.u1_colour_primaries = 2;
432
182
    ps_params->s_vui_sei_prms.u1_transfer_characteristics = 2;
433
182
    ps_params->s_vui_sei_prms.u1_matrix_coefficients = 2;
434
182
    ps_params->s_vui_sei_prms.u1_chroma_loc_info_present_flag = 0;
435
182
    ps_params->s_vui_sei_prms.u1_chroma_sample_loc_type_top_field = 0;
436
182
    ps_params->s_vui_sei_prms.u1_chroma_sample_loc_type_bottom_field = 0;
437
182
    ps_params->s_vui_sei_prms.u1_vui_hrd_parameters_present_flag = 0;
438
182
    ps_params->s_vui_sei_prms.u1_timing_info_present_flag = 0;
439
182
    ps_params->s_vui_sei_prms.u1_nal_hrd_parameters_present_flag = 0;
440
441
    /* Setting sysAPIs to NULL */
442
182
    memset(&ps_params->s_sys_api, 0, sizeof(ihevce_sys_api_t));
443
444
    /* Multi pass parameters */
445
182
    memset(&ps_params->s_pass_prms, 0, sizeof(ihevce_pass_prms_t));
446
182
    ps_params->s_pass_prms.i4_size = sizeof(ihevce_pass_prms_t);
447
448
    /* Tile parameters */
449
182
    ps_params->s_app_tile_params.i4_size = sizeof(ihevce_app_tile_params_t);
450
182
    ps_params->s_app_tile_params.i4_tiles_enabled_flag = 0;
451
182
    ps_params->s_app_tile_params.i4_uniform_spacing_flag = 1;
452
182
    ps_params->s_app_tile_params.i4_num_tile_cols = 1;
453
182
    ps_params->s_app_tile_params.i4_num_tile_rows = 1;
454
455
182
    ps_params->s_slice_params.i4_slice_segment_mode = 0;
456
182
    ps_params->s_slice_params.i4_slice_segment_argument = 1300;
457
458
182
    return (IHEVCE_EOK);
459
182
}
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
*/
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
0
{
484
    /*local variables*/
485
0
    plugin_ctxt_t *plugin_ctxt = (plugin_ctxt_t *)pv_cb_handle;
486
0
    ihevce_static_cfg_params_t *ps_static_cfg_params =
487
0
        ((ihevce_hle_ctxt_t *)plugin_ctxt->pv_hle_interface_ctxt)->ps_static_cfg_prms;
488
489
0
    if(i4_cmd_type == 0)
490
0
        ps_static_cfg_params->s_sys_api.ihevce_printf(
491
0
            ps_static_cfg_params->s_sys_api.pv_cb_handle,
492
0
            "PLUGIN ERROR: Asynchronous Buffer Error %d in Buffer Id %d",
493
0
            i4_error_code,
494
0
            i4_buf_id);
495
0
    else
496
0
        ps_static_cfg_params->s_sys_api.ihevce_printf(
497
0
            ps_static_cfg_params->s_sys_api.pv_cb_handle,
498
0
            "PLUGIN ERROR: Synchronous Buffer Error %d in Buffer Id %d",
499
0
            i4_error_code,
500
0
            i4_buf_id);
501
502
0
    return (IV_SUCCESS);
503
0
}
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
525
    ihevce_strm_fill_done(void *pv_ctxt, void *pv_curr_out, WORD32 i4_br_id, WORD32 i4_res_id)
526
4.06k
{
527
    /* local variables */
528
4.06k
    plugin_ctxt_t *ps_ctxt = (plugin_ctxt_t *)pv_ctxt;
529
4.06k
    app_ctxt_t *ps_app_ctxt = &ps_ctxt->s_app_ctxt;
530
4.06k
    out_strm_prms_t *ps_out_strm_prms = &ps_app_ctxt->as_out_strm_prms[i4_res_id][i4_br_id];
531
4.06k
    void *pv_app_out_strm_buf_mutex_hdl = ps_out_strm_prms->pv_app_out_strm_buf_mutex_hdl;
532
4.06k
    void *pv_app_out_strm_buf_cond_var_hdl = ps_out_strm_prms->pv_app_out_strm_buf_cond_var_hdl;
533
4.06k
    iv_output_data_buffs_t *ps_curr_out = (iv_output_data_buffs_t *)pv_curr_out;
534
4.06k
    WORD32 end_flag = ps_curr_out->i4_end_flag;
535
4.06k
    WORD32 osal_result;
536
537
    /* ------  output dump stream  -- */
538
4.06k
    if((WORD32)IV_FAIL != ps_curr_out->i4_process_ret_sts)
539
3.97k
    {
540
3.97k
        if(0 != ps_curr_out->i4_bytes_generated)
541
3.79k
        {
542
            /* accumulate the total bits generated */
543
3.79k
            (ps_out_strm_prms->u8_total_bits) += ps_curr_out->i4_bytes_generated * 8;
544
3.79k
            (ps_out_strm_prms->u4_num_frms_enc)++;
545
3.79k
        }
546
3.97k
    }
547
548
    /****** Lock the critical section ******/
549
4.06k
    osal_result = osal_mutex_lock(pv_app_out_strm_buf_mutex_hdl);
550
4.06k
    if(OSAL_SUCCESS != osal_result)
551
0
        return (IV_FAIL);
552
553
    /* Update the end flag to communicate with the o/p thread */
554
4.06k
    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
4.06k
    {
558
4.06k
        WORD32 idx = ps_curr_out->i4_cb_buf_id;
559
560
4.06k
        ps_ctxt->aaas_out_bufs[i4_res_id][i4_br_id][idx].i4_timestamp_low =
561
4.06k
            ps_curr_out->i4_out_timestamp_low;
562
4.06k
        ps_ctxt->aaas_out_bufs[i4_res_id][i4_br_id][idx].i4_timestamp_high =
563
4.06k
            ps_curr_out->i4_out_timestamp_high;
564
4.06k
        ps_ctxt->aaas_out_bufs[i4_res_id][i4_br_id][idx].i4_bytes_gen =
565
4.06k
            ps_curr_out->i4_bytes_generated;
566
4.06k
        ps_ctxt->aaas_out_bufs[i4_res_id][i4_br_id][idx].i4_is_key_frame = 0;
567
4.06k
        ps_ctxt->aaas_out_bufs[i4_res_id][i4_br_id][idx].i4_end_flag = end_flag;
568
569
4.06k
        if((IV_IDR_FRAME == ps_curr_out->i4_encoded_frame_type) ||
570
3.50k
           (IV_I_FRAME == ps_curr_out->i4_encoded_frame_type))
571
912
        {
572
912
            ps_ctxt->aaas_out_bufs[i4_res_id][i4_br_id][idx].i4_is_key_frame = 1;
573
912
        }
574
575
        /* set the buffer as produced */
576
4.06k
        ps_ctxt->aaas_out_bufs[i4_res_id][i4_br_id][idx].i4_is_prod = 1;
577
4.06k
    }
578
579
    /****** Wake ******/
580
4.06k
    osal_cond_var_signal(pv_app_out_strm_buf_cond_var_hdl);
581
582
    /****** Unlock the critical section ******/
583
4.06k
    osal_result = osal_mutex_unlock(pv_app_out_strm_buf_mutex_hdl);
584
4.06k
    if(OSAL_SUCCESS != osal_result)
585
0
        return (IV_FAIL);
586
587
4.06k
    return (IV_SUCCESS);
588
4.06k
}
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
*/
607
IHEVCE_PLUGIN_STATUS_T ihevce_init(ihevce_static_cfg_params_t *ps_params, void **ppv_ihevce_hdl)
608
182
{
609
    /* local variables */
610
182
    plugin_ctxt_t *ps_ctxt;
611
182
    app_ctxt_t *ps_app_ctxt;
612
182
    ihevce_hle_ctxt_t *ps_interface_ctxt;
613
182
    ihevce_sys_api_t *ps_sys_api;
614
182
    osal_cb_funcs_t s_cb_funcs;
615
182
    WORD32 status = 0;
616
617
    /* sanity checks */
618
182
    if(NULL == ps_params)
619
0
        return (IHEVCE_EFAIL);
620
621
182
    if(NULL == ppv_ihevce_hdl)
622
0
        return (IHEVCE_EFAIL);
623
624
    /* set the handle to null by default */
625
182
    *ppv_ihevce_hdl = NULL;
626
627
    /* Initiallizing system apis */
628
182
    ps_sys_api = &ps_params->s_sys_api;
629
182
    ihevce_init_sys_api(NULL, ps_sys_api);
630
631
    /* --------------------------------------------------------------------- */
632
    /*                   Query and print Encoder version                     */
633
    /* --------------------------------------------------------------------- */
634
182
    ps_sys_api->ihevce_printf(
635
182
        ps_sys_api->pv_cb_handle, "Encoder version %s\n\n", ihevce_get_encoder_version());
636
637
    /* --------------------------------------------------------------------- */
638
    /*                    Plugin Handle create                               */
639
    /* --------------------------------------------------------------------- */
640
182
    ps_ctxt = (plugin_ctxt_t *)memory_alloc(NULL, sizeof(plugin_ctxt_t));
641
182
    if(NULL == ps_ctxt)
642
0
    {
643
0
        ps_sys_api->ihevce_printf(
644
0
            ps_sys_api->pv_cb_handle, "IHEVCE ERROR: Error in Plugin initialization\n");
645
0
        return (IHEVCE_EFAIL);
646
0
    }
647
648
    /* initialise memory call backs */
649
182
    ps_ctxt->ihevce_mem_alloc = memory_alloc;
650
182
    ps_ctxt->ihevce_mem_free = memory_free;
651
652
182
    ps_ctxt->u8_num_frames_encoded = 0;
653
654
182
    if((0 == ps_params->i4_res_id) && (0 == ps_params->i4_br_id))
655
182
    {
656
        /* --------------------------------------------------------------------- */
657
        /*                      OSAL Handle create                               */
658
        /* --------------------------------------------------------------------- */
659
182
        ps_ctxt->pv_osal_handle = memory_alloc(NULL, OSAL_HANDLE_SIZE);
660
661
        /* Initialize OSAL call back functions */
662
182
        s_cb_funcs.mmr_handle = NULL;
663
182
        s_cb_funcs.osal_alloc = memory_alloc;
664
182
        s_cb_funcs.osal_free = memory_free;
665
666
182
        status = osal_init(ps_ctxt->pv_osal_handle);
667
182
        if(OSAL_SUCCESS != status)
668
0
        {
669
0
            ps_sys_api->ihevce_printf(
670
0
                ps_sys_api->pv_cb_handle, "IHEVCE ERROR: Error in OSAL initialization\n");
671
0
            return (IHEVCE_EFAIL);
672
0
        }
673
674
182
        status = osal_register_callbacks(ps_ctxt->pv_osal_handle, &s_cb_funcs);
675
182
        if(OSAL_SUCCESS != status)
676
0
        {
677
0
            ps_sys_api->ihevce_printf(
678
0
                ps_sys_api->pv_cb_handle, "IHEVCE ERROR: Error in OSAL call back registration\n");
679
0
            return (IHEVCE_EFAIL);
680
0
        }
681
682
        /* --------------------------------------------------------------------- */
683
        /*                      Thread affinity  Initialization                  */
684
        /* --------------------------------------------------------------------- */
685
182
        if(ps_params->s_multi_thrd_prms.i4_use_thrd_affinity)
686
182
        {
687
182
            WORD32 i4_ctr;
688
689
            /* loop over all the cores */
690
364
            for(i4_ctr = 0; i4_ctr < ps_params->s_multi_thrd_prms.i4_max_num_cores; i4_ctr++)
691
182
            {
692
                /* All cores are logical cores  */
693
182
                ps_params->s_multi_thrd_prms.au8_core_aff_mask[i4_ctr] = ((ULWORD64)1 << i4_ctr);
694
182
            }
695
182
        }
696
697
        /* --------------------------------------------------------------------- */
698
        /*             Context Initialization                                    */
699
        /* --------------------------------------------------------------------- */
700
182
        ps_app_ctxt = &ps_ctxt->s_app_ctxt;
701
702
182
        ps_ctxt->ps_static_cfg_prms = (ihevce_static_cfg_params_t *)ps_ctxt->ihevce_mem_alloc(
703
182
            NULL, sizeof(ihevce_static_cfg_params_t));
704
182
        if(NULL == ps_ctxt->ps_static_cfg_prms)
705
0
        {
706
0
            ps_sys_api->ihevce_printf(
707
0
                ps_sys_api->pv_cb_handle, "IHEVCE ERROR: Error in Plugin memory initialization\n");
708
0
            return (IHEVCE_EFAIL);
709
0
        }
710
711
182
        ps_params->apF_csv_file[0][0] = NULL;
712
713
        /* set the memory manager handle to NULL */
714
182
        ps_app_ctxt->pv_mem_mngr_handle = NULL;
715
716
        /* --------------------------------------------------------------------- */
717
        /*            Back up the static params passed by caller                 */
718
        /* --------------------------------------------------------------------- */
719
182
        memcpy(ps_ctxt->ps_static_cfg_prms, ps_params, sizeof(ihevce_static_cfg_params_t));
720
721
182
        ps_ctxt->ps_static_cfg_prms->s_src_prms.i4_orig_width =
722
182
            ps_ctxt->ps_static_cfg_prms->s_src_prms.i4_width;
723
182
        if(HEVCE_MIN_WIDTH > ps_ctxt->ps_static_cfg_prms->s_src_prms.i4_width)
724
52
        {
725
52
            ps_ctxt->ps_static_cfg_prms->s_src_prms.i4_width = HEVCE_MIN_WIDTH;
726
52
        }
727
728
182
        ps_ctxt->ps_static_cfg_prms->s_src_prms.i4_orig_height =
729
182
            ps_ctxt->ps_static_cfg_prms->s_src_prms.i4_height;
730
182
        if(HEVCE_MIN_HEIGHT > ps_ctxt->ps_static_cfg_prms->s_src_prms.i4_height)
731
53
        {
732
53
            ps_ctxt->ps_static_cfg_prms->s_src_prms.i4_height = HEVCE_MIN_HEIGHT;
733
53
        }
734
735
        /* setting tgt width and height same as src width and height */
736
182
        ps_ctxt->ps_static_cfg_prms->s_tgt_lyr_prms.as_tgt_params[0].i4_width =
737
182
            ps_ctxt->ps_static_cfg_prms->s_src_prms.i4_width;
738
182
        ps_ctxt->ps_static_cfg_prms->s_tgt_lyr_prms.as_tgt_params[0].i4_height =
739
182
            ps_ctxt->ps_static_cfg_prms->s_src_prms.i4_height;
740
741
        /* setting key frame interval */
742
182
        ps_ctxt->ps_static_cfg_prms->s_coding_tools_prms.i4_max_closed_gop_period =
743
182
            MIN(MAX_NUM_FRM_IN_GOP,
744
182
                ps_ctxt->ps_static_cfg_prms->s_coding_tools_prms.i4_max_closed_gop_period);
745
182
        ps_ctxt->ps_static_cfg_prms->s_coding_tools_prms.i4_max_cra_open_gop_period =
746
182
            MIN(MAX_NUM_FRM_IN_GOP,
747
182
                ps_ctxt->ps_static_cfg_prms->s_coding_tools_prms.i4_max_cra_open_gop_period);
748
182
        ps_ctxt->ps_static_cfg_prms->s_coding_tools_prms.i4_max_i_open_gop_period =
749
182
            MIN(MAX_NUM_FRM_IN_GOP,
750
182
                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
182
        if(ps_ctxt->ps_static_cfg_prms->s_src_prms.i4_height <=
754
182
            (1 << ps_ctxt->ps_static_cfg_prms->s_config_prms.i4_max_log2_cu_size))
755
55
        {
756
55
            ps_ctxt->ps_static_cfg_prms->s_coding_tools_prms.i4_enable_entropy_sync = 0;
757
55
        }
758
759
        /* --------------------------------------------------------------------- */
760
        /*            High Level Encoder context init                            */
761
        /* --------------------------------------------------------------------- */
762
182
        ps_interface_ctxt =
763
182
            (ihevce_hle_ctxt_t *)ps_ctxt->ihevce_mem_alloc(NULL, sizeof(ihevce_hle_ctxt_t));
764
182
        if(NULL == ps_interface_ctxt)
765
0
        {
766
0
            ps_sys_api->ihevce_printf(
767
0
                ps_sys_api->pv_cb_handle,
768
0
                "IHEVCE ERROR: Error in Plugin HLE memory initialization\n");
769
0
            return (IHEVCE_EFAIL);
770
0
        }
771
182
        ps_interface_ctxt->i4_size = sizeof(ihevce_hle_ctxt_t);
772
773
182
        ps_ctxt->pv_hle_interface_ctxt = ps_interface_ctxt;
774
775
        /* store the static config parameters pointer */
776
182
        ps_interface_ctxt->ps_static_cfg_prms = ps_ctxt->ps_static_cfg_prms;
777
778
        /* initialise the interface strucure parameters */
779
182
        ps_interface_ctxt->pv_inp_cb_handle = (void *)ps_ctxt;
780
182
        ps_interface_ctxt->pv_out_cb_handle = (void *)ps_ctxt;
781
182
        ps_interface_ctxt->pv_recon_cb_handle = (void *)ps_ctxt;
782
783
182
        ps_interface_ctxt->pv_osal_handle = ps_ctxt->pv_osal_handle;
784
182
        ps_interface_ctxt->ihevce_mem_alloc = mem_mngr_alloc;
785
182
        ps_interface_ctxt->ihevce_mem_free = mem_mngr_free;
786
182
        ps_interface_ctxt->i4_hle_init_done = 0;
787
182
        ps_interface_ctxt->pv_mem_mgr_hdl = ps_app_ctxt->pv_mem_mngr_handle;
788
789
        /* reigter the callbacks */
790
182
        ps_interface_ctxt->ihevce_output_strm_fill_done = ihevce_strm_fill_done;
791
182
        ps_interface_ctxt->ihevce_output_recon_fill_done = NULL;
792
182
        ps_interface_ctxt->ihevce_set_free_input_buff = NULL;
793
794
        /*Added for run time or create time creation*/
795
182
        ps_interface_ctxt->i4_create_time_input_allocation = (WORD32)CREATE_TIME_ALLOCATION_INPUT;
796
182
        ps_interface_ctxt->i4_create_time_output_allocation = (WORD32)CREATE_TIME_ALLOCATION_OUTPUT;
797
798
182
        ps_interface_ctxt->ihevce_cmds_error_report = ihevce_cmds_error_report;
799
182
        ps_interface_ctxt->pv_cmd_err_cb_handle = (void *)ps_ctxt;
800
801
        /* --------------------------------------------------------------------- */
802
        /*           High Level Encoder Instance Creation                        */
803
        /* --------------------------------------------------------------------- */
804
182
        status = ihevce_hle_interface_create(ps_interface_ctxt);
805
182
        if((WORD32)IV_FAIL == status)
806
0
        {
807
0
            ihevce_hle_interface_delete(ps_interface_ctxt);
808
809
0
            memory_free(NULL, ps_interface_ctxt);
810
811
            /* free static config memory */
812
0
            ps_ctxt->ihevce_mem_free(NULL, ps_ctxt->ps_static_cfg_prms);
813
814
            /* free osal handle */
815
0
            memory_free(NULL, ps_ctxt->pv_osal_handle);
816
817
            /* free plugin ctxt memory */
818
0
            memory_free(NULL, ps_ctxt);
819
820
0
            ps_sys_api->ihevce_printf(
821
0
                ps_sys_api->pv_cb_handle, "IHEVCE ERROR: Error in Plugin HLE create failed\n");
822
0
            return (IHEVCE_EFAIL);
823
0
        }
824
825
        /* --------------------------------------------------------------------- */
826
        /*            Input Output and Command buffer allocation                 */
827
        /* --------------------------------------------------------------------- */
828
182
        {
829
182
            WORD32 ctr;
830
182
            WORD32 buf_size;
831
182
            UWORD8 *pu1_tmp_buf;
832
182
            WORD32 i4_res_id;
833
182
            WORD32 i4_br_id;
834
182
            WORD32 i4_num_resolutions;
835
182
            WORD32 ai4_num_bitrate_instances[IHEVCE_MAX_NUM_RESOLUTIONS] = { 1 };
836
182
            iv_input_bufs_req_t s_input_bufs_req;
837
182
            iv_res_layer_output_bufs_req_t s_res_layer_output_bufs_req;
838
182
            iv_res_layer_recon_bufs_req_t s_res_layer_recon_bufs_req;
839
840
            /* local array of pointers */
841
182
            void *apv_inp_luma_bufs[MAX_NUM_INP_DATA_BUFS];
842
182
            void *apv_inp_cb_bufs[MAX_NUM_INP_DATA_BUFS];
843
182
            void *apv_inp_cr_bufs[MAX_NUM_INP_DATA_BUFS];
844
182
            void *apv_inp_sync_bufs[MAX_NUM_INP_CTRL_SYNC_BUFS];
845
182
            void *apv_inp_async_bufs[MAX_NUM_INP_CTRL_ASYNC_BUFS];
846
182
            void *apv_out_data_bufs[IHEVCE_MAX_NUM_RESOLUTIONS][IHEVCE_MAX_NUM_BITRATES]
847
182
                                   [MAX_NUM_OUT_DATA_BUFS];
848
849
            /* get the number of resolutions */
850
182
            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
182
            s_input_bufs_req.i4_size = sizeof(iv_input_bufs_req_t);
854
182
            s_res_layer_output_bufs_req.i4_size = sizeof(iv_res_layer_output_bufs_req_t);
855
182
            s_res_layer_recon_bufs_req.i4_size = sizeof(iv_res_layer_recon_bufs_req_t);
856
857
            /* loop over num resolutions */
858
364
            for(i4_res_id = 0; i4_res_id < i4_num_resolutions; i4_res_id++)
859
182
            {
860
                /* store the number of bitrates */
861
182
                ai4_num_bitrate_instances[i4_res_id] =
862
182
                    ps_ctxt->ps_static_cfg_prms->s_tgt_lyr_prms.as_tgt_params[i4_res_id]
863
182
                        .i4_num_bitrate_instances;
864
865
                /* loop over num bitrates */
866
364
                for(i4_br_id = 0; i4_br_id < ai4_num_bitrate_instances[i4_res_id]; i4_br_id++)
867
182
                {
868
182
                    s_res_layer_output_bufs_req.s_output_buf_req[i4_res_id][i4_br_id].i4_size =
869
182
                        sizeof(iv_output_bufs_req_t);
870
182
                }
871
182
            }
872
873
            /* call Query I/O buffer */
874
182
            status = ihevce_query_io_buf_req(
875
182
                ps_interface_ctxt,
876
182
                &s_input_bufs_req,
877
182
                &s_res_layer_output_bufs_req,
878
182
                &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
182
            if(ps_interface_ctxt->i4_create_time_input_allocation == 1)
886
182
            {
887
182
                buf_size = s_input_bufs_req.i4_min_size_uv_buf + s_input_bufs_req.i4_min_size_y_buf;
888
182
                ps_ctxt->s_memtab_inp_data_buf.i4_size = sizeof(iv_mem_rec_t);
889
182
                ps_ctxt->s_memtab_inp_data_buf.i4_mem_alignment = 4;
890
182
                ps_ctxt->s_memtab_inp_data_buf.i4_mem_size =
891
182
                    (s_input_bufs_req.i4_min_num_yuv_bufs + XTRA_INP_DATA_BUFS) * buf_size;
892
182
                ps_ctxt->s_memtab_inp_data_buf.e_mem_type = IV_EXT_CACHEABLE_NUMA_NODE0_MEM;
893
894
182
                mem_mngr_alloc(
895
182
                    ps_app_ctxt->pv_mem_mngr_handle, ps_sys_api, &ps_ctxt->s_memtab_inp_data_buf);
896
897
182
                pu1_tmp_buf = (UWORD8 *)ps_ctxt->s_memtab_inp_data_buf.pv_base;
898
899
182
                if(NULL == pu1_tmp_buf)
900
0
                {
901
0
                    ps_sys_api->ihevce_printf(
902
0
                        ps_sys_api->pv_cb_handle, "IHEVCE ERROR: Error in allocate memory\n");
903
0
                    return (IHEVCE_EFAIL);
904
0
                }
905
906
                /* loop to initialise the buffer pointer */
907
588
                for(ctr = 0; ctr < s_input_bufs_req.i4_min_num_yuv_bufs + XTRA_INP_DATA_BUFS; ctr++)
908
406
                {
909
406
                    apv_inp_luma_bufs[ctr] = pu1_tmp_buf;
910
406
                    apv_inp_cb_bufs[ctr] = pu1_tmp_buf + s_input_bufs_req.i4_min_size_y_buf;
911
406
                    apv_inp_cr_bufs[ctr] = NULL; /* 420SP case */
912
913
                    /* increment the input buffer pointer to next buffer */
914
406
                    pu1_tmp_buf += buf_size;
915
406
                }
916
182
            }
917
918
            /* ---------------  Output data buffers init ---------------------- */
919
920
            /* loop over num resolutions */
921
364
            for(i4_res_id = 0; i4_res_id < i4_num_resolutions; i4_res_id++)
922
182
            {
923
364
                for(i4_br_id = 0; i4_br_id < ai4_num_bitrate_instances[i4_res_id]; i4_br_id++)
924
182
                {
925
182
                    buf_size = s_res_layer_output_bufs_req.s_output_buf_req[i4_res_id][i4_br_id]
926
182
                                   .i4_min_size_bitstream_buf;
927
928
182
                    ps_ctxt->as_memtab_out_data_buf[i4_res_id][i4_br_id].i4_size =
929
182
                        sizeof(iv_mem_rec_t);
930
182
                    ps_ctxt->as_memtab_out_data_buf[i4_res_id][i4_br_id].i4_mem_alignment = 4;
931
932
182
                    if(!ps_interface_ctxt->i4_create_time_output_allocation)
933
182
                    {
934
182
                        ps_ctxt->as_memtab_out_data_buf[i4_res_id][i4_br_id].i4_mem_size =
935
182
                            (s_res_layer_output_bufs_req.s_output_buf_req[i4_res_id][i4_br_id]
936
182
                                 .i4_min_num_out_bufs +
937
182
                             XTRA_OUT_DATA_BUFS) *
938
182
                            buf_size;
939
182
                    }
940
0
                    else
941
0
                    {
942
0
                        ps_ctxt->as_memtab_out_data_buf[i4_res_id][i4_br_id].i4_mem_size =
943
0
                            (s_res_layer_output_bufs_req.s_output_buf_req[i4_res_id][i4_br_id]
944
0
                                 .i4_min_num_out_bufs) *
945
0
                            buf_size;
946
0
                    }
947
182
                    ps_ctxt->as_memtab_out_data_buf[i4_res_id][i4_br_id].e_mem_type =
948
182
                        IV_EXT_CACHEABLE_NUMA_NODE1_MEM;
949
950
182
                    mem_mngr_alloc(
951
182
                        ps_app_ctxt->pv_mem_mngr_handle,
952
182
                        ps_sys_api,
953
182
                        &ps_ctxt->as_memtab_out_data_buf[i4_res_id][i4_br_id]);
954
955
182
                    pu1_tmp_buf =
956
182
                        (UWORD8 *)ps_ctxt->as_memtab_out_data_buf[i4_res_id][i4_br_id].pv_base;
957
182
                    if(NULL == pu1_tmp_buf)
958
0
                    {
959
0
                        ps_sys_api->ihevce_printf(
960
0
                            ps_sys_api->pv_cb_handle, "IHEVCE ERROR: Error in allocate memory\n");
961
0
                        return (IHEVCE_EFAIL);
962
0
                    }
963
964
182
                    if(ps_interface_ctxt->i4_create_time_output_allocation == 1)
965
0
                    {
966
                        /* loop to initialise the buffer pointer */
967
0
                        for(ctr = 0;
968
0
                            ctr < s_res_layer_output_bufs_req.s_output_buf_req[i4_res_id][i4_br_id]
969
0
                                      .i4_min_num_out_bufs;
970
0
                            ctr++)
971
0
                        {
972
0
                            apv_out_data_bufs[i4_res_id][i4_br_id][ctr] = pu1_tmp_buf;
973
0
                            pu1_tmp_buf += buf_size;
974
0
                        }
975
0
                    }
976
182
                    else
977
182
                    {
978
182
                        WORD32 i4_num_out_bufs =
979
182
                            s_res_layer_output_bufs_req.s_output_buf_req[i4_res_id][i4_br_id]
980
182
                                .i4_min_num_out_bufs +
981
182
                            XTRA_OUT_DATA_BUFS;
982
182
                        ps_ctxt->i4_num_out_bufs = i4_num_out_bufs;
983
182
                        ps_ctxt->ai4_free_out_buf_idx[i4_res_id][i4_br_id] = 0;
984
182
                        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
182
                        ASSERT(ps_ctxt->i4_num_out_bufs <= MAX_NUM_OUT_DATA_BUFS);
990
991
                        /* loop to initialise the buffer pointer */
992
910
                        for(ctr = 0; ctr < i4_num_out_bufs; ctr++)
993
728
                        {
994
728
                            ps_ctxt->aaas_out_bufs[i4_res_id][i4_br_id][ctr].i4_idx = ctr;
995
728
                            ps_ctxt->aaas_out_bufs[i4_res_id][i4_br_id][ctr].i4_is_free = 1;
996
728
                            ps_ctxt->aaas_out_bufs[i4_res_id][i4_br_id][ctr].i4_is_prod = 0;
997
728
                            ps_ctxt->aaas_out_bufs[i4_res_id][i4_br_id][ctr].i4_bytes_gen = 0;
998
728
                            ps_ctxt->aaas_out_bufs[i4_res_id][i4_br_id][ctr].pu1_buf = pu1_tmp_buf;
999
728
                            ps_ctxt->aaas_out_bufs[i4_res_id][i4_br_id][ctr].i4_buf_size = buf_size;
1000
728
                            pu1_tmp_buf += buf_size;
1001
728
                        }
1002
182
                    }
1003
1004
                    /* create mutex for controlling the out strm buf b/w appln and encoder */
1005
182
                    ps_app_ctxt->as_out_strm_prms[i4_res_id][i4_br_id]
1006
182
                        .pv_app_out_strm_buf_mutex_hdl = osal_mutex_create(ps_ctxt->pv_osal_handle);
1007
182
                    if(NULL == ps_app_ctxt->as_out_strm_prms[i4_res_id][i4_br_id]
1008
182
                                   .pv_app_out_strm_buf_mutex_hdl)
1009
0
                    {
1010
0
                        ps_sys_api->ihevce_printf(
1011
0
                            ps_sys_api->pv_cb_handle,
1012
0
                            "IHEVCE ERROR: Error in Plugin initialization\n");
1013
0
                        return (IHEVCE_EFAIL);
1014
0
                    }
1015
1016
                    /* create mutex for controlling the out strm buf b/w appln and encoder */
1017
182
                    ps_app_ctxt->as_out_strm_prms[i4_res_id][i4_br_id]
1018
182
                        .pv_app_out_strm_buf_cond_var_hdl =
1019
182
                        osal_cond_var_create(ps_ctxt->pv_osal_handle);
1020
182
                    if(NULL == ps_app_ctxt->as_out_strm_prms[i4_res_id][i4_br_id]
1021
182
                                   .pv_app_out_strm_buf_cond_var_hdl)
1022
0
                    {
1023
0
                        ps_sys_api->ihevce_printf(
1024
0
                            ps_sys_api->pv_cb_handle,
1025
0
                            "IHEVCE ERROR: Error in Plugin initialization\n");
1026
0
                        return (IHEVCE_EFAIL);
1027
0
                    }
1028
182
                }
1029
182
            }
1030
1031
182
            if(ps_interface_ctxt->i4_create_time_input_allocation == 1)
1032
182
            {
1033
                /* ------------- Input sync command buffers init -------------------- */
1034
182
                buf_size = s_input_bufs_req.i4_min_size_synch_ctrl_bufs;
1035
1036
182
                ps_ctxt->s_memtab_inp_sync_ctrl_buf.i4_size = sizeof(iv_mem_rec_t);
1037
182
                ps_ctxt->s_memtab_inp_sync_ctrl_buf.i4_mem_alignment = 4;
1038
182
                ps_ctxt->s_memtab_inp_sync_ctrl_buf.i4_mem_size =
1039
182
                    (s_input_bufs_req.i4_min_num_yuv_bufs + XTRA_INP_DATA_BUFS) * buf_size;
1040
182
                ps_ctxt->s_memtab_inp_sync_ctrl_buf.e_mem_type = IV_EXT_CACHEABLE_NUMA_NODE0_MEM;
1041
1042
182
                mem_mngr_alloc(
1043
182
                    ps_app_ctxt->pv_mem_mngr_handle,
1044
182
                    ps_sys_api,
1045
182
                    &ps_ctxt->s_memtab_inp_sync_ctrl_buf);
1046
1047
182
                pu1_tmp_buf = (UWORD8 *)ps_ctxt->s_memtab_inp_sync_ctrl_buf.pv_base;
1048
1049
182
                if(NULL == pu1_tmp_buf)
1050
0
                {
1051
0
                    ps_sys_api->ihevce_printf(
1052
0
                        ps_sys_api->pv_cb_handle, "IHEVCE ERROR: Error in allocate memory\n");
1053
0
                    return (IHEVCE_EFAIL);
1054
0
                }
1055
1056
                /* loop to initialise the buffer pointer */
1057
588
                for(ctr = 0; ctr < s_input_bufs_req.i4_min_num_yuv_bufs + XTRA_INP_DATA_BUFS; ctr++)
1058
406
                {
1059
406
                    apv_inp_sync_bufs[ctr] = pu1_tmp_buf;
1060
406
                    pu1_tmp_buf += buf_size;
1061
406
                }
1062
182
            }
1063
1064
            /* ------------- Input async command buffers init -------------------- */
1065
182
            buf_size = s_input_bufs_req.i4_min_size_asynch_ctrl_bufs;
1066
1067
            /* allocate memory for output status buffer */
1068
182
            ps_ctxt->pu1_inp_async_ctrl_buf = (UWORD8 *)ps_ctxt->ihevce_mem_alloc(
1069
182
                NULL, s_input_bufs_req.i4_min_num_asynch_ctrl_bufs * buf_size);
1070
182
            if(ps_ctxt->pu1_inp_async_ctrl_buf == NULL)
1071
0
            {
1072
0
                ps_sys_api->ihevce_printf(
1073
0
                    ps_sys_api->pv_cb_handle,
1074
0
                    "IHEVCE ERROR: Error in Plugin memory initialization\n");
1075
0
                return (IHEVCE_EFAIL);
1076
0
            }
1077
1078
182
            pu1_tmp_buf = ps_ctxt->pu1_inp_async_ctrl_buf;
1079
1080
            /* loop to initialise the buffer pointer */
1081
910
            for(ctr = 0; ctr < s_input_bufs_req.i4_min_num_asynch_ctrl_bufs; ctr++)
1082
728
            {
1083
728
                apv_inp_async_bufs[ctr] = pu1_tmp_buf;
1084
728
                pu1_tmp_buf += buf_size;
1085
728
            }
1086
1087
            /* Create IO ports for the buffer allocated */
1088
182
            {
1089
182
                iv_input_data_ctrl_buffs_desc_t s_inp_desc;
1090
182
                iv_input_asynch_ctrl_buffs_desc_t s_inp_ctrl_desc;
1091
182
                iv_res_layer_output_data_buffs_desc_t s_mres_out_desc;
1092
182
                iv_res_layer_recon_data_buffs_desc_t s_mres_recon_desc;
1093
1094
                /* set the parameters of the input data control desc */
1095
182
                s_inp_desc.i4_size = sizeof(iv_input_data_ctrl_buffs_desc_t);
1096
182
                s_inp_desc.i4_num_synch_ctrl_bufs = s_input_bufs_req.i4_min_num_synch_ctrl_bufs;
1097
182
                s_inp_desc.i4_num_yuv_bufs =
1098
182
                    s_input_bufs_req.i4_min_num_yuv_bufs + XTRA_INP_DATA_BUFS;
1099
182
                s_inp_desc.i4_size_y_buf = s_input_bufs_req.i4_min_size_y_buf;
1100
182
                s_inp_desc.i4_size_uv_buf = s_input_bufs_req.i4_min_size_uv_buf;
1101
182
                s_inp_desc.i4_size_synch_ctrl_bufs = s_input_bufs_req.i4_min_size_synch_ctrl_bufs;
1102
182
                s_inp_desc.ppv_synch_ctrl_bufs = &apv_inp_sync_bufs[0];
1103
182
                s_inp_desc.ppv_y_buf = &apv_inp_luma_bufs[0];
1104
182
                s_inp_desc.ppv_u_buf = &apv_inp_cb_bufs[0];
1105
182
                s_inp_desc.ppv_v_buf = &apv_inp_cr_bufs[0];
1106
1107
                /* set the parameters of the input async control desc */
1108
182
                s_inp_ctrl_desc.i4_size = sizeof(iv_input_asynch_ctrl_buffs_desc_t);
1109
182
                s_inp_ctrl_desc.i4_num_asynch_ctrl_bufs =
1110
182
                    s_input_bufs_req.i4_min_num_asynch_ctrl_bufs;
1111
182
                s_inp_ctrl_desc.i4_size_asynch_ctrl_bufs =
1112
182
                    s_input_bufs_req.i4_min_size_asynch_ctrl_bufs;
1113
182
                s_inp_ctrl_desc.ppv_asynch_ctrl_bufs = &apv_inp_async_bufs[0];
1114
1115
364
                for(i4_res_id = 0; i4_res_id < i4_num_resolutions; i4_res_id++)
1116
182
                {
1117
                    /* set the parameters of the output data desc */
1118
364
                    for(i4_br_id = 0; i4_br_id < ai4_num_bitrate_instances[i4_res_id]; i4_br_id++)
1119
182
                    {
1120
182
                        s_mres_out_desc.s_output_data_buffs[i4_res_id][i4_br_id].i4_size =
1121
182
                            sizeof(iv_output_data_buffs_desc_t);
1122
1123
182
                        if(!ps_interface_ctxt->i4_create_time_output_allocation)
1124
182
                        {
1125
182
                            s_mres_out_desc.s_output_data_buffs[i4_res_id][i4_br_id]
1126
182
                                .i4_num_bitstream_bufs =
1127
182
                                s_res_layer_output_bufs_req.s_output_buf_req[i4_res_id][i4_br_id]
1128
182
                                    .i4_min_num_out_bufs +
1129
182
                                XTRA_OUT_DATA_BUFS;
1130
182
                        }
1131
0
                        else
1132
0
                        {
1133
0
                            s_mres_out_desc.s_output_data_buffs[i4_res_id][i4_br_id]
1134
0
                                .i4_num_bitstream_bufs =
1135
0
                                s_res_layer_output_bufs_req.s_output_buf_req[i4_res_id][i4_br_id]
1136
0
                                    .i4_min_num_out_bufs;
1137
0
                        }
1138
1139
182
                        s_mres_out_desc.s_output_data_buffs[i4_res_id][i4_br_id]
1140
182
                            .i4_size_bitstream_buf =
1141
182
                            s_res_layer_output_bufs_req.s_output_buf_req[i4_res_id][i4_br_id]
1142
182
                                .i4_min_size_bitstream_buf;
1143
182
                        s_mres_out_desc.s_output_data_buffs[i4_res_id][i4_br_id].ppv_bitstream_bufs =
1144
182
                            &apv_out_data_bufs[i4_res_id][i4_br_id][0];
1145
182
                    }
1146
182
                }
1147
1148
182
                s_mres_recon_desc.i4_size = sizeof(iv_res_layer_recon_data_buffs_desc_t);
1149
                /* call create I/O ports */
1150
182
                status = ihevce_create_ports(
1151
182
                    ps_interface_ctxt,
1152
182
                    &s_inp_desc,
1153
182
                    &s_inp_ctrl_desc,
1154
182
                    &s_mres_out_desc,
1155
182
                    &s_mres_recon_desc);
1156
182
            }
1157
182
        }
1158
1159
        /* --------------------------------------------------------------------- */
1160
        /*            Create a High level encoder  thread                        */
1161
        /* --------------------------------------------------------------------- */
1162
0
        {
1163
182
            osal_thread_attr_t s_thread_attr = OSAL_DEFAULT_THREAD_ATTR;
1164
1165
            /* Initialize application thread attributes */
1166
182
            s_thread_attr.exit_code = 0;
1167
182
            s_thread_attr.name = 0;
1168
182
            s_thread_attr.priority_map_flag = 1;
1169
182
            s_thread_attr.priority = OSAL_PRIORITY_DEFAULT;
1170
182
            s_thread_attr.stack_addr = 0;
1171
182
            s_thread_attr.stack_size = THREAD_STACK_SIZE;
1172
182
            s_thread_attr.thread_func = ihevce_hle_interface_thrd;
1173
182
            s_thread_attr.thread_param = (void *)(ps_interface_ctxt);
1174
182
            s_thread_attr.core_affinity_mask = 0;
1175
182
            s_thread_attr.group_num = 0;
1176
1177
            /* Create High level encoder thread */
1178
182
            ps_ctxt->pv_hle_thread_hdl =
1179
182
                osal_thread_create(ps_ctxt->pv_osal_handle, &s_thread_attr);
1180
182
            if(NULL == ps_ctxt->pv_hle_thread_hdl)
1181
0
            {
1182
0
                return IHEVCE_EFAIL;
1183
0
            }
1184
182
        }
1185
1186
        /* --------------------------------------------------------------------- */
1187
        /*                 Wait until HLE init is done                           */
1188
        /* --------------------------------------------------------------------- */
1189
182
        {
1190
182
            volatile WORD32 hle_init_done;
1191
182
            volatile WORD32 *pi4_hle_init_done;
1192
1193
182
            pi4_hle_init_done = (volatile WORD32 *)&ps_interface_ctxt->i4_hle_init_done;
1194
1195
182
            do
1196
30.1M
            {
1197
30.1M
                hle_init_done = *pi4_hle_init_done;
1198
1199
30.1M
            } while(0 == hle_init_done);
1200
182
        }
1201
1202
        /* reset flush mode */
1203
182
        ps_ctxt->i4_flush_mode_on = 0;
1204
1205
182
        {
1206
182
            WORD32 i4_res_id;
1207
182
            WORD32 i4_br_id;
1208
364
            for(i4_res_id = 0; i4_res_id < IHEVCE_MAX_NUM_RESOLUTIONS; i4_res_id++)
1209
182
            {
1210
364
                for(i4_br_id = 0; i4_br_id < IHEVCE_MAX_NUM_BITRATES; i4_br_id++)
1211
182
                {
1212
                    /* reset out end flag */
1213
182
                    ps_ctxt->ai4_out_end_flag[i4_res_id][i4_br_id] = 0;
1214
182
                }
1215
182
            }
1216
182
        }
1217
1218
        /* reset the field id */
1219
182
        ps_ctxt->i4_field_id = 0;
1220
1221
        /* based on number of B pics set the DTS value */
1222
182
        ps_ctxt->i8_dts = -1;
1223
1224
182
        if(0 != ps_ctxt->ps_static_cfg_prms->s_coding_tools_prms.i4_max_temporal_layers)
1225
14
        {
1226
14
            ps_ctxt->i8_dts =
1227
14
                (-1) *
1228
14
                (1 << ps_ctxt->ps_static_cfg_prms->s_coding_tools_prms.i4_max_temporal_layers);
1229
14
        }
1230
1231
        /* initialsie the buffer stride */
1232
182
        {
1233
182
            WORD32 max_cu_size;
1234
1235
182
            max_cu_size = (1 << ps_ctxt->ps_static_cfg_prms->s_config_prms.i4_max_log2_cu_size);
1236
182
            ps_ctxt->i4_frm_stride =
1237
182
                ps_ctxt->ps_static_cfg_prms->s_src_prms.i4_width +
1238
182
                SET_CTB_ALIGN(ps_ctxt->ps_static_cfg_prms->s_src_prms.i4_width, max_cu_size);
1239
182
        }
1240
182
    }
1241
0
    else
1242
0
    {
1243
        /* free plugin ctxt memory */
1244
0
        memory_free(NULL, ps_ctxt);
1245
1246
0
        return (IHEVCE_EFAIL);
1247
0
    }
1248
1249
    /* reset the place holders of old bitrate */
1250
182
    memset(&ps_ctxt->ai4_old_bitrate[0][0], 0, sizeof(ps_ctxt->ai4_old_bitrate));
1251
1252
182
    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
182
    *ppv_ihevce_hdl = (void *)ps_ctxt;
1256
1257
182
    return (IHEVCE_EOK);
1258
182
}
1259
1260
static IHEVCE_PLUGIN_STATUS_T
1261
    ihevce_receive_out_buffer(plugin_ctxt_t *ps_ctxt, ihevce_out_buf_t *ps_out)
1262
3.85k
{
1263
3.85k
    app_ctxt_t *ps_app_ctxt = &ps_ctxt->s_app_ctxt;
1264
3.85k
    WORD32 i4_res_id, i4_br_id;
1265
3.85k
    WORD32 i4_num_resolutions;
1266
3.85k
    WORD32 ai4_num_bitrate_instances[IHEVCE_MAX_NUM_RESOLUTIONS] = { 1 };
1267
1268
3.85k
    i4_num_resolutions = ps_ctxt->ps_static_cfg_prms->s_tgt_lyr_prms.i4_num_res_layers;
1269
7.71k
    for(i4_res_id = 0; i4_res_id < i4_num_resolutions; i4_res_id++)
1270
3.85k
    {
1271
3.85k
        ai4_num_bitrate_instances[i4_res_id] =
1272
3.85k
            ps_ctxt->ps_static_cfg_prms->s_tgt_lyr_prms.as_tgt_params[i4_res_id]
1273
3.85k
                .i4_num_bitrate_instances;
1274
3.85k
    }
1275
    /* default init */
1276
3.85k
    ps_out->pu1_output_buf = NULL;
1277
3.85k
    ps_out->i4_bytes_generated = 0;
1278
1279
    /* ---------------- if any output buffer is available return the buffer back ------------- */
1280
3.85k
    while(1)
1281
3.85k
    {
1282
3.85k
        WORD32 osal_result;
1283
3.85k
        WORD32 buf_present = 0;
1284
3.85k
        WORD32 i4_is_prod = 1;
1285
3.85k
        WORD32 i4_atleast_one_br_prod = 0;
1286
        /****** Lock the critical section ******/
1287
3.85k
        osal_result =
1288
3.85k
            osal_mutex_lock(ps_app_ctxt->as_out_strm_prms[0][0].pv_app_out_strm_buf_mutex_hdl);
1289
1290
3.85k
        if(OSAL_SUCCESS != osal_result)
1291
0
            return IHEVCE_EFAIL;
1292
1293
        /* wait until entropy sends an output */
1294
7.53k
        while(1)
1295
7.53k
        {
1296
7.53k
            i4_is_prod = 1;
1297
15.0k
            for(i4_res_id = 0; i4_res_id < i4_num_resolutions; i4_res_id++)
1298
7.53k
            {
1299
15.0k
                for(i4_br_id = 0; i4_br_id < ai4_num_bitrate_instances[i4_res_id]; i4_br_id++)
1300
7.53k
                {
1301
7.53k
                    i4_is_prod &=
1302
7.53k
                        ps_ctxt->aaas_out_bufs[i4_res_id][i4_br_id][ps_ctxt->i4_prod_out_buf_idx]
1303
7.53k
                            .i4_is_prod;
1304
7.53k
                    i4_atleast_one_br_prod |=
1305
7.53k
                        ps_ctxt->aaas_out_bufs[i4_res_id][i4_br_id][ps_ctxt->i4_prod_out_buf_idx]
1306
7.53k
                            .i4_is_prod;
1307
7.53k
                }
1308
7.53k
            }
1309
7.53k
            if(!i4_is_prod)
1310
3.67k
            {
1311
7.35k
                for(i4_res_id = 0; i4_res_id < i4_num_resolutions; i4_res_id++)
1312
3.67k
                {
1313
7.35k
                    for(i4_br_id = 0; i4_br_id < ai4_num_bitrate_instances[i4_res_id]; i4_br_id++)
1314
3.67k
                    {
1315
3.67k
                        osal_cond_var_wait(
1316
3.67k
                            ps_app_ctxt->as_out_strm_prms[i4_res_id][i4_br_id]
1317
3.67k
                                .pv_app_out_strm_buf_cond_var_hdl,
1318
3.67k
                            ps_app_ctxt->as_out_strm_prms[i4_res_id][i4_br_id]
1319
3.67k
                                .pv_app_out_strm_buf_mutex_hdl);
1320
3.67k
                    }
1321
3.67k
                }
1322
3.67k
            }
1323
3.85k
            else
1324
3.85k
            {
1325
3.85k
                break;
1326
3.85k
            }
1327
7.53k
        }
1328
1329
3.85k
        ASSERT(i4_is_prod == 1);
1330
1331
        /* check if the current buffer for all bitrates and resolutions have been produced */
1332
3.85k
        if(1 == i4_is_prod)
1333
3.85k
        {
1334
3.85k
            buf_present = 1;
1335
1336
7.71k
            for(i4_res_id = 0; i4_res_id < i4_num_resolutions; i4_res_id++)
1337
3.85k
            {
1338
7.71k
                for(i4_br_id = 0; i4_br_id < ai4_num_bitrate_instances[i4_res_id]; i4_br_id++)
1339
3.85k
                {
1340
                    /* set the buffer to free status */
1341
3.85k
                    ps_ctxt->aaas_out_bufs[i4_res_id][i4_br_id][ps_ctxt->i4_prod_out_buf_idx]
1342
3.85k
                        .i4_is_free = 1;
1343
3.85k
                    if((0 == i4_res_id) && (0 == i4_br_id))
1344
3.85k
                    {
1345
3.85k
                        ps_out->i4_bytes_generated =
1346
3.85k
                            ps_ctxt->aaas_out_bufs[0][0][ps_ctxt->i4_prod_out_buf_idx].i4_bytes_gen;
1347
3.85k
                        ps_out->pu1_output_buf =
1348
3.85k
                            ps_ctxt->aaas_out_bufs[0][0][ps_ctxt->i4_prod_out_buf_idx].pu1_buf;
1349
3.85k
                    }
1350
3.85k
                }
1351
3.85k
            }
1352
1353
            /* copy the contents to output buffer */
1354
3.85k
            ps_out->i4_is_key_frame =
1355
3.85k
                ps_ctxt->aaas_out_bufs[0][0][ps_ctxt->i4_prod_out_buf_idx].i4_is_key_frame;
1356
3.85k
            ps_out->u8_pts =
1357
3.85k
                ps_ctxt->aaas_out_bufs[0][0][ps_ctxt->i4_prod_out_buf_idx].i4_timestamp_low;
1358
3.85k
            ps_out->u8_pts =
1359
3.85k
                ps_out->u8_pts |
1360
3.85k
                ((ULWORD64)(
1361
3.85k
                     ps_ctxt->aaas_out_bufs[0][0][ps_ctxt->i4_prod_out_buf_idx].i4_timestamp_high)
1362
3.85k
                 << 32);
1363
3.85k
            ps_out->i4_end_flag =
1364
3.85k
                ps_ctxt->aaas_out_bufs[0][0][ps_ctxt->i4_prod_out_buf_idx].i4_end_flag;
1365
3.85k
            ps_out->i8_dts = ps_ctxt->i8_dts;
1366
1367
            /* increment the DTS */
1368
3.85k
            ps_ctxt->i8_dts++;
1369
3.85k
        }
1370
1371
        /* check for buffer present */
1372
3.85k
        if(1 == buf_present)
1373
3.85k
        {
1374
3.85k
            ps_ctxt->i4_prod_out_buf_idx++;
1375
1376
            /* wrap around case */
1377
3.85k
            if(ps_ctxt->i4_prod_out_buf_idx == ps_ctxt->i4_num_out_bufs)
1378
885
            {
1379
885
                ps_ctxt->i4_prod_out_buf_idx = 0;
1380
885
            }
1381
1382
            /****** Unlock the critical section ******/
1383
3.85k
            osal_result = osal_mutex_unlock(
1384
3.85k
                ps_app_ctxt->as_out_strm_prms[0][0].pv_app_out_strm_buf_mutex_hdl);
1385
3.85k
            if(OSAL_SUCCESS != osal_result)
1386
0
                return IHEVCE_EFAIL;
1387
1388
            /* break while 1 loop */
1389
3.85k
            break;
1390
3.85k
        }
1391
0
        else
1392
0
        {
1393
            /* in steady state*/
1394
0
            if(0 == ps_ctxt->i4_flush_mode_on)
1395
0
            {
1396
                /****** Unlock the critical section ******/
1397
0
                osal_result = osal_mutex_unlock(
1398
0
                    ps_app_ctxt->as_out_strm_prms[0][0].pv_app_out_strm_buf_mutex_hdl);
1399
0
                if(OSAL_SUCCESS != osal_result)
1400
0
                    return IHEVCE_EFAIL;
1401
0
                if(!i4_atleast_one_br_prod) /*** If atleast one bitrate is produced do not break from loop **/
1402
0
                { /*** Continue in while loop and Wait for next bitrate ***/
1403
                    /* break while 1 loop */
1404
0
                    break;
1405
0
                }
1406
0
            }
1407
0
            else
1408
0
            {
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
0
                osal_result = osal_mutex_unlock(
1413
0
                    ps_app_ctxt->as_out_strm_prms[0][0].pv_app_out_strm_buf_mutex_hdl);
1414
0
                if(OSAL_SUCCESS != osal_result)
1415
0
                    return IHEVCE_EFAIL;
1416
0
            }
1417
0
        }
1418
3.85k
    }
1419
1420
3.85k
    return IHEVCE_EOK;
1421
3.85k
}
1422
1423
static IHEVCE_PLUGIN_STATUS_T
1424
    ihevce_queue_out_buffer(plugin_ctxt_t *ps_ctxt, WORD32 i4_res_id, WORD32 i4_br_id)
1425
4.06k
{
1426
4.06k
    app_ctxt_t *ps_app_ctxt = &ps_ctxt->s_app_ctxt;
1427
4.06k
    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
4.06k
    if(0 == ps_ctxt->ai4_out_end_flag[i4_res_id][i4_br_id])
1434
4.06k
    {
1435
4.06k
        WORD32 osal_result;
1436
4.06k
        iv_output_data_buffs_t *ps_curr_out;
1437
4.06k
        WORD32 buf_id_strm;
1438
4.06k
        WORD32 free_idx;
1439
1440
4.06k
        free_idx = ps_ctxt->ai4_free_out_buf_idx[i4_res_id][i4_br_id];
1441
1442
4.06k
        if(1 == ps_ctxt->aaas_out_bufs[i4_res_id][i4_br_id][free_idx].i4_is_free)
1443
4.06k
        {
1444
            /* ---------- get a free desc. from output Q ------ */
1445
4.06k
            ps_curr_out = (iv_output_data_buffs_t *)ihevce_q_get_free_out_strm_buff(
1446
4.06k
                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
4.06k
            if(NULL != ps_curr_out)
1450
4.06k
            {
1451
                /****** Lock the critical section ******/
1452
4.06k
                osal_result = osal_mutex_lock(ps_app_ctxt->as_out_strm_prms[i4_res_id][i4_br_id]
1453
4.06k
                                                  .pv_app_out_strm_buf_mutex_hdl);
1454
1455
4.06k
                if(OSAL_SUCCESS != osal_result)
1456
0
                    return IHEVCE_EFAIL;
1457
1458
4.06k
                if(1 == ps_app_ctxt->ai4_out_strm_end_flag[i4_res_id][i4_br_id])
1459
0
                {
1460
0
                    ps_curr_out->i4_is_last_buf = 1;
1461
0
                    ps_ctxt->ai4_out_end_flag[i4_res_id][i4_br_id] = 1;
1462
0
                }
1463
4.06k
                else
1464
4.06k
                {
1465
4.06k
                    ps_curr_out->i4_is_last_buf = 0;
1466
4.06k
                }
1467
4.06k
                ASSERT(ps_ctxt->aaas_out_bufs[i4_res_id][i4_br_id][free_idx].i4_is_free == 1);
1468
4.06k
                ASSERT(free_idx == ps_ctxt->aaas_out_bufs[i4_res_id][i4_br_id][free_idx].i4_idx);
1469
1470
4.06k
                ps_curr_out->pv_bitstream_bufs =
1471
4.06k
                    (void *)ps_ctxt->aaas_out_bufs[i4_res_id][i4_br_id][free_idx].pu1_buf;
1472
4.06k
                ps_curr_out->i4_cb_buf_id =
1473
4.06k
                    ps_ctxt->aaas_out_bufs[i4_res_id][i4_br_id][free_idx].i4_idx;
1474
4.06k
                ps_ctxt->aaas_out_bufs[i4_res_id][i4_br_id][free_idx].i4_is_free = 0;
1475
4.06k
                ps_ctxt->aaas_out_bufs[i4_res_id][i4_br_id][free_idx].i4_is_prod = 0;
1476
4.06k
                ps_ctxt->aaas_out_bufs[i4_res_id][i4_br_id][free_idx].i4_bytes_gen = 0;
1477
1478
4.06k
                ps_ctxt->ai4_free_out_buf_idx[i4_res_id][i4_br_id]++;
1479
1480
                /* wrap around case */
1481
4.06k
                if(ps_ctxt->ai4_free_out_buf_idx[i4_res_id][i4_br_id] == ps_ctxt->i4_num_out_bufs)
1482
955
                {
1483
955
                    ps_ctxt->ai4_free_out_buf_idx[i4_res_id][i4_br_id] = 0;
1484
955
                }
1485
1486
                /****** Unlock the critical section ******/
1487
4.06k
                osal_result = osal_mutex_unlock(ps_app_ctxt->as_out_strm_prms[i4_res_id][i4_br_id]
1488
4.06k
                                                    .pv_app_out_strm_buf_mutex_hdl);
1489
4.06k
                if(OSAL_SUCCESS != osal_result)
1490
0
                    return IHEVCE_EFAIL;
1491
1492
                /* ---------- set the buffer as produced ---------- */
1493
4.06k
                ihevce_q_set_out_strm_buff_prod(
1494
4.06k
                    ps_interface_ctxt, buf_id_strm, i4_br_id, i4_res_id);
1495
4.06k
            }
1496
4.06k
        }
1497
4.06k
    }
1498
4.06k
    return IHEVCE_EOK;
1499
4.06k
}
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
*/
1518
IHEVCE_PLUGIN_STATUS_T ihevce_close(void *pv_ihevce_hdl)
1519
182
{
1520
    /* local variables */
1521
182
    plugin_ctxt_t *ps_ctxt;
1522
182
    app_ctxt_t *ps_app_ctxt;
1523
182
    ihevce_hle_ctxt_t *ps_interface_ctxt;
1524
182
    WORD32 i4_num_resolutions;
1525
182
    WORD32 i4_res_id;
1526
182
    WORD32 i4_br_id;
1527
182
    WORD32 ai4_num_bitrate_instances[IHEVCE_MAX_NUM_RESOLUTIONS] = { 1 };
1528
182
    ihevce_sys_api_t *ps_sys_api;
1529
1530
    /* sanity checks */
1531
182
    if(NULL == pv_ihevce_hdl)
1532
0
        return (IHEVCE_EFAIL);
1533
1534
    /* derive local variables */
1535
182
    ps_ctxt = (plugin_ctxt_t *)pv_ihevce_hdl;
1536
1537
182
    ps_sys_api = &ps_ctxt->ps_static_cfg_prms->s_sys_api;
1538
1539
182
    if((0 == ps_ctxt->ps_static_cfg_prms->i4_res_id) &&
1540
182
       (0 == ps_ctxt->ps_static_cfg_prms->i4_br_id))
1541
182
    {
1542
182
        ps_interface_ctxt = (ihevce_hle_ctxt_t *)ps_ctxt->pv_hle_interface_ctxt;
1543
182
        ps_app_ctxt = &ps_ctxt->s_app_ctxt;
1544
182
        i4_num_resolutions = ps_ctxt->ps_static_cfg_prms->s_tgt_lyr_prms.i4_num_res_layers;
1545
1546
182
        if(1 != ps_ctxt->i4_flush_mode_on)
1547
182
        {
1548
364
            for(i4_res_id = 0; i4_res_id < i4_num_resolutions; i4_res_id++)
1549
182
            {
1550
182
                ai4_num_bitrate_instances[i4_res_id] =
1551
182
                    ps_ctxt->ps_static_cfg_prms->s_tgt_lyr_prms.as_tgt_params[i4_res_id]
1552
182
                        .i4_num_bitrate_instances;
1553
364
                for(i4_br_id = 0; i4_br_id < ai4_num_bitrate_instances[i4_res_id]; i4_br_id++)
1554
182
                {
1555
                    /* ------- Que in free output buffer if end flag is not set ------ */
1556
182
                    ihevce_queue_out_buffer(ps_ctxt, i4_res_id, i4_br_id);
1557
182
                }
1558
182
            }
1559
            /* --------------------------------------------------------------------- */
1560
            /*            Input Processing                                           */
1561
            /* --------------------------------------------------------------------- */
1562
182
            {
1563
182
                WORD32 buf_id;
1564
1565
182
                iv_input_data_ctrl_buffs_t *ps_curr_inp;
1566
182
                WORD32 *pi4_ctrl_ptr;
1567
1568
                /* ---------- get a free buffer from input Q ------ */
1569
182
                ps_curr_inp = (iv_input_data_ctrl_buffs_t *)ihevce_q_get_free_inp_data_buff(
1570
182
                    ps_interface_ctxt, &buf_id, BUFF_QUE_BLOCKING_MODE);
1571
1572
182
                if(NULL != ps_curr_inp)
1573
182
                {
1574
                    /* flush mode command */
1575
1576
182
                    ps_curr_inp->i4_buf_id = buf_id;
1577
1578
                    /* set the input status to invalid flag */
1579
182
                    ps_curr_inp->i4_inp_frm_data_valid_flag = 0;
1580
1581
182
                    pi4_ctrl_ptr = (WORD32 *)ps_curr_inp->pv_synch_ctrl_bufs;
1582
1583
182
                    *pi4_ctrl_ptr = IHEVCE_SYNCH_API_FLUSH_TAG;
1584
182
                    *(pi4_ctrl_ptr + 1) = 0;
1585
182
                    *(pi4_ctrl_ptr + 2) = IHEVCE_SYNCH_API_END_TAG;
1586
1587
182
                    ps_curr_inp->i4_cmd_buf_size = 4 * 3; /* 4 bytes */
1588
1589
                    /* ---------- set the buffer as produced ---------- */
1590
182
                    ihevce_q_set_inp_data_buff_prod(ps_interface_ctxt, buf_id);
1591
182
                }
1592
0
                else
1593
0
                {
1594
                    /* Enable flush-mode and internal-flush once limit according to
1595
                    Eval-version is reached */
1596
0
                    ps_ctxt->i4_flush_mode_on = 1;
1597
0
                }
1598
182
            }
1599
182
        }
1600
1601
        /* --------------------------------------------------------------------- */
1602
        /*            Wait and destroy Processing threads                        */
1603
        /* --------------------------------------------------------------------- */
1604
1605
        /* Wait for High level encoder thread to complete */
1606
182
        osal_thread_wait(ps_ctxt->pv_hle_thread_hdl);
1607
1608
        /* Destroy Hle thread */
1609
182
        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
364
        for(i4_res_id = 0; i4_res_id < i4_num_resolutions; i4_res_id++)
1618
182
        {
1619
182
            ai4_num_bitrate_instances[i4_res_id] =
1620
182
                ps_ctxt->ps_static_cfg_prms->s_tgt_lyr_prms.as_tgt_params[i4_res_id]
1621
182
                    .i4_num_bitrate_instances;
1622
1623
364
            for(i4_br_id = 0; i4_br_id < ai4_num_bitrate_instances[i4_res_id]; i4_br_id++)
1624
182
            {
1625
182
                mem_mngr_free(
1626
182
                    ps_app_ctxt->pv_mem_mngr_handle,
1627
182
                    &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
182
                osal_mutex_destroy(ps_app_ctxt->as_out_strm_prms[i4_res_id][i4_br_id]
1631
182
                                       .pv_app_out_strm_buf_mutex_hdl);
1632
1633
182
                osal_cond_var_destroy(ps_app_ctxt->as_out_strm_prms[i4_res_id][i4_br_id]
1634
182
                                          .pv_app_out_strm_buf_cond_var_hdl);
1635
182
            }
1636
182
        }
1637
1638
182
        ps_ctxt->ihevce_mem_free(NULL, ps_ctxt->pu1_out_ctrl_buf);
1639
182
        ps_ctxt->ihevce_mem_free(NULL, ps_ctxt->pu1_inp_async_ctrl_buf);
1640
1641
        /* free input data and control buffer */
1642
182
        if(ps_interface_ctxt->i4_create_time_input_allocation == 1)
1643
182
        {
1644
182
            mem_mngr_free(ps_app_ctxt->pv_mem_mngr_handle, &ps_ctxt->s_memtab_inp_data_buf);
1645
182
            mem_mngr_free(ps_app_ctxt->pv_mem_mngr_handle, &ps_ctxt->s_memtab_inp_sync_ctrl_buf);
1646
182
        }
1647
1648
        /* --------------------------------------------------------------------- */
1649
        /*               Encoder Instance Deletion                               */
1650
        /* --------------------------------------------------------------------- */
1651
182
        ihevce_hle_interface_delete(ps_interface_ctxt);
1652
1653
        /* free the high level encoder context memory */
1654
182
        ps_ctxt->ihevce_mem_free(NULL, ps_ctxt->pv_hle_interface_ctxt);
1655
1656
182
        if(ps_ctxt->ps_static_cfg_prms->i4_enable_csv_dump)
1657
0
        {
1658
0
            ps_sys_api->s_file_io_api.ihevce_fclose(
1659
0
                (void *)ps_sys_api->pv_cb_handle, ps_ctxt->ps_static_cfg_prms->apF_csv_file[0][0]);
1660
0
        }
1661
1662
        /* free static config memory */
1663
182
        ps_ctxt->ihevce_mem_free(NULL, ps_ctxt->ps_static_cfg_prms);
1664
1665
        /* free osal handle */
1666
182
        memory_free(NULL, ps_ctxt->pv_osal_handle);
1667
1668
        /* free plugin ctxt memory */
1669
182
        memory_free(NULL, pv_ihevce_hdl);
1670
182
    }
1671
0
    else
1672
0
    {
1673
0
        return (IHEVCE_EFAIL);
1674
0
    }
1675
1676
182
    return (IHEVCE_EOK);
1677
182
}
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
*/
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
3.70k
{
1703
3.70k
    UWORD8 *pu1_src, *pu1_dst;
1704
3.70k
    WORD32 src_strd, dst_strd;
1705
3.70k
    WORD32 frm_height = i4_orig_ht;
1706
3.70k
    WORD32 frm_width = i4_orig_wd;
1707
3.70k
    WORD32 buf_height = ps_curr_inp->s_input_buf.i4_y_ht;
1708
3.70k
    WORD32 buf_width = ps_curr_inp->s_input_buf.i4_y_wd;
1709
3.70k
    WORD32 rows, cols;
1710
1711
3.70k
    pu1_src = (UWORD8 *)ps_inp->apv_inp_planes[0];
1712
3.70k
    src_strd = ps_inp->ai4_inp_strd[0];
1713
3.70k
    pu1_dst = (UWORD8 *)ps_curr_inp->s_input_buf.pv_y_buf;
1714
3.70k
    dst_strd = ps_curr_inp->s_input_buf.i4_y_strd;
1715
1716
3.70k
    if((ps_inp->ai4_inp_size[0] < (src_strd * frm_height)) || (ps_inp->ai4_inp_size[0] <= 0) ||
1717
3.70k
       (ps_inp->apv_inp_planes[0] == NULL))
1718
0
    {
1719
0
        return (IV_FAIL);
1720
0
    }
1721
    /* copy the input luma data into internal buffer */
1722
283k
    for(rows = 0; rows < frm_height; rows++)
1723
279k
    {
1724
279k
        memcpy(pu1_dst, pu1_src, frm_width);
1725
279k
        if(buf_width > frm_width)
1726
185k
        {
1727
185k
            memset(pu1_dst + frm_width, 0x0, buf_width - frm_width);
1728
185k
        }
1729
279k
        pu1_src += src_strd;
1730
279k
        pu1_dst += dst_strd;
1731
279k
    }
1732
82.3k
    while(rows < buf_height)
1733
78.6k
    {
1734
78.6k
        memset(pu1_dst, 0x0, buf_width);
1735
78.6k
        pu1_dst += dst_strd;
1736
78.6k
        rows++;
1737
78.6k
    }
1738
1739
3.70k
    if(IV_YUV_420P == chroma_format)
1740
3.70k
    {
1741
3.70k
        UWORD8 *pu1_src_u, *pu1_src_v;
1742
3.70k
        WORD32 src_strd_u, src_strd_v;
1743
1744
3.70k
        pu1_src_u = (UWORD8 *)ps_inp->apv_inp_planes[1];
1745
3.70k
        src_strd_u = ps_inp->ai4_inp_strd[1];
1746
3.70k
        pu1_src_v = (UWORD8 *)ps_inp->apv_inp_planes[2];
1747
3.70k
        src_strd_v = ps_inp->ai4_inp_strd[2];
1748
3.70k
        pu1_dst = (UWORD8 *)ps_curr_inp->s_input_buf.pv_u_buf;
1749
3.70k
        dst_strd = ps_curr_inp->s_input_buf.i4_uv_strd;
1750
1751
3.70k
        frm_width = i4_orig_wd >> 1;
1752
3.70k
        frm_height = i4_orig_ht >> 1;
1753
3.70k
        buf_width = ps_curr_inp->s_input_buf.i4_uv_wd;
1754
3.70k
        buf_height = ps_curr_inp->s_input_buf.i4_uv_ht;
1755
1756
3.70k
        if((ps_inp->ai4_inp_size[1] < (ps_inp->ai4_inp_strd[1] * frm_height)) ||
1757
3.70k
           (ps_inp->ai4_inp_size[1] <= 0) || (pu1_src_u == NULL))
1758
0
        {
1759
0
            return (IV_FAIL);
1760
0
        }
1761
3.70k
        if((ps_inp->ai4_inp_size[2] < (ps_inp->ai4_inp_strd[2] * frm_height)) ||
1762
3.70k
           (ps_inp->ai4_inp_size[2] <= 0) || (pu1_src_v == NULL))
1763
0
        {
1764
0
            return (IV_FAIL);
1765
0
        }
1766
1767
        /* copy the input chroma data in pixel interleaved format */
1768
143k
        for(rows = 0; rows < frm_height; rows++)
1769
139k
        {
1770
8.16M
            for(cols = 0; cols < frm_width; cols++)
1771
8.02M
            {
1772
                /* U V alternate */
1773
8.02M
                pu1_dst[(cols << 1)] = pu1_src_u[cols];
1774
8.02M
                pu1_dst[(cols << 1) + 1] = pu1_src_v[cols];
1775
8.02M
            }
1776
139k
            if(buf_width > (cols << 1))
1777
92.5k
            {
1778
92.5k
                memset(&pu1_dst[(cols << 1)], 0x80, buf_width - (cols << 1));
1779
92.5k
            }
1780
1781
139k
            pu1_src_u += src_strd_u;
1782
139k
            pu1_src_v += src_strd_v;
1783
139k
            pu1_dst += dst_strd;
1784
139k
        }
1785
43.1k
        while(rows < buf_height)
1786
39.4k
        {
1787
39.4k
            memset(pu1_dst, 0x80, buf_width);
1788
1789
39.4k
            pu1_dst += dst_strd;
1790
39.4k
            rows++;
1791
39.4k
        }
1792
3.70k
    }
1793
0
    else if(IV_YUV_420SP_UV == chroma_format)
1794
0
    {
1795
0
        pu1_src = (UWORD8 *)ps_inp->apv_inp_planes[1];
1796
0
        src_strd = ps_inp->ai4_inp_strd[1];
1797
0
        pu1_dst = (UWORD8 *)ps_curr_inp->s_input_buf.pv_u_buf;
1798
0
        dst_strd = ps_curr_inp->s_input_buf.i4_uv_strd;
1799
1800
0
        frm_width = i4_orig_wd;
1801
0
        frm_height = i4_orig_ht >> 1;
1802
0
        buf_width = ps_curr_inp->s_input_buf.i4_uv_wd;
1803
0
        buf_height = ps_curr_inp->s_input_buf.i4_uv_ht;
1804
1805
0
        if((ps_inp->ai4_inp_size[1] < (ps_inp->ai4_inp_strd[1] * frm_height)) ||
1806
0
           (ps_inp->ai4_inp_size[1] <= 0) || (pu1_src == NULL))
1807
0
        {
1808
0
            return (IV_FAIL);
1809
0
        }
1810
1811
        /* copy the input luma data into internal buffer */
1812
0
        for(rows = 0; rows < frm_height; rows++)
1813
0
        {
1814
0
            memcpy(pu1_dst, pu1_src, frm_width);
1815
0
            if(buf_width > frm_width)
1816
0
            {
1817
0
                memset(pu1_dst + frm_width, 0x80, buf_width - frm_width);
1818
0
            }
1819
0
            pu1_src += src_strd;
1820
0
            pu1_dst += dst_strd;
1821
0
        }
1822
0
        while(rows < buf_height)
1823
0
        {
1824
0
            memset(pu1_dst, 0x80, buf_width);
1825
0
            pu1_dst += dst_strd;
1826
0
            rows++;
1827
0
        }
1828
0
    }
1829
3.70k
    return (IV_SUCCESS);
1830
3.70k
}
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
*/
1849
IHEVCE_PLUGIN_STATUS_T ihevce_encode_header(void *pv_ihevce_hdl, ihevce_out_buf_t *ps_out)
1850
182
{
1851
182
    plugin_ctxt_t *ps_ctxt = (plugin_ctxt_t *)pv_ihevce_hdl;
1852
182
    ihevce_hle_ctxt_t *ps_interface_ctxt;
1853
1854
    /* sanity checks */
1855
182
    if(NULL == pv_ihevce_hdl)
1856
0
        return (IHEVCE_EFAIL);
1857
1858
182
    if(NULL == ps_out)
1859
0
        return (IHEVCE_EFAIL);
1860
1861
182
    if((0 == ps_ctxt->ps_static_cfg_prms->i4_res_id) &&
1862
182
       (0 == ps_ctxt->ps_static_cfg_prms->i4_br_id))
1863
182
    {
1864
182
        WORD32 status;
1865
1866
        /* ------- Que in free output buffer if end flag is not set ------ */
1867
182
        ihevce_queue_out_buffer(ps_ctxt, 0, 0);
1868
1869
        /* ------- API call to encoder header ------- */
1870
182
        ps_interface_ctxt = (ihevce_hle_ctxt_t *)ps_ctxt->pv_hle_interface_ctxt;
1871
182
        status = ihevce_entropy_encode_header(ps_interface_ctxt, 0, 0);
1872
182
        if(status)
1873
0
            return IHEVCE_EFAIL;
1874
1875
        /* ------- receive header ------- */
1876
182
        ihevce_receive_out_buffer(ps_ctxt, ps_out);
1877
182
    }
1878
0
    else
1879
0
    {
1880
0
        return (IHEVCE_EFAIL);
1881
0
    }
1882
1883
182
    return (IHEVCE_EOK);
1884
182
}
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
1904
    ihevce_encode(void *pv_ihevce_hdl, ihevce_inp_buf_t *ps_inp, ihevce_out_buf_t *ps_out)
1905
3.70k
{
1906
    /* local variables */
1907
3.70k
    plugin_ctxt_t *ps_ctxt;
1908
3.70k
    app_ctxt_t *ps_app_ctxt;
1909
3.70k
    ihevce_hle_ctxt_t *ps_interface_ctxt;
1910
1911
3.70k
    WORD32 i4_res_id, i4_br_id;
1912
3.70k
    WORD32 i4_num_resolutions;
1913
3.70k
    WORD32 ai4_num_bitrate_instances[IHEVCE_MAX_NUM_RESOLUTIONS] = { 1 };
1914
3.70k
    UWORD32 u4_latency = 0;
1915
1916
    /* sanity checks */
1917
3.70k
    if(NULL == pv_ihevce_hdl)
1918
0
        return (IHEVCE_EFAIL);
1919
1920
3.70k
    if(NULL == ps_out)
1921
0
        return (IHEVCE_EFAIL);
1922
1923
    /* derive local variables */
1924
3.70k
    ps_ctxt = (plugin_ctxt_t *)pv_ihevce_hdl;
1925
3.70k
    if((0 == ps_ctxt->ps_static_cfg_prms->i4_res_id) &&
1926
3.70k
       (0 == ps_ctxt->ps_static_cfg_prms->i4_br_id))
1927
3.70k
    {
1928
3.70k
        ps_interface_ctxt = (ihevce_hle_ctxt_t *)ps_ctxt->pv_hle_interface_ctxt;
1929
3.70k
        ps_app_ctxt = &ps_ctxt->s_app_ctxt;
1930
3.70k
        i4_num_resolutions = ps_ctxt->ps_static_cfg_prms->s_tgt_lyr_prms.i4_num_res_layers;
1931
1932
3.70k
        if(ps_ctxt->ps_static_cfg_prms->s_coding_tools_prms.i4_max_temporal_layers)
1933
95
        {
1934
95
            u4_latency +=
1935
95
                (1 << ps_ctxt->ps_static_cfg_prms->s_coding_tools_prms.i4_max_temporal_layers) - 1;
1936
95
        }
1937
1938
3.70k
        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
3.70k
        if(ps_ctxt->i4_internal_flush)
1943
0
        {
1944
0
            if(1 == ps_app_ctxt->ai4_out_strm_end_flag[0][0])
1945
0
                return (IHEVCE_EFAIL);
1946
0
        }
1947
1948
7.40k
        for(i4_res_id = 0; i4_res_id < i4_num_resolutions; i4_res_id++)
1949
3.70k
        {
1950
3.70k
            ai4_num_bitrate_instances[i4_res_id] =
1951
3.70k
                ps_ctxt->ps_static_cfg_prms->s_tgt_lyr_prms.as_tgt_params[i4_res_id]
1952
3.70k
                    .i4_num_bitrate_instances;
1953
7.40k
            for(i4_br_id = 0; i4_br_id < ai4_num_bitrate_instances[i4_res_id]; i4_br_id++)
1954
3.70k
            {
1955
                /* ------- Que in free output buffer if end flag is not set ------ */
1956
3.70k
                ihevce_queue_out_buffer(ps_ctxt, i4_res_id, i4_br_id);
1957
3.70k
            }
1958
3.70k
        }
1959
1960
        /* --------------------------------------------------------------------- */
1961
        /*            Input Processing                                           */
1962
        /* --------------------------------------------------------------------- */
1963
3.70k
        if(0 == ps_ctxt->i4_flush_mode_on)
1964
3.70k
        {
1965
3.70k
            WORD32 frm_stride;
1966
3.70k
            WORD32 frm_width;
1967
3.70k
            WORD32 frm_height;
1968
3.70k
            WORD32 buf_id;
1969
1970
3.70k
            iv_input_data_ctrl_buffs_t *ps_curr_inp;
1971
3.70k
            WORD32 *pi4_ctrl_ptr;
1972
1973
3.70k
            frm_width = ps_ctxt->ps_static_cfg_prms->s_src_prms.i4_width;
1974
3.70k
            frm_height = ps_ctxt->ps_static_cfg_prms->s_src_prms.i4_height;
1975
3.70k
            frm_stride = ps_ctxt->i4_frm_stride;
1976
1977
            /* ---------- get a free buffer from input Q ------ */
1978
3.70k
            ps_curr_inp = (iv_input_data_ctrl_buffs_t *)ihevce_q_get_free_inp_data_buff(
1979
3.70k
                ps_interface_ctxt, &buf_id, BUFF_QUE_BLOCKING_MODE);
1980
1981
3.70k
            if(NULL != ps_curr_inp)
1982
3.70k
            {
1983
                /* if input buffer is not NULL */
1984
3.70k
                if(NULL != ps_inp)
1985
3.70k
                {
1986
3.70k
                    WORD32 result;
1987
1988
3.70k
                    pi4_ctrl_ptr = (WORD32 *)ps_curr_inp->pv_synch_ctrl_bufs;
1989
1990
                    /* ---------- set ip params ---------- */
1991
3.70k
                    ps_curr_inp->s_input_buf.i4_size = sizeof(iv_yuv_buf_t);
1992
3.70k
                    ps_curr_inp->s_input_buf.i4_y_wd = frm_width;
1993
3.70k
                    ps_curr_inp->s_input_buf.i4_y_ht = frm_height;
1994
3.70k
                    ps_curr_inp->s_input_buf.i4_y_strd = frm_stride;
1995
3.70k
                    ps_curr_inp->s_input_buf.i4_uv_wd = frm_width;
1996
3.70k
                    ps_curr_inp->s_input_buf.i4_uv_ht =
1997
3.70k
                        frm_height >>
1998
3.70k
                        ((ps_ctxt->ps_static_cfg_prms->s_src_prms.inp_chr_format == 13) ? 0 : 1);
1999
3.70k
                    ps_curr_inp->s_input_buf.i4_uv_strd = frm_stride;
2000
2001
3.70k
                    ps_curr_inp->i4_buf_id = buf_id;
2002
3.70k
                    ps_curr_inp->i4_inp_frm_data_valid_flag = 1;
2003
3.70k
                    ps_curr_inp->i4_topfield_first = 1; /* set to default */
2004
3.70k
                    ps_curr_inp->i4_bottom_field = ps_ctxt->i4_field_id;
2005
3.70k
                    ps_curr_inp->i4_inp_timestamp_low = (WORD32)(ps_inp->u8_pts & 0xFFFFFFFF);
2006
3.70k
                    ps_curr_inp->i4_inp_timestamp_high = (WORD32)(ps_inp->u8_pts >> 32);
2007
2008
                    /* toggle field id */
2009
3.70k
                    ps_ctxt->i4_field_id = !ps_ctxt->i4_field_id;
2010
2011
                    /* ---------- Introduction of Force IDR locs   ---------- */
2012
3.70k
                    if(ps_inp->i4_force_idr_flag)
2013
53
                    {
2014
53
                        *pi4_ctrl_ptr = IHEVCE_SYNCH_API_FORCE_IDR_TAG;
2015
53
                        *(pi4_ctrl_ptr + 1) = 0;
2016
53
                        pi4_ctrl_ptr += 2;
2017
2018
                        /* set the cmd to NA */
2019
53
                        *pi4_ctrl_ptr = IHEVCE_SYNCH_API_END_TAG;
2020
2021
53
                        ps_curr_inp->i4_cmd_buf_size = 4 * 3; /* 12 bytes */
2022
53
                    }
2023
3.65k
                    else
2024
3.65k
                    {
2025
                        /* set the cmd to NA */
2026
3.65k
                        *pi4_ctrl_ptr = IHEVCE_SYNCH_API_END_TAG;
2027
2028
3.65k
                        ps_curr_inp->i4_cmd_buf_size = 4; /* 4 bytes */
2029
3.65k
                    }
2030
                    /* call the input copy function */
2031
3.70k
                    result = ihevce_copy_inp_8bit(
2032
3.70k
                        ps_curr_inp,
2033
3.70k
                        ps_inp,
2034
3.70k
                        ps_ctxt->ps_static_cfg_prms->s_src_prms.inp_chr_format,
2035
3.70k
                        ps_ctxt->ps_static_cfg_prms->s_src_prms.i4_orig_width,
2036
3.70k
                        ps_ctxt->ps_static_cfg_prms->s_src_prms.i4_orig_height);
2037
2038
3.70k
                    if(IV_SUCCESS != result)
2039
0
                        return (IHEVCE_EFAIL);
2040
2041
3.70k
                    if(3 != ps_ctxt->ps_static_cfg_prms->s_config_prms.i4_rate_control_mode)
2042
2.64k
                    {
2043
                        /* Dynamic Change in bitrate not supported for multi res/MBR */
2044
                        /*** Check for change in bitrate command ***/
2045
2.64k
                        if(ps_ctxt->ai4_old_bitrate[0][0] != ps_inp->i4_curr_bitrate)
2046
159
                        {
2047
159
                            WORD32 buf_id;
2048
159
                            WORD32 *pi4_cmd_buf;
2049
159
                            iv_input_ctrl_buffs_t *ps_ctrl_buf;
2050
159
                            ihevce_dyn_config_prms_t *ps_dyn_br;
2051
159
                            WORD32 codec_level_index = ihevce_get_level_index(
2052
159
                                ps_ctxt->ps_static_cfg_prms->s_tgt_lyr_prms.as_tgt_params[0]
2053
159
                                    .i4_codec_level);
2054
159
                            WORD32 max_bitrate =
2055
159
                                g_as_level_data[codec_level_index].i4_max_bit_rate
2056
159
                                    [ps_ctxt->ps_static_cfg_prms->s_out_strm_prms.i4_codec_tier] *
2057
159
                                1000;
2058
2059
                            /* ---------- get a free buffer from command Q ------ */
2060
159
                            ps_ctrl_buf = (iv_input_ctrl_buffs_t *)ihevce_q_get_free_inp_ctrl_buff(
2061
159
                                ps_interface_ctxt, &buf_id, BUFF_QUE_BLOCKING_MODE);
2062
                            /* store the buffer id */
2063
159
                            ps_ctrl_buf->i4_buf_id = buf_id;
2064
2065
                            /* get the buffer pointer */
2066
159
                            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
159
                            *pi4_cmd_buf = IHEVCE_ASYNCH_API_SETBITRATE_TAG;
2070
159
                            *(pi4_cmd_buf + 1) = sizeof(ihevce_dyn_config_prms_t);
2071
2072
159
                            ps_dyn_br = (ihevce_dyn_config_prms_t *)(pi4_cmd_buf + 2);
2073
159
                            ps_dyn_br->i4_size = sizeof(ihevce_dyn_config_prms_t);
2074
159
                            ps_dyn_br->i4_tgt_br_id = 0;
2075
159
                            ps_dyn_br->i4_tgt_res_id = 0;
2076
159
                            ps_dyn_br->i4_new_tgt_bitrate =
2077
159
                                MIN(ps_inp->i4_curr_bitrate, max_bitrate);
2078
159
                            ps_dyn_br->i4_new_tgt_bitrate =
2079
159
                                MAX(ps_dyn_br->i4_new_tgt_bitrate, MIN_BITRATE);
2080
159
                            ps_dyn_br->i4_new_peak_bitrate =
2081
159
                                MIN((ps_dyn_br->i4_new_tgt_bitrate << 1), max_bitrate);
2082
159
                            pi4_cmd_buf += 2;
2083
159
                            pi4_cmd_buf += (sizeof(ihevce_dyn_config_prms_t) >> 2);
2084
2085
159
                            *(pi4_cmd_buf) = IHEVCE_ASYNCH_API_END_TAG;
2086
2087
159
                            ps_ctrl_buf->i4_cmd_buf_size = 12 + sizeof(ihevce_dyn_config_prms_t);
2088
2089
                            /* ---------- set the buffer as produced ---------- */
2090
159
                            ihevce_q_set_inp_ctrl_buff_prod(ps_interface_ctxt, buf_id);
2091
2092
159
                            ps_ctxt->ai4_old_bitrate[0][0] = ps_dyn_br->i4_new_tgt_bitrate;
2093
159
                        }
2094
2.64k
                    }
2095
2096
3.70k
                    ps_ctxt->u8_num_frames_queued++;
2097
3.70k
                }
2098
0
                else
2099
0
                { /* flush mode command */
2100
2101
0
                    ps_curr_inp->i4_buf_id = buf_id;
2102
2103
                    /* set the input status to invalid flag */
2104
0
                    ps_curr_inp->i4_inp_frm_data_valid_flag = 0;
2105
2106
0
                    pi4_ctrl_ptr = (WORD32 *)ps_curr_inp->pv_synch_ctrl_bufs;
2107
2108
0
                    *pi4_ctrl_ptr = IHEVCE_SYNCH_API_FLUSH_TAG;
2109
0
                    *(pi4_ctrl_ptr + 1) = 0;
2110
0
                    *(pi4_ctrl_ptr + 2) = IHEVCE_SYNCH_API_END_TAG;
2111
2112
0
                    ps_curr_inp->i4_cmd_buf_size = 4 * 3; /* 4 bytes */
2113
0
                }
2114
2115
                /* ---------- set the buffer as produced ---------- */
2116
3.70k
                ihevce_q_set_inp_data_buff_prod(ps_interface_ctxt, buf_id);
2117
3.70k
                ps_ctxt->u8_num_frames_encoded++;
2118
3.70k
            }
2119
0
            else
2120
0
            {
2121
                /* Enable flush-mode and internal-flush once limit according to
2122
                Eval-version is reached */
2123
0
                ps_ctxt->i4_flush_mode_on = 1;
2124
0
                ps_ctxt->i4_internal_flush = 1;
2125
0
            }
2126
3.70k
        }
2127
2128
        /* set encoder in flush mode if input buffer is NULL */
2129
3.70k
        if(0 == ps_ctxt->i4_flush_mode_on)
2130
3.70k
        {
2131
3.70k
            if(NULL == ps_inp)
2132
0
            {
2133
0
                ps_ctxt->i4_flush_mode_on = 1;
2134
0
            }
2135
3.70k
        }
2136
2137
3.70k
        if((u4_latency < ps_ctxt->u8_num_frames_queued) || (1 == ps_ctxt->i4_flush_mode_on))
2138
3.67k
        {
2139
            /* --------------------------------------------------------------------- */
2140
            /*            Output Processing                                          */
2141
            /* --------------------------------------------------------------------- */
2142
3.67k
            ihevce_receive_out_buffer(ps_ctxt, ps_out);
2143
3.67k
        }
2144
3.70k
    }
2145
0
    else  //Other bitrate and resolution instances
2146
0
    {
2147
0
        return IHEVCE_EFAIL;
2148
0
    }
2149
3.70k
    return (IHEVCE_EOK);
2150
3.70k
}
2151