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_allocate_static_bufs()
36 * - ihevcd_create()
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 #define ALIGNED_FREE(ps_codec, y) \
97 if(y) {ps_codec->pf_aligned_free(ps_codec->pv_mem_ctxt, ((void *)y)); (y) = NULL;}
98 
99 /*****************************************************************************/
100 /* Function Prototypes                                                       */
101 /*****************************************************************************/
102 IV_API_CALL_STATUS_T ihevcd_get_version(CHAR *pc_version_string,
103                                         UWORD32 u4_version_buffer_size);
104 WORD32 ihevcd_free_dynamic_bufs(codec_t *ps_codec);
105 
106 
107 /**
108 *******************************************************************************
109 *
110 * @brief
111 *  Used to test arguments for corresponding API call
112 *
113 * @par Description:
114 *  For each command the arguments are validated
115 *
116 * @param[in] ps_handle
117 *  Codec handle at API level
118 *
119 * @param[in] pv_api_ip
120 *  Pointer to input structure
121 *
122 * @param[out] pv_api_op
123 *  Pointer to output structure
124 *
125 * @returns  Status of error checking
126 *
127 * @remarks
128 *
129 *
130 *******************************************************************************
131 */
132 
api_check_struct_sanity(iv_obj_t * ps_handle,void * pv_api_ip,void * pv_api_op)133 static IV_API_CALL_STATUS_T api_check_struct_sanity(iv_obj_t *ps_handle,
134                                                     void *pv_api_ip,
135                                                     void *pv_api_op)
136 {
137     IVD_API_COMMAND_TYPE_T e_cmd;
138     UWORD32 *pu4_api_ip;
139     UWORD32 *pu4_api_op;
140     WORD32 i;
141 
142     if(NULL == pv_api_op)
143         return (IV_FAIL);
144 
145     if(NULL == pv_api_ip)
146         return (IV_FAIL);
147 
148     pu4_api_ip = (UWORD32 *)pv_api_ip;
149     pu4_api_op = (UWORD32 *)pv_api_op;
150     e_cmd = (IVD_API_COMMAND_TYPE_T)*(pu4_api_ip + 1);
151 
152     *(pu4_api_op + 1) = 0;
153     /* error checks on handle */
154     switch((WORD32)e_cmd)
155     {
156         case IVD_CMD_CREATE:
157             break;
158 
159         case IVD_CMD_REL_DISPLAY_FRAME:
160         case IVD_CMD_SET_DISPLAY_FRAME:
161         case IVD_CMD_GET_DISPLAY_FRAME:
162         case IVD_CMD_VIDEO_DECODE:
163         case IVD_CMD_DELETE:
164         case IVD_CMD_VIDEO_CTL:
165             if(ps_handle == NULL)
166             {
167                 *(pu4_api_op + 1) |= 1 << IVD_UNSUPPORTEDPARAM;
168                 *(pu4_api_op + 1) |= IVD_HANDLE_NULL;
169                 return IV_FAIL;
170             }
171 
172             if(ps_handle->u4_size != sizeof(iv_obj_t))
173             {
174                 *(pu4_api_op + 1) |= 1 << IVD_UNSUPPORTEDPARAM;
175                 *(pu4_api_op + 1) |= IVD_HANDLE_STRUCT_SIZE_INCORRECT;
176                 return IV_FAIL;
177             }
178 
179 
180             if(ps_handle->pv_codec_handle == NULL)
181             {
182                 *(pu4_api_op + 1) |= 1 << IVD_UNSUPPORTEDPARAM;
183                 *(pu4_api_op + 1) |= IVD_INVALID_HANDLE_NULL;
184                 return IV_FAIL;
185             }
186             break;
187         default:
188             *(pu4_api_op + 1) |= 1 << IVD_UNSUPPORTEDPARAM;
189             *(pu4_api_op + 1) |= IVD_INVALID_API_CMD;
190             return IV_FAIL;
191     }
192 
193     switch((WORD32)e_cmd)
194     {
195         case IVD_CMD_CREATE:
196         {
197             ihevcd_cxa_create_ip_t *ps_ip = (ihevcd_cxa_create_ip_t *)pv_api_ip;
198             ihevcd_cxa_create_op_t *ps_op = (ihevcd_cxa_create_op_t *)pv_api_op;
199 
200 
201             ps_op->s_ivd_create_op_t.u4_error_code = 0;
202 
203             if((ps_ip->s_ivd_create_ip_t.u4_size > sizeof(ihevcd_cxa_create_ip_t))
204                             || (ps_ip->s_ivd_create_ip_t.u4_size
205                                             < sizeof(ivd_create_ip_t)))
206             {
207                 ps_op->s_ivd_create_op_t.u4_error_code |= 1
208                                 << IVD_UNSUPPORTEDPARAM;
209                 ps_op->s_ivd_create_op_t.u4_error_code |=
210                                 IVD_IP_API_STRUCT_SIZE_INCORRECT;
211 
212                 return (IV_FAIL);
213             }
214 
215             if((ps_op->s_ivd_create_op_t.u4_size != sizeof(ihevcd_cxa_create_op_t))
216                             && (ps_op->s_ivd_create_op_t.u4_size
217                                             != sizeof(ivd_create_op_t)))
218             {
219                 ps_op->s_ivd_create_op_t.u4_error_code |= 1
220                                 << IVD_UNSUPPORTEDPARAM;
221                 ps_op->s_ivd_create_op_t.u4_error_code |=
222                                 IVD_OP_API_STRUCT_SIZE_INCORRECT;
223 
224                 return (IV_FAIL);
225             }
226 
227 
228             if((ps_ip->s_ivd_create_ip_t.e_output_format != IV_YUV_420P)
229                             && (ps_ip->s_ivd_create_ip_t.e_output_format
230                                             != IV_YUV_422ILE)
231                             && (ps_ip->s_ivd_create_ip_t.e_output_format
232                                             != IV_RGB_565)
233                             && (ps_ip->s_ivd_create_ip_t.e_output_format
234                                             != IV_YUV_420SP_UV)
235                             && (ps_ip->s_ivd_create_ip_t.e_output_format
236                                             != IV_YUV_420SP_VU))
237             {
238                 ps_op->s_ivd_create_op_t.u4_error_code |= 1
239                                 << IVD_UNSUPPORTEDPARAM;
240                 ps_op->s_ivd_create_op_t.u4_error_code |=
241                                 IVD_INIT_DEC_COL_FMT_NOT_SUPPORTED;
242 
243                 return (IV_FAIL);
244             }
245 
246         }
247             break;
248 
249         case IVD_CMD_GET_DISPLAY_FRAME:
250         {
251             ihevcd_cxa_get_display_frame_ip_t *ps_ip =
252                             (ihevcd_cxa_get_display_frame_ip_t *)pv_api_ip;
253             ihevcd_cxa_get_display_frame_op_t *ps_op =
254                             (ihevcd_cxa_get_display_frame_op_t *)pv_api_op;
255 
256             ps_op->s_ivd_get_display_frame_op_t.u4_error_code = 0;
257 
258             if((ps_ip->s_ivd_get_display_frame_ip_t.u4_size
259                             != sizeof(ihevcd_cxa_get_display_frame_ip_t))
260                             && (ps_ip->s_ivd_get_display_frame_ip_t.u4_size
261                                             != sizeof(ivd_get_display_frame_ip_t)))
262             {
263                 ps_op->s_ivd_get_display_frame_op_t.u4_error_code |= 1
264                                 << IVD_UNSUPPORTEDPARAM;
265                 ps_op->s_ivd_get_display_frame_op_t.u4_error_code |=
266                                 IVD_IP_API_STRUCT_SIZE_INCORRECT;
267                 return (IV_FAIL);
268             }
269 
270             if((ps_op->s_ivd_get_display_frame_op_t.u4_size
271                             != sizeof(ihevcd_cxa_get_display_frame_op_t))
272                             && (ps_op->s_ivd_get_display_frame_op_t.u4_size
273                                             != sizeof(ivd_get_display_frame_op_t)))
274             {
275                 ps_op->s_ivd_get_display_frame_op_t.u4_error_code |= 1
276                                 << IVD_UNSUPPORTEDPARAM;
277                 ps_op->s_ivd_get_display_frame_op_t.u4_error_code |=
278                                 IVD_OP_API_STRUCT_SIZE_INCORRECT;
279                 return (IV_FAIL);
280             }
281 
282         }
283             break;
284 
285         case IVD_CMD_REL_DISPLAY_FRAME:
286         {
287             ihevcd_cxa_rel_display_frame_ip_t *ps_ip =
288                             (ihevcd_cxa_rel_display_frame_ip_t *)pv_api_ip;
289             ihevcd_cxa_rel_display_frame_op_t *ps_op =
290                             (ihevcd_cxa_rel_display_frame_op_t *)pv_api_op;
291 
292             ps_op->s_ivd_rel_display_frame_op_t.u4_error_code = 0;
293 
294             if((ps_ip->s_ivd_rel_display_frame_ip_t.u4_size
295                             != sizeof(ihevcd_cxa_rel_display_frame_ip_t))
296                             && (ps_ip->s_ivd_rel_display_frame_ip_t.u4_size
297                                             != sizeof(ivd_rel_display_frame_ip_t)))
298             {
299                 ps_op->s_ivd_rel_display_frame_op_t.u4_error_code |= 1
300                                 << IVD_UNSUPPORTEDPARAM;
301                 ps_op->s_ivd_rel_display_frame_op_t.u4_error_code |=
302                                 IVD_IP_API_STRUCT_SIZE_INCORRECT;
303                 return (IV_FAIL);
304             }
305 
306             if((ps_op->s_ivd_rel_display_frame_op_t.u4_size
307                             != sizeof(ihevcd_cxa_rel_display_frame_op_t))
308                             && (ps_op->s_ivd_rel_display_frame_op_t.u4_size
309                                             != sizeof(ivd_rel_display_frame_op_t)))
310             {
311                 ps_op->s_ivd_rel_display_frame_op_t.u4_error_code |= 1
312                                 << IVD_UNSUPPORTEDPARAM;
313                 ps_op->s_ivd_rel_display_frame_op_t.u4_error_code |=
314                                 IVD_OP_API_STRUCT_SIZE_INCORRECT;
315                 return (IV_FAIL);
316             }
317 
318         }
319             break;
320 
321         case IVD_CMD_SET_DISPLAY_FRAME:
322         {
323             ihevcd_cxa_set_display_frame_ip_t *ps_ip =
324                             (ihevcd_cxa_set_display_frame_ip_t *)pv_api_ip;
325             ihevcd_cxa_set_display_frame_op_t *ps_op =
326                             (ihevcd_cxa_set_display_frame_op_t *)pv_api_op;
327             UWORD32 j;
328 
329             ps_op->s_ivd_set_display_frame_op_t.u4_error_code = 0;
330 
331             if((ps_ip->s_ivd_set_display_frame_ip_t.u4_size
332                             != sizeof(ihevcd_cxa_set_display_frame_ip_t))
333                             && (ps_ip->s_ivd_set_display_frame_ip_t.u4_size
334                                             != sizeof(ivd_set_display_frame_ip_t)))
335             {
336                 ps_op->s_ivd_set_display_frame_op_t.u4_error_code |= 1
337                                 << IVD_UNSUPPORTEDPARAM;
338                 ps_op->s_ivd_set_display_frame_op_t.u4_error_code |=
339                                 IVD_IP_API_STRUCT_SIZE_INCORRECT;
340                 return (IV_FAIL);
341             }
342 
343             if((ps_op->s_ivd_set_display_frame_op_t.u4_size
344                             != sizeof(ihevcd_cxa_set_display_frame_op_t))
345                             && (ps_op->s_ivd_set_display_frame_op_t.u4_size
346                                             != sizeof(ivd_set_display_frame_op_t)))
347             {
348                 ps_op->s_ivd_set_display_frame_op_t.u4_error_code |= 1
349                                 << IVD_UNSUPPORTEDPARAM;
350                 ps_op->s_ivd_set_display_frame_op_t.u4_error_code |=
351                                 IVD_OP_API_STRUCT_SIZE_INCORRECT;
352                 return (IV_FAIL);
353             }
354 
355             if(ps_ip->s_ivd_set_display_frame_ip_t.num_disp_bufs == 0)
356             {
357                 ps_op->s_ivd_set_display_frame_op_t.u4_error_code |= 1
358                                 << IVD_UNSUPPORTEDPARAM;
359                 ps_op->s_ivd_set_display_frame_op_t.u4_error_code |=
360                                 IVD_DISP_FRM_ZERO_OP_BUFS;
361                 return IV_FAIL;
362             }
363 
364             for(j = 0; j < ps_ip->s_ivd_set_display_frame_ip_t.num_disp_bufs;
365                             j++)
366             {
367                 if(ps_ip->s_ivd_set_display_frame_ip_t.s_disp_buffer[j].u4_num_bufs
368                                 == 0)
369                 {
370                     ps_op->s_ivd_set_display_frame_op_t.u4_error_code |= 1
371                                     << IVD_UNSUPPORTEDPARAM;
372                     ps_op->s_ivd_set_display_frame_op_t.u4_error_code |=
373                                     IVD_DISP_FRM_ZERO_OP_BUFS;
374                     return IV_FAIL;
375                 }
376 
377                 for(i = 0;
378                                 i
379                                                 < (WORD32)ps_ip->s_ivd_set_display_frame_ip_t.s_disp_buffer[j].u4_num_bufs;
380                                 i++)
381                 {
382                     if(ps_ip->s_ivd_set_display_frame_ip_t.s_disp_buffer[j].pu1_bufs[i]
383                                     == NULL)
384                     {
385                         ps_op->s_ivd_set_display_frame_op_t.u4_error_code |= 1
386                                         << IVD_UNSUPPORTEDPARAM;
387                         ps_op->s_ivd_set_display_frame_op_t.u4_error_code |=
388                                         IVD_DISP_FRM_OP_BUF_NULL;
389                         return IV_FAIL;
390                     }
391 
392                     if(ps_ip->s_ivd_set_display_frame_ip_t.s_disp_buffer[j].u4_min_out_buf_size[i]
393                                     == 0)
394                     {
395                         ps_op->s_ivd_set_display_frame_op_t.u4_error_code |= 1
396                                         << IVD_UNSUPPORTEDPARAM;
397                         ps_op->s_ivd_set_display_frame_op_t.u4_error_code |=
398                                         IVD_DISP_FRM_ZERO_OP_BUF_SIZE;
399                         return IV_FAIL;
400                     }
401                 }
402             }
403         }
404             break;
405 
406         case IVD_CMD_VIDEO_DECODE:
407         {
408             ihevcd_cxa_video_decode_ip_t *ps_ip =
409                             (ihevcd_cxa_video_decode_ip_t *)pv_api_ip;
410             ihevcd_cxa_video_decode_op_t *ps_op =
411                             (ihevcd_cxa_video_decode_op_t *)pv_api_op;
412 
413             DEBUG("The input bytes is: %d",
414                             ps_ip->s_ivd_video_decode_ip_t.u4_num_Bytes);
415             ps_op->s_ivd_video_decode_op_t.u4_error_code = 0;
416 
417             if(ps_ip->s_ivd_video_decode_ip_t.u4_size
418                             != sizeof(ihevcd_cxa_video_decode_ip_t)
419                             && ps_ip->s_ivd_video_decode_ip_t.u4_size
420                                             != offsetof(ivd_video_decode_ip_t,
421                                                         s_out_buffer))
422             {
423                 ps_op->s_ivd_video_decode_op_t.u4_error_code |= 1
424                                 << IVD_UNSUPPORTEDPARAM;
425                 ps_op->s_ivd_video_decode_op_t.u4_error_code |=
426                                 IVD_IP_API_STRUCT_SIZE_INCORRECT;
427                 return (IV_FAIL);
428             }
429 
430             if(ps_op->s_ivd_video_decode_op_t.u4_size
431                             != sizeof(ihevcd_cxa_video_decode_op_t)
432                             && ps_op->s_ivd_video_decode_op_t.u4_size
433                                             != offsetof(ivd_video_decode_op_t,
434                                                         u4_output_present))
435             {
436                 ps_op->s_ivd_video_decode_op_t.u4_error_code |= 1
437                                 << IVD_UNSUPPORTEDPARAM;
438                 ps_op->s_ivd_video_decode_op_t.u4_error_code |=
439                                 IVD_OP_API_STRUCT_SIZE_INCORRECT;
440                 return (IV_FAIL);
441             }
442 
443         }
444             break;
445 
446         case IVD_CMD_DELETE:
447         {
448             ihevcd_cxa_delete_ip_t *ps_ip =
449                             (ihevcd_cxa_delete_ip_t *)pv_api_ip;
450             ihevcd_cxa_delete_op_t *ps_op =
451                             (ihevcd_cxa_delete_op_t *)pv_api_op;
452 
453             ps_op->s_ivd_delete_op_t.u4_error_code = 0;
454 
455             if(ps_ip->s_ivd_delete_ip_t.u4_size
456                             != sizeof(ihevcd_cxa_delete_ip_t))
457             {
458                 ps_op->s_ivd_delete_op_t.u4_error_code |= 1
459                                 << IVD_UNSUPPORTEDPARAM;
460                 ps_op->s_ivd_delete_op_t.u4_error_code |=
461                                 IVD_IP_API_STRUCT_SIZE_INCORRECT;
462                 return (IV_FAIL);
463             }
464 
465             if(ps_op->s_ivd_delete_op_t.u4_size
466                             != sizeof(ihevcd_cxa_delete_op_t))
467             {
468                 ps_op->s_ivd_delete_op_t.u4_error_code |= 1
469                                 << IVD_UNSUPPORTEDPARAM;
470                 ps_op->s_ivd_delete_op_t.u4_error_code |=
471                                 IVD_OP_API_STRUCT_SIZE_INCORRECT;
472                 return (IV_FAIL);
473             }
474 
475         }
476             break;
477 
478         case IVD_CMD_VIDEO_CTL:
479         {
480             UWORD32 *pu4_ptr_cmd;
481             UWORD32 sub_command;
482 
483             pu4_ptr_cmd = (UWORD32 *)pv_api_ip;
484             pu4_ptr_cmd += 2;
485             sub_command = *pu4_ptr_cmd;
486 
487             switch(sub_command)
488             {
489                 case IVD_CMD_CTL_SETPARAMS:
490                 {
491                     ihevcd_cxa_ctl_set_config_ip_t *ps_ip;
492                     ihevcd_cxa_ctl_set_config_op_t *ps_op;
493                     ps_ip = (ihevcd_cxa_ctl_set_config_ip_t *)pv_api_ip;
494                     ps_op = (ihevcd_cxa_ctl_set_config_op_t *)pv_api_op;
495 
496                     if(ps_ip->s_ivd_ctl_set_config_ip_t.u4_size
497                                     != sizeof(ihevcd_cxa_ctl_set_config_ip_t))
498                     {
499                         ps_op->s_ivd_ctl_set_config_op_t.u4_error_code |= 1
500                                         << IVD_UNSUPPORTEDPARAM;
501                         ps_op->s_ivd_ctl_set_config_op_t.u4_error_code |=
502                                         IVD_IP_API_STRUCT_SIZE_INCORRECT;
503                         return IV_FAIL;
504                     }
505                 }
506                     //no break; is needed here
507                 case IVD_CMD_CTL_SETDEFAULT:
508                 {
509                     ihevcd_cxa_ctl_set_config_op_t *ps_op;
510                     ps_op = (ihevcd_cxa_ctl_set_config_op_t *)pv_api_op;
511                     if(ps_op->s_ivd_ctl_set_config_op_t.u4_size
512                                     != sizeof(ihevcd_cxa_ctl_set_config_op_t))
513                     {
514                         ps_op->s_ivd_ctl_set_config_op_t.u4_error_code |= 1
515                                         << IVD_UNSUPPORTEDPARAM;
516                         ps_op->s_ivd_ctl_set_config_op_t.u4_error_code |=
517                                         IVD_OP_API_STRUCT_SIZE_INCORRECT;
518                         return IV_FAIL;
519                     }
520                 }
521                     break;
522 
523                 case IVD_CMD_CTL_GETPARAMS:
524                 {
525                     ihevcd_cxa_ctl_getstatus_ip_t *ps_ip;
526                     ihevcd_cxa_ctl_getstatus_op_t *ps_op;
527 
528                     ps_ip = (ihevcd_cxa_ctl_getstatus_ip_t *)pv_api_ip;
529                     ps_op = (ihevcd_cxa_ctl_getstatus_op_t *)pv_api_op;
530                     if(ps_ip->s_ivd_ctl_getstatus_ip_t.u4_size
531                                     != sizeof(ihevcd_cxa_ctl_getstatus_ip_t))
532                     {
533                         ps_op->s_ivd_ctl_getstatus_op_t.u4_error_code |= 1
534                                         << IVD_UNSUPPORTEDPARAM;
535                         ps_op->s_ivd_ctl_getstatus_op_t.u4_error_code |=
536                                         IVD_IP_API_STRUCT_SIZE_INCORRECT;
537                         return IV_FAIL;
538                     }
539                     if((ps_op->s_ivd_ctl_getstatus_op_t.u4_size
540                                     != sizeof(ihevcd_cxa_ctl_getstatus_op_t)) &&
541                        (ps_op->s_ivd_ctl_getstatus_op_t.u4_size
542                                     != sizeof(ivd_ctl_getstatus_op_t)))
543                     {
544                         ps_op->s_ivd_ctl_getstatus_op_t.u4_error_code |= 1
545                                         << IVD_UNSUPPORTEDPARAM;
546                         ps_op->s_ivd_ctl_getstatus_op_t.u4_error_code |=
547                                         IVD_OP_API_STRUCT_SIZE_INCORRECT;
548                         return IV_FAIL;
549                     }
550                 }
551                     break;
552 
553                 case IVD_CMD_CTL_GETBUFINFO:
554                 {
555                     ihevcd_cxa_ctl_getbufinfo_ip_t *ps_ip;
556                     ihevcd_cxa_ctl_getbufinfo_op_t *ps_op;
557                     ps_ip = (ihevcd_cxa_ctl_getbufinfo_ip_t *)pv_api_ip;
558                     ps_op = (ihevcd_cxa_ctl_getbufinfo_op_t *)pv_api_op;
559 
560                     if(ps_ip->s_ivd_ctl_getbufinfo_ip_t.u4_size
561                                     != sizeof(ihevcd_cxa_ctl_getbufinfo_ip_t))
562                     {
563                         ps_op->s_ivd_ctl_getbufinfo_op_t.u4_error_code |= 1
564                                         << IVD_UNSUPPORTEDPARAM;
565                         ps_op->s_ivd_ctl_getbufinfo_op_t.u4_error_code |=
566                                         IVD_IP_API_STRUCT_SIZE_INCORRECT;
567                         return IV_FAIL;
568                     }
569                     if(ps_op->s_ivd_ctl_getbufinfo_op_t.u4_size
570                                     != sizeof(ihevcd_cxa_ctl_getbufinfo_op_t))
571                     {
572                         ps_op->s_ivd_ctl_getbufinfo_op_t.u4_error_code |= 1
573                                         << IVD_UNSUPPORTEDPARAM;
574                         ps_op->s_ivd_ctl_getbufinfo_op_t.u4_error_code |=
575                                         IVD_OP_API_STRUCT_SIZE_INCORRECT;
576                         return IV_FAIL;
577                     }
578                 }
579                     break;
580 
581                 case IVD_CMD_CTL_GETVERSION:
582                 {
583                     ihevcd_cxa_ctl_getversioninfo_ip_t *ps_ip;
584                     ihevcd_cxa_ctl_getversioninfo_op_t *ps_op;
585                     ps_ip = (ihevcd_cxa_ctl_getversioninfo_ip_t *)pv_api_ip;
586                     ps_op = (ihevcd_cxa_ctl_getversioninfo_op_t *)pv_api_op;
587                     if(ps_ip->s_ivd_ctl_getversioninfo_ip_t.u4_size
588                                     != sizeof(ihevcd_cxa_ctl_getversioninfo_ip_t))
589                     {
590                         ps_op->s_ivd_ctl_getversioninfo_op_t.u4_error_code |= 1
591                                         << IVD_UNSUPPORTEDPARAM;
592                         ps_op->s_ivd_ctl_getversioninfo_op_t.u4_error_code |=
593                                         IVD_IP_API_STRUCT_SIZE_INCORRECT;
594                         return IV_FAIL;
595                     }
596                     if(ps_op->s_ivd_ctl_getversioninfo_op_t.u4_size
597                                     != sizeof(ihevcd_cxa_ctl_getversioninfo_op_t))
598                     {
599                         ps_op->s_ivd_ctl_getversioninfo_op_t.u4_error_code |= 1
600                                         << IVD_UNSUPPORTEDPARAM;
601                         ps_op->s_ivd_ctl_getversioninfo_op_t.u4_error_code |=
602                                         IVD_OP_API_STRUCT_SIZE_INCORRECT;
603                         return IV_FAIL;
604                     }
605                 }
606                     break;
607 
608                 case IVD_CMD_CTL_FLUSH:
609                 {
610                     ihevcd_cxa_ctl_flush_ip_t *ps_ip;
611                     ihevcd_cxa_ctl_flush_op_t *ps_op;
612                     ps_ip = (ihevcd_cxa_ctl_flush_ip_t *)pv_api_ip;
613                     ps_op = (ihevcd_cxa_ctl_flush_op_t *)pv_api_op;
614                     if(ps_ip->s_ivd_ctl_flush_ip_t.u4_size
615                                     != sizeof(ihevcd_cxa_ctl_flush_ip_t))
616                     {
617                         ps_op->s_ivd_ctl_flush_op_t.u4_error_code |= 1
618                                         << IVD_UNSUPPORTEDPARAM;
619                         ps_op->s_ivd_ctl_flush_op_t.u4_error_code |=
620                                         IVD_IP_API_STRUCT_SIZE_INCORRECT;
621                         return IV_FAIL;
622                     }
623                     if(ps_op->s_ivd_ctl_flush_op_t.u4_size
624                                     != sizeof(ihevcd_cxa_ctl_flush_op_t))
625                     {
626                         ps_op->s_ivd_ctl_flush_op_t.u4_error_code |= 1
627                                         << IVD_UNSUPPORTEDPARAM;
628                         ps_op->s_ivd_ctl_flush_op_t.u4_error_code |=
629                                         IVD_OP_API_STRUCT_SIZE_INCORRECT;
630                         return IV_FAIL;
631                     }
632                 }
633                     break;
634 
635                 case IVD_CMD_CTL_RESET:
636                 {
637                     ihevcd_cxa_ctl_reset_ip_t *ps_ip;
638                     ihevcd_cxa_ctl_reset_op_t *ps_op;
639                     ps_ip = (ihevcd_cxa_ctl_reset_ip_t *)pv_api_ip;
640                     ps_op = (ihevcd_cxa_ctl_reset_op_t *)pv_api_op;
641                     if(ps_ip->s_ivd_ctl_reset_ip_t.u4_size
642                                     != sizeof(ihevcd_cxa_ctl_reset_ip_t))
643                     {
644                         ps_op->s_ivd_ctl_reset_op_t.u4_error_code |= 1
645                                         << IVD_UNSUPPORTEDPARAM;
646                         ps_op->s_ivd_ctl_reset_op_t.u4_error_code |=
647                                         IVD_IP_API_STRUCT_SIZE_INCORRECT;
648                         return IV_FAIL;
649                     }
650                     if(ps_op->s_ivd_ctl_reset_op_t.u4_size
651                                     != sizeof(ihevcd_cxa_ctl_reset_op_t))
652                     {
653                         ps_op->s_ivd_ctl_reset_op_t.u4_error_code |= 1
654                                         << IVD_UNSUPPORTEDPARAM;
655                         ps_op->s_ivd_ctl_reset_op_t.u4_error_code |=
656                                         IVD_OP_API_STRUCT_SIZE_INCORRECT;
657                         return IV_FAIL;
658                     }
659                 }
660                     break;
661                 case IHEVCD_CXA_CMD_CTL_DEGRADE:
662                 {
663                     ihevcd_cxa_ctl_degrade_ip_t *ps_ip;
664                     ihevcd_cxa_ctl_degrade_op_t *ps_op;
665 
666                     ps_ip = (ihevcd_cxa_ctl_degrade_ip_t *)pv_api_ip;
667                     ps_op = (ihevcd_cxa_ctl_degrade_op_t *)pv_api_op;
668 
669                     if(ps_ip->u4_size
670                                     != sizeof(ihevcd_cxa_ctl_degrade_ip_t))
671                     {
672                         ps_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM;
673                         ps_op->u4_error_code |=
674                                         IVD_IP_API_STRUCT_SIZE_INCORRECT;
675                         return IV_FAIL;
676                     }
677 
678                     if(ps_op->u4_size
679                                     != sizeof(ihevcd_cxa_ctl_degrade_op_t))
680                     {
681                         ps_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM;
682                         ps_op->u4_error_code |=
683                                         IVD_OP_API_STRUCT_SIZE_INCORRECT;
684                         return IV_FAIL;
685                     }
686 
687                     if((ps_ip->i4_degrade_pics < 0) ||
688                        (ps_ip->i4_degrade_pics > 4) ||
689                        (ps_ip->i4_nondegrade_interval < 0) ||
690                        (ps_ip->i4_degrade_type < 0) ||
691                        (ps_ip->i4_degrade_type > 15))
692                     {
693                         ps_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM;
694                         return IV_FAIL;
695                     }
696 
697                     break;
698                 }
699 
700                 case IHEVCD_CXA_CMD_CTL_GET_BUFFER_DIMENSIONS:
701                 {
702                     ihevcd_cxa_ctl_get_frame_dimensions_ip_t *ps_ip;
703                     ihevcd_cxa_ctl_get_frame_dimensions_op_t *ps_op;
704 
705                     ps_ip =
706                                     (ihevcd_cxa_ctl_get_frame_dimensions_ip_t *)pv_api_ip;
707                     ps_op =
708                                     (ihevcd_cxa_ctl_get_frame_dimensions_op_t *)pv_api_op;
709 
710                     if(ps_ip->u4_size
711                                     != sizeof(ihevcd_cxa_ctl_get_frame_dimensions_ip_t))
712                     {
713                         ps_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM;
714                         ps_op->u4_error_code |=
715                                         IVD_IP_API_STRUCT_SIZE_INCORRECT;
716                         return IV_FAIL;
717                     }
718 
719                     if(ps_op->u4_size
720                                     != sizeof(ihevcd_cxa_ctl_get_frame_dimensions_op_t))
721                     {
722                         ps_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM;
723                         ps_op->u4_error_code |=
724                                         IVD_OP_API_STRUCT_SIZE_INCORRECT;
725                         return IV_FAIL;
726                     }
727 
728                     break;
729                 }
730 
731                 case IHEVCD_CXA_CMD_CTL_GET_VUI_PARAMS:
732                 {
733                     ihevcd_cxa_ctl_get_vui_params_ip_t *ps_ip;
734                     ihevcd_cxa_ctl_get_vui_params_op_t *ps_op;
735 
736                     ps_ip =
737                                     (ihevcd_cxa_ctl_get_vui_params_ip_t *)pv_api_ip;
738                     ps_op =
739                                     (ihevcd_cxa_ctl_get_vui_params_op_t *)pv_api_op;
740 
741                     if(ps_ip->u4_size
742                                     != sizeof(ihevcd_cxa_ctl_get_vui_params_ip_t))
743                     {
744                         ps_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM;
745                         ps_op->u4_error_code |=
746                                         IVD_IP_API_STRUCT_SIZE_INCORRECT;
747                         return IV_FAIL;
748                     }
749 
750                     if(ps_op->u4_size
751                                     != sizeof(ihevcd_cxa_ctl_get_vui_params_op_t))
752                     {
753                         ps_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM;
754                         ps_op->u4_error_code |=
755                                         IVD_OP_API_STRUCT_SIZE_INCORRECT;
756                         return IV_FAIL;
757                     }
758 
759                     break;
760                 }
761                 case IHEVCD_CXA_CMD_CTL_SET_NUM_CORES:
762                 {
763                     ihevcd_cxa_ctl_set_num_cores_ip_t *ps_ip;
764                     ihevcd_cxa_ctl_set_num_cores_op_t *ps_op;
765 
766                     ps_ip = (ihevcd_cxa_ctl_set_num_cores_ip_t *)pv_api_ip;
767                     ps_op = (ihevcd_cxa_ctl_set_num_cores_op_t *)pv_api_op;
768 
769                     if(ps_ip->u4_size
770                                     != sizeof(ihevcd_cxa_ctl_set_num_cores_ip_t))
771                     {
772                         ps_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM;
773                         ps_op->u4_error_code |=
774                                         IVD_IP_API_STRUCT_SIZE_INCORRECT;
775                         return IV_FAIL;
776                     }
777 
778                     if(ps_op->u4_size
779                                     != sizeof(ihevcd_cxa_ctl_set_num_cores_op_t))
780                     {
781                         ps_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM;
782                         ps_op->u4_error_code |=
783                                         IVD_OP_API_STRUCT_SIZE_INCORRECT;
784                         return IV_FAIL;
785                     }
786 
787 #ifdef MULTICORE
788                     if((ps_ip->u4_num_cores < 1) || (ps_ip->u4_num_cores > MAX_NUM_CORES))
789 #else
790                     if(ps_ip->u4_num_cores != 1)
791 #endif
792                         {
793                             ps_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM;
794                             return IV_FAIL;
795                         }
796                     break;
797                 }
798                 case IHEVCD_CXA_CMD_CTL_SET_PROCESSOR:
799                 {
800                     ihevcd_cxa_ctl_set_processor_ip_t *ps_ip;
801                     ihevcd_cxa_ctl_set_processor_op_t *ps_op;
802 
803                     ps_ip = (ihevcd_cxa_ctl_set_processor_ip_t *)pv_api_ip;
804                     ps_op = (ihevcd_cxa_ctl_set_processor_op_t *)pv_api_op;
805 
806                     if(ps_ip->u4_size
807                                     != sizeof(ihevcd_cxa_ctl_set_processor_ip_t))
808                     {
809                         ps_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM;
810                         ps_op->u4_error_code |=
811                                         IVD_IP_API_STRUCT_SIZE_INCORRECT;
812                         return IV_FAIL;
813                     }
814 
815                     if(ps_op->u4_size
816                                     != sizeof(ihevcd_cxa_ctl_set_processor_op_t))
817                     {
818                         ps_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM;
819                         ps_op->u4_error_code |=
820                                         IVD_OP_API_STRUCT_SIZE_INCORRECT;
821                         return IV_FAIL;
822                     }
823 
824                     break;
825                 }
826                 default:
827                     *(pu4_api_op + 1) |= 1 << IVD_UNSUPPORTEDPARAM;
828                     *(pu4_api_op + 1) |= IVD_UNSUPPORTED_API_CMD;
829                     return IV_FAIL;
830             }
831         }
832             break;
833         default:
834             *(pu4_api_op + 1) |= 1 << IVD_UNSUPPORTEDPARAM;
835             *(pu4_api_op + 1) |= IVD_UNSUPPORTED_API_CMD;
836             return IV_FAIL;
837     }
838 
839     return IV_SUCCESS;
840 }
841 
842 
843 /**
844 *******************************************************************************
845 *
846 * @brief
847 *  Sets default dynamic parameters
848 *
849 * @par Description:
850 *  Sets default dynamic parameters. Will be called in ihevcd_init() to ensure
851 * that even if set_params is not called, codec  continues to work
852 *
853 * @param[in] ps_codec_obj
854 *  Pointer to codec object at API level
855 *
856 * @param[in] pv_api_ip
857 *  Pointer to input argument structure
858 *
859 * @param[out] pv_api_op
860 *  Pointer to output argument structure
861 *
862 * @returns  Status
863 *
864 * @remarks
865 *
866 *
867 *******************************************************************************
868 */
ihevcd_set_default_params(codec_t * ps_codec)869 WORD32 ihevcd_set_default_params(codec_t *ps_codec)
870 {
871 
872     WORD32 ret = IV_SUCCESS;
873 
874     ps_codec->e_pic_skip_mode = IVD_SKIP_NONE;
875     ps_codec->i4_strd = 0;
876     ps_codec->i4_disp_strd = 0;
877     ps_codec->i4_header_mode = 0;
878     ps_codec->e_pic_out_order = IVD_DISPLAY_FRAME_OUT;
879     return ret;
880 }
881 
ihevcd_update_function_ptr(codec_t * ps_codec)882 void ihevcd_update_function_ptr(codec_t *ps_codec)
883 {
884 
885     /* Init inter pred function array */
886     ps_codec->apf_inter_pred[0] = NULL;
887     ps_codec->apf_inter_pred[1] = (pf_inter_pred)ps_codec->s_func_selector.ihevc_inter_pred_luma_copy_fptr;
888     ps_codec->apf_inter_pred[2] = (pf_inter_pred)ps_codec->s_func_selector.ihevc_inter_pred_luma_vert_fptr;
889     ps_codec->apf_inter_pred[3] = (pf_inter_pred)ps_codec->s_func_selector.ihevc_inter_pred_luma_horz_fptr;
890     ps_codec->apf_inter_pred[4] = (pf_inter_pred)ps_codec->s_func_selector.ihevc_inter_pred_luma_horz_w16out_fptr;
891     ps_codec->apf_inter_pred[5] = (pf_inter_pred)ps_codec->s_func_selector.ihevc_inter_pred_luma_copy_w16out_fptr;
892     ps_codec->apf_inter_pred[6] = (pf_inter_pred)ps_codec->s_func_selector.ihevc_inter_pred_luma_vert_w16out_fptr;
893     ps_codec->apf_inter_pred[7] = (pf_inter_pred)ps_codec->s_func_selector.ihevc_inter_pred_luma_horz_w16out_fptr;
894     ps_codec->apf_inter_pred[8] = (pf_inter_pred)ps_codec->s_func_selector.ihevc_inter_pred_luma_horz_w16out_fptr;
895     ps_codec->apf_inter_pred[9] = (pf_inter_pred)ps_codec->s_func_selector.ihevc_inter_pred_luma_vert_w16inp_fptr;
896     ps_codec->apf_inter_pred[10] = (pf_inter_pred)ps_codec->s_func_selector.ihevc_inter_pred_luma_vert_w16inp_w16out_fptr;
897     ps_codec->apf_inter_pred[11] = NULL;
898     ps_codec->apf_inter_pred[12] = (pf_inter_pred)ps_codec->s_func_selector.ihevc_inter_pred_chroma_copy_fptr;
899     ps_codec->apf_inter_pred[13] = (pf_inter_pred)ps_codec->s_func_selector.ihevc_inter_pred_chroma_vert_fptr;
900     ps_codec->apf_inter_pred[14] = (pf_inter_pred)ps_codec->s_func_selector.ihevc_inter_pred_chroma_horz_fptr;
901     ps_codec->apf_inter_pred[15] = (pf_inter_pred)ps_codec->s_func_selector.ihevc_inter_pred_chroma_horz_w16out_fptr;
902     ps_codec->apf_inter_pred[16] = (pf_inter_pred)ps_codec->s_func_selector.ihevc_inter_pred_chroma_copy_w16out_fptr;
903     ps_codec->apf_inter_pred[17] = (pf_inter_pred)ps_codec->s_func_selector.ihevc_inter_pred_chroma_vert_w16out_fptr;
904     ps_codec->apf_inter_pred[18] = (pf_inter_pred)ps_codec->s_func_selector.ihevc_inter_pred_chroma_horz_w16out_fptr;
905     ps_codec->apf_inter_pred[19] = (pf_inter_pred)ps_codec->s_func_selector.ihevc_inter_pred_chroma_horz_w16out_fptr;
906     ps_codec->apf_inter_pred[20] = (pf_inter_pred)ps_codec->s_func_selector.ihevc_inter_pred_chroma_vert_w16inp_fptr;
907     ps_codec->apf_inter_pred[21] = (pf_inter_pred)ps_codec->s_func_selector.ihevc_inter_pred_chroma_vert_w16inp_w16out_fptr;
908 
909     /* Init intra pred function array */
910     ps_codec->apf_intra_pred_luma[0] = (pf_intra_pred)NULL;
911     ps_codec->apf_intra_pred_luma[1] = (pf_intra_pred)ps_codec->s_func_selector.ihevc_intra_pred_luma_planar_fptr;
912     ps_codec->apf_intra_pred_luma[2] = (pf_intra_pred)ps_codec->s_func_selector.ihevc_intra_pred_luma_dc_fptr;
913     ps_codec->apf_intra_pred_luma[3] = (pf_intra_pred)ps_codec->s_func_selector.ihevc_intra_pred_luma_mode2_fptr;
914     ps_codec->apf_intra_pred_luma[4] = (pf_intra_pred)ps_codec->s_func_selector.ihevc_intra_pred_luma_mode_3_to_9_fptr;
915     ps_codec->apf_intra_pred_luma[5] = (pf_intra_pred)ps_codec->s_func_selector.ihevc_intra_pred_luma_horz_fptr;
916     ps_codec->apf_intra_pred_luma[6] = (pf_intra_pred)ps_codec->s_func_selector.ihevc_intra_pred_luma_mode_11_to_17_fptr;
917     ps_codec->apf_intra_pred_luma[7] = (pf_intra_pred)ps_codec->s_func_selector.ihevc_intra_pred_luma_mode_18_34_fptr;
918     ps_codec->apf_intra_pred_luma[8] = (pf_intra_pred)ps_codec->s_func_selector.ihevc_intra_pred_luma_mode_19_to_25_fptr;
919     ps_codec->apf_intra_pred_luma[9] = (pf_intra_pred)ps_codec->s_func_selector.ihevc_intra_pred_luma_ver_fptr;
920     ps_codec->apf_intra_pred_luma[10] =  (pf_intra_pred)ps_codec->s_func_selector.ihevc_intra_pred_luma_mode_27_to_33_fptr;
921 
922     ps_codec->apf_intra_pred_chroma[0] = (pf_intra_pred)NULL;
923     ps_codec->apf_intra_pred_chroma[1] = (pf_intra_pred)ps_codec->s_func_selector.ihevc_intra_pred_chroma_planar_fptr;
924     ps_codec->apf_intra_pred_chroma[2] = (pf_intra_pred)ps_codec->s_func_selector.ihevc_intra_pred_chroma_dc_fptr;
925     ps_codec->apf_intra_pred_chroma[3] = (pf_intra_pred)ps_codec->s_func_selector.ihevc_intra_pred_chroma_mode2_fptr;
926     ps_codec->apf_intra_pred_chroma[4] = (pf_intra_pred)ps_codec->s_func_selector.ihevc_intra_pred_chroma_mode_3_to_9_fptr;
927     ps_codec->apf_intra_pred_chroma[5] = (pf_intra_pred)ps_codec->s_func_selector.ihevc_intra_pred_chroma_horz_fptr;
928     ps_codec->apf_intra_pred_chroma[6] = (pf_intra_pred)ps_codec->s_func_selector.ihevc_intra_pred_chroma_mode_11_to_17_fptr;
929     ps_codec->apf_intra_pred_chroma[7] = (pf_intra_pred)ps_codec->s_func_selector.ihevc_intra_pred_chroma_mode_18_34_fptr;
930     ps_codec->apf_intra_pred_chroma[8] = (pf_intra_pred)ps_codec->s_func_selector.ihevc_intra_pred_chroma_mode_19_to_25_fptr;
931     ps_codec->apf_intra_pred_chroma[9] =  (pf_intra_pred)ps_codec->s_func_selector.ihevc_intra_pred_chroma_ver_fptr;
932     ps_codec->apf_intra_pred_chroma[10] = (pf_intra_pred)ps_codec->s_func_selector.ihevc_intra_pred_chroma_mode_27_to_33_fptr;
933 
934     /* Init itrans_recon function array */
935     ps_codec->apf_itrans_recon[0] = (pf_itrans_recon)ps_codec->s_func_selector.ihevc_itrans_recon_4x4_ttype1_fptr;
936     ps_codec->apf_itrans_recon[1] = (pf_itrans_recon)ps_codec->s_func_selector.ihevc_itrans_recon_4x4_fptr;
937     ps_codec->apf_itrans_recon[2] = (pf_itrans_recon)ps_codec->s_func_selector.ihevc_itrans_recon_8x8_fptr;
938     ps_codec->apf_itrans_recon[3] = (pf_itrans_recon)ps_codec->s_func_selector.ihevc_itrans_recon_16x16_fptr;
939     ps_codec->apf_itrans_recon[4] = (pf_itrans_recon)ps_codec->s_func_selector.ihevc_itrans_recon_32x32_fptr;
940     ps_codec->apf_itrans_recon[5] = (pf_itrans_recon)ps_codec->s_func_selector.ihevc_chroma_itrans_recon_4x4_fptr;
941     ps_codec->apf_itrans_recon[6] = (pf_itrans_recon)ps_codec->s_func_selector.ihevc_chroma_itrans_recon_8x8_fptr;
942     ps_codec->apf_itrans_recon[7] = (pf_itrans_recon)ps_codec->s_func_selector.ihevc_chroma_itrans_recon_16x16_fptr;
943 
944     /* Init recon function array */
945     ps_codec->apf_recon[0] = (pf_recon)ps_codec->s_func_selector.ihevc_recon_4x4_ttype1_fptr;
946     ps_codec->apf_recon[1] = (pf_recon)ps_codec->s_func_selector.ihevc_recon_4x4_fptr;
947     ps_codec->apf_recon[2] = (pf_recon)ps_codec->s_func_selector.ihevc_recon_8x8_fptr;
948     ps_codec->apf_recon[3] = (pf_recon)ps_codec->s_func_selector.ihevc_recon_16x16_fptr;
949     ps_codec->apf_recon[4] = (pf_recon)ps_codec->s_func_selector.ihevc_recon_32x32_fptr;
950     ps_codec->apf_recon[5] = (pf_recon)ps_codec->s_func_selector.ihevc_chroma_recon_4x4_fptr;
951     ps_codec->apf_recon[6] = (pf_recon)ps_codec->s_func_selector.ihevc_chroma_recon_8x8_fptr;
952     ps_codec->apf_recon[7] = (pf_recon)ps_codec->s_func_selector.ihevc_chroma_recon_16x16_fptr;
953 
954     /* Init itrans_recon_dc function array */
955     ps_codec->apf_itrans_recon_dc[0] = (pf_itrans_recon_dc)ps_codec->s_func_selector.ihevcd_itrans_recon_dc_luma_fptr;
956     ps_codec->apf_itrans_recon_dc[1] = (pf_itrans_recon_dc)ps_codec->s_func_selector.ihevcd_itrans_recon_dc_chroma_fptr;
957 
958     /* Init sao function array */
959     ps_codec->apf_sao_luma[0] = (pf_sao_luma)ps_codec->s_func_selector.ihevc_sao_edge_offset_class0_fptr;
960     ps_codec->apf_sao_luma[1] = (pf_sao_luma)ps_codec->s_func_selector.ihevc_sao_edge_offset_class1_fptr;
961     ps_codec->apf_sao_luma[2] = (pf_sao_luma)ps_codec->s_func_selector.ihevc_sao_edge_offset_class2_fptr;
962     ps_codec->apf_sao_luma[3] = (pf_sao_luma)ps_codec->s_func_selector.ihevc_sao_edge_offset_class3_fptr;
963 
964     ps_codec->apf_sao_chroma[0] = (pf_sao_chroma)ps_codec->s_func_selector.ihevc_sao_edge_offset_class0_chroma_fptr;
965     ps_codec->apf_sao_chroma[1] = (pf_sao_chroma)ps_codec->s_func_selector.ihevc_sao_edge_offset_class1_chroma_fptr;
966     ps_codec->apf_sao_chroma[2] = (pf_sao_chroma)ps_codec->s_func_selector.ihevc_sao_edge_offset_class2_chroma_fptr;
967     ps_codec->apf_sao_chroma[3] = (pf_sao_chroma)ps_codec->s_func_selector.ihevc_sao_edge_offset_class3_chroma_fptr;
968 }
969 /**
970 *******************************************************************************
971 *
972 * @brief
973 *  Initialize the context. This will be called by  create and during
974 * reset
975 *
976 * @par Description:
977 *  Initializes the context
978 *
979 * @param[in] ps_codec
980 *  Codec context pointer
981 *
982 * @returns  Status
983 *
984 * @remarks
985 *
986 *
987 *******************************************************************************
988 */
ihevcd_init(codec_t * ps_codec)989 WORD32 ihevcd_init(codec_t *ps_codec)
990 {
991     WORD32 status = IV_SUCCESS;
992     WORD32 i;
993 
994     /* Free any dynamic buffers that are allocated */
995     ihevcd_free_dynamic_bufs(ps_codec);
996 
997     ps_codec->u4_allocate_dynamic_done = 0;
998     ps_codec->i4_num_disp_bufs = 1;
999     ps_codec->i4_flush_mode = 0;
1000 
1001     ps_codec->i4_ht = ps_codec->i4_disp_ht = 0;
1002     ps_codec->i4_wd = ps_codec->i4_disp_wd = 0;
1003     ps_codec->i4_strd = 0;
1004     ps_codec->i4_disp_strd = 0;
1005     ps_codec->i4_num_cores = 1;
1006 
1007     ps_codec->u4_pic_cnt = 0;
1008     ps_codec->u4_disp_cnt = 0;
1009 
1010     ps_codec->i4_header_mode = 0;
1011     ps_codec->i4_header_in_slice_mode = 0;
1012     ps_codec->i4_sps_done = 0;
1013     ps_codec->i4_pps_done = 0;
1014     ps_codec->i4_init_done   = 1;
1015     ps_codec->i4_first_pic_done = 0;
1016     ps_codec->s_parse.i4_first_pic_init = 0;
1017     ps_codec->i4_error_code = 0;
1018     ps_codec->i4_reset_flag = 0;
1019     ps_codec->i4_cra_as_first_pic = 1;
1020     ps_codec->i4_rasl_output_flag = 0;
1021 
1022     ps_codec->i4_prev_poc_msb = 0;
1023     ps_codec->i4_prev_poc_lsb = -1;
1024     ps_codec->i4_max_prev_poc_lsb = -1;
1025     ps_codec->s_parse.i4_abs_pic_order_cnt = -1;
1026 
1027     /* Set ref chroma format by default to 420SP UV interleaved */
1028     ps_codec->e_ref_chroma_fmt = IV_YUV_420SP_UV;
1029 
1030     /* If the codec is in shared mode and required format is 420 SP VU interleaved then change
1031      * reference buffers chroma format
1032      */
1033     if(IV_YUV_420SP_VU == ps_codec->e_chroma_fmt)
1034     {
1035         ps_codec->e_ref_chroma_fmt = IV_YUV_420SP_VU;
1036     }
1037 
1038 
1039 
1040     ps_codec->i4_disable_deblk_pic = 0;
1041 
1042     ps_codec->i4_degrade_pic_cnt    = 0;
1043     ps_codec->i4_degrade_pics       = 0;
1044     ps_codec->i4_degrade_type       = 0;
1045     ps_codec->i4_disable_sao_pic    = 0;
1046     ps_codec->i4_fullpel_inter_pred = 0;
1047     ps_codec->u4_enable_fmt_conv_ahead = 0;
1048     ps_codec->i4_share_disp_buf_cnt = 0;
1049 
1050     {
1051         sps_t *ps_sps = ps_codec->ps_sps_base;
1052         pps_t *ps_pps = ps_codec->ps_pps_base;
1053 
1054         for(i = 0; i < MAX_SPS_CNT; i++)
1055         {
1056             ps_sps->i1_sps_valid = 0;
1057             ps_sps++;
1058         }
1059 
1060         for(i = 0; i < MAX_PPS_CNT; i++)
1061         {
1062             ps_pps->i1_pps_valid = 0;
1063             ps_pps++;
1064         }
1065     }
1066 
1067     ihevcd_set_default_params(ps_codec);
1068     /* Initialize MV Bank buffer manager */
1069     ihevc_buf_mgr_init((buf_mgr_t *)ps_codec->pv_mv_buf_mgr);
1070 
1071     /* Initialize Picture buffer manager */
1072     ihevc_buf_mgr_init((buf_mgr_t *)ps_codec->pv_pic_buf_mgr);
1073 
1074     ps_codec->ps_pic_buf = (pic_buf_t *)ps_codec->pv_pic_buf_base;
1075 
1076     memset(ps_codec->ps_pic_buf, 0, BUF_MGR_MAX_CNT  * sizeof(pic_buf_t));
1077 
1078 
1079 
1080     /* Initialize display buffer manager */
1081     ihevc_disp_mgr_init((disp_mgr_t *)ps_codec->pv_disp_buf_mgr);
1082 
1083     /* Initialize dpb manager */
1084     ihevc_dpb_mgr_init((dpb_mgr_t *)ps_codec->pv_dpb_mgr);
1085 
1086     ps_codec->e_processor_soc = SOC_GENERIC;
1087     /* The following can be over-ridden using soc parameter as a hack */
1088     ps_codec->u4_nctb = 0x7FFFFFFF;
1089     ihevcd_init_arch(ps_codec);
1090 
1091     ihevcd_init_function_ptr(ps_codec);
1092 
1093     ihevcd_update_function_ptr(ps_codec);
1094 
1095     return status;
1096 }
1097 
1098 /**
1099 *******************************************************************************
1100 *
1101 * @brief
1102 *  Allocate static memory for the codec
1103 *
1104 * @par Description:
1105 *  Allocates static memory for the codec
1106 *
1107 * @param[in] pv_api_ip
1108 *  Pointer to input argument structure
1109 *
1110 * @param[out] pv_api_op
1111 *  Pointer to output argument structure
1112 *
1113 * @returns  Status
1114 *
1115 * @remarks
1116 *
1117 *
1118 *******************************************************************************
1119 */
ihevcd_allocate_static_bufs(iv_obj_t ** pps_codec_obj,ihevcd_cxa_create_ip_t * ps_create_ip,ihevcd_cxa_create_op_t * ps_create_op)1120 WORD32 ihevcd_allocate_static_bufs(iv_obj_t **pps_codec_obj,
1121                                    ihevcd_cxa_create_ip_t *ps_create_ip,
1122                                    ihevcd_cxa_create_op_t *ps_create_op)
1123 {
1124     WORD32 size;
1125     void *pv_buf;
1126     UWORD8 *pu1_buf;
1127     WORD32 i;
1128     codec_t *ps_codec;
1129     IV_API_CALL_STATUS_T status = IV_SUCCESS;
1130     void *(*pf_aligned_alloc)(void *pv_mem_ctxt, WORD32 alignment, WORD32 size);
1131     void (*pf_aligned_free)(void *pv_mem_ctxt, void *pv_buf);
1132     void *pv_mem_ctxt;
1133 
1134     /* Request memory for HEVCD object */
1135     ps_create_op->s_ivd_create_op_t.pv_handle = NULL;
1136 
1137     pf_aligned_alloc = ps_create_ip->s_ivd_create_ip_t.pf_aligned_alloc;
1138     pf_aligned_free = ps_create_ip->s_ivd_create_ip_t.pf_aligned_free;
1139     pv_mem_ctxt  = ps_create_ip->s_ivd_create_ip_t.pv_mem_ctxt;
1140 
1141 
1142     pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, sizeof(iv_obj_t));
1143     RETURN_IF((NULL == pv_buf), IV_FAIL);
1144     *pps_codec_obj = (iv_obj_t *)pv_buf;
1145     ps_create_op->s_ivd_create_op_t.pv_handle = *pps_codec_obj;
1146 
1147 
1148     (*pps_codec_obj)->pv_codec_handle = NULL;
1149     pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, sizeof(codec_t));
1150     RETURN_IF((NULL == pv_buf), IV_FAIL);
1151     (*pps_codec_obj)->pv_codec_handle = (codec_t *)pv_buf;
1152     ps_codec = (codec_t *)pv_buf;
1153 
1154     memset(ps_codec, 0, sizeof(codec_t));
1155 
1156 #ifndef LOGO_EN
1157     ps_codec->i4_share_disp_buf = ps_create_ip->s_ivd_create_ip_t.u4_share_disp_buf;
1158 #else
1159     ps_codec->i4_share_disp_buf = 0;
1160 #endif
1161 
1162     /* Shared display mode is supported only for 420SP and 420P formats */
1163     if((ps_create_ip->s_ivd_create_ip_t.e_output_format != IV_YUV_420P) &&
1164        (ps_create_ip->s_ivd_create_ip_t.e_output_format != IV_YUV_420SP_UV) &&
1165        (ps_create_ip->s_ivd_create_ip_t.e_output_format != IV_YUV_420SP_VU))
1166     {
1167         ps_codec->i4_share_disp_buf = 0;
1168     }
1169 
1170     ps_codec->e_chroma_fmt = ps_create_ip->s_ivd_create_ip_t.e_output_format;
1171 
1172     ps_codec->pf_aligned_alloc = pf_aligned_alloc;
1173     ps_codec->pf_aligned_free = pf_aligned_free;
1174     ps_codec->pv_mem_ctxt = pv_mem_ctxt;
1175 
1176     /* Request memory to hold thread handles for each processing thread */
1177     size = MAX_PROCESS_THREADS * ithread_get_handle_size();
1178     pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size);
1179     RETURN_IF((NULL == pv_buf), IV_FAIL);
1180 
1181     for(i = 0; i < MAX_PROCESS_THREADS; i++)
1182     {
1183         WORD32 handle_size = ithread_get_handle_size();
1184         ps_codec->apv_process_thread_handle[i] =
1185                         (UWORD8 *)pv_buf + (i * handle_size);
1186     }
1187 
1188     /* Request memory for static bitstream buffer which holds bitstream after emulation prevention */
1189     size = MIN_BITSBUF_SIZE;
1190     pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size);
1191     RETURN_IF((NULL == pv_buf), IV_FAIL);
1192     ps_codec->pu1_bitsbuf_static = pv_buf;
1193     ps_codec->u4_bitsbuf_size_static = size;
1194 
1195     /* size for holding display manager context */
1196     size = sizeof(buf_mgr_t);
1197     pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size);
1198     RETURN_IF((NULL == pv_buf), IV_FAIL);
1199     ps_codec->pv_disp_buf_mgr = pv_buf;
1200 
1201     /* size for holding dpb manager context */
1202     size = sizeof(dpb_mgr_t);
1203     pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size);
1204     RETURN_IF((NULL == pv_buf), IV_FAIL);
1205     ps_codec->pv_dpb_mgr = pv_buf;
1206 
1207     /* size for holding buffer manager context */
1208     size = sizeof(buf_mgr_t);
1209     pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size);
1210     RETURN_IF((NULL == pv_buf), IV_FAIL);
1211     ps_codec->pv_pic_buf_mgr = pv_buf;
1212 
1213     /* size for holding mv buffer manager context */
1214     size = sizeof(buf_mgr_t);
1215     pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size);
1216     RETURN_IF((NULL == pv_buf), IV_FAIL);
1217     ps_codec->pv_mv_buf_mgr = pv_buf;
1218 
1219     size = MAX_VPS_CNT * sizeof(vps_t);
1220     pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size);
1221     RETURN_IF((NULL == pv_buf), IV_FAIL);
1222     ps_codec->ps_vps_base = pv_buf;
1223     ps_codec->s_parse.ps_vps_base = ps_codec->ps_vps_base;
1224 
1225     size = MAX_SPS_CNT * sizeof(sps_t);
1226     pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size);
1227     RETURN_IF((NULL == pv_buf), IV_FAIL);
1228     ps_codec->ps_sps_base = pv_buf;
1229     ps_codec->s_parse.ps_sps_base = ps_codec->ps_sps_base;
1230 
1231     size = MAX_PPS_CNT * sizeof(pps_t);
1232     pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size);
1233     RETURN_IF((NULL == pv_buf), IV_FAIL);
1234     ps_codec->ps_pps_base = pv_buf;
1235     ps_codec->s_parse.ps_pps_base = ps_codec->ps_pps_base;
1236 
1237     size = MAX_SLICE_HDR_CNT * sizeof(slice_header_t);
1238     pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size);
1239     RETURN_IF((NULL == pv_buf), IV_FAIL);
1240     memset(pv_buf, 0, size);
1241     ps_codec->ps_slice_hdr_base = (slice_header_t *)pv_buf;
1242     ps_codec->s_parse.ps_slice_hdr_base = ps_codec->ps_slice_hdr_base;
1243 
1244 
1245     SCALING_MAT_SIZE(size)
1246     size = (MAX_SPS_CNT + MAX_PPS_CNT) * size * sizeof(WORD16);
1247     pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size);
1248     RETURN_IF((NULL == pv_buf), IV_FAIL);
1249     ps_codec->pi2_scaling_mat = (WORD16 *)pv_buf;
1250 
1251 
1252     /* Size for holding pic_buf_t for each reference picture
1253      * Since this is only a structure allocation and not actual buffer allocation,
1254      * it is allocated for BUF_MGR_MAX_CNT entries
1255      */
1256     size = BUF_MGR_MAX_CNT * sizeof(pic_buf_t);
1257     pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size);
1258     RETURN_IF((NULL == pv_buf), IV_FAIL);
1259     ps_codec->pv_pic_buf_base = (UWORD8 *)pv_buf;
1260 
1261     /* TO hold scratch buffers needed for each SAO context */
1262     size = 4 * MAX_CTB_SIZE * MAX_CTB_SIZE;
1263 
1264     /* 2 temporary buffers*/
1265     size *= 2;
1266     size *= MAX_PROCESS_THREADS;
1267 
1268     pu1_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size);
1269     RETURN_IF((NULL == pu1_buf), IV_FAIL);
1270 
1271     for(i = 0; i < MAX_PROCESS_THREADS; i++)
1272     {
1273         ps_codec->as_process[i].s_sao_ctxt.pu1_tmp_buf_luma = (UWORD8 *)pu1_buf;
1274         pu1_buf += 4 * MAX_CTB_SIZE * MAX_CTB_SIZE * sizeof(UWORD8);
1275 
1276         ps_codec->as_process[i].s_sao_ctxt.pu1_tmp_buf_chroma = (UWORD8 *)pu1_buf;
1277         pu1_buf += 4 * MAX_CTB_SIZE * MAX_CTB_SIZE * sizeof(UWORD8);
1278     }
1279 
1280     /* Allocate intra pred modes buffer */
1281     /* 8 bits per 4x4 */
1282     /* 16 bytes each for top and left 64 pixels and 16 bytes for default mode */
1283     size =  3 * 16 * sizeof(UWORD8);
1284     pu1_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size);
1285     RETURN_IF((NULL == pu1_buf), IV_FAIL);
1286     ps_codec->s_parse.pu1_luma_intra_pred_mode_left = pu1_buf;
1287     ps_codec->s_parse.pu1_luma_intra_pred_mode_top  = pu1_buf + 16;
1288 
1289     {
1290         WORD32 inter_pred_tmp_buf_size, ntaps_luma;
1291         WORD32 pic_pu_idx_map_size;
1292 
1293         /* Max inter pred size */
1294         ntaps_luma = 8;
1295         inter_pred_tmp_buf_size = sizeof(WORD16) * (MAX_CTB_SIZE + ntaps_luma) * MAX_CTB_SIZE;
1296 
1297         inter_pred_tmp_buf_size = ALIGN64(inter_pred_tmp_buf_size);
1298 
1299         /* To hold pu_index w.r.t. frame level pu_t array for a CTB */
1300         pic_pu_idx_map_size = sizeof(WORD32) * (18 * 18);
1301         pic_pu_idx_map_size = ALIGN64(pic_pu_idx_map_size);
1302 
1303         size =  inter_pred_tmp_buf_size * 2;
1304         size += pic_pu_idx_map_size;
1305         size *= MAX_PROCESS_THREADS;
1306 
1307         pu1_buf = ps_codec->pf_aligned_alloc(pv_mem_ctxt, 128, size);
1308         RETURN_IF((NULL == pu1_buf), IV_FAIL);
1309         memset(pu1_buf, 0, size);
1310 
1311         for(i = 0; i < MAX_PROCESS_THREADS; i++)
1312         {
1313             ps_codec->as_process[i].pi2_inter_pred_tmp_buf1 = (WORD16 *)pu1_buf;
1314             pu1_buf += inter_pred_tmp_buf_size;
1315 
1316             ps_codec->as_process[i].pi2_inter_pred_tmp_buf2 = (WORD16 *)pu1_buf;
1317             pu1_buf += inter_pred_tmp_buf_size;
1318 
1319             /* Inverse transform intermediate and inverse scan output buffers reuse inter pred scratch buffers */
1320             ps_codec->as_process[i].pi2_itrans_intrmd_buf =
1321                             ps_codec->as_process[i].pi2_inter_pred_tmp_buf2;
1322             ps_codec->as_process[i].pi2_invscan_out =
1323                             ps_codec->as_process[i].pi2_inter_pred_tmp_buf1;
1324 
1325             ps_codec->as_process[i].pu4_pic_pu_idx_map = (UWORD32 *)pu1_buf;
1326             ps_codec->as_process[i].s_bs_ctxt.pu4_pic_pu_idx_map =
1327                             (UWORD32 *)pu1_buf;
1328             pu1_buf += pic_pu_idx_map_size;
1329 
1330             //   ps_codec->as_process[i].pi2_inter_pred_tmp_buf3 = (WORD16 *)pu1_buf;
1331             //   pu1_buf += inter_pred_tmp_buf_size;
1332 
1333             ps_codec->as_process[i].i4_inter_pred_tmp_buf_strd = MAX_CTB_SIZE;
1334 
1335         }
1336     }
1337     /* Initialize pointers in PPS structures */
1338     {
1339         sps_t *ps_sps = ps_codec->ps_sps_base;
1340         pps_t *ps_pps = ps_codec->ps_pps_base;
1341         WORD16 *pi2_scaling_mat =  ps_codec->pi2_scaling_mat;
1342         WORD32 scaling_mat_size;
1343 
1344         SCALING_MAT_SIZE(scaling_mat_size);
1345 
1346         for(i = 0; i < MAX_SPS_CNT; i++)
1347         {
1348             ps_sps->pi2_scaling_mat  = pi2_scaling_mat;
1349             pi2_scaling_mat += scaling_mat_size;
1350             ps_sps++;
1351         }
1352 
1353         for(i = 0; i < MAX_PPS_CNT; i++)
1354         {
1355             ps_pps->pi2_scaling_mat  = pi2_scaling_mat;
1356             pi2_scaling_mat += scaling_mat_size;
1357             ps_pps++;
1358         }
1359     }
1360 
1361     return (status);
1362 }
1363 
1364 /**
1365 *******************************************************************************
1366 *
1367 * @brief
1368 *  Free static memory for the codec
1369 *
1370 * @par Description:
1371 *  Free static memory for the codec
1372 *
1373 * @param[in] ps_codec
1374 *  Pointer to codec context
1375 *
1376 * @returns  Status
1377 *
1378 * @remarks
1379 *
1380 *
1381 *******************************************************************************
1382 */
ihevcd_free_static_bufs(iv_obj_t * ps_codec_obj)1383 WORD32 ihevcd_free_static_bufs(iv_obj_t *ps_codec_obj)
1384 {
1385     codec_t *ps_codec;
1386 
1387     void (*pf_aligned_free)(void *pv_mem_ctxt, void *pv_buf);
1388     void *pv_mem_ctxt;
1389 
1390     ps_codec = (codec_t *)ps_codec_obj->pv_codec_handle;
1391     pf_aligned_free = ps_codec->pf_aligned_free;
1392     pv_mem_ctxt = ps_codec->pv_mem_ctxt;
1393 
1394 
1395     ALIGNED_FREE(ps_codec, ps_codec->apv_process_thread_handle[0]);
1396     ALIGNED_FREE(ps_codec, ps_codec->pu1_bitsbuf_static);
1397 
1398     ALIGNED_FREE(ps_codec, ps_codec->pv_disp_buf_mgr);
1399     ALIGNED_FREE(ps_codec, ps_codec->pv_dpb_mgr);
1400     ALIGNED_FREE(ps_codec, ps_codec->pv_pic_buf_mgr);
1401     ALIGNED_FREE(ps_codec, ps_codec->pv_mv_buf_mgr);
1402     ALIGNED_FREE(ps_codec, ps_codec->ps_vps_base);
1403     ALIGNED_FREE(ps_codec, ps_codec->ps_sps_base);
1404     ALIGNED_FREE(ps_codec, ps_codec->ps_pps_base);
1405     ALIGNED_FREE(ps_codec, ps_codec->ps_slice_hdr_base);
1406     ALIGNED_FREE(ps_codec, ps_codec->pi2_scaling_mat);
1407     ALIGNED_FREE(ps_codec, ps_codec->pv_pic_buf_base);
1408     ALIGNED_FREE(ps_codec, ps_codec->s_parse.pu1_luma_intra_pred_mode_left);
1409     ALIGNED_FREE(ps_codec, ps_codec->as_process[0].s_sao_ctxt.pu1_tmp_buf_luma);
1410     ALIGNED_FREE(ps_codec, ps_codec->as_process[0].pi2_inter_pred_tmp_buf1);
1411     ALIGNED_FREE(ps_codec, ps_codec_obj->pv_codec_handle);
1412 
1413     if(ps_codec_obj)
1414     {
1415         pf_aligned_free(pv_mem_ctxt, ps_codec_obj);
1416     }
1417 
1418     return IV_SUCCESS;
1419 
1420 }
1421 
1422 
1423 /**
1424 *******************************************************************************
1425 *
1426 * @brief
1427 *  Allocate dynamic memory for the codec
1428 *
1429 * @par Description:
1430 *  Allocates dynamic memory for the codec
1431 *
1432 * @param[in] ps_codec
1433 *  Pointer to codec context
1434 *
1435 * @returns  Status
1436 *
1437 * @remarks
1438 *
1439 *
1440 *******************************************************************************
1441 */
ihevcd_allocate_dynamic_bufs(codec_t * ps_codec)1442 WORD32 ihevcd_allocate_dynamic_bufs(codec_t *ps_codec)
1443 {
1444     WORD32 max_tile_cols, max_tile_rows;
1445     WORD32 max_ctb_rows, max_ctb_cols;
1446     WORD32 max_num_cu_cols;
1447     WORD32 max_num_cu_rows;
1448     WORD32 max_num_4x4_cols;
1449     WORD32 max_ctb_cnt;
1450     WORD32 wd;
1451     WORD32 ht;
1452     WORD32 i;
1453     WORD32 max_dpb_size;
1454     void *pv_mem_ctxt = ps_codec->pv_mem_ctxt;
1455     void *pv_buf;
1456     UWORD8 *pu1_buf;
1457     WORD32 size;
1458 
1459     wd = ALIGN64(ps_codec->i4_wd);
1460     ht = ALIGN64(ps_codec->i4_ht);
1461 
1462     max_tile_cols = (wd + MIN_TILE_WD - 1) / MIN_TILE_WD;
1463     max_tile_rows = (ht + MIN_TILE_HT - 1) / MIN_TILE_HT;
1464     max_ctb_rows  = ht / MIN_CTB_SIZE;
1465     max_ctb_cols  = wd / MIN_CTB_SIZE;
1466     max_ctb_cnt   = max_ctb_rows * max_ctb_cols;
1467     max_num_cu_cols = wd / MIN_CU_SIZE;
1468     max_num_cu_rows = ht / MIN_CU_SIZE;
1469     max_num_4x4_cols = wd / 4;
1470 
1471     /* Allocate tile structures */
1472     size = max_tile_cols * max_tile_rows;
1473     size *= sizeof(tile_t);
1474     size *= MAX_PPS_CNT;
1475 
1476     pv_buf = ps_codec->pf_aligned_alloc(pv_mem_ctxt, 128, size);
1477     RETURN_IF((NULL == pv_buf), IV_FAIL);
1478     memset(pv_buf, 0, size);
1479     ps_codec->ps_tile = (tile_t *)pv_buf;
1480 
1481 
1482     /* Allocate memory to hold entry point offsets */
1483     /* One entry point per tile */
1484     size = max_tile_cols * max_tile_rows;
1485 
1486     /* One entry point per row of CTBs */
1487     /*********************************************************************/
1488     /* Only tiles or entropy sync is enabled at a time in main           */
1489     /* profile, but since memory required does not increase too much,    */
1490     /* this allocation is done to handle both cases                      */
1491     /*********************************************************************/
1492     size  += max_ctb_rows;
1493     size *= sizeof(WORD32);
1494 
1495     pv_buf = ps_codec->pf_aligned_alloc(pv_mem_ctxt, 128, size);
1496     RETURN_IF((NULL == pv_buf), IV_FAIL);
1497     memset(pv_buf, 0, size);
1498     ps_codec->pi4_entry_ofst = (WORD32 *)pv_buf;
1499 
1500     /* Allocate parse skip flag buffer */
1501     /* 1 bit per 8x8 */
1502     size = max_num_cu_cols / 8;
1503     size = ALIGN4(size);
1504     pv_buf = ps_codec->pf_aligned_alloc(pv_mem_ctxt, 128, size);
1505     RETURN_IF((NULL == pv_buf), IV_FAIL);
1506     memset(pv_buf, 0, size);
1507     ps_codec->s_parse.pu4_skip_cu_top = (UWORD32 *)pv_buf;
1508 
1509     /* Allocate parse coding tree depth buffer */
1510     /* 2 bits per 8x8 */
1511     size =  max_num_cu_cols / 4;
1512     size = ALIGN4(size);
1513     pv_buf = ps_codec->pf_aligned_alloc(pv_mem_ctxt, 128, size);
1514     RETURN_IF((NULL == pv_buf), IV_FAIL);
1515     memset(pv_buf, 0, size);
1516     ps_codec->s_parse.pu4_ct_depth_top = (UWORD32 *)pv_buf;
1517 
1518     /* Allocate intra flag buffer */
1519     /* 1 bit per 8x8 */
1520     size =  max_num_cu_cols * max_num_cu_rows / 8;
1521     size = ALIGN4(size);
1522     pv_buf = ps_codec->pf_aligned_alloc(pv_mem_ctxt, 128, size);
1523     RETURN_IF((NULL == pv_buf), IV_FAIL);
1524     memset(pv_buf, 0, size);
1525     ps_codec->pu1_pic_intra_flag = (UWORD8 *)pv_buf;
1526     ps_codec->s_parse.pu1_pic_intra_flag = ps_codec->pu1_pic_intra_flag;
1527 
1528     /* Allocate transquant bypass flag buffer */
1529     /* 1 bit per 8x8 */
1530     /* Extra row and column are allocated for easy processing of top and left blocks while loop filtering */
1531     size =  ((max_num_cu_cols + 8) * (max_num_cu_rows + 8)) / 8;
1532     size = ALIGN4(size);
1533     pv_buf = ps_codec->pf_aligned_alloc(pv_mem_ctxt, 128, size);
1534     RETURN_IF((NULL == pv_buf), IV_FAIL);
1535     memset(pv_buf, 1, size);
1536     {
1537         WORD32 loop_filter_strd = (wd + 63) >> 6;
1538         ps_codec->pu1_pic_no_loop_filter_flag_base = pv_buf;
1539         /* The offset is added for easy processing of top and left blocks while loop filtering */
1540         ps_codec->pu1_pic_no_loop_filter_flag = (UWORD8 *)pv_buf + loop_filter_strd + 1;
1541         ps_codec->s_parse.pu1_pic_no_loop_filter_flag = ps_codec->pu1_pic_no_loop_filter_flag;
1542         ps_codec->s_parse.s_deblk_ctxt.pu1_pic_no_loop_filter_flag = ps_codec->pu1_pic_no_loop_filter_flag;
1543         ps_codec->s_parse.s_sao_ctxt.pu1_pic_no_loop_filter_flag = ps_codec->pu1_pic_no_loop_filter_flag;
1544     }
1545 
1546     /* Initialize pointers in PPS structures */
1547     {
1548         pps_t *ps_pps = ps_codec->ps_pps_base;
1549         tile_t *ps_tile =  ps_codec->ps_tile;
1550 
1551         for(i = 0; i < MAX_PPS_CNT; i++)
1552         {
1553             ps_pps->ps_tile = ps_tile;
1554             ps_tile += (max_tile_cols * max_tile_rows);
1555             ps_pps++;
1556         }
1557 
1558     }
1559 
1560     /* Allocate memory for job queue */
1561 
1562     /* One job per row of CTBs */
1563     size  = max_ctb_rows;
1564 
1565     /* One each tile a row of CTBs, num_jobs has to incremented */
1566     size  *= max_tile_cols;
1567 
1568     /* One format convert/frame copy job per row of CTBs for non-shared mode*/
1569     size  += max_ctb_rows;
1570 
1571     size *= sizeof(proc_job_t);
1572 
1573     size += ihevcd_jobq_ctxt_size();
1574     size = ALIGN4(size);
1575 
1576     pv_buf = ps_codec->pf_aligned_alloc(pv_mem_ctxt, 128, size);
1577     RETURN_IF((NULL == pv_buf), IV_FAIL);
1578     ps_codec->pv_proc_jobq_buf = pv_buf;
1579     ps_codec->i4_proc_jobq_buf_size = size;
1580 
1581     size =  max_ctb_cnt;
1582     size = ALIGN4(size);
1583     pv_buf = ps_codec->pf_aligned_alloc(pv_mem_ctxt, 128, size);
1584     RETURN_IF((NULL == pv_buf), IV_FAIL);
1585     memset(pv_buf, 0, size);
1586     ps_codec->pu1_parse_map = (UWORD8 *)pv_buf;
1587 
1588     size =  max_ctb_cnt;
1589     size = ALIGN4(size);
1590     pv_buf = ps_codec->pf_aligned_alloc(pv_mem_ctxt, 128, size);
1591     RETURN_IF((NULL == pv_buf), IV_FAIL);
1592     memset(pv_buf, 0, size);
1593     ps_codec->pu1_proc_map = (UWORD8 *)pv_buf;
1594 
1595     /** Holds top and left neighbor's pu idx into picture level pu array */
1596     /* Only one top row is enough but left has to be replicated for each process context */
1597     size =  (max_num_4x4_cols  /* left */ + MAX_PROCESS_THREADS * (MAX_CTB_SIZE / 4)/* top */ + 1/* top right */) * sizeof(WORD32);
1598     size = ALIGN4(size);
1599     pv_buf = ps_codec->pf_aligned_alloc(pv_mem_ctxt, 128, size);
1600     RETURN_IF((NULL == pv_buf), IV_FAIL);
1601     memset(pv_buf, 0, size);
1602 
1603     for(i = 0; i < MAX_PROCESS_THREADS; i++)
1604     {
1605         UWORD32 *pu4_buf = (UWORD32 *)pv_buf;
1606         ps_codec->as_process[i].pu4_pic_pu_idx_left = pu4_buf + i * (MAX_CTB_SIZE / 4);
1607         memset(ps_codec->as_process[i].pu4_pic_pu_idx_left, 0, sizeof(UWORD32) * MAX_CTB_SIZE / 4);
1608         ps_codec->as_process[i].pu4_pic_pu_idx_top = pu4_buf + MAX_PROCESS_THREADS * (MAX_CTB_SIZE / 4);
1609     }
1610     memset(ps_codec->as_process[0].pu4_pic_pu_idx_top, 0, sizeof(UWORD32) * (wd / 4 + 1));
1611 
1612     {
1613         /* To hold SAO left buffer for luma */
1614         size  = sizeof(UWORD8) * (MAX(ht, wd));
1615 
1616         /* To hold SAO left buffer for chroma */
1617         size += sizeof(UWORD8) * (MAX(ht, wd));
1618 
1619         /* To hold SAO top buffer for luma */
1620         size += sizeof(UWORD8) * wd;
1621 
1622         /* To hold SAO top buffer for chroma */
1623         size += sizeof(UWORD8) * wd;
1624 
1625         /* To hold SAO top left luma pixel value for last output ctb in a row*/
1626         size += sizeof(UWORD8) * max_ctb_rows;
1627 
1628         /* To hold SAO top left chroma pixel value last output ctb in a row*/
1629         size += sizeof(UWORD8) * max_ctb_rows * 2;
1630 
1631         /* To hold SAO top left pixel luma for current ctb - column array*/
1632         size += sizeof(UWORD8) * max_ctb_rows;
1633 
1634         /* To hold SAO top left pixel chroma for current ctb-column array*/
1635         size += sizeof(UWORD8) * max_ctb_rows * 2;
1636 
1637         /* To hold SAO top right pixel luma pixel value last output ctb in a row*/
1638         size += sizeof(UWORD8) * max_ctb_cols;
1639 
1640         /* To hold SAO top right pixel chroma pixel value last output ctb in a row*/
1641         size += sizeof(UWORD8) * max_ctb_cols * 2;
1642 
1643         /*To hold SAO botton bottom left pixels for luma*/
1644         size += sizeof(UWORD8) * max_ctb_rows;
1645 
1646         /*To hold SAO botton bottom left pixels for luma*/
1647         size += sizeof(UWORD8) * max_ctb_rows * 2;
1648         size = ALIGN64(size);
1649 
1650         pu1_buf = ps_codec->pf_aligned_alloc(pv_mem_ctxt, 128, size);
1651         RETURN_IF((NULL == pu1_buf), IV_FAIL);
1652         memset(pu1_buf, 0, size);
1653 
1654         for(i = 0; i < MAX_PROCESS_THREADS; i++)
1655         {
1656             ps_codec->as_process[i].s_sao_ctxt.pu1_sao_src_left_luma = (UWORD8 *)pu1_buf;
1657         }
1658         ps_codec->s_parse.s_sao_ctxt.pu1_sao_src_left_luma = (UWORD8 *)pu1_buf;
1659         pu1_buf += MAX(ht, wd);
1660 
1661         for(i = 0; i < MAX_PROCESS_THREADS; i++)
1662         {
1663             ps_codec->as_process[i].s_sao_ctxt.pu1_sao_src_left_chroma = (UWORD8 *)pu1_buf;
1664         }
1665         ps_codec->s_parse.s_sao_ctxt.pu1_sao_src_left_chroma = (UWORD8 *)pu1_buf;
1666         pu1_buf += MAX(ht, wd);
1667         for(i = 0; i < MAX_PROCESS_THREADS; i++)
1668         {
1669             ps_codec->as_process[i].s_sao_ctxt.pu1_sao_src_top_luma = (UWORD8 *)pu1_buf;
1670         }
1671         ps_codec->s_parse.s_sao_ctxt.pu1_sao_src_top_luma = (UWORD8 *)pu1_buf;
1672         pu1_buf += wd;
1673 
1674         for(i = 0; i < MAX_PROCESS_THREADS; i++)
1675         {
1676             ps_codec->as_process[i].s_sao_ctxt.pu1_sao_src_top_chroma = (UWORD8 *)pu1_buf;
1677         }
1678         ps_codec->s_parse.s_sao_ctxt.pu1_sao_src_top_chroma = (UWORD8 *)pu1_buf;
1679         pu1_buf += wd;
1680         for(i = 0; i < MAX_PROCESS_THREADS; i++)
1681         {
1682             ps_codec->as_process[i].s_sao_ctxt.pu1_sao_src_luma_top_left_ctb = (UWORD8 *)pu1_buf;
1683         }
1684         ps_codec->s_parse.s_sao_ctxt.pu1_sao_src_luma_top_left_ctb = (UWORD8 *)pu1_buf;
1685         pu1_buf += ht / MIN_CTB_SIZE;
1686 
1687         for(i = 0; i < MAX_PROCESS_THREADS; i++)
1688         {
1689             ps_codec->as_process[i].s_sao_ctxt.pu1_sao_src_chroma_top_left_ctb = (UWORD8 *)pu1_buf;
1690         }
1691         ps_codec->s_parse.s_sao_ctxt.pu1_sao_src_chroma_top_left_ctb = (UWORD8 *)pu1_buf;
1692         pu1_buf += (ht / MIN_CTB_SIZE) * 2;
1693 
1694         for(i = 0; i < MAX_PROCESS_THREADS; i++)
1695         {
1696             ps_codec->as_process[i].s_sao_ctxt.pu1_sao_src_top_left_luma_curr_ctb = (UWORD8 *)pu1_buf;
1697         }
1698         ps_codec->s_parse.s_sao_ctxt.pu1_sao_src_top_left_luma_curr_ctb = (UWORD8 *)pu1_buf;
1699         pu1_buf += ht / MIN_CTB_SIZE;
1700 
1701         for(i = 0; i < MAX_PROCESS_THREADS; i++)
1702         {
1703             ps_codec->as_process[i].s_sao_ctxt.pu1_sao_src_top_left_chroma_curr_ctb = (UWORD8 *)pu1_buf;
1704         }
1705         ps_codec->s_parse.s_sao_ctxt.pu1_sao_src_top_left_chroma_curr_ctb = (UWORD8 *)pu1_buf;
1706 
1707         pu1_buf += (ht / MIN_CTB_SIZE) * 2;
1708         for(i = 0; i < MAX_PROCESS_THREADS; i++)
1709         {
1710             ps_codec->as_process[i].s_sao_ctxt.pu1_sao_src_top_left_luma_top_right = (UWORD8 *)pu1_buf;
1711         }
1712         ps_codec->s_parse.s_sao_ctxt.pu1_sao_src_top_left_luma_top_right = (UWORD8 *)pu1_buf;
1713 
1714         pu1_buf += wd / MIN_CTB_SIZE;
1715         for(i = 0; i < MAX_PROCESS_THREADS; i++)
1716         {
1717             ps_codec->as_process[i].s_sao_ctxt.pu1_sao_src_top_left_chroma_top_right = (UWORD8 *)pu1_buf;
1718         }
1719         ps_codec->s_parse.s_sao_ctxt.pu1_sao_src_top_left_chroma_top_right = (UWORD8 *)pu1_buf;
1720 
1721         pu1_buf += (wd / MIN_CTB_SIZE) * 2;
1722 
1723         /*Per CTB, Store 1 value for luma , 2 values for chroma*/
1724         for(i = 0; i < MAX_PROCESS_THREADS; i++)
1725         {
1726             ps_codec->as_process[i].s_sao_ctxt.pu1_sao_src_top_left_luma_bot_left = (UWORD8 *)pu1_buf;
1727         }
1728         ps_codec->s_parse.s_sao_ctxt.pu1_sao_src_top_left_luma_bot_left = (UWORD8 *)pu1_buf;
1729 
1730         pu1_buf += (ht / MIN_CTB_SIZE);
1731 
1732         for(i = 0; i < MAX_PROCESS_THREADS; i++)
1733         {
1734             ps_codec->as_process[i].s_sao_ctxt.pu1_sao_src_top_left_chroma_bot_left = (UWORD8 *)pu1_buf;
1735         }
1736         ps_codec->s_parse.s_sao_ctxt.pu1_sao_src_top_left_chroma_bot_left = (UWORD8 *)pu1_buf;
1737 
1738         pu1_buf += (ht / MIN_CTB_SIZE) * 2;
1739     }
1740 
1741 
1742     {
1743         UWORD8 *pu1_buf = (UWORD8 *)pv_buf;
1744         WORD32 vert_bs_size, horz_bs_size;
1745         WORD32 qp_const_flag_size;
1746         WORD32 qp_size;
1747         WORD32 num_8x8;
1748 
1749         /* Max Number of vertical edges */
1750         vert_bs_size = wd / 8 + 2 * MAX_CTB_SIZE / 8;
1751 
1752         /* Max Number of horizontal edges - extra MAX_CTB_SIZE / 8 to handle the last 4 rows separately(shifted CTB processing) */
1753         vert_bs_size *= (ht + MAX_CTB_SIZE) / MIN_TU_SIZE;
1754 
1755         /* Number of bytes */
1756         vert_bs_size /= 8;
1757 
1758         /* Two bits per edge */
1759         vert_bs_size *= 2;
1760 
1761         /* Max Number of horizontal edges */
1762         horz_bs_size = ht / 8 + MAX_CTB_SIZE / 8;
1763 
1764         /* Max Number of vertical edges - extra MAX_CTB_SIZE / 8 to handle the last 4 columns separately(shifted CTB processing) */
1765         horz_bs_size *= (wd + MAX_CTB_SIZE) / MIN_TU_SIZE;
1766 
1767         /* Number of bytes */
1768         horz_bs_size /= 8;
1769 
1770         /* Two bits per edge */
1771         horz_bs_size *= 2;
1772 
1773         /* Max CTBs in a row */
1774         qp_const_flag_size = wd / MIN_CTB_SIZE + 1 /* The last ctb row deblk is done in last ctb + 1 row.*/;
1775 
1776         /* Max CTBs in a column */
1777         qp_const_flag_size *= ht / MIN_CTB_SIZE;
1778 
1779         /* Number of bytes */
1780         qp_const_flag_size /= 8;
1781 
1782         /* QP changes at CU level - So store at 8x8 level */
1783         num_8x8 = (ht * wd) / (MIN_CU_SIZE * MIN_CU_SIZE);
1784         qp_size = num_8x8;
1785 
1786         /* To hold vertical boundary strength */
1787         size += vert_bs_size;
1788 
1789         /* To hold horizontal boundary strength */
1790         size += horz_bs_size;
1791 
1792         /* To hold QP */
1793         size += qp_size;
1794 
1795         /* To hold QP const in CTB flags */
1796         size += qp_const_flag_size;
1797 
1798         pu1_buf = ps_codec->pf_aligned_alloc(pv_mem_ctxt, 128, size);
1799         RETURN_IF((NULL == pu1_buf), IV_FAIL);
1800 
1801         memset(pu1_buf, 0, size);
1802 
1803         for(i = 0; i < MAX_PROCESS_THREADS; i++)
1804         {
1805             ps_codec->as_process[i].s_bs_ctxt.pu4_pic_vert_bs = (UWORD32 *)pu1_buf;
1806             ps_codec->as_process[i].s_deblk_ctxt.s_bs_ctxt.pu4_pic_vert_bs = (UWORD32 *)pu1_buf;
1807             ps_codec->s_parse.s_deblk_ctxt.s_bs_ctxt.pu4_pic_vert_bs = (UWORD32 *)pu1_buf;
1808             pu1_buf += vert_bs_size;
1809 
1810             ps_codec->as_process[i].s_bs_ctxt.pu4_pic_horz_bs = (UWORD32 *)pu1_buf;
1811             ps_codec->as_process[i].s_deblk_ctxt.s_bs_ctxt.pu4_pic_horz_bs = (UWORD32 *)pu1_buf;
1812             ps_codec->s_parse.s_deblk_ctxt.s_bs_ctxt.pu4_pic_horz_bs = (UWORD32 *)pu1_buf;
1813             pu1_buf += horz_bs_size;
1814 
1815             ps_codec->as_process[i].s_bs_ctxt.pu1_pic_qp = (UWORD8 *)pu1_buf;
1816             ps_codec->as_process[i].s_deblk_ctxt.s_bs_ctxt.pu1_pic_qp = (UWORD8 *)pu1_buf;
1817             ps_codec->s_parse.s_deblk_ctxt.s_bs_ctxt.pu1_pic_qp = (UWORD8 *)pu1_buf;
1818             pu1_buf += qp_size;
1819 
1820             ps_codec->as_process[i].s_bs_ctxt.pu1_pic_qp_const_in_ctb = (UWORD8 *)pu1_buf;
1821             ps_codec->as_process[i].s_deblk_ctxt.s_bs_ctxt.pu1_pic_qp_const_in_ctb = (UWORD8 *)pu1_buf;
1822             ps_codec->s_parse.s_deblk_ctxt.s_bs_ctxt.pu1_pic_qp_const_in_ctb = (UWORD8 *)pu1_buf;
1823             pu1_buf += qp_const_flag_size;
1824 
1825             pu1_buf -= (vert_bs_size + horz_bs_size + qp_size + qp_const_flag_size);
1826         }
1827         ps_codec->s_parse.s_bs_ctxt.pu4_pic_vert_bs = (UWORD32 *)pu1_buf;
1828         pu1_buf += vert_bs_size;
1829 
1830         ps_codec->s_parse.s_bs_ctxt.pu4_pic_horz_bs = (UWORD32 *)pu1_buf;
1831         pu1_buf += horz_bs_size;
1832 
1833         ps_codec->s_parse.s_bs_ctxt.pu1_pic_qp = (UWORD8 *)pu1_buf;
1834         pu1_buf += qp_size;
1835 
1836         ps_codec->s_parse.s_bs_ctxt.pu1_pic_qp_const_in_ctb = (UWORD8 *)pu1_buf;
1837         pu1_buf += qp_const_flag_size;
1838 
1839     }
1840 
1841     /* Max CTBs in a row */
1842     size  = wd / MIN_CTB_SIZE + 2 /* Top row and bottom row extra. This ensures accessing left,top in first row
1843                                               and right in last row will not result in invalid access*/;
1844     /* Max CTBs in a column */
1845     size *= ht / MIN_CTB_SIZE;
1846 
1847     size *= sizeof(UWORD16);
1848     pv_buf = ps_codec->pf_aligned_alloc(pv_mem_ctxt, 128, size);
1849     RETURN_IF((NULL == pv_buf), IV_FAIL);
1850     memset(pv_buf, 0, size);
1851 
1852     ps_codec->pu1_tile_idx_base = pv_buf;
1853     for(i = 0; i < MAX_PROCESS_THREADS; i++)
1854     {
1855         ps_codec->as_process[i].pu1_tile_idx = (UWORD16 *)pv_buf + wd / MIN_CTB_SIZE /* Offset 1 row */;
1856     }
1857 
1858     /* 4 bytes per color component per CTB */
1859     size = 3 * 4;
1860 
1861     /* MAX number of CTBs in a row */
1862     size *= wd / MIN_CTB_SIZE;
1863 
1864     /* MAX number of CTBs in a column */
1865     size *= ht / MIN_CTB_SIZE;
1866     pv_buf = ps_codec->pf_aligned_alloc(pv_mem_ctxt, 128, size);
1867     RETURN_IF((NULL == pv_buf), IV_FAIL);
1868     memset(pv_buf, 0, size);
1869 
1870     ps_codec->s_parse.ps_pic_sao = (sao_t *)pv_buf;
1871     ps_codec->s_parse.s_sao_ctxt.ps_pic_sao = (sao_t *)pv_buf;
1872     for(i = 0; i < MAX_PROCESS_THREADS; i++)
1873     {
1874         ps_codec->as_process[i].s_sao_ctxt.ps_pic_sao = ps_codec->s_parse.ps_pic_sao;
1875     }
1876 
1877     /* Only if width * height * 3 / 2 is greater than MIN_BITSBUF_SIZE,
1878     then allocate dynamic bistream buffer */
1879     ps_codec->pu1_bitsbuf_dynamic = NULL;
1880     size = wd * ht;
1881     if(size > MIN_BITSBUF_SIZE)
1882     {
1883         pv_buf = ps_codec->pf_aligned_alloc(pv_mem_ctxt, 128, size);
1884         RETURN_IF((NULL == pv_buf), IV_FAIL);
1885         ps_codec->pu1_bitsbuf_dynamic = pv_buf;
1886         ps_codec->u4_bitsbuf_size_dynamic = size;
1887     }
1888 
1889     size = ihevcd_get_tu_data_size(wd * ht);
1890     pv_buf = ps_codec->pf_aligned_alloc(pv_mem_ctxt, 128, size);
1891     RETURN_IF((NULL == pv_buf), IV_FAIL);
1892     ps_codec->pv_tu_data = pv_buf;
1893 
1894     {
1895         sps_t *ps_sps = (ps_codec->s_parse.ps_sps_base + ps_codec->i4_sps_id);
1896 
1897 
1898         /* Allocate for pu_map, pu_t and pic_pu_idx for each MV bank */
1899         /* Note: Number of luma samples is not max_wd * max_ht here, instead it is
1900          * set to maximum number of luma samples allowed at the given level.
1901          * This is done to ensure that any stream with width and height lesser
1902          * than max_wd and max_ht is supported. Number of buffers required can be greater
1903          * for lower width and heights at a given level and this increased number of buffers
1904          * might require more memory than what max_wd and max_ht buffer would have required
1905          * Also note one extra buffer is allocted to store current pictures MV bank
1906          * In case of asynchronous parsing and processing, number of buffers should increase here
1907          * based on when parsing and processing threads are synchronized
1908          */
1909         max_dpb_size = ps_sps->ai1_sps_max_dec_pic_buffering[ps_sps->i1_sps_max_sub_layers - 1];
1910         /* Size for holding mv_buf_t for each MV Bank
1911          * One extra MV Bank is needed to hold current pics MV bank.
1912          */
1913         size = (max_dpb_size + 1) * sizeof(mv_buf_t);
1914 
1915         size += (max_dpb_size + 1) *
1916                         ihevcd_get_pic_mv_bank_size(wd * ht);
1917 
1918         pv_buf = ps_codec->pf_aligned_alloc(pv_mem_ctxt, 128, size);
1919         RETURN_IF((NULL == pv_buf), IV_FAIL);
1920 
1921         ps_codec->pv_mv_bank_buf_base = pv_buf;
1922         ps_codec->i4_total_mv_bank_size = size;
1923 
1924     }
1925 
1926     /* In case of non-shared mode allocate for reference picture buffers */
1927     /* In case of shared and 420p output, allocate for chroma samples */
1928     if(0 == ps_codec->i4_share_disp_buf)
1929     {
1930         /* Number of buffers is doubled in order to return one frame at a time instead of sending
1931          * multiple outputs during dpb full case.
1932          * Also note one extra buffer is allocted to store current picture
1933          * In case of asynchronous parsing and processing, number of buffers should increase here
1934          * based on when parsing and processing threads are synchronized
1935          */
1936         size = ihevcd_get_total_pic_buf_size(ps_codec, wd, ht);
1937         pv_buf = ps_codec->pf_aligned_alloc(pv_mem_ctxt, 128, size);
1938         RETURN_IF((NULL == pv_buf), IV_FAIL);
1939 
1940 
1941         ps_codec->i4_total_pic_buf_size = size;
1942         ps_codec->pu1_ref_pic_buf_base = (UWORD8 *)pv_buf;
1943     }
1944 
1945     ps_codec->pv_proc_jobq = ihevcd_jobq_init(ps_codec->pv_proc_jobq_buf, ps_codec->i4_proc_jobq_buf_size);
1946     RETURN_IF((ps_codec->pv_proc_jobq == NULL), IV_FAIL);
1947 
1948     /* Update the jobq context to all the threads */
1949     ps_codec->s_parse.pv_proc_jobq = ps_codec->pv_proc_jobq;
1950     for(i = 0; i < MAX_PROCESS_THREADS; i++)
1951     {
1952         ps_codec->as_process[i].pv_proc_jobq = ps_codec->pv_proc_jobq;
1953         ps_codec->as_process[i].i4_id = i;
1954         ps_codec->as_process[i].ps_codec = ps_codec;
1955 
1956         /* Set the following to zero assuming it is a single core solution
1957          * When threads are launched these will be set appropriately
1958          */
1959         ps_codec->as_process[i].i4_check_parse_status = 0;
1960         ps_codec->as_process[i].i4_check_proc_status = 0;
1961     }
1962 
1963     ps_codec->u4_allocate_dynamic_done = 1;
1964 
1965     return IV_SUCCESS;
1966 }
1967 
1968 /**
1969 *******************************************************************************
1970 *
1971 * @brief
1972 *  Free dynamic memory for the codec
1973 *
1974 * @par Description:
1975 *  Free dynamic memory for the codec
1976 *
1977 * @param[in] ps_codec
1978 *  Pointer to codec context
1979 *
1980 * @returns  Status
1981 *
1982 * @remarks
1983 *
1984 *
1985 *******************************************************************************
1986 */
ihevcd_free_dynamic_bufs(codec_t * ps_codec)1987 WORD32 ihevcd_free_dynamic_bufs(codec_t *ps_codec)
1988 {
1989 
1990     if(ps_codec->pv_proc_jobq)
1991     {
1992         ihevcd_jobq_deinit(ps_codec->pv_proc_jobq);
1993         ps_codec->pv_proc_jobq = NULL;
1994     }
1995 
1996     ALIGNED_FREE(ps_codec, ps_codec->ps_tile);
1997     ALIGNED_FREE(ps_codec, ps_codec->pi4_entry_ofst);
1998     ALIGNED_FREE(ps_codec, ps_codec->s_parse.pu4_skip_cu_top);
1999     ALIGNED_FREE(ps_codec, ps_codec->s_parse.pu4_ct_depth_top);
2000     ALIGNED_FREE(ps_codec, ps_codec->pu1_pic_intra_flag);
2001     ALIGNED_FREE(ps_codec, ps_codec->pu1_pic_no_loop_filter_flag_base);
2002     ALIGNED_FREE(ps_codec, ps_codec->pv_proc_jobq_buf);
2003     ALIGNED_FREE(ps_codec, ps_codec->pu1_parse_map);
2004     ALIGNED_FREE(ps_codec, ps_codec->pu1_proc_map);
2005     ALIGNED_FREE(ps_codec, ps_codec->as_process[0].pu4_pic_pu_idx_left);
2006     ALIGNED_FREE(ps_codec, ps_codec->as_process[0].s_sao_ctxt.pu1_sao_src_left_luma);
2007     ALIGNED_FREE(ps_codec, ps_codec->as_process[0].s_bs_ctxt.pu4_pic_vert_bs);
2008     ALIGNED_FREE(ps_codec, ps_codec->pu1_tile_idx_base);
2009     ALIGNED_FREE(ps_codec, ps_codec->s_parse.ps_pic_sao);
2010     ALIGNED_FREE(ps_codec, ps_codec->pu1_bitsbuf_dynamic);
2011     ALIGNED_FREE(ps_codec, ps_codec->pv_tu_data);
2012     ALIGNED_FREE(ps_codec, ps_codec->pv_mv_bank_buf_base);
2013     ALIGNED_FREE(ps_codec, ps_codec->pu1_ref_pic_buf_base);
2014     ALIGNED_FREE(ps_codec, ps_codec->pu1_cur_chroma_ref_buf);
2015 
2016     ps_codec->u4_allocate_dynamic_done = 0;
2017     return IV_SUCCESS;
2018 }
2019 
2020 
2021 /**
2022 *******************************************************************************
2023 *
2024 * @brief
2025 *  Initializes from mem records passed to the codec
2026 *
2027 * @par Description:
2028 *  Initializes pointers based on mem records passed
2029 *
2030 * @param[in] ps_codec_obj
2031 *  Pointer to codec object at API level
2032 *
2033 * @param[in] pv_api_ip
2034 *  Pointer to input argument structure
2035 *
2036 * @param[out] pv_api_op
2037 *  Pointer to output argument structure
2038 *
2039 * @returns  Status
2040 *
2041 * @remarks
2042 *
2043 *
2044 *******************************************************************************
2045 */
ihevcd_create(iv_obj_t * ps_codec_obj,void * pv_api_ip,void * pv_api_op)2046 WORD32 ihevcd_create(iv_obj_t *ps_codec_obj,
2047                            void *pv_api_ip,
2048                            void *pv_api_op)
2049 {
2050 
2051     ihevcd_cxa_create_op_t *ps_create_op;
2052 
2053     WORD32 ret;
2054     codec_t *ps_codec;
2055     ps_create_op = (ihevcd_cxa_create_op_t *)pv_api_op;
2056 
2057     ps_create_op->s_ivd_create_op_t.u4_error_code = 0;
2058 
2059     ret = ihevcd_allocate_static_bufs(&ps_codec_obj, pv_api_ip, pv_api_op);
2060 
2061     /* If allocation of some buffer fails, then free buffers allocated till then */
2062     if((IV_FAIL == ret) && (NULL != ps_codec_obj))
2063     {
2064         ihevcd_free_static_bufs(ps_codec_obj);
2065         ps_create_op->s_ivd_create_op_t.u4_error_code = IVD_MEM_ALLOC_FAILED;
2066         ps_create_op->s_ivd_create_op_t.u4_error_code = 1 << IVD_FATALERROR;
2067 
2068         return IV_FAIL;
2069     }
2070     ps_codec = (codec_t *)ps_codec_obj->pv_codec_handle;
2071     ret = ihevcd_init(ps_codec);
2072 
2073     TRACE_INIT(NULL);
2074     STATS_INIT();
2075 
2076     return ret;
2077 }
2078 /**
2079 *******************************************************************************
2080 *
2081 * @brief
2082 *  Delete codec
2083 *
2084 * @par Description:
2085 *  Delete codec
2086 *
2087 * @param[in] ps_codec_obj
2088 *  Pointer to codec object at API level
2089 *
2090 * @param[in] pv_api_ip
2091 *  Pointer to input argument structure
2092 *
2093 * @param[out] pv_api_op
2094 *  Pointer to output argument structure
2095 *
2096 * @returns  Status
2097 *
2098 * @remarks
2099 *
2100 *
2101 *******************************************************************************
2102 */
ihevcd_delete(iv_obj_t * ps_codec_obj,void * pv_api_ip,void * pv_api_op)2103 WORD32 ihevcd_delete(iv_obj_t *ps_codec_obj, void *pv_api_ip, void *pv_api_op)
2104 {
2105     codec_t *ps_dec;
2106     ihevcd_cxa_delete_ip_t *ps_ip = (ihevcd_cxa_delete_ip_t *)pv_api_ip;
2107     ihevcd_cxa_delete_op_t *ps_op = (ihevcd_cxa_delete_op_t *)pv_api_op;
2108 
2109     ps_dec = (codec_t *)(ps_codec_obj->pv_codec_handle);
2110     UNUSED(ps_ip);
2111     ps_op->s_ivd_delete_op_t.u4_error_code = 0;
2112     ihevcd_free_dynamic_bufs(ps_dec);
2113     ihevcd_free_static_bufs(ps_codec_obj);
2114     return IV_SUCCESS;
2115 }
2116 
2117 
2118 /**
2119 *******************************************************************************
2120 *
2121 * @brief
2122 *  Passes display buffer from application to codec
2123 *
2124 * @par Description:
2125 *  Adds display buffer to the codec
2126 *
2127 * @param[in] ps_codec_obj
2128 *  Pointer to codec object at API level
2129 *
2130 * @param[in] pv_api_ip
2131 *  Pointer to input argument structure
2132 *
2133 * @param[out] pv_api_op
2134 *  Pointer to output argument structure
2135 *
2136 * @returns  Status
2137 *
2138 * @remarks
2139 *
2140 *
2141 *******************************************************************************
2142 */
ihevcd_set_display_frame(iv_obj_t * ps_codec_obj,void * pv_api_ip,void * pv_api_op)2143 WORD32 ihevcd_set_display_frame(iv_obj_t *ps_codec_obj,
2144                                 void *pv_api_ip,
2145                                 void *pv_api_op)
2146 {
2147     WORD32 ret = IV_SUCCESS;
2148 
2149     ivd_set_display_frame_ip_t *ps_dec_disp_ip;
2150     ivd_set_display_frame_op_t *ps_dec_disp_op;
2151 
2152     WORD32 i;
2153 
2154     codec_t *ps_codec = (codec_t *)(ps_codec_obj->pv_codec_handle);
2155 
2156     ps_dec_disp_ip = (ivd_set_display_frame_ip_t *)pv_api_ip;
2157     ps_dec_disp_op = (ivd_set_display_frame_op_t *)pv_api_op;
2158 
2159     ps_codec->i4_num_disp_bufs = 0;
2160     if(ps_codec->i4_share_disp_buf)
2161     {
2162         UWORD32 num_bufs = ps_dec_disp_ip->num_disp_bufs;
2163         pic_buf_t *ps_pic_buf;
2164         UWORD8 *pu1_buf;
2165         WORD32 buf_ret;
2166 
2167         UWORD8 *pu1_chroma_buf = NULL;
2168         num_bufs = MIN(num_bufs, BUF_MGR_MAX_CNT);
2169         ps_codec->i4_num_disp_bufs = num_bufs;
2170 
2171         ps_pic_buf = (pic_buf_t *)ps_codec->ps_pic_buf;
2172 
2173         /* If color format is 420P, then allocate chroma buffers to hold semiplanar
2174          * chroma data */
2175         if(ps_codec->e_chroma_fmt == IV_YUV_420P)
2176         {
2177             WORD32 num_samples = ps_dec_disp_ip->s_disp_buffer[0].u4_min_out_buf_size[1] << 1;
2178             WORD32 size = num_samples * num_bufs;
2179             void *pv_mem_ctxt = ps_codec->pv_mem_ctxt;
2180 
2181             pu1_chroma_buf = ps_codec->pf_aligned_alloc(pv_mem_ctxt, 128, size);
2182             RETURN_IF((NULL == pu1_chroma_buf), IV_FAIL);
2183 
2184             ps_codec->pu1_cur_chroma_ref_buf = pu1_chroma_buf;
2185         }
2186         for(i = 0; i < (WORD32)num_bufs; i++)
2187         {
2188             /* Stride is not available in some cases here.
2189                So store base pointers to buffer manager now,
2190                and update these pointers once header is decoded */
2191             pu1_buf =  ps_dec_disp_ip->s_disp_buffer[i].pu1_bufs[0];
2192             ps_pic_buf->pu1_luma = pu1_buf;
2193 
2194             if(ps_codec->e_chroma_fmt == IV_YUV_420P)
2195             {
2196                 pu1_buf = pu1_chroma_buf;
2197                 pu1_chroma_buf += ps_dec_disp_ip->s_disp_buffer[0].u4_min_out_buf_size[1] << 1;
2198             }
2199             else
2200             {
2201                 /* For YUV 420SP case use display buffer itself as chroma ref buffer */
2202                 pu1_buf =  ps_dec_disp_ip->s_disp_buffer[i].pu1_bufs[1];
2203             }
2204 
2205             ps_pic_buf->pu1_chroma = pu1_buf;
2206 
2207             buf_ret = ihevc_buf_mgr_add((buf_mgr_t *)ps_codec->pv_pic_buf_mgr, ps_pic_buf, i);
2208 
2209             if(0 != buf_ret)
2210             {
2211                 ps_codec->i4_error_code = IHEVCD_BUF_MGR_ERROR;
2212                 return IHEVCD_BUF_MGR_ERROR;
2213             }
2214 
2215             /* Mark pic buf as needed for display */
2216             /* This ensures that till the buffer is explicitly passed to the codec,
2217              * application owns the buffer. Decoder is allowed to use a buffer only
2218              * when application sends it through fill this buffer call in OMX
2219              */
2220             ihevc_buf_mgr_set_status((buf_mgr_t *)ps_codec->pv_pic_buf_mgr, i, BUF_MGR_DISP);
2221 
2222             ps_pic_buf++;
2223 
2224             /* Store display buffers in codec context. Needed for 420p output */
2225             memcpy(&ps_codec->s_disp_buffer[ps_codec->i4_share_disp_buf_cnt],
2226                    &ps_dec_disp_ip->s_disp_buffer[i],
2227                    sizeof(ps_dec_disp_ip->s_disp_buffer[i]));
2228 
2229             ps_codec->i4_share_disp_buf_cnt++;
2230 
2231         }
2232     }
2233 
2234     ps_dec_disp_op->u4_error_code = 0;
2235     return ret;
2236 
2237 }
2238 
2239 /**
2240 *******************************************************************************
2241 *
2242 * @brief
2243 *  Sets the decoder in flush mode. Decoder will come out of  flush only
2244 * after returning all the buffers or at reset
2245 *
2246 * @par Description:
2247 *  Sets the decoder in flush mode
2248 *
2249 * @param[in] ps_codec_obj
2250 *  Pointer to codec object at API level
2251 *
2252 * @param[in] pv_api_ip
2253 *  Pointer to input argument structure
2254 *
2255 * @param[out] pv_api_op
2256 *  Pointer to output argument structure
2257 *
2258 * @returns  Status
2259 *
2260 * @remarks
2261 *
2262 *
2263 *******************************************************************************
2264 */
ihevcd_set_flush_mode(iv_obj_t * ps_codec_obj,void * pv_api_ip,void * pv_api_op)2265 WORD32 ihevcd_set_flush_mode(iv_obj_t *ps_codec_obj,
2266                              void *pv_api_ip,
2267                              void *pv_api_op)
2268 {
2269 
2270     codec_t *ps_codec;
2271     ivd_ctl_flush_op_t *ps_ctl_op = (ivd_ctl_flush_op_t *)pv_api_op;
2272     UNUSED(pv_api_ip);
2273     ps_codec = (codec_t *)(ps_codec_obj->pv_codec_handle);
2274 
2275     /* Signal flush frame control call */
2276     ps_codec->i4_flush_mode = 1;
2277 
2278     ps_ctl_op->u4_error_code = 0;
2279 
2280     /* Set pic count to zero, so that decoder starts buffering again */
2281     /* once it comes out of flush mode */
2282     ps_codec->u4_pic_cnt = 0;
2283     ps_codec->u4_disp_cnt = 0;
2284     return IV_SUCCESS;
2285 
2286 
2287 }
2288 
2289 /**
2290 *******************************************************************************
2291 *
2292 * @brief
2293 *  Gets decoder status and buffer requirements
2294 *
2295 * @par Description:
2296 *  Gets the decoder status
2297 *
2298 * @param[in] ps_codec_obj
2299 *  Pointer to codec object at API level
2300 *
2301 * @param[in] pv_api_ip
2302 *  Pointer to input argument structure
2303 *
2304 * @param[out] pv_api_op
2305 *  Pointer to output argument structure
2306 *
2307 * @returns  Status
2308 *
2309 * @remarks
2310 *
2311 *
2312 *******************************************************************************
2313 */
2314 
ihevcd_get_status(iv_obj_t * ps_codec_obj,void * pv_api_ip,void * pv_api_op)2315 WORD32 ihevcd_get_status(iv_obj_t *ps_codec_obj,
2316                          void *pv_api_ip,
2317                          void *pv_api_op)
2318 {
2319 
2320     WORD32 i;
2321     codec_t *ps_codec;
2322     WORD32 wd, ht;
2323     ivd_ctl_getstatus_op_t *ps_ctl_op = (ivd_ctl_getstatus_op_t *)pv_api_op;
2324 
2325     UNUSED(pv_api_ip);
2326 
2327     ps_ctl_op->u4_error_code = 0;
2328 
2329     ps_codec = (codec_t *)(ps_codec_obj->pv_codec_handle);
2330 
2331     ps_ctl_op->u4_min_num_in_bufs = MIN_IN_BUFS;
2332     if(ps_codec->e_chroma_fmt == IV_YUV_420P)
2333         ps_ctl_op->u4_min_num_out_bufs = MIN_OUT_BUFS_420;
2334     else if(ps_codec->e_chroma_fmt == IV_YUV_422ILE)
2335         ps_ctl_op->u4_min_num_out_bufs = MIN_OUT_BUFS_422ILE;
2336     else if(ps_codec->e_chroma_fmt == IV_RGB_565)
2337         ps_ctl_op->u4_min_num_out_bufs = MIN_OUT_BUFS_RGB565;
2338     else if(ps_codec->e_chroma_fmt == IV_RGBA_8888)
2339         ps_ctl_op->u4_min_num_out_bufs = MIN_OUT_BUFS_RGBA8888;
2340     else if((ps_codec->e_chroma_fmt == IV_YUV_420SP_UV)
2341                     || (ps_codec->e_chroma_fmt == IV_YUV_420SP_VU))
2342         ps_ctl_op->u4_min_num_out_bufs = MIN_OUT_BUFS_420SP;
2343 
2344     ps_ctl_op->u4_num_disp_bufs = 1;
2345 
2346     for(i = 0; i < (WORD32)ps_ctl_op->u4_min_num_in_bufs; i++)
2347     {
2348         wd = ALIGN64(ps_codec->i4_wd);
2349         ht = ALIGN64(ps_codec->i4_ht);
2350         ps_ctl_op->u4_min_in_buf_size[i] = MAX((wd * ht), MIN_BITSBUF_SIZE);
2351     }
2352 
2353     wd = ps_codec->i4_wd;
2354     ht = ps_codec->i4_ht;
2355 
2356     if(ps_codec->i4_sps_done)
2357     {
2358         if(0 == ps_codec->i4_share_disp_buf)
2359         {
2360             wd = ps_codec->i4_disp_wd;
2361             ht = ps_codec->i4_disp_ht;
2362 
2363         }
2364         else
2365         {
2366             wd = ps_codec->i4_disp_strd;
2367             ht = ps_codec->i4_ht + PAD_HT;
2368         }
2369     }
2370 
2371     if(ps_codec->i4_disp_strd > wd)
2372         wd = ps_codec->i4_disp_strd;
2373 
2374     if(0 == ps_codec->i4_share_disp_buf)
2375         ps_ctl_op->u4_num_disp_bufs = 1;
2376     else
2377     {
2378         if(ps_codec->i4_sps_done)
2379         {
2380             sps_t *ps_sps = (ps_codec->s_parse.ps_sps_base + ps_codec->i4_sps_id);
2381             WORD32 reorder_pic_cnt, ref_pic_cnt;
2382             reorder_pic_cnt = 0;
2383             if(ps_codec->e_frm_out_mode != IVD_DECODE_FRAME_OUT)
2384                 reorder_pic_cnt = ps_sps->ai1_sps_max_num_reorder_pics[ps_sps->i1_sps_max_sub_layers - 1];
2385             ref_pic_cnt = ps_sps->ai1_sps_max_dec_pic_buffering[ps_sps->i1_sps_max_sub_layers - 1];
2386 
2387             ps_ctl_op->u4_num_disp_bufs = reorder_pic_cnt;
2388 
2389             ps_ctl_op->u4_num_disp_bufs += ref_pic_cnt + 1;
2390         }
2391         else
2392         {
2393             ps_ctl_op->u4_num_disp_bufs = MAX_REF_CNT;
2394         }
2395 
2396         ps_ctl_op->u4_num_disp_bufs = MIN(
2397                         ps_ctl_op->u4_num_disp_bufs, 32);
2398     }
2399 
2400     /*!*/
2401     if(ps_codec->e_chroma_fmt == IV_YUV_420P)
2402     {
2403         ps_ctl_op->u4_min_out_buf_size[0] = (wd * ht);
2404         ps_ctl_op->u4_min_out_buf_size[1] = (wd * ht) >> 2;
2405         ps_ctl_op->u4_min_out_buf_size[2] = (wd * ht) >> 2;
2406     }
2407     else if(ps_codec->e_chroma_fmt == IV_YUV_422ILE)
2408     {
2409         ps_ctl_op->u4_min_out_buf_size[0] = (wd * ht) * 2;
2410         ps_ctl_op->u4_min_out_buf_size[1] =
2411                         ps_ctl_op->u4_min_out_buf_size[2] = 0;
2412     }
2413     else if(ps_codec->e_chroma_fmt == IV_RGB_565)
2414     {
2415         ps_ctl_op->u4_min_out_buf_size[0] = (wd * ht) * 2;
2416         ps_ctl_op->u4_min_out_buf_size[1] =
2417                         ps_ctl_op->u4_min_out_buf_size[2] = 0;
2418     }
2419     else if(ps_codec->e_chroma_fmt == IV_RGBA_8888)
2420     {
2421         ps_ctl_op->u4_min_out_buf_size[0] = (wd * ht) * 4;
2422         ps_ctl_op->u4_min_out_buf_size[1] =
2423                         ps_ctl_op->u4_min_out_buf_size[2] = 0;
2424     }
2425     else if((ps_codec->e_chroma_fmt == IV_YUV_420SP_UV)
2426                     || (ps_codec->e_chroma_fmt == IV_YUV_420SP_VU))
2427     {
2428         ps_ctl_op->u4_min_out_buf_size[0] = (wd * ht);
2429         ps_ctl_op->u4_min_out_buf_size[1] = (wd * ht) >> 1;
2430         ps_ctl_op->u4_min_out_buf_size[2] = 0;
2431     }
2432     ps_ctl_op->u4_pic_ht = ht;
2433     ps_ctl_op->u4_pic_wd = wd;
2434     ps_ctl_op->u4_frame_rate = 30000;
2435     ps_ctl_op->u4_bit_rate = 1000000;
2436     ps_ctl_op->e_content_type = IV_PROGRESSIVE;
2437     ps_ctl_op->e_output_chroma_format = ps_codec->e_chroma_fmt;
2438     ps_codec->i4_num_disp_bufs = ps_ctl_op->u4_num_disp_bufs;
2439 
2440     if(ps_ctl_op->u4_size == sizeof(ihevcd_cxa_ctl_getstatus_op_t))
2441     {
2442         ihevcd_cxa_ctl_getstatus_op_t *ps_ext_ctl_op = (ihevcd_cxa_ctl_getstatus_op_t *)ps_ctl_op;
2443         ps_ext_ctl_op->u4_coded_pic_wd = ps_codec->i4_wd;
2444         ps_ext_ctl_op->u4_coded_pic_wd = ps_codec->i4_ht;
2445     }
2446     return IV_SUCCESS;
2447 }
2448 /**
2449 *******************************************************************************
2450 *
2451 * @brief
2452 *  Gets decoder buffer requirements
2453 *
2454 * @par Description:
2455 *  Gets the decoder buffer requirements. If called before  header decoder,
2456 * buffer requirements are based on max_wd  and max_ht else actual width and
2457 * height will be used
2458 *
2459 * @param[in] ps_codec_obj
2460 *  Pointer to codec object at API level
2461 *
2462 * @param[in] pv_api_ip
2463 *  Pointer to input argument structure
2464 *
2465 * @param[out] pv_api_op
2466 *  Pointer to output argument structure
2467 *
2468 * @returns  Status
2469 *
2470 * @remarks
2471 *
2472 *
2473 *******************************************************************************
2474 */
ihevcd_get_buf_info(iv_obj_t * ps_codec_obj,void * pv_api_ip,void * pv_api_op)2475 WORD32 ihevcd_get_buf_info(iv_obj_t *ps_codec_obj,
2476                            void *pv_api_ip,
2477                            void *pv_api_op)
2478 {
2479 
2480     codec_t *ps_codec;
2481     UWORD32 i = 0;
2482     WORD32 wd, ht;
2483     ivd_ctl_getbufinfo_op_t *ps_ctl_op =
2484                     (ivd_ctl_getbufinfo_op_t *)pv_api_op;
2485 
2486     UNUSED(pv_api_ip);
2487     ps_ctl_op->u4_error_code = 0;
2488 
2489     ps_codec = (codec_t *)(ps_codec_obj->pv_codec_handle);
2490 
2491     ps_ctl_op->u4_min_num_in_bufs = MIN_IN_BUFS;
2492     if(ps_codec->e_chroma_fmt == IV_YUV_420P)
2493         ps_ctl_op->u4_min_num_out_bufs = MIN_OUT_BUFS_420;
2494     else if(ps_codec->e_chroma_fmt == IV_YUV_422ILE)
2495         ps_ctl_op->u4_min_num_out_bufs = MIN_OUT_BUFS_422ILE;
2496     else if(ps_codec->e_chroma_fmt == IV_RGB_565)
2497         ps_ctl_op->u4_min_num_out_bufs = MIN_OUT_BUFS_RGB565;
2498     else if(ps_codec->e_chroma_fmt == IV_RGBA_8888)
2499         ps_ctl_op->u4_min_num_out_bufs = MIN_OUT_BUFS_RGBA8888;
2500     else if((ps_codec->e_chroma_fmt == IV_YUV_420SP_UV)
2501                     || (ps_codec->e_chroma_fmt == IV_YUV_420SP_VU))
2502         ps_ctl_op->u4_min_num_out_bufs = MIN_OUT_BUFS_420SP;
2503 
2504     ps_ctl_op->u4_num_disp_bufs = 1;
2505 
2506     for(i = 0; i < ps_ctl_op->u4_min_num_in_bufs; i++)
2507     {
2508         wd = ALIGN64(ps_codec->i4_wd);
2509         ht = ALIGN64(ps_codec->i4_ht);
2510 
2511         ps_ctl_op->u4_min_in_buf_size[i] = MAX((wd * ht), MIN_BITSBUF_SIZE);
2512     }
2513 
2514     wd = 0;
2515     ht = 0;
2516 
2517     if(ps_codec->i4_sps_done)
2518     {
2519         if(0 == ps_codec->i4_share_disp_buf)
2520         {
2521             wd = ps_codec->i4_disp_wd;
2522             ht = ps_codec->i4_disp_ht;
2523 
2524         }
2525         else
2526         {
2527             wd = ps_codec->i4_disp_strd;
2528             ht = ps_codec->i4_ht + PAD_HT;
2529         }
2530     }
2531     else
2532     {
2533         if(1 == ps_codec->i4_share_disp_buf)
2534         {
2535             wd = ALIGN32(wd + PAD_WD);
2536             ht += PAD_HT;
2537         }
2538     }
2539 
2540     if(ps_codec->i4_disp_strd > wd)
2541         wd = ps_codec->i4_disp_strd;
2542 
2543     if(0 == ps_codec->i4_share_disp_buf)
2544         ps_ctl_op->u4_num_disp_bufs = 1;
2545     else
2546     {
2547         if(ps_codec->i4_sps_done)
2548         {
2549             sps_t *ps_sps = (ps_codec->s_parse.ps_sps_base + ps_codec->i4_sps_id);
2550             WORD32 reorder_pic_cnt, ref_pic_cnt;
2551             reorder_pic_cnt = 0;
2552             if(ps_codec->e_frm_out_mode != IVD_DECODE_FRAME_OUT)
2553                 reorder_pic_cnt = ps_sps->ai1_sps_max_num_reorder_pics[ps_sps->i1_sps_max_sub_layers - 1];
2554             ref_pic_cnt = ps_sps->ai1_sps_max_dec_pic_buffering[ps_sps->i1_sps_max_sub_layers - 1];
2555 
2556             ps_ctl_op->u4_num_disp_bufs = reorder_pic_cnt;
2557 
2558             ps_ctl_op->u4_num_disp_bufs += ref_pic_cnt + 1;
2559         }
2560         else
2561         {
2562             ps_ctl_op->u4_num_disp_bufs = MAX_REF_CNT;
2563         }
2564 
2565         ps_ctl_op->u4_num_disp_bufs = MIN(
2566                         ps_ctl_op->u4_num_disp_bufs, 32);
2567 
2568     }
2569 
2570     /*!*/
2571     if(ps_codec->e_chroma_fmt == IV_YUV_420P)
2572     {
2573         ps_ctl_op->u4_min_out_buf_size[0] = (wd * ht);
2574         ps_ctl_op->u4_min_out_buf_size[1] = (wd * ht) >> 2;
2575         ps_ctl_op->u4_min_out_buf_size[2] = (wd * ht) >> 2;
2576     }
2577     else if(ps_codec->e_chroma_fmt == IV_YUV_422ILE)
2578     {
2579         ps_ctl_op->u4_min_out_buf_size[0] = (wd * ht) * 2;
2580         ps_ctl_op->u4_min_out_buf_size[1] =
2581                         ps_ctl_op->u4_min_out_buf_size[2] = 0;
2582     }
2583     else if(ps_codec->e_chroma_fmt == IV_RGB_565)
2584     {
2585         ps_ctl_op->u4_min_out_buf_size[0] = (wd * ht) * 2;
2586         ps_ctl_op->u4_min_out_buf_size[1] =
2587                         ps_ctl_op->u4_min_out_buf_size[2] = 0;
2588     }
2589     else if(ps_codec->e_chroma_fmt == IV_RGBA_8888)
2590     {
2591         ps_ctl_op->u4_min_out_buf_size[0] = (wd * ht) * 4;
2592         ps_ctl_op->u4_min_out_buf_size[1] =
2593                         ps_ctl_op->u4_min_out_buf_size[2] = 0;
2594     }
2595     else if((ps_codec->e_chroma_fmt == IV_YUV_420SP_UV)
2596                     || (ps_codec->e_chroma_fmt == IV_YUV_420SP_VU))
2597     {
2598         ps_ctl_op->u4_min_out_buf_size[0] = (wd * ht);
2599         ps_ctl_op->u4_min_out_buf_size[1] = (wd * ht) >> 1;
2600         ps_ctl_op->u4_min_out_buf_size[2] = 0;
2601     }
2602     ps_codec->i4_num_disp_bufs = ps_ctl_op->u4_num_disp_bufs;
2603 
2604     return IV_SUCCESS;
2605 }
2606 
2607 
2608 /**
2609 *******************************************************************************
2610 *
2611 * @brief
2612 *  Sets dynamic parameters
2613 *
2614 * @par Description:
2615 *  Sets dynamic parameters. Note Frame skip, decode header  mode are dynamic
2616 *  Dynamic change in stride is not  supported
2617 *
2618 * @param[in] ps_codec_obj
2619 *  Pointer to codec object at API level
2620 *
2621 * @param[in] pv_api_ip
2622 *  Pointer to input argument structure
2623 *
2624 * @param[out] pv_api_op
2625 *  Pointer to output argument structure
2626 *
2627 * @returns  Status
2628 *
2629 * @remarks
2630 *
2631 *
2632 *******************************************************************************
2633 */
ihevcd_set_params(iv_obj_t * ps_codec_obj,void * pv_api_ip,void * pv_api_op)2634 WORD32 ihevcd_set_params(iv_obj_t *ps_codec_obj,
2635                          void *pv_api_ip,
2636                          void *pv_api_op)
2637 {
2638 
2639     codec_t *ps_codec;
2640     WORD32 ret = IV_SUCCESS;
2641     WORD32 strd;
2642     ivd_ctl_set_config_ip_t *s_ctl_dynparams_ip =
2643                     (ivd_ctl_set_config_ip_t *)pv_api_ip;
2644     ivd_ctl_set_config_op_t *s_ctl_dynparams_op =
2645                     (ivd_ctl_set_config_op_t *)pv_api_op;
2646 
2647     ps_codec = (codec_t *)(ps_codec_obj->pv_codec_handle);
2648 
2649     s_ctl_dynparams_op->u4_error_code = 0;
2650 
2651     ps_codec->e_pic_skip_mode = s_ctl_dynparams_ip->e_frm_skip_mode;
2652 
2653     if(s_ctl_dynparams_ip->e_frm_skip_mode != IVD_SKIP_NONE)
2654     {
2655 
2656         if((s_ctl_dynparams_ip->e_frm_skip_mode != IVD_SKIP_P) &&
2657            (s_ctl_dynparams_ip->e_frm_skip_mode != IVD_SKIP_B) &&
2658            (s_ctl_dynparams_ip->e_frm_skip_mode != IVD_SKIP_PB))
2659         {
2660             s_ctl_dynparams_op->u4_error_code = (1 << IVD_UNSUPPORTEDPARAM);
2661             ret = IV_FAIL;
2662         }
2663     }
2664 
2665     strd = ps_codec->i4_disp_strd;
2666     if(1 == ps_codec->i4_share_disp_buf)
2667     {
2668         strd = ps_codec->i4_strd;
2669     }
2670 
2671 
2672     {
2673         if((WORD32)s_ctl_dynparams_ip->u4_disp_wd >= ps_codec->i4_disp_wd)
2674         {
2675             strd = s_ctl_dynparams_ip->u4_disp_wd;
2676         }
2677         else if(0 == ps_codec->i4_sps_done)
2678         {
2679             strd = s_ctl_dynparams_ip->u4_disp_wd;
2680         }
2681         else if(s_ctl_dynparams_ip->u4_disp_wd == 0)
2682         {
2683             strd = ps_codec->i4_disp_strd;
2684         }
2685         else
2686         {
2687             strd = 0;
2688             s_ctl_dynparams_op->u4_error_code |= (1 << IVD_UNSUPPORTEDPARAM);
2689             s_ctl_dynparams_op->u4_error_code |= IHEVCD_INVALID_DISP_STRD;
2690             ret = IV_FAIL;
2691         }
2692     }
2693 
2694     ps_codec->i4_disp_strd = strd;
2695     if(1 == ps_codec->i4_share_disp_buf)
2696     {
2697         ps_codec->i4_strd = strd;
2698     }
2699 
2700     if(s_ctl_dynparams_ip->e_vid_dec_mode == IVD_DECODE_FRAME)
2701         ps_codec->i4_header_mode = 0;
2702     else if(s_ctl_dynparams_ip->e_vid_dec_mode == IVD_DECODE_HEADER)
2703         ps_codec->i4_header_mode = 1;
2704     else
2705     {
2706 
2707         s_ctl_dynparams_op->u4_error_code = (1 << IVD_UNSUPPORTEDPARAM);
2708         ps_codec->i4_header_mode = 1;
2709         ret = IV_FAIL;
2710     }
2711 
2712     ps_codec->e_frm_out_mode = IVD_DISPLAY_FRAME_OUT;
2713 
2714     if((s_ctl_dynparams_ip->e_frm_out_mode != IVD_DECODE_FRAME_OUT) &&
2715        (s_ctl_dynparams_ip->e_frm_out_mode != IVD_DISPLAY_FRAME_OUT))
2716     {
2717         s_ctl_dynparams_op->u4_error_code = (1 << IVD_UNSUPPORTEDPARAM);
2718         ret = IV_FAIL;
2719     }
2720     ps_codec->e_frm_out_mode = s_ctl_dynparams_ip->e_frm_out_mode;
2721 
2722     return ret;
2723 
2724 }
2725 /**
2726 *******************************************************************************
2727 *
2728 * @brief
2729 *  Resets the decoder state
2730 *
2731 * @par Description:
2732 *  Resets the decoder state by calling ihevcd_init()
2733 *
2734 * @param[in] ps_codec_obj
2735 *  Pointer to codec object at API level
2736 *
2737 * @param[in] pv_api_ip
2738 *  Pointer to input argument structure
2739 *
2740 * @param[out] pv_api_op
2741 *  Pointer to output argument structure
2742 *
2743 * @returns  Status
2744 *
2745 * @remarks
2746 *
2747 *
2748 *******************************************************************************
2749 */
ihevcd_reset(iv_obj_t * ps_codec_obj,void * pv_api_ip,void * pv_api_op)2750 WORD32 ihevcd_reset(iv_obj_t *ps_codec_obj, void *pv_api_ip, void *pv_api_op)
2751 {
2752     codec_t *ps_codec;
2753     ivd_ctl_reset_op_t *s_ctl_reset_op = (ivd_ctl_reset_op_t *)pv_api_op;
2754     UNUSED(pv_api_ip);
2755     ps_codec = (codec_t *)(ps_codec_obj->pv_codec_handle);
2756 
2757     if(ps_codec != NULL)
2758     {
2759         DEBUG("\nReset called \n");
2760         ihevcd_init(ps_codec);
2761     }
2762     else
2763     {
2764         DEBUG("\nReset called without Initializing the decoder\n");
2765         s_ctl_reset_op->u4_error_code = IHEVCD_INIT_NOT_DONE;
2766     }
2767 
2768     return IV_SUCCESS;
2769 }
2770 
2771 /**
2772 *******************************************************************************
2773 *
2774 * @brief
2775 *  Releases display buffer from application to codec  to signal to the codec
2776 * that it can write to this buffer  if required. Till release is called,
2777 * codec can not write  to this buffer
2778 *
2779 * @par Description:
2780 *  Marks the buffer as display done
2781 *
2782 * @param[in] ps_codec_obj
2783 *  Pointer to codec object at API level
2784 *
2785 * @param[in] pv_api_ip
2786 *  Pointer to input argument structure
2787 *
2788 * @param[out] pv_api_op
2789 *  Pointer to output argument structure
2790 *
2791 * @returns  Status
2792 *
2793 * @remarks
2794 *
2795 *
2796 *******************************************************************************
2797 */
2798 
ihevcd_rel_display_frame(iv_obj_t * ps_codec_obj,void * pv_api_ip,void * pv_api_op)2799 WORD32 ihevcd_rel_display_frame(iv_obj_t *ps_codec_obj,
2800                                 void *pv_api_ip,
2801                                 void *pv_api_op)
2802 {
2803 
2804     ivd_rel_display_frame_ip_t *ps_dec_rel_disp_ip;
2805     ivd_rel_display_frame_op_t *ps_dec_rel_disp_op;
2806 
2807     codec_t *ps_codec = (codec_t *)ps_codec_obj->pv_codec_handle;
2808 
2809     ps_dec_rel_disp_ip = (ivd_rel_display_frame_ip_t *)pv_api_ip;
2810     ps_dec_rel_disp_op = (ivd_rel_display_frame_op_t *)pv_api_op;
2811 
2812     UNUSED(ps_dec_rel_disp_op);
2813 
2814     if(0 == ps_codec->i4_share_disp_buf)
2815     {
2816         return IV_SUCCESS;
2817     }
2818 
2819     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);
2820 
2821     return IV_SUCCESS;
2822 }
2823 /**
2824 *******************************************************************************
2825 *
2826 * @brief
2827 *  Sets degrade params
2828 *
2829 * @par Description:
2830 *  Sets degrade params.
2831 *  Refer to ihevcd_cxa_ctl_degrade_ip_t definition for details
2832 *
2833 * @param[in] ps_codec_obj
2834 *  Pointer to codec object at API level
2835 *
2836 * @param[in] pv_api_ip
2837 *  Pointer to input argument structure
2838 *
2839 * @param[out] pv_api_op
2840 *  Pointer to output argument structure
2841 *
2842 * @returns  Status
2843 *
2844 * @remarks
2845 *
2846 *
2847 *******************************************************************************
2848 */
2849 
ihevcd_set_degrade(iv_obj_t * ps_codec_obj,void * pv_api_ip,void * pv_api_op)2850 WORD32 ihevcd_set_degrade(iv_obj_t *ps_codec_obj,
2851                           void *pv_api_ip,
2852                           void *pv_api_op)
2853 {
2854     ihevcd_cxa_ctl_degrade_ip_t *ps_ip;
2855     ihevcd_cxa_ctl_degrade_op_t *ps_op;
2856     codec_t *ps_codec = (codec_t *)ps_codec_obj->pv_codec_handle;
2857 
2858     ps_ip = (ihevcd_cxa_ctl_degrade_ip_t *)pv_api_ip;
2859     ps_op = (ihevcd_cxa_ctl_degrade_op_t *)pv_api_op;
2860 
2861     ps_codec->i4_degrade_type = ps_ip->i4_degrade_type;
2862     ps_codec->i4_nondegrade_interval = ps_ip->i4_nondegrade_interval;
2863     ps_codec->i4_degrade_pics = ps_ip->i4_degrade_pics;
2864 
2865     ps_op->u4_error_code = 0;
2866     ps_codec->i4_degrade_pic_cnt = 0;
2867 
2868     return IV_SUCCESS;
2869 }
2870 
2871 
2872 /**
2873 *******************************************************************************
2874 *
2875 * @brief
2876 *  Gets frame dimensions/offsets
2877 *
2878 * @par Description:
2879 *  Gets frame buffer chararacteristics such a x & y offsets  display and
2880 * buffer dimensions
2881 *
2882 * @param[in] ps_codec_obj
2883 *  Pointer to codec object at API level
2884 *
2885 * @param[in] pv_api_ip
2886 *  Pointer to input argument structure
2887 *
2888 * @param[out] pv_api_op
2889 *  Pointer to output argument structure
2890 *
2891 * @returns  Status
2892 *
2893 * @remarks
2894 *
2895 *
2896 *******************************************************************************
2897 */
2898 
ihevcd_get_frame_dimensions(iv_obj_t * ps_codec_obj,void * pv_api_ip,void * pv_api_op)2899 WORD32 ihevcd_get_frame_dimensions(iv_obj_t *ps_codec_obj,
2900                                    void *pv_api_ip,
2901                                    void *pv_api_op)
2902 {
2903     ihevcd_cxa_ctl_get_frame_dimensions_ip_t *ps_ip;
2904     ihevcd_cxa_ctl_get_frame_dimensions_op_t *ps_op;
2905     codec_t *ps_codec = (codec_t *)ps_codec_obj->pv_codec_handle;
2906     WORD32 disp_wd, disp_ht, buffer_wd, buffer_ht, x_offset, y_offset;
2907     ps_ip = (ihevcd_cxa_ctl_get_frame_dimensions_ip_t *)pv_api_ip;
2908     ps_op = (ihevcd_cxa_ctl_get_frame_dimensions_op_t *)pv_api_op;
2909     UNUSED(ps_ip);
2910     if(ps_codec->i4_sps_done)
2911     {
2912         disp_wd = ps_codec->i4_disp_wd;
2913         disp_ht = ps_codec->i4_disp_ht;
2914 
2915         if(0 == ps_codec->i4_share_disp_buf)
2916         {
2917             buffer_wd = disp_wd;
2918             buffer_ht = disp_ht;
2919         }
2920         else
2921         {
2922             buffer_wd = ps_codec->i4_strd;
2923             buffer_ht = ps_codec->i4_ht + PAD_HT;
2924         }
2925     }
2926     else
2927     {
2928 
2929         disp_wd = 0;
2930         disp_ht = 0;
2931 
2932         if(0 == ps_codec->i4_share_disp_buf)
2933         {
2934             buffer_wd = disp_wd;
2935             buffer_ht = disp_ht;
2936         }
2937         else
2938         {
2939             buffer_wd = ALIGN16(disp_wd) + PAD_WD;
2940             buffer_ht = ALIGN16(disp_ht) + PAD_HT;
2941 
2942         }
2943     }
2944     if(ps_codec->i4_strd > buffer_wd)
2945         buffer_wd = ps_codec->i4_strd;
2946 
2947     if(0 == ps_codec->i4_share_disp_buf)
2948     {
2949         x_offset = 0;
2950         y_offset = 0;
2951     }
2952     else
2953     {
2954         y_offset = PAD_TOP;
2955         x_offset = PAD_LEFT;
2956     }
2957 
2958     ps_op->u4_disp_wd[0] = disp_wd;
2959     ps_op->u4_disp_ht[0] = disp_ht;
2960     ps_op->u4_buffer_wd[0] = buffer_wd;
2961     ps_op->u4_buffer_ht[0] = buffer_ht;
2962     ps_op->u4_x_offset[0] = x_offset;
2963     ps_op->u4_y_offset[0] = y_offset;
2964 
2965     ps_op->u4_disp_wd[1] = ps_op->u4_disp_wd[2] = ((ps_op->u4_disp_wd[0] + 1)
2966                     >> 1);
2967     ps_op->u4_disp_ht[1] = ps_op->u4_disp_ht[2] = ((ps_op->u4_disp_ht[0] + 1)
2968                     >> 1);
2969     ps_op->u4_buffer_wd[1] = ps_op->u4_buffer_wd[2] = (ps_op->u4_buffer_wd[0]
2970                     >> 1);
2971     ps_op->u4_buffer_ht[1] = ps_op->u4_buffer_ht[2] = (ps_op->u4_buffer_ht[0]
2972                     >> 1);
2973     ps_op->u4_x_offset[1] = ps_op->u4_x_offset[2] = (ps_op->u4_x_offset[0]
2974                     >> 1);
2975     ps_op->u4_y_offset[1] = ps_op->u4_y_offset[2] = (ps_op->u4_y_offset[0]
2976                     >> 1);
2977 
2978     if((ps_codec->e_chroma_fmt == IV_YUV_420SP_UV)
2979                     || (ps_codec->e_chroma_fmt == IV_YUV_420SP_VU))
2980     {
2981         ps_op->u4_disp_wd[2] = 0;
2982         ps_op->u4_disp_ht[2] = 0;
2983         ps_op->u4_buffer_wd[2] = 0;
2984         ps_op->u4_buffer_ht[2] = 0;
2985         ps_op->u4_x_offset[2] = 0;
2986         ps_op->u4_y_offset[2] = 0;
2987 
2988         ps_op->u4_disp_wd[1] <<= 1;
2989         ps_op->u4_buffer_wd[1] <<= 1;
2990         ps_op->u4_x_offset[1] <<= 1;
2991     }
2992 
2993     return IV_SUCCESS;
2994 
2995 }
2996 
2997 
2998 /**
2999 *******************************************************************************
3000 *
3001 * @brief
3002 *  Gets vui parameters
3003 *
3004 * @par Description:
3005 *  Gets VUI parameters
3006 *
3007 * @param[in] ps_codec_obj
3008 *  Pointer to codec object at API level
3009 *
3010 * @param[in] pv_api_ip
3011 *  Pointer to input argument structure
3012 *
3013 * @param[out] pv_api_op
3014 *  Pointer to output argument structure
3015 *
3016 * @returns  Status
3017 *
3018 * @remarks
3019 *
3020 *
3021 *******************************************************************************
3022 */
ihevcd_get_vui_params(iv_obj_t * ps_codec_obj,void * pv_api_ip,void * pv_api_op)3023 WORD32 ihevcd_get_vui_params(iv_obj_t *ps_codec_obj,
3024                              void *pv_api_ip,
3025                              void *pv_api_op)
3026 {
3027     ihevcd_cxa_ctl_get_vui_params_ip_t *ps_ip;
3028     ihevcd_cxa_ctl_get_vui_params_op_t *ps_op;
3029     codec_t *ps_codec = (codec_t *)ps_codec_obj->pv_codec_handle;
3030     sps_t *ps_sps;
3031     vui_t *ps_vui;
3032     WORD32 i;
3033 
3034     ps_ip = (ihevcd_cxa_ctl_get_vui_params_ip_t *)pv_api_ip;
3035     ps_op = (ihevcd_cxa_ctl_get_vui_params_op_t *)pv_api_op;
3036 
3037     if(0 == ps_codec->i4_sps_done)
3038     {
3039         ps_op->u4_error_code = IHEVCD_VUI_PARAMS_NOT_FOUND;
3040         return IV_FAIL;
3041     }
3042 
3043     ps_sps = ps_codec->s_parse.ps_sps;
3044     if(0 == ps_sps->i1_sps_valid || 0 == ps_sps->i1_vui_parameters_present_flag)
3045     {
3046         WORD32 sps_idx = 0;
3047         ps_sps = ps_codec->ps_sps_base;
3048 
3049         while((0 == ps_sps->i1_sps_valid) || (0 == ps_sps->i1_vui_parameters_present_flag))
3050         {
3051             sps_idx++;
3052             ps_sps++;
3053 
3054             if(sps_idx == MAX_SPS_CNT - 1)
3055             {
3056                 ps_op->u4_error_code = IHEVCD_VUI_PARAMS_NOT_FOUND;
3057                 return IV_FAIL;
3058             }
3059         }
3060     }
3061 
3062     ps_vui = &ps_sps->s_vui_parameters;
3063     UNUSED(ps_ip);
3064 
3065     ps_op->u1_aspect_ratio_info_present_flag         =  ps_vui->u1_aspect_ratio_info_present_flag;
3066     ps_op->u1_aspect_ratio_idc                       =  ps_vui->u1_aspect_ratio_idc;
3067     ps_op->u2_sar_width                              =  ps_vui->u2_sar_width;
3068     ps_op->u2_sar_height                             =  ps_vui->u2_sar_height;
3069     ps_op->u1_overscan_info_present_flag             =  ps_vui->u1_overscan_info_present_flag;
3070     ps_op->u1_overscan_appropriate_flag              =  ps_vui->u1_overscan_appropriate_flag;
3071     ps_op->u1_video_signal_type_present_flag         =  ps_vui->u1_video_signal_type_present_flag;
3072     ps_op->u1_video_format                           =  ps_vui->u1_video_format;
3073     ps_op->u1_video_full_range_flag                  =  ps_vui->u1_video_full_range_flag;
3074     ps_op->u1_colour_description_present_flag        =  ps_vui->u1_colour_description_present_flag;
3075     ps_op->u1_colour_primaries                       =  ps_vui->u1_colour_primaries;
3076     ps_op->u1_transfer_characteristics               =  ps_vui->u1_transfer_characteristics;
3077     ps_op->u1_matrix_coefficients                    =  ps_vui->u1_matrix_coefficients;
3078     ps_op->u1_chroma_loc_info_present_flag           =  ps_vui->u1_chroma_loc_info_present_flag;
3079     ps_op->u1_chroma_sample_loc_type_top_field       =  ps_vui->u1_chroma_sample_loc_type_top_field;
3080     ps_op->u1_chroma_sample_loc_type_bottom_field    =  ps_vui->u1_chroma_sample_loc_type_bottom_field;
3081     ps_op->u1_neutral_chroma_indication_flag         =  ps_vui->u1_neutral_chroma_indication_flag;
3082     ps_op->u1_field_seq_flag                         =  ps_vui->u1_field_seq_flag;
3083     ps_op->u1_frame_field_info_present_flag          =  ps_vui->u1_frame_field_info_present_flag;
3084     ps_op->u1_default_display_window_flag            =  ps_vui->u1_default_display_window_flag;
3085     ps_op->u4_def_disp_win_left_offset               =  ps_vui->u4_def_disp_win_left_offset;
3086     ps_op->u4_def_disp_win_right_offset              =  ps_vui->u4_def_disp_win_right_offset;
3087     ps_op->u4_def_disp_win_top_offset                =  ps_vui->u4_def_disp_win_top_offset;
3088     ps_op->u4_def_disp_win_bottom_offset             =  ps_vui->u4_def_disp_win_bottom_offset;
3089     ps_op->u1_vui_hrd_parameters_present_flag        =  ps_vui->u1_vui_hrd_parameters_present_flag;
3090     ps_op->u1_vui_timing_info_present_flag           =  ps_vui->u1_vui_timing_info_present_flag;
3091     ps_op->u4_vui_num_units_in_tick                  =  ps_vui->u4_vui_num_units_in_tick;
3092     ps_op->u4_vui_time_scale                         =  ps_vui->u4_vui_time_scale;
3093     ps_op->u1_poc_proportional_to_timing_flag        =  ps_vui->u1_poc_proportional_to_timing_flag;
3094     ps_op->u1_num_ticks_poc_diff_one_minus1          =  ps_vui->u1_num_ticks_poc_diff_one_minus1;
3095     ps_op->u1_bitstream_restriction_flag             =  ps_vui->u1_bitstream_restriction_flag;
3096     ps_op->u1_tiles_fixed_structure_flag             =  ps_vui->u1_tiles_fixed_structure_flag;
3097     ps_op->u1_motion_vectors_over_pic_boundaries_flag =  ps_vui->u1_motion_vectors_over_pic_boundaries_flag;
3098     ps_op->u1_restricted_ref_pic_lists_flag          =  ps_vui->u1_restricted_ref_pic_lists_flag;
3099     ps_op->u4_min_spatial_segmentation_idc           =  ps_vui->u4_min_spatial_segmentation_idc;
3100     ps_op->u1_max_bytes_per_pic_denom                =  ps_vui->u1_max_bytes_per_pic_denom;
3101     ps_op->u1_max_bits_per_mincu_denom               =  ps_vui->u1_max_bits_per_mincu_denom;
3102     ps_op->u1_log2_max_mv_length_horizontal          =  ps_vui->u1_log2_max_mv_length_horizontal;
3103     ps_op->u1_log2_max_mv_length_vertical            =  ps_vui->u1_log2_max_mv_length_vertical;
3104 
3105 
3106     /* HRD parameters */
3107     ps_op->u1_timing_info_present_flag                         =    ps_vui->s_vui_hrd_parameters.u1_timing_info_present_flag;
3108     ps_op->u4_num_units_in_tick                                =    ps_vui->s_vui_hrd_parameters.u4_num_units_in_tick;
3109     ps_op->u4_time_scale                                       =    ps_vui->s_vui_hrd_parameters.u4_time_scale;
3110     ps_op->u1_nal_hrd_parameters_present_flag                  =    ps_vui->s_vui_hrd_parameters.u1_nal_hrd_parameters_present_flag;
3111     ps_op->u1_vcl_hrd_parameters_present_flag                  =    ps_vui->s_vui_hrd_parameters.u1_vcl_hrd_parameters_present_flag;
3112     ps_op->u1_cpbdpb_delays_present_flag                       =    ps_vui->s_vui_hrd_parameters.u1_cpbdpb_delays_present_flag;
3113     ps_op->u1_sub_pic_cpb_params_present_flag                  =    ps_vui->s_vui_hrd_parameters.u1_sub_pic_cpb_params_present_flag;
3114     ps_op->u1_tick_divisor_minus2                              =    ps_vui->s_vui_hrd_parameters.u1_tick_divisor_minus2;
3115     ps_op->u1_du_cpb_removal_delay_increment_length_minus1     =    ps_vui->s_vui_hrd_parameters.u1_du_cpb_removal_delay_increment_length_minus1;
3116     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;
3117     ps_op->u1_dpb_output_delay_du_length_minus1                =    ps_vui->s_vui_hrd_parameters.u1_dpb_output_delay_du_length_minus1;
3118     ps_op->u4_bit_rate_scale                                   =    ps_vui->s_vui_hrd_parameters.u4_bit_rate_scale;
3119     ps_op->u4_cpb_size_scale                                   =    ps_vui->s_vui_hrd_parameters.u4_cpb_size_scale;
3120     ps_op->u4_cpb_size_du_scale                                =    ps_vui->s_vui_hrd_parameters.u4_cpb_size_du_scale;
3121     ps_op->u1_initial_cpb_removal_delay_length_minus1          =    ps_vui->s_vui_hrd_parameters.u1_initial_cpb_removal_delay_length_minus1;
3122     ps_op->u1_au_cpb_removal_delay_length_minus1               =    ps_vui->s_vui_hrd_parameters.u1_au_cpb_removal_delay_length_minus1;
3123     ps_op->u1_dpb_output_delay_length_minus1                   =    ps_vui->s_vui_hrd_parameters.u1_dpb_output_delay_length_minus1;
3124 
3125     for(i = 0; i < 6; i++)
3126     {
3127         ps_op->au1_fixed_pic_rate_general_flag[i]                  =    ps_vui->s_vui_hrd_parameters.au1_fixed_pic_rate_general_flag[i];
3128         ps_op->au1_fixed_pic_rate_within_cvs_flag[i]               =    ps_vui->s_vui_hrd_parameters.au1_fixed_pic_rate_within_cvs_flag[i];
3129         ps_op->au1_elemental_duration_in_tc_minus1[i]              =    ps_vui->s_vui_hrd_parameters.au1_elemental_duration_in_tc_minus1[i];
3130         ps_op->au1_low_delay_hrd_flag[i]                           =    ps_vui->s_vui_hrd_parameters.au1_low_delay_hrd_flag[i];
3131         ps_op->au1_cpb_cnt_minus1[i]                               =    ps_vui->s_vui_hrd_parameters.au1_cpb_cnt_minus1[i];
3132     }
3133 
3134 
3135     return IV_SUCCESS;
3136 }
3137 
3138 /**
3139 *******************************************************************************
3140 *
3141 * @brief
3142 *  Sets Processor type
3143 *
3144 * @par Description:
3145 *  Sets Processor type
3146 *
3147 * @param[in] ps_codec_obj
3148 *  Pointer to codec object at API level
3149 *
3150 * @param[in] pv_api_ip
3151 *  Pointer to input argument structure
3152 *
3153 * @param[out] pv_api_op
3154 *  Pointer to output argument structure
3155 *
3156 * @returns  Status
3157 *
3158 * @remarks
3159 *
3160 *
3161 *******************************************************************************
3162 */
3163 
ihevcd_set_processor(iv_obj_t * ps_codec_obj,void * pv_api_ip,void * pv_api_op)3164 WORD32 ihevcd_set_processor(iv_obj_t *ps_codec_obj,
3165                             void *pv_api_ip,
3166                             void *pv_api_op)
3167 {
3168     ihevcd_cxa_ctl_set_processor_ip_t *ps_ip;
3169     ihevcd_cxa_ctl_set_processor_op_t *ps_op;
3170     codec_t *ps_codec = (codec_t *)ps_codec_obj->pv_codec_handle;
3171 
3172     ps_ip = (ihevcd_cxa_ctl_set_processor_ip_t *)pv_api_ip;
3173     ps_op = (ihevcd_cxa_ctl_set_processor_op_t *)pv_api_op;
3174 
3175     ps_codec->e_processor_arch = (IVD_ARCH_T)ps_ip->u4_arch;
3176     ps_codec->e_processor_soc = (IVD_SOC_T)ps_ip->u4_soc;
3177 
3178     ihevcd_init_function_ptr(ps_codec);
3179 
3180     ihevcd_update_function_ptr(ps_codec);
3181 
3182     if(ps_codec->e_processor_soc && (ps_codec->e_processor_soc <= SOC_HISI_37X))
3183     {
3184         /* 8th bit indicates if format conversion is to be done ahead */
3185         if(ps_codec->e_processor_soc & 0x80)
3186             ps_codec->u4_enable_fmt_conv_ahead = 1;
3187 
3188         /* Lower 7 bit indicate NCTB - if non-zero */
3189         ps_codec->e_processor_soc &= 0x7F;
3190 
3191         if(ps_codec->e_processor_soc)
3192             ps_codec->u4_nctb = ps_codec->e_processor_soc;
3193 
3194 
3195     }
3196 
3197     if((ps_codec->e_processor_soc == SOC_HISI_37X) && (ps_codec->i4_num_cores == 2))
3198     {
3199         ps_codec->u4_nctb = 2;
3200     }
3201 
3202 
3203     ps_op->u4_error_code = 0;
3204     return IV_SUCCESS;
3205 }
3206 
3207 /**
3208 *******************************************************************************
3209 *
3210 * @brief
3211 *  Sets Number of cores that can be used in the codec. Codec uses these many
3212 * threads for decoding
3213 *
3214 * @par Description:
3215 *  Sets number of cores
3216 *
3217 * @param[in] ps_codec_obj
3218 *  Pointer to codec object at API level
3219 *
3220 * @param[in] pv_api_ip
3221 *  Pointer to input argument structure
3222 *
3223 * @param[out] pv_api_op
3224 *  Pointer to output argument structure
3225 *
3226 * @returns  Status
3227 *
3228 * @remarks
3229 *
3230 *
3231 *******************************************************************************
3232 */
3233 
ihevcd_set_num_cores(iv_obj_t * ps_codec_obj,void * pv_api_ip,void * pv_api_op)3234 WORD32 ihevcd_set_num_cores(iv_obj_t *ps_codec_obj,
3235                             void *pv_api_ip,
3236                             void *pv_api_op)
3237 {
3238     ihevcd_cxa_ctl_set_num_cores_ip_t *ps_ip;
3239     ihevcd_cxa_ctl_set_num_cores_op_t *ps_op;
3240     codec_t *ps_codec = (codec_t *)ps_codec_obj->pv_codec_handle;
3241 
3242     ps_ip = (ihevcd_cxa_ctl_set_num_cores_ip_t *)pv_api_ip;
3243     ps_op = (ihevcd_cxa_ctl_set_num_cores_op_t *)pv_api_op;
3244 
3245 #ifdef MULTICORE
3246     ps_codec->i4_num_cores = ps_ip->u4_num_cores;
3247 #else
3248     ps_codec->i4_num_cores = 1;
3249 #endif
3250     ps_op->u4_error_code = 0;
3251     return IV_SUCCESS;
3252 }
3253 /**
3254 *******************************************************************************
3255 *
3256 * @brief
3257 *  Codec control call
3258 *
3259 * @par Description:
3260 *  Codec control call which in turn calls appropriate calls  based on
3261 * subcommand
3262 *
3263 * @param[in] ps_codec_obj
3264 *  Pointer to codec object at API level
3265 *
3266 * @param[in] pv_api_ip
3267 *  Pointer to input argument structure
3268 *
3269 * @param[out] pv_api_op
3270 *  Pointer to output argument structure
3271 *
3272 * @returns  Status
3273 *
3274 * @remarks
3275 *
3276 *
3277 *******************************************************************************
3278 */
3279 
ihevcd_ctl(iv_obj_t * ps_codec_obj,void * pv_api_ip,void * pv_api_op)3280 WORD32 ihevcd_ctl(iv_obj_t *ps_codec_obj, void *pv_api_ip, void *pv_api_op)
3281 {
3282     ivd_ctl_set_config_ip_t *ps_ctl_ip;
3283     ivd_ctl_set_config_op_t *ps_ctl_op;
3284     WORD32 ret = 0;
3285     WORD32 subcommand;
3286     codec_t *ps_codec = (codec_t *)ps_codec_obj->pv_codec_handle;
3287 
3288     ps_ctl_ip = (ivd_ctl_set_config_ip_t *)pv_api_ip;
3289     ps_ctl_op = (ivd_ctl_set_config_op_t *)pv_api_op;
3290 
3291     if(ps_codec->i4_init_done != 1)
3292     {
3293         ps_ctl_op->u4_error_code |= 1 << IVD_FATALERROR;
3294         ps_ctl_op->u4_error_code |= IHEVCD_INIT_NOT_DONE;
3295         return IV_FAIL;
3296     }
3297     subcommand = ps_ctl_ip->e_sub_cmd;
3298 
3299     switch(subcommand)
3300     {
3301         case IVD_CMD_CTL_GETPARAMS:
3302             ret = ihevcd_get_status(ps_codec_obj, (void *)pv_api_ip,
3303                                     (void *)pv_api_op);
3304             break;
3305         case IVD_CMD_CTL_SETPARAMS:
3306             ret = ihevcd_set_params(ps_codec_obj, (void *)pv_api_ip,
3307                                     (void *)pv_api_op);
3308             break;
3309         case IVD_CMD_CTL_RESET:
3310             ret = ihevcd_reset(ps_codec_obj, (void *)pv_api_ip,
3311                                (void *)pv_api_op);
3312             break;
3313         case IVD_CMD_CTL_SETDEFAULT:
3314         {
3315             ivd_ctl_set_config_op_t *s_ctl_dynparams_op =
3316                             (ivd_ctl_set_config_op_t *)pv_api_op;
3317 
3318             ret = ihevcd_set_default_params(ps_codec);
3319             if(IV_SUCCESS == ret)
3320                 s_ctl_dynparams_op->u4_error_code = 0;
3321             break;
3322         }
3323         case IVD_CMD_CTL_FLUSH:
3324             ret = ihevcd_set_flush_mode(ps_codec_obj, (void *)pv_api_ip,
3325                                         (void *)pv_api_op);
3326             break;
3327         case IVD_CMD_CTL_GETBUFINFO:
3328             ret = ihevcd_get_buf_info(ps_codec_obj, (void *)pv_api_ip,
3329                                       (void *)pv_api_op);
3330             break;
3331         case IVD_CMD_CTL_GETVERSION:
3332         {
3333             ivd_ctl_getversioninfo_ip_t *ps_ip;
3334             ivd_ctl_getversioninfo_op_t *ps_op;
3335             IV_API_CALL_STATUS_T ret;
3336             ps_ip = (ivd_ctl_getversioninfo_ip_t *)pv_api_ip;
3337             ps_op = (ivd_ctl_getversioninfo_op_t *)pv_api_op;
3338 
3339             ps_op->u4_error_code = IV_SUCCESS;
3340 
3341             if((WORD32)ps_ip->u4_version_buffer_size <= 0)
3342             {
3343                 ps_op->u4_error_code = IHEVCD_CXA_VERS_BUF_INSUFFICIENT;
3344                 ret = IV_FAIL;
3345             }
3346             else
3347             {
3348                 ret = ihevcd_get_version((CHAR *)ps_ip->pv_version_buffer,
3349                                          ps_ip->u4_version_buffer_size);
3350                 if(ret != IV_SUCCESS)
3351                 {
3352                     ps_op->u4_error_code = IHEVCD_CXA_VERS_BUF_INSUFFICIENT;
3353                     ret = IV_FAIL;
3354                 }
3355             }
3356         }
3357             break;
3358         case IHEVCD_CXA_CMD_CTL_DEGRADE:
3359             ret = ihevcd_set_degrade(ps_codec_obj, (void *)pv_api_ip,
3360                             (void *)pv_api_op);
3361             break;
3362         case IHEVCD_CXA_CMD_CTL_SET_NUM_CORES:
3363             ret = ihevcd_set_num_cores(ps_codec_obj, (void *)pv_api_ip,
3364                                        (void *)pv_api_op);
3365             break;
3366         case IHEVCD_CXA_CMD_CTL_GET_BUFFER_DIMENSIONS:
3367             ret = ihevcd_get_frame_dimensions(ps_codec_obj, (void *)pv_api_ip,
3368                                               (void *)pv_api_op);
3369             break;
3370         case IHEVCD_CXA_CMD_CTL_GET_VUI_PARAMS:
3371             ret = ihevcd_get_vui_params(ps_codec_obj, (void *)pv_api_ip,
3372                                         (void *)pv_api_op);
3373             break;
3374         case IHEVCD_CXA_CMD_CTL_SET_PROCESSOR:
3375             ret = ihevcd_set_processor(ps_codec_obj, (void *)pv_api_ip,
3376                             (void *)pv_api_op);
3377             break;
3378         default:
3379             DEBUG("\nDo nothing\n");
3380             break;
3381     }
3382 
3383     return ret;
3384 }
3385 
3386 /**
3387 *******************************************************************************
3388 *
3389 * @brief
3390 *  Codecs entry point function. All the function calls to  the codec are
3391 * done using this function with different  values specified in command
3392 *
3393 * @par Description:
3394 *  Arguments are tested for validity and then based on the  command
3395 * appropriate function is called
3396 *
3397 * @param[in] ps_handle
3398 *  API level handle for codec
3399 *
3400 * @param[in] pv_api_ip
3401 *  Input argument structure
3402 *
3403 * @param[out] pv_api_op
3404 *  Output argument structure
3405 *
3406 * @returns  Status of the function corresponding to command
3407 *
3408 * @remarks
3409 *
3410 *
3411 *******************************************************************************
3412 */
ihevcd_cxa_api_function(iv_obj_t * ps_handle,void * pv_api_ip,void * pv_api_op)3413 IV_API_CALL_STATUS_T ihevcd_cxa_api_function(iv_obj_t *ps_handle,
3414                                              void *pv_api_ip,
3415                                              void *pv_api_op)
3416 {
3417     WORD32 command;
3418     UWORD32 *pu4_ptr_cmd;
3419     WORD32 ret = 0;
3420     IV_API_CALL_STATUS_T e_status;
3421     e_status = api_check_struct_sanity(ps_handle, pv_api_ip, pv_api_op);
3422 
3423     if(e_status != IV_SUCCESS)
3424     {
3425         DEBUG("error code = %d\n", *((UWORD32 *)pv_api_op + 1));
3426         return IV_FAIL;
3427     }
3428 
3429     pu4_ptr_cmd = (UWORD32 *)pv_api_ip;
3430     pu4_ptr_cmd++;
3431 
3432     command = *pu4_ptr_cmd;
3433 
3434     switch(command)
3435     {
3436         case IVD_CMD_CREATE:
3437             ret = ihevcd_create(ps_handle, (void *)pv_api_ip, (void *)pv_api_op);
3438             break;
3439         case IVD_CMD_DELETE:
3440             ret = ihevcd_delete(ps_handle, (void *)pv_api_ip, (void *)pv_api_op);
3441             break;
3442 
3443         case IVD_CMD_VIDEO_DECODE:
3444             ret = ihevcd_decode(ps_handle, (void *)pv_api_ip, (void *)pv_api_op);
3445             break;
3446 
3447         case IVD_CMD_GET_DISPLAY_FRAME:
3448             //ret = ihevcd_get_display_frame(ps_handle,(void *)pv_api_ip,(void *)pv_api_op);
3449             break;
3450 
3451         case IVD_CMD_SET_DISPLAY_FRAME:
3452             ret = ihevcd_set_display_frame(ps_handle, (void *)pv_api_ip,
3453                                            (void *)pv_api_op);
3454 
3455             break;
3456 
3457         case IVD_CMD_REL_DISPLAY_FRAME:
3458             ret = ihevcd_rel_display_frame(ps_handle, (void *)pv_api_ip,
3459                                            (void *)pv_api_op);
3460             break;
3461 
3462         case IVD_CMD_VIDEO_CTL:
3463             ret = ihevcd_ctl(ps_handle, (void *)pv_api_ip, (void *)pv_api_op);
3464             break;
3465         default:
3466             ret = IV_FAIL;
3467             break;
3468     }
3469 
3470     return (IV_API_CALL_STATUS_T)ret;
3471 }
3472 
3473