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