• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 /*****************************************************************************/
98 IV_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 
api_check_struct_sanity(iv_obj_t * ps_handle,void * pv_api_ip,void * pv_api_op)129 static 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 */
ihevcd_set_default_params(codec_t * ps_codec)1379 WORD32 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 
ihevcd_update_function_ptr(codec_t * ps_codec)1392 void 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 */
ihevcd_init(codec_t * ps_codec)1499 WORD32 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 */
ihevcd_get_num_rec(void * pv_api_ip,void * pv_api_op)1642 WORD32 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 */
ihevcd_fill_num_mem_rec(void * pv_api_ip,void * pv_api_op)1710 WORD32 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 */
ihevcd_init_mem_rec(iv_obj_t * ps_codec_obj,void * pv_api_ip,void * pv_api_op)2440 WORD32 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 */
ihevcd_retrieve_memrec(iv_obj_t * ps_codec_obj,void * pv_api_ip,void * pv_api_op)3024 WORD32 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 */
ihevcd_set_display_frame(iv_obj_t * ps_codec_obj,void * pv_api_ip,void * pv_api_op)3113 WORD32 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 */
ihevcd_set_flush_mode(iv_obj_t * ps_codec_obj,void * pv_api_ip,void * pv_api_op)3203 WORD32 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 
ihevcd_get_status(iv_obj_t * ps_codec_obj,void * pv_api_ip,void * pv_api_op)3253 WORD32 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 */
ihevcd_get_buf_info(iv_obj_t * ps_codec_obj,void * pv_api_ip,void * pv_api_op)3438 WORD32 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 */
ihevcd_set_params(iv_obj_t * ps_codec_obj,void * pv_api_ip,void * pv_api_op)3608 WORD32 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 */
ihevcd_reset(iv_obj_t * ps_codec_obj,void * pv_api_ip,void * pv_api_op)3726 WORD32 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 
ihevcd_rel_display_frame(iv_obj_t * ps_codec_obj,void * pv_api_ip,void * pv_api_op)3775 WORD32 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 
ihevcd_set_degrade(iv_obj_t * ps_codec_obj,void * pv_api_ip,void * pv_api_op)3826 WORD32 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 
ihevcd_get_frame_dimensions(iv_obj_t * ps_codec_obj,void * pv_api_ip,void * pv_api_op)3875 WORD32 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 */
ihevcd_get_vui_params(iv_obj_t * ps_codec_obj,void * pv_api_ip,void * pv_api_op)3999 WORD32 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 
ihevcd_set_processor(iv_obj_t * ps_codec_obj,void * pv_api_ip,void * pv_api_op)4140 WORD32 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 
ihevcd_set_num_cores(iv_obj_t * ps_codec_obj,void * pv_api_ip,void * pv_api_op)4210 WORD32 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 
ihevcd_ctl(iv_obj_t * ps_codec_obj,void * pv_api_ip,void * pv_api_op)4256 WORD32 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 */
ihevcd_cxa_api_function(iv_obj_t * ps_handle,void * pv_api_ip,void * pv_api_op)4389 IV_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