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