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_constrained_intra_pred != 0)
1424 && (ps_ip->s_ive_ip.u4_constrained_intra_pred != 1))
1425 {
1426 ps_op->s_ive_op.u4_error_code |= 1
1427 << IVE_UNSUPPORTEDPARAM;
1428 ps_op->s_ive_op.u4_error_code |=
1429 IH264E_INVALID_CONSTRAINED_INTRA_PREDICTION_MODE;
1430 return IV_FAIL;
1431 }
1432
1433 if ((ps_ip->s_ive_ip.u4_enc_speed_preset != IVE_CONFIG)
1434 && (ps_ip->s_ive_ip.u4_enc_speed_preset != IVE_SLOWEST)
1435 && (ps_ip->s_ive_ip.u4_enc_speed_preset != IVE_NORMAL)
1436 && (ps_ip->s_ive_ip.u4_enc_speed_preset != IVE_FAST)
1437 && (ps_ip->s_ive_ip.u4_enc_speed_preset != IVE_HIGH_SPEED)
1438 && (ps_ip->s_ive_ip.u4_enc_speed_preset != IVE_FASTEST))
1439 {
1440 ps_op->s_ive_op.u4_error_code |= 1
1441 << IVE_UNSUPPORTEDPARAM;
1442 ps_op->s_ive_op.u4_error_code |=
1443 IH264E_INVALID_ENC_SPEED_PRESET;
1444 return IV_FAIL;
1445 }
1446
1447 break;
1448 }
1449
1450 case IVE_CMD_CTL_SET_GOP_PARAMS:
1451 {
1452 ih264e_ctl_set_gop_params_ip_t *ps_ip = pv_api_ip;
1453 ih264e_ctl_set_gop_params_op_t *ps_op = pv_api_op;
1454
1455 if (ps_ip->s_ive_ip.u4_size
1456 != sizeof(ih264e_ctl_set_gop_params_ip_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_IP_CTL_SETGOPPARAMS_API_STRUCT_SIZE_INCORRECT;
1462 return IV_FAIL;
1463 }
1464
1465 if (ps_op->s_ive_op.u4_size
1466 != sizeof(ih264e_ctl_set_gop_params_op_t))
1467 {
1468 ps_op->s_ive_op.u4_error_code |= 1
1469 << IVE_UNSUPPORTEDPARAM;
1470 ps_op->s_ive_op.u4_error_code |=
1471 IVE_ERR_OP_CTL_SETGOPPARAMS_API_STRUCT_SIZE_INCORRECT;
1472 return IV_FAIL;
1473 }
1474
1475 if ((ps_ip->s_ive_ip.u4_i_frm_interval < DEFAULT_MIN_INTRA_FRAME_RATE)
1476 || (ps_ip->s_ive_ip.u4_i_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_INTRA_FRAME_INTERVAL;
1482 return IV_FAIL;
1483 }
1484
1485 if ((ps_ip->s_ive_ip.u4_idr_frm_interval < DEFAULT_MIN_INTRA_FRAME_RATE)
1486 || (ps_ip->s_ive_ip.u4_idr_frm_interval > DEFAULT_MAX_INTRA_FRAME_RATE))
1487 {
1488 ps_op->s_ive_op.u4_error_code |= 1
1489 << IVE_UNSUPPORTEDPARAM;
1490 ps_op->s_ive_op.u4_error_code |=
1491 IH264E_INVALID_IDR_FRAME_INTERVAL;
1492 return IV_FAIL;
1493 }
1494
1495 break;
1496 }
1497
1498 case IVE_CMD_CTL_SET_DEBLOCK_PARAMS:
1499 {
1500 ih264e_ctl_set_deblock_params_ip_t *ps_ip = pv_api_ip;
1501 ih264e_ctl_set_deblock_params_op_t *ps_op = pv_api_op;
1502
1503 if (ps_ip->s_ive_ip.u4_size
1504 != sizeof(ih264e_ctl_set_deblock_params_ip_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_IP_CTL_SETDEBLKPARAMS_API_STRUCT_SIZE_INCORRECT;
1510 return IV_FAIL;
1511 }
1512
1513 if (ps_op->s_ive_op.u4_size
1514 != sizeof(ih264e_ctl_set_deblock_params_op_t))
1515 {
1516 ps_op->s_ive_op.u4_error_code |= 1
1517 << IVE_UNSUPPORTEDPARAM;
1518 ps_op->s_ive_op.u4_error_code |=
1519 IVE_ERR_OP_CTL_SETDEBLKPARAMS_API_STRUCT_SIZE_INCORRECT;
1520 return IV_FAIL;
1521 }
1522
1523 if ((ps_ip->s_ive_ip.u4_disable_deblock_level != DISABLE_DEBLK_LEVEL_0)
1524 && (ps_ip->s_ive_ip.u4_disable_deblock_level != DISABLE_DEBLK_LEVEL_2)
1525 && (ps_ip->s_ive_ip.u4_disable_deblock_level != DISABLE_DEBLK_LEVEL_3)
1526 && (ps_ip->s_ive_ip.u4_disable_deblock_level != DISABLE_DEBLK_LEVEL_4))
1527 {
1528 ps_op->s_ive_op.u4_error_code |= 1
1529 << IVE_UNSUPPORTEDPARAM;
1530 ps_op->s_ive_op.u4_error_code |=
1531 IH264E_INVALID_DEBLOCKING_TYPE_INPUT;
1532 return IV_FAIL;
1533 }
1534
1535 break;
1536 }
1537
1538 case IVE_CMD_CTL_SET_QP:
1539 {
1540 ih264e_ctl_set_qp_ip_t *ps_ip = pv_api_ip;
1541 ih264e_ctl_set_qp_op_t *ps_op = pv_api_op;
1542
1543 if (ps_ip->s_ive_ip.u4_size
1544 != sizeof(ih264e_ctl_set_qp_ip_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_IP_CTL_SETQPPARAMS_API_STRUCT_SIZE_INCORRECT;
1550 return IV_FAIL;
1551 }
1552
1553 if (ps_op->s_ive_op.u4_size
1554 != sizeof(ih264e_ctl_set_qp_op_t))
1555 {
1556 ps_op->s_ive_op.u4_error_code |= 1
1557 << IVE_UNSUPPORTEDPARAM;
1558 ps_op->s_ive_op.u4_error_code |=
1559 IVE_ERR_OP_CTL_SETQPPARAMS_API_STRUCT_SIZE_INCORRECT;
1560 return IV_FAIL;
1561 }
1562
1563 if ((ps_ip->s_ive_ip.u4_i_qp_max > MAX_H264_QP)
1564 || (ps_ip->s_ive_ip.u4_p_qp_max > MAX_H264_QP)
1565 || (ps_ip->s_ive_ip.u4_b_qp_max > MAX_H264_QP))
1566 {
1567 ps_op->s_ive_op.u4_error_code |= 1
1568 << IVE_UNSUPPORTEDPARAM;
1569 ps_op->s_ive_op.u4_error_code |=
1570 IH264E_INVALID_MAX_FRAME_QP;
1571 return IV_FAIL;
1572 }
1573
1574 /* We donot support QP < 4 */
1575 if ((ps_ip->s_ive_ip.u4_i_qp_min < 4)
1576 || (ps_ip->s_ive_ip.u4_p_qp_min < 4)
1577 || (ps_ip->s_ive_ip.u4_b_qp_min < 4)
1578 || (ps_ip->s_ive_ip.u4_i_qp_min > ps_ip->s_ive_ip.u4_i_qp_max)
1579 || (ps_ip->s_ive_ip.u4_p_qp_min > ps_ip->s_ive_ip.u4_p_qp_max)
1580 || (ps_ip->s_ive_ip.u4_b_qp_min > ps_ip->s_ive_ip.u4_b_qp_max))
1581 {
1582 ps_op->s_ive_op.u4_error_code |= 1
1583 << IVE_UNSUPPORTEDPARAM;
1584 ps_op->s_ive_op.u4_error_code |=
1585 IH264E_INVALID_MIN_FRAME_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_max)
1590 || (ps_ip->s_ive_ip.u4_p_qp > ps_ip->s_ive_ip.u4_p_qp_max)
1591 || (ps_ip->s_ive_ip.u4_b_qp > ps_ip->s_ive_ip.u4_b_qp_max))
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 if ((ps_ip->s_ive_ip.u4_i_qp < ps_ip->s_ive_ip.u4_i_qp_min)
1600 || (ps_ip->s_ive_ip.u4_p_qp < ps_ip->s_ive_ip.u4_p_qp_min)
1601 || (ps_ip->s_ive_ip.u4_b_qp < ps_ip->s_ive_ip.u4_b_qp_min))
1602 {
1603 ps_op->s_ive_op.u4_error_code |= 1
1604 << IVE_UNSUPPORTEDPARAM;
1605 ps_op->s_ive_op.u4_error_code |= IH264E_INVALID_INIT_QP;
1606 return IV_FAIL;
1607 }
1608
1609 break;
1610 }
1611
1612 case IVE_CMD_CTL_SET_ENC_MODE:
1613 {
1614 ih264e_ctl_set_enc_mode_ip_t *ps_ip = pv_api_ip;
1615 ih264e_ctl_set_enc_mode_op_t *ps_op = pv_api_op;
1616
1617 if (ps_ip->s_ive_ip.u4_size
1618 != sizeof(ih264e_ctl_set_enc_mode_ip_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_IP_CTL_SETENCMODE_API_STRUCT_SIZE_INCORRECT;
1624 return IV_FAIL;
1625 }
1626
1627 if (ps_op->s_ive_op.u4_size
1628 != sizeof(ih264e_ctl_set_enc_mode_op_t))
1629 {
1630 ps_op->s_ive_op.u4_error_code |= 1
1631 << IVE_UNSUPPORTEDPARAM;
1632 ps_op->s_ive_op.u4_error_code |=
1633 IVE_ERR_OP_CTL_SETENCMODE_API_STRUCT_SIZE_INCORRECT;
1634 return IV_FAIL;
1635 }
1636
1637 if ((ps_ip->s_ive_ip.e_enc_mode != IVE_ENC_MODE_HEADER)
1638 && (ps_ip->s_ive_ip.e_enc_mode != IVE_ENC_MODE_PICTURE))
1639 {
1640 ps_op->s_ive_op.u4_error_code |= 1
1641 << IVE_UNSUPPORTEDPARAM;
1642 ps_op->s_ive_op.u4_error_code |=
1643 IH264E_INVALID_ENC_OPERATION_MODE;
1644 return IV_FAIL;
1645 }
1646
1647 break;
1648 }
1649
1650 case IVE_CMD_CTL_SET_VBV_PARAMS:
1651 {
1652 ih264e_ctl_set_vbv_params_ip_t *ps_ip = pv_api_ip;
1653 ih264e_ctl_set_vbv_params_op_t *ps_op = pv_api_op;
1654
1655 if (ps_ip->s_ive_ip.u4_size
1656 != sizeof(ih264e_ctl_set_vbv_params_ip_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_IP_CTL_SETVBVPARAMS_API_STRUCT_SIZE_INCORRECT;
1662 return IV_FAIL;
1663 }
1664
1665 if (ps_op->s_ive_op.u4_size
1666 != sizeof(ih264e_ctl_set_vbv_params_op_t))
1667 {
1668 ps_op->s_ive_op.u4_error_code |= 1
1669 << IVE_UNSUPPORTEDPARAM;
1670 ps_op->s_ive_op.u4_error_code |=
1671 IVE_ERR_OP_CTL_SETVBVPARAMS_API_STRUCT_SIZE_INCORRECT;
1672 return IV_FAIL;
1673 }
1674
1675 if ((ps_ip->s_ive_ip.u4_vbv_buffer_delay < DEFAULT_MIN_BUFFER_DELAY)
1676 || (ps_ip->s_ive_ip.u4_vbv_buffer_delay > DEFAULT_MAX_BUFFER_DELAY))
1677 {
1678 ps_op->s_ive_op.u4_error_code |= 1
1679 << IVE_UNSUPPORTEDPARAM;
1680 ps_op->s_ive_op.u4_error_code |=
1681 IH264E_INVALID_BUFFER_DELAY;
1682 return IV_FAIL;
1683 }
1684
1685 break;
1686 }
1687
1688 case IVE_CMD_CTL_SET_AIR_PARAMS:
1689 {
1690 ih264e_ctl_set_air_params_ip_t *ps_ip = pv_api_ip;
1691 ih264e_ctl_set_air_params_op_t *ps_op = pv_api_op;
1692
1693 if (ps_ip->s_ive_ip.u4_size
1694 != sizeof(ih264e_ctl_set_air_params_ip_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_IP_CTL_SETAIRPARAMS_API_STRUCT_SIZE_INCORRECT;
1700 return IV_FAIL;
1701 }
1702
1703 if (ps_op->s_ive_op.u4_size
1704 != sizeof(ih264e_ctl_set_air_params_op_t))
1705 {
1706 ps_op->s_ive_op.u4_error_code |= 1
1707 << IVE_UNSUPPORTEDPARAM;
1708 ps_op->s_ive_op.u4_error_code |=
1709 IVE_ERR_OP_CTL_SETAIRPARAMS_API_STRUCT_SIZE_INCORRECT;
1710 return IV_FAIL;
1711 }
1712
1713 if ((ps_ip->s_ive_ip.e_air_mode != IVE_AIR_MODE_NONE)
1714 && (ps_ip->s_ive_ip.e_air_mode != IVE_AIR_MODE_CYCLIC)
1715 && (ps_ip->s_ive_ip.e_air_mode != IVE_AIR_MODE_RANDOM))
1716 {
1717 ps_op->s_ive_op.u4_error_code |= 1
1718 << IVE_UNSUPPORTEDPARAM;
1719 ps_op->s_ive_op.u4_error_code |=
1720 IH264E_INVALID_AIR_MODE;
1721 return IV_FAIL;
1722 }
1723
1724 if (ps_ip->s_ive_ip.u4_air_refresh_period == 0)
1725 {
1726 ps_op->s_ive_op.u4_error_code |= 1
1727 << IVE_UNSUPPORTEDPARAM;
1728 ps_op->s_ive_op.u4_error_code |=
1729 IH264E_INVALID_AIR_REFRESH_PERIOD;
1730 return IV_FAIL;
1731 }
1732
1733 break;
1734 }
1735
1736 case IVE_CMD_CTL_SET_PROFILE_PARAMS:
1737 {
1738 ih264e_ctl_set_profile_params_ip_t *ps_ip = pv_api_ip;
1739 ih264e_ctl_set_profile_params_op_t *ps_op = pv_api_op;
1740
1741 if (ps_ip->s_ive_ip.u4_size
1742 != sizeof(ih264e_ctl_set_profile_params_ip_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_IP_CTL_SETPROFILE_API_STRUCT_SIZE_INCORRECT;
1748 return IV_FAIL;
1749 }
1750
1751 if (ps_op->s_ive_op.u4_size
1752 != sizeof(ih264e_ctl_set_profile_params_op_t))
1753 {
1754 ps_op->s_ive_op.u4_error_code |= 1
1755 << IVE_UNSUPPORTEDPARAM;
1756 ps_op->s_ive_op.u4_error_code |=
1757 IVE_ERR_OP_CTL_SETPROFILE_API_STRUCT_SIZE_INCORRECT;
1758 return IV_FAIL;
1759 }
1760
1761 if (ps_ip->s_ive_ip.e_profile != IV_PROFILE_BASE &&
1762 ps_ip->s_ive_ip.e_profile != IV_PROFILE_MAIN)
1763 {
1764 ps_op->s_ive_op.u4_error_code |= 1
1765 << IVE_UNSUPPORTEDPARAM;
1766 ps_op->s_ive_op.u4_error_code |=
1767 IH264E_PROFILE_NOT_SUPPORTED;
1768 return IV_FAIL;
1769 }
1770
1771 if (ps_ip->s_ive_ip.u4_entropy_coding_mode > 1)
1772 {
1773 ps_op->s_ive_op.u4_error_code |= 1
1774 << IVE_UNSUPPORTEDPARAM;
1775 ps_op->s_ive_op.u4_error_code |=
1776 IH264E_INVALID_ENTROPY_CODING_MODE;
1777 return IV_FAIL;
1778 }
1779
1780 break;
1781 }
1782
1783 default:
1784 *(pu4_api_op + 1) |= 1 << IVE_UNSUPPORTEDPARAM;
1785 *(pu4_api_op + 1) |= IVE_ERR_INVALID_API_SUB_CMD;
1786 return IV_FAIL;
1787 }
1788
1789 break;
1790 }
1791
1792 default:
1793 *(pu4_api_op + 1) |= 1 << IVE_UNSUPPORTEDPARAM;
1794 *(pu4_api_op + 1) |= IVE_ERR_INVALID_API_CMD;
1795 return IV_FAIL;
1796 }
1797
1798 return IV_SUCCESS;
1799 }
1800
1801 /**
1802 *******************************************************************************
1803 *
1804 * @brief update encoder configuration parameters
1805 *
1806 * @par Description:
1807 * updates encoder configuration parameters from the given config set.
1808 * Initialize/reinitialize codec parameters according to new configurations.
1809 *
1810 * @param[in] ps_codec
1811 * Pointer to codec context
1812 *
1813 * @param[in] ps_cfg
1814 * Pointer to config param set
1815 *
1816 * @remarks none
1817 *
1818 *******************************************************************************
1819 */
ih264e_codec_update_config(codec_t * ps_codec,cfg_params_t * ps_cfg)1820 IH264E_ERROR_T ih264e_codec_update_config(codec_t *ps_codec,
1821 cfg_params_t *ps_cfg)
1822 {
1823 /* config params */
1824 cfg_params_t *ps_curr_cfg = &ps_codec->s_cfg;
1825
1826 /* error status */
1827 IH264E_ERROR_T err = IH264E_SUCCESS;
1828
1829 /* temp var */
1830 UWORD32 u4_init_rc = 0;
1831
1832 /***********************/
1833 /* UPDATE CODEC CONFIG */
1834 /***********************/
1835 if (ps_cfg->e_cmd == IVE_CMD_CTL_SET_DIMENSIONS)
1836 {
1837 UWORD32 wd_aln = ALIGN16(ps_cfg->u4_wd);
1838 UWORD32 ht_aln = ALIGN16(ps_cfg->u4_ht);
1839
1840 if (ps_curr_cfg->u4_wd != wd_aln || ps_curr_cfg->u4_ht != ht_aln
1841 || ps_curr_cfg->u4_disp_wd != ps_cfg->u4_disp_wd
1842 || ps_curr_cfg->u4_disp_ht != ps_cfg->u4_disp_ht)
1843 {
1844 ps_curr_cfg->u4_wd = wd_aln;
1845 ps_curr_cfg->u4_ht = ht_aln;
1846
1847 ps_curr_cfg->u4_disp_wd = ps_cfg->u4_disp_wd;
1848 ps_curr_cfg->u4_disp_ht = ps_cfg->u4_disp_ht;
1849
1850 ps_curr_cfg->i4_wd_mbs = ps_curr_cfg->u4_wd >> 4;
1851 ps_curr_cfg->i4_ht_mbs = ps_curr_cfg->u4_ht >> 4;
1852
1853 ps_codec->i4_rec_strd = ALIGN16(ps_cfg->u4_wd) + PAD_WD;
1854
1855 /* If number of MBs in a frame changes the air map also changes.
1856 * Hence recompute air map also reset air pic cnt */
1857 if (ps_codec->s_cfg.e_air_mode != IVE_AIR_MODE_NONE)
1858 {
1859 /* re-init the air map */
1860 ih264e_init_air_map(ps_codec);
1861
1862 /* reset air counter */
1863 ps_codec->i4_air_pic_cnt = -1;
1864 }
1865
1866 /* initialize mv bank buffer manager */
1867 err = ih264e_mv_buf_mgr_add_bufs(ps_codec);
1868 if (err != IH264E_SUCCESS)
1869 return err;
1870
1871 /* initialize ref bank buffer manager */
1872 err = ih264e_pic_buf_mgr_add_bufs(ps_codec);
1873 if (err != IH264E_SUCCESS)
1874 return err;
1875
1876 /* since dimension changed, start new sequence by forcing IDR */
1877 ps_codec->force_curr_frame_type = IV_IDR_FRAME;
1878
1879 /* in case dimension changes, we need to reinitialize RC as the
1880 * old model shall not fit further */
1881 u4_init_rc = 1;
1882
1883 /* when the dimension changes, the header needs to be regenerated */
1884 ps_codec->i4_gen_header = 1;
1885 }
1886 }
1887 else if (ps_cfg->e_cmd == IVE_CMD_CTL_SET_FRAMERATE)
1888 {
1889 /* temp var */
1890 UWORD32 u4_src_ticks, u4_tgt_ticks;
1891
1892 u4_src_ticks = ih264e_frame_time_get_src_ticks(
1893 ps_codec->s_rate_control.pps_frame_time);
1894
1895 u4_tgt_ticks = ih264e_frame_time_get_tgt_ticks(
1896 ps_codec->s_rate_control.pps_frame_time);
1897
1898 /* Change frame rate */
1899 if (ps_codec->s_cfg.u4_src_frame_rate
1900 != ps_cfg->u4_src_frame_rate * 1000)
1901 {
1902 ps_codec->s_cfg.u4_src_frame_rate = ps_cfg->u4_src_frame_rate
1903 * 1000;
1904
1905 ih264e_frame_time_update_src_frame_rate(
1906 ps_codec->s_rate_control.pps_frame_time,
1907 ps_codec->s_cfg.u4_src_frame_rate);
1908
1909 ih264_time_stamp_update_frame_rate(
1910 ps_codec->s_rate_control.pps_time_stamp,
1911 ps_codec->s_cfg.u4_src_frame_rate);
1912
1913 irc_change_frame_rate(ps_codec->s_rate_control.pps_rate_control_api,
1914 ps_codec->s_cfg.u4_src_frame_rate,
1915 u4_src_ticks, u4_tgt_ticks);
1916 }
1917
1918 if (ps_codec->s_cfg.u4_tgt_frame_rate
1919 != ps_cfg->u4_tgt_frame_rate * 1000)
1920 {
1921 ps_codec->s_cfg.u4_tgt_frame_rate = ps_cfg->u4_tgt_frame_rate
1922 * 1000;
1923
1924 ih264e_frame_time_update_tgt_frame_rate(
1925 ps_codec->s_rate_control.pps_frame_time,
1926 ps_codec->s_cfg.u4_tgt_frame_rate);
1927
1928 irc_change_frame_rate(ps_codec->s_rate_control.pps_rate_control_api,
1929 ps_codec->s_cfg.u4_src_frame_rate,
1930 u4_src_ticks, u4_tgt_ticks);
1931
1932 irc_change_frm_rate_for_bit_alloc(
1933 ps_codec->s_rate_control.pps_rate_control_api,
1934 ps_codec->s_cfg.u4_tgt_frame_rate);
1935 }
1936
1937 }
1938 else if (ps_cfg->e_cmd == IVE_CMD_CTL_SET_BITRATE)
1939 {
1940 if (ps_curr_cfg->u4_target_bitrate != ps_cfg->u4_target_bitrate)
1941 {
1942 if (IVE_RC_NONE != ps_curr_cfg->e_rc_mode)
1943 irc_change_avg_bit_rate(
1944 ps_codec->s_rate_control.pps_rate_control_api,
1945 ps_cfg->u4_target_bitrate);
1946
1947 ps_curr_cfg->u4_target_bitrate = ps_cfg->u4_target_bitrate;
1948 }
1949 }
1950 else if (ps_cfg->e_cmd == IVE_CMD_CTL_SET_FRAMETYPE)
1951 {
1952 switch (ps_cfg->e_frame_type)
1953 {
1954 case IV_I_FRAME:
1955 ps_codec->force_curr_frame_type = IV_I_FRAME;
1956 break;
1957
1958 case IV_IDR_FRAME:
1959 ps_codec->force_curr_frame_type = IV_IDR_FRAME;
1960 break;
1961
1962 case IV_P_FRAME:
1963 default:
1964 break;
1965 }
1966 }
1967 else if (ps_cfg->e_cmd == IVE_CMD_CTL_SET_ME_PARAMS)
1968 {
1969 if (ps_curr_cfg->u4_enc_speed_preset == IVE_CONFIG)
1970 {
1971 ps_codec->s_cfg.u4_enable_hpel = ps_cfg->u4_enable_hpel;
1972 ps_codec->s_cfg.u4_enable_fast_sad = ps_cfg->u4_enable_fast_sad;
1973 ps_codec->s_cfg.u4_me_speed_preset = ps_cfg->u4_me_speed_preset;
1974 ps_codec->s_cfg.u4_enable_qpel = ps_cfg->u4_enable_qpel;
1975 }
1976 else if (ps_curr_cfg->u4_enc_speed_preset == IVE_FASTEST)
1977 {
1978 ps_codec->s_cfg.u4_enable_fast_sad = ps_cfg->u4_enable_fast_sad;
1979 }
1980 ps_codec->s_cfg.u4_srch_rng_x = ps_cfg->u4_srch_rng_x;
1981 ps_codec->s_cfg.u4_srch_rng_y = ps_cfg->u4_srch_rng_y;
1982
1983 if (ps_codec->s_cfg.u4_enable_alt_ref != ps_cfg->u4_enable_alt_ref)
1984 {
1985 ps_codec->s_cfg.u4_enable_alt_ref = ps_cfg->u4_enable_alt_ref;
1986 ps_codec->u4_is_curr_frm_ref = 1;
1987 }
1988 }
1989 else if (ps_cfg->e_cmd == IVE_CMD_CTL_SET_IPE_PARAMS)
1990 {
1991 ps_curr_cfg->u4_enc_speed_preset = ps_cfg->u4_enc_speed_preset;
1992 ps_curr_cfg->u4_constrained_intra_pred = ps_cfg->u4_constrained_intra_pred;
1993 if (ps_curr_cfg->u4_enc_speed_preset == IVE_SLOWEST)
1994 {/* high quality */
1995 /* enable diamond search */
1996 ps_curr_cfg->u4_me_speed_preset = DMND_SRCH;
1997 ps_curr_cfg->u4_enable_fast_sad = 0;
1998
1999 /* disable intra 4x4 */
2000 ps_curr_cfg->u4_enable_intra_4x4 = 1;
2001 ps_codec->luma_energy_compaction[1] =
2002 ih264e_code_luma_intra_macroblock_4x4_rdopt_on;
2003
2004 /* sub pel off */
2005 ps_curr_cfg->u4_enable_hpel = 1;
2006
2007 /* deblocking off */
2008 ps_curr_cfg->u4_disable_deblock_level = DISABLE_DEBLK_LEVEL_0;
2009
2010 /* disabled intra inter gating in Inter slices */
2011 ps_codec->u4_inter_gate = 0;
2012 }
2013 else if (ps_curr_cfg->u4_enc_speed_preset == IVE_NORMAL)
2014 {/* normal */
2015 /* enable diamond search */
2016 ps_curr_cfg->u4_me_speed_preset = DMND_SRCH;
2017 ps_curr_cfg->u4_enable_fast_sad = 0;
2018
2019 /* disable intra 4x4 */
2020 ps_curr_cfg->u4_enable_intra_4x4 = 1;
2021
2022 /* sub pel off */
2023 ps_curr_cfg->u4_enable_hpel = 1;
2024
2025 /* deblocking off */
2026 ps_curr_cfg->u4_disable_deblock_level = DISABLE_DEBLK_LEVEL_0;
2027
2028 /* disabled intra inter gating in Inter slices */
2029 ps_codec->u4_inter_gate = 0;
2030 }
2031 else if (ps_curr_cfg->u4_enc_speed_preset == IVE_FAST)
2032 {/* normal */
2033 /* enable diamond search */
2034 ps_curr_cfg->u4_me_speed_preset = DMND_SRCH;
2035 ps_curr_cfg->u4_enable_fast_sad = 0;
2036
2037 /* disable intra 4x4 */
2038 ps_curr_cfg->u4_enable_intra_4x4 = 0;
2039
2040 /* sub pel off */
2041 ps_curr_cfg->u4_enable_hpel = 1;
2042
2043 /* deblocking off */
2044 ps_curr_cfg->u4_disable_deblock_level = DISABLE_DEBLK_LEVEL_0;
2045
2046 /* disabled intra inter gating in Inter slices */
2047 ps_codec->u4_inter_gate = 1;
2048 }
2049 else if (ps_curr_cfg->u4_enc_speed_preset == IVE_HIGH_SPEED)
2050 {/* fast */
2051 /* enable diamond search */
2052 ps_curr_cfg->u4_me_speed_preset = DMND_SRCH;
2053 ps_curr_cfg->u4_enable_fast_sad = 0;
2054
2055 /* disable intra 4x4 */
2056 ps_curr_cfg->u4_enable_intra_4x4 = 0;
2057
2058 /* sub pel off */
2059 ps_curr_cfg->u4_enable_hpel = 0;
2060
2061 /* deblocking off */
2062 ps_curr_cfg->u4_disable_deblock_level = DISABLE_DEBLK_LEVEL_4;
2063
2064 /* disabled intra inter gating in Inter slices */
2065 ps_codec->u4_inter_gate = 0;
2066 }
2067 else if (ps_curr_cfg->u4_enc_speed_preset == IVE_FASTEST)
2068 {/* fastest */
2069 /* enable diamond search */
2070 ps_curr_cfg->u4_me_speed_preset = DMND_SRCH;
2071 //u4_num_layers = 4;
2072
2073 /* disable intra 4x4 */
2074 ps_curr_cfg->u4_enable_intra_4x4 = 0;
2075
2076 /* sub pel off */
2077 ps_curr_cfg->u4_enable_hpel = 0;
2078
2079 /* deblocking off */
2080 ps_curr_cfg->u4_disable_deblock_level = DISABLE_DEBLK_LEVEL_4;
2081
2082 /* disabled intra inter gating in Inter slices */
2083 ps_codec->u4_inter_gate = 1;
2084 }
2085 else if (ps_curr_cfg->u4_enc_speed_preset == IVE_CONFIG)
2086 {
2087 ps_curr_cfg->u4_enable_intra_4x4 = ps_cfg->u4_enable_intra_4x4;
2088 }
2089 }
2090 else if (ps_cfg->e_cmd == IVE_CMD_CTL_SET_GOP_PARAMS)
2091 {
2092 if (ps_curr_cfg->u4_i_frm_interval != ps_cfg->u4_i_frm_interval)
2093 {
2094 ps_curr_cfg->u4_i_frm_interval = ps_cfg->u4_i_frm_interval;
2095
2096 /* reset air counter */
2097 ps_codec->i4_air_pic_cnt = -1;
2098
2099 /* re-init air map */
2100 ih264e_init_air_map(ps_codec);
2101
2102 /*Effect intra frame interval change*/
2103
2104 irc_change_intra_frm_int_call(
2105 ps_codec->s_rate_control.pps_rate_control_api,
2106 ps_curr_cfg->u4_i_frm_interval);
2107 }
2108
2109 ps_curr_cfg->u4_idr_frm_interval = ps_cfg->u4_idr_frm_interval;
2110
2111 }
2112 else if (ps_cfg->e_cmd == IVE_CMD_CTL_SET_DEBLOCK_PARAMS)
2113 {
2114 if (ps_curr_cfg->u4_enc_speed_preset == IVE_CONFIG)
2115 {
2116 ps_curr_cfg->u4_disable_deblock_level =
2117 ps_cfg->u4_disable_deblock_level;
2118 }
2119 }
2120 else if (ps_cfg->e_cmd == IVE_CMD_CTL_SET_QP)
2121 {
2122 UWORD8 au1_init_qp[MAX_PIC_TYPE];
2123 UWORD8 au1_min_max_qp[2 * MAX_PIC_TYPE];
2124
2125 ps_codec->s_cfg.u4_i_qp_max = ps_cfg->u4_i_qp_max;
2126 ps_codec->s_cfg.u4_i_qp_min = ps_cfg->u4_i_qp_min;
2127 ps_codec->s_cfg.u4_i_qp = ps_cfg->u4_i_qp;
2128
2129 ps_codec->s_cfg.u4_p_qp_max = ps_cfg->u4_p_qp_max;
2130 ps_codec->s_cfg.u4_p_qp_min = ps_cfg->u4_p_qp_min;
2131 ps_codec->s_cfg.u4_p_qp = ps_cfg->u4_p_qp;
2132
2133 ps_codec->s_cfg.u4_b_qp_max = ps_cfg->u4_b_qp_max;
2134 ps_codec->s_cfg.u4_b_qp_min = ps_cfg->u4_b_qp_min;
2135 ps_codec->s_cfg.u4_b_qp = ps_cfg->u4_b_qp;
2136
2137 /* update rc lib with modified qp */
2138 au1_init_qp[0] = gau1_h264_to_mpeg2_qmap[ps_codec->s_cfg.u4_i_qp];
2139 au1_init_qp[1] = gau1_h264_to_mpeg2_qmap[ps_codec->s_cfg.u4_p_qp];
2140 au1_init_qp[2] = gau1_h264_to_mpeg2_qmap[ps_codec->s_cfg.u4_b_qp];
2141
2142 irc_change_init_qp(ps_codec->s_rate_control.pps_rate_control_api,
2143 au1_init_qp);
2144
2145 au1_min_max_qp[2 * I_PIC] =
2146 gau1_h264_to_mpeg2_qmap[ps_codec->s_cfg.u4_i_qp_min];
2147 au1_min_max_qp[2 * I_PIC + 1] =
2148 gau1_h264_to_mpeg2_qmap[ps_codec->s_cfg.u4_i_qp_max];
2149
2150 au1_min_max_qp[2 * P_PIC] =
2151 gau1_h264_to_mpeg2_qmap[ps_codec->s_cfg.u4_p_qp_min];
2152 au1_min_max_qp[2 * P_PIC + 1] =
2153 gau1_h264_to_mpeg2_qmap[ps_codec->s_cfg.u4_p_qp_max];
2154
2155 au1_min_max_qp[2 * B_PIC] =
2156 gau1_h264_to_mpeg2_qmap[ps_codec->s_cfg.u4_b_qp_min];
2157 au1_min_max_qp[2 * B_PIC + 1] =
2158 gau1_h264_to_mpeg2_qmap[ps_codec->s_cfg.u4_b_qp_max];
2159
2160 irc_change_min_max_qp(ps_codec->s_rate_control.pps_rate_control_api,
2161 au1_min_max_qp);
2162 }
2163 else if (ps_cfg->e_cmd == IVE_CMD_CTL_SET_ENC_MODE)
2164 {
2165 ps_codec->s_cfg.e_enc_mode = ps_cfg->e_enc_mode;
2166
2167 if (ps_codec->s_cfg.e_enc_mode == IVE_ENC_MODE_HEADER)
2168 {
2169 ps_codec->i4_header_mode = 1;
2170 ps_codec->s_cfg.e_enc_mode = IVE_ENC_MODE_PICTURE;
2171 }
2172 else
2173 {
2174 ps_codec->i4_header_mode = 0;
2175 }
2176 }
2177 else if (ps_cfg->e_cmd == IVE_CMD_CTL_SET_VBV_PARAMS
2178 && IVE_RC_NONE != ps_codec->s_cfg.e_rc_mode)
2179 {
2180 ps_codec->s_cfg.u4_vbv_buf_size = ps_cfg->u4_vbv_buf_size;
2181 ps_codec->s_cfg.u4_vbv_buffer_delay = ps_cfg->u4_vbv_buffer_delay;
2182
2183 // irc_change_buffer_delay(ps_codec->s_rate_control.pps_rate_control_api, ps_codec->s_cfg.u4_vbv_buffer_delay);
2184
2185 // TODO: remove this when the support for changing buffer dynamically
2186 // is yet to be added.
2187 u4_init_rc = 1;
2188 }
2189 else if (ps_cfg->e_cmd == IVE_CMD_CTL_SET_AIR_PARAMS)
2190 {
2191 if (ps_curr_cfg->e_air_mode != ps_cfg->e_air_mode
2192 || ps_curr_cfg->u4_air_refresh_period
2193 != ps_cfg->u4_air_refresh_period)
2194 {
2195 ps_curr_cfg->e_air_mode = ps_cfg->e_air_mode;
2196 ps_curr_cfg->u4_air_refresh_period = ps_cfg->u4_air_refresh_period;
2197
2198 ih264e_init_air_map(ps_codec);
2199
2200 /* reset air counter */
2201 ps_codec->i4_air_pic_cnt = -1;
2202 }
2203 }
2204 else if (ps_cfg->e_cmd == IVE_CMD_CTL_SET_PROFILE_PARAMS)
2205 {
2206 ps_codec->s_cfg.e_profile = ps_cfg->e_profile;
2207 ps_codec->s_cfg.u4_entropy_coding_mode = ps_cfg->u4_entropy_coding_mode;
2208 }
2209 else if (ps_cfg->e_cmd == IVE_CMD_CTL_SET_NUM_CORES)
2210 {
2211 ps_codec->s_cfg.u4_num_cores = ps_cfg->u4_num_cores;
2212 }
2213
2214 /* reset RC model */
2215 if (u4_init_rc)
2216 {
2217 /* init qp */
2218 UWORD8 au1_init_qp[MAX_PIC_TYPE];
2219
2220 /* min max qp */
2221 UWORD8 au1_min_max_qp[2 * MAX_PIC_TYPE];
2222
2223 /* init i,p,b qp */
2224 au1_init_qp[0] = gau1_h264_to_mpeg2_qmap[ps_codec->s_cfg.u4_i_qp];
2225 au1_init_qp[1] = gau1_h264_to_mpeg2_qmap[ps_codec->s_cfg.u4_p_qp];
2226 au1_init_qp[2] = gau1_h264_to_mpeg2_qmap[ps_codec->s_cfg.u4_b_qp];
2227
2228 /* init min max qp */
2229 au1_min_max_qp[2 * I_PIC] =
2230 gau1_h264_to_mpeg2_qmap[ps_codec->s_cfg.u4_i_qp_min];
2231 au1_min_max_qp[2 * I_PIC + 1] =
2232 gau1_h264_to_mpeg2_qmap[ps_codec->s_cfg.u4_i_qp_max];
2233
2234 au1_min_max_qp[2 * P_PIC] =
2235 gau1_h264_to_mpeg2_qmap[ps_codec->s_cfg.u4_p_qp_min];
2236 au1_min_max_qp[2 * P_PIC + 1] =
2237 gau1_h264_to_mpeg2_qmap[ps_codec->s_cfg.u4_p_qp_max];
2238
2239 au1_min_max_qp[2 * B_PIC] =
2240 gau1_h264_to_mpeg2_qmap[ps_codec->s_cfg.u4_b_qp_min];
2241 au1_min_max_qp[2 * B_PIC + 1] =
2242 gau1_h264_to_mpeg2_qmap[ps_codec->s_cfg.u4_b_qp_max];
2243
2244 /* get rc mode */
2245 switch (ps_codec->s_cfg.e_rc_mode)
2246 {
2247 case IVE_RC_STORAGE:
2248 ps_codec->s_rate_control.e_rc_type = VBR_STORAGE;
2249 break;
2250
2251 case IVE_RC_CBR_NON_LOW_DELAY:
2252 ps_codec->s_rate_control.e_rc_type = CBR_NLDRC;
2253 break;
2254
2255 case IVE_RC_CBR_LOW_DELAY:
2256 ps_codec->s_rate_control.e_rc_type = CBR_LDRC;
2257 break;
2258
2259 case IVE_RC_NONE:
2260 ps_codec->s_rate_control.e_rc_type = CONST_QP;
2261 break;
2262
2263 default:
2264 break;
2265 }
2266
2267 /* init rate control */
2268 ih264e_rc_init(ps_codec->s_rate_control.pps_rate_control_api,
2269 ps_codec->s_rate_control.pps_frame_time,
2270 ps_codec->s_rate_control.pps_time_stamp,
2271 ps_codec->s_rate_control.pps_pd_frm_rate,
2272 ps_codec->s_cfg.u4_max_framerate,
2273 ps_codec->s_cfg.u4_src_frame_rate,
2274 ps_codec->s_cfg.u4_tgt_frame_rate,
2275 ps_codec->s_rate_control.e_rc_type,
2276 ps_codec->s_cfg.u4_target_bitrate,
2277 ps_codec->s_cfg.u4_max_bitrate,
2278 ps_codec->s_cfg.u4_vbv_buffer_delay,
2279 ps_codec->s_cfg.u4_i_frm_interval,
2280 ps_codec->s_cfg.u4_num_bframes + 1, au1_init_qp,
2281 ps_codec->s_cfg.u4_num_bframes + 2, au1_min_max_qp,
2282 ps_codec->s_cfg.u4_max_level);
2283 }
2284
2285 return err;
2286 }
2287
2288 /**
2289 *******************************************************************************
2290 *
2291 * @brief
2292 * Sets default encoder config parameters
2293 *
2294 * @par Description:
2295 * Sets default dynamic parameters. Will be called in ih264e_init() to ensure
2296 * that even if set_params is not called, codec continues to work
2297 *
2298 * @param[in] ps_cfg
2299 * Pointer to encoder config params
2300 *
2301 * @returns error status
2302 *
2303 * @remarks none
2304 *
2305 *******************************************************************************
2306 */
ih264e_set_default_params(cfg_params_t * ps_cfg)2307 static WORD32 ih264e_set_default_params(cfg_params_t *ps_cfg)
2308 {
2309 WORD32 ret = IV_SUCCESS;
2310
2311 ps_cfg->u4_max_wd = MAX_WD;
2312 ps_cfg->u4_max_ht = MAX_HT;
2313 ps_cfg->u4_max_ref_cnt = MAX_REF_CNT;
2314 ps_cfg->u4_max_reorder_cnt = MAX_REF_CNT;
2315 ps_cfg->u4_max_level = DEFAULT_MAX_LEVEL;
2316 ps_cfg->e_inp_color_fmt = IV_YUV_420SP_UV;
2317 ps_cfg->u4_enable_recon = DEFAULT_RECON_ENABLE;
2318 ps_cfg->e_recon_color_fmt = IV_YUV_420P;
2319 ps_cfg->u4_enc_speed_preset = IVE_FASTEST;
2320 ps_cfg->e_rc_mode = DEFAULT_RC;
2321 ps_cfg->u4_max_framerate = DEFAULT_MAX_FRAMERATE;
2322 ps_cfg->u4_max_bitrate = DEFAULT_MAX_BITRATE;
2323 ps_cfg->u4_num_bframes = DEFAULT_MAX_NUM_BFRAMES;
2324 ps_cfg->e_content_type = IV_PROGRESSIVE;
2325 ps_cfg->u4_max_srch_rng_x = DEFAULT_MAX_SRCH_RANGE_X;
2326 ps_cfg->u4_max_srch_rng_y = DEFAULT_MAX_SRCH_RANGE_Y;
2327 ps_cfg->e_slice_mode = IVE_SLICE_MODE_NONE;
2328 ps_cfg->u4_slice_param = DEFAULT_SLICE_PARAM;
2329 ps_cfg->e_arch = ih264e_default_arch();
2330 ps_cfg->e_soc = SOC_GENERIC;
2331 ps_cfg->u4_disp_wd = MAX_WD;
2332 ps_cfg->u4_disp_ht = MAX_HT;
2333 ps_cfg->u4_wd = MAX_WD;
2334 ps_cfg->u4_ht = MAX_HT;
2335 ps_cfg->u4_src_frame_rate = DEFAULT_SRC_FRAME_RATE;
2336 ps_cfg->u4_tgt_frame_rate = DEFAULT_TGT_FRAME_RATE;
2337 ps_cfg->u4_target_bitrate = DEFAULT_BITRATE;
2338 ps_cfg->e_frame_type = IV_NA_FRAME;
2339 ps_cfg->e_enc_mode = IVE_ENC_MODE_DEFAULT;
2340 ps_cfg->u4_i_qp = DEFAULT_I_QP;
2341 ps_cfg->u4_p_qp = DEFAULT_P_QP;
2342 ps_cfg->u4_b_qp = DEFAULT_B_QP;
2343 ps_cfg->u4_i_qp_min = DEFAULT_QP_MIN;
2344 ps_cfg->u4_i_qp_max = DEFAULT_QP_MAX;
2345 ps_cfg->u4_p_qp_min = DEFAULT_QP_MIN;
2346 ps_cfg->u4_p_qp_max = DEFAULT_QP_MAX;
2347 ps_cfg->u4_b_qp_min = DEFAULT_QP_MIN;
2348 ps_cfg->u4_b_qp_max = DEFAULT_QP_MAX;
2349 ps_cfg->e_air_mode = DEFAULT_AIR_MODE;
2350 ps_cfg->u4_air_refresh_period = DEFAULT_AIR_REFRESH_PERIOD;
2351 ps_cfg->u4_vbv_buffer_delay = DEFAULT_VBV_DELAY;
2352 ps_cfg->u4_vbv_buf_size = DEFAULT_VBV_SIZE;
2353 ps_cfg->u4_num_cores = DEFAULT_NUM_CORES;
2354 ps_cfg->u4_me_speed_preset = DEFAULT_ME_SPEED_PRESET;
2355 ps_cfg->u4_enable_hpel = DEFAULT_HPEL;
2356 ps_cfg->u4_enable_qpel = DEFAULT_QPEL;
2357 ps_cfg->u4_enable_intra_4x4 = DEFAULT_I4;
2358 ps_cfg->u4_enable_intra_8x8 = DEFAULT_I8;
2359 ps_cfg->u4_enable_intra_16x16 = DEFAULT_I16;
2360 ps_cfg->u4_enable_fast_sad = DEFAULT_ENABLE_FAST_SAD;
2361 ps_cfg->u4_enable_satqd = DEFAULT_ENABLE_SATQD;
2362 ps_cfg->i4_min_sad =
2363 (ps_cfg->u4_enable_satqd == DEFAULT_ENABLE_SATQD) ?
2364 DEFAULT_MIN_SAD_ENABLE :
2365 DEFAULT_MIN_SAD_DISABLE;
2366 ps_cfg->u4_srch_rng_x = DEFAULT_SRCH_RNG_X;
2367 ps_cfg->u4_srch_rng_y = DEFAULT_SRCH_RNG_Y;
2368 ps_cfg->u4_i_frm_interval = DEFAULT_I_INTERVAL;
2369 ps_cfg->u4_idr_frm_interval = DEFAULT_IDR_INTERVAL;
2370 ps_cfg->u4_disable_deblock_level = DEFAULT_DISABLE_DEBLK_LEVEL;
2371 ps_cfg->e_profile = DEFAULT_PROFILE;
2372 ps_cfg->u4_timestamp_low = 0;
2373 ps_cfg->u4_timestamp_high = 0;
2374 ps_cfg->u4_is_valid = 1;
2375 ps_cfg->e_cmd = IVE_CMD_CT_NA;
2376 ps_cfg->i4_wd_mbs = ps_cfg->u4_max_wd >> 4;
2377 ps_cfg->i4_ht_mbs = ps_cfg->u4_max_ht >> 4;
2378 ps_cfg->u4_entropy_coding_mode = CAVLC;
2379 ps_cfg->u4_weighted_prediction = 0;
2380 ps_cfg->u4_constrained_intra_pred = 0;
2381 ps_cfg->u4_pic_info_type = 0;
2382 ps_cfg->u4_mb_info_type = 0;
2383
2384 return ret;
2385 }
2386
2387 /**
2388 *******************************************************************************
2389 *
2390 * @brief
2391 * Initialize encoder context. This will be called by init_mem_rec and during
2392 * codec reset
2393 *
2394 * @par Description:
2395 * Initializes the context
2396 *
2397 * @param[in] ps_codec
2398 * Codec context pointer
2399 *
2400 * @returns error status
2401 *
2402 * @remarks none
2403 *
2404 *******************************************************************************
2405 */
ih264e_init(codec_t * ps_codec)2406 static WORD32 ih264e_init(codec_t *ps_codec)
2407 {
2408 /* enc config param set */
2409 cfg_params_t *ps_cfg = &(ps_codec->s_cfg);
2410
2411 /* temp var */
2412 WORD32 i;
2413
2414 /* coded pic count */
2415 ps_codec->i4_poc = 0;
2416
2417 /* Number of API calls to encode are made */
2418 ps_codec->i4_encode_api_call_cnt = -1;
2419
2420 /* Indicates no header has been generated yet */
2421 ps_codec->u4_header_generated = 0;
2422
2423 /* Number of pictures encoded */
2424 ps_codec->i4_pic_cnt = -1;
2425
2426 /* Number of threads created */
2427 ps_codec->i4_proc_thread_cnt = 0;
2428
2429 /* ctl mutex init */
2430 ithread_mutex_init(ps_codec->pv_ctl_mutex);
2431
2432 /* Set encoder chroma format */
2433 ps_codec->e_codec_color_format =
2434 (ps_cfg->e_inp_color_fmt == IV_YUV_420SP_VU) ?
2435 IV_YUV_420SP_VU : IV_YUV_420SP_UV;
2436
2437 /* Number of continuous frames where deblocking was disabled */
2438 ps_codec->i4_disable_deblk_pic_cnt = 0;
2439
2440 /* frame num */
2441 ps_codec->i4_frame_num = 0;
2442
2443 /* set the current frame type to I frame, since we are going to start encoding*/
2444 ps_codec->force_curr_frame_type = IV_NA_FRAME;
2445
2446 /* idr_pic_id */
2447 ps_codec->i4_idr_pic_id = -1;
2448
2449 /* Flush mode */
2450 ps_codec->i4_flush_mode = 0;
2451
2452 /* Encode header mode */
2453 ps_codec->i4_header_mode = 0;
2454
2455 /* Encode generate header */
2456 ps_codec->i4_gen_header = 0;
2457
2458 /* To signal successful completion of init */
2459 ps_codec->i4_init_done = 1;
2460
2461 /* To signal that at least one picture was decoded */
2462 ps_codec->i4_first_pic_done = 0;
2463
2464 /* Reset Codec */
2465 ps_codec->i4_reset_flag = 0;
2466
2467 /* Current error code */
2468 ps_codec->i4_error_code = IH264E_SUCCESS;
2469
2470 /* threshold residue */
2471 ps_codec->u4_thres_resi = 1;
2472
2473 /* inter gating enable */
2474 ps_codec->u4_inter_gate = 0;
2475
2476 /* entropy mutex init */
2477 ithread_mutex_init(ps_codec->pv_entropy_mutex);
2478
2479 /* sps id */
2480 ps_codec->i4_sps_id = 0;
2481
2482 /* sps id */
2483 ps_codec->i4_pps_id = 0;
2484
2485 /* Process thread created status */
2486 memset(ps_codec->ai4_process_thread_created, 0, MAX_PROCESS_THREADS);
2487
2488 /* Number of MBs processed together */
2489 ps_codec->i4_proc_nmb = 8;
2490
2491 /* Previous POC msb */
2492 ps_codec->i4_prev_poc_msb = 0;
2493
2494 /* Previous POC lsb */
2495 ps_codec->i4_prev_poc_lsb = -1;
2496
2497 /* max Previous POC lsb */
2498 ps_codec->i4_max_prev_poc_lsb = -1;
2499
2500 /* sps, pps status */
2501 {
2502 sps_t *ps_sps = ps_codec->ps_sps_base;
2503 pps_t *ps_pps = ps_codec->ps_pps_base;
2504
2505 for (i = 0; i < MAX_SPS_CNT; i++)
2506 {
2507 ps_sps->i1_sps_valid = 0;
2508 ps_sps++;
2509 }
2510
2511 for (i = 0; i < MAX_PPS_CNT; i++)
2512 {
2513 ps_pps->i1_pps_valid = 0;
2514 ps_pps++;
2515 }
2516 }
2517
2518 {
2519 WORD32 max_mb_rows = ps_cfg->i4_ht_mbs;
2520
2521 WORD32 num_jobs = max_mb_rows * MAX_CTXT_SETS;
2522 WORD32 clz;
2523
2524 /* Use next power of two number of entries*/
2525 clz = CLZ(num_jobs);
2526 num_jobs = 1 << (32 - clz);
2527
2528 /* init process jobq */
2529 ps_codec->pv_proc_jobq = ih264_list_init(
2530 ps_codec->pv_proc_jobq_buf,
2531 ps_codec->i4_proc_jobq_buf_size, num_jobs,
2532 sizeof(job_t), 10);
2533 RETURN_IF((ps_codec->pv_proc_jobq == NULL), IV_FAIL);
2534 ih264_list_reset(ps_codec->pv_proc_jobq);
2535
2536 /* init entropy jobq */
2537 ps_codec->pv_entropy_jobq = ih264_list_init(
2538 ps_codec->pv_entropy_jobq_buf,
2539 ps_codec->i4_entropy_jobq_buf_size, num_jobs,
2540 sizeof(job_t), 10);
2541 RETURN_IF((ps_codec->pv_entropy_jobq == NULL), IV_FAIL);
2542 ih264_list_reset(ps_codec->pv_entropy_jobq);
2543 }
2544
2545 /* Update the jobq context to all the threads */
2546 for (i = 0; i < MAX_PROCESS_CTXT; i++)
2547 {
2548 ps_codec->as_process[i].pv_proc_jobq = ps_codec->pv_proc_jobq;
2549 ps_codec->as_process[i].pv_entropy_jobq = ps_codec->pv_entropy_jobq;
2550
2551 /* i4_id always stays between 0 and MAX_PROCESS_THREADS */
2552 ps_codec->as_process[i].i4_id =
2553 (i >= MAX_PROCESS_THREADS) ?
2554 (i - MAX_PROCESS_THREADS) : i;
2555 ps_codec->as_process[i].ps_codec = ps_codec;
2556
2557 ps_codec->as_process[i].s_entropy.pv_proc_jobq = ps_codec->pv_proc_jobq;
2558 ps_codec->as_process[i].s_entropy.pv_entropy_jobq =
2559 ps_codec->pv_entropy_jobq;
2560 ps_codec->as_process[i].s_entropy.i4_abs_pic_order_cnt = -1;
2561 }
2562
2563 /* Initialize MV Bank buffer manager */
2564 ps_codec->pv_mv_buf_mgr = ih264_buf_mgr_init(ps_codec->pv_mv_buf_mgr_base);
2565
2566 /* Initialize Picture buffer manager for reference buffers*/
2567 ps_codec->pv_ref_buf_mgr = ih264_buf_mgr_init(
2568 ps_codec->pv_ref_buf_mgr_base);
2569
2570 /* Initialize Picture buffer manager for input buffers*/
2571 ps_codec->pv_inp_buf_mgr = ih264_buf_mgr_init(
2572 ps_codec->pv_inp_buf_mgr_base);
2573
2574 /* Initialize buffer manager for output buffers*/
2575 ps_codec->pv_out_buf_mgr = ih264_buf_mgr_init(
2576 ps_codec->pv_out_buf_mgr_base);
2577
2578 /* buffer cnt in buffer manager */
2579 ps_codec->i4_inp_buf_cnt = 0;
2580 ps_codec->i4_out_buf_cnt = 0;
2581 ps_codec->i4_ref_buf_cnt = 0;
2582
2583 ps_codec->ps_pic_buf = (pic_buf_t *) ps_codec->pv_pic_buf_base;
2584 memset(ps_codec->ps_pic_buf, 0, BUF_MGR_MAX_CNT * sizeof(pic_buf_t));
2585
2586 /* Initialize dpb manager */
2587 ih264_dpb_mgr_init((dpb_mgr_t*) ps_codec->pv_dpb_mgr);
2588
2589 memset(ps_codec->as_ref_set, 0,
2590 sizeof(ref_set_t) * (MAX_DPB_SIZE + MAX_CTXT_SETS));
2591 for (i = 0; i < (MAX_DPB_SIZE + MAX_CTXT_SETS); i++)
2592 {
2593 ps_codec->as_ref_set[i].i4_pic_cnt = -1;
2594 }
2595
2596 /* fn ptr init */
2597 ih264e_init_function_ptr(ps_codec);
2598
2599 /* reset status flags */
2600 for (i = 0; i < MAX_CTXT_SETS; i++)
2601 {
2602 ps_codec->au4_entropy_thread_active[i] = 0;
2603 ps_codec->ai4_pic_cnt[i] = -1;
2604
2605 ps_codec->s_rate_control.pre_encode_skip[i] = 0;
2606 ps_codec->s_rate_control.post_encode_skip[i] = 0;
2607 }
2608
2609 ps_codec->s_rate_control.num_intra_in_prev_frame = 0;
2610 ps_codec->s_rate_control.i4_avg_activity = 0;
2611
2612 return IV_SUCCESS;
2613 }
2614
2615 /**
2616 *******************************************************************************
2617 *
2618 * @brief
2619 * Gets number of memory records required by the codec
2620 *
2621 * @par Description:
2622 * Gets codec memory requirements
2623 *
2624 * @param[in] pv_api_ip
2625 * Pointer to input argument structure
2626 *
2627 * @param[out] pv_api_op
2628 * Pointer to output argument structure
2629 *
2630 * @returns status
2631 *
2632 * @remarks
2633 *
2634 *******************************************************************************
2635 */
ih264e_get_num_rec(void * pv_api_ip,void * pv_api_op)2636 static WORD32 ih264e_get_num_rec(void *pv_api_ip, void *pv_api_op)
2637 {
2638 /* api call I/O structures */
2639 ih264e_num_mem_rec_op_t *ps_op = pv_api_op;
2640
2641 UNUSED(pv_api_ip);
2642
2643 ps_op->s_ive_op.u4_num_mem_rec = MEM_REC_CNT;
2644
2645 return IV_SUCCESS;
2646 }
2647
2648 /**
2649 *******************************************************************************
2650 *
2651 * @brief
2652 * Fills memory records of the codec
2653 *
2654 * @par Description:
2655 * Fills codec memory requirements
2656 *
2657 * @param[in] pv_api_ip
2658 * Pointer to input argument structure
2659 *
2660 * @param[out] pv_api_op
2661 * Pointer to output argument structure
2662 *
2663 * @returns error status
2664 *
2665 * @remarks none
2666 *
2667 *******************************************************************************
2668 */
ih264e_fill_num_mem_rec(void * pv_api_ip,void * pv_api_op)2669 static WORD32 ih264e_fill_num_mem_rec(void *pv_api_ip, void *pv_api_op)
2670 {
2671 /* api call I/O structures */
2672 ih264e_fill_mem_rec_ip_t *ps_ip = pv_api_ip;
2673 ih264e_fill_mem_rec_op_t *ps_op = pv_api_op;
2674
2675 /* profile / level info */
2676 WORD32 level;
2677 WORD32 num_reorder_frames;
2678 WORD32 num_ref_frames;
2679
2680 /* mem records */
2681 WORD32 no_of_mem_rec;
2682 iv_mem_rec_t *ps_mem_rec_base, *ps_mem_rec;
2683
2684 /* frame dimensions */
2685 WORD32 max_wd_luma, max_ht_luma;
2686 WORD32 max_mb_rows, max_mb_cols, max_mb_cnt;
2687
2688 /* temp var */
2689 WORD32 i;
2690
2691 /* error status */
2692 IV_STATUS_T status = IV_SUCCESS;
2693
2694 num_reorder_frames = ps_ip->s_ive_ip.u4_max_reorder_cnt;
2695 num_ref_frames = ps_ip->s_ive_ip.u4_max_ref_cnt;
2696
2697 /* mem records */
2698 ps_mem_rec_base = ps_ip->s_ive_ip.ps_mem_rec;
2699 no_of_mem_rec = ps_ip->s_ive_ip.u4_num_mem_rec;
2700
2701 /* frame dimensions */
2702 max_ht_luma = ps_ip->s_ive_ip.u4_max_ht;
2703 max_wd_luma = ps_ip->s_ive_ip.u4_max_wd;
2704 max_ht_luma = ALIGN16(max_ht_luma);
2705 max_wd_luma = ALIGN16(max_wd_luma);
2706 max_mb_rows = max_ht_luma / MB_SIZE;
2707 max_mb_cols = max_wd_luma / MB_SIZE;
2708 max_mb_cnt = max_mb_rows * max_mb_cols;
2709
2710 /* profile / level info */
2711 level = ih264e_get_min_level(max_ht_luma, max_wd_luma);
2712
2713 /* validate params */
2714 if ((level < MIN_LEVEL) || (level > MAX_LEVEL))
2715 {
2716 ps_op->s_ive_op.u4_error_code |= IH264E_CODEC_LEVEL_NOT_SUPPORTED;
2717 level = MAX_LEVEL;
2718 }
2719
2720 if (num_ref_frames > MAX_REF_CNT)
2721 {
2722 ps_op->s_ive_op.u4_error_code |= IH264E_NUM_REF_UNSUPPORTED;
2723 num_ref_frames = MAX_REF_CNT;
2724 }
2725
2726 if (num_reorder_frames > MAX_REF_CNT)
2727 {
2728 ps_op->s_ive_op.u4_error_code |= IH264E_NUM_REORDER_UNSUPPORTED;
2729 num_reorder_frames = MAX_REF_CNT;
2730 }
2731
2732 /* Set all memory records as persistent and alignment as 128 by default */
2733 ps_mem_rec = ps_mem_rec_base;
2734 for (i = 0; i < no_of_mem_rec; i++)
2735 {
2736 ps_mem_rec->u4_mem_alignment = 128;
2737 ps_mem_rec->e_mem_type = IV_EXTERNAL_CACHEABLE_PERSISTENT_MEM;
2738 ps_mem_rec++;
2739 }
2740
2741 /************************************************************************
2742 * Request memory for h264 encoder handle *
2743 ***********************************************************************/
2744 ps_mem_rec = &ps_mem_rec_base[MEM_REC_IV_OBJ];
2745 {
2746 ps_mem_rec->u4_mem_size = sizeof(iv_obj_t);
2747 }
2748 DEBUG("\nMemory record Id %d = %d \n", MEM_REC_IV_OBJ, ps_mem_rec->u4_mem_size);
2749
2750 /************************************************************************
2751 * Request memory for h264 encoder context *
2752 ***********************************************************************/
2753 ps_mem_rec = &ps_mem_rec_base[MEM_REC_CODEC];
2754 {
2755 ps_mem_rec->u4_mem_size = sizeof(codec_t);
2756 }
2757 DEBUG("\nMemory record Id %d = %d \n", MEM_REC_CODEC, ps_mem_rec->u4_mem_size);
2758
2759 /************************************************************************
2760 * Request memory for CABAC context *
2761 ***********************************************************************/
2762 ps_mem_rec = &ps_mem_rec_base[MEM_REC_CABAC];
2763 {
2764 ps_mem_rec->u4_mem_size = sizeof(cabac_ctxt_t);
2765 }
2766 DEBUG("\nMemory record Id %d = %d \n", MEM_REC_CABAC, ps_mem_rec->u4_mem_size);
2767
2768 /************************************************************************
2769 * Request memory for CABAC MB info *
2770 ***********************************************************************/
2771 ps_mem_rec = &ps_mem_rec_base[MEM_REC_CABAC_MB_INFO];
2772 {
2773 ps_mem_rec->u4_mem_size = ((max_mb_cols + 1) + 1)
2774 * sizeof(mb_info_ctxt_t);
2775 }
2776 DEBUG("\nMemory record Id %d = %d \n", MEM_REC_CABAC_MB_INFO, ps_mem_rec->u4_mem_size);
2777
2778
2779 /************************************************************************
2780 * Request memory for entropy context *
2781 * In multi core encoding, each row is assumed to be launched on a *
2782 * thread. The rows below can only start after its neighbors are coded *
2783 * The status of an mb coded/uncoded is signaled via entropy map. *
2784 * 1. One word32 to store skip run cnt *
2785 * 2. mb entropy map (mb status entropy coded/uncoded). The size*
2786 * of the entropy map is max mb cols. Further allocate one *
2787 * more additional row to evade checking for row -1. *
2788 * 3. size of bit stream buffer to store bit stream ctxt. *
2789 * 4. Entropy coding is dependent on nnz coefficient count for *
2790 * the neighbor blocks. It is sufficient to maintain one row *
2791 * worth of nnz as entropy for lower row waits on entropy map*
2792 ************************************************************************/
2793 ps_mem_rec = &ps_mem_rec_base[MEM_REC_ENTROPY];
2794 {
2795 /* total size of the mem record */
2796 WORD32 total_size = 0;
2797
2798 /* size of skip mb run */
2799 total_size += sizeof(WORD32);
2800 total_size = ALIGN8(total_size);
2801
2802 /* size in bytes to store entropy status of an entire frame */
2803 total_size += (max_mb_cols * max_mb_rows);
2804 /* add an additional 1 row of bytes to evade the special case of row 0 */
2805 total_size += max_mb_cols;
2806 total_size = ALIGN128(total_size);
2807
2808 /* size of bit stream buffer */
2809 total_size += sizeof(bitstrm_t);
2810 total_size = ALIGN128(total_size);
2811
2812 /* top nnz luma */
2813 total_size += (max_mb_cols * 4 * sizeof(UWORD8));
2814 total_size = ALIGN128(total_size);
2815
2816 /* top nnz cbcr */
2817 total_size += (max_mb_cols * 4 * sizeof(UWORD8));
2818 total_size = ALIGN128(total_size);
2819
2820 /* total size per each proc ctxt */
2821 total_size *= MAX_CTXT_SETS;
2822
2823 ps_mem_rec->u4_mem_size = total_size;
2824 }
2825 DEBUG("\nMemory record Id %d = %d \n", MEM_REC_ENTROPY, ps_mem_rec->u4_mem_size);
2826
2827 /************************************************************************
2828 * The residue coefficients that needs to be entropy coded are packed *
2829 * at a buffer space by the proc threads. The entropy thread shall *
2830 * read from the buffer space, unpack them and encode the same. The *
2831 * buffer space required to pack a row of mbs are as follows. *
2832 * Assuming transform_8x8_flag is disabled, *
2833 * In the worst case, 1 mb contains 1 dc 4x4 luma sub block, followed *
2834 * by 16 ac 4x4 luma sub blocks, 2 dc chroma 2x2 sub blocks, followed *
2835 * by 8 ac 4x4 chroma sub blocks. *
2836 * For the sake of simplicity we assume that all sub blocks are of *
2837 * type 4x4. The packing of each 4x4 is depicted by the structure *
2838 * tu_sblk_coeff_data_t *
2839 ************************************************************************/
2840 ps_mem_rec = &ps_mem_rec_base[MEM_REC_MB_COEFF_DATA];
2841 {
2842 /* temp var */
2843 WORD32 size = 0;
2844
2845 /* size of coeff data of 1 mb */
2846 size += sizeof(tu_sblk_coeff_data_t) * MAX_4x4_SUBBLKS;
2847
2848 /* size of coeff data of 1 row of mb's */
2849 size *= max_mb_cols;
2850
2851 /* align to avoid any false sharing across threads */
2852 size = ALIGN64(size);
2853
2854 /* size for one full frame */
2855 size *= max_mb_rows;
2856
2857 /* size of each proc buffer set (ping, pong) */
2858 size *= MAX_CTXT_SETS;
2859
2860 ps_mem_rec->u4_mem_size = size;
2861 }
2862 DEBUG("\nMemory record Id %d = %d \n", MEM_REC_MB_COEFF_DATA, ps_mem_rec->u4_mem_size);
2863
2864 /************************************************************************
2865 * while encoding an mb, the mb header data is signaled to the entropy*
2866 * thread by writing to a buffer space. the size of header data per mb *
2867 * is assumed to be 40 bytes *
2868 * TODO: revisit this inference *
2869 ************************************************************************/
2870 ps_mem_rec = &ps_mem_rec_base[MEM_REC_MB_HEADER_DATA];
2871 {
2872 /* temp var */
2873 WORD32 size;
2874
2875 /* size per MB */
2876 size = 40;
2877
2878 /* size for 1 row of mbs */
2879 size = size * max_mb_cols;
2880
2881 /* align to avoid any false sharing across threads */
2882 size = ALIGN64(size);
2883
2884 /* size for one full frame */
2885 size *= max_mb_rows;
2886
2887 /* size of each proc buffer set (ping, pong) */
2888 size *= MAX_CTXT_SETS;
2889
2890 ps_mem_rec->u4_mem_size = size;
2891 }
2892 DEBUG("\nMemory record Id %d = %d \n", MEM_REC_MB_HEADER_DATA, ps_mem_rec->u4_mem_size);
2893
2894 /************************************************************************
2895 * Size for holding mv_buf_t for each MV Bank. *
2896 * Note this allocation is done for BUF_MGR_MAX_CNT instead of *
2897 * MAX_DPB_SIZE or max_dpb_size for following reasons *
2898 * max_dpb_size will be based on max_wd and max_ht *
2899 * For higher max_wd and max_ht this number will be smaller than *
2900 * MAX_DPB_SIZE But during actual initialization number of buffers *
2901 * allocated can be more. *
2902 * *
2903 * One extra MV Bank is needed to hold current pics MV bank. *
2904 * Since this is only a structure allocation and not actual buffer *
2905 * allocation, it is allocated for BUF_MGR_MAX_CNT entries *
2906 ************************************************************************/
2907 ps_mem_rec = &ps_mem_rec_base[MEM_REC_MVBANK];
2908 {
2909 /* max luma samples */
2910 WORD32 max_luma_samples = 0;
2911
2912 /* determine max luma samples */
2913 for (i = 0; i < 16; i++)
2914 if (level ==(WORD32)gas_ih264_lvl_tbl[i].u4_level_idc)
2915 max_luma_samples = gas_ih264_lvl_tbl[i].u4_max_fs
2916 << (BLK_SIZE + BLK_SIZE);
2917
2918 ps_mem_rec->u4_mem_size = ih264_buf_mgr_size();
2919
2920 /************************************************************************
2921 * Allocate for pu_map, enc_pu_t and pic_pu_idx for each MV bank *
2922 * Note: Number of luma samples is not max_wd * max_ht here, instead it *
2923 * is set to maximum number of luma samples allowed at the given level. *
2924 * This is done to ensure that any stream with width and height lesser *
2925 * than max_wd and max_ht is supported. Number of buffers required can *
2926 * be greater for lower width and heights at a given level and this *
2927 * increased number of buffers might require more memory than what *
2928 * max_wd and max_ht buffer would have required Also note one extra *
2929 * buffer is allocated to store current pictures MV bank. *
2930 ***********************************************************************/
2931
2932 ps_mem_rec->u4_mem_size += BUF_MGR_MAX_CNT * sizeof(mv_buf_t);
2933
2934 ps_mem_rec->u4_mem_size += (num_ref_frames + num_reorder_frames
2935 + MAX_CTXT_SETS)
2936 * ih264e_get_pic_mv_bank_size(max_luma_samples);
2937 }
2938 DEBUG("\nMemory record Id %d = %d \n", MEM_REC_MVBANK, ps_mem_rec->u4_mem_size);
2939
2940 /************************************************************************
2941 * While encoding inter slices, to compute the cost of encoding an mb *
2942 * with the mv's at hand, we employ the expression cost = sad + lambda *
2943 * x mv_bits. Here mv_bits is the total number of bits taken to represe*
2944 * nt the mv in the stream. The mv bits for all the possible mv are *
2945 * stored in the look up table. The mem record for this look up table *
2946 * is given below. *
2947 ************************************************************************/
2948 ps_mem_rec = &ps_mem_rec_base[MEM_REC_MVBITS];
2949 {
2950 /* max srch range x */
2951 UWORD32 u4_srch_range_x = ps_ip->s_ive_ip.u4_max_srch_rng_x;
2952
2953 /* max srch range y */
2954 UWORD32 u4_srch_range_y = ps_ip->s_ive_ip.u4_max_srch_rng_y;
2955
2956 /* max srch range */
2957 UWORD32 u4_max_srch_range = MAX(u4_srch_range_x, u4_srch_range_y);
2958
2959 /* due to subpel */
2960 u4_max_srch_range <<= 2;
2961
2962 /* due to mv on either direction */
2963 u4_max_srch_range = (u4_max_srch_range << 1);
2964
2965 /* due to pred mv + zero */
2966 u4_max_srch_range = (u4_max_srch_range << 1) + 1;
2967
2968 u4_max_srch_range = ALIGN128(u4_max_srch_range);
2969
2970 ps_mem_rec->u4_mem_size = u4_max_srch_range;
2971 }
2972 DEBUG("\nMemory record Id %d = %d \n", MEM_REC_MVBITS, ps_mem_rec->u4_mem_size);
2973
2974 /************************************************************************
2975 * Request memory for SPS *
2976 ***********************************************************************/
2977 ps_mem_rec = &ps_mem_rec_base[MEM_REC_SPS];
2978 {
2979 ps_mem_rec->u4_mem_size = MAX_SPS_CNT * sizeof(sps_t);
2980 }
2981 DEBUG("\nMemory record Id %d = %d \n", MEM_REC_SPS, ps_mem_rec->u4_mem_size);
2982
2983 /************************************************************************
2984 * Request memory for PPS *
2985 ***********************************************************************/
2986 ps_mem_rec = &ps_mem_rec_base[MEM_REC_PPS];
2987 {
2988 ps_mem_rec->u4_mem_size = MAX_PPS_CNT * sizeof(pps_t);
2989 }
2990 DEBUG("\nMemory record Id %d = %d \n", MEM_REC_PPS, ps_mem_rec->u4_mem_size);
2991
2992 /************************************************************************
2993 * Request memory for Slice Header *
2994 ***********************************************************************/
2995 ps_mem_rec = &ps_mem_rec_base[MEM_REC_SLICE_HDR];
2996 {
2997 ps_mem_rec->u4_mem_size = MAX_CTXT_SETS * MAX_SLICE_HDR_CNT
2998 * sizeof(slice_header_t);
2999 }
3000 DEBUG("\nMemory record Id %d = %d \n", MEM_REC_SLICE_HDR, ps_mem_rec->u4_mem_size);
3001
3002 /************************************************************************
3003 * Request memory for Adaptive Intra Refresh *
3004 ***********************************************************************/
3005 ps_mem_rec = &ps_mem_rec_base[MEM_REC_AIR_MAP];
3006 {
3007 /* total size of the mem record */
3008 WORD32 total_size = 0;
3009
3010 /* intra coded map */
3011 total_size += max_mb_cnt;
3012 total_size *= MAX_CTXT_SETS;
3013
3014 /* mb refresh map */
3015 total_size += sizeof(UWORD16) * max_mb_cnt;
3016
3017 /* alignment */
3018 total_size = ALIGN128(total_size);
3019
3020 ps_mem_rec->u4_mem_size = total_size;
3021 }
3022 DEBUG("\nMemory record Id %d = %d \n", MEM_REC_AIR_MAP, ps_mem_rec->u4_mem_size);
3023
3024 /************************************************************************
3025 * In multi slice encoding, this memory record helps tracking the start*
3026 * of slice with reference to mb. *
3027 * MEM RECORD for holding *
3028 * 1. mb slice map *
3029 ************************************************************************/
3030 ps_mem_rec = &ps_mem_rec_base[MEM_REC_SLICE_MAP];
3031 {
3032 /* total size of the mem record */
3033 WORD32 total_size = 0;
3034
3035 /* size in bytes to slice index of all mbs of a frame */
3036 total_size = ALIGN64(max_mb_cnt);
3037
3038 /* ih264e_update_proc_ctxt can overread by 1 at the end */
3039 total_size += 1;
3040
3041 /* total size per each proc ctxt */
3042 total_size *= MAX_CTXT_SETS;
3043 ps_mem_rec->u4_mem_size = total_size;
3044 }
3045 DEBUG("\nMemory record Id %d = %d \n", MEM_REC_SLICE_MAP, ps_mem_rec->u4_mem_size);
3046
3047 /************************************************************************
3048 * Request memory to hold thread handles for each processing thread *
3049 ************************************************************************/
3050 ps_mem_rec = &ps_mem_rec_base[MEM_REC_THREAD_HANDLE];
3051 {
3052 WORD32 handle_size = ithread_get_handle_size();
3053
3054 ps_mem_rec->u4_mem_size = MAX_PROCESS_THREADS * handle_size;
3055 }
3056 DEBUG("\nMemory record Id %d = %d \n", MEM_REC_THREAD_HANDLE, ps_mem_rec->u4_mem_size);
3057
3058 /************************************************************************
3059 * Request memory to hold mutex for control calls *
3060 ************************************************************************/
3061 ps_mem_rec = &ps_mem_rec_base[MEM_REC_CTL_MUTEX];
3062 {
3063 ps_mem_rec->u4_mem_size = ithread_get_mutex_lock_size();
3064 }
3065 DEBUG("\nMemory record Id %d = %d \n", MEM_REC_CTL_MUTEX, ps_mem_rec->u4_mem_size);
3066
3067 /************************************************************************
3068 * Request memory to hold mutex for entropy calls *
3069 ************************************************************************/
3070 ps_mem_rec = &ps_mem_rec_base[MEM_REC_ENTROPY_MUTEX];
3071 {
3072 ps_mem_rec->u4_mem_size = ithread_get_mutex_lock_size();
3073 }
3074 DEBUG("\nMemory record Id %d = %d \n", MEM_REC_ENTROPY_MUTEX, ps_mem_rec->u4_mem_size);
3075
3076 /************************************************************************
3077 * Request memory to hold process jobs *
3078 ***********************************************************************/
3079 ps_mem_rec = &ps_mem_rec_base[MEM_REC_PROC_JOBQ];
3080 {
3081 /* One process job per row of MBs */
3082 /* Allocate for two pictures, so that wrap around can be handled easily */
3083 WORD32 num_jobs = max_mb_rows * MAX_CTXT_SETS;
3084
3085 WORD32 job_queue_size = ih264_list_size(num_jobs, sizeof(job_t));
3086
3087 ps_mem_rec->u4_mem_size = job_queue_size;
3088 }
3089 DEBUG("\nMemory record Id %d = %d \n", MEM_REC_PROC_JOBQ, ps_mem_rec->u4_mem_size);
3090
3091 /************************************************************************
3092 * Request memory to hold entropy jobs *
3093 ***********************************************************************/
3094 ps_mem_rec = &ps_mem_rec_base[MEM_REC_ENTROPY_JOBQ];
3095 {
3096 /* One process job per row of MBs */
3097 /* Allocate for two pictures, so that wrap around can be handled easily */
3098 WORD32 num_jobs = max_mb_rows * MAX_CTXT_SETS;
3099
3100 WORD32 job_queue_size = ih264_list_size(num_jobs, sizeof(job_t));
3101
3102 ps_mem_rec->u4_mem_size = job_queue_size;
3103 }
3104 DEBUG("\nMemory record Id %d = %d \n", MEM_REC_ENTROPY_JOBQ, ps_mem_rec->u4_mem_size);
3105
3106 /************************************************************************
3107 * In multi core encoding, each row is assumed to be launched on a *
3108 * thread. The rows below can only start after its neighbors are coded *
3109 * The status of an mb coded/uncoded is signaled via proc map. *
3110 * MEM RECORD for holding *
3111 * 1. mb proc map (mb status core coded/uncoded) *
3112 ************************************************************************/
3113 ps_mem_rec = &ps_mem_rec_base[MEM_REC_PROC_MAP];
3114 {
3115 /* total size of the mem record */
3116 WORD32 total_size = 0;
3117
3118 /* size in bytes to mb core coding status of an entire frame */
3119 total_size = max_mb_cnt;
3120
3121 /* add an additional 1 row of bytes to evade the special case of row 0 */
3122 total_size += max_mb_cols;
3123
3124 /* total size per each proc ctxt */
3125 total_size *= MAX_CTXT_SETS;
3126 ps_mem_rec->u4_mem_size = total_size;
3127 }
3128 DEBUG("\nMemory record Id %d = %d \n", MEM_REC_PROC_MAP, ps_mem_rec->u4_mem_size);
3129
3130 /************************************************************************
3131 * mem record for holding a particular MB is deblocked or not *
3132 * 1. mb deblk map (mb status deblocked/not deblocked) *
3133 ************************************************************************/
3134 ps_mem_rec = &ps_mem_rec_base[MEM_REC_DBLK_MAP];
3135 {
3136 /* total size of the mem record */
3137 WORD32 total_size = 0;
3138
3139 /* size in bytes to mb core coding status of an entire frame */
3140 total_size = max_mb_cnt;
3141
3142 /* add an additional 1 row of bytes to evade the special case of row 0 */
3143 total_size += max_mb_cols;
3144
3145 total_size = ALIGN64(total_size);
3146
3147 /* total size per each proc ctxt */
3148 total_size *= MAX_CTXT_SETS;
3149 ps_mem_rec->u4_mem_size = total_size;
3150 }
3151 DEBUG("\nMemory record Id %d = %d \n", MEM_REC_DBLK_MAP, ps_mem_rec->u4_mem_size);
3152
3153 /************************************************************************
3154 * mem record for holding a particular MB's me is done or not *
3155 * 1. mb me map *
3156 ************************************************************************/
3157 ps_mem_rec = &ps_mem_rec_base[MEM_REC_ME_MAP];
3158 {
3159 /* total size of the mem record */
3160 WORD32 total_size = 0;
3161
3162 /* size in bytes to mb core coding status of an entire frame */
3163 total_size = max_mb_cnt;
3164
3165 /* add an additional 1 row of bytes to evade the special case of row 0 */
3166 total_size += max_mb_cols;
3167
3168 /* total size per each proc ctxt */
3169 total_size *= MAX_CTXT_SETS;
3170
3171 ps_mem_rec->u4_mem_size = total_size;
3172 }
3173 DEBUG("\nMemory record Id %d = %d \n", MEM_REC_ME_MAP, ps_mem_rec->u4_mem_size);
3174
3175 /************************************************************************
3176 * size for holding dpb manager context *
3177 ************************************************************************/
3178 ps_mem_rec = &ps_mem_rec_base[MEM_REC_DPB_MGR];
3179 {
3180 ps_mem_rec->u4_mem_size = sizeof(dpb_mgr_t);
3181 }
3182 DEBUG("\nMemory record Id %d = %d \n", MEM_REC_DPB_MGR, ps_mem_rec->u4_mem_size);
3183
3184 /************************************************************************
3185 * luma or chroma core coding involves mb estimation, error computation*
3186 * between the estimated singnal and the actual signal, transform the *
3187 * error, quantize the error, then inverse transform and inverse quant *
3188 * ize the residue and add the result back to estimated signal. *
3189 * To perform all these, a set of temporary buffers are needed. *
3190 * MEM RECORD for holding scratch buffers *
3191 * 1. prediction buffer used during mb mode analysis *
3192 * 2 temp. reference buffer when intra 4x4 with rdopt on is *
3193 * enabled *
3194 * - when intra 4x4 is enabled, rdopt is on, to store the *
3195 * reconstructed values and use them later this temp. buffer *
3196 * is used. *
3197 * 3. prediction buffer used during intra mode analysis *
3198 * 4. prediction buffer used during intra 16x16 plane mode *
3199 * analysis
3200 * 5. prediction buffer used during intra chroma mode analysis *
3201 * 6. prediction buffer used during intra chroma 16x16 plane *
3202 * mode analysis
3203 * 7. forward transform output buffer *
3204 * - to store the error between estimated and the actual inp *
3205 * ut and to store the fwd transformed quantized output *
3206 * 8. forward transform output buffer *
3207 * - when intra 4x4 is enabled, rdopt is on, to store the *
3208 * fwd transform values and use them later this temp. buffer *
3209 * is used. *
3210 * 9. temporary buffer for inverse transform *
3211 * - temporary buffer used in inverse transform and inverse *
3212 * quantization *
3213 * A. Buffers for holding half_x , half_y and half_xy planes *
3214 ************************************************************************/
3215 ps_mem_rec = &ps_mem_rec_base[MEM_REC_PROC_SCRATCH];
3216 {
3217 WORD32 total_size = 0;
3218 WORD32 i4_tmp_size;
3219
3220 /* size to hold prediction buffer */
3221 total_size += sizeof(UWORD8) * 16 * 16;
3222 total_size = ALIGN64(total_size);
3223
3224 /* size to hold recon for intra 4x4 buffer */
3225 total_size += sizeof(UWORD8) * 16 * 16;
3226 total_size = ALIGN64(total_size);
3227
3228 /* prediction buffer intra 16x16 */
3229 total_size += sizeof(UWORD8) * 16 * 16;
3230 total_size = ALIGN64(total_size);
3231
3232 /* prediction buffer intra 16x16 plane*/
3233 total_size += sizeof(UWORD8) * 16 * 16;
3234 total_size = ALIGN64(total_size);
3235
3236 /* prediction buffer intra chroma*/
3237 total_size += sizeof(UWORD8) * 16 * 8;
3238 total_size = ALIGN64(total_size);
3239
3240 /* prediction buffer intra chroma plane*/
3241 total_size += sizeof(UWORD8) * 16 * 8;
3242 total_size = ALIGN64(total_size);
3243
3244 /* size to hold fwd transform output */
3245 total_size += sizeof(WORD16) * SIZE_TRANS_BUFF;
3246 total_size = ALIGN64(total_size);
3247
3248 /* size to hold fwd transform output */
3249 total_size += sizeof(WORD16) * SIZE_TRANS_BUFF;
3250 total_size = ALIGN64(total_size);
3251
3252 /* size to hold temporary data during inverse transform */
3253 total_size += sizeof(WORD32) * SIZE_TMP_BUFF_ITRANS;
3254 total_size = ALIGN64(total_size);
3255
3256 /* Buffers for holding half_x , half_y and half_xy planes */
3257 i4_tmp_size = sizeof(UWORD8) * (HP_BUFF_WD * HP_BUFF_HT);
3258 total_size += (ALIGN64(i4_tmp_size) * SUBPEL_BUFF_CNT);
3259
3260 /* Allocate for each process thread */
3261 total_size *= MAX_PROCESS_CTXT;
3262
3263 ps_mem_rec->u4_mem_size = total_size;
3264 }
3265 DEBUG("\nMemory record Id %d = %d \n", MEM_REC_PROC_SCRATCH, ps_mem_rec->u4_mem_size);
3266
3267 /************************************************************************
3268 * When transform_8x8_flag is disabled, the size of a sub block is *
3269 * 4x4 and when the transform_8x8_flag is enabled the size of the sub *
3270 * block is 8x8. The threshold matrix and the forward scaling list *
3271 * is of the size of the sub block. *
3272 * MEM RECORD for holding *
3273 * 1. quantization parameters for plane y, cb, cr *
3274 * - threshold matrix for quantization *
3275 * - forward weight matrix *
3276 * - satqd threshold matrix *
3277 ************************************************************************/
3278 ps_mem_rec = &ps_mem_rec_base[MEM_REC_QUANT_PARAM];
3279 {
3280 /* total size of the mem record */
3281 WORD32 total_size = 0;
3282
3283 /* quantization parameter list for planes y,cb and cr */
3284 total_size += ALIGN64(sizeof(quant_params_t)) * 3;
3285
3286 /* size of threshold matrix for quantization
3287 * (assuming the transform_8x8_flag is disabled).
3288 * for all 3 planes */
3289 total_size += ALIGN64(sizeof(WORD16) * 4 * 4) * 3;
3290
3291 /* size of forward weight matrix for quantization
3292 * (assuming the transform_8x8_flag is disabled).
3293 * for all 3 planes */
3294 total_size += ALIGN64(sizeof(WORD16) * 4 * 4) * 3;
3295
3296 /* Size for SATDQ threshold matrix for palnes y, cb and cr */
3297 total_size += ALIGN64(sizeof(UWORD16) * 9) * 3;
3298
3299 /* total size per each proc thread */
3300 total_size *= MAX_PROCESS_CTXT;
3301
3302 ps_mem_rec->u4_mem_size = total_size;
3303 }
3304 DEBUG("\nMemory record Id %d = %d \n", MEM_REC_QUANT_PARAM, ps_mem_rec->u4_mem_size);
3305
3306 /************************************************************************
3307 * While computing blocking strength for the current mb, the csbp, mb *
3308 * type for the neighboring mbs are necessary. memtab for storing top *
3309 * row mbtype and csbp is evaluated here. *
3310 * *
3311 * when encoding intra 4x4 or intra 8x8 the submb types are estimated *
3312 * and sent. The estimation is dependent on neighbor mbs. For this *
3313 * store the top row sub mb types for intra mbs *
3314 * *
3315 * During motion vector prediction, the curr mb mv is predicted from *
3316 * neigbors left, top, top right and sometimes top left depending on *
3317 * the availability. The top and top right content is accessed from *
3318 * the memtab specified below. *
3319 ************************************************************************/
3320 ps_mem_rec = &ps_mem_rec_base[MEM_REC_TOP_ROW_SYN_INFO];
3321 {
3322 /* total size of the mem record */
3323 WORD32 total_size = 0;
3324
3325 /* size in bytes to store 1 row of mb_info_t */
3326 /* one additional mb, to avoid checking end of row condition */
3327 total_size += (max_mb_cols + 1) * sizeof(mb_info_t);
3328
3329 /* size in bytes to store 1 row of intra macroblock sub modes */
3330 total_size += max_mb_cols * sizeof(UWORD8) * 16;
3331
3332 /* size in bytes to store 1 row + 1 of enc_pu_t */
3333 /* one additional mb, to avoid checking end of row condition */
3334 total_size += (max_mb_cols + 1) * sizeof(enc_pu_t);
3335
3336 /* total size per proc ctxt */
3337 total_size = ALIGN128(total_size);
3338
3339 /* total size per each proc ctxt */
3340 total_size *= MAX_CTXT_SETS;
3341 ps_mem_rec->u4_mem_size = total_size;
3342 }
3343 DEBUG("\nMemory record Id %d = %d \n", MEM_REC_TOP_ROW_SYN_INFO, ps_mem_rec->u4_mem_size);
3344
3345 /************************************************************************
3346 * When transform_8x8_flag is disabled, the mb is partitioned into *
3347 * 4 sub blocks. This corresponds to 1 vertical left edge and 1 *
3348 * vertical inner edge, 1 horizontal top edge and 1 horizontal *
3349 * inner edge per mb. Further, When transform_8x8_flag is enabled, *
3350 * the mb is partitioned in to 16 sub blocks. This corresponds to *
3351 * 1 vertical left edge and 3 vertical inner edges, 1 horizontal top *
3352 * edge and 3 horizontal inner edges per mb. *
3353 * MEM RECORD for holding *
3354 * 1. vertical edge blocking strength *
3355 * 2. horizontal edge blocking strength *
3356 * 3. mb qp *
3357 * all are frame level *
3358 ************************************************************************/
3359 ps_mem_rec = &ps_mem_rec_base[MEM_REC_BS_QP];
3360 {
3361 /* total size of the mem record */
3362 WORD32 total_size = 0;
3363
3364 /* size in bytes to store vertical edge bs, horizontal edge bs and qp of every mb*/
3365 WORD32 vert_bs_size, horz_bs_size, qp_size;
3366
3367 /* vertical edge bs = total number of vertical edges * number of bytes per each edge */
3368 /* total num of v edges = total mb * 4 (assuming transform_8x8_flag = 0),
3369 * each edge is formed by 4 pairs of subblks, requiring 4 bytes to storing bs */
3370 vert_bs_size = ALIGN64(max_mb_cnt * 4 * 4);
3371
3372 /* horizontal edge bs = total number of horizontal edges * number of bytes per each edge */
3373 /* total num of h edges = total mb * 4 (assuming transform_8x8_flag = 0),
3374 * each edge is formed by 4 pairs of subblks, requiring 4 bytes to storing bs */
3375 horz_bs_size = ALIGN64(max_mb_cnt * 4 * 4);
3376
3377 /* qp of each mb requires 1 byte */
3378 qp_size = ALIGN64(max_mb_cnt);
3379
3380 /* total size */
3381 total_size = vert_bs_size + horz_bs_size + qp_size;
3382
3383 /* total size per each proc ctxt */
3384 total_size *= MAX_CTXT_SETS;
3385
3386 ps_mem_rec->u4_mem_size = total_size;
3387 }
3388 DEBUG("\nMemory record Id %d = %d \n", MEM_REC_BS_QP, ps_mem_rec->u4_mem_size);
3389
3390 /************************************************************************
3391 * size for holding dpb manager context *
3392 ************************************************************************/
3393 ps_mem_rec = &ps_mem_rec_base[MEM_REC_INP_PIC];
3394 {
3395 ps_mem_rec->u4_mem_size = ih264_buf_mgr_size();
3396 }
3397 DEBUG("\nMemory record Id %d = %d \n", MEM_REC_INP_PIC, ps_mem_rec->u4_mem_size);
3398
3399 /************************************************************************
3400 * size for holding dpb manager context *
3401 ************************************************************************/
3402 ps_mem_rec = &ps_mem_rec_base[MEM_REC_OUT];
3403 {
3404 ps_mem_rec->u4_mem_size = ih264_buf_mgr_size();
3405 }
3406 DEBUG("\nMemory record Id %d = %d \n", MEM_REC_OUT, ps_mem_rec->u4_mem_size);
3407
3408 /************************************************************************
3409 * Size for color space conversion *
3410 ************************************************************************/
3411 ps_mem_rec = &ps_mem_rec_base[MEM_REC_CSC];
3412 {
3413 /* We need a total a memory for a single frame of 420 sp, ie
3414 * (wd * ht) for luma and (wd * ht / 2) for chroma*/
3415 ps_mem_rec->u4_mem_size = MAX_CTXT_SETS
3416 * ((3 * max_ht_luma * max_wd_luma) >> 1);
3417 /* Allocate an extra row, since inverse transform functions for
3418 * chroma access(only read, not used) few extra bytes due to
3419 * interleaved input
3420 */
3421 ps_mem_rec->u4_mem_size += max_wd_luma;
3422 }
3423 DEBUG("\nMemory record Id %d = %d \n", MEM_REC_CSC, ps_mem_rec->u4_mem_size);
3424
3425 /************************************************************************
3426 * Size for holding pic_buf_t for each reference picture *
3427 * Note this allocation is done for BUF_MGR_MAX_CNT instead of *
3428 * MAX_DPB_SIZE or max_dpb_size for following reasons *
3429 * max_dpb_size will be based on max_wd and max_ht *
3430 * For higher max_wd and max_ht this number will be smaller than *
3431 * MAX_DPB_SIZE But during actual initialization number of buffers *
3432 * allocated can be more. *
3433 * *
3434 * Also to handle display depth application can allocate more than *
3435 * what codec asks for in case of non-shared mode *
3436 * Since this is only a structure allocation and not actual buffer *
3437 * allocation, it is allocated for BUF_MGR_MAX_CNT entries *
3438 ************************************************************************/
3439 ps_mem_rec = &ps_mem_rec_base[MEM_REC_REF_PIC];
3440 {
3441 ps_mem_rec->u4_mem_size = ih264_buf_mgr_size();
3442 ps_mem_rec->u4_mem_size += BUF_MGR_MAX_CNT * sizeof(pic_buf_t);
3443
3444 /************************************************************************
3445 * Note: Number of luma samples is not max_wd * max_ht here, instead it *
3446 * is set to maximum number of luma samples allowed at the given level. *
3447 * This is done to ensure that any stream with width and height lesser *
3448 * than max_wd and max_ht is supported. Number of buffers required can *
3449 * be greater for lower width and heights at a given level and this *
3450 * increased number of buffers might require more memory than what *
3451 * max_wd and max_ht buffer would have required. Number of buffers is *
3452 * doubled in order to return one frame at a time instead of sending *
3453 * multiple outputs during dpb full case. Also note one extra buffer is *
3454 * allocted to store current picture. *
3455 * *
3456 * Half-pel planes for each reference buffer are allocated along with *
3457 * the reference buffer. So each reference buffer is 4 times the *
3458 * required size. This way buffer management for the half-pel planes is *
3459 * easier and while using the half-pel planes in MC, an offset can be *
3460 * used from a single pointer *
3461 ***********************************************************************/
3462 ps_mem_rec->u4_mem_size += HPEL_PLANES_CNT
3463 * ih264e_get_total_pic_buf_size(
3464 max_wd_luma * max_ht_luma, level,
3465 PAD_WD, PAD_HT, num_ref_frames,
3466 num_reorder_frames);
3467 }
3468 DEBUG("\nMemory record Id %d = %d \n", MEM_REC_REF_PIC, ps_mem_rec->u4_mem_size);
3469
3470 /************************************************************************
3471 * Request memory to hold mem recs to be returned during retrieve call *
3472 ************************************************************************/
3473 ps_mem_rec = &ps_mem_rec_base[MEM_REC_BACKUP];
3474 {
3475 ps_mem_rec->u4_mem_size = MEM_REC_CNT * sizeof(iv_mem_rec_t);
3476 }
3477 DEBUG("\nMemory record Id %d = %d \n", MEM_REC_BACKUP, ps_mem_rec->u4_mem_size);
3478
3479 /************************************************************************
3480 * size for memory required by NMB info structs and buffer for storing *
3481 * half pel plane *
3482 ************************************************************************/
3483 ps_mem_rec = &ps_mem_rec_base[MEM_REC_MB_INFO_NMB];
3484 {
3485 ps_mem_rec->u4_mem_size = MAX_PROCESS_CTXT * max_mb_cols *
3486 (sizeof(mb_info_nmb_t) + MB_SIZE * MB_SIZE
3487 * sizeof(UWORD8));
3488 }
3489 DEBUG("\nMemory record Id %d = %d \n", MEM_REC_MB_INFO_NMB, ps_mem_rec->u4_mem_size);
3490
3491 /************************************************************************
3492 * RC mem records *
3493 ************************************************************************/
3494 ps_mem_rec = &ps_mem_rec_base[MEM_REC_RC];
3495 {
3496 ih264e_get_rate_control_mem_tab(NULL, ps_mem_rec, FILL_MEMTAB);
3497 }
3498 DEBUG("\nMemory record Id %d = %d \n", MEM_REC_RC, ps_mem_rec->u4_mem_size);
3499
3500 /* Each memtab size is aligned to next multiple of 128 bytes */
3501 /* This is to ensure all the memtabs start at different cache lines */
3502 ps_mem_rec = ps_mem_rec_base;
3503 for (i = 0; i < MEM_REC_CNT; i++)
3504 {
3505 ps_mem_rec->u4_mem_size = ALIGN128(ps_mem_rec->u4_mem_size);
3506 ps_mem_rec++;
3507 }
3508
3509 ps_op->s_ive_op.u4_num_mem_rec = MEM_REC_CNT;
3510
3511 DEBUG("Num mem recs in fill call : %d\n", ps_op->s_ive_op.u4_num_mem_rec);
3512
3513 return (status);
3514 }
3515
3516 /**
3517 *******************************************************************************
3518 *
3519 * @brief
3520 * Initializes from mem records passed to the codec
3521 *
3522 * @par Description:
3523 * Initializes pointers based on mem records passed
3524 *
3525 * @param[in] ps_codec_obj
3526 * Pointer to codec object at API level
3527 *
3528 * @param[in] pv_api_ip
3529 * Pointer to input argument structure
3530 *
3531 * @param[out] pv_api_op
3532 * Pointer to output argument structure
3533 *
3534 * @returns error status
3535 *
3536 * @remarks none
3537 *
3538 *******************************************************************************
3539 */
ih264e_init_mem_rec(iv_obj_t * ps_codec_obj,void * pv_api_ip,void * pv_api_op)3540 static WORD32 ih264e_init_mem_rec(iv_obj_t *ps_codec_obj,
3541 void *pv_api_ip,
3542 void *pv_api_op)
3543 {
3544 /* api call I/O structures */
3545 ih264e_init_ip_t *ps_ip = pv_api_ip;
3546 ih264e_init_op_t *ps_op = pv_api_op;
3547
3548 /* mem records */
3549 iv_mem_rec_t *ps_mem_rec_base, *ps_mem_rec;
3550
3551 /* codec variables */
3552 codec_t * ps_codec;
3553 cabac_ctxt_t *ps_cabac;
3554 mb_info_ctxt_t *ps_mb_map_ctxt_inc;
3555
3556 cfg_params_t *ps_cfg;
3557
3558 /* frame dimensions */
3559 WORD32 max_wd_luma, max_ht_luma;
3560 WORD32 max_mb_rows, max_mb_cols, max_mb_cnt;
3561
3562 /* temp var */
3563 WORD32 i, j;
3564 WORD32 status = IV_SUCCESS;
3565
3566 /* frame dimensions */
3567 max_ht_luma = ALIGN16(ps_ip->s_ive_ip.u4_max_ht);
3568 max_wd_luma = ALIGN16(ps_ip->s_ive_ip.u4_max_wd);
3569 max_mb_rows = max_ht_luma / MB_SIZE;
3570 max_mb_cols = max_wd_luma / MB_SIZE;
3571 max_mb_cnt = max_mb_rows * max_mb_cols;
3572
3573 /* mem records */
3574 ps_mem_rec_base = ps_ip->s_ive_ip.ps_mem_rec;
3575
3576 /* Init mem records */
3577 ps_mem_rec = &ps_mem_rec_base[MEM_REC_CODEC];
3578 {
3579 ps_codec_obj->pv_codec_handle = ps_mem_rec->pv_base;
3580 ps_codec = (codec_t *) (ps_codec_obj->pv_codec_handle);
3581 }
3582 /* Init mem records_cabac ctxt */
3583 ps_mem_rec = &ps_mem_rec_base[MEM_REC_CABAC];
3584 {
3585 ps_cabac = (cabac_ctxt_t *)(ps_mem_rec->pv_base);
3586 }
3587
3588 /* Init mem records mb info array for CABAC */
3589 ps_mem_rec = &ps_mem_rec_base[MEM_REC_CABAC_MB_INFO];
3590 {
3591 ps_mb_map_ctxt_inc = (mb_info_ctxt_t *)(ps_mem_rec->pv_base);
3592 }
3593
3594 /* Note this memset can not be done in init() call, since init will called
3595 during reset as well. And calling this during reset will mean all pointers
3596 need to reinitialized */
3597 memset(ps_codec, 0, sizeof(codec_t));
3598 memset(ps_cabac, 0, sizeof(cabac_ctxt_t));
3599
3600 /* Set default Config Params */
3601 ps_cfg = &ps_codec->s_cfg;
3602 ih264e_set_default_params(ps_cfg);
3603
3604 /* Update config params as per input */
3605 ps_cfg->u4_max_wd = ALIGN16(ps_ip->s_ive_ip.u4_max_wd);
3606 ps_cfg->u4_max_ht = ALIGN16(ps_ip->s_ive_ip.u4_max_ht);
3607 ps_cfg->i4_wd_mbs = ps_cfg->u4_max_wd >> 4;
3608 ps_cfg->i4_ht_mbs = ps_cfg->u4_max_ht >> 4;
3609 ps_cfg->u4_max_ref_cnt = ps_ip->s_ive_ip.u4_max_ref_cnt;
3610 ps_cfg->u4_max_reorder_cnt = ps_ip->s_ive_ip.u4_max_reorder_cnt;
3611 ps_cfg->u4_max_level = ps_ip->s_ive_ip.u4_max_level;
3612 ps_cfg->e_inp_color_fmt = ps_ip->s_ive_ip.e_inp_color_fmt;
3613 ps_cfg->e_recon_color_fmt = ps_ip->s_ive_ip.e_recon_color_fmt;
3614 ps_cfg->u4_max_framerate = ps_ip->s_ive_ip.u4_max_framerate;
3615 ps_cfg->u4_max_bitrate = ps_ip->s_ive_ip.u4_max_bitrate;
3616 ps_cfg->u4_num_bframes = ps_ip->s_ive_ip.u4_num_bframes;
3617 ps_cfg->e_content_type = ps_ip->s_ive_ip.e_content_type;
3618 ps_cfg->u4_max_srch_rng_x = ps_ip->s_ive_ip.u4_max_srch_rng_x;
3619 ps_cfg->u4_max_srch_rng_y = ps_ip->s_ive_ip.u4_max_srch_rng_y;
3620 ps_cfg->e_slice_mode = ps_ip->s_ive_ip.e_slice_mode;
3621 ps_cfg->u4_slice_param = ps_ip->s_ive_ip.u4_slice_param;
3622 ps_cfg->e_arch = ps_ip->s_ive_ip.e_arch;
3623 ps_cfg->e_soc = ps_ip->s_ive_ip.e_soc;
3624 ps_cfg->u4_enable_recon = ps_ip->s_ive_ip.u4_enable_recon;
3625 ps_cfg->e_rc_mode = ps_ip->s_ive_ip.e_rc_mode;
3626
3627 /* Validate params */
3628 if ((ps_ip->s_ive_ip.u4_max_level < MIN_LEVEL)
3629 || (ps_ip->s_ive_ip.u4_max_level > MAX_LEVEL))
3630 {
3631 ps_op->s_ive_op.u4_error_code |= IH264E_CODEC_LEVEL_NOT_SUPPORTED;
3632 ps_cfg->u4_max_level = DEFAULT_MAX_LEVEL;
3633 }
3634
3635 if (ps_ip->s_ive_ip.u4_max_ref_cnt > MAX_REF_CNT)
3636 {
3637 ps_op->s_ive_op.u4_error_code |= IH264E_NUM_REF_UNSUPPORTED;
3638 ps_cfg->u4_max_ref_cnt = MAX_REF_CNT;
3639 }
3640
3641 if (ps_ip->s_ive_ip.u4_max_reorder_cnt > MAX_REF_CNT)
3642 {
3643 ps_op->s_ive_op.u4_error_code |= IH264E_NUM_REORDER_UNSUPPORTED;
3644 ps_cfg->u4_max_reorder_cnt = MAX_REF_CNT;
3645 }
3646
3647 ps_mem_rec = &ps_mem_rec_base[MEM_REC_BACKUP];
3648 {
3649 ps_codec->ps_mem_rec_backup = (iv_mem_rec_t *) ps_mem_rec->pv_base;
3650
3651 memcpy(ps_codec->ps_mem_rec_backup, ps_mem_rec_base,
3652 MEM_REC_CNT * sizeof(iv_mem_rec_t));
3653 }
3654
3655 ps_mem_rec = &ps_mem_rec_base[MEM_REC_ENTROPY];
3656 {
3657 /* temp var */
3658 WORD32 size = 0, offset;
3659
3660 for (i = 0; i < MAX_PROCESS_CTXT; i++)
3661 {
3662 if (i < MAX_PROCESS_CTXT / MAX_CTXT_SETS)
3663 {
3664 /* base ptr */
3665 UWORD8 *pu1_buf = ps_mem_rec->pv_base;
3666
3667 /* reset size */
3668 size = 0;
3669
3670 /* skip mb run */
3671 ps_codec->as_process[i].s_entropy.pi4_mb_skip_run =
3672 (void *) (pu1_buf + size);
3673 size += sizeof(WORD32);
3674 size = ALIGN8(size);
3675
3676 /* entropy map */
3677 ps_codec->as_process[i].s_entropy.pu1_entropy_map =
3678 (void *) (pu1_buf + size + max_mb_cols);
3679 /* size in bytes to store entropy status of an entire frame */
3680 size += (max_mb_cols * max_mb_rows);
3681 /* add an additional 1 row of bytes to evade the special case of row 0 */
3682 size += max_mb_cols;
3683 size = ALIGN128(size);
3684
3685 /* bit stream ptr */
3686 ps_codec->as_process[i].s_entropy.ps_bitstrm = (void *) (pu1_buf
3687 + size);
3688 size += sizeof(bitstrm_t);
3689 size = ALIGN128(size);
3690
3691 /* nnz luma */
3692 ps_codec->as_process[i].s_entropy.pu1_top_nnz_luma =
3693 (void *) (pu1_buf + size);
3694 size += (max_mb_cols * 4 * sizeof(UWORD8));
3695 size = ALIGN128(size);
3696
3697 /* nnz chroma */
3698 ps_codec->as_process[i].s_entropy.pu1_top_nnz_cbcr =
3699 (void *) (pu1_buf + size);
3700 size += (max_mb_cols * 4 * sizeof(UWORD8));
3701 size = ALIGN128(size);
3702 offset = size;
3703 /* cabac Context */
3704 ps_codec->as_process[i].s_entropy.ps_cabac = ps_cabac;
3705 }
3706 else
3707 {
3708 /* base ptr */
3709 UWORD8 *pu1_buf = ps_mem_rec->pv_base;
3710
3711 /* reset size */
3712 size = offset;
3713
3714 /* skip mb run */
3715 ps_codec->as_process[i].s_entropy.pi4_mb_skip_run =
3716 (void *) (pu1_buf + size);
3717 size += sizeof(WORD32);
3718 size = ALIGN8(size);
3719
3720 /* entropy map */
3721 ps_codec->as_process[i].s_entropy.pu1_entropy_map =
3722 (void *) (pu1_buf + size + max_mb_cols);
3723 /* size in bytes to store entropy status of an entire frame */
3724 size += (max_mb_cols * max_mb_rows);
3725 /* add an additional 1 row of bytes to evade the special case of row 0 */
3726 size += max_mb_cols;
3727 size = ALIGN128(size);
3728
3729 /* bit stream ptr */
3730 ps_codec->as_process[i].s_entropy.ps_bitstrm = (void *) (pu1_buf
3731 + size);
3732 size += sizeof(bitstrm_t);
3733 size = ALIGN128(size);
3734
3735 /* nnz luma */
3736 ps_codec->as_process[i].s_entropy.pu1_top_nnz_luma =
3737 (void *) (pu1_buf + size);
3738 size += (max_mb_cols * 4 * sizeof(UWORD8));
3739 size = ALIGN128(size);
3740
3741 /* nnz chroma */
3742 ps_codec->as_process[i].s_entropy.pu1_top_nnz_cbcr =
3743 (void *) (pu1_buf + size);
3744 size += (max_mb_cols * 4 * sizeof(UWORD8));
3745 size = ALIGN128(size);
3746 /* cabac Context */
3747 ps_codec->as_process[i].s_entropy.ps_cabac = ps_cabac;
3748 }
3749 }
3750 ps_codec->as_process[0].s_entropy.ps_cabac->ps_mb_map_ctxt_inc_base =
3751 ps_mb_map_ctxt_inc;
3752 }
3753
3754 ps_mem_rec = &ps_mem_rec_base[MEM_REC_MB_COEFF_DATA];
3755 {
3756 /* temp var */
3757 WORD32 size = 0, size_of_row;
3758 UWORD8 *pu1_buf = ps_mem_rec->pv_base;
3759
3760 /* size of coeff data of 1 mb */
3761 size += sizeof(tu_sblk_coeff_data_t) * MAX_4x4_SUBBLKS;
3762
3763 /* size of coeff data of 1 row of mb's */
3764 size *= max_mb_cols;
3765
3766 /* align to avoid false sharing */
3767 size = ALIGN64(size);
3768 size_of_row = size;
3769
3770 /* size for one full frame */
3771 size *= max_mb_rows;
3772
3773 ps_codec->u4_size_coeff_data = size_of_row;
3774
3775 for (i = 0; i < MAX_PROCESS_CTXT; i++)
3776 {
3777 if (i < MAX_PROCESS_CTXT / MAX_CTXT_SETS)
3778 {
3779 ps_codec->as_process[i].pv_pic_mb_coeff_data = pu1_buf;
3780 ps_codec->as_process[i].s_entropy.pv_pic_mb_coeff_data =
3781 pu1_buf;
3782 }
3783 else
3784 {
3785 ps_codec->as_process[i].pv_pic_mb_coeff_data = pu1_buf + size;
3786 ps_codec->as_process[i].s_entropy.pv_pic_mb_coeff_data = pu1_buf
3787 + size;
3788 }
3789 }
3790 }
3791
3792 ps_mem_rec = &ps_mem_rec_base[MEM_REC_MB_HEADER_DATA];
3793 {
3794 /* temp var */
3795 WORD32 size, size_of_row;
3796 UWORD8 *pu1_buf = ps_mem_rec->pv_base;
3797
3798 /* size of header data of 1 mb */
3799 size = 40;
3800
3801 /* size for 1 row of mbs */
3802 size = size * max_mb_cols;
3803
3804 /* align to avoid any false sharing across threads */
3805 size = ALIGN64(size);
3806 size_of_row = size;
3807
3808 /* size for one full frame */
3809 size *= max_mb_rows;
3810
3811 ps_codec->u4_size_header_data = size_of_row;
3812
3813 for (i = 0; i < MAX_PROCESS_CTXT; i++)
3814 {
3815 if (i < MAX_PROCESS_CTXT / MAX_CTXT_SETS)
3816 {
3817 ps_codec->as_process[i].pv_pic_mb_header_data = pu1_buf;
3818 ps_codec->as_process[i].s_entropy.pv_pic_mb_header_data =
3819 pu1_buf;
3820 }
3821 else
3822 {
3823 ps_codec->as_process[i].pv_pic_mb_header_data = pu1_buf + size;
3824 ps_codec->as_process[i].s_entropy.pv_pic_mb_header_data =
3825 pu1_buf + size;
3826 }
3827 }
3828 }
3829
3830 ps_mem_rec = &ps_mem_rec_base[MEM_REC_MVBANK];
3831 {
3832 /* size of buf mgr struct */
3833 WORD32 size = ih264_buf_mgr_size();
3834
3835 /* temp var */
3836 UWORD8 *pu1_buf = ps_mem_rec->pv_base;
3837
3838 /* mv buffer mgr */
3839 ps_codec->pv_mv_buf_mgr_base = pu1_buf;
3840
3841 /* mv bank */
3842 ps_codec->pv_mv_bank_buf_base = pu1_buf + size;
3843 ps_codec->i4_total_mv_bank_size = ps_mem_rec->u4_mem_size - size;
3844 }
3845
3846 ps_mem_rec = &ps_mem_rec_base[MEM_REC_MVBITS];
3847 {
3848 /* max srch range x */
3849 UWORD32 u4_srch_range_x = ps_ip->s_ive_ip.u4_max_srch_rng_x;
3850
3851 /* max srch range y */
3852 UWORD32 u4_srch_range_y = ps_ip->s_ive_ip.u4_max_srch_rng_y;
3853
3854 /* max srch range */
3855 UWORD32 u4_max_srch_range = MAX(u4_srch_range_x, u4_srch_range_y);
3856
3857 /* temp var */
3858 UWORD8 *pu1_buf = ps_mem_rec->pv_base;
3859
3860 /* due to subpel */
3861 u4_max_srch_range <<= 2;
3862
3863 // /* due to mv on either direction */
3864 // u4_max_srch_range = (u4_max_srch_range << 1);
3865
3866 /* due to pred mv + zero */
3867 u4_max_srch_range = (u4_max_srch_range << 1) + 1;
3868
3869 for (i = 0; i < MAX_PROCESS_CTXT; i++)
3870 {
3871 /* me ctxt */
3872 me_ctxt_t *ps_mem_ctxt = &(ps_codec->as_process[i].s_me_ctxt);
3873
3874 /* init at zero mv */
3875 ps_mem_ctxt->pu1_mv_bits = pu1_buf + u4_max_srch_range;
3876 }
3877 }
3878
3879 ps_mem_rec = &ps_mem_rec_base[MEM_REC_SPS];
3880 {
3881 ps_codec->ps_sps_base = (sps_t *) ps_mem_rec->pv_base;
3882 }
3883
3884 ps_mem_rec = &ps_mem_rec_base[MEM_REC_PPS];
3885 {
3886 ps_codec->ps_pps_base = (pps_t *) ps_mem_rec->pv_base;
3887 }
3888
3889 ps_mem_rec = &ps_mem_rec_base[MEM_REC_SLICE_HDR];
3890 {
3891 ps_codec->ps_slice_hdr_base = ps_mem_rec->pv_base;
3892
3893 for (i = 0; i < MAX_PROCESS_CTXT; i++)
3894 {
3895 if (i < MAX_PROCESS_CTXT / MAX_CTXT_SETS)
3896 {
3897 ps_codec->as_process[i].ps_slice_hdr_base = ps_mem_rec->pv_base;
3898 }
3899 else
3900 {
3901 /* temp var */
3902 WORD32 size = MAX_SLICE_HDR_CNT * sizeof(slice_header_t);
3903 void *pv_buf = (UWORD8 *) ps_mem_rec->pv_base + size;
3904
3905 ps_codec->as_process[i].ps_slice_hdr_base = pv_buf;
3906 }
3907 }
3908 }
3909
3910 ps_mem_rec = &ps_mem_rec_base[MEM_REC_AIR_MAP];
3911 {
3912 /* temp var */
3913 UWORD8 *pu1_buf = ps_mem_rec->pv_base;
3914
3915 for (i = 0; i < MAX_PROCESS_CTXT; i++)
3916 {
3917 if (i < MAX_PROCESS_CTXT / MAX_CTXT_SETS)
3918 {
3919 ps_codec->as_process[i].pu1_is_intra_coded = pu1_buf;
3920 }
3921 else
3922 {
3923 ps_codec->as_process[i].pu1_is_intra_coded = pu1_buf
3924 + max_mb_cnt;
3925 }
3926 }
3927
3928 ps_codec->pu2_intr_rfrsh_map = (UWORD16 *) (pu1_buf + max_mb_cnt * MAX_CTXT_SETS);
3929 }
3930
3931 ps_mem_rec = &ps_mem_rec_base[MEM_REC_SLICE_MAP];
3932 {
3933 /* pointer to storage space */
3934 UWORD8 *pu1_buf_ping, *pu1_buf_pong;
3935
3936 /* init pointer */
3937 pu1_buf_ping = ps_mem_rec->pv_base;
3938 pu1_buf_pong = pu1_buf_ping + ALIGN64(max_mb_cnt);
3939
3940 for (i = 0; i < MAX_PROCESS_CTXT; i++)
3941 {
3942 if (i < MAX_PROCESS_CTXT / MAX_CTXT_SETS)
3943 {
3944 ps_codec->as_process[i].pu1_slice_idx = pu1_buf_ping;
3945 }
3946 else
3947 {
3948 ps_codec->as_process[i].pu1_slice_idx = pu1_buf_pong;
3949 }
3950 }
3951 }
3952
3953 ps_mem_rec = &ps_mem_rec_base[MEM_REC_THREAD_HANDLE];
3954 {
3955 WORD32 handle_size = ithread_get_handle_size();
3956
3957 for (i = 0; i < MAX_PROCESS_THREADS; i++)
3958 {
3959 ps_codec->apv_proc_thread_handle[i] = (UWORD8 *) ps_mem_rec->pv_base
3960 + (i * handle_size);
3961 }
3962 }
3963
3964 ps_mem_rec = &ps_mem_rec_base[MEM_REC_CTL_MUTEX];
3965 {
3966 ps_codec->pv_ctl_mutex = ps_mem_rec->pv_base;
3967 }
3968
3969 ps_mem_rec = &ps_mem_rec_base[MEM_REC_ENTROPY_MUTEX];
3970 {
3971 ps_codec->pv_entropy_mutex = ps_mem_rec->pv_base;
3972 }
3973
3974 ps_mem_rec = &ps_mem_rec_base[MEM_REC_PROC_JOBQ];
3975 {
3976 ps_codec->pv_proc_jobq_buf = ps_mem_rec->pv_base;
3977 ps_codec->i4_proc_jobq_buf_size = ps_mem_rec->u4_mem_size;
3978 }
3979
3980 ps_mem_rec = &ps_mem_rec_base[MEM_REC_ENTROPY_JOBQ];
3981 {
3982 ps_codec->pv_entropy_jobq_buf = ps_mem_rec->pv_base;
3983 ps_codec->i4_entropy_jobq_buf_size = ps_mem_rec->u4_mem_size;
3984 }
3985
3986 ps_mem_rec = &ps_mem_rec_base[MEM_REC_PROC_MAP];
3987 {
3988 /* pointer to storage space */
3989 UWORD8 *pu1_buf = ps_mem_rec->pv_base;
3990
3991 /* total size of the mem record */
3992 WORD32 total_size = 0;
3993
3994 /* size in bytes to mb core coding status of an entire frame */
3995 total_size = max_mb_cnt;
3996
3997 /* add an additional 1 row of bytes to evade the special case of row 0 */
3998 total_size += max_mb_cols;
3999
4000 for (i = 0; i < MAX_PROCESS_CTXT; i++)
4001 {
4002 if (i < MAX_PROCESS_CTXT / MAX_CTXT_SETS)
4003 {
4004 ps_codec->as_process[i].pu1_proc_map = pu1_buf + max_mb_cols;
4005 }
4006 else
4007 {
4008 ps_codec->as_process[i].pu1_proc_map = pu1_buf + total_size
4009 + max_mb_cols;
4010 }
4011 }
4012 }
4013
4014 ps_mem_rec = &ps_mem_rec_base[MEM_REC_DBLK_MAP];
4015 {
4016 /* pointer to storage space */
4017 UWORD8 *pu1_buf = ps_mem_rec->pv_base;
4018
4019 /* total size of the mem record */
4020 WORD32 total_size = 0;
4021
4022 /* size in bytes to mb core coding status of an entire frame */
4023 total_size = max_mb_cnt;
4024
4025 /* add an additional 1 row of bytes to evade the special case of row 0 */
4026 total_size += max_mb_cols;
4027
4028 /*Align the memory offsets*/
4029 total_size = ALIGN64(total_size);
4030
4031 for (i = 0; i < MAX_PROCESS_CTXT; i++)
4032 {
4033 if (i < MAX_PROCESS_CTXT / MAX_CTXT_SETS)
4034 {
4035 ps_codec->as_process[i].pu1_deblk_map = pu1_buf + max_mb_cols;
4036
4037 }
4038 else
4039 {
4040 ps_codec->as_process[i].pu1_deblk_map = pu1_buf + total_size
4041 + max_mb_cols;
4042
4043 }
4044 }
4045 }
4046
4047 ps_mem_rec = &ps_mem_rec_base[MEM_REC_ME_MAP];
4048 {
4049 /* pointer to storage space */
4050 UWORD8 *pu1_buf = (UWORD8 *) ps_mem_rec->pv_base;
4051
4052 /* total size of the mem record */
4053 WORD32 total_size = 0;
4054
4055 /* size in bytes to mb core coding status of an entire frame */
4056 total_size = max_mb_cnt;
4057
4058 /* add an additional 1 row of bytes to evade the special case of row 0 */
4059 total_size += max_mb_cols;
4060
4061 for (i = 0; i < MAX_PROCESS_CTXT; i++)
4062 {
4063 if (i < MAX_PROCESS_CTXT / MAX_CTXT_SETS)
4064 {
4065 ps_codec->as_process[i].pu1_me_map = pu1_buf + max_mb_cols;
4066 }
4067 else
4068 {
4069 ps_codec->as_process[i].pu1_me_map = pu1_buf + total_size
4070 + max_mb_cols;
4071 }
4072 }
4073 }
4074
4075 ps_mem_rec = &ps_mem_rec_base[MEM_REC_DPB_MGR];
4076 {
4077 ps_codec->pv_dpb_mgr = ps_mem_rec->pv_base;
4078 }
4079
4080 ps_mem_rec = &ps_mem_rec_base[MEM_REC_PROC_SCRATCH];
4081 {
4082 /* pointer to storage space */
4083 UWORD8 *pu1_buf = (UWORD8 *) ps_mem_rec->pv_base;
4084
4085 /* size of pred buffer, fwd transform output, temp buffer for inv tra */
4086 WORD32 size_pred_luma, size_pred_chroma, size_fwd, size_inv, size_hp;
4087
4088 /* temp var */
4089 WORD32 size = 0;
4090
4091 /* size to hold intra/inter prediction buffer */
4092 size_pred_luma = sizeof(UWORD8) * 16 * 16;
4093 size_pred_chroma = sizeof(UWORD8) * 8 * 16;
4094
4095 /* size to hold fwd transform output */
4096 size_fwd = sizeof(WORD16) * SIZE_TRANS_BUFF;
4097
4098 /* size to hold temporary data during inverse transform */
4099 size_inv = sizeof(WORD32) * SIZE_TMP_BUFF_ITRANS;
4100
4101 /* size to hold half pel plane buffers */
4102 size_hp = sizeof(UWORD8) * (HP_BUFF_WD * HP_BUFF_HT);
4103
4104 for (i = 0; i < MAX_PROCESS_CTXT; i++)
4105 {
4106 /* prediction buffer */
4107 ps_codec->as_process[i].pu1_pred_mb = (void *) (pu1_buf + size);
4108 ps_codec->as_process[i].i4_pred_strd = 16;
4109 size += size_pred_luma;
4110 size = ALIGN64(size);
4111
4112 /* prediction buffer */
4113 ps_codec->as_process[i].pu1_ref_mb_intra_4x4 = (void *) (pu1_buf
4114 + size);
4115 size += size_pred_luma;
4116 size = ALIGN64(size);
4117
4118 /* prediction buffer intra 16x16 */
4119 ps_codec->as_process[i].pu1_pred_mb_intra_16x16 = (void *) (pu1_buf
4120 + size);
4121 size += size_pred_luma;
4122 size = ALIGN64(size);
4123
4124 /* prediction buffer intra 16x16 plane*/
4125 ps_codec->as_process[i].pu1_pred_mb_intra_16x16_plane =
4126 (void *) (pu1_buf + size);
4127 size += size_pred_luma;
4128 size = ALIGN64(size);
4129
4130 /* prediction buffer intra chroma*/
4131 ps_codec->as_process[i].pu1_pred_mb_intra_chroma = (void *) (pu1_buf
4132 + size);
4133 size += size_pred_chroma;
4134 size = ALIGN64(size);
4135
4136 /* prediction buffer intra chroma plane*/
4137 ps_codec->as_process[i].pu1_pred_mb_intra_chroma_plane =
4138 (void *) (pu1_buf + size);
4139 size += size_pred_chroma;
4140 size = ALIGN64(size);
4141
4142 /* Fwd transform output */
4143 ps_codec->as_process[i].pi2_res_buf = (void *) (pu1_buf + size);
4144 ps_codec->as_process[i].i4_res_strd = 16;
4145 size += size_fwd;
4146 size = ALIGN64(size);
4147
4148 /* Fwd transform output */
4149 ps_codec->as_process[i].pi2_res_buf_intra_4x4 = (void *) (pu1_buf
4150 + size);
4151 size += size_fwd;
4152 size = ALIGN64(size);
4153
4154 /* scratch buffer used during inverse transform */
4155 ps_codec->as_process[i].pv_scratch_buff = (void *) (pu1_buf + size);
4156 size += size_inv;
4157 size = ALIGN64(size);
4158
4159 for (j = 0; j < SUBPEL_BUFF_CNT; j++)
4160 {
4161 ps_codec->as_process[i].apu1_subpel_buffs[j] = (pu1_buf + size);
4162 size += ALIGN64(size_hp);
4163 }
4164 }
4165 }
4166
4167 ps_mem_rec = &ps_mem_rec_base[MEM_REC_QUANT_PARAM];
4168 {
4169 /* pointer to storage space */
4170 UWORD8 *pu1_buf = (UWORD8 *) ps_mem_rec->pv_base;
4171
4172 /* size of qp, threshold matrix, fwd scaling list for one plane */
4173 WORD32 size_quant_param, size_thres_mat, size_fwd_weight_mat,
4174 size_satqd_weight_mat;
4175
4176 /* temp var */
4177 WORD32 total_size = 0;
4178
4179 /* size of quantization parameter list of 1 plane */
4180 size_quant_param = ALIGN64(sizeof(quant_params_t));
4181
4182 /* size of threshold matrix for quantization
4183 * (assuming the transform_8x8_flag is disabled).
4184 * for 1 plane */
4185 size_thres_mat = ALIGN64(sizeof(WORD16) * 4 * 4);
4186
4187 /* size of forward weight matrix for quantization
4188 * (assuming the transform_8x8_flag is disabled).
4189 * for 1 plane */
4190 size_fwd_weight_mat = ALIGN64(sizeof(WORD16) * 4 * 4);
4191
4192 /* size of SATQD matrix*/
4193 size_satqd_weight_mat = ALIGN64(sizeof(UWORD16) * 9);
4194
4195 for (i = 0; i < MAX_PROCESS_CTXT; i++)
4196 {
4197 quant_params_t **ps_qp_params = ps_codec->as_process[i].ps_qp_params;
4198
4199 /* quantization param structure */
4200 ps_qp_params[0] = (quant_params_t *) (pu1_buf + total_size);
4201 total_size = total_size + size_quant_param;
4202 ps_qp_params[1] = (quant_params_t *) (pu1_buf + total_size);
4203 total_size = total_size + size_quant_param;
4204 ps_qp_params[2] = (quant_params_t *) (pu1_buf + total_size);
4205 total_size = total_size + size_quant_param;
4206
4207 /* threshold matrix for quantization */
4208 ps_qp_params[0]->pu2_thres_mat = (void *) (pu1_buf + total_size);
4209 total_size = total_size + size_thres_mat;
4210 ps_qp_params[1]->pu2_thres_mat = (void *) (pu1_buf + total_size);
4211 total_size = total_size + size_thres_mat;
4212 ps_qp_params[2]->pu2_thres_mat = (void *) (pu1_buf + total_size);
4213 total_size = total_size + size_thres_mat;
4214
4215 /* fwd weight matrix */
4216 ps_qp_params[0]->pu2_weigh_mat = (void *) (pu1_buf + total_size);
4217 total_size = total_size + size_fwd_weight_mat;
4218 ps_qp_params[1]->pu2_weigh_mat = (void *) (pu1_buf + total_size);
4219 total_size = total_size + size_fwd_weight_mat;
4220 ps_qp_params[2]->pu2_weigh_mat = (void *) (pu1_buf + total_size);
4221 total_size = total_size + size_fwd_weight_mat;
4222
4223 /* threshold matrix for SATQD */
4224 ps_qp_params[0]->pu2_sad_thrsh = (void *) (pu1_buf + total_size);
4225 total_size = total_size + size_satqd_weight_mat;
4226 ps_qp_params[1]->pu2_sad_thrsh = (void *) (pu1_buf + total_size);
4227 total_size = total_size + size_satqd_weight_mat;
4228 ps_qp_params[2]->pu2_sad_thrsh = (void *) (pu1_buf + total_size);
4229 total_size = total_size + size_satqd_weight_mat;
4230
4231 total_size = ALIGN128(total_size);
4232 }
4233 }
4234
4235 ps_mem_rec = &ps_mem_rec_base[MEM_REC_TOP_ROW_SYN_INFO];
4236 {
4237 /* total size of the mem record */
4238 WORD32 total_size = 0, size_csbp, size_intra_modes, size_mv;
4239
4240 /* pointer to buffer */
4241 UWORD8 *pu1_buf = ps_mem_rec->pv_base;
4242
4243 /* size in bytes to store 1 row of mb_info_t */
4244 /* one additional mb, to avoid checking end of row condition */
4245 size_csbp = (max_mb_cols + 1) * sizeof(mb_info_t);
4246
4247 /* size in bytes to store 1 row of intra macroblock sub modes */
4248 size_intra_modes = max_mb_cols * sizeof(UWORD8) * 16;
4249
4250 /* size in bytes to store 1 row + 1 of enc_pu_t */
4251 /* one additional mb, to avoid checking end of row condition */
4252 size_mv = (max_mb_cols + 1) * sizeof(enc_pu_t);
4253
4254 /* total size per proc ctxt */
4255 total_size = size_csbp + size_intra_modes + size_mv;
4256
4257 for (i = 0; i < MAX_PROCESS_CTXT; i++)
4258 {
4259 if (i < MAX_PROCESS_CTXT / MAX_CTXT_SETS)
4260 {
4261 ps_codec->as_process[i].ps_top_row_mb_syntax_ele_base =
4262 (mb_info_t *) pu1_buf;
4263 ps_codec->as_process[i].pu1_top_mb_intra_modes_base = pu1_buf
4264 + size_csbp;
4265 ps_codec->as_process[i].ps_top_row_pu_base =
4266 (enc_pu_t *) (pu1_buf + size_csbp
4267 + size_intra_modes);
4268 }
4269 else
4270 {
4271 ps_codec->as_process[i].ps_top_row_mb_syntax_ele_base =
4272 (mb_info_t *) (pu1_buf + total_size);
4273 ps_codec->as_process[i].pu1_top_mb_intra_modes_base = pu1_buf
4274 + total_size + size_csbp;
4275 ps_codec->as_process[i].ps_top_row_pu_base =
4276 (enc_pu_t *) (pu1_buf + total_size + size_csbp
4277 + size_intra_modes);
4278 }
4279 }
4280 }
4281
4282 ps_mem_rec = &ps_mem_rec_base[MEM_REC_BS_QP];
4283 {
4284 UWORD8 *pu1_buf_ping, *pu1_buf_pong;
4285
4286 /* total size of the mem record */
4287 WORD32 total_size = 0;
4288
4289 /* size in bytes to store vertical edge bs, horizontal edge bs and qp of every mb*/
4290 WORD32 vert_bs_size, horz_bs_size, qp_size;
4291
4292 /* vertical edge bs = total number of vertical edges * number of bytes per each edge */
4293 /* total num of v edges = total mb * 4 (assuming transform_8x8_flag = 0),
4294 * each edge is formed by 4 pairs of subblks, requiring 4 bytes to storing bs */
4295 vert_bs_size = ALIGN64(max_mb_cnt * 4 * 4);
4296
4297 /* horizontal edge bs = total number of horizontal edges * number of bytes per each edge */
4298 /* total num of h edges = total mb * 4 (assuming transform_8x8_flag = 0),
4299 * each edge is formed by 4 pairs of subblks, requiring 4 bytes to storing bs */
4300 horz_bs_size = ALIGN64(max_mb_cnt * 4 * 4);
4301
4302 /* qp of each mb requires 1 byte */
4303 qp_size = ALIGN64(max_mb_cnt);
4304
4305 /* total size */
4306 total_size = vert_bs_size + horz_bs_size + qp_size;
4307
4308 for (i = 0; i < MAX_PROCESS_CTXT; i++)
4309 {
4310 if (i < MAX_PROCESS_CTXT / MAX_CTXT_SETS)
4311 {
4312 pu1_buf_ping = (UWORD8 *) ps_mem_rec->pv_base;
4313
4314 /* vertical edge bs storage space */
4315 ps_codec->as_process[i].s_deblk_ctxt.s_bs_ctxt.pu4_pic_vert_bs =
4316 (UWORD32 *) pu1_buf_ping;
4317 pu1_buf_ping += vert_bs_size;
4318
4319 /* horizontal edge bs storage space */
4320 ps_codec->as_process[i].s_deblk_ctxt.s_bs_ctxt.pu4_pic_horz_bs =
4321 (UWORD32 *) pu1_buf_ping;
4322 pu1_buf_ping += horz_bs_size;
4323
4324 /* qp */
4325 ps_codec->as_process[i].s_deblk_ctxt.s_bs_ctxt.pu1_pic_qp =
4326 (UWORD8 *) pu1_buf_ping;
4327 pu1_buf_ping += qp_size;
4328 }
4329 else
4330 {
4331 pu1_buf_pong = (UWORD8 *) ps_mem_rec->pv_base;
4332 pu1_buf_pong += total_size;
4333
4334 /* vertical edge bs storage space */
4335 ps_codec->as_process[i].s_deblk_ctxt.s_bs_ctxt.pu4_pic_vert_bs =
4336 (UWORD32 *) pu1_buf_pong;
4337 pu1_buf_pong += vert_bs_size;
4338
4339 /* horizontal edge bs storage space */
4340 ps_codec->as_process[i].s_deblk_ctxt.s_bs_ctxt.pu4_pic_horz_bs =
4341 (UWORD32 *) pu1_buf_pong;
4342 pu1_buf_pong += horz_bs_size;
4343
4344 /* qp */
4345 ps_codec->as_process[i].s_deblk_ctxt.s_bs_ctxt.pu1_pic_qp =
4346 (UWORD8 *) pu1_buf_pong;
4347 pu1_buf_pong += qp_size;
4348 }
4349 }
4350 }
4351
4352 ps_mem_rec = &ps_mem_rec_base[MEM_REC_INP_PIC];
4353 {
4354 ps_codec->pv_inp_buf_mgr_base = ps_mem_rec->pv_base;
4355 }
4356
4357 ps_mem_rec = &ps_mem_rec_base[MEM_REC_OUT];
4358 {
4359 ps_codec->pv_out_buf_mgr_base = ps_mem_rec->pv_base;
4360 }
4361
4362 ps_mem_rec = &ps_mem_rec_base[MEM_REC_CSC];
4363 {
4364 ps_codec->pu1_y_csc_buf_base = ps_mem_rec->pv_base;
4365 ps_codec->pu1_uv_csc_buf_base = (UWORD8 *) ps_mem_rec->pv_base
4366 + (max_ht_luma * max_wd_luma);
4367 }
4368
4369 ps_mem_rec = &ps_mem_rec_base[MEM_REC_REF_PIC];
4370 {
4371 /* size of buf mgr struct */
4372 WORD32 size = ih264_buf_mgr_size();
4373
4374 /* temp var */
4375 UWORD8 *pu1_buf = ps_mem_rec->pv_base;
4376
4377 /* pic buffer mgr */
4378 ps_codec->pv_ref_buf_mgr_base = pu1_buf;
4379
4380 /* picture bank */
4381 ps_codec->pv_pic_buf_base = pu1_buf + size;
4382 ps_codec->i4_total_pic_buf_size = ps_mem_rec->u4_mem_size - size;
4383 }
4384
4385 ps_mem_rec = &ps_mem_rec_base[MEM_REC_MB_INFO_NMB];
4386 {
4387 /* temp var */
4388 UWORD8 *pu1_buf = ps_mem_rec->pv_base;
4389
4390 /* size of nmb ctxt */
4391 WORD32 size = max_mb_cols * sizeof(mb_info_nmb_t);
4392
4393 WORD32 nmb_cntr, subpel_buf_size;
4394
4395 /* init nmb info structure pointer in all proc ctxts */
4396 for (i = 0; i < MAX_PROCESS_CTXT; i++)
4397 {
4398 ps_codec->as_process[i].ps_nmb_info = (mb_info_nmb_t *) (pu1_buf);
4399
4400 pu1_buf += size;
4401 }
4402
4403 subpel_buf_size = MB_SIZE * MB_SIZE * sizeof(UWORD8);
4404
4405 /* adjusting pointers for nmb halfpel buffer */
4406 for (i = 0; i < MAX_PROCESS_CTXT; i++)
4407 {
4408 mb_info_nmb_t* ps_mb_info_nmb =
4409 &ps_codec->as_process[i].ps_nmb_info[0];
4410
4411 for (nmb_cntr = 0; nmb_cntr < max_mb_cols; nmb_cntr++)
4412 {
4413 ps_mb_info_nmb[nmb_cntr].pu1_best_sub_pel_buf = pu1_buf;
4414
4415 pu1_buf = pu1_buf + subpel_buf_size;
4416
4417 ps_mb_info_nmb[nmb_cntr].u4_bst_spel_buf_strd = MB_SIZE;
4418 }
4419 }
4420 }
4421
4422 ps_mem_rec = &ps_mem_rec_base[MEM_REC_RC];
4423 {
4424 ih264e_get_rate_control_mem_tab(&ps_codec->s_rate_control, ps_mem_rec,
4425 USE_BASE);
4426 }
4427
4428 /* init codec ctxt */
4429 status = ih264e_init(ps_codec);
4430
4431 return status;
4432 }
4433
4434 /**
4435 *******************************************************************************
4436 *
4437 * @brief
4438 * Retrieves mem records passed to the codec
4439 *
4440 * @par Description:
4441 * Retrieves mem recs passed during init
4442 *
4443 * @param[in] ps_codec_obj
4444 * Pointer to codec object at API level
4445 *
4446 * @param[in] pv_api_ip
4447 * Pointer to input argument structure
4448 *
4449 * @param[out] pv_api_op
4450 * Pointer to output argument structure
4451 *
4452 * @returns error status
4453 *
4454 * @remarks none
4455 *
4456 *******************************************************************************
4457 */
ih264e_retrieve_memrec(iv_obj_t * ps_codec_obj,void * pv_api_ip,void * pv_api_op)4458 static WORD32 ih264e_retrieve_memrec(iv_obj_t *ps_codec_obj,
4459 void *pv_api_ip,
4460 void *pv_api_op)
4461 {
4462 /* codec ctxt */
4463 codec_t *ps_codec = (codec_t *) ps_codec_obj->pv_codec_handle;
4464
4465 /* ctrl call I/O structures */
4466 ih264e_retrieve_mem_rec_ip_t *ps_ip = pv_api_ip;
4467 ih264e_retrieve_mem_rec_op_t *ps_op = pv_api_op;
4468
4469 if (ps_codec->i4_init_done != 1)
4470 {
4471 ps_op->s_ive_op.u4_error_code |= 1 << IVE_FATALERROR;
4472 ps_op->s_ive_op.u4_error_code |= IH264E_INIT_NOT_DONE;
4473 return IV_FAIL;
4474 }
4475
4476 /* join threads upon at end of sequence */
4477 ih264e_join_threads(ps_codec);
4478
4479 /* collect list of memory records used by the encoder library */
4480 memcpy(ps_ip->s_ive_ip.ps_mem_rec, ps_codec->ps_mem_rec_backup,
4481 MEM_REC_CNT * (sizeof(iv_mem_rec_t)));
4482 ps_op->s_ive_op.u4_num_mem_rec_filled = MEM_REC_CNT;
4483
4484 /* clean up mutex memory */
4485 ih264_list_free(ps_codec->pv_entropy_jobq);
4486 ih264_list_free(ps_codec->pv_proc_jobq);
4487 ithread_mutex_destroy(ps_codec->pv_ctl_mutex);
4488 ithread_mutex_destroy(ps_codec->pv_entropy_mutex);
4489
4490
4491 ih264_buf_mgr_free((buf_mgr_t *)ps_codec->pv_mv_buf_mgr);
4492 ih264_buf_mgr_free((buf_mgr_t *)ps_codec->pv_ref_buf_mgr);
4493 ih264_buf_mgr_free((buf_mgr_t *)ps_codec->pv_inp_buf_mgr);
4494 ih264_buf_mgr_free((buf_mgr_t *)ps_codec->pv_out_buf_mgr);
4495
4496 return IV_SUCCESS;
4497 }
4498
4499 /**
4500 *******************************************************************************
4501 *
4502 * @brief
4503 * Sets the encoder in flush mode.
4504 *
4505 * @par Description:
4506 * Sets the encoder in flush mode
4507 *
4508 * @param[in] ps_codec_obj
4509 * Pointer to codec object at API level
4510 *
4511 * @param[in] pv_api_ip
4512 * Pointer to input argument structure
4513 *
4514 * @param[out] pv_api_op
4515 * Pointer to output argument structure
4516 *
4517 * @returns error status
4518 *
4519 * @remarks This call has no real effect on encoder
4520 *
4521 *******************************************************************************
4522 */
ih264e_set_flush_mode(iv_obj_t * ps_codec_obj,void * pv_api_ip,void * pv_api_op)4523 static WORD32 ih264e_set_flush_mode(iv_obj_t *ps_codec_obj,
4524 void *pv_api_ip,
4525 void *pv_api_op)
4526 {
4527 /* codec ctxt */
4528 codec_t *ps_codec = (codec_t *) ps_codec_obj->pv_codec_handle;
4529
4530 /* ctrl call I/O structures */
4531 ih264e_ctl_flush_op_t *ps_ctl_op = pv_api_op;
4532
4533 UNUSED(pv_api_ip);
4534
4535 ps_ctl_op->s_ive_op.u4_error_code = 0;
4536
4537 /* signal flush frame control call */
4538 ps_codec->i4_flush_mode = 1;
4539
4540 return IV_SUCCESS;
4541 }
4542
4543 /**
4544 *******************************************************************************
4545 *
4546 * @brief
4547 * Gets encoder buffer requirements
4548 *
4549 * @par Description:
4550 * Gets the encoder buffer requirements. Basing on max width and max height
4551 * configuration settings, this routine, computes the sizes of necessary input,
4552 * output buffers returns this info to callee.
4553 *
4554 * @param[in] ps_codec_obj
4555 * Pointer to codec object at API level
4556 *
4557 * @param[in] pv_api_ip
4558 * Pointer to input argument structure
4559 *
4560 * @param[out] pv_api_op
4561 * Pointer to output argument structure
4562 *
4563 * @returns error status
4564 *
4565 * @remarks none
4566 *
4567 *******************************************************************************
4568 */
ih264e_get_buf_info(iv_obj_t * ps_codec_obj,void * pv_api_ip,void * pv_api_op)4569 static WORD32 ih264e_get_buf_info(iv_obj_t *ps_codec_obj,
4570 void *pv_api_ip,
4571 void *pv_api_op)
4572 {
4573 /* ctrl call I/O structures */
4574 ih264e_ctl_getbufinfo_ip_t *ps_ip = pv_api_ip;
4575 ih264e_ctl_getbufinfo_op_t *ps_op = pv_api_op;
4576
4577 /* temp var */
4578 WORD32 wd = ALIGN16(ps_ip->s_ive_ip.u4_max_wd);
4579 WORD32 ht = ALIGN16(ps_ip->s_ive_ip.u4_max_ht);
4580 WORD32 i;
4581
4582 UNUSED(ps_codec_obj);
4583
4584 ps_op->s_ive_op.u4_error_code = 0;
4585
4586 /* Number of components in input buffers required for codec &
4587 * Minimum sizes of each component in input buffer required */
4588 if (ps_ip->s_ive_ip.e_inp_color_fmt == IV_YUV_420P)
4589 {
4590 ps_op->s_ive_op.u4_inp_comp_cnt = MIN_RAW_BUFS_420_COMP;
4591
4592 ps_op->s_ive_op.au4_min_in_buf_size[0] = wd * ht;
4593 ps_op->s_ive_op.au4_min_in_buf_size[1] = (wd >> 1) * (ht >> 1);
4594 ps_op->s_ive_op.au4_min_in_buf_size[2] = (wd >> 1) * (ht >> 1);
4595 }
4596 else if (ps_ip->s_ive_ip.e_inp_color_fmt == IV_YUV_422ILE)
4597 {
4598 ps_op->s_ive_op.u4_inp_comp_cnt = MIN_RAW_BUFS_422ILE_COMP;
4599
4600 ps_op->s_ive_op.au4_min_in_buf_size[0] = wd * ht * 2;
4601 ps_op->s_ive_op.au4_min_in_buf_size[1] =
4602 ps_op->s_ive_op.au4_min_in_buf_size[2] = 0;
4603 }
4604 else if (ps_ip->s_ive_ip.e_inp_color_fmt == IV_RGB_565)
4605 {
4606 ps_op->s_ive_op.u4_inp_comp_cnt = MIN_RAW_BUFS_RGB565_COMP;
4607
4608 ps_op->s_ive_op.au4_min_in_buf_size[0] = wd * ht * 2;
4609 ps_op->s_ive_op.au4_min_in_buf_size[1] =
4610 ps_op->s_ive_op.au4_min_in_buf_size[2] = 0;
4611 }
4612 else if (ps_ip->s_ive_ip.e_inp_color_fmt == IV_RGBA_8888)
4613 {
4614 ps_op->s_ive_op.u4_inp_comp_cnt = MIN_RAW_BUFS_RGBA8888_COMP;
4615
4616 ps_op->s_ive_op.au4_min_in_buf_size[0] = wd * ht * 4;
4617 ps_op->s_ive_op.au4_min_in_buf_size[1] =
4618 ps_op->s_ive_op.au4_min_in_buf_size[2] = 0;
4619 }
4620 else if ((ps_ip->s_ive_ip.e_inp_color_fmt == IV_YUV_420SP_UV)
4621 || (ps_ip->s_ive_ip.e_inp_color_fmt == IV_YUV_420SP_VU))
4622 {
4623 ps_op->s_ive_op.u4_inp_comp_cnt = MIN_RAW_BUFS_420SP_COMP;
4624
4625 ps_op->s_ive_op.au4_min_in_buf_size[0] = wd * ht;
4626 ps_op->s_ive_op.au4_min_in_buf_size[1] = wd * (ht >> 1);
4627 ps_op->s_ive_op.au4_min_in_buf_size[2] = 0;
4628 }
4629
4630 /* Number of components in output buffers required for codec &
4631 * Minimum sizes of each component in output buffer required */
4632 ps_op->s_ive_op.u4_out_comp_cnt = MIN_BITS_BUFS_COMP;
4633
4634 for (i = 0; i < (WORD32) ps_op->s_ive_op.u4_out_comp_cnt; i++)
4635 {
4636 ps_op->s_ive_op.au4_min_out_buf_size[i] = MAX(((wd * ht * 3) >> 1), MIN_STREAM_SIZE);
4637 }
4638
4639 ps_op->s_ive_op.u4_min_inp_bufs = MIN_INP_BUFS;
4640 ps_op->s_ive_op.u4_min_out_bufs = MIN_OUT_BUFS;
4641
4642 return IV_SUCCESS;
4643 }
4644
4645 /**
4646 *******************************************************************************
4647 *
4648 * @brief
4649 * Sets the picture dimensions
4650 *
4651 * @par Description:
4652 * Sets width, height, display width, display height and strides
4653 *
4654 * @param[in] pv_api_ip
4655 * Pointer to input argument structure
4656 *
4657 * @param[out] pv_api_op
4658 * Pointer to output argument structure
4659 *
4660 * @param[out] ps_cfg
4661 * Pointer to config structure to be updated
4662 *
4663 * @returns error status
4664 *
4665 * @remarks none
4666 *
4667 *******************************************************************************
4668 */
ih264e_set_dimensions(void * pv_api_ip,void * pv_api_op,cfg_params_t * ps_cfg)4669 static IV_STATUS_T ih264e_set_dimensions(void *pv_api_ip,
4670 void *pv_api_op,
4671 cfg_params_t *ps_cfg)
4672 {
4673 /* ctrl call I/O structures */
4674 ih264e_ctl_set_dimensions_ip_t *ps_ip = pv_api_ip;
4675 ih264e_ctl_set_dimensions_op_t *ps_op = pv_api_op;
4676
4677 ps_op->s_ive_op.u4_error_code = 0;
4678
4679 ps_cfg->u4_wd = ALIGN16(ps_ip->s_ive_ip.u4_wd);
4680 ps_cfg->u4_ht = ALIGN16(ps_ip->s_ive_ip.u4_ht);
4681 ps_cfg->i4_wd_mbs = ps_cfg->u4_wd >> 4;
4682 ps_cfg->i4_ht_mbs = ps_cfg->u4_ht >> 4;
4683 ps_cfg->u4_disp_wd = ps_ip->s_ive_ip.u4_wd;
4684 ps_cfg->u4_disp_ht = ps_ip->s_ive_ip.u4_ht;
4685
4686 ps_cfg->u4_timestamp_high = ps_ip->s_ive_ip.u4_timestamp_high;
4687 ps_cfg->u4_timestamp_low = ps_ip->s_ive_ip.u4_timestamp_low;
4688
4689 return IV_SUCCESS;
4690 }
4691
4692 /**
4693 *******************************************************************************
4694 *
4695 * @brief
4696 * Sets source and target frame rates
4697 *
4698 * @par Description:
4699 * Sets source and target frame rates
4700 *
4701 * @param[in] pv_api_ip
4702 * Pointer to input argument structure
4703 *
4704 * @param[out] pv_api_op
4705 * Pointer to output argument structure
4706 *
4707 * @param[out] ps_cfg
4708 * Pointer to config structure to be updated
4709 *
4710 * @returns error status
4711 *
4712 * @remarks none
4713 *
4714 *******************************************************************************
4715 */
ih264e_set_frame_rate(void * pv_api_ip,void * pv_api_op,cfg_params_t * ps_cfg)4716 static IV_STATUS_T ih264e_set_frame_rate(void *pv_api_ip,
4717 void *pv_api_op,
4718 cfg_params_t *ps_cfg)
4719 {
4720 /* ctrl call I/O structures */
4721 ih264e_ctl_set_frame_rate_ip_t *ps_ip = pv_api_ip;
4722 ih264e_ctl_set_frame_rate_op_t *ps_op = pv_api_op;
4723
4724 ps_op->s_ive_op.u4_error_code = 0;
4725
4726 ps_cfg->u4_src_frame_rate = ps_ip->s_ive_ip.u4_src_frame_rate;
4727 ps_cfg->u4_tgt_frame_rate = ps_ip->s_ive_ip.u4_tgt_frame_rate;
4728
4729 ps_cfg->u4_timestamp_high = ps_ip->s_ive_ip.u4_timestamp_high;
4730 ps_cfg->u4_timestamp_low = ps_ip->s_ive_ip.u4_timestamp_low;
4731
4732 return IV_SUCCESS;
4733 }
4734
4735 /**
4736 *******************************************************************************
4737 *
4738 * @brief
4739 * Sets target bit rate
4740 *
4741 * @par Description:
4742 * Sets target bit rate
4743 *
4744 * @param[in] pv_api_ip
4745 * Pointer to input argument structure
4746 *
4747 * @param[out] pv_api_op
4748 * Pointer to output argument structure
4749 *
4750 * @param[out] ps_cfg
4751 * Pointer to config structure to be updated
4752 *
4753 * @returns error status
4754 *
4755 * @remarks none
4756 *
4757 *******************************************************************************
4758 */
ih264e_set_bit_rate(void * pv_api_ip,void * pv_api_op,cfg_params_t * ps_cfg)4759 static IV_STATUS_T ih264e_set_bit_rate(void *pv_api_ip,
4760 void *pv_api_op,
4761 cfg_params_t *ps_cfg)
4762 {
4763 /* ctrl call I/O structures */
4764 ih264e_ctl_set_bitrate_ip_t *ps_ip = pv_api_ip;
4765 ih264e_ctl_set_bitrate_op_t *ps_op = pv_api_op;
4766
4767 ps_op->s_ive_op.u4_error_code = 0;
4768
4769 ps_cfg->u4_target_bitrate = ps_ip->s_ive_ip.u4_target_bitrate;
4770
4771 ps_cfg->u4_timestamp_high = ps_ip->s_ive_ip.u4_timestamp_high;
4772 ps_cfg->u4_timestamp_low = ps_ip->s_ive_ip.u4_timestamp_low;
4773
4774 return IV_SUCCESS;
4775 }
4776
4777 /**
4778 *******************************************************************************
4779 *
4780 * @brief
4781 * Sets frame type
4782 *
4783 * @par Description:
4784 * Sets frame type
4785 *
4786 * @param[in] pv_api_ip
4787 * Pointer to input argument structure
4788 *
4789 * @param[out] pv_api_op
4790 * Pointer to output argument structure
4791 *
4792 * @param[out] ps_cfg
4793 * Pointer to config structure to be updated
4794 *
4795 * @returns error status
4796 *
4797 * @remarks not a sticky tag
4798 *
4799 *******************************************************************************
4800 */
ih264e_set_frame_type(void * pv_api_ip,void * pv_api_op,cfg_params_t * ps_cfg)4801 static IV_STATUS_T ih264e_set_frame_type(void *pv_api_ip,
4802 void *pv_api_op,
4803 cfg_params_t *ps_cfg)
4804 {
4805 /* ctrl call I/O structures */
4806 ih264e_ctl_set_frame_type_ip_t *ps_ip = pv_api_ip;
4807 ih264e_ctl_set_frame_type_op_t *ps_op = pv_api_op;
4808
4809 ps_op->s_ive_op.u4_error_code = 0;
4810
4811 ps_cfg->e_frame_type = ps_ip->s_ive_ip.e_frame_type;
4812
4813 ps_cfg->u4_timestamp_high = ps_ip->s_ive_ip.u4_timestamp_high;
4814 ps_cfg->u4_timestamp_low = ps_ip->s_ive_ip.u4_timestamp_low;
4815
4816 return IV_SUCCESS;
4817 }
4818
4819 /**
4820 *******************************************************************************
4821 *
4822 * @brief
4823 * Sets quantization params
4824 *
4825 * @par Description:
4826 * Sets the max, min and default qp for I frame, P frame and B frame
4827 *
4828 * @param[in] pv_api_ip
4829 * Pointer to input argument structure
4830 *
4831 * @param[out] pv_api_op
4832 * Pointer to output argument structure
4833 *
4834 * @param[out] ps_cfg
4835 * Pointer to config structure to be updated
4836 *
4837 * @returns error status
4838 *
4839 * @remarks none
4840 *
4841 *******************************************************************************
4842 */
ih264e_set_qp(void * pv_api_ip,void * pv_api_op,cfg_params_t * ps_cfg)4843 static IV_STATUS_T ih264e_set_qp(void *pv_api_ip,
4844 void *pv_api_op,
4845 cfg_params_t *ps_cfg)
4846 {
4847 /* ctrl call I/O structures */
4848 ih264e_ctl_set_qp_ip_t *ps_set_qp_ip = pv_api_ip;
4849 ih264e_ctl_set_qp_op_t *ps_set_qp_op = pv_api_op;
4850
4851 ps_set_qp_op->s_ive_op.u4_error_code = 0;
4852
4853 ps_cfg->u4_i_qp_max = ps_set_qp_ip->s_ive_ip.u4_i_qp_max;
4854 ps_cfg->u4_i_qp_min = ps_set_qp_ip->s_ive_ip.u4_i_qp_min;
4855 ps_cfg->u4_i_qp = ps_set_qp_ip->s_ive_ip.u4_i_qp;
4856 ps_cfg->u4_p_qp_max = ps_set_qp_ip->s_ive_ip.u4_p_qp_max;
4857 ps_cfg->u4_p_qp_min = ps_set_qp_ip->s_ive_ip.u4_p_qp_min;
4858 ps_cfg->u4_p_qp = ps_set_qp_ip->s_ive_ip.u4_p_qp;
4859 ps_cfg->u4_b_qp_max = ps_set_qp_ip->s_ive_ip.u4_b_qp_max;
4860 ps_cfg->u4_b_qp_min = ps_set_qp_ip->s_ive_ip.u4_b_qp_min;
4861 ps_cfg->u4_b_qp = ps_set_qp_ip->s_ive_ip.u4_b_qp;
4862
4863 ps_cfg->u4_timestamp_high = ps_set_qp_ip->s_ive_ip.u4_timestamp_high;
4864 ps_cfg->u4_timestamp_low = ps_set_qp_ip->s_ive_ip.u4_timestamp_low;
4865
4866 return IV_SUCCESS;
4867 }
4868
4869 /**
4870 *******************************************************************************
4871 *
4872 * @brief
4873 * Sets encoding mode
4874 *
4875 * @par Description:
4876 * Sets encoding mode
4877 *
4878 * @param[in] pv_api_ip
4879 * Pointer to input argument structure
4880 *
4881 * @param[out] pv_api_op
4882 * Pointer to output argument structure
4883 *
4884 * @param[out] ps_cfg
4885 * Pointer to config structure to be updated
4886 *
4887 * @returns error status
4888 *
4889 * @remarks none
4890 *
4891 *******************************************************************************
4892 */
ih264e_set_enc_mode(void * pv_api_ip,void * pv_api_op,cfg_params_t * ps_cfg)4893 static IV_STATUS_T ih264e_set_enc_mode(void *pv_api_ip,
4894 void *pv_api_op,
4895 cfg_params_t *ps_cfg)
4896 {
4897 /* ctrl call I/O structures */
4898 ih264e_ctl_set_enc_mode_ip_t *ps_ip = pv_api_ip;
4899 ih264e_ctl_set_enc_mode_op_t *ps_op = pv_api_op;
4900
4901 ps_op->s_ive_op.u4_error_code = 0;
4902
4903 ps_cfg->e_enc_mode = ps_ip->s_ive_ip.e_enc_mode;
4904
4905 ps_cfg->u4_timestamp_high = ps_ip->s_ive_ip.u4_timestamp_high;
4906 ps_cfg->u4_timestamp_low = ps_ip->s_ive_ip.u4_timestamp_low;
4907
4908 return IV_SUCCESS;
4909 }
4910
4911 /**
4912 *******************************************************************************
4913 *
4914 * @brief
4915 * Sets vbv parameters
4916 *
4917 * @par Description:
4918 * Sets vbv parameters
4919 *
4920 * @param[in] pv_api_ip
4921 * Pointer to input argument structure
4922 *
4923 * @param[out] pv_api_op
4924 * Pointer to output argument structure
4925 *
4926 * @param[out] ps_cfg
4927 * Pointer to config structure to be updated
4928 *
4929 * @returns error status
4930 *
4931 * @remarks none
4932 *
4933 *******************************************************************************
4934 */
ih264e_set_vbv_params(void * pv_api_ip,void * pv_api_op,cfg_params_t * ps_cfg)4935 static IV_STATUS_T ih264e_set_vbv_params(void *pv_api_ip,
4936 void *pv_api_op,
4937 cfg_params_t *ps_cfg)
4938 {
4939 /* ctrl call I/O structures */
4940 ih264e_ctl_set_vbv_params_ip_t *ps_ip = pv_api_ip;
4941 ih264e_ctl_set_vbv_params_op_t *ps_op = pv_api_op;
4942
4943 ps_op->s_ive_op.u4_error_code = 0;
4944
4945 ps_cfg->u4_vbv_buf_size = ps_ip->s_ive_ip.u4_vbv_buf_size;
4946 ps_cfg->u4_vbv_buffer_delay = ps_ip->s_ive_ip.u4_vbv_buffer_delay;
4947
4948 ps_cfg->u4_timestamp_high = ps_ip->s_ive_ip.u4_timestamp_high;
4949 ps_cfg->u4_timestamp_low = ps_ip->s_ive_ip.u4_timestamp_low;
4950
4951 return IV_SUCCESS;
4952 }
4953
4954 /**
4955 *******************************************************************************
4956 *
4957 * @brief
4958 * Sets AIR parameters
4959 *
4960 * @par Description:
4961 * Sets AIR parameters
4962 *
4963 * @param[in] pv_api_ip
4964 * Pointer to input argument structure
4965 *
4966 * @param[out] pv_api_op
4967 * Pointer to output argument structure
4968 *
4969 * @param[out] ps_cfg
4970 * Pointer to config structure to be updated
4971 *
4972 * @returns error status
4973 *
4974 * @remarks none
4975 *
4976 *******************************************************************************
4977 */
ih264_set_air_params(void * pv_api_ip,void * pv_api_op,cfg_params_t * ps_cfg)4978 static IV_STATUS_T ih264_set_air_params(void *pv_api_ip,
4979 void *pv_api_op,
4980 cfg_params_t *ps_cfg)
4981 {
4982 /* ctrl call I/O structures */
4983 ih264e_ctl_set_air_params_ip_t *ps_ip = pv_api_ip;
4984 ih264e_ctl_set_air_params_op_t *ps_op = pv_api_op;
4985
4986 ps_op->s_ive_op.u4_error_code = 0;
4987
4988 ps_cfg->e_air_mode = ps_ip->s_ive_ip.e_air_mode;
4989 ps_cfg->u4_air_refresh_period = ps_ip->s_ive_ip.u4_air_refresh_period;
4990
4991 ps_cfg->u4_timestamp_high = ps_ip->s_ive_ip.u4_timestamp_high;
4992 ps_cfg->u4_timestamp_low = ps_ip->s_ive_ip.u4_timestamp_low;
4993
4994 return IV_SUCCESS;
4995 }
4996
4997 /**
4998 *******************************************************************************
4999 *
5000 * @brief
5001 * Sets motion estimation parameters
5002 *
5003 * @par Description:
5004 * Sets motion estimation parameters
5005 *
5006 * @param[in] pv_api_ip
5007 * Pointer to input argument structure
5008 *
5009 * @param[out] pv_api_op
5010 * Pointer to output argument structure
5011 *
5012 * @param[out] ps_cfg
5013 * Pointer to config structure to be updated
5014 *
5015 * @returns error status
5016 *
5017 * @remarks none
5018 *
5019 *******************************************************************************
5020 */
ih264_set_me_params(void * pv_api_ip,void * pv_api_op,cfg_params_t * ps_cfg)5021 static IV_STATUS_T ih264_set_me_params(void *pv_api_ip,
5022 void *pv_api_op,
5023 cfg_params_t *ps_cfg)
5024 {
5025 /* ctrl call I/O structures */
5026 ih264e_ctl_set_me_params_ip_t *ps_ip = pv_api_ip;
5027 ih264e_ctl_set_me_params_op_t *ps_op = pv_api_op;
5028
5029 ps_op->s_ive_op.u4_error_code = 0;
5030
5031 ps_cfg->u4_enable_hpel = ps_ip->s_ive_ip.u4_enable_hpel;
5032 ps_cfg->u4_enable_qpel = ps_ip->s_ive_ip.u4_enable_qpel;
5033 ps_cfg->u4_enable_fast_sad = ps_ip->s_ive_ip.u4_enable_fast_sad;
5034 ps_cfg->u4_enable_alt_ref = ps_ip->s_ive_ip.u4_enable_alt_ref;
5035 ps_cfg->u4_srch_rng_x = ps_ip->s_ive_ip.u4_srch_rng_x;
5036 ps_cfg->u4_srch_rng_y = ps_ip->s_ive_ip.u4_srch_rng_y;
5037 ps_cfg->u4_me_speed_preset = ps_ip->s_ive_ip.u4_me_speed_preset;
5038
5039 ps_cfg->u4_timestamp_high = ps_ip->s_ive_ip.u4_timestamp_high;
5040 ps_cfg->u4_timestamp_low = ps_ip->s_ive_ip.u4_timestamp_low;
5041
5042 return IV_SUCCESS;
5043 }
5044
5045 /**
5046 *******************************************************************************
5047 *
5048 * @brief
5049 * Sets Intra/Inter Prediction estimation parameters
5050 *
5051 * @par Description:
5052 * Sets Intra/Inter Prediction estimation parameters
5053 *
5054 * @param[in] pv_api_ip
5055 * Pointer to input argument structure
5056 *
5057 * @param[out] pv_api_op
5058 * Pointer to output argument structure
5059 *
5060 * @param[out] ps_cfg
5061 * Pointer to config structure to be updated
5062 *
5063 * @returns error status
5064 *
5065 * @remarks none
5066 *
5067 *******************************************************************************
5068 */
ih264_set_ipe_params(void * pv_api_ip,void * pv_api_op,cfg_params_t * ps_cfg)5069 static IV_STATUS_T ih264_set_ipe_params(void *pv_api_ip,
5070 void *pv_api_op,
5071 cfg_params_t *ps_cfg)
5072 {
5073 /* ctrl call I/O structures */
5074 ih264e_ctl_set_ipe_params_ip_t *ps_ip = pv_api_ip;
5075 ih264e_ctl_set_ipe_params_op_t *ps_op = pv_api_op;
5076
5077 ps_op->s_ive_op.u4_error_code = 0;
5078
5079 ps_cfg->u4_enable_intra_4x4 = ps_ip->s_ive_ip.u4_enable_intra_4x4;
5080 ps_cfg->u4_enc_speed_preset = ps_ip->s_ive_ip.u4_enc_speed_preset;
5081
5082 ps_cfg->u4_constrained_intra_pred = ps_ip->s_ive_ip.u4_constrained_intra_pred;
5083
5084 ps_cfg->u4_timestamp_high = ps_ip->s_ive_ip.u4_timestamp_high;
5085 ps_cfg->u4_timestamp_low = ps_ip->s_ive_ip.u4_timestamp_low;
5086
5087 return IV_SUCCESS;
5088 }
5089
5090 /**
5091 *******************************************************************************
5092 *
5093 * @brief
5094 * Sets GOP parameters
5095 *
5096 * @par Description:
5097 * Sets GOP parameters
5098 *
5099 * @param[in] pv_api_ip
5100 * Pointer to input argument structure
5101 *
5102 * @param[out] pv_api_op
5103 * Pointer to output argument structure
5104 *
5105 * @param[out] ps_cfg
5106 * Pointer to config structure to be updated
5107 *
5108 * @returns error status
5109 *
5110 * @remarks none
5111 *
5112 *******************************************************************************
5113 */
ih264_set_gop_params(void * pv_api_ip,void * pv_api_op,cfg_params_t * ps_cfg)5114 static IV_STATUS_T ih264_set_gop_params(void *pv_api_ip,
5115 void *pv_api_op,
5116 cfg_params_t *ps_cfg)
5117 {
5118 /* ctrl call I/O structures */
5119 ih264e_ctl_set_gop_params_ip_t *ps_ip = pv_api_ip;
5120 ih264e_ctl_set_gop_params_op_t *ps_op = pv_api_op;
5121
5122 ps_op->s_ive_op.u4_error_code = 0;
5123
5124 ps_cfg->u4_i_frm_interval = ps_ip->s_ive_ip.u4_i_frm_interval;
5125 ps_cfg->u4_idr_frm_interval = ps_ip->s_ive_ip.u4_idr_frm_interval;
5126
5127 ps_cfg->u4_timestamp_high = ps_ip->s_ive_ip.u4_timestamp_high;
5128 ps_cfg->u4_timestamp_low = ps_ip->s_ive_ip.u4_timestamp_low;
5129
5130 return IV_SUCCESS;
5131 }
5132
5133 /**
5134 *******************************************************************************
5135 *
5136 * @brief
5137 * Sets profile parameters
5138 *
5139 * @par Description:
5140 * Sets profile parameters
5141 *
5142 * @param[in] pv_api_ip
5143 * Pointer to input argument structure
5144 *
5145 * @param[out] pv_api_op
5146 * Pointer to output argument structure
5147 *
5148 * @param[out] ps_cfg
5149 * Pointer to config structure to be updated
5150 *
5151 * @returns error status
5152 *
5153 * @remarks none
5154 *
5155 *******************************************************************************
5156 */
ih264_set_profile_params(void * pv_api_ip,void * pv_api_op,cfg_params_t * ps_cfg)5157 static IV_STATUS_T ih264_set_profile_params(void *pv_api_ip,
5158 void *pv_api_op,
5159 cfg_params_t *ps_cfg)
5160 {
5161 /* ctrl call I/O structures */
5162 ih264e_ctl_set_profile_params_ip_t *ps_ip = pv_api_ip;
5163 ih264e_ctl_set_profile_params_op_t *ps_op = pv_api_op;
5164
5165 ps_op->s_ive_op.u4_error_code = 0;
5166
5167 ps_cfg->e_profile = ps_ip->s_ive_ip.e_profile;
5168
5169 ps_cfg->u4_entropy_coding_mode = ps_ip->s_ive_ip.u4_entropy_coding_mode;
5170
5171 ps_cfg->u4_timestamp_high = ps_ip->s_ive_ip.u4_timestamp_high;
5172 ps_cfg->u4_timestamp_low = ps_ip->s_ive_ip.u4_timestamp_low;
5173
5174 return IV_SUCCESS;
5175 }
5176
5177 /**
5178 *******************************************************************************
5179 *
5180 * @brief
5181 * Sets disable deblock level
5182 *
5183 * @par Description:
5184 * Sets disable deblock level. Level 0 means no disabling and level 4 means
5185 * disable completely. 1, 2, 3 are intermediate levels that control amount
5186 * of deblocking done.
5187 *
5188 * @param[in] ps_codec_obj
5189 * Pointer to codec object at API level
5190 *
5191 * @param[in] pv_api_ip
5192 * Pointer to input argument structure
5193 *
5194 * @param[out] pv_api_op
5195 * Pointer to output argument structure
5196 *
5197 * @returns error status
5198 *
5199 * @remarks none
5200 *
5201 *******************************************************************************
5202 */
ih264_set_deblock_params(void * pv_api_ip,void * pv_api_op,cfg_params_t * ps_cfg)5203 static WORD32 ih264_set_deblock_params(void *pv_api_ip,
5204 void *pv_api_op,
5205 cfg_params_t *ps_cfg)
5206 {
5207 /* ctrl call I/O structures */
5208 ih264e_ctl_set_deblock_params_ip_t *ps_ip = pv_api_ip;
5209 ih264e_ctl_set_deblock_params_op_t *ps_op = pv_api_op;
5210
5211 ps_op->s_ive_op.u4_error_code = 0;
5212
5213 ps_cfg->u4_disable_deblock_level = ps_ip->s_ive_ip.u4_disable_deblock_level;
5214
5215 ps_cfg->u4_timestamp_high = ps_ip->s_ive_ip.u4_timestamp_high;
5216 ps_cfg->u4_timestamp_low = ps_ip->s_ive_ip.u4_timestamp_low;
5217
5218 return IV_SUCCESS;
5219 }
5220
5221 /**
5222 *******************************************************************************
5223 *
5224 * @brief
5225 * Sets number of cores
5226 *
5227 * @par Description:
5228 * Sets number of cores
5229 *
5230 * @param[in] ps_codec_obj
5231 * Pointer to codec object at API level
5232 *
5233 * @param[in] pv_api_ip
5234 * Pointer to input argument structure
5235 *
5236 * @param[out] pv_api_op
5237 * Pointer to output argument structure
5238 *
5239 * @returns error status
5240 *
5241 * @remarks The number of encoder threads is limited to MAX_PROCESS_THREADS
5242 *
5243 *******************************************************************************
5244 */
ih264e_set_num_cores(void * pv_api_ip,void * pv_api_op,cfg_params_t * ps_cfg)5245 static WORD32 ih264e_set_num_cores(void *pv_api_ip,
5246 void *pv_api_op,
5247 cfg_params_t *ps_cfg)
5248 {
5249 /* ctrl call I/O structures */
5250 ih264e_ctl_set_num_cores_ip_t *ps_ip = pv_api_ip;
5251 ih264e_ctl_set_num_cores_op_t *ps_op = pv_api_op;
5252
5253 ps_op->s_ive_op.u4_error_code = 0;
5254
5255 ps_cfg->u4_num_cores = MIN(ps_ip->s_ive_ip.u4_num_cores, MAX_PROCESS_THREADS);
5256
5257 ps_cfg->u4_timestamp_high = ps_ip->s_ive_ip.u4_timestamp_high;
5258 ps_cfg->u4_timestamp_low = ps_ip->s_ive_ip.u4_timestamp_low;
5259
5260 return IV_SUCCESS;
5261 }
5262
5263 /**
5264 *******************************************************************************
5265 *
5266 * @brief
5267 * Resets encoder state
5268 *
5269 * @par Description:
5270 * Resets encoder state by calling ih264e_init()
5271 *
5272 * @param[in] ps_codec_obj
5273 * Pointer to codec object at API level
5274 *
5275 * @param[in] pv_api_ip
5276 * Pointer to input argument structure
5277 *
5278 * @param[out] pv_api_op
5279 * Pointer to output argument structure
5280 *
5281 * @returns error status
5282 *
5283 * @remarks none
5284 *
5285 *******************************************************************************
5286 */
ih264e_reset(iv_obj_t * ps_codec_obj,void * pv_api_ip,void * pv_api_op)5287 static WORD32 ih264e_reset(iv_obj_t *ps_codec_obj,
5288 void *pv_api_ip,
5289 void *pv_api_op)
5290 {
5291 /* codec ctxt */
5292 codec_t * ps_codec = (codec_t *) (ps_codec_obj->pv_codec_handle);
5293
5294 /* ctrl call I/O structures */
5295 ih264e_ctl_reset_op_t *ps_op = pv_api_op;
5296
5297 UNUSED(pv_api_ip);
5298
5299 ps_op->s_ive_op.u4_error_code = 0;
5300
5301 if (ps_codec != NULL)
5302 {
5303 ih264e_init(ps_codec);
5304 }
5305 else
5306 {
5307 ps_op->s_ive_op.u4_error_code = IH264E_INIT_NOT_DONE;
5308 }
5309
5310 return IV_SUCCESS;
5311 }
5312
5313 /**
5314 *******************************************************************************
5315 *
5316 * @brief
5317 * Codec control call
5318 *
5319 * @par Description:
5320 * Codec control call which in turn calls appropriate calls based on sub-command
5321 *
5322 * @param[in] ps_codec_obj
5323 * Pointer to codec object at API level
5324 *
5325 * @param[in] pv_api_ip
5326 * Pointer to input argument structure
5327 *
5328 * @param[out] pv_api_op
5329 * Pointer to output argument structure
5330 *
5331 * @returns error status
5332 *
5333 * @remarks none
5334 *
5335 *******************************************************************************
5336 */
ih264e_ctl(iv_obj_t * ps_codec_obj,void * pv_api_ip,void * pv_api_op)5337 static WORD32 ih264e_ctl(iv_obj_t *ps_codec_obj,
5338 void *pv_api_ip,
5339 void *pv_api_op)
5340 {
5341 /* codec ctxt */
5342 codec_t *ps_codec = (codec_t *) ps_codec_obj->pv_codec_handle;
5343
5344 /* ctrl call I/O structures */
5345 ih264e_ctl_setdefault_ip_t *ps_ctl_ip = pv_api_ip;
5346 ih264e_ctl_setdefault_op_t *ps_ctl_op = pv_api_op;
5347
5348 /* ctrl call sub cmd */
5349 IVE_CONTROL_API_COMMAND_TYPE_T sub_cmd = ps_ctl_ip->s_ive_ip.e_sub_cmd;
5350
5351 /* error status */
5352 IV_STATUS_T ret = IV_SUCCESS;
5353
5354 /* temp var */
5355 WORD32 i;
5356 cfg_params_t *ps_cfg = NULL;
5357
5358 /* control call is for configuring encoding params, this is not to be called
5359 * before a successful init call */
5360 if (ps_codec->i4_init_done != 1)
5361 {
5362 ps_ctl_op->s_ive_op.u4_error_code |= 1 << IVE_FATALERROR;
5363 ps_ctl_op->s_ive_op.u4_error_code |= IH264E_INIT_NOT_DONE;
5364 return IV_FAIL;
5365 }
5366
5367 /* make it thread safe */
5368 ithread_mutex_lock(ps_codec->pv_ctl_mutex);
5369
5370 /* find a free config param set to hold current parameters */
5371 for (i = 0; i < MAX_ACTIVE_CONFIG_PARAMS; i++)
5372 {
5373 if (0 == ps_codec->as_cfg[i].u4_is_valid)
5374 {
5375 ps_cfg = &ps_codec->as_cfg[i];
5376 break;
5377 }
5378 }
5379
5380 /* If all are invalid, then start overwriting from the head config params */
5381 if (NULL == ps_cfg)
5382 {
5383 ps_cfg = &ps_codec->as_cfg[0];
5384 }
5385
5386 ps_cfg->u4_is_valid = 1;
5387
5388 ps_cfg->e_cmd = sub_cmd;
5389
5390 switch (sub_cmd)
5391 {
5392 case IVE_CMD_CTL_SET_DIMENSIONS:
5393 ret = ih264e_set_dimensions(pv_api_ip, pv_api_op, ps_cfg);
5394 break;
5395
5396 case IVE_CMD_CTL_SET_FRAMERATE:
5397 ret = ih264e_set_frame_rate(pv_api_ip, pv_api_op, ps_cfg);
5398 break;
5399
5400 case IVE_CMD_CTL_SET_BITRATE:
5401 ret = ih264e_set_bit_rate(pv_api_ip, pv_api_op, ps_cfg);
5402 break;
5403
5404 case IVE_CMD_CTL_SET_FRAMETYPE:
5405 ret = ih264e_set_frame_type(pv_api_ip, pv_api_op, ps_cfg);
5406 break;
5407
5408 case IVE_CMD_CTL_SET_QP:
5409 ret = ih264e_set_qp(pv_api_ip, pv_api_op, ps_cfg);
5410 break;
5411
5412 case IVE_CMD_CTL_SET_ENC_MODE:
5413 ret = ih264e_set_enc_mode(pv_api_ip, pv_api_op, ps_cfg);
5414 break;
5415
5416 case IVE_CMD_CTL_SET_VBV_PARAMS:
5417 ret = ih264e_set_vbv_params(pv_api_ip, pv_api_op, ps_cfg);
5418 break;
5419
5420 case IVE_CMD_CTL_SET_AIR_PARAMS:
5421 ret = ih264_set_air_params(pv_api_ip, pv_api_op, ps_cfg);
5422 break;
5423
5424 case IVE_CMD_CTL_SET_ME_PARAMS:
5425 ret = ih264_set_me_params(pv_api_ip, pv_api_op, ps_cfg);
5426 break;
5427
5428 case IVE_CMD_CTL_SET_IPE_PARAMS:
5429 ret = ih264_set_ipe_params(pv_api_ip, pv_api_op, ps_cfg);
5430 break;
5431
5432 case IVE_CMD_CTL_SET_GOP_PARAMS:
5433 ret = ih264_set_gop_params(pv_api_ip, pv_api_op, ps_cfg);
5434 break;
5435
5436 case IVE_CMD_CTL_SET_PROFILE_PARAMS:
5437 ret = ih264_set_profile_params(pv_api_ip, pv_api_op, ps_cfg);
5438 break;
5439
5440 case IVE_CMD_CTL_SET_DEBLOCK_PARAMS:
5441 ret = ih264_set_deblock_params(pv_api_ip, pv_api_op, ps_cfg);
5442 break;
5443
5444 case IVE_CMD_CTL_RESET:
5445
5446 /* invalidate config param struct as it is being served right away */
5447 ps_codec->as_cfg[i].u4_is_valid = 0;
5448
5449 ret = ih264e_reset(ps_codec_obj, pv_api_ip, pv_api_op);
5450 break;
5451
5452 case IVE_CMD_CTL_SETDEFAULT:
5453 {
5454 /* ctrl call I/O structures */
5455 ih264e_ctl_setdefault_op_t *ps_op = pv_api_op;
5456
5457 /* invalidate config param struct as it is being served right away */
5458 ps_codec->as_cfg[i].u4_is_valid = 0;
5459
5460 /* error status */
5461 ret = ih264e_set_default_params(ps_cfg);
5462
5463 ps_op->s_ive_op.u4_error_code = ret;
5464
5465 break;
5466 }
5467
5468 case IVE_CMD_CTL_FLUSH:
5469
5470 /* invalidate config param struct as it is being served right away */
5471 ps_codec->as_cfg[i].u4_is_valid = 0;
5472
5473 ret = ih264e_set_flush_mode(ps_codec_obj, pv_api_ip, pv_api_op);
5474 break;
5475
5476 case IVE_CMD_CTL_GETBUFINFO:
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 ret = ih264e_get_buf_info(ps_codec_obj, pv_api_ip, pv_api_op);
5482 break;
5483
5484 case IVE_CMD_CTL_GETVERSION:
5485 {
5486 /* ctrl call I/O structures */
5487 ih264e_ctl_getversioninfo_ip_t *ps_ip = pv_api_ip;
5488 ih264e_ctl_getversioninfo_op_t *ps_op = pv_api_op;
5489
5490 /* invalidate config param struct as it is being served right away */
5491 ps_codec->as_cfg[i].u4_is_valid = 0;
5492
5493 /* error status */
5494 ps_op->s_ive_op.u4_error_code = IV_SUCCESS;
5495
5496 if (ps_ip->s_ive_ip.u4_version_bufsize <= 0)
5497 {
5498 ps_op->s_ive_op.u4_error_code =
5499 IH264E_CXA_VERS_BUF_INSUFFICIENT;
5500 ret = IV_FAIL;
5501 }
5502 else
5503 {
5504 ret = ih264e_get_version((CHAR *) ps_ip->s_ive_ip.pu1_version,
5505 ps_ip->s_ive_ip.u4_version_bufsize);
5506
5507 if (ret != IV_SUCCESS)
5508 {
5509 ps_op->s_ive_op.u4_error_code =
5510 IH264E_CXA_VERS_BUF_INSUFFICIENT;
5511 ret = IV_FAIL;
5512 }
5513 }
5514 break;
5515 }
5516
5517 case IVE_CMD_CTL_SET_NUM_CORES:
5518 ret = ih264e_set_num_cores(pv_api_ip, pv_api_op, ps_cfg);
5519 break;
5520
5521 default:
5522 /* invalidate config param struct as it is being served right away */
5523 ps_codec->as_cfg[i].u4_is_valid = 0;
5524
5525 DEBUG("Warning !! unrecognized control api command \n");
5526 break;
5527 }
5528
5529 ithread_mutex_unlock(ps_codec->pv_ctl_mutex);
5530
5531 return ret;
5532 }
5533
5534 /**
5535 *******************************************************************************
5536 *
5537 * @brief
5538 * Codec entry point function. All the function calls to the codec are done
5539 * using this function with different values specified in command
5540 *
5541 * @par Description:
5542 * Arguments are tested for validity and then based on the command
5543 * appropriate function is called
5544 *
5545 * @param[in] ps_handle
5546 * API level handle for codec
5547 *
5548 * @param[in] pv_api_ip
5549 * Input argument structure
5550 *
5551 * @param[out] pv_api_op
5552 * Output argument structure
5553 *
5554 * @returns error_status
5555 *
5556 * @remarks
5557 *
5558 *******************************************************************************
5559 */
ih264e_api_function(iv_obj_t * ps_handle,void * pv_api_ip,void * pv_api_op)5560 IV_STATUS_T ih264e_api_function(iv_obj_t *ps_handle,
5561 void *pv_api_ip,
5562 void *pv_api_op)
5563 {
5564 /* api command */
5565 WORD32 command = IV_CMD_NA;
5566
5567 /* error status */
5568 IV_STATUS_T e_status;
5569 WORD32 ret;
5570
5571 /* tmp var */
5572 WORD32 *pu4_ptr_cmd = (WORD32 *) pv_api_ip;
5573
5574 /* validate input / output structures */
5575 e_status = api_check_struct_sanity(ps_handle, pv_api_ip, pv_api_op);
5576
5577 if (e_status != IV_SUCCESS)
5578 {
5579 DEBUG("error code = %d\n", *((UWORD32 *)pv_api_op + 1));
5580 return IV_FAIL;
5581 }
5582
5583 pu4_ptr_cmd++;
5584
5585 command = *pu4_ptr_cmd;
5586
5587 switch (command)
5588 {
5589 case IV_CMD_GET_NUM_MEM_REC:
5590 ret = ih264e_get_num_rec(pv_api_ip, pv_api_op);
5591 break;
5592
5593 case IV_CMD_FILL_NUM_MEM_REC:
5594 ret = ih264e_fill_num_mem_rec(pv_api_ip, pv_api_op);
5595 break;
5596
5597 case IV_CMD_INIT:
5598 ret = ih264e_init_mem_rec(ps_handle, pv_api_ip, pv_api_op);
5599 break;
5600
5601 case IV_CMD_RETRIEVE_MEMREC:
5602 ret = ih264e_retrieve_memrec(ps_handle, pv_api_ip, pv_api_op);
5603 break;
5604
5605 case IVE_CMD_VIDEO_CTL:
5606 ret = ih264e_ctl(ps_handle, pv_api_ip, pv_api_op);
5607 break;
5608
5609 case IVE_CMD_VIDEO_ENCODE:
5610 ret = ih264e_encode(ps_handle, pv_api_ip, pv_api_op);
5611 break;
5612
5613 default:
5614 ret = IV_FAIL;
5615 break;
5616 }
5617
5618 return (IV_STATUS_T) ret;
5619 }
5620