1 /******************************************************************************
2 *
3 * Copyright (C) 2012 Ittiam Systems Pvt Ltd, Bangalore
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at:
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 *
17 ******************************************************************************/
18 /**
19 *******************************************************************************
20 * @file
21 * ihevcd_api.c
22 *
23 * @brief
24 * Contains api functions definitions for HEVC decoder
25 *
26 * @author
27 * Harish
28 *
29 * @par List of Functions:
30 * - api_check_struct_sanity()
31 * - ihevcd_get_version()
32 * - ihevcd_set_default_params()
33 * - ihevcd_init()
34 * - ihevcd_get_num_rec()
35 * - ihevcd_fill_num_mem_rec()
36 * - ihevcd_init_mem_rec()
37 * - ihevcd_retrieve_memrec()
38 * - ihevcd_set_display_frame()
39 * - ihevcd_set_flush_mode()
40 * - ihevcd_get_status()
41 * - ihevcd_get_buf_info()
42 * - ihevcd_set_params()
43 * - ihevcd_reset()
44 * - ihevcd_rel_display_frame()
45 * - ihevcd_disable_deblk()
46 * - ihevcd_get_frame_dimensions()
47 * - ihevcd_set_num_cores()
48 * - ihevcd_ctl()
49 * - ihevcd_cxa_api_function()
50 *
51 * @remarks
52 * None
53 *
54 *******************************************************************************
55 */
56 /*****************************************************************************/
57 /* File Includes */
58 /*****************************************************************************/
59 #include <stdio.h>
60 #include <stddef.h>
61 #include <stdlib.h>
62 #include <string.h>
63
64 #include "ihevc_typedefs.h"
65 #include "iv.h"
66 #include "ivd.h"
67 #include "ihevcd_cxa.h"
68 #include "ithread.h"
69
70 #include "ihevc_defs.h"
71 #include "ihevc_debug.h"
72
73 #include "ihevc_structs.h"
74 #include "ihevc_macros.h"
75 #include "ihevc_platform_macros.h"
76
77 #include "ihevc_buf_mgr.h"
78 #include "ihevc_dpb_mgr.h"
79 #include "ihevc_disp_mgr.h"
80 #include "ihevc_common_tables.h"
81 #include "ihevc_cabac_tables.h"
82 #include "ihevc_error.h"
83
84 #include "ihevcd_defs.h"
85 #include "ihevcd_trace.h"
86
87 #include "ihevcd_function_selector.h"
88 #include "ihevcd_structs.h"
89 #include "ihevcd_error.h"
90 #include "ihevcd_utils.h"
91 #include "ihevcd_decode.h"
92 #include "ihevcd_job_queue.h"
93 #include "ihevcd_statistics.h"
94
95 /*****************************************************************************/
96 /* Function Prototypes */
97 /*****************************************************************************/
98 IV_API_CALL_STATUS_T ihevcd_get_version(CHAR *pc_version_string,
99 UWORD32 u4_version_buffer_size);
100
101
102
103 /**
104 *******************************************************************************
105 *
106 * @brief
107 * Used to test arguments for corresponding API call
108 *
109 * @par Description:
110 * For each command the arguments are validated
111 *
112 * @param[in] ps_handle
113 * Codec handle at API level
114 *
115 * @param[in] pv_api_ip
116 * Pointer to input structure
117 *
118 * @param[out] pv_api_op
119 * Pointer to output structure
120 *
121 * @returns Status of error checking
122 *
123 * @remarks
124 *
125 *
126 *******************************************************************************
127 */
128
api_check_struct_sanity(iv_obj_t * ps_handle,void * pv_api_ip,void * pv_api_op)129 static IV_API_CALL_STATUS_T api_check_struct_sanity(iv_obj_t *ps_handle,
130 void *pv_api_ip,
131 void *pv_api_op)
132 {
133 IVD_API_COMMAND_TYPE_T e_cmd;
134 UWORD32 *pu4_api_ip;
135 UWORD32 *pu4_api_op;
136 WORD32 i, j;
137
138 if(NULL == pv_api_op)
139 return (IV_FAIL);
140
141 if(NULL == pv_api_ip)
142 return (IV_FAIL);
143
144 pu4_api_ip = (UWORD32 *)pv_api_ip;
145 pu4_api_op = (UWORD32 *)pv_api_op;
146 e_cmd = (IVD_API_COMMAND_TYPE_T)*(pu4_api_ip + 1);
147
148 *(pu4_api_op + 1) = 0;
149 /* error checks on handle */
150 switch((WORD32)e_cmd)
151 {
152 case IV_CMD_GET_NUM_MEM_REC:
153 case IV_CMD_FILL_NUM_MEM_REC:
154 break;
155 case IV_CMD_INIT:
156 if(ps_handle == NULL)
157 {
158 *(pu4_api_op + 1) |= 1 << IVD_UNSUPPORTEDPARAM;
159 *(pu4_api_op + 1) |= IVD_HANDLE_NULL;
160 return IV_FAIL;
161 }
162
163 if(ps_handle->u4_size != sizeof(iv_obj_t))
164 {
165 *(pu4_api_op + 1) |= 1 << IVD_UNSUPPORTEDPARAM;
166 *(pu4_api_op + 1) |= IVD_HANDLE_STRUCT_SIZE_INCORRECT;
167 DEBUG("Sizes do not match. Expected: %d, Got: %d",
168 sizeof(iv_obj_t), ps_handle->u4_size);
169 return IV_FAIL;
170 }
171 break;
172 case IVD_CMD_REL_DISPLAY_FRAME:
173 case IVD_CMD_SET_DISPLAY_FRAME:
174 case IVD_CMD_GET_DISPLAY_FRAME:
175 case IVD_CMD_VIDEO_DECODE:
176 case IV_CMD_RETRIEVE_MEMREC:
177 case IVD_CMD_VIDEO_CTL:
178 if(ps_handle == NULL)
179 {
180 *(pu4_api_op + 1) |= 1 << IVD_UNSUPPORTEDPARAM;
181 *(pu4_api_op + 1) |= IVD_HANDLE_NULL;
182 return IV_FAIL;
183 }
184
185 if(ps_handle->u4_size != sizeof(iv_obj_t))
186 {
187 *(pu4_api_op + 1) |= 1 << IVD_UNSUPPORTEDPARAM;
188 *(pu4_api_op + 1) |= IVD_HANDLE_STRUCT_SIZE_INCORRECT;
189 return IV_FAIL;
190 }
191
192
193 if(ps_handle->pv_codec_handle == NULL)
194 {
195 *(pu4_api_op + 1) |= 1 << IVD_UNSUPPORTEDPARAM;
196 *(pu4_api_op + 1) |= IVD_INVALID_HANDLE_NULL;
197 return IV_FAIL;
198 }
199 break;
200 default:
201 *(pu4_api_op + 1) |= 1 << IVD_UNSUPPORTEDPARAM;
202 *(pu4_api_op + 1) |= IVD_INVALID_API_CMD;
203 return IV_FAIL;
204 }
205
206 switch((WORD32)e_cmd)
207 {
208 case IV_CMD_GET_NUM_MEM_REC:
209 {
210 ihevcd_cxa_num_mem_rec_ip_t *ps_ip =
211 (ihevcd_cxa_num_mem_rec_ip_t *)pv_api_ip;
212 ihevcd_cxa_num_mem_rec_op_t *ps_op =
213 (ihevcd_cxa_num_mem_rec_op_t *)pv_api_op;
214 ps_op->s_ivd_num_mem_rec_op_t.u4_error_code = 0;
215
216 if(ps_ip->s_ivd_num_mem_rec_ip_t.u4_size
217 != sizeof(ihevcd_cxa_num_mem_rec_ip_t))
218 {
219 ps_op->s_ivd_num_mem_rec_op_t.u4_error_code |= 1
220 << IVD_UNSUPPORTEDPARAM;
221 ps_op->s_ivd_num_mem_rec_op_t.u4_error_code |=
222 IVD_IP_API_STRUCT_SIZE_INCORRECT;
223 return (IV_FAIL);
224 }
225
226 if(ps_op->s_ivd_num_mem_rec_op_t.u4_size
227 != sizeof(ihevcd_cxa_num_mem_rec_op_t))
228 {
229 ps_op->s_ivd_num_mem_rec_op_t.u4_error_code |= 1
230 << IVD_UNSUPPORTEDPARAM;
231 ps_op->s_ivd_num_mem_rec_op_t.u4_error_code |=
232 IVD_OP_API_STRUCT_SIZE_INCORRECT;
233 return (IV_FAIL);
234 }
235 }
236 break;
237 case IV_CMD_FILL_NUM_MEM_REC:
238 {
239 ihevcd_cxa_fill_mem_rec_ip_t *ps_ip =
240 (ihevcd_cxa_fill_mem_rec_ip_t *)pv_api_ip;
241 ihevcd_cxa_fill_mem_rec_op_t *ps_op =
242 (ihevcd_cxa_fill_mem_rec_op_t *)pv_api_op;
243 iv_mem_rec_t *ps_mem_rec;
244 WORD32 max_wd = ps_ip->s_ivd_fill_mem_rec_ip_t.u4_max_frm_wd;
245 WORD32 max_ht = ps_ip->s_ivd_fill_mem_rec_ip_t.u4_max_frm_ht;
246
247 max_wd = ALIGN64(max_wd);
248 max_ht = ALIGN64(max_ht);
249
250 ps_op->s_ivd_fill_mem_rec_op_t.u4_error_code = 0;
251
252 if((ps_ip->s_ivd_fill_mem_rec_ip_t.u4_size
253 > sizeof(ihevcd_cxa_fill_mem_rec_ip_t))
254 || (ps_ip->s_ivd_fill_mem_rec_ip_t.u4_size
255 < sizeof(iv_fill_mem_rec_ip_t)))
256 {
257 ps_op->s_ivd_fill_mem_rec_op_t.u4_error_code |= 1
258 << IVD_UNSUPPORTEDPARAM;
259 ps_op->s_ivd_fill_mem_rec_op_t.u4_error_code |=
260 IVD_IP_API_STRUCT_SIZE_INCORRECT;
261 return (IV_FAIL);
262 }
263
264 if((ps_op->s_ivd_fill_mem_rec_op_t.u4_size
265 != sizeof(ihevcd_cxa_fill_mem_rec_op_t))
266 && (ps_op->s_ivd_fill_mem_rec_op_t.u4_size
267 != sizeof(iv_fill_mem_rec_op_t)))
268 {
269 ps_op->s_ivd_fill_mem_rec_op_t.u4_error_code |= 1
270 << IVD_UNSUPPORTEDPARAM;
271 ps_op->s_ivd_fill_mem_rec_op_t.u4_error_code |=
272 IVD_OP_API_STRUCT_SIZE_INCORRECT;
273 return (IV_FAIL);
274 }
275
276 if(max_wd < MIN_WD)
277 {
278 ps_op->s_ivd_fill_mem_rec_op_t.u4_error_code |= 1
279 << IVD_UNSUPPORTEDPARAM;
280 ps_op->s_ivd_fill_mem_rec_op_t.u4_error_code |=
281 IVD_REQUESTED_WIDTH_NOT_SUPPPORTED;
282 return (IV_FAIL);
283 }
284
285 if(max_wd > MAX_WD)
286 {
287 ps_op->s_ivd_fill_mem_rec_op_t.u4_error_code |= 1
288 << IVD_UNSUPPORTEDPARAM;
289 ps_op->s_ivd_fill_mem_rec_op_t.u4_error_code |=
290 IVD_REQUESTED_WIDTH_NOT_SUPPPORTED;
291 return (IV_FAIL);
292 }
293
294 if(max_ht < MIN_HT)
295 {
296 ps_op->s_ivd_fill_mem_rec_op_t.u4_error_code |= 1
297 << IVD_UNSUPPORTEDPARAM;
298 ps_op->s_ivd_fill_mem_rec_op_t.u4_error_code |=
299 IVD_REQUESTED_HEIGHT_NOT_SUPPPORTED;
300 return (IV_FAIL);
301 }
302
303 if((max_ht * max_wd) > (MAX_HT * MAX_WD))
304
305 {
306 ps_op->s_ivd_fill_mem_rec_op_t.u4_error_code |= 1
307 << IVD_UNSUPPORTEDPARAM;
308 ps_op->s_ivd_fill_mem_rec_op_t.u4_error_code |=
309 IVD_REQUESTED_HEIGHT_NOT_SUPPPORTED;
310 return (IV_FAIL);
311 }
312
313 if(NULL == ps_ip->s_ivd_fill_mem_rec_ip_t.pv_mem_rec_location)
314 {
315 ps_op->s_ivd_fill_mem_rec_op_t.u4_error_code |= 1
316 << IVD_UNSUPPORTEDPARAM;
317 ps_op->s_ivd_fill_mem_rec_op_t.u4_error_code |=
318 IVD_NUM_REC_NOT_SUFFICIENT;
319 return (IV_FAIL);
320 }
321
322 /* check memrecords sizes are correct */
323 ps_mem_rec = ps_ip->s_ivd_fill_mem_rec_ip_t.pv_mem_rec_location;
324 for(i = 0; i < MEM_REC_CNT; i++)
325 {
326 if(ps_mem_rec[i].u4_size != sizeof(iv_mem_rec_t))
327 {
328 ps_op->s_ivd_fill_mem_rec_op_t.u4_error_code |= 1
329 << IVD_UNSUPPORTEDPARAM;
330 ps_op->s_ivd_fill_mem_rec_op_t.u4_error_code |=
331 IVD_MEM_REC_STRUCT_SIZE_INCORRECT;
332 return IV_FAIL;
333 }
334 }
335 }
336 break;
337
338 case IV_CMD_INIT:
339 {
340 ihevcd_cxa_init_ip_t *ps_ip = (ihevcd_cxa_init_ip_t *)pv_api_ip;
341 ihevcd_cxa_init_op_t *ps_op = (ihevcd_cxa_init_op_t *)pv_api_op;
342 iv_mem_rec_t *ps_mem_rec;
343 WORD32 max_wd = ps_ip->s_ivd_init_ip_t.u4_frm_max_wd;
344 WORD32 max_ht = ps_ip->s_ivd_init_ip_t.u4_frm_max_ht;
345
346 max_wd = ALIGN64(max_wd);
347 max_ht = ALIGN64(max_ht);
348
349 ps_op->s_ivd_init_op_t.u4_error_code = 0;
350
351 if((ps_ip->s_ivd_init_ip_t.u4_size > sizeof(ihevcd_cxa_init_ip_t))
352 || (ps_ip->s_ivd_init_ip_t.u4_size
353 < sizeof(ivd_init_ip_t)))
354 {
355 ps_op->s_ivd_init_op_t.u4_error_code |= 1
356 << IVD_UNSUPPORTEDPARAM;
357 ps_op->s_ivd_init_op_t.u4_error_code |=
358 IVD_IP_API_STRUCT_SIZE_INCORRECT;
359 DEBUG("\n");
360 return (IV_FAIL);
361 }
362
363 if((ps_op->s_ivd_init_op_t.u4_size != sizeof(ihevcd_cxa_init_op_t))
364 && (ps_op->s_ivd_init_op_t.u4_size
365 != sizeof(ivd_init_op_t)))
366 {
367 ps_op->s_ivd_init_op_t.u4_error_code |= 1
368 << IVD_UNSUPPORTEDPARAM;
369 ps_op->s_ivd_init_op_t.u4_error_code |=
370 IVD_OP_API_STRUCT_SIZE_INCORRECT;
371 DEBUG("\n");
372 return (IV_FAIL);
373 }
374
375 if(ps_ip->s_ivd_init_ip_t.u4_num_mem_rec != MEM_REC_CNT)
376 {
377 ps_op->s_ivd_init_op_t.u4_error_code |= 1
378 << IVD_UNSUPPORTEDPARAM;
379 ps_op->s_ivd_init_op_t.u4_error_code |=
380 IVD_INIT_DEC_NOT_SUFFICIENT;
381 DEBUG("\n");
382 return (IV_FAIL);
383 }
384
385 if(max_wd < MIN_WD)
386 {
387 ps_op->s_ivd_init_op_t.u4_error_code |= 1
388 << IVD_UNSUPPORTEDPARAM;
389 ps_op->s_ivd_init_op_t.u4_error_code |=
390 IVD_INIT_DEC_WIDTH_NOT_SUPPPORTED;
391 DEBUG("\n");
392 return (IV_FAIL);
393 }
394
395 if(max_wd > MAX_WD)
396 {
397 ps_op->s_ivd_init_op_t.u4_error_code |= 1
398 << IVD_UNSUPPORTEDPARAM;
399 ps_op->s_ivd_init_op_t.u4_error_code |=
400 IVD_INIT_DEC_WIDTH_NOT_SUPPPORTED;
401 DEBUG("\n");
402 return (IV_FAIL);
403 }
404
405 if(max_ht < MIN_HT)
406 {
407 ps_op->s_ivd_init_op_t.u4_error_code |= 1
408 << IVD_UNSUPPORTEDPARAM;
409 ps_op->s_ivd_init_op_t.u4_error_code |=
410 IVD_INIT_DEC_HEIGHT_NOT_SUPPPORTED;
411 DEBUG("\n");
412 return (IV_FAIL);
413 }
414
415 if((max_ht * max_wd) > (MAX_HT * MAX_WD))
416
417 {
418 ps_op->s_ivd_init_op_t.u4_error_code |= 1
419 << IVD_UNSUPPORTEDPARAM;
420 ps_op->s_ivd_init_op_t.u4_error_code |=
421 IVD_INIT_DEC_HEIGHT_NOT_SUPPPORTED;
422 DEBUG("\n");
423 return (IV_FAIL);
424 }
425
426 if(NULL == ps_ip->s_ivd_init_ip_t.pv_mem_rec_location)
427 {
428 ps_op->s_ivd_init_op_t.u4_error_code |= 1
429 << IVD_UNSUPPORTEDPARAM;
430 ps_op->s_ivd_init_op_t.u4_error_code |=
431 IVD_NUM_REC_NOT_SUFFICIENT;
432 DEBUG("\n");
433 return (IV_FAIL);
434 }
435
436 if((ps_ip->s_ivd_init_ip_t.e_output_format != IV_YUV_420P)
437 && (ps_ip->s_ivd_init_ip_t.e_output_format
438 != IV_YUV_422ILE)
439 && (ps_ip->s_ivd_init_ip_t.e_output_format
440 != IV_RGB_565)
441 && (ps_ip->s_ivd_init_ip_t.e_output_format
442 != IV_RGBA_8888)
443 && (ps_ip->s_ivd_init_ip_t.e_output_format
444 != IV_YUV_420SP_UV)
445 && (ps_ip->s_ivd_init_ip_t.e_output_format
446 != IV_YUV_420SP_VU))
447 {
448 ps_op->s_ivd_init_op_t.u4_error_code |= 1
449 << IVD_UNSUPPORTEDPARAM;
450 ps_op->s_ivd_init_op_t.u4_error_code |=
451 IVD_INIT_DEC_COL_FMT_NOT_SUPPORTED;
452 DEBUG("\n");
453 return (IV_FAIL);
454 }
455
456 /* verify number of mem records */
457 if(ps_ip->s_ivd_init_ip_t.u4_num_mem_rec < MEM_REC_CNT)
458 {
459 ps_op->s_ivd_init_op_t.u4_error_code |= 1
460 << IVD_UNSUPPORTEDPARAM;
461 ps_op->s_ivd_init_op_t.u4_error_code |=
462 IVD_INIT_DEC_MEM_REC_NOT_SUFFICIENT;
463 DEBUG("\n");
464 return IV_FAIL;
465 }
466
467 ps_mem_rec = ps_ip->s_ivd_init_ip_t.pv_mem_rec_location;
468 /* check memrecords sizes are correct */
469 for(i = 0; i < (WORD32)ps_ip->s_ivd_init_ip_t.u4_num_mem_rec; i++)
470 {
471 if(ps_mem_rec[i].u4_size != sizeof(iv_mem_rec_t))
472 {
473 ps_op->s_ivd_init_op_t.u4_error_code |= 1
474 << IVD_UNSUPPORTEDPARAM;
475 ps_op->s_ivd_init_op_t.u4_error_code |=
476 IVD_MEM_REC_STRUCT_SIZE_INCORRECT;
477 DEBUG("i: %d\n", i);
478 return IV_FAIL;
479 }
480 /* check memrecords pointers are not NULL */
481
482 if(ps_mem_rec[i].pv_base == NULL)
483 {
484
485 ps_op->s_ivd_init_op_t.u4_error_code |= 1
486 << IVD_UNSUPPORTEDPARAM;
487 ps_op->s_ivd_init_op_t.u4_error_code |=
488 IVD_INIT_DEC_MEM_REC_BASE_NULL;
489 DEBUG("i: %d\n", i);
490 return IV_FAIL;
491
492 }
493
494 }
495
496 /* verify memtabs for overlapping regions */
497 {
498 void *start[MEM_REC_CNT];
499 void *end[MEM_REC_CNT];
500
501 start[0] = (ps_mem_rec[0].pv_base);
502 end[0] = (UWORD8 *)(ps_mem_rec[0].pv_base)
503 + ps_mem_rec[0].u4_mem_size - 1;
504 for(i = 1; i < MEM_REC_CNT; i++)
505 {
506 /* This array is populated to check memtab overlapp */
507 start[i] = (ps_mem_rec[i].pv_base);
508 end[i] = (UWORD8 *)(ps_mem_rec[i].pv_base)
509 + ps_mem_rec[i].u4_mem_size - 1;
510
511 for(j = 0; j < i; j++)
512 {
513 if((start[i] >= start[j]) && (start[i] <= end[j]))
514 {
515 ps_op->s_ivd_init_op_t.u4_error_code |= 1
516 << IVD_UNSUPPORTEDPARAM;
517 ps_op->s_ivd_init_op_t.u4_error_code |=
518 IVD_INIT_DEC_MEM_REC_OVERLAP_ERR;
519 DEBUG("i: %d, j: %d\n", i, j);
520 return IV_FAIL;
521 }
522
523 if((end[i] >= start[j]) && (end[i] <= end[j]))
524 {
525 ps_op->s_ivd_init_op_t.u4_error_code |= 1
526 << IVD_UNSUPPORTEDPARAM;
527 ps_op->s_ivd_init_op_t.u4_error_code |=
528 IVD_INIT_DEC_MEM_REC_OVERLAP_ERR;
529 DEBUG("i: %d, j: %d\n", i, j);
530 return IV_FAIL;
531 }
532
533 if((start[i] < start[j]) && (end[i] > end[j]))
534 {
535 ps_op->s_ivd_init_op_t.u4_error_code |= 1
536 << IVD_UNSUPPORTEDPARAM;
537 ps_op->s_ivd_init_op_t.u4_error_code |=
538 IVD_INIT_DEC_MEM_REC_OVERLAP_ERR;
539 DEBUG("i: %d, j: %d\n", i, j);
540 return IV_FAIL;
541 }
542 }
543
544 }
545 }
546
547 {
548 iv_mem_rec_t mem_rec_ittiam_api[MEM_REC_CNT];
549 ihevcd_cxa_fill_mem_rec_ip_t s_fill_mem_rec_ip;
550 ihevcd_cxa_fill_mem_rec_op_t s_fill_mem_rec_op;
551 IV_API_CALL_STATUS_T e_status;
552
553 WORD32 i;
554 s_fill_mem_rec_ip.s_ivd_fill_mem_rec_ip_t.e_cmd =
555 IV_CMD_FILL_NUM_MEM_REC;
556 s_fill_mem_rec_ip.s_ivd_fill_mem_rec_ip_t.pv_mem_rec_location =
557 mem_rec_ittiam_api;
558 s_fill_mem_rec_ip.s_ivd_fill_mem_rec_ip_t.u4_max_frm_wd =
559 max_wd;
560 s_fill_mem_rec_ip.s_ivd_fill_mem_rec_ip_t.u4_max_frm_ht =
561 max_ht;
562
563 if(ps_ip->s_ivd_init_ip_t.u4_size
564 > offsetof(ihevcd_cxa_init_ip_t, i4_level))
565 {
566 s_fill_mem_rec_ip.i4_level = ps_ip->i4_level;
567 }
568 else
569 {
570 s_fill_mem_rec_ip.i4_level = IHEVC_LEVEL_31;
571 }
572
573 if(ps_ip->s_ivd_init_ip_t.u4_size
574 > offsetof(ihevcd_cxa_init_ip_t,
575 u4_num_ref_frames))
576 {
577 s_fill_mem_rec_ip.u4_num_ref_frames =
578 ps_ip->u4_num_ref_frames;
579 }
580 else
581 {
582 s_fill_mem_rec_ip.u4_num_ref_frames = (MAX_REF_CNT + 1);
583 }
584
585 if(ps_ip->s_ivd_init_ip_t.u4_size
586 > offsetof(ihevcd_cxa_init_ip_t,
587 u4_num_reorder_frames))
588 {
589 s_fill_mem_rec_ip.u4_num_reorder_frames =
590 ps_ip->u4_num_reorder_frames;
591 }
592 else
593 {
594 s_fill_mem_rec_ip.u4_num_reorder_frames = (MAX_REF_CNT + 1);
595 }
596
597 if(ps_ip->s_ivd_init_ip_t.u4_size
598 > offsetof(ihevcd_cxa_init_ip_t,
599 u4_num_extra_disp_buf))
600 {
601 s_fill_mem_rec_ip.u4_num_extra_disp_buf =
602 ps_ip->u4_num_extra_disp_buf;
603 }
604 else
605 {
606 s_fill_mem_rec_ip.u4_num_extra_disp_buf = 0;
607 }
608
609 if(ps_ip->s_ivd_init_ip_t.u4_size
610 > offsetof(ihevcd_cxa_init_ip_t,
611 u4_share_disp_buf))
612 {
613 #ifndef LOGO_EN
614 s_fill_mem_rec_ip.u4_share_disp_buf =
615 ps_ip->u4_share_disp_buf;
616 #else
617 s_fill_mem_rec_ip.u4_share_disp_buf = 0;
618 #endif
619 }
620 else
621 {
622 s_fill_mem_rec_ip.u4_share_disp_buf = 0;
623 }
624
625 s_fill_mem_rec_ip.e_output_format =
626 ps_ip->s_ivd_init_ip_t.e_output_format;
627
628 if((s_fill_mem_rec_ip.e_output_format != IV_YUV_420P)
629 && (s_fill_mem_rec_ip.e_output_format
630 != IV_YUV_420SP_UV)
631 && (s_fill_mem_rec_ip.e_output_format
632 != IV_YUV_420SP_VU))
633 {
634 s_fill_mem_rec_ip.u4_share_disp_buf = 0;
635 }
636
637 s_fill_mem_rec_ip.s_ivd_fill_mem_rec_ip_t.u4_size =
638 sizeof(ihevcd_cxa_fill_mem_rec_ip_t);
639 s_fill_mem_rec_op.s_ivd_fill_mem_rec_op_t.u4_size =
640 sizeof(ihevcd_cxa_fill_mem_rec_op_t);
641
642 for(i = 0; i < MEM_REC_CNT; i++)
643 mem_rec_ittiam_api[i].u4_size = sizeof(iv_mem_rec_t);
644
645 e_status = ihevcd_cxa_api_function(NULL,
646 (void *)&s_fill_mem_rec_ip,
647 (void *)&s_fill_mem_rec_op);
648 if(IV_FAIL == e_status)
649 {
650 ps_op->s_ivd_init_op_t.u4_error_code =
651 s_fill_mem_rec_op.s_ivd_fill_mem_rec_op_t.u4_error_code;
652 DEBUG("Fail\n");
653 return (IV_FAIL);
654 }
655
656 for(i = 0; i < MEM_REC_CNT; i++)
657 {
658 #ifdef ARMRVDS
659 if((UWORD32)(ps_mem_rec[i].pv_base) & (mem_rec_ittiam_api[i].u4_mem_alignment - 1))
660 {
661 ps_op->s_ivd_init_op_t.u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM;
662 ps_op->s_ivd_init_op_t.u4_error_code |= IVD_INIT_DEC_MEM_REC_ALIGNMENT_ERR;
663 DEBUG("Fail\n");
664 return IV_FAIL;
665 }
666 #endif
667
668 if(ps_mem_rec[i].u4_mem_size
669 < mem_rec_ittiam_api[i].u4_mem_size)
670 {
671 ps_op->s_ivd_init_op_t.u4_error_code |= 1
672 << IVD_UNSUPPORTEDPARAM;
673 ps_op->s_ivd_init_op_t.u4_error_code |=
674 IVD_INIT_DEC_MEM_REC_INSUFFICIENT_SIZE;
675 DEBUG("i: %d \n", i);
676 return IV_FAIL;
677 }
678 if(ps_mem_rec[i].u4_mem_alignment
679 != mem_rec_ittiam_api[i].u4_mem_alignment)
680 {
681 ps_op->s_ivd_init_op_t.u4_error_code |= 1
682 << IVD_UNSUPPORTEDPARAM;
683 ps_op->s_ivd_init_op_t.u4_error_code |=
684 IVD_INIT_DEC_MEM_REC_ALIGNMENT_ERR;
685 DEBUG("i: %d \n", i);
686 return IV_FAIL;
687 }
688 if(ps_mem_rec[i].e_mem_type
689 != mem_rec_ittiam_api[i].e_mem_type)
690 {
691 UWORD32 check = IV_SUCCESS;
692 UWORD32 diff = mem_rec_ittiam_api[i].e_mem_type
693 - ps_mem_rec[i].e_mem_type;
694
695 if((ps_mem_rec[i].e_mem_type
696 <= IV_EXTERNAL_CACHEABLE_SCRATCH_MEM)
697 && (mem_rec_ittiam_api[i].e_mem_type
698 >= IV_INTERNAL_NONCACHEABLE_PERSISTENT_MEM))
699 {
700 check = IV_FAIL;
701 }
702 if(3 != (mem_rec_ittiam_api[i].e_mem_type % 4))
703 {
704 /*
705 * It is not IV_EXTERNAL_NONCACHEABLE_PERSISTENT_MEM or IV_EXTERNAL_CACHEABLE_PERSISTENT_MEM
706 */
707 if((diff < 1) || (diff > 3))
708 {
709 // Difference between 1 and 3 is okay for all cases other than the two filtered
710 // with the MOD condition above
711 check = IV_FAIL;
712 }
713 }
714 else
715 {
716 if(diff == 1)
717 {
718 /*
719 * This particular case is when codec asked for External Persistent, but got
720 * Internal Scratch.
721 */
722 check = IV_FAIL;
723 }
724 if((diff != 2) && (diff != 3))
725 {
726 check = IV_FAIL;
727 }
728 }
729 if(check == IV_FAIL)
730 {
731 ps_op->s_ivd_init_op_t.u4_error_code |= 1
732 << IVD_UNSUPPORTEDPARAM;
733 ps_op->s_ivd_init_op_t.u4_error_code |=
734 IVD_INIT_DEC_MEM_REC_INCORRECT_TYPE;
735 DEBUG("i: %d \n", i);
736 return IV_FAIL;
737 }
738 }
739 }
740 }
741
742 }
743 break;
744
745 case IVD_CMD_GET_DISPLAY_FRAME:
746 {
747 ihevcd_cxa_get_display_frame_ip_t *ps_ip =
748 (ihevcd_cxa_get_display_frame_ip_t *)pv_api_ip;
749 ihevcd_cxa_get_display_frame_op_t *ps_op =
750 (ihevcd_cxa_get_display_frame_op_t *)pv_api_op;
751
752 ps_op->s_ivd_get_display_frame_op_t.u4_error_code = 0;
753
754 if((ps_ip->s_ivd_get_display_frame_ip_t.u4_size
755 != sizeof(ihevcd_cxa_get_display_frame_ip_t))
756 && (ps_ip->s_ivd_get_display_frame_ip_t.u4_size
757 != sizeof(ivd_get_display_frame_ip_t)))
758 {
759 ps_op->s_ivd_get_display_frame_op_t.u4_error_code |= 1
760 << IVD_UNSUPPORTEDPARAM;
761 ps_op->s_ivd_get_display_frame_op_t.u4_error_code |=
762 IVD_IP_API_STRUCT_SIZE_INCORRECT;
763 return (IV_FAIL);
764 }
765
766 if((ps_op->s_ivd_get_display_frame_op_t.u4_size
767 != sizeof(ihevcd_cxa_get_display_frame_op_t))
768 && (ps_op->s_ivd_get_display_frame_op_t.u4_size
769 != sizeof(ivd_get_display_frame_op_t)))
770 {
771 ps_op->s_ivd_get_display_frame_op_t.u4_error_code |= 1
772 << IVD_UNSUPPORTEDPARAM;
773 ps_op->s_ivd_get_display_frame_op_t.u4_error_code |=
774 IVD_OP_API_STRUCT_SIZE_INCORRECT;
775 return (IV_FAIL);
776 }
777
778 }
779 break;
780
781 case IVD_CMD_REL_DISPLAY_FRAME:
782 {
783 ihevcd_cxa_rel_display_frame_ip_t *ps_ip =
784 (ihevcd_cxa_rel_display_frame_ip_t *)pv_api_ip;
785 ihevcd_cxa_rel_display_frame_op_t *ps_op =
786 (ihevcd_cxa_rel_display_frame_op_t *)pv_api_op;
787
788 ps_op->s_ivd_rel_display_frame_op_t.u4_error_code = 0;
789
790 if((ps_ip->s_ivd_rel_display_frame_ip_t.u4_size
791 != sizeof(ihevcd_cxa_rel_display_frame_ip_t))
792 && (ps_ip->s_ivd_rel_display_frame_ip_t.u4_size
793 != sizeof(ivd_rel_display_frame_ip_t)))
794 {
795 ps_op->s_ivd_rel_display_frame_op_t.u4_error_code |= 1
796 << IVD_UNSUPPORTEDPARAM;
797 ps_op->s_ivd_rel_display_frame_op_t.u4_error_code |=
798 IVD_IP_API_STRUCT_SIZE_INCORRECT;
799 return (IV_FAIL);
800 }
801
802 if((ps_op->s_ivd_rel_display_frame_op_t.u4_size
803 != sizeof(ihevcd_cxa_rel_display_frame_op_t))
804 && (ps_op->s_ivd_rel_display_frame_op_t.u4_size
805 != sizeof(ivd_rel_display_frame_op_t)))
806 {
807 ps_op->s_ivd_rel_display_frame_op_t.u4_error_code |= 1
808 << IVD_UNSUPPORTEDPARAM;
809 ps_op->s_ivd_rel_display_frame_op_t.u4_error_code |=
810 IVD_OP_API_STRUCT_SIZE_INCORRECT;
811 return (IV_FAIL);
812 }
813
814 }
815 break;
816
817 case IVD_CMD_SET_DISPLAY_FRAME:
818 {
819 ihevcd_cxa_set_display_frame_ip_t *ps_ip =
820 (ihevcd_cxa_set_display_frame_ip_t *)pv_api_ip;
821 ihevcd_cxa_set_display_frame_op_t *ps_op =
822 (ihevcd_cxa_set_display_frame_op_t *)pv_api_op;
823 UWORD32 j;
824
825 ps_op->s_ivd_set_display_frame_op_t.u4_error_code = 0;
826
827 if((ps_ip->s_ivd_set_display_frame_ip_t.u4_size
828 != sizeof(ihevcd_cxa_set_display_frame_ip_t))
829 && (ps_ip->s_ivd_set_display_frame_ip_t.u4_size
830 != sizeof(ivd_set_display_frame_ip_t)))
831 {
832 ps_op->s_ivd_set_display_frame_op_t.u4_error_code |= 1
833 << IVD_UNSUPPORTEDPARAM;
834 ps_op->s_ivd_set_display_frame_op_t.u4_error_code |=
835 IVD_IP_API_STRUCT_SIZE_INCORRECT;
836 return (IV_FAIL);
837 }
838
839 if((ps_op->s_ivd_set_display_frame_op_t.u4_size
840 != sizeof(ihevcd_cxa_set_display_frame_op_t))
841 && (ps_op->s_ivd_set_display_frame_op_t.u4_size
842 != sizeof(ivd_set_display_frame_op_t)))
843 {
844 ps_op->s_ivd_set_display_frame_op_t.u4_error_code |= 1
845 << IVD_UNSUPPORTEDPARAM;
846 ps_op->s_ivd_set_display_frame_op_t.u4_error_code |=
847 IVD_OP_API_STRUCT_SIZE_INCORRECT;
848 return (IV_FAIL);
849 }
850
851 if(ps_ip->s_ivd_set_display_frame_ip_t.num_disp_bufs == 0)
852 {
853 ps_op->s_ivd_set_display_frame_op_t.u4_error_code |= 1
854 << IVD_UNSUPPORTEDPARAM;
855 ps_op->s_ivd_set_display_frame_op_t.u4_error_code |=
856 IVD_DISP_FRM_ZERO_OP_BUFS;
857 return IV_FAIL;
858 }
859
860 for(j = 0; j < ps_ip->s_ivd_set_display_frame_ip_t.num_disp_bufs;
861 j++)
862 {
863 if(ps_ip->s_ivd_set_display_frame_ip_t.s_disp_buffer[j].u4_num_bufs
864 == 0)
865 {
866 ps_op->s_ivd_set_display_frame_op_t.u4_error_code |= 1
867 << IVD_UNSUPPORTEDPARAM;
868 ps_op->s_ivd_set_display_frame_op_t.u4_error_code |=
869 IVD_DISP_FRM_ZERO_OP_BUFS;
870 return IV_FAIL;
871 }
872
873 for(i = 0;
874 i
875 < (WORD32)ps_ip->s_ivd_set_display_frame_ip_t.s_disp_buffer[j].u4_num_bufs;
876 i++)
877 {
878 if(ps_ip->s_ivd_set_display_frame_ip_t.s_disp_buffer[j].pu1_bufs[i]
879 == NULL)
880 {
881 ps_op->s_ivd_set_display_frame_op_t.u4_error_code |= 1
882 << IVD_UNSUPPORTEDPARAM;
883 ps_op->s_ivd_set_display_frame_op_t.u4_error_code |=
884 IVD_DISP_FRM_OP_BUF_NULL;
885 return IV_FAIL;
886 }
887
888 if(ps_ip->s_ivd_set_display_frame_ip_t.s_disp_buffer[j].u4_min_out_buf_size[i]
889 == 0)
890 {
891 ps_op->s_ivd_set_display_frame_op_t.u4_error_code |= 1
892 << IVD_UNSUPPORTEDPARAM;
893 ps_op->s_ivd_set_display_frame_op_t.u4_error_code |=
894 IVD_DISP_FRM_ZERO_OP_BUF_SIZE;
895 return IV_FAIL;
896 }
897 }
898 }
899 }
900 break;
901
902 case IVD_CMD_VIDEO_DECODE:
903 {
904 ihevcd_cxa_video_decode_ip_t *ps_ip =
905 (ihevcd_cxa_video_decode_ip_t *)pv_api_ip;
906 ihevcd_cxa_video_decode_op_t *ps_op =
907 (ihevcd_cxa_video_decode_op_t *)pv_api_op;
908
909 DEBUG("The input bytes is: %d",
910 ps_ip->s_ivd_video_decode_ip_t.u4_num_Bytes);
911 ps_op->s_ivd_video_decode_op_t.u4_error_code = 0;
912
913 if(ps_ip->s_ivd_video_decode_ip_t.u4_size
914 != sizeof(ihevcd_cxa_video_decode_ip_t)
915 && ps_ip->s_ivd_video_decode_ip_t.u4_size
916 != offsetof(ivd_video_decode_ip_t,
917 s_out_buffer))
918 {
919 ps_op->s_ivd_video_decode_op_t.u4_error_code |= 1
920 << IVD_UNSUPPORTEDPARAM;
921 ps_op->s_ivd_video_decode_op_t.u4_error_code |=
922 IVD_IP_API_STRUCT_SIZE_INCORRECT;
923 return (IV_FAIL);
924 }
925
926 if(ps_op->s_ivd_video_decode_op_t.u4_size
927 != sizeof(ihevcd_cxa_video_decode_op_t)
928 && ps_op->s_ivd_video_decode_op_t.u4_size
929 != offsetof(ivd_video_decode_op_t,
930 u4_output_present))
931 {
932 ps_op->s_ivd_video_decode_op_t.u4_error_code |= 1
933 << IVD_UNSUPPORTEDPARAM;
934 ps_op->s_ivd_video_decode_op_t.u4_error_code |=
935 IVD_OP_API_STRUCT_SIZE_INCORRECT;
936 return (IV_FAIL);
937 }
938
939 }
940 break;
941
942 case IV_CMD_RETRIEVE_MEMREC:
943 {
944 ihevcd_cxa_retrieve_mem_rec_ip_t *ps_ip =
945 (ihevcd_cxa_retrieve_mem_rec_ip_t *)pv_api_ip;
946 ihevcd_cxa_retrieve_mem_rec_op_t *ps_op =
947 (ihevcd_cxa_retrieve_mem_rec_op_t *)pv_api_op;
948 iv_mem_rec_t *ps_mem_rec;
949
950 ps_op->s_ivd_retrieve_mem_rec_op_t.u4_error_code = 0;
951
952 if(ps_ip->s_ivd_retrieve_mem_rec_ip_t.u4_size
953 != sizeof(ihevcd_cxa_retrieve_mem_rec_ip_t))
954 {
955 ps_op->s_ivd_retrieve_mem_rec_op_t.u4_error_code |= 1
956 << IVD_UNSUPPORTEDPARAM;
957 ps_op->s_ivd_retrieve_mem_rec_op_t.u4_error_code |=
958 IVD_IP_API_STRUCT_SIZE_INCORRECT;
959 return (IV_FAIL);
960 }
961
962 if(ps_op->s_ivd_retrieve_mem_rec_op_t.u4_size
963 != sizeof(ihevcd_cxa_retrieve_mem_rec_op_t))
964 {
965 ps_op->s_ivd_retrieve_mem_rec_op_t.u4_error_code |= 1
966 << IVD_UNSUPPORTEDPARAM;
967 ps_op->s_ivd_retrieve_mem_rec_op_t.u4_error_code |=
968 IVD_OP_API_STRUCT_SIZE_INCORRECT;
969 return (IV_FAIL);
970 }
971
972 ps_mem_rec = ps_ip->s_ivd_retrieve_mem_rec_ip_t.pv_mem_rec_location;
973 /* check memrecords sizes are correct */
974 for(i = 0; i < MEM_REC_CNT; i++)
975 {
976 if(ps_mem_rec[i].u4_size != sizeof(iv_mem_rec_t))
977 {
978 ps_op->s_ivd_retrieve_mem_rec_op_t.u4_error_code |= 1
979 << IVD_UNSUPPORTEDPARAM;
980 ps_op->s_ivd_retrieve_mem_rec_op_t.u4_error_code |=
981 IVD_MEM_REC_STRUCT_SIZE_INCORRECT;
982 return IV_FAIL;
983 }
984 }
985 }
986 break;
987
988 case IVD_CMD_VIDEO_CTL:
989 {
990 UWORD32 *pu4_ptr_cmd;
991 UWORD32 sub_command;
992
993 pu4_ptr_cmd = (UWORD32 *)pv_api_ip;
994 pu4_ptr_cmd += 2;
995 sub_command = *pu4_ptr_cmd;
996
997 switch(sub_command)
998 {
999 case IVD_CMD_CTL_SETPARAMS:
1000 {
1001 ihevcd_cxa_ctl_set_config_ip_t *ps_ip;
1002 ihevcd_cxa_ctl_set_config_op_t *ps_op;
1003 ps_ip = (ihevcd_cxa_ctl_set_config_ip_t *)pv_api_ip;
1004 ps_op = (ihevcd_cxa_ctl_set_config_op_t *)pv_api_op;
1005
1006 if(ps_ip->s_ivd_ctl_set_config_ip_t.u4_size
1007 != sizeof(ihevcd_cxa_ctl_set_config_ip_t))
1008 {
1009 ps_op->s_ivd_ctl_set_config_op_t.u4_error_code |= 1
1010 << IVD_UNSUPPORTEDPARAM;
1011 ps_op->s_ivd_ctl_set_config_op_t.u4_error_code |=
1012 IVD_IP_API_STRUCT_SIZE_INCORRECT;
1013 return IV_FAIL;
1014 }
1015 }
1016 //no break; is needed here
1017 case IVD_CMD_CTL_SETDEFAULT:
1018 {
1019 ihevcd_cxa_ctl_set_config_op_t *ps_op;
1020 ps_op = (ihevcd_cxa_ctl_set_config_op_t *)pv_api_op;
1021 if(ps_op->s_ivd_ctl_set_config_op_t.u4_size
1022 != sizeof(ihevcd_cxa_ctl_set_config_op_t))
1023 {
1024 ps_op->s_ivd_ctl_set_config_op_t.u4_error_code |= 1
1025 << IVD_UNSUPPORTEDPARAM;
1026 ps_op->s_ivd_ctl_set_config_op_t.u4_error_code |=
1027 IVD_OP_API_STRUCT_SIZE_INCORRECT;
1028 return IV_FAIL;
1029 }
1030 }
1031 break;
1032
1033 case IVD_CMD_CTL_GETPARAMS:
1034 {
1035 ihevcd_cxa_ctl_getstatus_ip_t *ps_ip;
1036 ihevcd_cxa_ctl_getstatus_op_t *ps_op;
1037
1038 ps_ip = (ihevcd_cxa_ctl_getstatus_ip_t *)pv_api_ip;
1039 ps_op = (ihevcd_cxa_ctl_getstatus_op_t *)pv_api_op;
1040 if(ps_ip->s_ivd_ctl_getstatus_ip_t.u4_size
1041 != sizeof(ihevcd_cxa_ctl_getstatus_ip_t))
1042 {
1043 ps_op->s_ivd_ctl_getstatus_op_t.u4_error_code |= 1
1044 << IVD_UNSUPPORTEDPARAM;
1045 ps_op->s_ivd_ctl_getstatus_op_t.u4_error_code |=
1046 IVD_IP_API_STRUCT_SIZE_INCORRECT;
1047 return IV_FAIL;
1048 }
1049 if((ps_op->s_ivd_ctl_getstatus_op_t.u4_size
1050 != sizeof(ihevcd_cxa_ctl_getstatus_op_t)) &&
1051 (ps_op->s_ivd_ctl_getstatus_op_t.u4_size
1052 != sizeof(ivd_ctl_getstatus_op_t)))
1053 {
1054 ps_op->s_ivd_ctl_getstatus_op_t.u4_error_code |= 1
1055 << IVD_UNSUPPORTEDPARAM;
1056 ps_op->s_ivd_ctl_getstatus_op_t.u4_error_code |=
1057 IVD_OP_API_STRUCT_SIZE_INCORRECT;
1058 return IV_FAIL;
1059 }
1060 }
1061 break;
1062
1063 case IVD_CMD_CTL_GETBUFINFO:
1064 {
1065 ihevcd_cxa_ctl_getbufinfo_ip_t *ps_ip;
1066 ihevcd_cxa_ctl_getbufinfo_op_t *ps_op;
1067 ps_ip = (ihevcd_cxa_ctl_getbufinfo_ip_t *)pv_api_ip;
1068 ps_op = (ihevcd_cxa_ctl_getbufinfo_op_t *)pv_api_op;
1069
1070 if(ps_ip->s_ivd_ctl_getbufinfo_ip_t.u4_size
1071 != sizeof(ihevcd_cxa_ctl_getbufinfo_ip_t))
1072 {
1073 ps_op->s_ivd_ctl_getbufinfo_op_t.u4_error_code |= 1
1074 << IVD_UNSUPPORTEDPARAM;
1075 ps_op->s_ivd_ctl_getbufinfo_op_t.u4_error_code |=
1076 IVD_IP_API_STRUCT_SIZE_INCORRECT;
1077 return IV_FAIL;
1078 }
1079 if(ps_op->s_ivd_ctl_getbufinfo_op_t.u4_size
1080 != sizeof(ihevcd_cxa_ctl_getbufinfo_op_t))
1081 {
1082 ps_op->s_ivd_ctl_getbufinfo_op_t.u4_error_code |= 1
1083 << IVD_UNSUPPORTEDPARAM;
1084 ps_op->s_ivd_ctl_getbufinfo_op_t.u4_error_code |=
1085 IVD_OP_API_STRUCT_SIZE_INCORRECT;
1086 return IV_FAIL;
1087 }
1088 }
1089 break;
1090
1091 case IVD_CMD_CTL_GETVERSION:
1092 {
1093 ihevcd_cxa_ctl_getversioninfo_ip_t *ps_ip;
1094 ihevcd_cxa_ctl_getversioninfo_op_t *ps_op;
1095 ps_ip = (ihevcd_cxa_ctl_getversioninfo_ip_t *)pv_api_ip;
1096 ps_op = (ihevcd_cxa_ctl_getversioninfo_op_t *)pv_api_op;
1097 if(ps_ip->s_ivd_ctl_getversioninfo_ip_t.u4_size
1098 != sizeof(ihevcd_cxa_ctl_getversioninfo_ip_t))
1099 {
1100 ps_op->s_ivd_ctl_getversioninfo_op_t.u4_error_code |= 1
1101 << IVD_UNSUPPORTEDPARAM;
1102 ps_op->s_ivd_ctl_getversioninfo_op_t.u4_error_code |=
1103 IVD_IP_API_STRUCT_SIZE_INCORRECT;
1104 return IV_FAIL;
1105 }
1106 if(ps_op->s_ivd_ctl_getversioninfo_op_t.u4_size
1107 != sizeof(ihevcd_cxa_ctl_getversioninfo_op_t))
1108 {
1109 ps_op->s_ivd_ctl_getversioninfo_op_t.u4_error_code |= 1
1110 << IVD_UNSUPPORTEDPARAM;
1111 ps_op->s_ivd_ctl_getversioninfo_op_t.u4_error_code |=
1112 IVD_OP_API_STRUCT_SIZE_INCORRECT;
1113 return IV_FAIL;
1114 }
1115 }
1116 break;
1117
1118 case IVD_CMD_CTL_FLUSH:
1119 {
1120 ihevcd_cxa_ctl_flush_ip_t *ps_ip;
1121 ihevcd_cxa_ctl_flush_op_t *ps_op;
1122 ps_ip = (ihevcd_cxa_ctl_flush_ip_t *)pv_api_ip;
1123 ps_op = (ihevcd_cxa_ctl_flush_op_t *)pv_api_op;
1124 if(ps_ip->s_ivd_ctl_flush_ip_t.u4_size
1125 != sizeof(ihevcd_cxa_ctl_flush_ip_t))
1126 {
1127 ps_op->s_ivd_ctl_flush_op_t.u4_error_code |= 1
1128 << IVD_UNSUPPORTEDPARAM;
1129 ps_op->s_ivd_ctl_flush_op_t.u4_error_code |=
1130 IVD_IP_API_STRUCT_SIZE_INCORRECT;
1131 return IV_FAIL;
1132 }
1133 if(ps_op->s_ivd_ctl_flush_op_t.u4_size
1134 != sizeof(ihevcd_cxa_ctl_flush_op_t))
1135 {
1136 ps_op->s_ivd_ctl_flush_op_t.u4_error_code |= 1
1137 << IVD_UNSUPPORTEDPARAM;
1138 ps_op->s_ivd_ctl_flush_op_t.u4_error_code |=
1139 IVD_OP_API_STRUCT_SIZE_INCORRECT;
1140 return IV_FAIL;
1141 }
1142 }
1143 break;
1144
1145 case IVD_CMD_CTL_RESET:
1146 {
1147 ihevcd_cxa_ctl_reset_ip_t *ps_ip;
1148 ihevcd_cxa_ctl_reset_op_t *ps_op;
1149 ps_ip = (ihevcd_cxa_ctl_reset_ip_t *)pv_api_ip;
1150 ps_op = (ihevcd_cxa_ctl_reset_op_t *)pv_api_op;
1151 if(ps_ip->s_ivd_ctl_reset_ip_t.u4_size
1152 != sizeof(ihevcd_cxa_ctl_reset_ip_t))
1153 {
1154 ps_op->s_ivd_ctl_reset_op_t.u4_error_code |= 1
1155 << IVD_UNSUPPORTEDPARAM;
1156 ps_op->s_ivd_ctl_reset_op_t.u4_error_code |=
1157 IVD_IP_API_STRUCT_SIZE_INCORRECT;
1158 return IV_FAIL;
1159 }
1160 if(ps_op->s_ivd_ctl_reset_op_t.u4_size
1161 != sizeof(ihevcd_cxa_ctl_reset_op_t))
1162 {
1163 ps_op->s_ivd_ctl_reset_op_t.u4_error_code |= 1
1164 << IVD_UNSUPPORTEDPARAM;
1165 ps_op->s_ivd_ctl_reset_op_t.u4_error_code |=
1166 IVD_OP_API_STRUCT_SIZE_INCORRECT;
1167 return IV_FAIL;
1168 }
1169 }
1170 break;
1171 case IHEVCD_CXA_CMD_CTL_DEGRADE:
1172 {
1173 ihevcd_cxa_ctl_degrade_ip_t *ps_ip;
1174 ihevcd_cxa_ctl_degrade_op_t *ps_op;
1175
1176 ps_ip = (ihevcd_cxa_ctl_degrade_ip_t *)pv_api_ip;
1177 ps_op = (ihevcd_cxa_ctl_degrade_op_t *)pv_api_op;
1178
1179 if(ps_ip->u4_size
1180 != sizeof(ihevcd_cxa_ctl_degrade_ip_t))
1181 {
1182 ps_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM;
1183 ps_op->u4_error_code |=
1184 IVD_IP_API_STRUCT_SIZE_INCORRECT;
1185 return IV_FAIL;
1186 }
1187
1188 if(ps_op->u4_size
1189 != sizeof(ihevcd_cxa_ctl_degrade_op_t))
1190 {
1191 ps_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM;
1192 ps_op->u4_error_code |=
1193 IVD_OP_API_STRUCT_SIZE_INCORRECT;
1194 return IV_FAIL;
1195 }
1196
1197 if((ps_ip->i4_degrade_pics < 0) ||
1198 (ps_ip->i4_degrade_pics > 4) ||
1199 (ps_ip->i4_nondegrade_interval < 0) ||
1200 (ps_ip->i4_degrade_type < 0) ||
1201 (ps_ip->i4_degrade_type > 15))
1202 {
1203 ps_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM;
1204 return IV_FAIL;
1205 }
1206
1207 break;
1208 }
1209
1210 case IHEVCD_CXA_CMD_CTL_GET_BUFFER_DIMENSIONS:
1211 {
1212 ihevcd_cxa_ctl_get_frame_dimensions_ip_t *ps_ip;
1213 ihevcd_cxa_ctl_get_frame_dimensions_op_t *ps_op;
1214
1215 ps_ip =
1216 (ihevcd_cxa_ctl_get_frame_dimensions_ip_t *)pv_api_ip;
1217 ps_op =
1218 (ihevcd_cxa_ctl_get_frame_dimensions_op_t *)pv_api_op;
1219
1220 if(ps_ip->u4_size
1221 != sizeof(ihevcd_cxa_ctl_get_frame_dimensions_ip_t))
1222 {
1223 ps_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM;
1224 ps_op->u4_error_code |=
1225 IVD_IP_API_STRUCT_SIZE_INCORRECT;
1226 return IV_FAIL;
1227 }
1228
1229 if(ps_op->u4_size
1230 != sizeof(ihevcd_cxa_ctl_get_frame_dimensions_op_t))
1231 {
1232 ps_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM;
1233 ps_op->u4_error_code |=
1234 IVD_OP_API_STRUCT_SIZE_INCORRECT;
1235 return IV_FAIL;
1236 }
1237
1238 break;
1239 }
1240
1241 case IHEVCD_CXA_CMD_CTL_GET_VUI_PARAMS:
1242 {
1243 ihevcd_cxa_ctl_get_vui_params_ip_t *ps_ip;
1244 ihevcd_cxa_ctl_get_vui_params_op_t *ps_op;
1245
1246 ps_ip =
1247 (ihevcd_cxa_ctl_get_vui_params_ip_t *)pv_api_ip;
1248 ps_op =
1249 (ihevcd_cxa_ctl_get_vui_params_op_t *)pv_api_op;
1250
1251 if(ps_ip->u4_size
1252 != sizeof(ihevcd_cxa_ctl_get_vui_params_ip_t))
1253 {
1254 ps_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM;
1255 ps_op->u4_error_code |=
1256 IVD_IP_API_STRUCT_SIZE_INCORRECT;
1257 return IV_FAIL;
1258 }
1259
1260 if(ps_op->u4_size
1261 != sizeof(ihevcd_cxa_ctl_get_vui_params_op_t))
1262 {
1263 ps_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM;
1264 ps_op->u4_error_code |=
1265 IVD_OP_API_STRUCT_SIZE_INCORRECT;
1266 return IV_FAIL;
1267 }
1268
1269 break;
1270 }
1271 case IHEVCD_CXA_CMD_CTL_SET_NUM_CORES:
1272 {
1273 ihevcd_cxa_ctl_set_num_cores_ip_t *ps_ip;
1274 ihevcd_cxa_ctl_set_num_cores_op_t *ps_op;
1275
1276 ps_ip = (ihevcd_cxa_ctl_set_num_cores_ip_t *)pv_api_ip;
1277 ps_op = (ihevcd_cxa_ctl_set_num_cores_op_t *)pv_api_op;
1278
1279 if(ps_ip->u4_size
1280 != sizeof(ihevcd_cxa_ctl_set_num_cores_ip_t))
1281 {
1282 ps_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM;
1283 ps_op->u4_error_code |=
1284 IVD_IP_API_STRUCT_SIZE_INCORRECT;
1285 return IV_FAIL;
1286 }
1287
1288 if(ps_op->u4_size
1289 != sizeof(ihevcd_cxa_ctl_set_num_cores_op_t))
1290 {
1291 ps_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM;
1292 ps_op->u4_error_code |=
1293 IVD_OP_API_STRUCT_SIZE_INCORRECT;
1294 return IV_FAIL;
1295 }
1296
1297 #ifdef MULTICORE
1298 if((ps_ip->u4_num_cores < 1) || (ps_ip->u4_num_cores > MAX_NUM_CORES))
1299 #else
1300 if(ps_ip->u4_num_cores != 1)
1301 #endif
1302 {
1303 ps_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM;
1304 return IV_FAIL;
1305 }
1306 break;
1307 }
1308 case IHEVCD_CXA_CMD_CTL_SET_PROCESSOR:
1309 {
1310 ihevcd_cxa_ctl_set_processor_ip_t *ps_ip;
1311 ihevcd_cxa_ctl_set_processor_op_t *ps_op;
1312
1313 ps_ip = (ihevcd_cxa_ctl_set_processor_ip_t *)pv_api_ip;
1314 ps_op = (ihevcd_cxa_ctl_set_processor_op_t *)pv_api_op;
1315
1316 if(ps_ip->u4_size
1317 != sizeof(ihevcd_cxa_ctl_set_processor_ip_t))
1318 {
1319 ps_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM;
1320 ps_op->u4_error_code |=
1321 IVD_IP_API_STRUCT_SIZE_INCORRECT;
1322 return IV_FAIL;
1323 }
1324
1325 if(ps_op->u4_size
1326 != sizeof(ihevcd_cxa_ctl_set_processor_op_t))
1327 {
1328 ps_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM;
1329 ps_op->u4_error_code |=
1330 IVD_OP_API_STRUCT_SIZE_INCORRECT;
1331 return IV_FAIL;
1332 }
1333
1334 break;
1335 }
1336 default:
1337 *(pu4_api_op + 1) |= 1 << IVD_UNSUPPORTEDPARAM;
1338 *(pu4_api_op + 1) |= IVD_UNSUPPORTED_API_CMD;
1339 return IV_FAIL;
1340 }
1341 }
1342 break;
1343 default:
1344 *(pu4_api_op + 1) |= 1 << IVD_UNSUPPORTEDPARAM;
1345 *(pu4_api_op + 1) |= IVD_UNSUPPORTED_API_CMD;
1346 return IV_FAIL;
1347 }
1348
1349 return IV_SUCCESS;
1350 }
1351
1352
1353 /**
1354 *******************************************************************************
1355 *
1356 * @brief
1357 * Sets default dynamic parameters
1358 *
1359 * @par Description:
1360 * Sets default dynamic parameters. Will be called in ihevcd_init() to ensure
1361 * that even if set_params is not called, codec continues to work
1362 *
1363 * @param[in] ps_codec_obj
1364 * Pointer to codec object at API level
1365 *
1366 * @param[in] pv_api_ip
1367 * Pointer to input argument structure
1368 *
1369 * @param[out] pv_api_op
1370 * Pointer to output argument structure
1371 *
1372 * @returns Status
1373 *
1374 * @remarks
1375 *
1376 *
1377 *******************************************************************************
1378 */
ihevcd_set_default_params(codec_t * ps_codec)1379 WORD32 ihevcd_set_default_params(codec_t *ps_codec)
1380 {
1381
1382 WORD32 ret = IV_SUCCESS;
1383
1384 ps_codec->e_pic_skip_mode = IVD_SKIP_NONE;
1385 ps_codec->i4_strd = 0;
1386 ps_codec->i4_disp_strd = 0;
1387 ps_codec->i4_header_mode = 0;
1388 ps_codec->e_pic_out_order = IVD_DISPLAY_FRAME_OUT;
1389 return ret;
1390 }
1391
ihevcd_update_function_ptr(codec_t * ps_codec)1392 void ihevcd_update_function_ptr(codec_t *ps_codec)
1393 {
1394
1395 /* Init inter pred function array */
1396 ps_codec->apf_inter_pred[0] = NULL;
1397 ps_codec->apf_inter_pred[1] = (pf_inter_pred)ps_codec->s_func_selector.ihevc_inter_pred_luma_copy_fptr;
1398 ps_codec->apf_inter_pred[2] = (pf_inter_pred)ps_codec->s_func_selector.ihevc_inter_pred_luma_vert_fptr;
1399 ps_codec->apf_inter_pred[3] = (pf_inter_pred)ps_codec->s_func_selector.ihevc_inter_pred_luma_horz_fptr;
1400 ps_codec->apf_inter_pred[4] = (pf_inter_pred)ps_codec->s_func_selector.ihevc_inter_pred_luma_horz_w16out_fptr;
1401 ps_codec->apf_inter_pred[5] = (pf_inter_pred)ps_codec->s_func_selector.ihevc_inter_pred_luma_copy_w16out_fptr;
1402 ps_codec->apf_inter_pred[6] = (pf_inter_pred)ps_codec->s_func_selector.ihevc_inter_pred_luma_vert_w16out_fptr;
1403 ps_codec->apf_inter_pred[7] = (pf_inter_pred)ps_codec->s_func_selector.ihevc_inter_pred_luma_horz_w16out_fptr;
1404 ps_codec->apf_inter_pred[8] = (pf_inter_pred)ps_codec->s_func_selector.ihevc_inter_pred_luma_horz_w16out_fptr;
1405 ps_codec->apf_inter_pred[9] = (pf_inter_pred)ps_codec->s_func_selector.ihevc_inter_pred_luma_vert_w16inp_fptr;
1406 ps_codec->apf_inter_pred[10] = (pf_inter_pred)ps_codec->s_func_selector.ihevc_inter_pred_luma_vert_w16inp_w16out_fptr;
1407 ps_codec->apf_inter_pred[11] = NULL;
1408 ps_codec->apf_inter_pred[12] = (pf_inter_pred)ps_codec->s_func_selector.ihevc_inter_pred_chroma_copy_fptr;
1409 ps_codec->apf_inter_pred[13] = (pf_inter_pred)ps_codec->s_func_selector.ihevc_inter_pred_chroma_vert_fptr;
1410 ps_codec->apf_inter_pred[14] = (pf_inter_pred)ps_codec->s_func_selector.ihevc_inter_pred_chroma_horz_fptr;
1411 ps_codec->apf_inter_pred[15] = (pf_inter_pred)ps_codec->s_func_selector.ihevc_inter_pred_chroma_horz_w16out_fptr;
1412 ps_codec->apf_inter_pred[16] = (pf_inter_pred)ps_codec->s_func_selector.ihevc_inter_pred_chroma_copy_w16out_fptr;
1413 ps_codec->apf_inter_pred[17] = (pf_inter_pred)ps_codec->s_func_selector.ihevc_inter_pred_chroma_vert_w16out_fptr;
1414 ps_codec->apf_inter_pred[18] = (pf_inter_pred)ps_codec->s_func_selector.ihevc_inter_pred_chroma_horz_w16out_fptr;
1415 ps_codec->apf_inter_pred[19] = (pf_inter_pred)ps_codec->s_func_selector.ihevc_inter_pred_chroma_horz_w16out_fptr;
1416 ps_codec->apf_inter_pred[20] = (pf_inter_pred)ps_codec->s_func_selector.ihevc_inter_pred_chroma_vert_w16inp_fptr;
1417 ps_codec->apf_inter_pred[21] = (pf_inter_pred)ps_codec->s_func_selector.ihevc_inter_pred_chroma_vert_w16inp_w16out_fptr;
1418
1419 /* Init intra pred function array */
1420 ps_codec->apf_intra_pred_luma[0] = (pf_intra_pred)NULL;
1421 ps_codec->apf_intra_pred_luma[1] = (pf_intra_pred)ps_codec->s_func_selector.ihevc_intra_pred_luma_planar_fptr;
1422 ps_codec->apf_intra_pred_luma[2] = (pf_intra_pred)ps_codec->s_func_selector.ihevc_intra_pred_luma_dc_fptr;
1423 ps_codec->apf_intra_pred_luma[3] = (pf_intra_pred)ps_codec->s_func_selector.ihevc_intra_pred_luma_mode2_fptr;
1424 ps_codec->apf_intra_pred_luma[4] = (pf_intra_pred)ps_codec->s_func_selector.ihevc_intra_pred_luma_mode_3_to_9_fptr;
1425 ps_codec->apf_intra_pred_luma[5] = (pf_intra_pred)ps_codec->s_func_selector.ihevc_intra_pred_luma_horz_fptr;
1426 ps_codec->apf_intra_pred_luma[6] = (pf_intra_pred)ps_codec->s_func_selector.ihevc_intra_pred_luma_mode_11_to_17_fptr;
1427 ps_codec->apf_intra_pred_luma[7] = (pf_intra_pred)ps_codec->s_func_selector.ihevc_intra_pred_luma_mode_18_34_fptr;
1428 ps_codec->apf_intra_pred_luma[8] = (pf_intra_pred)ps_codec->s_func_selector.ihevc_intra_pred_luma_mode_19_to_25_fptr;
1429 ps_codec->apf_intra_pred_luma[9] = (pf_intra_pred)ps_codec->s_func_selector.ihevc_intra_pred_luma_ver_fptr;
1430 ps_codec->apf_intra_pred_luma[10] = (pf_intra_pred)ps_codec->s_func_selector.ihevc_intra_pred_luma_mode_27_to_33_fptr;
1431
1432 ps_codec->apf_intra_pred_chroma[0] = (pf_intra_pred)NULL;
1433 ps_codec->apf_intra_pred_chroma[1] = (pf_intra_pred)ps_codec->s_func_selector.ihevc_intra_pred_chroma_planar_fptr;
1434 ps_codec->apf_intra_pred_chroma[2] = (pf_intra_pred)ps_codec->s_func_selector.ihevc_intra_pred_chroma_dc_fptr;
1435 ps_codec->apf_intra_pred_chroma[3] = (pf_intra_pred)ps_codec->s_func_selector.ihevc_intra_pred_chroma_mode2_fptr;
1436 ps_codec->apf_intra_pred_chroma[4] = (pf_intra_pred)ps_codec->s_func_selector.ihevc_intra_pred_chroma_mode_3_to_9_fptr;
1437 ps_codec->apf_intra_pred_chroma[5] = (pf_intra_pred)ps_codec->s_func_selector.ihevc_intra_pred_chroma_horz_fptr;
1438 ps_codec->apf_intra_pred_chroma[6] = (pf_intra_pred)ps_codec->s_func_selector.ihevc_intra_pred_chroma_mode_11_to_17_fptr;
1439 ps_codec->apf_intra_pred_chroma[7] = (pf_intra_pred)ps_codec->s_func_selector.ihevc_intra_pred_chroma_mode_18_34_fptr;
1440 ps_codec->apf_intra_pred_chroma[8] = (pf_intra_pred)ps_codec->s_func_selector.ihevc_intra_pred_chroma_mode_19_to_25_fptr;
1441 ps_codec->apf_intra_pred_chroma[9] = (pf_intra_pred)ps_codec->s_func_selector.ihevc_intra_pred_chroma_ver_fptr;
1442 ps_codec->apf_intra_pred_chroma[10] = (pf_intra_pred)ps_codec->s_func_selector.ihevc_intra_pred_chroma_mode_27_to_33_fptr;
1443
1444 /* Init itrans_recon function array */
1445 ps_codec->apf_itrans_recon[0] = (pf_itrans_recon)ps_codec->s_func_selector.ihevc_itrans_recon_4x4_ttype1_fptr;
1446 ps_codec->apf_itrans_recon[1] = (pf_itrans_recon)ps_codec->s_func_selector.ihevc_itrans_recon_4x4_fptr;
1447 ps_codec->apf_itrans_recon[2] = (pf_itrans_recon)ps_codec->s_func_selector.ihevc_itrans_recon_8x8_fptr;
1448 ps_codec->apf_itrans_recon[3] = (pf_itrans_recon)ps_codec->s_func_selector.ihevc_itrans_recon_16x16_fptr;
1449 ps_codec->apf_itrans_recon[4] = (pf_itrans_recon)ps_codec->s_func_selector.ihevc_itrans_recon_32x32_fptr;
1450 ps_codec->apf_itrans_recon[5] = (pf_itrans_recon)ps_codec->s_func_selector.ihevc_chroma_itrans_recon_4x4_fptr;
1451 ps_codec->apf_itrans_recon[6] = (pf_itrans_recon)ps_codec->s_func_selector.ihevc_chroma_itrans_recon_8x8_fptr;
1452 ps_codec->apf_itrans_recon[7] = (pf_itrans_recon)ps_codec->s_func_selector.ihevc_chroma_itrans_recon_16x16_fptr;
1453
1454 /* Init recon function array */
1455 ps_codec->apf_recon[0] = (pf_recon)ps_codec->s_func_selector.ihevc_recon_4x4_ttype1_fptr;
1456 ps_codec->apf_recon[1] = (pf_recon)ps_codec->s_func_selector.ihevc_recon_4x4_fptr;
1457 ps_codec->apf_recon[2] = (pf_recon)ps_codec->s_func_selector.ihevc_recon_8x8_fptr;
1458 ps_codec->apf_recon[3] = (pf_recon)ps_codec->s_func_selector.ihevc_recon_16x16_fptr;
1459 ps_codec->apf_recon[4] = (pf_recon)ps_codec->s_func_selector.ihevc_recon_32x32_fptr;
1460 ps_codec->apf_recon[5] = (pf_recon)ps_codec->s_func_selector.ihevc_chroma_recon_4x4_fptr;
1461 ps_codec->apf_recon[6] = (pf_recon)ps_codec->s_func_selector.ihevc_chroma_recon_8x8_fptr;
1462 ps_codec->apf_recon[7] = (pf_recon)ps_codec->s_func_selector.ihevc_chroma_recon_16x16_fptr;
1463
1464 /* Init itrans_recon_dc function array */
1465 ps_codec->apf_itrans_recon_dc[0] = (pf_itrans_recon_dc)ps_codec->s_func_selector.ihevcd_itrans_recon_dc_luma_fptr;
1466 ps_codec->apf_itrans_recon_dc[1] = (pf_itrans_recon_dc)ps_codec->s_func_selector.ihevcd_itrans_recon_dc_chroma_fptr;
1467
1468 /* Init sao function array */
1469 ps_codec->apf_sao_luma[0] = (pf_sao_luma)ps_codec->s_func_selector.ihevc_sao_edge_offset_class0_fptr;
1470 ps_codec->apf_sao_luma[1] = (pf_sao_luma)ps_codec->s_func_selector.ihevc_sao_edge_offset_class1_fptr;
1471 ps_codec->apf_sao_luma[2] = (pf_sao_luma)ps_codec->s_func_selector.ihevc_sao_edge_offset_class2_fptr;
1472 ps_codec->apf_sao_luma[3] = (pf_sao_luma)ps_codec->s_func_selector.ihevc_sao_edge_offset_class3_fptr;
1473
1474 ps_codec->apf_sao_chroma[0] = (pf_sao_chroma)ps_codec->s_func_selector.ihevc_sao_edge_offset_class0_chroma_fptr;
1475 ps_codec->apf_sao_chroma[1] = (pf_sao_chroma)ps_codec->s_func_selector.ihevc_sao_edge_offset_class1_chroma_fptr;
1476 ps_codec->apf_sao_chroma[2] = (pf_sao_chroma)ps_codec->s_func_selector.ihevc_sao_edge_offset_class2_chroma_fptr;
1477 ps_codec->apf_sao_chroma[3] = (pf_sao_chroma)ps_codec->s_func_selector.ihevc_sao_edge_offset_class3_chroma_fptr;
1478 }
1479 /**
1480 *******************************************************************************
1481 *
1482 * @brief
1483 * Initialize the context. This will be called by init_mem_rec and during
1484 * reset
1485 *
1486 * @par Description:
1487 * Initializes the context
1488 *
1489 * @param[in] ps_codec
1490 * Codec context pointer
1491 *
1492 * @returns Status
1493 *
1494 * @remarks
1495 *
1496 *
1497 *******************************************************************************
1498 */
ihevcd_init(codec_t * ps_codec)1499 WORD32 ihevcd_init(codec_t *ps_codec)
1500 {
1501 WORD32 status = IV_SUCCESS;
1502 WORD32 i;
1503
1504
1505 ps_codec->i4_num_disp_bufs = 1;
1506 ps_codec->i4_flush_mode = 0;
1507
1508 ps_codec->i4_ht = ps_codec->i4_disp_ht = ps_codec->i4_max_ht;
1509 ps_codec->i4_wd = ps_codec->i4_disp_wd = ps_codec->i4_max_wd;
1510 ps_codec->i4_strd = 0;
1511 ps_codec->i4_disp_strd = 0;
1512 ps_codec->i4_num_cores = 1;
1513
1514 ps_codec->u4_pic_cnt = 0;
1515 ps_codec->u4_disp_cnt = 0;
1516
1517 ps_codec->i4_header_mode = 0;
1518 ps_codec->i4_header_in_slice_mode = 0;
1519 ps_codec->i4_sps_done = 0;
1520 ps_codec->i4_pps_done = 0;
1521 ps_codec->i4_init_done = 1;
1522 ps_codec->i4_first_pic_done = 0;
1523 ps_codec->s_parse.i4_first_pic_init = 0;
1524 ps_codec->i4_error_code = 0;
1525 ps_codec->i4_reset_flag = 0;
1526
1527 ps_codec->i4_prev_poc_msb = 0;
1528 ps_codec->i4_prev_poc_lsb = -1;
1529 ps_codec->i4_max_prev_poc_lsb = -1;
1530 ps_codec->s_parse.i4_abs_pic_order_cnt = -1;
1531
1532 /* Set ref chroma format by default to 420SP UV interleaved */
1533 ps_codec->e_ref_chroma_fmt = IV_YUV_420SP_UV;
1534
1535 /* If the codec is in shared mode and required format is 420 SP VU interleaved then change
1536 * reference buffers chroma format
1537 */
1538 if(IV_YUV_420SP_VU == ps_codec->e_chroma_fmt)
1539 {
1540 ps_codec->e_ref_chroma_fmt = IV_YUV_420SP_VU;
1541 }
1542
1543
1544
1545 ps_codec->i4_disable_deblk_pic = 0;
1546
1547 ps_codec->i4_degrade_pic_cnt = 0;
1548 ps_codec->i4_degrade_pics = 0;
1549 ps_codec->i4_degrade_type = 0;
1550 ps_codec->i4_disable_sao_pic = 0;
1551 ps_codec->i4_fullpel_inter_pred = 0;
1552 ps_codec->u4_enable_fmt_conv_ahead = 0;
1553
1554 {
1555 sps_t *ps_sps = ps_codec->ps_sps_base;
1556 pps_t *ps_pps = ps_codec->ps_pps_base;
1557
1558 for(i = 0; i < MAX_SPS_CNT; i++)
1559 {
1560 ps_sps->i1_sps_valid = 0;
1561 ps_sps++;
1562 }
1563
1564 for(i = 0; i < MAX_PPS_CNT; i++)
1565 {
1566 ps_pps->i1_pps_valid = 0;
1567 ps_pps++;
1568 }
1569 }
1570
1571 ihevcd_set_default_params(ps_codec);
1572 ps_codec->pv_proc_jobq = ihevcd_jobq_init(ps_codec->pv_proc_jobq_buf, ps_codec->i4_proc_jobq_buf_size);
1573 RETURN_IF((ps_codec->pv_proc_jobq == NULL), IV_FAIL);
1574
1575 /* Update the jobq context to all the threads */
1576 ps_codec->s_parse.pv_proc_jobq = ps_codec->pv_proc_jobq;
1577 for(i = 0; i < MAX_PROCESS_THREADS; i++)
1578 {
1579 ps_codec->as_process[i].pv_proc_jobq = ps_codec->pv_proc_jobq;
1580 ps_codec->as_process[i].i4_id = i;
1581 ps_codec->as_process[i].ps_codec = ps_codec;
1582
1583 /* Set the following to zero assuming it is a single core solution
1584 * When threads are launched these will be set appropriately
1585 */
1586 ps_codec->as_process[i].i4_check_parse_status = 0;
1587 ps_codec->as_process[i].i4_check_proc_status = 0;
1588 }
1589 /* Initialize MV Bank buffer manager */
1590 ihevc_buf_mgr_init((buf_mgr_t *)ps_codec->pv_mv_buf_mgr);
1591
1592 /* Initialize Picture buffer manager */
1593 ihevc_buf_mgr_init((buf_mgr_t *)ps_codec->pv_pic_buf_mgr);
1594
1595 ps_codec->ps_pic_buf = (pic_buf_t *)ps_codec->pv_pic_buf_base;
1596
1597 memset(ps_codec->ps_pic_buf, 0, BUF_MGR_MAX_CNT * sizeof(pic_buf_t));
1598
1599
1600
1601 /* Initialize display buffer manager */
1602 ihevc_disp_mgr_init((disp_mgr_t *)ps_codec->pv_disp_buf_mgr);
1603
1604 /* Initialize dpb manager */
1605 ihevc_dpb_mgr_init((dpb_mgr_t *)ps_codec->pv_dpb_mgr);
1606
1607 ps_codec->e_processor_soc = SOC_GENERIC;
1608 /* The following can be over-ridden using soc parameter as a hack */
1609 ps_codec->u4_nctb = 0x7FFFFFFF;
1610 ihevcd_init_arch(ps_codec);
1611
1612 ihevcd_init_function_ptr(ps_codec);
1613
1614 ihevcd_update_function_ptr(ps_codec);
1615
1616 return status;
1617 }
1618
1619 /**
1620 *******************************************************************************
1621 *
1622 * @brief
1623 * Gets number of memory records required by the codec
1624 *
1625 * @par Description:
1626 * Gets codec mem record requirements and adds concealment modules
1627 * requirements
1628 *
1629 * @param[in] pv_api_ip
1630 * Pointer to input argument structure
1631 *
1632 * @param[out] pv_api_op
1633 * Pointer to output argument structure
1634 *
1635 * @returns Status
1636 *
1637 * @remarks
1638 *
1639 *
1640 *******************************************************************************
1641 */
ihevcd_get_num_rec(void * pv_api_ip,void * pv_api_op)1642 WORD32 ihevcd_get_num_rec(void *pv_api_ip, void *pv_api_op)
1643 {
1644
1645 iv_num_mem_rec_op_t *ps_mem_q_op;
1646
1647 UNUSED(pv_api_ip);
1648 ps_mem_q_op = (iv_num_mem_rec_op_t *)pv_api_op;
1649 ps_mem_q_op->u4_num_mem_rec = MEM_REC_CNT;
1650 DEBUG("Get num mem records without concealment %d\n",
1651 ps_mem_q_op->u4_num_mem_rec);
1652 #ifdef APPLY_CONCEALMENT
1653 {
1654 IV_API_CALL_STATUS_T status;
1655 icncl_num_mem_rec_ip_t cncl_mem_ip;
1656 icncl_num_mem_rec_op_t cncl_mem_op;
1657
1658 cncl_mem_ip.s_ivd_num_rec_ip_t.e_cmd = IV_CMD_GET_NUM_MEM_REC;
1659 cncl_mem_ip.s_ivd_num_rec_ip_t.u4_size = sizeof(icncl_num_mem_rec_ip_t);
1660
1661 status = icncl_api_function(NULL, (void *)&cncl_mem_ip, (void *)&cncl_mem_op);
1662
1663 if(status == IV_SUCCESS)
1664 {
1665 /* Add the concealment library's memory requirements */
1666 ps_mem_q_op->u4_num_mem_rec += cncl_mem_op.s_ivd_num_mem_rec_op_t.u4_num_mem_rec;
1667 DEBUG("Get num mem records %d\n", ps_mem_q_op->u4_num_mem_rec);
1668 return status; /* Nothing else to do, return */
1669 }
1670 else
1671 {
1672 /*
1673 * Something went wrong with the concealment library call.
1674 */
1675 DEBUG("ERROR: Get num mem records %d\n", ps_mem_q_op->u4_num_mem_rec);
1676 return status;
1677 }
1678
1679 }
1680 #endif //APPLY_CONCEALMENT
1681
1682
1683 return IV_SUCCESS;
1684
1685 }
1686
1687 /**
1688 *******************************************************************************
1689 *
1690 * @brief
1691 * Fills memory requirements of the codec
1692 *
1693 * @par Description:
1694 * Gets codec mem record requirements and adds concealment modules
1695 * requirements
1696 *
1697 * @param[in] pv_api_ip
1698 * Pointer to input argument structure
1699 *
1700 * @param[out] pv_api_op
1701 * Pointer to output argument structure
1702 *
1703 * @returns Status
1704 *
1705 * @remarks
1706 *
1707 *
1708 *******************************************************************************
1709 */
ihevcd_fill_num_mem_rec(void * pv_api_ip,void * pv_api_op)1710 WORD32 ihevcd_fill_num_mem_rec(void *pv_api_ip, void *pv_api_op)
1711 {
1712
1713 ihevcd_cxa_fill_mem_rec_ip_t *ps_mem_q_ip;
1714 ihevcd_cxa_fill_mem_rec_op_t *ps_mem_q_op;
1715 WORD32 level;
1716 WORD32 num_reorder_frames;
1717 WORD32 num_ref_frames;
1718 WORD32 num_extra_disp_bufs;
1719 WORD32 max_dpb_size;
1720
1721 iv_mem_rec_t *ps_mem_rec;
1722 iv_mem_rec_t *ps_mem_rec_base;
1723 WORD32 no_of_mem_rec_filled;
1724 WORD32 chroma_format, share_disp_buf;
1725 WORD32 max_ctb_cnt;
1726 WORD32 max_wd_luma, max_wd_chroma;
1727 WORD32 max_ht_luma, max_ht_chroma;
1728 WORD32 max_tile_cols, max_tile_rows;
1729 WORD32 max_ctb_rows, max_ctb_cols;
1730 WORD32 max_num_cu_cols;
1731 WORD32 i;
1732 WORD32 max_num_4x4_cols;
1733 IV_API_CALL_STATUS_T status = IV_SUCCESS;
1734 no_of_mem_rec_filled = 0;
1735
1736 //TODO: Remove as and when the following are used
1737 UNUSED(num_extra_disp_bufs);
1738 UNUSED(no_of_mem_rec_filled);
1739 UNUSED(max_wd_chroma);
1740 UNUSED(max_ht_chroma);
1741
1742 ps_mem_q_ip = (ihevcd_cxa_fill_mem_rec_ip_t *)pv_api_ip;
1743 ps_mem_q_op = (ihevcd_cxa_fill_mem_rec_op_t *)pv_api_op;
1744
1745 if(ps_mem_q_ip->s_ivd_fill_mem_rec_ip_t.u4_size
1746 > offsetof(ihevcd_cxa_fill_mem_rec_ip_t, i4_level))
1747 {
1748 level = ps_mem_q_ip->i4_level;
1749 /* Spec requires level should be multiplied by 30
1750 * API has values where level is multiplied by 10. This keeps it consistent with H264
1751 * Because of the above differences, level is multiplied by 3 here.
1752 */
1753 level *= 3;
1754 }
1755 else
1756 {
1757 level = MAX_LEVEL;
1758 }
1759
1760 if(ps_mem_q_ip->s_ivd_fill_mem_rec_ip_t.u4_size
1761 > offsetof(ihevcd_cxa_fill_mem_rec_ip_t,
1762 u4_num_reorder_frames))
1763 {
1764 num_reorder_frames = ps_mem_q_ip->u4_num_reorder_frames;
1765 }
1766 else
1767 {
1768 num_reorder_frames = MAX_REF_CNT;
1769 }
1770
1771 if(ps_mem_q_ip->s_ivd_fill_mem_rec_ip_t.u4_size
1772 > offsetof(ihevcd_cxa_fill_mem_rec_ip_t, u4_num_ref_frames))
1773 {
1774 num_ref_frames = ps_mem_q_ip->u4_num_ref_frames;
1775 }
1776 else
1777 {
1778 num_ref_frames = MAX_REF_CNT;
1779 }
1780
1781 if(ps_mem_q_ip->s_ivd_fill_mem_rec_ip_t.u4_size
1782 > offsetof(ihevcd_cxa_fill_mem_rec_ip_t,
1783 u4_num_extra_disp_buf))
1784 {
1785 num_extra_disp_bufs = ps_mem_q_ip->u4_num_extra_disp_buf;
1786 }
1787 else
1788 {
1789 num_extra_disp_bufs = 0;
1790 }
1791
1792 if(ps_mem_q_ip->s_ivd_fill_mem_rec_ip_t.u4_size
1793 > offsetof(ihevcd_cxa_fill_mem_rec_ip_t, u4_share_disp_buf))
1794 {
1795 #ifndef LOGO_EN
1796 share_disp_buf = ps_mem_q_ip->u4_share_disp_buf;
1797 #else
1798 share_disp_buf = 0;
1799 #endif
1800 }
1801 else
1802 {
1803 share_disp_buf = 0;
1804 }
1805
1806 if(ps_mem_q_ip->s_ivd_fill_mem_rec_ip_t.u4_size
1807 > offsetof(ihevcd_cxa_fill_mem_rec_ip_t, e_output_format))
1808 {
1809 chroma_format = ps_mem_q_ip->e_output_format;
1810 }
1811 else
1812 {
1813 chroma_format = -1;
1814 }
1815
1816 /* Shared disp buffer mode is supported only for 420SP formats */
1817 if((chroma_format != IV_YUV_420P) &&
1818 (chroma_format != IV_YUV_420SP_UV) &&
1819 (chroma_format != IV_YUV_420SP_VU))
1820 {
1821 share_disp_buf = 0;
1822 }
1823
1824 {
1825
1826 max_ht_luma = ps_mem_q_ip->s_ivd_fill_mem_rec_ip_t.u4_max_frm_ht;
1827 max_wd_luma = ps_mem_q_ip->s_ivd_fill_mem_rec_ip_t.u4_max_frm_wd;
1828
1829 max_ht_luma = ALIGN64(max_ht_luma);
1830 max_wd_luma = ALIGN64(max_wd_luma);
1831
1832
1833
1834 max_tile_cols = (max_wd_luma + MIN_TILE_WD - 1) / MIN_TILE_WD;
1835 max_tile_rows = (max_ht_luma + MIN_TILE_HT - 1) / MIN_TILE_HT;
1836 max_ctb_rows = max_ht_luma / MIN_CTB_SIZE;
1837 max_ctb_cols = max_wd_luma / MIN_CTB_SIZE;
1838 max_ctb_cnt = max_ctb_rows * max_ctb_cols;
1839 max_num_cu_cols = max_wd_luma / MIN_CU_SIZE;
1840 max_num_4x4_cols = max_wd_luma / 4;
1841 }
1842 /*
1843 * If level is lesser than 31 and the resolution required is higher,
1844 * then make the level at least 31.
1845 */
1846 /* if (num_mbs > MAX_NUM_MBS_3_0 && level < MAX_LEVEL)
1847 {
1848 level = MAX_LEVEL;
1849 }
1850 */
1851 if((level < MIN_LEVEL) || (level > MAX_LEVEL))
1852 {
1853 ps_mem_q_op->s_ivd_fill_mem_rec_op_t.u4_error_code |=
1854 IHEVCD_LEVEL_UNSUPPORTED;
1855 level = MAX_LEVEL;
1856 }
1857 if(num_ref_frames > MAX_REF_CNT)
1858 {
1859 ps_mem_q_op->s_ivd_fill_mem_rec_op_t.u4_error_code |=
1860 IHEVCD_NUM_REF_UNSUPPORTED;
1861 num_ref_frames = MAX_REF_CNT;
1862 }
1863
1864 if(num_reorder_frames > MAX_REF_CNT)
1865 {
1866 ps_mem_q_op->s_ivd_fill_mem_rec_op_t.u4_error_code |=
1867 IHEVCD_NUM_REORDER_UNSUPPORTED;
1868 num_reorder_frames = MAX_REF_CNT;
1869 }
1870
1871 max_dpb_size = ihevcd_get_dpb_size(level, max_wd_luma * max_ht_luma);
1872 ps_mem_rec_base = ps_mem_q_ip->s_ivd_fill_mem_rec_ip_t.pv_mem_rec_location;
1873
1874 /* Set all memory reconds as persistent and alignment as 128
1875 * by default
1876 */
1877 ps_mem_rec = ps_mem_rec_base;
1878 for(i = 0; i < MEM_REC_CNT; i++)
1879 {
1880 ps_mem_rec->u4_mem_alignment = 128;
1881 ps_mem_rec->e_mem_type = IV_EXTERNAL_CACHEABLE_PERSISTENT_MEM;
1882 ps_mem_rec++;
1883 }
1884
1885 /* Request memory for HEVCD object */
1886 ps_mem_rec = &ps_mem_rec_base[MEM_REC_IV_OBJ];
1887 ps_mem_rec->u4_mem_size = sizeof(iv_obj_t);
1888
1889 DEBUG("\nMemory record Id %d = %d \n", MEM_REC_IV_OBJ,
1890 ps_mem_rec->u4_mem_size);
1891
1892 /* Request memory for HEVC Codec context */
1893 ps_mem_rec = &ps_mem_rec_base[MEM_REC_CODEC];
1894 ps_mem_rec->u4_mem_size = sizeof(codec_t);
1895 DEBUG("\nMemory record Id %d = %d \n", MEM_REC_CODEC,
1896 ps_mem_rec->u4_mem_size);
1897
1898 /* Request memory for buffer which holds bitstream after emulation prevention */
1899 ps_mem_rec = &ps_mem_rec_base[MEM_REC_BITSBUF];
1900 ps_mem_rec->u4_mem_size = MAX((max_wd_luma * max_ht_luma), MIN_BITSBUF_SIZE);
1901 DEBUG("\nMemory record Id %d = %d \n", MEM_REC_BITSBUF,
1902 ps_mem_rec->u4_mem_size);
1903
1904 /* Request memory for buffer which holds TU structures and coeff data for
1905 * a set of CTBs in the current picture */
1906 /*TODO Currently the buffer is allocated at a frame level. Reduce this to
1907 * allocate for s set of CTBs and add appropriate synchronization logic to
1908 * ensure that this is data is not overwritten before consumption
1909 */
1910 ps_mem_rec = &ps_mem_rec_base[MEM_REC_TU_DATA];
1911 ps_mem_rec->u4_mem_size = ihevcd_get_tu_data_size(max_wd_luma * max_ht_luma);
1912 DEBUG("\nMemory record Id %d = %d \n", MEM_REC_TU_DATA,
1913 ps_mem_rec->u4_mem_size);
1914
1915 ps_mem_rec = &ps_mem_rec_base[MEM_REC_MVBANK];
1916
1917 ps_mem_rec->u4_mem_size = sizeof(buf_mgr_t);
1918
1919 /* Size for holding mv_buf_t for each MV Bank */
1920 /* Note this allocation is done for BUF_MGR_MAX_CNT instead of
1921 * max_dpb_size or MAX_DPB_SIZE for following reasons
1922 * max_dpb_size will be based on max_wd and max_ht
1923 * For higher max_wd and max_ht this number will be smaller than MAX_DPB_SIZE
1924 * But during actual initialization number of buffers allocated can be more
1925 *
1926 * One extra MV Bank is needed to hold current pics MV bank.
1927 * Since this is only a structure allocation and not actual buffer allocation,
1928 * it is allocated for BUF_MGR_MAX_CNT entries
1929 */
1930 ps_mem_rec->u4_mem_size += BUF_MGR_MAX_CNT * sizeof(mv_buf_t);
1931
1932 {
1933 /* Allocate for pu_map, pu_t and pic_pu_idx for each MV bank */
1934 /* Note: Number of luma samples is not max_wd * max_ht here, instead it is
1935 * set to maximum number of luma samples allowed at the given level.
1936 * This is done to ensure that any stream with width and height lesser
1937 * than max_wd and max_ht is supported. Number of buffers required can be greater
1938 * for lower width and heights at a given level and this increased number of buffers
1939 * might require more memory than what max_wd and max_ht buffer would have required
1940 * Also note one extra buffer is allocted to store current pictures MV bank
1941 * In case of asynchronous parsing and processing, number of buffers should increase here
1942 * based on when parsing and processing threads are synchronized
1943 */
1944 WORD32 lvl_idx = ihevcd_get_lvl_idx(level);
1945 WORD32 max_luma_samples = gai4_ihevc_max_luma_pic_size[lvl_idx];
1946 ps_mem_rec->u4_mem_size += (max_dpb_size + 1) *
1947 ihevcd_get_pic_mv_bank_size(max_luma_samples);
1948 DEBUG("\nMemory record Id %d = %d \n", MEM_REC_MVBANK,
1949 ps_mem_rec->u4_mem_size);
1950 }
1951 // TODO GPU : Have to creat ping-pong view for VPS,SPS,PPS.
1952 ps_mem_rec = &ps_mem_rec_base[MEM_REC_VPS];
1953 ps_mem_rec->u4_mem_size = MAX_VPS_CNT * sizeof(vps_t);
1954 DEBUG("\nMemory record Id %d = %d \n", MEM_REC_VPS,
1955 ps_mem_rec->u4_mem_size);
1956
1957 ps_mem_rec = &ps_mem_rec_base[MEM_REC_SPS];
1958 ps_mem_rec->u4_mem_size = MAX_SPS_CNT * sizeof(sps_t);
1959 DEBUG("\nMemory record Id %d = %d \n", MEM_REC_SPS,
1960 ps_mem_rec->u4_mem_size);
1961
1962 ps_mem_rec = &ps_mem_rec_base[MEM_REC_PPS];
1963 ps_mem_rec->u4_mem_size = MAX_PPS_CNT * sizeof(pps_t);
1964 DEBUG("\nMemory record Id %d = %d \n", MEM_REC_PPS,
1965 ps_mem_rec->u4_mem_size);
1966
1967 ps_mem_rec = &ps_mem_rec_base[MEM_REC_SLICE_HDR];
1968 ps_mem_rec->u4_mem_size = MAX_SLICE_HDR_CNT * sizeof(slice_header_t);
1969 DEBUG("\nMemory record Id %d = %d \n", MEM_REC_SLICE_HDR,
1970 ps_mem_rec->u4_mem_size);
1971
1972 ps_mem_rec = &ps_mem_rec_base[MEM_REC_TILE];
1973 {
1974 WORD32 tile_size;
1975
1976 tile_size = max_tile_cols * max_tile_rows;
1977 tile_size *= sizeof(tile_t);
1978
1979
1980 ps_mem_rec->u4_mem_size = MAX_PPS_CNT * tile_size;
1981 }
1982
1983
1984 DEBUG("\nMemory record Id %d = %d \n", MEM_REC_TILE,
1985 ps_mem_rec->u4_mem_size);
1986
1987 ps_mem_rec = &ps_mem_rec_base[MEM_REC_ENTRY_OFST];
1988 {
1989 WORD32 num_entry_points;
1990
1991 /* One entry point per tile */
1992 num_entry_points = max_tile_cols * max_tile_rows;
1993
1994 /* One entry point per row of CTBs */
1995 /*********************************************************************/
1996 /* Only tiles or entropy sync is enabled at a time in main */
1997 /* profile, but since memory required does not increase too much, */
1998 /* this allocation is done to handle both cases */
1999 /*********************************************************************/
2000 num_entry_points += max_ctb_rows;
2001
2002
2003 ps_mem_rec->u4_mem_size = sizeof(WORD32) * num_entry_points;
2004 }
2005
2006
2007 DEBUG("\nMemory record Id %d = %d \n", MEM_REC_ENTRY_OFST,
2008 ps_mem_rec->u4_mem_size);
2009
2010
2011 ps_mem_rec = &ps_mem_rec_base[MEM_REC_SCALING_MAT];
2012 {
2013 WORD32 scaling_mat_size;
2014
2015 SCALING_MAT_SIZE(scaling_mat_size)
2016 ps_mem_rec->u4_mem_size = (MAX_SPS_CNT + MAX_PPS_CNT) * scaling_mat_size * sizeof(WORD16);
2017 }
2018 DEBUG("\nMemory record Id %d = %d \n", MEM_REC_SCALING_MAT,
2019 ps_mem_rec->u4_mem_size);
2020
2021 /* Holds one row skip_flag at 8x8 level used during parsing */
2022 ps_mem_rec = &ps_mem_rec_base[MEM_REC_PARSE_SKIP_FLAG];
2023
2024 /* 1 bit per 8x8 */
2025 ps_mem_rec->u4_mem_size = max_num_cu_cols / 8;
2026 DEBUG("\nMemory record Id %d = %d \n", MEM_REC_PARSE_SKIP_FLAG,
2027 ps_mem_rec->u4_mem_size);
2028
2029 /* Holds one row skip_flag at 8x8 level used during parsing */
2030 ps_mem_rec = &ps_mem_rec_base[MEM_REC_PARSE_CT_DEPTH];
2031
2032 /* 2 bits per 8x8 */
2033 ps_mem_rec->u4_mem_size = max_num_cu_cols / 4;
2034 DEBUG("\nMemory record Id %d = %d \n", MEM_REC_PARSE_CT_DEPTH,
2035 ps_mem_rec->u4_mem_size);
2036
2037 /* Holds one row skip_flag at 8x8 level used during parsing */
2038 ps_mem_rec = &ps_mem_rec_base[MEM_REC_PARSE_INTRA_PRED_MODE];
2039
2040 /* 8 bits per 4x4 */
2041 /* 16 bytes each for top and left 64 pixels and 16 bytes for default mode */
2042 ps_mem_rec->u4_mem_size = 3 * 16 * sizeof(UWORD8);
2043 DEBUG("\nMemory record Id %d = %d \n", MEM_REC_PARSE_INTRA_PRED_MODE,
2044 ps_mem_rec->u4_mem_size);
2045
2046 /* Holds one intra mode at 8x8 level for entire picture */
2047 ps_mem_rec = &ps_mem_rec_base[MEM_REC_INTRA_FLAG];
2048
2049 /* 1 bit per 8x8 */
2050 ps_mem_rec->u4_mem_size = (max_wd_luma / MIN_CU_SIZE) * (max_ht_luma / MIN_CU_SIZE) / 8;
2051 DEBUG("\nMemory record Id %d = %d \n", MEM_REC_INTRA_FLAG,
2052 ps_mem_rec->u4_mem_size);
2053
2054 /* Holds one transquant bypass flag at 8x8 level for entire picture */
2055 ps_mem_rec = &ps_mem_rec_base[MEM_REC_TRANSQUANT_BYPASS_FLAG];
2056
2057 /* 1 bit per 8x8 */
2058 /* Extra row and column are allocated for easy processing of top and left blocks while loop filtering */
2059 ps_mem_rec->u4_mem_size = ((max_wd_luma + 64) / MIN_CU_SIZE) * ((max_ht_luma + 64) / MIN_CU_SIZE) / 8;
2060 DEBUG("\nMemory record Id %d = %d \n", MEM_REC_TRANSQUANT_BYPASS_FLAG,
2061 ps_mem_rec->u4_mem_size);
2062
2063 /* Request memory to hold thread handles for each processing thread */
2064 ps_mem_rec = &ps_mem_rec_base[MEM_REC_THREAD_HANDLE];
2065 ps_mem_rec->u4_mem_size = MAX_PROCESS_THREADS * ithread_get_handle_size();
2066 DEBUG("\nMemory record Id %d = %d \n", MEM_REC_THREAD_HANDLE,
2067 ps_mem_rec->u4_mem_size);
2068
2069
2070 {
2071 WORD32 job_queue_size;
2072 WORD32 num_jobs;
2073 ps_mem_rec = &ps_mem_rec_base[MEM_REC_PROC_JOBQ];
2074
2075
2076 /* One job per row of CTBs */
2077 num_jobs = max_ctb_rows;
2078
2079 /* One each tile a row of CTBs, num_jobs has to incremented */
2080 num_jobs *= max_tile_cols;
2081
2082 /* One format convert/frame copy job per row of CTBs for non-shared mode*/
2083 num_jobs += max_ctb_rows;
2084
2085
2086 job_queue_size = ihevcd_jobq_ctxt_size();
2087 job_queue_size += num_jobs * sizeof(proc_job_t);
2088 ps_mem_rec->u4_mem_size = job_queue_size;
2089 DEBUG("\nMemory record Id %d = %d \n", MEM_REC_PROC_JOBQ,
2090 ps_mem_rec->u4_mem_size);
2091 }
2092
2093
2094 ps_mem_rec = &ps_mem_rec_base[MEM_REC_PARSE_MAP];
2095 ps_mem_rec->u4_mem_size = max_ctb_cnt;
2096 DEBUG("\nMemory record Id %d = %d \n", MEM_REC_PARSE_MAP,
2097 ps_mem_rec->u4_mem_size);
2098
2099 ps_mem_rec = &ps_mem_rec_base[MEM_REC_PROC_MAP];
2100 ps_mem_rec->u4_mem_size = max_ctb_cnt;
2101 DEBUG("\nMemory record Id %d = %d \n", MEM_REC_PROC_MAP,
2102 ps_mem_rec->u4_mem_size);
2103
2104
2105 ps_mem_rec = &ps_mem_rec_base[MEM_REC_DISP_MGR];
2106
2107 /* size for holding display manager context */
2108 ps_mem_rec->u4_mem_size = sizeof(buf_mgr_t);
2109 DEBUG("\nMemory record Id %d = %d \n", MEM_REC_DISP_MGR,
2110 ps_mem_rec->u4_mem_size);
2111
2112 ps_mem_rec = &ps_mem_rec_base[MEM_REC_DPB_MGR];
2113
2114 /* size for holding dpb manager context */
2115 ps_mem_rec->u4_mem_size = sizeof(dpb_mgr_t);
2116 DEBUG("\nMemory record Id %d = %d \n", MEM_REC_DPB_MGR,
2117 ps_mem_rec->u4_mem_size);
2118
2119 /** Holds top and left neighbor's pu idx into picture level pu array */
2120 /* Only one top row is enough but left has to be replicated for each process context */
2121 ps_mem_rec = &ps_mem_rec_base[MEM_REC_PIC_PU_IDX_NEIGHBOR];
2122
2123 ps_mem_rec->u4_mem_size = (max_num_4x4_cols /* left */ + MAX_PROCESS_THREADS * (MAX_CTB_SIZE / 4)/* top */ + 1/* top right */) * sizeof(WORD32);
2124 DEBUG("\nMemory record Id %d = %d \n", MEM_REC_PIC_PU_IDX_NEIGHBOR,
2125 ps_mem_rec->u4_mem_size);
2126
2127
2128
2129 /* TO hold scratch buffers needed for each process context */
2130 ps_mem_rec = &ps_mem_rec_base[MEM_REC_PROC_SCRATCH];
2131 {
2132 WORD32 size = 0;
2133 WORD32 inter_pred_tmp_buf_size;
2134 WORD32 ntaps_luma;
2135 WORD32 pu_map_size;
2136 WORD32 sao_size = 0;
2137 ntaps_luma = 8;
2138
2139 /* Max inter pred size (number of bytes) */
2140 inter_pred_tmp_buf_size = sizeof(WORD16) * (MAX_CTB_SIZE + ntaps_luma) * MAX_CTB_SIZE;
2141 inter_pred_tmp_buf_size = ALIGN64(inter_pred_tmp_buf_size);
2142
2143
2144 /* To hold pu_index w.r.t. frame level pu_t array for a CTB at 4x4 level*/
2145 /* 16 x 16 4x4 in a CTB of size 64 x 64 and two extra needed for holding
2146 * neighbors
2147 */
2148 pu_map_size = sizeof(WORD32) * (18 * 18);
2149
2150 pu_map_size = ALIGN64(pu_map_size);
2151 size += pu_map_size;
2152
2153 /* To hold inter pred temporary buffers */
2154 size += 2 * inter_pred_tmp_buf_size;
2155
2156
2157 /* Allocate for each process context */
2158 size *= MAX_PROCESS_THREADS;
2159
2160
2161 /* To hold SAO left buffer for luma */
2162 sao_size += sizeof(UWORD8) * (MAX(max_ht_luma, max_wd_luma));
2163
2164 /* To hold SAO left buffer for chroma */
2165 sao_size += sizeof(UWORD8) * (MAX(max_ht_luma, max_wd_luma));
2166
2167 /* To hold SAO top buffer for luma */
2168 sao_size += sizeof(UWORD8) * max_wd_luma;
2169
2170 /* To hold SAO top buffer for chroma */
2171 sao_size += sizeof(UWORD8) * max_wd_luma;
2172
2173 /* To hold SAO top left luma pixel value for last output ctb in a row*/
2174 sao_size += sizeof(UWORD8) * max_ctb_rows;
2175
2176 /* To hold SAO top left chroma pixel value last output ctb in a row*/
2177 sao_size += sizeof(UWORD8) * max_ctb_rows * 2;
2178
2179 /* To hold SAO top left pixel luma for current ctb - column array*/
2180 sao_size += sizeof(UWORD8) * max_ctb_rows;
2181
2182 /* To hold SAO top left pixel chroma for current ctb-column array*/
2183 sao_size += sizeof(UWORD8) * max_ctb_rows * 2;
2184
2185 /* To hold SAO top right pixel luma pixel value last output ctb in a row*/
2186 sao_size += sizeof(UWORD8) * max_ctb_cols;
2187
2188 /* To hold SAO top right pixel chroma pixel value last output ctb in a row*/
2189 sao_size += sizeof(UWORD8) * max_ctb_cols * 2;
2190
2191 /*To hold SAO botton bottom left pixels for luma*/
2192 sao_size += sizeof(UWORD8) * max_ctb_rows;
2193
2194 /*To hold SAO botton bottom left pixels for luma*/
2195 sao_size += sizeof(UWORD8) * max_ctb_rows * 2;
2196 sao_size = ALIGN64(sao_size);
2197 size += sao_size;
2198 ps_mem_rec->u4_mem_size = size;
2199 }
2200 DEBUG("\nMemory record Id %d = %d \n", MEM_REC_PROC_SCRATCH,
2201 ps_mem_rec->u4_mem_size);
2202
2203 /* TO hold scratch buffers needed for each SAO context */
2204 ps_mem_rec = &ps_mem_rec_base[MEM_REC_SAO_SCRATCH];
2205 {
2206 WORD32 size = 0;
2207
2208 size = 4 * MAX_CTB_SIZE * MAX_CTB_SIZE;
2209
2210 /* 2 temporary buffers*/
2211 size *= 2;
2212
2213 size *= MAX_PROCESS_THREADS;
2214
2215 ps_mem_rec->u4_mem_size = size;
2216 }
2217 DEBUG("\nMemory record Id %d = %d \n", MEM_REC_SAO_SCRATCH,
2218 ps_mem_rec->u4_mem_size);
2219
2220 ps_mem_rec = &ps_mem_rec_base[MEM_REC_BS_QP];
2221 {
2222 WORD32 size = 0;
2223 WORD32 vert_bs_size, horz_bs_size;
2224 WORD32 qp_const_flag_size;
2225 WORD32 qp_size, num_8x8;
2226
2227 /* Max Number of vertical edges */
2228 vert_bs_size = max_wd_luma / 8 + 2 * MAX_CTB_SIZE / 8;
2229
2230 /* Max Number of horizontal edges - extra MAX_CTB_SIZE / 8 to handle the last 4 rows separately(shifted CTB processing) */
2231 vert_bs_size *= (max_ht_luma + MAX_CTB_SIZE) / MIN_TU_SIZE;
2232
2233 /* Number of bytes */
2234 vert_bs_size /= 8;
2235
2236 /* Two bits per edge */
2237 vert_bs_size *= 2;
2238
2239 /* Max Number of horizontal edges */
2240 horz_bs_size = max_ht_luma / 8 + MAX_CTB_SIZE / 8;
2241
2242 /* Max Number of vertical edges - extra MAX_CTB_SIZE / 8 to handle the last 4 columns separately(shifted CTB processing) */
2243 horz_bs_size *= (max_wd_luma + MAX_CTB_SIZE) / MIN_TU_SIZE;
2244
2245 /* Number of bytes */
2246 horz_bs_size /= 8;
2247
2248 /* Two bits per edge */
2249 horz_bs_size *= 2;
2250
2251 /* Max CTBs in a row */
2252 qp_const_flag_size = max_wd_luma / MIN_CTB_SIZE + 1 /* The last ctb row deblk is done in last ctb + 1 row.*/;
2253
2254 /* Max CTBs in a column */
2255 qp_const_flag_size *= max_ht_luma / MIN_CTB_SIZE;
2256
2257 /* Number of bytes */
2258 qp_const_flag_size = (qp_const_flag_size + 7) >> 3;
2259
2260 /* QP changes at CU level - So store at 8x8 level */
2261 num_8x8 = (max_ht_luma * max_wd_luma) / (MIN_CU_SIZE * MIN_CU_SIZE);
2262 qp_size = num_8x8;
2263
2264 /* To hold vertical boundary strength */
2265 size += vert_bs_size;
2266
2267 /* To hold horizontal boundary strength */
2268 size += horz_bs_size;
2269
2270 /* To hold QP */
2271 size += qp_size;
2272
2273 /* To hold QP const in CTB flags */
2274 size += qp_const_flag_size;
2275
2276 ps_mem_rec->u4_mem_size = size;
2277 }
2278
2279 DEBUG("\nMemory record Id %d = %d \n", MEM_REC_BS_QP,
2280 ps_mem_rec->u4_mem_size);
2281
2282 ps_mem_rec = &ps_mem_rec_base[MEM_REC_TILE_IDX];
2283 {
2284 WORD32 size = 0;
2285 /* Max CTBs in a row */
2286 size = max_wd_luma / MIN_CTB_SIZE + 2 /* Top row and bottom row extra. This ensures accessing left,top in first row
2287 and right in last row will not result in invalid access*/;
2288 /* Max CTBs in a column */
2289 size *= max_ht_luma / MIN_CTB_SIZE;
2290
2291 size *= sizeof(UWORD16);
2292 ps_mem_rec->u4_mem_size = size;
2293 }
2294 DEBUG("\nMemory record Id %d = %d \n", MEM_REC_TILE_IDX,
2295 ps_mem_rec->u4_mem_size);
2296
2297 ps_mem_rec = &ps_mem_rec_base[MEM_REC_SAO];
2298 {
2299 UWORD32 size;
2300
2301 /* 4 bytes per color component per CTB */
2302 size = 3 * 4;
2303
2304 /* MAX number of CTBs in a row */
2305 size *= max_wd_luma / MIN_CTB_SIZE;
2306
2307 /* MAX number of CTBs in a column */
2308 size *= max_ht_luma / MIN_CTB_SIZE;
2309 ps_mem_rec->u4_mem_size = size;
2310 }
2311
2312 DEBUG("\nMemory record Id %d = %d \n", MEM_REC_SAO,
2313 ps_mem_rec->u4_mem_size);
2314
2315
2316 ps_mem_rec = &ps_mem_rec_base[MEM_REC_REF_PIC];
2317
2318 /* size for holding buffer manager context */
2319 ps_mem_rec->u4_mem_size = sizeof(buf_mgr_t);
2320
2321 /* Size for holding pic_buf_t for each reference picture */
2322 /* Note this allocation is done for BUF_MGR_MAX_CNT instead of
2323 * max_dpb_size or MAX_DPB_SIZE for following reasons
2324 * max_dpb_size will be based on max_wd and max_ht
2325 * For higher max_wd and max_ht this number will be smaller than MAX_DPB_SIZE
2326 * But during actual initialization number of buffers allocated can be more
2327 *
2328 * Also to handle display depth application can allocate more than what
2329 * codec asks for in case of non-shared mode
2330 * Since this is only a structure allocation and not actual buffer allocation,
2331 * it is allocated for BUF_MGR_MAX_CNT entries
2332 */
2333 ps_mem_rec->u4_mem_size += BUF_MGR_MAX_CNT * sizeof(pic_buf_t);
2334
2335 /* In case of non-shared mode allocate for reference picture buffers */
2336 if(0 == share_disp_buf)
2337 {
2338 UWORD32 num_reorder_frames_local = num_reorder_frames;
2339 /* Note: Number of luma samples is not max_wd * max_ht here, instead it is
2340 * set to maximum number of luma samples allowed at the given level.
2341 * This is done to ensure that any stream with width and height lesser
2342 * than max_wd and max_ht is supported. Number of buffers required can be greater
2343 * for lower width and heights at a given level and this increased number of buffers
2344 * might require more memory than what max_wd and max_ht buffer would have required
2345 * Number of buffers is doubled in order to return one frame at a time instead of sending
2346 * multiple outputs during dpb full case.
2347 * Also note one extra buffer is allocted to store current picture
2348 * In case of asynchronous parsing and processing, number of buffers should increase here
2349 * based on when parsing and processing threads are synchronized
2350 */
2351 ps_mem_rec->u4_mem_size +=
2352 ihevcd_get_total_pic_buf_size(max_wd_luma * max_ht_luma, level, PAD_WD, PAD_HT,
2353 num_ref_frames, num_reorder_frames_local);
2354 }
2355 DEBUG("\nMemory record Id %d = %d \n", MEM_REC_REF_PIC,
2356 ps_mem_rec->u4_mem_size);
2357
2358 /* Request memory to hold mem records to be returned during retrieve call */
2359 ps_mem_rec = &ps_mem_rec_base[MEM_REC_BACKUP];
2360 ps_mem_rec->u4_mem_size = MEM_REC_CNT * sizeof(iv_mem_rec_t);
2361 DEBUG("\nMemory record Id %d = %d \n", MEM_REC_BACKUP,
2362 ps_mem_rec->u4_mem_size);
2363
2364 /* Each memtab size is aligned to next multiple of 128 bytes */
2365 /* This is to ensure all the memtabs start at different cache lines */
2366 ps_mem_rec = ps_mem_rec_base;
2367 for(i = 0; i < MEM_REC_CNT; i++)
2368 {
2369 ps_mem_rec->u4_mem_size = ALIGN128(ps_mem_rec->u4_mem_size);
2370 ps_mem_rec++;
2371 }
2372 ps_mem_q_op->s_ivd_fill_mem_rec_op_t.u4_num_mem_rec_filled = MEM_REC_CNT;
2373 #ifdef APPLY_CONCEALMENT
2374 {
2375 IV_API_CALL_STATUS_T status;
2376 icncl_fill_mem_rec_ip_t cncl_fill_ip;
2377 icncl_fill_mem_rec_op_t cncl_fill_op;
2378 UWORD8 mem_loc = MEM_REC_CNT;
2379
2380 cncl_fill_ip.s_ivd_fill_mem_rec_ip_t.e_cmd = IV_CMD_FILL_NUM_MEM_REC;
2381 cncl_fill_ip.s_ivd_fill_mem_rec_ip_t.pv_mem_rec_location = &(memTab[mem_loc]);
2382 cncl_fill_ip.s_ivd_fill_mem_rec_ip_t.u4_size = ps_mem_q_ip->s_ivd_fill_mem_rec_ip_t.u4_size;
2383 cncl_fill_ip.s_ivd_fill_mem_rec_ip_t.u4_max_frm_wd = max_wd_luma;
2384 cncl_fill_ip.s_ivd_fill_mem_rec_ip_t.u4_max_frm_ht = max_ht_luma;
2385
2386 status = icncl_api_function(NULL, (void *)&cncl_fill_ip, (void *)&cncl_fill_op);
2387
2388 if(IV_SUCCESS == status)
2389 {
2390 icncl_num_mem_rec_ip_t cncl_mem_ip;
2391 icncl_num_mem_rec_op_t cncl_mem_op;
2392
2393 cncl_mem_ip.s_ivd_num_rec_ip_t.e_cmd = IV_CMD_GET_NUM_MEM_REC;
2394 cncl_mem_ip.s_ivd_num_rec_ip_t.u4_size = sizeof(icncl_num_mem_rec_ip_t);
2395
2396 status = icncl_api_function(NULL, (void *)&cncl_mem_ip, (void *)&cncl_mem_op);
2397 if(IV_SUCCESS == status)
2398 {
2399 ps_mem_q_op->s_ivd_fill_mem_rec_op_t.u4_num_mem_rec_filled += cncl_mem_op.s_ivd_num_mem_rec_op_t.u4_num_mem_rec;
2400 }
2401 }
2402
2403 return status;
2404
2405 }
2406 #endif //APPLY_CONCEALMENT
2407 DEBUG("Num mem recs in fill call : %d\n",
2408 ps_mem_q_op->s_ivd_fill_mem_rec_op_t.u4_num_mem_rec_filled);
2409
2410
2411 return (status);
2412 }
2413
2414
2415 /**
2416 *******************************************************************************
2417 *
2418 * @brief
2419 * Initializes from mem records passed to the codec
2420 *
2421 * @par Description:
2422 * Initializes pointers based on mem records passed
2423 *
2424 * @param[in] ps_codec_obj
2425 * Pointer to codec object at API level
2426 *
2427 * @param[in] pv_api_ip
2428 * Pointer to input argument structure
2429 *
2430 * @param[out] pv_api_op
2431 * Pointer to output argument structure
2432 *
2433 * @returns Status
2434 *
2435 * @remarks
2436 *
2437 *
2438 *******************************************************************************
2439 */
ihevcd_init_mem_rec(iv_obj_t * ps_codec_obj,void * pv_api_ip,void * pv_api_op)2440 WORD32 ihevcd_init_mem_rec(iv_obj_t *ps_codec_obj,
2441 void *pv_api_ip,
2442 void *pv_api_op)
2443 {
2444
2445 ihevcd_cxa_init_ip_t *dec_init_ip;
2446 ihevcd_cxa_init_op_t *dec_init_op;
2447 WORD32 i;
2448 iv_mem_rec_t *ps_mem_rec, *ps_mem_rec_base;
2449 WORD32 status = IV_SUCCESS;
2450 codec_t *ps_codec;
2451 WORD32 max_tile_cols, max_tile_rows;
2452
2453 dec_init_ip = (ihevcd_cxa_init_ip_t *)pv_api_ip;
2454 dec_init_op = (ihevcd_cxa_init_op_t *)pv_api_op;
2455
2456 ps_mem_rec_base = dec_init_ip->s_ivd_init_ip_t.pv_mem_rec_location;
2457
2458 ps_mem_rec = &ps_mem_rec_base[MEM_REC_CODEC];
2459 ps_codec_obj->pv_codec_handle = ps_mem_rec->pv_base;
2460
2461 ps_codec = (codec_t *)(ps_codec_obj->pv_codec_handle);
2462
2463 /* Note this memset can not be done in init() call, since init will called
2464 during reset as well. And calling this during reset will mean all pointers
2465 need to reinitialized*/
2466 memset(ps_codec, 0, sizeof(codec_t));
2467
2468 if(dec_init_ip->s_ivd_init_ip_t.u4_size
2469 > offsetof(ihevcd_cxa_init_ip_t, i4_level))
2470 {
2471 ps_codec->i4_init_level = dec_init_ip->i4_level;
2472
2473 ps_codec->i4_init_level *= 3;
2474 }
2475 else
2476 {
2477 ps_codec->i4_init_level = MAX_LEVEL;
2478 }
2479
2480 if(dec_init_ip->s_ivd_init_ip_t.u4_size
2481 > offsetof(ihevcd_cxa_init_ip_t, u4_num_ref_frames))
2482 {
2483 ps_codec->i4_init_num_ref = dec_init_ip->u4_num_ref_frames;
2484 }
2485 else
2486 {
2487 ps_codec->i4_init_num_ref = MAX_REF_CNT;
2488 }
2489
2490 if(dec_init_ip->s_ivd_init_ip_t.u4_size
2491 > offsetof(ihevcd_cxa_init_ip_t, u4_num_reorder_frames))
2492 {
2493 ps_codec->i4_init_num_reorder = dec_init_ip->u4_num_reorder_frames;
2494 }
2495 else
2496 {
2497 ps_codec->i4_init_num_reorder = MAX_REF_CNT;
2498 }
2499
2500 if(dec_init_ip->s_ivd_init_ip_t.u4_size
2501 > offsetof(ihevcd_cxa_init_ip_t, u4_num_extra_disp_buf))
2502 {
2503 ps_codec->i4_init_num_extra_disp_buf =
2504 dec_init_ip->u4_num_extra_disp_buf;
2505 }
2506 else
2507 {
2508 ps_codec->i4_init_num_extra_disp_buf = 0;
2509 }
2510
2511 if(dec_init_ip->s_ivd_init_ip_t.u4_size
2512 > offsetof(ihevcd_cxa_init_ip_t, u4_share_disp_buf))
2513 {
2514 #ifndef LOGO_EN
2515 ps_codec->i4_share_disp_buf = dec_init_ip->u4_share_disp_buf;
2516 #else
2517 ps_codec->i4_share_disp_buf = 0;
2518 #endif
2519 }
2520 else
2521 {
2522 ps_codec->i4_share_disp_buf = 0;
2523 }
2524 /* Shared display mode is supported only for 420SP and 420P formats */
2525 if((dec_init_ip->s_ivd_init_ip_t.e_output_format != IV_YUV_420P) &&
2526 (dec_init_ip->s_ivd_init_ip_t.e_output_format != IV_YUV_420SP_UV) &&
2527 (dec_init_ip->s_ivd_init_ip_t.e_output_format != IV_YUV_420SP_VU))
2528 {
2529 ps_codec->i4_share_disp_buf = 0;
2530 }
2531
2532 if((ps_codec->i4_init_level < MIN_LEVEL)
2533 || (ps_codec->i4_init_level > MAX_LEVEL))
2534 {
2535 dec_init_op->s_ivd_init_op_t.u4_error_code |= IHEVCD_LEVEL_UNSUPPORTED;
2536 return (IV_FAIL);
2537 }
2538
2539 if(ps_codec->i4_init_num_ref > MAX_REF_CNT)
2540 {
2541 dec_init_op->s_ivd_init_op_t.u4_error_code |=
2542 IHEVCD_NUM_REF_UNSUPPORTED;
2543 ps_codec->i4_init_num_ref = MAX_REF_CNT;
2544 }
2545
2546 if(ps_codec->i4_init_num_reorder > MAX_REF_CNT)
2547 {
2548 dec_init_op->s_ivd_init_op_t.u4_error_code |=
2549 IHEVCD_NUM_REORDER_UNSUPPORTED;
2550 ps_codec->i4_init_num_reorder = MAX_REF_CNT;
2551 }
2552
2553 if(ps_codec->i4_init_num_extra_disp_buf > MAX_REF_CNT)
2554 {
2555 dec_init_op->s_ivd_init_op_t.u4_error_code |=
2556 IHEVCD_NUM_EXTRA_DISP_UNSUPPORTED;
2557 ps_codec->i4_init_num_extra_disp_buf = 0;
2558 }
2559
2560 ps_codec->e_chroma_fmt = dec_init_ip->s_ivd_init_ip_t.e_output_format;
2561
2562 ps_codec->i4_max_wd = dec_init_ip->s_ivd_init_ip_t.u4_frm_max_wd;
2563 ps_codec->i4_max_ht = dec_init_ip->s_ivd_init_ip_t.u4_frm_max_ht;
2564
2565 ps_codec->i4_max_wd = ALIGN64(ps_codec->i4_max_wd);
2566 ps_codec->i4_max_ht = ALIGN64(ps_codec->i4_max_ht);
2567
2568 ps_codec->i4_new_max_wd = ps_codec->i4_max_wd;
2569 ps_codec->i4_new_max_ht = ps_codec->i4_max_ht;
2570
2571 max_tile_cols = (ps_codec->i4_max_wd + MIN_TILE_WD - 1) / MIN_TILE_WD;
2572 max_tile_rows = (ps_codec->i4_max_ht + MIN_TILE_HT - 1) / MIN_TILE_HT;
2573
2574 ps_mem_rec = &ps_mem_rec_base[MEM_REC_BACKUP];
2575 ps_codec->ps_mem_rec_backup = (iv_mem_rec_t *)ps_mem_rec->pv_base;
2576
2577 memcpy(ps_codec->ps_mem_rec_backup, ps_mem_rec_base,
2578 MEM_REC_CNT * sizeof(iv_mem_rec_t));
2579
2580 ps_mem_rec = &ps_mem_rec_base[MEM_REC_BITSBUF];
2581 ps_codec->pu1_bitsbuf = (UWORD8 *)ps_mem_rec->pv_base;
2582 ps_codec->u4_bitsbuf_size = ps_mem_rec->u4_mem_size;
2583
2584 ps_mem_rec = &ps_mem_rec_base[MEM_REC_TU_DATA];
2585 ps_codec->pv_tu_data = ps_mem_rec->pv_base;
2586 ps_mem_rec = &ps_mem_rec_base[MEM_REC_MVBANK];
2587 ps_codec->pv_mv_buf_mgr = ps_mem_rec->pv_base;
2588 ps_codec->pv_mv_bank_buf_base = (UWORD8 *)ps_codec->pv_mv_buf_mgr + sizeof(buf_mgr_t);
2589
2590 ps_codec->i4_total_mv_bank_size = ps_mem_rec->u4_mem_size - sizeof(buf_mgr_t);
2591
2592
2593 ps_mem_rec = &ps_mem_rec_base[MEM_REC_VPS];
2594 ps_codec->ps_vps_base = (vps_t *)ps_mem_rec->pv_base;
2595 ps_codec->s_parse.ps_vps_base = ps_codec->ps_vps_base;
2596
2597 ps_mem_rec = &ps_mem_rec_base[MEM_REC_SPS];
2598 ps_codec->ps_sps_base = (sps_t *)ps_mem_rec->pv_base;
2599 ps_codec->s_parse.ps_sps_base = ps_codec->ps_sps_base;
2600
2601 ps_mem_rec = &ps_mem_rec_base[MEM_REC_PPS];
2602 ps_codec->ps_pps_base = (pps_t *)ps_mem_rec->pv_base;
2603 ps_codec->s_parse.ps_pps_base = ps_codec->ps_pps_base;
2604
2605 ps_mem_rec = &ps_mem_rec_base[MEM_REC_SLICE_HDR];
2606 ps_codec->ps_slice_hdr_base = (slice_header_t *)ps_mem_rec->pv_base;
2607 ps_codec->s_parse.ps_slice_hdr_base = ps_codec->ps_slice_hdr_base;
2608
2609 ps_mem_rec = &ps_mem_rec_base[MEM_REC_TILE];
2610 ps_codec->ps_tile = (tile_t *)ps_mem_rec->pv_base;
2611
2612 ps_mem_rec = &ps_mem_rec_base[MEM_REC_ENTRY_OFST];
2613 ps_codec->pi4_entry_ofst = (WORD32 *)ps_mem_rec->pv_base;
2614
2615 ps_mem_rec = &ps_mem_rec_base[MEM_REC_SCALING_MAT];
2616 ps_codec->pi2_scaling_mat = (WORD16 *)ps_mem_rec->pv_base;
2617
2618 ps_mem_rec = &ps_mem_rec_base[MEM_REC_PARSE_SKIP_FLAG];
2619 ps_codec->s_parse.pu4_skip_cu_top = (UWORD32 *)ps_mem_rec->pv_base;
2620
2621 ps_mem_rec = &ps_mem_rec_base[MEM_REC_PARSE_CT_DEPTH];
2622 ps_codec->s_parse.pu4_ct_depth_top = (UWORD32 *)ps_mem_rec->pv_base;
2623
2624 ps_mem_rec = &ps_mem_rec_base[MEM_REC_PARSE_INTRA_PRED_MODE];
2625 ps_codec->s_parse.pu1_luma_intra_pred_mode_left =
2626 (UWORD8 *)ps_mem_rec->pv_base;
2627 ps_codec->s_parse.pu1_luma_intra_pred_mode_top =
2628 (UWORD8 *)ps_mem_rec->pv_base + 16;
2629
2630 ps_mem_rec = &ps_mem_rec_base[MEM_REC_INTRA_FLAG];
2631
2632 memset(ps_mem_rec->pv_base, 0, (ps_codec->i4_max_wd / MIN_CU_SIZE) * (ps_codec->i4_max_ht / MIN_CU_SIZE) / 8);
2633
2634 ps_codec->pu1_pic_intra_flag = (UWORD8 *)ps_mem_rec->pv_base;
2635 ps_codec->s_parse.pu1_pic_intra_flag = ps_codec->pu1_pic_intra_flag;
2636 ps_mem_rec = &ps_mem_rec_base[MEM_REC_TRANSQUANT_BYPASS_FLAG];
2637
2638 {
2639 WORD32 loop_filter_size = ((ps_codec->i4_max_wd + 64) / MIN_CU_SIZE) * ((ps_codec->i4_max_ht + 64) / MIN_CU_SIZE) / 8;
2640 WORD32 loop_filter_strd = (ps_codec->i4_max_wd + 63) >> 6;
2641
2642 memset(ps_mem_rec->pv_base, 0, loop_filter_size);
2643
2644 /* The offset is added for easy processing of top and left blocks while loop filtering */
2645 ps_codec->pu1_pic_no_loop_filter_flag = (UWORD8 *)ps_mem_rec->pv_base + loop_filter_strd + 1;
2646 ps_codec->s_parse.pu1_pic_no_loop_filter_flag = ps_codec->pu1_pic_no_loop_filter_flag;
2647 ps_codec->s_parse.s_deblk_ctxt.pu1_pic_no_loop_filter_flag = ps_codec->pu1_pic_no_loop_filter_flag;
2648 ps_codec->s_parse.s_sao_ctxt.pu1_pic_no_loop_filter_flag = ps_codec->pu1_pic_no_loop_filter_flag;
2649 }
2650
2651 /* Initialize pointers in PPS structures */
2652 {
2653 sps_t *ps_sps = ps_codec->ps_sps_base;
2654 pps_t *ps_pps = ps_codec->ps_pps_base;
2655 tile_t *ps_tile = ps_codec->ps_tile;
2656 WORD16 *pi2_scaling_mat = ps_codec->pi2_scaling_mat;
2657 WORD32 scaling_mat_size;
2658
2659 SCALING_MAT_SIZE(scaling_mat_size);
2660
2661 for(i = 0; i < MAX_SPS_CNT; i++)
2662 {
2663 ps_sps->pi2_scaling_mat = pi2_scaling_mat;
2664 pi2_scaling_mat += scaling_mat_size;
2665 ps_sps++;
2666 }
2667
2668 for(i = 0; i < MAX_PPS_CNT; i++)
2669 {
2670 ps_pps->ps_tile = ps_tile;
2671 ps_tile += (max_tile_cols * max_tile_rows);
2672
2673 ps_pps->pi2_scaling_mat = pi2_scaling_mat;
2674 pi2_scaling_mat += scaling_mat_size;
2675 ps_pps++;
2676 }
2677
2678 }
2679
2680 ps_mem_rec = &ps_mem_rec_base[MEM_REC_THREAD_HANDLE];
2681 for(i = 0; i < MAX_PROCESS_THREADS; i++)
2682 {
2683 WORD32 handle_size = ithread_get_handle_size();
2684 ps_codec->apv_process_thread_handle[i] =
2685 (UWORD8 *)ps_mem_rec->pv_base + (i * handle_size);
2686 }
2687
2688 ps_mem_rec = &ps_mem_rec_base[MEM_REC_PROC_JOBQ];
2689 ps_codec->pv_proc_jobq_buf = ps_mem_rec->pv_base;
2690 ps_codec->i4_proc_jobq_buf_size = ps_mem_rec->u4_mem_size;
2691
2692 ps_mem_rec = &ps_mem_rec_base[MEM_REC_PARSE_MAP];
2693 ps_codec->pu1_parse_map = (UWORD8 *)ps_mem_rec->pv_base;
2694
2695 ps_mem_rec = &ps_mem_rec_base[MEM_REC_PROC_MAP];
2696 ps_codec->pu1_proc_map = (UWORD8 *)ps_mem_rec->pv_base;
2697 ps_mem_rec = &ps_mem_rec_base[MEM_REC_DISP_MGR];
2698 ps_codec->pv_disp_buf_mgr = ps_mem_rec->pv_base;
2699
2700 ps_mem_rec = &ps_mem_rec_base[MEM_REC_DPB_MGR];
2701 ps_codec->pv_dpb_mgr = ps_mem_rec->pv_base;
2702
2703
2704 ps_mem_rec = &ps_mem_rec_base[MEM_REC_PIC_PU_IDX_NEIGHBOR];
2705
2706 for(i = 0; i < MAX_PROCESS_THREADS; i++)
2707 {
2708 UWORD32 *pu4_buf = (UWORD32 *)ps_mem_rec->pv_base;
2709 ps_codec->as_process[i].pu4_pic_pu_idx_left = pu4_buf + i * (MAX_CTB_SIZE / 4);
2710 memset(ps_codec->as_process[i].pu4_pic_pu_idx_left, 0, sizeof(UWORD32) * MAX_CTB_SIZE / 4);
2711 ps_codec->as_process[i].pu4_pic_pu_idx_top = pu4_buf + MAX_PROCESS_THREADS * (MAX_CTB_SIZE / 4);
2712 }
2713 memset(ps_codec->as_process[0].pu4_pic_pu_idx_top, 0, sizeof(UWORD32) * (ps_codec->i4_max_wd / 4 + 1));
2714
2715
2716 ps_mem_rec = &ps_mem_rec_base[MEM_REC_PROC_SCRATCH];
2717 {
2718 UWORD8 *pu1_buf = (UWORD8 *)ps_mem_rec->pv_base;
2719 WORD32 pic_pu_idx_map_size;
2720
2721 WORD32 inter_pred_tmp_buf_size, ntaps_luma;
2722
2723 /* Max inter pred size */
2724 ntaps_luma = 8;
2725 inter_pred_tmp_buf_size = sizeof(WORD16) * (MAX_CTB_SIZE + ntaps_luma) * MAX_CTB_SIZE;
2726
2727 inter_pred_tmp_buf_size = ALIGN64(inter_pred_tmp_buf_size);
2728
2729 /* To hold pu_index w.r.t. frame level pu_t array for a CTB */
2730 pic_pu_idx_map_size = sizeof(WORD32) * (18 * 18);
2731 pic_pu_idx_map_size = ALIGN64(pic_pu_idx_map_size);
2732 for(i = 0; i < MAX_PROCESS_THREADS; i++)
2733 {
2734 ps_codec->as_process[i].pi2_inter_pred_tmp_buf1 = (WORD16 *)pu1_buf;
2735 pu1_buf += inter_pred_tmp_buf_size;
2736
2737 ps_codec->as_process[i].pi2_inter_pred_tmp_buf2 = (WORD16 *)pu1_buf;
2738 pu1_buf += inter_pred_tmp_buf_size;
2739
2740 /* Inverse transform intermediate and inverse scan output buffers reuse inter pred scratch buffers */
2741 ps_codec->as_process[i].pi2_itrans_intrmd_buf =
2742 ps_codec->as_process[i].pi2_inter_pred_tmp_buf2;
2743 ps_codec->as_process[i].pi2_invscan_out =
2744 ps_codec->as_process[i].pi2_inter_pred_tmp_buf1;
2745
2746 ps_codec->as_process[i].pu4_pic_pu_idx_map = (UWORD32 *)pu1_buf;
2747 ps_codec->as_process[i].s_bs_ctxt.pu4_pic_pu_idx_map =
2748 (UWORD32 *)pu1_buf;
2749 pu1_buf += pic_pu_idx_map_size;
2750
2751 // ps_codec->as_process[i].pi2_inter_pred_tmp_buf3 = (WORD16 *)pu1_buf;
2752 // pu1_buf += inter_pred_tmp_buf_size;
2753
2754 ps_codec->as_process[i].i4_inter_pred_tmp_buf_strd = MAX_CTB_SIZE;
2755
2756 }
2757 for(i = 0; i < MAX_PROCESS_THREADS; i++)
2758 {
2759 ps_codec->as_process[i].s_sao_ctxt.pu1_sao_src_left_luma = (UWORD8 *)pu1_buf;
2760 }
2761 ps_codec->s_parse.s_sao_ctxt.pu1_sao_src_left_luma = (UWORD8 *)pu1_buf;
2762 pu1_buf += MAX(ps_codec->i4_max_ht, ps_codec->i4_max_wd);
2763
2764 for(i = 0; i < MAX_PROCESS_THREADS; i++)
2765 {
2766 ps_codec->as_process[i].s_sao_ctxt.pu1_sao_src_left_chroma = (UWORD8 *)pu1_buf;
2767 }
2768 ps_codec->s_parse.s_sao_ctxt.pu1_sao_src_left_chroma = (UWORD8 *)pu1_buf;
2769 pu1_buf += MAX(ps_codec->i4_max_ht, ps_codec->i4_max_wd);
2770 for(i = 0; i < MAX_PROCESS_THREADS; i++)
2771 {
2772 ps_codec->as_process[i].s_sao_ctxt.pu1_sao_src_top_luma = (UWORD8 *)pu1_buf;
2773 }
2774 ps_codec->s_parse.s_sao_ctxt.pu1_sao_src_top_luma = (UWORD8 *)pu1_buf;
2775 pu1_buf += ps_codec->i4_max_wd;
2776
2777 for(i = 0; i < MAX_PROCESS_THREADS; i++)
2778 {
2779 ps_codec->as_process[i].s_sao_ctxt.pu1_sao_src_top_chroma = (UWORD8 *)pu1_buf;
2780 }
2781 ps_codec->s_parse.s_sao_ctxt.pu1_sao_src_top_chroma = (UWORD8 *)pu1_buf;
2782 pu1_buf += ps_codec->i4_max_wd;
2783 for(i = 0; i < MAX_PROCESS_THREADS; i++)
2784 {
2785 ps_codec->as_process[i].s_sao_ctxt.pu1_sao_src_luma_top_left_ctb = (UWORD8 *)pu1_buf;
2786 }
2787 ps_codec->s_parse.s_sao_ctxt.pu1_sao_src_luma_top_left_ctb = (UWORD8 *)pu1_buf;
2788 pu1_buf += ps_codec->i4_max_ht / MIN_CTB_SIZE;
2789
2790 for(i = 0; i < MAX_PROCESS_THREADS; i++)
2791 {
2792 ps_codec->as_process[i].s_sao_ctxt.pu1_sao_src_chroma_top_left_ctb = (UWORD8 *)pu1_buf;
2793 }
2794 ps_codec->s_parse.s_sao_ctxt.pu1_sao_src_chroma_top_left_ctb = (UWORD8 *)pu1_buf;
2795 pu1_buf += (ps_codec->i4_max_ht / MIN_CTB_SIZE) * 2;
2796
2797 for(i = 0; i < MAX_PROCESS_THREADS; i++)
2798 {
2799 ps_codec->as_process[i].s_sao_ctxt.pu1_sao_src_top_left_luma_curr_ctb = (UWORD8 *)pu1_buf;
2800 }
2801 ps_codec->s_parse.s_sao_ctxt.pu1_sao_src_top_left_luma_curr_ctb = (UWORD8 *)pu1_buf;
2802 pu1_buf += ps_codec->i4_max_ht / MIN_CTB_SIZE;
2803
2804 for(i = 0; i < MAX_PROCESS_THREADS; i++)
2805 {
2806 ps_codec->as_process[i].s_sao_ctxt.pu1_sao_src_top_left_chroma_curr_ctb = (UWORD8 *)pu1_buf;
2807 }
2808 ps_codec->s_parse.s_sao_ctxt.pu1_sao_src_top_left_chroma_curr_ctb = (UWORD8 *)pu1_buf;
2809
2810 pu1_buf += (ps_codec->i4_max_ht / MIN_CTB_SIZE) * 2;
2811 for(i = 0; i < MAX_PROCESS_THREADS; i++)
2812 {
2813 ps_codec->as_process[i].s_sao_ctxt.pu1_sao_src_top_left_luma_top_right = (UWORD8 *)pu1_buf;
2814 }
2815 ps_codec->s_parse.s_sao_ctxt.pu1_sao_src_top_left_luma_top_right = (UWORD8 *)pu1_buf;
2816
2817 pu1_buf += ps_codec->i4_max_wd / MIN_CTB_SIZE;
2818 for(i = 0; i < MAX_PROCESS_THREADS; i++)
2819 {
2820 ps_codec->as_process[i].s_sao_ctxt.pu1_sao_src_top_left_chroma_top_right = (UWORD8 *)pu1_buf;
2821 }
2822 ps_codec->s_parse.s_sao_ctxt.pu1_sao_src_top_left_chroma_top_right = (UWORD8 *)pu1_buf;
2823
2824 pu1_buf += (ps_codec->i4_max_wd / MIN_CTB_SIZE) * 2;
2825
2826 /*Per CTB, Store 1 value for luma , 2 values for chroma*/
2827 for(i = 0; i < MAX_PROCESS_THREADS; i++)
2828 {
2829 ps_codec->as_process[i].s_sao_ctxt.pu1_sao_src_top_left_luma_bot_left = (UWORD8 *)pu1_buf;
2830 }
2831 ps_codec->s_parse.s_sao_ctxt.pu1_sao_src_top_left_luma_bot_left = (UWORD8 *)pu1_buf;
2832
2833 pu1_buf += (ps_codec->i4_max_ht / MIN_CTB_SIZE);
2834
2835 for(i = 0; i < MAX_PROCESS_THREADS; i++)
2836 {
2837 ps_codec->as_process[i].s_sao_ctxt.pu1_sao_src_top_left_chroma_bot_left = (UWORD8 *)pu1_buf;
2838 }
2839 ps_codec->s_parse.s_sao_ctxt.pu1_sao_src_top_left_chroma_bot_left = (UWORD8 *)pu1_buf;
2840
2841 pu1_buf += (ps_codec->i4_max_ht / MIN_CTB_SIZE) * 2;
2842 }
2843
2844 ps_mem_rec = &ps_mem_rec_base[MEM_REC_SAO_SCRATCH];
2845 {
2846 UWORD8 *pu1_buf = (UWORD8 *)ps_mem_rec->pv_base;
2847 for(i = 0; i < MAX_PROCESS_THREADS; i++)
2848 {
2849 ps_codec->as_process[i].s_sao_ctxt.pu1_tmp_buf_luma = (UWORD8 *)pu1_buf;
2850 pu1_buf += 4 * MAX_CTB_SIZE * MAX_CTB_SIZE * sizeof(UWORD8);
2851
2852 ps_codec->as_process[i].s_sao_ctxt.pu1_tmp_buf_chroma = (UWORD8 *)pu1_buf;
2853 pu1_buf += 4 * MAX_CTB_SIZE * MAX_CTB_SIZE * sizeof(UWORD8);
2854 }
2855 }
2856
2857 ps_mem_rec = &ps_mem_rec_base[MEM_REC_BS_QP];
2858 {
2859 UWORD8 *pu1_buf = (UWORD8 *)ps_mem_rec->pv_base;
2860 WORD32 vert_bs_size, horz_bs_size;
2861 WORD32 qp_const_flag_size;
2862 WORD32 qp_size;
2863 WORD32 num_8x8;
2864
2865 /* Max Number of vertical edges */
2866 vert_bs_size = ps_codec->i4_max_wd / 8 + 2 * MAX_CTB_SIZE / 8;
2867
2868 /* Max Number of horizontal edges - extra MAX_CTB_SIZE / 8 to handle the last 4 rows separately(shifted CTB processing) */
2869 vert_bs_size *= (ps_codec->i4_max_ht + MAX_CTB_SIZE) / MIN_TU_SIZE;
2870
2871 /* Number of bytes */
2872 vert_bs_size /= 8;
2873
2874 /* Two bits per edge */
2875 vert_bs_size *= 2;
2876
2877 /* Max Number of horizontal edges */
2878 horz_bs_size = ps_codec->i4_max_ht / 8 + MAX_CTB_SIZE / 8;
2879
2880 /* Max Number of vertical edges - extra MAX_CTB_SIZE / 8 to handle the last 4 columns separately(shifted CTB processing) */
2881 horz_bs_size *= (ps_codec->i4_max_wd + MAX_CTB_SIZE) / MIN_TU_SIZE;
2882
2883 /* Number of bytes */
2884 horz_bs_size /= 8;
2885
2886 /* Two bits per edge */
2887 horz_bs_size *= 2;
2888
2889 /* Max CTBs in a row */
2890 qp_const_flag_size = ps_codec->i4_max_wd / MIN_CTB_SIZE + 1 /* The last ctb row deblk is done in last ctb + 1 row.*/;
2891
2892 /* Max CTBs in a column */
2893 qp_const_flag_size *= ps_codec->i4_max_ht / MIN_CTB_SIZE;
2894
2895 /* Number of bytes */
2896 qp_const_flag_size /= 8;
2897
2898 /* QP changes at CU level - So store at 8x8 level */
2899 num_8x8 = (ps_codec->i4_max_ht * ps_codec->i4_max_wd) / (MIN_CU_SIZE * MIN_CU_SIZE);
2900 qp_size = num_8x8;
2901 memset(pu1_buf, 0, vert_bs_size + horz_bs_size + qp_size + qp_const_flag_size);
2902
2903 for(i = 0; i < MAX_PROCESS_THREADS; i++)
2904 {
2905 ps_codec->as_process[i].s_bs_ctxt.pu4_pic_vert_bs = (UWORD32 *)pu1_buf;
2906 ps_codec->as_process[i].s_deblk_ctxt.s_bs_ctxt.pu4_pic_vert_bs = (UWORD32 *)pu1_buf;
2907 ps_codec->s_parse.s_deblk_ctxt.s_bs_ctxt.pu4_pic_vert_bs = (UWORD32 *)pu1_buf;
2908 pu1_buf += vert_bs_size;
2909
2910 ps_codec->as_process[i].s_bs_ctxt.pu4_pic_horz_bs = (UWORD32 *)pu1_buf;
2911 ps_codec->as_process[i].s_deblk_ctxt.s_bs_ctxt.pu4_pic_horz_bs = (UWORD32 *)pu1_buf;
2912 ps_codec->s_parse.s_deblk_ctxt.s_bs_ctxt.pu4_pic_horz_bs = (UWORD32 *)pu1_buf;
2913 pu1_buf += horz_bs_size;
2914
2915 ps_codec->as_process[i].s_bs_ctxt.pu1_pic_qp = (UWORD8 *)pu1_buf;
2916 ps_codec->as_process[i].s_deblk_ctxt.s_bs_ctxt.pu1_pic_qp = (UWORD8 *)pu1_buf;
2917 ps_codec->s_parse.s_deblk_ctxt.s_bs_ctxt.pu1_pic_qp = (UWORD8 *)pu1_buf;
2918 pu1_buf += qp_size;
2919
2920 ps_codec->as_process[i].s_bs_ctxt.pu1_pic_qp_const_in_ctb = (UWORD8 *)pu1_buf;
2921 ps_codec->as_process[i].s_deblk_ctxt.s_bs_ctxt.pu1_pic_qp_const_in_ctb = (UWORD8 *)pu1_buf;
2922 ps_codec->s_parse.s_deblk_ctxt.s_bs_ctxt.pu1_pic_qp_const_in_ctb = (UWORD8 *)pu1_buf;
2923 pu1_buf += qp_const_flag_size;
2924
2925 pu1_buf -= (vert_bs_size + horz_bs_size + qp_size + qp_const_flag_size);
2926 }
2927 ps_codec->s_parse.s_bs_ctxt.pu4_pic_vert_bs = (UWORD32 *)pu1_buf;
2928 pu1_buf += vert_bs_size;
2929
2930 ps_codec->s_parse.s_bs_ctxt.pu4_pic_horz_bs = (UWORD32 *)pu1_buf;
2931 pu1_buf += horz_bs_size;
2932
2933 ps_codec->s_parse.s_bs_ctxt.pu1_pic_qp = (UWORD8 *)pu1_buf;
2934 pu1_buf += qp_size;
2935
2936 ps_codec->s_parse.s_bs_ctxt.pu1_pic_qp_const_in_ctb = (UWORD8 *)pu1_buf;
2937 pu1_buf += qp_const_flag_size;
2938
2939 }
2940
2941 ps_mem_rec = &ps_mem_rec_base[MEM_REC_TILE_IDX];
2942 {
2943 UWORD8 *pu1_buf = (UWORD8 *)ps_mem_rec->pv_base;
2944
2945 for(i = 0; i < MAX_PROCESS_THREADS; i++)
2946 {
2947 ps_codec->as_process[i].pu1_tile_idx = (UWORD16 *)pu1_buf + ps_codec->i4_max_wd / MIN_CTB_SIZE /* Offset 1 row */;
2948 }
2949 }
2950
2951 ps_mem_rec = &ps_mem_rec_base[MEM_REC_SAO];
2952 ps_codec->s_parse.ps_pic_sao = (sao_t *)ps_mem_rec->pv_base;
2953 ps_codec->s_parse.s_sao_ctxt.ps_pic_sao = (sao_t *)ps_mem_rec->pv_base;
2954 for(i = 0; i < MAX_PROCESS_THREADS; i++)
2955 {
2956 ps_codec->as_process[i].s_sao_ctxt.ps_pic_sao = ps_codec->s_parse.ps_pic_sao;
2957 }
2958
2959 ps_mem_rec = &ps_mem_rec_base[MEM_REC_REF_PIC];
2960 ps_codec->pv_pic_buf_mgr = ps_mem_rec->pv_base;
2961 ps_codec->pv_pic_buf_base = (UWORD8 *)ps_codec->pv_pic_buf_mgr + sizeof(buf_mgr_t);
2962 ps_codec->i4_total_pic_buf_size = ps_mem_rec->u4_mem_size - sizeof(buf_mgr_t);
2963
2964
2965
2966
2967
2968 #ifdef APPLY_CONCEALMENT
2969 {
2970
2971 UWORD32 mem_loc;
2972
2973 icncl_init_ip_t cncl_init_ip;
2974 icncl_init_op_t cncl_init_op;
2975 iv_mem_rec_t *ps_mem_rec;
2976 DecStruct *ps_codec;
2977
2978 ps_mem_rec = dec_init_ip->s_ivd_init_ip_t.pv_mem_rec_location;
2979 mem_loc = MEM_REC_CNT;
2980
2981 ps_codec->ps_conceal = (iv_obj_t *)ps_mem_rec[mem_loc].pv_base;
2982 ps_codec->i4_first_frame_done = 0;
2983
2984 cncl_init_ip.u4_size = sizeof(icncl_init_ip_t);
2985 cncl_init_ip.pv_mem_rec_location = &(ps_mem_rec[mem_loc]);
2986 cncl_init_ip.e_cmd = IV_CMD_INIT;
2987
2988 status = icncl_api_function(ps_codec->ps_conceal, (void *)&cncl_init_ip, (void *)&cncl_init_op);
2989
2990 }
2991 #endif //APPLY_CONCEALMENT
2992
2993 status = ihevcd_init(ps_codec);
2994
2995 TRACE_INIT(NULL);
2996 STATS_INIT();
2997 return status;
2998 }
2999 /**
3000 *******************************************************************************
3001 *
3002 * @brief
3003 * Retrieves mem records passed to the codec
3004 *
3005 * @par Description:
3006 * Retrieves memrecs passed earlier
3007 *
3008 * @param[in] ps_codec_obj
3009 * Pointer to codec object at API level
3010 *
3011 * @param[in] pv_api_ip
3012 * Pointer to input argument structure
3013 *
3014 * @param[out] pv_api_op
3015 * Pointer to output argument structure
3016 *
3017 * @returns Status
3018 *
3019 * @remarks
3020 *
3021 *
3022 *******************************************************************************
3023 */
ihevcd_retrieve_memrec(iv_obj_t * ps_codec_obj,void * pv_api_ip,void * pv_api_op)3024 WORD32 ihevcd_retrieve_memrec(iv_obj_t *ps_codec_obj,
3025 void *pv_api_ip,
3026 void *pv_api_op)
3027 {
3028
3029 iv_retrieve_mem_rec_ip_t *dec_clr_ip;
3030 iv_retrieve_mem_rec_op_t *dec_clr_op;
3031 codec_t *ps_codec;
3032 dec_clr_ip = (iv_retrieve_mem_rec_ip_t *)pv_api_ip;
3033 dec_clr_op = (iv_retrieve_mem_rec_op_t *)pv_api_op;
3034 ps_codec = (codec_t *)(ps_codec_obj->pv_codec_handle);
3035
3036 if(ps_codec->i4_init_done != 1)
3037 {
3038 dec_clr_op->u4_error_code |= 1 << IVD_FATALERROR;
3039 dec_clr_op->u4_error_code |= IHEVCD_INIT_NOT_DONE;
3040 return IV_FAIL;
3041 }
3042
3043 memcpy(dec_clr_ip->pv_mem_rec_location, ps_codec->ps_mem_rec_backup,
3044 MEM_REC_CNT * (sizeof(iv_mem_rec_t)));
3045 dec_clr_op->u4_num_mem_rec_filled = MEM_REC_CNT;
3046
3047 #ifdef APPLY_CONCEALMENT
3048 {
3049 IV_API_CALL_STATUS_T status;
3050 icncl_fill_mem_rec_ip_t cncl_fill_ip;
3051 icncl_fill_mem_rec_op_t cncl_fill_op;
3052
3053 iv_mem_rec_t *ps_mem_rec;
3054
3055 UWORD8 mem_loc = MEM_REC_CNT;
3056 UWORD8 num_cncl_mem = 0;
3057
3058 ps_mem_rec = dec_clr_ip->pv_mem_rec_location;
3059
3060 cncl_fill_ip.s_ivd_fill_mem_rec_ip_t.e_cmd = IV_CMD_FILL_NUM_MEM_REC;
3061 cncl_fill_ip.s_ivd_fill_mem_rec_ip_t.pv_mem_rec_location = &(ps_mem_rec[mem_loc]);
3062 cncl_fill_ip.s_ivd_fill_mem_rec_ip_t.u4_size = sizeof(icncl_fill_mem_rec_ip_t);
3063
3064 status = icncl_api_function(NULL, (void *)&cncl_fill_ip, (void *)&cncl_fill_op);
3065
3066 cncl_fill_ip.s_ivd_fill_mem_rec_ip_t.e_cmd = IV_CMD_RETRIEVE_MEMREC;
3067 cncl_fill_op.s_ivd_fill_mem_rec_op_t.u4_size = sizeof(icncl_fill_mem_rec_op_t);
3068
3069 status = icncl_api_function(ps_codec->ps_conceal, (void *)&cncl_fill_ip, (void *)&cncl_fill_op);
3070
3071 if(status == IV_SUCCESS)
3072 {
3073 /* Add the concealment library's memory requirements */
3074 dec_clr_op->u4_num_mem_rec_filled += cncl_fill_op.s_ivd_fill_mem_rec_op_t.u4_num_mem_rec_filled;
3075 }
3076 }
3077 #endif //APPLY_CONCEALMENT
3078 DEBUG("Retrieve num mem recs: %d\n",
3079 dec_clr_op->u4_num_mem_rec_filled);
3080 STATS_PRINT();
3081 ihevcd_jobq_free((jobq_t *)ps_codec->pv_proc_jobq);
3082
3083
3084
3085 return IV_SUCCESS;
3086
3087 }
3088 /**
3089 *******************************************************************************
3090 *
3091 * @brief
3092 * Passes display buffer from application to codec
3093 *
3094 * @par Description:
3095 * Adds display buffer to the codec
3096 *
3097 * @param[in] ps_codec_obj
3098 * Pointer to codec object at API level
3099 *
3100 * @param[in] pv_api_ip
3101 * Pointer to input argument structure
3102 *
3103 * @param[out] pv_api_op
3104 * Pointer to output argument structure
3105 *
3106 * @returns Status
3107 *
3108 * @remarks
3109 *
3110 *
3111 *******************************************************************************
3112 */
ihevcd_set_display_frame(iv_obj_t * ps_codec_obj,void * pv_api_ip,void * pv_api_op)3113 WORD32 ihevcd_set_display_frame(iv_obj_t *ps_codec_obj,
3114 void *pv_api_ip,
3115 void *pv_api_op)
3116 {
3117 WORD32 ret = IV_SUCCESS;
3118
3119 ivd_set_display_frame_ip_t *ps_dec_disp_ip;
3120 ivd_set_display_frame_op_t *ps_dec_disp_op;
3121
3122 WORD32 i;
3123
3124 codec_t *ps_codec = (codec_t *)(ps_codec_obj->pv_codec_handle);
3125
3126 ps_dec_disp_ip = (ivd_set_display_frame_ip_t *)pv_api_ip;
3127 ps_dec_disp_op = (ivd_set_display_frame_op_t *)pv_api_op;
3128
3129 ps_codec->i4_num_disp_bufs = 0;
3130 if(ps_codec->i4_share_disp_buf)
3131 {
3132 UWORD32 num_bufs = ps_dec_disp_ip->num_disp_bufs;
3133 pic_buf_t *ps_pic_buf;
3134 UWORD8 *pu1_buf;
3135 WORD32 buf_ret;
3136 WORD32 strd;
3137 strd = ps_codec->i4_strd;
3138 if(0 == strd)
3139 strd = ps_codec->i4_max_wd + PAD_WD;
3140 num_bufs = MIN(num_bufs, BUF_MGR_MAX_CNT);
3141 ps_codec->i4_num_disp_bufs = num_bufs;
3142
3143 ps_pic_buf = (pic_buf_t *)ps_codec->ps_pic_buf;
3144 for(i = 0; i < (WORD32)num_bufs; i++)
3145 {
3146 pu1_buf = ps_dec_disp_ip->s_disp_buffer[i].pu1_bufs[0];
3147 ps_pic_buf->pu1_luma = pu1_buf + strd * PAD_TOP + PAD_LEFT;
3148
3149 pu1_buf = ps_dec_disp_ip->s_disp_buffer[i].pu1_bufs[1];
3150 ps_pic_buf->pu1_chroma = pu1_buf + strd * (PAD_TOP / 2) + PAD_LEFT;
3151
3152 buf_ret = ihevc_buf_mgr_add((buf_mgr_t *)ps_codec->pv_pic_buf_mgr, ps_pic_buf, i);
3153
3154 if(0 != buf_ret)
3155 {
3156 ps_codec->i4_error_code = IHEVCD_BUF_MGR_ERROR;
3157 return IHEVCD_BUF_MGR_ERROR;
3158 }
3159
3160 /* Mark pic buf as needed for display */
3161 /* This ensures that till the buffer is explicitly passed to the codec,
3162 * application owns the buffer. Decoder is allowed to use a buffer only
3163 * when application sends it through fill this buffer call in OMX
3164 */
3165 ihevc_buf_mgr_set_status((buf_mgr_t *)ps_codec->pv_pic_buf_mgr, i, BUF_MGR_DISP);
3166
3167 ps_pic_buf++;
3168
3169 }
3170 }
3171
3172 ps_dec_disp_op->u4_error_code = 0;
3173 return ret;
3174
3175 }
3176
3177 /**
3178 *******************************************************************************
3179 *
3180 * @brief
3181 * Sets the decoder in flush mode. Decoder will come out of flush only
3182 * after returning all the buffers or at reset
3183 *
3184 * @par Description:
3185 * Sets the decoder in flush mode
3186 *
3187 * @param[in] ps_codec_obj
3188 * Pointer to codec object at API level
3189 *
3190 * @param[in] pv_api_ip
3191 * Pointer to input argument structure
3192 *
3193 * @param[out] pv_api_op
3194 * Pointer to output argument structure
3195 *
3196 * @returns Status
3197 *
3198 * @remarks
3199 *
3200 *
3201 *******************************************************************************
3202 */
ihevcd_set_flush_mode(iv_obj_t * ps_codec_obj,void * pv_api_ip,void * pv_api_op)3203 WORD32 ihevcd_set_flush_mode(iv_obj_t *ps_codec_obj,
3204 void *pv_api_ip,
3205 void *pv_api_op)
3206 {
3207
3208 codec_t *ps_codec;
3209 ivd_ctl_flush_op_t *ps_ctl_op = (ivd_ctl_flush_op_t *)pv_api_op;
3210 UNUSED(pv_api_ip);
3211 ps_codec = (codec_t *)(ps_codec_obj->pv_codec_handle);
3212
3213 /* Signal flush frame control call */
3214 ps_codec->i4_flush_mode = 1;
3215
3216 ps_ctl_op->u4_error_code = 0;
3217
3218 /* Set pic count to zero, so that decoder starts buffering again */
3219 /* once it comes out of flush mode */
3220 ps_codec->u4_pic_cnt = 0;
3221 ps_codec->u4_disp_cnt = 0;
3222 return IV_SUCCESS;
3223
3224
3225 }
3226
3227 /**
3228 *******************************************************************************
3229 *
3230 * @brief
3231 * Gets decoder status and buffer requirements
3232 *
3233 * @par Description:
3234 * Gets the decoder status
3235 *
3236 * @param[in] ps_codec_obj
3237 * Pointer to codec object at API level
3238 *
3239 * @param[in] pv_api_ip
3240 * Pointer to input argument structure
3241 *
3242 * @param[out] pv_api_op
3243 * Pointer to output argument structure
3244 *
3245 * @returns Status
3246 *
3247 * @remarks
3248 *
3249 *
3250 *******************************************************************************
3251 */
3252
ihevcd_get_status(iv_obj_t * ps_codec_obj,void * pv_api_ip,void * pv_api_op)3253 WORD32 ihevcd_get_status(iv_obj_t *ps_codec_obj,
3254 void *pv_api_ip,
3255 void *pv_api_op)
3256 {
3257
3258 WORD32 i;
3259 codec_t *ps_codec;
3260 WORD32 wd, ht;
3261 ivd_ctl_getstatus_op_t *ps_ctl_op = (ivd_ctl_getstatus_op_t *)pv_api_op;
3262
3263 UNUSED(pv_api_ip);
3264
3265 ps_ctl_op->u4_error_code = 0;
3266
3267 ps_codec = (codec_t *)(ps_codec_obj->pv_codec_handle);
3268
3269 ps_ctl_op->u4_min_num_in_bufs = MIN_IN_BUFS;
3270 if(ps_codec->e_chroma_fmt == IV_YUV_420P)
3271 ps_ctl_op->u4_min_num_out_bufs = MIN_OUT_BUFS_420;
3272 else if(ps_codec->e_chroma_fmt == IV_YUV_422ILE)
3273 ps_ctl_op->u4_min_num_out_bufs = MIN_OUT_BUFS_422ILE;
3274 else if(ps_codec->e_chroma_fmt == IV_RGB_565)
3275 ps_ctl_op->u4_min_num_out_bufs = MIN_OUT_BUFS_RGB565;
3276 else if(ps_codec->e_chroma_fmt == IV_RGBA_8888)
3277 ps_ctl_op->u4_min_num_out_bufs = MIN_OUT_BUFS_RGBA8888;
3278 else if((ps_codec->e_chroma_fmt == IV_YUV_420SP_UV)
3279 || (ps_codec->e_chroma_fmt == IV_YUV_420SP_VU))
3280 ps_ctl_op->u4_min_num_out_bufs = MIN_OUT_BUFS_420SP;
3281
3282 ps_ctl_op->u4_num_disp_bufs = 1;
3283
3284 for(i = 0; i < (WORD32)ps_ctl_op->u4_min_num_in_bufs; i++)
3285 {
3286 ps_ctl_op->u4_min_in_buf_size[i] = MAX((ps_codec->i4_wd * ps_codec->i4_ht), MIN_BITSBUF_SIZE);
3287 }
3288
3289 wd = ps_codec->i4_wd;
3290 ht = ps_codec->i4_ht;
3291
3292 if(ps_codec->i4_sps_done)
3293 {
3294 if(0 == ps_codec->i4_share_disp_buf)
3295 {
3296 wd = ps_codec->i4_disp_wd;
3297 ht = ps_codec->i4_disp_ht;
3298
3299 }
3300 else
3301 {
3302 wd = ps_codec->i4_disp_strd;
3303 ht = ps_codec->i4_ht + PAD_HT;
3304 }
3305 }
3306 else
3307 {
3308 if(0 == ps_codec->i4_share_disp_buf)
3309 {
3310 wd = ps_codec->i4_new_max_wd;
3311 ht = ps_codec->i4_new_max_ht;
3312 }
3313 else
3314 {
3315 wd = ALIGN32(wd + PAD_WD);
3316 ht += PAD_HT;
3317 }
3318 }
3319
3320 if(ps_codec->i4_disp_strd > wd)
3321 wd = ps_codec->i4_disp_strd;
3322
3323 if(0 == ps_codec->i4_share_disp_buf)
3324 ps_ctl_op->u4_num_disp_bufs = 1;
3325 else
3326 {
3327 WORD32 pic_size;
3328 WORD32 max_dpb_size;
3329
3330 if(ps_codec->i4_sps_done)
3331 {
3332 sps_t *ps_sps = (ps_codec->s_parse.ps_sps_base + ps_codec->i4_sps_id);
3333 WORD32 reorder_pic_cnt;
3334 WORD32 ref_pic_cnt;
3335 WORD32 level;
3336
3337 reorder_pic_cnt = MIN(ps_sps->ai1_sps_max_num_reorder_pics[0], ps_codec->i4_init_num_reorder);
3338 pic_size = ps_sps->i2_pic_width_in_luma_samples * ps_sps->i2_pic_height_in_luma_samples;
3339
3340 level = ps_codec->i4_init_level;
3341 max_dpb_size = ihevcd_get_dpb_size(level, pic_size);
3342 ref_pic_cnt = max_dpb_size;
3343 ps_ctl_op->u4_num_disp_bufs = reorder_pic_cnt;
3344
3345 ps_ctl_op->u4_num_disp_bufs += ref_pic_cnt + 1;
3346
3347 }
3348 else
3349 {
3350 pic_size = ps_codec->i4_max_wd * ps_codec->i4_max_ht;
3351 max_dpb_size = ihevcd_get_dpb_size(ps_codec->i4_init_level, pic_size);
3352 ps_ctl_op->u4_num_disp_bufs = 2 * max_dpb_size;
3353
3354 ps_ctl_op->u4_num_disp_bufs = MIN(ps_ctl_op->u4_num_disp_bufs,
3355 (UWORD32)(ps_codec->i4_init_num_ref + ps_codec->i4_init_num_reorder + 1));
3356
3357 }
3358
3359 ps_ctl_op->u4_num_disp_bufs = MIN(
3360 ps_ctl_op->u4_num_disp_bufs, 32);
3361 }
3362
3363 /*!*/
3364 if(ps_codec->e_chroma_fmt == IV_YUV_420P)
3365 {
3366 ps_ctl_op->u4_min_out_buf_size[0] = (wd * ht);
3367 ps_ctl_op->u4_min_out_buf_size[1] = (wd * ht) >> 2;
3368 ps_ctl_op->u4_min_out_buf_size[2] = (wd * ht) >> 2;
3369 }
3370 else if(ps_codec->e_chroma_fmt == IV_YUV_422ILE)
3371 {
3372 ps_ctl_op->u4_min_out_buf_size[0] = (wd * ht) * 2;
3373 ps_ctl_op->u4_min_out_buf_size[1] =
3374 ps_ctl_op->u4_min_out_buf_size[2] = 0;
3375 }
3376 else if(ps_codec->e_chroma_fmt == IV_RGB_565)
3377 {
3378 ps_ctl_op->u4_min_out_buf_size[0] = (wd * ht) * 2;
3379 ps_ctl_op->u4_min_out_buf_size[1] =
3380 ps_ctl_op->u4_min_out_buf_size[2] = 0;
3381 }
3382 else if(ps_codec->e_chroma_fmt == IV_RGBA_8888)
3383 {
3384 ps_ctl_op->u4_min_out_buf_size[0] = (wd * ht) * 4;
3385 ps_ctl_op->u4_min_out_buf_size[1] =
3386 ps_ctl_op->u4_min_out_buf_size[2] = 0;
3387 }
3388 else if((ps_codec->e_chroma_fmt == IV_YUV_420SP_UV)
3389 || (ps_codec->e_chroma_fmt == IV_YUV_420SP_VU))
3390 {
3391 ps_ctl_op->u4_min_out_buf_size[0] = (wd * ht);
3392 ps_ctl_op->u4_min_out_buf_size[1] = (wd * ht) >> 1;
3393 ps_ctl_op->u4_min_out_buf_size[2] = 0;
3394 }
3395 ps_ctl_op->u4_pic_ht = ht;
3396 ps_ctl_op->u4_pic_wd = wd;
3397 ps_ctl_op->u4_frame_rate = 30000;
3398 ps_ctl_op->u4_bit_rate = 1000000;
3399 ps_ctl_op->e_content_type = IV_PROGRESSIVE;
3400 ps_ctl_op->e_output_chroma_format = ps_codec->e_chroma_fmt;
3401 ps_codec->i4_num_disp_bufs = ps_ctl_op->u4_num_disp_bufs;
3402
3403 if(ps_ctl_op->u4_size == sizeof(ihevcd_cxa_ctl_getstatus_op_t))
3404 {
3405 ihevcd_cxa_ctl_getstatus_op_t *ps_ext_ctl_op = (ihevcd_cxa_ctl_getstatus_op_t *)ps_ctl_op;
3406 ps_ext_ctl_op->u4_coded_pic_wd = ps_codec->i4_wd;
3407 ps_ext_ctl_op->u4_coded_pic_wd = ps_codec->i4_ht;
3408 }
3409 return IV_SUCCESS;
3410 }
3411 /**
3412 *******************************************************************************
3413 *
3414 * @brief
3415 * Gets decoder buffer requirements
3416 *
3417 * @par Description:
3418 * Gets the decoder buffer requirements. If called before header decoder,
3419 * buffer requirements are based on max_wd and max_ht else actual width and
3420 * height will be used
3421 *
3422 * @param[in] ps_codec_obj
3423 * Pointer to codec object at API level
3424 *
3425 * @param[in] pv_api_ip
3426 * Pointer to input argument structure
3427 *
3428 * @param[out] pv_api_op
3429 * Pointer to output argument structure
3430 *
3431 * @returns Status
3432 *
3433 * @remarks
3434 *
3435 *
3436 *******************************************************************************
3437 */
ihevcd_get_buf_info(iv_obj_t * ps_codec_obj,void * pv_api_ip,void * pv_api_op)3438 WORD32 ihevcd_get_buf_info(iv_obj_t *ps_codec_obj,
3439 void *pv_api_ip,
3440 void *pv_api_op)
3441 {
3442
3443 codec_t *ps_codec;
3444 UWORD32 i = 0;
3445 WORD32 wd, ht;
3446 ivd_ctl_getbufinfo_op_t *ps_ctl_op =
3447 (ivd_ctl_getbufinfo_op_t *)pv_api_op;
3448
3449 UNUSED(pv_api_ip);
3450 ps_ctl_op->u4_error_code = 0;
3451
3452 ps_codec = (codec_t *)(ps_codec_obj->pv_codec_handle);
3453
3454 ps_ctl_op->u4_min_num_in_bufs = MIN_IN_BUFS;
3455 if(ps_codec->e_chroma_fmt == IV_YUV_420P)
3456 ps_ctl_op->u4_min_num_out_bufs = MIN_OUT_BUFS_420;
3457 else if(ps_codec->e_chroma_fmt == IV_YUV_422ILE)
3458 ps_ctl_op->u4_min_num_out_bufs = MIN_OUT_BUFS_422ILE;
3459 else if(ps_codec->e_chroma_fmt == IV_RGB_565)
3460 ps_ctl_op->u4_min_num_out_bufs = MIN_OUT_BUFS_RGB565;
3461 else if(ps_codec->e_chroma_fmt == IV_RGBA_8888)
3462 ps_ctl_op->u4_min_num_out_bufs = MIN_OUT_BUFS_RGBA8888;
3463 else if((ps_codec->e_chroma_fmt == IV_YUV_420SP_UV)
3464 || (ps_codec->e_chroma_fmt == IV_YUV_420SP_VU))
3465 ps_ctl_op->u4_min_num_out_bufs = MIN_OUT_BUFS_420SP;
3466
3467 ps_ctl_op->u4_num_disp_bufs = 1;
3468
3469 for(i = 0; i < ps_ctl_op->u4_min_num_in_bufs; i++)
3470 {
3471 ps_ctl_op->u4_min_in_buf_size[i] = MAX((ps_codec->i4_wd * ps_codec->i4_ht), MIN_BITSBUF_SIZE);
3472 }
3473
3474 wd = ps_codec->i4_max_wd;
3475 ht = ps_codec->i4_max_ht;
3476
3477 if(ps_codec->i4_sps_done)
3478 {
3479 if(0 == ps_codec->i4_share_disp_buf)
3480 {
3481 wd = ps_codec->i4_disp_wd;
3482 ht = ps_codec->i4_disp_ht;
3483
3484 }
3485 else
3486 {
3487 wd = ps_codec->i4_disp_strd;
3488 ht = ps_codec->i4_ht + PAD_HT;
3489 }
3490 }
3491 else
3492 {
3493 if(1 == ps_codec->i4_share_disp_buf)
3494 {
3495 wd = ALIGN32(wd + PAD_WD);
3496 ht += PAD_HT;
3497 }
3498 }
3499
3500 if(ps_codec->i4_disp_strd > wd)
3501 wd = ps_codec->i4_disp_strd;
3502
3503 if(0 == ps_codec->i4_share_disp_buf)
3504 ps_ctl_op->u4_num_disp_bufs = 1;
3505 else
3506 {
3507 WORD32 pic_size;
3508 WORD32 max_dpb_size;
3509
3510 if(ps_codec->i4_sps_done)
3511 {
3512 sps_t *ps_sps = (ps_codec->s_parse.ps_sps_base + ps_codec->i4_sps_id);
3513 WORD32 reorder_pic_cnt;
3514 WORD32 ref_pic_cnt;
3515 WORD32 level;
3516
3517 reorder_pic_cnt = MIN(ps_sps->ai1_sps_max_num_reorder_pics[0], ps_codec->i4_init_num_reorder);
3518 pic_size = ps_sps->i2_pic_width_in_luma_samples * ps_sps->i2_pic_height_in_luma_samples;
3519
3520 level = ps_codec->i4_init_level;
3521 max_dpb_size = ihevcd_get_dpb_size(level, pic_size);
3522 ref_pic_cnt = max_dpb_size;
3523 ps_ctl_op->u4_num_disp_bufs = reorder_pic_cnt;
3524
3525 ps_ctl_op->u4_num_disp_bufs += ref_pic_cnt + 1;
3526
3527 }
3528 else
3529 {
3530 pic_size = ps_codec->i4_max_wd * ps_codec->i4_max_ht;
3531 max_dpb_size = ihevcd_get_dpb_size(ps_codec->i4_init_level, pic_size);
3532 ps_ctl_op->u4_num_disp_bufs = 2 * max_dpb_size;
3533
3534 ps_ctl_op->u4_num_disp_bufs = MIN(ps_ctl_op->u4_num_disp_bufs,
3535 (UWORD32)(ps_codec->i4_init_num_ref + ps_codec->i4_init_num_reorder + 1));
3536
3537 }
3538
3539 ps_ctl_op->u4_num_disp_bufs = MIN(
3540 ps_ctl_op->u4_num_disp_bufs, 32);
3541
3542 }
3543
3544 /*!*/
3545 if(ps_codec->e_chroma_fmt == IV_YUV_420P)
3546 {
3547 ps_ctl_op->u4_min_out_buf_size[0] = (wd * ht);
3548 ps_ctl_op->u4_min_out_buf_size[1] = (wd * ht) >> 2;
3549 ps_ctl_op->u4_min_out_buf_size[2] = (wd * ht) >> 2;
3550 }
3551 else if(ps_codec->e_chroma_fmt == IV_YUV_422ILE)
3552 {
3553 ps_ctl_op->u4_min_out_buf_size[0] = (wd * ht) * 2;
3554 ps_ctl_op->u4_min_out_buf_size[1] =
3555 ps_ctl_op->u4_min_out_buf_size[2] = 0;
3556 }
3557 else if(ps_codec->e_chroma_fmt == IV_RGB_565)
3558 {
3559 ps_ctl_op->u4_min_out_buf_size[0] = (wd * ht) * 2;
3560 ps_ctl_op->u4_min_out_buf_size[1] =
3561 ps_ctl_op->u4_min_out_buf_size[2] = 0;
3562 }
3563 else if(ps_codec->e_chroma_fmt == IV_RGBA_8888)
3564 {
3565 ps_ctl_op->u4_min_out_buf_size[0] = (wd * ht) * 4;
3566 ps_ctl_op->u4_min_out_buf_size[1] =
3567 ps_ctl_op->u4_min_out_buf_size[2] = 0;
3568 }
3569 else if((ps_codec->e_chroma_fmt == IV_YUV_420SP_UV)
3570 || (ps_codec->e_chroma_fmt == IV_YUV_420SP_VU))
3571 {
3572 ps_ctl_op->u4_min_out_buf_size[0] = (wd * ht);
3573 ps_ctl_op->u4_min_out_buf_size[1] = (wd * ht) >> 1;
3574 ps_ctl_op->u4_min_out_buf_size[2] = 0;
3575 }
3576 ps_codec->i4_num_disp_bufs = ps_ctl_op->u4_num_disp_bufs;
3577
3578 return IV_SUCCESS;
3579 }
3580
3581
3582 /**
3583 *******************************************************************************
3584 *
3585 * @brief
3586 * Sets dynamic parameters
3587 *
3588 * @par Description:
3589 * Sets dynamic parameters. Note Frame skip, decode header mode are dynamic
3590 * Dynamic change in stride is not supported
3591 *
3592 * @param[in] ps_codec_obj
3593 * Pointer to codec object at API level
3594 *
3595 * @param[in] pv_api_ip
3596 * Pointer to input argument structure
3597 *
3598 * @param[out] pv_api_op
3599 * Pointer to output argument structure
3600 *
3601 * @returns Status
3602 *
3603 * @remarks
3604 *
3605 *
3606 *******************************************************************************
3607 */
ihevcd_set_params(iv_obj_t * ps_codec_obj,void * pv_api_ip,void * pv_api_op)3608 WORD32 ihevcd_set_params(iv_obj_t *ps_codec_obj,
3609 void *pv_api_ip,
3610 void *pv_api_op)
3611 {
3612
3613 codec_t *ps_codec;
3614 WORD32 ret = IV_SUCCESS;
3615 WORD32 strd;
3616 ivd_ctl_set_config_ip_t *s_ctl_dynparams_ip =
3617 (ivd_ctl_set_config_ip_t *)pv_api_ip;
3618 ivd_ctl_set_config_op_t *s_ctl_dynparams_op =
3619 (ivd_ctl_set_config_op_t *)pv_api_op;
3620
3621 ps_codec = (codec_t *)(ps_codec_obj->pv_codec_handle);
3622
3623 s_ctl_dynparams_op->u4_error_code = 0;
3624
3625 ps_codec->e_pic_skip_mode = s_ctl_dynparams_ip->e_frm_skip_mode;
3626
3627 if(s_ctl_dynparams_ip->e_frm_skip_mode != IVD_SKIP_NONE)
3628 {
3629
3630 if((s_ctl_dynparams_ip->e_frm_skip_mode != IVD_SKIP_P) &&
3631 (s_ctl_dynparams_ip->e_frm_skip_mode != IVD_SKIP_B) &&
3632 (s_ctl_dynparams_ip->e_frm_skip_mode != IVD_SKIP_PB))
3633 {
3634 s_ctl_dynparams_op->u4_error_code = (1 << IVD_UNSUPPORTEDPARAM);
3635 ret = IV_FAIL;
3636 }
3637 }
3638
3639 strd = ps_codec->i4_disp_strd;
3640 if(1 == ps_codec->i4_share_disp_buf)
3641 {
3642 strd = ps_codec->i4_strd;
3643 }
3644
3645
3646 if((-1 != (WORD32)s_ctl_dynparams_ip->u4_disp_wd) &&
3647 (0 != s_ctl_dynparams_ip->u4_disp_wd) &&
3648 (0 != strd) &&
3649 ((WORD32)s_ctl_dynparams_ip->u4_disp_wd < strd))
3650 {
3651 s_ctl_dynparams_op->u4_error_code |= (1 << IVD_UNSUPPORTEDPARAM);
3652 s_ctl_dynparams_op->u4_error_code |= IHEVCD_INVALID_DISP_STRD;
3653 ret = IV_FAIL;
3654 }
3655 else
3656 {
3657 if((WORD32)s_ctl_dynparams_ip->u4_disp_wd >= ps_codec->i4_wd)
3658 {
3659 strd = s_ctl_dynparams_ip->u4_disp_wd;
3660 }
3661 else if(0 == ps_codec->i4_sps_done ||
3662 0 == ps_codec->i4_pps_done)
3663 {
3664 strd = s_ctl_dynparams_ip->u4_disp_wd;
3665 }
3666 else if(s_ctl_dynparams_ip->u4_disp_wd == 0)
3667 {
3668 strd = ps_codec->i4_disp_strd;
3669 }
3670 else
3671 {
3672 strd = 0;
3673 s_ctl_dynparams_op->u4_error_code |= (1 << IVD_UNSUPPORTEDPARAM);
3674 s_ctl_dynparams_op->u4_error_code |= IHEVCD_INVALID_DISP_STRD;
3675 ret = IV_FAIL;
3676 }
3677 }
3678
3679 ps_codec->i4_disp_strd = strd;
3680 if(1 == ps_codec->i4_share_disp_buf)
3681 {
3682 ps_codec->i4_strd = strd;
3683 }
3684
3685 if(s_ctl_dynparams_ip->e_vid_dec_mode == IVD_DECODE_FRAME)
3686 ps_codec->i4_header_mode = 0;
3687 else if(s_ctl_dynparams_ip->e_vid_dec_mode == IVD_DECODE_HEADER)
3688 ps_codec->i4_header_mode = 1;
3689 else
3690 {
3691
3692 s_ctl_dynparams_op->u4_error_code = (1 << IVD_UNSUPPORTEDPARAM);
3693 ps_codec->i4_header_mode = 1;
3694 ret = IV_FAIL;
3695 }
3696
3697
3698 return ret;
3699
3700 }
3701 /**
3702 *******************************************************************************
3703 *
3704 * @brief
3705 * Resets the decoder state
3706 *
3707 * @par Description:
3708 * Resets the decoder state by calling ihevcd_init()
3709 *
3710 * @param[in] ps_codec_obj
3711 * Pointer to codec object at API level
3712 *
3713 * @param[in] pv_api_ip
3714 * Pointer to input argument structure
3715 *
3716 * @param[out] pv_api_op
3717 * Pointer to output argument structure
3718 *
3719 * @returns Status
3720 *
3721 * @remarks
3722 *
3723 *
3724 *******************************************************************************
3725 */
ihevcd_reset(iv_obj_t * ps_codec_obj,void * pv_api_ip,void * pv_api_op)3726 WORD32 ihevcd_reset(iv_obj_t *ps_codec_obj, void *pv_api_ip, void *pv_api_op)
3727 {
3728 codec_t *ps_codec;
3729 ivd_ctl_reset_op_t *s_ctl_reset_op = (ivd_ctl_reset_op_t *)pv_api_op;
3730 UNUSED(pv_api_ip);
3731 ps_codec = (codec_t *)(ps_codec_obj->pv_codec_handle);
3732
3733 if(ps_codec != NULL)
3734 {
3735 DEBUG("\nReset called \n");
3736 ihevcd_init(ps_codec);
3737 }
3738 else
3739 {
3740 DEBUG("\nReset called without Initializing the decoder\n");
3741 s_ctl_reset_op->u4_error_code = IHEVCD_INIT_NOT_DONE;
3742 }
3743
3744 return IV_SUCCESS;
3745 }
3746
3747 /**
3748 *******************************************************************************
3749 *
3750 * @brief
3751 * Releases display buffer from application to codec to signal to the codec
3752 * that it can write to this buffer if required. Till release is called,
3753 * codec can not write to this buffer
3754 *
3755 * @par Description:
3756 * Marks the buffer as display done
3757 *
3758 * @param[in] ps_codec_obj
3759 * Pointer to codec object at API level
3760 *
3761 * @param[in] pv_api_ip
3762 * Pointer to input argument structure
3763 *
3764 * @param[out] pv_api_op
3765 * Pointer to output argument structure
3766 *
3767 * @returns Status
3768 *
3769 * @remarks
3770 *
3771 *
3772 *******************************************************************************
3773 */
3774
ihevcd_rel_display_frame(iv_obj_t * ps_codec_obj,void * pv_api_ip,void * pv_api_op)3775 WORD32 ihevcd_rel_display_frame(iv_obj_t *ps_codec_obj,
3776 void *pv_api_ip,
3777 void *pv_api_op)
3778 {
3779
3780 ivd_rel_display_frame_ip_t *ps_dec_rel_disp_ip;
3781 ivd_rel_display_frame_op_t *ps_dec_rel_disp_op;
3782
3783 codec_t *ps_codec = (codec_t *)ps_codec_obj->pv_codec_handle;
3784
3785 ps_dec_rel_disp_ip = (ivd_rel_display_frame_ip_t *)pv_api_ip;
3786 ps_dec_rel_disp_op = (ivd_rel_display_frame_op_t *)pv_api_op;
3787
3788 UNUSED(ps_dec_rel_disp_op);
3789
3790 if(0 == ps_codec->i4_share_disp_buf)
3791 {
3792 return IV_SUCCESS;
3793 }
3794
3795 ihevc_buf_mgr_release((buf_mgr_t *)ps_codec->pv_pic_buf_mgr, ps_dec_rel_disp_ip->u4_disp_buf_id, BUF_MGR_DISP);
3796
3797 return IV_SUCCESS;
3798 }
3799 /**
3800 *******************************************************************************
3801 *
3802 * @brief
3803 * Sets degrade params
3804 *
3805 * @par Description:
3806 * Sets degrade params.
3807 * Refer to ihevcd_cxa_ctl_degrade_ip_t definition for details
3808 *
3809 * @param[in] ps_codec_obj
3810 * Pointer to codec object at API level
3811 *
3812 * @param[in] pv_api_ip
3813 * Pointer to input argument structure
3814 *
3815 * @param[out] pv_api_op
3816 * Pointer to output argument structure
3817 *
3818 * @returns Status
3819 *
3820 * @remarks
3821 *
3822 *
3823 *******************************************************************************
3824 */
3825
ihevcd_set_degrade(iv_obj_t * ps_codec_obj,void * pv_api_ip,void * pv_api_op)3826 WORD32 ihevcd_set_degrade(iv_obj_t *ps_codec_obj,
3827 void *pv_api_ip,
3828 void *pv_api_op)
3829 {
3830 ihevcd_cxa_ctl_degrade_ip_t *ps_ip;
3831 ihevcd_cxa_ctl_degrade_op_t *ps_op;
3832 codec_t *ps_codec = (codec_t *)ps_codec_obj->pv_codec_handle;
3833
3834 ps_ip = (ihevcd_cxa_ctl_degrade_ip_t *)pv_api_ip;
3835 ps_op = (ihevcd_cxa_ctl_degrade_op_t *)pv_api_op;
3836
3837 ps_codec->i4_degrade_type = ps_ip->i4_degrade_type;
3838 ps_codec->i4_nondegrade_interval = ps_ip->i4_nondegrade_interval;
3839 ps_codec->i4_degrade_pics = ps_ip->i4_degrade_pics;
3840
3841 ps_op->u4_error_code = 0;
3842 ps_codec->i4_degrade_pic_cnt = 0;
3843
3844 return IV_SUCCESS;
3845 }
3846
3847
3848 /**
3849 *******************************************************************************
3850 *
3851 * @brief
3852 * Gets frame dimensions/offsets
3853 *
3854 * @par Description:
3855 * Gets frame buffer chararacteristics such a x & y offsets display and
3856 * buffer dimensions
3857 *
3858 * @param[in] ps_codec_obj
3859 * Pointer to codec object at API level
3860 *
3861 * @param[in] pv_api_ip
3862 * Pointer to input argument structure
3863 *
3864 * @param[out] pv_api_op
3865 * Pointer to output argument structure
3866 *
3867 * @returns Status
3868 *
3869 * @remarks
3870 *
3871 *
3872 *******************************************************************************
3873 */
3874
ihevcd_get_frame_dimensions(iv_obj_t * ps_codec_obj,void * pv_api_ip,void * pv_api_op)3875 WORD32 ihevcd_get_frame_dimensions(iv_obj_t *ps_codec_obj,
3876 void *pv_api_ip,
3877 void *pv_api_op)
3878 {
3879 ihevcd_cxa_ctl_get_frame_dimensions_ip_t *ps_ip;
3880 ihevcd_cxa_ctl_get_frame_dimensions_op_t *ps_op;
3881 codec_t *ps_codec = (codec_t *)ps_codec_obj->pv_codec_handle;
3882 WORD32 disp_wd, disp_ht, buffer_wd, buffer_ht, x_offset, y_offset;
3883 ps_ip = (ihevcd_cxa_ctl_get_frame_dimensions_ip_t *)pv_api_ip;
3884 ps_op = (ihevcd_cxa_ctl_get_frame_dimensions_op_t *)pv_api_op;
3885 UNUSED(ps_ip);
3886 if(ps_codec->i4_sps_done)
3887 {
3888 disp_wd = ps_codec->i4_disp_wd;
3889 disp_ht = ps_codec->i4_disp_ht;
3890
3891 if(0 == ps_codec->i4_share_disp_buf)
3892 {
3893 buffer_wd = disp_wd;
3894 buffer_ht = disp_ht;
3895 }
3896 else
3897 {
3898 buffer_wd = ps_codec->i4_strd;
3899 buffer_ht = ps_codec->i4_ht + PAD_HT;
3900 }
3901 }
3902 else
3903 {
3904
3905 disp_wd = ps_codec->i4_max_wd;
3906 disp_ht = ps_codec->i4_max_ht;
3907
3908 if(0 == ps_codec->i4_share_disp_buf)
3909 {
3910 buffer_wd = disp_wd;
3911 buffer_ht = disp_ht;
3912 }
3913 else
3914 {
3915 buffer_wd = ALIGN16(disp_wd) + PAD_WD;
3916 buffer_ht = ALIGN16(disp_ht) + PAD_HT;
3917
3918 }
3919 }
3920 if(ps_codec->i4_strd > buffer_wd)
3921 buffer_wd = ps_codec->i4_strd;
3922
3923 if(0 == ps_codec->i4_share_disp_buf)
3924 {
3925 x_offset = 0;
3926 y_offset = 0;
3927 }
3928 else
3929 {
3930 y_offset = PAD_TOP;
3931 x_offset = PAD_LEFT;
3932 }
3933
3934 ps_op->u4_disp_wd[0] = disp_wd;
3935 ps_op->u4_disp_ht[0] = disp_ht;
3936 ps_op->u4_buffer_wd[0] = buffer_wd;
3937 ps_op->u4_buffer_ht[0] = buffer_ht;
3938 ps_op->u4_x_offset[0] = x_offset;
3939 ps_op->u4_y_offset[0] = y_offset;
3940
3941 ps_op->u4_disp_wd[1] = ps_op->u4_disp_wd[2] = ((ps_op->u4_disp_wd[0] + 1)
3942 >> 1);
3943 ps_op->u4_disp_ht[1] = ps_op->u4_disp_ht[2] = ((ps_op->u4_disp_ht[0] + 1)
3944 >> 1);
3945 ps_op->u4_buffer_wd[1] = ps_op->u4_buffer_wd[2] = (ps_op->u4_buffer_wd[0]
3946 >> 1);
3947 ps_op->u4_buffer_ht[1] = ps_op->u4_buffer_ht[2] = (ps_op->u4_buffer_ht[0]
3948 >> 1);
3949 ps_op->u4_x_offset[1] = ps_op->u4_x_offset[2] = (ps_op->u4_x_offset[0]
3950 >> 1);
3951 ps_op->u4_y_offset[1] = ps_op->u4_y_offset[2] = (ps_op->u4_y_offset[0]
3952 >> 1);
3953
3954 if((ps_codec->e_chroma_fmt == IV_YUV_420SP_UV)
3955 || (ps_codec->e_chroma_fmt == IV_YUV_420SP_VU))
3956 {
3957 ps_op->u4_disp_wd[2] = 0;
3958 ps_op->u4_disp_ht[2] = 0;
3959 ps_op->u4_buffer_wd[2] = 0;
3960 ps_op->u4_buffer_ht[2] = 0;
3961 ps_op->u4_x_offset[2] = 0;
3962 ps_op->u4_y_offset[2] = 0;
3963
3964 ps_op->u4_disp_wd[1] <<= 1;
3965 ps_op->u4_buffer_wd[1] <<= 1;
3966 ps_op->u4_x_offset[1] <<= 1;
3967 }
3968
3969 return IV_SUCCESS;
3970
3971 }
3972
3973
3974 /**
3975 *******************************************************************************
3976 *
3977 * @brief
3978 * Gets vui parameters
3979 *
3980 * @par Description:
3981 * Gets VUI parameters
3982 *
3983 * @param[in] ps_codec_obj
3984 * Pointer to codec object at API level
3985 *
3986 * @param[in] pv_api_ip
3987 * Pointer to input argument structure
3988 *
3989 * @param[out] pv_api_op
3990 * Pointer to output argument structure
3991 *
3992 * @returns Status
3993 *
3994 * @remarks
3995 *
3996 *
3997 *******************************************************************************
3998 */
ihevcd_get_vui_params(iv_obj_t * ps_codec_obj,void * pv_api_ip,void * pv_api_op)3999 WORD32 ihevcd_get_vui_params(iv_obj_t *ps_codec_obj,
4000 void *pv_api_ip,
4001 void *pv_api_op)
4002 {
4003 ihevcd_cxa_ctl_get_vui_params_ip_t *ps_ip;
4004 ihevcd_cxa_ctl_get_vui_params_op_t *ps_op;
4005 codec_t *ps_codec = (codec_t *)ps_codec_obj->pv_codec_handle;
4006 sps_t *ps_sps;
4007 vui_t *ps_vui;
4008 WORD32 i;
4009
4010 ps_ip = (ihevcd_cxa_ctl_get_vui_params_ip_t *)pv_api_ip;
4011 ps_op = (ihevcd_cxa_ctl_get_vui_params_op_t *)pv_api_op;
4012
4013 if(0 == ps_codec->i4_sps_done)
4014 {
4015 ps_op->u4_error_code = IHEVCD_VUI_PARAMS_NOT_FOUND;
4016 return IV_FAIL;
4017 }
4018
4019 ps_sps = ps_codec->s_parse.ps_sps;
4020 if(0 == ps_sps->i1_sps_valid || 0 == ps_sps->i1_vui_parameters_present_flag)
4021 {
4022 WORD32 sps_idx = 0;
4023 ps_sps = ps_codec->ps_sps_base;
4024
4025 while((0 == ps_sps->i1_sps_valid) || (0 == ps_sps->i1_vui_parameters_present_flag))
4026 {
4027 sps_idx++;
4028 ps_sps++;
4029
4030 if(sps_idx == MAX_SPS_CNT - 1)
4031 {
4032 ps_op->u4_error_code = IHEVCD_VUI_PARAMS_NOT_FOUND;
4033 return IV_FAIL;
4034 }
4035 }
4036 }
4037
4038 ps_vui = &ps_sps->s_vui_parameters;
4039 UNUSED(ps_ip);
4040
4041 ps_op->u1_aspect_ratio_info_present_flag = ps_vui->u1_aspect_ratio_info_present_flag;
4042 ps_op->u1_aspect_ratio_idc = ps_vui->u1_aspect_ratio_idc;
4043 ps_op->u2_sar_width = ps_vui->u2_sar_width;
4044 ps_op->u2_sar_height = ps_vui->u2_sar_height;
4045 ps_op->u1_overscan_info_present_flag = ps_vui->u1_overscan_info_present_flag;
4046 ps_op->u1_overscan_appropriate_flag = ps_vui->u1_overscan_appropriate_flag;
4047 ps_op->u1_video_signal_type_present_flag = ps_vui->u1_video_signal_type_present_flag;
4048 ps_op->u1_video_format = ps_vui->u1_video_format;
4049 ps_op->u1_video_full_range_flag = ps_vui->u1_video_full_range_flag;
4050 ps_op->u1_colour_description_present_flag = ps_vui->u1_colour_description_present_flag;
4051 ps_op->u1_colour_primaries = ps_vui->u1_colour_primaries;
4052 ps_op->u1_transfer_characteristics = ps_vui->u1_transfer_characteristics;
4053 ps_op->u1_matrix_coefficients = ps_vui->u1_matrix_coefficients;
4054 ps_op->u1_chroma_loc_info_present_flag = ps_vui->u1_chroma_loc_info_present_flag;
4055 ps_op->u1_chroma_sample_loc_type_top_field = ps_vui->u1_chroma_sample_loc_type_top_field;
4056 ps_op->u1_chroma_sample_loc_type_bottom_field = ps_vui->u1_chroma_sample_loc_type_bottom_field;
4057 ps_op->u1_neutral_chroma_indication_flag = ps_vui->u1_neutral_chroma_indication_flag;
4058 ps_op->u1_field_seq_flag = ps_vui->u1_field_seq_flag;
4059 ps_op->u1_frame_field_info_present_flag = ps_vui->u1_frame_field_info_present_flag;
4060 ps_op->u1_default_display_window_flag = ps_vui->u1_default_display_window_flag;
4061 ps_op->u4_def_disp_win_left_offset = ps_vui->u4_def_disp_win_left_offset;
4062 ps_op->u4_def_disp_win_right_offset = ps_vui->u4_def_disp_win_right_offset;
4063 ps_op->u4_def_disp_win_top_offset = ps_vui->u4_def_disp_win_top_offset;
4064 ps_op->u4_def_disp_win_bottom_offset = ps_vui->u4_def_disp_win_bottom_offset;
4065 ps_op->u1_vui_hrd_parameters_present_flag = ps_vui->u1_vui_hrd_parameters_present_flag;
4066 ps_op->u1_vui_timing_info_present_flag = ps_vui->u1_vui_timing_info_present_flag;
4067 ps_op->u4_vui_num_units_in_tick = ps_vui->u4_vui_num_units_in_tick;
4068 ps_op->u4_vui_time_scale = ps_vui->u4_vui_time_scale;
4069 ps_op->u1_poc_proportional_to_timing_flag = ps_vui->u1_poc_proportional_to_timing_flag;
4070 ps_op->u1_num_ticks_poc_diff_one_minus1 = ps_vui->u1_num_ticks_poc_diff_one_minus1;
4071 ps_op->u1_bitstream_restriction_flag = ps_vui->u1_bitstream_restriction_flag;
4072 ps_op->u1_tiles_fixed_structure_flag = ps_vui->u1_tiles_fixed_structure_flag;
4073 ps_op->u1_motion_vectors_over_pic_boundaries_flag = ps_vui->u1_motion_vectors_over_pic_boundaries_flag;
4074 ps_op->u1_restricted_ref_pic_lists_flag = ps_vui->u1_restricted_ref_pic_lists_flag;
4075 ps_op->u4_min_spatial_segmentation_idc = ps_vui->u4_min_spatial_segmentation_idc;
4076 ps_op->u1_max_bytes_per_pic_denom = ps_vui->u1_max_bytes_per_pic_denom;
4077 ps_op->u1_max_bits_per_mincu_denom = ps_vui->u1_max_bits_per_mincu_denom;
4078 ps_op->u1_log2_max_mv_length_horizontal = ps_vui->u1_log2_max_mv_length_horizontal;
4079 ps_op->u1_log2_max_mv_length_vertical = ps_vui->u1_log2_max_mv_length_vertical;
4080
4081
4082 /* HRD parameters */
4083 ps_op->u1_timing_info_present_flag = ps_vui->s_vui_hrd_parameters.u1_timing_info_present_flag;
4084 ps_op->u4_num_units_in_tick = ps_vui->s_vui_hrd_parameters.u4_num_units_in_tick;
4085 ps_op->u4_time_scale = ps_vui->s_vui_hrd_parameters.u4_time_scale;
4086 ps_op->u1_nal_hrd_parameters_present_flag = ps_vui->s_vui_hrd_parameters.u1_nal_hrd_parameters_present_flag;
4087 ps_op->u1_vcl_hrd_parameters_present_flag = ps_vui->s_vui_hrd_parameters.u1_vcl_hrd_parameters_present_flag;
4088 ps_op->u1_cpbdpb_delays_present_flag = ps_vui->s_vui_hrd_parameters.u1_cpbdpb_delays_present_flag;
4089 ps_op->u1_sub_pic_cpb_params_present_flag = ps_vui->s_vui_hrd_parameters.u1_sub_pic_cpb_params_present_flag;
4090 ps_op->u1_tick_divisor_minus2 = ps_vui->s_vui_hrd_parameters.u1_tick_divisor_minus2;
4091 ps_op->u1_du_cpb_removal_delay_increment_length_minus1 = ps_vui->s_vui_hrd_parameters.u1_du_cpb_removal_delay_increment_length_minus1;
4092 ps_op->u1_sub_pic_cpb_params_in_pic_timing_sei_flag = ps_vui->s_vui_hrd_parameters.u1_sub_pic_cpb_params_in_pic_timing_sei_flag;
4093 ps_op->u1_dpb_output_delay_du_length_minus1 = ps_vui->s_vui_hrd_parameters.u1_dpb_output_delay_du_length_minus1;
4094 ps_op->u4_bit_rate_scale = ps_vui->s_vui_hrd_parameters.u4_bit_rate_scale;
4095 ps_op->u4_cpb_size_scale = ps_vui->s_vui_hrd_parameters.u4_cpb_size_scale;
4096 ps_op->u4_cpb_size_du_scale = ps_vui->s_vui_hrd_parameters.u4_cpb_size_du_scale;
4097 ps_op->u1_initial_cpb_removal_delay_length_minus1 = ps_vui->s_vui_hrd_parameters.u1_initial_cpb_removal_delay_length_minus1;
4098 ps_op->u1_au_cpb_removal_delay_length_minus1 = ps_vui->s_vui_hrd_parameters.u1_au_cpb_removal_delay_length_minus1;
4099 ps_op->u1_dpb_output_delay_length_minus1 = ps_vui->s_vui_hrd_parameters.u1_dpb_output_delay_length_minus1;
4100
4101 for(i = 0; i < 6; i++)
4102 {
4103 ps_op->au1_fixed_pic_rate_general_flag[i] = ps_vui->s_vui_hrd_parameters.au1_fixed_pic_rate_general_flag[i];
4104 ps_op->au1_fixed_pic_rate_within_cvs_flag[i] = ps_vui->s_vui_hrd_parameters.au1_fixed_pic_rate_within_cvs_flag[i];
4105 ps_op->au1_elemental_duration_in_tc_minus1[i] = ps_vui->s_vui_hrd_parameters.au1_elemental_duration_in_tc_minus1[i];
4106 ps_op->au1_low_delay_hrd_flag[i] = ps_vui->s_vui_hrd_parameters.au1_low_delay_hrd_flag[i];
4107 ps_op->au1_cpb_cnt_minus1[i] = ps_vui->s_vui_hrd_parameters.au1_cpb_cnt_minus1[i];
4108 }
4109
4110
4111 return IV_SUCCESS;
4112 }
4113
4114 /**
4115 *******************************************************************************
4116 *
4117 * @brief
4118 * Sets Processor type
4119 *
4120 * @par Description:
4121 * Sets Processor type
4122 *
4123 * @param[in] ps_codec_obj
4124 * Pointer to codec object at API level
4125 *
4126 * @param[in] pv_api_ip
4127 * Pointer to input argument structure
4128 *
4129 * @param[out] pv_api_op
4130 * Pointer to output argument structure
4131 *
4132 * @returns Status
4133 *
4134 * @remarks
4135 *
4136 *
4137 *******************************************************************************
4138 */
4139
ihevcd_set_processor(iv_obj_t * ps_codec_obj,void * pv_api_ip,void * pv_api_op)4140 WORD32 ihevcd_set_processor(iv_obj_t *ps_codec_obj,
4141 void *pv_api_ip,
4142 void *pv_api_op)
4143 {
4144 ihevcd_cxa_ctl_set_processor_ip_t *ps_ip;
4145 ihevcd_cxa_ctl_set_processor_op_t *ps_op;
4146 codec_t *ps_codec = (codec_t *)ps_codec_obj->pv_codec_handle;
4147
4148 ps_ip = (ihevcd_cxa_ctl_set_processor_ip_t *)pv_api_ip;
4149 ps_op = (ihevcd_cxa_ctl_set_processor_op_t *)pv_api_op;
4150
4151 ps_codec->e_processor_arch = (IVD_ARCH_T)ps_ip->u4_arch;
4152 ps_codec->e_processor_soc = (IVD_SOC_T)ps_ip->u4_soc;
4153
4154 ihevcd_init_function_ptr(ps_codec);
4155
4156 ihevcd_update_function_ptr(ps_codec);
4157
4158 if(ps_codec->e_processor_soc && (ps_codec->e_processor_soc <= SOC_HISI_37X))
4159 {
4160 /* 8th bit indicates if format conversion is to be done ahead */
4161 if(ps_codec->e_processor_soc & 0x80)
4162 ps_codec->u4_enable_fmt_conv_ahead = 1;
4163
4164 /* Lower 7 bit indicate NCTB - if non-zero */
4165 ps_codec->e_processor_soc &= 0x7F;
4166
4167 if(ps_codec->e_processor_soc)
4168 ps_codec->u4_nctb = ps_codec->e_processor_soc;
4169
4170
4171 }
4172
4173 if((ps_codec->e_processor_soc == SOC_HISI_37X) && (ps_codec->i4_num_cores == 2))
4174 {
4175 ps_codec->u4_nctb = 2;
4176 }
4177
4178
4179 ps_op->u4_error_code = 0;
4180 return IV_SUCCESS;
4181 }
4182
4183 /**
4184 *******************************************************************************
4185 *
4186 * @brief
4187 * Sets Number of cores that can be used in the codec. Codec uses these many
4188 * threads for decoding
4189 *
4190 * @par Description:
4191 * Sets number of cores
4192 *
4193 * @param[in] ps_codec_obj
4194 * Pointer to codec object at API level
4195 *
4196 * @param[in] pv_api_ip
4197 * Pointer to input argument structure
4198 *
4199 * @param[out] pv_api_op
4200 * Pointer to output argument structure
4201 *
4202 * @returns Status
4203 *
4204 * @remarks
4205 *
4206 *
4207 *******************************************************************************
4208 */
4209
ihevcd_set_num_cores(iv_obj_t * ps_codec_obj,void * pv_api_ip,void * pv_api_op)4210 WORD32 ihevcd_set_num_cores(iv_obj_t *ps_codec_obj,
4211 void *pv_api_ip,
4212 void *pv_api_op)
4213 {
4214 ihevcd_cxa_ctl_set_num_cores_ip_t *ps_ip;
4215 ihevcd_cxa_ctl_set_num_cores_op_t *ps_op;
4216 codec_t *ps_codec = (codec_t *)ps_codec_obj->pv_codec_handle;
4217
4218 ps_ip = (ihevcd_cxa_ctl_set_num_cores_ip_t *)pv_api_ip;
4219 ps_op = (ihevcd_cxa_ctl_set_num_cores_op_t *)pv_api_op;
4220
4221 #ifdef MULTICORE
4222 ps_codec->i4_num_cores = ps_ip->u4_num_cores;
4223 #else
4224 ps_codec->i4_num_cores = 1;
4225 #endif
4226 ps_op->u4_error_code = 0;
4227 return IV_SUCCESS;
4228 }
4229 /**
4230 *******************************************************************************
4231 *
4232 * @brief
4233 * Codec control call
4234 *
4235 * @par Description:
4236 * Codec control call which in turn calls appropriate calls based on
4237 * subcommand
4238 *
4239 * @param[in] ps_codec_obj
4240 * Pointer to codec object at API level
4241 *
4242 * @param[in] pv_api_ip
4243 * Pointer to input argument structure
4244 *
4245 * @param[out] pv_api_op
4246 * Pointer to output argument structure
4247 *
4248 * @returns Status
4249 *
4250 * @remarks
4251 *
4252 *
4253 *******************************************************************************
4254 */
4255
ihevcd_ctl(iv_obj_t * ps_codec_obj,void * pv_api_ip,void * pv_api_op)4256 WORD32 ihevcd_ctl(iv_obj_t *ps_codec_obj, void *pv_api_ip, void *pv_api_op)
4257 {
4258 ivd_ctl_set_config_ip_t *ps_ctl_ip;
4259 ivd_ctl_set_config_op_t *ps_ctl_op;
4260 WORD32 ret = 0;
4261 WORD32 subcommand;
4262 codec_t *ps_codec = (codec_t *)ps_codec_obj->pv_codec_handle;
4263
4264 ps_ctl_ip = (ivd_ctl_set_config_ip_t *)pv_api_ip;
4265 ps_ctl_op = (ivd_ctl_set_config_op_t *)pv_api_op;
4266
4267 if(ps_codec->i4_init_done != 1)
4268 {
4269 ps_ctl_op->u4_error_code |= 1 << IVD_FATALERROR;
4270 ps_ctl_op->u4_error_code |= IHEVCD_INIT_NOT_DONE;
4271 return IV_FAIL;
4272 }
4273 subcommand = ps_ctl_ip->e_sub_cmd;
4274
4275 switch(subcommand)
4276 {
4277 case IVD_CMD_CTL_GETPARAMS:
4278 ret = ihevcd_get_status(ps_codec_obj, (void *)pv_api_ip,
4279 (void *)pv_api_op);
4280 break;
4281 case IVD_CMD_CTL_SETPARAMS:
4282 ret = ihevcd_set_params(ps_codec_obj, (void *)pv_api_ip,
4283 (void *)pv_api_op);
4284 break;
4285 case IVD_CMD_CTL_RESET:
4286 ret = ihevcd_reset(ps_codec_obj, (void *)pv_api_ip,
4287 (void *)pv_api_op);
4288 break;
4289 case IVD_CMD_CTL_SETDEFAULT:
4290 {
4291 ivd_ctl_set_config_op_t *s_ctl_dynparams_op =
4292 (ivd_ctl_set_config_op_t *)pv_api_op;
4293
4294 ret = ihevcd_set_default_params(ps_codec);
4295 if(IV_SUCCESS == ret)
4296 s_ctl_dynparams_op->u4_error_code = 0;
4297 break;
4298 }
4299 case IVD_CMD_CTL_FLUSH:
4300 ret = ihevcd_set_flush_mode(ps_codec_obj, (void *)pv_api_ip,
4301 (void *)pv_api_op);
4302 break;
4303 case IVD_CMD_CTL_GETBUFINFO:
4304 ret = ihevcd_get_buf_info(ps_codec_obj, (void *)pv_api_ip,
4305 (void *)pv_api_op);
4306 break;
4307 case IVD_CMD_CTL_GETVERSION:
4308 {
4309 ivd_ctl_getversioninfo_ip_t *ps_ip;
4310 ivd_ctl_getversioninfo_op_t *ps_op;
4311 IV_API_CALL_STATUS_T ret;
4312 ps_ip = (ivd_ctl_getversioninfo_ip_t *)pv_api_ip;
4313 ps_op = (ivd_ctl_getversioninfo_op_t *)pv_api_op;
4314
4315 ps_op->u4_error_code = IV_SUCCESS;
4316
4317 if((WORD32)ps_ip->u4_version_buffer_size <= 0)
4318 {
4319 ps_op->u4_error_code = IHEVCD_CXA_VERS_BUF_INSUFFICIENT;
4320 ret = IV_FAIL;
4321 }
4322 else
4323 {
4324 ret = ihevcd_get_version((CHAR *)ps_ip->pv_version_buffer,
4325 ps_ip->u4_version_buffer_size);
4326 if(ret != IV_SUCCESS)
4327 {
4328 ps_op->u4_error_code = IHEVCD_CXA_VERS_BUF_INSUFFICIENT;
4329 ret = IV_FAIL;
4330 }
4331 }
4332 }
4333 break;
4334 case IHEVCD_CXA_CMD_CTL_DEGRADE:
4335 ret = ihevcd_set_degrade(ps_codec_obj, (void *)pv_api_ip,
4336 (void *)pv_api_op);
4337 break;
4338 case IHEVCD_CXA_CMD_CTL_SET_NUM_CORES:
4339 ret = ihevcd_set_num_cores(ps_codec_obj, (void *)pv_api_ip,
4340 (void *)pv_api_op);
4341 break;
4342 case IHEVCD_CXA_CMD_CTL_GET_BUFFER_DIMENSIONS:
4343 ret = ihevcd_get_frame_dimensions(ps_codec_obj, (void *)pv_api_ip,
4344 (void *)pv_api_op);
4345 break;
4346 case IHEVCD_CXA_CMD_CTL_GET_VUI_PARAMS:
4347 ret = ihevcd_get_vui_params(ps_codec_obj, (void *)pv_api_ip,
4348 (void *)pv_api_op);
4349 break;
4350 case IHEVCD_CXA_CMD_CTL_SET_PROCESSOR:
4351 ret = ihevcd_set_processor(ps_codec_obj, (void *)pv_api_ip,
4352 (void *)pv_api_op);
4353 break;
4354 default:
4355 DEBUG("\nDo nothing\n");
4356 break;
4357 }
4358
4359 return ret;
4360 }
4361
4362 /**
4363 *******************************************************************************
4364 *
4365 * @brief
4366 * Codecs entry point function. All the function calls to the codec are
4367 * done using this function with different values specified in command
4368 *
4369 * @par Description:
4370 * Arguments are tested for validity and then based on the command
4371 * appropriate function is called
4372 *
4373 * @param[in] ps_handle
4374 * API level handle for codec
4375 *
4376 * @param[in] pv_api_ip
4377 * Input argument structure
4378 *
4379 * @param[out] pv_api_op
4380 * Output argument structure
4381 *
4382 * @returns Status of the function corresponding to command
4383 *
4384 * @remarks
4385 *
4386 *
4387 *******************************************************************************
4388 */
ihevcd_cxa_api_function(iv_obj_t * ps_handle,void * pv_api_ip,void * pv_api_op)4389 IV_API_CALL_STATUS_T ihevcd_cxa_api_function(iv_obj_t *ps_handle,
4390 void *pv_api_ip,
4391 void *pv_api_op)
4392 {
4393 WORD32 command;
4394 UWORD32 *pu4_ptr_cmd;
4395 WORD32 ret = 0;
4396 IV_API_CALL_STATUS_T e_status;
4397 e_status = api_check_struct_sanity(ps_handle, pv_api_ip, pv_api_op);
4398
4399 if(e_status != IV_SUCCESS)
4400 {
4401 DEBUG("error code = %d\n", *((UWORD32 *)pv_api_op + 1));
4402 return IV_FAIL;
4403 }
4404
4405 pu4_ptr_cmd = (UWORD32 *)pv_api_ip;
4406 pu4_ptr_cmd++;
4407
4408 command = *pu4_ptr_cmd;
4409
4410 switch(command)
4411 {
4412 case IV_CMD_GET_NUM_MEM_REC:
4413 ret = ihevcd_get_num_rec((void *)pv_api_ip, (void *)pv_api_op);
4414
4415 break;
4416 case IV_CMD_FILL_NUM_MEM_REC:
4417
4418 ret = ihevcd_fill_num_mem_rec((void *)pv_api_ip, (void *)pv_api_op);
4419 break;
4420 case IV_CMD_INIT:
4421 ret = ihevcd_init_mem_rec(ps_handle, (void *)pv_api_ip,
4422 (void *)pv_api_op);
4423 break;
4424
4425 case IVD_CMD_VIDEO_DECODE:
4426 ret = ihevcd_decode(ps_handle, (void *)pv_api_ip, (void *)pv_api_op);
4427 break;
4428
4429 case IVD_CMD_GET_DISPLAY_FRAME:
4430 //ret = ihevcd_get_display_frame(ps_handle,(void *)pv_api_ip,(void *)pv_api_op);
4431 break;
4432
4433 case IVD_CMD_SET_DISPLAY_FRAME:
4434 ret = ihevcd_set_display_frame(ps_handle, (void *)pv_api_ip,
4435 (void *)pv_api_op);
4436
4437 break;
4438
4439 case IVD_CMD_REL_DISPLAY_FRAME:
4440 ret = ihevcd_rel_display_frame(ps_handle, (void *)pv_api_ip,
4441 (void *)pv_api_op);
4442 break;
4443
4444 case IV_CMD_RETRIEVE_MEMREC:
4445 ret = ihevcd_retrieve_memrec(ps_handle, (void *)pv_api_ip,
4446 (void *)pv_api_op);
4447 break;
4448
4449 case IVD_CMD_VIDEO_CTL:
4450 ret = ihevcd_ctl(ps_handle, (void *)pv_api_ip, (void *)pv_api_op);
4451 break;
4452 default:
4453 ret = IV_FAIL;
4454 break;
4455 }
4456
4457 return (IV_API_CALL_STATUS_T)ret;
4458 }
4459
4460