1/******************************************************************************
2*
3* Copyright (C) 2012 Ittiam Systems Pvt Ltd, Bangalore
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/**
19*******************************************************************************
20* @file
21*  ihevcd_api.c
22*
23* @brief
24*  Contains api functions definitions for HEVC decoder
25*
26* @author
27*  Harish
28*
29* @par List of Functions:
30* - api_check_struct_sanity()
31* - ihevcd_get_version()
32* - ihevcd_set_default_params()
33* - ihevcd_init()
34* - ihevcd_get_num_rec()
35* - ihevcd_fill_num_mem_rec()
36* - ihevcd_init_mem_rec()
37* - ihevcd_retrieve_memrec()
38* - ihevcd_set_display_frame()
39* - ihevcd_set_flush_mode()
40* - ihevcd_get_status()
41* - ihevcd_get_buf_info()
42* - ihevcd_set_params()
43* - ihevcd_reset()
44* - ihevcd_rel_display_frame()
45* - ihevcd_disable_deblk()
46* - ihevcd_get_frame_dimensions()
47* - ihevcd_set_num_cores()
48* - ihevcd_ctl()
49* - ihevcd_cxa_api_function()
50*
51* @remarks
52*  None
53*
54*******************************************************************************
55*/
56/*****************************************************************************/
57/* File Includes                                                             */
58/*****************************************************************************/
59#include <stdio.h>
60#include <stddef.h>
61#include <stdlib.h>
62#include <string.h>
63
64#include "ihevc_typedefs.h"
65#include "iv.h"
66#include "ivd.h"
67#include "ihevcd_cxa.h"
68#include "ithread.h"
69
70#include "ihevc_defs.h"
71#include "ihevc_debug.h"
72
73#include "ihevc_structs.h"
74#include "ihevc_macros.h"
75#include "ihevc_platform_macros.h"
76
77#include "ihevc_buf_mgr.h"
78#include "ihevc_dpb_mgr.h"
79#include "ihevc_disp_mgr.h"
80#include "ihevc_common_tables.h"
81#include "ihevc_cabac_tables.h"
82#include "ihevc_error.h"
83
84#include "ihevcd_defs.h"
85#include "ihevcd_trace.h"
86
87#include "ihevcd_function_selector.h"
88#include "ihevcd_structs.h"
89#include "ihevcd_error.h"
90#include "ihevcd_utils.h"
91#include "ihevcd_decode.h"
92#include "ihevcd_job_queue.h"
93#include "ihevcd_statistics.h"
94
95/*****************************************************************************/
96/* Function Prototypes                                                       */
97/*****************************************************************************/
98IV_API_CALL_STATUS_T ihevcd_get_version(CHAR *pc_version_string,
99                                        UWORD32 u4_version_buffer_size);
100
101
102
103/**
104*******************************************************************************
105*
106* @brief
107*  Used to test arguments for corresponding API call
108*
109* @par Description:
110*  For each command the arguments are validated
111*
112* @param[in] ps_handle
113*  Codec handle at API level
114*
115* @param[in] pv_api_ip
116*  Pointer to input structure
117*
118* @param[out] pv_api_op
119*  Pointer to output structure
120*
121* @returns  Status of error checking
122*
123* @remarks
124*
125*
126*******************************************************************************
127*/
128
129static IV_API_CALL_STATUS_T api_check_struct_sanity(iv_obj_t *ps_handle,
130                                                    void *pv_api_ip,
131                                                    void *pv_api_op)
132{
133    IVD_API_COMMAND_TYPE_T e_cmd;
134    UWORD32 *pu4_api_ip;
135    UWORD32 *pu4_api_op;
136    WORD32 i, j;
137
138    if(NULL == pv_api_op)
139        return (IV_FAIL);
140
141    if(NULL == pv_api_ip)
142        return (IV_FAIL);
143
144    pu4_api_ip = (UWORD32 *)pv_api_ip;
145    pu4_api_op = (UWORD32 *)pv_api_op;
146    e_cmd = (IVD_API_COMMAND_TYPE_T)*(pu4_api_ip + 1);
147
148    *(pu4_api_op + 1) = 0;
149    /* error checks on handle */
150    switch((WORD32)e_cmd)
151    {
152        case IV_CMD_GET_NUM_MEM_REC:
153        case IV_CMD_FILL_NUM_MEM_REC:
154            break;
155        case IV_CMD_INIT:
156            if(ps_handle == NULL)
157            {
158                *(pu4_api_op + 1) |= 1 << IVD_UNSUPPORTEDPARAM;
159                *(pu4_api_op + 1) |= IVD_HANDLE_NULL;
160                return IV_FAIL;
161            }
162
163            if(ps_handle->u4_size != sizeof(iv_obj_t))
164            {
165                *(pu4_api_op + 1) |= 1 << IVD_UNSUPPORTEDPARAM;
166                *(pu4_api_op + 1) |= IVD_HANDLE_STRUCT_SIZE_INCORRECT;
167                DEBUG("Sizes do not match. Expected: %d, Got: %d",
168                                sizeof(iv_obj_t), ps_handle->u4_size);
169                return IV_FAIL;
170            }
171            break;
172        case IVD_CMD_REL_DISPLAY_FRAME:
173        case IVD_CMD_SET_DISPLAY_FRAME:
174        case IVD_CMD_GET_DISPLAY_FRAME:
175        case IVD_CMD_VIDEO_DECODE:
176        case IV_CMD_RETRIEVE_MEMREC:
177        case IVD_CMD_VIDEO_CTL:
178            if(ps_handle == NULL)
179            {
180                *(pu4_api_op + 1) |= 1 << IVD_UNSUPPORTEDPARAM;
181                *(pu4_api_op + 1) |= IVD_HANDLE_NULL;
182                return IV_FAIL;
183            }
184
185            if(ps_handle->u4_size != sizeof(iv_obj_t))
186            {
187                *(pu4_api_op + 1) |= 1 << IVD_UNSUPPORTEDPARAM;
188                *(pu4_api_op + 1) |= IVD_HANDLE_STRUCT_SIZE_INCORRECT;
189                return IV_FAIL;
190            }
191
192
193            if(ps_handle->pv_codec_handle == NULL)
194            {
195                *(pu4_api_op + 1) |= 1 << IVD_UNSUPPORTEDPARAM;
196                *(pu4_api_op + 1) |= IVD_INVALID_HANDLE_NULL;
197                return IV_FAIL;
198            }
199            break;
200        default:
201            *(pu4_api_op + 1) |= 1 << IVD_UNSUPPORTEDPARAM;
202            *(pu4_api_op + 1) |= IVD_INVALID_API_CMD;
203            return IV_FAIL;
204    }
205
206    switch((WORD32)e_cmd)
207    {
208        case IV_CMD_GET_NUM_MEM_REC:
209        {
210            ihevcd_cxa_num_mem_rec_ip_t *ps_ip =
211                            (ihevcd_cxa_num_mem_rec_ip_t *)pv_api_ip;
212            ihevcd_cxa_num_mem_rec_op_t *ps_op =
213                            (ihevcd_cxa_num_mem_rec_op_t *)pv_api_op;
214            ps_op->s_ivd_num_mem_rec_op_t.u4_error_code = 0;
215
216            if(ps_ip->s_ivd_num_mem_rec_ip_t.u4_size
217                            != sizeof(ihevcd_cxa_num_mem_rec_ip_t))
218            {
219                ps_op->s_ivd_num_mem_rec_op_t.u4_error_code |= 1
220                                << IVD_UNSUPPORTEDPARAM;
221                ps_op->s_ivd_num_mem_rec_op_t.u4_error_code |=
222                                IVD_IP_API_STRUCT_SIZE_INCORRECT;
223                return (IV_FAIL);
224            }
225
226            if(ps_op->s_ivd_num_mem_rec_op_t.u4_size
227                            != sizeof(ihevcd_cxa_num_mem_rec_op_t))
228            {
229                ps_op->s_ivd_num_mem_rec_op_t.u4_error_code |= 1
230                                << IVD_UNSUPPORTEDPARAM;
231                ps_op->s_ivd_num_mem_rec_op_t.u4_error_code |=
232                                IVD_OP_API_STRUCT_SIZE_INCORRECT;
233                return (IV_FAIL);
234            }
235        }
236            break;
237        case IV_CMD_FILL_NUM_MEM_REC:
238        {
239            ihevcd_cxa_fill_mem_rec_ip_t *ps_ip =
240                            (ihevcd_cxa_fill_mem_rec_ip_t *)pv_api_ip;
241            ihevcd_cxa_fill_mem_rec_op_t *ps_op =
242                            (ihevcd_cxa_fill_mem_rec_op_t *)pv_api_op;
243            iv_mem_rec_t *ps_mem_rec;
244            WORD32 max_wd = ps_ip->s_ivd_fill_mem_rec_ip_t.u4_max_frm_wd;
245            WORD32 max_ht = ps_ip->s_ivd_fill_mem_rec_ip_t.u4_max_frm_ht;
246
247            max_wd = ALIGN64(max_wd);
248            max_ht = ALIGN64(max_ht);
249
250            ps_op->s_ivd_fill_mem_rec_op_t.u4_error_code = 0;
251
252            if((ps_ip->s_ivd_fill_mem_rec_ip_t.u4_size
253                            > sizeof(ihevcd_cxa_fill_mem_rec_ip_t))
254                            || (ps_ip->s_ivd_fill_mem_rec_ip_t.u4_size
255                                            < sizeof(iv_fill_mem_rec_ip_t)))
256            {
257                ps_op->s_ivd_fill_mem_rec_op_t.u4_error_code |= 1
258                                << IVD_UNSUPPORTEDPARAM;
259                ps_op->s_ivd_fill_mem_rec_op_t.u4_error_code |=
260                                IVD_IP_API_STRUCT_SIZE_INCORRECT;
261                return (IV_FAIL);
262            }
263
264            if((ps_op->s_ivd_fill_mem_rec_op_t.u4_size
265                            != sizeof(ihevcd_cxa_fill_mem_rec_op_t))
266                            && (ps_op->s_ivd_fill_mem_rec_op_t.u4_size
267                                            != sizeof(iv_fill_mem_rec_op_t)))
268            {
269                ps_op->s_ivd_fill_mem_rec_op_t.u4_error_code |= 1
270                                << IVD_UNSUPPORTEDPARAM;
271                ps_op->s_ivd_fill_mem_rec_op_t.u4_error_code |=
272                                IVD_OP_API_STRUCT_SIZE_INCORRECT;
273                return (IV_FAIL);
274            }
275
276            if(max_wd < MIN_WD)
277            {
278                ps_op->s_ivd_fill_mem_rec_op_t.u4_error_code |= 1
279                                << IVD_UNSUPPORTEDPARAM;
280                ps_op->s_ivd_fill_mem_rec_op_t.u4_error_code |=
281                                IVD_REQUESTED_WIDTH_NOT_SUPPPORTED;
282                return (IV_FAIL);
283            }
284
285            if(max_wd > MAX_WD)
286            {
287                ps_op->s_ivd_fill_mem_rec_op_t.u4_error_code |= 1
288                                << IVD_UNSUPPORTEDPARAM;
289                ps_op->s_ivd_fill_mem_rec_op_t.u4_error_code |=
290                                IVD_REQUESTED_WIDTH_NOT_SUPPPORTED;
291                return (IV_FAIL);
292            }
293
294            if(max_ht < MIN_HT)
295            {
296                ps_op->s_ivd_fill_mem_rec_op_t.u4_error_code |= 1
297                                << IVD_UNSUPPORTEDPARAM;
298                ps_op->s_ivd_fill_mem_rec_op_t.u4_error_code |=
299                                IVD_REQUESTED_HEIGHT_NOT_SUPPPORTED;
300                return (IV_FAIL);
301            }
302
303            if((max_ht * max_wd) > (MAX_HT * MAX_WD))
304
305            {
306                ps_op->s_ivd_fill_mem_rec_op_t.u4_error_code |= 1
307                                << IVD_UNSUPPORTEDPARAM;
308                ps_op->s_ivd_fill_mem_rec_op_t.u4_error_code |=
309                                IVD_REQUESTED_HEIGHT_NOT_SUPPPORTED;
310                return (IV_FAIL);
311            }
312
313            if(NULL == ps_ip->s_ivd_fill_mem_rec_ip_t.pv_mem_rec_location)
314            {
315                ps_op->s_ivd_fill_mem_rec_op_t.u4_error_code |= 1
316                                << IVD_UNSUPPORTEDPARAM;
317                ps_op->s_ivd_fill_mem_rec_op_t.u4_error_code |=
318                                IVD_NUM_REC_NOT_SUFFICIENT;
319                return (IV_FAIL);
320            }
321
322            /* check memrecords sizes are correct */
323            ps_mem_rec = ps_ip->s_ivd_fill_mem_rec_ip_t.pv_mem_rec_location;
324            for(i = 0; i < MEM_REC_CNT; i++)
325            {
326                if(ps_mem_rec[i].u4_size != sizeof(iv_mem_rec_t))
327                {
328                    ps_op->s_ivd_fill_mem_rec_op_t.u4_error_code |= 1
329                                    << IVD_UNSUPPORTEDPARAM;
330                    ps_op->s_ivd_fill_mem_rec_op_t.u4_error_code |=
331                                    IVD_MEM_REC_STRUCT_SIZE_INCORRECT;
332                    return IV_FAIL;
333                }
334            }
335        }
336            break;
337
338        case IV_CMD_INIT:
339        {
340            ihevcd_cxa_init_ip_t *ps_ip = (ihevcd_cxa_init_ip_t *)pv_api_ip;
341            ihevcd_cxa_init_op_t *ps_op = (ihevcd_cxa_init_op_t *)pv_api_op;
342            iv_mem_rec_t *ps_mem_rec;
343            WORD32 max_wd = ps_ip->s_ivd_init_ip_t.u4_frm_max_wd;
344            WORD32 max_ht = ps_ip->s_ivd_init_ip_t.u4_frm_max_ht;
345
346            max_wd = ALIGN64(max_wd);
347            max_ht = ALIGN64(max_ht);
348
349            ps_op->s_ivd_init_op_t.u4_error_code = 0;
350
351            if((ps_ip->s_ivd_init_ip_t.u4_size > sizeof(ihevcd_cxa_init_ip_t))
352                            || (ps_ip->s_ivd_init_ip_t.u4_size
353                                            < sizeof(ivd_init_ip_t)))
354            {
355                ps_op->s_ivd_init_op_t.u4_error_code |= 1
356                                << IVD_UNSUPPORTEDPARAM;
357                ps_op->s_ivd_init_op_t.u4_error_code |=
358                                IVD_IP_API_STRUCT_SIZE_INCORRECT;
359                DEBUG("\n");
360                return (IV_FAIL);
361            }
362
363            if((ps_op->s_ivd_init_op_t.u4_size != sizeof(ihevcd_cxa_init_op_t))
364                            && (ps_op->s_ivd_init_op_t.u4_size
365                                            != sizeof(ivd_init_op_t)))
366            {
367                ps_op->s_ivd_init_op_t.u4_error_code |= 1
368                                << IVD_UNSUPPORTEDPARAM;
369                ps_op->s_ivd_init_op_t.u4_error_code |=
370                                IVD_OP_API_STRUCT_SIZE_INCORRECT;
371                DEBUG("\n");
372                return (IV_FAIL);
373            }
374
375            if(ps_ip->s_ivd_init_ip_t.u4_num_mem_rec != MEM_REC_CNT)
376            {
377                ps_op->s_ivd_init_op_t.u4_error_code |= 1
378                                << IVD_UNSUPPORTEDPARAM;
379                ps_op->s_ivd_init_op_t.u4_error_code |=
380                                IVD_INIT_DEC_NOT_SUFFICIENT;
381                DEBUG("\n");
382                return (IV_FAIL);
383            }
384
385            if(max_wd < MIN_WD)
386            {
387                ps_op->s_ivd_init_op_t.u4_error_code |= 1
388                                << IVD_UNSUPPORTEDPARAM;
389                ps_op->s_ivd_init_op_t.u4_error_code |=
390                                IVD_INIT_DEC_WIDTH_NOT_SUPPPORTED;
391                DEBUG("\n");
392                return (IV_FAIL);
393            }
394
395            if(max_wd > MAX_WD)
396            {
397                ps_op->s_ivd_init_op_t.u4_error_code |= 1
398                                << IVD_UNSUPPORTEDPARAM;
399                ps_op->s_ivd_init_op_t.u4_error_code |=
400                                IVD_INIT_DEC_WIDTH_NOT_SUPPPORTED;
401                DEBUG("\n");
402                return (IV_FAIL);
403            }
404
405            if(max_ht < MIN_HT)
406            {
407                ps_op->s_ivd_init_op_t.u4_error_code |= 1
408                                << IVD_UNSUPPORTEDPARAM;
409                ps_op->s_ivd_init_op_t.u4_error_code |=
410                                IVD_INIT_DEC_HEIGHT_NOT_SUPPPORTED;
411                DEBUG("\n");
412                return (IV_FAIL);
413            }
414
415            if((max_ht * max_wd) > (MAX_HT * MAX_WD))
416
417            {
418                ps_op->s_ivd_init_op_t.u4_error_code |= 1
419                                << IVD_UNSUPPORTEDPARAM;
420                ps_op->s_ivd_init_op_t.u4_error_code |=
421                                IVD_INIT_DEC_HEIGHT_NOT_SUPPPORTED;
422                DEBUG("\n");
423                return (IV_FAIL);
424            }
425
426            if(NULL == ps_ip->s_ivd_init_ip_t.pv_mem_rec_location)
427            {
428                ps_op->s_ivd_init_op_t.u4_error_code |= 1
429                                << IVD_UNSUPPORTEDPARAM;
430                ps_op->s_ivd_init_op_t.u4_error_code |=
431                                IVD_NUM_REC_NOT_SUFFICIENT;
432                DEBUG("\n");
433                return (IV_FAIL);
434            }
435
436            if((ps_ip->s_ivd_init_ip_t.e_output_format != IV_YUV_420P)
437                            && (ps_ip->s_ivd_init_ip_t.e_output_format
438                                            != IV_YUV_422ILE)
439                            && (ps_ip->s_ivd_init_ip_t.e_output_format
440                                            != IV_RGB_565)
441                            && (ps_ip->s_ivd_init_ip_t.e_output_format
442                                            != IV_RGBA_8888)
443                            && (ps_ip->s_ivd_init_ip_t.e_output_format
444                                            != IV_YUV_420SP_UV)
445                            && (ps_ip->s_ivd_init_ip_t.e_output_format
446                                            != IV_YUV_420SP_VU))
447            {
448                ps_op->s_ivd_init_op_t.u4_error_code |= 1
449                                << IVD_UNSUPPORTEDPARAM;
450                ps_op->s_ivd_init_op_t.u4_error_code |=
451                                IVD_INIT_DEC_COL_FMT_NOT_SUPPORTED;
452                DEBUG("\n");
453                return (IV_FAIL);
454            }
455
456            /* verify number of mem records */
457            if(ps_ip->s_ivd_init_ip_t.u4_num_mem_rec < MEM_REC_CNT)
458            {
459                ps_op->s_ivd_init_op_t.u4_error_code |= 1
460                                << IVD_UNSUPPORTEDPARAM;
461                ps_op->s_ivd_init_op_t.u4_error_code |=
462                                IVD_INIT_DEC_MEM_REC_NOT_SUFFICIENT;
463                DEBUG("\n");
464                return IV_FAIL;
465            }
466
467            ps_mem_rec = ps_ip->s_ivd_init_ip_t.pv_mem_rec_location;
468            /* check memrecords sizes are correct */
469            for(i = 0; i < (WORD32)ps_ip->s_ivd_init_ip_t.u4_num_mem_rec; i++)
470            {
471                if(ps_mem_rec[i].u4_size != sizeof(iv_mem_rec_t))
472                {
473                    ps_op->s_ivd_init_op_t.u4_error_code |= 1
474                                    << IVD_UNSUPPORTEDPARAM;
475                    ps_op->s_ivd_init_op_t.u4_error_code |=
476                                    IVD_MEM_REC_STRUCT_SIZE_INCORRECT;
477                    DEBUG("i: %d\n", i);
478                    return IV_FAIL;
479                }
480                /* check memrecords pointers are not NULL */
481
482                if(ps_mem_rec[i].pv_base == NULL)
483                {
484
485                    ps_op->s_ivd_init_op_t.u4_error_code |= 1
486                                    << IVD_UNSUPPORTEDPARAM;
487                    ps_op->s_ivd_init_op_t.u4_error_code |=
488                                    IVD_INIT_DEC_MEM_REC_BASE_NULL;
489                    DEBUG("i: %d\n", i);
490                    return IV_FAIL;
491
492                }
493
494            }
495
496            /* verify memtabs for overlapping regions */
497            {
498                void *start[MEM_REC_CNT];
499                void *end[MEM_REC_CNT];
500
501                start[0] = (ps_mem_rec[0].pv_base);
502                end[0] = (UWORD8 *)(ps_mem_rec[0].pv_base)
503                                + ps_mem_rec[0].u4_mem_size - 1;
504                for(i = 1; i < MEM_REC_CNT; i++)
505                {
506                    /* This array is populated to check memtab overlapp */
507                    start[i] = (ps_mem_rec[i].pv_base);
508                    end[i] = (UWORD8 *)(ps_mem_rec[i].pv_base)
509                                    + ps_mem_rec[i].u4_mem_size - 1;
510
511                    for(j = 0; j < i; j++)
512                    {
513                        if((start[i] >= start[j]) && (start[i] <= end[j]))
514                        {
515                            ps_op->s_ivd_init_op_t.u4_error_code |= 1
516                                            << IVD_UNSUPPORTEDPARAM;
517                            ps_op->s_ivd_init_op_t.u4_error_code |=
518                                            IVD_INIT_DEC_MEM_REC_OVERLAP_ERR;
519                            DEBUG("i: %d, j: %d\n", i, j);
520                            return IV_FAIL;
521                        }
522
523                        if((end[i] >= start[j]) && (end[i] <= end[j]))
524                        {
525                            ps_op->s_ivd_init_op_t.u4_error_code |= 1
526                                            << IVD_UNSUPPORTEDPARAM;
527                            ps_op->s_ivd_init_op_t.u4_error_code |=
528                                            IVD_INIT_DEC_MEM_REC_OVERLAP_ERR;
529                            DEBUG("i: %d, j: %d\n", i, j);
530                            return IV_FAIL;
531                        }
532
533                        if((start[i] < start[j]) && (end[i] > end[j]))
534                        {
535                            ps_op->s_ivd_init_op_t.u4_error_code |= 1
536                                            << IVD_UNSUPPORTEDPARAM;
537                            ps_op->s_ivd_init_op_t.u4_error_code |=
538                                            IVD_INIT_DEC_MEM_REC_OVERLAP_ERR;
539                            DEBUG("i: %d, j: %d\n", i, j);
540                            return IV_FAIL;
541                        }
542                    }
543
544                }
545            }
546
547            {
548                iv_mem_rec_t mem_rec_ittiam_api[MEM_REC_CNT];
549                ihevcd_cxa_fill_mem_rec_ip_t s_fill_mem_rec_ip;
550                ihevcd_cxa_fill_mem_rec_op_t s_fill_mem_rec_op;
551                IV_API_CALL_STATUS_T e_status;
552
553                WORD32 i;
554                s_fill_mem_rec_ip.s_ivd_fill_mem_rec_ip_t.e_cmd =
555                                IV_CMD_FILL_NUM_MEM_REC;
556                s_fill_mem_rec_ip.s_ivd_fill_mem_rec_ip_t.pv_mem_rec_location =
557                                mem_rec_ittiam_api;
558                s_fill_mem_rec_ip.s_ivd_fill_mem_rec_ip_t.u4_max_frm_wd =
559                                max_wd;
560                s_fill_mem_rec_ip.s_ivd_fill_mem_rec_ip_t.u4_max_frm_ht =
561                                max_ht;
562
563                if(ps_ip->s_ivd_init_ip_t.u4_size
564                                > offsetof(ihevcd_cxa_init_ip_t, i4_level))
565                {
566                    s_fill_mem_rec_ip.i4_level = ps_ip->i4_level;
567                }
568                else
569                {
570                    s_fill_mem_rec_ip.i4_level = IHEVC_LEVEL_31;
571                }
572
573                if(ps_ip->s_ivd_init_ip_t.u4_size
574                                > offsetof(ihevcd_cxa_init_ip_t,
575                                           u4_num_ref_frames))
576                {
577                    s_fill_mem_rec_ip.u4_num_ref_frames =
578                                    ps_ip->u4_num_ref_frames;
579                }
580                else
581                {
582                    s_fill_mem_rec_ip.u4_num_ref_frames = (MAX_REF_CNT + 1);
583                }
584
585                if(ps_ip->s_ivd_init_ip_t.u4_size
586                                > offsetof(ihevcd_cxa_init_ip_t,
587                                           u4_num_reorder_frames))
588                {
589                    s_fill_mem_rec_ip.u4_num_reorder_frames =
590                                    ps_ip->u4_num_reorder_frames;
591                }
592                else
593                {
594                    s_fill_mem_rec_ip.u4_num_reorder_frames = (MAX_REF_CNT + 1);
595                }
596
597                if(ps_ip->s_ivd_init_ip_t.u4_size
598                                > offsetof(ihevcd_cxa_init_ip_t,
599                                           u4_num_extra_disp_buf))
600                {
601                    s_fill_mem_rec_ip.u4_num_extra_disp_buf =
602                                    ps_ip->u4_num_extra_disp_buf;
603                }
604                else
605                {
606                    s_fill_mem_rec_ip.u4_num_extra_disp_buf = 0;
607                }
608
609                if(ps_ip->s_ivd_init_ip_t.u4_size
610                                > offsetof(ihevcd_cxa_init_ip_t,
611                                           u4_share_disp_buf))
612                {
613#ifndef LOGO_EN
614                    s_fill_mem_rec_ip.u4_share_disp_buf =
615                                    ps_ip->u4_share_disp_buf;
616#else
617                    s_fill_mem_rec_ip.u4_share_disp_buf = 0;
618#endif
619                }
620                else
621                {
622                    s_fill_mem_rec_ip.u4_share_disp_buf = 0;
623                }
624
625                s_fill_mem_rec_ip.e_output_format =
626                                ps_ip->s_ivd_init_ip_t.e_output_format;
627
628                if((s_fill_mem_rec_ip.e_output_format != IV_YUV_420P)
629                                && (s_fill_mem_rec_ip.e_output_format
630                                                != IV_YUV_420SP_UV)
631                                && (s_fill_mem_rec_ip.e_output_format
632                                                != IV_YUV_420SP_VU))
633                {
634                    s_fill_mem_rec_ip.u4_share_disp_buf = 0;
635                }
636
637                s_fill_mem_rec_ip.s_ivd_fill_mem_rec_ip_t.u4_size =
638                                sizeof(ihevcd_cxa_fill_mem_rec_ip_t);
639                s_fill_mem_rec_op.s_ivd_fill_mem_rec_op_t.u4_size =
640                                sizeof(ihevcd_cxa_fill_mem_rec_op_t);
641
642                for(i = 0; i < MEM_REC_CNT; i++)
643                    mem_rec_ittiam_api[i].u4_size = sizeof(iv_mem_rec_t);
644
645                e_status = ihevcd_cxa_api_function(NULL,
646                                                   (void *)&s_fill_mem_rec_ip,
647                                                   (void *)&s_fill_mem_rec_op);
648                if(IV_FAIL == e_status)
649                {
650                    ps_op->s_ivd_init_op_t.u4_error_code =
651                                    s_fill_mem_rec_op.s_ivd_fill_mem_rec_op_t.u4_error_code;
652                    DEBUG("Fail\n");
653                    return (IV_FAIL);
654                }
655
656                for(i = 0; i < MEM_REC_CNT; i++)
657                {
658#ifdef ARMRVDS
659                    if((UWORD32)(ps_mem_rec[i].pv_base) & (mem_rec_ittiam_api[i].u4_mem_alignment - 1))
660                    {
661                        ps_op->s_ivd_init_op_t.u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM;
662                        ps_op->s_ivd_init_op_t.u4_error_code |= IVD_INIT_DEC_MEM_REC_ALIGNMENT_ERR;
663                        DEBUG("Fail\n");
664                        return IV_FAIL;
665                    }
666#endif
667
668                    if(ps_mem_rec[i].u4_mem_size
669                                    < mem_rec_ittiam_api[i].u4_mem_size)
670                    {
671                        ps_op->s_ivd_init_op_t.u4_error_code |= 1
672                                        << IVD_UNSUPPORTEDPARAM;
673                        ps_op->s_ivd_init_op_t.u4_error_code |=
674                                        IVD_INIT_DEC_MEM_REC_INSUFFICIENT_SIZE;
675                        DEBUG("i: %d \n", i);
676                        return IV_FAIL;
677                    }
678                    if(ps_mem_rec[i].u4_mem_alignment
679                                    != mem_rec_ittiam_api[i].u4_mem_alignment)
680                    {
681                        ps_op->s_ivd_init_op_t.u4_error_code |= 1
682                                        << IVD_UNSUPPORTEDPARAM;
683                        ps_op->s_ivd_init_op_t.u4_error_code |=
684                                        IVD_INIT_DEC_MEM_REC_ALIGNMENT_ERR;
685                        DEBUG("i: %d \n", i);
686                        return IV_FAIL;
687                    }
688                    if(ps_mem_rec[i].e_mem_type
689                                    != mem_rec_ittiam_api[i].e_mem_type)
690                    {
691                        UWORD32 check = IV_SUCCESS;
692                        UWORD32 diff = mem_rec_ittiam_api[i].e_mem_type
693                                        - ps_mem_rec[i].e_mem_type;
694
695                        if((ps_mem_rec[i].e_mem_type
696                                        <= IV_EXTERNAL_CACHEABLE_SCRATCH_MEM)
697                                        && (mem_rec_ittiam_api[i].e_mem_type
698                                                        >= IV_INTERNAL_NONCACHEABLE_PERSISTENT_MEM))
699                        {
700                            check = IV_FAIL;
701                        }
702                        if(3 != (mem_rec_ittiam_api[i].e_mem_type % 4))
703                        {
704                            /*
705                             * It is not IV_EXTERNAL_NONCACHEABLE_PERSISTENT_MEM or IV_EXTERNAL_CACHEABLE_PERSISTENT_MEM
706                             */
707                            if((diff < 1) || (diff > 3))
708                            {
709                                // Difference between 1 and 3 is okay for all cases other than the two filtered
710                                // with the MOD condition above
711                                check = IV_FAIL;
712                            }
713                        }
714                        else
715                        {
716                            if(diff == 1)
717                            {
718                                /*
719                                 * This particular case is when codec asked for External Persistent, but got
720                                 * Internal Scratch.
721                                 */
722                                check = IV_FAIL;
723                            }
724                            if((diff != 2) && (diff != 3))
725                            {
726                                check = IV_FAIL;
727                            }
728                        }
729                        if(check == IV_FAIL)
730                        {
731                            ps_op->s_ivd_init_op_t.u4_error_code |= 1
732                                            << IVD_UNSUPPORTEDPARAM;
733                            ps_op->s_ivd_init_op_t.u4_error_code |=
734                                            IVD_INIT_DEC_MEM_REC_INCORRECT_TYPE;
735                            DEBUG("i: %d \n", i);
736                            return IV_FAIL;
737                        }
738                    }
739                }
740            }
741
742        }
743            break;
744
745        case IVD_CMD_GET_DISPLAY_FRAME:
746        {
747            ihevcd_cxa_get_display_frame_ip_t *ps_ip =
748                            (ihevcd_cxa_get_display_frame_ip_t *)pv_api_ip;
749            ihevcd_cxa_get_display_frame_op_t *ps_op =
750                            (ihevcd_cxa_get_display_frame_op_t *)pv_api_op;
751
752            ps_op->s_ivd_get_display_frame_op_t.u4_error_code = 0;
753
754            if((ps_ip->s_ivd_get_display_frame_ip_t.u4_size
755                            != sizeof(ihevcd_cxa_get_display_frame_ip_t))
756                            && (ps_ip->s_ivd_get_display_frame_ip_t.u4_size
757                                            != sizeof(ivd_get_display_frame_ip_t)))
758            {
759                ps_op->s_ivd_get_display_frame_op_t.u4_error_code |= 1
760                                << IVD_UNSUPPORTEDPARAM;
761                ps_op->s_ivd_get_display_frame_op_t.u4_error_code |=
762                                IVD_IP_API_STRUCT_SIZE_INCORRECT;
763                return (IV_FAIL);
764            }
765
766            if((ps_op->s_ivd_get_display_frame_op_t.u4_size
767                            != sizeof(ihevcd_cxa_get_display_frame_op_t))
768                            && (ps_op->s_ivd_get_display_frame_op_t.u4_size
769                                            != sizeof(ivd_get_display_frame_op_t)))
770            {
771                ps_op->s_ivd_get_display_frame_op_t.u4_error_code |= 1
772                                << IVD_UNSUPPORTEDPARAM;
773                ps_op->s_ivd_get_display_frame_op_t.u4_error_code |=
774                                IVD_OP_API_STRUCT_SIZE_INCORRECT;
775                return (IV_FAIL);
776            }
777
778        }
779            break;
780
781        case IVD_CMD_REL_DISPLAY_FRAME:
782        {
783            ihevcd_cxa_rel_display_frame_ip_t *ps_ip =
784                            (ihevcd_cxa_rel_display_frame_ip_t *)pv_api_ip;
785            ihevcd_cxa_rel_display_frame_op_t *ps_op =
786                            (ihevcd_cxa_rel_display_frame_op_t *)pv_api_op;
787
788            ps_op->s_ivd_rel_display_frame_op_t.u4_error_code = 0;
789
790            if((ps_ip->s_ivd_rel_display_frame_ip_t.u4_size
791                            != sizeof(ihevcd_cxa_rel_display_frame_ip_t))
792                            && (ps_ip->s_ivd_rel_display_frame_ip_t.u4_size
793                                            != sizeof(ivd_rel_display_frame_ip_t)))
794            {
795                ps_op->s_ivd_rel_display_frame_op_t.u4_error_code |= 1
796                                << IVD_UNSUPPORTEDPARAM;
797                ps_op->s_ivd_rel_display_frame_op_t.u4_error_code |=
798                                IVD_IP_API_STRUCT_SIZE_INCORRECT;
799                return (IV_FAIL);
800            }
801
802            if((ps_op->s_ivd_rel_display_frame_op_t.u4_size
803                            != sizeof(ihevcd_cxa_rel_display_frame_op_t))
804                            && (ps_op->s_ivd_rel_display_frame_op_t.u4_size
805                                            != sizeof(ivd_rel_display_frame_op_t)))
806            {
807                ps_op->s_ivd_rel_display_frame_op_t.u4_error_code |= 1
808                                << IVD_UNSUPPORTEDPARAM;
809                ps_op->s_ivd_rel_display_frame_op_t.u4_error_code |=
810                                IVD_OP_API_STRUCT_SIZE_INCORRECT;
811                return (IV_FAIL);
812            }
813
814        }
815            break;
816
817        case IVD_CMD_SET_DISPLAY_FRAME:
818        {
819            ihevcd_cxa_set_display_frame_ip_t *ps_ip =
820                            (ihevcd_cxa_set_display_frame_ip_t *)pv_api_ip;
821            ihevcd_cxa_set_display_frame_op_t *ps_op =
822                            (ihevcd_cxa_set_display_frame_op_t *)pv_api_op;
823            UWORD32 j;
824
825            ps_op->s_ivd_set_display_frame_op_t.u4_error_code = 0;
826
827            if((ps_ip->s_ivd_set_display_frame_ip_t.u4_size
828                            != sizeof(ihevcd_cxa_set_display_frame_ip_t))
829                            && (ps_ip->s_ivd_set_display_frame_ip_t.u4_size
830                                            != sizeof(ivd_set_display_frame_ip_t)))
831            {
832                ps_op->s_ivd_set_display_frame_op_t.u4_error_code |= 1
833                                << IVD_UNSUPPORTEDPARAM;
834                ps_op->s_ivd_set_display_frame_op_t.u4_error_code |=
835                                IVD_IP_API_STRUCT_SIZE_INCORRECT;
836                return (IV_FAIL);
837            }
838
839            if((ps_op->s_ivd_set_display_frame_op_t.u4_size
840                            != sizeof(ihevcd_cxa_set_display_frame_op_t))
841                            && (ps_op->s_ivd_set_display_frame_op_t.u4_size
842                                            != sizeof(ivd_set_display_frame_op_t)))
843            {
844                ps_op->s_ivd_set_display_frame_op_t.u4_error_code |= 1
845                                << IVD_UNSUPPORTEDPARAM;
846                ps_op->s_ivd_set_display_frame_op_t.u4_error_code |=
847                                IVD_OP_API_STRUCT_SIZE_INCORRECT;
848                return (IV_FAIL);
849            }
850
851            if(ps_ip->s_ivd_set_display_frame_ip_t.num_disp_bufs == 0)
852            {
853                ps_op->s_ivd_set_display_frame_op_t.u4_error_code |= 1
854                                << IVD_UNSUPPORTEDPARAM;
855                ps_op->s_ivd_set_display_frame_op_t.u4_error_code |=
856                                IVD_DISP_FRM_ZERO_OP_BUFS;
857                return IV_FAIL;
858            }
859
860            for(j = 0; j < ps_ip->s_ivd_set_display_frame_ip_t.num_disp_bufs;
861                            j++)
862            {
863                if(ps_ip->s_ivd_set_display_frame_ip_t.s_disp_buffer[j].u4_num_bufs
864                                == 0)
865                {
866                    ps_op->s_ivd_set_display_frame_op_t.u4_error_code |= 1
867                                    << IVD_UNSUPPORTEDPARAM;
868                    ps_op->s_ivd_set_display_frame_op_t.u4_error_code |=
869                                    IVD_DISP_FRM_ZERO_OP_BUFS;
870                    return IV_FAIL;
871                }
872
873                for(i = 0;
874                                i
875                                                < (WORD32)ps_ip->s_ivd_set_display_frame_ip_t.s_disp_buffer[j].u4_num_bufs;
876                                i++)
877                {
878                    if(ps_ip->s_ivd_set_display_frame_ip_t.s_disp_buffer[j].pu1_bufs[i]
879                                    == NULL)
880                    {
881                        ps_op->s_ivd_set_display_frame_op_t.u4_error_code |= 1
882                                        << IVD_UNSUPPORTEDPARAM;
883                        ps_op->s_ivd_set_display_frame_op_t.u4_error_code |=
884                                        IVD_DISP_FRM_OP_BUF_NULL;
885                        return IV_FAIL;
886                    }
887
888                    if(ps_ip->s_ivd_set_display_frame_ip_t.s_disp_buffer[j].u4_min_out_buf_size[i]
889                                    == 0)
890                    {
891                        ps_op->s_ivd_set_display_frame_op_t.u4_error_code |= 1
892                                        << IVD_UNSUPPORTEDPARAM;
893                        ps_op->s_ivd_set_display_frame_op_t.u4_error_code |=
894                                        IVD_DISP_FRM_ZERO_OP_BUF_SIZE;
895                        return IV_FAIL;
896                    }
897                }
898            }
899        }
900            break;
901
902        case IVD_CMD_VIDEO_DECODE:
903        {
904            ihevcd_cxa_video_decode_ip_t *ps_ip =
905                            (ihevcd_cxa_video_decode_ip_t *)pv_api_ip;
906            ihevcd_cxa_video_decode_op_t *ps_op =
907                            (ihevcd_cxa_video_decode_op_t *)pv_api_op;
908
909            DEBUG("The input bytes is: %d",
910                            ps_ip->s_ivd_video_decode_ip_t.u4_num_Bytes);
911            ps_op->s_ivd_video_decode_op_t.u4_error_code = 0;
912
913            if(ps_ip->s_ivd_video_decode_ip_t.u4_size
914                            != sizeof(ihevcd_cxa_video_decode_ip_t)
915                            && ps_ip->s_ivd_video_decode_ip_t.u4_size
916                                            != offsetof(ivd_video_decode_ip_t,
917                                                        s_out_buffer))
918            {
919                ps_op->s_ivd_video_decode_op_t.u4_error_code |= 1
920                                << IVD_UNSUPPORTEDPARAM;
921                ps_op->s_ivd_video_decode_op_t.u4_error_code |=
922                                IVD_IP_API_STRUCT_SIZE_INCORRECT;
923                return (IV_FAIL);
924            }
925
926            if(ps_op->s_ivd_video_decode_op_t.u4_size
927                            != sizeof(ihevcd_cxa_video_decode_op_t)
928                            && ps_op->s_ivd_video_decode_op_t.u4_size
929                                            != offsetof(ivd_video_decode_op_t,
930                                                        u4_output_present))
931            {
932                ps_op->s_ivd_video_decode_op_t.u4_error_code |= 1
933                                << IVD_UNSUPPORTEDPARAM;
934                ps_op->s_ivd_video_decode_op_t.u4_error_code |=
935                                IVD_OP_API_STRUCT_SIZE_INCORRECT;
936                return (IV_FAIL);
937            }
938
939        }
940            break;
941
942        case IV_CMD_RETRIEVE_MEMREC:
943        {
944            ihevcd_cxa_retrieve_mem_rec_ip_t *ps_ip =
945                            (ihevcd_cxa_retrieve_mem_rec_ip_t *)pv_api_ip;
946            ihevcd_cxa_retrieve_mem_rec_op_t *ps_op =
947                            (ihevcd_cxa_retrieve_mem_rec_op_t *)pv_api_op;
948            iv_mem_rec_t *ps_mem_rec;
949
950            ps_op->s_ivd_retrieve_mem_rec_op_t.u4_error_code = 0;
951
952            if(ps_ip->s_ivd_retrieve_mem_rec_ip_t.u4_size
953                            != sizeof(ihevcd_cxa_retrieve_mem_rec_ip_t))
954            {
955                ps_op->s_ivd_retrieve_mem_rec_op_t.u4_error_code |= 1
956                                << IVD_UNSUPPORTEDPARAM;
957                ps_op->s_ivd_retrieve_mem_rec_op_t.u4_error_code |=
958                                IVD_IP_API_STRUCT_SIZE_INCORRECT;
959                return (IV_FAIL);
960            }
961
962            if(ps_op->s_ivd_retrieve_mem_rec_op_t.u4_size
963                            != sizeof(ihevcd_cxa_retrieve_mem_rec_op_t))
964            {
965                ps_op->s_ivd_retrieve_mem_rec_op_t.u4_error_code |= 1
966                                << IVD_UNSUPPORTEDPARAM;
967                ps_op->s_ivd_retrieve_mem_rec_op_t.u4_error_code |=
968                                IVD_OP_API_STRUCT_SIZE_INCORRECT;
969                return (IV_FAIL);
970            }
971
972            ps_mem_rec = ps_ip->s_ivd_retrieve_mem_rec_ip_t.pv_mem_rec_location;
973            /* check memrecords sizes are correct */
974            for(i = 0; i < MEM_REC_CNT; i++)
975            {
976                if(ps_mem_rec[i].u4_size != sizeof(iv_mem_rec_t))
977                {
978                    ps_op->s_ivd_retrieve_mem_rec_op_t.u4_error_code |= 1
979                                    << IVD_UNSUPPORTEDPARAM;
980                    ps_op->s_ivd_retrieve_mem_rec_op_t.u4_error_code |=
981                                    IVD_MEM_REC_STRUCT_SIZE_INCORRECT;
982                    return IV_FAIL;
983                }
984            }
985        }
986            break;
987
988        case IVD_CMD_VIDEO_CTL:
989        {
990            UWORD32 *pu4_ptr_cmd;
991            UWORD32 sub_command;
992
993            pu4_ptr_cmd = (UWORD32 *)pv_api_ip;
994            pu4_ptr_cmd += 2;
995            sub_command = *pu4_ptr_cmd;
996
997            switch(sub_command)
998            {
999                case IVD_CMD_CTL_SETPARAMS:
1000                {
1001                    ihevcd_cxa_ctl_set_config_ip_t *ps_ip;
1002                    ihevcd_cxa_ctl_set_config_op_t *ps_op;
1003                    ps_ip = (ihevcd_cxa_ctl_set_config_ip_t *)pv_api_ip;
1004                    ps_op = (ihevcd_cxa_ctl_set_config_op_t *)pv_api_op;
1005
1006                    if(ps_ip->s_ivd_ctl_set_config_ip_t.u4_size
1007                                    != sizeof(ihevcd_cxa_ctl_set_config_ip_t))
1008                    {
1009                        ps_op->s_ivd_ctl_set_config_op_t.u4_error_code |= 1
1010                                        << IVD_UNSUPPORTEDPARAM;
1011                        ps_op->s_ivd_ctl_set_config_op_t.u4_error_code |=
1012                                        IVD_IP_API_STRUCT_SIZE_INCORRECT;
1013                        return IV_FAIL;
1014                    }
1015                }
1016                    //no break; is needed here
1017                case IVD_CMD_CTL_SETDEFAULT:
1018                {
1019                    ihevcd_cxa_ctl_set_config_op_t *ps_op;
1020                    ps_op = (ihevcd_cxa_ctl_set_config_op_t *)pv_api_op;
1021                    if(ps_op->s_ivd_ctl_set_config_op_t.u4_size
1022                                    != sizeof(ihevcd_cxa_ctl_set_config_op_t))
1023                    {
1024                        ps_op->s_ivd_ctl_set_config_op_t.u4_error_code |= 1
1025                                        << IVD_UNSUPPORTEDPARAM;
1026                        ps_op->s_ivd_ctl_set_config_op_t.u4_error_code |=
1027                                        IVD_OP_API_STRUCT_SIZE_INCORRECT;
1028                        return IV_FAIL;
1029                    }
1030                }
1031                    break;
1032
1033                case IVD_CMD_CTL_GETPARAMS:
1034                {
1035                    ihevcd_cxa_ctl_getstatus_ip_t *ps_ip;
1036                    ihevcd_cxa_ctl_getstatus_op_t *ps_op;
1037
1038                    ps_ip = (ihevcd_cxa_ctl_getstatus_ip_t *)pv_api_ip;
1039                    ps_op = (ihevcd_cxa_ctl_getstatus_op_t *)pv_api_op;
1040                    if(ps_ip->s_ivd_ctl_getstatus_ip_t.u4_size
1041                                    != sizeof(ihevcd_cxa_ctl_getstatus_ip_t))
1042                    {
1043                        ps_op->s_ivd_ctl_getstatus_op_t.u4_error_code |= 1
1044                                        << IVD_UNSUPPORTEDPARAM;
1045                        ps_op->s_ivd_ctl_getstatus_op_t.u4_error_code |=
1046                                        IVD_IP_API_STRUCT_SIZE_INCORRECT;
1047                        return IV_FAIL;
1048                    }
1049                    if((ps_op->s_ivd_ctl_getstatus_op_t.u4_size
1050                                    != sizeof(ihevcd_cxa_ctl_getstatus_op_t)) &&
1051                       (ps_op->s_ivd_ctl_getstatus_op_t.u4_size
1052                                    != sizeof(ivd_ctl_getstatus_op_t)))
1053                    {
1054                        ps_op->s_ivd_ctl_getstatus_op_t.u4_error_code |= 1
1055                                        << IVD_UNSUPPORTEDPARAM;
1056                        ps_op->s_ivd_ctl_getstatus_op_t.u4_error_code |=
1057                                        IVD_OP_API_STRUCT_SIZE_INCORRECT;
1058                        return IV_FAIL;
1059                    }
1060                }
1061                    break;
1062
1063                case IVD_CMD_CTL_GETBUFINFO:
1064                {
1065                    ihevcd_cxa_ctl_getbufinfo_ip_t *ps_ip;
1066                    ihevcd_cxa_ctl_getbufinfo_op_t *ps_op;
1067                    ps_ip = (ihevcd_cxa_ctl_getbufinfo_ip_t *)pv_api_ip;
1068                    ps_op = (ihevcd_cxa_ctl_getbufinfo_op_t *)pv_api_op;
1069
1070                    if(ps_ip->s_ivd_ctl_getbufinfo_ip_t.u4_size
1071                                    != sizeof(ihevcd_cxa_ctl_getbufinfo_ip_t))
1072                    {
1073                        ps_op->s_ivd_ctl_getbufinfo_op_t.u4_error_code |= 1
1074                                        << IVD_UNSUPPORTEDPARAM;
1075                        ps_op->s_ivd_ctl_getbufinfo_op_t.u4_error_code |=
1076                                        IVD_IP_API_STRUCT_SIZE_INCORRECT;
1077                        return IV_FAIL;
1078                    }
1079                    if(ps_op->s_ivd_ctl_getbufinfo_op_t.u4_size
1080                                    != sizeof(ihevcd_cxa_ctl_getbufinfo_op_t))
1081                    {
1082                        ps_op->s_ivd_ctl_getbufinfo_op_t.u4_error_code |= 1
1083                                        << IVD_UNSUPPORTEDPARAM;
1084                        ps_op->s_ivd_ctl_getbufinfo_op_t.u4_error_code |=
1085                                        IVD_OP_API_STRUCT_SIZE_INCORRECT;
1086                        return IV_FAIL;
1087                    }
1088                }
1089                    break;
1090
1091                case IVD_CMD_CTL_GETVERSION:
1092                {
1093                    ihevcd_cxa_ctl_getversioninfo_ip_t *ps_ip;
1094                    ihevcd_cxa_ctl_getversioninfo_op_t *ps_op;
1095                    ps_ip = (ihevcd_cxa_ctl_getversioninfo_ip_t *)pv_api_ip;
1096                    ps_op = (ihevcd_cxa_ctl_getversioninfo_op_t *)pv_api_op;
1097                    if(ps_ip->s_ivd_ctl_getversioninfo_ip_t.u4_size
1098                                    != sizeof(ihevcd_cxa_ctl_getversioninfo_ip_t))
1099                    {
1100                        ps_op->s_ivd_ctl_getversioninfo_op_t.u4_error_code |= 1
1101                                        << IVD_UNSUPPORTEDPARAM;
1102                        ps_op->s_ivd_ctl_getversioninfo_op_t.u4_error_code |=
1103                                        IVD_IP_API_STRUCT_SIZE_INCORRECT;
1104                        return IV_FAIL;
1105                    }
1106                    if(ps_op->s_ivd_ctl_getversioninfo_op_t.u4_size
1107                                    != sizeof(ihevcd_cxa_ctl_getversioninfo_op_t))
1108                    {
1109                        ps_op->s_ivd_ctl_getversioninfo_op_t.u4_error_code |= 1
1110                                        << IVD_UNSUPPORTEDPARAM;
1111                        ps_op->s_ivd_ctl_getversioninfo_op_t.u4_error_code |=
1112                                        IVD_OP_API_STRUCT_SIZE_INCORRECT;
1113                        return IV_FAIL;
1114                    }
1115                }
1116                    break;
1117
1118                case IVD_CMD_CTL_FLUSH:
1119                {
1120                    ihevcd_cxa_ctl_flush_ip_t *ps_ip;
1121                    ihevcd_cxa_ctl_flush_op_t *ps_op;
1122                    ps_ip = (ihevcd_cxa_ctl_flush_ip_t *)pv_api_ip;
1123                    ps_op = (ihevcd_cxa_ctl_flush_op_t *)pv_api_op;
1124                    if(ps_ip->s_ivd_ctl_flush_ip_t.u4_size
1125                                    != sizeof(ihevcd_cxa_ctl_flush_ip_t))
1126                    {
1127                        ps_op->s_ivd_ctl_flush_op_t.u4_error_code |= 1
1128                                        << IVD_UNSUPPORTEDPARAM;
1129                        ps_op->s_ivd_ctl_flush_op_t.u4_error_code |=
1130                                        IVD_IP_API_STRUCT_SIZE_INCORRECT;
1131                        return IV_FAIL;
1132                    }
1133                    if(ps_op->s_ivd_ctl_flush_op_t.u4_size
1134                                    != sizeof(ihevcd_cxa_ctl_flush_op_t))
1135                    {
1136                        ps_op->s_ivd_ctl_flush_op_t.u4_error_code |= 1
1137                                        << IVD_UNSUPPORTEDPARAM;
1138                        ps_op->s_ivd_ctl_flush_op_t.u4_error_code |=
1139                                        IVD_OP_API_STRUCT_SIZE_INCORRECT;
1140                        return IV_FAIL;
1141                    }
1142                }
1143                    break;
1144
1145                case IVD_CMD_CTL_RESET:
1146                {
1147                    ihevcd_cxa_ctl_reset_ip_t *ps_ip;
1148                    ihevcd_cxa_ctl_reset_op_t *ps_op;
1149                    ps_ip = (ihevcd_cxa_ctl_reset_ip_t *)pv_api_ip;
1150                    ps_op = (ihevcd_cxa_ctl_reset_op_t *)pv_api_op;
1151                    if(ps_ip->s_ivd_ctl_reset_ip_t.u4_size
1152                                    != sizeof(ihevcd_cxa_ctl_reset_ip_t))
1153                    {
1154                        ps_op->s_ivd_ctl_reset_op_t.u4_error_code |= 1
1155                                        << IVD_UNSUPPORTEDPARAM;
1156                        ps_op->s_ivd_ctl_reset_op_t.u4_error_code |=
1157                                        IVD_IP_API_STRUCT_SIZE_INCORRECT;
1158                        return IV_FAIL;
1159                    }
1160                    if(ps_op->s_ivd_ctl_reset_op_t.u4_size
1161                                    != sizeof(ihevcd_cxa_ctl_reset_op_t))
1162                    {
1163                        ps_op->s_ivd_ctl_reset_op_t.u4_error_code |= 1
1164                                        << IVD_UNSUPPORTEDPARAM;
1165                        ps_op->s_ivd_ctl_reset_op_t.u4_error_code |=
1166                                        IVD_OP_API_STRUCT_SIZE_INCORRECT;
1167                        return IV_FAIL;
1168                    }
1169                }
1170                    break;
1171                case IHEVCD_CXA_CMD_CTL_DEGRADE:
1172                {
1173                    ihevcd_cxa_ctl_degrade_ip_t *ps_ip;
1174                    ihevcd_cxa_ctl_degrade_op_t *ps_op;
1175
1176                    ps_ip = (ihevcd_cxa_ctl_degrade_ip_t *)pv_api_ip;
1177                    ps_op = (ihevcd_cxa_ctl_degrade_op_t *)pv_api_op;
1178
1179                    if(ps_ip->u4_size
1180                                    != sizeof(ihevcd_cxa_ctl_degrade_ip_t))
1181                    {
1182                        ps_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM;
1183                        ps_op->u4_error_code |=
1184                                        IVD_IP_API_STRUCT_SIZE_INCORRECT;
1185                        return IV_FAIL;
1186                    }
1187
1188                    if(ps_op->u4_size
1189                                    != sizeof(ihevcd_cxa_ctl_degrade_op_t))
1190                    {
1191                        ps_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM;
1192                        ps_op->u4_error_code |=
1193                                        IVD_OP_API_STRUCT_SIZE_INCORRECT;
1194                        return IV_FAIL;
1195                    }
1196
1197                    if((ps_ip->i4_degrade_pics < 0) ||
1198                       (ps_ip->i4_degrade_pics > 4) ||
1199                       (ps_ip->i4_nondegrade_interval < 0) ||
1200                       (ps_ip->i4_degrade_type < 0) ||
1201                       (ps_ip->i4_degrade_type > 15))
1202                    {
1203                        ps_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM;
1204                        return IV_FAIL;
1205                    }
1206
1207                    break;
1208                }
1209
1210                case IHEVCD_CXA_CMD_CTL_GET_BUFFER_DIMENSIONS:
1211                {
1212                    ihevcd_cxa_ctl_get_frame_dimensions_ip_t *ps_ip;
1213                    ihevcd_cxa_ctl_get_frame_dimensions_op_t *ps_op;
1214
1215                    ps_ip =
1216                                    (ihevcd_cxa_ctl_get_frame_dimensions_ip_t *)pv_api_ip;
1217                    ps_op =
1218                                    (ihevcd_cxa_ctl_get_frame_dimensions_op_t *)pv_api_op;
1219
1220                    if(ps_ip->u4_size
1221                                    != sizeof(ihevcd_cxa_ctl_get_frame_dimensions_ip_t))
1222                    {
1223                        ps_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM;
1224                        ps_op->u4_error_code |=
1225                                        IVD_IP_API_STRUCT_SIZE_INCORRECT;
1226                        return IV_FAIL;
1227                    }
1228
1229                    if(ps_op->u4_size
1230                                    != sizeof(ihevcd_cxa_ctl_get_frame_dimensions_op_t))
1231                    {
1232                        ps_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM;
1233                        ps_op->u4_error_code |=
1234                                        IVD_OP_API_STRUCT_SIZE_INCORRECT;
1235                        return IV_FAIL;
1236                    }
1237
1238                    break;
1239                }
1240
1241                case IHEVCD_CXA_CMD_CTL_GET_VUI_PARAMS:
1242                {
1243                    ihevcd_cxa_ctl_get_vui_params_ip_t *ps_ip;
1244                    ihevcd_cxa_ctl_get_vui_params_op_t *ps_op;
1245
1246                    ps_ip =
1247                                    (ihevcd_cxa_ctl_get_vui_params_ip_t *)pv_api_ip;
1248                    ps_op =
1249                                    (ihevcd_cxa_ctl_get_vui_params_op_t *)pv_api_op;
1250
1251                    if(ps_ip->u4_size
1252                                    != sizeof(ihevcd_cxa_ctl_get_vui_params_ip_t))
1253                    {
1254                        ps_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM;
1255                        ps_op->u4_error_code |=
1256                                        IVD_IP_API_STRUCT_SIZE_INCORRECT;
1257                        return IV_FAIL;
1258                    }
1259
1260                    if(ps_op->u4_size
1261                                    != sizeof(ihevcd_cxa_ctl_get_vui_params_op_t))
1262                    {
1263                        ps_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM;
1264                        ps_op->u4_error_code |=
1265                                        IVD_OP_API_STRUCT_SIZE_INCORRECT;
1266                        return IV_FAIL;
1267                    }
1268
1269                    break;
1270                }
1271                case IHEVCD_CXA_CMD_CTL_SET_NUM_CORES:
1272                {
1273                    ihevcd_cxa_ctl_set_num_cores_ip_t *ps_ip;
1274                    ihevcd_cxa_ctl_set_num_cores_op_t *ps_op;
1275
1276                    ps_ip = (ihevcd_cxa_ctl_set_num_cores_ip_t *)pv_api_ip;
1277                    ps_op = (ihevcd_cxa_ctl_set_num_cores_op_t *)pv_api_op;
1278
1279                    if(ps_ip->u4_size
1280                                    != sizeof(ihevcd_cxa_ctl_set_num_cores_ip_t))
1281                    {
1282                        ps_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM;
1283                        ps_op->u4_error_code |=
1284                                        IVD_IP_API_STRUCT_SIZE_INCORRECT;
1285                        return IV_FAIL;
1286                    }
1287
1288                    if(ps_op->u4_size
1289                                    != sizeof(ihevcd_cxa_ctl_set_num_cores_op_t))
1290                    {
1291                        ps_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM;
1292                        ps_op->u4_error_code |=
1293                                        IVD_OP_API_STRUCT_SIZE_INCORRECT;
1294                        return IV_FAIL;
1295                    }
1296
1297#ifdef MULTICORE
1298                    if((ps_ip->u4_num_cores < 1) || (ps_ip->u4_num_cores > MAX_NUM_CORES))
1299#else
1300                    if(ps_ip->u4_num_cores != 1)
1301#endif
1302                        {
1303                            ps_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM;
1304                            return IV_FAIL;
1305                        }
1306                    break;
1307                }
1308                case IHEVCD_CXA_CMD_CTL_SET_PROCESSOR:
1309                {
1310                    ihevcd_cxa_ctl_set_processor_ip_t *ps_ip;
1311                    ihevcd_cxa_ctl_set_processor_op_t *ps_op;
1312
1313                    ps_ip = (ihevcd_cxa_ctl_set_processor_ip_t *)pv_api_ip;
1314                    ps_op = (ihevcd_cxa_ctl_set_processor_op_t *)pv_api_op;
1315
1316                    if(ps_ip->u4_size
1317                                    != sizeof(ihevcd_cxa_ctl_set_processor_ip_t))
1318                    {
1319                        ps_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM;
1320                        ps_op->u4_error_code |=
1321                                        IVD_IP_API_STRUCT_SIZE_INCORRECT;
1322                        return IV_FAIL;
1323                    }
1324
1325                    if(ps_op->u4_size
1326                                    != sizeof(ihevcd_cxa_ctl_set_processor_op_t))
1327                    {
1328                        ps_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM;
1329                        ps_op->u4_error_code |=
1330                                        IVD_OP_API_STRUCT_SIZE_INCORRECT;
1331                        return IV_FAIL;
1332                    }
1333
1334                    break;
1335                }
1336                default:
1337                    *(pu4_api_op + 1) |= 1 << IVD_UNSUPPORTEDPARAM;
1338                    *(pu4_api_op + 1) |= IVD_UNSUPPORTED_API_CMD;
1339                    return IV_FAIL;
1340            }
1341        }
1342            break;
1343        default:
1344            *(pu4_api_op + 1) |= 1 << IVD_UNSUPPORTEDPARAM;
1345            *(pu4_api_op + 1) |= IVD_UNSUPPORTED_API_CMD;
1346            return IV_FAIL;
1347    }
1348
1349    return IV_SUCCESS;
1350}
1351
1352
1353/**
1354*******************************************************************************
1355*
1356* @brief
1357*  Sets default dynamic parameters
1358*
1359* @par Description:
1360*  Sets default dynamic parameters. Will be called in ihevcd_init() to ensure
1361* that even if set_params is not called, codec  continues to work
1362*
1363* @param[in] ps_codec_obj
1364*  Pointer to codec object at API level
1365*
1366* @param[in] pv_api_ip
1367*  Pointer to input argument structure
1368*
1369* @param[out] pv_api_op
1370*  Pointer to output argument structure
1371*
1372* @returns  Status
1373*
1374* @remarks
1375*
1376*
1377*******************************************************************************
1378*/
1379WORD32 ihevcd_set_default_params(codec_t *ps_codec)
1380{
1381
1382    WORD32 ret = IV_SUCCESS;
1383
1384    ps_codec->e_pic_skip_mode = IVD_SKIP_NONE;
1385    ps_codec->i4_strd = 0;
1386    ps_codec->i4_disp_strd = 0;
1387    ps_codec->i4_header_mode = 0;
1388    ps_codec->e_pic_out_order = IVD_DISPLAY_FRAME_OUT;
1389    return ret;
1390}
1391
1392void ihevcd_update_function_ptr(codec_t *ps_codec)
1393{
1394
1395    /* Init inter pred function array */
1396    ps_codec->apf_inter_pred[0] = NULL;
1397    ps_codec->apf_inter_pred[1] = (pf_inter_pred)ps_codec->s_func_selector.ihevc_inter_pred_luma_copy_fptr;
1398    ps_codec->apf_inter_pred[2] = (pf_inter_pred)ps_codec->s_func_selector.ihevc_inter_pred_luma_vert_fptr;
1399    ps_codec->apf_inter_pred[3] = (pf_inter_pred)ps_codec->s_func_selector.ihevc_inter_pred_luma_horz_fptr;
1400    ps_codec->apf_inter_pred[4] = (pf_inter_pred)ps_codec->s_func_selector.ihevc_inter_pred_luma_horz_w16out_fptr;
1401    ps_codec->apf_inter_pred[5] = (pf_inter_pred)ps_codec->s_func_selector.ihevc_inter_pred_luma_copy_w16out_fptr;
1402    ps_codec->apf_inter_pred[6] = (pf_inter_pred)ps_codec->s_func_selector.ihevc_inter_pred_luma_vert_w16out_fptr;
1403    ps_codec->apf_inter_pred[7] = (pf_inter_pred)ps_codec->s_func_selector.ihevc_inter_pred_luma_horz_w16out_fptr;
1404    ps_codec->apf_inter_pred[8] = (pf_inter_pred)ps_codec->s_func_selector.ihevc_inter_pred_luma_horz_w16out_fptr;
1405    ps_codec->apf_inter_pred[9] = (pf_inter_pred)ps_codec->s_func_selector.ihevc_inter_pred_luma_vert_w16inp_fptr;
1406    ps_codec->apf_inter_pred[10] = (pf_inter_pred)ps_codec->s_func_selector.ihevc_inter_pred_luma_vert_w16inp_w16out_fptr;
1407    ps_codec->apf_inter_pred[11] = NULL;
1408    ps_codec->apf_inter_pred[12] = (pf_inter_pred)ps_codec->s_func_selector.ihevc_inter_pred_chroma_copy_fptr;
1409    ps_codec->apf_inter_pred[13] = (pf_inter_pred)ps_codec->s_func_selector.ihevc_inter_pred_chroma_vert_fptr;
1410    ps_codec->apf_inter_pred[14] = (pf_inter_pred)ps_codec->s_func_selector.ihevc_inter_pred_chroma_horz_fptr;
1411    ps_codec->apf_inter_pred[15] = (pf_inter_pred)ps_codec->s_func_selector.ihevc_inter_pred_chroma_horz_w16out_fptr;
1412    ps_codec->apf_inter_pred[16] = (pf_inter_pred)ps_codec->s_func_selector.ihevc_inter_pred_chroma_copy_w16out_fptr;
1413    ps_codec->apf_inter_pred[17] = (pf_inter_pred)ps_codec->s_func_selector.ihevc_inter_pred_chroma_vert_w16out_fptr;
1414    ps_codec->apf_inter_pred[18] = (pf_inter_pred)ps_codec->s_func_selector.ihevc_inter_pred_chroma_horz_w16out_fptr;
1415    ps_codec->apf_inter_pred[19] = (pf_inter_pred)ps_codec->s_func_selector.ihevc_inter_pred_chroma_horz_w16out_fptr;
1416    ps_codec->apf_inter_pred[20] = (pf_inter_pred)ps_codec->s_func_selector.ihevc_inter_pred_chroma_vert_w16inp_fptr;
1417    ps_codec->apf_inter_pred[21] = (pf_inter_pred)ps_codec->s_func_selector.ihevc_inter_pred_chroma_vert_w16inp_w16out_fptr;
1418
1419    /* Init intra pred function array */
1420    ps_codec->apf_intra_pred_luma[0] = (pf_intra_pred)NULL;
1421    ps_codec->apf_intra_pred_luma[1] = (pf_intra_pred)ps_codec->s_func_selector.ihevc_intra_pred_luma_planar_fptr;
1422    ps_codec->apf_intra_pred_luma[2] = (pf_intra_pred)ps_codec->s_func_selector.ihevc_intra_pred_luma_dc_fptr;
1423    ps_codec->apf_intra_pred_luma[3] = (pf_intra_pred)ps_codec->s_func_selector.ihevc_intra_pred_luma_mode2_fptr;
1424    ps_codec->apf_intra_pred_luma[4] = (pf_intra_pred)ps_codec->s_func_selector.ihevc_intra_pred_luma_mode_3_to_9_fptr;
1425    ps_codec->apf_intra_pred_luma[5] = (pf_intra_pred)ps_codec->s_func_selector.ihevc_intra_pred_luma_horz_fptr;
1426    ps_codec->apf_intra_pred_luma[6] = (pf_intra_pred)ps_codec->s_func_selector.ihevc_intra_pred_luma_mode_11_to_17_fptr;
1427    ps_codec->apf_intra_pred_luma[7] = (pf_intra_pred)ps_codec->s_func_selector.ihevc_intra_pred_luma_mode_18_34_fptr;
1428    ps_codec->apf_intra_pred_luma[8] = (pf_intra_pred)ps_codec->s_func_selector.ihevc_intra_pred_luma_mode_19_to_25_fptr;
1429    ps_codec->apf_intra_pred_luma[9] = (pf_intra_pred)ps_codec->s_func_selector.ihevc_intra_pred_luma_ver_fptr;
1430    ps_codec->apf_intra_pred_luma[10] =  (pf_intra_pred)ps_codec->s_func_selector.ihevc_intra_pred_luma_mode_27_to_33_fptr;
1431
1432    ps_codec->apf_intra_pred_chroma[0] = (pf_intra_pred)NULL;
1433    ps_codec->apf_intra_pred_chroma[1] = (pf_intra_pred)ps_codec->s_func_selector.ihevc_intra_pred_chroma_planar_fptr;
1434    ps_codec->apf_intra_pred_chroma[2] = (pf_intra_pred)ps_codec->s_func_selector.ihevc_intra_pred_chroma_dc_fptr;
1435    ps_codec->apf_intra_pred_chroma[3] = (pf_intra_pred)ps_codec->s_func_selector.ihevc_intra_pred_chroma_mode2_fptr;
1436    ps_codec->apf_intra_pred_chroma[4] = (pf_intra_pred)ps_codec->s_func_selector.ihevc_intra_pred_chroma_mode_3_to_9_fptr;
1437    ps_codec->apf_intra_pred_chroma[5] = (pf_intra_pred)ps_codec->s_func_selector.ihevc_intra_pred_chroma_horz_fptr;
1438    ps_codec->apf_intra_pred_chroma[6] = (pf_intra_pred)ps_codec->s_func_selector.ihevc_intra_pred_chroma_mode_11_to_17_fptr;
1439    ps_codec->apf_intra_pred_chroma[7] = (pf_intra_pred)ps_codec->s_func_selector.ihevc_intra_pred_chroma_mode_18_34_fptr;
1440    ps_codec->apf_intra_pred_chroma[8] = (pf_intra_pred)ps_codec->s_func_selector.ihevc_intra_pred_chroma_mode_19_to_25_fptr;
1441    ps_codec->apf_intra_pred_chroma[9] =  (pf_intra_pred)ps_codec->s_func_selector.ihevc_intra_pred_chroma_ver_fptr;
1442    ps_codec->apf_intra_pred_chroma[10] = (pf_intra_pred)ps_codec->s_func_selector.ihevc_intra_pred_chroma_mode_27_to_33_fptr;
1443
1444    /* Init itrans_recon function array */
1445    ps_codec->apf_itrans_recon[0] = (pf_itrans_recon)ps_codec->s_func_selector.ihevc_itrans_recon_4x4_ttype1_fptr;
1446    ps_codec->apf_itrans_recon[1] = (pf_itrans_recon)ps_codec->s_func_selector.ihevc_itrans_recon_4x4_fptr;
1447    ps_codec->apf_itrans_recon[2] = (pf_itrans_recon)ps_codec->s_func_selector.ihevc_itrans_recon_8x8_fptr;
1448    ps_codec->apf_itrans_recon[3] = (pf_itrans_recon)ps_codec->s_func_selector.ihevc_itrans_recon_16x16_fptr;
1449    ps_codec->apf_itrans_recon[4] = (pf_itrans_recon)ps_codec->s_func_selector.ihevc_itrans_recon_32x32_fptr;
1450    ps_codec->apf_itrans_recon[5] = (pf_itrans_recon)ps_codec->s_func_selector.ihevc_chroma_itrans_recon_4x4_fptr;
1451    ps_codec->apf_itrans_recon[6] = (pf_itrans_recon)ps_codec->s_func_selector.ihevc_chroma_itrans_recon_8x8_fptr;
1452    ps_codec->apf_itrans_recon[7] = (pf_itrans_recon)ps_codec->s_func_selector.ihevc_chroma_itrans_recon_16x16_fptr;
1453
1454    /* Init recon function array */
1455    ps_codec->apf_recon[0] = (pf_recon)ps_codec->s_func_selector.ihevc_recon_4x4_ttype1_fptr;
1456    ps_codec->apf_recon[1] = (pf_recon)ps_codec->s_func_selector.ihevc_recon_4x4_fptr;
1457    ps_codec->apf_recon[2] = (pf_recon)ps_codec->s_func_selector.ihevc_recon_8x8_fptr;
1458    ps_codec->apf_recon[3] = (pf_recon)ps_codec->s_func_selector.ihevc_recon_16x16_fptr;
1459    ps_codec->apf_recon[4] = (pf_recon)ps_codec->s_func_selector.ihevc_recon_32x32_fptr;
1460    ps_codec->apf_recon[5] = (pf_recon)ps_codec->s_func_selector.ihevc_chroma_recon_4x4_fptr;
1461    ps_codec->apf_recon[6] = (pf_recon)ps_codec->s_func_selector.ihevc_chroma_recon_8x8_fptr;
1462    ps_codec->apf_recon[7] = (pf_recon)ps_codec->s_func_selector.ihevc_chroma_recon_16x16_fptr;
1463
1464    /* Init itrans_recon_dc function array */
1465    ps_codec->apf_itrans_recon_dc[0] = (pf_itrans_recon_dc)ps_codec->s_func_selector.ihevcd_itrans_recon_dc_luma_fptr;
1466    ps_codec->apf_itrans_recon_dc[1] = (pf_itrans_recon_dc)ps_codec->s_func_selector.ihevcd_itrans_recon_dc_chroma_fptr;
1467
1468    /* Init sao function array */
1469    ps_codec->apf_sao_luma[0] = (pf_sao_luma)ps_codec->s_func_selector.ihevc_sao_edge_offset_class0_fptr;
1470    ps_codec->apf_sao_luma[1] = (pf_sao_luma)ps_codec->s_func_selector.ihevc_sao_edge_offset_class1_fptr;
1471    ps_codec->apf_sao_luma[2] = (pf_sao_luma)ps_codec->s_func_selector.ihevc_sao_edge_offset_class2_fptr;
1472    ps_codec->apf_sao_luma[3] = (pf_sao_luma)ps_codec->s_func_selector.ihevc_sao_edge_offset_class3_fptr;
1473
1474    ps_codec->apf_sao_chroma[0] = (pf_sao_chroma)ps_codec->s_func_selector.ihevc_sao_edge_offset_class0_chroma_fptr;
1475    ps_codec->apf_sao_chroma[1] = (pf_sao_chroma)ps_codec->s_func_selector.ihevc_sao_edge_offset_class1_chroma_fptr;
1476    ps_codec->apf_sao_chroma[2] = (pf_sao_chroma)ps_codec->s_func_selector.ihevc_sao_edge_offset_class2_chroma_fptr;
1477    ps_codec->apf_sao_chroma[3] = (pf_sao_chroma)ps_codec->s_func_selector.ihevc_sao_edge_offset_class3_chroma_fptr;
1478}
1479/**
1480*******************************************************************************
1481*
1482* @brief
1483*  Initialize the context. This will be called by  init_mem_rec and during
1484* reset
1485*
1486* @par Description:
1487*  Initializes the context
1488*
1489* @param[in] ps_codec
1490*  Codec context pointer
1491*
1492* @returns  Status
1493*
1494* @remarks
1495*
1496*
1497*******************************************************************************
1498*/
1499WORD32 ihevcd_init(codec_t *ps_codec)
1500{
1501    WORD32 status = IV_SUCCESS;
1502    WORD32 i;
1503
1504
1505    ps_codec->i4_num_disp_bufs = 1;
1506    ps_codec->i4_flush_mode = 0;
1507
1508    ps_codec->i4_ht = ps_codec->i4_disp_ht = ps_codec->i4_max_ht;
1509    ps_codec->i4_wd = ps_codec->i4_disp_wd = ps_codec->i4_max_wd;
1510    ps_codec->i4_strd = 0;
1511    ps_codec->i4_disp_strd = 0;
1512    ps_codec->i4_num_cores = 1;
1513
1514    ps_codec->u4_pic_cnt = 0;
1515    ps_codec->u4_disp_cnt = 0;
1516
1517    ps_codec->i4_header_mode = 0;
1518    ps_codec->i4_header_in_slice_mode = 0;
1519    ps_codec->i4_sps_done = 0;
1520    ps_codec->i4_pps_done = 0;
1521    ps_codec->i4_init_done   = 1;
1522    ps_codec->i4_first_pic_done = 0;
1523    ps_codec->s_parse.i4_first_pic_init = 0;
1524    ps_codec->i4_error_code = 0;
1525    ps_codec->i4_reset_flag = 0;
1526
1527    ps_codec->i4_prev_poc_msb = 0;
1528    ps_codec->i4_prev_poc_lsb = -1;
1529    ps_codec->i4_max_prev_poc_lsb = -1;
1530    ps_codec->s_parse.i4_abs_pic_order_cnt = -1;
1531
1532    /* Set ref chroma format by default to 420SP UV interleaved */
1533    ps_codec->e_ref_chroma_fmt = IV_YUV_420SP_UV;
1534
1535    /* If the codec is in shared mode and required format is 420 SP VU interleaved then change
1536     * reference buffers chroma format
1537     */
1538    if(IV_YUV_420SP_VU == ps_codec->e_chroma_fmt)
1539    {
1540        ps_codec->e_ref_chroma_fmt = IV_YUV_420SP_VU;
1541    }
1542
1543
1544
1545    ps_codec->i4_disable_deblk_pic = 0;
1546
1547    ps_codec->i4_degrade_pic_cnt    = 0;
1548    ps_codec->i4_degrade_pics       = 0;
1549    ps_codec->i4_degrade_type       = 0;
1550    ps_codec->i4_disable_sao_pic    = 0;
1551    ps_codec->i4_fullpel_inter_pred = 0;
1552    ps_codec->u4_enable_fmt_conv_ahead = 0;
1553
1554    {
1555        sps_t *ps_sps = ps_codec->ps_sps_base;
1556        pps_t *ps_pps = ps_codec->ps_pps_base;
1557
1558        for(i = 0; i < MAX_SPS_CNT; i++)
1559        {
1560            ps_sps->i1_sps_valid = 0;
1561            ps_sps++;
1562        }
1563
1564        for(i = 0; i < MAX_PPS_CNT; i++)
1565        {
1566            ps_pps->i1_pps_valid = 0;
1567            ps_pps++;
1568        }
1569    }
1570
1571    ihevcd_set_default_params(ps_codec);
1572    ps_codec->pv_proc_jobq = ihevcd_jobq_init(ps_codec->pv_proc_jobq_buf, ps_codec->i4_proc_jobq_buf_size);
1573    RETURN_IF((ps_codec->pv_proc_jobq == NULL), IV_FAIL);
1574
1575    /* Update the jobq context to all the threads */
1576    ps_codec->s_parse.pv_proc_jobq = ps_codec->pv_proc_jobq;
1577    for(i = 0; i < MAX_PROCESS_THREADS; i++)
1578    {
1579        ps_codec->as_process[i].pv_proc_jobq = ps_codec->pv_proc_jobq;
1580        ps_codec->as_process[i].i4_id = i;
1581        ps_codec->as_process[i].ps_codec = ps_codec;
1582
1583        /* Set the following to zero assuming it is a single core solution
1584         * When threads are launched these will be set appropriately
1585         */
1586        ps_codec->as_process[i].i4_check_parse_status = 0;
1587        ps_codec->as_process[i].i4_check_proc_status = 0;
1588    }
1589    /* Initialize MV Bank buffer manager */
1590    ihevc_buf_mgr_init((buf_mgr_t *)ps_codec->pv_mv_buf_mgr);
1591
1592    /* Initialize Picture buffer manager */
1593    ihevc_buf_mgr_init((buf_mgr_t *)ps_codec->pv_pic_buf_mgr);
1594
1595    ps_codec->ps_pic_buf = (pic_buf_t *)ps_codec->pv_pic_buf_base;
1596
1597    memset(ps_codec->ps_pic_buf, 0, BUF_MGR_MAX_CNT  * sizeof(pic_buf_t));
1598
1599
1600
1601    /* Initialize display buffer manager */
1602    ihevc_disp_mgr_init((disp_mgr_t *)ps_codec->pv_disp_buf_mgr);
1603
1604    /* Initialize dpb manager */
1605    ihevc_dpb_mgr_init((dpb_mgr_t *)ps_codec->pv_dpb_mgr);
1606
1607    ps_codec->e_processor_soc = SOC_GENERIC;
1608    /* The following can be over-ridden using soc parameter as a hack */
1609    ps_codec->u4_nctb = 0x7FFFFFFF;
1610    ihevcd_init_arch(ps_codec);
1611
1612    ihevcd_init_function_ptr(ps_codec);
1613
1614    ihevcd_update_function_ptr(ps_codec);
1615
1616    return status;
1617}
1618
1619/**
1620*******************************************************************************
1621*
1622* @brief
1623*  Gets number of memory records required by the codec
1624*
1625* @par Description:
1626*  Gets codec mem record requirements and adds concealment  modules
1627* requirements
1628*
1629* @param[in] pv_api_ip
1630*  Pointer to input argument structure
1631*
1632* @param[out] pv_api_op
1633*  Pointer to output argument structure
1634*
1635* @returns  Status
1636*
1637* @remarks
1638*
1639*
1640*******************************************************************************
1641*/
1642WORD32 ihevcd_get_num_rec(void *pv_api_ip, void *pv_api_op)
1643{
1644
1645    iv_num_mem_rec_op_t *ps_mem_q_op;
1646
1647    UNUSED(pv_api_ip);
1648    ps_mem_q_op = (iv_num_mem_rec_op_t *)pv_api_op;
1649    ps_mem_q_op->u4_num_mem_rec = MEM_REC_CNT;
1650    DEBUG("Get num mem records without concealment %d\n",
1651                    ps_mem_q_op->u4_num_mem_rec);
1652#ifdef APPLY_CONCEALMENT
1653    {
1654        IV_API_CALL_STATUS_T status;
1655        icncl_num_mem_rec_ip_t cncl_mem_ip;
1656        icncl_num_mem_rec_op_t cncl_mem_op;
1657
1658        cncl_mem_ip.s_ivd_num_rec_ip_t.e_cmd = IV_CMD_GET_NUM_MEM_REC;
1659        cncl_mem_ip.s_ivd_num_rec_ip_t.u4_size = sizeof(icncl_num_mem_rec_ip_t);
1660
1661        status = icncl_api_function(NULL, (void *)&cncl_mem_ip, (void *)&cncl_mem_op);
1662
1663        if(status == IV_SUCCESS)
1664        {
1665            /* Add the concealment library's memory requirements */
1666            ps_mem_q_op->u4_num_mem_rec += cncl_mem_op.s_ivd_num_mem_rec_op_t.u4_num_mem_rec;
1667            DEBUG("Get num mem records %d\n", ps_mem_q_op->u4_num_mem_rec);
1668            return status; /* Nothing else to do, return */
1669        }
1670        else
1671        {
1672            /*
1673             * Something went wrong with the concealment library call.
1674             */
1675            DEBUG("ERROR: Get num mem records %d\n", ps_mem_q_op->u4_num_mem_rec);
1676            return status;
1677        }
1678
1679    }
1680#endif //APPLY_CONCEALMENT
1681
1682
1683    return IV_SUCCESS;
1684
1685}
1686
1687/**
1688*******************************************************************************
1689*
1690* @brief
1691*  Fills memory requirements of the codec
1692*
1693* @par Description:
1694*  Gets codec mem record requirements and adds concealment  modules
1695* requirements
1696*
1697* @param[in] pv_api_ip
1698*  Pointer to input argument structure
1699*
1700* @param[out] pv_api_op
1701*  Pointer to output argument structure
1702*
1703* @returns  Status
1704*
1705* @remarks
1706*
1707*
1708*******************************************************************************
1709*/
1710WORD32 ihevcd_fill_num_mem_rec(void *pv_api_ip, void *pv_api_op)
1711{
1712
1713    ihevcd_cxa_fill_mem_rec_ip_t *ps_mem_q_ip;
1714    ihevcd_cxa_fill_mem_rec_op_t *ps_mem_q_op;
1715    WORD32 level;
1716    WORD32 num_reorder_frames;
1717    WORD32 num_ref_frames;
1718    WORD32 num_extra_disp_bufs;
1719    WORD32 max_dpb_size;
1720
1721    iv_mem_rec_t *ps_mem_rec;
1722    iv_mem_rec_t *ps_mem_rec_base;
1723    WORD32 no_of_mem_rec_filled;
1724    WORD32 chroma_format, share_disp_buf;
1725    WORD32 max_ctb_cnt;
1726    WORD32 max_wd_luma, max_wd_chroma;
1727    WORD32 max_ht_luma, max_ht_chroma;
1728    WORD32 max_tile_cols, max_tile_rows;
1729    WORD32 max_ctb_rows, max_ctb_cols;
1730    WORD32 max_num_cu_cols;
1731    WORD32 i;
1732    WORD32 max_num_4x4_cols;
1733    IV_API_CALL_STATUS_T status = IV_SUCCESS;
1734    no_of_mem_rec_filled = 0;
1735
1736    //TODO: Remove as and when the following are used
1737    UNUSED(num_extra_disp_bufs);
1738    UNUSED(no_of_mem_rec_filled);
1739    UNUSED(max_wd_chroma);
1740    UNUSED(max_ht_chroma);
1741
1742    ps_mem_q_ip = (ihevcd_cxa_fill_mem_rec_ip_t *)pv_api_ip;
1743    ps_mem_q_op = (ihevcd_cxa_fill_mem_rec_op_t *)pv_api_op;
1744
1745    if(ps_mem_q_ip->s_ivd_fill_mem_rec_ip_t.u4_size
1746                    > offsetof(ihevcd_cxa_fill_mem_rec_ip_t, i4_level))
1747    {
1748        level = ps_mem_q_ip->i4_level;
1749        /* Spec requires level should be multiplied by 30
1750         * API has values where level is multiplied by 10. This keeps it consistent with H264
1751         * Because of the above differences, level is multiplied by 3 here.
1752         */
1753        level *= 3;
1754    }
1755    else
1756    {
1757        level = MAX_LEVEL;
1758    }
1759
1760    if(ps_mem_q_ip->s_ivd_fill_mem_rec_ip_t.u4_size
1761                    > offsetof(ihevcd_cxa_fill_mem_rec_ip_t,
1762                               u4_num_reorder_frames))
1763    {
1764        num_reorder_frames = ps_mem_q_ip->u4_num_reorder_frames;
1765    }
1766    else
1767    {
1768        num_reorder_frames = MAX_REF_CNT;
1769    }
1770
1771    if(ps_mem_q_ip->s_ivd_fill_mem_rec_ip_t.u4_size
1772                    > offsetof(ihevcd_cxa_fill_mem_rec_ip_t, u4_num_ref_frames))
1773    {
1774        num_ref_frames = ps_mem_q_ip->u4_num_ref_frames;
1775    }
1776    else
1777    {
1778        num_ref_frames = MAX_REF_CNT;
1779    }
1780
1781    if(ps_mem_q_ip->s_ivd_fill_mem_rec_ip_t.u4_size
1782                    > offsetof(ihevcd_cxa_fill_mem_rec_ip_t,
1783                               u4_num_extra_disp_buf))
1784    {
1785        num_extra_disp_bufs = ps_mem_q_ip->u4_num_extra_disp_buf;
1786    }
1787    else
1788    {
1789        num_extra_disp_bufs = 0;
1790    }
1791
1792    if(ps_mem_q_ip->s_ivd_fill_mem_rec_ip_t.u4_size
1793                    > offsetof(ihevcd_cxa_fill_mem_rec_ip_t, u4_share_disp_buf))
1794    {
1795#ifndef LOGO_EN
1796        share_disp_buf = ps_mem_q_ip->u4_share_disp_buf;
1797#else
1798        share_disp_buf = 0;
1799#endif
1800    }
1801    else
1802    {
1803        share_disp_buf = 0;
1804    }
1805
1806    if(ps_mem_q_ip->s_ivd_fill_mem_rec_ip_t.u4_size
1807                    > offsetof(ihevcd_cxa_fill_mem_rec_ip_t, e_output_format))
1808    {
1809        chroma_format = ps_mem_q_ip->e_output_format;
1810    }
1811    else
1812    {
1813        chroma_format = -1;
1814    }
1815
1816    /* Shared disp buffer mode is supported only for 420SP formats */
1817    if((chroma_format != IV_YUV_420P) &&
1818       (chroma_format != IV_YUV_420SP_UV) &&
1819       (chroma_format != IV_YUV_420SP_VU))
1820    {
1821        share_disp_buf = 0;
1822    }
1823
1824    {
1825
1826        max_ht_luma = ps_mem_q_ip->s_ivd_fill_mem_rec_ip_t.u4_max_frm_ht;
1827        max_wd_luma = ps_mem_q_ip->s_ivd_fill_mem_rec_ip_t.u4_max_frm_wd;
1828
1829        max_ht_luma = ALIGN64(max_ht_luma);
1830        max_wd_luma = ALIGN64(max_wd_luma);
1831
1832
1833
1834        max_tile_cols = (max_wd_luma + MIN_TILE_WD - 1) / MIN_TILE_WD;
1835        max_tile_rows = (max_ht_luma + MIN_TILE_HT - 1) / MIN_TILE_HT;
1836        max_ctb_rows  = max_ht_luma / MIN_CTB_SIZE;
1837        max_ctb_cols  = max_wd_luma / MIN_CTB_SIZE;
1838        max_ctb_cnt   = max_ctb_rows * max_ctb_cols;
1839        max_num_cu_cols = max_wd_luma / MIN_CU_SIZE;
1840        max_num_4x4_cols = max_wd_luma / 4;
1841    }
1842    /*
1843     * If level is lesser than 31 and the resolution required is higher,
1844     * then make the level at least 31.
1845     */
1846    /*    if (num_mbs > MAX_NUM_MBS_3_0 && level < MAX_LEVEL)
1847     {
1848     level           = MAX_LEVEL;
1849     }
1850     */
1851    if((level < MIN_LEVEL) || (level > MAX_LEVEL))
1852    {
1853        ps_mem_q_op->s_ivd_fill_mem_rec_op_t.u4_error_code |=
1854                        IHEVCD_LEVEL_UNSUPPORTED;
1855        level = MAX_LEVEL;
1856    }
1857    if(num_ref_frames > MAX_REF_CNT)
1858    {
1859        ps_mem_q_op->s_ivd_fill_mem_rec_op_t.u4_error_code |=
1860                        IHEVCD_NUM_REF_UNSUPPORTED;
1861        num_ref_frames = MAX_REF_CNT;
1862    }
1863
1864    if(num_reorder_frames > MAX_REF_CNT)
1865    {
1866        ps_mem_q_op->s_ivd_fill_mem_rec_op_t.u4_error_code |=
1867                        IHEVCD_NUM_REORDER_UNSUPPORTED;
1868        num_reorder_frames = MAX_REF_CNT;
1869    }
1870
1871    max_dpb_size = ihevcd_get_dpb_size(level, max_wd_luma * max_ht_luma);
1872    ps_mem_rec_base = ps_mem_q_ip->s_ivd_fill_mem_rec_ip_t.pv_mem_rec_location;
1873
1874    /* Set all memory reconds as persistent and alignment as 128
1875     * by default
1876     */
1877    ps_mem_rec = ps_mem_rec_base;
1878    for(i = 0; i < MEM_REC_CNT; i++)
1879    {
1880        ps_mem_rec->u4_mem_alignment = 128;
1881        ps_mem_rec->e_mem_type = IV_EXTERNAL_CACHEABLE_PERSISTENT_MEM;
1882        ps_mem_rec++;
1883    }
1884
1885    /* Request memory for HEVCD object */
1886    ps_mem_rec = &ps_mem_rec_base[MEM_REC_IV_OBJ];
1887    ps_mem_rec->u4_mem_size = sizeof(iv_obj_t);
1888
1889    DEBUG("\nMemory record Id %d = %d \n", MEM_REC_IV_OBJ,
1890                    ps_mem_rec->u4_mem_size);
1891
1892    /* Request memory for HEVC Codec context */
1893    ps_mem_rec = &ps_mem_rec_base[MEM_REC_CODEC];
1894    ps_mem_rec->u4_mem_size = sizeof(codec_t);
1895    DEBUG("\nMemory record Id %d = %d \n", MEM_REC_CODEC,
1896                    ps_mem_rec->u4_mem_size);
1897
1898    /* Request memory for buffer which holds bitstream after emulation prevention */
1899    ps_mem_rec = &ps_mem_rec_base[MEM_REC_BITSBUF];
1900    ps_mem_rec->u4_mem_size = MAX((max_wd_luma * max_ht_luma), MIN_BITSBUF_SIZE);
1901    DEBUG("\nMemory record Id %d = %d \n", MEM_REC_BITSBUF,
1902                    ps_mem_rec->u4_mem_size);
1903
1904    /* Request memory for buffer which holds TU structures and coeff data for
1905     * a set of CTBs in the current picture */
1906    /*TODO Currently the buffer is allocated at a frame level. Reduce this to
1907     * allocate for s set of CTBs and add appropriate synchronization logic to
1908     * ensure that this is data is not overwritten before consumption
1909     */
1910    ps_mem_rec = &ps_mem_rec_base[MEM_REC_TU_DATA];
1911    ps_mem_rec->u4_mem_size = ihevcd_get_tu_data_size(max_wd_luma * max_ht_luma);
1912    DEBUG("\nMemory record Id %d = %d \n", MEM_REC_TU_DATA,
1913                    ps_mem_rec->u4_mem_size);
1914
1915    ps_mem_rec = &ps_mem_rec_base[MEM_REC_MVBANK];
1916
1917    ps_mem_rec->u4_mem_size = sizeof(buf_mgr_t);
1918
1919    /* Size for holding mv_buf_t for each MV Bank */
1920    /* Note this allocation is done for BUF_MGR_MAX_CNT instead of
1921     * max_dpb_size or MAX_DPB_SIZE for following reasons
1922     * max_dpb_size will be based on max_wd and max_ht
1923     * For higher max_wd and max_ht this number will be smaller than MAX_DPB_SIZE
1924     * But during actual initialization number of buffers allocated can be more
1925     *
1926     * One extra MV Bank is needed to hold current pics MV bank.
1927     * Since this is only a structure allocation and not actual buffer allocation,
1928     * it is allocated for BUF_MGR_MAX_CNT entries
1929     */
1930    ps_mem_rec->u4_mem_size += BUF_MGR_MAX_CNT * sizeof(mv_buf_t);
1931
1932    {
1933        /* Allocate for pu_map, pu_t and pic_pu_idx for each MV bank */
1934        /* Note: Number of luma samples is not max_wd * max_ht here, instead it is
1935         * set to maximum number of luma samples allowed at the given level.
1936         * This is done to ensure that any stream with width and height lesser
1937         * than max_wd and max_ht is supported. Number of buffers required can be greater
1938         * for lower width and heights at a given level and this increased number of buffers
1939         * might require more memory than what max_wd and max_ht buffer would have required
1940         * Also note one extra buffer is allocted to store current pictures MV bank
1941         * In case of asynchronous parsing and processing, number of buffers should increase here
1942         * based on when parsing and processing threads are synchronized
1943         */
1944        WORD32 lvl_idx = ihevcd_get_lvl_idx(level);
1945        WORD32 max_luma_samples = gai4_ihevc_max_luma_pic_size[lvl_idx];
1946        ps_mem_rec->u4_mem_size += (max_dpb_size + 1) *
1947                        ihevcd_get_pic_mv_bank_size(max_luma_samples);
1948        DEBUG("\nMemory record Id %d = %d \n", MEM_REC_MVBANK,
1949                        ps_mem_rec->u4_mem_size);
1950    }
1951    // TODO GPU : Have to creat ping-pong view for VPS,SPS,PPS.
1952    ps_mem_rec = &ps_mem_rec_base[MEM_REC_VPS];
1953    ps_mem_rec->u4_mem_size = MAX_VPS_CNT * sizeof(vps_t);
1954    DEBUG("\nMemory record Id %d = %d \n", MEM_REC_VPS,
1955                    ps_mem_rec->u4_mem_size);
1956
1957    ps_mem_rec = &ps_mem_rec_base[MEM_REC_SPS];
1958    ps_mem_rec->u4_mem_size = MAX_SPS_CNT * sizeof(sps_t);
1959    DEBUG("\nMemory record Id %d = %d \n", MEM_REC_SPS,
1960                    ps_mem_rec->u4_mem_size);
1961
1962    ps_mem_rec = &ps_mem_rec_base[MEM_REC_PPS];
1963    ps_mem_rec->u4_mem_size = MAX_PPS_CNT * sizeof(pps_t);
1964    DEBUG("\nMemory record Id %d = %d \n", MEM_REC_PPS,
1965                    ps_mem_rec->u4_mem_size);
1966
1967    ps_mem_rec = &ps_mem_rec_base[MEM_REC_SLICE_HDR];
1968    ps_mem_rec->u4_mem_size = MAX_SLICE_HDR_CNT * sizeof(slice_header_t);
1969    DEBUG("\nMemory record Id %d = %d \n", MEM_REC_SLICE_HDR,
1970                    ps_mem_rec->u4_mem_size);
1971
1972    ps_mem_rec = &ps_mem_rec_base[MEM_REC_TILE];
1973    {
1974        WORD32 tile_size;
1975
1976        tile_size  = max_tile_cols * max_tile_rows;
1977        tile_size  *= sizeof(tile_t);
1978
1979
1980        ps_mem_rec->u4_mem_size = MAX_PPS_CNT * tile_size;
1981    }
1982
1983
1984    DEBUG("\nMemory record Id %d = %d \n", MEM_REC_TILE,
1985                    ps_mem_rec->u4_mem_size);
1986
1987    ps_mem_rec = &ps_mem_rec_base[MEM_REC_ENTRY_OFST];
1988    {
1989        WORD32 num_entry_points;
1990
1991        /* One entry point per tile */
1992        num_entry_points  = max_tile_cols * max_tile_rows;
1993
1994        /* One entry point per row of CTBs */
1995        /*********************************************************************/
1996        /* Only tiles or entropy sync is enabled at a time in main           */
1997        /* profile, but since memory required does not increase too much,    */
1998        /* this allocation is done to handle both cases                      */
1999        /*********************************************************************/
2000        num_entry_points  += max_ctb_rows;
2001
2002
2003        ps_mem_rec->u4_mem_size = sizeof(WORD32) * num_entry_points;
2004    }
2005
2006
2007    DEBUG("\nMemory record Id %d = %d \n", MEM_REC_ENTRY_OFST,
2008                    ps_mem_rec->u4_mem_size);
2009
2010
2011    ps_mem_rec = &ps_mem_rec_base[MEM_REC_SCALING_MAT];
2012    {
2013        WORD32 scaling_mat_size;
2014
2015        SCALING_MAT_SIZE(scaling_mat_size)
2016        ps_mem_rec->u4_mem_size = (MAX_SPS_CNT + MAX_PPS_CNT) * scaling_mat_size * sizeof(WORD16);
2017    }
2018    DEBUG("\nMemory record Id %d = %d \n", MEM_REC_SCALING_MAT,
2019                    ps_mem_rec->u4_mem_size);
2020
2021    /* Holds one row skip_flag at 8x8 level used during parsing */
2022    ps_mem_rec = &ps_mem_rec_base[MEM_REC_PARSE_SKIP_FLAG];
2023
2024    /* 1 bit per 8x8 */
2025    ps_mem_rec->u4_mem_size = max_num_cu_cols / 8;
2026    DEBUG("\nMemory record Id %d = %d \n", MEM_REC_PARSE_SKIP_FLAG,
2027                  ps_mem_rec->u4_mem_size);
2028
2029    /* Holds one row skip_flag at 8x8 level used during parsing */
2030    ps_mem_rec = &ps_mem_rec_base[MEM_REC_PARSE_CT_DEPTH];
2031
2032    /* 2 bits per 8x8 */
2033    ps_mem_rec->u4_mem_size = max_num_cu_cols / 4;
2034    DEBUG("\nMemory record Id %d = %d \n", MEM_REC_PARSE_CT_DEPTH,
2035                  ps_mem_rec->u4_mem_size);
2036
2037    /* Holds one row skip_flag at 8x8 level used during parsing */
2038    ps_mem_rec = &ps_mem_rec_base[MEM_REC_PARSE_INTRA_PRED_MODE];
2039
2040    /* 8 bits per 4x4 */
2041    /* 16 bytes each for top and left 64 pixels and 16 bytes for default mode */
2042    ps_mem_rec->u4_mem_size = 3 * 16 * sizeof(UWORD8);
2043    DEBUG("\nMemory record Id %d = %d \n", MEM_REC_PARSE_INTRA_PRED_MODE,
2044                  ps_mem_rec->u4_mem_size);
2045
2046    /* Holds one intra mode at 8x8 level for entire picture */
2047    ps_mem_rec = &ps_mem_rec_base[MEM_REC_INTRA_FLAG];
2048
2049    /* 1 bit per 8x8 */
2050    ps_mem_rec->u4_mem_size = (max_wd_luma / MIN_CU_SIZE) * (max_ht_luma / MIN_CU_SIZE) / 8;
2051    DEBUG("\nMemory record Id %d = %d \n", MEM_REC_INTRA_FLAG,
2052                  ps_mem_rec->u4_mem_size);
2053
2054    /* Holds one transquant bypass flag at 8x8 level for entire picture */
2055    ps_mem_rec = &ps_mem_rec_base[MEM_REC_TRANSQUANT_BYPASS_FLAG];
2056
2057    /* 1 bit per 8x8 */
2058    /* Extra row and column are allocated for easy processing of top and left blocks while loop filtering */
2059    ps_mem_rec->u4_mem_size = ((max_wd_luma + 64) / MIN_CU_SIZE) * ((max_ht_luma + 64) / MIN_CU_SIZE) / 8;
2060    DEBUG("\nMemory record Id %d = %d \n", MEM_REC_TRANSQUANT_BYPASS_FLAG,
2061                  ps_mem_rec->u4_mem_size);
2062
2063    /* Request memory to hold thread handles for each processing thread */
2064    ps_mem_rec = &ps_mem_rec_base[MEM_REC_THREAD_HANDLE];
2065    ps_mem_rec->u4_mem_size = MAX_PROCESS_THREADS * ithread_get_handle_size();
2066    DEBUG("\nMemory record Id %d = %d \n", MEM_REC_THREAD_HANDLE,
2067                    ps_mem_rec->u4_mem_size);
2068
2069
2070    {
2071        WORD32 job_queue_size;
2072        WORD32 num_jobs;
2073        ps_mem_rec = &ps_mem_rec_base[MEM_REC_PROC_JOBQ];
2074
2075
2076        /* One job per row of CTBs */
2077        num_jobs  = max_ctb_rows;
2078
2079        /* One each tile a row of CTBs, num_jobs has to incremented */
2080        num_jobs  *= max_tile_cols;
2081
2082        /* One format convert/frame copy job per row of CTBs for non-shared mode*/
2083        num_jobs  += max_ctb_rows;
2084
2085
2086        job_queue_size = ihevcd_jobq_ctxt_size();
2087        job_queue_size += num_jobs * sizeof(proc_job_t);
2088        ps_mem_rec->u4_mem_size = job_queue_size;
2089        DEBUG("\nMemory record Id %d = %d \n", MEM_REC_PROC_JOBQ,
2090                        ps_mem_rec->u4_mem_size);
2091    }
2092
2093
2094    ps_mem_rec = &ps_mem_rec_base[MEM_REC_PARSE_MAP];
2095    ps_mem_rec->u4_mem_size = max_ctb_cnt;
2096    DEBUG("\nMemory record Id %d = %d \n", MEM_REC_PARSE_MAP,
2097                    ps_mem_rec->u4_mem_size);
2098
2099    ps_mem_rec = &ps_mem_rec_base[MEM_REC_PROC_MAP];
2100    ps_mem_rec->u4_mem_size = max_ctb_cnt;
2101    DEBUG("\nMemory record Id %d = %d \n", MEM_REC_PROC_MAP,
2102                    ps_mem_rec->u4_mem_size);
2103
2104
2105    ps_mem_rec = &ps_mem_rec_base[MEM_REC_DISP_MGR];
2106
2107    /* size for holding display manager context */
2108    ps_mem_rec->u4_mem_size = sizeof(buf_mgr_t);
2109    DEBUG("\nMemory record Id %d = %d \n", MEM_REC_DISP_MGR,
2110                    ps_mem_rec->u4_mem_size);
2111
2112    ps_mem_rec = &ps_mem_rec_base[MEM_REC_DPB_MGR];
2113
2114    /* size for holding dpb manager context */
2115    ps_mem_rec->u4_mem_size = sizeof(dpb_mgr_t);
2116    DEBUG("\nMemory record Id %d = %d \n", MEM_REC_DPB_MGR,
2117                    ps_mem_rec->u4_mem_size);
2118
2119    /** Holds top and left neighbor's pu idx into picture level pu array */
2120    /* Only one top row is enough but left has to be replicated for each process context */
2121    ps_mem_rec = &ps_mem_rec_base[MEM_REC_PIC_PU_IDX_NEIGHBOR];
2122
2123    ps_mem_rec->u4_mem_size = (max_num_4x4_cols  /* left */ + MAX_PROCESS_THREADS * (MAX_CTB_SIZE / 4)/* top */ + 1/* top right */) * sizeof(WORD32);
2124    DEBUG("\nMemory record Id %d = %d \n", MEM_REC_PIC_PU_IDX_NEIGHBOR,
2125                    ps_mem_rec->u4_mem_size);
2126
2127
2128
2129    /* TO hold scratch buffers needed for each process context */
2130    ps_mem_rec = &ps_mem_rec_base[MEM_REC_PROC_SCRATCH];
2131    {
2132        WORD32 size = 0;
2133        WORD32 inter_pred_tmp_buf_size;
2134        WORD32 ntaps_luma;
2135        WORD32 pu_map_size;
2136        WORD32 sao_size = 0;
2137        ntaps_luma = 8;
2138
2139        /* Max inter pred size (number of bytes) */
2140        inter_pred_tmp_buf_size = sizeof(WORD16) * (MAX_CTB_SIZE + ntaps_luma) * MAX_CTB_SIZE;
2141        inter_pred_tmp_buf_size = ALIGN64(inter_pred_tmp_buf_size);
2142
2143
2144        /* To hold pu_index w.r.t. frame level pu_t array for a CTB at 4x4 level*/
2145        /* 16 x 16 4x4 in a CTB of size 64 x 64 and two extra needed for holding
2146         * neighbors
2147         */
2148        pu_map_size = sizeof(WORD32) * (18 * 18);
2149
2150        pu_map_size = ALIGN64(pu_map_size);
2151        size += pu_map_size;
2152
2153        /* To hold inter pred temporary buffers */
2154        size += 2 * inter_pred_tmp_buf_size;
2155
2156
2157        /* Allocate for each process context */
2158        size *= MAX_PROCESS_THREADS;
2159
2160
2161        /* To hold SAO left buffer for luma */
2162        sao_size += sizeof(UWORD8) * (MAX(max_ht_luma, max_wd_luma));
2163
2164        /* To hold SAO left buffer for chroma */
2165        sao_size += sizeof(UWORD8) * (MAX(max_ht_luma, max_wd_luma));
2166
2167        /* To hold SAO top buffer for luma */
2168        sao_size += sizeof(UWORD8) * max_wd_luma;
2169
2170        /* To hold SAO top buffer for chroma */
2171        sao_size += sizeof(UWORD8) * max_wd_luma;
2172
2173        /* To hold SAO top left luma pixel value for last output ctb in a row*/
2174        sao_size += sizeof(UWORD8) * max_ctb_rows;
2175
2176        /* To hold SAO top left chroma pixel value last output ctb in a row*/
2177        sao_size += sizeof(UWORD8) * max_ctb_rows * 2;
2178
2179        /* To hold SAO top left pixel luma for current ctb - column array*/
2180        sao_size += sizeof(UWORD8) * max_ctb_rows;
2181
2182        /* To hold SAO top left pixel chroma for current ctb-column array*/
2183        sao_size += sizeof(UWORD8) * max_ctb_rows * 2;
2184
2185        /* To hold SAO top right pixel luma pixel value last output ctb in a row*/
2186        sao_size += sizeof(UWORD8) * max_ctb_cols;
2187
2188        /* To hold SAO top right pixel chroma pixel value last output ctb in a row*/
2189        sao_size += sizeof(UWORD8) * max_ctb_cols * 2;
2190
2191        /*To hold SAO botton bottom left pixels for luma*/
2192        sao_size += sizeof(UWORD8) * max_ctb_rows;
2193
2194        /*To hold SAO botton bottom left pixels for luma*/
2195        sao_size += sizeof(UWORD8) * max_ctb_rows * 2;
2196        sao_size = ALIGN64(sao_size);
2197        size += sao_size;
2198        ps_mem_rec->u4_mem_size = size;
2199    }
2200    DEBUG("\nMemory record Id %d = %d \n", MEM_REC_PROC_SCRATCH,
2201                    ps_mem_rec->u4_mem_size);
2202
2203    /* TO hold scratch buffers needed for each SAO context */
2204    ps_mem_rec = &ps_mem_rec_base[MEM_REC_SAO_SCRATCH];
2205    {
2206        WORD32 size = 0;
2207
2208        size = 4 * MAX_CTB_SIZE * MAX_CTB_SIZE;
2209
2210        /* 2 temporary buffers*/
2211        size *= 2;
2212
2213        size *= MAX_PROCESS_THREADS;
2214
2215        ps_mem_rec->u4_mem_size = size;
2216    }
2217    DEBUG("\nMemory record Id %d = %d \n", MEM_REC_SAO_SCRATCH,
2218                    ps_mem_rec->u4_mem_size);
2219
2220    ps_mem_rec = &ps_mem_rec_base[MEM_REC_BS_QP];
2221    {
2222        WORD32 size = 0;
2223        WORD32 vert_bs_size, horz_bs_size;
2224        WORD32 qp_const_flag_size;
2225        WORD32 qp_size, num_8x8;
2226
2227        /* Max Number of vertical edges */
2228        vert_bs_size = max_wd_luma / 8 + 2 * MAX_CTB_SIZE / 8;
2229
2230        /* Max Number of horizontal edges - extra MAX_CTB_SIZE / 8 to handle the last 4 rows separately(shifted CTB processing) */
2231        vert_bs_size *= (max_ht_luma + MAX_CTB_SIZE) / MIN_TU_SIZE;
2232
2233        /* Number of bytes */
2234        vert_bs_size /= 8;
2235
2236        /* Two bits per edge */
2237        vert_bs_size *= 2;
2238
2239        /* Max Number of horizontal edges */
2240        horz_bs_size = max_ht_luma / 8 + MAX_CTB_SIZE / 8;
2241
2242        /* Max Number of vertical edges - extra MAX_CTB_SIZE / 8 to handle the last 4 columns separately(shifted CTB processing) */
2243        horz_bs_size *= (max_wd_luma + MAX_CTB_SIZE) / MIN_TU_SIZE;
2244
2245        /* Number of bytes */
2246        horz_bs_size /= 8;
2247
2248        /* Two bits per edge */
2249        horz_bs_size *= 2;
2250
2251        /* Max CTBs in a row */
2252        qp_const_flag_size = max_wd_luma / MIN_CTB_SIZE + 1 /* The last ctb row deblk is done in last ctb + 1 row.*/;
2253
2254        /* Max CTBs in a column */
2255        qp_const_flag_size *= max_ht_luma / MIN_CTB_SIZE;
2256
2257        /* Number of bytes */
2258        qp_const_flag_size = (qp_const_flag_size + 7) >> 3;
2259
2260        /* QP changes at CU level - So store at 8x8 level */
2261        num_8x8 = (max_ht_luma * max_wd_luma) / (MIN_CU_SIZE * MIN_CU_SIZE);
2262        qp_size = num_8x8;
2263
2264        /* To hold vertical boundary strength */
2265        size += vert_bs_size;
2266
2267        /* To hold horizontal boundary strength */
2268        size += horz_bs_size;
2269
2270        /* To hold QP */
2271        size += qp_size;
2272
2273        /* To hold QP const in CTB flags */
2274        size += qp_const_flag_size;
2275
2276        ps_mem_rec->u4_mem_size = size;
2277    }
2278
2279    DEBUG("\nMemory record Id %d = %d \n", MEM_REC_BS_QP,
2280                    ps_mem_rec->u4_mem_size);
2281
2282    ps_mem_rec = &ps_mem_rec_base[MEM_REC_TILE_IDX];
2283    {
2284        WORD32 size = 0;
2285        /* Max CTBs in a row */
2286        size  = max_wd_luma / MIN_CTB_SIZE + 2 /* Top row and bottom row extra. This ensures accessing left,top in first row
2287                                                  and right in last row will not result in invalid access*/;
2288        /* Max CTBs in a column */
2289        size *= max_ht_luma / MIN_CTB_SIZE;
2290
2291        size *= sizeof(UWORD16);
2292        ps_mem_rec->u4_mem_size = size;
2293    }
2294    DEBUG("\nMemory record Id %d = %d \n", MEM_REC_TILE_IDX,
2295                    ps_mem_rec->u4_mem_size);
2296
2297    ps_mem_rec = &ps_mem_rec_base[MEM_REC_SAO];
2298    {
2299        UWORD32 size;
2300
2301        /* 4 bytes per color component per CTB */
2302        size = 3 * 4;
2303
2304        /* MAX number of CTBs in a row */
2305        size *= max_wd_luma / MIN_CTB_SIZE;
2306
2307        /* MAX number of CTBs in a column */
2308        size *= max_ht_luma / MIN_CTB_SIZE;
2309        ps_mem_rec->u4_mem_size = size;
2310    }
2311
2312    DEBUG("\nMemory record Id %d = %d \n", MEM_REC_SAO,
2313                    ps_mem_rec->u4_mem_size);
2314
2315
2316    ps_mem_rec = &ps_mem_rec_base[MEM_REC_REF_PIC];
2317
2318    /* size for holding buffer manager context */
2319    ps_mem_rec->u4_mem_size = sizeof(buf_mgr_t);
2320
2321    /* Size for holding pic_buf_t for each reference picture */
2322    /* Note this allocation is done for BUF_MGR_MAX_CNT instead of
2323     * max_dpb_size or MAX_DPB_SIZE for following reasons
2324     * max_dpb_size will be based on max_wd and max_ht
2325     * For higher max_wd and max_ht this number will be smaller than MAX_DPB_SIZE
2326     * But during actual initialization number of buffers allocated can be more
2327     *
2328     * Also to handle display depth application can allocate more than what
2329     * codec asks for in case of non-shared mode
2330     * Since this is only a structure allocation and not actual buffer allocation,
2331     * it is allocated for BUF_MGR_MAX_CNT entries
2332     */
2333    ps_mem_rec->u4_mem_size += BUF_MGR_MAX_CNT * sizeof(pic_buf_t);
2334
2335    /* In case of non-shared mode allocate for reference picture buffers */
2336    if(0 == share_disp_buf)
2337    {
2338        UWORD32 num_reorder_frames_local = num_reorder_frames;
2339        /* Note: Number of luma samples is not max_wd * max_ht here, instead it is
2340         * set to maximum number of luma samples allowed at the given level.
2341         * This is done to ensure that any stream with width and height lesser
2342         * than max_wd and max_ht is supported. Number of buffers required can be greater
2343         * for lower width and heights at a given level and this increased number of buffers
2344         * might require more memory than what max_wd and max_ht buffer would have required
2345         * Number of buffers is doubled in order to return one frame at a time instead of sending
2346         * multiple outputs during dpb full case.
2347         * Also note one extra buffer is allocted to store current picture
2348         * In case of asynchronous parsing and processing, number of buffers should increase here
2349         * based on when parsing and processing threads are synchronized
2350         */
2351        ps_mem_rec->u4_mem_size +=
2352                        ihevcd_get_total_pic_buf_size(max_wd_luma * max_ht_luma, level,  PAD_WD,  PAD_HT,
2353                                                      num_ref_frames, num_reorder_frames_local);
2354    }
2355    DEBUG("\nMemory record Id %d = %d \n", MEM_REC_REF_PIC,
2356                    ps_mem_rec->u4_mem_size);
2357
2358    /* Request memory to hold mem records to be returned during retrieve call */
2359    ps_mem_rec = &ps_mem_rec_base[MEM_REC_BACKUP];
2360    ps_mem_rec->u4_mem_size = MEM_REC_CNT * sizeof(iv_mem_rec_t);
2361    DEBUG("\nMemory record Id %d = %d \n", MEM_REC_BACKUP,
2362                    ps_mem_rec->u4_mem_size);
2363
2364    /* Each memtab size is aligned to next multiple of 128 bytes */
2365    /* This is to ensure all the memtabs start at different cache lines */
2366    ps_mem_rec = ps_mem_rec_base;
2367    for(i = 0; i < MEM_REC_CNT; i++)
2368    {
2369        ps_mem_rec->u4_mem_size = ALIGN128(ps_mem_rec->u4_mem_size);
2370        ps_mem_rec++;
2371    }
2372    ps_mem_q_op->s_ivd_fill_mem_rec_op_t.u4_num_mem_rec_filled = MEM_REC_CNT;
2373#ifdef APPLY_CONCEALMENT
2374    {
2375        IV_API_CALL_STATUS_T status;
2376        icncl_fill_mem_rec_ip_t cncl_fill_ip;
2377        icncl_fill_mem_rec_op_t cncl_fill_op;
2378        UWORD8 mem_loc = MEM_REC_CNT;
2379
2380        cncl_fill_ip.s_ivd_fill_mem_rec_ip_t.e_cmd = IV_CMD_FILL_NUM_MEM_REC;
2381        cncl_fill_ip.s_ivd_fill_mem_rec_ip_t.pv_mem_rec_location = &(memTab[mem_loc]);
2382        cncl_fill_ip.s_ivd_fill_mem_rec_ip_t.u4_size = ps_mem_q_ip->s_ivd_fill_mem_rec_ip_t.u4_size;
2383        cncl_fill_ip.s_ivd_fill_mem_rec_ip_t.u4_max_frm_wd = max_wd_luma;
2384        cncl_fill_ip.s_ivd_fill_mem_rec_ip_t.u4_max_frm_ht = max_ht_luma;
2385
2386        status = icncl_api_function(NULL, (void *)&cncl_fill_ip, (void *)&cncl_fill_op);
2387
2388        if(IV_SUCCESS == status)
2389        {
2390            icncl_num_mem_rec_ip_t cncl_mem_ip;
2391            icncl_num_mem_rec_op_t cncl_mem_op;
2392
2393            cncl_mem_ip.s_ivd_num_rec_ip_t.e_cmd = IV_CMD_GET_NUM_MEM_REC;
2394            cncl_mem_ip.s_ivd_num_rec_ip_t.u4_size = sizeof(icncl_num_mem_rec_ip_t);
2395
2396            status = icncl_api_function(NULL, (void *)&cncl_mem_ip, (void *)&cncl_mem_op);
2397            if(IV_SUCCESS == status)
2398            {
2399                ps_mem_q_op->s_ivd_fill_mem_rec_op_t.u4_num_mem_rec_filled += cncl_mem_op.s_ivd_num_mem_rec_op_t.u4_num_mem_rec;
2400            }
2401        }
2402
2403        return status;
2404
2405    }
2406#endif //APPLY_CONCEALMENT
2407    DEBUG("Num mem recs in fill call : %d\n",
2408                    ps_mem_q_op->s_ivd_fill_mem_rec_op_t.u4_num_mem_rec_filled);
2409
2410
2411    return (status);
2412}
2413
2414
2415/**
2416*******************************************************************************
2417*
2418* @brief
2419*  Initializes from mem records passed to the codec
2420*
2421* @par Description:
2422*  Initializes pointers based on mem records passed
2423*
2424* @param[in] ps_codec_obj
2425*  Pointer to codec object at API level
2426*
2427* @param[in] pv_api_ip
2428*  Pointer to input argument structure
2429*
2430* @param[out] pv_api_op
2431*  Pointer to output argument structure
2432*
2433* @returns  Status
2434*
2435* @remarks
2436*
2437*
2438*******************************************************************************
2439*/
2440WORD32 ihevcd_init_mem_rec(iv_obj_t *ps_codec_obj,
2441                           void *pv_api_ip,
2442                           void *pv_api_op)
2443{
2444
2445    ihevcd_cxa_init_ip_t *dec_init_ip;
2446    ihevcd_cxa_init_op_t *dec_init_op;
2447    WORD32 i;
2448    iv_mem_rec_t *ps_mem_rec, *ps_mem_rec_base;
2449    WORD32 status = IV_SUCCESS;
2450    codec_t *ps_codec;
2451    WORD32 max_tile_cols, max_tile_rows;
2452
2453    dec_init_ip = (ihevcd_cxa_init_ip_t *)pv_api_ip;
2454    dec_init_op = (ihevcd_cxa_init_op_t *)pv_api_op;
2455
2456    ps_mem_rec_base = dec_init_ip->s_ivd_init_ip_t.pv_mem_rec_location;
2457
2458    ps_mem_rec = &ps_mem_rec_base[MEM_REC_CODEC];
2459    ps_codec_obj->pv_codec_handle = ps_mem_rec->pv_base;
2460
2461    ps_codec = (codec_t *)(ps_codec_obj->pv_codec_handle);
2462
2463    /* Note this memset can not be done in init() call, since init will called
2464    during reset as well. And calling this during reset will mean all pointers
2465    need to reinitialized*/
2466    memset(ps_codec, 0, sizeof(codec_t));
2467
2468    if(dec_init_ip->s_ivd_init_ip_t.u4_size
2469                    > offsetof(ihevcd_cxa_init_ip_t, i4_level))
2470    {
2471        ps_codec->i4_init_level = dec_init_ip->i4_level;
2472
2473        ps_codec->i4_init_level *= 3;
2474    }
2475    else
2476    {
2477        ps_codec->i4_init_level = MAX_LEVEL;
2478    }
2479
2480    if(dec_init_ip->s_ivd_init_ip_t.u4_size
2481                    > offsetof(ihevcd_cxa_init_ip_t, u4_num_ref_frames))
2482    {
2483        ps_codec->i4_init_num_ref = dec_init_ip->u4_num_ref_frames;
2484    }
2485    else
2486    {
2487        ps_codec->i4_init_num_ref = MAX_REF_CNT;
2488    }
2489
2490    if(dec_init_ip->s_ivd_init_ip_t.u4_size
2491                    > offsetof(ihevcd_cxa_init_ip_t, u4_num_reorder_frames))
2492    {
2493        ps_codec->i4_init_num_reorder = dec_init_ip->u4_num_reorder_frames;
2494    }
2495    else
2496    {
2497        ps_codec->i4_init_num_reorder = MAX_REF_CNT;
2498    }
2499
2500    if(dec_init_ip->s_ivd_init_ip_t.u4_size
2501                    > offsetof(ihevcd_cxa_init_ip_t, u4_num_extra_disp_buf))
2502    {
2503        ps_codec->i4_init_num_extra_disp_buf =
2504                        dec_init_ip->u4_num_extra_disp_buf;
2505    }
2506    else
2507    {
2508        ps_codec->i4_init_num_extra_disp_buf = 0;
2509    }
2510
2511    if(dec_init_ip->s_ivd_init_ip_t.u4_size
2512                    > offsetof(ihevcd_cxa_init_ip_t, u4_share_disp_buf))
2513    {
2514#ifndef LOGO_EN
2515        ps_codec->i4_share_disp_buf = dec_init_ip->u4_share_disp_buf;
2516#else
2517        ps_codec->i4_share_disp_buf = 0;
2518#endif
2519    }
2520    else
2521    {
2522        ps_codec->i4_share_disp_buf = 0;
2523    }
2524    /* Shared display mode is supported only for 420SP and 420P formats */
2525    if((dec_init_ip->s_ivd_init_ip_t.e_output_format != IV_YUV_420P) &&
2526       (dec_init_ip->s_ivd_init_ip_t.e_output_format != IV_YUV_420SP_UV) &&
2527       (dec_init_ip->s_ivd_init_ip_t.e_output_format != IV_YUV_420SP_VU))
2528    {
2529        ps_codec->i4_share_disp_buf = 0;
2530    }
2531
2532    if((ps_codec->i4_init_level < MIN_LEVEL)
2533                    || (ps_codec->i4_init_level > MAX_LEVEL))
2534    {
2535        dec_init_op->s_ivd_init_op_t.u4_error_code |= IHEVCD_LEVEL_UNSUPPORTED;
2536        return (IV_FAIL);
2537    }
2538
2539    if(ps_codec->i4_init_num_ref > MAX_REF_CNT)
2540    {
2541        dec_init_op->s_ivd_init_op_t.u4_error_code |=
2542                        IHEVCD_NUM_REF_UNSUPPORTED;
2543        ps_codec->i4_init_num_ref = MAX_REF_CNT;
2544    }
2545
2546    if(ps_codec->i4_init_num_reorder > MAX_REF_CNT)
2547    {
2548        dec_init_op->s_ivd_init_op_t.u4_error_code |=
2549                        IHEVCD_NUM_REORDER_UNSUPPORTED;
2550        ps_codec->i4_init_num_reorder = MAX_REF_CNT;
2551    }
2552
2553    if(ps_codec->i4_init_num_extra_disp_buf > MAX_REF_CNT)
2554    {
2555        dec_init_op->s_ivd_init_op_t.u4_error_code |=
2556                        IHEVCD_NUM_EXTRA_DISP_UNSUPPORTED;
2557        ps_codec->i4_init_num_extra_disp_buf = 0;
2558    }
2559
2560    ps_codec->e_chroma_fmt = dec_init_ip->s_ivd_init_ip_t.e_output_format;
2561
2562    ps_codec->i4_max_wd = dec_init_ip->s_ivd_init_ip_t.u4_frm_max_wd;
2563    ps_codec->i4_max_ht = dec_init_ip->s_ivd_init_ip_t.u4_frm_max_ht;
2564
2565    ps_codec->i4_max_wd = ALIGN64(ps_codec->i4_max_wd);
2566    ps_codec->i4_max_ht = ALIGN64(ps_codec->i4_max_ht);
2567
2568    ps_codec->i4_new_max_wd = ps_codec->i4_max_wd;
2569    ps_codec->i4_new_max_ht = ps_codec->i4_max_ht;
2570
2571    max_tile_cols = (ps_codec->i4_max_wd + MIN_TILE_WD - 1) / MIN_TILE_WD;
2572    max_tile_rows = (ps_codec->i4_max_ht + MIN_TILE_HT - 1) / MIN_TILE_HT;
2573
2574    ps_mem_rec = &ps_mem_rec_base[MEM_REC_BACKUP];
2575    ps_codec->ps_mem_rec_backup = (iv_mem_rec_t *)ps_mem_rec->pv_base;
2576
2577    memcpy(ps_codec->ps_mem_rec_backup, ps_mem_rec_base,
2578           MEM_REC_CNT * sizeof(iv_mem_rec_t));
2579
2580    ps_mem_rec = &ps_mem_rec_base[MEM_REC_BITSBUF];
2581    ps_codec->pu1_bitsbuf = (UWORD8 *)ps_mem_rec->pv_base;
2582    ps_codec->u4_bitsbuf_size = ps_mem_rec->u4_mem_size;
2583
2584    ps_mem_rec = &ps_mem_rec_base[MEM_REC_TU_DATA];
2585    ps_codec->pv_tu_data = ps_mem_rec->pv_base;
2586    ps_mem_rec = &ps_mem_rec_base[MEM_REC_MVBANK];
2587    ps_codec->pv_mv_buf_mgr = ps_mem_rec->pv_base;
2588    ps_codec->pv_mv_bank_buf_base = (UWORD8 *)ps_codec->pv_mv_buf_mgr + sizeof(buf_mgr_t);
2589
2590    ps_codec->i4_total_mv_bank_size = ps_mem_rec->u4_mem_size - sizeof(buf_mgr_t);
2591
2592
2593    ps_mem_rec = &ps_mem_rec_base[MEM_REC_VPS];
2594    ps_codec->ps_vps_base = (vps_t *)ps_mem_rec->pv_base;
2595    ps_codec->s_parse.ps_vps_base = ps_codec->ps_vps_base;
2596
2597    ps_mem_rec = &ps_mem_rec_base[MEM_REC_SPS];
2598    ps_codec->ps_sps_base = (sps_t *)ps_mem_rec->pv_base;
2599    ps_codec->s_parse.ps_sps_base = ps_codec->ps_sps_base;
2600
2601    ps_mem_rec = &ps_mem_rec_base[MEM_REC_PPS];
2602    ps_codec->ps_pps_base = (pps_t *)ps_mem_rec->pv_base;
2603    ps_codec->s_parse.ps_pps_base = ps_codec->ps_pps_base;
2604
2605    ps_mem_rec = &ps_mem_rec_base[MEM_REC_SLICE_HDR];
2606    ps_codec->ps_slice_hdr_base = (slice_header_t *)ps_mem_rec->pv_base;
2607    ps_codec->s_parse.ps_slice_hdr_base = ps_codec->ps_slice_hdr_base;
2608
2609    ps_mem_rec = &ps_mem_rec_base[MEM_REC_TILE];
2610    ps_codec->ps_tile = (tile_t *)ps_mem_rec->pv_base;
2611
2612    ps_mem_rec = &ps_mem_rec_base[MEM_REC_ENTRY_OFST];
2613    ps_codec->pi4_entry_ofst = (WORD32 *)ps_mem_rec->pv_base;
2614
2615    ps_mem_rec = &ps_mem_rec_base[MEM_REC_SCALING_MAT];
2616    ps_codec->pi2_scaling_mat = (WORD16 *)ps_mem_rec->pv_base;
2617
2618    ps_mem_rec = &ps_mem_rec_base[MEM_REC_PARSE_SKIP_FLAG];
2619    ps_codec->s_parse.pu4_skip_cu_top = (UWORD32 *)ps_mem_rec->pv_base;
2620
2621    ps_mem_rec = &ps_mem_rec_base[MEM_REC_PARSE_CT_DEPTH];
2622    ps_codec->s_parse.pu4_ct_depth_top = (UWORD32 *)ps_mem_rec->pv_base;
2623
2624    ps_mem_rec = &ps_mem_rec_base[MEM_REC_PARSE_INTRA_PRED_MODE];
2625    ps_codec->s_parse.pu1_luma_intra_pred_mode_left =
2626                    (UWORD8 *)ps_mem_rec->pv_base;
2627    ps_codec->s_parse.pu1_luma_intra_pred_mode_top  =
2628                    (UWORD8 *)ps_mem_rec->pv_base + 16;
2629
2630    ps_mem_rec = &ps_mem_rec_base[MEM_REC_INTRA_FLAG];
2631
2632    memset(ps_mem_rec->pv_base, 0, (ps_codec->i4_max_wd / MIN_CU_SIZE) * (ps_codec->i4_max_ht / MIN_CU_SIZE) / 8);
2633
2634    ps_codec->pu1_pic_intra_flag = (UWORD8 *)ps_mem_rec->pv_base;
2635    ps_codec->s_parse.pu1_pic_intra_flag = ps_codec->pu1_pic_intra_flag;
2636    ps_mem_rec = &ps_mem_rec_base[MEM_REC_TRANSQUANT_BYPASS_FLAG];
2637
2638    {
2639        WORD32 loop_filter_size = ((ps_codec->i4_max_wd  + 64) / MIN_CU_SIZE) * ((ps_codec->i4_max_ht + 64) / MIN_CU_SIZE) / 8;
2640        WORD32 loop_filter_strd = (ps_codec->i4_max_wd + 63) >> 6;
2641
2642        memset(ps_mem_rec->pv_base, 0, loop_filter_size);
2643
2644        /* The offset is added for easy processing of top and left blocks while loop filtering */
2645        ps_codec->pu1_pic_no_loop_filter_flag = (UWORD8 *)ps_mem_rec->pv_base + loop_filter_strd + 1;
2646        ps_codec->s_parse.pu1_pic_no_loop_filter_flag = ps_codec->pu1_pic_no_loop_filter_flag;
2647        ps_codec->s_parse.s_deblk_ctxt.pu1_pic_no_loop_filter_flag = ps_codec->pu1_pic_no_loop_filter_flag;
2648        ps_codec->s_parse.s_sao_ctxt.pu1_pic_no_loop_filter_flag = ps_codec->pu1_pic_no_loop_filter_flag;
2649    }
2650
2651    /* Initialize pointers in PPS structures */
2652    {
2653        sps_t *ps_sps = ps_codec->ps_sps_base;
2654        pps_t *ps_pps = ps_codec->ps_pps_base;
2655        tile_t *ps_tile =  ps_codec->ps_tile;
2656        WORD16 *pi2_scaling_mat =  ps_codec->pi2_scaling_mat;
2657        WORD32 scaling_mat_size;
2658
2659        SCALING_MAT_SIZE(scaling_mat_size);
2660
2661        for(i = 0; i < MAX_SPS_CNT; i++)
2662        {
2663            ps_sps->pi2_scaling_mat  = pi2_scaling_mat;
2664            pi2_scaling_mat += scaling_mat_size;
2665            ps_sps++;
2666        }
2667
2668        for(i = 0; i < MAX_PPS_CNT; i++)
2669        {
2670            ps_pps->ps_tile = ps_tile;
2671            ps_tile += (max_tile_cols * max_tile_rows);
2672
2673            ps_pps->pi2_scaling_mat  = pi2_scaling_mat;
2674            pi2_scaling_mat += scaling_mat_size;
2675            ps_pps++;
2676        }
2677
2678    }
2679
2680    ps_mem_rec = &ps_mem_rec_base[MEM_REC_THREAD_HANDLE];
2681    for(i = 0; i < MAX_PROCESS_THREADS; i++)
2682    {
2683        WORD32 handle_size = ithread_get_handle_size();
2684        ps_codec->apv_process_thread_handle[i] =
2685                        (UWORD8 *)ps_mem_rec->pv_base + (i * handle_size);
2686    }
2687
2688    ps_mem_rec = &ps_mem_rec_base[MEM_REC_PROC_JOBQ];
2689    ps_codec->pv_proc_jobq_buf = ps_mem_rec->pv_base;
2690    ps_codec->i4_proc_jobq_buf_size = ps_mem_rec->u4_mem_size;
2691
2692    ps_mem_rec = &ps_mem_rec_base[MEM_REC_PARSE_MAP];
2693    ps_codec->pu1_parse_map = (UWORD8 *)ps_mem_rec->pv_base;
2694
2695    ps_mem_rec = &ps_mem_rec_base[MEM_REC_PROC_MAP];
2696    ps_codec->pu1_proc_map = (UWORD8 *)ps_mem_rec->pv_base;
2697    ps_mem_rec = &ps_mem_rec_base[MEM_REC_DISP_MGR];
2698    ps_codec->pv_disp_buf_mgr = ps_mem_rec->pv_base;
2699
2700    ps_mem_rec = &ps_mem_rec_base[MEM_REC_DPB_MGR];
2701    ps_codec->pv_dpb_mgr = ps_mem_rec->pv_base;
2702
2703
2704    ps_mem_rec = &ps_mem_rec_base[MEM_REC_PIC_PU_IDX_NEIGHBOR];
2705
2706    for(i = 0; i < MAX_PROCESS_THREADS; i++)
2707    {
2708        UWORD32 *pu4_buf = (UWORD32 *)ps_mem_rec->pv_base;
2709        ps_codec->as_process[i].pu4_pic_pu_idx_left = pu4_buf + i * (MAX_CTB_SIZE / 4);
2710        memset(ps_codec->as_process[i].pu4_pic_pu_idx_left, 0, sizeof(UWORD32) * MAX_CTB_SIZE / 4);
2711        ps_codec->as_process[i].pu4_pic_pu_idx_top = pu4_buf + MAX_PROCESS_THREADS * (MAX_CTB_SIZE / 4);
2712    }
2713    memset(ps_codec->as_process[0].pu4_pic_pu_idx_top, 0, sizeof(UWORD32) * (ps_codec->i4_max_wd / 4 + 1));
2714
2715
2716    ps_mem_rec = &ps_mem_rec_base[MEM_REC_PROC_SCRATCH];
2717    {
2718        UWORD8 *pu1_buf = (UWORD8 *)ps_mem_rec->pv_base;
2719        WORD32 pic_pu_idx_map_size;
2720
2721        WORD32 inter_pred_tmp_buf_size, ntaps_luma;
2722
2723        /* Max inter pred size */
2724        ntaps_luma = 8;
2725        inter_pred_tmp_buf_size = sizeof(WORD16) * (MAX_CTB_SIZE + ntaps_luma) * MAX_CTB_SIZE;
2726
2727        inter_pred_tmp_buf_size = ALIGN64(inter_pred_tmp_buf_size);
2728
2729        /* To hold pu_index w.r.t. frame level pu_t array for a CTB */
2730        pic_pu_idx_map_size = sizeof(WORD32) * (18 * 18);
2731        pic_pu_idx_map_size = ALIGN64(pic_pu_idx_map_size);
2732        for(i = 0; i < MAX_PROCESS_THREADS; i++)
2733        {
2734            ps_codec->as_process[i].pi2_inter_pred_tmp_buf1 = (WORD16 *)pu1_buf;
2735            pu1_buf += inter_pred_tmp_buf_size;
2736
2737            ps_codec->as_process[i].pi2_inter_pred_tmp_buf2 = (WORD16 *)pu1_buf;
2738            pu1_buf += inter_pred_tmp_buf_size;
2739
2740            /* Inverse transform intermediate and inverse scan output buffers reuse inter pred scratch buffers */
2741            ps_codec->as_process[i].pi2_itrans_intrmd_buf =
2742                            ps_codec->as_process[i].pi2_inter_pred_tmp_buf2;
2743            ps_codec->as_process[i].pi2_invscan_out =
2744                            ps_codec->as_process[i].pi2_inter_pred_tmp_buf1;
2745
2746            ps_codec->as_process[i].pu4_pic_pu_idx_map = (UWORD32 *)pu1_buf;
2747            ps_codec->as_process[i].s_bs_ctxt.pu4_pic_pu_idx_map =
2748                            (UWORD32 *)pu1_buf;
2749            pu1_buf += pic_pu_idx_map_size;
2750
2751            //   ps_codec->as_process[i].pi2_inter_pred_tmp_buf3 = (WORD16 *)pu1_buf;
2752            //   pu1_buf += inter_pred_tmp_buf_size;
2753
2754            ps_codec->as_process[i].i4_inter_pred_tmp_buf_strd = MAX_CTB_SIZE;
2755
2756        }
2757        for(i = 0; i < MAX_PROCESS_THREADS; i++)
2758        {
2759            ps_codec->as_process[i].s_sao_ctxt.pu1_sao_src_left_luma = (UWORD8 *)pu1_buf;
2760        }
2761        ps_codec->s_parse.s_sao_ctxt.pu1_sao_src_left_luma = (UWORD8 *)pu1_buf;
2762        pu1_buf += MAX(ps_codec->i4_max_ht, ps_codec->i4_max_wd);
2763
2764        for(i = 0; i < MAX_PROCESS_THREADS; i++)
2765        {
2766            ps_codec->as_process[i].s_sao_ctxt.pu1_sao_src_left_chroma = (UWORD8 *)pu1_buf;
2767        }
2768        ps_codec->s_parse.s_sao_ctxt.pu1_sao_src_left_chroma = (UWORD8 *)pu1_buf;
2769        pu1_buf += MAX(ps_codec->i4_max_ht, ps_codec->i4_max_wd);
2770        for(i = 0; i < MAX_PROCESS_THREADS; i++)
2771        {
2772            ps_codec->as_process[i].s_sao_ctxt.pu1_sao_src_top_luma = (UWORD8 *)pu1_buf;
2773        }
2774        ps_codec->s_parse.s_sao_ctxt.pu1_sao_src_top_luma = (UWORD8 *)pu1_buf;
2775        pu1_buf += ps_codec->i4_max_wd;
2776
2777        for(i = 0; i < MAX_PROCESS_THREADS; i++)
2778        {
2779            ps_codec->as_process[i].s_sao_ctxt.pu1_sao_src_top_chroma = (UWORD8 *)pu1_buf;
2780        }
2781        ps_codec->s_parse.s_sao_ctxt.pu1_sao_src_top_chroma = (UWORD8 *)pu1_buf;
2782        pu1_buf += ps_codec->i4_max_wd;
2783        for(i = 0; i < MAX_PROCESS_THREADS; i++)
2784        {
2785            ps_codec->as_process[i].s_sao_ctxt.pu1_sao_src_luma_top_left_ctb = (UWORD8 *)pu1_buf;
2786        }
2787        ps_codec->s_parse.s_sao_ctxt.pu1_sao_src_luma_top_left_ctb = (UWORD8 *)pu1_buf;
2788        pu1_buf += ps_codec->i4_max_ht / MIN_CTB_SIZE;
2789
2790        for(i = 0; i < MAX_PROCESS_THREADS; i++)
2791        {
2792            ps_codec->as_process[i].s_sao_ctxt.pu1_sao_src_chroma_top_left_ctb = (UWORD8 *)pu1_buf;
2793        }
2794        ps_codec->s_parse.s_sao_ctxt.pu1_sao_src_chroma_top_left_ctb = (UWORD8 *)pu1_buf;
2795        pu1_buf += (ps_codec->i4_max_ht / MIN_CTB_SIZE) * 2;
2796
2797        for(i = 0; i < MAX_PROCESS_THREADS; i++)
2798        {
2799            ps_codec->as_process[i].s_sao_ctxt.pu1_sao_src_top_left_luma_curr_ctb = (UWORD8 *)pu1_buf;
2800        }
2801        ps_codec->s_parse.s_sao_ctxt.pu1_sao_src_top_left_luma_curr_ctb = (UWORD8 *)pu1_buf;
2802        pu1_buf += ps_codec->i4_max_ht / MIN_CTB_SIZE;
2803
2804        for(i = 0; i < MAX_PROCESS_THREADS; i++)
2805        {
2806            ps_codec->as_process[i].s_sao_ctxt.pu1_sao_src_top_left_chroma_curr_ctb = (UWORD8 *)pu1_buf;
2807        }
2808        ps_codec->s_parse.s_sao_ctxt.pu1_sao_src_top_left_chroma_curr_ctb = (UWORD8 *)pu1_buf;
2809
2810        pu1_buf += (ps_codec->i4_max_ht / MIN_CTB_SIZE) * 2;
2811        for(i = 0; i < MAX_PROCESS_THREADS; i++)
2812        {
2813            ps_codec->as_process[i].s_sao_ctxt.pu1_sao_src_top_left_luma_top_right = (UWORD8 *)pu1_buf;
2814        }
2815        ps_codec->s_parse.s_sao_ctxt.pu1_sao_src_top_left_luma_top_right = (UWORD8 *)pu1_buf;
2816
2817        pu1_buf += ps_codec->i4_max_wd / MIN_CTB_SIZE;
2818        for(i = 0; i < MAX_PROCESS_THREADS; i++)
2819        {
2820            ps_codec->as_process[i].s_sao_ctxt.pu1_sao_src_top_left_chroma_top_right = (UWORD8 *)pu1_buf;
2821        }
2822        ps_codec->s_parse.s_sao_ctxt.pu1_sao_src_top_left_chroma_top_right = (UWORD8 *)pu1_buf;
2823
2824        pu1_buf += (ps_codec->i4_max_wd / MIN_CTB_SIZE) * 2;
2825
2826        /*Per CTB, Store 1 value for luma , 2 values for chroma*/
2827        for(i = 0; i < MAX_PROCESS_THREADS; i++)
2828        {
2829            ps_codec->as_process[i].s_sao_ctxt.pu1_sao_src_top_left_luma_bot_left = (UWORD8 *)pu1_buf;
2830        }
2831        ps_codec->s_parse.s_sao_ctxt.pu1_sao_src_top_left_luma_bot_left = (UWORD8 *)pu1_buf;
2832
2833        pu1_buf += (ps_codec->i4_max_ht / MIN_CTB_SIZE);
2834
2835        for(i = 0; i < MAX_PROCESS_THREADS; i++)
2836        {
2837            ps_codec->as_process[i].s_sao_ctxt.pu1_sao_src_top_left_chroma_bot_left = (UWORD8 *)pu1_buf;
2838        }
2839        ps_codec->s_parse.s_sao_ctxt.pu1_sao_src_top_left_chroma_bot_left = (UWORD8 *)pu1_buf;
2840
2841        pu1_buf += (ps_codec->i4_max_ht / MIN_CTB_SIZE) * 2;
2842    }
2843
2844    ps_mem_rec = &ps_mem_rec_base[MEM_REC_SAO_SCRATCH];
2845    {
2846        UWORD8 *pu1_buf = (UWORD8 *)ps_mem_rec->pv_base;
2847        for(i = 0; i < MAX_PROCESS_THREADS; i++)
2848        {
2849            ps_codec->as_process[i].s_sao_ctxt.pu1_tmp_buf_luma = (UWORD8 *)pu1_buf;
2850            pu1_buf += 4 * MAX_CTB_SIZE * MAX_CTB_SIZE * sizeof(UWORD8);
2851
2852            ps_codec->as_process[i].s_sao_ctxt.pu1_tmp_buf_chroma = (UWORD8 *)pu1_buf;
2853            pu1_buf += 4 * MAX_CTB_SIZE * MAX_CTB_SIZE * sizeof(UWORD8);
2854        }
2855    }
2856
2857    ps_mem_rec = &ps_mem_rec_base[MEM_REC_BS_QP];
2858    {
2859        UWORD8 *pu1_buf = (UWORD8 *)ps_mem_rec->pv_base;
2860        WORD32 vert_bs_size, horz_bs_size;
2861        WORD32 qp_const_flag_size;
2862        WORD32 qp_size;
2863        WORD32 num_8x8;
2864
2865        /* Max Number of vertical edges */
2866        vert_bs_size = ps_codec->i4_max_wd / 8 + 2 * MAX_CTB_SIZE / 8;
2867
2868        /* Max Number of horizontal edges - extra MAX_CTB_SIZE / 8 to handle the last 4 rows separately(shifted CTB processing) */
2869        vert_bs_size *= (ps_codec->i4_max_ht + MAX_CTB_SIZE) / MIN_TU_SIZE;
2870
2871        /* Number of bytes */
2872        vert_bs_size /= 8;
2873
2874        /* Two bits per edge */
2875        vert_bs_size *= 2;
2876
2877        /* Max Number of horizontal edges */
2878        horz_bs_size = ps_codec->i4_max_ht / 8 + MAX_CTB_SIZE / 8;
2879
2880        /* Max Number of vertical edges - extra MAX_CTB_SIZE / 8 to handle the last 4 columns separately(shifted CTB processing) */
2881        horz_bs_size *= (ps_codec->i4_max_wd + MAX_CTB_SIZE) / MIN_TU_SIZE;
2882
2883        /* Number of bytes */
2884        horz_bs_size /= 8;
2885
2886        /* Two bits per edge */
2887        horz_bs_size *= 2;
2888
2889        /* Max CTBs in a row */
2890        qp_const_flag_size = ps_codec->i4_max_wd / MIN_CTB_SIZE + 1 /* The last ctb row deblk is done in last ctb + 1 row.*/;
2891
2892        /* Max CTBs in a column */
2893        qp_const_flag_size *= ps_codec->i4_max_ht / MIN_CTB_SIZE;
2894
2895        /* Number of bytes */
2896        qp_const_flag_size /= 8;
2897
2898        /* QP changes at CU level - So store at 8x8 level */
2899        num_8x8 = (ps_codec->i4_max_ht * ps_codec->i4_max_wd) / (MIN_CU_SIZE * MIN_CU_SIZE);
2900        qp_size = num_8x8;
2901        memset(pu1_buf, 0, vert_bs_size + horz_bs_size + qp_size + qp_const_flag_size);
2902
2903        for(i = 0; i < MAX_PROCESS_THREADS; i++)
2904        {
2905            ps_codec->as_process[i].s_bs_ctxt.pu4_pic_vert_bs = (UWORD32 *)pu1_buf;
2906            ps_codec->as_process[i].s_deblk_ctxt.s_bs_ctxt.pu4_pic_vert_bs = (UWORD32 *)pu1_buf;
2907            ps_codec->s_parse.s_deblk_ctxt.s_bs_ctxt.pu4_pic_vert_bs = (UWORD32 *)pu1_buf;
2908            pu1_buf += vert_bs_size;
2909
2910            ps_codec->as_process[i].s_bs_ctxt.pu4_pic_horz_bs = (UWORD32 *)pu1_buf;
2911            ps_codec->as_process[i].s_deblk_ctxt.s_bs_ctxt.pu4_pic_horz_bs = (UWORD32 *)pu1_buf;
2912            ps_codec->s_parse.s_deblk_ctxt.s_bs_ctxt.pu4_pic_horz_bs = (UWORD32 *)pu1_buf;
2913            pu1_buf += horz_bs_size;
2914
2915            ps_codec->as_process[i].s_bs_ctxt.pu1_pic_qp = (UWORD8 *)pu1_buf;
2916            ps_codec->as_process[i].s_deblk_ctxt.s_bs_ctxt.pu1_pic_qp = (UWORD8 *)pu1_buf;
2917            ps_codec->s_parse.s_deblk_ctxt.s_bs_ctxt.pu1_pic_qp = (UWORD8 *)pu1_buf;
2918            pu1_buf += qp_size;
2919
2920            ps_codec->as_process[i].s_bs_ctxt.pu1_pic_qp_const_in_ctb = (UWORD8 *)pu1_buf;
2921            ps_codec->as_process[i].s_deblk_ctxt.s_bs_ctxt.pu1_pic_qp_const_in_ctb = (UWORD8 *)pu1_buf;
2922            ps_codec->s_parse.s_deblk_ctxt.s_bs_ctxt.pu1_pic_qp_const_in_ctb = (UWORD8 *)pu1_buf;
2923            pu1_buf += qp_const_flag_size;
2924
2925            pu1_buf -= (vert_bs_size + horz_bs_size + qp_size + qp_const_flag_size);
2926        }
2927        ps_codec->s_parse.s_bs_ctxt.pu4_pic_vert_bs = (UWORD32 *)pu1_buf;
2928        pu1_buf += vert_bs_size;
2929
2930        ps_codec->s_parse.s_bs_ctxt.pu4_pic_horz_bs = (UWORD32 *)pu1_buf;
2931        pu1_buf += horz_bs_size;
2932
2933        ps_codec->s_parse.s_bs_ctxt.pu1_pic_qp = (UWORD8 *)pu1_buf;
2934        pu1_buf += qp_size;
2935
2936        ps_codec->s_parse.s_bs_ctxt.pu1_pic_qp_const_in_ctb = (UWORD8 *)pu1_buf;
2937        pu1_buf += qp_const_flag_size;
2938
2939    }
2940
2941    ps_mem_rec = &ps_mem_rec_base[MEM_REC_TILE_IDX];
2942    {
2943        UWORD8 *pu1_buf = (UWORD8 *)ps_mem_rec->pv_base;
2944
2945        for(i = 0; i < MAX_PROCESS_THREADS; i++)
2946        {
2947            ps_codec->as_process[i].pu1_tile_idx = (UWORD16 *)pu1_buf + ps_codec->i4_max_wd / MIN_CTB_SIZE /* Offset 1 row */;
2948        }
2949    }
2950
2951    ps_mem_rec = &ps_mem_rec_base[MEM_REC_SAO];
2952    ps_codec->s_parse.ps_pic_sao = (sao_t *)ps_mem_rec->pv_base;
2953    ps_codec->s_parse.s_sao_ctxt.ps_pic_sao = (sao_t *)ps_mem_rec->pv_base;
2954    for(i = 0; i < MAX_PROCESS_THREADS; i++)
2955    {
2956        ps_codec->as_process[i].s_sao_ctxt.ps_pic_sao = ps_codec->s_parse.ps_pic_sao;
2957    }
2958
2959    ps_mem_rec = &ps_mem_rec_base[MEM_REC_REF_PIC];
2960    ps_codec->pv_pic_buf_mgr = ps_mem_rec->pv_base;
2961    ps_codec->pv_pic_buf_base = (UWORD8 *)ps_codec->pv_pic_buf_mgr + sizeof(buf_mgr_t);
2962    ps_codec->i4_total_pic_buf_size = ps_mem_rec->u4_mem_size - sizeof(buf_mgr_t);
2963
2964
2965
2966
2967
2968#ifdef APPLY_CONCEALMENT
2969    {
2970
2971        UWORD32 mem_loc;
2972
2973        icncl_init_ip_t cncl_init_ip;
2974        icncl_init_op_t cncl_init_op;
2975        iv_mem_rec_t *ps_mem_rec;
2976        DecStruct *ps_codec;
2977
2978        ps_mem_rec = dec_init_ip->s_ivd_init_ip_t.pv_mem_rec_location;
2979        mem_loc = MEM_REC_CNT;
2980
2981        ps_codec->ps_conceal = (iv_obj_t *)ps_mem_rec[mem_loc].pv_base;
2982        ps_codec->i4_first_frame_done = 0;
2983
2984        cncl_init_ip.u4_size = sizeof(icncl_init_ip_t);
2985        cncl_init_ip.pv_mem_rec_location = &(ps_mem_rec[mem_loc]);
2986        cncl_init_ip.e_cmd = IV_CMD_INIT;
2987
2988        status = icncl_api_function(ps_codec->ps_conceal, (void *)&cncl_init_ip, (void *)&cncl_init_op);
2989
2990    }
2991#endif //APPLY_CONCEALMENT
2992
2993    status = ihevcd_init(ps_codec);
2994
2995    TRACE_INIT(NULL);
2996    STATS_INIT();
2997    return status;
2998}
2999/**
3000*******************************************************************************
3001*
3002* @brief
3003*  Retrieves mem records passed to the codec
3004*
3005* @par Description:
3006*  Retrieves memrecs passed earlier
3007*
3008* @param[in] ps_codec_obj
3009*  Pointer to codec object at API level
3010*
3011* @param[in] pv_api_ip
3012*  Pointer to input argument structure
3013*
3014* @param[out] pv_api_op
3015*  Pointer to output argument structure
3016*
3017* @returns  Status
3018*
3019* @remarks
3020*
3021*
3022*******************************************************************************
3023*/
3024WORD32 ihevcd_retrieve_memrec(iv_obj_t *ps_codec_obj,
3025                              void *pv_api_ip,
3026                              void *pv_api_op)
3027{
3028
3029    iv_retrieve_mem_rec_ip_t *dec_clr_ip;
3030    iv_retrieve_mem_rec_op_t *dec_clr_op;
3031    codec_t *ps_codec;
3032    dec_clr_ip = (iv_retrieve_mem_rec_ip_t *)pv_api_ip;
3033    dec_clr_op = (iv_retrieve_mem_rec_op_t *)pv_api_op;
3034    ps_codec = (codec_t *)(ps_codec_obj->pv_codec_handle);
3035
3036    if(ps_codec->i4_init_done != 1)
3037    {
3038        dec_clr_op->u4_error_code |= 1 << IVD_FATALERROR;
3039        dec_clr_op->u4_error_code |= IHEVCD_INIT_NOT_DONE;
3040        return IV_FAIL;
3041    }
3042
3043    memcpy(dec_clr_ip->pv_mem_rec_location, ps_codec->ps_mem_rec_backup,
3044           MEM_REC_CNT * (sizeof(iv_mem_rec_t)));
3045    dec_clr_op->u4_num_mem_rec_filled = MEM_REC_CNT;
3046
3047#ifdef APPLY_CONCEALMENT
3048    {
3049        IV_API_CALL_STATUS_T status;
3050        icncl_fill_mem_rec_ip_t cncl_fill_ip;
3051        icncl_fill_mem_rec_op_t cncl_fill_op;
3052
3053        iv_mem_rec_t *ps_mem_rec;
3054
3055        UWORD8 mem_loc = MEM_REC_CNT;
3056        UWORD8 num_cncl_mem = 0;
3057
3058        ps_mem_rec = dec_clr_ip->pv_mem_rec_location;
3059
3060        cncl_fill_ip.s_ivd_fill_mem_rec_ip_t.e_cmd = IV_CMD_FILL_NUM_MEM_REC;
3061        cncl_fill_ip.s_ivd_fill_mem_rec_ip_t.pv_mem_rec_location = &(ps_mem_rec[mem_loc]);
3062        cncl_fill_ip.s_ivd_fill_mem_rec_ip_t.u4_size = sizeof(icncl_fill_mem_rec_ip_t);
3063
3064        status = icncl_api_function(NULL, (void *)&cncl_fill_ip, (void *)&cncl_fill_op);
3065
3066        cncl_fill_ip.s_ivd_fill_mem_rec_ip_t.e_cmd = IV_CMD_RETRIEVE_MEMREC;
3067        cncl_fill_op.s_ivd_fill_mem_rec_op_t.u4_size = sizeof(icncl_fill_mem_rec_op_t);
3068
3069        status = icncl_api_function(ps_codec->ps_conceal, (void *)&cncl_fill_ip, (void *)&cncl_fill_op);
3070
3071        if(status == IV_SUCCESS)
3072        {
3073            /* Add the concealment library's memory requirements */
3074            dec_clr_op->u4_num_mem_rec_filled += cncl_fill_op.s_ivd_fill_mem_rec_op_t.u4_num_mem_rec_filled;
3075        }
3076    }
3077#endif //APPLY_CONCEALMENT
3078    DEBUG("Retrieve num mem recs: %d\n",
3079                    dec_clr_op->u4_num_mem_rec_filled);
3080    STATS_PRINT();
3081    ihevcd_jobq_free((jobq_t *)ps_codec->pv_proc_jobq);
3082
3083
3084
3085    return IV_SUCCESS;
3086
3087}
3088/**
3089*******************************************************************************
3090*
3091* @brief
3092*  Passes display buffer from application to codec
3093*
3094* @par Description:
3095*  Adds display buffer to the codec
3096*
3097* @param[in] ps_codec_obj
3098*  Pointer to codec object at API level
3099*
3100* @param[in] pv_api_ip
3101*  Pointer to input argument structure
3102*
3103* @param[out] pv_api_op
3104*  Pointer to output argument structure
3105*
3106* @returns  Status
3107*
3108* @remarks
3109*
3110*
3111*******************************************************************************
3112*/
3113WORD32 ihevcd_set_display_frame(iv_obj_t *ps_codec_obj,
3114                                void *pv_api_ip,
3115                                void *pv_api_op)
3116{
3117    WORD32 ret = IV_SUCCESS;
3118
3119    ivd_set_display_frame_ip_t *ps_dec_disp_ip;
3120    ivd_set_display_frame_op_t *ps_dec_disp_op;
3121
3122    WORD32 i;
3123
3124    codec_t *ps_codec = (codec_t *)(ps_codec_obj->pv_codec_handle);
3125
3126    ps_dec_disp_ip = (ivd_set_display_frame_ip_t *)pv_api_ip;
3127    ps_dec_disp_op = (ivd_set_display_frame_op_t *)pv_api_op;
3128
3129    ps_codec->i4_num_disp_bufs = 0;
3130    if(ps_codec->i4_share_disp_buf)
3131    {
3132        UWORD32 num_bufs = ps_dec_disp_ip->num_disp_bufs;
3133        pic_buf_t *ps_pic_buf;
3134        UWORD8 *pu1_buf;
3135        WORD32 buf_ret;
3136        WORD32 strd;
3137        strd = ps_codec->i4_strd;
3138        if(0 == strd)
3139            strd = ps_codec->i4_max_wd + PAD_WD;
3140        num_bufs = MIN(num_bufs, BUF_MGR_MAX_CNT);
3141        ps_codec->i4_num_disp_bufs = num_bufs;
3142
3143        ps_pic_buf = (pic_buf_t *)ps_codec->ps_pic_buf;
3144        for(i = 0; i < (WORD32)num_bufs; i++)
3145        {
3146            pu1_buf =  ps_dec_disp_ip->s_disp_buffer[i].pu1_bufs[0];
3147            ps_pic_buf->pu1_luma = pu1_buf + strd * PAD_TOP + PAD_LEFT;
3148
3149            pu1_buf =  ps_dec_disp_ip->s_disp_buffer[i].pu1_bufs[1];
3150            ps_pic_buf->pu1_chroma = pu1_buf + strd * (PAD_TOP / 2) + PAD_LEFT;
3151
3152            buf_ret = ihevc_buf_mgr_add((buf_mgr_t *)ps_codec->pv_pic_buf_mgr, ps_pic_buf, i);
3153
3154            if(0 != buf_ret)
3155            {
3156                ps_codec->i4_error_code = IHEVCD_BUF_MGR_ERROR;
3157                return IHEVCD_BUF_MGR_ERROR;
3158            }
3159
3160            /* Mark pic buf as needed for display */
3161            /* This ensures that till the buffer is explicitly passed to the codec,
3162             * application owns the buffer. Decoder is allowed to use a buffer only
3163             * when application sends it through fill this buffer call in OMX
3164             */
3165            ihevc_buf_mgr_set_status((buf_mgr_t *)ps_codec->pv_pic_buf_mgr, i, BUF_MGR_DISP);
3166
3167            ps_pic_buf++;
3168
3169        }
3170    }
3171
3172    ps_dec_disp_op->u4_error_code = 0;
3173    return ret;
3174
3175}
3176
3177/**
3178*******************************************************************************
3179*
3180* @brief
3181*  Sets the decoder in flush mode. Decoder will come out of  flush only
3182* after returning all the buffers or at reset
3183*
3184* @par Description:
3185*  Sets the decoder in flush mode
3186*
3187* @param[in] ps_codec_obj
3188*  Pointer to codec object at API level
3189*
3190* @param[in] pv_api_ip
3191*  Pointer to input argument structure
3192*
3193* @param[out] pv_api_op
3194*  Pointer to output argument structure
3195*
3196* @returns  Status
3197*
3198* @remarks
3199*
3200*
3201*******************************************************************************
3202*/
3203WORD32 ihevcd_set_flush_mode(iv_obj_t *ps_codec_obj,
3204                             void *pv_api_ip,
3205                             void *pv_api_op)
3206{
3207
3208    codec_t *ps_codec;
3209    ivd_ctl_flush_op_t *ps_ctl_op = (ivd_ctl_flush_op_t *)pv_api_op;
3210    UNUSED(pv_api_ip);
3211    ps_codec = (codec_t *)(ps_codec_obj->pv_codec_handle);
3212
3213    /* Signal flush frame control call */
3214    ps_codec->i4_flush_mode = 1;
3215
3216    ps_ctl_op->u4_error_code = 0;
3217
3218    /* Set pic count to zero, so that decoder starts buffering again */
3219    /* once it comes out of flush mode */
3220    ps_codec->u4_pic_cnt = 0;
3221    ps_codec->u4_disp_cnt = 0;
3222    return IV_SUCCESS;
3223
3224
3225}
3226
3227/**
3228*******************************************************************************
3229*
3230* @brief
3231*  Gets decoder status and buffer requirements
3232*
3233* @par Description:
3234*  Gets the decoder status
3235*
3236* @param[in] ps_codec_obj
3237*  Pointer to codec object at API level
3238*
3239* @param[in] pv_api_ip
3240*  Pointer to input argument structure
3241*
3242* @param[out] pv_api_op
3243*  Pointer to output argument structure
3244*
3245* @returns  Status
3246*
3247* @remarks
3248*
3249*
3250*******************************************************************************
3251*/
3252
3253WORD32 ihevcd_get_status(iv_obj_t *ps_codec_obj,
3254                         void *pv_api_ip,
3255                         void *pv_api_op)
3256{
3257
3258    WORD32 i;
3259    codec_t *ps_codec;
3260    WORD32 wd, ht;
3261    ivd_ctl_getstatus_op_t *ps_ctl_op = (ivd_ctl_getstatus_op_t *)pv_api_op;
3262
3263    UNUSED(pv_api_ip);
3264
3265    ps_ctl_op->u4_error_code = 0;
3266
3267    ps_codec = (codec_t *)(ps_codec_obj->pv_codec_handle);
3268
3269    ps_ctl_op->u4_min_num_in_bufs = MIN_IN_BUFS;
3270    if(ps_codec->e_chroma_fmt == IV_YUV_420P)
3271        ps_ctl_op->u4_min_num_out_bufs = MIN_OUT_BUFS_420;
3272    else if(ps_codec->e_chroma_fmt == IV_YUV_422ILE)
3273        ps_ctl_op->u4_min_num_out_bufs = MIN_OUT_BUFS_422ILE;
3274    else if(ps_codec->e_chroma_fmt == IV_RGB_565)
3275        ps_ctl_op->u4_min_num_out_bufs = MIN_OUT_BUFS_RGB565;
3276    else if(ps_codec->e_chroma_fmt == IV_RGBA_8888)
3277        ps_ctl_op->u4_min_num_out_bufs = MIN_OUT_BUFS_RGBA8888;
3278    else if((ps_codec->e_chroma_fmt == IV_YUV_420SP_UV)
3279                    || (ps_codec->e_chroma_fmt == IV_YUV_420SP_VU))
3280        ps_ctl_op->u4_min_num_out_bufs = MIN_OUT_BUFS_420SP;
3281
3282    ps_ctl_op->u4_num_disp_bufs = 1;
3283
3284    for(i = 0; i < (WORD32)ps_ctl_op->u4_min_num_in_bufs; i++)
3285    {
3286        ps_ctl_op->u4_min_in_buf_size[i] = MAX((ps_codec->i4_wd * ps_codec->i4_ht), MIN_BITSBUF_SIZE);
3287    }
3288
3289    wd = ps_codec->i4_wd;
3290    ht = ps_codec->i4_ht;
3291
3292    if(ps_codec->i4_sps_done)
3293    {
3294        if(0 == ps_codec->i4_share_disp_buf)
3295        {
3296            wd = ps_codec->i4_disp_wd;
3297            ht = ps_codec->i4_disp_ht;
3298
3299        }
3300        else
3301        {
3302            wd = ps_codec->i4_disp_strd;
3303            ht = ps_codec->i4_ht + PAD_HT;
3304        }
3305    }
3306    else
3307    {
3308        if(0 == ps_codec->i4_share_disp_buf)
3309        {
3310            wd = ps_codec->i4_new_max_wd;
3311            ht = ps_codec->i4_new_max_ht;
3312        }
3313        else
3314        {
3315            wd = ALIGN32(wd + PAD_WD);
3316            ht += PAD_HT;
3317        }
3318    }
3319
3320    if(ps_codec->i4_disp_strd > wd)
3321        wd = ps_codec->i4_disp_strd;
3322
3323    if(0 == ps_codec->i4_share_disp_buf)
3324        ps_ctl_op->u4_num_disp_bufs = 1;
3325    else
3326    {
3327        WORD32 pic_size;
3328        WORD32 max_dpb_size;
3329
3330        if(ps_codec->i4_sps_done)
3331        {
3332            sps_t *ps_sps = (ps_codec->s_parse.ps_sps_base + ps_codec->i4_sps_id);
3333            WORD32 reorder_pic_cnt;
3334            WORD32 ref_pic_cnt;
3335            WORD32 level;
3336
3337            reorder_pic_cnt = MIN(ps_sps->ai1_sps_max_num_reorder_pics[0], ps_codec->i4_init_num_reorder);
3338            pic_size = ps_sps->i2_pic_width_in_luma_samples * ps_sps->i2_pic_height_in_luma_samples;
3339
3340            level = ps_codec->i4_init_level;
3341            max_dpb_size = ihevcd_get_dpb_size(level, pic_size);
3342            ref_pic_cnt = max_dpb_size;
3343            ps_ctl_op->u4_num_disp_bufs = reorder_pic_cnt;
3344
3345            ps_ctl_op->u4_num_disp_bufs += ref_pic_cnt + 1;
3346
3347        }
3348        else
3349        {
3350            pic_size = ps_codec->i4_max_wd * ps_codec->i4_max_ht;
3351            max_dpb_size = ihevcd_get_dpb_size(ps_codec->i4_init_level, pic_size);
3352            ps_ctl_op->u4_num_disp_bufs = 2 * max_dpb_size;
3353
3354            ps_ctl_op->u4_num_disp_bufs = MIN(ps_ctl_op->u4_num_disp_bufs,
3355                            (UWORD32)(ps_codec->i4_init_num_ref + ps_codec->i4_init_num_reorder + 1));
3356
3357        }
3358
3359        ps_ctl_op->u4_num_disp_bufs = MIN(
3360                        ps_ctl_op->u4_num_disp_bufs, 32);
3361    }
3362
3363    /*!*/
3364    if(ps_codec->e_chroma_fmt == IV_YUV_420P)
3365    {
3366        ps_ctl_op->u4_min_out_buf_size[0] = (wd * ht);
3367        ps_ctl_op->u4_min_out_buf_size[1] = (wd * ht) >> 2;
3368        ps_ctl_op->u4_min_out_buf_size[2] = (wd * ht) >> 2;
3369    }
3370    else if(ps_codec->e_chroma_fmt == IV_YUV_422ILE)
3371    {
3372        ps_ctl_op->u4_min_out_buf_size[0] = (wd * ht) * 2;
3373        ps_ctl_op->u4_min_out_buf_size[1] =
3374                        ps_ctl_op->u4_min_out_buf_size[2] = 0;
3375    }
3376    else if(ps_codec->e_chroma_fmt == IV_RGB_565)
3377    {
3378        ps_ctl_op->u4_min_out_buf_size[0] = (wd * ht) * 2;
3379        ps_ctl_op->u4_min_out_buf_size[1] =
3380                        ps_ctl_op->u4_min_out_buf_size[2] = 0;
3381    }
3382    else if(ps_codec->e_chroma_fmt == IV_RGBA_8888)
3383    {
3384        ps_ctl_op->u4_min_out_buf_size[0] = (wd * ht) * 4;
3385        ps_ctl_op->u4_min_out_buf_size[1] =
3386                        ps_ctl_op->u4_min_out_buf_size[2] = 0;
3387    }
3388    else if((ps_codec->e_chroma_fmt == IV_YUV_420SP_UV)
3389                    || (ps_codec->e_chroma_fmt == IV_YUV_420SP_VU))
3390    {
3391        ps_ctl_op->u4_min_out_buf_size[0] = (wd * ht);
3392        ps_ctl_op->u4_min_out_buf_size[1] = (wd * ht) >> 1;
3393        ps_ctl_op->u4_min_out_buf_size[2] = 0;
3394    }
3395    ps_ctl_op->u4_pic_ht = ht;
3396    ps_ctl_op->u4_pic_wd = wd;
3397    ps_ctl_op->u4_frame_rate = 30000;
3398    ps_ctl_op->u4_bit_rate = 1000000;
3399    ps_ctl_op->e_content_type = IV_PROGRESSIVE;
3400    ps_ctl_op->e_output_chroma_format = ps_codec->e_chroma_fmt;
3401    ps_codec->i4_num_disp_bufs = ps_ctl_op->u4_num_disp_bufs;
3402
3403    if(ps_ctl_op->u4_size == sizeof(ihevcd_cxa_ctl_getstatus_op_t))
3404    {
3405        ihevcd_cxa_ctl_getstatus_op_t *ps_ext_ctl_op = (ihevcd_cxa_ctl_getstatus_op_t *)ps_ctl_op;
3406        ps_ext_ctl_op->u4_coded_pic_wd = ps_codec->i4_wd;
3407        ps_ext_ctl_op->u4_coded_pic_wd = ps_codec->i4_ht;
3408    }
3409    return IV_SUCCESS;
3410}
3411/**
3412*******************************************************************************
3413*
3414* @brief
3415*  Gets decoder buffer requirements
3416*
3417* @par Description:
3418*  Gets the decoder buffer requirements. If called before  header decoder,
3419* buffer requirements are based on max_wd  and max_ht else actual width and
3420* height will be used
3421*
3422* @param[in] ps_codec_obj
3423*  Pointer to codec object at API level
3424*
3425* @param[in] pv_api_ip
3426*  Pointer to input argument structure
3427*
3428* @param[out] pv_api_op
3429*  Pointer to output argument structure
3430*
3431* @returns  Status
3432*
3433* @remarks
3434*
3435*
3436*******************************************************************************
3437*/
3438WORD32 ihevcd_get_buf_info(iv_obj_t *ps_codec_obj,
3439                           void *pv_api_ip,
3440                           void *pv_api_op)
3441{
3442
3443    codec_t *ps_codec;
3444    UWORD32 i = 0;
3445    WORD32 wd, ht;
3446    ivd_ctl_getbufinfo_op_t *ps_ctl_op =
3447                    (ivd_ctl_getbufinfo_op_t *)pv_api_op;
3448
3449    UNUSED(pv_api_ip);
3450    ps_ctl_op->u4_error_code = 0;
3451
3452    ps_codec = (codec_t *)(ps_codec_obj->pv_codec_handle);
3453
3454    ps_ctl_op->u4_min_num_in_bufs = MIN_IN_BUFS;
3455    if(ps_codec->e_chroma_fmt == IV_YUV_420P)
3456        ps_ctl_op->u4_min_num_out_bufs = MIN_OUT_BUFS_420;
3457    else if(ps_codec->e_chroma_fmt == IV_YUV_422ILE)
3458        ps_ctl_op->u4_min_num_out_bufs = MIN_OUT_BUFS_422ILE;
3459    else if(ps_codec->e_chroma_fmt == IV_RGB_565)
3460        ps_ctl_op->u4_min_num_out_bufs = MIN_OUT_BUFS_RGB565;
3461    else if(ps_codec->e_chroma_fmt == IV_RGBA_8888)
3462        ps_ctl_op->u4_min_num_out_bufs = MIN_OUT_BUFS_RGBA8888;
3463    else if((ps_codec->e_chroma_fmt == IV_YUV_420SP_UV)
3464                    || (ps_codec->e_chroma_fmt == IV_YUV_420SP_VU))
3465        ps_ctl_op->u4_min_num_out_bufs = MIN_OUT_BUFS_420SP;
3466
3467    ps_ctl_op->u4_num_disp_bufs = 1;
3468
3469    for(i = 0; i < ps_ctl_op->u4_min_num_in_bufs; i++)
3470    {
3471        ps_ctl_op->u4_min_in_buf_size[i] = MAX((ps_codec->i4_wd * ps_codec->i4_ht), MIN_BITSBUF_SIZE);
3472    }
3473
3474    wd = ps_codec->i4_max_wd;
3475    ht = ps_codec->i4_max_ht;
3476
3477    if(ps_codec->i4_sps_done)
3478    {
3479        if(0 == ps_codec->i4_share_disp_buf)
3480        {
3481            wd = ps_codec->i4_disp_wd;
3482            ht = ps_codec->i4_disp_ht;
3483
3484        }
3485        else
3486        {
3487            wd = ps_codec->i4_disp_strd;
3488            ht = ps_codec->i4_ht + PAD_HT;
3489        }
3490    }
3491    else
3492    {
3493        if(1 == ps_codec->i4_share_disp_buf)
3494        {
3495            wd = ALIGN32(wd + PAD_WD);
3496            ht += PAD_HT;
3497        }
3498    }
3499
3500    if(ps_codec->i4_disp_strd > wd)
3501        wd = ps_codec->i4_disp_strd;
3502
3503    if(0 == ps_codec->i4_share_disp_buf)
3504        ps_ctl_op->u4_num_disp_bufs = 1;
3505    else
3506    {
3507        WORD32 pic_size;
3508        WORD32 max_dpb_size;
3509
3510        if(ps_codec->i4_sps_done)
3511        {
3512            sps_t *ps_sps = (ps_codec->s_parse.ps_sps_base + ps_codec->i4_sps_id);
3513            WORD32 reorder_pic_cnt;
3514            WORD32 ref_pic_cnt;
3515            WORD32 level;
3516
3517            reorder_pic_cnt = MIN(ps_sps->ai1_sps_max_num_reorder_pics[0], ps_codec->i4_init_num_reorder);
3518            pic_size = ps_sps->i2_pic_width_in_luma_samples * ps_sps->i2_pic_height_in_luma_samples;
3519
3520            level = ps_codec->i4_init_level;
3521            max_dpb_size = ihevcd_get_dpb_size(level, pic_size);
3522            ref_pic_cnt = max_dpb_size;
3523            ps_ctl_op->u4_num_disp_bufs = reorder_pic_cnt;
3524
3525            ps_ctl_op->u4_num_disp_bufs += ref_pic_cnt + 1;
3526
3527        }
3528        else
3529        {
3530            pic_size = ps_codec->i4_max_wd * ps_codec->i4_max_ht;
3531            max_dpb_size = ihevcd_get_dpb_size(ps_codec->i4_init_level, pic_size);
3532            ps_ctl_op->u4_num_disp_bufs = 2 * max_dpb_size;
3533
3534            ps_ctl_op->u4_num_disp_bufs = MIN(ps_ctl_op->u4_num_disp_bufs,
3535                            (UWORD32)(ps_codec->i4_init_num_ref + ps_codec->i4_init_num_reorder + 1));
3536
3537        }
3538
3539        ps_ctl_op->u4_num_disp_bufs = MIN(
3540                        ps_ctl_op->u4_num_disp_bufs, 32);
3541
3542    }
3543
3544    /*!*/
3545    if(ps_codec->e_chroma_fmt == IV_YUV_420P)
3546    {
3547        ps_ctl_op->u4_min_out_buf_size[0] = (wd * ht);
3548        ps_ctl_op->u4_min_out_buf_size[1] = (wd * ht) >> 2;
3549        ps_ctl_op->u4_min_out_buf_size[2] = (wd * ht) >> 2;
3550    }
3551    else if(ps_codec->e_chroma_fmt == IV_YUV_422ILE)
3552    {
3553        ps_ctl_op->u4_min_out_buf_size[0] = (wd * ht) * 2;
3554        ps_ctl_op->u4_min_out_buf_size[1] =
3555                        ps_ctl_op->u4_min_out_buf_size[2] = 0;
3556    }
3557    else if(ps_codec->e_chroma_fmt == IV_RGB_565)
3558    {
3559        ps_ctl_op->u4_min_out_buf_size[0] = (wd * ht) * 2;
3560        ps_ctl_op->u4_min_out_buf_size[1] =
3561                        ps_ctl_op->u4_min_out_buf_size[2] = 0;
3562    }
3563    else if(ps_codec->e_chroma_fmt == IV_RGBA_8888)
3564    {
3565        ps_ctl_op->u4_min_out_buf_size[0] = (wd * ht) * 4;
3566        ps_ctl_op->u4_min_out_buf_size[1] =
3567                        ps_ctl_op->u4_min_out_buf_size[2] = 0;
3568    }
3569    else if((ps_codec->e_chroma_fmt == IV_YUV_420SP_UV)
3570                    || (ps_codec->e_chroma_fmt == IV_YUV_420SP_VU))
3571    {
3572        ps_ctl_op->u4_min_out_buf_size[0] = (wd * ht);
3573        ps_ctl_op->u4_min_out_buf_size[1] = (wd * ht) >> 1;
3574        ps_ctl_op->u4_min_out_buf_size[2] = 0;
3575    }
3576    ps_codec->i4_num_disp_bufs = ps_ctl_op->u4_num_disp_bufs;
3577
3578    return IV_SUCCESS;
3579}
3580
3581
3582/**
3583*******************************************************************************
3584*
3585* @brief
3586*  Sets dynamic parameters
3587*
3588* @par Description:
3589*  Sets dynamic parameters. Note Frame skip, decode header  mode are dynamic
3590*  Dynamic change in stride is not  supported
3591*
3592* @param[in] ps_codec_obj
3593*  Pointer to codec object at API level
3594*
3595* @param[in] pv_api_ip
3596*  Pointer to input argument structure
3597*
3598* @param[out] pv_api_op
3599*  Pointer to output argument structure
3600*
3601* @returns  Status
3602*
3603* @remarks
3604*
3605*
3606*******************************************************************************
3607*/
3608WORD32 ihevcd_set_params(iv_obj_t *ps_codec_obj,
3609                         void *pv_api_ip,
3610                         void *pv_api_op)
3611{
3612
3613    codec_t *ps_codec;
3614    WORD32 ret = IV_SUCCESS;
3615    WORD32 strd;
3616    ivd_ctl_set_config_ip_t *s_ctl_dynparams_ip =
3617                    (ivd_ctl_set_config_ip_t *)pv_api_ip;
3618    ivd_ctl_set_config_op_t *s_ctl_dynparams_op =
3619                    (ivd_ctl_set_config_op_t *)pv_api_op;
3620
3621    ps_codec = (codec_t *)(ps_codec_obj->pv_codec_handle);
3622
3623    s_ctl_dynparams_op->u4_error_code = 0;
3624
3625    ps_codec->e_pic_skip_mode = s_ctl_dynparams_ip->e_frm_skip_mode;
3626
3627    if(s_ctl_dynparams_ip->e_frm_skip_mode != IVD_SKIP_NONE)
3628    {
3629
3630        if((s_ctl_dynparams_ip->e_frm_skip_mode != IVD_SKIP_P) &&
3631           (s_ctl_dynparams_ip->e_frm_skip_mode != IVD_SKIP_B) &&
3632           (s_ctl_dynparams_ip->e_frm_skip_mode != IVD_SKIP_PB))
3633        {
3634            s_ctl_dynparams_op->u4_error_code = (1 << IVD_UNSUPPORTEDPARAM);
3635            ret = IV_FAIL;
3636        }
3637    }
3638
3639    strd = ps_codec->i4_disp_strd;
3640    if(1 == ps_codec->i4_share_disp_buf)
3641    {
3642        strd = ps_codec->i4_strd;
3643    }
3644
3645
3646    if((-1 != (WORD32)s_ctl_dynparams_ip->u4_disp_wd) &&
3647                    (0  != s_ctl_dynparams_ip->u4_disp_wd) &&
3648                    (0  != strd) &&
3649                    ((WORD32)s_ctl_dynparams_ip->u4_disp_wd < strd))
3650    {
3651        s_ctl_dynparams_op->u4_error_code |= (1 << IVD_UNSUPPORTEDPARAM);
3652        s_ctl_dynparams_op->u4_error_code |= IHEVCD_INVALID_DISP_STRD;
3653        ret = IV_FAIL;
3654    }
3655    else
3656    {
3657        if((WORD32)s_ctl_dynparams_ip->u4_disp_wd >= ps_codec->i4_wd)
3658        {
3659            strd = s_ctl_dynparams_ip->u4_disp_wd;
3660        }
3661        else if(0 == ps_codec->i4_sps_done ||
3662                        0 == ps_codec->i4_pps_done)
3663        {
3664            strd = s_ctl_dynparams_ip->u4_disp_wd;
3665        }
3666        else if(s_ctl_dynparams_ip->u4_disp_wd == 0)
3667        {
3668            strd = ps_codec->i4_disp_strd;
3669        }
3670        else
3671        {
3672            strd = 0;
3673            s_ctl_dynparams_op->u4_error_code |= (1 << IVD_UNSUPPORTEDPARAM);
3674            s_ctl_dynparams_op->u4_error_code |= IHEVCD_INVALID_DISP_STRD;
3675            ret = IV_FAIL;
3676        }
3677    }
3678
3679    ps_codec->i4_disp_strd = strd;
3680    if(1 == ps_codec->i4_share_disp_buf)
3681    {
3682        ps_codec->i4_strd = strd;
3683    }
3684
3685    if(s_ctl_dynparams_ip->e_vid_dec_mode == IVD_DECODE_FRAME)
3686        ps_codec->i4_header_mode = 0;
3687    else if(s_ctl_dynparams_ip->e_vid_dec_mode == IVD_DECODE_HEADER)
3688        ps_codec->i4_header_mode = 1;
3689    else
3690    {
3691
3692        s_ctl_dynparams_op->u4_error_code = (1 << IVD_UNSUPPORTEDPARAM);
3693        ps_codec->i4_header_mode = 1;
3694        ret = IV_FAIL;
3695    }
3696
3697
3698    return ret;
3699
3700}
3701/**
3702*******************************************************************************
3703*
3704* @brief
3705*  Resets the decoder state
3706*
3707* @par Description:
3708*  Resets the decoder state by calling ihevcd_init()
3709*
3710* @param[in] ps_codec_obj
3711*  Pointer to codec object at API level
3712*
3713* @param[in] pv_api_ip
3714*  Pointer to input argument structure
3715*
3716* @param[out] pv_api_op
3717*  Pointer to output argument structure
3718*
3719* @returns  Status
3720*
3721* @remarks
3722*
3723*
3724*******************************************************************************
3725*/
3726WORD32 ihevcd_reset(iv_obj_t *ps_codec_obj, void *pv_api_ip, void *pv_api_op)
3727{
3728    codec_t *ps_codec;
3729    ivd_ctl_reset_op_t *s_ctl_reset_op = (ivd_ctl_reset_op_t *)pv_api_op;
3730    UNUSED(pv_api_ip);
3731    ps_codec = (codec_t *)(ps_codec_obj->pv_codec_handle);
3732
3733    if(ps_codec != NULL)
3734    {
3735        DEBUG("\nReset called \n");
3736        ihevcd_init(ps_codec);
3737    }
3738    else
3739    {
3740        DEBUG("\nReset called without Initializing the decoder\n");
3741        s_ctl_reset_op->u4_error_code = IHEVCD_INIT_NOT_DONE;
3742    }
3743
3744    return IV_SUCCESS;
3745}
3746
3747/**
3748*******************************************************************************
3749*
3750* @brief
3751*  Releases display buffer from application to codec  to signal to the codec
3752* that it can write to this buffer  if required. Till release is called,
3753* codec can not write  to this buffer
3754*
3755* @par Description:
3756*  Marks the buffer as display done
3757*
3758* @param[in] ps_codec_obj
3759*  Pointer to codec object at API level
3760*
3761* @param[in] pv_api_ip
3762*  Pointer to input argument structure
3763*
3764* @param[out] pv_api_op
3765*  Pointer to output argument structure
3766*
3767* @returns  Status
3768*
3769* @remarks
3770*
3771*
3772*******************************************************************************
3773*/
3774
3775WORD32 ihevcd_rel_display_frame(iv_obj_t *ps_codec_obj,
3776                                void *pv_api_ip,
3777                                void *pv_api_op)
3778{
3779
3780    ivd_rel_display_frame_ip_t *ps_dec_rel_disp_ip;
3781    ivd_rel_display_frame_op_t *ps_dec_rel_disp_op;
3782
3783    codec_t *ps_codec = (codec_t *)ps_codec_obj->pv_codec_handle;
3784
3785    ps_dec_rel_disp_ip = (ivd_rel_display_frame_ip_t *)pv_api_ip;
3786    ps_dec_rel_disp_op = (ivd_rel_display_frame_op_t *)pv_api_op;
3787
3788    UNUSED(ps_dec_rel_disp_op);
3789
3790    if(0 == ps_codec->i4_share_disp_buf)
3791    {
3792        return IV_SUCCESS;
3793    }
3794
3795    ihevc_buf_mgr_release((buf_mgr_t *)ps_codec->pv_pic_buf_mgr, ps_dec_rel_disp_ip->u4_disp_buf_id, BUF_MGR_DISP);
3796
3797    return IV_SUCCESS;
3798}
3799/**
3800*******************************************************************************
3801*
3802* @brief
3803*  Sets degrade params
3804*
3805* @par Description:
3806*  Sets degrade params.
3807*  Refer to ihevcd_cxa_ctl_degrade_ip_t definition for details
3808*
3809* @param[in] ps_codec_obj
3810*  Pointer to codec object at API level
3811*
3812* @param[in] pv_api_ip
3813*  Pointer to input argument structure
3814*
3815* @param[out] pv_api_op
3816*  Pointer to output argument structure
3817*
3818* @returns  Status
3819*
3820* @remarks
3821*
3822*
3823*******************************************************************************
3824*/
3825
3826WORD32 ihevcd_set_degrade(iv_obj_t *ps_codec_obj,
3827                          void *pv_api_ip,
3828                          void *pv_api_op)
3829{
3830    ihevcd_cxa_ctl_degrade_ip_t *ps_ip;
3831    ihevcd_cxa_ctl_degrade_op_t *ps_op;
3832    codec_t *ps_codec = (codec_t *)ps_codec_obj->pv_codec_handle;
3833
3834    ps_ip = (ihevcd_cxa_ctl_degrade_ip_t *)pv_api_ip;
3835    ps_op = (ihevcd_cxa_ctl_degrade_op_t *)pv_api_op;
3836
3837    ps_codec->i4_degrade_type = ps_ip->i4_degrade_type;
3838    ps_codec->i4_nondegrade_interval = ps_ip->i4_nondegrade_interval;
3839    ps_codec->i4_degrade_pics = ps_ip->i4_degrade_pics;
3840
3841    ps_op->u4_error_code = 0;
3842    ps_codec->i4_degrade_pic_cnt = 0;
3843
3844    return IV_SUCCESS;
3845}
3846
3847
3848/**
3849*******************************************************************************
3850*
3851* @brief
3852*  Gets frame dimensions/offsets
3853*
3854* @par Description:
3855*  Gets frame buffer chararacteristics such a x & y offsets  display and
3856* buffer dimensions
3857*
3858* @param[in] ps_codec_obj
3859*  Pointer to codec object at API level
3860*
3861* @param[in] pv_api_ip
3862*  Pointer to input argument structure
3863*
3864* @param[out] pv_api_op
3865*  Pointer to output argument structure
3866*
3867* @returns  Status
3868*
3869* @remarks
3870*
3871*
3872*******************************************************************************
3873*/
3874
3875WORD32 ihevcd_get_frame_dimensions(iv_obj_t *ps_codec_obj,
3876                                   void *pv_api_ip,
3877                                   void *pv_api_op)
3878{
3879    ihevcd_cxa_ctl_get_frame_dimensions_ip_t *ps_ip;
3880    ihevcd_cxa_ctl_get_frame_dimensions_op_t *ps_op;
3881    codec_t *ps_codec = (codec_t *)ps_codec_obj->pv_codec_handle;
3882    WORD32 disp_wd, disp_ht, buffer_wd, buffer_ht, x_offset, y_offset;
3883    ps_ip = (ihevcd_cxa_ctl_get_frame_dimensions_ip_t *)pv_api_ip;
3884    ps_op = (ihevcd_cxa_ctl_get_frame_dimensions_op_t *)pv_api_op;
3885    UNUSED(ps_ip);
3886    if(ps_codec->i4_sps_done)
3887    {
3888        disp_wd = ps_codec->i4_disp_wd;
3889        disp_ht = ps_codec->i4_disp_ht;
3890
3891        if(0 == ps_codec->i4_share_disp_buf)
3892        {
3893            buffer_wd = disp_wd;
3894            buffer_ht = disp_ht;
3895        }
3896        else
3897        {
3898            buffer_wd = ps_codec->i4_strd;
3899            buffer_ht = ps_codec->i4_ht + PAD_HT;
3900        }
3901    }
3902    else
3903    {
3904
3905        disp_wd = ps_codec->i4_max_wd;
3906        disp_ht = ps_codec->i4_max_ht;
3907
3908        if(0 == ps_codec->i4_share_disp_buf)
3909        {
3910            buffer_wd = disp_wd;
3911            buffer_ht = disp_ht;
3912        }
3913        else
3914        {
3915            buffer_wd = ALIGN16(disp_wd) + PAD_WD;
3916            buffer_ht = ALIGN16(disp_ht) + PAD_HT;
3917
3918        }
3919    }
3920    if(ps_codec->i4_strd > buffer_wd)
3921        buffer_wd = ps_codec->i4_strd;
3922
3923    if(0 == ps_codec->i4_share_disp_buf)
3924    {
3925        x_offset = 0;
3926        y_offset = 0;
3927    }
3928    else
3929    {
3930        y_offset = PAD_TOP;
3931        x_offset = PAD_LEFT;
3932    }
3933
3934    ps_op->u4_disp_wd[0] = disp_wd;
3935    ps_op->u4_disp_ht[0] = disp_ht;
3936    ps_op->u4_buffer_wd[0] = buffer_wd;
3937    ps_op->u4_buffer_ht[0] = buffer_ht;
3938    ps_op->u4_x_offset[0] = x_offset;
3939    ps_op->u4_y_offset[0] = y_offset;
3940
3941    ps_op->u4_disp_wd[1] = ps_op->u4_disp_wd[2] = ((ps_op->u4_disp_wd[0] + 1)
3942                    >> 1);
3943    ps_op->u4_disp_ht[1] = ps_op->u4_disp_ht[2] = ((ps_op->u4_disp_ht[0] + 1)
3944                    >> 1);
3945    ps_op->u4_buffer_wd[1] = ps_op->u4_buffer_wd[2] = (ps_op->u4_buffer_wd[0]
3946                    >> 1);
3947    ps_op->u4_buffer_ht[1] = ps_op->u4_buffer_ht[2] = (ps_op->u4_buffer_ht[0]
3948                    >> 1);
3949    ps_op->u4_x_offset[1] = ps_op->u4_x_offset[2] = (ps_op->u4_x_offset[0]
3950                    >> 1);
3951    ps_op->u4_y_offset[1] = ps_op->u4_y_offset[2] = (ps_op->u4_y_offset[0]
3952                    >> 1);
3953
3954    if((ps_codec->e_chroma_fmt == IV_YUV_420SP_UV)
3955                    || (ps_codec->e_chroma_fmt == IV_YUV_420SP_VU))
3956    {
3957        ps_op->u4_disp_wd[2] = 0;
3958        ps_op->u4_disp_ht[2] = 0;
3959        ps_op->u4_buffer_wd[2] = 0;
3960        ps_op->u4_buffer_ht[2] = 0;
3961        ps_op->u4_x_offset[2] = 0;
3962        ps_op->u4_y_offset[2] = 0;
3963
3964        ps_op->u4_disp_wd[1] <<= 1;
3965        ps_op->u4_buffer_wd[1] <<= 1;
3966        ps_op->u4_x_offset[1] <<= 1;
3967    }
3968
3969    return IV_SUCCESS;
3970
3971}
3972
3973
3974/**
3975*******************************************************************************
3976*
3977* @brief
3978*  Gets vui parameters
3979*
3980* @par Description:
3981*  Gets VUI parameters
3982*
3983* @param[in] ps_codec_obj
3984*  Pointer to codec object at API level
3985*
3986* @param[in] pv_api_ip
3987*  Pointer to input argument structure
3988*
3989* @param[out] pv_api_op
3990*  Pointer to output argument structure
3991*
3992* @returns  Status
3993*
3994* @remarks
3995*
3996*
3997*******************************************************************************
3998*/
3999WORD32 ihevcd_get_vui_params(iv_obj_t *ps_codec_obj,
4000                             void *pv_api_ip,
4001                             void *pv_api_op)
4002{
4003    ihevcd_cxa_ctl_get_vui_params_ip_t *ps_ip;
4004    ihevcd_cxa_ctl_get_vui_params_op_t *ps_op;
4005    codec_t *ps_codec = (codec_t *)ps_codec_obj->pv_codec_handle;
4006    sps_t *ps_sps;
4007    vui_t *ps_vui;
4008    WORD32 i;
4009
4010    ps_ip = (ihevcd_cxa_ctl_get_vui_params_ip_t *)pv_api_ip;
4011    ps_op = (ihevcd_cxa_ctl_get_vui_params_op_t *)pv_api_op;
4012
4013    if(0 == ps_codec->i4_sps_done)
4014    {
4015        ps_op->u4_error_code = IHEVCD_VUI_PARAMS_NOT_FOUND;
4016        return IV_FAIL;
4017    }
4018
4019    ps_sps = ps_codec->s_parse.ps_sps;
4020    if(0 == ps_sps->i1_sps_valid || 0 == ps_sps->i1_vui_parameters_present_flag)
4021    {
4022        WORD32 sps_idx = 0;
4023        ps_sps = ps_codec->ps_sps_base;
4024
4025        while((0 == ps_sps->i1_sps_valid) || (0 == ps_sps->i1_vui_parameters_present_flag))
4026        {
4027            sps_idx++;
4028            ps_sps++;
4029
4030            if(sps_idx == MAX_SPS_CNT - 1)
4031            {
4032                ps_op->u4_error_code = IHEVCD_VUI_PARAMS_NOT_FOUND;
4033                return IV_FAIL;
4034            }
4035        }
4036    }
4037
4038    ps_vui = &ps_sps->s_vui_parameters;
4039    UNUSED(ps_ip);
4040
4041    ps_op->u1_aspect_ratio_info_present_flag         =  ps_vui->u1_aspect_ratio_info_present_flag;
4042    ps_op->u1_aspect_ratio_idc                       =  ps_vui->u1_aspect_ratio_idc;
4043    ps_op->u2_sar_width                              =  ps_vui->u2_sar_width;
4044    ps_op->u2_sar_height                             =  ps_vui->u2_sar_height;
4045    ps_op->u1_overscan_info_present_flag             =  ps_vui->u1_overscan_info_present_flag;
4046    ps_op->u1_overscan_appropriate_flag              =  ps_vui->u1_overscan_appropriate_flag;
4047    ps_op->u1_video_signal_type_present_flag         =  ps_vui->u1_video_signal_type_present_flag;
4048    ps_op->u1_video_format                           =  ps_vui->u1_video_format;
4049    ps_op->u1_video_full_range_flag                  =  ps_vui->u1_video_full_range_flag;
4050    ps_op->u1_colour_description_present_flag        =  ps_vui->u1_colour_description_present_flag;
4051    ps_op->u1_colour_primaries                       =  ps_vui->u1_colour_primaries;
4052    ps_op->u1_transfer_characteristics               =  ps_vui->u1_transfer_characteristics;
4053    ps_op->u1_matrix_coefficients                    =  ps_vui->u1_matrix_coefficients;
4054    ps_op->u1_chroma_loc_info_present_flag           =  ps_vui->u1_chroma_loc_info_present_flag;
4055    ps_op->u1_chroma_sample_loc_type_top_field       =  ps_vui->u1_chroma_sample_loc_type_top_field;
4056    ps_op->u1_chroma_sample_loc_type_bottom_field    =  ps_vui->u1_chroma_sample_loc_type_bottom_field;
4057    ps_op->u1_neutral_chroma_indication_flag         =  ps_vui->u1_neutral_chroma_indication_flag;
4058    ps_op->u1_field_seq_flag                         =  ps_vui->u1_field_seq_flag;
4059    ps_op->u1_frame_field_info_present_flag          =  ps_vui->u1_frame_field_info_present_flag;
4060    ps_op->u1_default_display_window_flag            =  ps_vui->u1_default_display_window_flag;
4061    ps_op->u4_def_disp_win_left_offset               =  ps_vui->u4_def_disp_win_left_offset;
4062    ps_op->u4_def_disp_win_right_offset              =  ps_vui->u4_def_disp_win_right_offset;
4063    ps_op->u4_def_disp_win_top_offset                =  ps_vui->u4_def_disp_win_top_offset;
4064    ps_op->u4_def_disp_win_bottom_offset             =  ps_vui->u4_def_disp_win_bottom_offset;
4065    ps_op->u1_vui_hrd_parameters_present_flag        =  ps_vui->u1_vui_hrd_parameters_present_flag;
4066    ps_op->u1_vui_timing_info_present_flag           =  ps_vui->u1_vui_timing_info_present_flag;
4067    ps_op->u4_vui_num_units_in_tick                  =  ps_vui->u4_vui_num_units_in_tick;
4068    ps_op->u4_vui_time_scale                         =  ps_vui->u4_vui_time_scale;
4069    ps_op->u1_poc_proportional_to_timing_flag        =  ps_vui->u1_poc_proportional_to_timing_flag;
4070    ps_op->u1_num_ticks_poc_diff_one_minus1          =  ps_vui->u1_num_ticks_poc_diff_one_minus1;
4071    ps_op->u1_bitstream_restriction_flag             =  ps_vui->u1_bitstream_restriction_flag;
4072    ps_op->u1_tiles_fixed_structure_flag             =  ps_vui->u1_tiles_fixed_structure_flag;
4073    ps_op->u1_motion_vectors_over_pic_boundaries_flag =  ps_vui->u1_motion_vectors_over_pic_boundaries_flag;
4074    ps_op->u1_restricted_ref_pic_lists_flag          =  ps_vui->u1_restricted_ref_pic_lists_flag;
4075    ps_op->u4_min_spatial_segmentation_idc           =  ps_vui->u4_min_spatial_segmentation_idc;
4076    ps_op->u1_max_bytes_per_pic_denom                =  ps_vui->u1_max_bytes_per_pic_denom;
4077    ps_op->u1_max_bits_per_mincu_denom               =  ps_vui->u1_max_bits_per_mincu_denom;
4078    ps_op->u1_log2_max_mv_length_horizontal          =  ps_vui->u1_log2_max_mv_length_horizontal;
4079    ps_op->u1_log2_max_mv_length_vertical            =  ps_vui->u1_log2_max_mv_length_vertical;
4080
4081
4082    /* HRD parameters */
4083    ps_op->u1_timing_info_present_flag                         =    ps_vui->s_vui_hrd_parameters.u1_timing_info_present_flag;
4084    ps_op->u4_num_units_in_tick                                =    ps_vui->s_vui_hrd_parameters.u4_num_units_in_tick;
4085    ps_op->u4_time_scale                                       =    ps_vui->s_vui_hrd_parameters.u4_time_scale;
4086    ps_op->u1_nal_hrd_parameters_present_flag                  =    ps_vui->s_vui_hrd_parameters.u1_nal_hrd_parameters_present_flag;
4087    ps_op->u1_vcl_hrd_parameters_present_flag                  =    ps_vui->s_vui_hrd_parameters.u1_vcl_hrd_parameters_present_flag;
4088    ps_op->u1_cpbdpb_delays_present_flag                       =    ps_vui->s_vui_hrd_parameters.u1_cpbdpb_delays_present_flag;
4089    ps_op->u1_sub_pic_cpb_params_present_flag                  =    ps_vui->s_vui_hrd_parameters.u1_sub_pic_cpb_params_present_flag;
4090    ps_op->u1_tick_divisor_minus2                              =    ps_vui->s_vui_hrd_parameters.u1_tick_divisor_minus2;
4091    ps_op->u1_du_cpb_removal_delay_increment_length_minus1     =    ps_vui->s_vui_hrd_parameters.u1_du_cpb_removal_delay_increment_length_minus1;
4092    ps_op->u1_sub_pic_cpb_params_in_pic_timing_sei_flag        =    ps_vui->s_vui_hrd_parameters.u1_sub_pic_cpb_params_in_pic_timing_sei_flag;
4093    ps_op->u1_dpb_output_delay_du_length_minus1                =    ps_vui->s_vui_hrd_parameters.u1_dpb_output_delay_du_length_minus1;
4094    ps_op->u4_bit_rate_scale                                   =    ps_vui->s_vui_hrd_parameters.u4_bit_rate_scale;
4095    ps_op->u4_cpb_size_scale                                   =    ps_vui->s_vui_hrd_parameters.u4_cpb_size_scale;
4096    ps_op->u4_cpb_size_du_scale                                =    ps_vui->s_vui_hrd_parameters.u4_cpb_size_du_scale;
4097    ps_op->u1_initial_cpb_removal_delay_length_minus1          =    ps_vui->s_vui_hrd_parameters.u1_initial_cpb_removal_delay_length_minus1;
4098    ps_op->u1_au_cpb_removal_delay_length_minus1               =    ps_vui->s_vui_hrd_parameters.u1_au_cpb_removal_delay_length_minus1;
4099    ps_op->u1_dpb_output_delay_length_minus1                   =    ps_vui->s_vui_hrd_parameters.u1_dpb_output_delay_length_minus1;
4100
4101    for(i = 0; i < 6; i++)
4102    {
4103        ps_op->au1_fixed_pic_rate_general_flag[i]                  =    ps_vui->s_vui_hrd_parameters.au1_fixed_pic_rate_general_flag[i];
4104        ps_op->au1_fixed_pic_rate_within_cvs_flag[i]               =    ps_vui->s_vui_hrd_parameters.au1_fixed_pic_rate_within_cvs_flag[i];
4105        ps_op->au1_elemental_duration_in_tc_minus1[i]              =    ps_vui->s_vui_hrd_parameters.au1_elemental_duration_in_tc_minus1[i];
4106        ps_op->au1_low_delay_hrd_flag[i]                           =    ps_vui->s_vui_hrd_parameters.au1_low_delay_hrd_flag[i];
4107        ps_op->au1_cpb_cnt_minus1[i]                               =    ps_vui->s_vui_hrd_parameters.au1_cpb_cnt_minus1[i];
4108    }
4109
4110
4111    return IV_SUCCESS;
4112}
4113
4114/**
4115*******************************************************************************
4116*
4117* @brief
4118*  Sets Processor type
4119*
4120* @par Description:
4121*  Sets Processor type
4122*
4123* @param[in] ps_codec_obj
4124*  Pointer to codec object at API level
4125*
4126* @param[in] pv_api_ip
4127*  Pointer to input argument structure
4128*
4129* @param[out] pv_api_op
4130*  Pointer to output argument structure
4131*
4132* @returns  Status
4133*
4134* @remarks
4135*
4136*
4137*******************************************************************************
4138*/
4139
4140WORD32 ihevcd_set_processor(iv_obj_t *ps_codec_obj,
4141                            void *pv_api_ip,
4142                            void *pv_api_op)
4143{
4144    ihevcd_cxa_ctl_set_processor_ip_t *ps_ip;
4145    ihevcd_cxa_ctl_set_processor_op_t *ps_op;
4146    codec_t *ps_codec = (codec_t *)ps_codec_obj->pv_codec_handle;
4147
4148    ps_ip = (ihevcd_cxa_ctl_set_processor_ip_t *)pv_api_ip;
4149    ps_op = (ihevcd_cxa_ctl_set_processor_op_t *)pv_api_op;
4150
4151    ps_codec->e_processor_arch = (IVD_ARCH_T)ps_ip->u4_arch;
4152    ps_codec->e_processor_soc = (IVD_SOC_T)ps_ip->u4_soc;
4153
4154    ihevcd_init_function_ptr(ps_codec);
4155
4156    ihevcd_update_function_ptr(ps_codec);
4157
4158    if(ps_codec->e_processor_soc && (ps_codec->e_processor_soc <= SOC_HISI_37X))
4159    {
4160        /* 8th bit indicates if format conversion is to be done ahead */
4161        if(ps_codec->e_processor_soc & 0x80)
4162            ps_codec->u4_enable_fmt_conv_ahead = 1;
4163
4164        /* Lower 7 bit indicate NCTB - if non-zero */
4165        ps_codec->e_processor_soc &= 0x7F;
4166
4167        if(ps_codec->e_processor_soc)
4168            ps_codec->u4_nctb = ps_codec->e_processor_soc;
4169
4170
4171    }
4172
4173    if((ps_codec->e_processor_soc == SOC_HISI_37X) && (ps_codec->i4_num_cores == 2))
4174    {
4175        ps_codec->u4_nctb = 2;
4176    }
4177
4178
4179    ps_op->u4_error_code = 0;
4180    return IV_SUCCESS;
4181}
4182
4183/**
4184*******************************************************************************
4185*
4186* @brief
4187*  Sets Number of cores that can be used in the codec. Codec uses these many
4188* threads for decoding
4189*
4190* @par Description:
4191*  Sets number of cores
4192*
4193* @param[in] ps_codec_obj
4194*  Pointer to codec object at API level
4195*
4196* @param[in] pv_api_ip
4197*  Pointer to input argument structure
4198*
4199* @param[out] pv_api_op
4200*  Pointer to output argument structure
4201*
4202* @returns  Status
4203*
4204* @remarks
4205*
4206*
4207*******************************************************************************
4208*/
4209
4210WORD32 ihevcd_set_num_cores(iv_obj_t *ps_codec_obj,
4211                            void *pv_api_ip,
4212                            void *pv_api_op)
4213{
4214    ihevcd_cxa_ctl_set_num_cores_ip_t *ps_ip;
4215    ihevcd_cxa_ctl_set_num_cores_op_t *ps_op;
4216    codec_t *ps_codec = (codec_t *)ps_codec_obj->pv_codec_handle;
4217
4218    ps_ip = (ihevcd_cxa_ctl_set_num_cores_ip_t *)pv_api_ip;
4219    ps_op = (ihevcd_cxa_ctl_set_num_cores_op_t *)pv_api_op;
4220
4221#ifdef MULTICORE
4222    ps_codec->i4_num_cores = ps_ip->u4_num_cores;
4223#else
4224    ps_codec->i4_num_cores = 1;
4225#endif
4226    ps_op->u4_error_code = 0;
4227    return IV_SUCCESS;
4228}
4229/**
4230*******************************************************************************
4231*
4232* @brief
4233*  Codec control call
4234*
4235* @par Description:
4236*  Codec control call which in turn calls appropriate calls  based on
4237* subcommand
4238*
4239* @param[in] ps_codec_obj
4240*  Pointer to codec object at API level
4241*
4242* @param[in] pv_api_ip
4243*  Pointer to input argument structure
4244*
4245* @param[out] pv_api_op
4246*  Pointer to output argument structure
4247*
4248* @returns  Status
4249*
4250* @remarks
4251*
4252*
4253*******************************************************************************
4254*/
4255
4256WORD32 ihevcd_ctl(iv_obj_t *ps_codec_obj, void *pv_api_ip, void *pv_api_op)
4257{
4258    ivd_ctl_set_config_ip_t *ps_ctl_ip;
4259    ivd_ctl_set_config_op_t *ps_ctl_op;
4260    WORD32 ret = 0;
4261    WORD32 subcommand;
4262    codec_t *ps_codec = (codec_t *)ps_codec_obj->pv_codec_handle;
4263
4264    ps_ctl_ip = (ivd_ctl_set_config_ip_t *)pv_api_ip;
4265    ps_ctl_op = (ivd_ctl_set_config_op_t *)pv_api_op;
4266
4267    if(ps_codec->i4_init_done != 1)
4268    {
4269        ps_ctl_op->u4_error_code |= 1 << IVD_FATALERROR;
4270        ps_ctl_op->u4_error_code |= IHEVCD_INIT_NOT_DONE;
4271        return IV_FAIL;
4272    }
4273    subcommand = ps_ctl_ip->e_sub_cmd;
4274
4275    switch(subcommand)
4276    {
4277        case IVD_CMD_CTL_GETPARAMS:
4278            ret = ihevcd_get_status(ps_codec_obj, (void *)pv_api_ip,
4279                                    (void *)pv_api_op);
4280            break;
4281        case IVD_CMD_CTL_SETPARAMS:
4282            ret = ihevcd_set_params(ps_codec_obj, (void *)pv_api_ip,
4283                                    (void *)pv_api_op);
4284            break;
4285        case IVD_CMD_CTL_RESET:
4286            ret = ihevcd_reset(ps_codec_obj, (void *)pv_api_ip,
4287                               (void *)pv_api_op);
4288            break;
4289        case IVD_CMD_CTL_SETDEFAULT:
4290        {
4291            ivd_ctl_set_config_op_t *s_ctl_dynparams_op =
4292                            (ivd_ctl_set_config_op_t *)pv_api_op;
4293
4294            ret = ihevcd_set_default_params(ps_codec);
4295            if(IV_SUCCESS == ret)
4296                s_ctl_dynparams_op->u4_error_code = 0;
4297            break;
4298        }
4299        case IVD_CMD_CTL_FLUSH:
4300            ret = ihevcd_set_flush_mode(ps_codec_obj, (void *)pv_api_ip,
4301                                        (void *)pv_api_op);
4302            break;
4303        case IVD_CMD_CTL_GETBUFINFO:
4304            ret = ihevcd_get_buf_info(ps_codec_obj, (void *)pv_api_ip,
4305                                      (void *)pv_api_op);
4306            break;
4307        case IVD_CMD_CTL_GETVERSION:
4308        {
4309            ivd_ctl_getversioninfo_ip_t *ps_ip;
4310            ivd_ctl_getversioninfo_op_t *ps_op;
4311            IV_API_CALL_STATUS_T ret;
4312            ps_ip = (ivd_ctl_getversioninfo_ip_t *)pv_api_ip;
4313            ps_op = (ivd_ctl_getversioninfo_op_t *)pv_api_op;
4314
4315            ps_op->u4_error_code = IV_SUCCESS;
4316
4317            if((WORD32)ps_ip->u4_version_buffer_size <= 0)
4318            {
4319                ps_op->u4_error_code = IHEVCD_CXA_VERS_BUF_INSUFFICIENT;
4320                ret = IV_FAIL;
4321            }
4322            else
4323            {
4324                ret = ihevcd_get_version((CHAR *)ps_ip->pv_version_buffer,
4325                                         ps_ip->u4_version_buffer_size);
4326                if(ret != IV_SUCCESS)
4327                {
4328                    ps_op->u4_error_code = IHEVCD_CXA_VERS_BUF_INSUFFICIENT;
4329                    ret = IV_FAIL;
4330                }
4331            }
4332        }
4333            break;
4334        case IHEVCD_CXA_CMD_CTL_DEGRADE:
4335            ret = ihevcd_set_degrade(ps_codec_obj, (void *)pv_api_ip,
4336                            (void *)pv_api_op);
4337            break;
4338        case IHEVCD_CXA_CMD_CTL_SET_NUM_CORES:
4339            ret = ihevcd_set_num_cores(ps_codec_obj, (void *)pv_api_ip,
4340                                       (void *)pv_api_op);
4341            break;
4342        case IHEVCD_CXA_CMD_CTL_GET_BUFFER_DIMENSIONS:
4343            ret = ihevcd_get_frame_dimensions(ps_codec_obj, (void *)pv_api_ip,
4344                                              (void *)pv_api_op);
4345            break;
4346        case IHEVCD_CXA_CMD_CTL_GET_VUI_PARAMS:
4347            ret = ihevcd_get_vui_params(ps_codec_obj, (void *)pv_api_ip,
4348                                        (void *)pv_api_op);
4349            break;
4350        case IHEVCD_CXA_CMD_CTL_SET_PROCESSOR:
4351            ret = ihevcd_set_processor(ps_codec_obj, (void *)pv_api_ip,
4352                            (void *)pv_api_op);
4353            break;
4354        default:
4355            DEBUG("\nDo nothing\n");
4356            break;
4357    }
4358
4359    return ret;
4360}
4361
4362/**
4363*******************************************************************************
4364*
4365* @brief
4366*  Codecs entry point function. All the function calls to  the codec are
4367* done using this function with different  values specified in command
4368*
4369* @par Description:
4370*  Arguments are tested for validity and then based on the  command
4371* appropriate function is called
4372*
4373* @param[in] ps_handle
4374*  API level handle for codec
4375*
4376* @param[in] pv_api_ip
4377*  Input argument structure
4378*
4379* @param[out] pv_api_op
4380*  Output argument structure
4381*
4382* @returns  Status of the function corresponding to command
4383*
4384* @remarks
4385*
4386*
4387*******************************************************************************
4388*/
4389IV_API_CALL_STATUS_T ihevcd_cxa_api_function(iv_obj_t *ps_handle,
4390                                             void *pv_api_ip,
4391                                             void *pv_api_op)
4392{
4393    WORD32 command;
4394    UWORD32 *pu4_ptr_cmd;
4395    WORD32 ret = 0;
4396    IV_API_CALL_STATUS_T e_status;
4397    e_status = api_check_struct_sanity(ps_handle, pv_api_ip, pv_api_op);
4398
4399    if(e_status != IV_SUCCESS)
4400    {
4401        DEBUG("error code = %d\n", *((UWORD32 *)pv_api_op + 1));
4402        return IV_FAIL;
4403    }
4404
4405    pu4_ptr_cmd = (UWORD32 *)pv_api_ip;
4406    pu4_ptr_cmd++;
4407
4408    command = *pu4_ptr_cmd;
4409
4410    switch(command)
4411    {
4412        case IV_CMD_GET_NUM_MEM_REC:
4413            ret = ihevcd_get_num_rec((void *)pv_api_ip, (void *)pv_api_op);
4414
4415            break;
4416        case IV_CMD_FILL_NUM_MEM_REC:
4417
4418            ret = ihevcd_fill_num_mem_rec((void *)pv_api_ip, (void *)pv_api_op);
4419            break;
4420        case IV_CMD_INIT:
4421            ret = ihevcd_init_mem_rec(ps_handle, (void *)pv_api_ip,
4422                                      (void *)pv_api_op);
4423            break;
4424
4425        case IVD_CMD_VIDEO_DECODE:
4426            ret = ihevcd_decode(ps_handle, (void *)pv_api_ip, (void *)pv_api_op);
4427            break;
4428
4429        case IVD_CMD_GET_DISPLAY_FRAME:
4430            //ret = ihevcd_get_display_frame(ps_handle,(void *)pv_api_ip,(void *)pv_api_op);
4431            break;
4432
4433        case IVD_CMD_SET_DISPLAY_FRAME:
4434            ret = ihevcd_set_display_frame(ps_handle, (void *)pv_api_ip,
4435                                           (void *)pv_api_op);
4436
4437            break;
4438
4439        case IVD_CMD_REL_DISPLAY_FRAME:
4440            ret = ihevcd_rel_display_frame(ps_handle, (void *)pv_api_ip,
4441                                           (void *)pv_api_op);
4442            break;
4443
4444        case IV_CMD_RETRIEVE_MEMREC:
4445            ret = ihevcd_retrieve_memrec(ps_handle, (void *)pv_api_ip,
4446                                         (void *)pv_api_op);
4447            break;
4448
4449        case IVD_CMD_VIDEO_CTL:
4450            ret = ihevcd_ctl(ps_handle, (void *)pv_api_ip, (void *)pv_api_op);
4451            break;
4452        default:
4453            ret = IV_FAIL;
4454            break;
4455    }
4456
4457    return (IV_API_CALL_STATUS_T)ret;
4458}
4459
4460