1 /******************************************************************************
2 *
3 * Copyright (C) 2015 The Android Open Source Project
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at:
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 *
17 *****************************************************************************
18 * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
19 */
20
21 /**
22 *******************************************************************************
23 * @file
24 * ih264e_api.c
25 *
26 * @brief
27 * Contains api function definitions for H264 encoder
28 *
29 * @author
30 * ittiam
31 *
32 * @par List of Functions:
33 * - api_check_struct_sanity()
34 * - ih264e_codec_update_config()
35 * - ih264e_set_default_params()
36 * - ih264e_init()
37 * - ih264e_get_num_rec()
38 * - ih264e_fill_num_mem_rec()
39 * - ih264e_init_mem_rec()
40 * - ih264e_retrieve_memrec()
41 * - ih264e_set_flush_mode()
42 * - ih264e_get_buf_info()
43 * - ih264e_set_dimensions()
44 * - ih264e_set_frame_rate()
45 * - ih264e_set_bit_rate()
46 * - ih264e_set_frame_type()
47 * - ih264e_set_qp()
48 * - ih264e_set_enc_mode()
49 * - ih264e_set_vbv_params()
50 * - ih264_set_air_params()
51 * - ih264_set_me_params()
52 * - ih264_set_ipe_params()
53 * - ih264_set_gop_params()
54 * - ih264_set_profile_params()
55 * - ih264_set_deblock_params()
56 * - ih264e_set_num_cores()
57 * - ih264e_reset()
58 * - ih264e_ctl()
59 * - ih264e_api_function()
60 *
61 * @remarks
62 * None
63 *
64 *******************************************************************************
65 */
66
67 /*****************************************************************************/
68 /* File Includes */
69 /*****************************************************************************/
70
71 /* System Include Files */
72 #include <stdio.h>
73 #include <stddef.h>
74 #include <stdlib.h>
75 #include <string.h>
76 #include <assert.h>
77
78 /* User Include Files */
79 #include "ih264e_config.h"
80 #include "ih264_typedefs.h"
81 #include "ih264_size_defs.h"
82 #include "iv2.h"
83 #include "ive2.h"
84 #include "ih264e.h"
85 #include "ithread.h"
86 #include "ih264_debug.h"
87 #include "ih264_defs.h"
88 #include "ih264_error.h"
89 #include "ih264_structs.h"
90 #include "ih264_trans_quant_itrans_iquant.h"
91 #include "ih264_inter_pred_filters.h"
92 #include "ih264_mem_fns.h"
93 #include "ih264_padding.h"
94 #include "ih264_intra_pred_filters.h"
95 #include "ih264_deblk_edge_filters.h"
96 #include "ih264_cabac_tables.h"
97 #include "ih264_macros.h"
98 #include "ih264e_defs.h"
99 #include "ih264e_globals.h"
100 #include "ih264_buf_mgr.h"
101 #include "irc_mem_req_and_acq.h"
102 #include "irc_cntrl_param.h"
103 #include "irc_frame_info_collector.h"
104 #include "irc_rate_control_api.h"
105 #include "ih264e_time_stamp.h"
106 #include "ih264e_modify_frm_rate.h"
107 #include "ih264e_rate_control.h"
108 #include "ih264e_error.h"
109 #include "ih264e_bitstream.h"
110 #include "ime_defs.h"
111 #include "ime_distortion_metrics.h"
112 #include "ime_structs.h"
113 #include "ih264e_cabac_structs.h"
114 #include "ih264e_structs.h"
115 #include "ih264e_utils.h"
116 #include "ih264e_core_coding.h"
117 #include "ih264_platform_macros.h"
118 #include "ih264e_platform_macros.h"
119 #include "ih264_list.h"
120 #include "ih264_dpb_mgr.h"
121 #include "ih264_cavlc_tables.h"
122 #include "ih264e_cavlc.h"
123 #include "ih264_common_tables.h"
124 #include "ih264e_master.h"
125 #include "ih264e_fmt_conv.h"
126 #include "ih264e_version.h"
127
128
129 /*****************************************************************************/
130 /* Function Declarations */
131 /*****************************************************************************/
132 WORD32 ih264e_get_rate_control_mem_tab(void *pv_rate_control,
133 iv_mem_rec_t *ps_mem,
134 ITT_FUNC_TYPE_E e_func_type);
135
136
137 /*****************************************************************************/
138 /* Function Definitions */
139 /*****************************************************************************/
140
141 /**
142 *******************************************************************************
143 *
144 * @brief
145 * Used to test arguments for corresponding API call
146 *
147 * @par Description:
148 * For each command the arguments are validated
149 *
150 * @param[in] ps_handle
151 * Codec handle at API level
152 *
153 * @param[in] pv_api_ip
154 * Pointer to input structure
155 *
156 * @param[out] pv_api_op
157 * Pointer to output structure
158 *
159 * @returns error status
160 *
161 * @remarks none
162 *
163 *******************************************************************************
164 */
api_check_struct_sanity(iv_obj_t * ps_handle,void * pv_api_ip,void * pv_api_op)165 static IV_STATUS_T api_check_struct_sanity(iv_obj_t *ps_handle,
166 void *pv_api_ip,
167 void *pv_api_op)
168 {
169 /* api call */
170 WORD32 command = IV_CMD_NA;
171
172 /* input structure expected by the api call */
173 UWORD32 *pu4_api_ip = pv_api_ip;
174
175 /* output structure expected by the api call */
176 UWORD32 *pu4_api_op = pv_api_op;
177
178 /* temp var */
179 WORD32 i, j;
180
181 if (NULL == pv_api_op || NULL == pv_api_ip)
182 {
183 return (IV_FAIL);
184 }
185
186 /* get command */
187 command = pu4_api_ip[1];
188
189 /* set error code */
190 pu4_api_op[1] = 0;
191
192 /* error checks on handle */
193 switch (command)
194 {
195 case IV_CMD_GET_NUM_MEM_REC:
196 case IV_CMD_FILL_NUM_MEM_REC:
197 break;
198
199 case IV_CMD_INIT:
200 if (ps_handle == NULL)
201 {
202 *(pu4_api_op + 1) |= 1 << IVE_UNSUPPORTEDPARAM;
203 *(pu4_api_op + 1) |= IVE_ERR_HANDLE_NULL;
204 return IV_FAIL;
205 }
206
207 if (ps_handle->u4_size != sizeof(iv_obj_t))
208 {
209 *(pu4_api_op + 1) |= 1 << IVE_UNSUPPORTEDPARAM;
210 *(pu4_api_op + 1) |= IVE_ERR_HANDLE_STRUCT_SIZE_INCORRECT;
211 return IV_FAIL;
212 }
213 break;
214
215 case IVE_CMD_QUEUE_INPUT:
216 case IVE_CMD_QUEUE_OUTPUT:
217 case IVE_CMD_DEQUEUE_OUTPUT:
218 case IVE_CMD_GET_RECON:
219 case IV_CMD_RETRIEVE_MEMREC:
220 case IVE_CMD_VIDEO_CTL:
221 case IVE_CMD_VIDEO_ENCODE:
222
223 if (ps_handle == NULL)
224 {
225 *(pu4_api_op + 1) |= 1 << IVE_UNSUPPORTEDPARAM;
226 *(pu4_api_op + 1) |= IVE_ERR_HANDLE_NULL;
227 return IV_FAIL;
228 }
229
230 if (ps_handle->u4_size != sizeof(iv_obj_t))
231 {
232 *(pu4_api_op + 1) |= 1 << IVE_UNSUPPORTEDPARAM;
233 *(pu4_api_op + 1) |= IVE_ERR_HANDLE_STRUCT_SIZE_INCORRECT;
234 return IV_FAIL;
235 }
236
237 if (ps_handle->pv_fxns != ih264e_api_function)
238 {
239 *(pu4_api_op + 1) |= 1 << IVE_UNSUPPORTEDPARAM;
240 *(pu4_api_op + 1) |= IVE_ERR_API_FUNCTION_PTR_NULL;
241 return IV_FAIL;
242 }
243
244 if (ps_handle->pv_codec_handle == NULL)
245 {
246 *(pu4_api_op + 1) |= 1 << IVE_UNSUPPORTEDPARAM;
247 *(pu4_api_op + 1) |= IVE_ERR_INVALID_CODEC_HANDLE;
248 return IV_FAIL;
249 }
250 break;
251
252 default:
253 *(pu4_api_op + 1) |= 1 << IVE_UNSUPPORTEDPARAM;
254 *(pu4_api_op + 1) |= IVE_ERR_INVALID_API_CMD;
255 return IV_FAIL;
256 }
257
258 /* error checks on input output structures */
259 switch (command)
260 {
261 case IV_CMD_GET_NUM_MEM_REC:
262 {
263 ih264e_num_mem_rec_ip_t *ps_ip = pv_api_ip;
264 ih264e_num_mem_rec_op_t *ps_op = pv_api_op;
265
266 ps_op->s_ive_op.u4_error_code = 0;
267
268 if (ps_ip->s_ive_ip.u4_size != sizeof(ih264e_num_mem_rec_ip_t))
269 {
270 ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM;
271 ps_op->s_ive_op.u4_error_code |=
272 IVE_ERR_IP_GET_MEM_REC_API_STRUCT_SIZE_INCORRECT;
273 return (IV_FAIL);
274 }
275
276 if (ps_op->s_ive_op.u4_size != sizeof(ih264e_num_mem_rec_op_t))
277 {
278 ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM;
279 ps_op->s_ive_op.u4_error_code |=
280 IVE_ERR_OP_GET_MEM_REC_API_STRUCT_SIZE_INCORRECT;
281 return (IV_FAIL);
282 }
283 break;
284 }
285
286 case IV_CMD_FILL_NUM_MEM_REC:
287 {
288 ih264e_fill_mem_rec_ip_t *ps_ip = pv_api_ip;
289 ih264e_fill_mem_rec_op_t *ps_op = pv_api_op;
290
291 iv_mem_rec_t *ps_mem_rec = NULL;
292
293 WORD32 max_wd = ALIGN16(ps_ip->s_ive_ip.u4_max_wd);
294 WORD32 max_ht = ALIGN16(ps_ip->s_ive_ip.u4_max_ht);
295
296 ps_op->s_ive_op.u4_error_code = 0;
297
298 if (ps_ip->s_ive_ip.u4_size != sizeof(ih264e_fill_mem_rec_ip_t))
299 {
300 ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM;
301 ps_op->s_ive_op.u4_error_code |=
302 IVE_ERR_IP_FILL_MEM_REC_API_STRUCT_SIZE_INCORRECT;
303 return (IV_FAIL);
304 }
305
306 if (ps_op->s_ive_op.u4_size != sizeof(ih264e_fill_mem_rec_op_t))
307 {
308 ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM;
309 ps_op->s_ive_op.u4_error_code |=
310 IVE_ERR_OP_FILL_MEM_REC_API_STRUCT_SIZE_INCORRECT;
311 return (IV_FAIL);
312 }
313
314 if (max_wd < MIN_WD || max_wd > MAX_WD)
315 {
316 ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM;
317 ps_op->s_ive_op.u4_error_code |= IH264E_WIDTH_NOT_SUPPORTED;
318 return (IV_FAIL);
319 }
320
321 if (max_ht < MIN_HT || max_ht > MAX_HT)
322 {
323 ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM;
324 ps_op->s_ive_op.u4_error_code |= IH264E_HEIGHT_NOT_SUPPORTED;
325 return (IV_FAIL);
326 }
327
328 /* verify number of mem rec ptr */
329 if (NULL == ps_ip->s_ive_ip.ps_mem_rec)
330 {
331 ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM;
332 ps_op->s_ive_op.u4_error_code |=
333 IVE_ERR_FILL_NUM_MEM_RECS_POINTER_NULL;
334 return (IV_FAIL);
335 }
336
337 /* verify number of mem records */
338 if (ps_ip->s_ive_ip.u4_num_mem_rec != MEM_REC_CNT)
339 {
340 ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM;
341 ps_op->s_ive_op.u4_error_code |=
342 IVE_ERR_NUM_MEM_REC_NOT_SUFFICIENT;
343 return IV_FAIL;
344 }
345
346 /* check mem records sizes are correct */
347 ps_mem_rec = ps_ip->s_ive_ip.ps_mem_rec;
348 for (i = 0; i < MEM_REC_CNT; i++)
349 {
350 if (ps_mem_rec[i].u4_size != sizeof(iv_mem_rec_t))
351 {
352 ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM;
353 ps_op->s_ive_op.u4_error_code |=
354 IVE_ERR_MEM_REC_STRUCT_SIZE_INCORRECT;
355 return IV_FAIL;
356 }
357 }
358 break;
359 }
360
361 case IV_CMD_INIT:
362 {
363 ih264e_init_ip_t *ps_ip = pv_api_ip;
364 ih264e_init_op_t *ps_op = pv_api_op;
365
366 iv_mem_rec_t *ps_mem_rec = NULL;
367
368 WORD32 max_wd = ALIGN16(ps_ip->s_ive_ip.u4_max_wd);
369 WORD32 max_ht = ALIGN16(ps_ip->s_ive_ip.u4_max_ht);
370
371 ps_op->s_ive_op.u4_error_code = 0;
372
373 if (ps_ip->s_ive_ip.u4_size != sizeof(ih264e_init_ip_t))
374 {
375 ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM;
376 ps_op->s_ive_op.u4_error_code |=
377 IVE_ERR_IP_INIT_API_STRUCT_SIZE_INCORRECT;
378 return (IV_FAIL);
379 }
380
381 if (ps_op->s_ive_op.u4_size != sizeof(ih264e_init_op_t))
382 {
383 ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM;
384 ps_op->s_ive_op.u4_error_code |=
385 IVE_ERR_OP_INIT_API_STRUCT_SIZE_INCORRECT;
386 return (IV_FAIL);
387 }
388
389 if (max_wd < MIN_WD || max_wd > MAX_WD)
390 {
391 ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM;
392 ps_op->s_ive_op.u4_error_code |= IH264E_WIDTH_NOT_SUPPORTED;
393 return (IV_FAIL);
394 }
395
396 if (max_ht < MIN_HT || max_ht > MAX_HT)
397 {
398 ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM;
399 ps_op->s_ive_op.u4_error_code |= IH264E_HEIGHT_NOT_SUPPORTED;
400 return (IV_FAIL);
401 }
402
403 if (ps_ip->s_ive_ip.u4_max_ref_cnt > MAX_REF_PIC_CNT ||
404 ps_ip->s_ive_ip.u4_max_ref_cnt < MIN_REF_PIC_CNT)
405 {
406 ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM;
407 ps_op->s_ive_op.u4_error_code |= IH264E_NUM_REF_UNSUPPORTED;
408 return (IV_FAIL);
409 }
410
411 if (ps_ip->s_ive_ip.u4_max_reorder_cnt != 0)
412 {
413 ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM;
414 ps_op->s_ive_op.u4_error_code |= IH264E_NUM_REORDER_UNSUPPORTED;
415 return (IV_FAIL);
416 }
417
418 if ((ps_ip->s_ive_ip.u4_max_level != IH264_LEVEL_10)
419 && (ps_ip->s_ive_ip.u4_max_level != IH264_LEVEL_1B)
420 && (ps_ip->s_ive_ip.u4_max_level != IH264_LEVEL_11)
421 && (ps_ip->s_ive_ip.u4_max_level != IH264_LEVEL_12)
422 && (ps_ip->s_ive_ip.u4_max_level != IH264_LEVEL_13)
423 && (ps_ip->s_ive_ip.u4_max_level != IH264_LEVEL_20)
424 && (ps_ip->s_ive_ip.u4_max_level != IH264_LEVEL_21)
425 && (ps_ip->s_ive_ip.u4_max_level != IH264_LEVEL_22)
426 && (ps_ip->s_ive_ip.u4_max_level != IH264_LEVEL_30)
427 && (ps_ip->s_ive_ip.u4_max_level != IH264_LEVEL_31)
428 && (ps_ip->s_ive_ip.u4_max_level != IH264_LEVEL_32)
429 && (ps_ip->s_ive_ip.u4_max_level != IH264_LEVEL_40)
430 && (ps_ip->s_ive_ip.u4_max_level != IH264_LEVEL_41)
431 && (ps_ip->s_ive_ip.u4_max_level != IH264_LEVEL_42)
432 && (ps_ip->s_ive_ip.u4_max_level != IH264_LEVEL_50)
433 && (ps_ip->s_ive_ip.u4_max_level != IH264_LEVEL_51))
434 {
435 ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM;
436 ps_op->s_ive_op.u4_error_code |=
437 IH264E_CODEC_LEVEL_NOT_SUPPORTED;
438 return (IV_FAIL);
439 }
440
441 if ((ps_ip->s_ive_ip.e_inp_color_fmt != IV_YUV_420P)
442 && (ps_ip->s_ive_ip.e_inp_color_fmt != IV_YUV_422ILE)
443 && (ps_ip->s_ive_ip.e_inp_color_fmt != IV_YUV_420SP_UV)
444 && (ps_ip->s_ive_ip.e_inp_color_fmt != IV_YUV_420SP_VU))
445 {
446 ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM;
447 ps_op->s_ive_op.u4_error_code |=
448 IH264E_INPUT_CHROMA_FORMAT_NOT_SUPPORTED;
449 return (IV_FAIL);
450 }
451
452 if ((ps_ip->s_ive_ip.e_recon_color_fmt != IV_YUV_420P)
453 && (ps_ip->s_ive_ip.e_recon_color_fmt != IV_YUV_420SP_UV)
454 && (ps_ip->s_ive_ip.e_recon_color_fmt != IV_YUV_420SP_VU))
455 {
456 ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM;
457 ps_op->s_ive_op.u4_error_code |=
458 IH264E_RECON_CHROMA_FORMAT_NOT_SUPPORTED;
459 return (IV_FAIL);
460 }
461
462 if ((ps_ip->s_ive_ip.e_rc_mode != IVE_RC_NONE)
463 && (ps_ip->s_ive_ip.e_rc_mode != IVE_RC_STORAGE)
464 && (ps_ip->s_ive_ip.e_rc_mode != IVE_RC_CBR_NON_LOW_DELAY))
465 {
466 ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM;
467 ps_op->s_ive_op.u4_error_code |=
468 IH264E_RATE_CONTROL_MODE_NOT_SUPPORTED;
469 return (IV_FAIL);
470 }
471
472 if (ps_ip->s_ive_ip.u4_max_framerate > DEFAULT_MAX_FRAMERATE)
473 {
474 ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM;
475 ps_op->s_ive_op.u4_error_code |=
476 IH264E_FRAME_RATE_NOT_SUPPORTED;
477 return (IV_FAIL);
478 }
479
480 if (ps_ip->s_ive_ip.u4_max_bitrate > DEFAULT_MAX_BITRATE)
481 {
482 ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM;
483 ps_op->s_ive_op.u4_error_code |= IH264E_BITRATE_NOT_SUPPORTED;
484 return (IV_FAIL);
485 }
486
487 if (ps_ip->s_ive_ip.u4_num_bframes > MAX_NUM_BFRAMES)
488 {
489 ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM;
490 ps_op->s_ive_op.u4_error_code |= IH264E_BFRAMES_NOT_SUPPORTED;
491 return (IV_FAIL);
492 }
493
494 if (ps_ip->s_ive_ip.u4_num_bframes
495 && (ps_ip->s_ive_ip.u4_max_ref_cnt < 2))
496 {
497 ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM;
498 ps_op->s_ive_op.u4_error_code |= IH264E_BFRAMES_NOT_SUPPORTED;
499 return (IV_FAIL);
500 }
501
502 if (ps_ip->s_ive_ip.e_content_type != IV_PROGRESSIVE)
503 {
504 ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM;
505 ps_op->s_ive_op.u4_error_code |=
506 IH264E_CONTENT_TYPE_NOT_SUPPORTED;
507 return (IV_FAIL);
508 }
509
510 if (ps_ip->s_ive_ip.u4_max_srch_rng_x > DEFAULT_MAX_SRCH_RANGE_X)
511 {
512 ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM;
513 ps_op->s_ive_op.u4_error_code |=
514 IH264E_HORIZONTAL_SEARCH_RANGE_NOT_SUPPORTED;
515 return (IV_FAIL);
516 }
517
518 if (ps_ip->s_ive_ip.u4_max_srch_rng_y > DEFAULT_MAX_SRCH_RANGE_Y)
519 {
520 ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM;
521 ps_op->s_ive_op.u4_error_code |=
522 IH264E_VERTICAL_SEARCH_RANGE_NOT_SUPPORTED;
523 return (IV_FAIL);
524 }
525
526 if ((ps_ip->s_ive_ip.e_slice_mode != IVE_SLICE_MODE_NONE)
527 && (ps_ip->s_ive_ip.e_slice_mode != IVE_SLICE_MODE_BLOCKS))
528 {
529 ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM;
530 ps_op->s_ive_op.u4_error_code |=
531 IH264E_SLICE_TYPE_INPUT_INVALID;
532 return (IV_FAIL);
533 }
534
535 if (ps_ip->s_ive_ip.e_slice_mode == IVE_SLICE_MODE_BLOCKS)
536 {
537 if (ps_ip->s_ive_ip.u4_slice_param == 0
538 || ps_ip->s_ive_ip.u4_slice_param > ((UWORD32)max_ht >> 4))
539 {
540 ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM;
541 ps_op->s_ive_op.u4_error_code |=
542 IH264E_SLICE_PARAM_INPUT_INVALID;
543 return (IV_FAIL);
544 }
545 }
546
547 if (NULL == ps_ip->s_ive_ip.ps_mem_rec)
548 {
549 ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM;
550 ps_op->s_ive_op.u4_error_code |=
551 IVE_ERR_FILL_NUM_MEM_RECS_POINTER_NULL;
552 return (IV_FAIL);
553 }
554
555 /* verify number of mem records */
556 if (ps_ip->s_ive_ip.u4_num_mem_rec != MEM_REC_CNT)
557 {
558 ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM;
559 ps_op->s_ive_op.u4_error_code |=
560 IVE_ERR_NUM_MEM_REC_NOT_SUFFICIENT;
561 return (IV_FAIL);
562 }
563
564 ps_mem_rec = ps_ip->s_ive_ip.ps_mem_rec;
565
566 /* check memrecords sizes are correct */
567 for (i = 0; i <((WORD32)ps_ip->s_ive_ip.u4_num_mem_rec); i++)
568 {
569 if (ps_mem_rec[i].u4_size != sizeof(iv_mem_rec_t))
570 {
571 ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM;
572 ps_op->s_ive_op.u4_error_code |=
573 IVE_ERR_MEM_REC_STRUCT_SIZE_INCORRECT;
574 return IV_FAIL;
575 }
576
577 /* check memrecords pointers are not NULL */
578 if (ps_mem_rec[i].pv_base == NULL)
579 {
580 ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM;
581 ps_op->s_ive_op.u4_error_code |=
582 IVE_ERR_MEM_REC_BASE_POINTER_NULL;
583 return IV_FAIL;
584 }
585 }
586
587 /* verify memtabs for overlapping regions */
588 {
589 void *start[MEM_REC_CNT];
590 void *end[MEM_REC_CNT];
591
592 start[0] = (ps_mem_rec[0].pv_base);
593 end[0] = ((UWORD8 *) ps_mem_rec[0].pv_base)
594 + ps_mem_rec[0].u4_mem_size - 1;
595
596 for (i = 1; i < MEM_REC_CNT; i++)
597 {
598 /* This array is populated to check memtab overlap */
599 start[i] = (ps_mem_rec[i].pv_base);
600 end[i] = ((UWORD8 *) ps_mem_rec[i].pv_base)
601 + ps_mem_rec[i].u4_mem_size - 1;
602
603 for (j = 0; j < i; j++)
604 {
605 if ((start[i] >= start[j]) && (start[i] <= end[j]))
606 {
607 ps_op->s_ive_op.u4_error_code |= 1
608 << IVE_UNSUPPORTEDPARAM;
609 ps_op->s_ive_op.u4_error_code |=
610 IVE_ERR_MEM_REC_OVERLAP_ERR;
611 return IV_FAIL;
612 }
613
614 if ((end[i] >= start[j]) && (end[i] <= end[j]))
615 {
616 ps_op->s_ive_op.u4_error_code |= 1
617 << IVE_UNSUPPORTEDPARAM;
618 ps_op->s_ive_op.u4_error_code |=
619 IVE_ERR_MEM_REC_OVERLAP_ERR;
620 return IV_FAIL;
621 }
622
623 if ((start[i] < start[j]) && (end[i] > end[j]))
624 {
625 ps_op->s_ive_op.u4_error_code |= 1
626 << IVE_UNSUPPORTEDPARAM;
627 ps_op->s_ive_op.u4_error_code |=
628 IVE_ERR_MEM_REC_OVERLAP_ERR;
629 return IV_FAIL;
630 }
631 }
632 }
633 }
634
635 /* re-validate mem records with init config */
636 {
637 /* mem records */
638 iv_mem_rec_t s_mem_rec_ittiam_api[MEM_REC_CNT];
639
640 /* api interface structs */
641 ih264e_fill_mem_rec_ip_t s_ip;
642 ih264e_fill_mem_rec_op_t s_op;
643
644 /* error status */
645 IV_STATUS_T e_status;
646
647 /* temp var */
648 WORD32 i;
649
650 s_ip.s_ive_ip.u4_size = sizeof(ih264e_fill_mem_rec_ip_t);
651 s_op.s_ive_op.u4_size = sizeof(ih264e_fill_mem_rec_op_t);
652
653 s_ip.s_ive_ip.e_cmd = IV_CMD_FILL_NUM_MEM_REC;
654 s_ip.s_ive_ip.ps_mem_rec = s_mem_rec_ittiam_api;
655 s_ip.s_ive_ip.u4_max_wd = max_wd;
656 s_ip.s_ive_ip.u4_max_ht = max_ht;
657 s_ip.s_ive_ip.u4_num_mem_rec = ps_ip->s_ive_ip.u4_num_mem_rec;
658 s_ip.s_ive_ip.u4_max_level = ps_ip->s_ive_ip.u4_max_level;
659 s_ip.s_ive_ip.u4_max_ref_cnt = ps_ip->s_ive_ip.u4_max_ref_cnt;
660 s_ip.s_ive_ip.u4_max_reorder_cnt =
661 ps_ip->s_ive_ip.u4_max_reorder_cnt;
662 s_ip.s_ive_ip.e_color_format = ps_ip->s_ive_ip.e_inp_color_fmt;
663 s_ip.s_ive_ip.u4_max_srch_rng_x =
664 ps_ip->s_ive_ip.u4_max_srch_rng_x;
665 s_ip.s_ive_ip.u4_max_srch_rng_y =
666 ps_ip->s_ive_ip.u4_max_srch_rng_y;
667
668 for (i = 0; i < MEM_REC_CNT; i++)
669 {
670 s_mem_rec_ittiam_api[i].u4_size = sizeof(iv_mem_rec_t);
671 }
672
673 /* fill mem records */
674 e_status = ih264e_api_function(NULL, (void *) &s_ip,
675 (void *) &s_op);
676
677 if (IV_FAIL == e_status)
678 {
679 ps_op->s_ive_op.u4_error_code = s_op.s_ive_op.u4_error_code;
680 return (IV_FAIL);
681 }
682
683 /* verify mem records */
684 for (i = 0; i < MEM_REC_CNT; i++)
685 {
686 if (ps_mem_rec[i].u4_mem_size
687 < s_mem_rec_ittiam_api[i].u4_mem_size)
688 {
689 ps_op->s_ive_op.u4_error_code |= 1
690 << IVE_UNSUPPORTEDPARAM;
691 ps_op->s_ive_op.u4_error_code |=
692 IVE_ERR_MEM_REC_INSUFFICIENT_SIZE;
693
694 return IV_FAIL;
695 }
696
697 if (ps_mem_rec[i].u4_mem_alignment
698 != s_mem_rec_ittiam_api[i].u4_mem_alignment)
699 {
700 ps_op->s_ive_op.u4_error_code |= 1
701 << IVE_UNSUPPORTEDPARAM;
702 ps_op->s_ive_op.u4_error_code |=
703 IVE_ERR_MEM_REC_ALIGNMENT_ERR;
704
705 return IV_FAIL;
706 }
707
708 if (ps_mem_rec[i].e_mem_type
709 != s_mem_rec_ittiam_api[i].e_mem_type)
710 {
711 UWORD32 check = IV_SUCCESS;
712 UWORD32 diff = s_mem_rec_ittiam_api[i].e_mem_type
713 - ps_mem_rec[i].e_mem_type;
714
715 if ((ps_mem_rec[i].e_mem_type
716 <= IV_EXTERNAL_CACHEABLE_SCRATCH_MEM)
717 && (s_mem_rec_ittiam_api[i].e_mem_type
718 >= IV_INTERNAL_NONCACHEABLE_PERSISTENT_MEM))
719 {
720 check = IV_FAIL;
721 }
722
723 if (3 != (s_mem_rec_ittiam_api[i].e_mem_type % 4))
724 {
725 /* It is not IV_EXTERNAL_NONCACHEABLE_PERSISTENT_MEM or
726 * IV_EXTERNAL_CACHEABLE_PERSISTENT_MEM */
727
728 if ((diff < 1) || (diff > 3))
729 {
730 /* Difference between 1 and 3 is okay for all cases other than the
731 * two filtered with the MOD condition above */
732 check = IV_FAIL;
733 }
734 }
735 else
736 {
737 if (diff == 1)
738 {
739 /* This particular case is when codec asked for External Persistent,
740 * but got Internal Scratch */
741 check = IV_FAIL;
742 }
743 if ((diff != 2) && (diff != 3))
744 {
745 check = IV_FAIL;
746 }
747 }
748
749 if (check == IV_FAIL)
750 {
751 ps_op->s_ive_op.u4_error_code |= 1
752 << IVE_UNSUPPORTEDPARAM;
753 ps_op->s_ive_op.u4_error_code |=
754 IVE_ERR_MEM_REC_INCORRECT_TYPE;
755
756 return IV_FAIL;
757 }
758 }
759 }
760 }
761 break;
762 }
763
764 case IVE_CMD_QUEUE_INPUT:
765 case IVE_CMD_QUEUE_OUTPUT:
766 case IVE_CMD_DEQUEUE_OUTPUT:
767 case IVE_CMD_GET_RECON:
768 break;
769
770 case IV_CMD_RETRIEVE_MEMREC:
771 {
772 ih264e_retrieve_mem_rec_ip_t *ps_ip = pv_api_ip;
773 ih264e_retrieve_mem_rec_op_t *ps_op = pv_api_op;
774
775 iv_mem_rec_t *ps_mem_rec = NULL;
776
777 ps_op->s_ive_op.u4_error_code = 0;
778
779 if (ps_ip->s_ive_ip.u4_size != sizeof(ih264e_retrieve_mem_rec_ip_t))
780 {
781 ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM;
782 ps_op->s_ive_op.u4_error_code |=
783 IVE_ERR_IP_RETRIEVE_MEM_REC_API_STRUCT_SIZE_INCORRECT;
784 return (IV_FAIL);
785 }
786
787 if (ps_op->s_ive_op.u4_size != sizeof(ih264e_retrieve_mem_rec_op_t))
788 {
789 ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM;
790 ps_op->s_ive_op.u4_error_code |=
791 IVE_ERR_OP_RETRIEVE_MEM_REC_API_STRUCT_SIZE_INCORRECT;
792 return (IV_FAIL);
793 }
794
795 if (NULL == ps_ip->s_ive_ip.ps_mem_rec)
796 {
797 ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM;
798 ps_op->s_ive_op.u4_error_code |=
799 IVE_ERR_FILL_NUM_MEM_RECS_POINTER_NULL;
800 return (IV_FAIL);
801 }
802
803 ps_mem_rec = ps_ip->s_ive_ip.ps_mem_rec;
804
805 /* check memrecords sizes are correct */
806 for (i = 0; i < MEM_REC_CNT; i++)
807 {
808 if (ps_mem_rec[i].u4_size != sizeof(iv_mem_rec_t))
809 {
810 ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM;
811 ps_op->s_ive_op.u4_error_code |=
812 IVE_ERR_MEM_REC_STRUCT_SIZE_INCORRECT;
813 return IV_FAIL;
814 }
815 }
816 break;
817 }
818
819 case IVE_CMD_VIDEO_ENCODE:
820 {
821 ih264e_video_encode_ip_t *ps_ip = pv_api_ip;
822 ih264e_video_encode_op_t *ps_op = pv_api_op;
823
824 if (ps_ip->s_ive_ip.u4_size != sizeof(ih264e_video_encode_ip_t))
825 {
826 ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM;
827 ps_op->s_ive_op.u4_error_code |=
828 IVE_ERR_IP_ENCODE_API_STRUCT_SIZE_INCORRECT;
829 return (IV_FAIL);
830 }
831
832 if (ps_op->s_ive_op.u4_size != sizeof(ih264e_video_encode_op_t))
833 {
834 ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM;
835 ps_op->s_ive_op.u4_error_code |=
836 IVE_ERR_OP_ENCODE_API_STRUCT_SIZE_INCORRECT;
837 return (IV_FAIL);
838 }
839 break;
840 }
841
842 case IVE_CMD_VIDEO_CTL:
843 {
844 /* ptr to input structure */
845 WORD32 *pu4_ptr_cmd = pv_api_ip;
846
847 /* sub command */
848 WORD32 sub_command = pu4_ptr_cmd[2];
849
850 switch (sub_command)
851 {
852 case IVE_CMD_CTL_SETDEFAULT:
853 {
854 ih264e_ctl_setdefault_ip_t *ps_ip = pv_api_ip;
855 ih264e_ctl_setdefault_op_t *ps_op = pv_api_op;
856
857 if (ps_ip->s_ive_ip.u4_size
858 != sizeof(ih264e_ctl_setdefault_ip_t))
859 {
860 ps_op->s_ive_op.u4_error_code |= 1
861 << IVE_UNSUPPORTEDPARAM;
862 ps_op->s_ive_op.u4_error_code |=
863 IVE_ERR_IP_CTL_SETDEF_API_STRUCT_SIZE_INCORRECT;
864 return IV_FAIL;
865 }
866
867 if (ps_op->s_ive_op.u4_size
868 != sizeof(ih264e_ctl_setdefault_op_t))
869 {
870 ps_op->s_ive_op.u4_error_code |= 1
871 << IVE_UNSUPPORTEDPARAM;
872 ps_op->s_ive_op.u4_error_code |=
873 IVE_ERR_OP_CTL_SETDEF_API_STRUCT_SIZE_INCORRECT;
874 return IV_FAIL;
875 }
876 break;
877 }
878
879 case IVE_CMD_CTL_GETBUFINFO:
880 {
881 codec_t *ps_codec = (codec_t *) (ps_handle->pv_codec_handle);
882
883 ih264e_ctl_getbufinfo_ip_t *ps_ip = pv_api_ip;
884 ih264e_ctl_getbufinfo_op_t *ps_op = pv_api_op;
885
886 if (ps_ip->s_ive_ip.u4_size
887 != sizeof(ih264e_ctl_getbufinfo_ip_t))
888 {
889 ps_op->s_ive_op.u4_error_code |= 1
890 << IVE_UNSUPPORTEDPARAM;
891 ps_op->s_ive_op.u4_error_code |=
892 IVE_ERR_IP_CTL_GETBUFINFO_API_STRUCT_SIZE_INCORRECT;
893 return IV_FAIL;
894 }
895
896 if (ps_op->s_ive_op.u4_size
897 != sizeof(ih264e_ctl_getbufinfo_op_t))
898 {
899 ps_op->s_ive_op.u4_error_code |= 1
900 << IVE_UNSUPPORTEDPARAM;
901 ps_op->s_ive_op.u4_error_code |=
902 IVE_ERR_OP_CTL_GETBUFINFO_API_STRUCT_SIZE_INCORRECT;
903 return IV_FAIL;
904 }
905
906 if (ps_ip->s_ive_ip.u4_max_wd < MIN_WD)
907 {
908 ps_op->s_ive_op.u4_error_code |= 1
909 << IVE_UNSUPPORTEDPARAM;
910 ps_op->s_ive_op.u4_error_code |=
911 IH264E_WIDTH_NOT_SUPPORTED;
912 return (IV_FAIL);
913 }
914
915 if (ps_ip->s_ive_ip.u4_max_wd > ps_codec->s_cfg.u4_max_wd)
916 {
917 ps_op->s_ive_op.u4_error_code |= 1
918 << IVE_UNSUPPORTEDPARAM;
919 ps_op->s_ive_op.u4_error_code |=
920 IH264E_WIDTH_NOT_SUPPORTED;
921 return (IV_FAIL);
922 }
923
924 if (ps_ip->s_ive_ip.u4_max_ht < MIN_HT)
925 {
926 ps_op->s_ive_op.u4_error_code |= 1
927 << IVE_UNSUPPORTEDPARAM;
928 ps_op->s_ive_op.u4_error_code |=
929 IH264E_HEIGHT_NOT_SUPPORTED;
930 return (IV_FAIL);
931 }
932
933 if (ps_ip->s_ive_ip.u4_max_ht > ps_codec->s_cfg.u4_max_ht)
934 {
935 ps_op->s_ive_op.u4_error_code |= 1
936 << IVE_UNSUPPORTEDPARAM;
937 ps_op->s_ive_op.u4_error_code |=
938 IH264E_HEIGHT_NOT_SUPPORTED;
939 return (IV_FAIL);
940 }
941
942 if ((ps_ip->s_ive_ip.e_inp_color_fmt != IV_YUV_420P)
943 && (ps_ip->s_ive_ip.e_inp_color_fmt != IV_YUV_422ILE)
944 && (ps_ip->s_ive_ip.e_inp_color_fmt != IV_YUV_420SP_UV)
945 && (ps_ip->s_ive_ip.e_inp_color_fmt != IV_YUV_420SP_VU))
946 {
947 ps_op->s_ive_op.u4_error_code |= 1
948 << IVE_UNSUPPORTEDPARAM;
949 ps_op->s_ive_op.u4_error_code |=
950 IH264E_INPUT_CHROMA_FORMAT_NOT_SUPPORTED;
951 return (IV_FAIL);
952 }
953 break;
954 }
955
956 case IVE_CMD_CTL_GETVERSION:
957 {
958 ih264e_ctl_getversioninfo_ip_t *ps_ip = pv_api_ip;
959 ih264e_ctl_getversioninfo_op_t *ps_op = pv_api_op;
960
961 if (ps_ip->s_ive_ip.u4_size
962 != sizeof(ih264e_ctl_getversioninfo_ip_t))
963 {
964 ps_op->s_ive_op.u4_error_code |= 1
965 << IVE_UNSUPPORTEDPARAM;
966 ps_op->s_ive_op.u4_error_code |=
967 IVE_ERR_IP_CTL_GETVERSION_API_STRUCT_SIZE_INCORRECT;
968 return IV_FAIL;
969 }
970
971 if (ps_op->s_ive_op.u4_size
972 != sizeof(ih264e_ctl_getversioninfo_op_t))
973 {
974 ps_op->s_ive_op.u4_error_code |= 1
975 << IVE_UNSUPPORTEDPARAM;
976 ps_op->s_ive_op.u4_error_code |=
977 IVE_ERR_OP_CTL_GETVERSION_API_STRUCT_SIZE_INCORRECT;
978 return IV_FAIL;
979 }
980
981 if (ps_ip->s_ive_ip.pu1_version == NULL)
982 {
983 ps_op->s_ive_op.u4_error_code |= 1
984 << IVE_UNSUPPORTEDPARAM;
985 ps_op->s_ive_op.u4_error_code |=
986 IVE_ERR_CTL_GET_VERSION_BUFFER_IS_NULL;
987 return IV_FAIL;
988 }
989
990 break;
991 }
992
993 case IVE_CMD_CTL_FLUSH:
994 {
995 ih264e_ctl_flush_ip_t *ps_ip = pv_api_ip;
996 ih264e_ctl_flush_op_t *ps_op = pv_api_op;
997
998 if (ps_ip->s_ive_ip.u4_size
999 != sizeof(ih264e_ctl_flush_ip_t))
1000 {
1001 ps_op->s_ive_op.u4_error_code |= 1
1002 << IVE_UNSUPPORTEDPARAM;
1003 ps_op->s_ive_op.u4_error_code |=
1004 IVE_ERR_IP_CTL_FLUSH_API_STRUCT_SIZE_INCORRECT;
1005 return IV_FAIL;
1006 }
1007
1008 if (ps_op->s_ive_op.u4_size
1009 != sizeof(ih264e_ctl_flush_op_t))
1010 {
1011 ps_op->s_ive_op.u4_error_code |= 1
1012 << IVE_UNSUPPORTEDPARAM;
1013 ps_op->s_ive_op.u4_error_code |=
1014 IVE_ERR_OP_CTL_FLUSH_API_STRUCT_SIZE_INCORRECT;
1015 return IV_FAIL;
1016 }
1017
1018 break;
1019 }
1020
1021 case IVE_CMD_CTL_RESET:
1022 {
1023 ih264e_ctl_reset_ip_t *ps_ip = pv_api_ip;
1024 ih264e_ctl_reset_op_t *ps_op = pv_api_op;
1025
1026 if (ps_ip->s_ive_ip.u4_size
1027 != sizeof(ih264e_ctl_reset_ip_t))
1028 {
1029 ps_op->s_ive_op.u4_error_code |= 1
1030 << IVE_UNSUPPORTEDPARAM;
1031 ps_op->s_ive_op.u4_error_code |=
1032 IVE_ERR_IP_CTL_RESET_API_STRUCT_SIZE_INCORRECT;
1033 return IV_FAIL;
1034 }
1035
1036 if (ps_op->s_ive_op.u4_size
1037 != sizeof(ih264e_ctl_reset_op_t))
1038 {
1039 ps_op->s_ive_op.u4_error_code |= 1
1040 << IVE_UNSUPPORTEDPARAM;
1041 ps_op->s_ive_op.u4_error_code |=
1042 IVE_ERR_OP_CTL_RESET_API_STRUCT_SIZE_INCORRECT;
1043 return IV_FAIL;
1044 }
1045
1046 break;
1047 }
1048
1049 case IVE_CMD_CTL_SET_NUM_CORES:
1050 {
1051 ih264e_ctl_set_num_cores_ip_t *ps_ip = pv_api_ip;
1052 ih264e_ctl_set_num_cores_op_t *ps_op = pv_api_op;
1053
1054 if (ps_ip->s_ive_ip.u4_size
1055 != sizeof(ih264e_ctl_set_num_cores_ip_t))
1056 {
1057 ps_op->s_ive_op.u4_error_code |= 1
1058 << IVE_UNSUPPORTEDPARAM;
1059 ps_op->s_ive_op.u4_error_code |=
1060 IVE_ERR_IP_CTL_SETCORES_API_STRUCT_SIZE_INCORRECT;
1061 return IV_FAIL;
1062 }
1063
1064 if (ps_op->s_ive_op.u4_size
1065 != sizeof(ih264e_ctl_set_num_cores_op_t))
1066 {
1067 ps_op->s_ive_op.u4_error_code |= 1
1068 << IVE_UNSUPPORTEDPARAM;
1069 ps_op->s_ive_op.u4_error_code |=
1070 IVE_ERR_OP_CTL_SETCORES_API_STRUCT_SIZE_INCORRECT;
1071 return IV_FAIL;
1072 }
1073
1074 if ((ps_ip->s_ive_ip.u4_num_cores < 1)
1075 || (ps_ip->s_ive_ip.u4_num_cores > MAX_NUM_CORES))
1076 {
1077 ps_op->s_ive_op.u4_error_code |= 1
1078 << IVE_UNSUPPORTEDPARAM;
1079 ps_op->s_ive_op.u4_error_code |=
1080 IH264E_INVALID_NUM_CORES;
1081 return IV_FAIL;
1082 }
1083
1084 break;
1085 }
1086
1087 case IVE_CMD_CTL_SET_DIMENSIONS:
1088 {
1089 codec_t *ps_codec = (codec_t *) (ps_handle->pv_codec_handle);
1090
1091 ih264e_ctl_set_dimensions_ip_t *ps_ip = pv_api_ip;
1092 ih264e_ctl_set_dimensions_op_t *ps_op = pv_api_op;
1093
1094 if (ps_ip->s_ive_ip.u4_size
1095 != sizeof(ih264e_ctl_set_dimensions_ip_t))
1096 {
1097 ps_op->s_ive_op.u4_error_code |= 1
1098 << IVE_UNSUPPORTEDPARAM;
1099 ps_op->s_ive_op.u4_error_code |=
1100 IVE_ERR_IP_CTL_SETDIM_API_STRUCT_SIZE_INCORRECT;
1101 return IV_FAIL;
1102 }
1103
1104 if (ps_op->s_ive_op.u4_size
1105 != sizeof(ih264e_ctl_set_dimensions_op_t))
1106 {
1107 ps_op->s_ive_op.u4_error_code |= 1
1108 << IVE_UNSUPPORTEDPARAM;
1109 ps_op->s_ive_op.u4_error_code |=
1110 IVE_ERR_OP_CTL_SETDIM_API_STRUCT_SIZE_INCORRECT;
1111 return IV_FAIL;
1112 }
1113
1114 if (ps_ip->s_ive_ip.u4_wd < MIN_WD)
1115 {
1116 ps_op->s_ive_op.u4_error_code |= 1
1117 << IVE_UNSUPPORTEDPARAM;
1118 ps_op->s_ive_op.u4_error_code |=
1119 IH264E_WIDTH_NOT_SUPPORTED;
1120 return (IV_FAIL);
1121 }
1122
1123 if (ps_ip->s_ive_ip.u4_wd > ps_codec->s_cfg.u4_max_wd)
1124 {
1125 ps_op->s_ive_op.u4_error_code |= 1
1126 << IVE_UNSUPPORTEDPARAM;
1127 ps_op->s_ive_op.u4_error_code |=
1128 IH264E_WIDTH_NOT_SUPPORTED;
1129 return (IV_FAIL);
1130 }
1131
1132 if (ps_ip->s_ive_ip.u4_ht < MIN_HT)
1133 {
1134 ps_op->s_ive_op.u4_error_code |= 1
1135 << IVE_UNSUPPORTEDPARAM;
1136 ps_op->s_ive_op.u4_error_code |=
1137 IH264E_HEIGHT_NOT_SUPPORTED;
1138 return (IV_FAIL);
1139 }
1140
1141 if (ps_ip->s_ive_ip.u4_ht > ps_codec->s_cfg.u4_max_ht)
1142 {
1143 ps_op->s_ive_op.u4_error_code |= 1
1144 << IVE_UNSUPPORTEDPARAM;
1145 ps_op->s_ive_op.u4_error_code |=
1146 IH264E_HEIGHT_NOT_SUPPORTED;
1147 return (IV_FAIL);
1148 }
1149
1150 break;
1151 }
1152
1153 case IVE_CMD_CTL_SET_FRAMERATE:
1154 {
1155 ih264e_ctl_set_frame_rate_ip_t *ps_ip = pv_api_ip;
1156 ih264e_ctl_set_frame_rate_op_t *ps_op = pv_api_op;
1157
1158 if (ps_ip->s_ive_ip.u4_size
1159 != sizeof(ih264e_ctl_set_frame_rate_ip_t))
1160 {
1161 ps_op->s_ive_op.u4_error_code |= 1
1162 << IVE_UNSUPPORTEDPARAM;
1163 ps_op->s_ive_op.u4_error_code |=
1164 IVE_ERR_IP_CTL_SETFRAMERATE_API_STRUCT_SIZE_INCORRECT;
1165 return IV_FAIL;
1166 }
1167
1168 if (ps_op->s_ive_op.u4_size
1169 != sizeof(ih264e_ctl_set_frame_rate_op_t))
1170 {
1171 ps_op->s_ive_op.u4_error_code |= 1
1172 << IVE_UNSUPPORTEDPARAM;
1173 ps_op->s_ive_op.u4_error_code |=
1174 IVE_ERR_OP_CTL_SETFRAMERATE_API_STRUCT_SIZE_INCORRECT;
1175 return IV_FAIL;
1176 }
1177
1178 if (((ps_ip->s_ive_ip.u4_src_frame_rate * 1000) > DEFAULT_MAX_FRAMERATE)
1179 || ((ps_ip->s_ive_ip.u4_tgt_frame_rate * 1000) > DEFAULT_MAX_FRAMERATE))
1180 {
1181 ps_op->s_ive_op.u4_error_code |= 1
1182 << IVE_UNSUPPORTEDPARAM;
1183 ps_op->s_ive_op.u4_error_code |=
1184 IH264E_FRAME_RATE_NOT_SUPPORTED;
1185 return (IV_FAIL);
1186 }
1187
1188 if ((ps_ip->s_ive_ip.u4_src_frame_rate == 0)
1189 || (ps_ip->s_ive_ip.u4_tgt_frame_rate == 0))
1190 {
1191 ps_op->s_ive_op.u4_error_code |= 1
1192 << IVE_UNSUPPORTEDPARAM;
1193 ps_op->s_ive_op.u4_error_code |=
1194 IH264E_FRAME_RATE_NOT_SUPPORTED;
1195 return (IV_FAIL);
1196 }
1197
1198 if (ps_ip->s_ive_ip.u4_tgt_frame_rate
1199 > ps_ip->s_ive_ip.u4_src_frame_rate)
1200 {
1201 ps_op->s_ive_op.u4_error_code |= 1
1202 << IVE_UNSUPPORTEDPARAM;
1203 ps_op->s_ive_op.u4_error_code |=
1204 IH264E_TGT_FRAME_RATE_EXCEEDS_SRC_FRAME_RATE;
1205 return (IV_FAIL);
1206 }
1207
1208 break;
1209 }
1210
1211 case IVE_CMD_CTL_SET_BITRATE:
1212 {
1213 ih264e_ctl_set_bitrate_ip_t *ps_ip = pv_api_ip;
1214 ih264e_ctl_set_bitrate_op_t *ps_op = pv_api_op;
1215
1216 if (ps_ip->s_ive_ip.u4_size
1217 != sizeof(ih264e_ctl_set_bitrate_ip_t))
1218 {
1219 ps_op->s_ive_op.u4_error_code |= 1
1220 << IVE_UNSUPPORTEDPARAM;
1221 ps_op->s_ive_op.u4_error_code |=
1222 IVE_ERR_IP_CTL_SETBITRATE_API_STRUCT_SIZE_INCORRECT;
1223 return IV_FAIL;
1224 }
1225
1226 if (ps_op->s_ive_op.u4_size
1227 != sizeof(ih264e_ctl_set_bitrate_op_t))
1228 {
1229 ps_op->s_ive_op.u4_error_code |= 1
1230 << IVE_UNSUPPORTEDPARAM;
1231 ps_op->s_ive_op.u4_error_code |=
1232 IVE_ERR_OP_CTL_SETBITRATE_API_STRUCT_SIZE_INCORRECT;
1233 return IV_FAIL;
1234 }
1235
1236 if ((ps_ip->s_ive_ip.u4_target_bitrate > DEFAULT_MAX_BITRATE)
1237 || (ps_ip->s_ive_ip.u4_target_bitrate == 0))
1238 {
1239 ps_op->s_ive_op.u4_error_code |= 1
1240 << IVE_UNSUPPORTEDPARAM;
1241 ps_op->s_ive_op.u4_error_code |=
1242 IH264E_BITRATE_NOT_SUPPORTED;
1243 return (IV_FAIL);
1244 }
1245
1246 break;
1247 }
1248
1249 case IVE_CMD_CTL_SET_FRAMETYPE:
1250 {
1251 ih264e_ctl_set_frame_type_ip_t *ps_ip = pv_api_ip;
1252 ih264e_ctl_set_frame_type_op_t *ps_op = pv_api_op;
1253
1254 if (ps_ip->s_ive_ip.u4_size
1255 != sizeof(ih264e_ctl_set_frame_type_ip_t))
1256 {
1257 ps_op->s_ive_op.u4_error_code |= 1
1258 << IVE_UNSUPPORTEDPARAM;
1259 ps_op->s_ive_op.u4_error_code |=
1260 IVE_ERR_IP_CTL_SETFRAMETYPE_API_STRUCT_SIZE_INCORRECT;
1261 return IV_FAIL;
1262 }
1263
1264 if (ps_op->s_ive_op.u4_size
1265 != sizeof(ih264e_ctl_set_frame_type_op_t))
1266 {
1267 ps_op->s_ive_op.u4_error_code |= 1
1268 << IVE_UNSUPPORTEDPARAM;
1269 ps_op->s_ive_op.u4_error_code |=
1270 IVE_ERR_OP_CTL_SETFRAMETYPE_API_STRUCT_SIZE_INCORRECT;
1271 return IV_FAIL;
1272 }
1273
1274 if ((ps_ip->s_ive_ip.e_frame_type != IV_NA_FRAME)
1275 && (ps_ip->s_ive_ip.e_frame_type != IV_I_FRAME)
1276 && (ps_ip->s_ive_ip.e_frame_type != IV_P_FRAME)
1277 && (ps_ip->s_ive_ip.e_frame_type != IV_IDR_FRAME))
1278 {
1279 ps_op->s_ive_op.u4_error_code |= 1
1280 << IVE_UNSUPPORTEDPARAM;
1281 ps_op->s_ive_op.u4_error_code |=
1282 IH264E_INVALID_FORCE_FRAME_INPUT;
1283 return IV_FAIL;
1284 }
1285 break;
1286 }
1287
1288 case IVE_CMD_CTL_SET_ME_PARAMS:
1289 {
1290 codec_t *ps_codec = (codec_t *) (ps_handle->pv_codec_handle);
1291
1292 ih264e_ctl_set_me_params_ip_t *ps_ip = pv_api_ip;
1293 ih264e_ctl_set_me_params_op_t *ps_op = pv_api_op;
1294
1295 if (ps_ip->s_ive_ip.u4_size
1296 != sizeof(ih264e_ctl_set_me_params_ip_t))
1297 {
1298 ps_op->s_ive_op.u4_error_code |= 1
1299 << IVE_UNSUPPORTEDPARAM;
1300 ps_op->s_ive_op.u4_error_code |=
1301 IVE_ERR_IP_CTL_SETMEPARAMS_API_STRUCT_SIZE_INCORRECT;
1302 return IV_FAIL;
1303 }
1304
1305 if (ps_op->s_ive_op.u4_size
1306 != sizeof(ih264e_ctl_set_me_params_op_t))
1307 {
1308 ps_op->s_ive_op.u4_error_code |= 1
1309 << IVE_UNSUPPORTEDPARAM;
1310 ps_op->s_ive_op.u4_error_code |=
1311 IVE_ERR_OP_CTL_SETMEPARAMS_API_STRUCT_SIZE_INCORRECT;
1312 return IV_FAIL;
1313 }
1314
1315 if ((ps_ip->s_ive_ip.u4_me_speed_preset != FULL_SRCH)
1316 && (ps_ip->s_ive_ip.u4_me_speed_preset != DMND_SRCH)
1317 && (ps_ip->s_ive_ip.u4_me_speed_preset != HEX_SRCH))
1318 {
1319 ps_op->s_ive_op.u4_error_code |= 1
1320 << IVE_UNSUPPORTEDPARAM;
1321 ps_op->s_ive_op.u4_error_code |=
1322 IH264E_INVALID_ME_SPEED_PRESET;
1323 return IV_FAIL;
1324 }
1325
1326 if ((ps_ip->s_ive_ip.u4_enable_hpel != 0)
1327 && (ps_ip->s_ive_ip.u4_enable_hpel != 1))
1328 {
1329 ps_op->s_ive_op.u4_error_code |= 1
1330 << IVE_UNSUPPORTEDPARAM;
1331 ps_op->s_ive_op.u4_error_code |=
1332 IH264E_INVALID_HALFPEL_OPTION;
1333 return IV_FAIL;
1334 }
1335
1336 if ((ps_ip->s_ive_ip.u4_enable_qpel != 0)
1337 && (ps_ip->s_ive_ip.u4_enable_qpel != 1))
1338 {
1339 ps_op->s_ive_op.u4_error_code |= 1
1340 << IVE_UNSUPPORTEDPARAM;
1341 ps_op->s_ive_op.u4_error_code |=
1342 IH264E_INVALID_QPEL_OPTION;
1343 return IV_FAIL;
1344 }
1345
1346 if ((ps_ip->s_ive_ip.u4_enable_fast_sad != 0)
1347 && (ps_ip->s_ive_ip.u4_enable_fast_sad != 1))
1348 {
1349 ps_op->s_ive_op.u4_error_code |= 1
1350 << IVE_UNSUPPORTEDPARAM;
1351 ps_op->s_ive_op.u4_error_code |=
1352 IH264E_INVALID_FAST_SAD_OPTION;
1353 return IV_FAIL;
1354 }
1355
1356 if (ps_ip->s_ive_ip.u4_enable_alt_ref > 255)
1357 {
1358 ps_op->s_ive_op.u4_error_code |= 1
1359 << IVE_UNSUPPORTEDPARAM;
1360 ps_op->s_ive_op.u4_error_code |=
1361 IH264E_INVALID_ALT_REF_OPTION;
1362 return IV_FAIL;
1363 }
1364
1365 if (ps_ip->s_ive_ip.u4_srch_rng_x
1366 > ps_codec->s_cfg.u4_max_srch_rng_x)
1367 {
1368 ps_op->s_ive_op.u4_error_code |= 1
1369 << IVE_UNSUPPORTEDPARAM;
1370 ps_op->s_ive_op.u4_error_code |=
1371 IH264E_HORIZONTAL_SEARCH_RANGE_NOT_SUPPORTED;
1372 return (IV_FAIL);
1373 }
1374
1375 if (ps_ip->s_ive_ip.u4_srch_rng_y
1376 > ps_codec->s_cfg.u4_max_srch_rng_y)
1377 {
1378 ps_op->s_ive_op.u4_error_code |= 1
1379 << IVE_UNSUPPORTEDPARAM;
1380 ps_op->s_ive_op.u4_error_code |=
1381 IH264E_VERTICAL_SEARCH_RANGE_NOT_SUPPORTED;
1382 return (IV_FAIL);
1383 }
1384
1385 break;
1386 }
1387
1388 case IVE_CMD_CTL_SET_IPE_PARAMS:
1389 {
1390 ih264e_ctl_set_ipe_params_ip_t *ps_ip = pv_api_ip;
1391 ih264e_ctl_set_ipe_params_op_t *ps_op = pv_api_op;
1392
1393 if (ps_ip->s_ive_ip.u4_size
1394 != sizeof(ih264e_ctl_set_ipe_params_ip_t))
1395 {
1396 ps_op->s_ive_op.u4_error_code |= 1
1397 << IVE_UNSUPPORTEDPARAM;
1398 ps_op->s_ive_op.u4_error_code |=
1399 IVE_ERR_IP_CTL_SETIPEPARAMS_API_STRUCT_SIZE_INCORRECT;
1400 return IV_FAIL;
1401 }
1402
1403 if (ps_op->s_ive_op.u4_size
1404 != sizeof(ih264e_ctl_set_ipe_params_op_t))
1405 {
1406 ps_op->s_ive_op.u4_error_code |= 1
1407 << IVE_UNSUPPORTEDPARAM;
1408 ps_op->s_ive_op.u4_error_code |=
1409 IVE_ERR_OP_CTL_SETIPEPARAMS_API_STRUCT_SIZE_INCORRECT;
1410 return IV_FAIL;
1411 }
1412
1413 if ((ps_ip->s_ive_ip.u4_enable_intra_4x4 != 0)
1414 && (ps_ip->s_ive_ip.u4_enable_intra_4x4 != 1))
1415 {
1416 ps_op->s_ive_op.u4_error_code |= 1
1417 << IVE_UNSUPPORTEDPARAM;
1418 ps_op->s_ive_op.u4_error_code |=
1419 IH264E_INVALID_INTRA4x4_OPTION;
1420 return IV_FAIL;
1421 }
1422
1423 if ((ps_ip->s_ive_ip.u4_enc_speed_preset != IVE_CONFIG)
1424 && (ps_ip->s_ive_ip.u4_enc_speed_preset != IVE_SLOWEST)
1425 && (ps_ip->s_ive_ip.u4_enc_speed_preset != IVE_NORMAL)
1426 && (ps_ip->s_ive_ip.u4_enc_speed_preset != IVE_FAST)
1427 && (ps_ip->s_ive_ip.u4_enc_speed_preset != IVE_HIGH_SPEED)
1428 && (ps_ip->s_ive_ip.u4_enc_speed_preset != IVE_FASTEST))
1429 {
1430 ps_op->s_ive_op.u4_error_code |= 1
1431 << IVE_UNSUPPORTEDPARAM;
1432 ps_op->s_ive_op.u4_error_code |=
1433 IH264E_INVALID_ENC_SPEED_PRESET;
1434 return IV_FAIL;
1435 }
1436
1437 break;
1438 }
1439
1440 case IVE_CMD_CTL_SET_GOP_PARAMS:
1441 {
1442 ih264e_ctl_set_gop_params_ip_t *ps_ip = pv_api_ip;
1443 ih264e_ctl_set_gop_params_op_t *ps_op = pv_api_op;
1444
1445 if (ps_ip->s_ive_ip.u4_size
1446 != sizeof(ih264e_ctl_set_gop_params_ip_t))
1447 {
1448 ps_op->s_ive_op.u4_error_code |= 1
1449 << IVE_UNSUPPORTEDPARAM;
1450 ps_op->s_ive_op.u4_error_code |=
1451 IVE_ERR_IP_CTL_SETGOPPARAMS_API_STRUCT_SIZE_INCORRECT;
1452 return IV_FAIL;
1453 }
1454
1455 if (ps_op->s_ive_op.u4_size
1456 != sizeof(ih264e_ctl_set_gop_params_op_t))
1457 {
1458 ps_op->s_ive_op.u4_error_code |= 1
1459 << IVE_UNSUPPORTEDPARAM;
1460 ps_op->s_ive_op.u4_error_code |=
1461 IVE_ERR_OP_CTL_SETGOPPARAMS_API_STRUCT_SIZE_INCORRECT;
1462 return IV_FAIL;
1463 }
1464
1465 if ((ps_ip->s_ive_ip.u4_i_frm_interval < DEFAULT_MIN_INTRA_FRAME_RATE)
1466 || (ps_ip->s_ive_ip.u4_i_frm_interval > DEFAULT_MAX_INTRA_FRAME_RATE))
1467 {
1468 ps_op->s_ive_op.u4_error_code |= 1
1469 << IVE_UNSUPPORTEDPARAM;
1470 ps_op->s_ive_op.u4_error_code |=
1471 IH264E_INVALID_INTRA_FRAME_INTERVAL;
1472 return IV_FAIL;
1473 }
1474
1475 if ((ps_ip->s_ive_ip.u4_idr_frm_interval < DEFAULT_MIN_INTRA_FRAME_RATE)
1476 || (ps_ip->s_ive_ip.u4_idr_frm_interval > DEFAULT_MAX_INTRA_FRAME_RATE))
1477 {
1478 ps_op->s_ive_op.u4_error_code |= 1
1479 << IVE_UNSUPPORTEDPARAM;
1480 ps_op->s_ive_op.u4_error_code |=
1481 IH264E_INVALID_IDR_FRAME_INTERVAL;
1482 return IV_FAIL;
1483 }
1484
1485 break;
1486 }
1487
1488 case IVE_CMD_CTL_SET_DEBLOCK_PARAMS:
1489 {
1490 ih264e_ctl_set_deblock_params_ip_t *ps_ip = pv_api_ip;
1491 ih264e_ctl_set_deblock_params_op_t *ps_op = pv_api_op;
1492
1493 if (ps_ip->s_ive_ip.u4_size
1494 != sizeof(ih264e_ctl_set_deblock_params_ip_t))
1495 {
1496 ps_op->s_ive_op.u4_error_code |= 1
1497 << IVE_UNSUPPORTEDPARAM;
1498 ps_op->s_ive_op.u4_error_code |=
1499 IVE_ERR_IP_CTL_SETDEBLKPARAMS_API_STRUCT_SIZE_INCORRECT;
1500 return IV_FAIL;
1501 }
1502
1503 if (ps_op->s_ive_op.u4_size
1504 != sizeof(ih264e_ctl_set_deblock_params_op_t))
1505 {
1506 ps_op->s_ive_op.u4_error_code |= 1
1507 << IVE_UNSUPPORTEDPARAM;
1508 ps_op->s_ive_op.u4_error_code |=
1509 IVE_ERR_OP_CTL_SETDEBLKPARAMS_API_STRUCT_SIZE_INCORRECT;
1510 return IV_FAIL;
1511 }
1512
1513 if ((ps_ip->s_ive_ip.u4_disable_deblock_level != DISABLE_DEBLK_LEVEL_0)
1514 && (ps_ip->s_ive_ip.u4_disable_deblock_level != DISABLE_DEBLK_LEVEL_2)
1515 && (ps_ip->s_ive_ip.u4_disable_deblock_level != DISABLE_DEBLK_LEVEL_3)
1516 && (ps_ip->s_ive_ip.u4_disable_deblock_level != DISABLE_DEBLK_LEVEL_4))
1517 {
1518 ps_op->s_ive_op.u4_error_code |= 1
1519 << IVE_UNSUPPORTEDPARAM;
1520 ps_op->s_ive_op.u4_error_code |=
1521 IH264E_INVALID_DEBLOCKING_TYPE_INPUT;
1522 return IV_FAIL;
1523 }
1524
1525 break;
1526 }
1527
1528 case IVE_CMD_CTL_SET_QP:
1529 {
1530 ih264e_ctl_set_qp_ip_t *ps_ip = pv_api_ip;
1531 ih264e_ctl_set_qp_op_t *ps_op = pv_api_op;
1532
1533 if (ps_ip->s_ive_ip.u4_size
1534 != sizeof(ih264e_ctl_set_qp_ip_t))
1535 {
1536 ps_op->s_ive_op.u4_error_code |= 1
1537 << IVE_UNSUPPORTEDPARAM;
1538 ps_op->s_ive_op.u4_error_code |=
1539 IVE_ERR_IP_CTL_SETQPPARAMS_API_STRUCT_SIZE_INCORRECT;
1540 return IV_FAIL;
1541 }
1542
1543 if (ps_op->s_ive_op.u4_size
1544 != sizeof(ih264e_ctl_set_qp_op_t))
1545 {
1546 ps_op->s_ive_op.u4_error_code |= 1
1547 << IVE_UNSUPPORTEDPARAM;
1548 ps_op->s_ive_op.u4_error_code |=
1549 IVE_ERR_OP_CTL_SETQPPARAMS_API_STRUCT_SIZE_INCORRECT;
1550 return IV_FAIL;
1551 }
1552
1553 if ((ps_ip->s_ive_ip.u4_i_qp_max > MAX_H264_QP)
1554 || (ps_ip->s_ive_ip.u4_p_qp_max > MAX_H264_QP)
1555 || (ps_ip->s_ive_ip.u4_b_qp_max > MAX_H264_QP))
1556 {
1557 ps_op->s_ive_op.u4_error_code |= 1
1558 << IVE_UNSUPPORTEDPARAM;
1559 ps_op->s_ive_op.u4_error_code |=
1560 IH264E_INVALID_MAX_FRAME_QP;
1561 return IV_FAIL;
1562 }
1563
1564 /* We donot support QP < 4 */
1565 if ((ps_ip->s_ive_ip.u4_i_qp_min < 4)
1566 || (ps_ip->s_ive_ip.u4_p_qp_min < 4)
1567 || (ps_ip->s_ive_ip.u4_b_qp_min < 4)
1568 || (ps_ip->s_ive_ip.u4_i_qp_min > ps_ip->s_ive_ip.u4_i_qp_max)
1569 || (ps_ip->s_ive_ip.u4_p_qp_min > ps_ip->s_ive_ip.u4_p_qp_max)
1570 || (ps_ip->s_ive_ip.u4_b_qp_min > ps_ip->s_ive_ip.u4_b_qp_max))
1571 {
1572 ps_op->s_ive_op.u4_error_code |= 1
1573 << IVE_UNSUPPORTEDPARAM;
1574 ps_op->s_ive_op.u4_error_code |=
1575 IH264E_INVALID_MIN_FRAME_QP;
1576 return IV_FAIL;
1577 }
1578
1579 if ((ps_ip->s_ive_ip.u4_i_qp > ps_ip->s_ive_ip.u4_i_qp_max)
1580 || (ps_ip->s_ive_ip.u4_p_qp > ps_ip->s_ive_ip.u4_p_qp_max)
1581 || (ps_ip->s_ive_ip.u4_b_qp > ps_ip->s_ive_ip.u4_b_qp_max))
1582 {
1583 ps_op->s_ive_op.u4_error_code |= 1
1584 << IVE_UNSUPPORTEDPARAM;
1585 ps_op->s_ive_op.u4_error_code |= IH264E_INVALID_INIT_QP;
1586 return IV_FAIL;
1587 }
1588
1589 if ((ps_ip->s_ive_ip.u4_i_qp < ps_ip->s_ive_ip.u4_i_qp_min)
1590 || (ps_ip->s_ive_ip.u4_p_qp < ps_ip->s_ive_ip.u4_p_qp_min)
1591 || (ps_ip->s_ive_ip.u4_b_qp < ps_ip->s_ive_ip.u4_b_qp_min))
1592 {
1593 ps_op->s_ive_op.u4_error_code |= 1
1594 << IVE_UNSUPPORTEDPARAM;
1595 ps_op->s_ive_op.u4_error_code |= IH264E_INVALID_INIT_QP;
1596 return IV_FAIL;
1597 }
1598
1599 break;
1600 }
1601
1602 case IVE_CMD_CTL_SET_ENC_MODE:
1603 {
1604 ih264e_ctl_set_enc_mode_ip_t *ps_ip = pv_api_ip;
1605 ih264e_ctl_set_enc_mode_op_t *ps_op = pv_api_op;
1606
1607 if (ps_ip->s_ive_ip.u4_size
1608 != sizeof(ih264e_ctl_set_enc_mode_ip_t))
1609 {
1610 ps_op->s_ive_op.u4_error_code |= 1
1611 << IVE_UNSUPPORTEDPARAM;
1612 ps_op->s_ive_op.u4_error_code |=
1613 IVE_ERR_IP_CTL_SETENCMODE_API_STRUCT_SIZE_INCORRECT;
1614 return IV_FAIL;
1615 }
1616
1617 if (ps_op->s_ive_op.u4_size
1618 != sizeof(ih264e_ctl_set_enc_mode_op_t))
1619 {
1620 ps_op->s_ive_op.u4_error_code |= 1
1621 << IVE_UNSUPPORTEDPARAM;
1622 ps_op->s_ive_op.u4_error_code |=
1623 IVE_ERR_OP_CTL_SETENCMODE_API_STRUCT_SIZE_INCORRECT;
1624 return IV_FAIL;
1625 }
1626
1627 if ((ps_ip->s_ive_ip.e_enc_mode != IVE_ENC_MODE_HEADER)
1628 && (ps_ip->s_ive_ip.e_enc_mode != IVE_ENC_MODE_PICTURE))
1629 {
1630 ps_op->s_ive_op.u4_error_code |= 1
1631 << IVE_UNSUPPORTEDPARAM;
1632 ps_op->s_ive_op.u4_error_code |=
1633 IH264E_INVALID_ENC_OPERATION_MODE;
1634 return IV_FAIL;
1635 }
1636
1637 break;
1638 }
1639
1640 case IVE_CMD_CTL_SET_VBV_PARAMS:
1641 {
1642 ih264e_ctl_set_vbv_params_ip_t *ps_ip = pv_api_ip;
1643 ih264e_ctl_set_vbv_params_op_t *ps_op = pv_api_op;
1644
1645 if (ps_ip->s_ive_ip.u4_size
1646 != sizeof(ih264e_ctl_set_vbv_params_ip_t))
1647 {
1648 ps_op->s_ive_op.u4_error_code |= 1
1649 << IVE_UNSUPPORTEDPARAM;
1650 ps_op->s_ive_op.u4_error_code |=
1651 IVE_ERR_IP_CTL_SETVBVPARAMS_API_STRUCT_SIZE_INCORRECT;
1652 return IV_FAIL;
1653 }
1654
1655 if (ps_op->s_ive_op.u4_size
1656 != sizeof(ih264e_ctl_set_vbv_params_op_t))
1657 {
1658 ps_op->s_ive_op.u4_error_code |= 1
1659 << IVE_UNSUPPORTEDPARAM;
1660 ps_op->s_ive_op.u4_error_code |=
1661 IVE_ERR_OP_CTL_SETVBVPARAMS_API_STRUCT_SIZE_INCORRECT;
1662 return IV_FAIL;
1663 }
1664
1665 if ((ps_ip->s_ive_ip.u4_vbv_buffer_delay < DEFAULT_MIN_BUFFER_DELAY)
1666 || (ps_ip->s_ive_ip.u4_vbv_buffer_delay > DEFAULT_MAX_BUFFER_DELAY))
1667 {
1668 ps_op->s_ive_op.u4_error_code |= 1
1669 << IVE_UNSUPPORTEDPARAM;
1670 ps_op->s_ive_op.u4_error_code |=
1671 IH264E_INVALID_BUFFER_DELAY;
1672 return IV_FAIL;
1673 }
1674
1675 break;
1676 }
1677
1678 case IVE_CMD_CTL_SET_AIR_PARAMS:
1679 {
1680 ih264e_ctl_set_air_params_ip_t *ps_ip = pv_api_ip;
1681 ih264e_ctl_set_air_params_op_t *ps_op = pv_api_op;
1682
1683 if (ps_ip->s_ive_ip.u4_size
1684 != sizeof(ih264e_ctl_set_air_params_ip_t))
1685 {
1686 ps_op->s_ive_op.u4_error_code |= 1
1687 << IVE_UNSUPPORTEDPARAM;
1688 ps_op->s_ive_op.u4_error_code |=
1689 IVE_ERR_IP_CTL_SETAIRPARAMS_API_STRUCT_SIZE_INCORRECT;
1690 return IV_FAIL;
1691 }
1692
1693 if (ps_op->s_ive_op.u4_size
1694 != sizeof(ih264e_ctl_set_air_params_op_t))
1695 {
1696 ps_op->s_ive_op.u4_error_code |= 1
1697 << IVE_UNSUPPORTEDPARAM;
1698 ps_op->s_ive_op.u4_error_code |=
1699 IVE_ERR_OP_CTL_SETAIRPARAMS_API_STRUCT_SIZE_INCORRECT;
1700 return IV_FAIL;
1701 }
1702
1703 if ((ps_ip->s_ive_ip.e_air_mode != IVE_AIR_MODE_NONE)
1704 && (ps_ip->s_ive_ip.e_air_mode != IVE_AIR_MODE_CYCLIC)
1705 && (ps_ip->s_ive_ip.e_air_mode != IVE_AIR_MODE_RANDOM))
1706 {
1707 ps_op->s_ive_op.u4_error_code |= 1
1708 << IVE_UNSUPPORTEDPARAM;
1709 ps_op->s_ive_op.u4_error_code |=
1710 IH264E_INVALID_AIR_MODE;
1711 return IV_FAIL;
1712 }
1713
1714 if (ps_ip->s_ive_ip.u4_air_refresh_period == 0)
1715 {
1716 ps_op->s_ive_op.u4_error_code |= 1
1717 << IVE_UNSUPPORTEDPARAM;
1718 ps_op->s_ive_op.u4_error_code |=
1719 IH264E_INVALID_AIR_REFRESH_PERIOD;
1720 return IV_FAIL;
1721 }
1722
1723 break;
1724 }
1725
1726 case IVE_CMD_CTL_SET_PROFILE_PARAMS:
1727 {
1728 ih264e_ctl_set_profile_params_ip_t *ps_ip = pv_api_ip;
1729 ih264e_ctl_set_profile_params_op_t *ps_op = pv_api_op;
1730
1731 if (ps_ip->s_ive_ip.u4_size
1732 != sizeof(ih264e_ctl_set_profile_params_ip_t))
1733 {
1734 ps_op->s_ive_op.u4_error_code |= 1
1735 << IVE_UNSUPPORTEDPARAM;
1736 ps_op->s_ive_op.u4_error_code |=
1737 IVE_ERR_IP_CTL_SETPROFILE_API_STRUCT_SIZE_INCORRECT;
1738 return IV_FAIL;
1739 }
1740
1741 if (ps_op->s_ive_op.u4_size
1742 != sizeof(ih264e_ctl_set_profile_params_op_t))
1743 {
1744 ps_op->s_ive_op.u4_error_code |= 1
1745 << IVE_UNSUPPORTEDPARAM;
1746 ps_op->s_ive_op.u4_error_code |=
1747 IVE_ERR_OP_CTL_SETPROFILE_API_STRUCT_SIZE_INCORRECT;
1748 return IV_FAIL;
1749 }
1750
1751 if (ps_ip->s_ive_ip.e_profile != IV_PROFILE_BASE &&
1752 ps_ip->s_ive_ip.e_profile != IV_PROFILE_MAIN)
1753 {
1754 ps_op->s_ive_op.u4_error_code |= 1
1755 << IVE_UNSUPPORTEDPARAM;
1756 ps_op->s_ive_op.u4_error_code |=
1757 IH264E_PROFILE_NOT_SUPPORTED;
1758 return IV_FAIL;
1759 }
1760
1761 if (ps_ip->s_ive_ip.u4_entropy_coding_mode > 1)
1762 {
1763 ps_op->s_ive_op.u4_error_code |= 1
1764 << IVE_UNSUPPORTEDPARAM;
1765 ps_op->s_ive_op.u4_error_code |=
1766 IH264E_INVALID_ENTROPY_CODING_MODE;
1767 return IV_FAIL;
1768 }
1769
1770 break;
1771 }
1772
1773 default:
1774 *(pu4_api_op + 1) |= 1 << IVE_UNSUPPORTEDPARAM;
1775 *(pu4_api_op + 1) |= IVE_ERR_INVALID_API_SUB_CMD;
1776 return IV_FAIL;
1777 }
1778
1779 break;
1780 }
1781
1782 default:
1783 *(pu4_api_op + 1) |= 1 << IVE_UNSUPPORTEDPARAM;
1784 *(pu4_api_op + 1) |= IVE_ERR_INVALID_API_CMD;
1785 return IV_FAIL;
1786 }
1787
1788 return IV_SUCCESS;
1789 }
1790
1791 /**
1792 *******************************************************************************
1793 *
1794 * @brief update encoder configuration parameters
1795 *
1796 * @par Description:
1797 * updates encoder configuration parameters from the given config set.
1798 * Initialize/reinitialize codec parameters according to new configurations.
1799 *
1800 * @param[in] ps_codec
1801 * Pointer to codec context
1802 *
1803 * @param[in] ps_cfg
1804 * Pointer to config param set
1805 *
1806 * @remarks none
1807 *
1808 *******************************************************************************
1809 */
ih264e_codec_update_config(codec_t * ps_codec,cfg_params_t * ps_cfg)1810 IH264E_ERROR_T ih264e_codec_update_config(codec_t *ps_codec,
1811 cfg_params_t *ps_cfg)
1812 {
1813 /* config params */
1814 cfg_params_t *ps_curr_cfg = &ps_codec->s_cfg;
1815
1816 /* error status */
1817 IH264E_ERROR_T err = IH264E_SUCCESS;
1818
1819 /* temp var */
1820 UWORD32 u4_init_rc = 0;
1821
1822 /***********************/
1823 /* UPDATE CODEC CONFIG */
1824 /***********************/
1825 if (ps_cfg->e_cmd == IVE_CMD_CTL_SET_DIMENSIONS)
1826 {
1827 UWORD32 wd_aln = ALIGN16(ps_cfg->u4_wd);
1828 UWORD32 ht_aln = ALIGN16(ps_cfg->u4_ht);
1829
1830 if (ps_curr_cfg->u4_wd != wd_aln || ps_curr_cfg->u4_ht != ht_aln
1831 || ps_curr_cfg->u4_disp_wd != ps_cfg->u4_disp_wd
1832 || ps_curr_cfg->u4_disp_ht != ps_cfg->u4_disp_ht)
1833 {
1834 ps_curr_cfg->u4_wd = wd_aln;
1835 ps_curr_cfg->u4_ht = ht_aln;
1836
1837 ps_curr_cfg->u4_disp_wd = ps_cfg->u4_disp_wd;
1838 ps_curr_cfg->u4_disp_ht = ps_cfg->u4_disp_ht;
1839
1840 ps_curr_cfg->i4_wd_mbs = ps_curr_cfg->u4_wd >> 4;
1841 ps_curr_cfg->i4_ht_mbs = ps_curr_cfg->u4_ht >> 4;
1842
1843 ps_codec->i4_rec_strd = ALIGN16(ps_cfg->u4_wd) + PAD_WD;
1844
1845 /* If number of MBs in a frame changes the air map also changes.
1846 * Hence recompute air map also reset air pic cnt */
1847 if (ps_codec->s_cfg.e_air_mode != IVE_AIR_MODE_NONE)
1848 {
1849 /* re-init the air map */
1850 ih264e_init_air_map(ps_codec);
1851
1852 /* reset air counter */
1853 ps_codec->i4_air_pic_cnt = -1;
1854 }
1855
1856 /* initialize mv bank buffer manager */
1857 err = ih264e_mv_buf_mgr_add_bufs(ps_codec);
1858 if (err != IH264E_SUCCESS)
1859 return err;
1860
1861 /* initialize ref bank buffer manager */
1862 err = ih264e_pic_buf_mgr_add_bufs(ps_codec);
1863 if (err != IH264E_SUCCESS)
1864 return err;
1865
1866 /* since dimension changed, start new sequence by forcing IDR */
1867 ps_codec->force_curr_frame_type = IV_IDR_FRAME;
1868
1869 /* in case dimension changes, we need to reinitialize RC as the
1870 * old model shall not fit further */
1871 u4_init_rc = 1;
1872
1873 /* when the dimension changes, the header needs to be regenerated */
1874 ps_codec->i4_gen_header = 1;
1875 }
1876 }
1877 else if (ps_cfg->e_cmd == IVE_CMD_CTL_SET_FRAMERATE)
1878 {
1879 /* temp var */
1880 UWORD32 u4_src_ticks, u4_tgt_ticks;
1881
1882 u4_src_ticks = ih264e_frame_time_get_src_ticks(
1883 ps_codec->s_rate_control.pps_frame_time);
1884
1885 u4_tgt_ticks = ih264e_frame_time_get_tgt_ticks(
1886 ps_codec->s_rate_control.pps_frame_time);
1887
1888 /* Change frame rate */
1889 if (ps_codec->s_cfg.u4_src_frame_rate
1890 != ps_cfg->u4_src_frame_rate * 1000)
1891 {
1892 ps_codec->s_cfg.u4_src_frame_rate = ps_cfg->u4_src_frame_rate
1893 * 1000;
1894
1895 ih264e_frame_time_update_src_frame_rate(
1896 ps_codec->s_rate_control.pps_frame_time,
1897 ps_codec->s_cfg.u4_src_frame_rate);
1898
1899 ih264_time_stamp_update_frame_rate(
1900 ps_codec->s_rate_control.pps_time_stamp,
1901 ps_codec->s_cfg.u4_src_frame_rate);
1902
1903 irc_change_frame_rate(ps_codec->s_rate_control.pps_rate_control_api,
1904 ps_codec->s_cfg.u4_src_frame_rate,
1905 u4_src_ticks, u4_tgt_ticks);
1906 }
1907
1908 if (ps_codec->s_cfg.u4_tgt_frame_rate
1909 != ps_cfg->u4_tgt_frame_rate * 1000)
1910 {
1911 ps_codec->s_cfg.u4_tgt_frame_rate = ps_cfg->u4_tgt_frame_rate
1912 * 1000;
1913
1914 ih264e_frame_time_update_tgt_frame_rate(
1915 ps_codec->s_rate_control.pps_frame_time,
1916 ps_codec->s_cfg.u4_tgt_frame_rate);
1917
1918 irc_change_frame_rate(ps_codec->s_rate_control.pps_rate_control_api,
1919 ps_codec->s_cfg.u4_src_frame_rate,
1920 u4_src_ticks, u4_tgt_ticks);
1921
1922 irc_change_frm_rate_for_bit_alloc(
1923 ps_codec->s_rate_control.pps_rate_control_api,
1924 ps_codec->s_cfg.u4_tgt_frame_rate);
1925 }
1926
1927 }
1928 else if (ps_cfg->e_cmd == IVE_CMD_CTL_SET_BITRATE)
1929 {
1930 if (ps_curr_cfg->u4_target_bitrate != ps_cfg->u4_target_bitrate)
1931 {
1932 if (IVE_RC_NONE != ps_curr_cfg->e_rc_mode)
1933 irc_change_avg_bit_rate(
1934 ps_codec->s_rate_control.pps_rate_control_api,
1935 ps_cfg->u4_target_bitrate);
1936
1937 ps_curr_cfg->u4_target_bitrate = ps_cfg->u4_target_bitrate;
1938 }
1939 }
1940 else if (ps_cfg->e_cmd == IVE_CMD_CTL_SET_FRAMETYPE)
1941 {
1942 switch (ps_cfg->e_frame_type)
1943 {
1944 case IV_I_FRAME:
1945 ps_codec->force_curr_frame_type = IV_I_FRAME;
1946 break;
1947
1948 case IV_IDR_FRAME:
1949 ps_codec->force_curr_frame_type = IV_IDR_FRAME;
1950 break;
1951
1952 case IV_P_FRAME:
1953 default:
1954 break;
1955 }
1956 }
1957 else if (ps_cfg->e_cmd == IVE_CMD_CTL_SET_ME_PARAMS)
1958 {
1959 if (ps_curr_cfg->u4_enc_speed_preset == IVE_CONFIG)
1960 {
1961 ps_codec->s_cfg.u4_enable_hpel = ps_cfg->u4_enable_hpel;
1962 ps_codec->s_cfg.u4_enable_fast_sad = ps_cfg->u4_enable_fast_sad;
1963 ps_codec->s_cfg.u4_me_speed_preset = ps_cfg->u4_me_speed_preset;
1964 ps_codec->s_cfg.u4_enable_qpel = ps_cfg->u4_enable_qpel;
1965 }
1966 else if (ps_curr_cfg->u4_enc_speed_preset == IVE_FASTEST)
1967 {
1968 ps_codec->s_cfg.u4_enable_fast_sad = ps_cfg->u4_enable_fast_sad;
1969 }
1970 ps_codec->s_cfg.u4_srch_rng_x = ps_cfg->u4_srch_rng_x;
1971 ps_codec->s_cfg.u4_srch_rng_y = ps_cfg->u4_srch_rng_y;
1972
1973 if (ps_codec->s_cfg.u4_enable_alt_ref != ps_cfg->u4_enable_alt_ref)
1974 {
1975 ps_codec->s_cfg.u4_enable_alt_ref = ps_cfg->u4_enable_alt_ref;
1976 ps_codec->u4_is_curr_frm_ref = 1;
1977 }
1978 }
1979 else if (ps_cfg->e_cmd == IVE_CMD_CTL_SET_IPE_PARAMS)
1980 {
1981 ps_curr_cfg->u4_enc_speed_preset = ps_cfg->u4_enc_speed_preset;
1982
1983 if (ps_curr_cfg->u4_enc_speed_preset == IVE_SLOWEST)
1984 {/* high quality */
1985 /* enable diamond search */
1986 ps_curr_cfg->u4_me_speed_preset = DMND_SRCH;
1987 ps_curr_cfg->u4_enable_fast_sad = 0;
1988
1989 /* disable intra 4x4 */
1990 ps_curr_cfg->u4_enable_intra_4x4 = 1;
1991 ps_codec->luma_energy_compaction[1] =
1992 ih264e_code_luma_intra_macroblock_4x4_rdopt_on;
1993
1994 /* sub pel off */
1995 ps_curr_cfg->u4_enable_hpel = 1;
1996
1997 /* deblocking off */
1998 ps_curr_cfg->u4_disable_deblock_level = DISABLE_DEBLK_LEVEL_0;
1999
2000 /* disabled intra inter gating in Inter slices */
2001 ps_codec->u4_inter_gate = 0;
2002 }
2003 else if (ps_curr_cfg->u4_enc_speed_preset == IVE_NORMAL)
2004 {/* normal */
2005 /* enable diamond search */
2006 ps_curr_cfg->u4_me_speed_preset = DMND_SRCH;
2007 ps_curr_cfg->u4_enable_fast_sad = 0;
2008
2009 /* disable intra 4x4 */
2010 ps_curr_cfg->u4_enable_intra_4x4 = 1;
2011
2012 /* sub pel off */
2013 ps_curr_cfg->u4_enable_hpel = 1;
2014
2015 /* deblocking off */
2016 ps_curr_cfg->u4_disable_deblock_level = DISABLE_DEBLK_LEVEL_0;
2017
2018 /* disabled intra inter gating in Inter slices */
2019 ps_codec->u4_inter_gate = 0;
2020 }
2021 else if (ps_curr_cfg->u4_enc_speed_preset == IVE_FAST)
2022 {/* normal */
2023 /* enable diamond search */
2024 ps_curr_cfg->u4_me_speed_preset = DMND_SRCH;
2025 ps_curr_cfg->u4_enable_fast_sad = 0;
2026
2027 /* disable intra 4x4 */
2028 ps_curr_cfg->u4_enable_intra_4x4 = 0;
2029
2030 /* sub pel off */
2031 ps_curr_cfg->u4_enable_hpel = 1;
2032
2033 /* deblocking off */
2034 ps_curr_cfg->u4_disable_deblock_level = DISABLE_DEBLK_LEVEL_0;
2035
2036 /* disabled intra inter gating in Inter slices */
2037 ps_codec->u4_inter_gate = 1;
2038 }
2039 else if (ps_curr_cfg->u4_enc_speed_preset == IVE_HIGH_SPEED)
2040 {/* fast */
2041 /* enable diamond search */
2042 ps_curr_cfg->u4_me_speed_preset = DMND_SRCH;
2043 ps_curr_cfg->u4_enable_fast_sad = 0;
2044
2045 /* disable intra 4x4 */
2046 ps_curr_cfg->u4_enable_intra_4x4 = 0;
2047
2048 /* sub pel off */
2049 ps_curr_cfg->u4_enable_hpel = 0;
2050
2051 /* deblocking off */
2052 ps_curr_cfg->u4_disable_deblock_level = DISABLE_DEBLK_LEVEL_4;
2053
2054 /* disabled intra inter gating in Inter slices */
2055 ps_codec->u4_inter_gate = 0;
2056 }
2057 else if (ps_curr_cfg->u4_enc_speed_preset == IVE_FASTEST)
2058 {/* fastest */
2059 /* enable diamond search */
2060 ps_curr_cfg->u4_me_speed_preset = DMND_SRCH;
2061 //u4_num_layers = 4;
2062
2063 /* disable intra 4x4 */
2064 ps_curr_cfg->u4_enable_intra_4x4 = 0;
2065
2066 /* sub pel off */
2067 ps_curr_cfg->u4_enable_hpel = 0;
2068
2069 /* deblocking off */
2070 ps_curr_cfg->u4_disable_deblock_level = DISABLE_DEBLK_LEVEL_4;
2071
2072 /* disabled intra inter gating in Inter slices */
2073 ps_codec->u4_inter_gate = 1;
2074 }
2075 else if (ps_curr_cfg->u4_enc_speed_preset == IVE_CONFIG)
2076 {
2077 ps_curr_cfg->u4_enable_intra_4x4 = ps_cfg->u4_enable_intra_4x4;
2078 }
2079 }
2080 else if (ps_cfg->e_cmd == IVE_CMD_CTL_SET_GOP_PARAMS)
2081 {
2082 if (ps_curr_cfg->u4_i_frm_interval != ps_cfg->u4_i_frm_interval)
2083 {
2084 ps_curr_cfg->u4_i_frm_interval = ps_cfg->u4_i_frm_interval;
2085
2086 /* reset air counter */
2087 ps_codec->i4_air_pic_cnt = -1;
2088
2089 /* re-init air map */
2090 ih264e_init_air_map(ps_codec);
2091
2092 /*Effect intra frame interval change*/
2093
2094 irc_change_intra_frm_int_call(
2095 ps_codec->s_rate_control.pps_rate_control_api,
2096 ps_curr_cfg->u4_i_frm_interval);
2097 }
2098
2099 ps_curr_cfg->u4_idr_frm_interval = ps_cfg->u4_idr_frm_interval;
2100
2101 }
2102 else if (ps_cfg->e_cmd == IVE_CMD_CTL_SET_DEBLOCK_PARAMS)
2103 {
2104 if (ps_curr_cfg->u4_enc_speed_preset == IVE_CONFIG)
2105 {
2106 ps_curr_cfg->u4_disable_deblock_level =
2107 ps_cfg->u4_disable_deblock_level;
2108 }
2109 }
2110 else if (ps_cfg->e_cmd == IVE_CMD_CTL_SET_QP)
2111 {
2112 UWORD8 au1_init_qp[MAX_PIC_TYPE];
2113 UWORD8 au1_min_max_qp[2 * MAX_PIC_TYPE];
2114
2115 ps_codec->s_cfg.u4_i_qp_max = ps_cfg->u4_i_qp_max;
2116 ps_codec->s_cfg.u4_i_qp_min = ps_cfg->u4_i_qp_min;
2117 ps_codec->s_cfg.u4_i_qp = ps_cfg->u4_i_qp;
2118
2119 ps_codec->s_cfg.u4_p_qp_max = ps_cfg->u4_p_qp_max;
2120 ps_codec->s_cfg.u4_p_qp_min = ps_cfg->u4_p_qp_min;
2121 ps_codec->s_cfg.u4_p_qp = ps_cfg->u4_p_qp;
2122
2123 ps_codec->s_cfg.u4_b_qp_max = ps_cfg->u4_b_qp_max;
2124 ps_codec->s_cfg.u4_b_qp_min = ps_cfg->u4_b_qp_min;
2125 ps_codec->s_cfg.u4_b_qp = ps_cfg->u4_b_qp;
2126
2127 /* update rc lib with modified qp */
2128 au1_init_qp[0] = gau1_h264_to_mpeg2_qmap[ps_codec->s_cfg.u4_i_qp];
2129 au1_init_qp[1] = gau1_h264_to_mpeg2_qmap[ps_codec->s_cfg.u4_p_qp];
2130 au1_init_qp[2] = gau1_h264_to_mpeg2_qmap[ps_codec->s_cfg.u4_b_qp];
2131
2132 irc_change_init_qp(ps_codec->s_rate_control.pps_rate_control_api,
2133 au1_init_qp);
2134
2135 au1_min_max_qp[2 * I_PIC] =
2136 gau1_h264_to_mpeg2_qmap[ps_codec->s_cfg.u4_i_qp_min];
2137 au1_min_max_qp[2 * I_PIC + 1] =
2138 gau1_h264_to_mpeg2_qmap[ps_codec->s_cfg.u4_i_qp_max];
2139
2140 au1_min_max_qp[2 * P_PIC] =
2141 gau1_h264_to_mpeg2_qmap[ps_codec->s_cfg.u4_p_qp_min];
2142 au1_min_max_qp[2 * P_PIC + 1] =
2143 gau1_h264_to_mpeg2_qmap[ps_codec->s_cfg.u4_p_qp_max];
2144
2145 au1_min_max_qp[2 * B_PIC] =
2146 gau1_h264_to_mpeg2_qmap[ps_codec->s_cfg.u4_b_qp_min];
2147 au1_min_max_qp[2 * B_PIC + 1] =
2148 gau1_h264_to_mpeg2_qmap[ps_codec->s_cfg.u4_b_qp_max];
2149
2150 irc_change_min_max_qp(ps_codec->s_rate_control.pps_rate_control_api,
2151 au1_min_max_qp);
2152 }
2153 else if (ps_cfg->e_cmd == IVE_CMD_CTL_SET_ENC_MODE)
2154 {
2155 ps_codec->s_cfg.e_enc_mode = ps_cfg->e_enc_mode;
2156
2157 if (ps_codec->s_cfg.e_enc_mode == IVE_ENC_MODE_HEADER)
2158 {
2159 ps_codec->i4_header_mode = 1;
2160 ps_codec->s_cfg.e_enc_mode = IVE_ENC_MODE_PICTURE;
2161 }
2162 else
2163 {
2164 ps_codec->i4_header_mode = 0;
2165 }
2166 }
2167 else if (ps_cfg->e_cmd == IVE_CMD_CTL_SET_VBV_PARAMS
2168 && IVE_RC_NONE != ps_codec->s_cfg.e_rc_mode)
2169 {
2170 ps_codec->s_cfg.u4_vbv_buf_size = ps_cfg->u4_vbv_buf_size;
2171 ps_codec->s_cfg.u4_vbv_buffer_delay = ps_cfg->u4_vbv_buffer_delay;
2172
2173 // irc_change_buffer_delay(ps_codec->s_rate_control.pps_rate_control_api, ps_codec->s_cfg.u4_vbv_buffer_delay);
2174
2175 // TODO: remove this when the support for changing buffer dynamically
2176 // is yet to be added.
2177 u4_init_rc = 1;
2178 }
2179 else if (ps_cfg->e_cmd == IVE_CMD_CTL_SET_AIR_PARAMS)
2180 {
2181 if (ps_curr_cfg->e_air_mode != ps_cfg->e_air_mode
2182 || ps_curr_cfg->u4_air_refresh_period
2183 != ps_cfg->u4_air_refresh_period)
2184 {
2185 ps_curr_cfg->e_air_mode = ps_cfg->e_air_mode;
2186 ps_curr_cfg->u4_air_refresh_period = ps_cfg->u4_air_refresh_period;
2187
2188 ih264e_init_air_map(ps_codec);
2189
2190 /* reset air counter */
2191 ps_codec->i4_air_pic_cnt = -1;
2192 }
2193 }
2194 else if (ps_cfg->e_cmd == IVE_CMD_CTL_SET_PROFILE_PARAMS)
2195 {
2196 ps_codec->s_cfg.e_profile = ps_cfg->e_profile;
2197 ps_codec->s_cfg.u4_entropy_coding_mode = ps_cfg->u4_entropy_coding_mode;
2198 }
2199 else if (ps_cfg->e_cmd == IVE_CMD_CTL_SET_NUM_CORES)
2200 {
2201 ps_codec->s_cfg.u4_num_cores = ps_cfg->u4_num_cores;
2202 }
2203
2204 /* reset RC model */
2205 if (u4_init_rc)
2206 {
2207 /* init qp */
2208 UWORD8 au1_init_qp[MAX_PIC_TYPE];
2209
2210 /* min max qp */
2211 UWORD8 au1_min_max_qp[2 * MAX_PIC_TYPE];
2212
2213 /* init i,p,b qp */
2214 au1_init_qp[0] = gau1_h264_to_mpeg2_qmap[ps_codec->s_cfg.u4_i_qp];
2215 au1_init_qp[1] = gau1_h264_to_mpeg2_qmap[ps_codec->s_cfg.u4_p_qp];
2216 au1_init_qp[2] = gau1_h264_to_mpeg2_qmap[ps_codec->s_cfg.u4_b_qp];
2217
2218 /* init min max qp */
2219 au1_min_max_qp[2 * I_PIC] =
2220 gau1_h264_to_mpeg2_qmap[ps_codec->s_cfg.u4_i_qp_min];
2221 au1_min_max_qp[2 * I_PIC + 1] =
2222 gau1_h264_to_mpeg2_qmap[ps_codec->s_cfg.u4_i_qp_max];
2223
2224 au1_min_max_qp[2 * P_PIC] =
2225 gau1_h264_to_mpeg2_qmap[ps_codec->s_cfg.u4_p_qp_min];
2226 au1_min_max_qp[2 * P_PIC + 1] =
2227 gau1_h264_to_mpeg2_qmap[ps_codec->s_cfg.u4_p_qp_max];
2228
2229 au1_min_max_qp[2 * B_PIC] =
2230 gau1_h264_to_mpeg2_qmap[ps_codec->s_cfg.u4_b_qp_min];
2231 au1_min_max_qp[2 * B_PIC + 1] =
2232 gau1_h264_to_mpeg2_qmap[ps_codec->s_cfg.u4_b_qp_max];
2233
2234 /* get rc mode */
2235 switch (ps_codec->s_cfg.e_rc_mode)
2236 {
2237 case IVE_RC_STORAGE:
2238 ps_codec->s_rate_control.e_rc_type = VBR_STORAGE;
2239 break;
2240
2241 case IVE_RC_CBR_NON_LOW_DELAY:
2242 ps_codec->s_rate_control.e_rc_type = CBR_NLDRC;
2243 break;
2244
2245 case IVE_RC_CBR_LOW_DELAY:
2246 ps_codec->s_rate_control.e_rc_type = CBR_LDRC;
2247 break;
2248
2249 case IVE_RC_NONE:
2250 ps_codec->s_rate_control.e_rc_type = CONST_QP;
2251 break;
2252
2253 default:
2254 break;
2255 }
2256
2257 /* init rate control */
2258 ih264e_rc_init(ps_codec->s_rate_control.pps_rate_control_api,
2259 ps_codec->s_rate_control.pps_frame_time,
2260 ps_codec->s_rate_control.pps_time_stamp,
2261 ps_codec->s_rate_control.pps_pd_frm_rate,
2262 ps_codec->s_cfg.u4_max_framerate,
2263 ps_codec->s_cfg.u4_src_frame_rate,
2264 ps_codec->s_cfg.u4_tgt_frame_rate,
2265 ps_codec->s_rate_control.e_rc_type,
2266 ps_codec->s_cfg.u4_target_bitrate,
2267 ps_codec->s_cfg.u4_max_bitrate,
2268 ps_codec->s_cfg.u4_vbv_buffer_delay,
2269 ps_codec->s_cfg.u4_i_frm_interval,
2270 ps_codec->s_cfg.u4_num_bframes + 1, au1_init_qp,
2271 ps_codec->s_cfg.u4_num_bframes + 2, au1_min_max_qp,
2272 ps_codec->s_cfg.u4_max_level);
2273 }
2274
2275 return err;
2276 }
2277
2278 /**
2279 *******************************************************************************
2280 *
2281 * @brief
2282 * Sets default encoder config parameters
2283 *
2284 * @par Description:
2285 * Sets default dynamic parameters. Will be called in ih264e_init() to ensure
2286 * that even if set_params is not called, codec continues to work
2287 *
2288 * @param[in] ps_cfg
2289 * Pointer to encoder config params
2290 *
2291 * @returns error status
2292 *
2293 * @remarks none
2294 *
2295 *******************************************************************************
2296 */
ih264e_set_default_params(cfg_params_t * ps_cfg)2297 static WORD32 ih264e_set_default_params(cfg_params_t *ps_cfg)
2298 {
2299 WORD32 ret = IV_SUCCESS;
2300
2301 ps_cfg->u4_max_wd = MAX_WD;
2302 ps_cfg->u4_max_ht = MAX_HT;
2303 ps_cfg->u4_max_ref_cnt = MAX_REF_CNT;
2304 ps_cfg->u4_max_reorder_cnt = MAX_REF_CNT;
2305 ps_cfg->u4_max_level = DEFAULT_MAX_LEVEL;
2306 ps_cfg->e_inp_color_fmt = IV_YUV_420SP_UV;
2307 ps_cfg->u4_enable_recon = DEFAULT_RECON_ENABLE;
2308 ps_cfg->e_recon_color_fmt = IV_YUV_420P;
2309 ps_cfg->u4_enc_speed_preset = IVE_FASTEST;
2310 ps_cfg->e_rc_mode = DEFAULT_RC;
2311 ps_cfg->u4_max_framerate = DEFAULT_MAX_FRAMERATE;
2312 ps_cfg->u4_max_bitrate = DEFAULT_MAX_BITRATE;
2313 ps_cfg->u4_num_bframes = DEFAULT_MAX_NUM_BFRAMES;
2314 ps_cfg->e_content_type = IV_PROGRESSIVE;
2315 ps_cfg->u4_max_srch_rng_x = DEFAULT_MAX_SRCH_RANGE_X;
2316 ps_cfg->u4_max_srch_rng_y = DEFAULT_MAX_SRCH_RANGE_Y;
2317 ps_cfg->e_slice_mode = IVE_SLICE_MODE_NONE;
2318 ps_cfg->u4_slice_param = DEFAULT_SLICE_PARAM;
2319 ps_cfg->e_arch = ih264e_default_arch();
2320 ps_cfg->e_soc = SOC_GENERIC;
2321 ps_cfg->u4_disp_wd = MAX_WD;
2322 ps_cfg->u4_disp_ht = MAX_HT;
2323 ps_cfg->u4_wd = MAX_WD;
2324 ps_cfg->u4_ht = MAX_HT;
2325 ps_cfg->u4_src_frame_rate = DEFAULT_SRC_FRAME_RATE;
2326 ps_cfg->u4_tgt_frame_rate = DEFAULT_TGT_FRAME_RATE;
2327 ps_cfg->u4_target_bitrate = DEFAULT_BITRATE;
2328 ps_cfg->e_frame_type = IV_NA_FRAME;
2329 ps_cfg->e_enc_mode = IVE_ENC_MODE_DEFAULT;
2330 ps_cfg->u4_i_qp = DEFAULT_I_QP;
2331 ps_cfg->u4_p_qp = DEFAULT_P_QP;
2332 ps_cfg->u4_b_qp = DEFAULT_B_QP;
2333 ps_cfg->u4_i_qp_min = DEFAULT_QP_MIN;
2334 ps_cfg->u4_i_qp_max = DEFAULT_QP_MAX;
2335 ps_cfg->u4_p_qp_min = DEFAULT_QP_MIN;
2336 ps_cfg->u4_p_qp_max = DEFAULT_QP_MAX;
2337 ps_cfg->u4_b_qp_min = DEFAULT_QP_MIN;
2338 ps_cfg->u4_b_qp_max = DEFAULT_QP_MAX;
2339 ps_cfg->e_air_mode = DEFAULT_AIR_MODE;
2340 ps_cfg->u4_air_refresh_period = DEFAULT_AIR_REFRESH_PERIOD;
2341 ps_cfg->u4_vbv_buffer_delay = DEFAULT_VBV_DELAY;
2342 ps_cfg->u4_vbv_buf_size = DEFAULT_VBV_SIZE;
2343 ps_cfg->u4_num_cores = DEFAULT_NUM_CORES;
2344 ps_cfg->u4_me_speed_preset = DEFAULT_ME_SPEED_PRESET;
2345 ps_cfg->u4_enable_hpel = DEFAULT_HPEL;
2346 ps_cfg->u4_enable_qpel = DEFAULT_QPEL;
2347 ps_cfg->u4_enable_intra_4x4 = DEFAULT_I4;
2348 ps_cfg->u4_enable_intra_8x8 = DEFAULT_I8;
2349 ps_cfg->u4_enable_intra_16x16 = DEFAULT_I16;
2350 ps_cfg->u4_enable_fast_sad = DEFAULT_ENABLE_FAST_SAD;
2351 ps_cfg->u4_enable_satqd = DEFAULT_ENABLE_SATQD;
2352 ps_cfg->i4_min_sad =
2353 (ps_cfg->u4_enable_satqd == DEFAULT_ENABLE_SATQD) ?
2354 DEFAULT_MIN_SAD_ENABLE :
2355 DEFAULT_MIN_SAD_DISABLE;
2356 ps_cfg->u4_srch_rng_x = DEFAULT_SRCH_RNG_X;
2357 ps_cfg->u4_srch_rng_y = DEFAULT_SRCH_RNG_Y;
2358 ps_cfg->u4_i_frm_interval = DEFAULT_I_INTERVAL;
2359 ps_cfg->u4_idr_frm_interval = DEFAULT_IDR_INTERVAL;
2360 ps_cfg->u4_disable_deblock_level = DEFAULT_DISABLE_DEBLK_LEVEL;
2361 ps_cfg->e_profile = DEFAULT_PROFILE;
2362 ps_cfg->u4_timestamp_low = 0;
2363 ps_cfg->u4_timestamp_high = 0;
2364 ps_cfg->u4_is_valid = 1;
2365 ps_cfg->e_cmd = IVE_CMD_CT_NA;
2366 ps_cfg->i4_wd_mbs = ps_cfg->u4_max_wd >> 4;
2367 ps_cfg->i4_ht_mbs = ps_cfg->u4_max_ht >> 4;
2368 ps_cfg->u4_entropy_coding_mode = CAVLC;
2369 ps_cfg->u4_weighted_prediction = 0;
2370 ps_cfg->u4_constrained_intra_pred = 0;
2371 ps_cfg->u4_pic_info_type = 0;
2372 ps_cfg->u4_mb_info_type = 0;
2373
2374 return ret;
2375 }
2376
2377 /**
2378 *******************************************************************************
2379 *
2380 * @brief
2381 * Initialize encoder context. This will be called by init_mem_rec and during
2382 * codec reset
2383 *
2384 * @par Description:
2385 * Initializes the context
2386 *
2387 * @param[in] ps_codec
2388 * Codec context pointer
2389 *
2390 * @returns error status
2391 *
2392 * @remarks none
2393 *
2394 *******************************************************************************
2395 */
ih264e_init(codec_t * ps_codec)2396 static WORD32 ih264e_init(codec_t *ps_codec)
2397 {
2398 /* enc config param set */
2399 cfg_params_t *ps_cfg = &(ps_codec->s_cfg);
2400
2401 /* temp var */
2402 WORD32 i;
2403
2404 /* coded pic count */
2405 ps_codec->i4_poc = 0;
2406
2407 /* Number of API calls to encode are made */
2408 ps_codec->i4_encode_api_call_cnt = -1;
2409
2410 /* Indicates no header has been generated yet */
2411 ps_codec->u4_header_generated = 0;
2412
2413 /* Number of pictures encoded */
2414 ps_codec->i4_pic_cnt = -1;
2415
2416 /* Number of threads created */
2417 ps_codec->i4_proc_thread_cnt = 0;
2418
2419 /* ctl mutex init */
2420 ithread_mutex_init(ps_codec->pv_ctl_mutex);
2421
2422 /* Set encoder chroma format */
2423 ps_codec->e_codec_color_format =
2424 (ps_cfg->e_inp_color_fmt == IV_YUV_420SP_VU) ?
2425 IV_YUV_420SP_VU : IV_YUV_420SP_UV;
2426
2427 /* Number of continuous frames where deblocking was disabled */
2428 ps_codec->i4_disable_deblk_pic_cnt = 0;
2429
2430 /* frame num */
2431 ps_codec->i4_frame_num = 0;
2432
2433 /* set the current frame type to I frame, since we are going to start encoding*/
2434 ps_codec->force_curr_frame_type = IV_NA_FRAME;
2435
2436 /* idr_pic_id */
2437 ps_codec->i4_idr_pic_id = -1;
2438
2439 /* Flush mode */
2440 ps_codec->i4_flush_mode = 0;
2441
2442 /* Encode header mode */
2443 ps_codec->i4_header_mode = 0;
2444
2445 /* Encode generate header */
2446 ps_codec->i4_gen_header = 0;
2447
2448 /* To signal successful completion of init */
2449 ps_codec->i4_init_done = 1;
2450
2451 /* To signal that at least one picture was decoded */
2452 ps_codec->i4_first_pic_done = 0;
2453
2454 /* Reset Codec */
2455 ps_codec->i4_reset_flag = 0;
2456
2457 /* Current error code */
2458 ps_codec->i4_error_code = IH264E_SUCCESS;
2459
2460 /* threshold residue */
2461 ps_codec->u4_thres_resi = 1;
2462
2463 /* inter gating enable */
2464 ps_codec->u4_inter_gate = 0;
2465
2466 /* entropy mutex init */
2467 ithread_mutex_init(ps_codec->pv_entropy_mutex);
2468
2469 /* sps id */
2470 ps_codec->i4_sps_id = 0;
2471
2472 /* sps id */
2473 ps_codec->i4_pps_id = 0;
2474
2475 /* Process thread created status */
2476 memset(ps_codec->ai4_process_thread_created, 0, MAX_PROCESS_THREADS);
2477
2478 /* Number of MBs processed together */
2479 ps_codec->i4_proc_nmb = 8;
2480
2481 /* Previous POC msb */
2482 ps_codec->i4_prev_poc_msb = 0;
2483
2484 /* Previous POC lsb */
2485 ps_codec->i4_prev_poc_lsb = -1;
2486
2487 /* max Previous POC lsb */
2488 ps_codec->i4_max_prev_poc_lsb = -1;
2489
2490 /* sps, pps status */
2491 {
2492 sps_t *ps_sps = ps_codec->ps_sps_base;
2493 pps_t *ps_pps = ps_codec->ps_pps_base;
2494
2495 for (i = 0; i < MAX_SPS_CNT; i++)
2496 {
2497 ps_sps->i1_sps_valid = 0;
2498 ps_sps++;
2499 }
2500
2501 for (i = 0; i < MAX_PPS_CNT; i++)
2502 {
2503 ps_pps->i1_pps_valid = 0;
2504 ps_pps++;
2505 }
2506 }
2507
2508 {
2509 WORD32 max_mb_rows = ps_cfg->i4_ht_mbs;
2510
2511 WORD32 num_jobs = max_mb_rows * MAX_CTXT_SETS;
2512 WORD32 clz;
2513
2514 /* Use next power of two number of entries*/
2515 clz = CLZ(num_jobs);
2516 num_jobs = 1 << (32 - clz);
2517
2518 /* init process jobq */
2519 ps_codec->pv_proc_jobq = ih264_list_init(
2520 ps_codec->pv_proc_jobq_buf,
2521 ps_codec->i4_proc_jobq_buf_size, num_jobs,
2522 sizeof(job_t), 10);
2523 RETURN_IF((ps_codec->pv_proc_jobq == NULL), IV_FAIL);
2524 ih264_list_reset(ps_codec->pv_proc_jobq);
2525
2526 /* init entropy jobq */
2527 ps_codec->pv_entropy_jobq = ih264_list_init(
2528 ps_codec->pv_entropy_jobq_buf,
2529 ps_codec->i4_entropy_jobq_buf_size, num_jobs,
2530 sizeof(job_t), 10);
2531 RETURN_IF((ps_codec->pv_entropy_jobq == NULL), IV_FAIL);
2532 ih264_list_reset(ps_codec->pv_entropy_jobq);
2533 }
2534
2535 /* Update the jobq context to all the threads */
2536 for (i = 0; i < MAX_PROCESS_CTXT; i++)
2537 {
2538 ps_codec->as_process[i].pv_proc_jobq = ps_codec->pv_proc_jobq;
2539 ps_codec->as_process[i].pv_entropy_jobq = ps_codec->pv_entropy_jobq;
2540
2541 /* i4_id always stays between 0 and MAX_PROCESS_THREADS */
2542 ps_codec->as_process[i].i4_id =
2543 (i >= MAX_PROCESS_THREADS) ?
2544 (i - MAX_PROCESS_THREADS) : i;
2545 ps_codec->as_process[i].ps_codec = ps_codec;
2546
2547 ps_codec->as_process[i].s_entropy.pv_proc_jobq = ps_codec->pv_proc_jobq;
2548 ps_codec->as_process[i].s_entropy.pv_entropy_jobq =
2549 ps_codec->pv_entropy_jobq;
2550 ps_codec->as_process[i].s_entropy.i4_abs_pic_order_cnt = -1;
2551 }
2552
2553 /* Initialize MV Bank buffer manager */
2554 ps_codec->pv_mv_buf_mgr = ih264_buf_mgr_init(ps_codec->pv_mv_buf_mgr_base);
2555
2556 /* Initialize Picture buffer manager for reference buffers*/
2557 ps_codec->pv_ref_buf_mgr = ih264_buf_mgr_init(
2558 ps_codec->pv_ref_buf_mgr_base);
2559
2560 /* Initialize Picture buffer manager for input buffers*/
2561 ps_codec->pv_inp_buf_mgr = ih264_buf_mgr_init(
2562 ps_codec->pv_inp_buf_mgr_base);
2563
2564 /* Initialize buffer manager for output buffers*/
2565 ps_codec->pv_out_buf_mgr = ih264_buf_mgr_init(
2566 ps_codec->pv_out_buf_mgr_base);
2567
2568 /* buffer cnt in buffer manager */
2569 ps_codec->i4_inp_buf_cnt = 0;
2570 ps_codec->i4_out_buf_cnt = 0;
2571 ps_codec->i4_ref_buf_cnt = 0;
2572
2573 ps_codec->ps_pic_buf = (pic_buf_t *) ps_codec->pv_pic_buf_base;
2574 memset(ps_codec->ps_pic_buf, 0, BUF_MGR_MAX_CNT * sizeof(pic_buf_t));
2575
2576 /* Initialize dpb manager */
2577 ih264_dpb_mgr_init((dpb_mgr_t*) ps_codec->pv_dpb_mgr);
2578
2579 memset(ps_codec->as_ref_set, 0,
2580 sizeof(ref_set_t) * (MAX_DPB_SIZE + MAX_CTXT_SETS));
2581 for (i = 0; i < (MAX_DPB_SIZE + MAX_CTXT_SETS); i++)
2582 {
2583 ps_codec->as_ref_set[i].i4_pic_cnt = -1;
2584 }
2585
2586 /* fn ptr init */
2587 ih264e_init_function_ptr(ps_codec);
2588
2589 /* reset status flags */
2590 for (i = 0; i < MAX_CTXT_SETS; i++)
2591 {
2592 ps_codec->au4_entropy_thread_active[i] = 0;
2593 ps_codec->ai4_pic_cnt[i] = -1;
2594
2595 ps_codec->s_rate_control.pre_encode_skip[i] = 0;
2596 ps_codec->s_rate_control.post_encode_skip[i] = 0;
2597 }
2598
2599 ps_codec->s_rate_control.num_intra_in_prev_frame = 0;
2600 ps_codec->s_rate_control.i4_avg_activity = 0;
2601
2602 return IV_SUCCESS;
2603 }
2604
2605 /**
2606 *******************************************************************************
2607 *
2608 * @brief
2609 * Gets number of memory records required by the codec
2610 *
2611 * @par Description:
2612 * Gets codec memory requirements
2613 *
2614 * @param[in] pv_api_ip
2615 * Pointer to input argument structure
2616 *
2617 * @param[out] pv_api_op
2618 * Pointer to output argument structure
2619 *
2620 * @returns status
2621 *
2622 * @remarks
2623 *
2624 *******************************************************************************
2625 */
ih264e_get_num_rec(void * pv_api_ip,void * pv_api_op)2626 static WORD32 ih264e_get_num_rec(void *pv_api_ip, void *pv_api_op)
2627 {
2628 /* api call I/O structures */
2629 ih264e_num_mem_rec_op_t *ps_op = pv_api_op;
2630
2631 UNUSED(pv_api_ip);
2632
2633 ps_op->s_ive_op.u4_num_mem_rec = MEM_REC_CNT;
2634
2635 return IV_SUCCESS;
2636 }
2637
2638 /**
2639 *******************************************************************************
2640 *
2641 * @brief
2642 * Fills memory records of the codec
2643 *
2644 * @par Description:
2645 * Fills codec memory requirements
2646 *
2647 * @param[in] pv_api_ip
2648 * Pointer to input argument structure
2649 *
2650 * @param[out] pv_api_op
2651 * Pointer to output argument structure
2652 *
2653 * @returns error status
2654 *
2655 * @remarks none
2656 *
2657 *******************************************************************************
2658 */
ih264e_fill_num_mem_rec(void * pv_api_ip,void * pv_api_op)2659 static WORD32 ih264e_fill_num_mem_rec(void *pv_api_ip, void *pv_api_op)
2660 {
2661 /* api call I/O structures */
2662 ih264e_fill_mem_rec_ip_t *ps_ip = pv_api_ip;
2663 ih264e_fill_mem_rec_op_t *ps_op = pv_api_op;
2664
2665 /* profile / level info */
2666 WORD32 level;
2667 WORD32 num_reorder_frames;
2668 WORD32 num_ref_frames;
2669
2670 /* mem records */
2671 WORD32 no_of_mem_rec;
2672 iv_mem_rec_t *ps_mem_rec_base, *ps_mem_rec;
2673
2674 /* frame dimensions */
2675 WORD32 max_wd_luma, max_ht_luma;
2676 WORD32 max_mb_rows, max_mb_cols, max_mb_cnt;
2677
2678 /* temp var */
2679 WORD32 i;
2680
2681 /* error status */
2682 IV_STATUS_T status = IV_SUCCESS;
2683
2684 num_reorder_frames = ps_ip->s_ive_ip.u4_max_reorder_cnt;
2685 num_ref_frames = ps_ip->s_ive_ip.u4_max_ref_cnt;
2686
2687 /* mem records */
2688 ps_mem_rec_base = ps_ip->s_ive_ip.ps_mem_rec;
2689 no_of_mem_rec = ps_ip->s_ive_ip.u4_num_mem_rec;
2690
2691 /* frame dimensions */
2692 max_ht_luma = ps_ip->s_ive_ip.u4_max_ht;
2693 max_wd_luma = ps_ip->s_ive_ip.u4_max_wd;
2694 max_ht_luma = ALIGN16(max_ht_luma);
2695 max_wd_luma = ALIGN16(max_wd_luma);
2696 max_mb_rows = max_ht_luma / MB_SIZE;
2697 max_mb_cols = max_wd_luma / MB_SIZE;
2698 max_mb_cnt = max_mb_rows * max_mb_cols;
2699
2700 /* profile / level info */
2701 level = ih264e_get_min_level(max_ht_luma, max_wd_luma);
2702
2703 /* validate params */
2704 if ((level < MIN_LEVEL) || (level > MAX_LEVEL))
2705 {
2706 ps_op->s_ive_op.u4_error_code |= IH264E_CODEC_LEVEL_NOT_SUPPORTED;
2707 level = MAX_LEVEL;
2708 }
2709
2710 if (num_ref_frames > MAX_REF_CNT)
2711 {
2712 ps_op->s_ive_op.u4_error_code |= IH264E_NUM_REF_UNSUPPORTED;
2713 num_ref_frames = MAX_REF_CNT;
2714 }
2715
2716 if (num_reorder_frames > MAX_REF_CNT)
2717 {
2718 ps_op->s_ive_op.u4_error_code |= IH264E_NUM_REORDER_UNSUPPORTED;
2719 num_reorder_frames = MAX_REF_CNT;
2720 }
2721
2722 /* Set all memory records as persistent and alignment as 128 by default */
2723 ps_mem_rec = ps_mem_rec_base;
2724 for (i = 0; i < no_of_mem_rec; i++)
2725 {
2726 ps_mem_rec->u4_mem_alignment = 128;
2727 ps_mem_rec->e_mem_type = IV_EXTERNAL_CACHEABLE_PERSISTENT_MEM;
2728 ps_mem_rec++;
2729 }
2730
2731 /************************************************************************
2732 * Request memory for h264 encoder handle *
2733 ***********************************************************************/
2734 ps_mem_rec = &ps_mem_rec_base[MEM_REC_IV_OBJ];
2735 {
2736 ps_mem_rec->u4_mem_size = sizeof(iv_obj_t);
2737 }
2738 DEBUG("\nMemory record Id %d = %d \n", MEM_REC_IV_OBJ, ps_mem_rec->u4_mem_size);
2739
2740 /************************************************************************
2741 * Request memory for h264 encoder context *
2742 ***********************************************************************/
2743 ps_mem_rec = &ps_mem_rec_base[MEM_REC_CODEC];
2744 {
2745 ps_mem_rec->u4_mem_size = sizeof(codec_t);
2746 }
2747 DEBUG("\nMemory record Id %d = %d \n", MEM_REC_CODEC, ps_mem_rec->u4_mem_size);
2748
2749 /************************************************************************
2750 * Request memory for CABAC context *
2751 ***********************************************************************/
2752 ps_mem_rec = &ps_mem_rec_base[MEM_REC_CABAC];
2753 {
2754 ps_mem_rec->u4_mem_size = sizeof(cabac_ctxt_t);
2755 }
2756 DEBUG("\nMemory record Id %d = %d \n", MEM_REC_CABAC, ps_mem_rec->u4_mem_size);
2757
2758 /************************************************************************
2759 * Request memory for CABAC MB info *
2760 ***********************************************************************/
2761 ps_mem_rec = &ps_mem_rec_base[MEM_REC_CABAC_MB_INFO];
2762 {
2763 ps_mem_rec->u4_mem_size = ((max_mb_cols + 1) + 1)
2764 * sizeof(mb_info_ctxt_t);
2765 }
2766 DEBUG("\nMemory record Id %d = %d \n", MEM_REC_CABAC_MB_INFO, ps_mem_rec->u4_mem_size);
2767
2768
2769 /************************************************************************
2770 * Request memory for entropy context *
2771 * In multi core encoding, each row is assumed to be launched on a *
2772 * thread. The rows below can only start after its neighbors are coded *
2773 * The status of an mb coded/uncoded is signaled via entropy map. *
2774 * 1. One word32 to store skip run cnt *
2775 * 2. mb entropy map (mb status entropy coded/uncoded). The size*
2776 * of the entropy map is max mb cols. Further allocate one *
2777 * more additional row to evade checking for row -1. *
2778 * 3. size of bit stream buffer to store bit stream ctxt. *
2779 * 4. Entropy coding is dependent on nnz coefficient count for *
2780 * the neighbor blocks. It is sufficient to maintain one row *
2781 * worth of nnz as entropy for lower row waits on entropy map*
2782 ************************************************************************/
2783 ps_mem_rec = &ps_mem_rec_base[MEM_REC_ENTROPY];
2784 {
2785 /* total size of the mem record */
2786 WORD32 total_size = 0;
2787
2788 /* size of skip mb run */
2789 total_size += sizeof(WORD32);
2790 total_size = ALIGN8(total_size);
2791
2792 /* size in bytes to store entropy status of an entire frame */
2793 total_size += (max_mb_cols * max_mb_rows);
2794 /* add an additional 1 row of bytes to evade the special case of row 0 */
2795 total_size += max_mb_cols;
2796 total_size = ALIGN128(total_size);
2797
2798 /* size of bit stream buffer */
2799 total_size += sizeof(bitstrm_t);
2800 total_size = ALIGN128(total_size);
2801
2802 /* top nnz luma */
2803 total_size += (max_mb_cols * 4 * sizeof(UWORD8));
2804 total_size = ALIGN128(total_size);
2805
2806 /* top nnz cbcr */
2807 total_size += (max_mb_cols * 4 * sizeof(UWORD8));
2808 total_size = ALIGN128(total_size);
2809
2810 /* total size per each proc ctxt */
2811 total_size *= MAX_CTXT_SETS;
2812
2813 ps_mem_rec->u4_mem_size = total_size;
2814 }
2815 DEBUG("\nMemory record Id %d = %d \n", MEM_REC_ENTROPY, ps_mem_rec->u4_mem_size);
2816
2817 /************************************************************************
2818 * The residue coefficients that needs to be entropy coded are packed *
2819 * at a buffer space by the proc threads. The entropy thread shall *
2820 * read from the buffer space, unpack them and encode the same. The *
2821 * buffer space required to pack a row of mbs are as follows. *
2822 * Assuming transform_8x8_flag is disabled, *
2823 * In the worst case, 1 mb contains 1 dc 4x4 luma sub block, followed *
2824 * by 16 ac 4x4 luma sub blocks, 2 dc chroma 2x2 sub blocks, followed *
2825 * by 8 ac 4x4 chroma sub blocks. *
2826 * For the sake of simplicity we assume that all sub blocks are of *
2827 * type 4x4. The packing of each 4x4 is depicted by the structure *
2828 * tu_sblk_coeff_data_t *
2829 ************************************************************************/
2830 ps_mem_rec = &ps_mem_rec_base[MEM_REC_MB_COEFF_DATA];
2831 {
2832 /* temp var */
2833 WORD32 size = 0;
2834
2835 /* size of coeff data of 1 mb */
2836 size += sizeof(tu_sblk_coeff_data_t) * MAX_4x4_SUBBLKS;
2837
2838 /* size of coeff data of 1 row of mb's */
2839 size *= max_mb_cols;
2840
2841 /* align to avoid any false sharing across threads */
2842 size = ALIGN64(size);
2843
2844 /* size for one full frame */
2845 size *= max_mb_rows;
2846
2847 /* size of each proc buffer set (ping, pong) */
2848 size *= MAX_CTXT_SETS;
2849
2850 ps_mem_rec->u4_mem_size = size;
2851 }
2852 DEBUG("\nMemory record Id %d = %d \n", MEM_REC_MB_COEFF_DATA, ps_mem_rec->u4_mem_size);
2853
2854 /************************************************************************
2855 * while encoding an mb, the mb header data is signaled to the entropy*
2856 * thread by writing to a buffer space. the size of header data per mb *
2857 * is assumed to be 40 bytes *
2858 * TODO: revisit this inference *
2859 ************************************************************************/
2860 ps_mem_rec = &ps_mem_rec_base[MEM_REC_MB_HEADER_DATA];
2861 {
2862 /* temp var */
2863 WORD32 size;
2864
2865 /* size per MB */
2866 size = 40;
2867
2868 /* size for 1 row of mbs */
2869 size = size * max_mb_cols;
2870
2871 /* align to avoid any false sharing across threads */
2872 size = ALIGN64(size);
2873
2874 /* size for one full frame */
2875 size *= max_mb_rows;
2876
2877 /* size of each proc buffer set (ping, pong) */
2878 size *= MAX_CTXT_SETS;
2879
2880 ps_mem_rec->u4_mem_size = size;
2881 }
2882 DEBUG("\nMemory record Id %d = %d \n", MEM_REC_MB_HEADER_DATA, ps_mem_rec->u4_mem_size);
2883
2884 /************************************************************************
2885 * Size for holding mv_buf_t for each MV Bank. *
2886 * Note this allocation is done for BUF_MGR_MAX_CNT instead of *
2887 * MAX_DPB_SIZE or max_dpb_size for following reasons *
2888 * max_dpb_size will be based on max_wd and max_ht *
2889 * For higher max_wd and max_ht this number will be smaller than *
2890 * MAX_DPB_SIZE But during actual initialization number of buffers *
2891 * allocated can be more. *
2892 * *
2893 * One extra MV Bank is needed to hold current pics MV bank. *
2894 * Since this is only a structure allocation and not actual buffer *
2895 * allocation, it is allocated for BUF_MGR_MAX_CNT entries *
2896 ************************************************************************/
2897 ps_mem_rec = &ps_mem_rec_base[MEM_REC_MVBANK];
2898 {
2899 /* max luma samples */
2900 WORD32 max_luma_samples = 0;
2901
2902 /* determine max luma samples */
2903 for (i = 0; i < 16; i++)
2904 if (level ==(WORD32)gas_ih264_lvl_tbl[i].u4_level_idc)
2905 max_luma_samples = gas_ih264_lvl_tbl[i].u4_max_fs
2906 << (BLK_SIZE + BLK_SIZE);
2907
2908 ps_mem_rec->u4_mem_size = ih264_buf_mgr_size();
2909
2910 /************************************************************************
2911 * Allocate for pu_map, enc_pu_t and pic_pu_idx for each MV bank *
2912 * Note: Number of luma samples is not max_wd * max_ht here, instead it *
2913 * is set to maximum number of luma samples allowed at the given level. *
2914 * This is done to ensure that any stream with width and height lesser *
2915 * than max_wd and max_ht is supported. Number of buffers required can *
2916 * be greater for lower width and heights at a given level and this *
2917 * increased number of buffers might require more memory than what *
2918 * max_wd and max_ht buffer would have required Also note one extra *
2919 * buffer is allocated to store current pictures MV bank. *
2920 ***********************************************************************/
2921
2922 ps_mem_rec->u4_mem_size += BUF_MGR_MAX_CNT * sizeof(mv_buf_t);
2923
2924 ps_mem_rec->u4_mem_size += (num_ref_frames + num_reorder_frames
2925 + MAX_CTXT_SETS)
2926 * ih264e_get_pic_mv_bank_size(max_luma_samples);
2927 }
2928 DEBUG("\nMemory record Id %d = %d \n", MEM_REC_MVBANK, ps_mem_rec->u4_mem_size);
2929
2930 /************************************************************************
2931 * While encoding inter slices, to compute the cost of encoding an mb *
2932 * with the mv's at hand, we employ the expression cost = sad + lambda *
2933 * x mv_bits. Here mv_bits is the total number of bits taken to represe*
2934 * nt the mv in the stream. The mv bits for all the possible mv are *
2935 * stored in the look up table. The mem record for this look up table *
2936 * is given below. *
2937 ************************************************************************/
2938 ps_mem_rec = &ps_mem_rec_base[MEM_REC_MVBITS];
2939 {
2940 /* max srch range x */
2941 UWORD32 u4_srch_range_x = ps_ip->s_ive_ip.u4_max_srch_rng_x;
2942
2943 /* max srch range y */
2944 UWORD32 u4_srch_range_y = ps_ip->s_ive_ip.u4_max_srch_rng_y;
2945
2946 /* max srch range */
2947 UWORD32 u4_max_srch_range = MAX(u4_srch_range_x, u4_srch_range_y);
2948
2949 /* due to subpel */
2950 u4_max_srch_range <<= 2;
2951
2952 /* due to mv on either direction */
2953 u4_max_srch_range = (u4_max_srch_range << 1);
2954
2955 /* due to pred mv + zero */
2956 u4_max_srch_range = (u4_max_srch_range << 1) + 1;
2957
2958 u4_max_srch_range = ALIGN128(u4_max_srch_range);
2959
2960 ps_mem_rec->u4_mem_size = u4_max_srch_range;
2961 }
2962 DEBUG("\nMemory record Id %d = %d \n", MEM_REC_MVBITS, ps_mem_rec->u4_mem_size);
2963
2964 /************************************************************************
2965 * Request memory for SPS *
2966 ***********************************************************************/
2967 ps_mem_rec = &ps_mem_rec_base[MEM_REC_SPS];
2968 {
2969 ps_mem_rec->u4_mem_size = MAX_SPS_CNT * sizeof(sps_t);
2970 }
2971 DEBUG("\nMemory record Id %d = %d \n", MEM_REC_SPS, ps_mem_rec->u4_mem_size);
2972
2973 /************************************************************************
2974 * Request memory for PPS *
2975 ***********************************************************************/
2976 ps_mem_rec = &ps_mem_rec_base[MEM_REC_PPS];
2977 {
2978 ps_mem_rec->u4_mem_size = MAX_PPS_CNT * sizeof(pps_t);
2979 }
2980 DEBUG("\nMemory record Id %d = %d \n", MEM_REC_PPS, ps_mem_rec->u4_mem_size);
2981
2982 /************************************************************************
2983 * Request memory for Slice Header *
2984 ***********************************************************************/
2985 ps_mem_rec = &ps_mem_rec_base[MEM_REC_SLICE_HDR];
2986 {
2987 ps_mem_rec->u4_mem_size = MAX_CTXT_SETS * MAX_SLICE_HDR_CNT
2988 * sizeof(slice_header_t);
2989 }
2990 DEBUG("\nMemory record Id %d = %d \n", MEM_REC_SLICE_HDR, ps_mem_rec->u4_mem_size);
2991
2992 /************************************************************************
2993 * Request memory for Adaptive Intra Refresh *
2994 ***********************************************************************/
2995 ps_mem_rec = &ps_mem_rec_base[MEM_REC_AIR_MAP];
2996 {
2997 /* total size of the mem record */
2998 WORD32 total_size = 0;
2999
3000 /* intra coded map */
3001 total_size += max_mb_cnt;
3002 total_size *= MAX_CTXT_SETS;
3003
3004 /* mb refresh map */
3005 total_size += sizeof(UWORD16) * max_mb_cnt;
3006
3007 /* alignment */
3008 total_size = ALIGN128(total_size);
3009
3010 ps_mem_rec->u4_mem_size = total_size;
3011 }
3012 DEBUG("\nMemory record Id %d = %d \n", MEM_REC_AIR_MAP, ps_mem_rec->u4_mem_size);
3013
3014 /************************************************************************
3015 * In multi slice encoding, this memory record helps tracking the start*
3016 * of slice with reference to mb. *
3017 * MEM RECORD for holding *
3018 * 1. mb slice map *
3019 ************************************************************************/
3020 ps_mem_rec = &ps_mem_rec_base[MEM_REC_SLICE_MAP];
3021 {
3022 /* total size of the mem record */
3023 WORD32 total_size = 0;
3024
3025 /* size in bytes to slice index of all mbs of a frame */
3026 total_size = ALIGN64(max_mb_cnt);
3027
3028 /* ih264e_update_proc_ctxt can overread by 1 at the end */
3029 total_size += 1;
3030
3031 /* total size per each proc ctxt */
3032 total_size *= MAX_CTXT_SETS;
3033 ps_mem_rec->u4_mem_size = total_size;
3034 }
3035 DEBUG("\nMemory record Id %d = %d \n", MEM_REC_SLICE_MAP, ps_mem_rec->u4_mem_size);
3036
3037 /************************************************************************
3038 * Request memory to hold thread handles for each processing thread *
3039 ************************************************************************/
3040 ps_mem_rec = &ps_mem_rec_base[MEM_REC_THREAD_HANDLE];
3041 {
3042 WORD32 handle_size = ithread_get_handle_size();
3043
3044 ps_mem_rec->u4_mem_size = MAX_PROCESS_THREADS * handle_size;
3045 }
3046 DEBUG("\nMemory record Id %d = %d \n", MEM_REC_THREAD_HANDLE, ps_mem_rec->u4_mem_size);
3047
3048 /************************************************************************
3049 * Request memory to hold mutex for control calls *
3050 ************************************************************************/
3051 ps_mem_rec = &ps_mem_rec_base[MEM_REC_CTL_MUTEX];
3052 {
3053 ps_mem_rec->u4_mem_size = ithread_get_mutex_lock_size();
3054 }
3055 DEBUG("\nMemory record Id %d = %d \n", MEM_REC_CTL_MUTEX, ps_mem_rec->u4_mem_size);
3056
3057 /************************************************************************
3058 * Request memory to hold mutex for entropy calls *
3059 ************************************************************************/
3060 ps_mem_rec = &ps_mem_rec_base[MEM_REC_ENTROPY_MUTEX];
3061 {
3062 ps_mem_rec->u4_mem_size = ithread_get_mutex_lock_size();
3063 }
3064 DEBUG("\nMemory record Id %d = %d \n", MEM_REC_ENTROPY_MUTEX, ps_mem_rec->u4_mem_size);
3065
3066 /************************************************************************
3067 * Request memory to hold process jobs *
3068 ***********************************************************************/
3069 ps_mem_rec = &ps_mem_rec_base[MEM_REC_PROC_JOBQ];
3070 {
3071 /* One process job per row of MBs */
3072 /* Allocate for two pictures, so that wrap around can be handled easily */
3073 WORD32 num_jobs = max_mb_rows * MAX_CTXT_SETS;
3074
3075 WORD32 job_queue_size = ih264_list_size(num_jobs, sizeof(job_t));
3076
3077 ps_mem_rec->u4_mem_size = job_queue_size;
3078 }
3079 DEBUG("\nMemory record Id %d = %d \n", MEM_REC_PROC_JOBQ, ps_mem_rec->u4_mem_size);
3080
3081 /************************************************************************
3082 * Request memory to hold entropy jobs *
3083 ***********************************************************************/
3084 ps_mem_rec = &ps_mem_rec_base[MEM_REC_ENTROPY_JOBQ];
3085 {
3086 /* One process job per row of MBs */
3087 /* Allocate for two pictures, so that wrap around can be handled easily */
3088 WORD32 num_jobs = max_mb_rows * MAX_CTXT_SETS;
3089
3090 WORD32 job_queue_size = ih264_list_size(num_jobs, sizeof(job_t));
3091
3092 ps_mem_rec->u4_mem_size = job_queue_size;
3093 }
3094 DEBUG("\nMemory record Id %d = %d \n", MEM_REC_ENTROPY_JOBQ, ps_mem_rec->u4_mem_size);
3095
3096 /************************************************************************
3097 * In multi core encoding, each row is assumed to be launched on a *
3098 * thread. The rows below can only start after its neighbors are coded *
3099 * The status of an mb coded/uncoded is signaled via proc map. *
3100 * MEM RECORD for holding *
3101 * 1. mb proc map (mb status core coded/uncoded) *
3102 ************************************************************************/
3103 ps_mem_rec = &ps_mem_rec_base[MEM_REC_PROC_MAP];
3104 {
3105 /* total size of the mem record */
3106 WORD32 total_size = 0;
3107
3108 /* size in bytes to mb core coding status of an entire frame */
3109 total_size = max_mb_cnt;
3110
3111 /* add an additional 1 row of bytes to evade the special case of row 0 */
3112 total_size += max_mb_cols;
3113
3114 /* total size per each proc ctxt */
3115 total_size *= MAX_CTXT_SETS;
3116 ps_mem_rec->u4_mem_size = total_size;
3117 }
3118 DEBUG("\nMemory record Id %d = %d \n", MEM_REC_PROC_MAP, ps_mem_rec->u4_mem_size);
3119
3120 /************************************************************************
3121 * mem record for holding a particular MB is deblocked or not *
3122 * 1. mb deblk map (mb status deblocked/not deblocked) *
3123 ************************************************************************/
3124 ps_mem_rec = &ps_mem_rec_base[MEM_REC_DBLK_MAP];
3125 {
3126 /* total size of the mem record */
3127 WORD32 total_size = 0;
3128
3129 /* size in bytes to mb core coding status of an entire frame */
3130 total_size = max_mb_cnt;
3131
3132 /* add an additional 1 row of bytes to evade the special case of row 0 */
3133 total_size += max_mb_cols;
3134
3135 total_size = ALIGN64(total_size);
3136
3137 /* total size per each proc ctxt */
3138 total_size *= MAX_CTXT_SETS;
3139 ps_mem_rec->u4_mem_size = total_size;
3140 }
3141 DEBUG("\nMemory record Id %d = %d \n", MEM_REC_DBLK_MAP, ps_mem_rec->u4_mem_size);
3142
3143 /************************************************************************
3144 * mem record for holding a particular MB's me is done or not *
3145 * 1. mb me map *
3146 ************************************************************************/
3147 ps_mem_rec = &ps_mem_rec_base[MEM_REC_ME_MAP];
3148 {
3149 /* total size of the mem record */
3150 WORD32 total_size = 0;
3151
3152 /* size in bytes to mb core coding status of an entire frame */
3153 total_size = max_mb_cnt;
3154
3155 /* add an additional 1 row of bytes to evade the special case of row 0 */
3156 total_size += max_mb_cols;
3157
3158 /* total size per each proc ctxt */
3159 total_size *= MAX_CTXT_SETS;
3160
3161 ps_mem_rec->u4_mem_size = total_size;
3162 }
3163 DEBUG("\nMemory record Id %d = %d \n", MEM_REC_ME_MAP, ps_mem_rec->u4_mem_size);
3164
3165 /************************************************************************
3166 * size for holding dpb manager context *
3167 ************************************************************************/
3168 ps_mem_rec = &ps_mem_rec_base[MEM_REC_DPB_MGR];
3169 {
3170 ps_mem_rec->u4_mem_size = sizeof(dpb_mgr_t);
3171 }
3172 DEBUG("\nMemory record Id %d = %d \n", MEM_REC_DPB_MGR, ps_mem_rec->u4_mem_size);
3173
3174 /************************************************************************
3175 * luma or chroma core coding involves mb estimation, error computation*
3176 * between the estimated singnal and the actual signal, transform the *
3177 * error, quantize the error, then inverse transform and inverse quant *
3178 * ize the residue and add the result back to estimated signal. *
3179 * To perform all these, a set of temporary buffers are needed. *
3180 * MEM RECORD for holding scratch buffers *
3181 * 1. prediction buffer used during mb mode analysis *
3182 * 2 temp. reference buffer when intra 4x4 with rdopt on is *
3183 * enabled *
3184 * - when intra 4x4 is enabled, rdopt is on, to store the *
3185 * reconstructed values and use them later this temp. buffer *
3186 * is used. *
3187 * 3. prediction buffer used during intra mode analysis *
3188 * 4. prediction buffer used during intra 16x16 plane mode *
3189 * analysis
3190 * 5. prediction buffer used during intra chroma mode analysis *
3191 * 6. prediction buffer used during intra chroma 16x16 plane *
3192 * mode analysis
3193 * 7. forward transform output buffer *
3194 * - to store the error between estimated and the actual inp *
3195 * ut and to store the fwd transformed quantized output *
3196 * 8. forward transform output buffer *
3197 * - when intra 4x4 is enabled, rdopt is on, to store the *
3198 * fwd transform values and use them later this temp. buffer *
3199 * is used. *
3200 * 9. temporary buffer for inverse transform *
3201 * - temporary buffer used in inverse transform and inverse *
3202 * quantization *
3203 * A. Buffers for holding half_x , half_y and half_xy planes *
3204 ************************************************************************/
3205 ps_mem_rec = &ps_mem_rec_base[MEM_REC_PROC_SCRATCH];
3206 {
3207 WORD32 total_size = 0;
3208 WORD32 i4_tmp_size;
3209
3210 /* size to hold prediction buffer */
3211 total_size += sizeof(UWORD8) * 16 * 16;
3212 total_size = ALIGN64(total_size);
3213
3214 /* size to hold recon for intra 4x4 buffer */
3215 total_size += sizeof(UWORD8) * 16 * 16;
3216 total_size = ALIGN64(total_size);
3217
3218 /* prediction buffer intra 16x16 */
3219 total_size += sizeof(UWORD8) * 16 * 16;
3220 total_size = ALIGN64(total_size);
3221
3222 /* prediction buffer intra 16x16 plane*/
3223 total_size += sizeof(UWORD8) * 16 * 16;
3224 total_size = ALIGN64(total_size);
3225
3226 /* prediction buffer intra chroma*/
3227 total_size += sizeof(UWORD8) * 16 * 8;
3228 total_size = ALIGN64(total_size);
3229
3230 /* prediction buffer intra chroma plane*/
3231 total_size += sizeof(UWORD8) * 16 * 8;
3232 total_size = ALIGN64(total_size);
3233
3234 /* size to hold fwd transform output */
3235 total_size += sizeof(WORD16) * SIZE_TRANS_BUFF;
3236 total_size = ALIGN64(total_size);
3237
3238 /* size to hold fwd transform output */
3239 total_size += sizeof(WORD16) * SIZE_TRANS_BUFF;
3240 total_size = ALIGN64(total_size);
3241
3242 /* size to hold temporary data during inverse transform */
3243 total_size += sizeof(WORD32) * SIZE_TMP_BUFF_ITRANS;
3244 total_size = ALIGN64(total_size);
3245
3246 /* Buffers for holding half_x , half_y and half_xy planes */
3247 i4_tmp_size = sizeof(UWORD8) * (HP_BUFF_WD * HP_BUFF_HT);
3248 total_size += (ALIGN64(i4_tmp_size) * SUBPEL_BUFF_CNT);
3249
3250 /* Allocate for each process thread */
3251 total_size *= MAX_PROCESS_CTXT;
3252
3253 ps_mem_rec->u4_mem_size = total_size;
3254 }
3255 DEBUG("\nMemory record Id %d = %d \n", MEM_REC_PROC_SCRATCH, ps_mem_rec->u4_mem_size);
3256
3257 /************************************************************************
3258 * When transform_8x8_flag is disabled, the size of a sub block is *
3259 * 4x4 and when the transform_8x8_flag is enabled the size of the sub *
3260 * block is 8x8. The threshold matrix and the forward scaling list *
3261 * is of the size of the sub block. *
3262 * MEM RECORD for holding *
3263 * 1. quantization parameters for plane y, cb, cr *
3264 * - threshold matrix for quantization *
3265 * - forward weight matrix *
3266 * - satqd threshold matrix *
3267 ************************************************************************/
3268 ps_mem_rec = &ps_mem_rec_base[MEM_REC_QUANT_PARAM];
3269 {
3270 /* total size of the mem record */
3271 WORD32 total_size = 0;
3272
3273 /* quantization parameter list for planes y,cb and cr */
3274 total_size += ALIGN64(sizeof(quant_params_t)) * 3;
3275
3276 /* size of threshold matrix for quantization
3277 * (assuming the transform_8x8_flag is disabled).
3278 * for all 3 planes */
3279 total_size += ALIGN64(sizeof(WORD16) * 4 * 4) * 3;
3280
3281 /* size of forward weight matrix for quantization
3282 * (assuming the transform_8x8_flag is disabled).
3283 * for all 3 planes */
3284 total_size += ALIGN64(sizeof(WORD16) * 4 * 4) * 3;
3285
3286 /* Size for SATDQ threshold matrix for palnes y, cb and cr */
3287 total_size += ALIGN64(sizeof(UWORD16) * 9) * 3;
3288
3289 /* total size per each proc thread */
3290 total_size *= MAX_PROCESS_CTXT;
3291
3292 ps_mem_rec->u4_mem_size = total_size;
3293 }
3294 DEBUG("\nMemory record Id %d = %d \n", MEM_REC_QUANT_PARAM, ps_mem_rec->u4_mem_size);
3295
3296 /************************************************************************
3297 * While computing blocking strength for the current mb, the csbp, mb *
3298 * type for the neighboring mbs are necessary. memtab for storing top *
3299 * row mbtype and csbp is evaluated here. *
3300 * *
3301 * when encoding intra 4x4 or intra 8x8 the submb types are estimated *
3302 * and sent. The estimation is dependent on neighbor mbs. For this *
3303 * store the top row sub mb types for intra mbs *
3304 * *
3305 * During motion vector prediction, the curr mb mv is predicted from *
3306 * neigbors left, top, top right and sometimes top left depending on *
3307 * the availability. The top and top right content is accessed from *
3308 * the memtab specified below. *
3309 ************************************************************************/
3310 ps_mem_rec = &ps_mem_rec_base[MEM_REC_TOP_ROW_SYN_INFO];
3311 {
3312 /* total size of the mem record */
3313 WORD32 total_size = 0;
3314
3315 /* size in bytes to store 1 row of mb_info_t */
3316 /* one additional mb, to avoid checking end of row condition */
3317 total_size += (max_mb_cols + 1) * sizeof(mb_info_t);
3318
3319 /* size in bytes to store 1 row of intra macroblock sub modes */
3320 total_size += max_mb_cols * sizeof(UWORD8) * 16;
3321
3322 /* size in bytes to store 1 row + 1 of enc_pu_t */
3323 /* one additional mb, to avoid checking end of row condition */
3324 total_size += (max_mb_cols + 1) * sizeof(enc_pu_t);
3325
3326 /* total size per proc ctxt */
3327 total_size = ALIGN128(total_size);
3328
3329 /* total size per each proc ctxt */
3330 total_size *= MAX_CTXT_SETS;
3331 ps_mem_rec->u4_mem_size = total_size;
3332 }
3333 DEBUG("\nMemory record Id %d = %d \n", MEM_REC_TOP_ROW_SYN_INFO, ps_mem_rec->u4_mem_size);
3334
3335 /************************************************************************
3336 * When transform_8x8_flag is disabled, the mb is partitioned into *
3337 * 4 sub blocks. This corresponds to 1 vertical left edge and 1 *
3338 * vertical inner edge, 1 horizontal top edge and 1 horizontal *
3339 * inner edge per mb. Further, When transform_8x8_flag is enabled, *
3340 * the mb is partitioned in to 16 sub blocks. This corresponds to *
3341 * 1 vertical left edge and 3 vertical inner edges, 1 horizontal top *
3342 * edge and 3 horizontal inner edges per mb. *
3343 * MEM RECORD for holding *
3344 * 1. vertical edge blocking strength *
3345 * 2. horizontal edge blocking strength *
3346 * 3. mb qp *
3347 * all are frame level *
3348 ************************************************************************/
3349 ps_mem_rec = &ps_mem_rec_base[MEM_REC_BS_QP];
3350 {
3351 /* total size of the mem record */
3352 WORD32 total_size = 0;
3353
3354 /* size in bytes to store vertical edge bs, horizontal edge bs and qp of every mb*/
3355 WORD32 vert_bs_size, horz_bs_size, qp_size;
3356
3357 /* vertical edge bs = total number of vertical edges * number of bytes per each edge */
3358 /* total num of v edges = total mb * 4 (assuming transform_8x8_flag = 0),
3359 * each edge is formed by 4 pairs of subblks, requiring 4 bytes to storing bs */
3360 vert_bs_size = ALIGN64(max_mb_cnt * 4 * 4);
3361
3362 /* horizontal edge bs = total number of horizontal edges * number of bytes per each edge */
3363 /* total num of h edges = total mb * 4 (assuming transform_8x8_flag = 0),
3364 * each edge is formed by 4 pairs of subblks, requiring 4 bytes to storing bs */
3365 horz_bs_size = ALIGN64(max_mb_cnt * 4 * 4);
3366
3367 /* qp of each mb requires 1 byte */
3368 qp_size = ALIGN64(max_mb_cnt);
3369
3370 /* total size */
3371 total_size = vert_bs_size + horz_bs_size + qp_size;
3372
3373 /* total size per each proc ctxt */
3374 total_size *= MAX_CTXT_SETS;
3375
3376 ps_mem_rec->u4_mem_size = total_size;
3377 }
3378 DEBUG("\nMemory record Id %d = %d \n", MEM_REC_BS_QP, ps_mem_rec->u4_mem_size);
3379
3380 /************************************************************************
3381 * size for holding dpb manager context *
3382 ************************************************************************/
3383 ps_mem_rec = &ps_mem_rec_base[MEM_REC_INP_PIC];
3384 {
3385 ps_mem_rec->u4_mem_size = ih264_buf_mgr_size();
3386 }
3387 DEBUG("\nMemory record Id %d = %d \n", MEM_REC_INP_PIC, ps_mem_rec->u4_mem_size);
3388
3389 /************************************************************************
3390 * size for holding dpb manager context *
3391 ************************************************************************/
3392 ps_mem_rec = &ps_mem_rec_base[MEM_REC_OUT];
3393 {
3394 ps_mem_rec->u4_mem_size = ih264_buf_mgr_size();
3395 }
3396 DEBUG("\nMemory record Id %d = %d \n", MEM_REC_OUT, ps_mem_rec->u4_mem_size);
3397
3398 /************************************************************************
3399 * Size for color space conversion *
3400 ************************************************************************/
3401 ps_mem_rec = &ps_mem_rec_base[MEM_REC_CSC];
3402 {
3403 /* We need a total a memory for a single frame of 420 sp, ie
3404 * (wd * ht) for luma and (wd * ht / 2) for chroma*/
3405 ps_mem_rec->u4_mem_size = MAX_CTXT_SETS
3406 * ((3 * max_ht_luma * max_wd_luma) >> 1);
3407 /* Allocate an extra row, since inverse transform functions for
3408 * chroma access(only read, not used) few extra bytes due to
3409 * interleaved input
3410 */
3411 ps_mem_rec->u4_mem_size += max_wd_luma;
3412 }
3413 DEBUG("\nMemory record Id %d = %d \n", MEM_REC_CSC, ps_mem_rec->u4_mem_size);
3414
3415 /************************************************************************
3416 * Size for holding pic_buf_t for each reference picture *
3417 * Note this allocation is done for BUF_MGR_MAX_CNT instead of *
3418 * MAX_DPB_SIZE or max_dpb_size for following reasons *
3419 * max_dpb_size will be based on max_wd and max_ht *
3420 * For higher max_wd and max_ht this number will be smaller than *
3421 * MAX_DPB_SIZE But during actual initialization number of buffers *
3422 * allocated can be more. *
3423 * *
3424 * Also to handle display depth application can allocate more than *
3425 * what codec asks for in case of non-shared mode *
3426 * Since this is only a structure allocation and not actual buffer *
3427 * allocation, it is allocated for BUF_MGR_MAX_CNT entries *
3428 ************************************************************************/
3429 ps_mem_rec = &ps_mem_rec_base[MEM_REC_REF_PIC];
3430 {
3431 ps_mem_rec->u4_mem_size = ih264_buf_mgr_size();
3432 ps_mem_rec->u4_mem_size += BUF_MGR_MAX_CNT * sizeof(pic_buf_t);
3433
3434 /************************************************************************
3435 * Note: Number of luma samples is not max_wd * max_ht here, instead it *
3436 * is set to maximum number of luma samples allowed at the given level. *
3437 * This is done to ensure that any stream with width and height lesser *
3438 * than max_wd and max_ht is supported. Number of buffers required can *
3439 * be greater for lower width and heights at a given level and this *
3440 * increased number of buffers might require more memory than what *
3441 * max_wd and max_ht buffer would have required. Number of buffers is *
3442 * doubled in order to return one frame at a time instead of sending *
3443 * multiple outputs during dpb full case. Also note one extra buffer is *
3444 * allocted to store current picture. *
3445 * *
3446 * Half-pel planes for each reference buffer are allocated along with *
3447 * the reference buffer. So each reference buffer is 4 times the *
3448 * required size. This way buffer management for the half-pel planes is *
3449 * easier and while using the half-pel planes in MC, an offset can be *
3450 * used from a single pointer *
3451 ***********************************************************************/
3452 ps_mem_rec->u4_mem_size += HPEL_PLANES_CNT
3453 * ih264e_get_total_pic_buf_size(
3454 max_wd_luma * max_ht_luma, level,
3455 PAD_WD, PAD_HT, num_ref_frames,
3456 num_reorder_frames);
3457 }
3458 DEBUG("\nMemory record Id %d = %d \n", MEM_REC_REF_PIC, ps_mem_rec->u4_mem_size);
3459
3460 /************************************************************************
3461 * Request memory to hold mem recs to be returned during retrieve call *
3462 ************************************************************************/
3463 ps_mem_rec = &ps_mem_rec_base[MEM_REC_BACKUP];
3464 {
3465 ps_mem_rec->u4_mem_size = MEM_REC_CNT * sizeof(iv_mem_rec_t);
3466 }
3467 DEBUG("\nMemory record Id %d = %d \n", MEM_REC_BACKUP, ps_mem_rec->u4_mem_size);
3468
3469 /************************************************************************
3470 * size for memory required by NMB info structs and buffer for storing *
3471 * half pel plane *
3472 ************************************************************************/
3473 ps_mem_rec = &ps_mem_rec_base[MEM_REC_MB_INFO_NMB];
3474 {
3475 ps_mem_rec->u4_mem_size = MAX_PROCESS_CTXT * max_mb_cols *
3476 (sizeof(mb_info_nmb_t) + MB_SIZE * MB_SIZE
3477 * sizeof(UWORD8));
3478 }
3479 DEBUG("\nMemory record Id %d = %d \n", MEM_REC_MB_INFO_NMB, ps_mem_rec->u4_mem_size);
3480
3481 /************************************************************************
3482 * RC mem records *
3483 ************************************************************************/
3484 ps_mem_rec = &ps_mem_rec_base[MEM_REC_RC];
3485 {
3486 ih264e_get_rate_control_mem_tab(NULL, ps_mem_rec, FILL_MEMTAB);
3487 }
3488 DEBUG("\nMemory record Id %d = %d \n", MEM_REC_RC, ps_mem_rec->u4_mem_size);
3489
3490 /* Each memtab size is aligned to next multiple of 128 bytes */
3491 /* This is to ensure all the memtabs start at different cache lines */
3492 ps_mem_rec = ps_mem_rec_base;
3493 for (i = 0; i < MEM_REC_CNT; i++)
3494 {
3495 ps_mem_rec->u4_mem_size = ALIGN128(ps_mem_rec->u4_mem_size);
3496 ps_mem_rec++;
3497 }
3498
3499 ps_op->s_ive_op.u4_num_mem_rec = MEM_REC_CNT;
3500
3501 DEBUG("Num mem recs in fill call : %d\n", ps_op->s_ive_op.u4_num_mem_rec);
3502
3503 return (status);
3504 }
3505
3506 /**
3507 *******************************************************************************
3508 *
3509 * @brief
3510 * Initializes from mem records passed to the codec
3511 *
3512 * @par Description:
3513 * Initializes pointers based on mem records passed
3514 *
3515 * @param[in] ps_codec_obj
3516 * Pointer to codec object at API level
3517 *
3518 * @param[in] pv_api_ip
3519 * Pointer to input argument structure
3520 *
3521 * @param[out] pv_api_op
3522 * Pointer to output argument structure
3523 *
3524 * @returns error status
3525 *
3526 * @remarks none
3527 *
3528 *******************************************************************************
3529 */
ih264e_init_mem_rec(iv_obj_t * ps_codec_obj,void * pv_api_ip,void * pv_api_op)3530 static WORD32 ih264e_init_mem_rec(iv_obj_t *ps_codec_obj,
3531 void *pv_api_ip,
3532 void *pv_api_op)
3533 {
3534 /* api call I/O structures */
3535 ih264e_init_ip_t *ps_ip = pv_api_ip;
3536 ih264e_init_op_t *ps_op = pv_api_op;
3537
3538 /* mem records */
3539 iv_mem_rec_t *ps_mem_rec_base, *ps_mem_rec;
3540
3541 /* codec variables */
3542 codec_t * ps_codec;
3543 cabac_ctxt_t *ps_cabac;
3544 mb_info_ctxt_t *ps_mb_map_ctxt_inc;
3545
3546 cfg_params_t *ps_cfg;
3547
3548 /* frame dimensions */
3549 WORD32 max_wd_luma, max_ht_luma;
3550 WORD32 max_mb_rows, max_mb_cols, max_mb_cnt;
3551
3552 /* temp var */
3553 WORD32 i, j;
3554 WORD32 status = IV_SUCCESS;
3555
3556 /* frame dimensions */
3557 max_ht_luma = ALIGN16(ps_ip->s_ive_ip.u4_max_ht);
3558 max_wd_luma = ALIGN16(ps_ip->s_ive_ip.u4_max_wd);
3559 max_mb_rows = max_ht_luma / MB_SIZE;
3560 max_mb_cols = max_wd_luma / MB_SIZE;
3561 max_mb_cnt = max_mb_rows * max_mb_cols;
3562
3563 /* mem records */
3564 ps_mem_rec_base = ps_ip->s_ive_ip.ps_mem_rec;
3565
3566 /* Init mem records */
3567 ps_mem_rec = &ps_mem_rec_base[MEM_REC_CODEC];
3568 {
3569 ps_codec_obj->pv_codec_handle = ps_mem_rec->pv_base;
3570 ps_codec = (codec_t *) (ps_codec_obj->pv_codec_handle);
3571 }
3572 /* Init mem records_cabac ctxt */
3573 ps_mem_rec = &ps_mem_rec_base[MEM_REC_CABAC];
3574 {
3575 ps_cabac = (cabac_ctxt_t *)(ps_mem_rec->pv_base);
3576 }
3577
3578 /* Init mem records mb info array for CABAC */
3579 ps_mem_rec = &ps_mem_rec_base[MEM_REC_CABAC_MB_INFO];
3580 {
3581 ps_mb_map_ctxt_inc = (mb_info_ctxt_t *)(ps_mem_rec->pv_base);
3582 }
3583
3584 /* Note this memset can not be done in init() call, since init will called
3585 during reset as well. And calling this during reset will mean all pointers
3586 need to reinitialized */
3587 memset(ps_codec, 0, sizeof(codec_t));
3588 memset(ps_cabac, 0, sizeof(cabac_ctxt_t));
3589
3590 /* Set default Config Params */
3591 ps_cfg = &ps_codec->s_cfg;
3592 ih264e_set_default_params(ps_cfg);
3593
3594 /* Update config params as per input */
3595 ps_cfg->u4_max_wd = ALIGN16(ps_ip->s_ive_ip.u4_max_wd);
3596 ps_cfg->u4_max_ht = ALIGN16(ps_ip->s_ive_ip.u4_max_ht);
3597 ps_cfg->i4_wd_mbs = ps_cfg->u4_max_wd >> 4;
3598 ps_cfg->i4_ht_mbs = ps_cfg->u4_max_ht >> 4;
3599 ps_cfg->u4_max_ref_cnt = ps_ip->s_ive_ip.u4_max_ref_cnt;
3600 ps_cfg->u4_max_reorder_cnt = ps_ip->s_ive_ip.u4_max_reorder_cnt;
3601 ps_cfg->u4_max_level = ps_ip->s_ive_ip.u4_max_level;
3602 ps_cfg->e_inp_color_fmt = ps_ip->s_ive_ip.e_inp_color_fmt;
3603 ps_cfg->e_recon_color_fmt = ps_ip->s_ive_ip.e_recon_color_fmt;
3604 ps_cfg->u4_max_framerate = ps_ip->s_ive_ip.u4_max_framerate;
3605 ps_cfg->u4_max_bitrate = ps_ip->s_ive_ip.u4_max_bitrate;
3606 ps_cfg->u4_num_bframes = ps_ip->s_ive_ip.u4_num_bframes;
3607 ps_cfg->e_content_type = ps_ip->s_ive_ip.e_content_type;
3608 ps_cfg->u4_max_srch_rng_x = ps_ip->s_ive_ip.u4_max_srch_rng_x;
3609 ps_cfg->u4_max_srch_rng_y = ps_ip->s_ive_ip.u4_max_srch_rng_y;
3610 ps_cfg->e_slice_mode = ps_ip->s_ive_ip.e_slice_mode;
3611 ps_cfg->u4_slice_param = ps_ip->s_ive_ip.u4_slice_param;
3612 ps_cfg->e_arch = ps_ip->s_ive_ip.e_arch;
3613 ps_cfg->e_soc = ps_ip->s_ive_ip.e_soc;
3614 ps_cfg->u4_enable_recon = ps_ip->s_ive_ip.u4_enable_recon;
3615 ps_cfg->e_rc_mode = ps_ip->s_ive_ip.e_rc_mode;
3616
3617 /* Validate params */
3618 if ((ps_ip->s_ive_ip.u4_max_level < MIN_LEVEL)
3619 || (ps_ip->s_ive_ip.u4_max_level > MAX_LEVEL))
3620 {
3621 ps_op->s_ive_op.u4_error_code |= IH264E_CODEC_LEVEL_NOT_SUPPORTED;
3622 ps_cfg->u4_max_level = DEFAULT_MAX_LEVEL;
3623 }
3624
3625 if (ps_ip->s_ive_ip.u4_max_ref_cnt > MAX_REF_CNT)
3626 {
3627 ps_op->s_ive_op.u4_error_code |= IH264E_NUM_REF_UNSUPPORTED;
3628 ps_cfg->u4_max_ref_cnt = MAX_REF_CNT;
3629 }
3630
3631 if (ps_ip->s_ive_ip.u4_max_reorder_cnt > MAX_REF_CNT)
3632 {
3633 ps_op->s_ive_op.u4_error_code |= IH264E_NUM_REORDER_UNSUPPORTED;
3634 ps_cfg->u4_max_reorder_cnt = MAX_REF_CNT;
3635 }
3636
3637 ps_mem_rec = &ps_mem_rec_base[MEM_REC_BACKUP];
3638 {
3639 ps_codec->ps_mem_rec_backup = (iv_mem_rec_t *) ps_mem_rec->pv_base;
3640
3641 memcpy(ps_codec->ps_mem_rec_backup, ps_mem_rec_base,
3642 MEM_REC_CNT * sizeof(iv_mem_rec_t));
3643 }
3644
3645 ps_mem_rec = &ps_mem_rec_base[MEM_REC_ENTROPY];
3646 {
3647 /* temp var */
3648 WORD32 size = 0, offset;
3649
3650 for (i = 0; i < MAX_PROCESS_CTXT; i++)
3651 {
3652 if (i < MAX_PROCESS_CTXT / MAX_CTXT_SETS)
3653 {
3654 /* base ptr */
3655 UWORD8 *pu1_buf = ps_mem_rec->pv_base;
3656
3657 /* reset size */
3658 size = 0;
3659
3660 /* skip mb run */
3661 ps_codec->as_process[i].s_entropy.pi4_mb_skip_run =
3662 (void *) (pu1_buf + size);
3663 size += sizeof(WORD32);
3664 size = ALIGN8(size);
3665
3666 /* entropy map */
3667 ps_codec->as_process[i].s_entropy.pu1_entropy_map =
3668 (void *) (pu1_buf + size + max_mb_cols);
3669 /* size in bytes to store entropy status of an entire frame */
3670 size += (max_mb_cols * max_mb_rows);
3671 /* add an additional 1 row of bytes to evade the special case of row 0 */
3672 size += max_mb_cols;
3673 size = ALIGN128(size);
3674
3675 /* bit stream ptr */
3676 ps_codec->as_process[i].s_entropy.ps_bitstrm = (void *) (pu1_buf
3677 + size);
3678 size += sizeof(bitstrm_t);
3679 size = ALIGN128(size);
3680
3681 /* nnz luma */
3682 ps_codec->as_process[i].s_entropy.pu1_top_nnz_luma =
3683 (void *) (pu1_buf + size);
3684 size += (max_mb_cols * 4 * sizeof(UWORD8));
3685 size = ALIGN128(size);
3686
3687 /* nnz chroma */
3688 ps_codec->as_process[i].s_entropy.pu1_top_nnz_cbcr =
3689 (void *) (pu1_buf + size);
3690 size += (max_mb_cols * 4 * sizeof(UWORD8));
3691 size = ALIGN128(size);
3692 offset = size;
3693 /* cabac Context */
3694 ps_codec->as_process[i].s_entropy.ps_cabac = ps_cabac;
3695 }
3696 else
3697 {
3698 /* base ptr */
3699 UWORD8 *pu1_buf = ps_mem_rec->pv_base;
3700
3701 /* reset size */
3702 size = offset;
3703
3704 /* skip mb run */
3705 ps_codec->as_process[i].s_entropy.pi4_mb_skip_run =
3706 (void *) (pu1_buf + size);
3707 size += sizeof(WORD32);
3708 size = ALIGN8(size);
3709
3710 /* entropy map */
3711 ps_codec->as_process[i].s_entropy.pu1_entropy_map =
3712 (void *) (pu1_buf + size + max_mb_cols);
3713 /* size in bytes to store entropy status of an entire frame */
3714 size += (max_mb_cols * max_mb_rows);
3715 /* add an additional 1 row of bytes to evade the special case of row 0 */
3716 size += max_mb_cols;
3717 size = ALIGN128(size);
3718
3719 /* bit stream ptr */
3720 ps_codec->as_process[i].s_entropy.ps_bitstrm = (void *) (pu1_buf
3721 + size);
3722 size += sizeof(bitstrm_t);
3723 size = ALIGN128(size);
3724
3725 /* nnz luma */
3726 ps_codec->as_process[i].s_entropy.pu1_top_nnz_luma =
3727 (void *) (pu1_buf + size);
3728 size += (max_mb_cols * 4 * sizeof(UWORD8));
3729 size = ALIGN128(size);
3730
3731 /* nnz chroma */
3732 ps_codec->as_process[i].s_entropy.pu1_top_nnz_cbcr =
3733 (void *) (pu1_buf + size);
3734 size += (max_mb_cols * 4 * sizeof(UWORD8));
3735 size = ALIGN128(size);
3736 /* cabac Context */
3737 ps_codec->as_process[i].s_entropy.ps_cabac = ps_cabac;
3738 }
3739 }
3740 ps_codec->as_process[0].s_entropy.ps_cabac->ps_mb_map_ctxt_inc_base =
3741 ps_mb_map_ctxt_inc;
3742 }
3743
3744 ps_mem_rec = &ps_mem_rec_base[MEM_REC_MB_COEFF_DATA];
3745 {
3746 /* temp var */
3747 WORD32 size = 0, size_of_row;
3748 UWORD8 *pu1_buf = ps_mem_rec->pv_base;
3749
3750 /* size of coeff data of 1 mb */
3751 size += sizeof(tu_sblk_coeff_data_t) * MAX_4x4_SUBBLKS;
3752
3753 /* size of coeff data of 1 row of mb's */
3754 size *= max_mb_cols;
3755
3756 /* align to avoid false sharing */
3757 size = ALIGN64(size);
3758 size_of_row = size;
3759
3760 /* size for one full frame */
3761 size *= max_mb_rows;
3762
3763 ps_codec->u4_size_coeff_data = size_of_row;
3764
3765 for (i = 0; i < MAX_PROCESS_CTXT; i++)
3766 {
3767 if (i < MAX_PROCESS_CTXT / MAX_CTXT_SETS)
3768 {
3769 ps_codec->as_process[i].pv_pic_mb_coeff_data = pu1_buf;
3770 ps_codec->as_process[i].s_entropy.pv_pic_mb_coeff_data =
3771 pu1_buf;
3772 }
3773 else
3774 {
3775 ps_codec->as_process[i].pv_pic_mb_coeff_data = pu1_buf + size;
3776 ps_codec->as_process[i].s_entropy.pv_pic_mb_coeff_data = pu1_buf
3777 + size;
3778 }
3779 }
3780 }
3781
3782 ps_mem_rec = &ps_mem_rec_base[MEM_REC_MB_HEADER_DATA];
3783 {
3784 /* temp var */
3785 WORD32 size, size_of_row;
3786 UWORD8 *pu1_buf = ps_mem_rec->pv_base;
3787
3788 /* size of header data of 1 mb */
3789 size = 40;
3790
3791 /* size for 1 row of mbs */
3792 size = size * max_mb_cols;
3793
3794 /* align to avoid any false sharing across threads */
3795 size = ALIGN64(size);
3796 size_of_row = size;
3797
3798 /* size for one full frame */
3799 size *= max_mb_rows;
3800
3801 ps_codec->u4_size_header_data = size_of_row;
3802
3803 for (i = 0; i < MAX_PROCESS_CTXT; i++)
3804 {
3805 if (i < MAX_PROCESS_CTXT / MAX_CTXT_SETS)
3806 {
3807 ps_codec->as_process[i].pv_pic_mb_header_data = pu1_buf;
3808 ps_codec->as_process[i].s_entropy.pv_pic_mb_header_data =
3809 pu1_buf;
3810 }
3811 else
3812 {
3813 ps_codec->as_process[i].pv_pic_mb_header_data = pu1_buf + size;
3814 ps_codec->as_process[i].s_entropy.pv_pic_mb_header_data =
3815 pu1_buf + size;
3816 }
3817 }
3818 }
3819
3820 ps_mem_rec = &ps_mem_rec_base[MEM_REC_MVBANK];
3821 {
3822 /* size of buf mgr struct */
3823 WORD32 size = ih264_buf_mgr_size();
3824
3825 /* temp var */
3826 UWORD8 *pu1_buf = ps_mem_rec->pv_base;
3827
3828 /* mv buffer mgr */
3829 ps_codec->pv_mv_buf_mgr_base = pu1_buf;
3830
3831 /* mv bank */
3832 ps_codec->pv_mv_bank_buf_base = pu1_buf + size;
3833 ps_codec->i4_total_mv_bank_size = ps_mem_rec->u4_mem_size - size;
3834 }
3835
3836 ps_mem_rec = &ps_mem_rec_base[MEM_REC_MVBITS];
3837 {
3838 /* max srch range x */
3839 UWORD32 u4_srch_range_x = ps_ip->s_ive_ip.u4_max_srch_rng_x;
3840
3841 /* max srch range y */
3842 UWORD32 u4_srch_range_y = ps_ip->s_ive_ip.u4_max_srch_rng_y;
3843
3844 /* max srch range */
3845 UWORD32 u4_max_srch_range = MAX(u4_srch_range_x, u4_srch_range_y);
3846
3847 /* temp var */
3848 UWORD8 *pu1_buf = ps_mem_rec->pv_base;
3849
3850 /* due to subpel */
3851 u4_max_srch_range <<= 2;
3852
3853 // /* due to mv on either direction */
3854 // u4_max_srch_range = (u4_max_srch_range << 1);
3855
3856 /* due to pred mv + zero */
3857 u4_max_srch_range = (u4_max_srch_range << 1) + 1;
3858
3859 for (i = 0; i < MAX_PROCESS_CTXT; i++)
3860 {
3861 /* me ctxt */
3862 me_ctxt_t *ps_mem_ctxt = &(ps_codec->as_process[i].s_me_ctxt);
3863
3864 /* init at zero mv */
3865 ps_mem_ctxt->pu1_mv_bits = pu1_buf + u4_max_srch_range;
3866 }
3867 }
3868
3869 ps_mem_rec = &ps_mem_rec_base[MEM_REC_SPS];
3870 {
3871 ps_codec->ps_sps_base = (sps_t *) ps_mem_rec->pv_base;
3872 }
3873
3874 ps_mem_rec = &ps_mem_rec_base[MEM_REC_PPS];
3875 {
3876 ps_codec->ps_pps_base = (pps_t *) ps_mem_rec->pv_base;
3877 }
3878
3879 ps_mem_rec = &ps_mem_rec_base[MEM_REC_SLICE_HDR];
3880 {
3881 ps_codec->ps_slice_hdr_base = ps_mem_rec->pv_base;
3882
3883 for (i = 0; i < MAX_PROCESS_CTXT; i++)
3884 {
3885 if (i < MAX_PROCESS_CTXT / MAX_CTXT_SETS)
3886 {
3887 ps_codec->as_process[i].ps_slice_hdr_base = ps_mem_rec->pv_base;
3888 }
3889 else
3890 {
3891 /* temp var */
3892 WORD32 size = MAX_SLICE_HDR_CNT * sizeof(slice_header_t);
3893 void *pv_buf = (UWORD8 *) ps_mem_rec->pv_base + size;
3894
3895 ps_codec->as_process[i].ps_slice_hdr_base = pv_buf;
3896 }
3897 }
3898 }
3899
3900 ps_mem_rec = &ps_mem_rec_base[MEM_REC_AIR_MAP];
3901 {
3902 /* temp var */
3903 UWORD8 *pu1_buf = ps_mem_rec->pv_base;
3904
3905 for (i = 0; i < MAX_PROCESS_CTXT; i++)
3906 {
3907 if (i < MAX_PROCESS_CTXT / MAX_CTXT_SETS)
3908 {
3909 ps_codec->as_process[i].pu1_is_intra_coded = pu1_buf;
3910 }
3911 else
3912 {
3913 ps_codec->as_process[i].pu1_is_intra_coded = pu1_buf
3914 + max_mb_cnt;
3915 }
3916 }
3917
3918 ps_codec->pu2_intr_rfrsh_map = (UWORD16 *) (pu1_buf + max_mb_cnt * 2);
3919 }
3920
3921 ps_mem_rec = &ps_mem_rec_base[MEM_REC_SLICE_MAP];
3922 {
3923 /* pointer to storage space */
3924 UWORD8 *pu1_buf_ping, *pu1_buf_pong;
3925
3926 /* init pointer */
3927 pu1_buf_ping = ps_mem_rec->pv_base;
3928 pu1_buf_pong = pu1_buf_ping + ALIGN64(max_mb_cnt);
3929
3930 for (i = 0; i < MAX_PROCESS_CTXT; i++)
3931 {
3932 if (i < MAX_PROCESS_CTXT / MAX_CTXT_SETS)
3933 {
3934 ps_codec->as_process[i].pu1_slice_idx = pu1_buf_ping;
3935 }
3936 else
3937 {
3938 ps_codec->as_process[i].pu1_slice_idx = pu1_buf_pong;
3939 }
3940 }
3941 }
3942
3943 ps_mem_rec = &ps_mem_rec_base[MEM_REC_THREAD_HANDLE];
3944 {
3945 WORD32 handle_size = ithread_get_handle_size();
3946
3947 for (i = 0; i < MAX_PROCESS_THREADS; i++)
3948 {
3949 ps_codec->apv_proc_thread_handle[i] = (UWORD8 *) ps_mem_rec->pv_base
3950 + (i * handle_size);
3951 }
3952 }
3953
3954 ps_mem_rec = &ps_mem_rec_base[MEM_REC_CTL_MUTEX];
3955 {
3956 ps_codec->pv_ctl_mutex = ps_mem_rec->pv_base;
3957 }
3958
3959 ps_mem_rec = &ps_mem_rec_base[MEM_REC_ENTROPY_MUTEX];
3960 {
3961 ps_codec->pv_entropy_mutex = ps_mem_rec->pv_base;
3962 }
3963
3964 ps_mem_rec = &ps_mem_rec_base[MEM_REC_PROC_JOBQ];
3965 {
3966 ps_codec->pv_proc_jobq_buf = ps_mem_rec->pv_base;
3967 ps_codec->i4_proc_jobq_buf_size = ps_mem_rec->u4_mem_size;
3968 }
3969
3970 ps_mem_rec = &ps_mem_rec_base[MEM_REC_ENTROPY_JOBQ];
3971 {
3972 ps_codec->pv_entropy_jobq_buf = ps_mem_rec->pv_base;
3973 ps_codec->i4_entropy_jobq_buf_size = ps_mem_rec->u4_mem_size;
3974 }
3975
3976 ps_mem_rec = &ps_mem_rec_base[MEM_REC_PROC_MAP];
3977 {
3978 /* pointer to storage space */
3979 UWORD8 *pu1_buf = ps_mem_rec->pv_base;
3980
3981 /* total size of the mem record */
3982 WORD32 total_size = 0;
3983
3984 /* size in bytes to mb core coding status of an entire frame */
3985 total_size = max_mb_cnt;
3986
3987 /* add an additional 1 row of bytes to evade the special case of row 0 */
3988 total_size += max_mb_cols;
3989
3990 for (i = 0; i < MAX_PROCESS_CTXT; i++)
3991 {
3992 if (i < MAX_PROCESS_CTXT / MAX_CTXT_SETS)
3993 {
3994 ps_codec->as_process[i].pu1_proc_map = pu1_buf + max_mb_cols;
3995 }
3996 else
3997 {
3998 ps_codec->as_process[i].pu1_proc_map = pu1_buf + total_size
3999 + max_mb_cols;
4000 }
4001 }
4002 }
4003
4004 ps_mem_rec = &ps_mem_rec_base[MEM_REC_DBLK_MAP];
4005 {
4006 /* pointer to storage space */
4007 UWORD8 *pu1_buf = ps_mem_rec->pv_base;
4008
4009 /* total size of the mem record */
4010 WORD32 total_size = 0;
4011
4012 /* size in bytes to mb core coding status of an entire frame */
4013 total_size = max_mb_cnt;
4014
4015 /* add an additional 1 row of bytes to evade the special case of row 0 */
4016 total_size += max_mb_cols;
4017
4018 /*Align the memory offsets*/
4019 total_size = ALIGN64(total_size);
4020
4021 for (i = 0; i < MAX_PROCESS_CTXT; i++)
4022 {
4023 if (i < MAX_PROCESS_CTXT / MAX_CTXT_SETS)
4024 {
4025 ps_codec->as_process[i].pu1_deblk_map = pu1_buf + max_mb_cols;
4026
4027 }
4028 else
4029 {
4030 ps_codec->as_process[i].pu1_deblk_map = pu1_buf + total_size
4031 + max_mb_cols;
4032
4033 }
4034 }
4035 }
4036
4037 ps_mem_rec = &ps_mem_rec_base[MEM_REC_ME_MAP];
4038 {
4039 /* pointer to storage space */
4040 UWORD8 *pu1_buf = (UWORD8 *) ps_mem_rec->pv_base;
4041
4042 /* total size of the mem record */
4043 WORD32 total_size = 0;
4044
4045 /* size in bytes to mb core coding status of an entire frame */
4046 total_size = max_mb_cnt;
4047
4048 /* add an additional 1 row of bytes to evade the special case of row 0 */
4049 total_size += max_mb_cols;
4050
4051 for (i = 0; i < MAX_PROCESS_CTXT; i++)
4052 {
4053 if (i < MAX_PROCESS_CTXT / MAX_CTXT_SETS)
4054 {
4055 ps_codec->as_process[i].pu1_me_map = pu1_buf + max_mb_cols;
4056 }
4057 else
4058 {
4059 ps_codec->as_process[i].pu1_me_map = pu1_buf + total_size
4060 + max_mb_cols;
4061 }
4062 }
4063 }
4064
4065 ps_mem_rec = &ps_mem_rec_base[MEM_REC_DPB_MGR];
4066 {
4067 ps_codec->pv_dpb_mgr = ps_mem_rec->pv_base;
4068 }
4069
4070 ps_mem_rec = &ps_mem_rec_base[MEM_REC_PROC_SCRATCH];
4071 {
4072 /* pointer to storage space */
4073 UWORD8 *pu1_buf = (UWORD8 *) ps_mem_rec->pv_base;
4074
4075 /* size of pred buffer, fwd transform output, temp buffer for inv tra */
4076 WORD32 size_pred_luma, size_pred_chroma, size_fwd, size_inv, size_hp;
4077
4078 /* temp var */
4079 WORD32 size = 0;
4080
4081 /* size to hold intra/inter prediction buffer */
4082 size_pred_luma = sizeof(UWORD8) * 16 * 16;
4083 size_pred_chroma = sizeof(UWORD8) * 8 * 16;
4084
4085 /* size to hold fwd transform output */
4086 size_fwd = sizeof(WORD16) * SIZE_TRANS_BUFF;
4087
4088 /* size to hold temporary data during inverse transform */
4089 size_inv = sizeof(WORD32) * SIZE_TMP_BUFF_ITRANS;
4090
4091 /* size to hold half pel plane buffers */
4092 size_hp = sizeof(UWORD8) * (HP_BUFF_WD * HP_BUFF_HT);
4093
4094 for (i = 0; i < MAX_PROCESS_CTXT; i++)
4095 {
4096 /* prediction buffer */
4097 ps_codec->as_process[i].pu1_pred_mb = (void *) (pu1_buf + size);
4098 ps_codec->as_process[i].i4_pred_strd = 16;
4099 size += size_pred_luma;
4100 size = ALIGN64(size);
4101
4102 /* prediction buffer */
4103 ps_codec->as_process[i].pu1_ref_mb_intra_4x4 = (void *) (pu1_buf
4104 + size);
4105 size += size_pred_luma;
4106 size = ALIGN64(size);
4107
4108 /* prediction buffer intra 16x16 */
4109 ps_codec->as_process[i].pu1_pred_mb_intra_16x16 = (void *) (pu1_buf
4110 + size);
4111 size += size_pred_luma;
4112 size = ALIGN64(size);
4113
4114 /* prediction buffer intra 16x16 plane*/
4115 ps_codec->as_process[i].pu1_pred_mb_intra_16x16_plane =
4116 (void *) (pu1_buf + size);
4117 size += size_pred_luma;
4118 size = ALIGN64(size);
4119
4120 /* prediction buffer intra chroma*/
4121 ps_codec->as_process[i].pu1_pred_mb_intra_chroma = (void *) (pu1_buf
4122 + size);
4123 size += size_pred_chroma;
4124 size = ALIGN64(size);
4125
4126 /* prediction buffer intra chroma plane*/
4127 ps_codec->as_process[i].pu1_pred_mb_intra_chroma_plane =
4128 (void *) (pu1_buf + size);
4129 size += size_pred_chroma;
4130 size = ALIGN64(size);
4131
4132 /* Fwd transform output */
4133 ps_codec->as_process[i].pi2_res_buf = (void *) (pu1_buf + size);
4134 ps_codec->as_process[i].i4_res_strd = 16;
4135 size += size_fwd;
4136 size = ALIGN64(size);
4137
4138 /* Fwd transform output */
4139 ps_codec->as_process[i].pi2_res_buf_intra_4x4 = (void *) (pu1_buf
4140 + size);
4141 size += size_fwd;
4142 size = ALIGN64(size);
4143
4144 /* scratch buffer used during inverse transform */
4145 ps_codec->as_process[i].pv_scratch_buff = (void *) (pu1_buf + size);
4146 size += size_inv;
4147 size = ALIGN64(size);
4148
4149 for (j = 0; j < SUBPEL_BUFF_CNT; j++)
4150 {
4151 ps_codec->as_process[i].apu1_subpel_buffs[j] = (pu1_buf + size);
4152 size += ALIGN64(size_hp);
4153 }
4154 }
4155 }
4156
4157 ps_mem_rec = &ps_mem_rec_base[MEM_REC_QUANT_PARAM];
4158 {
4159 /* pointer to storage space */
4160 UWORD8 *pu1_buf = (UWORD8 *) ps_mem_rec->pv_base;
4161
4162 /* size of qp, threshold matrix, fwd scaling list for one plane */
4163 WORD32 size_quant_param, size_thres_mat, size_fwd_weight_mat,
4164 size_satqd_weight_mat;
4165
4166 /* temp var */
4167 WORD32 total_size = 0;
4168
4169 /* size of quantization parameter list of 1 plane */
4170 size_quant_param = ALIGN64(sizeof(quant_params_t));
4171
4172 /* size of threshold matrix for quantization
4173 * (assuming the transform_8x8_flag is disabled).
4174 * for 1 plane */
4175 size_thres_mat = ALIGN64(sizeof(WORD16) * 4 * 4);
4176
4177 /* size of forward weight matrix for quantization
4178 * (assuming the transform_8x8_flag is disabled).
4179 * for 1 plane */
4180 size_fwd_weight_mat = ALIGN64(sizeof(WORD16) * 4 * 4);
4181
4182 /* size of SATQD matrix*/
4183 size_satqd_weight_mat = ALIGN64(sizeof(UWORD16) * 9);
4184
4185 for (i = 0; i < MAX_PROCESS_CTXT; i++)
4186 {
4187 quant_params_t **ps_qp_params = ps_codec->as_process[i].ps_qp_params;
4188
4189 /* quantization param structure */
4190 ps_qp_params[0] = (quant_params_t *) (pu1_buf + total_size);
4191 total_size = total_size + size_quant_param;
4192 ps_qp_params[1] = (quant_params_t *) (pu1_buf + total_size);
4193 total_size = total_size + size_quant_param;
4194 ps_qp_params[2] = (quant_params_t *) (pu1_buf + total_size);
4195 total_size = total_size + size_quant_param;
4196
4197 /* threshold matrix for quantization */
4198 ps_qp_params[0]->pu2_thres_mat = (void *) (pu1_buf + total_size);
4199 total_size = total_size + size_thres_mat;
4200 ps_qp_params[1]->pu2_thres_mat = (void *) (pu1_buf + total_size);
4201 total_size = total_size + size_thres_mat;
4202 ps_qp_params[2]->pu2_thres_mat = (void *) (pu1_buf + total_size);
4203 total_size = total_size + size_thres_mat;
4204
4205 /* fwd weight matrix */
4206 ps_qp_params[0]->pu2_weigh_mat = (void *) (pu1_buf + total_size);
4207 total_size = total_size + size_fwd_weight_mat;
4208 ps_qp_params[1]->pu2_weigh_mat = (void *) (pu1_buf + total_size);
4209 total_size = total_size + size_fwd_weight_mat;
4210 ps_qp_params[2]->pu2_weigh_mat = (void *) (pu1_buf + total_size);
4211 total_size = total_size + size_fwd_weight_mat;
4212
4213 /* threshold matrix for SATQD */
4214 ps_qp_params[0]->pu2_sad_thrsh = (void *) (pu1_buf + total_size);
4215 total_size = total_size + size_satqd_weight_mat;
4216 ps_qp_params[1]->pu2_sad_thrsh = (void *) (pu1_buf + total_size);
4217 total_size = total_size + size_satqd_weight_mat;
4218 ps_qp_params[2]->pu2_sad_thrsh = (void *) (pu1_buf + total_size);
4219 total_size = total_size + size_satqd_weight_mat;
4220
4221 total_size = ALIGN128(total_size);
4222 }
4223 }
4224
4225 ps_mem_rec = &ps_mem_rec_base[MEM_REC_TOP_ROW_SYN_INFO];
4226 {
4227 /* total size of the mem record */
4228 WORD32 total_size = 0, size_csbp, size_intra_modes, size_mv;
4229
4230 /* pointer to buffer */
4231 UWORD8 *pu1_buf = ps_mem_rec->pv_base;
4232
4233 /* size in bytes to store 1 row of mb_info_t */
4234 /* one additional mb, to avoid checking end of row condition */
4235 size_csbp = (max_mb_cols + 1) * sizeof(mb_info_t);
4236
4237 /* size in bytes to store 1 row of intra macroblock sub modes */
4238 size_intra_modes = max_mb_cols * sizeof(UWORD8) * 16;
4239
4240 /* size in bytes to store 1 row + 1 of enc_pu_t */
4241 /* one additional mb, to avoid checking end of row condition */
4242 size_mv = (max_mb_cols + 1) * sizeof(enc_pu_t);
4243
4244 /* total size per proc ctxt */
4245 total_size = size_csbp + size_intra_modes + size_mv;
4246
4247 for (i = 0; i < MAX_PROCESS_CTXT; i++)
4248 {
4249 if (i < MAX_PROCESS_CTXT / MAX_CTXT_SETS)
4250 {
4251 ps_codec->as_process[i].ps_top_row_mb_syntax_ele_base =
4252 (mb_info_t *) pu1_buf;
4253 ps_codec->as_process[i].pu1_top_mb_intra_modes_base = pu1_buf
4254 + size_csbp;
4255 ps_codec->as_process[i].ps_top_row_pu_base =
4256 (enc_pu_t *) (pu1_buf + size_csbp
4257 + size_intra_modes);
4258 }
4259 else
4260 {
4261 ps_codec->as_process[i].ps_top_row_mb_syntax_ele_base =
4262 (mb_info_t *) (pu1_buf + total_size);
4263 ps_codec->as_process[i].pu1_top_mb_intra_modes_base = pu1_buf
4264 + total_size + size_csbp;
4265 ps_codec->as_process[i].ps_top_row_pu_base =
4266 (enc_pu_t *) (pu1_buf + total_size + size_csbp
4267 + size_intra_modes);
4268 }
4269 }
4270 }
4271
4272 ps_mem_rec = &ps_mem_rec_base[MEM_REC_BS_QP];
4273 {
4274 UWORD8 *pu1_buf_ping, *pu1_buf_pong;
4275
4276 /* total size of the mem record */
4277 WORD32 total_size = 0;
4278
4279 /* size in bytes to store vertical edge bs, horizontal edge bs and qp of every mb*/
4280 WORD32 vert_bs_size, horz_bs_size, qp_size;
4281
4282 /* vertical edge bs = total number of vertical edges * number of bytes per each edge */
4283 /* total num of v edges = total mb * 4 (assuming transform_8x8_flag = 0),
4284 * each edge is formed by 4 pairs of subblks, requiring 4 bytes to storing bs */
4285 vert_bs_size = ALIGN64(max_mb_cnt * 4 * 4);
4286
4287 /* horizontal edge bs = total number of horizontal edges * number of bytes per each edge */
4288 /* total num of h edges = total mb * 4 (assuming transform_8x8_flag = 0),
4289 * each edge is formed by 4 pairs of subblks, requiring 4 bytes to storing bs */
4290 horz_bs_size = ALIGN64(max_mb_cnt * 4 * 4);
4291
4292 /* qp of each mb requires 1 byte */
4293 qp_size = ALIGN64(max_mb_cnt);
4294
4295 /* total size */
4296 total_size = vert_bs_size + horz_bs_size + qp_size;
4297
4298 for (i = 0; i < MAX_PROCESS_CTXT; i++)
4299 {
4300 if (i < MAX_PROCESS_CTXT / MAX_CTXT_SETS)
4301 {
4302 pu1_buf_ping = (UWORD8 *) ps_mem_rec->pv_base;
4303
4304 /* vertical edge bs storage space */
4305 ps_codec->as_process[i].s_deblk_ctxt.s_bs_ctxt.pu4_pic_vert_bs =
4306 (UWORD32 *) pu1_buf_ping;
4307 pu1_buf_ping += vert_bs_size;
4308
4309 /* horizontal edge bs storage space */
4310 ps_codec->as_process[i].s_deblk_ctxt.s_bs_ctxt.pu4_pic_horz_bs =
4311 (UWORD32 *) pu1_buf_ping;
4312 pu1_buf_ping += horz_bs_size;
4313
4314 /* qp */
4315 ps_codec->as_process[i].s_deblk_ctxt.s_bs_ctxt.pu1_pic_qp =
4316 (UWORD8 *) pu1_buf_ping;
4317 pu1_buf_ping += qp_size;
4318 }
4319 else
4320 {
4321 pu1_buf_pong = (UWORD8 *) ps_mem_rec->pv_base;
4322 pu1_buf_pong += total_size;
4323
4324 /* vertical edge bs storage space */
4325 ps_codec->as_process[i].s_deblk_ctxt.s_bs_ctxt.pu4_pic_vert_bs =
4326 (UWORD32 *) pu1_buf_pong;
4327 pu1_buf_pong += vert_bs_size;
4328
4329 /* horizontal edge bs storage space */
4330 ps_codec->as_process[i].s_deblk_ctxt.s_bs_ctxt.pu4_pic_horz_bs =
4331 (UWORD32 *) pu1_buf_pong;
4332 pu1_buf_pong += horz_bs_size;
4333
4334 /* qp */
4335 ps_codec->as_process[i].s_deblk_ctxt.s_bs_ctxt.pu1_pic_qp =
4336 (UWORD8 *) pu1_buf_pong;
4337 pu1_buf_pong += qp_size;
4338 }
4339 }
4340 }
4341
4342 ps_mem_rec = &ps_mem_rec_base[MEM_REC_INP_PIC];
4343 {
4344 ps_codec->pv_inp_buf_mgr_base = ps_mem_rec->pv_base;
4345 }
4346
4347 ps_mem_rec = &ps_mem_rec_base[MEM_REC_OUT];
4348 {
4349 ps_codec->pv_out_buf_mgr_base = ps_mem_rec->pv_base;
4350 }
4351
4352 ps_mem_rec = &ps_mem_rec_base[MEM_REC_CSC];
4353 {
4354 ps_codec->pu1_y_csc_buf_base = ps_mem_rec->pv_base;
4355 ps_codec->pu1_uv_csc_buf_base = (UWORD8 *) ps_mem_rec->pv_base
4356 + (max_ht_luma * max_wd_luma);
4357 }
4358
4359 ps_mem_rec = &ps_mem_rec_base[MEM_REC_REF_PIC];
4360 {
4361 /* size of buf mgr struct */
4362 WORD32 size = ih264_buf_mgr_size();
4363
4364 /* temp var */
4365 UWORD8 *pu1_buf = ps_mem_rec->pv_base;
4366
4367 /* pic buffer mgr */
4368 ps_codec->pv_ref_buf_mgr_base = pu1_buf;
4369
4370 /* picture bank */
4371 ps_codec->pv_pic_buf_base = pu1_buf + size;
4372 ps_codec->i4_total_pic_buf_size = ps_mem_rec->u4_mem_size - size;
4373 }
4374
4375 ps_mem_rec = &ps_mem_rec_base[MEM_REC_MB_INFO_NMB];
4376 {
4377 /* temp var */
4378 UWORD8 *pu1_buf = ps_mem_rec->pv_base;
4379
4380 /* size of nmb ctxt */
4381 WORD32 size = max_mb_cols * sizeof(mb_info_nmb_t);
4382
4383 WORD32 nmb_cntr, subpel_buf_size;
4384
4385 /* init nmb info structure pointer in all proc ctxts */
4386 for (i = 0; i < MAX_PROCESS_CTXT; i++)
4387 {
4388 ps_codec->as_process[i].ps_nmb_info = (mb_info_nmb_t *) (pu1_buf);
4389
4390 pu1_buf += size;
4391 }
4392
4393 subpel_buf_size = MB_SIZE * MB_SIZE * sizeof(UWORD8);
4394
4395 /* adjusting pointers for nmb halfpel buffer */
4396 for (i = 0; i < MAX_PROCESS_CTXT; i++)
4397 {
4398 mb_info_nmb_t* ps_mb_info_nmb =
4399 &ps_codec->as_process[i].ps_nmb_info[0];
4400
4401 for (nmb_cntr = 0; nmb_cntr < max_mb_cols; nmb_cntr++)
4402 {
4403 ps_mb_info_nmb[nmb_cntr].pu1_best_sub_pel_buf = pu1_buf;
4404
4405 pu1_buf = pu1_buf + subpel_buf_size;
4406
4407 ps_mb_info_nmb[nmb_cntr].u4_bst_spel_buf_strd = MB_SIZE;
4408 }
4409 }
4410 }
4411
4412 ps_mem_rec = &ps_mem_rec_base[MEM_REC_RC];
4413 {
4414 ih264e_get_rate_control_mem_tab(&ps_codec->s_rate_control, ps_mem_rec,
4415 USE_BASE);
4416 }
4417
4418 /* init codec ctxt */
4419 status = ih264e_init(ps_codec);
4420
4421 return status;
4422 }
4423
4424 /**
4425 *******************************************************************************
4426 *
4427 * @brief
4428 * Retrieves mem records passed to the codec
4429 *
4430 * @par Description:
4431 * Retrieves mem recs passed during init
4432 *
4433 * @param[in] ps_codec_obj
4434 * Pointer to codec object at API level
4435 *
4436 * @param[in] pv_api_ip
4437 * Pointer to input argument structure
4438 *
4439 * @param[out] pv_api_op
4440 * Pointer to output argument structure
4441 *
4442 * @returns error status
4443 *
4444 * @remarks none
4445 *
4446 *******************************************************************************
4447 */
ih264e_retrieve_memrec(iv_obj_t * ps_codec_obj,void * pv_api_ip,void * pv_api_op)4448 static WORD32 ih264e_retrieve_memrec(iv_obj_t *ps_codec_obj,
4449 void *pv_api_ip,
4450 void *pv_api_op)
4451 {
4452 /* codec ctxt */
4453 codec_t *ps_codec = (codec_t *) ps_codec_obj->pv_codec_handle;
4454
4455 /* ctrl call I/O structures */
4456 ih264e_retrieve_mem_rec_ip_t *ps_ip = pv_api_ip;
4457 ih264e_retrieve_mem_rec_op_t *ps_op = pv_api_op;
4458
4459 if (ps_codec->i4_init_done != 1)
4460 {
4461 ps_op->s_ive_op.u4_error_code |= 1 << IVE_FATALERROR;
4462 ps_op->s_ive_op.u4_error_code |= IH264E_INIT_NOT_DONE;
4463 return IV_FAIL;
4464 }
4465
4466 /* join threads upon at end of sequence */
4467 ih264e_join_threads(ps_codec);
4468
4469 /* collect list of memory records used by the encoder library */
4470 memcpy(ps_ip->s_ive_ip.ps_mem_rec, ps_codec->ps_mem_rec_backup,
4471 MEM_REC_CNT * (sizeof(iv_mem_rec_t)));
4472 ps_op->s_ive_op.u4_num_mem_rec_filled = MEM_REC_CNT;
4473
4474 /* clean up mutex memory */
4475 ih264_list_free(ps_codec->pv_entropy_jobq);
4476 ih264_list_free(ps_codec->pv_proc_jobq);
4477 ithread_mutex_destroy(ps_codec->pv_ctl_mutex);
4478 ithread_mutex_destroy(ps_codec->pv_entropy_mutex);
4479
4480
4481 ih264_buf_mgr_free((buf_mgr_t *)ps_codec->pv_mv_buf_mgr);
4482 ih264_buf_mgr_free((buf_mgr_t *)ps_codec->pv_ref_buf_mgr);
4483 ih264_buf_mgr_free((buf_mgr_t *)ps_codec->pv_inp_buf_mgr);
4484 ih264_buf_mgr_free((buf_mgr_t *)ps_codec->pv_out_buf_mgr);
4485
4486 return IV_SUCCESS;
4487 }
4488
4489 /**
4490 *******************************************************************************
4491 *
4492 * @brief
4493 * Sets the encoder in flush mode.
4494 *
4495 * @par Description:
4496 * Sets the encoder in flush mode
4497 *
4498 * @param[in] ps_codec_obj
4499 * Pointer to codec object at API level
4500 *
4501 * @param[in] pv_api_ip
4502 * Pointer to input argument structure
4503 *
4504 * @param[out] pv_api_op
4505 * Pointer to output argument structure
4506 *
4507 * @returns error status
4508 *
4509 * @remarks This call has no real effect on encoder
4510 *
4511 *******************************************************************************
4512 */
ih264e_set_flush_mode(iv_obj_t * ps_codec_obj,void * pv_api_ip,void * pv_api_op)4513 static WORD32 ih264e_set_flush_mode(iv_obj_t *ps_codec_obj,
4514 void *pv_api_ip,
4515 void *pv_api_op)
4516 {
4517 /* codec ctxt */
4518 codec_t *ps_codec = (codec_t *) ps_codec_obj->pv_codec_handle;
4519
4520 /* ctrl call I/O structures */
4521 ih264e_ctl_flush_op_t *ps_ctl_op = pv_api_op;
4522
4523 UNUSED(pv_api_ip);
4524
4525 ps_ctl_op->s_ive_op.u4_error_code = 0;
4526
4527 /* signal flush frame control call */
4528 ps_codec->i4_flush_mode = 1;
4529
4530 return IV_SUCCESS;
4531 }
4532
4533 /**
4534 *******************************************************************************
4535 *
4536 * @brief
4537 * Gets encoder buffer requirements
4538 *
4539 * @par Description:
4540 * Gets the encoder buffer requirements. Basing on max width and max height
4541 * configuration settings, this routine, computes the sizes of necessary input,
4542 * output buffers returns this info to callee.
4543 *
4544 * @param[in] ps_codec_obj
4545 * Pointer to codec object at API level
4546 *
4547 * @param[in] pv_api_ip
4548 * Pointer to input argument structure
4549 *
4550 * @param[out] pv_api_op
4551 * Pointer to output argument structure
4552 *
4553 * @returns error status
4554 *
4555 * @remarks none
4556 *
4557 *******************************************************************************
4558 */
ih264e_get_buf_info(iv_obj_t * ps_codec_obj,void * pv_api_ip,void * pv_api_op)4559 static WORD32 ih264e_get_buf_info(iv_obj_t *ps_codec_obj,
4560 void *pv_api_ip,
4561 void *pv_api_op)
4562 {
4563 /* ctrl call I/O structures */
4564 ih264e_ctl_getbufinfo_ip_t *ps_ip = pv_api_ip;
4565 ih264e_ctl_getbufinfo_op_t *ps_op = pv_api_op;
4566
4567 /* temp var */
4568 WORD32 wd = ALIGN16(ps_ip->s_ive_ip.u4_max_wd);
4569 WORD32 ht = ALIGN16(ps_ip->s_ive_ip.u4_max_ht);
4570 WORD32 i;
4571
4572 UNUSED(ps_codec_obj);
4573
4574 ps_op->s_ive_op.u4_error_code = 0;
4575
4576 /* Number of components in input buffers required for codec &
4577 * Minimum sizes of each component in input buffer required */
4578 if (ps_ip->s_ive_ip.e_inp_color_fmt == IV_YUV_420P)
4579 {
4580 ps_op->s_ive_op.u4_inp_comp_cnt = MIN_RAW_BUFS_420_COMP;
4581
4582 ps_op->s_ive_op.au4_min_in_buf_size[0] = wd * ht;
4583 ps_op->s_ive_op.au4_min_in_buf_size[1] = (wd >> 1) * (ht >> 1);
4584 ps_op->s_ive_op.au4_min_in_buf_size[2] = (wd >> 1) * (ht >> 1);
4585 }
4586 else if (ps_ip->s_ive_ip.e_inp_color_fmt == IV_YUV_422ILE)
4587 {
4588 ps_op->s_ive_op.u4_inp_comp_cnt = MIN_RAW_BUFS_422ILE_COMP;
4589
4590 ps_op->s_ive_op.au4_min_in_buf_size[0] = wd * ht * 2;
4591 ps_op->s_ive_op.au4_min_in_buf_size[1] =
4592 ps_op->s_ive_op.au4_min_in_buf_size[2] = 0;
4593 }
4594 else if (ps_ip->s_ive_ip.e_inp_color_fmt == IV_RGB_565)
4595 {
4596 ps_op->s_ive_op.u4_inp_comp_cnt = MIN_RAW_BUFS_RGB565_COMP;
4597
4598 ps_op->s_ive_op.au4_min_in_buf_size[0] = wd * ht * 2;
4599 ps_op->s_ive_op.au4_min_in_buf_size[1] =
4600 ps_op->s_ive_op.au4_min_in_buf_size[2] = 0;
4601 }
4602 else if (ps_ip->s_ive_ip.e_inp_color_fmt == IV_RGBA_8888)
4603 {
4604 ps_op->s_ive_op.u4_inp_comp_cnt = MIN_RAW_BUFS_RGBA8888_COMP;
4605
4606 ps_op->s_ive_op.au4_min_in_buf_size[0] = wd * ht * 4;
4607 ps_op->s_ive_op.au4_min_in_buf_size[1] =
4608 ps_op->s_ive_op.au4_min_in_buf_size[2] = 0;
4609 }
4610 else if ((ps_ip->s_ive_ip.e_inp_color_fmt == IV_YUV_420SP_UV)
4611 || (ps_ip->s_ive_ip.e_inp_color_fmt == IV_YUV_420SP_VU))
4612 {
4613 ps_op->s_ive_op.u4_inp_comp_cnt = MIN_RAW_BUFS_420SP_COMP;
4614
4615 ps_op->s_ive_op.au4_min_in_buf_size[0] = wd * ht;
4616 ps_op->s_ive_op.au4_min_in_buf_size[1] = wd * (ht >> 1);
4617 ps_op->s_ive_op.au4_min_in_buf_size[2] = 0;
4618 }
4619
4620 /* Number of components in output buffers required for codec &
4621 * Minimum sizes of each component in output buffer required */
4622 ps_op->s_ive_op.u4_out_comp_cnt = MIN_BITS_BUFS_COMP;
4623
4624 for (i = 0; i < (WORD32) ps_op->s_ive_op.u4_out_comp_cnt; i++)
4625 {
4626 ps_op->s_ive_op.au4_min_out_buf_size[i] = MAX(((wd * ht * 3) >> 1), MIN_STREAM_SIZE);
4627 }
4628
4629 ps_op->s_ive_op.u4_min_inp_bufs = MIN_INP_BUFS;
4630 ps_op->s_ive_op.u4_min_out_bufs = MIN_OUT_BUFS;
4631
4632 return IV_SUCCESS;
4633 }
4634
4635 /**
4636 *******************************************************************************
4637 *
4638 * @brief
4639 * Sets the picture dimensions
4640 *
4641 * @par Description:
4642 * Sets width, height, display width, display height and strides
4643 *
4644 * @param[in] pv_api_ip
4645 * Pointer to input argument structure
4646 *
4647 * @param[out] pv_api_op
4648 * Pointer to output argument structure
4649 *
4650 * @param[out] ps_cfg
4651 * Pointer to config structure to be updated
4652 *
4653 * @returns error status
4654 *
4655 * @remarks none
4656 *
4657 *******************************************************************************
4658 */
ih264e_set_dimensions(void * pv_api_ip,void * pv_api_op,cfg_params_t * ps_cfg)4659 static IV_STATUS_T ih264e_set_dimensions(void *pv_api_ip,
4660 void *pv_api_op,
4661 cfg_params_t *ps_cfg)
4662 {
4663 /* ctrl call I/O structures */
4664 ih264e_ctl_set_dimensions_ip_t *ps_ip = pv_api_ip;
4665 ih264e_ctl_set_dimensions_op_t *ps_op = pv_api_op;
4666
4667 ps_op->s_ive_op.u4_error_code = 0;
4668
4669 ps_cfg->u4_wd = ALIGN16(ps_ip->s_ive_ip.u4_wd);
4670 ps_cfg->u4_ht = ALIGN16(ps_ip->s_ive_ip.u4_ht);
4671 ps_cfg->i4_wd_mbs = ps_cfg->u4_wd >> 4;
4672 ps_cfg->i4_ht_mbs = ps_cfg->u4_ht >> 4;
4673 ps_cfg->u4_disp_wd = ps_ip->s_ive_ip.u4_wd;
4674 ps_cfg->u4_disp_ht = ps_ip->s_ive_ip.u4_ht;
4675
4676 ps_cfg->u4_timestamp_high = ps_ip->s_ive_ip.u4_timestamp_high;
4677 ps_cfg->u4_timestamp_low = ps_ip->s_ive_ip.u4_timestamp_low;
4678
4679 return IV_SUCCESS;
4680 }
4681
4682 /**
4683 *******************************************************************************
4684 *
4685 * @brief
4686 * Sets source and target frame rates
4687 *
4688 * @par Description:
4689 * Sets source and target frame rates
4690 *
4691 * @param[in] pv_api_ip
4692 * Pointer to input argument structure
4693 *
4694 * @param[out] pv_api_op
4695 * Pointer to output argument structure
4696 *
4697 * @param[out] ps_cfg
4698 * Pointer to config structure to be updated
4699 *
4700 * @returns error status
4701 *
4702 * @remarks none
4703 *
4704 *******************************************************************************
4705 */
ih264e_set_frame_rate(void * pv_api_ip,void * pv_api_op,cfg_params_t * ps_cfg)4706 static IV_STATUS_T ih264e_set_frame_rate(void *pv_api_ip,
4707 void *pv_api_op,
4708 cfg_params_t *ps_cfg)
4709 {
4710 /* ctrl call I/O structures */
4711 ih264e_ctl_set_frame_rate_ip_t *ps_ip = pv_api_ip;
4712 ih264e_ctl_set_frame_rate_op_t *ps_op = pv_api_op;
4713
4714 ps_op->s_ive_op.u4_error_code = 0;
4715
4716 ps_cfg->u4_src_frame_rate = ps_ip->s_ive_ip.u4_src_frame_rate;
4717 ps_cfg->u4_tgt_frame_rate = ps_ip->s_ive_ip.u4_tgt_frame_rate;
4718
4719 ps_cfg->u4_timestamp_high = ps_ip->s_ive_ip.u4_timestamp_high;
4720 ps_cfg->u4_timestamp_low = ps_ip->s_ive_ip.u4_timestamp_low;
4721
4722 return IV_SUCCESS;
4723 }
4724
4725 /**
4726 *******************************************************************************
4727 *
4728 * @brief
4729 * Sets target bit rate
4730 *
4731 * @par Description:
4732 * Sets target bit rate
4733 *
4734 * @param[in] pv_api_ip
4735 * Pointer to input argument structure
4736 *
4737 * @param[out] pv_api_op
4738 * Pointer to output argument structure
4739 *
4740 * @param[out] ps_cfg
4741 * Pointer to config structure to be updated
4742 *
4743 * @returns error status
4744 *
4745 * @remarks none
4746 *
4747 *******************************************************************************
4748 */
ih264e_set_bit_rate(void * pv_api_ip,void * pv_api_op,cfg_params_t * ps_cfg)4749 static IV_STATUS_T ih264e_set_bit_rate(void *pv_api_ip,
4750 void *pv_api_op,
4751 cfg_params_t *ps_cfg)
4752 {
4753 /* ctrl call I/O structures */
4754 ih264e_ctl_set_bitrate_ip_t *ps_ip = pv_api_ip;
4755 ih264e_ctl_set_bitrate_op_t *ps_op = pv_api_op;
4756
4757 ps_op->s_ive_op.u4_error_code = 0;
4758
4759 ps_cfg->u4_target_bitrate = ps_ip->s_ive_ip.u4_target_bitrate;
4760
4761 ps_cfg->u4_timestamp_high = ps_ip->s_ive_ip.u4_timestamp_high;
4762 ps_cfg->u4_timestamp_low = ps_ip->s_ive_ip.u4_timestamp_low;
4763
4764 return IV_SUCCESS;
4765 }
4766
4767 /**
4768 *******************************************************************************
4769 *
4770 * @brief
4771 * Sets frame type
4772 *
4773 * @par Description:
4774 * Sets frame type
4775 *
4776 * @param[in] pv_api_ip
4777 * Pointer to input argument structure
4778 *
4779 * @param[out] pv_api_op
4780 * Pointer to output argument structure
4781 *
4782 * @param[out] ps_cfg
4783 * Pointer to config structure to be updated
4784 *
4785 * @returns error status
4786 *
4787 * @remarks not a sticky tag
4788 *
4789 *******************************************************************************
4790 */
ih264e_set_frame_type(void * pv_api_ip,void * pv_api_op,cfg_params_t * ps_cfg)4791 static IV_STATUS_T ih264e_set_frame_type(void *pv_api_ip,
4792 void *pv_api_op,
4793 cfg_params_t *ps_cfg)
4794 {
4795 /* ctrl call I/O structures */
4796 ih264e_ctl_set_frame_type_ip_t *ps_ip = pv_api_ip;
4797 ih264e_ctl_set_frame_type_op_t *ps_op = pv_api_op;
4798
4799 ps_op->s_ive_op.u4_error_code = 0;
4800
4801 ps_cfg->e_frame_type = ps_ip->s_ive_ip.e_frame_type;
4802
4803 ps_cfg->u4_timestamp_high = ps_ip->s_ive_ip.u4_timestamp_high;
4804 ps_cfg->u4_timestamp_low = ps_ip->s_ive_ip.u4_timestamp_low;
4805
4806 return IV_SUCCESS;
4807 }
4808
4809 /**
4810 *******************************************************************************
4811 *
4812 * @brief
4813 * Sets quantization params
4814 *
4815 * @par Description:
4816 * Sets the max, min and default qp for I frame, P frame and B frame
4817 *
4818 * @param[in] pv_api_ip
4819 * Pointer to input argument structure
4820 *
4821 * @param[out] pv_api_op
4822 * Pointer to output argument structure
4823 *
4824 * @param[out] ps_cfg
4825 * Pointer to config structure to be updated
4826 *
4827 * @returns error status
4828 *
4829 * @remarks none
4830 *
4831 *******************************************************************************
4832 */
ih264e_set_qp(void * pv_api_ip,void * pv_api_op,cfg_params_t * ps_cfg)4833 static IV_STATUS_T ih264e_set_qp(void *pv_api_ip,
4834 void *pv_api_op,
4835 cfg_params_t *ps_cfg)
4836 {
4837 /* ctrl call I/O structures */
4838 ih264e_ctl_set_qp_ip_t *ps_set_qp_ip = pv_api_ip;
4839 ih264e_ctl_set_qp_op_t *ps_set_qp_op = pv_api_op;
4840
4841 ps_set_qp_op->s_ive_op.u4_error_code = 0;
4842
4843 ps_cfg->u4_i_qp_max = ps_set_qp_ip->s_ive_ip.u4_i_qp_max;
4844 ps_cfg->u4_i_qp_min = ps_set_qp_ip->s_ive_ip.u4_i_qp_min;
4845 ps_cfg->u4_i_qp = ps_set_qp_ip->s_ive_ip.u4_i_qp;
4846 ps_cfg->u4_p_qp_max = ps_set_qp_ip->s_ive_ip.u4_p_qp_max;
4847 ps_cfg->u4_p_qp_min = ps_set_qp_ip->s_ive_ip.u4_p_qp_min;
4848 ps_cfg->u4_p_qp = ps_set_qp_ip->s_ive_ip.u4_p_qp;
4849 ps_cfg->u4_b_qp_max = ps_set_qp_ip->s_ive_ip.u4_b_qp_max;
4850 ps_cfg->u4_b_qp_min = ps_set_qp_ip->s_ive_ip.u4_b_qp_min;
4851 ps_cfg->u4_b_qp = ps_set_qp_ip->s_ive_ip.u4_b_qp;
4852
4853 ps_cfg->u4_timestamp_high = ps_set_qp_ip->s_ive_ip.u4_timestamp_high;
4854 ps_cfg->u4_timestamp_low = ps_set_qp_ip->s_ive_ip.u4_timestamp_low;
4855
4856 return IV_SUCCESS;
4857 }
4858
4859 /**
4860 *******************************************************************************
4861 *
4862 * @brief
4863 * Sets encoding mode
4864 *
4865 * @par Description:
4866 * Sets encoding mode
4867 *
4868 * @param[in] pv_api_ip
4869 * Pointer to input argument structure
4870 *
4871 * @param[out] pv_api_op
4872 * Pointer to output argument structure
4873 *
4874 * @param[out] ps_cfg
4875 * Pointer to config structure to be updated
4876 *
4877 * @returns error status
4878 *
4879 * @remarks none
4880 *
4881 *******************************************************************************
4882 */
ih264e_set_enc_mode(void * pv_api_ip,void * pv_api_op,cfg_params_t * ps_cfg)4883 static IV_STATUS_T ih264e_set_enc_mode(void *pv_api_ip,
4884 void *pv_api_op,
4885 cfg_params_t *ps_cfg)
4886 {
4887 /* ctrl call I/O structures */
4888 ih264e_ctl_set_enc_mode_ip_t *ps_ip = pv_api_ip;
4889 ih264e_ctl_set_enc_mode_op_t *ps_op = pv_api_op;
4890
4891 ps_op->s_ive_op.u4_error_code = 0;
4892
4893 ps_cfg->e_enc_mode = ps_ip->s_ive_ip.e_enc_mode;
4894
4895 ps_cfg->u4_timestamp_high = ps_ip->s_ive_ip.u4_timestamp_high;
4896 ps_cfg->u4_timestamp_low = ps_ip->s_ive_ip.u4_timestamp_low;
4897
4898 return IV_SUCCESS;
4899 }
4900
4901 /**
4902 *******************************************************************************
4903 *
4904 * @brief
4905 * Sets vbv parameters
4906 *
4907 * @par Description:
4908 * Sets vbv parameters
4909 *
4910 * @param[in] pv_api_ip
4911 * Pointer to input argument structure
4912 *
4913 * @param[out] pv_api_op
4914 * Pointer to output argument structure
4915 *
4916 * @param[out] ps_cfg
4917 * Pointer to config structure to be updated
4918 *
4919 * @returns error status
4920 *
4921 * @remarks none
4922 *
4923 *******************************************************************************
4924 */
ih264e_set_vbv_params(void * pv_api_ip,void * pv_api_op,cfg_params_t * ps_cfg)4925 static IV_STATUS_T ih264e_set_vbv_params(void *pv_api_ip,
4926 void *pv_api_op,
4927 cfg_params_t *ps_cfg)
4928 {
4929 /* ctrl call I/O structures */
4930 ih264e_ctl_set_vbv_params_ip_t *ps_ip = pv_api_ip;
4931 ih264e_ctl_set_vbv_params_op_t *ps_op = pv_api_op;
4932
4933 ps_op->s_ive_op.u4_error_code = 0;
4934
4935 ps_cfg->u4_vbv_buf_size = ps_ip->s_ive_ip.u4_vbv_buf_size;
4936 ps_cfg->u4_vbv_buffer_delay = ps_ip->s_ive_ip.u4_vbv_buffer_delay;
4937
4938 ps_cfg->u4_timestamp_high = ps_ip->s_ive_ip.u4_timestamp_high;
4939 ps_cfg->u4_timestamp_low = ps_ip->s_ive_ip.u4_timestamp_low;
4940
4941 return IV_SUCCESS;
4942 }
4943
4944 /**
4945 *******************************************************************************
4946 *
4947 * @brief
4948 * Sets AIR parameters
4949 *
4950 * @par Description:
4951 * Sets AIR parameters
4952 *
4953 * @param[in] pv_api_ip
4954 * Pointer to input argument structure
4955 *
4956 * @param[out] pv_api_op
4957 * Pointer to output argument structure
4958 *
4959 * @param[out] ps_cfg
4960 * Pointer to config structure to be updated
4961 *
4962 * @returns error status
4963 *
4964 * @remarks none
4965 *
4966 *******************************************************************************
4967 */
ih264_set_air_params(void * pv_api_ip,void * pv_api_op,cfg_params_t * ps_cfg)4968 static IV_STATUS_T ih264_set_air_params(void *pv_api_ip,
4969 void *pv_api_op,
4970 cfg_params_t *ps_cfg)
4971 {
4972 /* ctrl call I/O structures */
4973 ih264e_ctl_set_air_params_ip_t *ps_ip = pv_api_ip;
4974 ih264e_ctl_set_air_params_op_t *ps_op = pv_api_op;
4975
4976 ps_op->s_ive_op.u4_error_code = 0;
4977
4978 ps_cfg->e_air_mode = ps_ip->s_ive_ip.e_air_mode;
4979 ps_cfg->u4_air_refresh_period = ps_ip->s_ive_ip.u4_air_refresh_period;
4980
4981 ps_cfg->u4_timestamp_high = ps_ip->s_ive_ip.u4_timestamp_high;
4982 ps_cfg->u4_timestamp_low = ps_ip->s_ive_ip.u4_timestamp_low;
4983
4984 return IV_SUCCESS;
4985 }
4986
4987 /**
4988 *******************************************************************************
4989 *
4990 * @brief
4991 * Sets motion estimation parameters
4992 *
4993 * @par Description:
4994 * Sets motion estimation parameters
4995 *
4996 * @param[in] pv_api_ip
4997 * Pointer to input argument structure
4998 *
4999 * @param[out] pv_api_op
5000 * Pointer to output argument structure
5001 *
5002 * @param[out] ps_cfg
5003 * Pointer to config structure to be updated
5004 *
5005 * @returns error status
5006 *
5007 * @remarks none
5008 *
5009 *******************************************************************************
5010 */
ih264_set_me_params(void * pv_api_ip,void * pv_api_op,cfg_params_t * ps_cfg)5011 static IV_STATUS_T ih264_set_me_params(void *pv_api_ip,
5012 void *pv_api_op,
5013 cfg_params_t *ps_cfg)
5014 {
5015 /* ctrl call I/O structures */
5016 ih264e_ctl_set_me_params_ip_t *ps_ip = pv_api_ip;
5017 ih264e_ctl_set_me_params_op_t *ps_op = pv_api_op;
5018
5019 ps_op->s_ive_op.u4_error_code = 0;
5020
5021 ps_cfg->u4_enable_hpel = ps_ip->s_ive_ip.u4_enable_hpel;
5022 ps_cfg->u4_enable_qpel = ps_ip->s_ive_ip.u4_enable_qpel;
5023 ps_cfg->u4_enable_fast_sad = ps_ip->s_ive_ip.u4_enable_fast_sad;
5024 ps_cfg->u4_enable_alt_ref = ps_ip->s_ive_ip.u4_enable_alt_ref;
5025 ps_cfg->u4_srch_rng_x = ps_ip->s_ive_ip.u4_srch_rng_x;
5026 ps_cfg->u4_srch_rng_y = ps_ip->s_ive_ip.u4_srch_rng_y;
5027 ps_cfg->u4_me_speed_preset = ps_ip->s_ive_ip.u4_me_speed_preset;
5028
5029 ps_cfg->u4_timestamp_high = ps_ip->s_ive_ip.u4_timestamp_high;
5030 ps_cfg->u4_timestamp_low = ps_ip->s_ive_ip.u4_timestamp_low;
5031
5032 return IV_SUCCESS;
5033 }
5034
5035 /**
5036 *******************************************************************************
5037 *
5038 * @brief
5039 * Sets Intra/Inter Prediction estimation parameters
5040 *
5041 * @par Description:
5042 * Sets Intra/Inter Prediction estimation parameters
5043 *
5044 * @param[in] pv_api_ip
5045 * Pointer to input argument structure
5046 *
5047 * @param[out] pv_api_op
5048 * Pointer to output argument structure
5049 *
5050 * @param[out] ps_cfg
5051 * Pointer to config structure to be updated
5052 *
5053 * @returns error status
5054 *
5055 * @remarks none
5056 *
5057 *******************************************************************************
5058 */
ih264_set_ipe_params(void * pv_api_ip,void * pv_api_op,cfg_params_t * ps_cfg)5059 static IV_STATUS_T ih264_set_ipe_params(void *pv_api_ip,
5060 void *pv_api_op,
5061 cfg_params_t *ps_cfg)
5062 {
5063 /* ctrl call I/O structures */
5064 ih264e_ctl_set_ipe_params_ip_t *ps_ip = pv_api_ip;
5065 ih264e_ctl_set_ipe_params_op_t *ps_op = pv_api_op;
5066
5067 ps_op->s_ive_op.u4_error_code = 0;
5068
5069 ps_cfg->u4_enable_intra_4x4 = ps_ip->s_ive_ip.u4_enable_intra_4x4;
5070 ps_cfg->u4_enc_speed_preset = ps_ip->s_ive_ip.u4_enc_speed_preset;
5071
5072 ps_cfg->u4_timestamp_high = ps_ip->s_ive_ip.u4_timestamp_high;
5073 ps_cfg->u4_timestamp_low = ps_ip->s_ive_ip.u4_timestamp_low;
5074
5075 return IV_SUCCESS;
5076 }
5077
5078 /**
5079 *******************************************************************************
5080 *
5081 * @brief
5082 * Sets GOP parameters
5083 *
5084 * @par Description:
5085 * Sets GOP parameters
5086 *
5087 * @param[in] pv_api_ip
5088 * Pointer to input argument structure
5089 *
5090 * @param[out] pv_api_op
5091 * Pointer to output argument structure
5092 *
5093 * @param[out] ps_cfg
5094 * Pointer to config structure to be updated
5095 *
5096 * @returns error status
5097 *
5098 * @remarks none
5099 *
5100 *******************************************************************************
5101 */
ih264_set_gop_params(void * pv_api_ip,void * pv_api_op,cfg_params_t * ps_cfg)5102 static IV_STATUS_T ih264_set_gop_params(void *pv_api_ip,
5103 void *pv_api_op,
5104 cfg_params_t *ps_cfg)
5105 {
5106 /* ctrl call I/O structures */
5107 ih264e_ctl_set_gop_params_ip_t *ps_ip = pv_api_ip;
5108 ih264e_ctl_set_gop_params_op_t *ps_op = pv_api_op;
5109
5110 ps_op->s_ive_op.u4_error_code = 0;
5111
5112 ps_cfg->u4_i_frm_interval = ps_ip->s_ive_ip.u4_i_frm_interval;
5113 ps_cfg->u4_idr_frm_interval = ps_ip->s_ive_ip.u4_idr_frm_interval;
5114
5115 ps_cfg->u4_timestamp_high = ps_ip->s_ive_ip.u4_timestamp_high;
5116 ps_cfg->u4_timestamp_low = ps_ip->s_ive_ip.u4_timestamp_low;
5117
5118 return IV_SUCCESS;
5119 }
5120
5121 /**
5122 *******************************************************************************
5123 *
5124 * @brief
5125 * Sets profile parameters
5126 *
5127 * @par Description:
5128 * Sets profile parameters
5129 *
5130 * @param[in] pv_api_ip
5131 * Pointer to input argument structure
5132 *
5133 * @param[out] pv_api_op
5134 * Pointer to output argument structure
5135 *
5136 * @param[out] ps_cfg
5137 * Pointer to config structure to be updated
5138 *
5139 * @returns error status
5140 *
5141 * @remarks none
5142 *
5143 *******************************************************************************
5144 */
ih264_set_profile_params(void * pv_api_ip,void * pv_api_op,cfg_params_t * ps_cfg)5145 static IV_STATUS_T ih264_set_profile_params(void *pv_api_ip,
5146 void *pv_api_op,
5147 cfg_params_t *ps_cfg)
5148 {
5149 /* ctrl call I/O structures */
5150 ih264e_ctl_set_profile_params_ip_t *ps_ip = pv_api_ip;
5151 ih264e_ctl_set_profile_params_op_t *ps_op = pv_api_op;
5152
5153 ps_op->s_ive_op.u4_error_code = 0;
5154
5155 ps_cfg->e_profile = ps_ip->s_ive_ip.e_profile;
5156
5157 ps_cfg->u4_entropy_coding_mode = ps_ip->s_ive_ip.u4_entropy_coding_mode;
5158
5159 ps_cfg->u4_timestamp_high = ps_ip->s_ive_ip.u4_timestamp_high;
5160 ps_cfg->u4_timestamp_low = ps_ip->s_ive_ip.u4_timestamp_low;
5161
5162 return IV_SUCCESS;
5163 }
5164
5165 /**
5166 *******************************************************************************
5167 *
5168 * @brief
5169 * Sets disable deblock level
5170 *
5171 * @par Description:
5172 * Sets disable deblock level. Level 0 means no disabling and level 4 means
5173 * disable completely. 1, 2, 3 are intermediate levels that control amount
5174 * of deblocking done.
5175 *
5176 * @param[in] ps_codec_obj
5177 * Pointer to codec object at API level
5178 *
5179 * @param[in] pv_api_ip
5180 * Pointer to input argument structure
5181 *
5182 * @param[out] pv_api_op
5183 * Pointer to output argument structure
5184 *
5185 * @returns error status
5186 *
5187 * @remarks none
5188 *
5189 *******************************************************************************
5190 */
ih264_set_deblock_params(void * pv_api_ip,void * pv_api_op,cfg_params_t * ps_cfg)5191 static WORD32 ih264_set_deblock_params(void *pv_api_ip,
5192 void *pv_api_op,
5193 cfg_params_t *ps_cfg)
5194 {
5195 /* ctrl call I/O structures */
5196 ih264e_ctl_set_deblock_params_ip_t *ps_ip = pv_api_ip;
5197 ih264e_ctl_set_deblock_params_op_t *ps_op = pv_api_op;
5198
5199 ps_op->s_ive_op.u4_error_code = 0;
5200
5201 ps_cfg->u4_disable_deblock_level = ps_ip->s_ive_ip.u4_disable_deblock_level;
5202
5203 ps_cfg->u4_timestamp_high = ps_ip->s_ive_ip.u4_timestamp_high;
5204 ps_cfg->u4_timestamp_low = ps_ip->s_ive_ip.u4_timestamp_low;
5205
5206 return IV_SUCCESS;
5207 }
5208
5209 /**
5210 *******************************************************************************
5211 *
5212 * @brief
5213 * Sets number of cores
5214 *
5215 * @par Description:
5216 * Sets number of cores
5217 *
5218 * @param[in] ps_codec_obj
5219 * Pointer to codec object at API level
5220 *
5221 * @param[in] pv_api_ip
5222 * Pointer to input argument structure
5223 *
5224 * @param[out] pv_api_op
5225 * Pointer to output argument structure
5226 *
5227 * @returns error status
5228 *
5229 * @remarks The number of encoder threads is limited to MAX_PROCESS_THREADS
5230 *
5231 *******************************************************************************
5232 */
ih264e_set_num_cores(void * pv_api_ip,void * pv_api_op,cfg_params_t * ps_cfg)5233 static WORD32 ih264e_set_num_cores(void *pv_api_ip,
5234 void *pv_api_op,
5235 cfg_params_t *ps_cfg)
5236 {
5237 /* ctrl call I/O structures */
5238 ih264e_ctl_set_num_cores_ip_t *ps_ip = pv_api_ip;
5239 ih264e_ctl_set_num_cores_op_t *ps_op = pv_api_op;
5240
5241 ps_op->s_ive_op.u4_error_code = 0;
5242
5243 ps_cfg->u4_num_cores = MIN(ps_ip->s_ive_ip.u4_num_cores, MAX_PROCESS_THREADS);
5244
5245 ps_cfg->u4_timestamp_high = ps_ip->s_ive_ip.u4_timestamp_high;
5246 ps_cfg->u4_timestamp_low = ps_ip->s_ive_ip.u4_timestamp_low;
5247
5248 return IV_SUCCESS;
5249 }
5250
5251 /**
5252 *******************************************************************************
5253 *
5254 * @brief
5255 * Resets encoder state
5256 *
5257 * @par Description:
5258 * Resets encoder state by calling ih264e_init()
5259 *
5260 * @param[in] ps_codec_obj
5261 * Pointer to codec object at API level
5262 *
5263 * @param[in] pv_api_ip
5264 * Pointer to input argument structure
5265 *
5266 * @param[out] pv_api_op
5267 * Pointer to output argument structure
5268 *
5269 * @returns error status
5270 *
5271 * @remarks none
5272 *
5273 *******************************************************************************
5274 */
ih264e_reset(iv_obj_t * ps_codec_obj,void * pv_api_ip,void * pv_api_op)5275 static WORD32 ih264e_reset(iv_obj_t *ps_codec_obj,
5276 void *pv_api_ip,
5277 void *pv_api_op)
5278 {
5279 /* codec ctxt */
5280 codec_t * ps_codec = (codec_t *) (ps_codec_obj->pv_codec_handle);
5281
5282 /* ctrl call I/O structures */
5283 ih264e_ctl_reset_op_t *ps_op = pv_api_op;
5284
5285 UNUSED(pv_api_ip);
5286
5287 ps_op->s_ive_op.u4_error_code = 0;
5288
5289 if (ps_codec != NULL)
5290 {
5291 ih264e_init(ps_codec);
5292 }
5293 else
5294 {
5295 ps_op->s_ive_op.u4_error_code = IH264E_INIT_NOT_DONE;
5296 }
5297
5298 return IV_SUCCESS;
5299 }
5300
5301 /**
5302 *******************************************************************************
5303 *
5304 * @brief
5305 * Codec control call
5306 *
5307 * @par Description:
5308 * Codec control call which in turn calls appropriate calls based on sub-command
5309 *
5310 * @param[in] ps_codec_obj
5311 * Pointer to codec object at API level
5312 *
5313 * @param[in] pv_api_ip
5314 * Pointer to input argument structure
5315 *
5316 * @param[out] pv_api_op
5317 * Pointer to output argument structure
5318 *
5319 * @returns error status
5320 *
5321 * @remarks none
5322 *
5323 *******************************************************************************
5324 */
ih264e_ctl(iv_obj_t * ps_codec_obj,void * pv_api_ip,void * pv_api_op)5325 static WORD32 ih264e_ctl(iv_obj_t *ps_codec_obj,
5326 void *pv_api_ip,
5327 void *pv_api_op)
5328 {
5329 /* codec ctxt */
5330 codec_t *ps_codec = (codec_t *) ps_codec_obj->pv_codec_handle;
5331
5332 /* ctrl call I/O structures */
5333 ih264e_ctl_setdefault_ip_t *ps_ctl_ip = pv_api_ip;
5334 ih264e_ctl_setdefault_op_t *ps_ctl_op = pv_api_op;
5335
5336 /* ctrl call sub cmd */
5337 IVE_CONTROL_API_COMMAND_TYPE_T sub_cmd = ps_ctl_ip->s_ive_ip.e_sub_cmd;
5338
5339 /* error status */
5340 IV_STATUS_T ret = IV_SUCCESS;
5341
5342 /* temp var */
5343 WORD32 i;
5344 cfg_params_t *ps_cfg = NULL;
5345
5346 /* control call is for configuring encoding params, this is not to be called
5347 * before a successful init call */
5348 if (ps_codec->i4_init_done != 1)
5349 {
5350 ps_ctl_op->s_ive_op.u4_error_code |= 1 << IVE_FATALERROR;
5351 ps_ctl_op->s_ive_op.u4_error_code |= IH264E_INIT_NOT_DONE;
5352 return IV_FAIL;
5353 }
5354
5355 /* make it thread safe */
5356 ithread_mutex_lock(ps_codec->pv_ctl_mutex);
5357
5358 /* find a free config param set to hold current parameters */
5359 for (i = 0; i < MAX_ACTIVE_CONFIG_PARAMS; i++)
5360 {
5361 if (0 == ps_codec->as_cfg[i].u4_is_valid)
5362 {
5363 ps_cfg = &ps_codec->as_cfg[i];
5364 break;
5365 }
5366 }
5367
5368 /* If all are invalid, then start overwriting from the head config params */
5369 if (NULL == ps_cfg)
5370 {
5371 ps_cfg = &ps_codec->as_cfg[0];
5372 }
5373
5374 ps_cfg->u4_is_valid = 1;
5375
5376 ps_cfg->e_cmd = sub_cmd;
5377
5378 switch (sub_cmd)
5379 {
5380 case IVE_CMD_CTL_SET_DIMENSIONS:
5381 ret = ih264e_set_dimensions(pv_api_ip, pv_api_op, ps_cfg);
5382 break;
5383
5384 case IVE_CMD_CTL_SET_FRAMERATE:
5385 ret = ih264e_set_frame_rate(pv_api_ip, pv_api_op, ps_cfg);
5386 break;
5387
5388 case IVE_CMD_CTL_SET_BITRATE:
5389 ret = ih264e_set_bit_rate(pv_api_ip, pv_api_op, ps_cfg);
5390 break;
5391
5392 case IVE_CMD_CTL_SET_FRAMETYPE:
5393 ret = ih264e_set_frame_type(pv_api_ip, pv_api_op, ps_cfg);
5394 break;
5395
5396 case IVE_CMD_CTL_SET_QP:
5397 ret = ih264e_set_qp(pv_api_ip, pv_api_op, ps_cfg);
5398 break;
5399
5400 case IVE_CMD_CTL_SET_ENC_MODE:
5401 ret = ih264e_set_enc_mode(pv_api_ip, pv_api_op, ps_cfg);
5402 break;
5403
5404 case IVE_CMD_CTL_SET_VBV_PARAMS:
5405 ret = ih264e_set_vbv_params(pv_api_ip, pv_api_op, ps_cfg);
5406 break;
5407
5408 case IVE_CMD_CTL_SET_AIR_PARAMS:
5409 ret = ih264_set_air_params(pv_api_ip, pv_api_op, ps_cfg);
5410 break;
5411
5412 case IVE_CMD_CTL_SET_ME_PARAMS:
5413 ret = ih264_set_me_params(pv_api_ip, pv_api_op, ps_cfg);
5414 break;
5415
5416 case IVE_CMD_CTL_SET_IPE_PARAMS:
5417 ret = ih264_set_ipe_params(pv_api_ip, pv_api_op, ps_cfg);
5418 break;
5419
5420 case IVE_CMD_CTL_SET_GOP_PARAMS:
5421 ret = ih264_set_gop_params(pv_api_ip, pv_api_op, ps_cfg);
5422 break;
5423
5424 case IVE_CMD_CTL_SET_PROFILE_PARAMS:
5425 ret = ih264_set_profile_params(pv_api_ip, pv_api_op, ps_cfg);
5426 break;
5427
5428 case IVE_CMD_CTL_SET_DEBLOCK_PARAMS:
5429 ret = ih264_set_deblock_params(pv_api_ip, pv_api_op, ps_cfg);
5430 break;
5431
5432 case IVE_CMD_CTL_RESET:
5433
5434 /* invalidate config param struct as it is being served right away */
5435 ps_codec->as_cfg[i].u4_is_valid = 0;
5436
5437 ret = ih264e_reset(ps_codec_obj, pv_api_ip, pv_api_op);
5438 break;
5439
5440 case IVE_CMD_CTL_SETDEFAULT:
5441 {
5442 /* ctrl call I/O structures */
5443 ih264e_ctl_setdefault_op_t *ps_op = pv_api_op;
5444
5445 /* invalidate config param struct as it is being served right away */
5446 ps_codec->as_cfg[i].u4_is_valid = 0;
5447
5448 /* error status */
5449 ret = ih264e_set_default_params(ps_cfg);
5450
5451 ps_op->s_ive_op.u4_error_code = ret;
5452
5453 break;
5454 }
5455
5456 case IVE_CMD_CTL_FLUSH:
5457
5458 /* invalidate config param struct as it is being served right away */
5459 ps_codec->as_cfg[i].u4_is_valid = 0;
5460
5461 ret = ih264e_set_flush_mode(ps_codec_obj, pv_api_ip, pv_api_op);
5462 break;
5463
5464 case IVE_CMD_CTL_GETBUFINFO:
5465
5466 /* invalidate config param struct as it is being served right away */
5467 ps_codec->as_cfg[i].u4_is_valid = 0;
5468
5469 ret = ih264e_get_buf_info(ps_codec_obj, pv_api_ip, pv_api_op);
5470 break;
5471
5472 case IVE_CMD_CTL_GETVERSION:
5473 {
5474 /* ctrl call I/O structures */
5475 ih264e_ctl_getversioninfo_ip_t *ps_ip = pv_api_ip;
5476 ih264e_ctl_getversioninfo_op_t *ps_op = pv_api_op;
5477
5478 /* invalidate config param struct as it is being served right away */
5479 ps_codec->as_cfg[i].u4_is_valid = 0;
5480
5481 /* error status */
5482 ps_op->s_ive_op.u4_error_code = IV_SUCCESS;
5483
5484 if (ps_ip->s_ive_ip.u4_version_bufsize <= 0)
5485 {
5486 ps_op->s_ive_op.u4_error_code =
5487 IH264E_CXA_VERS_BUF_INSUFFICIENT;
5488 ret = IV_FAIL;
5489 }
5490 else
5491 {
5492 ret = ih264e_get_version((CHAR *) ps_ip->s_ive_ip.pu1_version,
5493 ps_ip->s_ive_ip.u4_version_bufsize);
5494
5495 if (ret != IV_SUCCESS)
5496 {
5497 ps_op->s_ive_op.u4_error_code =
5498 IH264E_CXA_VERS_BUF_INSUFFICIENT;
5499 ret = IV_FAIL;
5500 }
5501 }
5502 break;
5503 }
5504
5505 case IVE_CMD_CTL_SET_NUM_CORES:
5506 ret = ih264e_set_num_cores(pv_api_ip, pv_api_op, ps_cfg);
5507 break;
5508
5509 default:
5510 /* invalidate config param struct as it is being served right away */
5511 ps_codec->as_cfg[i].u4_is_valid = 0;
5512
5513 DEBUG("Warning !! unrecognized control api command \n");
5514 break;
5515 }
5516
5517 ithread_mutex_unlock(ps_codec->pv_ctl_mutex);
5518
5519 return ret;
5520 }
5521
5522 /**
5523 *******************************************************************************
5524 *
5525 * @brief
5526 * Codec entry point function. All the function calls to the codec are done
5527 * using this function with different values specified in command
5528 *
5529 * @par Description:
5530 * Arguments are tested for validity and then based on the command
5531 * appropriate function is called
5532 *
5533 * @param[in] ps_handle
5534 * API level handle for codec
5535 *
5536 * @param[in] pv_api_ip
5537 * Input argument structure
5538 *
5539 * @param[out] pv_api_op
5540 * Output argument structure
5541 *
5542 * @returns error_status
5543 *
5544 * @remarks
5545 *
5546 *******************************************************************************
5547 */
ih264e_api_function(iv_obj_t * ps_handle,void * pv_api_ip,void * pv_api_op)5548 IV_STATUS_T ih264e_api_function(iv_obj_t *ps_handle,
5549 void *pv_api_ip,
5550 void *pv_api_op)
5551 {
5552 /* api command */
5553 WORD32 command = IV_CMD_NA;
5554
5555 /* error status */
5556 IV_STATUS_T e_status;
5557 WORD32 ret;
5558
5559 /* tmp var */
5560 WORD32 *pu4_ptr_cmd = (WORD32 *) pv_api_ip;
5561
5562 /* validate input / output structures */
5563 e_status = api_check_struct_sanity(ps_handle, pv_api_ip, pv_api_op);
5564
5565 if (e_status != IV_SUCCESS)
5566 {
5567 DEBUG("error code = %d\n", *((UWORD32 *)pv_api_op + 1));
5568 return IV_FAIL;
5569 }
5570
5571 pu4_ptr_cmd++;
5572
5573 command = *pu4_ptr_cmd;
5574
5575 switch (command)
5576 {
5577 case IV_CMD_GET_NUM_MEM_REC:
5578 ret = ih264e_get_num_rec(pv_api_ip, pv_api_op);
5579 break;
5580
5581 case IV_CMD_FILL_NUM_MEM_REC:
5582 ret = ih264e_fill_num_mem_rec(pv_api_ip, pv_api_op);
5583 break;
5584
5585 case IV_CMD_INIT:
5586 ret = ih264e_init_mem_rec(ps_handle, pv_api_ip, pv_api_op);
5587 break;
5588
5589 case IV_CMD_RETRIEVE_MEMREC:
5590 ret = ih264e_retrieve_memrec(ps_handle, pv_api_ip, pv_api_op);
5591 break;
5592
5593 case IVE_CMD_VIDEO_CTL:
5594 ret = ih264e_ctl(ps_handle, pv_api_ip, pv_api_op);
5595 break;
5596
5597 case IVE_CMD_VIDEO_ENCODE:
5598 ret = ih264e_encode(ps_handle, pv_api_ip, pv_api_op);
5599 break;
5600
5601 default:
5602 ret = IV_FAIL;
5603 break;
5604 }
5605
5606 return (IV_STATUS_T) ret;
5607 }
5608