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 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 */ 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 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 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 */ 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 */ 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 */ 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 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 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 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 */ 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 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 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 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 */ 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