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 1527 ps_codec->i4_prev_poc_msb = 0; 1528 ps_codec->i4_prev_poc_lsb = -1; 1529 ps_codec->i4_max_prev_poc_lsb = -1; 1530 ps_codec->s_parse.i4_abs_pic_order_cnt = -1; 1531 1532 /* Set ref chroma format by default to 420SP UV interleaved */ 1533 ps_codec->e_ref_chroma_fmt = IV_YUV_420SP_UV; 1534 1535 /* If the codec is in shared mode and required format is 420 SP VU interleaved then change 1536 * reference buffers chroma format 1537 */ 1538 if(IV_YUV_420SP_VU == ps_codec->e_chroma_fmt) 1539 { 1540 ps_codec->e_ref_chroma_fmt = IV_YUV_420SP_VU; 1541 } 1542 1543 1544 1545 ps_codec->i4_disable_deblk_pic = 0; 1546 1547 ps_codec->i4_degrade_pic_cnt = 0; 1548 ps_codec->i4_degrade_pics = 0; 1549 ps_codec->i4_degrade_type = 0; 1550 ps_codec->i4_disable_sao_pic = 0; 1551 ps_codec->i4_fullpel_inter_pred = 0; 1552 ps_codec->u4_enable_fmt_conv_ahead = 0; 1553 1554 { 1555 sps_t *ps_sps = ps_codec->ps_sps_base; 1556 pps_t *ps_pps = ps_codec->ps_pps_base; 1557 1558 for(i = 0; i < MAX_SPS_CNT; i++) 1559 { 1560 ps_sps->i1_sps_valid = 0; 1561 ps_sps++; 1562 } 1563 1564 for(i = 0; i < MAX_PPS_CNT; i++) 1565 { 1566 ps_pps->i1_pps_valid = 0; 1567 ps_pps++; 1568 } 1569 } 1570 1571 ihevcd_set_default_params(ps_codec); 1572 ps_codec->pv_proc_jobq = ihevcd_jobq_init(ps_codec->pv_proc_jobq_buf, ps_codec->i4_proc_jobq_buf_size); 1573 RETURN_IF((ps_codec->pv_proc_jobq == NULL), IV_FAIL); 1574 1575 /* Update the jobq context to all the threads */ 1576 ps_codec->s_parse.pv_proc_jobq = ps_codec->pv_proc_jobq; 1577 for(i = 0; i < MAX_PROCESS_THREADS; i++) 1578 { 1579 ps_codec->as_process[i].pv_proc_jobq = ps_codec->pv_proc_jobq; 1580 ps_codec->as_process[i].i4_id = i; 1581 ps_codec->as_process[i].ps_codec = ps_codec; 1582 1583 /* Set the following to zero assuming it is a single core solution 1584 * When threads are launched these will be set appropriately 1585 */ 1586 ps_codec->as_process[i].i4_check_parse_status = 0; 1587 ps_codec->as_process[i].i4_check_proc_status = 0; 1588 } 1589 /* Initialize MV Bank buffer manager */ 1590 ihevc_buf_mgr_init((buf_mgr_t *)ps_codec->pv_mv_buf_mgr); 1591 1592 /* Initialize Picture buffer manager */ 1593 ihevc_buf_mgr_init((buf_mgr_t *)ps_codec->pv_pic_buf_mgr); 1594 1595 ps_codec->ps_pic_buf = (pic_buf_t *)ps_codec->pv_pic_buf_base; 1596 1597 memset(ps_codec->ps_pic_buf, 0, BUF_MGR_MAX_CNT * sizeof(pic_buf_t)); 1598 1599 1600 1601 /* Initialize display buffer manager */ 1602 ihevc_disp_mgr_init((disp_mgr_t *)ps_codec->pv_disp_buf_mgr); 1603 1604 /* Initialize dpb manager */ 1605 ihevc_dpb_mgr_init((dpb_mgr_t *)ps_codec->pv_dpb_mgr); 1606 1607 ps_codec->e_processor_soc = SOC_GENERIC; 1608 /* The following can be over-ridden using soc parameter as a hack */ 1609 ps_codec->u4_nctb = 0x7FFFFFFF; 1610 ihevcd_init_arch(ps_codec); 1611 1612 ihevcd_init_function_ptr(ps_codec); 1613 1614 ihevcd_update_function_ptr(ps_codec); 1615 1616 return status; 1617 } 1618 1619 /** 1620 ******************************************************************************* 1621 * 1622 * @brief 1623 * Gets number of memory records required by the codec 1624 * 1625 * @par Description: 1626 * Gets codec mem record requirements and adds concealment modules 1627 * requirements 1628 * 1629 * @param[in] pv_api_ip 1630 * Pointer to input argument structure 1631 * 1632 * @param[out] pv_api_op 1633 * Pointer to output argument structure 1634 * 1635 * @returns Status 1636 * 1637 * @remarks 1638 * 1639 * 1640 ******************************************************************************* 1641 */ 1642 WORD32 ihevcd_get_num_rec(void *pv_api_ip, void *pv_api_op) 1643 { 1644 1645 iv_num_mem_rec_op_t *ps_mem_q_op; 1646 1647 UNUSED(pv_api_ip); 1648 ps_mem_q_op = (iv_num_mem_rec_op_t *)pv_api_op; 1649 ps_mem_q_op->u4_num_mem_rec = MEM_REC_CNT; 1650 DEBUG("Get num mem records without concealment %d\n", 1651 ps_mem_q_op->u4_num_mem_rec); 1652 #ifdef APPLY_CONCEALMENT 1653 { 1654 IV_API_CALL_STATUS_T status; 1655 icncl_num_mem_rec_ip_t cncl_mem_ip; 1656 icncl_num_mem_rec_op_t cncl_mem_op; 1657 1658 cncl_mem_ip.s_ivd_num_rec_ip_t.e_cmd = IV_CMD_GET_NUM_MEM_REC; 1659 cncl_mem_ip.s_ivd_num_rec_ip_t.u4_size = sizeof(icncl_num_mem_rec_ip_t); 1660 1661 status = icncl_api_function(NULL, (void *)&cncl_mem_ip, (void *)&cncl_mem_op); 1662 1663 if(status == IV_SUCCESS) 1664 { 1665 /* Add the concealment library's memory requirements */ 1666 ps_mem_q_op->u4_num_mem_rec += cncl_mem_op.s_ivd_num_mem_rec_op_t.u4_num_mem_rec; 1667 DEBUG("Get num mem records %d\n", ps_mem_q_op->u4_num_mem_rec); 1668 return status; /* Nothing else to do, return */ 1669 } 1670 else 1671 { 1672 /* 1673 * Something went wrong with the concealment library call. 1674 */ 1675 DEBUG("ERROR: Get num mem records %d\n", ps_mem_q_op->u4_num_mem_rec); 1676 return status; 1677 } 1678 1679 } 1680 #endif //APPLY_CONCEALMENT 1681 1682 1683 return IV_SUCCESS; 1684 1685 } 1686 1687 /** 1688 ******************************************************************************* 1689 * 1690 * @brief 1691 * Fills memory requirements of the codec 1692 * 1693 * @par Description: 1694 * Gets codec mem record requirements and adds concealment modules 1695 * requirements 1696 * 1697 * @param[in] pv_api_ip 1698 * Pointer to input argument structure 1699 * 1700 * @param[out] pv_api_op 1701 * Pointer to output argument structure 1702 * 1703 * @returns Status 1704 * 1705 * @remarks 1706 * 1707 * 1708 ******************************************************************************* 1709 */ 1710 WORD32 ihevcd_fill_num_mem_rec(void *pv_api_ip, void *pv_api_op) 1711 { 1712 1713 ihevcd_cxa_fill_mem_rec_ip_t *ps_mem_q_ip; 1714 ihevcd_cxa_fill_mem_rec_op_t *ps_mem_q_op; 1715 WORD32 level; 1716 WORD32 num_reorder_frames; 1717 WORD32 num_ref_frames; 1718 WORD32 num_extra_disp_bufs; 1719 WORD32 max_dpb_size; 1720 1721 iv_mem_rec_t *ps_mem_rec; 1722 iv_mem_rec_t *ps_mem_rec_base; 1723 WORD32 no_of_mem_rec_filled; 1724 WORD32 chroma_format, share_disp_buf; 1725 WORD32 max_ctb_cnt; 1726 WORD32 max_wd_luma, max_wd_chroma; 1727 WORD32 max_ht_luma, max_ht_chroma; 1728 WORD32 max_tile_cols, max_tile_rows; 1729 WORD32 max_ctb_rows, max_ctb_cols; 1730 WORD32 max_num_cu_cols; 1731 WORD32 i; 1732 WORD32 max_num_4x4_cols; 1733 IV_API_CALL_STATUS_T status = IV_SUCCESS; 1734 no_of_mem_rec_filled = 0; 1735 1736 //TODO: Remove as and when the following are used 1737 UNUSED(num_extra_disp_bufs); 1738 UNUSED(no_of_mem_rec_filled); 1739 UNUSED(max_wd_chroma); 1740 UNUSED(max_ht_chroma); 1741 1742 ps_mem_q_ip = (ihevcd_cxa_fill_mem_rec_ip_t *)pv_api_ip; 1743 ps_mem_q_op = (ihevcd_cxa_fill_mem_rec_op_t *)pv_api_op; 1744 1745 if(ps_mem_q_ip->s_ivd_fill_mem_rec_ip_t.u4_size 1746 > offsetof(ihevcd_cxa_fill_mem_rec_ip_t, i4_level)) 1747 { 1748 level = ps_mem_q_ip->i4_level; 1749 /* Spec requires level should be multiplied by 30 1750 * API has values where level is multiplied by 10. This keeps it consistent with H264 1751 * Because of the above differences, level is multiplied by 3 here. 1752 */ 1753 level *= 3; 1754 } 1755 else 1756 { 1757 level = MAX_LEVEL; 1758 } 1759 1760 if(ps_mem_q_ip->s_ivd_fill_mem_rec_ip_t.u4_size 1761 > offsetof(ihevcd_cxa_fill_mem_rec_ip_t, 1762 u4_num_reorder_frames)) 1763 { 1764 num_reorder_frames = ps_mem_q_ip->u4_num_reorder_frames; 1765 } 1766 else 1767 { 1768 num_reorder_frames = MAX_REF_CNT; 1769 } 1770 1771 if(ps_mem_q_ip->s_ivd_fill_mem_rec_ip_t.u4_size 1772 > offsetof(ihevcd_cxa_fill_mem_rec_ip_t, u4_num_ref_frames)) 1773 { 1774 num_ref_frames = ps_mem_q_ip->u4_num_ref_frames; 1775 } 1776 else 1777 { 1778 num_ref_frames = MAX_REF_CNT; 1779 } 1780 1781 if(ps_mem_q_ip->s_ivd_fill_mem_rec_ip_t.u4_size 1782 > offsetof(ihevcd_cxa_fill_mem_rec_ip_t, 1783 u4_num_extra_disp_buf)) 1784 { 1785 num_extra_disp_bufs = ps_mem_q_ip->u4_num_extra_disp_buf; 1786 } 1787 else 1788 { 1789 num_extra_disp_bufs = 0; 1790 } 1791 1792 if(ps_mem_q_ip->s_ivd_fill_mem_rec_ip_t.u4_size 1793 > offsetof(ihevcd_cxa_fill_mem_rec_ip_t, u4_share_disp_buf)) 1794 { 1795 #ifndef LOGO_EN 1796 share_disp_buf = ps_mem_q_ip->u4_share_disp_buf; 1797 #else 1798 share_disp_buf = 0; 1799 #endif 1800 } 1801 else 1802 { 1803 share_disp_buf = 0; 1804 } 1805 1806 if(ps_mem_q_ip->s_ivd_fill_mem_rec_ip_t.u4_size 1807 > offsetof(ihevcd_cxa_fill_mem_rec_ip_t, e_output_format)) 1808 { 1809 chroma_format = ps_mem_q_ip->e_output_format; 1810 } 1811 else 1812 { 1813 chroma_format = -1; 1814 } 1815 1816 /* Shared disp buffer mode is supported only for 420SP formats */ 1817 if((chroma_format != IV_YUV_420P) && 1818 (chroma_format != IV_YUV_420SP_UV) && 1819 (chroma_format != IV_YUV_420SP_VU)) 1820 { 1821 share_disp_buf = 0; 1822 } 1823 1824 { 1825 1826 max_ht_luma = ps_mem_q_ip->s_ivd_fill_mem_rec_ip_t.u4_max_frm_ht; 1827 max_wd_luma = ps_mem_q_ip->s_ivd_fill_mem_rec_ip_t.u4_max_frm_wd; 1828 1829 max_ht_luma = ALIGN64(max_ht_luma); 1830 max_wd_luma = ALIGN64(max_wd_luma); 1831 1832 1833 1834 max_tile_cols = (max_wd_luma + MIN_TILE_WD - 1) / MIN_TILE_WD; 1835 max_tile_rows = (max_ht_luma + MIN_TILE_HT - 1) / MIN_TILE_HT; 1836 max_ctb_rows = max_ht_luma / MIN_CTB_SIZE; 1837 max_ctb_cols = max_wd_luma / MIN_CTB_SIZE; 1838 max_ctb_cnt = max_ctb_rows * max_ctb_cols; 1839 max_num_cu_cols = max_wd_luma / MIN_CU_SIZE; 1840 max_num_4x4_cols = max_wd_luma / 4; 1841 } 1842 /* 1843 * If level is lesser than 31 and the resolution required is higher, 1844 * then make the level at least 31. 1845 */ 1846 /* if (num_mbs > MAX_NUM_MBS_3_0 && level < MAX_LEVEL) 1847 { 1848 level = MAX_LEVEL; 1849 } 1850 */ 1851 if((level < MIN_LEVEL) || (level > MAX_LEVEL)) 1852 { 1853 ps_mem_q_op->s_ivd_fill_mem_rec_op_t.u4_error_code |= 1854 IHEVCD_LEVEL_UNSUPPORTED; 1855 level = MAX_LEVEL; 1856 } 1857 if(num_ref_frames > MAX_REF_CNT) 1858 { 1859 ps_mem_q_op->s_ivd_fill_mem_rec_op_t.u4_error_code |= 1860 IHEVCD_NUM_REF_UNSUPPORTED; 1861 num_ref_frames = MAX_REF_CNT; 1862 } 1863 1864 if(num_reorder_frames > MAX_REF_CNT) 1865 { 1866 ps_mem_q_op->s_ivd_fill_mem_rec_op_t.u4_error_code |= 1867 IHEVCD_NUM_REORDER_UNSUPPORTED; 1868 num_reorder_frames = MAX_REF_CNT; 1869 } 1870 1871 max_dpb_size = ihevcd_get_dpb_size(level, max_wd_luma * max_ht_luma); 1872 ps_mem_rec_base = ps_mem_q_ip->s_ivd_fill_mem_rec_ip_t.pv_mem_rec_location; 1873 1874 /* Set all memory reconds as persistent and alignment as 128 1875 * by default 1876 */ 1877 ps_mem_rec = ps_mem_rec_base; 1878 for(i = 0; i < MEM_REC_CNT; i++) 1879 { 1880 ps_mem_rec->u4_mem_alignment = 128; 1881 ps_mem_rec->e_mem_type = IV_EXTERNAL_CACHEABLE_PERSISTENT_MEM; 1882 ps_mem_rec++; 1883 } 1884 1885 /* Request memory for HEVCD object */ 1886 ps_mem_rec = &ps_mem_rec_base[MEM_REC_IV_OBJ]; 1887 ps_mem_rec->u4_mem_size = sizeof(iv_obj_t); 1888 1889 DEBUG("\nMemory record Id %d = %d \n", MEM_REC_IV_OBJ, 1890 ps_mem_rec->u4_mem_size); 1891 1892 /* Request memory for HEVC Codec context */ 1893 ps_mem_rec = &ps_mem_rec_base[MEM_REC_CODEC]; 1894 ps_mem_rec->u4_mem_size = sizeof(codec_t); 1895 DEBUG("\nMemory record Id %d = %d \n", MEM_REC_CODEC, 1896 ps_mem_rec->u4_mem_size); 1897 1898 /* Request memory for buffer which holds bitstream after emulation prevention */ 1899 ps_mem_rec = &ps_mem_rec_base[MEM_REC_BITSBUF]; 1900 ps_mem_rec->u4_mem_size = MAX((max_wd_luma * max_ht_luma), MIN_BITSBUF_SIZE); 1901 DEBUG("\nMemory record Id %d = %d \n", MEM_REC_BITSBUF, 1902 ps_mem_rec->u4_mem_size); 1903 1904 /* Request memory for buffer which holds TU structures and coeff data for 1905 * a set of CTBs in the current picture */ 1906 /*TODO Currently the buffer is allocated at a frame level. Reduce this to 1907 * allocate for s set of CTBs and add appropriate synchronization logic to 1908 * ensure that this is data is not overwritten before consumption 1909 */ 1910 ps_mem_rec = &ps_mem_rec_base[MEM_REC_TU_DATA]; 1911 ps_mem_rec->u4_mem_size = ihevcd_get_tu_data_size(max_wd_luma * max_ht_luma); 1912 DEBUG("\nMemory record Id %d = %d \n", MEM_REC_TU_DATA, 1913 ps_mem_rec->u4_mem_size); 1914 1915 ps_mem_rec = &ps_mem_rec_base[MEM_REC_MVBANK]; 1916 1917 ps_mem_rec->u4_mem_size = sizeof(buf_mgr_t); 1918 1919 /* Size for holding mv_buf_t for each MV Bank */ 1920 /* Note this allocation is done for BUF_MGR_MAX_CNT instead of 1921 * max_dpb_size or MAX_DPB_SIZE for following reasons 1922 * max_dpb_size will be based on max_wd and max_ht 1923 * For higher max_wd and max_ht this number will be smaller than MAX_DPB_SIZE 1924 * But during actual initialization number of buffers allocated can be more 1925 * 1926 * One extra MV Bank is needed to hold current pics MV bank. 1927 * Since this is only a structure allocation and not actual buffer allocation, 1928 * it is allocated for BUF_MGR_MAX_CNT entries 1929 */ 1930 ps_mem_rec->u4_mem_size += BUF_MGR_MAX_CNT * sizeof(mv_buf_t); 1931 1932 { 1933 /* Allocate for pu_map, pu_t and pic_pu_idx for each MV bank */ 1934 /* Note: Number of luma samples is not max_wd * max_ht here, instead it is 1935 * set to maximum number of luma samples allowed at the given level. 1936 * This is done to ensure that any stream with width and height lesser 1937 * than max_wd and max_ht is supported. Number of buffers required can be greater 1938 * for lower width and heights at a given level and this increased number of buffers 1939 * might require more memory than what max_wd and max_ht buffer would have required 1940 * Also note one extra buffer is allocted to store current pictures MV bank 1941 * In case of asynchronous parsing and processing, number of buffers should increase here 1942 * based on when parsing and processing threads are synchronized 1943 */ 1944 WORD32 lvl_idx = ihevcd_get_lvl_idx(level); 1945 WORD32 max_luma_samples = gai4_ihevc_max_luma_pic_size[lvl_idx]; 1946 ps_mem_rec->u4_mem_size += (max_dpb_size + 1) * 1947 ihevcd_get_pic_mv_bank_size(max_luma_samples); 1948 DEBUG("\nMemory record Id %d = %d \n", MEM_REC_MVBANK, 1949 ps_mem_rec->u4_mem_size); 1950 } 1951 // TODO GPU : Have to creat ping-pong view for VPS,SPS,PPS. 1952 ps_mem_rec = &ps_mem_rec_base[MEM_REC_VPS]; 1953 ps_mem_rec->u4_mem_size = MAX_VPS_CNT * sizeof(vps_t); 1954 DEBUG("\nMemory record Id %d = %d \n", MEM_REC_VPS, 1955 ps_mem_rec->u4_mem_size); 1956 1957 ps_mem_rec = &ps_mem_rec_base[MEM_REC_SPS]; 1958 ps_mem_rec->u4_mem_size = MAX_SPS_CNT * sizeof(sps_t); 1959 DEBUG("\nMemory record Id %d = %d \n", MEM_REC_SPS, 1960 ps_mem_rec->u4_mem_size); 1961 1962 ps_mem_rec = &ps_mem_rec_base[MEM_REC_PPS]; 1963 ps_mem_rec->u4_mem_size = MAX_PPS_CNT * sizeof(pps_t); 1964 DEBUG("\nMemory record Id %d = %d \n", MEM_REC_PPS, 1965 ps_mem_rec->u4_mem_size); 1966 1967 ps_mem_rec = &ps_mem_rec_base[MEM_REC_SLICE_HDR]; 1968 ps_mem_rec->u4_mem_size = MAX_SLICE_HDR_CNT * sizeof(slice_header_t); 1969 DEBUG("\nMemory record Id %d = %d \n", MEM_REC_SLICE_HDR, 1970 ps_mem_rec->u4_mem_size); 1971 1972 ps_mem_rec = &ps_mem_rec_base[MEM_REC_TILE]; 1973 { 1974 WORD32 tile_size; 1975 1976 tile_size = max_tile_cols * max_tile_rows; 1977 tile_size *= sizeof(tile_t); 1978 1979 1980 ps_mem_rec->u4_mem_size = MAX_PPS_CNT * tile_size; 1981 } 1982 1983 1984 DEBUG("\nMemory record Id %d = %d \n", MEM_REC_TILE, 1985 ps_mem_rec->u4_mem_size); 1986 1987 ps_mem_rec = &ps_mem_rec_base[MEM_REC_ENTRY_OFST]; 1988 { 1989 WORD32 num_entry_points; 1990 1991 /* One entry point per tile */ 1992 num_entry_points = max_tile_cols * max_tile_rows; 1993 1994 /* One entry point per row of CTBs */ 1995 /*********************************************************************/ 1996 /* Only tiles or entropy sync is enabled at a time in main */ 1997 /* profile, but since memory required does not increase too much, */ 1998 /* this allocation is done to handle both cases */ 1999 /*********************************************************************/ 2000 num_entry_points += max_ctb_rows; 2001 2002 2003 ps_mem_rec->u4_mem_size = sizeof(WORD32) * num_entry_points; 2004 } 2005 2006 2007 DEBUG("\nMemory record Id %d = %d \n", MEM_REC_ENTRY_OFST, 2008 ps_mem_rec->u4_mem_size); 2009 2010 2011 ps_mem_rec = &ps_mem_rec_base[MEM_REC_SCALING_MAT]; 2012 { 2013 WORD32 scaling_mat_size; 2014 2015 SCALING_MAT_SIZE(scaling_mat_size) 2016 ps_mem_rec->u4_mem_size = (MAX_SPS_CNT + MAX_PPS_CNT) * scaling_mat_size * sizeof(WORD16); 2017 } 2018 DEBUG("\nMemory record Id %d = %d \n", MEM_REC_SCALING_MAT, 2019 ps_mem_rec->u4_mem_size); 2020 2021 /* Holds one row skip_flag at 8x8 level used during parsing */ 2022 ps_mem_rec = &ps_mem_rec_base[MEM_REC_PARSE_SKIP_FLAG]; 2023 2024 /* 1 bit per 8x8 */ 2025 ps_mem_rec->u4_mem_size = max_num_cu_cols / 8; 2026 DEBUG("\nMemory record Id %d = %d \n", MEM_REC_PARSE_SKIP_FLAG, 2027 ps_mem_rec->u4_mem_size); 2028 2029 /* Holds one row skip_flag at 8x8 level used during parsing */ 2030 ps_mem_rec = &ps_mem_rec_base[MEM_REC_PARSE_CT_DEPTH]; 2031 2032 /* 2 bits per 8x8 */ 2033 ps_mem_rec->u4_mem_size = max_num_cu_cols / 4; 2034 DEBUG("\nMemory record Id %d = %d \n", MEM_REC_PARSE_CT_DEPTH, 2035 ps_mem_rec->u4_mem_size); 2036 2037 /* Holds one row skip_flag at 8x8 level used during parsing */ 2038 ps_mem_rec = &ps_mem_rec_base[MEM_REC_PARSE_INTRA_PRED_MODE]; 2039 2040 /* 8 bits per 4x4 */ 2041 /* 16 bytes each for top and left 64 pixels and 16 bytes for default mode */ 2042 ps_mem_rec->u4_mem_size = 3 * 16 * sizeof(UWORD8); 2043 DEBUG("\nMemory record Id %d = %d \n", MEM_REC_PARSE_INTRA_PRED_MODE, 2044 ps_mem_rec->u4_mem_size); 2045 2046 /* Holds one intra mode at 8x8 level for entire picture */ 2047 ps_mem_rec = &ps_mem_rec_base[MEM_REC_INTRA_FLAG]; 2048 2049 /* 1 bit per 8x8 */ 2050 ps_mem_rec->u4_mem_size = (max_wd_luma / MIN_CU_SIZE) * (max_ht_luma / MIN_CU_SIZE) / 8; 2051 DEBUG("\nMemory record Id %d = %d \n", MEM_REC_INTRA_FLAG, 2052 ps_mem_rec->u4_mem_size); 2053 2054 /* Holds one transquant bypass flag at 8x8 level for entire picture */ 2055 ps_mem_rec = &ps_mem_rec_base[MEM_REC_TRANSQUANT_BYPASS_FLAG]; 2056 2057 /* 1 bit per 8x8 */ 2058 /* Extra row and column are allocated for easy processing of top and left blocks while loop filtering */ 2059 ps_mem_rec->u4_mem_size = ((max_wd_luma + 64) / MIN_CU_SIZE) * ((max_ht_luma + 64) / MIN_CU_SIZE) / 8; 2060 DEBUG("\nMemory record Id %d = %d \n", MEM_REC_TRANSQUANT_BYPASS_FLAG, 2061 ps_mem_rec->u4_mem_size); 2062 2063 /* Request memory to hold thread handles for each processing thread */ 2064 ps_mem_rec = &ps_mem_rec_base[MEM_REC_THREAD_HANDLE]; 2065 ps_mem_rec->u4_mem_size = MAX_PROCESS_THREADS * ithread_get_handle_size(); 2066 DEBUG("\nMemory record Id %d = %d \n", MEM_REC_THREAD_HANDLE, 2067 ps_mem_rec->u4_mem_size); 2068 2069 2070 { 2071 WORD32 job_queue_size; 2072 WORD32 num_jobs; 2073 ps_mem_rec = &ps_mem_rec_base[MEM_REC_PROC_JOBQ]; 2074 2075 2076 /* One job per row of CTBs */ 2077 num_jobs = max_ctb_rows; 2078 2079 /* One each tile a row of CTBs, num_jobs has to incremented */ 2080 num_jobs *= max_tile_cols; 2081 2082 /* One format convert/frame copy job per row of CTBs for non-shared mode*/ 2083 num_jobs += max_ctb_rows; 2084 2085 2086 job_queue_size = ihevcd_jobq_ctxt_size(); 2087 job_queue_size += num_jobs * sizeof(proc_job_t); 2088 ps_mem_rec->u4_mem_size = job_queue_size; 2089 DEBUG("\nMemory record Id %d = %d \n", MEM_REC_PROC_JOBQ, 2090 ps_mem_rec->u4_mem_size); 2091 } 2092 2093 2094 ps_mem_rec = &ps_mem_rec_base[MEM_REC_PARSE_MAP]; 2095 ps_mem_rec->u4_mem_size = max_ctb_cnt; 2096 DEBUG("\nMemory record Id %d = %d \n", MEM_REC_PARSE_MAP, 2097 ps_mem_rec->u4_mem_size); 2098 2099 ps_mem_rec = &ps_mem_rec_base[MEM_REC_PROC_MAP]; 2100 ps_mem_rec->u4_mem_size = max_ctb_cnt; 2101 DEBUG("\nMemory record Id %d = %d \n", MEM_REC_PROC_MAP, 2102 ps_mem_rec->u4_mem_size); 2103 2104 2105 ps_mem_rec = &ps_mem_rec_base[MEM_REC_DISP_MGR]; 2106 2107 /* size for holding display manager context */ 2108 ps_mem_rec->u4_mem_size = sizeof(buf_mgr_t); 2109 DEBUG("\nMemory record Id %d = %d \n", MEM_REC_DISP_MGR, 2110 ps_mem_rec->u4_mem_size); 2111 2112 ps_mem_rec = &ps_mem_rec_base[MEM_REC_DPB_MGR]; 2113 2114 /* size for holding dpb manager context */ 2115 ps_mem_rec->u4_mem_size = sizeof(dpb_mgr_t); 2116 DEBUG("\nMemory record Id %d = %d \n", MEM_REC_DPB_MGR, 2117 ps_mem_rec->u4_mem_size); 2118 2119 /** Holds top and left neighbor's pu idx into picture level pu array */ 2120 /* Only one top row is enough but left has to be replicated for each process context */ 2121 ps_mem_rec = &ps_mem_rec_base[MEM_REC_PIC_PU_IDX_NEIGHBOR]; 2122 2123 ps_mem_rec->u4_mem_size = (max_num_4x4_cols /* left */ + MAX_PROCESS_THREADS * (MAX_CTB_SIZE / 4)/* top */ + 1/* top right */) * sizeof(WORD32); 2124 DEBUG("\nMemory record Id %d = %d \n", MEM_REC_PIC_PU_IDX_NEIGHBOR, 2125 ps_mem_rec->u4_mem_size); 2126 2127 2128 2129 /* TO hold scratch buffers needed for each process context */ 2130 ps_mem_rec = &ps_mem_rec_base[MEM_REC_PROC_SCRATCH]; 2131 { 2132 WORD32 size = 0; 2133 WORD32 inter_pred_tmp_buf_size; 2134 WORD32 ntaps_luma; 2135 WORD32 pu_map_size; 2136 WORD32 sao_size = 0; 2137 ntaps_luma = 8; 2138 2139 /* Max inter pred size (number of bytes) */ 2140 inter_pred_tmp_buf_size = sizeof(WORD16) * (MAX_CTB_SIZE + ntaps_luma) * MAX_CTB_SIZE; 2141 inter_pred_tmp_buf_size = ALIGN64(inter_pred_tmp_buf_size); 2142 2143 2144 /* To hold pu_index w.r.t. frame level pu_t array for a CTB at 4x4 level*/ 2145 /* 16 x 16 4x4 in a CTB of size 64 x 64 and two extra needed for holding 2146 * neighbors 2147 */ 2148 pu_map_size = sizeof(WORD32) * (18 * 18); 2149 2150 pu_map_size = ALIGN64(pu_map_size); 2151 size += pu_map_size; 2152 2153 /* To hold inter pred temporary buffers */ 2154 size += 2 * inter_pred_tmp_buf_size; 2155 2156 2157 /* Allocate for each process context */ 2158 size *= MAX_PROCESS_THREADS; 2159 2160 2161 /* To hold SAO left buffer for luma */ 2162 sao_size += sizeof(UWORD8) * (MAX(max_ht_luma, max_wd_luma)); 2163 2164 /* To hold SAO left buffer for chroma */ 2165 sao_size += sizeof(UWORD8) * (MAX(max_ht_luma, max_wd_luma)); 2166 2167 /* To hold SAO top buffer for luma */ 2168 sao_size += sizeof(UWORD8) * max_wd_luma; 2169 2170 /* To hold SAO top buffer for chroma */ 2171 sao_size += sizeof(UWORD8) * max_wd_luma; 2172 2173 /* To hold SAO top left luma pixel value for last output ctb in a row*/ 2174 sao_size += sizeof(UWORD8) * max_ctb_rows; 2175 2176 /* To hold SAO top left chroma pixel value last output ctb in a row*/ 2177 sao_size += sizeof(UWORD8) * max_ctb_rows * 2; 2178 2179 /* To hold SAO top left pixel luma for current ctb - column array*/ 2180 sao_size += sizeof(UWORD8) * max_ctb_rows; 2181 2182 /* To hold SAO top left pixel chroma for current ctb-column array*/ 2183 sao_size += sizeof(UWORD8) * max_ctb_rows * 2; 2184 2185 /* To hold SAO top right pixel luma pixel value last output ctb in a row*/ 2186 sao_size += sizeof(UWORD8) * max_ctb_cols; 2187 2188 /* To hold SAO top right pixel chroma pixel value last output ctb in a row*/ 2189 sao_size += sizeof(UWORD8) * max_ctb_cols * 2; 2190 2191 /*To hold SAO botton bottom left pixels for luma*/ 2192 sao_size += sizeof(UWORD8) * max_ctb_rows; 2193 2194 /*To hold SAO botton bottom left pixels for luma*/ 2195 sao_size += sizeof(UWORD8) * max_ctb_rows * 2; 2196 sao_size = ALIGN64(sao_size); 2197 size += sao_size; 2198 ps_mem_rec->u4_mem_size = size; 2199 } 2200 DEBUG("\nMemory record Id %d = %d \n", MEM_REC_PROC_SCRATCH, 2201 ps_mem_rec->u4_mem_size); 2202 2203 /* TO hold scratch buffers needed for each SAO context */ 2204 ps_mem_rec = &ps_mem_rec_base[MEM_REC_SAO_SCRATCH]; 2205 { 2206 WORD32 size = 0; 2207 2208 size = 4 * MAX_CTB_SIZE * MAX_CTB_SIZE; 2209 2210 /* 2 temporary buffers*/ 2211 size *= 2; 2212 2213 size *= MAX_PROCESS_THREADS; 2214 2215 ps_mem_rec->u4_mem_size = size; 2216 } 2217 DEBUG("\nMemory record Id %d = %d \n", MEM_REC_SAO_SCRATCH, 2218 ps_mem_rec->u4_mem_size); 2219 2220 ps_mem_rec = &ps_mem_rec_base[MEM_REC_BS_QP]; 2221 { 2222 WORD32 size = 0; 2223 WORD32 vert_bs_size, horz_bs_size; 2224 WORD32 qp_const_flag_size; 2225 WORD32 qp_size, num_8x8; 2226 2227 /* Max Number of vertical edges */ 2228 vert_bs_size = max_wd_luma / 8 + 2 * MAX_CTB_SIZE / 8; 2229 2230 /* Max Number of horizontal edges - extra MAX_CTB_SIZE / 8 to handle the last 4 rows separately(shifted CTB processing) */ 2231 vert_bs_size *= (max_ht_luma + MAX_CTB_SIZE) / MIN_TU_SIZE; 2232 2233 /* Number of bytes */ 2234 vert_bs_size /= 8; 2235 2236 /* Two bits per edge */ 2237 vert_bs_size *= 2; 2238 2239 /* Max Number of horizontal edges */ 2240 horz_bs_size = max_ht_luma / 8 + MAX_CTB_SIZE / 8; 2241 2242 /* Max Number of vertical edges - extra MAX_CTB_SIZE / 8 to handle the last 4 columns separately(shifted CTB processing) */ 2243 horz_bs_size *= (max_wd_luma + MAX_CTB_SIZE) / MIN_TU_SIZE; 2244 2245 /* Number of bytes */ 2246 horz_bs_size /= 8; 2247 2248 /* Two bits per edge */ 2249 horz_bs_size *= 2; 2250 2251 /* Max CTBs in a row */ 2252 qp_const_flag_size = max_wd_luma / MIN_CTB_SIZE + 1 /* The last ctb row deblk is done in last ctb + 1 row.*/; 2253 2254 /* Max CTBs in a column */ 2255 qp_const_flag_size *= max_ht_luma / MIN_CTB_SIZE; 2256 2257 /* Number of bytes */ 2258 qp_const_flag_size = (qp_const_flag_size + 7) >> 3; 2259 2260 /* QP changes at CU level - So store at 8x8 level */ 2261 num_8x8 = (max_ht_luma * max_wd_luma) / (MIN_CU_SIZE * MIN_CU_SIZE); 2262 qp_size = num_8x8; 2263 2264 /* To hold vertical boundary strength */ 2265 size += vert_bs_size; 2266 2267 /* To hold horizontal boundary strength */ 2268 size += horz_bs_size; 2269 2270 /* To hold QP */ 2271 size += qp_size; 2272 2273 /* To hold QP const in CTB flags */ 2274 size += qp_const_flag_size; 2275 2276 ps_mem_rec->u4_mem_size = size; 2277 } 2278 2279 DEBUG("\nMemory record Id %d = %d \n", MEM_REC_BS_QP, 2280 ps_mem_rec->u4_mem_size); 2281 2282 ps_mem_rec = &ps_mem_rec_base[MEM_REC_TILE_IDX]; 2283 { 2284 WORD32 size = 0; 2285 /* Max CTBs in a row */ 2286 size = max_wd_luma / MIN_CTB_SIZE + 2 /* Top row and bottom row extra. This ensures accessing left,top in first row 2287 and right in last row will not result in invalid access*/; 2288 /* Max CTBs in a column */ 2289 size *= max_ht_luma / MIN_CTB_SIZE; 2290 2291 size *= sizeof(UWORD16); 2292 ps_mem_rec->u4_mem_size = size; 2293 } 2294 DEBUG("\nMemory record Id %d = %d \n", MEM_REC_TILE_IDX, 2295 ps_mem_rec->u4_mem_size); 2296 2297 ps_mem_rec = &ps_mem_rec_base[MEM_REC_SAO]; 2298 { 2299 UWORD32 size; 2300 2301 /* 4 bytes per color component per CTB */ 2302 size = 3 * 4; 2303 2304 /* MAX number of CTBs in a row */ 2305 size *= max_wd_luma / MIN_CTB_SIZE; 2306 2307 /* MAX number of CTBs in a column */ 2308 size *= max_ht_luma / MIN_CTB_SIZE; 2309 ps_mem_rec->u4_mem_size = size; 2310 } 2311 2312 DEBUG("\nMemory record Id %d = %d \n", MEM_REC_SAO, 2313 ps_mem_rec->u4_mem_size); 2314 2315 2316 ps_mem_rec = &ps_mem_rec_base[MEM_REC_REF_PIC]; 2317 2318 /* size for holding buffer manager context */ 2319 ps_mem_rec->u4_mem_size = sizeof(buf_mgr_t); 2320 2321 /* Size for holding pic_buf_t for each reference picture */ 2322 /* Note this allocation is done for BUF_MGR_MAX_CNT instead of 2323 * max_dpb_size or MAX_DPB_SIZE for following reasons 2324 * max_dpb_size will be based on max_wd and max_ht 2325 * For higher max_wd and max_ht this number will be smaller than MAX_DPB_SIZE 2326 * But during actual initialization number of buffers allocated can be more 2327 * 2328 * Also to handle display depth application can allocate more than what 2329 * codec asks for in case of non-shared mode 2330 * Since this is only a structure allocation and not actual buffer allocation, 2331 * it is allocated for BUF_MGR_MAX_CNT entries 2332 */ 2333 ps_mem_rec->u4_mem_size += BUF_MGR_MAX_CNT * sizeof(pic_buf_t); 2334 2335 /* In case of non-shared mode allocate for reference picture buffers */ 2336 if(0 == share_disp_buf) 2337 { 2338 UWORD32 num_reorder_frames_local = num_reorder_frames; 2339 /* Note: Number of luma samples is not max_wd * max_ht here, instead it is 2340 * set to maximum number of luma samples allowed at the given level. 2341 * This is done to ensure that any stream with width and height lesser 2342 * than max_wd and max_ht is supported. Number of buffers required can be greater 2343 * for lower width and heights at a given level and this increased number of buffers 2344 * might require more memory than what max_wd and max_ht buffer would have required 2345 * Number of buffers is doubled in order to return one frame at a time instead of sending 2346 * multiple outputs during dpb full case. 2347 * Also note one extra buffer is allocted to store current picture 2348 * In case of asynchronous parsing and processing, number of buffers should increase here 2349 * based on when parsing and processing threads are synchronized 2350 */ 2351 ps_mem_rec->u4_mem_size += 2352 ihevcd_get_total_pic_buf_size(max_wd_luma * max_ht_luma, level, PAD_WD, PAD_HT, 2353 num_ref_frames, num_reorder_frames_local); 2354 } 2355 DEBUG("\nMemory record Id %d = %d \n", MEM_REC_REF_PIC, 2356 ps_mem_rec->u4_mem_size); 2357 2358 /* Request memory to hold mem records to be returned during retrieve call */ 2359 ps_mem_rec = &ps_mem_rec_base[MEM_REC_BACKUP]; 2360 ps_mem_rec->u4_mem_size = MEM_REC_CNT * sizeof(iv_mem_rec_t); 2361 DEBUG("\nMemory record Id %d = %d \n", MEM_REC_BACKUP, 2362 ps_mem_rec->u4_mem_size); 2363 2364 /* Each memtab size is aligned to next multiple of 128 bytes */ 2365 /* This is to ensure all the memtabs start at different cache lines */ 2366 ps_mem_rec = ps_mem_rec_base; 2367 for(i = 0; i < MEM_REC_CNT; i++) 2368 { 2369 ps_mem_rec->u4_mem_size = ALIGN128(ps_mem_rec->u4_mem_size); 2370 ps_mem_rec++; 2371 } 2372 ps_mem_q_op->s_ivd_fill_mem_rec_op_t.u4_num_mem_rec_filled = MEM_REC_CNT; 2373 #ifdef APPLY_CONCEALMENT 2374 { 2375 IV_API_CALL_STATUS_T status; 2376 icncl_fill_mem_rec_ip_t cncl_fill_ip; 2377 icncl_fill_mem_rec_op_t cncl_fill_op; 2378 UWORD8 mem_loc = MEM_REC_CNT; 2379 2380 cncl_fill_ip.s_ivd_fill_mem_rec_ip_t.e_cmd = IV_CMD_FILL_NUM_MEM_REC; 2381 cncl_fill_ip.s_ivd_fill_mem_rec_ip_t.pv_mem_rec_location = &(memTab[mem_loc]); 2382 cncl_fill_ip.s_ivd_fill_mem_rec_ip_t.u4_size = ps_mem_q_ip->s_ivd_fill_mem_rec_ip_t.u4_size; 2383 cncl_fill_ip.s_ivd_fill_mem_rec_ip_t.u4_max_frm_wd = max_wd_luma; 2384 cncl_fill_ip.s_ivd_fill_mem_rec_ip_t.u4_max_frm_ht = max_ht_luma; 2385 2386 status = icncl_api_function(NULL, (void *)&cncl_fill_ip, (void *)&cncl_fill_op); 2387 2388 if(IV_SUCCESS == status) 2389 { 2390 icncl_num_mem_rec_ip_t cncl_mem_ip; 2391 icncl_num_mem_rec_op_t cncl_mem_op; 2392 2393 cncl_mem_ip.s_ivd_num_rec_ip_t.e_cmd = IV_CMD_GET_NUM_MEM_REC; 2394 cncl_mem_ip.s_ivd_num_rec_ip_t.u4_size = sizeof(icncl_num_mem_rec_ip_t); 2395 2396 status = icncl_api_function(NULL, (void *)&cncl_mem_ip, (void *)&cncl_mem_op); 2397 if(IV_SUCCESS == status) 2398 { 2399 ps_mem_q_op->s_ivd_fill_mem_rec_op_t.u4_num_mem_rec_filled += cncl_mem_op.s_ivd_num_mem_rec_op_t.u4_num_mem_rec; 2400 } 2401 } 2402 2403 return status; 2404 2405 } 2406 #endif //APPLY_CONCEALMENT 2407 DEBUG("Num mem recs in fill call : %d\n", 2408 ps_mem_q_op->s_ivd_fill_mem_rec_op_t.u4_num_mem_rec_filled); 2409 2410 2411 return (status); 2412 } 2413 2414 2415 /** 2416 ******************************************************************************* 2417 * 2418 * @brief 2419 * Initializes from mem records passed to the codec 2420 * 2421 * @par Description: 2422 * Initializes pointers based on mem records passed 2423 * 2424 * @param[in] ps_codec_obj 2425 * Pointer to codec object at API level 2426 * 2427 * @param[in] pv_api_ip 2428 * Pointer to input argument structure 2429 * 2430 * @param[out] pv_api_op 2431 * Pointer to output argument structure 2432 * 2433 * @returns Status 2434 * 2435 * @remarks 2436 * 2437 * 2438 ******************************************************************************* 2439 */ 2440 WORD32 ihevcd_init_mem_rec(iv_obj_t *ps_codec_obj, 2441 void *pv_api_ip, 2442 void *pv_api_op) 2443 { 2444 2445 ihevcd_cxa_init_ip_t *dec_init_ip; 2446 ihevcd_cxa_init_op_t *dec_init_op; 2447 WORD32 i; 2448 iv_mem_rec_t *ps_mem_rec, *ps_mem_rec_base; 2449 WORD32 status = IV_SUCCESS; 2450 codec_t *ps_codec; 2451 WORD32 max_tile_cols, max_tile_rows; 2452 2453 dec_init_ip = (ihevcd_cxa_init_ip_t *)pv_api_ip; 2454 dec_init_op = (ihevcd_cxa_init_op_t *)pv_api_op; 2455 2456 ps_mem_rec_base = dec_init_ip->s_ivd_init_ip_t.pv_mem_rec_location; 2457 2458 ps_mem_rec = &ps_mem_rec_base[MEM_REC_CODEC]; 2459 ps_codec_obj->pv_codec_handle = ps_mem_rec->pv_base; 2460 2461 ps_codec = (codec_t *)(ps_codec_obj->pv_codec_handle); 2462 2463 /* Note this memset can not be done in init() call, since init will called 2464 during reset as well. And calling this during reset will mean all pointers 2465 need to reinitialized*/ 2466 memset(ps_codec, 0, sizeof(codec_t)); 2467 2468 if(dec_init_ip->s_ivd_init_ip_t.u4_size 2469 > offsetof(ihevcd_cxa_init_ip_t, i4_level)) 2470 { 2471 ps_codec->i4_init_level = dec_init_ip->i4_level; 2472 2473 ps_codec->i4_init_level *= 3; 2474 } 2475 else 2476 { 2477 ps_codec->i4_init_level = MAX_LEVEL; 2478 } 2479 2480 if(dec_init_ip->s_ivd_init_ip_t.u4_size 2481 > offsetof(ihevcd_cxa_init_ip_t, u4_num_ref_frames)) 2482 { 2483 ps_codec->i4_init_num_ref = dec_init_ip->u4_num_ref_frames; 2484 } 2485 else 2486 { 2487 ps_codec->i4_init_num_ref = MAX_REF_CNT; 2488 } 2489 2490 if(dec_init_ip->s_ivd_init_ip_t.u4_size 2491 > offsetof(ihevcd_cxa_init_ip_t, u4_num_reorder_frames)) 2492 { 2493 ps_codec->i4_init_num_reorder = dec_init_ip->u4_num_reorder_frames; 2494 } 2495 else 2496 { 2497 ps_codec->i4_init_num_reorder = MAX_REF_CNT; 2498 } 2499 2500 if(dec_init_ip->s_ivd_init_ip_t.u4_size 2501 > offsetof(ihevcd_cxa_init_ip_t, u4_num_extra_disp_buf)) 2502 { 2503 ps_codec->i4_init_num_extra_disp_buf = 2504 dec_init_ip->u4_num_extra_disp_buf; 2505 } 2506 else 2507 { 2508 ps_codec->i4_init_num_extra_disp_buf = 0; 2509 } 2510 2511 if(dec_init_ip->s_ivd_init_ip_t.u4_size 2512 > offsetof(ihevcd_cxa_init_ip_t, u4_share_disp_buf)) 2513 { 2514 #ifndef LOGO_EN 2515 ps_codec->i4_share_disp_buf = dec_init_ip->u4_share_disp_buf; 2516 #else 2517 ps_codec->i4_share_disp_buf = 0; 2518 #endif 2519 } 2520 else 2521 { 2522 ps_codec->i4_share_disp_buf = 0; 2523 } 2524 /* Shared display mode is supported only for 420SP and 420P formats */ 2525 if((dec_init_ip->s_ivd_init_ip_t.e_output_format != IV_YUV_420P) && 2526 (dec_init_ip->s_ivd_init_ip_t.e_output_format != IV_YUV_420SP_UV) && 2527 (dec_init_ip->s_ivd_init_ip_t.e_output_format != IV_YUV_420SP_VU)) 2528 { 2529 ps_codec->i4_share_disp_buf = 0; 2530 } 2531 2532 if((ps_codec->i4_init_level < MIN_LEVEL) 2533 || (ps_codec->i4_init_level > MAX_LEVEL)) 2534 { 2535 dec_init_op->s_ivd_init_op_t.u4_error_code |= IHEVCD_LEVEL_UNSUPPORTED; 2536 return (IV_FAIL); 2537 } 2538 2539 if(ps_codec->i4_init_num_ref > MAX_REF_CNT) 2540 { 2541 dec_init_op->s_ivd_init_op_t.u4_error_code |= 2542 IHEVCD_NUM_REF_UNSUPPORTED; 2543 ps_codec->i4_init_num_ref = MAX_REF_CNT; 2544 } 2545 2546 if(ps_codec->i4_init_num_reorder > MAX_REF_CNT) 2547 { 2548 dec_init_op->s_ivd_init_op_t.u4_error_code |= 2549 IHEVCD_NUM_REORDER_UNSUPPORTED; 2550 ps_codec->i4_init_num_reorder = MAX_REF_CNT; 2551 } 2552 2553 if(ps_codec->i4_init_num_extra_disp_buf > MAX_REF_CNT) 2554 { 2555 dec_init_op->s_ivd_init_op_t.u4_error_code |= 2556 IHEVCD_NUM_EXTRA_DISP_UNSUPPORTED; 2557 ps_codec->i4_init_num_extra_disp_buf = 0; 2558 } 2559 2560 ps_codec->e_chroma_fmt = dec_init_ip->s_ivd_init_ip_t.e_output_format; 2561 2562 ps_codec->i4_max_wd = dec_init_ip->s_ivd_init_ip_t.u4_frm_max_wd; 2563 ps_codec->i4_max_ht = dec_init_ip->s_ivd_init_ip_t.u4_frm_max_ht; 2564 2565 ps_codec->i4_max_wd = ALIGN64(ps_codec->i4_max_wd); 2566 ps_codec->i4_max_ht = ALIGN64(ps_codec->i4_max_ht); 2567 2568 ps_codec->i4_new_max_wd = ps_codec->i4_max_wd; 2569 ps_codec->i4_new_max_ht = ps_codec->i4_max_ht; 2570 2571 max_tile_cols = (ps_codec->i4_max_wd + MIN_TILE_WD - 1) / MIN_TILE_WD; 2572 max_tile_rows = (ps_codec->i4_max_ht + MIN_TILE_HT - 1) / MIN_TILE_HT; 2573 2574 ps_mem_rec = &ps_mem_rec_base[MEM_REC_BACKUP]; 2575 ps_codec->ps_mem_rec_backup = (iv_mem_rec_t *)ps_mem_rec->pv_base; 2576 2577 memcpy(ps_codec->ps_mem_rec_backup, ps_mem_rec_base, 2578 MEM_REC_CNT * sizeof(iv_mem_rec_t)); 2579 2580 ps_mem_rec = &ps_mem_rec_base[MEM_REC_BITSBUF]; 2581 ps_codec->pu1_bitsbuf = (UWORD8 *)ps_mem_rec->pv_base; 2582 ps_codec->u4_bitsbuf_size = ps_mem_rec->u4_mem_size; 2583 2584 ps_mem_rec = &ps_mem_rec_base[MEM_REC_TU_DATA]; 2585 ps_codec->pv_tu_data = ps_mem_rec->pv_base; 2586 ps_mem_rec = &ps_mem_rec_base[MEM_REC_MVBANK]; 2587 ps_codec->pv_mv_buf_mgr = ps_mem_rec->pv_base; 2588 ps_codec->pv_mv_bank_buf_base = (UWORD8 *)ps_codec->pv_mv_buf_mgr + sizeof(buf_mgr_t); 2589 2590 ps_codec->i4_total_mv_bank_size = ps_mem_rec->u4_mem_size - sizeof(buf_mgr_t); 2591 2592 2593 ps_mem_rec = &ps_mem_rec_base[MEM_REC_VPS]; 2594 ps_codec->ps_vps_base = (vps_t *)ps_mem_rec->pv_base; 2595 ps_codec->s_parse.ps_vps_base = ps_codec->ps_vps_base; 2596 2597 ps_mem_rec = &ps_mem_rec_base[MEM_REC_SPS]; 2598 ps_codec->ps_sps_base = (sps_t *)ps_mem_rec->pv_base; 2599 ps_codec->s_parse.ps_sps_base = ps_codec->ps_sps_base; 2600 2601 ps_mem_rec = &ps_mem_rec_base[MEM_REC_PPS]; 2602 ps_codec->ps_pps_base = (pps_t *)ps_mem_rec->pv_base; 2603 ps_codec->s_parse.ps_pps_base = ps_codec->ps_pps_base; 2604 2605 ps_mem_rec = &ps_mem_rec_base[MEM_REC_SLICE_HDR]; 2606 ps_codec->ps_slice_hdr_base = (slice_header_t *)ps_mem_rec->pv_base; 2607 ps_codec->s_parse.ps_slice_hdr_base = ps_codec->ps_slice_hdr_base; 2608 2609 ps_mem_rec = &ps_mem_rec_base[MEM_REC_TILE]; 2610 ps_codec->ps_tile = (tile_t *)ps_mem_rec->pv_base; 2611 2612 ps_mem_rec = &ps_mem_rec_base[MEM_REC_ENTRY_OFST]; 2613 ps_codec->pi4_entry_ofst = (WORD32 *)ps_mem_rec->pv_base; 2614 2615 ps_mem_rec = &ps_mem_rec_base[MEM_REC_SCALING_MAT]; 2616 ps_codec->pi2_scaling_mat = (WORD16 *)ps_mem_rec->pv_base; 2617 2618 ps_mem_rec = &ps_mem_rec_base[MEM_REC_PARSE_SKIP_FLAG]; 2619 ps_codec->s_parse.pu4_skip_cu_top = (UWORD32 *)ps_mem_rec->pv_base; 2620 2621 ps_mem_rec = &ps_mem_rec_base[MEM_REC_PARSE_CT_DEPTH]; 2622 ps_codec->s_parse.pu4_ct_depth_top = (UWORD32 *)ps_mem_rec->pv_base; 2623 2624 ps_mem_rec = &ps_mem_rec_base[MEM_REC_PARSE_INTRA_PRED_MODE]; 2625 ps_codec->s_parse.pu1_luma_intra_pred_mode_left = 2626 (UWORD8 *)ps_mem_rec->pv_base; 2627 ps_codec->s_parse.pu1_luma_intra_pred_mode_top = 2628 (UWORD8 *)ps_mem_rec->pv_base + 16; 2629 2630 ps_mem_rec = &ps_mem_rec_base[MEM_REC_INTRA_FLAG]; 2631 2632 memset(ps_mem_rec->pv_base, 0, (ps_codec->i4_max_wd / MIN_CU_SIZE) * (ps_codec->i4_max_ht / MIN_CU_SIZE) / 8); 2633 2634 ps_codec->pu1_pic_intra_flag = (UWORD8 *)ps_mem_rec->pv_base; 2635 ps_codec->s_parse.pu1_pic_intra_flag = ps_codec->pu1_pic_intra_flag; 2636 ps_mem_rec = &ps_mem_rec_base[MEM_REC_TRANSQUANT_BYPASS_FLAG]; 2637 2638 { 2639 WORD32 loop_filter_size = ((ps_codec->i4_max_wd + 64) / MIN_CU_SIZE) * ((ps_codec->i4_max_ht + 64) / MIN_CU_SIZE) / 8; 2640 WORD32 loop_filter_strd = (ps_codec->i4_max_wd + 63) >> 6; 2641 2642 memset(ps_mem_rec->pv_base, 0, loop_filter_size); 2643 2644 /* The offset is added for easy processing of top and left blocks while loop filtering */ 2645 ps_codec->pu1_pic_no_loop_filter_flag = (UWORD8 *)ps_mem_rec->pv_base + loop_filter_strd + 1; 2646 ps_codec->s_parse.pu1_pic_no_loop_filter_flag = ps_codec->pu1_pic_no_loop_filter_flag; 2647 ps_codec->s_parse.s_deblk_ctxt.pu1_pic_no_loop_filter_flag = ps_codec->pu1_pic_no_loop_filter_flag; 2648 ps_codec->s_parse.s_sao_ctxt.pu1_pic_no_loop_filter_flag = ps_codec->pu1_pic_no_loop_filter_flag; 2649 } 2650 2651 /* Initialize pointers in PPS structures */ 2652 { 2653 sps_t *ps_sps = ps_codec->ps_sps_base; 2654 pps_t *ps_pps = ps_codec->ps_pps_base; 2655 tile_t *ps_tile = ps_codec->ps_tile; 2656 WORD16 *pi2_scaling_mat = ps_codec->pi2_scaling_mat; 2657 WORD32 scaling_mat_size; 2658 2659 SCALING_MAT_SIZE(scaling_mat_size); 2660 2661 for(i = 0; i < MAX_SPS_CNT; i++) 2662 { 2663 ps_sps->pi2_scaling_mat = pi2_scaling_mat; 2664 pi2_scaling_mat += scaling_mat_size; 2665 ps_sps++; 2666 } 2667 2668 for(i = 0; i < MAX_PPS_CNT; i++) 2669 { 2670 ps_pps->ps_tile = ps_tile; 2671 ps_tile += (max_tile_cols * max_tile_rows); 2672 2673 ps_pps->pi2_scaling_mat = pi2_scaling_mat; 2674 pi2_scaling_mat += scaling_mat_size; 2675 ps_pps++; 2676 } 2677 2678 } 2679 2680 ps_mem_rec = &ps_mem_rec_base[MEM_REC_THREAD_HANDLE]; 2681 for(i = 0; i < MAX_PROCESS_THREADS; i++) 2682 { 2683 WORD32 handle_size = ithread_get_handle_size(); 2684 ps_codec->apv_process_thread_handle[i] = 2685 (UWORD8 *)ps_mem_rec->pv_base + (i * handle_size); 2686 } 2687 2688 ps_mem_rec = &ps_mem_rec_base[MEM_REC_PROC_JOBQ]; 2689 ps_codec->pv_proc_jobq_buf = ps_mem_rec->pv_base; 2690 ps_codec->i4_proc_jobq_buf_size = ps_mem_rec->u4_mem_size; 2691 2692 ps_mem_rec = &ps_mem_rec_base[MEM_REC_PARSE_MAP]; 2693 ps_codec->pu1_parse_map = (UWORD8 *)ps_mem_rec->pv_base; 2694 2695 ps_mem_rec = &ps_mem_rec_base[MEM_REC_PROC_MAP]; 2696 ps_codec->pu1_proc_map = (UWORD8 *)ps_mem_rec->pv_base; 2697 ps_mem_rec = &ps_mem_rec_base[MEM_REC_DISP_MGR]; 2698 ps_codec->pv_disp_buf_mgr = ps_mem_rec->pv_base; 2699 2700 ps_mem_rec = &ps_mem_rec_base[MEM_REC_DPB_MGR]; 2701 ps_codec->pv_dpb_mgr = ps_mem_rec->pv_base; 2702 2703 2704 ps_mem_rec = &ps_mem_rec_base[MEM_REC_PIC_PU_IDX_NEIGHBOR]; 2705 2706 for(i = 0; i < MAX_PROCESS_THREADS; i++) 2707 { 2708 UWORD32 *pu4_buf = (UWORD32 *)ps_mem_rec->pv_base; 2709 ps_codec->as_process[i].pu4_pic_pu_idx_left = pu4_buf + i * (MAX_CTB_SIZE / 4); 2710 memset(ps_codec->as_process[i].pu4_pic_pu_idx_left, 0, sizeof(UWORD32) * MAX_CTB_SIZE / 4); 2711 ps_codec->as_process[i].pu4_pic_pu_idx_top = pu4_buf + MAX_PROCESS_THREADS * (MAX_CTB_SIZE / 4); 2712 } 2713 memset(ps_codec->as_process[0].pu4_pic_pu_idx_top, 0, sizeof(UWORD32) * (ps_codec->i4_max_wd / 4 + 1)); 2714 2715 2716 ps_mem_rec = &ps_mem_rec_base[MEM_REC_PROC_SCRATCH]; 2717 { 2718 UWORD8 *pu1_buf = (UWORD8 *)ps_mem_rec->pv_base; 2719 WORD32 pic_pu_idx_map_size; 2720 2721 WORD32 inter_pred_tmp_buf_size, ntaps_luma; 2722 2723 /* Max inter pred size */ 2724 ntaps_luma = 8; 2725 inter_pred_tmp_buf_size = sizeof(WORD16) * (MAX_CTB_SIZE + ntaps_luma) * MAX_CTB_SIZE; 2726 2727 inter_pred_tmp_buf_size = ALIGN64(inter_pred_tmp_buf_size); 2728 2729 /* To hold pu_index w.r.t. frame level pu_t array for a CTB */ 2730 pic_pu_idx_map_size = sizeof(WORD32) * (18 * 18); 2731 pic_pu_idx_map_size = ALIGN64(pic_pu_idx_map_size); 2732 for(i = 0; i < MAX_PROCESS_THREADS; i++) 2733 { 2734 ps_codec->as_process[i].pi2_inter_pred_tmp_buf1 = (WORD16 *)pu1_buf; 2735 pu1_buf += inter_pred_tmp_buf_size; 2736 2737 ps_codec->as_process[i].pi2_inter_pred_tmp_buf2 = (WORD16 *)pu1_buf; 2738 pu1_buf += inter_pred_tmp_buf_size; 2739 2740 /* Inverse transform intermediate and inverse scan output buffers reuse inter pred scratch buffers */ 2741 ps_codec->as_process[i].pi2_itrans_intrmd_buf = 2742 ps_codec->as_process[i].pi2_inter_pred_tmp_buf2; 2743 ps_codec->as_process[i].pi2_invscan_out = 2744 ps_codec->as_process[i].pi2_inter_pred_tmp_buf1; 2745 2746 ps_codec->as_process[i].pu4_pic_pu_idx_map = (UWORD32 *)pu1_buf; 2747 ps_codec->as_process[i].s_bs_ctxt.pu4_pic_pu_idx_map = 2748 (UWORD32 *)pu1_buf; 2749 pu1_buf += pic_pu_idx_map_size; 2750 2751 // ps_codec->as_process[i].pi2_inter_pred_tmp_buf3 = (WORD16 *)pu1_buf; 2752 // pu1_buf += inter_pred_tmp_buf_size; 2753 2754 ps_codec->as_process[i].i4_inter_pred_tmp_buf_strd = MAX_CTB_SIZE; 2755 2756 } 2757 for(i = 0; i < MAX_PROCESS_THREADS; i++) 2758 { 2759 ps_codec->as_process[i].s_sao_ctxt.pu1_sao_src_left_luma = (UWORD8 *)pu1_buf; 2760 } 2761 ps_codec->s_parse.s_sao_ctxt.pu1_sao_src_left_luma = (UWORD8 *)pu1_buf; 2762 pu1_buf += MAX(ps_codec->i4_max_ht, ps_codec->i4_max_wd); 2763 2764 for(i = 0; i < MAX_PROCESS_THREADS; i++) 2765 { 2766 ps_codec->as_process[i].s_sao_ctxt.pu1_sao_src_left_chroma = (UWORD8 *)pu1_buf; 2767 } 2768 ps_codec->s_parse.s_sao_ctxt.pu1_sao_src_left_chroma = (UWORD8 *)pu1_buf; 2769 pu1_buf += MAX(ps_codec->i4_max_ht, ps_codec->i4_max_wd); 2770 for(i = 0; i < MAX_PROCESS_THREADS; i++) 2771 { 2772 ps_codec->as_process[i].s_sao_ctxt.pu1_sao_src_top_luma = (UWORD8 *)pu1_buf; 2773 } 2774 ps_codec->s_parse.s_sao_ctxt.pu1_sao_src_top_luma = (UWORD8 *)pu1_buf; 2775 pu1_buf += ps_codec->i4_max_wd; 2776 2777 for(i = 0; i < MAX_PROCESS_THREADS; i++) 2778 { 2779 ps_codec->as_process[i].s_sao_ctxt.pu1_sao_src_top_chroma = (UWORD8 *)pu1_buf; 2780 } 2781 ps_codec->s_parse.s_sao_ctxt.pu1_sao_src_top_chroma = (UWORD8 *)pu1_buf; 2782 pu1_buf += ps_codec->i4_max_wd; 2783 for(i = 0; i < MAX_PROCESS_THREADS; i++) 2784 { 2785 ps_codec->as_process[i].s_sao_ctxt.pu1_sao_src_luma_top_left_ctb = (UWORD8 *)pu1_buf; 2786 } 2787 ps_codec->s_parse.s_sao_ctxt.pu1_sao_src_luma_top_left_ctb = (UWORD8 *)pu1_buf; 2788 pu1_buf += ps_codec->i4_max_ht / MIN_CTB_SIZE; 2789 2790 for(i = 0; i < MAX_PROCESS_THREADS; i++) 2791 { 2792 ps_codec->as_process[i].s_sao_ctxt.pu1_sao_src_chroma_top_left_ctb = (UWORD8 *)pu1_buf; 2793 } 2794 ps_codec->s_parse.s_sao_ctxt.pu1_sao_src_chroma_top_left_ctb = (UWORD8 *)pu1_buf; 2795 pu1_buf += (ps_codec->i4_max_ht / MIN_CTB_SIZE) * 2; 2796 2797 for(i = 0; i < MAX_PROCESS_THREADS; i++) 2798 { 2799 ps_codec->as_process[i].s_sao_ctxt.pu1_sao_src_top_left_luma_curr_ctb = (UWORD8 *)pu1_buf; 2800 } 2801 ps_codec->s_parse.s_sao_ctxt.pu1_sao_src_top_left_luma_curr_ctb = (UWORD8 *)pu1_buf; 2802 pu1_buf += ps_codec->i4_max_ht / MIN_CTB_SIZE; 2803 2804 for(i = 0; i < MAX_PROCESS_THREADS; i++) 2805 { 2806 ps_codec->as_process[i].s_sao_ctxt.pu1_sao_src_top_left_chroma_curr_ctb = (UWORD8 *)pu1_buf; 2807 } 2808 ps_codec->s_parse.s_sao_ctxt.pu1_sao_src_top_left_chroma_curr_ctb = (UWORD8 *)pu1_buf; 2809 2810 pu1_buf += (ps_codec->i4_max_ht / MIN_CTB_SIZE) * 2; 2811 for(i = 0; i < MAX_PROCESS_THREADS; i++) 2812 { 2813 ps_codec->as_process[i].s_sao_ctxt.pu1_sao_src_top_left_luma_top_right = (UWORD8 *)pu1_buf; 2814 } 2815 ps_codec->s_parse.s_sao_ctxt.pu1_sao_src_top_left_luma_top_right = (UWORD8 *)pu1_buf; 2816 2817 pu1_buf += ps_codec->i4_max_wd / MIN_CTB_SIZE; 2818 for(i = 0; i < MAX_PROCESS_THREADS; i++) 2819 { 2820 ps_codec->as_process[i].s_sao_ctxt.pu1_sao_src_top_left_chroma_top_right = (UWORD8 *)pu1_buf; 2821 } 2822 ps_codec->s_parse.s_sao_ctxt.pu1_sao_src_top_left_chroma_top_right = (UWORD8 *)pu1_buf; 2823 2824 pu1_buf += (ps_codec->i4_max_wd / MIN_CTB_SIZE) * 2; 2825 2826 /*Per CTB, Store 1 value for luma , 2 values for chroma*/ 2827 for(i = 0; i < MAX_PROCESS_THREADS; i++) 2828 { 2829 ps_codec->as_process[i].s_sao_ctxt.pu1_sao_src_top_left_luma_bot_left = (UWORD8 *)pu1_buf; 2830 } 2831 ps_codec->s_parse.s_sao_ctxt.pu1_sao_src_top_left_luma_bot_left = (UWORD8 *)pu1_buf; 2832 2833 pu1_buf += (ps_codec->i4_max_ht / MIN_CTB_SIZE); 2834 2835 for(i = 0; i < MAX_PROCESS_THREADS; i++) 2836 { 2837 ps_codec->as_process[i].s_sao_ctxt.pu1_sao_src_top_left_chroma_bot_left = (UWORD8 *)pu1_buf; 2838 } 2839 ps_codec->s_parse.s_sao_ctxt.pu1_sao_src_top_left_chroma_bot_left = (UWORD8 *)pu1_buf; 2840 2841 pu1_buf += (ps_codec->i4_max_ht / MIN_CTB_SIZE) * 2; 2842 } 2843 2844 ps_mem_rec = &ps_mem_rec_base[MEM_REC_SAO_SCRATCH]; 2845 { 2846 UWORD8 *pu1_buf = (UWORD8 *)ps_mem_rec->pv_base; 2847 for(i = 0; i < MAX_PROCESS_THREADS; i++) 2848 { 2849 ps_codec->as_process[i].s_sao_ctxt.pu1_tmp_buf_luma = (UWORD8 *)pu1_buf; 2850 pu1_buf += 4 * MAX_CTB_SIZE * MAX_CTB_SIZE * sizeof(UWORD8); 2851 2852 ps_codec->as_process[i].s_sao_ctxt.pu1_tmp_buf_chroma = (UWORD8 *)pu1_buf; 2853 pu1_buf += 4 * MAX_CTB_SIZE * MAX_CTB_SIZE * sizeof(UWORD8); 2854 } 2855 } 2856 2857 ps_mem_rec = &ps_mem_rec_base[MEM_REC_BS_QP]; 2858 { 2859 UWORD8 *pu1_buf = (UWORD8 *)ps_mem_rec->pv_base; 2860 WORD32 vert_bs_size, horz_bs_size; 2861 WORD32 qp_const_flag_size; 2862 WORD32 qp_size; 2863 WORD32 num_8x8; 2864 2865 /* Max Number of vertical edges */ 2866 vert_bs_size = ps_codec->i4_max_wd / 8 + 2 * MAX_CTB_SIZE / 8; 2867 2868 /* Max Number of horizontal edges - extra MAX_CTB_SIZE / 8 to handle the last 4 rows separately(shifted CTB processing) */ 2869 vert_bs_size *= (ps_codec->i4_max_ht + MAX_CTB_SIZE) / MIN_TU_SIZE; 2870 2871 /* Number of bytes */ 2872 vert_bs_size /= 8; 2873 2874 /* Two bits per edge */ 2875 vert_bs_size *= 2; 2876 2877 /* Max Number of horizontal edges */ 2878 horz_bs_size = ps_codec->i4_max_ht / 8 + MAX_CTB_SIZE / 8; 2879 2880 /* Max Number of vertical edges - extra MAX_CTB_SIZE / 8 to handle the last 4 columns separately(shifted CTB processing) */ 2881 horz_bs_size *= (ps_codec->i4_max_wd + MAX_CTB_SIZE) / MIN_TU_SIZE; 2882 2883 /* Number of bytes */ 2884 horz_bs_size /= 8; 2885 2886 /* Two bits per edge */ 2887 horz_bs_size *= 2; 2888 2889 /* Max CTBs in a row */ 2890 qp_const_flag_size = ps_codec->i4_max_wd / MIN_CTB_SIZE + 1 /* The last ctb row deblk is done in last ctb + 1 row.*/; 2891 2892 /* Max CTBs in a column */ 2893 qp_const_flag_size *= ps_codec->i4_max_ht / MIN_CTB_SIZE; 2894 2895 /* Number of bytes */ 2896 qp_const_flag_size /= 8; 2897 2898 /* QP changes at CU level - So store at 8x8 level */ 2899 num_8x8 = (ps_codec->i4_max_ht * ps_codec->i4_max_wd) / (MIN_CU_SIZE * MIN_CU_SIZE); 2900 qp_size = num_8x8; 2901 memset(pu1_buf, 0, vert_bs_size + horz_bs_size + qp_size + qp_const_flag_size); 2902 2903 for(i = 0; i < MAX_PROCESS_THREADS; i++) 2904 { 2905 ps_codec->as_process[i].s_bs_ctxt.pu4_pic_vert_bs = (UWORD32 *)pu1_buf; 2906 ps_codec->as_process[i].s_deblk_ctxt.s_bs_ctxt.pu4_pic_vert_bs = (UWORD32 *)pu1_buf; 2907 ps_codec->s_parse.s_deblk_ctxt.s_bs_ctxt.pu4_pic_vert_bs = (UWORD32 *)pu1_buf; 2908 pu1_buf += vert_bs_size; 2909 2910 ps_codec->as_process[i].s_bs_ctxt.pu4_pic_horz_bs = (UWORD32 *)pu1_buf; 2911 ps_codec->as_process[i].s_deblk_ctxt.s_bs_ctxt.pu4_pic_horz_bs = (UWORD32 *)pu1_buf; 2912 ps_codec->s_parse.s_deblk_ctxt.s_bs_ctxt.pu4_pic_horz_bs = (UWORD32 *)pu1_buf; 2913 pu1_buf += horz_bs_size; 2914 2915 ps_codec->as_process[i].s_bs_ctxt.pu1_pic_qp = (UWORD8 *)pu1_buf; 2916 ps_codec->as_process[i].s_deblk_ctxt.s_bs_ctxt.pu1_pic_qp = (UWORD8 *)pu1_buf; 2917 ps_codec->s_parse.s_deblk_ctxt.s_bs_ctxt.pu1_pic_qp = (UWORD8 *)pu1_buf; 2918 pu1_buf += qp_size; 2919 2920 ps_codec->as_process[i].s_bs_ctxt.pu1_pic_qp_const_in_ctb = (UWORD8 *)pu1_buf; 2921 ps_codec->as_process[i].s_deblk_ctxt.s_bs_ctxt.pu1_pic_qp_const_in_ctb = (UWORD8 *)pu1_buf; 2922 ps_codec->s_parse.s_deblk_ctxt.s_bs_ctxt.pu1_pic_qp_const_in_ctb = (UWORD8 *)pu1_buf; 2923 pu1_buf += qp_const_flag_size; 2924 2925 pu1_buf -= (vert_bs_size + horz_bs_size + qp_size + qp_const_flag_size); 2926 } 2927 ps_codec->s_parse.s_bs_ctxt.pu4_pic_vert_bs = (UWORD32 *)pu1_buf; 2928 pu1_buf += vert_bs_size; 2929 2930 ps_codec->s_parse.s_bs_ctxt.pu4_pic_horz_bs = (UWORD32 *)pu1_buf; 2931 pu1_buf += horz_bs_size; 2932 2933 ps_codec->s_parse.s_bs_ctxt.pu1_pic_qp = (UWORD8 *)pu1_buf; 2934 pu1_buf += qp_size; 2935 2936 ps_codec->s_parse.s_bs_ctxt.pu1_pic_qp_const_in_ctb = (UWORD8 *)pu1_buf; 2937 pu1_buf += qp_const_flag_size; 2938 2939 } 2940 2941 ps_mem_rec = &ps_mem_rec_base[MEM_REC_TILE_IDX]; 2942 { 2943 UWORD8 *pu1_buf = (UWORD8 *)ps_mem_rec->pv_base; 2944 2945 for(i = 0; i < MAX_PROCESS_THREADS; i++) 2946 { 2947 ps_codec->as_process[i].pu1_tile_idx = (UWORD16 *)pu1_buf + ps_codec->i4_max_wd / MIN_CTB_SIZE /* Offset 1 row */; 2948 } 2949 } 2950 2951 ps_mem_rec = &ps_mem_rec_base[MEM_REC_SAO]; 2952 ps_codec->s_parse.ps_pic_sao = (sao_t *)ps_mem_rec->pv_base; 2953 ps_codec->s_parse.s_sao_ctxt.ps_pic_sao = (sao_t *)ps_mem_rec->pv_base; 2954 for(i = 0; i < MAX_PROCESS_THREADS; i++) 2955 { 2956 ps_codec->as_process[i].s_sao_ctxt.ps_pic_sao = ps_codec->s_parse.ps_pic_sao; 2957 } 2958 2959 ps_mem_rec = &ps_mem_rec_base[MEM_REC_REF_PIC]; 2960 ps_codec->pv_pic_buf_mgr = ps_mem_rec->pv_base; 2961 ps_codec->pv_pic_buf_base = (UWORD8 *)ps_codec->pv_pic_buf_mgr + sizeof(buf_mgr_t); 2962 ps_codec->i4_total_pic_buf_size = ps_mem_rec->u4_mem_size - sizeof(buf_mgr_t); 2963 2964 2965 2966 2967 2968 #ifdef APPLY_CONCEALMENT 2969 { 2970 2971 UWORD32 mem_loc; 2972 2973 icncl_init_ip_t cncl_init_ip; 2974 icncl_init_op_t cncl_init_op; 2975 iv_mem_rec_t *ps_mem_rec; 2976 DecStruct *ps_codec; 2977 2978 ps_mem_rec = dec_init_ip->s_ivd_init_ip_t.pv_mem_rec_location; 2979 mem_loc = MEM_REC_CNT; 2980 2981 ps_codec->ps_conceal = (iv_obj_t *)ps_mem_rec[mem_loc].pv_base; 2982 ps_codec->i4_first_frame_done = 0; 2983 2984 cncl_init_ip.u4_size = sizeof(icncl_init_ip_t); 2985 cncl_init_ip.pv_mem_rec_location = &(ps_mem_rec[mem_loc]); 2986 cncl_init_ip.e_cmd = IV_CMD_INIT; 2987 2988 status = icncl_api_function(ps_codec->ps_conceal, (void *)&cncl_init_ip, (void *)&cncl_init_op); 2989 2990 } 2991 #endif //APPLY_CONCEALMENT 2992 2993 status = ihevcd_init(ps_codec); 2994 2995 TRACE_INIT(NULL); 2996 STATS_INIT(); 2997 return status; 2998 } 2999 /** 3000 ******************************************************************************* 3001 * 3002 * @brief 3003 * Retrieves mem records passed to the codec 3004 * 3005 * @par Description: 3006 * Retrieves memrecs passed earlier 3007 * 3008 * @param[in] ps_codec_obj 3009 * Pointer to codec object at API level 3010 * 3011 * @param[in] pv_api_ip 3012 * Pointer to input argument structure 3013 * 3014 * @param[out] pv_api_op 3015 * Pointer to output argument structure 3016 * 3017 * @returns Status 3018 * 3019 * @remarks 3020 * 3021 * 3022 ******************************************************************************* 3023 */ 3024 WORD32 ihevcd_retrieve_memrec(iv_obj_t *ps_codec_obj, 3025 void *pv_api_ip, 3026 void *pv_api_op) 3027 { 3028 3029 iv_retrieve_mem_rec_ip_t *dec_clr_ip; 3030 iv_retrieve_mem_rec_op_t *dec_clr_op; 3031 codec_t *ps_codec; 3032 dec_clr_ip = (iv_retrieve_mem_rec_ip_t *)pv_api_ip; 3033 dec_clr_op = (iv_retrieve_mem_rec_op_t *)pv_api_op; 3034 ps_codec = (codec_t *)(ps_codec_obj->pv_codec_handle); 3035 3036 if(ps_codec->i4_init_done != 1) 3037 { 3038 dec_clr_op->u4_error_code |= 1 << IVD_FATALERROR; 3039 dec_clr_op->u4_error_code |= IHEVCD_INIT_NOT_DONE; 3040 return IV_FAIL; 3041 } 3042 3043 memcpy(dec_clr_ip->pv_mem_rec_location, ps_codec->ps_mem_rec_backup, 3044 MEM_REC_CNT * (sizeof(iv_mem_rec_t))); 3045 dec_clr_op->u4_num_mem_rec_filled = MEM_REC_CNT; 3046 3047 #ifdef APPLY_CONCEALMENT 3048 { 3049 IV_API_CALL_STATUS_T status; 3050 icncl_fill_mem_rec_ip_t cncl_fill_ip; 3051 icncl_fill_mem_rec_op_t cncl_fill_op; 3052 3053 iv_mem_rec_t *ps_mem_rec; 3054 3055 UWORD8 mem_loc = MEM_REC_CNT; 3056 UWORD8 num_cncl_mem = 0; 3057 3058 ps_mem_rec = dec_clr_ip->pv_mem_rec_location; 3059 3060 cncl_fill_ip.s_ivd_fill_mem_rec_ip_t.e_cmd = IV_CMD_FILL_NUM_MEM_REC; 3061 cncl_fill_ip.s_ivd_fill_mem_rec_ip_t.pv_mem_rec_location = &(ps_mem_rec[mem_loc]); 3062 cncl_fill_ip.s_ivd_fill_mem_rec_ip_t.u4_size = sizeof(icncl_fill_mem_rec_ip_t); 3063 3064 status = icncl_api_function(NULL, (void *)&cncl_fill_ip, (void *)&cncl_fill_op); 3065 3066 cncl_fill_ip.s_ivd_fill_mem_rec_ip_t.e_cmd = IV_CMD_RETRIEVE_MEMREC; 3067 cncl_fill_op.s_ivd_fill_mem_rec_op_t.u4_size = sizeof(icncl_fill_mem_rec_op_t); 3068 3069 status = icncl_api_function(ps_codec->ps_conceal, (void *)&cncl_fill_ip, (void *)&cncl_fill_op); 3070 3071 if(status == IV_SUCCESS) 3072 { 3073 /* Add the concealment library's memory requirements */ 3074 dec_clr_op->u4_num_mem_rec_filled += cncl_fill_op.s_ivd_fill_mem_rec_op_t.u4_num_mem_rec_filled; 3075 } 3076 } 3077 #endif //APPLY_CONCEALMENT 3078 DEBUG("Retrieve num mem recs: %d\n", 3079 dec_clr_op->u4_num_mem_rec_filled); 3080 STATS_PRINT(); 3081 ihevcd_jobq_free((jobq_t *)ps_codec->pv_proc_jobq); 3082 3083 3084 3085 return IV_SUCCESS; 3086 3087 } 3088 /** 3089 ******************************************************************************* 3090 * 3091 * @brief 3092 * Passes display buffer from application to codec 3093 * 3094 * @par Description: 3095 * Adds display buffer to the codec 3096 * 3097 * @param[in] ps_codec_obj 3098 * Pointer to codec object at API level 3099 * 3100 * @param[in] pv_api_ip 3101 * Pointer to input argument structure 3102 * 3103 * @param[out] pv_api_op 3104 * Pointer to output argument structure 3105 * 3106 * @returns Status 3107 * 3108 * @remarks 3109 * 3110 * 3111 ******************************************************************************* 3112 */ 3113 WORD32 ihevcd_set_display_frame(iv_obj_t *ps_codec_obj, 3114 void *pv_api_ip, 3115 void *pv_api_op) 3116 { 3117 WORD32 ret = IV_SUCCESS; 3118 3119 ivd_set_display_frame_ip_t *ps_dec_disp_ip; 3120 ivd_set_display_frame_op_t *ps_dec_disp_op; 3121 3122 WORD32 i; 3123 3124 codec_t *ps_codec = (codec_t *)(ps_codec_obj->pv_codec_handle); 3125 3126 ps_dec_disp_ip = (ivd_set_display_frame_ip_t *)pv_api_ip; 3127 ps_dec_disp_op = (ivd_set_display_frame_op_t *)pv_api_op; 3128 3129 ps_codec->i4_num_disp_bufs = 0; 3130 if(ps_codec->i4_share_disp_buf) 3131 { 3132 UWORD32 num_bufs = ps_dec_disp_ip->num_disp_bufs; 3133 pic_buf_t *ps_pic_buf; 3134 UWORD8 *pu1_buf; 3135 WORD32 buf_ret; 3136 WORD32 strd; 3137 strd = ps_codec->i4_strd; 3138 if(0 == strd) 3139 strd = ps_codec->i4_max_wd + PAD_WD; 3140 num_bufs = MIN(num_bufs, BUF_MGR_MAX_CNT); 3141 ps_codec->i4_num_disp_bufs = num_bufs; 3142 3143 ps_pic_buf = (pic_buf_t *)ps_codec->ps_pic_buf; 3144 for(i = 0; i < (WORD32)num_bufs; i++) 3145 { 3146 pu1_buf = ps_dec_disp_ip->s_disp_buffer[i].pu1_bufs[0]; 3147 ps_pic_buf->pu1_luma = pu1_buf + strd * PAD_TOP + PAD_LEFT; 3148 3149 pu1_buf = ps_dec_disp_ip->s_disp_buffer[i].pu1_bufs[1]; 3150 ps_pic_buf->pu1_chroma = pu1_buf + strd * (PAD_TOP / 2) + PAD_LEFT; 3151 3152 buf_ret = ihevc_buf_mgr_add((buf_mgr_t *)ps_codec->pv_pic_buf_mgr, ps_pic_buf, i); 3153 3154 if(0 != buf_ret) 3155 { 3156 ps_codec->i4_error_code = IHEVCD_BUF_MGR_ERROR; 3157 return IHEVCD_BUF_MGR_ERROR; 3158 } 3159 3160 /* Mark pic buf as needed for display */ 3161 /* This ensures that till the buffer is explicitly passed to the codec, 3162 * application owns the buffer. Decoder is allowed to use a buffer only 3163 * when application sends it through fill this buffer call in OMX 3164 */ 3165 ihevc_buf_mgr_set_status((buf_mgr_t *)ps_codec->pv_pic_buf_mgr, i, BUF_MGR_DISP); 3166 3167 ps_pic_buf++; 3168 3169 } 3170 } 3171 3172 ps_dec_disp_op->u4_error_code = 0; 3173 return ret; 3174 3175 } 3176 3177 /** 3178 ******************************************************************************* 3179 * 3180 * @brief 3181 * Sets the decoder in flush mode. Decoder will come out of flush only 3182 * after returning all the buffers or at reset 3183 * 3184 * @par Description: 3185 * Sets the decoder in flush mode 3186 * 3187 * @param[in] ps_codec_obj 3188 * Pointer to codec object at API level 3189 * 3190 * @param[in] pv_api_ip 3191 * Pointer to input argument structure 3192 * 3193 * @param[out] pv_api_op 3194 * Pointer to output argument structure 3195 * 3196 * @returns Status 3197 * 3198 * @remarks 3199 * 3200 * 3201 ******************************************************************************* 3202 */ 3203 WORD32 ihevcd_set_flush_mode(iv_obj_t *ps_codec_obj, 3204 void *pv_api_ip, 3205 void *pv_api_op) 3206 { 3207 3208 codec_t *ps_codec; 3209 ivd_ctl_flush_op_t *ps_ctl_op = (ivd_ctl_flush_op_t *)pv_api_op; 3210 UNUSED(pv_api_ip); 3211 ps_codec = (codec_t *)(ps_codec_obj->pv_codec_handle); 3212 3213 /* Signal flush frame control call */ 3214 ps_codec->i4_flush_mode = 1; 3215 3216 ps_ctl_op->u4_error_code = 0; 3217 3218 /* Set pic count to zero, so that decoder starts buffering again */ 3219 /* once it comes out of flush mode */ 3220 ps_codec->u4_pic_cnt = 0; 3221 ps_codec->u4_disp_cnt = 0; 3222 return IV_SUCCESS; 3223 3224 3225 } 3226 3227 /** 3228 ******************************************************************************* 3229 * 3230 * @brief 3231 * Gets decoder status and buffer requirements 3232 * 3233 * @par Description: 3234 * Gets the decoder status 3235 * 3236 * @param[in] ps_codec_obj 3237 * Pointer to codec object at API level 3238 * 3239 * @param[in] pv_api_ip 3240 * Pointer to input argument structure 3241 * 3242 * @param[out] pv_api_op 3243 * Pointer to output argument structure 3244 * 3245 * @returns Status 3246 * 3247 * @remarks 3248 * 3249 * 3250 ******************************************************************************* 3251 */ 3252 3253 WORD32 ihevcd_get_status(iv_obj_t *ps_codec_obj, 3254 void *pv_api_ip, 3255 void *pv_api_op) 3256 { 3257 3258 WORD32 i; 3259 codec_t *ps_codec; 3260 WORD32 wd, ht; 3261 ivd_ctl_getstatus_op_t *ps_ctl_op = (ivd_ctl_getstatus_op_t *)pv_api_op; 3262 3263 UNUSED(pv_api_ip); 3264 3265 ps_ctl_op->u4_error_code = 0; 3266 3267 ps_codec = (codec_t *)(ps_codec_obj->pv_codec_handle); 3268 3269 ps_ctl_op->u4_min_num_in_bufs = MIN_IN_BUFS; 3270 if(ps_codec->e_chroma_fmt == IV_YUV_420P) 3271 ps_ctl_op->u4_min_num_out_bufs = MIN_OUT_BUFS_420; 3272 else if(ps_codec->e_chroma_fmt == IV_YUV_422ILE) 3273 ps_ctl_op->u4_min_num_out_bufs = MIN_OUT_BUFS_422ILE; 3274 else if(ps_codec->e_chroma_fmt == IV_RGB_565) 3275 ps_ctl_op->u4_min_num_out_bufs = MIN_OUT_BUFS_RGB565; 3276 else if(ps_codec->e_chroma_fmt == IV_RGBA_8888) 3277 ps_ctl_op->u4_min_num_out_bufs = MIN_OUT_BUFS_RGBA8888; 3278 else if((ps_codec->e_chroma_fmt == IV_YUV_420SP_UV) 3279 || (ps_codec->e_chroma_fmt == IV_YUV_420SP_VU)) 3280 ps_ctl_op->u4_min_num_out_bufs = MIN_OUT_BUFS_420SP; 3281 3282 ps_ctl_op->u4_num_disp_bufs = 1; 3283 3284 for(i = 0; i < (WORD32)ps_ctl_op->u4_min_num_in_bufs; i++) 3285 { 3286 ps_ctl_op->u4_min_in_buf_size[i] = MAX((ps_codec->i4_wd * ps_codec->i4_ht), MIN_BITSBUF_SIZE); 3287 } 3288 3289 wd = ps_codec->i4_wd; 3290 ht = ps_codec->i4_ht; 3291 3292 if(ps_codec->i4_sps_done) 3293 { 3294 if(0 == ps_codec->i4_share_disp_buf) 3295 { 3296 wd = ps_codec->i4_disp_wd; 3297 ht = ps_codec->i4_disp_ht; 3298 3299 } 3300 else 3301 { 3302 wd = ps_codec->i4_disp_strd; 3303 ht = ps_codec->i4_ht + PAD_HT; 3304 } 3305 } 3306 else 3307 { 3308 if(0 == ps_codec->i4_share_disp_buf) 3309 { 3310 wd = ps_codec->i4_new_max_wd; 3311 ht = ps_codec->i4_new_max_ht; 3312 } 3313 else 3314 { 3315 wd = ALIGN32(wd + PAD_WD); 3316 ht += PAD_HT; 3317 } 3318 } 3319 3320 if(ps_codec->i4_disp_strd > wd) 3321 wd = ps_codec->i4_disp_strd; 3322 3323 if(0 == ps_codec->i4_share_disp_buf) 3324 ps_ctl_op->u4_num_disp_bufs = 1; 3325 else 3326 { 3327 WORD32 pic_size; 3328 WORD32 max_dpb_size; 3329 3330 if(ps_codec->i4_sps_done) 3331 { 3332 sps_t *ps_sps = (ps_codec->s_parse.ps_sps_base + ps_codec->i4_sps_id); 3333 WORD32 reorder_pic_cnt; 3334 WORD32 ref_pic_cnt; 3335 WORD32 level; 3336 3337 reorder_pic_cnt = MIN(ps_sps->ai1_sps_max_num_reorder_pics[0], ps_codec->i4_init_num_reorder); 3338 pic_size = ps_sps->i2_pic_width_in_luma_samples * ps_sps->i2_pic_height_in_luma_samples; 3339 3340 level = ps_codec->i4_init_level; 3341 max_dpb_size = ihevcd_get_dpb_size(level, pic_size); 3342 ref_pic_cnt = max_dpb_size; 3343 ps_ctl_op->u4_num_disp_bufs = reorder_pic_cnt; 3344 3345 ps_ctl_op->u4_num_disp_bufs += ref_pic_cnt + 1; 3346 3347 } 3348 else 3349 { 3350 pic_size = ps_codec->i4_max_wd * ps_codec->i4_max_ht; 3351 max_dpb_size = ihevcd_get_dpb_size(ps_codec->i4_init_level, pic_size); 3352 ps_ctl_op->u4_num_disp_bufs = 2 * max_dpb_size; 3353 3354 ps_ctl_op->u4_num_disp_bufs = MIN(ps_ctl_op->u4_num_disp_bufs, 3355 (UWORD32)(ps_codec->i4_init_num_ref + ps_codec->i4_init_num_reorder + 1)); 3356 3357 } 3358 3359 ps_ctl_op->u4_num_disp_bufs = MIN( 3360 ps_ctl_op->u4_num_disp_bufs, 32); 3361 } 3362 3363 /*!*/ 3364 if(ps_codec->e_chroma_fmt == IV_YUV_420P) 3365 { 3366 ps_ctl_op->u4_min_out_buf_size[0] = (wd * ht); 3367 ps_ctl_op->u4_min_out_buf_size[1] = (wd * ht) >> 2; 3368 ps_ctl_op->u4_min_out_buf_size[2] = (wd * ht) >> 2; 3369 } 3370 else if(ps_codec->e_chroma_fmt == IV_YUV_422ILE) 3371 { 3372 ps_ctl_op->u4_min_out_buf_size[0] = (wd * ht) * 2; 3373 ps_ctl_op->u4_min_out_buf_size[1] = 3374 ps_ctl_op->u4_min_out_buf_size[2] = 0; 3375 } 3376 else if(ps_codec->e_chroma_fmt == IV_RGB_565) 3377 { 3378 ps_ctl_op->u4_min_out_buf_size[0] = (wd * ht) * 2; 3379 ps_ctl_op->u4_min_out_buf_size[1] = 3380 ps_ctl_op->u4_min_out_buf_size[2] = 0; 3381 } 3382 else if(ps_codec->e_chroma_fmt == IV_RGBA_8888) 3383 { 3384 ps_ctl_op->u4_min_out_buf_size[0] = (wd * ht) * 4; 3385 ps_ctl_op->u4_min_out_buf_size[1] = 3386 ps_ctl_op->u4_min_out_buf_size[2] = 0; 3387 } 3388 else if((ps_codec->e_chroma_fmt == IV_YUV_420SP_UV) 3389 || (ps_codec->e_chroma_fmt == IV_YUV_420SP_VU)) 3390 { 3391 ps_ctl_op->u4_min_out_buf_size[0] = (wd * ht); 3392 ps_ctl_op->u4_min_out_buf_size[1] = (wd * ht) >> 1; 3393 ps_ctl_op->u4_min_out_buf_size[2] = 0; 3394 } 3395 ps_ctl_op->u4_pic_ht = ht; 3396 ps_ctl_op->u4_pic_wd = wd; 3397 ps_ctl_op->u4_frame_rate = 30000; 3398 ps_ctl_op->u4_bit_rate = 1000000; 3399 ps_ctl_op->e_content_type = IV_PROGRESSIVE; 3400 ps_ctl_op->e_output_chroma_format = ps_codec->e_chroma_fmt; 3401 ps_codec->i4_num_disp_bufs = ps_ctl_op->u4_num_disp_bufs; 3402 3403 if(ps_ctl_op->u4_size == sizeof(ihevcd_cxa_ctl_getstatus_op_t)) 3404 { 3405 ihevcd_cxa_ctl_getstatus_op_t *ps_ext_ctl_op = (ihevcd_cxa_ctl_getstatus_op_t *)ps_ctl_op; 3406 ps_ext_ctl_op->u4_coded_pic_wd = ps_codec->i4_wd; 3407 ps_ext_ctl_op->u4_coded_pic_wd = ps_codec->i4_ht; 3408 } 3409 return IV_SUCCESS; 3410 } 3411 /** 3412 ******************************************************************************* 3413 * 3414 * @brief 3415 * Gets decoder buffer requirements 3416 * 3417 * @par Description: 3418 * Gets the decoder buffer requirements. If called before header decoder, 3419 * buffer requirements are based on max_wd and max_ht else actual width and 3420 * height will be used 3421 * 3422 * @param[in] ps_codec_obj 3423 * Pointer to codec object at API level 3424 * 3425 * @param[in] pv_api_ip 3426 * Pointer to input argument structure 3427 * 3428 * @param[out] pv_api_op 3429 * Pointer to output argument structure 3430 * 3431 * @returns Status 3432 * 3433 * @remarks 3434 * 3435 * 3436 ******************************************************************************* 3437 */ 3438 WORD32 ihevcd_get_buf_info(iv_obj_t *ps_codec_obj, 3439 void *pv_api_ip, 3440 void *pv_api_op) 3441 { 3442 3443 codec_t *ps_codec; 3444 UWORD32 i = 0; 3445 WORD32 wd, ht; 3446 ivd_ctl_getbufinfo_op_t *ps_ctl_op = 3447 (ivd_ctl_getbufinfo_op_t *)pv_api_op; 3448 3449 UNUSED(pv_api_ip); 3450 ps_ctl_op->u4_error_code = 0; 3451 3452 ps_codec = (codec_t *)(ps_codec_obj->pv_codec_handle); 3453 3454 ps_ctl_op->u4_min_num_in_bufs = MIN_IN_BUFS; 3455 if(ps_codec->e_chroma_fmt == IV_YUV_420P) 3456 ps_ctl_op->u4_min_num_out_bufs = MIN_OUT_BUFS_420; 3457 else if(ps_codec->e_chroma_fmt == IV_YUV_422ILE) 3458 ps_ctl_op->u4_min_num_out_bufs = MIN_OUT_BUFS_422ILE; 3459 else if(ps_codec->e_chroma_fmt == IV_RGB_565) 3460 ps_ctl_op->u4_min_num_out_bufs = MIN_OUT_BUFS_RGB565; 3461 else if(ps_codec->e_chroma_fmt == IV_RGBA_8888) 3462 ps_ctl_op->u4_min_num_out_bufs = MIN_OUT_BUFS_RGBA8888; 3463 else if((ps_codec->e_chroma_fmt == IV_YUV_420SP_UV) 3464 || (ps_codec->e_chroma_fmt == IV_YUV_420SP_VU)) 3465 ps_ctl_op->u4_min_num_out_bufs = MIN_OUT_BUFS_420SP; 3466 3467 ps_ctl_op->u4_num_disp_bufs = 1; 3468 3469 for(i = 0; i < ps_ctl_op->u4_min_num_in_bufs; i++) 3470 { 3471 ps_ctl_op->u4_min_in_buf_size[i] = MAX((ps_codec->i4_wd * ps_codec->i4_ht), MIN_BITSBUF_SIZE); 3472 } 3473 3474 wd = ps_codec->i4_max_wd; 3475 ht = ps_codec->i4_max_ht; 3476 3477 if(ps_codec->i4_sps_done) 3478 { 3479 if(0 == ps_codec->i4_share_disp_buf) 3480 { 3481 wd = ps_codec->i4_disp_wd; 3482 ht = ps_codec->i4_disp_ht; 3483 3484 } 3485 else 3486 { 3487 wd = ps_codec->i4_disp_strd; 3488 ht = ps_codec->i4_ht + PAD_HT; 3489 } 3490 } 3491 else 3492 { 3493 if(1 == ps_codec->i4_share_disp_buf) 3494 { 3495 wd = ALIGN32(wd + PAD_WD); 3496 ht += PAD_HT; 3497 } 3498 } 3499 3500 if(ps_codec->i4_disp_strd > wd) 3501 wd = ps_codec->i4_disp_strd; 3502 3503 if(0 == ps_codec->i4_share_disp_buf) 3504 ps_ctl_op->u4_num_disp_bufs = 1; 3505 else 3506 { 3507 WORD32 pic_size; 3508 WORD32 max_dpb_size; 3509 3510 if(ps_codec->i4_sps_done) 3511 { 3512 sps_t *ps_sps = (ps_codec->s_parse.ps_sps_base + ps_codec->i4_sps_id); 3513 WORD32 reorder_pic_cnt; 3514 WORD32 ref_pic_cnt; 3515 WORD32 level; 3516 3517 reorder_pic_cnt = MIN(ps_sps->ai1_sps_max_num_reorder_pics[0], ps_codec->i4_init_num_reorder); 3518 pic_size = ps_sps->i2_pic_width_in_luma_samples * ps_sps->i2_pic_height_in_luma_samples; 3519 3520 level = ps_codec->i4_init_level; 3521 max_dpb_size = ihevcd_get_dpb_size(level, pic_size); 3522 ref_pic_cnt = max_dpb_size; 3523 ps_ctl_op->u4_num_disp_bufs = reorder_pic_cnt; 3524 3525 ps_ctl_op->u4_num_disp_bufs += ref_pic_cnt + 1; 3526 3527 } 3528 else 3529 { 3530 pic_size = ps_codec->i4_max_wd * ps_codec->i4_max_ht; 3531 max_dpb_size = ihevcd_get_dpb_size(ps_codec->i4_init_level, pic_size); 3532 ps_ctl_op->u4_num_disp_bufs = 2 * max_dpb_size; 3533 3534 ps_ctl_op->u4_num_disp_bufs = MIN(ps_ctl_op->u4_num_disp_bufs, 3535 (UWORD32)(ps_codec->i4_init_num_ref + ps_codec->i4_init_num_reorder + 1)); 3536 3537 } 3538 3539 ps_ctl_op->u4_num_disp_bufs = MIN( 3540 ps_ctl_op->u4_num_disp_bufs, 32); 3541 3542 } 3543 3544 /*!*/ 3545 if(ps_codec->e_chroma_fmt == IV_YUV_420P) 3546 { 3547 ps_ctl_op->u4_min_out_buf_size[0] = (wd * ht); 3548 ps_ctl_op->u4_min_out_buf_size[1] = (wd * ht) >> 2; 3549 ps_ctl_op->u4_min_out_buf_size[2] = (wd * ht) >> 2; 3550 } 3551 else if(ps_codec->e_chroma_fmt == IV_YUV_422ILE) 3552 { 3553 ps_ctl_op->u4_min_out_buf_size[0] = (wd * ht) * 2; 3554 ps_ctl_op->u4_min_out_buf_size[1] = 3555 ps_ctl_op->u4_min_out_buf_size[2] = 0; 3556 } 3557 else if(ps_codec->e_chroma_fmt == IV_RGB_565) 3558 { 3559 ps_ctl_op->u4_min_out_buf_size[0] = (wd * ht) * 2; 3560 ps_ctl_op->u4_min_out_buf_size[1] = 3561 ps_ctl_op->u4_min_out_buf_size[2] = 0; 3562 } 3563 else if(ps_codec->e_chroma_fmt == IV_RGBA_8888) 3564 { 3565 ps_ctl_op->u4_min_out_buf_size[0] = (wd * ht) * 4; 3566 ps_ctl_op->u4_min_out_buf_size[1] = 3567 ps_ctl_op->u4_min_out_buf_size[2] = 0; 3568 } 3569 else if((ps_codec->e_chroma_fmt == IV_YUV_420SP_UV) 3570 || (ps_codec->e_chroma_fmt == IV_YUV_420SP_VU)) 3571 { 3572 ps_ctl_op->u4_min_out_buf_size[0] = (wd * ht); 3573 ps_ctl_op->u4_min_out_buf_size[1] = (wd * ht) >> 1; 3574 ps_ctl_op->u4_min_out_buf_size[2] = 0; 3575 } 3576 ps_codec->i4_num_disp_bufs = ps_ctl_op->u4_num_disp_bufs; 3577 3578 return IV_SUCCESS; 3579 } 3580 3581 3582 /** 3583 ******************************************************************************* 3584 * 3585 * @brief 3586 * Sets dynamic parameters 3587 * 3588 * @par Description: 3589 * Sets dynamic parameters. Note Frame skip, decode header mode are dynamic 3590 * Dynamic change in stride is not supported 3591 * 3592 * @param[in] ps_codec_obj 3593 * Pointer to codec object at API level 3594 * 3595 * @param[in] pv_api_ip 3596 * Pointer to input argument structure 3597 * 3598 * @param[out] pv_api_op 3599 * Pointer to output argument structure 3600 * 3601 * @returns Status 3602 * 3603 * @remarks 3604 * 3605 * 3606 ******************************************************************************* 3607 */ 3608 WORD32 ihevcd_set_params(iv_obj_t *ps_codec_obj, 3609 void *pv_api_ip, 3610 void *pv_api_op) 3611 { 3612 3613 codec_t *ps_codec; 3614 WORD32 ret = IV_SUCCESS; 3615 WORD32 strd; 3616 ivd_ctl_set_config_ip_t *s_ctl_dynparams_ip = 3617 (ivd_ctl_set_config_ip_t *)pv_api_ip; 3618 ivd_ctl_set_config_op_t *s_ctl_dynparams_op = 3619 (ivd_ctl_set_config_op_t *)pv_api_op; 3620 3621 ps_codec = (codec_t *)(ps_codec_obj->pv_codec_handle); 3622 3623 s_ctl_dynparams_op->u4_error_code = 0; 3624 3625 ps_codec->e_pic_skip_mode = s_ctl_dynparams_ip->e_frm_skip_mode; 3626 3627 if(s_ctl_dynparams_ip->e_frm_skip_mode != IVD_SKIP_NONE) 3628 { 3629 3630 if((s_ctl_dynparams_ip->e_frm_skip_mode != IVD_SKIP_P) && 3631 (s_ctl_dynparams_ip->e_frm_skip_mode != IVD_SKIP_B) && 3632 (s_ctl_dynparams_ip->e_frm_skip_mode != IVD_SKIP_PB)) 3633 { 3634 s_ctl_dynparams_op->u4_error_code = (1 << IVD_UNSUPPORTEDPARAM); 3635 ret = IV_FAIL; 3636 } 3637 } 3638 3639 strd = ps_codec->i4_disp_strd; 3640 if(1 == ps_codec->i4_share_disp_buf) 3641 { 3642 strd = ps_codec->i4_strd; 3643 } 3644 3645 3646 if((-1 != (WORD32)s_ctl_dynparams_ip->u4_disp_wd) && 3647 (0 != s_ctl_dynparams_ip->u4_disp_wd) && 3648 (0 != strd) && 3649 ((WORD32)s_ctl_dynparams_ip->u4_disp_wd < strd)) 3650 { 3651 s_ctl_dynparams_op->u4_error_code |= (1 << IVD_UNSUPPORTEDPARAM); 3652 s_ctl_dynparams_op->u4_error_code |= IHEVCD_INVALID_DISP_STRD; 3653 ret = IV_FAIL; 3654 } 3655 else 3656 { 3657 if((WORD32)s_ctl_dynparams_ip->u4_disp_wd >= ps_codec->i4_wd) 3658 { 3659 strd = s_ctl_dynparams_ip->u4_disp_wd; 3660 } 3661 else if(0 == ps_codec->i4_sps_done || 3662 0 == ps_codec->i4_pps_done) 3663 { 3664 strd = s_ctl_dynparams_ip->u4_disp_wd; 3665 } 3666 else if(s_ctl_dynparams_ip->u4_disp_wd == 0) 3667 { 3668 strd = ps_codec->i4_disp_strd; 3669 } 3670 else 3671 { 3672 strd = 0; 3673 s_ctl_dynparams_op->u4_error_code |= (1 << IVD_UNSUPPORTEDPARAM); 3674 s_ctl_dynparams_op->u4_error_code |= IHEVCD_INVALID_DISP_STRD; 3675 ret = IV_FAIL; 3676 } 3677 } 3678 3679 ps_codec->i4_disp_strd = strd; 3680 if(1 == ps_codec->i4_share_disp_buf) 3681 { 3682 ps_codec->i4_strd = strd; 3683 } 3684 3685 if(s_ctl_dynparams_ip->e_vid_dec_mode == IVD_DECODE_FRAME) 3686 ps_codec->i4_header_mode = 0; 3687 else if(s_ctl_dynparams_ip->e_vid_dec_mode == IVD_DECODE_HEADER) 3688 ps_codec->i4_header_mode = 1; 3689 else 3690 { 3691 3692 s_ctl_dynparams_op->u4_error_code = (1 << IVD_UNSUPPORTEDPARAM); 3693 ps_codec->i4_header_mode = 1; 3694 ret = IV_FAIL; 3695 } 3696 3697 3698 return ret; 3699 3700 } 3701 /** 3702 ******************************************************************************* 3703 * 3704 * @brief 3705 * Resets the decoder state 3706 * 3707 * @par Description: 3708 * Resets the decoder state by calling ihevcd_init() 3709 * 3710 * @param[in] ps_codec_obj 3711 * Pointer to codec object at API level 3712 * 3713 * @param[in] pv_api_ip 3714 * Pointer to input argument structure 3715 * 3716 * @param[out] pv_api_op 3717 * Pointer to output argument structure 3718 * 3719 * @returns Status 3720 * 3721 * @remarks 3722 * 3723 * 3724 ******************************************************************************* 3725 */ 3726 WORD32 ihevcd_reset(iv_obj_t *ps_codec_obj, void *pv_api_ip, void *pv_api_op) 3727 { 3728 codec_t *ps_codec; 3729 ivd_ctl_reset_op_t *s_ctl_reset_op = (ivd_ctl_reset_op_t *)pv_api_op; 3730 UNUSED(pv_api_ip); 3731 ps_codec = (codec_t *)(ps_codec_obj->pv_codec_handle); 3732 3733 if(ps_codec != NULL) 3734 { 3735 DEBUG("\nReset called \n"); 3736 ihevcd_init(ps_codec); 3737 } 3738 else 3739 { 3740 DEBUG("\nReset called without Initializing the decoder\n"); 3741 s_ctl_reset_op->u4_error_code = IHEVCD_INIT_NOT_DONE; 3742 } 3743 3744 return IV_SUCCESS; 3745 } 3746 3747 /** 3748 ******************************************************************************* 3749 * 3750 * @brief 3751 * Releases display buffer from application to codec to signal to the codec 3752 * that it can write to this buffer if required. Till release is called, 3753 * codec can not write to this buffer 3754 * 3755 * @par Description: 3756 * Marks the buffer as display done 3757 * 3758 * @param[in] ps_codec_obj 3759 * Pointer to codec object at API level 3760 * 3761 * @param[in] pv_api_ip 3762 * Pointer to input argument structure 3763 * 3764 * @param[out] pv_api_op 3765 * Pointer to output argument structure 3766 * 3767 * @returns Status 3768 * 3769 * @remarks 3770 * 3771 * 3772 ******************************************************************************* 3773 */ 3774 3775 WORD32 ihevcd_rel_display_frame(iv_obj_t *ps_codec_obj, 3776 void *pv_api_ip, 3777 void *pv_api_op) 3778 { 3779 3780 ivd_rel_display_frame_ip_t *ps_dec_rel_disp_ip; 3781 ivd_rel_display_frame_op_t *ps_dec_rel_disp_op; 3782 3783 codec_t *ps_codec = (codec_t *)ps_codec_obj->pv_codec_handle; 3784 3785 ps_dec_rel_disp_ip = (ivd_rel_display_frame_ip_t *)pv_api_ip; 3786 ps_dec_rel_disp_op = (ivd_rel_display_frame_op_t *)pv_api_op; 3787 3788 UNUSED(ps_dec_rel_disp_op); 3789 3790 if(0 == ps_codec->i4_share_disp_buf) 3791 { 3792 return IV_SUCCESS; 3793 } 3794 3795 ihevc_buf_mgr_release((buf_mgr_t *)ps_codec->pv_pic_buf_mgr, ps_dec_rel_disp_ip->u4_disp_buf_id, BUF_MGR_DISP); 3796 3797 return IV_SUCCESS; 3798 } 3799 /** 3800 ******************************************************************************* 3801 * 3802 * @brief 3803 * Sets degrade params 3804 * 3805 * @par Description: 3806 * Sets degrade params. 3807 * Refer to ihevcd_cxa_ctl_degrade_ip_t definition for details 3808 * 3809 * @param[in] ps_codec_obj 3810 * Pointer to codec object at API level 3811 * 3812 * @param[in] pv_api_ip 3813 * Pointer to input argument structure 3814 * 3815 * @param[out] pv_api_op 3816 * Pointer to output argument structure 3817 * 3818 * @returns Status 3819 * 3820 * @remarks 3821 * 3822 * 3823 ******************************************************************************* 3824 */ 3825 3826 WORD32 ihevcd_set_degrade(iv_obj_t *ps_codec_obj, 3827 void *pv_api_ip, 3828 void *pv_api_op) 3829 { 3830 ihevcd_cxa_ctl_degrade_ip_t *ps_ip; 3831 ihevcd_cxa_ctl_degrade_op_t *ps_op; 3832 codec_t *ps_codec = (codec_t *)ps_codec_obj->pv_codec_handle; 3833 3834 ps_ip = (ihevcd_cxa_ctl_degrade_ip_t *)pv_api_ip; 3835 ps_op = (ihevcd_cxa_ctl_degrade_op_t *)pv_api_op; 3836 3837 ps_codec->i4_degrade_type = ps_ip->i4_degrade_type; 3838 ps_codec->i4_nondegrade_interval = ps_ip->i4_nondegrade_interval; 3839 ps_codec->i4_degrade_pics = ps_ip->i4_degrade_pics; 3840 3841 ps_op->u4_error_code = 0; 3842 ps_codec->i4_degrade_pic_cnt = 0; 3843 3844 return IV_SUCCESS; 3845 } 3846 3847 3848 /** 3849 ******************************************************************************* 3850 * 3851 * @brief 3852 * Gets frame dimensions/offsets 3853 * 3854 * @par Description: 3855 * Gets frame buffer chararacteristics such a x & y offsets display and 3856 * buffer dimensions 3857 * 3858 * @param[in] ps_codec_obj 3859 * Pointer to codec object at API level 3860 * 3861 * @param[in] pv_api_ip 3862 * Pointer to input argument structure 3863 * 3864 * @param[out] pv_api_op 3865 * Pointer to output argument structure 3866 * 3867 * @returns Status 3868 * 3869 * @remarks 3870 * 3871 * 3872 ******************************************************************************* 3873 */ 3874 3875 WORD32 ihevcd_get_frame_dimensions(iv_obj_t *ps_codec_obj, 3876 void *pv_api_ip, 3877 void *pv_api_op) 3878 { 3879 ihevcd_cxa_ctl_get_frame_dimensions_ip_t *ps_ip; 3880 ihevcd_cxa_ctl_get_frame_dimensions_op_t *ps_op; 3881 codec_t *ps_codec = (codec_t *)ps_codec_obj->pv_codec_handle; 3882 WORD32 disp_wd, disp_ht, buffer_wd, buffer_ht, x_offset, y_offset; 3883 ps_ip = (ihevcd_cxa_ctl_get_frame_dimensions_ip_t *)pv_api_ip; 3884 ps_op = (ihevcd_cxa_ctl_get_frame_dimensions_op_t *)pv_api_op; 3885 UNUSED(ps_ip); 3886 if(ps_codec->i4_sps_done) 3887 { 3888 disp_wd = ps_codec->i4_disp_wd; 3889 disp_ht = ps_codec->i4_disp_ht; 3890 3891 if(0 == ps_codec->i4_share_disp_buf) 3892 { 3893 buffer_wd = disp_wd; 3894 buffer_ht = disp_ht; 3895 } 3896 else 3897 { 3898 buffer_wd = ps_codec->i4_strd; 3899 buffer_ht = ps_codec->i4_ht + PAD_HT; 3900 } 3901 } 3902 else 3903 { 3904 3905 disp_wd = ps_codec->i4_max_wd; 3906 disp_ht = ps_codec->i4_max_ht; 3907 3908 if(0 == ps_codec->i4_share_disp_buf) 3909 { 3910 buffer_wd = disp_wd; 3911 buffer_ht = disp_ht; 3912 } 3913 else 3914 { 3915 buffer_wd = ALIGN16(disp_wd) + PAD_WD; 3916 buffer_ht = ALIGN16(disp_ht) + PAD_HT; 3917 3918 } 3919 } 3920 if(ps_codec->i4_strd > buffer_wd) 3921 buffer_wd = ps_codec->i4_strd; 3922 3923 if(0 == ps_codec->i4_share_disp_buf) 3924 { 3925 x_offset = 0; 3926 y_offset = 0; 3927 } 3928 else 3929 { 3930 y_offset = PAD_TOP; 3931 x_offset = PAD_LEFT; 3932 } 3933 3934 ps_op->u4_disp_wd[0] = disp_wd; 3935 ps_op->u4_disp_ht[0] = disp_ht; 3936 ps_op->u4_buffer_wd[0] = buffer_wd; 3937 ps_op->u4_buffer_ht[0] = buffer_ht; 3938 ps_op->u4_x_offset[0] = x_offset; 3939 ps_op->u4_y_offset[0] = y_offset; 3940 3941 ps_op->u4_disp_wd[1] = ps_op->u4_disp_wd[2] = ((ps_op->u4_disp_wd[0] + 1) 3942 >> 1); 3943 ps_op->u4_disp_ht[1] = ps_op->u4_disp_ht[2] = ((ps_op->u4_disp_ht[0] + 1) 3944 >> 1); 3945 ps_op->u4_buffer_wd[1] = ps_op->u4_buffer_wd[2] = (ps_op->u4_buffer_wd[0] 3946 >> 1); 3947 ps_op->u4_buffer_ht[1] = ps_op->u4_buffer_ht[2] = (ps_op->u4_buffer_ht[0] 3948 >> 1); 3949 ps_op->u4_x_offset[1] = ps_op->u4_x_offset[2] = (ps_op->u4_x_offset[0] 3950 >> 1); 3951 ps_op->u4_y_offset[1] = ps_op->u4_y_offset[2] = (ps_op->u4_y_offset[0] 3952 >> 1); 3953 3954 if((ps_codec->e_chroma_fmt == IV_YUV_420SP_UV) 3955 || (ps_codec->e_chroma_fmt == IV_YUV_420SP_VU)) 3956 { 3957 ps_op->u4_disp_wd[2] = 0; 3958 ps_op->u4_disp_ht[2] = 0; 3959 ps_op->u4_buffer_wd[2] = 0; 3960 ps_op->u4_buffer_ht[2] = 0; 3961 ps_op->u4_x_offset[2] = 0; 3962 ps_op->u4_y_offset[2] = 0; 3963 3964 ps_op->u4_disp_wd[1] <<= 1; 3965 ps_op->u4_buffer_wd[1] <<= 1; 3966 ps_op->u4_x_offset[1] <<= 1; 3967 } 3968 3969 return IV_SUCCESS; 3970 3971 } 3972 3973 3974 /** 3975 ******************************************************************************* 3976 * 3977 * @brief 3978 * Gets vui parameters 3979 * 3980 * @par Description: 3981 * Gets VUI parameters 3982 * 3983 * @param[in] ps_codec_obj 3984 * Pointer to codec object at API level 3985 * 3986 * @param[in] pv_api_ip 3987 * Pointer to input argument structure 3988 * 3989 * @param[out] pv_api_op 3990 * Pointer to output argument structure 3991 * 3992 * @returns Status 3993 * 3994 * @remarks 3995 * 3996 * 3997 ******************************************************************************* 3998 */ 3999 WORD32 ihevcd_get_vui_params(iv_obj_t *ps_codec_obj, 4000 void *pv_api_ip, 4001 void *pv_api_op) 4002 { 4003 ihevcd_cxa_ctl_get_vui_params_ip_t *ps_ip; 4004 ihevcd_cxa_ctl_get_vui_params_op_t *ps_op; 4005 codec_t *ps_codec = (codec_t *)ps_codec_obj->pv_codec_handle; 4006 sps_t *ps_sps; 4007 vui_t *ps_vui; 4008 WORD32 i; 4009 4010 ps_ip = (ihevcd_cxa_ctl_get_vui_params_ip_t *)pv_api_ip; 4011 ps_op = (ihevcd_cxa_ctl_get_vui_params_op_t *)pv_api_op; 4012 4013 if(0 == ps_codec->i4_sps_done) 4014 { 4015 ps_op->u4_error_code = IHEVCD_VUI_PARAMS_NOT_FOUND; 4016 return IV_FAIL; 4017 } 4018 4019 ps_sps = ps_codec->s_parse.ps_sps; 4020 if(0 == ps_sps->i1_sps_valid || 0 == ps_sps->i1_vui_parameters_present_flag) 4021 { 4022 WORD32 sps_idx = 0; 4023 ps_sps = ps_codec->ps_sps_base; 4024 4025 while((0 == ps_sps->i1_sps_valid) || (0 == ps_sps->i1_vui_parameters_present_flag)) 4026 { 4027 sps_idx++; 4028 ps_sps++; 4029 4030 if(sps_idx == MAX_SPS_CNT - 1) 4031 { 4032 ps_op->u4_error_code = IHEVCD_VUI_PARAMS_NOT_FOUND; 4033 return IV_FAIL; 4034 } 4035 } 4036 } 4037 4038 ps_vui = &ps_sps->s_vui_parameters; 4039 UNUSED(ps_ip); 4040 4041 ps_op->u1_aspect_ratio_info_present_flag = ps_vui->u1_aspect_ratio_info_present_flag; 4042 ps_op->u1_aspect_ratio_idc = ps_vui->u1_aspect_ratio_idc; 4043 ps_op->u2_sar_width = ps_vui->u2_sar_width; 4044 ps_op->u2_sar_height = ps_vui->u2_sar_height; 4045 ps_op->u1_overscan_info_present_flag = ps_vui->u1_overscan_info_present_flag; 4046 ps_op->u1_overscan_appropriate_flag = ps_vui->u1_overscan_appropriate_flag; 4047 ps_op->u1_video_signal_type_present_flag = ps_vui->u1_video_signal_type_present_flag; 4048 ps_op->u1_video_format = ps_vui->u1_video_format; 4049 ps_op->u1_video_full_range_flag = ps_vui->u1_video_full_range_flag; 4050 ps_op->u1_colour_description_present_flag = ps_vui->u1_colour_description_present_flag; 4051 ps_op->u1_colour_primaries = ps_vui->u1_colour_primaries; 4052 ps_op->u1_transfer_characteristics = ps_vui->u1_transfer_characteristics; 4053 ps_op->u1_matrix_coefficients = ps_vui->u1_matrix_coefficients; 4054 ps_op->u1_chroma_loc_info_present_flag = ps_vui->u1_chroma_loc_info_present_flag; 4055 ps_op->u1_chroma_sample_loc_type_top_field = ps_vui->u1_chroma_sample_loc_type_top_field; 4056 ps_op->u1_chroma_sample_loc_type_bottom_field = ps_vui->u1_chroma_sample_loc_type_bottom_field; 4057 ps_op->u1_neutral_chroma_indication_flag = ps_vui->u1_neutral_chroma_indication_flag; 4058 ps_op->u1_field_seq_flag = ps_vui->u1_field_seq_flag; 4059 ps_op->u1_frame_field_info_present_flag = ps_vui->u1_frame_field_info_present_flag; 4060 ps_op->u1_default_display_window_flag = ps_vui->u1_default_display_window_flag; 4061 ps_op->u4_def_disp_win_left_offset = ps_vui->u4_def_disp_win_left_offset; 4062 ps_op->u4_def_disp_win_right_offset = ps_vui->u4_def_disp_win_right_offset; 4063 ps_op->u4_def_disp_win_top_offset = ps_vui->u4_def_disp_win_top_offset; 4064 ps_op->u4_def_disp_win_bottom_offset = ps_vui->u4_def_disp_win_bottom_offset; 4065 ps_op->u1_vui_hrd_parameters_present_flag = ps_vui->u1_vui_hrd_parameters_present_flag; 4066 ps_op->u1_vui_timing_info_present_flag = ps_vui->u1_vui_timing_info_present_flag; 4067 ps_op->u4_vui_num_units_in_tick = ps_vui->u4_vui_num_units_in_tick; 4068 ps_op->u4_vui_time_scale = ps_vui->u4_vui_time_scale; 4069 ps_op->u1_poc_proportional_to_timing_flag = ps_vui->u1_poc_proportional_to_timing_flag; 4070 ps_op->u1_num_ticks_poc_diff_one_minus1 = ps_vui->u1_num_ticks_poc_diff_one_minus1; 4071 ps_op->u1_bitstream_restriction_flag = ps_vui->u1_bitstream_restriction_flag; 4072 ps_op->u1_tiles_fixed_structure_flag = ps_vui->u1_tiles_fixed_structure_flag; 4073 ps_op->u1_motion_vectors_over_pic_boundaries_flag = ps_vui->u1_motion_vectors_over_pic_boundaries_flag; 4074 ps_op->u1_restricted_ref_pic_lists_flag = ps_vui->u1_restricted_ref_pic_lists_flag; 4075 ps_op->u4_min_spatial_segmentation_idc = ps_vui->u4_min_spatial_segmentation_idc; 4076 ps_op->u1_max_bytes_per_pic_denom = ps_vui->u1_max_bytes_per_pic_denom; 4077 ps_op->u1_max_bits_per_mincu_denom = ps_vui->u1_max_bits_per_mincu_denom; 4078 ps_op->u1_log2_max_mv_length_horizontal = ps_vui->u1_log2_max_mv_length_horizontal; 4079 ps_op->u1_log2_max_mv_length_vertical = ps_vui->u1_log2_max_mv_length_vertical; 4080 4081 4082 /* HRD parameters */ 4083 ps_op->u1_timing_info_present_flag = ps_vui->s_vui_hrd_parameters.u1_timing_info_present_flag; 4084 ps_op->u4_num_units_in_tick = ps_vui->s_vui_hrd_parameters.u4_num_units_in_tick; 4085 ps_op->u4_time_scale = ps_vui->s_vui_hrd_parameters.u4_time_scale; 4086 ps_op->u1_nal_hrd_parameters_present_flag = ps_vui->s_vui_hrd_parameters.u1_nal_hrd_parameters_present_flag; 4087 ps_op->u1_vcl_hrd_parameters_present_flag = ps_vui->s_vui_hrd_parameters.u1_vcl_hrd_parameters_present_flag; 4088 ps_op->u1_cpbdpb_delays_present_flag = ps_vui->s_vui_hrd_parameters.u1_cpbdpb_delays_present_flag; 4089 ps_op->u1_sub_pic_cpb_params_present_flag = ps_vui->s_vui_hrd_parameters.u1_sub_pic_cpb_params_present_flag; 4090 ps_op->u1_tick_divisor_minus2 = ps_vui->s_vui_hrd_parameters.u1_tick_divisor_minus2; 4091 ps_op->u1_du_cpb_removal_delay_increment_length_minus1 = ps_vui->s_vui_hrd_parameters.u1_du_cpb_removal_delay_increment_length_minus1; 4092 ps_op->u1_sub_pic_cpb_params_in_pic_timing_sei_flag = ps_vui->s_vui_hrd_parameters.u1_sub_pic_cpb_params_in_pic_timing_sei_flag; 4093 ps_op->u1_dpb_output_delay_du_length_minus1 = ps_vui->s_vui_hrd_parameters.u1_dpb_output_delay_du_length_minus1; 4094 ps_op->u4_bit_rate_scale = ps_vui->s_vui_hrd_parameters.u4_bit_rate_scale; 4095 ps_op->u4_cpb_size_scale = ps_vui->s_vui_hrd_parameters.u4_cpb_size_scale; 4096 ps_op->u4_cpb_size_du_scale = ps_vui->s_vui_hrd_parameters.u4_cpb_size_du_scale; 4097 ps_op->u1_initial_cpb_removal_delay_length_minus1 = ps_vui->s_vui_hrd_parameters.u1_initial_cpb_removal_delay_length_minus1; 4098 ps_op->u1_au_cpb_removal_delay_length_minus1 = ps_vui->s_vui_hrd_parameters.u1_au_cpb_removal_delay_length_minus1; 4099 ps_op->u1_dpb_output_delay_length_minus1 = ps_vui->s_vui_hrd_parameters.u1_dpb_output_delay_length_minus1; 4100 4101 for(i = 0; i < 6; i++) 4102 { 4103 ps_op->au1_fixed_pic_rate_general_flag[i] = ps_vui->s_vui_hrd_parameters.au1_fixed_pic_rate_general_flag[i]; 4104 ps_op->au1_fixed_pic_rate_within_cvs_flag[i] = ps_vui->s_vui_hrd_parameters.au1_fixed_pic_rate_within_cvs_flag[i]; 4105 ps_op->au1_elemental_duration_in_tc_minus1[i] = ps_vui->s_vui_hrd_parameters.au1_elemental_duration_in_tc_minus1[i]; 4106 ps_op->au1_low_delay_hrd_flag[i] = ps_vui->s_vui_hrd_parameters.au1_low_delay_hrd_flag[i]; 4107 ps_op->au1_cpb_cnt_minus1[i] = ps_vui->s_vui_hrd_parameters.au1_cpb_cnt_minus1[i]; 4108 } 4109 4110 4111 return IV_SUCCESS; 4112 } 4113 4114 /** 4115 ******************************************************************************* 4116 * 4117 * @brief 4118 * Sets Processor type 4119 * 4120 * @par Description: 4121 * Sets Processor type 4122 * 4123 * @param[in] ps_codec_obj 4124 * Pointer to codec object at API level 4125 * 4126 * @param[in] pv_api_ip 4127 * Pointer to input argument structure 4128 * 4129 * @param[out] pv_api_op 4130 * Pointer to output argument structure 4131 * 4132 * @returns Status 4133 * 4134 * @remarks 4135 * 4136 * 4137 ******************************************************************************* 4138 */ 4139 4140 WORD32 ihevcd_set_processor(iv_obj_t *ps_codec_obj, 4141 void *pv_api_ip, 4142 void *pv_api_op) 4143 { 4144 ihevcd_cxa_ctl_set_processor_ip_t *ps_ip; 4145 ihevcd_cxa_ctl_set_processor_op_t *ps_op; 4146 codec_t *ps_codec = (codec_t *)ps_codec_obj->pv_codec_handle; 4147 4148 ps_ip = (ihevcd_cxa_ctl_set_processor_ip_t *)pv_api_ip; 4149 ps_op = (ihevcd_cxa_ctl_set_processor_op_t *)pv_api_op; 4150 4151 ps_codec->e_processor_arch = (IVD_ARCH_T)ps_ip->u4_arch; 4152 ps_codec->e_processor_soc = (IVD_SOC_T)ps_ip->u4_soc; 4153 4154 ihevcd_init_function_ptr(ps_codec); 4155 4156 ihevcd_update_function_ptr(ps_codec); 4157 4158 if(ps_codec->e_processor_soc && (ps_codec->e_processor_soc <= SOC_HISI_37X)) 4159 { 4160 /* 8th bit indicates if format conversion is to be done ahead */ 4161 if(ps_codec->e_processor_soc & 0x80) 4162 ps_codec->u4_enable_fmt_conv_ahead = 1; 4163 4164 /* Lower 7 bit indicate NCTB - if non-zero */ 4165 ps_codec->e_processor_soc &= 0x7F; 4166 4167 if(ps_codec->e_processor_soc) 4168 ps_codec->u4_nctb = ps_codec->e_processor_soc; 4169 4170 4171 } 4172 4173 if((ps_codec->e_processor_soc == SOC_HISI_37X) && (ps_codec->i4_num_cores == 2)) 4174 { 4175 ps_codec->u4_nctb = 2; 4176 } 4177 4178 4179 ps_op->u4_error_code = 0; 4180 return IV_SUCCESS; 4181 } 4182 4183 /** 4184 ******************************************************************************* 4185 * 4186 * @brief 4187 * Sets Number of cores that can be used in the codec. Codec uses these many 4188 * threads for decoding 4189 * 4190 * @par Description: 4191 * Sets number of cores 4192 * 4193 * @param[in] ps_codec_obj 4194 * Pointer to codec object at API level 4195 * 4196 * @param[in] pv_api_ip 4197 * Pointer to input argument structure 4198 * 4199 * @param[out] pv_api_op 4200 * Pointer to output argument structure 4201 * 4202 * @returns Status 4203 * 4204 * @remarks 4205 * 4206 * 4207 ******************************************************************************* 4208 */ 4209 4210 WORD32 ihevcd_set_num_cores(iv_obj_t *ps_codec_obj, 4211 void *pv_api_ip, 4212 void *pv_api_op) 4213 { 4214 ihevcd_cxa_ctl_set_num_cores_ip_t *ps_ip; 4215 ihevcd_cxa_ctl_set_num_cores_op_t *ps_op; 4216 codec_t *ps_codec = (codec_t *)ps_codec_obj->pv_codec_handle; 4217 4218 ps_ip = (ihevcd_cxa_ctl_set_num_cores_ip_t *)pv_api_ip; 4219 ps_op = (ihevcd_cxa_ctl_set_num_cores_op_t *)pv_api_op; 4220 4221 #ifdef MULTICORE 4222 ps_codec->i4_num_cores = ps_ip->u4_num_cores; 4223 #else 4224 ps_codec->i4_num_cores = 1; 4225 #endif 4226 ps_op->u4_error_code = 0; 4227 return IV_SUCCESS; 4228 } 4229 /** 4230 ******************************************************************************* 4231 * 4232 * @brief 4233 * Codec control call 4234 * 4235 * @par Description: 4236 * Codec control call which in turn calls appropriate calls based on 4237 * subcommand 4238 * 4239 * @param[in] ps_codec_obj 4240 * Pointer to codec object at API level 4241 * 4242 * @param[in] pv_api_ip 4243 * Pointer to input argument structure 4244 * 4245 * @param[out] pv_api_op 4246 * Pointer to output argument structure 4247 * 4248 * @returns Status 4249 * 4250 * @remarks 4251 * 4252 * 4253 ******************************************************************************* 4254 */ 4255 4256 WORD32 ihevcd_ctl(iv_obj_t *ps_codec_obj, void *pv_api_ip, void *pv_api_op) 4257 { 4258 ivd_ctl_set_config_ip_t *ps_ctl_ip; 4259 ivd_ctl_set_config_op_t *ps_ctl_op; 4260 WORD32 ret = 0; 4261 WORD32 subcommand; 4262 codec_t *ps_codec = (codec_t *)ps_codec_obj->pv_codec_handle; 4263 4264 ps_ctl_ip = (ivd_ctl_set_config_ip_t *)pv_api_ip; 4265 ps_ctl_op = (ivd_ctl_set_config_op_t *)pv_api_op; 4266 4267 if(ps_codec->i4_init_done != 1) 4268 { 4269 ps_ctl_op->u4_error_code |= 1 << IVD_FATALERROR; 4270 ps_ctl_op->u4_error_code |= IHEVCD_INIT_NOT_DONE; 4271 return IV_FAIL; 4272 } 4273 subcommand = ps_ctl_ip->e_sub_cmd; 4274 4275 switch(subcommand) 4276 { 4277 case IVD_CMD_CTL_GETPARAMS: 4278 ret = ihevcd_get_status(ps_codec_obj, (void *)pv_api_ip, 4279 (void *)pv_api_op); 4280 break; 4281 case IVD_CMD_CTL_SETPARAMS: 4282 ret = ihevcd_set_params(ps_codec_obj, (void *)pv_api_ip, 4283 (void *)pv_api_op); 4284 break; 4285 case IVD_CMD_CTL_RESET: 4286 ret = ihevcd_reset(ps_codec_obj, (void *)pv_api_ip, 4287 (void *)pv_api_op); 4288 break; 4289 case IVD_CMD_CTL_SETDEFAULT: 4290 { 4291 ivd_ctl_set_config_op_t *s_ctl_dynparams_op = 4292 (ivd_ctl_set_config_op_t *)pv_api_op; 4293 4294 ret = ihevcd_set_default_params(ps_codec); 4295 if(IV_SUCCESS == ret) 4296 s_ctl_dynparams_op->u4_error_code = 0; 4297 break; 4298 } 4299 case IVD_CMD_CTL_FLUSH: 4300 ret = ihevcd_set_flush_mode(ps_codec_obj, (void *)pv_api_ip, 4301 (void *)pv_api_op); 4302 break; 4303 case IVD_CMD_CTL_GETBUFINFO: 4304 ret = ihevcd_get_buf_info(ps_codec_obj, (void *)pv_api_ip, 4305 (void *)pv_api_op); 4306 break; 4307 case IVD_CMD_CTL_GETVERSION: 4308 { 4309 ivd_ctl_getversioninfo_ip_t *ps_ip; 4310 ivd_ctl_getversioninfo_op_t *ps_op; 4311 IV_API_CALL_STATUS_T ret; 4312 ps_ip = (ivd_ctl_getversioninfo_ip_t *)pv_api_ip; 4313 ps_op = (ivd_ctl_getversioninfo_op_t *)pv_api_op; 4314 4315 ps_op->u4_error_code = IV_SUCCESS; 4316 4317 if((WORD32)ps_ip->u4_version_buffer_size <= 0) 4318 { 4319 ps_op->u4_error_code = IHEVCD_CXA_VERS_BUF_INSUFFICIENT; 4320 ret = IV_FAIL; 4321 } 4322 else 4323 { 4324 ret = ihevcd_get_version((CHAR *)ps_ip->pv_version_buffer, 4325 ps_ip->u4_version_buffer_size); 4326 if(ret != IV_SUCCESS) 4327 { 4328 ps_op->u4_error_code = IHEVCD_CXA_VERS_BUF_INSUFFICIENT; 4329 ret = IV_FAIL; 4330 } 4331 } 4332 } 4333 break; 4334 case IHEVCD_CXA_CMD_CTL_DEGRADE: 4335 ret = ihevcd_set_degrade(ps_codec_obj, (void *)pv_api_ip, 4336 (void *)pv_api_op); 4337 break; 4338 case IHEVCD_CXA_CMD_CTL_SET_NUM_CORES: 4339 ret = ihevcd_set_num_cores(ps_codec_obj, (void *)pv_api_ip, 4340 (void *)pv_api_op); 4341 break; 4342 case IHEVCD_CXA_CMD_CTL_GET_BUFFER_DIMENSIONS: 4343 ret = ihevcd_get_frame_dimensions(ps_codec_obj, (void *)pv_api_ip, 4344 (void *)pv_api_op); 4345 break; 4346 case IHEVCD_CXA_CMD_CTL_GET_VUI_PARAMS: 4347 ret = ihevcd_get_vui_params(ps_codec_obj, (void *)pv_api_ip, 4348 (void *)pv_api_op); 4349 break; 4350 case IHEVCD_CXA_CMD_CTL_SET_PROCESSOR: 4351 ret = ihevcd_set_processor(ps_codec_obj, (void *)pv_api_ip, 4352 (void *)pv_api_op); 4353 break; 4354 default: 4355 DEBUG("\nDo nothing\n"); 4356 break; 4357 } 4358 4359 return ret; 4360 } 4361 4362 /** 4363 ******************************************************************************* 4364 * 4365 * @brief 4366 * Codecs entry point function. All the function calls to the codec are 4367 * done using this function with different values specified in command 4368 * 4369 * @par Description: 4370 * Arguments are tested for validity and then based on the command 4371 * appropriate function is called 4372 * 4373 * @param[in] ps_handle 4374 * API level handle for codec 4375 * 4376 * @param[in] pv_api_ip 4377 * Input argument structure 4378 * 4379 * @param[out] pv_api_op 4380 * Output argument structure 4381 * 4382 * @returns Status of the function corresponding to command 4383 * 4384 * @remarks 4385 * 4386 * 4387 ******************************************************************************* 4388 */ 4389 IV_API_CALL_STATUS_T ihevcd_cxa_api_function(iv_obj_t *ps_handle, 4390 void *pv_api_ip, 4391 void *pv_api_op) 4392 { 4393 WORD32 command; 4394 UWORD32 *pu4_ptr_cmd; 4395 WORD32 ret = 0; 4396 IV_API_CALL_STATUS_T e_status; 4397 e_status = api_check_struct_sanity(ps_handle, pv_api_ip, pv_api_op); 4398 4399 if(e_status != IV_SUCCESS) 4400 { 4401 DEBUG("error code = %d\n", *((UWORD32 *)pv_api_op + 1)); 4402 return IV_FAIL; 4403 } 4404 4405 pu4_ptr_cmd = (UWORD32 *)pv_api_ip; 4406 pu4_ptr_cmd++; 4407 4408 command = *pu4_ptr_cmd; 4409 4410 switch(command) 4411 { 4412 case IV_CMD_GET_NUM_MEM_REC: 4413 ret = ihevcd_get_num_rec((void *)pv_api_ip, (void *)pv_api_op); 4414 4415 break; 4416 case IV_CMD_FILL_NUM_MEM_REC: 4417 4418 ret = ihevcd_fill_num_mem_rec((void *)pv_api_ip, (void *)pv_api_op); 4419 break; 4420 case IV_CMD_INIT: 4421 ret = ihevcd_init_mem_rec(ps_handle, (void *)pv_api_ip, 4422 (void *)pv_api_op); 4423 break; 4424 4425 case IVD_CMD_VIDEO_DECODE: 4426 ret = ihevcd_decode(ps_handle, (void *)pv_api_ip, (void *)pv_api_op); 4427 break; 4428 4429 case IVD_CMD_GET_DISPLAY_FRAME: 4430 //ret = ihevcd_get_display_frame(ps_handle,(void *)pv_api_ip,(void *)pv_api_op); 4431 break; 4432 4433 case IVD_CMD_SET_DISPLAY_FRAME: 4434 ret = ihevcd_set_display_frame(ps_handle, (void *)pv_api_ip, 4435 (void *)pv_api_op); 4436 4437 break; 4438 4439 case IVD_CMD_REL_DISPLAY_FRAME: 4440 ret = ihevcd_rel_display_frame(ps_handle, (void *)pv_api_ip, 4441 (void *)pv_api_op); 4442 break; 4443 4444 case IV_CMD_RETRIEVE_MEMREC: 4445 ret = ihevcd_retrieve_memrec(ps_handle, (void *)pv_api_ip, 4446 (void *)pv_api_op); 4447 break; 4448 4449 case IVD_CMD_VIDEO_CTL: 4450 ret = ihevcd_ctl(ps_handle, (void *)pv_api_ip, (void *)pv_api_op); 4451 break; 4452 default: 4453 ret = IV_FAIL; 4454 break; 4455 } 4456 4457 return (IV_API_CALL_STATUS_T)ret; 4458 } 4459 4460