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     ps_codec->i4_cra_as_first_pic = 1;
1527     ps_codec->i4_rasl_output_flag = 0;
1528 
1529     ps_codec->i4_prev_poc_msb = 0;
1530     ps_codec->i4_prev_poc_lsb = -1;
1531     ps_codec->i4_max_prev_poc_lsb = -1;
1532     ps_codec->s_parse.i4_abs_pic_order_cnt = -1;
1533 
1534     /* Set ref chroma format by default to 420SP UV interleaved */
1535     ps_codec->e_ref_chroma_fmt = IV_YUV_420SP_UV;
1536 
1537     /* If the codec is in shared mode and required format is 420 SP VU interleaved then change
1538      * reference buffers chroma format
1539      */
1540     if(IV_YUV_420SP_VU == ps_codec->e_chroma_fmt)
1541     {
1542         ps_codec->e_ref_chroma_fmt = IV_YUV_420SP_VU;
1543     }
1544 
1545 
1546 
1547     ps_codec->i4_disable_deblk_pic = 0;
1548 
1549     ps_codec->i4_degrade_pic_cnt    = 0;
1550     ps_codec->i4_degrade_pics       = 0;
1551     ps_codec->i4_degrade_type       = 0;
1552     ps_codec->i4_disable_sao_pic    = 0;
1553     ps_codec->i4_fullpel_inter_pred = 0;
1554     ps_codec->u4_enable_fmt_conv_ahead = 0;
1555     ps_codec->i4_share_disp_buf_cnt = 0;
1556 
1557     {
1558         sps_t *ps_sps = ps_codec->ps_sps_base;
1559         pps_t *ps_pps = ps_codec->ps_pps_base;
1560 
1561         for(i = 0; i < MAX_SPS_CNT; i++)
1562         {
1563             ps_sps->i1_sps_valid = 0;
1564             ps_sps++;
1565         }
1566 
1567         for(i = 0; i < MAX_PPS_CNT; i++)
1568         {
1569             ps_pps->i1_pps_valid = 0;
1570             ps_pps++;
1571         }
1572     }
1573 
1574     ihevcd_set_default_params(ps_codec);
1575     ps_codec->pv_proc_jobq = ihevcd_jobq_init(ps_codec->pv_proc_jobq_buf, ps_codec->i4_proc_jobq_buf_size);
1576     RETURN_IF((ps_codec->pv_proc_jobq == NULL), IV_FAIL);
1577 
1578     /* Update the jobq context to all the threads */
1579     ps_codec->s_parse.pv_proc_jobq = ps_codec->pv_proc_jobq;
1580     for(i = 0; i < MAX_PROCESS_THREADS; i++)
1581     {
1582         ps_codec->as_process[i].pv_proc_jobq = ps_codec->pv_proc_jobq;
1583         ps_codec->as_process[i].i4_id = i;
1584         ps_codec->as_process[i].ps_codec = ps_codec;
1585 
1586         /* Set the following to zero assuming it is a single core solution
1587          * When threads are launched these will be set appropriately
1588          */
1589         ps_codec->as_process[i].i4_check_parse_status = 0;
1590         ps_codec->as_process[i].i4_check_proc_status = 0;
1591     }
1592     /* Initialize MV Bank buffer manager */
1593     ihevc_buf_mgr_init((buf_mgr_t *)ps_codec->pv_mv_buf_mgr);
1594 
1595     /* Initialize Picture buffer manager */
1596     ihevc_buf_mgr_init((buf_mgr_t *)ps_codec->pv_pic_buf_mgr);
1597 
1598     ps_codec->ps_pic_buf = (pic_buf_t *)ps_codec->pv_pic_buf_base;
1599 
1600     memset(ps_codec->ps_pic_buf, 0, BUF_MGR_MAX_CNT  * sizeof(pic_buf_t));
1601 
1602 
1603 
1604     /* Initialize display buffer manager */
1605     ihevc_disp_mgr_init((disp_mgr_t *)ps_codec->pv_disp_buf_mgr);
1606 
1607     /* Initialize dpb manager */
1608     ihevc_dpb_mgr_init((dpb_mgr_t *)ps_codec->pv_dpb_mgr);
1609 
1610     ps_codec->e_processor_soc = SOC_GENERIC;
1611     /* The following can be over-ridden using soc parameter as a hack */
1612     ps_codec->u4_nctb = 0x7FFFFFFF;
1613     ihevcd_init_arch(ps_codec);
1614 
1615     ihevcd_init_function_ptr(ps_codec);
1616 
1617     ihevcd_update_function_ptr(ps_codec);
1618 
1619     return status;
1620 }
1621 
1622 /**
1623 *******************************************************************************
1624 *
1625 * @brief
1626 *  Gets number of memory records required by the codec
1627 *
1628 * @par Description:
1629 *  Gets codec mem record requirements and adds concealment  modules
1630 * requirements
1631 *
1632 * @param[in] pv_api_ip
1633 *  Pointer to input argument structure
1634 *
1635 * @param[out] pv_api_op
1636 *  Pointer to output argument structure
1637 *
1638 * @returns  Status
1639 *
1640 * @remarks
1641 *
1642 *
1643 *******************************************************************************
1644 */
ihevcd_get_num_rec(void * pv_api_ip,void * pv_api_op)1645 WORD32 ihevcd_get_num_rec(void *pv_api_ip, void *pv_api_op)
1646 {
1647 
1648     iv_num_mem_rec_op_t *ps_mem_q_op;
1649 
1650     UNUSED(pv_api_ip);
1651     ps_mem_q_op = (iv_num_mem_rec_op_t *)pv_api_op;
1652     ps_mem_q_op->u4_num_mem_rec = MEM_REC_CNT;
1653     DEBUG("Get num mem records without concealment %d\n",
1654                     ps_mem_q_op->u4_num_mem_rec);
1655 #ifdef APPLY_CONCEALMENT
1656     {
1657         IV_API_CALL_STATUS_T status;
1658         icncl_num_mem_rec_ip_t cncl_mem_ip;
1659         icncl_num_mem_rec_op_t cncl_mem_op;
1660 
1661         cncl_mem_ip.s_ivd_num_rec_ip_t.e_cmd = IV_CMD_GET_NUM_MEM_REC;
1662         cncl_mem_ip.s_ivd_num_rec_ip_t.u4_size = sizeof(icncl_num_mem_rec_ip_t);
1663 
1664         status = icncl_api_function(NULL, (void *)&cncl_mem_ip, (void *)&cncl_mem_op);
1665 
1666         if(status == IV_SUCCESS)
1667         {
1668             /* Add the concealment library's memory requirements */
1669             ps_mem_q_op->u4_num_mem_rec += cncl_mem_op.s_ivd_num_mem_rec_op_t.u4_num_mem_rec;
1670             DEBUG("Get num mem records %d\n", ps_mem_q_op->u4_num_mem_rec);
1671             return status; /* Nothing else to do, return */
1672         }
1673         else
1674         {
1675             /*
1676              * Something went wrong with the concealment library call.
1677              */
1678             DEBUG("ERROR: Get num mem records %d\n", ps_mem_q_op->u4_num_mem_rec);
1679             return status;
1680         }
1681 
1682     }
1683 #endif //APPLY_CONCEALMENT
1684 
1685 
1686     return IV_SUCCESS;
1687 
1688 }
1689 
1690 /**
1691 *******************************************************************************
1692 *
1693 * @brief
1694 *  Fills memory requirements of the codec
1695 *
1696 * @par Description:
1697 *  Gets codec mem record requirements and adds concealment  modules
1698 * requirements
1699 *
1700 * @param[in] pv_api_ip
1701 *  Pointer to input argument structure
1702 *
1703 * @param[out] pv_api_op
1704 *  Pointer to output argument structure
1705 *
1706 * @returns  Status
1707 *
1708 * @remarks
1709 *
1710 *
1711 *******************************************************************************
1712 */
ihevcd_fill_num_mem_rec(void * pv_api_ip,void * pv_api_op)1713 WORD32 ihevcd_fill_num_mem_rec(void *pv_api_ip, void *pv_api_op)
1714 {
1715 
1716     ihevcd_cxa_fill_mem_rec_ip_t *ps_mem_q_ip;
1717     ihevcd_cxa_fill_mem_rec_op_t *ps_mem_q_op;
1718     WORD32 level;
1719     WORD32 num_reorder_frames;
1720     WORD32 num_ref_frames;
1721     WORD32 num_extra_disp_bufs;
1722     WORD32 max_dpb_size;
1723 
1724     iv_mem_rec_t *ps_mem_rec;
1725     iv_mem_rec_t *ps_mem_rec_base;
1726     WORD32 no_of_mem_rec_filled;
1727     WORD32 chroma_format, share_disp_buf;
1728     WORD32 max_ctb_cnt;
1729     WORD32 max_wd_luma, max_wd_chroma;
1730     WORD32 max_ht_luma, max_ht_chroma;
1731     WORD32 max_tile_cols, max_tile_rows;
1732     WORD32 max_ctb_rows, max_ctb_cols;
1733     WORD32 max_num_cu_cols;
1734     WORD32 i;
1735     WORD32 max_num_4x4_cols;
1736     IV_API_CALL_STATUS_T status = IV_SUCCESS;
1737     no_of_mem_rec_filled = 0;
1738 
1739     //TODO: Remove as and when the following are used
1740     UNUSED(num_extra_disp_bufs);
1741     UNUSED(no_of_mem_rec_filled);
1742     UNUSED(max_wd_chroma);
1743     UNUSED(max_ht_chroma);
1744 
1745     ps_mem_q_ip = (ihevcd_cxa_fill_mem_rec_ip_t *)pv_api_ip;
1746     ps_mem_q_op = (ihevcd_cxa_fill_mem_rec_op_t *)pv_api_op;
1747 
1748     if(ps_mem_q_ip->s_ivd_fill_mem_rec_ip_t.u4_size
1749                     > offsetof(ihevcd_cxa_fill_mem_rec_ip_t, i4_level))
1750     {
1751         level = ps_mem_q_ip->i4_level;
1752         /* Spec requires level should be multiplied by 30
1753          * API has values where level is multiplied by 10. This keeps it consistent with H264
1754          * Because of the above differences, level is multiplied by 3 here.
1755          */
1756         level *= 3;
1757     }
1758     else
1759     {
1760         level = MAX_LEVEL;
1761     }
1762 
1763     if(ps_mem_q_ip->s_ivd_fill_mem_rec_ip_t.u4_size
1764                     > offsetof(ihevcd_cxa_fill_mem_rec_ip_t,
1765                                u4_num_reorder_frames))
1766     {
1767         num_reorder_frames = ps_mem_q_ip->u4_num_reorder_frames;
1768     }
1769     else
1770     {
1771         num_reorder_frames = MAX_REF_CNT;
1772     }
1773 
1774     if(ps_mem_q_ip->s_ivd_fill_mem_rec_ip_t.u4_size
1775                     > offsetof(ihevcd_cxa_fill_mem_rec_ip_t, u4_num_ref_frames))
1776     {
1777         num_ref_frames = ps_mem_q_ip->u4_num_ref_frames;
1778     }
1779     else
1780     {
1781         num_ref_frames = MAX_REF_CNT;
1782     }
1783 
1784     if(ps_mem_q_ip->s_ivd_fill_mem_rec_ip_t.u4_size
1785                     > offsetof(ihevcd_cxa_fill_mem_rec_ip_t,
1786                                u4_num_extra_disp_buf))
1787     {
1788         num_extra_disp_bufs = ps_mem_q_ip->u4_num_extra_disp_buf;
1789     }
1790     else
1791     {
1792         num_extra_disp_bufs = 0;
1793     }
1794 
1795     if(ps_mem_q_ip->s_ivd_fill_mem_rec_ip_t.u4_size
1796                     > offsetof(ihevcd_cxa_fill_mem_rec_ip_t, u4_share_disp_buf))
1797     {
1798 #ifndef LOGO_EN
1799         share_disp_buf = ps_mem_q_ip->u4_share_disp_buf;
1800 #else
1801         share_disp_buf = 0;
1802 #endif
1803     }
1804     else
1805     {
1806         share_disp_buf = 0;
1807     }
1808 
1809     if(ps_mem_q_ip->s_ivd_fill_mem_rec_ip_t.u4_size
1810                     > offsetof(ihevcd_cxa_fill_mem_rec_ip_t, e_output_format))
1811     {
1812         chroma_format = ps_mem_q_ip->e_output_format;
1813     }
1814     else
1815     {
1816         chroma_format = -1;
1817     }
1818 
1819     /* Shared disp buffer mode is supported only for 420SP formats */
1820     if((chroma_format != IV_YUV_420P) &&
1821        (chroma_format != IV_YUV_420SP_UV) &&
1822        (chroma_format != IV_YUV_420SP_VU))
1823     {
1824         share_disp_buf = 0;
1825     }
1826 
1827     {
1828 
1829         max_ht_luma = ps_mem_q_ip->s_ivd_fill_mem_rec_ip_t.u4_max_frm_ht;
1830         max_wd_luma = ps_mem_q_ip->s_ivd_fill_mem_rec_ip_t.u4_max_frm_wd;
1831 
1832         max_ht_luma = ALIGN64(max_ht_luma);
1833         max_wd_luma = ALIGN64(max_wd_luma);
1834 
1835 
1836 
1837         max_tile_cols = (max_wd_luma + MIN_TILE_WD - 1) / MIN_TILE_WD;
1838         max_tile_rows = (max_ht_luma + MIN_TILE_HT - 1) / MIN_TILE_HT;
1839         max_ctb_rows  = max_ht_luma / MIN_CTB_SIZE;
1840         max_ctb_cols  = max_wd_luma / MIN_CTB_SIZE;
1841         max_ctb_cnt   = max_ctb_rows * max_ctb_cols;
1842         max_num_cu_cols = max_wd_luma / MIN_CU_SIZE;
1843         max_num_4x4_cols = max_wd_luma / 4;
1844     }
1845     /*
1846      * If level is lesser than 31 and the resolution required is higher,
1847      * then make the level at least 31.
1848      */
1849     /*    if (num_mbs > MAX_NUM_MBS_3_0 && level < MAX_LEVEL)
1850      {
1851      level           = MAX_LEVEL;
1852      }
1853      */
1854     if((level < MIN_LEVEL) || (level > MAX_LEVEL))
1855     {
1856         ps_mem_q_op->s_ivd_fill_mem_rec_op_t.u4_error_code |=
1857                         IHEVCD_LEVEL_UNSUPPORTED;
1858         level = MAX_LEVEL;
1859     }
1860     if(num_ref_frames > MAX_REF_CNT)
1861     {
1862         ps_mem_q_op->s_ivd_fill_mem_rec_op_t.u4_error_code |=
1863                         IHEVCD_NUM_REF_UNSUPPORTED;
1864         num_ref_frames = MAX_REF_CNT;
1865     }
1866 
1867     if(num_reorder_frames > MAX_REF_CNT)
1868     {
1869         ps_mem_q_op->s_ivd_fill_mem_rec_op_t.u4_error_code |=
1870                         IHEVCD_NUM_REORDER_UNSUPPORTED;
1871         num_reorder_frames = MAX_REF_CNT;
1872     }
1873 
1874     max_dpb_size = ihevcd_get_dpb_size(level, max_wd_luma * max_ht_luma);
1875     ps_mem_rec_base = ps_mem_q_ip->s_ivd_fill_mem_rec_ip_t.pv_mem_rec_location;
1876 
1877     /* Set all memory reconds as persistent and alignment as 128
1878      * by default
1879      */
1880     ps_mem_rec = ps_mem_rec_base;
1881     for(i = 0; i < MEM_REC_CNT; i++)
1882     {
1883         ps_mem_rec->u4_mem_alignment = 128;
1884         ps_mem_rec->e_mem_type = IV_EXTERNAL_CACHEABLE_PERSISTENT_MEM;
1885         ps_mem_rec++;
1886     }
1887 
1888     /* Request memory for HEVCD object */
1889     ps_mem_rec = &ps_mem_rec_base[MEM_REC_IV_OBJ];
1890     ps_mem_rec->u4_mem_size = sizeof(iv_obj_t);
1891 
1892     DEBUG("\nMemory record Id %d = %d \n", MEM_REC_IV_OBJ,
1893                     ps_mem_rec->u4_mem_size);
1894 
1895     /* Request memory for HEVC Codec context */
1896     ps_mem_rec = &ps_mem_rec_base[MEM_REC_CODEC];
1897     ps_mem_rec->u4_mem_size = sizeof(codec_t);
1898     DEBUG("\nMemory record Id %d = %d \n", MEM_REC_CODEC,
1899                     ps_mem_rec->u4_mem_size);
1900 
1901     /* Request memory for buffer which holds bitstream after emulation prevention */
1902     ps_mem_rec = &ps_mem_rec_base[MEM_REC_BITSBUF];
1903     ps_mem_rec->u4_mem_size = MAX((max_wd_luma * max_ht_luma), MIN_BITSBUF_SIZE);
1904     DEBUG("\nMemory record Id %d = %d \n", MEM_REC_BITSBUF,
1905                     ps_mem_rec->u4_mem_size);
1906 
1907     /* Request memory for buffer which holds TU structures and coeff data for
1908      * a set of CTBs in the current picture */
1909     /*TODO Currently the buffer is allocated at a frame level. Reduce this to
1910      * allocate for s set of CTBs and add appropriate synchronization logic to
1911      * ensure that this is data is not overwritten before consumption
1912      */
1913     ps_mem_rec = &ps_mem_rec_base[MEM_REC_TU_DATA];
1914     ps_mem_rec->u4_mem_size = ihevcd_get_tu_data_size(max_wd_luma * max_ht_luma);
1915     DEBUG("\nMemory record Id %d = %d \n", MEM_REC_TU_DATA,
1916                     ps_mem_rec->u4_mem_size);
1917 
1918     ps_mem_rec = &ps_mem_rec_base[MEM_REC_MVBANK];
1919 
1920     ps_mem_rec->u4_mem_size = sizeof(buf_mgr_t);
1921 
1922     /* Size for holding mv_buf_t for each MV Bank */
1923     /* Note this allocation is done for BUF_MGR_MAX_CNT instead of
1924      * max_dpb_size or MAX_DPB_SIZE for following reasons
1925      * max_dpb_size will be based on max_wd and max_ht
1926      * For higher max_wd and max_ht this number will be smaller than MAX_DPB_SIZE
1927      * But during actual initialization number of buffers allocated can be more
1928      *
1929      * One extra MV Bank is needed to hold current pics MV bank.
1930      * Since this is only a structure allocation and not actual buffer allocation,
1931      * it is allocated for (MAX_DPB_SIZE + 1) entries
1932      */
1933     ps_mem_rec->u4_mem_size += (MAX_DPB_SIZE + 1) * sizeof(mv_buf_t);
1934 
1935     {
1936         /* Allocate for pu_map, pu_t and pic_pu_idx for each MV bank */
1937         /* Note: Number of luma samples is not max_wd * max_ht here, instead it is
1938          * set to maximum number of luma samples allowed at the given level.
1939          * This is done to ensure that any stream with width and height lesser
1940          * than max_wd and max_ht is supported. Number of buffers required can be greater
1941          * for lower width and heights at a given level and this increased number of buffers
1942          * might require more memory than what max_wd and max_ht buffer would have required
1943          * Also note one extra buffer is allocted to store current pictures MV bank
1944          * In case of asynchronous parsing and processing, number of buffers should increase here
1945          * based on when parsing and processing threads are synchronized
1946          */
1947         WORD32 lvl_idx = ihevcd_get_lvl_idx(level);
1948         WORD32 max_luma_samples = gai4_ihevc_max_luma_pic_size[lvl_idx];
1949         ps_mem_rec->u4_mem_size += (max_dpb_size + 1) *
1950                         ihevcd_get_pic_mv_bank_size(max_luma_samples);
1951         DEBUG("\nMemory record Id %d = %d \n", MEM_REC_MVBANK,
1952                         ps_mem_rec->u4_mem_size);
1953     }
1954     // TODO GPU : Have to creat ping-pong view for VPS,SPS,PPS.
1955     ps_mem_rec = &ps_mem_rec_base[MEM_REC_VPS];
1956     ps_mem_rec->u4_mem_size = MAX_VPS_CNT * sizeof(vps_t);
1957     DEBUG("\nMemory record Id %d = %d \n", MEM_REC_VPS,
1958                     ps_mem_rec->u4_mem_size);
1959 
1960     ps_mem_rec = &ps_mem_rec_base[MEM_REC_SPS];
1961     ps_mem_rec->u4_mem_size = MAX_SPS_CNT * sizeof(sps_t);
1962     DEBUG("\nMemory record Id %d = %d \n", MEM_REC_SPS,
1963                     ps_mem_rec->u4_mem_size);
1964 
1965     ps_mem_rec = &ps_mem_rec_base[MEM_REC_PPS];
1966     ps_mem_rec->u4_mem_size = MAX_PPS_CNT * sizeof(pps_t);
1967     DEBUG("\nMemory record Id %d = %d \n", MEM_REC_PPS,
1968                     ps_mem_rec->u4_mem_size);
1969 
1970     ps_mem_rec = &ps_mem_rec_base[MEM_REC_SLICE_HDR];
1971     ps_mem_rec->u4_mem_size = MAX_SLICE_HDR_CNT * sizeof(slice_header_t);
1972     DEBUG("\nMemory record Id %d = %d \n", MEM_REC_SLICE_HDR,
1973                     ps_mem_rec->u4_mem_size);
1974 
1975     ps_mem_rec = &ps_mem_rec_base[MEM_REC_TILE];
1976     {
1977         WORD32 tile_size;
1978 
1979         tile_size  = max_tile_cols * max_tile_rows;
1980         tile_size  *= sizeof(tile_t);
1981 
1982 
1983         ps_mem_rec->u4_mem_size = MAX_PPS_CNT * tile_size;
1984     }
1985 
1986 
1987     DEBUG("\nMemory record Id %d = %d \n", MEM_REC_TILE,
1988                     ps_mem_rec->u4_mem_size);
1989 
1990     ps_mem_rec = &ps_mem_rec_base[MEM_REC_ENTRY_OFST];
1991     {
1992         WORD32 num_entry_points;
1993 
1994         /* One entry point per tile */
1995         num_entry_points  = max_tile_cols * max_tile_rows;
1996 
1997         /* One entry point per row of CTBs */
1998         /*********************************************************************/
1999         /* Only tiles or entropy sync is enabled at a time in main           */
2000         /* profile, but since memory required does not increase too much,    */
2001         /* this allocation is done to handle both cases                      */
2002         /*********************************************************************/
2003         num_entry_points  += max_ctb_rows;
2004 
2005 
2006         ps_mem_rec->u4_mem_size = sizeof(WORD32) * num_entry_points;
2007     }
2008 
2009 
2010     DEBUG("\nMemory record Id %d = %d \n", MEM_REC_ENTRY_OFST,
2011                     ps_mem_rec->u4_mem_size);
2012 
2013 
2014     ps_mem_rec = &ps_mem_rec_base[MEM_REC_SCALING_MAT];
2015     {
2016         WORD32 scaling_mat_size;
2017 
2018         SCALING_MAT_SIZE(scaling_mat_size)
2019         ps_mem_rec->u4_mem_size = (MAX_SPS_CNT + MAX_PPS_CNT) * scaling_mat_size * sizeof(WORD16);
2020     }
2021     DEBUG("\nMemory record Id %d = %d \n", MEM_REC_SCALING_MAT,
2022                     ps_mem_rec->u4_mem_size);
2023 
2024     /* Holds one row skip_flag at 8x8 level used during parsing */
2025     ps_mem_rec = &ps_mem_rec_base[MEM_REC_PARSE_SKIP_FLAG];
2026 
2027     /* 1 bit per 8x8 */
2028     ps_mem_rec->u4_mem_size = max_num_cu_cols / 8;
2029     DEBUG("\nMemory record Id %d = %d \n", MEM_REC_PARSE_SKIP_FLAG,
2030                   ps_mem_rec->u4_mem_size);
2031 
2032     /* Holds one row skip_flag at 8x8 level used during parsing */
2033     ps_mem_rec = &ps_mem_rec_base[MEM_REC_PARSE_CT_DEPTH];
2034 
2035     /* 2 bits per 8x8 */
2036     ps_mem_rec->u4_mem_size = max_num_cu_cols / 4;
2037     DEBUG("\nMemory record Id %d = %d \n", MEM_REC_PARSE_CT_DEPTH,
2038                   ps_mem_rec->u4_mem_size);
2039 
2040     /* Holds one row skip_flag at 8x8 level used during parsing */
2041     ps_mem_rec = &ps_mem_rec_base[MEM_REC_PARSE_INTRA_PRED_MODE];
2042 
2043     /* 8 bits per 4x4 */
2044     /* 16 bytes each for top and left 64 pixels and 16 bytes for default mode */
2045     ps_mem_rec->u4_mem_size = 3 * 16 * sizeof(UWORD8);
2046     DEBUG("\nMemory record Id %d = %d \n", MEM_REC_PARSE_INTRA_PRED_MODE,
2047                   ps_mem_rec->u4_mem_size);
2048 
2049     /* Holds one intra mode at 8x8 level for entire picture */
2050     ps_mem_rec = &ps_mem_rec_base[MEM_REC_INTRA_FLAG];
2051 
2052     /* 1 bit per 8x8 */
2053     ps_mem_rec->u4_mem_size = (max_wd_luma / MIN_CU_SIZE) * (max_ht_luma / MIN_CU_SIZE) / 8;
2054     DEBUG("\nMemory record Id %d = %d \n", MEM_REC_INTRA_FLAG,
2055                   ps_mem_rec->u4_mem_size);
2056 
2057     /* Holds one transquant bypass flag at 8x8 level for entire picture */
2058     ps_mem_rec = &ps_mem_rec_base[MEM_REC_TRANSQUANT_BYPASS_FLAG];
2059 
2060     /* 1 bit per 8x8 */
2061     /* Extra row and column are allocated for easy processing of top and left blocks while loop filtering */
2062     ps_mem_rec->u4_mem_size = ((max_wd_luma + 64) / MIN_CU_SIZE) * ((max_ht_luma + 64) / MIN_CU_SIZE) / 8;
2063     DEBUG("\nMemory record Id %d = %d \n", MEM_REC_TRANSQUANT_BYPASS_FLAG,
2064                   ps_mem_rec->u4_mem_size);
2065 
2066     /* Request memory to hold thread handles for each processing thread */
2067     ps_mem_rec = &ps_mem_rec_base[MEM_REC_THREAD_HANDLE];
2068     ps_mem_rec->u4_mem_size = MAX_PROCESS_THREADS * ithread_get_handle_size();
2069     DEBUG("\nMemory record Id %d = %d \n", MEM_REC_THREAD_HANDLE,
2070                     ps_mem_rec->u4_mem_size);
2071 
2072 
2073     {
2074         WORD32 job_queue_size;
2075         WORD32 num_jobs;
2076         ps_mem_rec = &ps_mem_rec_base[MEM_REC_PROC_JOBQ];
2077 
2078 
2079         /* One job per row of CTBs */
2080         num_jobs  = max_ctb_rows;
2081 
2082         /* One each tile a row of CTBs, num_jobs has to incremented */
2083         num_jobs  *= max_tile_cols;
2084 
2085         /* One format convert/frame copy job per row of CTBs for non-shared mode*/
2086         num_jobs  += max_ctb_rows;
2087 
2088 
2089         job_queue_size = ihevcd_jobq_ctxt_size();
2090         job_queue_size += num_jobs * sizeof(proc_job_t);
2091         ps_mem_rec->u4_mem_size = job_queue_size;
2092         DEBUG("\nMemory record Id %d = %d \n", MEM_REC_PROC_JOBQ,
2093                         ps_mem_rec->u4_mem_size);
2094     }
2095 
2096 
2097     ps_mem_rec = &ps_mem_rec_base[MEM_REC_PARSE_MAP];
2098     ps_mem_rec->u4_mem_size = max_ctb_cnt;
2099     DEBUG("\nMemory record Id %d = %d \n", MEM_REC_PARSE_MAP,
2100                     ps_mem_rec->u4_mem_size);
2101 
2102     ps_mem_rec = &ps_mem_rec_base[MEM_REC_PROC_MAP];
2103     ps_mem_rec->u4_mem_size = max_ctb_cnt;
2104     DEBUG("\nMemory record Id %d = %d \n", MEM_REC_PROC_MAP,
2105                     ps_mem_rec->u4_mem_size);
2106 
2107 
2108     ps_mem_rec = &ps_mem_rec_base[MEM_REC_DISP_MGR];
2109 
2110     /* size for holding display manager context */
2111     ps_mem_rec->u4_mem_size = sizeof(buf_mgr_t);
2112     DEBUG("\nMemory record Id %d = %d \n", MEM_REC_DISP_MGR,
2113                     ps_mem_rec->u4_mem_size);
2114 
2115     ps_mem_rec = &ps_mem_rec_base[MEM_REC_DPB_MGR];
2116 
2117     /* size for holding dpb manager context */
2118     ps_mem_rec->u4_mem_size = sizeof(dpb_mgr_t);
2119     DEBUG("\nMemory record Id %d = %d \n", MEM_REC_DPB_MGR,
2120                     ps_mem_rec->u4_mem_size);
2121 
2122     /** Holds top and left neighbor's pu idx into picture level pu array */
2123     /* Only one top row is enough but left has to be replicated for each process context */
2124     ps_mem_rec = &ps_mem_rec_base[MEM_REC_PIC_PU_IDX_NEIGHBOR];
2125 
2126     ps_mem_rec->u4_mem_size = (max_num_4x4_cols  /* left */ + MAX_PROCESS_THREADS * (MAX_CTB_SIZE / 4)/* top */ + 1/* top right */) * sizeof(WORD32);
2127     DEBUG("\nMemory record Id %d = %d \n", MEM_REC_PIC_PU_IDX_NEIGHBOR,
2128                     ps_mem_rec->u4_mem_size);
2129 
2130 
2131 
2132     /* TO hold scratch buffers needed for each process context */
2133     ps_mem_rec = &ps_mem_rec_base[MEM_REC_PROC_SCRATCH];
2134     {
2135         WORD32 size = 0;
2136         WORD32 inter_pred_tmp_buf_size;
2137         WORD32 ntaps_luma;
2138         WORD32 pu_map_size;
2139         WORD32 sao_size = 0;
2140         ntaps_luma = 8;
2141 
2142         /* Max inter pred size (number of bytes) */
2143         inter_pred_tmp_buf_size = sizeof(WORD16) * (MAX_CTB_SIZE + ntaps_luma) * MAX_CTB_SIZE;
2144         inter_pred_tmp_buf_size = ALIGN64(inter_pred_tmp_buf_size);
2145 
2146 
2147         /* To hold pu_index w.r.t. frame level pu_t array for a CTB at 4x4 level*/
2148         /* 16 x 16 4x4 in a CTB of size 64 x 64 and two extra needed for holding
2149          * neighbors
2150          */
2151         pu_map_size = sizeof(WORD32) * (18 * 18);
2152 
2153         pu_map_size = ALIGN64(pu_map_size);
2154         size += pu_map_size;
2155 
2156         /* To hold inter pred temporary buffers */
2157         size += 2 * inter_pred_tmp_buf_size;
2158 
2159 
2160         /* Allocate for each process context */
2161         size *= MAX_PROCESS_THREADS;
2162 
2163 
2164         /* To hold SAO left buffer for luma */
2165         sao_size += sizeof(UWORD8) * (MAX(max_ht_luma, max_wd_luma));
2166 
2167         /* To hold SAO left buffer for chroma */
2168         sao_size += sizeof(UWORD8) * (MAX(max_ht_luma, max_wd_luma));
2169 
2170         /* To hold SAO top buffer for luma */
2171         sao_size += sizeof(UWORD8) * max_wd_luma;
2172 
2173         /* To hold SAO top buffer for chroma */
2174         sao_size += sizeof(UWORD8) * max_wd_luma;
2175 
2176         /* To hold SAO top left luma pixel value for last output ctb in a row*/
2177         sao_size += sizeof(UWORD8) * max_ctb_rows;
2178 
2179         /* To hold SAO top left chroma pixel value last output ctb in a row*/
2180         sao_size += sizeof(UWORD8) * max_ctb_rows * 2;
2181 
2182         /* To hold SAO top left pixel luma for current ctb - column array*/
2183         sao_size += sizeof(UWORD8) * max_ctb_rows;
2184 
2185         /* To hold SAO top left pixel chroma for current ctb-column array*/
2186         sao_size += sizeof(UWORD8) * max_ctb_rows * 2;
2187 
2188         /* To hold SAO top right pixel luma pixel value last output ctb in a row*/
2189         sao_size += sizeof(UWORD8) * max_ctb_cols;
2190 
2191         /* To hold SAO top right pixel chroma pixel value last output ctb in a row*/
2192         sao_size += sizeof(UWORD8) * max_ctb_cols * 2;
2193 
2194         /*To hold SAO botton bottom left pixels for luma*/
2195         sao_size += sizeof(UWORD8) * max_ctb_rows;
2196 
2197         /*To hold SAO botton bottom left pixels for luma*/
2198         sao_size += sizeof(UWORD8) * max_ctb_rows * 2;
2199         sao_size = ALIGN64(sao_size);
2200         size += sao_size;
2201         ps_mem_rec->u4_mem_size = size;
2202     }
2203     DEBUG("\nMemory record Id %d = %d \n", MEM_REC_PROC_SCRATCH,
2204                     ps_mem_rec->u4_mem_size);
2205 
2206     /* TO hold scratch buffers needed for each SAO context */
2207     ps_mem_rec = &ps_mem_rec_base[MEM_REC_SAO_SCRATCH];
2208     {
2209         WORD32 size = 0;
2210 
2211         size = 4 * MAX_CTB_SIZE * MAX_CTB_SIZE;
2212 
2213         /* 2 temporary buffers*/
2214         size *= 2;
2215 
2216         size *= MAX_PROCESS_THREADS;
2217 
2218         ps_mem_rec->u4_mem_size = size;
2219     }
2220     DEBUG("\nMemory record Id %d = %d \n", MEM_REC_SAO_SCRATCH,
2221                     ps_mem_rec->u4_mem_size);
2222 
2223     ps_mem_rec = &ps_mem_rec_base[MEM_REC_BS_QP];
2224     {
2225         WORD32 size = 0;
2226         WORD32 vert_bs_size, horz_bs_size;
2227         WORD32 qp_const_flag_size;
2228         WORD32 qp_size, num_8x8;
2229 
2230         /* Max Number of vertical edges */
2231         vert_bs_size = max_wd_luma / 8 + 2 * MAX_CTB_SIZE / 8;
2232 
2233         /* Max Number of horizontal edges - extra MAX_CTB_SIZE / 8 to handle the last 4 rows separately(shifted CTB processing) */
2234         vert_bs_size *= (max_ht_luma + MAX_CTB_SIZE) / MIN_TU_SIZE;
2235 
2236         /* Number of bytes */
2237         vert_bs_size /= 8;
2238 
2239         /* Two bits per edge */
2240         vert_bs_size *= 2;
2241 
2242         /* Max Number of horizontal edges */
2243         horz_bs_size = max_ht_luma / 8 + MAX_CTB_SIZE / 8;
2244 
2245         /* Max Number of vertical edges - extra MAX_CTB_SIZE / 8 to handle the last 4 columns separately(shifted CTB processing) */
2246         horz_bs_size *= (max_wd_luma + MAX_CTB_SIZE) / MIN_TU_SIZE;
2247 
2248         /* Number of bytes */
2249         horz_bs_size /= 8;
2250 
2251         /* Two bits per edge */
2252         horz_bs_size *= 2;
2253 
2254         /* Max CTBs in a row */
2255         qp_const_flag_size = max_wd_luma / MIN_CTB_SIZE + 1 /* The last ctb row deblk is done in last ctb + 1 row.*/;
2256 
2257         /* Max CTBs in a column */
2258         qp_const_flag_size *= max_ht_luma / MIN_CTB_SIZE;
2259 
2260         /* Number of bytes */
2261         qp_const_flag_size = (qp_const_flag_size + 7) >> 3;
2262 
2263         /* QP changes at CU level - So store at 8x8 level */
2264         num_8x8 = (max_ht_luma * max_wd_luma) / (MIN_CU_SIZE * MIN_CU_SIZE);
2265         qp_size = num_8x8;
2266 
2267         /* To hold vertical boundary strength */
2268         size += vert_bs_size;
2269 
2270         /* To hold horizontal boundary strength */
2271         size += horz_bs_size;
2272 
2273         /* To hold QP */
2274         size += qp_size;
2275 
2276         /* To hold QP const in CTB flags */
2277         size += qp_const_flag_size;
2278 
2279         ps_mem_rec->u4_mem_size = size;
2280     }
2281 
2282     DEBUG("\nMemory record Id %d = %d \n", MEM_REC_BS_QP,
2283                     ps_mem_rec->u4_mem_size);
2284 
2285     ps_mem_rec = &ps_mem_rec_base[MEM_REC_TILE_IDX];
2286     {
2287         WORD32 size = 0;
2288         /* Max CTBs in a row */
2289         size  = max_wd_luma / MIN_CTB_SIZE + 2 /* Top row and bottom row extra. This ensures accessing left,top in first row
2290                                                   and right in last row will not result in invalid access*/;
2291         /* Max CTBs in a column */
2292         size *= max_ht_luma / MIN_CTB_SIZE;
2293 
2294         size *= sizeof(UWORD16);
2295         ps_mem_rec->u4_mem_size = size;
2296     }
2297     DEBUG("\nMemory record Id %d = %d \n", MEM_REC_TILE_IDX,
2298                     ps_mem_rec->u4_mem_size);
2299 
2300     ps_mem_rec = &ps_mem_rec_base[MEM_REC_SAO];
2301     {
2302         UWORD32 size;
2303 
2304         /* 4 bytes per color component per CTB */
2305         size = 3 * 4;
2306 
2307         /* MAX number of CTBs in a row */
2308         size *= max_wd_luma / MIN_CTB_SIZE;
2309 
2310         /* MAX number of CTBs in a column */
2311         size *= max_ht_luma / MIN_CTB_SIZE;
2312         ps_mem_rec->u4_mem_size = size;
2313     }
2314 
2315     DEBUG("\nMemory record Id %d = %d \n", MEM_REC_SAO,
2316                     ps_mem_rec->u4_mem_size);
2317 
2318 
2319     ps_mem_rec = &ps_mem_rec_base[MEM_REC_REF_PIC];
2320 
2321     /* size for holding buffer manager context */
2322     ps_mem_rec->u4_mem_size = sizeof(buf_mgr_t);
2323 
2324     /* Size for holding pic_buf_t for each reference picture */
2325     /* Note this allocation is done for BUF_MGR_MAX_CNT instead of
2326      * max_dpb_size or MAX_DPB_SIZE for following reasons
2327      * max_dpb_size will be based on max_wd and max_ht
2328      * For higher max_wd and max_ht this number will be smaller than MAX_DPB_SIZE
2329      * But during actual initialization number of buffers allocated can be more
2330      *
2331      * Also to handle display depth application can allocate more than what
2332      * codec asks for in case of non-shared mode
2333      * Since this is only a structure allocation and not actual buffer allocation,
2334      * it is allocated for BUF_MGR_MAX_CNT entries
2335      */
2336     ps_mem_rec->u4_mem_size += BUF_MGR_MAX_CNT * sizeof(pic_buf_t);
2337 
2338     /* In case of non-shared mode allocate for reference picture buffers */
2339     /* In case of shared and 420p output, allocate for chroma samples */
2340     if((0 == share_disp_buf) || (chroma_format == IV_YUV_420P))
2341     {
2342         UWORD32 init_num_bufs;
2343         UWORD32 init_extra_bufs;
2344         WORD32 chroma_only;
2345 
2346         chroma_only = 0;
2347         init_extra_bufs = 0;
2348         init_num_bufs = num_reorder_frames + num_ref_frames + 1;
2349 
2350         /* In case of shared display buffers and chroma format 420P
2351          * Allocate for chroma in reference buffers, luma buffer will be display buffer
2352          */
2353 
2354         if((1 == share_disp_buf) && (chroma_format == IV_YUV_420P))
2355         {
2356             chroma_only = 1;
2357             init_extra_bufs = num_extra_disp_bufs;
2358         }
2359 
2360         /* Note: Number of luma samples is not max_wd * max_ht here, instead it is
2361          * set to maximum number of luma samples allowed at the given level.
2362          * This is done to ensure that any stream with width and height lesser
2363          * than max_wd and max_ht is supported. Number of buffers required can be greater
2364          * for lower width and heights at a given level and this increased number of buffers
2365          * might require more memory than what max_wd and max_ht buffer would have required
2366          * Number of buffers is doubled in order to return one frame at a time instead of sending
2367          * multiple outputs during dpb full case.
2368          * Also note one extra buffer is allocted to store current picture
2369          * In case of asynchronous parsing and processing, number of buffers should increase here
2370          * based on when parsing and processing threads are synchronized
2371          */
2372         ps_mem_rec->u4_mem_size +=
2373                         ihevcd_get_total_pic_buf_size(max_wd_luma * max_ht_luma, level,  PAD_WD,  PAD_HT,
2374                                                       init_num_bufs, init_extra_bufs, chroma_only);
2375     }
2376     DEBUG("\nMemory record Id %d = %d \n", MEM_REC_REF_PIC,
2377                     ps_mem_rec->u4_mem_size);
2378 
2379     /* Request memory to hold mem records to be returned during retrieve call */
2380     ps_mem_rec = &ps_mem_rec_base[MEM_REC_BACKUP];
2381     ps_mem_rec->u4_mem_size = MEM_REC_CNT * sizeof(iv_mem_rec_t);
2382     DEBUG("\nMemory record Id %d = %d \n", MEM_REC_BACKUP,
2383                     ps_mem_rec->u4_mem_size);
2384 
2385     /* Each memtab size is aligned to next multiple of 128 bytes */
2386     /* This is to ensure all the memtabs start at different cache lines */
2387     ps_mem_rec = ps_mem_rec_base;
2388     for(i = 0; i < MEM_REC_CNT; i++)
2389     {
2390         ps_mem_rec->u4_mem_size = ALIGN128(ps_mem_rec->u4_mem_size);
2391         ps_mem_rec++;
2392     }
2393     ps_mem_q_op->s_ivd_fill_mem_rec_op_t.u4_num_mem_rec_filled = MEM_REC_CNT;
2394 #ifdef APPLY_CONCEALMENT
2395     {
2396         IV_API_CALL_STATUS_T status;
2397         icncl_fill_mem_rec_ip_t cncl_fill_ip;
2398         icncl_fill_mem_rec_op_t cncl_fill_op;
2399         UWORD8 mem_loc = MEM_REC_CNT;
2400 
2401         cncl_fill_ip.s_ivd_fill_mem_rec_ip_t.e_cmd = IV_CMD_FILL_NUM_MEM_REC;
2402         cncl_fill_ip.s_ivd_fill_mem_rec_ip_t.pv_mem_rec_location = &(memTab[mem_loc]);
2403         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;
2404         cncl_fill_ip.s_ivd_fill_mem_rec_ip_t.u4_max_frm_wd = max_wd_luma;
2405         cncl_fill_ip.s_ivd_fill_mem_rec_ip_t.u4_max_frm_ht = max_ht_luma;
2406 
2407         status = icncl_api_function(NULL, (void *)&cncl_fill_ip, (void *)&cncl_fill_op);
2408 
2409         if(IV_SUCCESS == status)
2410         {
2411             icncl_num_mem_rec_ip_t cncl_mem_ip;
2412             icncl_num_mem_rec_op_t cncl_mem_op;
2413 
2414             cncl_mem_ip.s_ivd_num_rec_ip_t.e_cmd = IV_CMD_GET_NUM_MEM_REC;
2415             cncl_mem_ip.s_ivd_num_rec_ip_t.u4_size = sizeof(icncl_num_mem_rec_ip_t);
2416 
2417             status = icncl_api_function(NULL, (void *)&cncl_mem_ip, (void *)&cncl_mem_op);
2418             if(IV_SUCCESS == status)
2419             {
2420                 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;
2421             }
2422         }
2423 
2424         return status;
2425 
2426     }
2427 #endif //APPLY_CONCEALMENT
2428     DEBUG("Num mem recs in fill call : %d\n",
2429                     ps_mem_q_op->s_ivd_fill_mem_rec_op_t.u4_num_mem_rec_filled);
2430 
2431 
2432     return (status);
2433 }
2434 
2435 
2436 /**
2437 *******************************************************************************
2438 *
2439 * @brief
2440 *  Initializes from mem records passed to the codec
2441 *
2442 * @par Description:
2443 *  Initializes pointers based on mem records passed
2444 *
2445 * @param[in] ps_codec_obj
2446 *  Pointer to codec object at API level
2447 *
2448 * @param[in] pv_api_ip
2449 *  Pointer to input argument structure
2450 *
2451 * @param[out] pv_api_op
2452 *  Pointer to output argument structure
2453 *
2454 * @returns  Status
2455 *
2456 * @remarks
2457 *
2458 *
2459 *******************************************************************************
2460 */
ihevcd_init_mem_rec(iv_obj_t * ps_codec_obj,void * pv_api_ip,void * pv_api_op)2461 WORD32 ihevcd_init_mem_rec(iv_obj_t *ps_codec_obj,
2462                            void *pv_api_ip,
2463                            void *pv_api_op)
2464 {
2465 
2466     ihevcd_cxa_init_ip_t *dec_init_ip;
2467     ihevcd_cxa_init_op_t *dec_init_op;
2468     WORD32 i;
2469     iv_mem_rec_t *ps_mem_rec, *ps_mem_rec_base;
2470     WORD32 status = IV_SUCCESS;
2471     codec_t *ps_codec;
2472     WORD32 max_tile_cols, max_tile_rows;
2473 
2474     dec_init_ip = (ihevcd_cxa_init_ip_t *)pv_api_ip;
2475     dec_init_op = (ihevcd_cxa_init_op_t *)pv_api_op;
2476 
2477     ps_mem_rec_base = dec_init_ip->s_ivd_init_ip_t.pv_mem_rec_location;
2478 
2479     ps_mem_rec = &ps_mem_rec_base[MEM_REC_CODEC];
2480     ps_codec_obj->pv_codec_handle = ps_mem_rec->pv_base;
2481 
2482     ps_codec = (codec_t *)(ps_codec_obj->pv_codec_handle);
2483 
2484     /* Note this memset can not be done in init() call, since init will called
2485     during reset as well. And calling this during reset will mean all pointers
2486     need to reinitialized*/
2487     memset(ps_codec, 0, sizeof(codec_t));
2488 
2489     if(dec_init_ip->s_ivd_init_ip_t.u4_size
2490                     > offsetof(ihevcd_cxa_init_ip_t, i4_level))
2491     {
2492         ps_codec->i4_init_level = dec_init_ip->i4_level;
2493 
2494         ps_codec->i4_init_level *= 3;
2495     }
2496     else
2497     {
2498         ps_codec->i4_init_level = MAX_LEVEL;
2499     }
2500 
2501     if(dec_init_ip->s_ivd_init_ip_t.u4_size
2502                     > offsetof(ihevcd_cxa_init_ip_t, u4_num_ref_frames))
2503     {
2504         ps_codec->i4_init_num_ref = dec_init_ip->u4_num_ref_frames;
2505     }
2506     else
2507     {
2508         ps_codec->i4_init_num_ref = MAX_REF_CNT;
2509     }
2510 
2511     if(dec_init_ip->s_ivd_init_ip_t.u4_size
2512                     > offsetof(ihevcd_cxa_init_ip_t, u4_num_reorder_frames))
2513     {
2514         ps_codec->i4_init_num_reorder = dec_init_ip->u4_num_reorder_frames;
2515     }
2516     else
2517     {
2518         ps_codec->i4_init_num_reorder = MAX_REF_CNT;
2519     }
2520 
2521     if(dec_init_ip->s_ivd_init_ip_t.u4_size
2522                     > offsetof(ihevcd_cxa_init_ip_t, u4_num_extra_disp_buf))
2523     {
2524         ps_codec->i4_init_num_extra_disp_buf =
2525                         dec_init_ip->u4_num_extra_disp_buf;
2526     }
2527     else
2528     {
2529         ps_codec->i4_init_num_extra_disp_buf = 0;
2530     }
2531 
2532     if(dec_init_ip->s_ivd_init_ip_t.u4_size
2533                     > offsetof(ihevcd_cxa_init_ip_t, u4_share_disp_buf))
2534     {
2535 #ifndef LOGO_EN
2536         ps_codec->i4_share_disp_buf = dec_init_ip->u4_share_disp_buf;
2537 #else
2538         ps_codec->i4_share_disp_buf = 0;
2539 #endif
2540     }
2541     else
2542     {
2543         ps_codec->i4_share_disp_buf = 0;
2544     }
2545     /* Shared display mode is supported only for 420SP and 420P formats */
2546     if((dec_init_ip->s_ivd_init_ip_t.e_output_format != IV_YUV_420P) &&
2547        (dec_init_ip->s_ivd_init_ip_t.e_output_format != IV_YUV_420SP_UV) &&
2548        (dec_init_ip->s_ivd_init_ip_t.e_output_format != IV_YUV_420SP_VU))
2549     {
2550         ps_codec->i4_share_disp_buf = 0;
2551     }
2552 
2553     if((ps_codec->i4_init_level < MIN_LEVEL)
2554                     || (ps_codec->i4_init_level > MAX_LEVEL))
2555     {
2556         dec_init_op->s_ivd_init_op_t.u4_error_code |= IHEVCD_LEVEL_UNSUPPORTED;
2557         return (IV_FAIL);
2558     }
2559 
2560     if(ps_codec->i4_init_num_ref > MAX_REF_CNT)
2561     {
2562         dec_init_op->s_ivd_init_op_t.u4_error_code |=
2563                         IHEVCD_NUM_REF_UNSUPPORTED;
2564         ps_codec->i4_init_num_ref = MAX_REF_CNT;
2565     }
2566 
2567     if(ps_codec->i4_init_num_reorder > MAX_REF_CNT)
2568     {
2569         dec_init_op->s_ivd_init_op_t.u4_error_code |=
2570                         IHEVCD_NUM_REORDER_UNSUPPORTED;
2571         ps_codec->i4_init_num_reorder = MAX_REF_CNT;
2572     }
2573 
2574     if(ps_codec->i4_init_num_extra_disp_buf > MAX_REF_CNT)
2575     {
2576         dec_init_op->s_ivd_init_op_t.u4_error_code |=
2577                         IHEVCD_NUM_EXTRA_DISP_UNSUPPORTED;
2578         ps_codec->i4_init_num_extra_disp_buf = 0;
2579     }
2580 
2581     ps_codec->e_chroma_fmt = dec_init_ip->s_ivd_init_ip_t.e_output_format;
2582 
2583     ps_codec->i4_max_wd = dec_init_ip->s_ivd_init_ip_t.u4_frm_max_wd;
2584     ps_codec->i4_max_ht = dec_init_ip->s_ivd_init_ip_t.u4_frm_max_ht;
2585 
2586     ps_codec->i4_max_wd = ALIGN64(ps_codec->i4_max_wd);
2587     ps_codec->i4_max_ht = ALIGN64(ps_codec->i4_max_ht);
2588 
2589     ps_codec->i4_new_max_wd = ps_codec->i4_max_wd;
2590     ps_codec->i4_new_max_ht = ps_codec->i4_max_ht;
2591 
2592     max_tile_cols = (ps_codec->i4_max_wd + MIN_TILE_WD - 1) / MIN_TILE_WD;
2593     max_tile_rows = (ps_codec->i4_max_ht + MIN_TILE_HT - 1) / MIN_TILE_HT;
2594 
2595     ps_mem_rec = &ps_mem_rec_base[MEM_REC_BACKUP];
2596     ps_codec->ps_mem_rec_backup = (iv_mem_rec_t *)ps_mem_rec->pv_base;
2597 
2598     memcpy(ps_codec->ps_mem_rec_backup, ps_mem_rec_base,
2599            MEM_REC_CNT * sizeof(iv_mem_rec_t));
2600 
2601     ps_mem_rec = &ps_mem_rec_base[MEM_REC_BITSBUF];
2602     ps_codec->pu1_bitsbuf = (UWORD8 *)ps_mem_rec->pv_base;
2603     ps_codec->u4_bitsbuf_size = ps_mem_rec->u4_mem_size;
2604 
2605     ps_mem_rec = &ps_mem_rec_base[MEM_REC_TU_DATA];
2606     ps_codec->pv_tu_data = ps_mem_rec->pv_base;
2607     ps_mem_rec = &ps_mem_rec_base[MEM_REC_MVBANK];
2608     ps_codec->pv_mv_buf_mgr = ps_mem_rec->pv_base;
2609     ps_codec->pv_mv_bank_buf_base = (UWORD8 *)ps_codec->pv_mv_buf_mgr + sizeof(buf_mgr_t);
2610 
2611     ps_codec->i4_total_mv_bank_size = ps_mem_rec->u4_mem_size - sizeof(buf_mgr_t);
2612 
2613 
2614     ps_mem_rec = &ps_mem_rec_base[MEM_REC_VPS];
2615     ps_codec->ps_vps_base = (vps_t *)ps_mem_rec->pv_base;
2616     ps_codec->s_parse.ps_vps_base = ps_codec->ps_vps_base;
2617 
2618     ps_mem_rec = &ps_mem_rec_base[MEM_REC_SPS];
2619     ps_codec->ps_sps_base = (sps_t *)ps_mem_rec->pv_base;
2620     ps_codec->s_parse.ps_sps_base = ps_codec->ps_sps_base;
2621 
2622     ps_mem_rec = &ps_mem_rec_base[MEM_REC_PPS];
2623     ps_codec->ps_pps_base = (pps_t *)ps_mem_rec->pv_base;
2624     ps_codec->s_parse.ps_pps_base = ps_codec->ps_pps_base;
2625 
2626     ps_mem_rec = &ps_mem_rec_base[MEM_REC_SLICE_HDR];
2627     ps_codec->ps_slice_hdr_base = (slice_header_t *)ps_mem_rec->pv_base;
2628     ps_codec->s_parse.ps_slice_hdr_base = ps_codec->ps_slice_hdr_base;
2629 
2630     ps_mem_rec = &ps_mem_rec_base[MEM_REC_TILE];
2631     ps_codec->ps_tile = (tile_t *)ps_mem_rec->pv_base;
2632 
2633     ps_mem_rec = &ps_mem_rec_base[MEM_REC_ENTRY_OFST];
2634     ps_codec->pi4_entry_ofst = (WORD32 *)ps_mem_rec->pv_base;
2635 
2636     ps_mem_rec = &ps_mem_rec_base[MEM_REC_SCALING_MAT];
2637     ps_codec->pi2_scaling_mat = (WORD16 *)ps_mem_rec->pv_base;
2638 
2639     ps_mem_rec = &ps_mem_rec_base[MEM_REC_PARSE_SKIP_FLAG];
2640     ps_codec->s_parse.pu4_skip_cu_top = (UWORD32 *)ps_mem_rec->pv_base;
2641 
2642     ps_mem_rec = &ps_mem_rec_base[MEM_REC_PARSE_CT_DEPTH];
2643     ps_codec->s_parse.pu4_ct_depth_top = (UWORD32 *)ps_mem_rec->pv_base;
2644 
2645     ps_mem_rec = &ps_mem_rec_base[MEM_REC_PARSE_INTRA_PRED_MODE];
2646     ps_codec->s_parse.pu1_luma_intra_pred_mode_left =
2647                     (UWORD8 *)ps_mem_rec->pv_base;
2648     ps_codec->s_parse.pu1_luma_intra_pred_mode_top  =
2649                     (UWORD8 *)ps_mem_rec->pv_base + 16;
2650 
2651     ps_mem_rec = &ps_mem_rec_base[MEM_REC_INTRA_FLAG];
2652 
2653     memset(ps_mem_rec->pv_base, 0, (ps_codec->i4_max_wd / MIN_CU_SIZE) * (ps_codec->i4_max_ht / MIN_CU_SIZE) / 8);
2654 
2655     ps_codec->pu1_pic_intra_flag = (UWORD8 *)ps_mem_rec->pv_base;
2656     ps_codec->s_parse.pu1_pic_intra_flag = ps_codec->pu1_pic_intra_flag;
2657     ps_mem_rec = &ps_mem_rec_base[MEM_REC_TRANSQUANT_BYPASS_FLAG];
2658 
2659     {
2660         WORD32 loop_filter_size = ((ps_codec->i4_max_wd  + 64) / MIN_CU_SIZE) * ((ps_codec->i4_max_ht + 64) / MIN_CU_SIZE) / 8;
2661         WORD32 loop_filter_strd = (ps_codec->i4_max_wd + 63) >> 6;
2662 
2663         memset(ps_mem_rec->pv_base, 0, loop_filter_size);
2664 
2665         /* The offset is added for easy processing of top and left blocks while loop filtering */
2666         ps_codec->pu1_pic_no_loop_filter_flag = (UWORD8 *)ps_mem_rec->pv_base + loop_filter_strd + 1;
2667         ps_codec->s_parse.pu1_pic_no_loop_filter_flag = ps_codec->pu1_pic_no_loop_filter_flag;
2668         ps_codec->s_parse.s_deblk_ctxt.pu1_pic_no_loop_filter_flag = ps_codec->pu1_pic_no_loop_filter_flag;
2669         ps_codec->s_parse.s_sao_ctxt.pu1_pic_no_loop_filter_flag = ps_codec->pu1_pic_no_loop_filter_flag;
2670     }
2671 
2672     /* Initialize pointers in PPS structures */
2673     {
2674         sps_t *ps_sps = ps_codec->ps_sps_base;
2675         pps_t *ps_pps = ps_codec->ps_pps_base;
2676         tile_t *ps_tile =  ps_codec->ps_tile;
2677         WORD16 *pi2_scaling_mat =  ps_codec->pi2_scaling_mat;
2678         WORD32 scaling_mat_size;
2679 
2680         SCALING_MAT_SIZE(scaling_mat_size);
2681 
2682         for(i = 0; i < MAX_SPS_CNT; i++)
2683         {
2684             ps_sps->pi2_scaling_mat  = pi2_scaling_mat;
2685             pi2_scaling_mat += scaling_mat_size;
2686             ps_sps++;
2687         }
2688 
2689         for(i = 0; i < MAX_PPS_CNT; i++)
2690         {
2691             ps_pps->ps_tile = ps_tile;
2692             ps_tile += (max_tile_cols * max_tile_rows);
2693 
2694             ps_pps->pi2_scaling_mat  = pi2_scaling_mat;
2695             pi2_scaling_mat += scaling_mat_size;
2696             ps_pps++;
2697         }
2698 
2699     }
2700 
2701     ps_mem_rec = &ps_mem_rec_base[MEM_REC_THREAD_HANDLE];
2702     for(i = 0; i < MAX_PROCESS_THREADS; i++)
2703     {
2704         WORD32 handle_size = ithread_get_handle_size();
2705         ps_codec->apv_process_thread_handle[i] =
2706                         (UWORD8 *)ps_mem_rec->pv_base + (i * handle_size);
2707     }
2708 
2709     ps_mem_rec = &ps_mem_rec_base[MEM_REC_PROC_JOBQ];
2710     ps_codec->pv_proc_jobq_buf = ps_mem_rec->pv_base;
2711     ps_codec->i4_proc_jobq_buf_size = ps_mem_rec->u4_mem_size;
2712 
2713     ps_mem_rec = &ps_mem_rec_base[MEM_REC_PARSE_MAP];
2714     ps_codec->pu1_parse_map = (UWORD8 *)ps_mem_rec->pv_base;
2715 
2716     ps_mem_rec = &ps_mem_rec_base[MEM_REC_PROC_MAP];
2717     ps_codec->pu1_proc_map = (UWORD8 *)ps_mem_rec->pv_base;
2718     ps_mem_rec = &ps_mem_rec_base[MEM_REC_DISP_MGR];
2719     ps_codec->pv_disp_buf_mgr = ps_mem_rec->pv_base;
2720 
2721     ps_mem_rec = &ps_mem_rec_base[MEM_REC_DPB_MGR];
2722     ps_codec->pv_dpb_mgr = ps_mem_rec->pv_base;
2723 
2724 
2725     ps_mem_rec = &ps_mem_rec_base[MEM_REC_PIC_PU_IDX_NEIGHBOR];
2726 
2727     for(i = 0; i < MAX_PROCESS_THREADS; i++)
2728     {
2729         UWORD32 *pu4_buf = (UWORD32 *)ps_mem_rec->pv_base;
2730         ps_codec->as_process[i].pu4_pic_pu_idx_left = pu4_buf + i * (MAX_CTB_SIZE / 4);
2731         memset(ps_codec->as_process[i].pu4_pic_pu_idx_left, 0, sizeof(UWORD32) * MAX_CTB_SIZE / 4);
2732         ps_codec->as_process[i].pu4_pic_pu_idx_top = pu4_buf + MAX_PROCESS_THREADS * (MAX_CTB_SIZE / 4);
2733     }
2734     memset(ps_codec->as_process[0].pu4_pic_pu_idx_top, 0, sizeof(UWORD32) * (ps_codec->i4_max_wd / 4 + 1));
2735 
2736 
2737     ps_mem_rec = &ps_mem_rec_base[MEM_REC_PROC_SCRATCH];
2738     {
2739         UWORD8 *pu1_buf = (UWORD8 *)ps_mem_rec->pv_base;
2740         WORD32 pic_pu_idx_map_size;
2741 
2742         WORD32 inter_pred_tmp_buf_size, ntaps_luma;
2743 
2744         /* Max inter pred size */
2745         ntaps_luma = 8;
2746         inter_pred_tmp_buf_size = sizeof(WORD16) * (MAX_CTB_SIZE + ntaps_luma) * MAX_CTB_SIZE;
2747 
2748         inter_pred_tmp_buf_size = ALIGN64(inter_pred_tmp_buf_size);
2749 
2750         /* To hold pu_index w.r.t. frame level pu_t array for a CTB */
2751         pic_pu_idx_map_size = sizeof(WORD32) * (18 * 18);
2752         pic_pu_idx_map_size = ALIGN64(pic_pu_idx_map_size);
2753         for(i = 0; i < MAX_PROCESS_THREADS; i++)
2754         {
2755             ps_codec->as_process[i].pi2_inter_pred_tmp_buf1 = (WORD16 *)pu1_buf;
2756             pu1_buf += inter_pred_tmp_buf_size;
2757 
2758             ps_codec->as_process[i].pi2_inter_pred_tmp_buf2 = (WORD16 *)pu1_buf;
2759             pu1_buf += inter_pred_tmp_buf_size;
2760 
2761             /* Inverse transform intermediate and inverse scan output buffers reuse inter pred scratch buffers */
2762             ps_codec->as_process[i].pi2_itrans_intrmd_buf =
2763                             ps_codec->as_process[i].pi2_inter_pred_tmp_buf2;
2764             ps_codec->as_process[i].pi2_invscan_out =
2765                             ps_codec->as_process[i].pi2_inter_pred_tmp_buf1;
2766 
2767             ps_codec->as_process[i].pu4_pic_pu_idx_map = (UWORD32 *)pu1_buf;
2768             ps_codec->as_process[i].s_bs_ctxt.pu4_pic_pu_idx_map =
2769                             (UWORD32 *)pu1_buf;
2770             pu1_buf += pic_pu_idx_map_size;
2771 
2772             //   ps_codec->as_process[i].pi2_inter_pred_tmp_buf3 = (WORD16 *)pu1_buf;
2773             //   pu1_buf += inter_pred_tmp_buf_size;
2774 
2775             ps_codec->as_process[i].i4_inter_pred_tmp_buf_strd = MAX_CTB_SIZE;
2776 
2777         }
2778         for(i = 0; i < MAX_PROCESS_THREADS; i++)
2779         {
2780             ps_codec->as_process[i].s_sao_ctxt.pu1_sao_src_left_luma = (UWORD8 *)pu1_buf;
2781         }
2782         ps_codec->s_parse.s_sao_ctxt.pu1_sao_src_left_luma = (UWORD8 *)pu1_buf;
2783         pu1_buf += MAX(ps_codec->i4_max_ht, ps_codec->i4_max_wd);
2784 
2785         for(i = 0; i < MAX_PROCESS_THREADS; i++)
2786         {
2787             ps_codec->as_process[i].s_sao_ctxt.pu1_sao_src_left_chroma = (UWORD8 *)pu1_buf;
2788         }
2789         ps_codec->s_parse.s_sao_ctxt.pu1_sao_src_left_chroma = (UWORD8 *)pu1_buf;
2790         pu1_buf += MAX(ps_codec->i4_max_ht, ps_codec->i4_max_wd);
2791         for(i = 0; i < MAX_PROCESS_THREADS; i++)
2792         {
2793             ps_codec->as_process[i].s_sao_ctxt.pu1_sao_src_top_luma = (UWORD8 *)pu1_buf;
2794         }
2795         ps_codec->s_parse.s_sao_ctxt.pu1_sao_src_top_luma = (UWORD8 *)pu1_buf;
2796         pu1_buf += ps_codec->i4_max_wd;
2797 
2798         for(i = 0; i < MAX_PROCESS_THREADS; i++)
2799         {
2800             ps_codec->as_process[i].s_sao_ctxt.pu1_sao_src_top_chroma = (UWORD8 *)pu1_buf;
2801         }
2802         ps_codec->s_parse.s_sao_ctxt.pu1_sao_src_top_chroma = (UWORD8 *)pu1_buf;
2803         pu1_buf += ps_codec->i4_max_wd;
2804         for(i = 0; i < MAX_PROCESS_THREADS; i++)
2805         {
2806             ps_codec->as_process[i].s_sao_ctxt.pu1_sao_src_luma_top_left_ctb = (UWORD8 *)pu1_buf;
2807         }
2808         ps_codec->s_parse.s_sao_ctxt.pu1_sao_src_luma_top_left_ctb = (UWORD8 *)pu1_buf;
2809         pu1_buf += ps_codec->i4_max_ht / MIN_CTB_SIZE;
2810 
2811         for(i = 0; i < MAX_PROCESS_THREADS; i++)
2812         {
2813             ps_codec->as_process[i].s_sao_ctxt.pu1_sao_src_chroma_top_left_ctb = (UWORD8 *)pu1_buf;
2814         }
2815         ps_codec->s_parse.s_sao_ctxt.pu1_sao_src_chroma_top_left_ctb = (UWORD8 *)pu1_buf;
2816         pu1_buf += (ps_codec->i4_max_ht / MIN_CTB_SIZE) * 2;
2817 
2818         for(i = 0; i < MAX_PROCESS_THREADS; i++)
2819         {
2820             ps_codec->as_process[i].s_sao_ctxt.pu1_sao_src_top_left_luma_curr_ctb = (UWORD8 *)pu1_buf;
2821         }
2822         ps_codec->s_parse.s_sao_ctxt.pu1_sao_src_top_left_luma_curr_ctb = (UWORD8 *)pu1_buf;
2823         pu1_buf += ps_codec->i4_max_ht / MIN_CTB_SIZE;
2824 
2825         for(i = 0; i < MAX_PROCESS_THREADS; i++)
2826         {
2827             ps_codec->as_process[i].s_sao_ctxt.pu1_sao_src_top_left_chroma_curr_ctb = (UWORD8 *)pu1_buf;
2828         }
2829         ps_codec->s_parse.s_sao_ctxt.pu1_sao_src_top_left_chroma_curr_ctb = (UWORD8 *)pu1_buf;
2830 
2831         pu1_buf += (ps_codec->i4_max_ht / MIN_CTB_SIZE) * 2;
2832         for(i = 0; i < MAX_PROCESS_THREADS; i++)
2833         {
2834             ps_codec->as_process[i].s_sao_ctxt.pu1_sao_src_top_left_luma_top_right = (UWORD8 *)pu1_buf;
2835         }
2836         ps_codec->s_parse.s_sao_ctxt.pu1_sao_src_top_left_luma_top_right = (UWORD8 *)pu1_buf;
2837 
2838         pu1_buf += ps_codec->i4_max_wd / MIN_CTB_SIZE;
2839         for(i = 0; i < MAX_PROCESS_THREADS; i++)
2840         {
2841             ps_codec->as_process[i].s_sao_ctxt.pu1_sao_src_top_left_chroma_top_right = (UWORD8 *)pu1_buf;
2842         }
2843         ps_codec->s_parse.s_sao_ctxt.pu1_sao_src_top_left_chroma_top_right = (UWORD8 *)pu1_buf;
2844 
2845         pu1_buf += (ps_codec->i4_max_wd / MIN_CTB_SIZE) * 2;
2846 
2847         /*Per CTB, Store 1 value for luma , 2 values for chroma*/
2848         for(i = 0; i < MAX_PROCESS_THREADS; i++)
2849         {
2850             ps_codec->as_process[i].s_sao_ctxt.pu1_sao_src_top_left_luma_bot_left = (UWORD8 *)pu1_buf;
2851         }
2852         ps_codec->s_parse.s_sao_ctxt.pu1_sao_src_top_left_luma_bot_left = (UWORD8 *)pu1_buf;
2853 
2854         pu1_buf += (ps_codec->i4_max_ht / MIN_CTB_SIZE);
2855 
2856         for(i = 0; i < MAX_PROCESS_THREADS; i++)
2857         {
2858             ps_codec->as_process[i].s_sao_ctxt.pu1_sao_src_top_left_chroma_bot_left = (UWORD8 *)pu1_buf;
2859         }
2860         ps_codec->s_parse.s_sao_ctxt.pu1_sao_src_top_left_chroma_bot_left = (UWORD8 *)pu1_buf;
2861 
2862         pu1_buf += (ps_codec->i4_max_ht / MIN_CTB_SIZE) * 2;
2863     }
2864 
2865     ps_mem_rec = &ps_mem_rec_base[MEM_REC_SAO_SCRATCH];
2866     {
2867         UWORD8 *pu1_buf = (UWORD8 *)ps_mem_rec->pv_base;
2868         for(i = 0; i < MAX_PROCESS_THREADS; i++)
2869         {
2870             ps_codec->as_process[i].s_sao_ctxt.pu1_tmp_buf_luma = (UWORD8 *)pu1_buf;
2871             pu1_buf += 4 * MAX_CTB_SIZE * MAX_CTB_SIZE * sizeof(UWORD8);
2872 
2873             ps_codec->as_process[i].s_sao_ctxt.pu1_tmp_buf_chroma = (UWORD8 *)pu1_buf;
2874             pu1_buf += 4 * MAX_CTB_SIZE * MAX_CTB_SIZE * sizeof(UWORD8);
2875         }
2876     }
2877 
2878     ps_mem_rec = &ps_mem_rec_base[MEM_REC_BS_QP];
2879     {
2880         UWORD8 *pu1_buf = (UWORD8 *)ps_mem_rec->pv_base;
2881         WORD32 vert_bs_size, horz_bs_size;
2882         WORD32 qp_const_flag_size;
2883         WORD32 qp_size;
2884         WORD32 num_8x8;
2885 
2886         /* Max Number of vertical edges */
2887         vert_bs_size = ps_codec->i4_max_wd / 8 + 2 * MAX_CTB_SIZE / 8;
2888 
2889         /* Max Number of horizontal edges - extra MAX_CTB_SIZE / 8 to handle the last 4 rows separately(shifted CTB processing) */
2890         vert_bs_size *= (ps_codec->i4_max_ht + MAX_CTB_SIZE) / MIN_TU_SIZE;
2891 
2892         /* Number of bytes */
2893         vert_bs_size /= 8;
2894 
2895         /* Two bits per edge */
2896         vert_bs_size *= 2;
2897 
2898         /* Max Number of horizontal edges */
2899         horz_bs_size = ps_codec->i4_max_ht / 8 + MAX_CTB_SIZE / 8;
2900 
2901         /* Max Number of vertical edges - extra MAX_CTB_SIZE / 8 to handle the last 4 columns separately(shifted CTB processing) */
2902         horz_bs_size *= (ps_codec->i4_max_wd + MAX_CTB_SIZE) / MIN_TU_SIZE;
2903 
2904         /* Number of bytes */
2905         horz_bs_size /= 8;
2906 
2907         /* Two bits per edge */
2908         horz_bs_size *= 2;
2909 
2910         /* Max CTBs in a row */
2911         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.*/;
2912 
2913         /* Max CTBs in a column */
2914         qp_const_flag_size *= ps_codec->i4_max_ht / MIN_CTB_SIZE;
2915 
2916         /* Number of bytes */
2917         qp_const_flag_size /= 8;
2918 
2919         /* QP changes at CU level - So store at 8x8 level */
2920         num_8x8 = (ps_codec->i4_max_ht * ps_codec->i4_max_wd) / (MIN_CU_SIZE * MIN_CU_SIZE);
2921         qp_size = num_8x8;
2922         memset(pu1_buf, 0, vert_bs_size + horz_bs_size + qp_size + qp_const_flag_size);
2923 
2924         for(i = 0; i < MAX_PROCESS_THREADS; i++)
2925         {
2926             ps_codec->as_process[i].s_bs_ctxt.pu4_pic_vert_bs = (UWORD32 *)pu1_buf;
2927             ps_codec->as_process[i].s_deblk_ctxt.s_bs_ctxt.pu4_pic_vert_bs = (UWORD32 *)pu1_buf;
2928             ps_codec->s_parse.s_deblk_ctxt.s_bs_ctxt.pu4_pic_vert_bs = (UWORD32 *)pu1_buf;
2929             pu1_buf += vert_bs_size;
2930 
2931             ps_codec->as_process[i].s_bs_ctxt.pu4_pic_horz_bs = (UWORD32 *)pu1_buf;
2932             ps_codec->as_process[i].s_deblk_ctxt.s_bs_ctxt.pu4_pic_horz_bs = (UWORD32 *)pu1_buf;
2933             ps_codec->s_parse.s_deblk_ctxt.s_bs_ctxt.pu4_pic_horz_bs = (UWORD32 *)pu1_buf;
2934             pu1_buf += horz_bs_size;
2935 
2936             ps_codec->as_process[i].s_bs_ctxt.pu1_pic_qp = (UWORD8 *)pu1_buf;
2937             ps_codec->as_process[i].s_deblk_ctxt.s_bs_ctxt.pu1_pic_qp = (UWORD8 *)pu1_buf;
2938             ps_codec->s_parse.s_deblk_ctxt.s_bs_ctxt.pu1_pic_qp = (UWORD8 *)pu1_buf;
2939             pu1_buf += qp_size;
2940 
2941             ps_codec->as_process[i].s_bs_ctxt.pu1_pic_qp_const_in_ctb = (UWORD8 *)pu1_buf;
2942             ps_codec->as_process[i].s_deblk_ctxt.s_bs_ctxt.pu1_pic_qp_const_in_ctb = (UWORD8 *)pu1_buf;
2943             ps_codec->s_parse.s_deblk_ctxt.s_bs_ctxt.pu1_pic_qp_const_in_ctb = (UWORD8 *)pu1_buf;
2944             pu1_buf += qp_const_flag_size;
2945 
2946             pu1_buf -= (vert_bs_size + horz_bs_size + qp_size + qp_const_flag_size);
2947         }
2948         ps_codec->s_parse.s_bs_ctxt.pu4_pic_vert_bs = (UWORD32 *)pu1_buf;
2949         pu1_buf += vert_bs_size;
2950 
2951         ps_codec->s_parse.s_bs_ctxt.pu4_pic_horz_bs = (UWORD32 *)pu1_buf;
2952         pu1_buf += horz_bs_size;
2953 
2954         ps_codec->s_parse.s_bs_ctxt.pu1_pic_qp = (UWORD8 *)pu1_buf;
2955         pu1_buf += qp_size;
2956 
2957         ps_codec->s_parse.s_bs_ctxt.pu1_pic_qp_const_in_ctb = (UWORD8 *)pu1_buf;
2958         pu1_buf += qp_const_flag_size;
2959 
2960     }
2961 
2962     ps_mem_rec = &ps_mem_rec_base[MEM_REC_TILE_IDX];
2963     {
2964         UWORD8 *pu1_buf = (UWORD8 *)ps_mem_rec->pv_base;
2965 
2966         for(i = 0; i < MAX_PROCESS_THREADS; i++)
2967         {
2968             ps_codec->as_process[i].pu1_tile_idx = (UWORD16 *)pu1_buf + ps_codec->i4_max_wd / MIN_CTB_SIZE /* Offset 1 row */;
2969         }
2970     }
2971 
2972     ps_mem_rec = &ps_mem_rec_base[MEM_REC_SAO];
2973     ps_codec->s_parse.ps_pic_sao = (sao_t *)ps_mem_rec->pv_base;
2974     ps_codec->s_parse.s_sao_ctxt.ps_pic_sao = (sao_t *)ps_mem_rec->pv_base;
2975     for(i = 0; i < MAX_PROCESS_THREADS; i++)
2976     {
2977         ps_codec->as_process[i].s_sao_ctxt.ps_pic_sao = ps_codec->s_parse.ps_pic_sao;
2978     }
2979 
2980     ps_mem_rec = &ps_mem_rec_base[MEM_REC_REF_PIC];
2981     ps_codec->pv_pic_buf_mgr = ps_mem_rec->pv_base;
2982     ps_codec->pv_pic_buf_base = (UWORD8 *)ps_codec->pv_pic_buf_mgr + sizeof(buf_mgr_t);
2983     ps_codec->i4_total_pic_buf_size = ps_mem_rec->u4_mem_size - sizeof(buf_mgr_t);
2984     ps_codec->pu1_cur_chroma_ref_buf = (UWORD8 *)ps_codec->pv_pic_buf_base + BUF_MGR_MAX_CNT * sizeof(pic_buf_t);
2985     ps_codec->i4_remaining_pic_buf_size = ps_codec->i4_total_pic_buf_size - BUF_MGR_MAX_CNT * sizeof(pic_buf_t);
2986 
2987 
2988 
2989 
2990 #ifdef APPLY_CONCEALMENT
2991     {
2992 
2993         UWORD32 mem_loc;
2994 
2995         icncl_init_ip_t cncl_init_ip;
2996         icncl_init_op_t cncl_init_op;
2997         iv_mem_rec_t *ps_mem_rec;
2998         DecStruct *ps_codec;
2999 
3000         ps_mem_rec = dec_init_ip->s_ivd_init_ip_t.pv_mem_rec_location;
3001         mem_loc = MEM_REC_CNT;
3002 
3003         ps_codec->ps_conceal = (iv_obj_t *)ps_mem_rec[mem_loc].pv_base;
3004         ps_codec->i4_first_frame_done = 0;
3005 
3006         cncl_init_ip.u4_size = sizeof(icncl_init_ip_t);
3007         cncl_init_ip.pv_mem_rec_location = &(ps_mem_rec[mem_loc]);
3008         cncl_init_ip.e_cmd = IV_CMD_INIT;
3009 
3010         status = icncl_api_function(ps_codec->ps_conceal, (void *)&cncl_init_ip, (void *)&cncl_init_op);
3011 
3012     }
3013 #endif //APPLY_CONCEALMENT
3014 
3015     status = ihevcd_init(ps_codec);
3016 
3017     TRACE_INIT(NULL);
3018     STATS_INIT();
3019     return status;
3020 }
3021 /**
3022 *******************************************************************************
3023 *
3024 * @brief
3025 *  Retrieves mem records passed to the codec
3026 *
3027 * @par Description:
3028 *  Retrieves memrecs passed earlier
3029 *
3030 * @param[in] ps_codec_obj
3031 *  Pointer to codec object at API level
3032 *
3033 * @param[in] pv_api_ip
3034 *  Pointer to input argument structure
3035 *
3036 * @param[out] pv_api_op
3037 *  Pointer to output argument structure
3038 *
3039 * @returns  Status
3040 *
3041 * @remarks
3042 *
3043 *
3044 *******************************************************************************
3045 */
ihevcd_retrieve_memrec(iv_obj_t * ps_codec_obj,void * pv_api_ip,void * pv_api_op)3046 WORD32 ihevcd_retrieve_memrec(iv_obj_t *ps_codec_obj,
3047                               void *pv_api_ip,
3048                               void *pv_api_op)
3049 {
3050 
3051     iv_retrieve_mem_rec_ip_t *dec_clr_ip;
3052     iv_retrieve_mem_rec_op_t *dec_clr_op;
3053     codec_t *ps_codec;
3054     dec_clr_ip = (iv_retrieve_mem_rec_ip_t *)pv_api_ip;
3055     dec_clr_op = (iv_retrieve_mem_rec_op_t *)pv_api_op;
3056     ps_codec = (codec_t *)(ps_codec_obj->pv_codec_handle);
3057 
3058     if(ps_codec->i4_init_done != 1)
3059     {
3060         dec_clr_op->u4_error_code |= 1 << IVD_FATALERROR;
3061         dec_clr_op->u4_error_code |= IHEVCD_INIT_NOT_DONE;
3062         return IV_FAIL;
3063     }
3064 
3065     memcpy(dec_clr_ip->pv_mem_rec_location, ps_codec->ps_mem_rec_backup,
3066            MEM_REC_CNT * (sizeof(iv_mem_rec_t)));
3067     dec_clr_op->u4_num_mem_rec_filled = MEM_REC_CNT;
3068 
3069 #ifdef APPLY_CONCEALMENT
3070     {
3071         IV_API_CALL_STATUS_T status;
3072         icncl_fill_mem_rec_ip_t cncl_fill_ip;
3073         icncl_fill_mem_rec_op_t cncl_fill_op;
3074 
3075         iv_mem_rec_t *ps_mem_rec;
3076 
3077         UWORD8 mem_loc = MEM_REC_CNT;
3078         UWORD8 num_cncl_mem = 0;
3079 
3080         ps_mem_rec = dec_clr_ip->pv_mem_rec_location;
3081 
3082         cncl_fill_ip.s_ivd_fill_mem_rec_ip_t.e_cmd = IV_CMD_FILL_NUM_MEM_REC;
3083         cncl_fill_ip.s_ivd_fill_mem_rec_ip_t.pv_mem_rec_location = &(ps_mem_rec[mem_loc]);
3084         cncl_fill_ip.s_ivd_fill_mem_rec_ip_t.u4_size = sizeof(icncl_fill_mem_rec_ip_t);
3085 
3086         status = icncl_api_function(NULL, (void *)&cncl_fill_ip, (void *)&cncl_fill_op);
3087 
3088         cncl_fill_ip.s_ivd_fill_mem_rec_ip_t.e_cmd = IV_CMD_RETRIEVE_MEMREC;
3089         cncl_fill_op.s_ivd_fill_mem_rec_op_t.u4_size = sizeof(icncl_fill_mem_rec_op_t);
3090 
3091         status = icncl_api_function(ps_codec->ps_conceal, (void *)&cncl_fill_ip, (void *)&cncl_fill_op);
3092 
3093         if(status == IV_SUCCESS)
3094         {
3095             /* Add the concealment library's memory requirements */
3096             dec_clr_op->u4_num_mem_rec_filled += cncl_fill_op.s_ivd_fill_mem_rec_op_t.u4_num_mem_rec_filled;
3097         }
3098     }
3099 #endif //APPLY_CONCEALMENT
3100     DEBUG("Retrieve num mem recs: %d\n",
3101                     dec_clr_op->u4_num_mem_rec_filled);
3102     STATS_PRINT();
3103     ihevcd_jobq_free((jobq_t *)ps_codec->pv_proc_jobq);
3104 
3105 
3106 
3107     return IV_SUCCESS;
3108 
3109 }
3110 /**
3111 *******************************************************************************
3112 *
3113 * @brief
3114 *  Passes display buffer from application to codec
3115 *
3116 * @par Description:
3117 *  Adds display buffer to the codec
3118 *
3119 * @param[in] ps_codec_obj
3120 *  Pointer to codec object at API level
3121 *
3122 * @param[in] pv_api_ip
3123 *  Pointer to input argument structure
3124 *
3125 * @param[out] pv_api_op
3126 *  Pointer to output argument structure
3127 *
3128 * @returns  Status
3129 *
3130 * @remarks
3131 *
3132 *
3133 *******************************************************************************
3134 */
ihevcd_set_display_frame(iv_obj_t * ps_codec_obj,void * pv_api_ip,void * pv_api_op)3135 WORD32 ihevcd_set_display_frame(iv_obj_t *ps_codec_obj,
3136                                 void *pv_api_ip,
3137                                 void *pv_api_op)
3138 {
3139     WORD32 ret = IV_SUCCESS;
3140 
3141     ivd_set_display_frame_ip_t *ps_dec_disp_ip;
3142     ivd_set_display_frame_op_t *ps_dec_disp_op;
3143 
3144     WORD32 i;
3145 
3146     codec_t *ps_codec = (codec_t *)(ps_codec_obj->pv_codec_handle);
3147 
3148     ps_dec_disp_ip = (ivd_set_display_frame_ip_t *)pv_api_ip;
3149     ps_dec_disp_op = (ivd_set_display_frame_op_t *)pv_api_op;
3150 
3151     ps_codec->i4_num_disp_bufs = 0;
3152     if(ps_codec->i4_share_disp_buf)
3153     {
3154         UWORD32 num_bufs = ps_dec_disp_ip->num_disp_bufs;
3155         pic_buf_t *ps_pic_buf;
3156         UWORD8 *pu1_buf;
3157         WORD32 buf_ret;
3158         WORD32 strd;
3159         strd = ps_codec->i4_strd;
3160         if(0 == strd)
3161             strd = ps_codec->i4_max_wd + PAD_WD;
3162         num_bufs = MIN(num_bufs, BUF_MGR_MAX_CNT);
3163         ps_codec->i4_num_disp_bufs = num_bufs;
3164 
3165         ps_pic_buf = (pic_buf_t *)ps_codec->ps_pic_buf;
3166         for(i = 0; i < (WORD32)num_bufs; i++)
3167         {
3168             pu1_buf =  ps_dec_disp_ip->s_disp_buffer[i].pu1_bufs[0];
3169             ps_pic_buf->pu1_luma = pu1_buf + strd * PAD_TOP + PAD_LEFT;
3170 
3171             if(ps_codec->e_chroma_fmt == IV_YUV_420P)
3172             {
3173                 pu1_buf =  ps_codec->pu1_cur_chroma_ref_buf;
3174                 ps_codec->pu1_cur_chroma_ref_buf += strd * (ps_codec->i4_ht / 2 + PAD_HT / 2);
3175                 ps_codec->i4_remaining_pic_buf_size -= strd * (ps_codec->i4_ht / 2 + PAD_HT / 2);
3176 
3177                 if(0 > ps_codec->i4_remaining_pic_buf_size)
3178                 {
3179                     ps_codec->i4_error_code = IHEVCD_BUF_MGR_ERROR;
3180                     return IHEVCD_BUF_MGR_ERROR;
3181                 }
3182 
3183             }
3184             else
3185             {
3186                 /* For YUV 420SP case use display buffer itself as chroma ref buffer */
3187                 pu1_buf =  ps_dec_disp_ip->s_disp_buffer[i].pu1_bufs[1];
3188             }
3189 
3190             ps_pic_buf->pu1_chroma = pu1_buf + strd * (PAD_TOP / 2) + PAD_LEFT;
3191 
3192             buf_ret = ihevc_buf_mgr_add((buf_mgr_t *)ps_codec->pv_pic_buf_mgr, ps_pic_buf, i);
3193 
3194             if(0 != buf_ret)
3195             {
3196                 ps_codec->i4_error_code = IHEVCD_BUF_MGR_ERROR;
3197                 return IHEVCD_BUF_MGR_ERROR;
3198             }
3199 
3200             /* Mark pic buf as needed for display */
3201             /* This ensures that till the buffer is explicitly passed to the codec,
3202              * application owns the buffer. Decoder is allowed to use a buffer only
3203              * when application sends it through fill this buffer call in OMX
3204              */
3205             ihevc_buf_mgr_set_status((buf_mgr_t *)ps_codec->pv_pic_buf_mgr, i, BUF_MGR_DISP);
3206 
3207             ps_pic_buf++;
3208 
3209             /* Store display buffers in codec context. Needed for 420p output */
3210             memcpy(&ps_codec->s_disp_buffer[ps_codec->i4_share_disp_buf_cnt],
3211                    &ps_dec_disp_ip->s_disp_buffer[i],
3212                    sizeof(ps_dec_disp_ip->s_disp_buffer[i]));
3213 
3214             ps_codec->i4_share_disp_buf_cnt++;
3215 
3216         }
3217     }
3218 
3219     ps_dec_disp_op->u4_error_code = 0;
3220     return ret;
3221 
3222 }
3223 
3224 /**
3225 *******************************************************************************
3226 *
3227 * @brief
3228 *  Sets the decoder in flush mode. Decoder will come out of  flush only
3229 * after returning all the buffers or at reset
3230 *
3231 * @par Description:
3232 *  Sets the decoder in flush mode
3233 *
3234 * @param[in] ps_codec_obj
3235 *  Pointer to codec object at API level
3236 *
3237 * @param[in] pv_api_ip
3238 *  Pointer to input argument structure
3239 *
3240 * @param[out] pv_api_op
3241 *  Pointer to output argument structure
3242 *
3243 * @returns  Status
3244 *
3245 * @remarks
3246 *
3247 *
3248 *******************************************************************************
3249 */
ihevcd_set_flush_mode(iv_obj_t * ps_codec_obj,void * pv_api_ip,void * pv_api_op)3250 WORD32 ihevcd_set_flush_mode(iv_obj_t *ps_codec_obj,
3251                              void *pv_api_ip,
3252                              void *pv_api_op)
3253 {
3254 
3255     codec_t *ps_codec;
3256     ivd_ctl_flush_op_t *ps_ctl_op = (ivd_ctl_flush_op_t *)pv_api_op;
3257     UNUSED(pv_api_ip);
3258     ps_codec = (codec_t *)(ps_codec_obj->pv_codec_handle);
3259 
3260     /* Signal flush frame control call */
3261     ps_codec->i4_flush_mode = 1;
3262 
3263     ps_ctl_op->u4_error_code = 0;
3264 
3265     /* Set pic count to zero, so that decoder starts buffering again */
3266     /* once it comes out of flush mode */
3267     ps_codec->u4_pic_cnt = 0;
3268     ps_codec->u4_disp_cnt = 0;
3269     return IV_SUCCESS;
3270 
3271 
3272 }
3273 
3274 /**
3275 *******************************************************************************
3276 *
3277 * @brief
3278 *  Gets decoder status and buffer requirements
3279 *
3280 * @par Description:
3281 *  Gets the decoder status
3282 *
3283 * @param[in] ps_codec_obj
3284 *  Pointer to codec object at API level
3285 *
3286 * @param[in] pv_api_ip
3287 *  Pointer to input argument structure
3288 *
3289 * @param[out] pv_api_op
3290 *  Pointer to output argument structure
3291 *
3292 * @returns  Status
3293 *
3294 * @remarks
3295 *
3296 *
3297 *******************************************************************************
3298 */
3299 
ihevcd_get_status(iv_obj_t * ps_codec_obj,void * pv_api_ip,void * pv_api_op)3300 WORD32 ihevcd_get_status(iv_obj_t *ps_codec_obj,
3301                          void *pv_api_ip,
3302                          void *pv_api_op)
3303 {
3304 
3305     WORD32 i;
3306     codec_t *ps_codec;
3307     WORD32 wd, ht;
3308     ivd_ctl_getstatus_op_t *ps_ctl_op = (ivd_ctl_getstatus_op_t *)pv_api_op;
3309 
3310     UNUSED(pv_api_ip);
3311 
3312     ps_ctl_op->u4_error_code = 0;
3313 
3314     ps_codec = (codec_t *)(ps_codec_obj->pv_codec_handle);
3315 
3316     ps_ctl_op->u4_min_num_in_bufs = MIN_IN_BUFS;
3317     if(ps_codec->e_chroma_fmt == IV_YUV_420P)
3318         ps_ctl_op->u4_min_num_out_bufs = MIN_OUT_BUFS_420;
3319     else if(ps_codec->e_chroma_fmt == IV_YUV_422ILE)
3320         ps_ctl_op->u4_min_num_out_bufs = MIN_OUT_BUFS_422ILE;
3321     else if(ps_codec->e_chroma_fmt == IV_RGB_565)
3322         ps_ctl_op->u4_min_num_out_bufs = MIN_OUT_BUFS_RGB565;
3323     else if(ps_codec->e_chroma_fmt == IV_RGBA_8888)
3324         ps_ctl_op->u4_min_num_out_bufs = MIN_OUT_BUFS_RGBA8888;
3325     else if((ps_codec->e_chroma_fmt == IV_YUV_420SP_UV)
3326                     || (ps_codec->e_chroma_fmt == IV_YUV_420SP_VU))
3327         ps_ctl_op->u4_min_num_out_bufs = MIN_OUT_BUFS_420SP;
3328 
3329     ps_ctl_op->u4_num_disp_bufs = 1;
3330 
3331     for(i = 0; i < (WORD32)ps_ctl_op->u4_min_num_in_bufs; i++)
3332     {
3333         ps_ctl_op->u4_min_in_buf_size[i] = MAX((ps_codec->i4_wd * ps_codec->i4_ht), MIN_BITSBUF_SIZE);
3334     }
3335 
3336     wd = ps_codec->i4_wd;
3337     ht = ps_codec->i4_ht;
3338 
3339     if(ps_codec->i4_sps_done)
3340     {
3341         if(0 == ps_codec->i4_share_disp_buf)
3342         {
3343             wd = ps_codec->i4_disp_wd;
3344             ht = ps_codec->i4_disp_ht;
3345 
3346         }
3347         else
3348         {
3349             wd = ps_codec->i4_disp_strd;
3350             ht = ps_codec->i4_ht + PAD_HT;
3351         }
3352     }
3353     else
3354     {
3355         if(0 == ps_codec->i4_share_disp_buf)
3356         {
3357             wd = ps_codec->i4_new_max_wd;
3358             ht = ps_codec->i4_new_max_ht;
3359         }
3360         else
3361         {
3362             wd = ALIGN32(wd + PAD_WD);
3363             ht += PAD_HT;
3364         }
3365     }
3366 
3367     if(ps_codec->i4_disp_strd > wd)
3368         wd = ps_codec->i4_disp_strd;
3369 
3370     if(0 == ps_codec->i4_share_disp_buf)
3371         ps_ctl_op->u4_num_disp_bufs = 1;
3372     else
3373     {
3374         WORD32 pic_size;
3375         WORD32 max_dpb_size;
3376 
3377         if(ps_codec->i4_sps_done)
3378         {
3379             sps_t *ps_sps = (ps_codec->s_parse.ps_sps_base + ps_codec->i4_sps_id);
3380             WORD32 reorder_pic_cnt;
3381             WORD32 ref_pic_cnt;
3382             WORD32 level;
3383 
3384             reorder_pic_cnt = MIN(ps_sps->ai1_sps_max_num_reorder_pics[0], ps_codec->i4_init_num_reorder);
3385             pic_size = ps_sps->i2_pic_width_in_luma_samples * ps_sps->i2_pic_height_in_luma_samples;
3386 
3387             level = ps_codec->i4_init_level;
3388             max_dpb_size = ihevcd_get_dpb_size(level, pic_size);
3389             ref_pic_cnt = max_dpb_size;
3390             ps_ctl_op->u4_num_disp_bufs = reorder_pic_cnt;
3391 
3392             ps_ctl_op->u4_num_disp_bufs += ref_pic_cnt + 1;
3393 
3394         }
3395         else
3396         {
3397             pic_size = ps_codec->i4_max_wd * ps_codec->i4_max_ht;
3398             max_dpb_size = ihevcd_get_dpb_size(ps_codec->i4_init_level, pic_size);
3399             ps_ctl_op->u4_num_disp_bufs = 2 * max_dpb_size;
3400 
3401             ps_ctl_op->u4_num_disp_bufs = MIN(ps_ctl_op->u4_num_disp_bufs,
3402                             (UWORD32)(ps_codec->i4_init_num_ref + ps_codec->i4_init_num_reorder + 1));
3403 
3404         }
3405 
3406         ps_ctl_op->u4_num_disp_bufs = MIN(
3407                         ps_ctl_op->u4_num_disp_bufs, 32);
3408     }
3409 
3410     /*!*/
3411     if(ps_codec->e_chroma_fmt == IV_YUV_420P)
3412     {
3413         ps_ctl_op->u4_min_out_buf_size[0] = (wd * ht);
3414         ps_ctl_op->u4_min_out_buf_size[1] = (wd * ht) >> 2;
3415         ps_ctl_op->u4_min_out_buf_size[2] = (wd * ht) >> 2;
3416     }
3417     else if(ps_codec->e_chroma_fmt == IV_YUV_422ILE)
3418     {
3419         ps_ctl_op->u4_min_out_buf_size[0] = (wd * ht) * 2;
3420         ps_ctl_op->u4_min_out_buf_size[1] =
3421                         ps_ctl_op->u4_min_out_buf_size[2] = 0;
3422     }
3423     else if(ps_codec->e_chroma_fmt == IV_RGB_565)
3424     {
3425         ps_ctl_op->u4_min_out_buf_size[0] = (wd * ht) * 2;
3426         ps_ctl_op->u4_min_out_buf_size[1] =
3427                         ps_ctl_op->u4_min_out_buf_size[2] = 0;
3428     }
3429     else if(ps_codec->e_chroma_fmt == IV_RGBA_8888)
3430     {
3431         ps_ctl_op->u4_min_out_buf_size[0] = (wd * ht) * 4;
3432         ps_ctl_op->u4_min_out_buf_size[1] =
3433                         ps_ctl_op->u4_min_out_buf_size[2] = 0;
3434     }
3435     else if((ps_codec->e_chroma_fmt == IV_YUV_420SP_UV)
3436                     || (ps_codec->e_chroma_fmt == IV_YUV_420SP_VU))
3437     {
3438         ps_ctl_op->u4_min_out_buf_size[0] = (wd * ht);
3439         ps_ctl_op->u4_min_out_buf_size[1] = (wd * ht) >> 1;
3440         ps_ctl_op->u4_min_out_buf_size[2] = 0;
3441     }
3442     ps_ctl_op->u4_pic_ht = ht;
3443     ps_ctl_op->u4_pic_wd = wd;
3444     ps_ctl_op->u4_frame_rate = 30000;
3445     ps_ctl_op->u4_bit_rate = 1000000;
3446     ps_ctl_op->e_content_type = IV_PROGRESSIVE;
3447     ps_ctl_op->e_output_chroma_format = ps_codec->e_chroma_fmt;
3448     ps_codec->i4_num_disp_bufs = ps_ctl_op->u4_num_disp_bufs;
3449 
3450     if(ps_ctl_op->u4_size == sizeof(ihevcd_cxa_ctl_getstatus_op_t))
3451     {
3452         ihevcd_cxa_ctl_getstatus_op_t *ps_ext_ctl_op = (ihevcd_cxa_ctl_getstatus_op_t *)ps_ctl_op;
3453         ps_ext_ctl_op->u4_coded_pic_wd = ps_codec->i4_wd;
3454         ps_ext_ctl_op->u4_coded_pic_wd = ps_codec->i4_ht;
3455     }
3456     return IV_SUCCESS;
3457 }
3458 /**
3459 *******************************************************************************
3460 *
3461 * @brief
3462 *  Gets decoder buffer requirements
3463 *
3464 * @par Description:
3465 *  Gets the decoder buffer requirements. If called before  header decoder,
3466 * buffer requirements are based on max_wd  and max_ht else actual width and
3467 * height will be used
3468 *
3469 * @param[in] ps_codec_obj
3470 *  Pointer to codec object at API level
3471 *
3472 * @param[in] pv_api_ip
3473 *  Pointer to input argument structure
3474 *
3475 * @param[out] pv_api_op
3476 *  Pointer to output argument structure
3477 *
3478 * @returns  Status
3479 *
3480 * @remarks
3481 *
3482 *
3483 *******************************************************************************
3484 */
ihevcd_get_buf_info(iv_obj_t * ps_codec_obj,void * pv_api_ip,void * pv_api_op)3485 WORD32 ihevcd_get_buf_info(iv_obj_t *ps_codec_obj,
3486                            void *pv_api_ip,
3487                            void *pv_api_op)
3488 {
3489 
3490     codec_t *ps_codec;
3491     UWORD32 i = 0;
3492     WORD32 wd, ht;
3493     ivd_ctl_getbufinfo_op_t *ps_ctl_op =
3494                     (ivd_ctl_getbufinfo_op_t *)pv_api_op;
3495 
3496     UNUSED(pv_api_ip);
3497     ps_ctl_op->u4_error_code = 0;
3498 
3499     ps_codec = (codec_t *)(ps_codec_obj->pv_codec_handle);
3500 
3501     ps_ctl_op->u4_min_num_in_bufs = MIN_IN_BUFS;
3502     if(ps_codec->e_chroma_fmt == IV_YUV_420P)
3503         ps_ctl_op->u4_min_num_out_bufs = MIN_OUT_BUFS_420;
3504     else if(ps_codec->e_chroma_fmt == IV_YUV_422ILE)
3505         ps_ctl_op->u4_min_num_out_bufs = MIN_OUT_BUFS_422ILE;
3506     else if(ps_codec->e_chroma_fmt == IV_RGB_565)
3507         ps_ctl_op->u4_min_num_out_bufs = MIN_OUT_BUFS_RGB565;
3508     else if(ps_codec->e_chroma_fmt == IV_RGBA_8888)
3509         ps_ctl_op->u4_min_num_out_bufs = MIN_OUT_BUFS_RGBA8888;
3510     else if((ps_codec->e_chroma_fmt == IV_YUV_420SP_UV)
3511                     || (ps_codec->e_chroma_fmt == IV_YUV_420SP_VU))
3512         ps_ctl_op->u4_min_num_out_bufs = MIN_OUT_BUFS_420SP;
3513 
3514     ps_ctl_op->u4_num_disp_bufs = 1;
3515 
3516     for(i = 0; i < ps_ctl_op->u4_min_num_in_bufs; i++)
3517     {
3518         ps_ctl_op->u4_min_in_buf_size[i] = MAX((ps_codec->i4_wd * ps_codec->i4_ht), MIN_BITSBUF_SIZE);
3519     }
3520 
3521     wd = ps_codec->i4_max_wd;
3522     ht = ps_codec->i4_max_ht;
3523 
3524     if(ps_codec->i4_sps_done)
3525     {
3526         if(0 == ps_codec->i4_share_disp_buf)
3527         {
3528             wd = ps_codec->i4_disp_wd;
3529             ht = ps_codec->i4_disp_ht;
3530 
3531         }
3532         else
3533         {
3534             wd = ps_codec->i4_disp_strd;
3535             ht = ps_codec->i4_ht + PAD_HT;
3536         }
3537     }
3538     else
3539     {
3540         if(1 == ps_codec->i4_share_disp_buf)
3541         {
3542             wd = ALIGN32(wd + PAD_WD);
3543             ht += PAD_HT;
3544         }
3545     }
3546 
3547     if(ps_codec->i4_disp_strd > wd)
3548         wd = ps_codec->i4_disp_strd;
3549 
3550     if(0 == ps_codec->i4_share_disp_buf)
3551         ps_ctl_op->u4_num_disp_bufs = 1;
3552     else
3553     {
3554         WORD32 pic_size;
3555         WORD32 max_dpb_size;
3556 
3557         if(ps_codec->i4_sps_done)
3558         {
3559             sps_t *ps_sps = (ps_codec->s_parse.ps_sps_base + ps_codec->i4_sps_id);
3560             WORD32 reorder_pic_cnt;
3561             WORD32 ref_pic_cnt;
3562             WORD32 level;
3563 
3564             reorder_pic_cnt = MIN(ps_sps->ai1_sps_max_num_reorder_pics[0], ps_codec->i4_init_num_reorder);
3565             pic_size = ps_sps->i2_pic_width_in_luma_samples * ps_sps->i2_pic_height_in_luma_samples;
3566 
3567             level = ps_codec->i4_init_level;
3568             max_dpb_size = ihevcd_get_dpb_size(level, pic_size);
3569             ref_pic_cnt = max_dpb_size;
3570             ps_ctl_op->u4_num_disp_bufs = reorder_pic_cnt;
3571 
3572             ps_ctl_op->u4_num_disp_bufs += ref_pic_cnt + 1;
3573 
3574         }
3575         else
3576         {
3577             pic_size = ps_codec->i4_max_wd * ps_codec->i4_max_ht;
3578             max_dpb_size = ihevcd_get_dpb_size(ps_codec->i4_init_level, pic_size);
3579             ps_ctl_op->u4_num_disp_bufs = 2 * max_dpb_size;
3580 
3581             ps_ctl_op->u4_num_disp_bufs = MIN(ps_ctl_op->u4_num_disp_bufs,
3582                             (UWORD32)(ps_codec->i4_init_num_ref + ps_codec->i4_init_num_reorder + 1));
3583 
3584         }
3585 
3586         ps_ctl_op->u4_num_disp_bufs = MIN(
3587                         ps_ctl_op->u4_num_disp_bufs, 32);
3588 
3589     }
3590 
3591     /*!*/
3592     if(ps_codec->e_chroma_fmt == IV_YUV_420P)
3593     {
3594         ps_ctl_op->u4_min_out_buf_size[0] = (wd * ht);
3595         ps_ctl_op->u4_min_out_buf_size[1] = (wd * ht) >> 2;
3596         ps_ctl_op->u4_min_out_buf_size[2] = (wd * ht) >> 2;
3597     }
3598     else if(ps_codec->e_chroma_fmt == IV_YUV_422ILE)
3599     {
3600         ps_ctl_op->u4_min_out_buf_size[0] = (wd * ht) * 2;
3601         ps_ctl_op->u4_min_out_buf_size[1] =
3602                         ps_ctl_op->u4_min_out_buf_size[2] = 0;
3603     }
3604     else if(ps_codec->e_chroma_fmt == IV_RGB_565)
3605     {
3606         ps_ctl_op->u4_min_out_buf_size[0] = (wd * ht) * 2;
3607         ps_ctl_op->u4_min_out_buf_size[1] =
3608                         ps_ctl_op->u4_min_out_buf_size[2] = 0;
3609     }
3610     else if(ps_codec->e_chroma_fmt == IV_RGBA_8888)
3611     {
3612         ps_ctl_op->u4_min_out_buf_size[0] = (wd * ht) * 4;
3613         ps_ctl_op->u4_min_out_buf_size[1] =
3614                         ps_ctl_op->u4_min_out_buf_size[2] = 0;
3615     }
3616     else if((ps_codec->e_chroma_fmt == IV_YUV_420SP_UV)
3617                     || (ps_codec->e_chroma_fmt == IV_YUV_420SP_VU))
3618     {
3619         ps_ctl_op->u4_min_out_buf_size[0] = (wd * ht);
3620         ps_ctl_op->u4_min_out_buf_size[1] = (wd * ht) >> 1;
3621         ps_ctl_op->u4_min_out_buf_size[2] = 0;
3622     }
3623     ps_codec->i4_num_disp_bufs = ps_ctl_op->u4_num_disp_bufs;
3624 
3625     return IV_SUCCESS;
3626 }
3627 
3628 
3629 /**
3630 *******************************************************************************
3631 *
3632 * @brief
3633 *  Sets dynamic parameters
3634 *
3635 * @par Description:
3636 *  Sets dynamic parameters. Note Frame skip, decode header  mode are dynamic
3637 *  Dynamic change in stride is not  supported
3638 *
3639 * @param[in] ps_codec_obj
3640 *  Pointer to codec object at API level
3641 *
3642 * @param[in] pv_api_ip
3643 *  Pointer to input argument structure
3644 *
3645 * @param[out] pv_api_op
3646 *  Pointer to output argument structure
3647 *
3648 * @returns  Status
3649 *
3650 * @remarks
3651 *
3652 *
3653 *******************************************************************************
3654 */
ihevcd_set_params(iv_obj_t * ps_codec_obj,void * pv_api_ip,void * pv_api_op)3655 WORD32 ihevcd_set_params(iv_obj_t *ps_codec_obj,
3656                          void *pv_api_ip,
3657                          void *pv_api_op)
3658 {
3659 
3660     codec_t *ps_codec;
3661     WORD32 ret = IV_SUCCESS;
3662     WORD32 strd;
3663     ivd_ctl_set_config_ip_t *s_ctl_dynparams_ip =
3664                     (ivd_ctl_set_config_ip_t *)pv_api_ip;
3665     ivd_ctl_set_config_op_t *s_ctl_dynparams_op =
3666                     (ivd_ctl_set_config_op_t *)pv_api_op;
3667 
3668     ps_codec = (codec_t *)(ps_codec_obj->pv_codec_handle);
3669 
3670     s_ctl_dynparams_op->u4_error_code = 0;
3671 
3672     ps_codec->e_pic_skip_mode = s_ctl_dynparams_ip->e_frm_skip_mode;
3673 
3674     if(s_ctl_dynparams_ip->e_frm_skip_mode != IVD_SKIP_NONE)
3675     {
3676 
3677         if((s_ctl_dynparams_ip->e_frm_skip_mode != IVD_SKIP_P) &&
3678            (s_ctl_dynparams_ip->e_frm_skip_mode != IVD_SKIP_B) &&
3679            (s_ctl_dynparams_ip->e_frm_skip_mode != IVD_SKIP_PB))
3680         {
3681             s_ctl_dynparams_op->u4_error_code = (1 << IVD_UNSUPPORTEDPARAM);
3682             ret = IV_FAIL;
3683         }
3684     }
3685 
3686     strd = ps_codec->i4_disp_strd;
3687     if(1 == ps_codec->i4_share_disp_buf)
3688     {
3689         strd = ps_codec->i4_strd;
3690     }
3691 
3692 
3693     if((-1 != (WORD32)s_ctl_dynparams_ip->u4_disp_wd) &&
3694                     (0  != s_ctl_dynparams_ip->u4_disp_wd) &&
3695                     (0  != strd) &&
3696                     ((WORD32)s_ctl_dynparams_ip->u4_disp_wd < strd))
3697     {
3698         s_ctl_dynparams_op->u4_error_code |= (1 << IVD_UNSUPPORTEDPARAM);
3699         s_ctl_dynparams_op->u4_error_code |= IHEVCD_INVALID_DISP_STRD;
3700         ret = IV_FAIL;
3701     }
3702     else
3703     {
3704         if((WORD32)s_ctl_dynparams_ip->u4_disp_wd >= ps_codec->i4_wd)
3705         {
3706             strd = s_ctl_dynparams_ip->u4_disp_wd;
3707         }
3708         else if(0 == ps_codec->i4_sps_done)
3709         {
3710             strd = s_ctl_dynparams_ip->u4_disp_wd;
3711         }
3712         else if(s_ctl_dynparams_ip->u4_disp_wd == 0)
3713         {
3714             strd = ps_codec->i4_disp_strd;
3715         }
3716         else
3717         {
3718             strd = 0;
3719             s_ctl_dynparams_op->u4_error_code |= (1 << IVD_UNSUPPORTEDPARAM);
3720             s_ctl_dynparams_op->u4_error_code |= IHEVCD_INVALID_DISP_STRD;
3721             ret = IV_FAIL;
3722         }
3723     }
3724 
3725     ps_codec->i4_disp_strd = strd;
3726     if(1 == ps_codec->i4_share_disp_buf)
3727     {
3728         ps_codec->i4_strd = strd;
3729     }
3730 
3731     if(s_ctl_dynparams_ip->e_vid_dec_mode == IVD_DECODE_FRAME)
3732         ps_codec->i4_header_mode = 0;
3733     else if(s_ctl_dynparams_ip->e_vid_dec_mode == IVD_DECODE_HEADER)
3734         ps_codec->i4_header_mode = 1;
3735     else
3736     {
3737 
3738         s_ctl_dynparams_op->u4_error_code = (1 << IVD_UNSUPPORTEDPARAM);
3739         ps_codec->i4_header_mode = 1;
3740         ret = IV_FAIL;
3741     }
3742 
3743 
3744     return ret;
3745 
3746 }
3747 /**
3748 *******************************************************************************
3749 *
3750 * @brief
3751 *  Resets the decoder state
3752 *
3753 * @par Description:
3754 *  Resets the decoder state by calling ihevcd_init()
3755 *
3756 * @param[in] ps_codec_obj
3757 *  Pointer to codec object at API level
3758 *
3759 * @param[in] pv_api_ip
3760 *  Pointer to input argument structure
3761 *
3762 * @param[out] pv_api_op
3763 *  Pointer to output argument structure
3764 *
3765 * @returns  Status
3766 *
3767 * @remarks
3768 *
3769 *
3770 *******************************************************************************
3771 */
ihevcd_reset(iv_obj_t * ps_codec_obj,void * pv_api_ip,void * pv_api_op)3772 WORD32 ihevcd_reset(iv_obj_t *ps_codec_obj, void *pv_api_ip, void *pv_api_op)
3773 {
3774     codec_t *ps_codec;
3775     ivd_ctl_reset_op_t *s_ctl_reset_op = (ivd_ctl_reset_op_t *)pv_api_op;
3776     UNUSED(pv_api_ip);
3777     ps_codec = (codec_t *)(ps_codec_obj->pv_codec_handle);
3778 
3779     if(ps_codec != NULL)
3780     {
3781         DEBUG("\nReset called \n");
3782         ihevcd_init(ps_codec);
3783     }
3784     else
3785     {
3786         DEBUG("\nReset called without Initializing the decoder\n");
3787         s_ctl_reset_op->u4_error_code = IHEVCD_INIT_NOT_DONE;
3788     }
3789 
3790     return IV_SUCCESS;
3791 }
3792 
3793 /**
3794 *******************************************************************************
3795 *
3796 * @brief
3797 *  Releases display buffer from application to codec  to signal to the codec
3798 * that it can write to this buffer  if required. Till release is called,
3799 * codec can not write  to this buffer
3800 *
3801 * @par Description:
3802 *  Marks the buffer as display done
3803 *
3804 * @param[in] ps_codec_obj
3805 *  Pointer to codec object at API level
3806 *
3807 * @param[in] pv_api_ip
3808 *  Pointer to input argument structure
3809 *
3810 * @param[out] pv_api_op
3811 *  Pointer to output argument structure
3812 *
3813 * @returns  Status
3814 *
3815 * @remarks
3816 *
3817 *
3818 *******************************************************************************
3819 */
3820 
ihevcd_rel_display_frame(iv_obj_t * ps_codec_obj,void * pv_api_ip,void * pv_api_op)3821 WORD32 ihevcd_rel_display_frame(iv_obj_t *ps_codec_obj,
3822                                 void *pv_api_ip,
3823                                 void *pv_api_op)
3824 {
3825 
3826     ivd_rel_display_frame_ip_t *ps_dec_rel_disp_ip;
3827     ivd_rel_display_frame_op_t *ps_dec_rel_disp_op;
3828 
3829     codec_t *ps_codec = (codec_t *)ps_codec_obj->pv_codec_handle;
3830 
3831     ps_dec_rel_disp_ip = (ivd_rel_display_frame_ip_t *)pv_api_ip;
3832     ps_dec_rel_disp_op = (ivd_rel_display_frame_op_t *)pv_api_op;
3833 
3834     UNUSED(ps_dec_rel_disp_op);
3835 
3836     if(0 == ps_codec->i4_share_disp_buf)
3837     {
3838         return IV_SUCCESS;
3839     }
3840 
3841     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);
3842 
3843     return IV_SUCCESS;
3844 }
3845 /**
3846 *******************************************************************************
3847 *
3848 * @brief
3849 *  Sets degrade params
3850 *
3851 * @par Description:
3852 *  Sets degrade params.
3853 *  Refer to ihevcd_cxa_ctl_degrade_ip_t definition for details
3854 *
3855 * @param[in] ps_codec_obj
3856 *  Pointer to codec object at API level
3857 *
3858 * @param[in] pv_api_ip
3859 *  Pointer to input argument structure
3860 *
3861 * @param[out] pv_api_op
3862 *  Pointer to output argument structure
3863 *
3864 * @returns  Status
3865 *
3866 * @remarks
3867 *
3868 *
3869 *******************************************************************************
3870 */
3871 
ihevcd_set_degrade(iv_obj_t * ps_codec_obj,void * pv_api_ip,void * pv_api_op)3872 WORD32 ihevcd_set_degrade(iv_obj_t *ps_codec_obj,
3873                           void *pv_api_ip,
3874                           void *pv_api_op)
3875 {
3876     ihevcd_cxa_ctl_degrade_ip_t *ps_ip;
3877     ihevcd_cxa_ctl_degrade_op_t *ps_op;
3878     codec_t *ps_codec = (codec_t *)ps_codec_obj->pv_codec_handle;
3879 
3880     ps_ip = (ihevcd_cxa_ctl_degrade_ip_t *)pv_api_ip;
3881     ps_op = (ihevcd_cxa_ctl_degrade_op_t *)pv_api_op;
3882 
3883     ps_codec->i4_degrade_type = ps_ip->i4_degrade_type;
3884     ps_codec->i4_nondegrade_interval = ps_ip->i4_nondegrade_interval;
3885     ps_codec->i4_degrade_pics = ps_ip->i4_degrade_pics;
3886 
3887     ps_op->u4_error_code = 0;
3888     ps_codec->i4_degrade_pic_cnt = 0;
3889 
3890     return IV_SUCCESS;
3891 }
3892 
3893 
3894 /**
3895 *******************************************************************************
3896 *
3897 * @brief
3898 *  Gets frame dimensions/offsets
3899 *
3900 * @par Description:
3901 *  Gets frame buffer chararacteristics such a x & y offsets  display and
3902 * buffer dimensions
3903 *
3904 * @param[in] ps_codec_obj
3905 *  Pointer to codec object at API level
3906 *
3907 * @param[in] pv_api_ip
3908 *  Pointer to input argument structure
3909 *
3910 * @param[out] pv_api_op
3911 *  Pointer to output argument structure
3912 *
3913 * @returns  Status
3914 *
3915 * @remarks
3916 *
3917 *
3918 *******************************************************************************
3919 */
3920 
ihevcd_get_frame_dimensions(iv_obj_t * ps_codec_obj,void * pv_api_ip,void * pv_api_op)3921 WORD32 ihevcd_get_frame_dimensions(iv_obj_t *ps_codec_obj,
3922                                    void *pv_api_ip,
3923                                    void *pv_api_op)
3924 {
3925     ihevcd_cxa_ctl_get_frame_dimensions_ip_t *ps_ip;
3926     ihevcd_cxa_ctl_get_frame_dimensions_op_t *ps_op;
3927     codec_t *ps_codec = (codec_t *)ps_codec_obj->pv_codec_handle;
3928     WORD32 disp_wd, disp_ht, buffer_wd, buffer_ht, x_offset, y_offset;
3929     ps_ip = (ihevcd_cxa_ctl_get_frame_dimensions_ip_t *)pv_api_ip;
3930     ps_op = (ihevcd_cxa_ctl_get_frame_dimensions_op_t *)pv_api_op;
3931     UNUSED(ps_ip);
3932     if(ps_codec->i4_sps_done)
3933     {
3934         disp_wd = ps_codec->i4_disp_wd;
3935         disp_ht = ps_codec->i4_disp_ht;
3936 
3937         if(0 == ps_codec->i4_share_disp_buf)
3938         {
3939             buffer_wd = disp_wd;
3940             buffer_ht = disp_ht;
3941         }
3942         else
3943         {
3944             buffer_wd = ps_codec->i4_strd;
3945             buffer_ht = ps_codec->i4_ht + PAD_HT;
3946         }
3947     }
3948     else
3949     {
3950 
3951         disp_wd = ps_codec->i4_max_wd;
3952         disp_ht = ps_codec->i4_max_ht;
3953 
3954         if(0 == ps_codec->i4_share_disp_buf)
3955         {
3956             buffer_wd = disp_wd;
3957             buffer_ht = disp_ht;
3958         }
3959         else
3960         {
3961             buffer_wd = ALIGN16(disp_wd) + PAD_WD;
3962             buffer_ht = ALIGN16(disp_ht) + PAD_HT;
3963 
3964         }
3965     }
3966     if(ps_codec->i4_strd > buffer_wd)
3967         buffer_wd = ps_codec->i4_strd;
3968 
3969     if(0 == ps_codec->i4_share_disp_buf)
3970     {
3971         x_offset = 0;
3972         y_offset = 0;
3973     }
3974     else
3975     {
3976         y_offset = PAD_TOP;
3977         x_offset = PAD_LEFT;
3978     }
3979 
3980     ps_op->u4_disp_wd[0] = disp_wd;
3981     ps_op->u4_disp_ht[0] = disp_ht;
3982     ps_op->u4_buffer_wd[0] = buffer_wd;
3983     ps_op->u4_buffer_ht[0] = buffer_ht;
3984     ps_op->u4_x_offset[0] = x_offset;
3985     ps_op->u4_y_offset[0] = y_offset;
3986 
3987     ps_op->u4_disp_wd[1] = ps_op->u4_disp_wd[2] = ((ps_op->u4_disp_wd[0] + 1)
3988                     >> 1);
3989     ps_op->u4_disp_ht[1] = ps_op->u4_disp_ht[2] = ((ps_op->u4_disp_ht[0] + 1)
3990                     >> 1);
3991     ps_op->u4_buffer_wd[1] = ps_op->u4_buffer_wd[2] = (ps_op->u4_buffer_wd[0]
3992                     >> 1);
3993     ps_op->u4_buffer_ht[1] = ps_op->u4_buffer_ht[2] = (ps_op->u4_buffer_ht[0]
3994                     >> 1);
3995     ps_op->u4_x_offset[1] = ps_op->u4_x_offset[2] = (ps_op->u4_x_offset[0]
3996                     >> 1);
3997     ps_op->u4_y_offset[1] = ps_op->u4_y_offset[2] = (ps_op->u4_y_offset[0]
3998                     >> 1);
3999 
4000     if((ps_codec->e_chroma_fmt == IV_YUV_420SP_UV)
4001                     || (ps_codec->e_chroma_fmt == IV_YUV_420SP_VU))
4002     {
4003         ps_op->u4_disp_wd[2] = 0;
4004         ps_op->u4_disp_ht[2] = 0;
4005         ps_op->u4_buffer_wd[2] = 0;
4006         ps_op->u4_buffer_ht[2] = 0;
4007         ps_op->u4_x_offset[2] = 0;
4008         ps_op->u4_y_offset[2] = 0;
4009 
4010         ps_op->u4_disp_wd[1] <<= 1;
4011         ps_op->u4_buffer_wd[1] <<= 1;
4012         ps_op->u4_x_offset[1] <<= 1;
4013     }
4014 
4015     return IV_SUCCESS;
4016 
4017 }
4018 
4019 
4020 /**
4021 *******************************************************************************
4022 *
4023 * @brief
4024 *  Gets vui parameters
4025 *
4026 * @par Description:
4027 *  Gets VUI parameters
4028 *
4029 * @param[in] ps_codec_obj
4030 *  Pointer to codec object at API level
4031 *
4032 * @param[in] pv_api_ip
4033 *  Pointer to input argument structure
4034 *
4035 * @param[out] pv_api_op
4036 *  Pointer to output argument structure
4037 *
4038 * @returns  Status
4039 *
4040 * @remarks
4041 *
4042 *
4043 *******************************************************************************
4044 */
ihevcd_get_vui_params(iv_obj_t * ps_codec_obj,void * pv_api_ip,void * pv_api_op)4045 WORD32 ihevcd_get_vui_params(iv_obj_t *ps_codec_obj,
4046                              void *pv_api_ip,
4047                              void *pv_api_op)
4048 {
4049     ihevcd_cxa_ctl_get_vui_params_ip_t *ps_ip;
4050     ihevcd_cxa_ctl_get_vui_params_op_t *ps_op;
4051     codec_t *ps_codec = (codec_t *)ps_codec_obj->pv_codec_handle;
4052     sps_t *ps_sps;
4053     vui_t *ps_vui;
4054     WORD32 i;
4055 
4056     ps_ip = (ihevcd_cxa_ctl_get_vui_params_ip_t *)pv_api_ip;
4057     ps_op = (ihevcd_cxa_ctl_get_vui_params_op_t *)pv_api_op;
4058 
4059     if(0 == ps_codec->i4_sps_done)
4060     {
4061         ps_op->u4_error_code = IHEVCD_VUI_PARAMS_NOT_FOUND;
4062         return IV_FAIL;
4063     }
4064 
4065     ps_sps = ps_codec->s_parse.ps_sps;
4066     if(0 == ps_sps->i1_sps_valid || 0 == ps_sps->i1_vui_parameters_present_flag)
4067     {
4068         WORD32 sps_idx = 0;
4069         ps_sps = ps_codec->ps_sps_base;
4070 
4071         while((0 == ps_sps->i1_sps_valid) || (0 == ps_sps->i1_vui_parameters_present_flag))
4072         {
4073             sps_idx++;
4074             ps_sps++;
4075 
4076             if(sps_idx == MAX_SPS_CNT - 1)
4077             {
4078                 ps_op->u4_error_code = IHEVCD_VUI_PARAMS_NOT_FOUND;
4079                 return IV_FAIL;
4080             }
4081         }
4082     }
4083 
4084     ps_vui = &ps_sps->s_vui_parameters;
4085     UNUSED(ps_ip);
4086 
4087     ps_op->u1_aspect_ratio_info_present_flag         =  ps_vui->u1_aspect_ratio_info_present_flag;
4088     ps_op->u1_aspect_ratio_idc                       =  ps_vui->u1_aspect_ratio_idc;
4089     ps_op->u2_sar_width                              =  ps_vui->u2_sar_width;
4090     ps_op->u2_sar_height                             =  ps_vui->u2_sar_height;
4091     ps_op->u1_overscan_info_present_flag             =  ps_vui->u1_overscan_info_present_flag;
4092     ps_op->u1_overscan_appropriate_flag              =  ps_vui->u1_overscan_appropriate_flag;
4093     ps_op->u1_video_signal_type_present_flag         =  ps_vui->u1_video_signal_type_present_flag;
4094     ps_op->u1_video_format                           =  ps_vui->u1_video_format;
4095     ps_op->u1_video_full_range_flag                  =  ps_vui->u1_video_full_range_flag;
4096     ps_op->u1_colour_description_present_flag        =  ps_vui->u1_colour_description_present_flag;
4097     ps_op->u1_colour_primaries                       =  ps_vui->u1_colour_primaries;
4098     ps_op->u1_transfer_characteristics               =  ps_vui->u1_transfer_characteristics;
4099     ps_op->u1_matrix_coefficients                    =  ps_vui->u1_matrix_coefficients;
4100     ps_op->u1_chroma_loc_info_present_flag           =  ps_vui->u1_chroma_loc_info_present_flag;
4101     ps_op->u1_chroma_sample_loc_type_top_field       =  ps_vui->u1_chroma_sample_loc_type_top_field;
4102     ps_op->u1_chroma_sample_loc_type_bottom_field    =  ps_vui->u1_chroma_sample_loc_type_bottom_field;
4103     ps_op->u1_neutral_chroma_indication_flag         =  ps_vui->u1_neutral_chroma_indication_flag;
4104     ps_op->u1_field_seq_flag                         =  ps_vui->u1_field_seq_flag;
4105     ps_op->u1_frame_field_info_present_flag          =  ps_vui->u1_frame_field_info_present_flag;
4106     ps_op->u1_default_display_window_flag            =  ps_vui->u1_default_display_window_flag;
4107     ps_op->u4_def_disp_win_left_offset               =  ps_vui->u4_def_disp_win_left_offset;
4108     ps_op->u4_def_disp_win_right_offset              =  ps_vui->u4_def_disp_win_right_offset;
4109     ps_op->u4_def_disp_win_top_offset                =  ps_vui->u4_def_disp_win_top_offset;
4110     ps_op->u4_def_disp_win_bottom_offset             =  ps_vui->u4_def_disp_win_bottom_offset;
4111     ps_op->u1_vui_hrd_parameters_present_flag        =  ps_vui->u1_vui_hrd_parameters_present_flag;
4112     ps_op->u1_vui_timing_info_present_flag           =  ps_vui->u1_vui_timing_info_present_flag;
4113     ps_op->u4_vui_num_units_in_tick                  =  ps_vui->u4_vui_num_units_in_tick;
4114     ps_op->u4_vui_time_scale                         =  ps_vui->u4_vui_time_scale;
4115     ps_op->u1_poc_proportional_to_timing_flag        =  ps_vui->u1_poc_proportional_to_timing_flag;
4116     ps_op->u1_num_ticks_poc_diff_one_minus1          =  ps_vui->u1_num_ticks_poc_diff_one_minus1;
4117     ps_op->u1_bitstream_restriction_flag             =  ps_vui->u1_bitstream_restriction_flag;
4118     ps_op->u1_tiles_fixed_structure_flag             =  ps_vui->u1_tiles_fixed_structure_flag;
4119     ps_op->u1_motion_vectors_over_pic_boundaries_flag =  ps_vui->u1_motion_vectors_over_pic_boundaries_flag;
4120     ps_op->u1_restricted_ref_pic_lists_flag          =  ps_vui->u1_restricted_ref_pic_lists_flag;
4121     ps_op->u4_min_spatial_segmentation_idc           =  ps_vui->u4_min_spatial_segmentation_idc;
4122     ps_op->u1_max_bytes_per_pic_denom                =  ps_vui->u1_max_bytes_per_pic_denom;
4123     ps_op->u1_max_bits_per_mincu_denom               =  ps_vui->u1_max_bits_per_mincu_denom;
4124     ps_op->u1_log2_max_mv_length_horizontal          =  ps_vui->u1_log2_max_mv_length_horizontal;
4125     ps_op->u1_log2_max_mv_length_vertical            =  ps_vui->u1_log2_max_mv_length_vertical;
4126 
4127 
4128     /* HRD parameters */
4129     ps_op->u1_timing_info_present_flag                         =    ps_vui->s_vui_hrd_parameters.u1_timing_info_present_flag;
4130     ps_op->u4_num_units_in_tick                                =    ps_vui->s_vui_hrd_parameters.u4_num_units_in_tick;
4131     ps_op->u4_time_scale                                       =    ps_vui->s_vui_hrd_parameters.u4_time_scale;
4132     ps_op->u1_nal_hrd_parameters_present_flag                  =    ps_vui->s_vui_hrd_parameters.u1_nal_hrd_parameters_present_flag;
4133     ps_op->u1_vcl_hrd_parameters_present_flag                  =    ps_vui->s_vui_hrd_parameters.u1_vcl_hrd_parameters_present_flag;
4134     ps_op->u1_cpbdpb_delays_present_flag                       =    ps_vui->s_vui_hrd_parameters.u1_cpbdpb_delays_present_flag;
4135     ps_op->u1_sub_pic_cpb_params_present_flag                  =    ps_vui->s_vui_hrd_parameters.u1_sub_pic_cpb_params_present_flag;
4136     ps_op->u1_tick_divisor_minus2                              =    ps_vui->s_vui_hrd_parameters.u1_tick_divisor_minus2;
4137     ps_op->u1_du_cpb_removal_delay_increment_length_minus1     =    ps_vui->s_vui_hrd_parameters.u1_du_cpb_removal_delay_increment_length_minus1;
4138     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;
4139     ps_op->u1_dpb_output_delay_du_length_minus1                =    ps_vui->s_vui_hrd_parameters.u1_dpb_output_delay_du_length_minus1;
4140     ps_op->u4_bit_rate_scale                                   =    ps_vui->s_vui_hrd_parameters.u4_bit_rate_scale;
4141     ps_op->u4_cpb_size_scale                                   =    ps_vui->s_vui_hrd_parameters.u4_cpb_size_scale;
4142     ps_op->u4_cpb_size_du_scale                                =    ps_vui->s_vui_hrd_parameters.u4_cpb_size_du_scale;
4143     ps_op->u1_initial_cpb_removal_delay_length_minus1          =    ps_vui->s_vui_hrd_parameters.u1_initial_cpb_removal_delay_length_minus1;
4144     ps_op->u1_au_cpb_removal_delay_length_minus1               =    ps_vui->s_vui_hrd_parameters.u1_au_cpb_removal_delay_length_minus1;
4145     ps_op->u1_dpb_output_delay_length_minus1                   =    ps_vui->s_vui_hrd_parameters.u1_dpb_output_delay_length_minus1;
4146 
4147     for(i = 0; i < 6; i++)
4148     {
4149         ps_op->au1_fixed_pic_rate_general_flag[i]                  =    ps_vui->s_vui_hrd_parameters.au1_fixed_pic_rate_general_flag[i];
4150         ps_op->au1_fixed_pic_rate_within_cvs_flag[i]               =    ps_vui->s_vui_hrd_parameters.au1_fixed_pic_rate_within_cvs_flag[i];
4151         ps_op->au1_elemental_duration_in_tc_minus1[i]              =    ps_vui->s_vui_hrd_parameters.au1_elemental_duration_in_tc_minus1[i];
4152         ps_op->au1_low_delay_hrd_flag[i]                           =    ps_vui->s_vui_hrd_parameters.au1_low_delay_hrd_flag[i];
4153         ps_op->au1_cpb_cnt_minus1[i]                               =    ps_vui->s_vui_hrd_parameters.au1_cpb_cnt_minus1[i];
4154     }
4155 
4156 
4157     return IV_SUCCESS;
4158 }
4159 
4160 /**
4161 *******************************************************************************
4162 *
4163 * @brief
4164 *  Sets Processor type
4165 *
4166 * @par Description:
4167 *  Sets Processor type
4168 *
4169 * @param[in] ps_codec_obj
4170 *  Pointer to codec object at API level
4171 *
4172 * @param[in] pv_api_ip
4173 *  Pointer to input argument structure
4174 *
4175 * @param[out] pv_api_op
4176 *  Pointer to output argument structure
4177 *
4178 * @returns  Status
4179 *
4180 * @remarks
4181 *
4182 *
4183 *******************************************************************************
4184 */
4185 
ihevcd_set_processor(iv_obj_t * ps_codec_obj,void * pv_api_ip,void * pv_api_op)4186 WORD32 ihevcd_set_processor(iv_obj_t *ps_codec_obj,
4187                             void *pv_api_ip,
4188                             void *pv_api_op)
4189 {
4190     ihevcd_cxa_ctl_set_processor_ip_t *ps_ip;
4191     ihevcd_cxa_ctl_set_processor_op_t *ps_op;
4192     codec_t *ps_codec = (codec_t *)ps_codec_obj->pv_codec_handle;
4193 
4194     ps_ip = (ihevcd_cxa_ctl_set_processor_ip_t *)pv_api_ip;
4195     ps_op = (ihevcd_cxa_ctl_set_processor_op_t *)pv_api_op;
4196 
4197     ps_codec->e_processor_arch = (IVD_ARCH_T)ps_ip->u4_arch;
4198     ps_codec->e_processor_soc = (IVD_SOC_T)ps_ip->u4_soc;
4199 
4200     ihevcd_init_function_ptr(ps_codec);
4201 
4202     ihevcd_update_function_ptr(ps_codec);
4203 
4204     if(ps_codec->e_processor_soc && (ps_codec->e_processor_soc <= SOC_HISI_37X))
4205     {
4206         /* 8th bit indicates if format conversion is to be done ahead */
4207         if(ps_codec->e_processor_soc & 0x80)
4208             ps_codec->u4_enable_fmt_conv_ahead = 1;
4209 
4210         /* Lower 7 bit indicate NCTB - if non-zero */
4211         ps_codec->e_processor_soc &= 0x7F;
4212 
4213         if(ps_codec->e_processor_soc)
4214             ps_codec->u4_nctb = ps_codec->e_processor_soc;
4215 
4216 
4217     }
4218 
4219     if((ps_codec->e_processor_soc == SOC_HISI_37X) && (ps_codec->i4_num_cores == 2))
4220     {
4221         ps_codec->u4_nctb = 2;
4222     }
4223 
4224 
4225     ps_op->u4_error_code = 0;
4226     return IV_SUCCESS;
4227 }
4228 
4229 /**
4230 *******************************************************************************
4231 *
4232 * @brief
4233 *  Sets Number of cores that can be used in the codec. Codec uses these many
4234 * threads for decoding
4235 *
4236 * @par Description:
4237 *  Sets number of cores
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_set_num_cores(iv_obj_t * ps_codec_obj,void * pv_api_ip,void * pv_api_op)4256 WORD32 ihevcd_set_num_cores(iv_obj_t *ps_codec_obj,
4257                             void *pv_api_ip,
4258                             void *pv_api_op)
4259 {
4260     ihevcd_cxa_ctl_set_num_cores_ip_t *ps_ip;
4261     ihevcd_cxa_ctl_set_num_cores_op_t *ps_op;
4262     codec_t *ps_codec = (codec_t *)ps_codec_obj->pv_codec_handle;
4263 
4264     ps_ip = (ihevcd_cxa_ctl_set_num_cores_ip_t *)pv_api_ip;
4265     ps_op = (ihevcd_cxa_ctl_set_num_cores_op_t *)pv_api_op;
4266 
4267 #ifdef MULTICORE
4268     ps_codec->i4_num_cores = ps_ip->u4_num_cores;
4269 #else
4270     ps_codec->i4_num_cores = 1;
4271 #endif
4272     ps_op->u4_error_code = 0;
4273     return IV_SUCCESS;
4274 }
4275 /**
4276 *******************************************************************************
4277 *
4278 * @brief
4279 *  Codec control call
4280 *
4281 * @par Description:
4282 *  Codec control call which in turn calls appropriate calls  based on
4283 * subcommand
4284 *
4285 * @param[in] ps_codec_obj
4286 *  Pointer to codec object at API level
4287 *
4288 * @param[in] pv_api_ip
4289 *  Pointer to input argument structure
4290 *
4291 * @param[out] pv_api_op
4292 *  Pointer to output argument structure
4293 *
4294 * @returns  Status
4295 *
4296 * @remarks
4297 *
4298 *
4299 *******************************************************************************
4300 */
4301 
ihevcd_ctl(iv_obj_t * ps_codec_obj,void * pv_api_ip,void * pv_api_op)4302 WORD32 ihevcd_ctl(iv_obj_t *ps_codec_obj, void *pv_api_ip, void *pv_api_op)
4303 {
4304     ivd_ctl_set_config_ip_t *ps_ctl_ip;
4305     ivd_ctl_set_config_op_t *ps_ctl_op;
4306     WORD32 ret = 0;
4307     WORD32 subcommand;
4308     codec_t *ps_codec = (codec_t *)ps_codec_obj->pv_codec_handle;
4309 
4310     ps_ctl_ip = (ivd_ctl_set_config_ip_t *)pv_api_ip;
4311     ps_ctl_op = (ivd_ctl_set_config_op_t *)pv_api_op;
4312 
4313     if(ps_codec->i4_init_done != 1)
4314     {
4315         ps_ctl_op->u4_error_code |= 1 << IVD_FATALERROR;
4316         ps_ctl_op->u4_error_code |= IHEVCD_INIT_NOT_DONE;
4317         return IV_FAIL;
4318     }
4319     subcommand = ps_ctl_ip->e_sub_cmd;
4320 
4321     switch(subcommand)
4322     {
4323         case IVD_CMD_CTL_GETPARAMS:
4324             ret = ihevcd_get_status(ps_codec_obj, (void *)pv_api_ip,
4325                                     (void *)pv_api_op);
4326             break;
4327         case IVD_CMD_CTL_SETPARAMS:
4328             ret = ihevcd_set_params(ps_codec_obj, (void *)pv_api_ip,
4329                                     (void *)pv_api_op);
4330             break;
4331         case IVD_CMD_CTL_RESET:
4332             ret = ihevcd_reset(ps_codec_obj, (void *)pv_api_ip,
4333                                (void *)pv_api_op);
4334             break;
4335         case IVD_CMD_CTL_SETDEFAULT:
4336         {
4337             ivd_ctl_set_config_op_t *s_ctl_dynparams_op =
4338                             (ivd_ctl_set_config_op_t *)pv_api_op;
4339 
4340             ret = ihevcd_set_default_params(ps_codec);
4341             if(IV_SUCCESS == ret)
4342                 s_ctl_dynparams_op->u4_error_code = 0;
4343             break;
4344         }
4345         case IVD_CMD_CTL_FLUSH:
4346             ret = ihevcd_set_flush_mode(ps_codec_obj, (void *)pv_api_ip,
4347                                         (void *)pv_api_op);
4348             break;
4349         case IVD_CMD_CTL_GETBUFINFO:
4350             ret = ihevcd_get_buf_info(ps_codec_obj, (void *)pv_api_ip,
4351                                       (void *)pv_api_op);
4352             break;
4353         case IVD_CMD_CTL_GETVERSION:
4354         {
4355             ivd_ctl_getversioninfo_ip_t *ps_ip;
4356             ivd_ctl_getversioninfo_op_t *ps_op;
4357             IV_API_CALL_STATUS_T ret;
4358             ps_ip = (ivd_ctl_getversioninfo_ip_t *)pv_api_ip;
4359             ps_op = (ivd_ctl_getversioninfo_op_t *)pv_api_op;
4360 
4361             ps_op->u4_error_code = IV_SUCCESS;
4362 
4363             if((WORD32)ps_ip->u4_version_buffer_size <= 0)
4364             {
4365                 ps_op->u4_error_code = IHEVCD_CXA_VERS_BUF_INSUFFICIENT;
4366                 ret = IV_FAIL;
4367             }
4368             else
4369             {
4370                 ret = ihevcd_get_version((CHAR *)ps_ip->pv_version_buffer,
4371                                          ps_ip->u4_version_buffer_size);
4372                 if(ret != IV_SUCCESS)
4373                 {
4374                     ps_op->u4_error_code = IHEVCD_CXA_VERS_BUF_INSUFFICIENT;
4375                     ret = IV_FAIL;
4376                 }
4377             }
4378         }
4379             break;
4380         case IHEVCD_CXA_CMD_CTL_DEGRADE:
4381             ret = ihevcd_set_degrade(ps_codec_obj, (void *)pv_api_ip,
4382                             (void *)pv_api_op);
4383             break;
4384         case IHEVCD_CXA_CMD_CTL_SET_NUM_CORES:
4385             ret = ihevcd_set_num_cores(ps_codec_obj, (void *)pv_api_ip,
4386                                        (void *)pv_api_op);
4387             break;
4388         case IHEVCD_CXA_CMD_CTL_GET_BUFFER_DIMENSIONS:
4389             ret = ihevcd_get_frame_dimensions(ps_codec_obj, (void *)pv_api_ip,
4390                                               (void *)pv_api_op);
4391             break;
4392         case IHEVCD_CXA_CMD_CTL_GET_VUI_PARAMS:
4393             ret = ihevcd_get_vui_params(ps_codec_obj, (void *)pv_api_ip,
4394                                         (void *)pv_api_op);
4395             break;
4396         case IHEVCD_CXA_CMD_CTL_SET_PROCESSOR:
4397             ret = ihevcd_set_processor(ps_codec_obj, (void *)pv_api_ip,
4398                             (void *)pv_api_op);
4399             break;
4400         default:
4401             DEBUG("\nDo nothing\n");
4402             break;
4403     }
4404 
4405     return ret;
4406 }
4407 
4408 /**
4409 *******************************************************************************
4410 *
4411 * @brief
4412 *  Codecs entry point function. All the function calls to  the codec are
4413 * done using this function with different  values specified in command
4414 *
4415 * @par Description:
4416 *  Arguments are tested for validity and then based on the  command
4417 * appropriate function is called
4418 *
4419 * @param[in] ps_handle
4420 *  API level handle for codec
4421 *
4422 * @param[in] pv_api_ip
4423 *  Input argument structure
4424 *
4425 * @param[out] pv_api_op
4426 *  Output argument structure
4427 *
4428 * @returns  Status of the function corresponding to command
4429 *
4430 * @remarks
4431 *
4432 *
4433 *******************************************************************************
4434 */
ihevcd_cxa_api_function(iv_obj_t * ps_handle,void * pv_api_ip,void * pv_api_op)4435 IV_API_CALL_STATUS_T ihevcd_cxa_api_function(iv_obj_t *ps_handle,
4436                                              void *pv_api_ip,
4437                                              void *pv_api_op)
4438 {
4439     WORD32 command;
4440     UWORD32 *pu4_ptr_cmd;
4441     WORD32 ret = 0;
4442     IV_API_CALL_STATUS_T e_status;
4443     e_status = api_check_struct_sanity(ps_handle, pv_api_ip, pv_api_op);
4444 
4445     if(e_status != IV_SUCCESS)
4446     {
4447         DEBUG("error code = %d\n", *((UWORD32 *)pv_api_op + 1));
4448         return IV_FAIL;
4449     }
4450 
4451     pu4_ptr_cmd = (UWORD32 *)pv_api_ip;
4452     pu4_ptr_cmd++;
4453 
4454     command = *pu4_ptr_cmd;
4455 
4456     switch(command)
4457     {
4458         case IV_CMD_GET_NUM_MEM_REC:
4459             ret = ihevcd_get_num_rec((void *)pv_api_ip, (void *)pv_api_op);
4460 
4461             break;
4462         case IV_CMD_FILL_NUM_MEM_REC:
4463 
4464             ret = ihevcd_fill_num_mem_rec((void *)pv_api_ip, (void *)pv_api_op);
4465             break;
4466         case IV_CMD_INIT:
4467             ret = ihevcd_init_mem_rec(ps_handle, (void *)pv_api_ip,
4468                                       (void *)pv_api_op);
4469             break;
4470 
4471         case IVD_CMD_VIDEO_DECODE:
4472             ret = ihevcd_decode(ps_handle, (void *)pv_api_ip, (void *)pv_api_op);
4473             break;
4474 
4475         case IVD_CMD_GET_DISPLAY_FRAME:
4476             //ret = ihevcd_get_display_frame(ps_handle,(void *)pv_api_ip,(void *)pv_api_op);
4477             break;
4478 
4479         case IVD_CMD_SET_DISPLAY_FRAME:
4480             ret = ihevcd_set_display_frame(ps_handle, (void *)pv_api_ip,
4481                                            (void *)pv_api_op);
4482 
4483             break;
4484 
4485         case IVD_CMD_REL_DISPLAY_FRAME:
4486             ret = ihevcd_rel_display_frame(ps_handle, (void *)pv_api_ip,
4487                                            (void *)pv_api_op);
4488             break;
4489 
4490         case IV_CMD_RETRIEVE_MEMREC:
4491             ret = ihevcd_retrieve_memrec(ps_handle, (void *)pv_api_ip,
4492                                          (void *)pv_api_op);
4493             break;
4494 
4495         case IVD_CMD_VIDEO_CTL:
4496             ret = ihevcd_ctl(ps_handle, (void *)pv_api_ip, (void *)pv_api_op);
4497             break;
4498         default:
4499             ret = IV_FAIL;
4500             break;
4501     }
4502 
4503     return (IV_API_CALL_STATUS_T)ret;
4504 }
4505 
4506