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