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