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