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