1/****************************************************************************** 2* 3* Copyright (C) 2012 Ittiam Systems Pvt Ltd, Bangalore 4* 5* Licensed under the Apache License, Version 2.0 (the "License"); 6* you may not use this file except in compliance with the License. 7* You may obtain a copy of the License at: 8* 9* http://www.apache.org/licenses/LICENSE-2.0 10* 11* Unless required by applicable law or agreed to in writing, software 12* distributed under the License is distributed on an "AS IS" BASIS, 13* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14* See the License for the specific language governing permissions and 15* limitations under the License. 16* 17******************************************************************************/ 18/** 19******************************************************************************* 20* @file 21* ihevcd_api.c 22* 23* @brief 24* Contains api functions definitions for HEVC decoder 25* 26* @author 27* Harish 28* 29* @par List of Functions: 30* - api_check_struct_sanity() 31* - ihevcd_get_version() 32* - ihevcd_set_default_params() 33* - ihevcd_init() 34* - ihevcd_get_num_rec() 35* - ihevcd_allocate_static_bufs() 36* - ihevcd_create() 37* - ihevcd_retrieve_memrec() 38* - ihevcd_set_display_frame() 39* - ihevcd_set_flush_mode() 40* - ihevcd_get_status() 41* - ihevcd_get_buf_info() 42* - ihevcd_set_params() 43* - ihevcd_reset() 44* - ihevcd_rel_display_frame() 45* - ihevcd_disable_deblk() 46* - ihevcd_get_frame_dimensions() 47* - ihevcd_set_num_cores() 48* - ihevcd_ctl() 49* - ihevcd_cxa_api_function() 50* 51* @remarks 52* None 53* 54******************************************************************************* 55*/ 56/*****************************************************************************/ 57/* File Includes */ 58/*****************************************************************************/ 59#include <stdio.h> 60#include <stddef.h> 61#include <stdlib.h> 62#include <string.h> 63 64#include "ihevc_typedefs.h" 65#include "iv.h" 66#include "ivd.h" 67#include "ihevcd_cxa.h" 68#include "ithread.h" 69 70#include "ihevc_defs.h" 71#include "ihevc_debug.h" 72 73#include "ihevc_structs.h" 74#include "ihevc_macros.h" 75#include "ihevc_platform_macros.h" 76 77#include "ihevc_buf_mgr.h" 78#include "ihevc_dpb_mgr.h" 79#include "ihevc_disp_mgr.h" 80#include "ihevc_common_tables.h" 81#include "ihevc_cabac_tables.h" 82#include "ihevc_error.h" 83 84#include "ihevcd_defs.h" 85#include "ihevcd_trace.h" 86 87#include "ihevcd_function_selector.h" 88#include "ihevcd_structs.h" 89#include "ihevcd_error.h" 90#include "ihevcd_utils.h" 91#include "ihevcd_decode.h" 92#include "ihevcd_job_queue.h" 93#include "ihevcd_statistics.h" 94 95 96#define ALIGNED_FREE(ps_codec, y) \ 97if(y) {ps_codec->pf_aligned_free(ps_codec->pv_mem_ctxt, ((void *)y)); (y) = NULL;} 98 99/*****************************************************************************/ 100/* Function Prototypes */ 101/*****************************************************************************/ 102IV_API_CALL_STATUS_T ihevcd_get_version(CHAR *pc_version_string, 103 UWORD32 u4_version_buffer_size); 104WORD32 ihevcd_free_dynamic_bufs(codec_t *ps_codec); 105 106 107/** 108******************************************************************************* 109* 110* @brief 111* Used to test arguments for corresponding API call 112* 113* @par Description: 114* For each command the arguments are validated 115* 116* @param[in] ps_handle 117* Codec handle at API level 118* 119* @param[in] pv_api_ip 120* Pointer to input structure 121* 122* @param[out] pv_api_op 123* Pointer to output structure 124* 125* @returns Status of error checking 126* 127* @remarks 128* 129* 130******************************************************************************* 131*/ 132 133static IV_API_CALL_STATUS_T api_check_struct_sanity(iv_obj_t *ps_handle, 134 void *pv_api_ip, 135 void *pv_api_op) 136{ 137 IVD_API_COMMAND_TYPE_T e_cmd; 138 UWORD32 *pu4_api_ip; 139 UWORD32 *pu4_api_op; 140 WORD32 i; 141 142 if(NULL == pv_api_op) 143 return (IV_FAIL); 144 145 if(NULL == pv_api_ip) 146 return (IV_FAIL); 147 148 pu4_api_ip = (UWORD32 *)pv_api_ip; 149 pu4_api_op = (UWORD32 *)pv_api_op; 150 e_cmd = (IVD_API_COMMAND_TYPE_T)*(pu4_api_ip + 1); 151 152 *(pu4_api_op + 1) = 0; 153 /* error checks on handle */ 154 switch((WORD32)e_cmd) 155 { 156 case IVD_CMD_CREATE: 157 break; 158 159 case IVD_CMD_REL_DISPLAY_FRAME: 160 case IVD_CMD_SET_DISPLAY_FRAME: 161 case IVD_CMD_GET_DISPLAY_FRAME: 162 case IVD_CMD_VIDEO_DECODE: 163 case IVD_CMD_DELETE: 164 case IVD_CMD_VIDEO_CTL: 165 if(ps_handle == NULL) 166 { 167 *(pu4_api_op + 1) |= 1 << IVD_UNSUPPORTEDPARAM; 168 *(pu4_api_op + 1) |= IVD_HANDLE_NULL; 169 return IV_FAIL; 170 } 171 172 if(ps_handle->u4_size != sizeof(iv_obj_t)) 173 { 174 *(pu4_api_op + 1) |= 1 << IVD_UNSUPPORTEDPARAM; 175 *(pu4_api_op + 1) |= IVD_HANDLE_STRUCT_SIZE_INCORRECT; 176 return IV_FAIL; 177 } 178 179 180 if(ps_handle->pv_codec_handle == NULL) 181 { 182 *(pu4_api_op + 1) |= 1 << IVD_UNSUPPORTEDPARAM; 183 *(pu4_api_op + 1) |= IVD_INVALID_HANDLE_NULL; 184 return IV_FAIL; 185 } 186 break; 187 default: 188 *(pu4_api_op + 1) |= 1 << IVD_UNSUPPORTEDPARAM; 189 *(pu4_api_op + 1) |= IVD_INVALID_API_CMD; 190 return IV_FAIL; 191 } 192 193 switch((WORD32)e_cmd) 194 { 195 case IVD_CMD_CREATE: 196 { 197 ihevcd_cxa_create_ip_t *ps_ip = (ihevcd_cxa_create_ip_t *)pv_api_ip; 198 ihevcd_cxa_create_op_t *ps_op = (ihevcd_cxa_create_op_t *)pv_api_op; 199 200 201 ps_op->s_ivd_create_op_t.u4_error_code = 0; 202 203 if((ps_ip->s_ivd_create_ip_t.u4_size > sizeof(ihevcd_cxa_create_ip_t)) 204 || (ps_ip->s_ivd_create_ip_t.u4_size 205 < sizeof(ivd_create_ip_t))) 206 { 207 ps_op->s_ivd_create_op_t.u4_error_code |= 1 208 << IVD_UNSUPPORTEDPARAM; 209 ps_op->s_ivd_create_op_t.u4_error_code |= 210 IVD_IP_API_STRUCT_SIZE_INCORRECT; 211 212 return (IV_FAIL); 213 } 214 215 if((ps_op->s_ivd_create_op_t.u4_size != sizeof(ihevcd_cxa_create_op_t)) 216 && (ps_op->s_ivd_create_op_t.u4_size 217 != sizeof(ivd_create_op_t))) 218 { 219 ps_op->s_ivd_create_op_t.u4_error_code |= 1 220 << IVD_UNSUPPORTEDPARAM; 221 ps_op->s_ivd_create_op_t.u4_error_code |= 222 IVD_OP_API_STRUCT_SIZE_INCORRECT; 223 224 return (IV_FAIL); 225 } 226 227 228 if((ps_ip->s_ivd_create_ip_t.e_output_format != IV_YUV_420P) 229 && (ps_ip->s_ivd_create_ip_t.e_output_format 230 != IV_YUV_422ILE) 231 && (ps_ip->s_ivd_create_ip_t.e_output_format 232 != IV_RGB_565) 233 && (ps_ip->s_ivd_create_ip_t.e_output_format 234 != IV_YUV_420SP_UV) 235 && (ps_ip->s_ivd_create_ip_t.e_output_format 236 != IV_YUV_420SP_VU)) 237 { 238 ps_op->s_ivd_create_op_t.u4_error_code |= 1 239 << IVD_UNSUPPORTEDPARAM; 240 ps_op->s_ivd_create_op_t.u4_error_code |= 241 IVD_INIT_DEC_COL_FMT_NOT_SUPPORTED; 242 243 return (IV_FAIL); 244 } 245 246 } 247 break; 248 249 case IVD_CMD_GET_DISPLAY_FRAME: 250 { 251 ihevcd_cxa_get_display_frame_ip_t *ps_ip = 252 (ihevcd_cxa_get_display_frame_ip_t *)pv_api_ip; 253 ihevcd_cxa_get_display_frame_op_t *ps_op = 254 (ihevcd_cxa_get_display_frame_op_t *)pv_api_op; 255 256 ps_op->s_ivd_get_display_frame_op_t.u4_error_code = 0; 257 258 if((ps_ip->s_ivd_get_display_frame_ip_t.u4_size 259 != sizeof(ihevcd_cxa_get_display_frame_ip_t)) 260 && (ps_ip->s_ivd_get_display_frame_ip_t.u4_size 261 != sizeof(ivd_get_display_frame_ip_t))) 262 { 263 ps_op->s_ivd_get_display_frame_op_t.u4_error_code |= 1 264 << IVD_UNSUPPORTEDPARAM; 265 ps_op->s_ivd_get_display_frame_op_t.u4_error_code |= 266 IVD_IP_API_STRUCT_SIZE_INCORRECT; 267 return (IV_FAIL); 268 } 269 270 if((ps_op->s_ivd_get_display_frame_op_t.u4_size 271 != sizeof(ihevcd_cxa_get_display_frame_op_t)) 272 && (ps_op->s_ivd_get_display_frame_op_t.u4_size 273 != sizeof(ivd_get_display_frame_op_t))) 274 { 275 ps_op->s_ivd_get_display_frame_op_t.u4_error_code |= 1 276 << IVD_UNSUPPORTEDPARAM; 277 ps_op->s_ivd_get_display_frame_op_t.u4_error_code |= 278 IVD_OP_API_STRUCT_SIZE_INCORRECT; 279 return (IV_FAIL); 280 } 281 282 } 283 break; 284 285 case IVD_CMD_REL_DISPLAY_FRAME: 286 { 287 ihevcd_cxa_rel_display_frame_ip_t *ps_ip = 288 (ihevcd_cxa_rel_display_frame_ip_t *)pv_api_ip; 289 ihevcd_cxa_rel_display_frame_op_t *ps_op = 290 (ihevcd_cxa_rel_display_frame_op_t *)pv_api_op; 291 292 ps_op->s_ivd_rel_display_frame_op_t.u4_error_code = 0; 293 294 if((ps_ip->s_ivd_rel_display_frame_ip_t.u4_size 295 != sizeof(ihevcd_cxa_rel_display_frame_ip_t)) 296 && (ps_ip->s_ivd_rel_display_frame_ip_t.u4_size 297 != sizeof(ivd_rel_display_frame_ip_t))) 298 { 299 ps_op->s_ivd_rel_display_frame_op_t.u4_error_code |= 1 300 << IVD_UNSUPPORTEDPARAM; 301 ps_op->s_ivd_rel_display_frame_op_t.u4_error_code |= 302 IVD_IP_API_STRUCT_SIZE_INCORRECT; 303 return (IV_FAIL); 304 } 305 306 if((ps_op->s_ivd_rel_display_frame_op_t.u4_size 307 != sizeof(ihevcd_cxa_rel_display_frame_op_t)) 308 && (ps_op->s_ivd_rel_display_frame_op_t.u4_size 309 != sizeof(ivd_rel_display_frame_op_t))) 310 { 311 ps_op->s_ivd_rel_display_frame_op_t.u4_error_code |= 1 312 << IVD_UNSUPPORTEDPARAM; 313 ps_op->s_ivd_rel_display_frame_op_t.u4_error_code |= 314 IVD_OP_API_STRUCT_SIZE_INCORRECT; 315 return (IV_FAIL); 316 } 317 318 } 319 break; 320 321 case IVD_CMD_SET_DISPLAY_FRAME: 322 { 323 ihevcd_cxa_set_display_frame_ip_t *ps_ip = 324 (ihevcd_cxa_set_display_frame_ip_t *)pv_api_ip; 325 ihevcd_cxa_set_display_frame_op_t *ps_op = 326 (ihevcd_cxa_set_display_frame_op_t *)pv_api_op; 327 UWORD32 j; 328 329 ps_op->s_ivd_set_display_frame_op_t.u4_error_code = 0; 330 331 if((ps_ip->s_ivd_set_display_frame_ip_t.u4_size 332 != sizeof(ihevcd_cxa_set_display_frame_ip_t)) 333 && (ps_ip->s_ivd_set_display_frame_ip_t.u4_size 334 != sizeof(ivd_set_display_frame_ip_t))) 335 { 336 ps_op->s_ivd_set_display_frame_op_t.u4_error_code |= 1 337 << IVD_UNSUPPORTEDPARAM; 338 ps_op->s_ivd_set_display_frame_op_t.u4_error_code |= 339 IVD_IP_API_STRUCT_SIZE_INCORRECT; 340 return (IV_FAIL); 341 } 342 343 if((ps_op->s_ivd_set_display_frame_op_t.u4_size 344 != sizeof(ihevcd_cxa_set_display_frame_op_t)) 345 && (ps_op->s_ivd_set_display_frame_op_t.u4_size 346 != sizeof(ivd_set_display_frame_op_t))) 347 { 348 ps_op->s_ivd_set_display_frame_op_t.u4_error_code |= 1 349 << IVD_UNSUPPORTEDPARAM; 350 ps_op->s_ivd_set_display_frame_op_t.u4_error_code |= 351 IVD_OP_API_STRUCT_SIZE_INCORRECT; 352 return (IV_FAIL); 353 } 354 355 if(ps_ip->s_ivd_set_display_frame_ip_t.num_disp_bufs == 0) 356 { 357 ps_op->s_ivd_set_display_frame_op_t.u4_error_code |= 1 358 << IVD_UNSUPPORTEDPARAM; 359 ps_op->s_ivd_set_display_frame_op_t.u4_error_code |= 360 IVD_DISP_FRM_ZERO_OP_BUFS; 361 return IV_FAIL; 362 } 363 364 for(j = 0; j < ps_ip->s_ivd_set_display_frame_ip_t.num_disp_bufs; 365 j++) 366 { 367 if(ps_ip->s_ivd_set_display_frame_ip_t.s_disp_buffer[j].u4_num_bufs 368 == 0) 369 { 370 ps_op->s_ivd_set_display_frame_op_t.u4_error_code |= 1 371 << IVD_UNSUPPORTEDPARAM; 372 ps_op->s_ivd_set_display_frame_op_t.u4_error_code |= 373 IVD_DISP_FRM_ZERO_OP_BUFS; 374 return IV_FAIL; 375 } 376 377 for(i = 0; 378 i 379 < (WORD32)ps_ip->s_ivd_set_display_frame_ip_t.s_disp_buffer[j].u4_num_bufs; 380 i++) 381 { 382 if(ps_ip->s_ivd_set_display_frame_ip_t.s_disp_buffer[j].pu1_bufs[i] 383 == NULL) 384 { 385 ps_op->s_ivd_set_display_frame_op_t.u4_error_code |= 1 386 << IVD_UNSUPPORTEDPARAM; 387 ps_op->s_ivd_set_display_frame_op_t.u4_error_code |= 388 IVD_DISP_FRM_OP_BUF_NULL; 389 return IV_FAIL; 390 } 391 392 if(ps_ip->s_ivd_set_display_frame_ip_t.s_disp_buffer[j].u4_min_out_buf_size[i] 393 == 0) 394 { 395 ps_op->s_ivd_set_display_frame_op_t.u4_error_code |= 1 396 << IVD_UNSUPPORTEDPARAM; 397 ps_op->s_ivd_set_display_frame_op_t.u4_error_code |= 398 IVD_DISP_FRM_ZERO_OP_BUF_SIZE; 399 return IV_FAIL; 400 } 401 } 402 } 403 } 404 break; 405 406 case IVD_CMD_VIDEO_DECODE: 407 { 408 ihevcd_cxa_video_decode_ip_t *ps_ip = 409 (ihevcd_cxa_video_decode_ip_t *)pv_api_ip; 410 ihevcd_cxa_video_decode_op_t *ps_op = 411 (ihevcd_cxa_video_decode_op_t *)pv_api_op; 412 413 DEBUG("The input bytes is: %d", 414 ps_ip->s_ivd_video_decode_ip_t.u4_num_Bytes); 415 ps_op->s_ivd_video_decode_op_t.u4_error_code = 0; 416 417 if(ps_ip->s_ivd_video_decode_ip_t.u4_size 418 != sizeof(ihevcd_cxa_video_decode_ip_t) 419 && ps_ip->s_ivd_video_decode_ip_t.u4_size 420 != offsetof(ivd_video_decode_ip_t, 421 s_out_buffer)) 422 { 423 ps_op->s_ivd_video_decode_op_t.u4_error_code |= 1 424 << IVD_UNSUPPORTEDPARAM; 425 ps_op->s_ivd_video_decode_op_t.u4_error_code |= 426 IVD_IP_API_STRUCT_SIZE_INCORRECT; 427 return (IV_FAIL); 428 } 429 430 if(ps_op->s_ivd_video_decode_op_t.u4_size 431 != sizeof(ihevcd_cxa_video_decode_op_t) 432 && ps_op->s_ivd_video_decode_op_t.u4_size 433 != offsetof(ivd_video_decode_op_t, 434 u4_output_present)) 435 { 436 ps_op->s_ivd_video_decode_op_t.u4_error_code |= 1 437 << IVD_UNSUPPORTEDPARAM; 438 ps_op->s_ivd_video_decode_op_t.u4_error_code |= 439 IVD_OP_API_STRUCT_SIZE_INCORRECT; 440 return (IV_FAIL); 441 } 442 443 } 444 break; 445 446 case IVD_CMD_DELETE: 447 { 448 ihevcd_cxa_delete_ip_t *ps_ip = 449 (ihevcd_cxa_delete_ip_t *)pv_api_ip; 450 ihevcd_cxa_delete_op_t *ps_op = 451 (ihevcd_cxa_delete_op_t *)pv_api_op; 452 453 ps_op->s_ivd_delete_op_t.u4_error_code = 0; 454 455 if(ps_ip->s_ivd_delete_ip_t.u4_size 456 != sizeof(ihevcd_cxa_delete_ip_t)) 457 { 458 ps_op->s_ivd_delete_op_t.u4_error_code |= 1 459 << IVD_UNSUPPORTEDPARAM; 460 ps_op->s_ivd_delete_op_t.u4_error_code |= 461 IVD_IP_API_STRUCT_SIZE_INCORRECT; 462 return (IV_FAIL); 463 } 464 465 if(ps_op->s_ivd_delete_op_t.u4_size 466 != sizeof(ihevcd_cxa_delete_op_t)) 467 { 468 ps_op->s_ivd_delete_op_t.u4_error_code |= 1 469 << IVD_UNSUPPORTEDPARAM; 470 ps_op->s_ivd_delete_op_t.u4_error_code |= 471 IVD_OP_API_STRUCT_SIZE_INCORRECT; 472 return (IV_FAIL); 473 } 474 475 } 476 break; 477 478 case IVD_CMD_VIDEO_CTL: 479 { 480 UWORD32 *pu4_ptr_cmd; 481 UWORD32 sub_command; 482 483 pu4_ptr_cmd = (UWORD32 *)pv_api_ip; 484 pu4_ptr_cmd += 2; 485 sub_command = *pu4_ptr_cmd; 486 487 switch(sub_command) 488 { 489 case IVD_CMD_CTL_SETPARAMS: 490 { 491 ihevcd_cxa_ctl_set_config_ip_t *ps_ip; 492 ihevcd_cxa_ctl_set_config_op_t *ps_op; 493 ps_ip = (ihevcd_cxa_ctl_set_config_ip_t *)pv_api_ip; 494 ps_op = (ihevcd_cxa_ctl_set_config_op_t *)pv_api_op; 495 496 if(ps_ip->s_ivd_ctl_set_config_ip_t.u4_size 497 != sizeof(ihevcd_cxa_ctl_set_config_ip_t)) 498 { 499 ps_op->s_ivd_ctl_set_config_op_t.u4_error_code |= 1 500 << IVD_UNSUPPORTEDPARAM; 501 ps_op->s_ivd_ctl_set_config_op_t.u4_error_code |= 502 IVD_IP_API_STRUCT_SIZE_INCORRECT; 503 return IV_FAIL; 504 } 505 } 506 //no break; is needed here 507 case IVD_CMD_CTL_SETDEFAULT: 508 { 509 ihevcd_cxa_ctl_set_config_op_t *ps_op; 510 ps_op = (ihevcd_cxa_ctl_set_config_op_t *)pv_api_op; 511 if(ps_op->s_ivd_ctl_set_config_op_t.u4_size 512 != sizeof(ihevcd_cxa_ctl_set_config_op_t)) 513 { 514 ps_op->s_ivd_ctl_set_config_op_t.u4_error_code |= 1 515 << IVD_UNSUPPORTEDPARAM; 516 ps_op->s_ivd_ctl_set_config_op_t.u4_error_code |= 517 IVD_OP_API_STRUCT_SIZE_INCORRECT; 518 return IV_FAIL; 519 } 520 } 521 break; 522 523 case IVD_CMD_CTL_GETPARAMS: 524 { 525 ihevcd_cxa_ctl_getstatus_ip_t *ps_ip; 526 ihevcd_cxa_ctl_getstatus_op_t *ps_op; 527 528 ps_ip = (ihevcd_cxa_ctl_getstatus_ip_t *)pv_api_ip; 529 ps_op = (ihevcd_cxa_ctl_getstatus_op_t *)pv_api_op; 530 if(ps_ip->s_ivd_ctl_getstatus_ip_t.u4_size 531 != sizeof(ihevcd_cxa_ctl_getstatus_ip_t)) 532 { 533 ps_op->s_ivd_ctl_getstatus_op_t.u4_error_code |= 1 534 << IVD_UNSUPPORTEDPARAM; 535 ps_op->s_ivd_ctl_getstatus_op_t.u4_error_code |= 536 IVD_IP_API_STRUCT_SIZE_INCORRECT; 537 return IV_FAIL; 538 } 539 if((ps_op->s_ivd_ctl_getstatus_op_t.u4_size 540 != sizeof(ihevcd_cxa_ctl_getstatus_op_t)) && 541 (ps_op->s_ivd_ctl_getstatus_op_t.u4_size 542 != sizeof(ivd_ctl_getstatus_op_t))) 543 { 544 ps_op->s_ivd_ctl_getstatus_op_t.u4_error_code |= 1 545 << IVD_UNSUPPORTEDPARAM; 546 ps_op->s_ivd_ctl_getstatus_op_t.u4_error_code |= 547 IVD_OP_API_STRUCT_SIZE_INCORRECT; 548 return IV_FAIL; 549 } 550 } 551 break; 552 553 case IVD_CMD_CTL_GETBUFINFO: 554 { 555 ihevcd_cxa_ctl_getbufinfo_ip_t *ps_ip; 556 ihevcd_cxa_ctl_getbufinfo_op_t *ps_op; 557 ps_ip = (ihevcd_cxa_ctl_getbufinfo_ip_t *)pv_api_ip; 558 ps_op = (ihevcd_cxa_ctl_getbufinfo_op_t *)pv_api_op; 559 560 if(ps_ip->s_ivd_ctl_getbufinfo_ip_t.u4_size 561 != sizeof(ihevcd_cxa_ctl_getbufinfo_ip_t)) 562 { 563 ps_op->s_ivd_ctl_getbufinfo_op_t.u4_error_code |= 1 564 << IVD_UNSUPPORTEDPARAM; 565 ps_op->s_ivd_ctl_getbufinfo_op_t.u4_error_code |= 566 IVD_IP_API_STRUCT_SIZE_INCORRECT; 567 return IV_FAIL; 568 } 569 if(ps_op->s_ivd_ctl_getbufinfo_op_t.u4_size 570 != sizeof(ihevcd_cxa_ctl_getbufinfo_op_t)) 571 { 572 ps_op->s_ivd_ctl_getbufinfo_op_t.u4_error_code |= 1 573 << IVD_UNSUPPORTEDPARAM; 574 ps_op->s_ivd_ctl_getbufinfo_op_t.u4_error_code |= 575 IVD_OP_API_STRUCT_SIZE_INCORRECT; 576 return IV_FAIL; 577 } 578 } 579 break; 580 581 case IVD_CMD_CTL_GETVERSION: 582 { 583 ihevcd_cxa_ctl_getversioninfo_ip_t *ps_ip; 584 ihevcd_cxa_ctl_getversioninfo_op_t *ps_op; 585 ps_ip = (ihevcd_cxa_ctl_getversioninfo_ip_t *)pv_api_ip; 586 ps_op = (ihevcd_cxa_ctl_getversioninfo_op_t *)pv_api_op; 587 if(ps_ip->s_ivd_ctl_getversioninfo_ip_t.u4_size 588 != sizeof(ihevcd_cxa_ctl_getversioninfo_ip_t)) 589 { 590 ps_op->s_ivd_ctl_getversioninfo_op_t.u4_error_code |= 1 591 << IVD_UNSUPPORTEDPARAM; 592 ps_op->s_ivd_ctl_getversioninfo_op_t.u4_error_code |= 593 IVD_IP_API_STRUCT_SIZE_INCORRECT; 594 return IV_FAIL; 595 } 596 if(ps_op->s_ivd_ctl_getversioninfo_op_t.u4_size 597 != sizeof(ihevcd_cxa_ctl_getversioninfo_op_t)) 598 { 599 ps_op->s_ivd_ctl_getversioninfo_op_t.u4_error_code |= 1 600 << IVD_UNSUPPORTEDPARAM; 601 ps_op->s_ivd_ctl_getversioninfo_op_t.u4_error_code |= 602 IVD_OP_API_STRUCT_SIZE_INCORRECT; 603 return IV_FAIL; 604 } 605 } 606 break; 607 608 case IVD_CMD_CTL_FLUSH: 609 { 610 ihevcd_cxa_ctl_flush_ip_t *ps_ip; 611 ihevcd_cxa_ctl_flush_op_t *ps_op; 612 ps_ip = (ihevcd_cxa_ctl_flush_ip_t *)pv_api_ip; 613 ps_op = (ihevcd_cxa_ctl_flush_op_t *)pv_api_op; 614 if(ps_ip->s_ivd_ctl_flush_ip_t.u4_size 615 != sizeof(ihevcd_cxa_ctl_flush_ip_t)) 616 { 617 ps_op->s_ivd_ctl_flush_op_t.u4_error_code |= 1 618 << IVD_UNSUPPORTEDPARAM; 619 ps_op->s_ivd_ctl_flush_op_t.u4_error_code |= 620 IVD_IP_API_STRUCT_SIZE_INCORRECT; 621 return IV_FAIL; 622 } 623 if(ps_op->s_ivd_ctl_flush_op_t.u4_size 624 != sizeof(ihevcd_cxa_ctl_flush_op_t)) 625 { 626 ps_op->s_ivd_ctl_flush_op_t.u4_error_code |= 1 627 << IVD_UNSUPPORTEDPARAM; 628 ps_op->s_ivd_ctl_flush_op_t.u4_error_code |= 629 IVD_OP_API_STRUCT_SIZE_INCORRECT; 630 return IV_FAIL; 631 } 632 } 633 break; 634 635 case IVD_CMD_CTL_RESET: 636 { 637 ihevcd_cxa_ctl_reset_ip_t *ps_ip; 638 ihevcd_cxa_ctl_reset_op_t *ps_op; 639 ps_ip = (ihevcd_cxa_ctl_reset_ip_t *)pv_api_ip; 640 ps_op = (ihevcd_cxa_ctl_reset_op_t *)pv_api_op; 641 if(ps_ip->s_ivd_ctl_reset_ip_t.u4_size 642 != sizeof(ihevcd_cxa_ctl_reset_ip_t)) 643 { 644 ps_op->s_ivd_ctl_reset_op_t.u4_error_code |= 1 645 << IVD_UNSUPPORTEDPARAM; 646 ps_op->s_ivd_ctl_reset_op_t.u4_error_code |= 647 IVD_IP_API_STRUCT_SIZE_INCORRECT; 648 return IV_FAIL; 649 } 650 if(ps_op->s_ivd_ctl_reset_op_t.u4_size 651 != sizeof(ihevcd_cxa_ctl_reset_op_t)) 652 { 653 ps_op->s_ivd_ctl_reset_op_t.u4_error_code |= 1 654 << IVD_UNSUPPORTEDPARAM; 655 ps_op->s_ivd_ctl_reset_op_t.u4_error_code |= 656 IVD_OP_API_STRUCT_SIZE_INCORRECT; 657 return IV_FAIL; 658 } 659 } 660 break; 661 case IHEVCD_CXA_CMD_CTL_DEGRADE: 662 { 663 ihevcd_cxa_ctl_degrade_ip_t *ps_ip; 664 ihevcd_cxa_ctl_degrade_op_t *ps_op; 665 666 ps_ip = (ihevcd_cxa_ctl_degrade_ip_t *)pv_api_ip; 667 ps_op = (ihevcd_cxa_ctl_degrade_op_t *)pv_api_op; 668 669 if(ps_ip->u4_size 670 != sizeof(ihevcd_cxa_ctl_degrade_ip_t)) 671 { 672 ps_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM; 673 ps_op->u4_error_code |= 674 IVD_IP_API_STRUCT_SIZE_INCORRECT; 675 return IV_FAIL; 676 } 677 678 if(ps_op->u4_size 679 != sizeof(ihevcd_cxa_ctl_degrade_op_t)) 680 { 681 ps_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM; 682 ps_op->u4_error_code |= 683 IVD_OP_API_STRUCT_SIZE_INCORRECT; 684 return IV_FAIL; 685 } 686 687 if((ps_ip->i4_degrade_pics < 0) || 688 (ps_ip->i4_degrade_pics > 4) || 689 (ps_ip->i4_nondegrade_interval < 0) || 690 (ps_ip->i4_degrade_type < 0) || 691 (ps_ip->i4_degrade_type > 15)) 692 { 693 ps_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM; 694 return IV_FAIL; 695 } 696 697 break; 698 } 699 700 case IHEVCD_CXA_CMD_CTL_GET_BUFFER_DIMENSIONS: 701 { 702 ihevcd_cxa_ctl_get_frame_dimensions_ip_t *ps_ip; 703 ihevcd_cxa_ctl_get_frame_dimensions_op_t *ps_op; 704 705 ps_ip = 706 (ihevcd_cxa_ctl_get_frame_dimensions_ip_t *)pv_api_ip; 707 ps_op = 708 (ihevcd_cxa_ctl_get_frame_dimensions_op_t *)pv_api_op; 709 710 if(ps_ip->u4_size 711 != sizeof(ihevcd_cxa_ctl_get_frame_dimensions_ip_t)) 712 { 713 ps_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM; 714 ps_op->u4_error_code |= 715 IVD_IP_API_STRUCT_SIZE_INCORRECT; 716 return IV_FAIL; 717 } 718 719 if(ps_op->u4_size 720 != sizeof(ihevcd_cxa_ctl_get_frame_dimensions_op_t)) 721 { 722 ps_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM; 723 ps_op->u4_error_code |= 724 IVD_OP_API_STRUCT_SIZE_INCORRECT; 725 return IV_FAIL; 726 } 727 728 break; 729 } 730 731 case IHEVCD_CXA_CMD_CTL_GET_VUI_PARAMS: 732 { 733 ihevcd_cxa_ctl_get_vui_params_ip_t *ps_ip; 734 ihevcd_cxa_ctl_get_vui_params_op_t *ps_op; 735 736 ps_ip = 737 (ihevcd_cxa_ctl_get_vui_params_ip_t *)pv_api_ip; 738 ps_op = 739 (ihevcd_cxa_ctl_get_vui_params_op_t *)pv_api_op; 740 741 if(ps_ip->u4_size 742 != sizeof(ihevcd_cxa_ctl_get_vui_params_ip_t)) 743 { 744 ps_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM; 745 ps_op->u4_error_code |= 746 IVD_IP_API_STRUCT_SIZE_INCORRECT; 747 return IV_FAIL; 748 } 749 750 if(ps_op->u4_size 751 != sizeof(ihevcd_cxa_ctl_get_vui_params_op_t)) 752 { 753 ps_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM; 754 ps_op->u4_error_code |= 755 IVD_OP_API_STRUCT_SIZE_INCORRECT; 756 return IV_FAIL; 757 } 758 759 break; 760 } 761 case IHEVCD_CXA_CMD_CTL_GET_SEI_MASTERING_PARAMS: 762 { 763 ihevcd_cxa_ctl_get_sei_mastering_params_ip_t *ps_ip; 764 ihevcd_cxa_ctl_get_sei_mastering_params_op_t *ps_op; 765 766 ps_ip = (ihevcd_cxa_ctl_get_sei_mastering_params_ip_t *)pv_api_ip; 767 ps_op = (ihevcd_cxa_ctl_get_sei_mastering_params_op_t *)pv_api_op; 768 769 if(ps_ip->u4_size 770 != sizeof(ihevcd_cxa_ctl_get_sei_mastering_params_ip_t)) 771 { 772 ps_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM; 773 ps_op->u4_error_code |= 774 IVD_IP_API_STRUCT_SIZE_INCORRECT; 775 return IV_FAIL; 776 } 777 778 if(ps_op->u4_size 779 != sizeof(ihevcd_cxa_ctl_get_sei_mastering_params_op_t)) 780 { 781 ps_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM; 782 ps_op->u4_error_code |= 783 IVD_OP_API_STRUCT_SIZE_INCORRECT; 784 return IV_FAIL; 785 } 786 787 break; 788 } 789 case IHEVCD_CXA_CMD_CTL_SET_NUM_CORES: 790 { 791 ihevcd_cxa_ctl_set_num_cores_ip_t *ps_ip; 792 ihevcd_cxa_ctl_set_num_cores_op_t *ps_op; 793 794 ps_ip = (ihevcd_cxa_ctl_set_num_cores_ip_t *)pv_api_ip; 795 ps_op = (ihevcd_cxa_ctl_set_num_cores_op_t *)pv_api_op; 796 797 if(ps_ip->u4_size 798 != sizeof(ihevcd_cxa_ctl_set_num_cores_ip_t)) 799 { 800 ps_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM; 801 ps_op->u4_error_code |= 802 IVD_IP_API_STRUCT_SIZE_INCORRECT; 803 return IV_FAIL; 804 } 805 806 if(ps_op->u4_size 807 != sizeof(ihevcd_cxa_ctl_set_num_cores_op_t)) 808 { 809 ps_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM; 810 ps_op->u4_error_code |= 811 IVD_OP_API_STRUCT_SIZE_INCORRECT; 812 return IV_FAIL; 813 } 814 815#ifdef MULTICORE 816 if((ps_ip->u4_num_cores < 1) || (ps_ip->u4_num_cores > MAX_NUM_CORES)) 817#else 818 if(ps_ip->u4_num_cores != 1) 819#endif 820 { 821 ps_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM; 822 return IV_FAIL; 823 } 824 break; 825 } 826 case IHEVCD_CXA_CMD_CTL_SET_PROCESSOR: 827 { 828 ihevcd_cxa_ctl_set_processor_ip_t *ps_ip; 829 ihevcd_cxa_ctl_set_processor_op_t *ps_op; 830 831 ps_ip = (ihevcd_cxa_ctl_set_processor_ip_t *)pv_api_ip; 832 ps_op = (ihevcd_cxa_ctl_set_processor_op_t *)pv_api_op; 833 834 if(ps_ip->u4_size 835 != sizeof(ihevcd_cxa_ctl_set_processor_ip_t)) 836 { 837 ps_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM; 838 ps_op->u4_error_code |= 839 IVD_IP_API_STRUCT_SIZE_INCORRECT; 840 return IV_FAIL; 841 } 842 843 if(ps_op->u4_size 844 != sizeof(ihevcd_cxa_ctl_set_processor_op_t)) 845 { 846 ps_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM; 847 ps_op->u4_error_code |= 848 IVD_OP_API_STRUCT_SIZE_INCORRECT; 849 return IV_FAIL; 850 } 851 852 break; 853 } 854 default: 855 *(pu4_api_op + 1) |= 1 << IVD_UNSUPPORTEDPARAM; 856 *(pu4_api_op + 1) |= IVD_UNSUPPORTED_API_CMD; 857 return IV_FAIL; 858 } 859 } 860 break; 861 default: 862 *(pu4_api_op + 1) |= 1 << IVD_UNSUPPORTEDPARAM; 863 *(pu4_api_op + 1) |= IVD_UNSUPPORTED_API_CMD; 864 return IV_FAIL; 865 } 866 867 return IV_SUCCESS; 868} 869 870 871/** 872******************************************************************************* 873* 874* @brief 875* Sets default dynamic parameters 876* 877* @par Description: 878* Sets default dynamic parameters. Will be called in ihevcd_init() to ensure 879* that even if set_params is not called, codec continues to work 880* 881* @param[in] ps_codec_obj 882* Pointer to codec object at API level 883* 884* @param[in] pv_api_ip 885* Pointer to input argument structure 886* 887* @param[out] pv_api_op 888* Pointer to output argument structure 889* 890* @returns Status 891* 892* @remarks 893* 894* 895******************************************************************************* 896*/ 897WORD32 ihevcd_set_default_params(codec_t *ps_codec) 898{ 899 900 WORD32 ret = IV_SUCCESS; 901 902 ps_codec->e_pic_skip_mode = IVD_SKIP_NONE; 903 ps_codec->i4_strd = 0; 904 ps_codec->i4_disp_strd = 0; 905 ps_codec->i4_header_mode = 0; 906 ps_codec->e_pic_out_order = IVD_DISPLAY_FRAME_OUT; 907 return ret; 908} 909 910void ihevcd_update_function_ptr(codec_t *ps_codec) 911{ 912 913 /* Init inter pred function array */ 914 ps_codec->apf_inter_pred[0] = NULL; 915 ps_codec->apf_inter_pred[1] = (pf_inter_pred)ps_codec->s_func_selector.ihevc_inter_pred_luma_copy_fptr; 916 ps_codec->apf_inter_pred[2] = (pf_inter_pred)ps_codec->s_func_selector.ihevc_inter_pred_luma_vert_fptr; 917 ps_codec->apf_inter_pred[3] = (pf_inter_pred)ps_codec->s_func_selector.ihevc_inter_pred_luma_horz_fptr; 918 ps_codec->apf_inter_pred[4] = (pf_inter_pred)ps_codec->s_func_selector.ihevc_inter_pred_luma_horz_w16out_fptr; 919 ps_codec->apf_inter_pred[5] = (pf_inter_pred)ps_codec->s_func_selector.ihevc_inter_pred_luma_copy_w16out_fptr; 920 ps_codec->apf_inter_pred[6] = (pf_inter_pred)ps_codec->s_func_selector.ihevc_inter_pred_luma_vert_w16out_fptr; 921 ps_codec->apf_inter_pred[7] = (pf_inter_pred)ps_codec->s_func_selector.ihevc_inter_pred_luma_horz_w16out_fptr; 922 ps_codec->apf_inter_pred[8] = (pf_inter_pred)ps_codec->s_func_selector.ihevc_inter_pred_luma_horz_w16out_fptr; 923 ps_codec->apf_inter_pred[9] = (pf_inter_pred)ps_codec->s_func_selector.ihevc_inter_pred_luma_vert_w16inp_fptr; 924 ps_codec->apf_inter_pred[10] = (pf_inter_pred)ps_codec->s_func_selector.ihevc_inter_pred_luma_vert_w16inp_w16out_fptr; 925 ps_codec->apf_inter_pred[11] = NULL; 926 ps_codec->apf_inter_pred[12] = (pf_inter_pred)ps_codec->s_func_selector.ihevc_inter_pred_chroma_copy_fptr; 927 ps_codec->apf_inter_pred[13] = (pf_inter_pred)ps_codec->s_func_selector.ihevc_inter_pred_chroma_vert_fptr; 928 ps_codec->apf_inter_pred[14] = (pf_inter_pred)ps_codec->s_func_selector.ihevc_inter_pred_chroma_horz_fptr; 929 ps_codec->apf_inter_pred[15] = (pf_inter_pred)ps_codec->s_func_selector.ihevc_inter_pred_chroma_horz_w16out_fptr; 930 ps_codec->apf_inter_pred[16] = (pf_inter_pred)ps_codec->s_func_selector.ihevc_inter_pred_chroma_copy_w16out_fptr; 931 ps_codec->apf_inter_pred[17] = (pf_inter_pred)ps_codec->s_func_selector.ihevc_inter_pred_chroma_vert_w16out_fptr; 932 ps_codec->apf_inter_pred[18] = (pf_inter_pred)ps_codec->s_func_selector.ihevc_inter_pred_chroma_horz_w16out_fptr; 933 ps_codec->apf_inter_pred[19] = (pf_inter_pred)ps_codec->s_func_selector.ihevc_inter_pred_chroma_horz_w16out_fptr; 934 ps_codec->apf_inter_pred[20] = (pf_inter_pred)ps_codec->s_func_selector.ihevc_inter_pred_chroma_vert_w16inp_fptr; 935 ps_codec->apf_inter_pred[21] = (pf_inter_pred)ps_codec->s_func_selector.ihevc_inter_pred_chroma_vert_w16inp_w16out_fptr; 936 937 /* Init intra pred function array */ 938 ps_codec->apf_intra_pred_luma[0] = (pf_intra_pred)NULL; 939 ps_codec->apf_intra_pred_luma[1] = (pf_intra_pred)ps_codec->s_func_selector.ihevc_intra_pred_luma_planar_fptr; 940 ps_codec->apf_intra_pred_luma[2] = (pf_intra_pred)ps_codec->s_func_selector.ihevc_intra_pred_luma_dc_fptr; 941 ps_codec->apf_intra_pred_luma[3] = (pf_intra_pred)ps_codec->s_func_selector.ihevc_intra_pred_luma_mode2_fptr; 942 ps_codec->apf_intra_pred_luma[4] = (pf_intra_pred)ps_codec->s_func_selector.ihevc_intra_pred_luma_mode_3_to_9_fptr; 943 ps_codec->apf_intra_pred_luma[5] = (pf_intra_pred)ps_codec->s_func_selector.ihevc_intra_pred_luma_horz_fptr; 944 ps_codec->apf_intra_pred_luma[6] = (pf_intra_pred)ps_codec->s_func_selector.ihevc_intra_pred_luma_mode_11_to_17_fptr; 945 ps_codec->apf_intra_pred_luma[7] = (pf_intra_pred)ps_codec->s_func_selector.ihevc_intra_pred_luma_mode_18_34_fptr; 946 ps_codec->apf_intra_pred_luma[8] = (pf_intra_pred)ps_codec->s_func_selector.ihevc_intra_pred_luma_mode_19_to_25_fptr; 947 ps_codec->apf_intra_pred_luma[9] = (pf_intra_pred)ps_codec->s_func_selector.ihevc_intra_pred_luma_ver_fptr; 948 ps_codec->apf_intra_pred_luma[10] = (pf_intra_pred)ps_codec->s_func_selector.ihevc_intra_pred_luma_mode_27_to_33_fptr; 949 950 ps_codec->apf_intra_pred_chroma[0] = (pf_intra_pred)NULL; 951 ps_codec->apf_intra_pred_chroma[1] = (pf_intra_pred)ps_codec->s_func_selector.ihevc_intra_pred_chroma_planar_fptr; 952 ps_codec->apf_intra_pred_chroma[2] = (pf_intra_pred)ps_codec->s_func_selector.ihevc_intra_pred_chroma_dc_fptr; 953 ps_codec->apf_intra_pred_chroma[3] = (pf_intra_pred)ps_codec->s_func_selector.ihevc_intra_pred_chroma_mode2_fptr; 954 ps_codec->apf_intra_pred_chroma[4] = (pf_intra_pred)ps_codec->s_func_selector.ihevc_intra_pred_chroma_mode_3_to_9_fptr; 955 ps_codec->apf_intra_pred_chroma[5] = (pf_intra_pred)ps_codec->s_func_selector.ihevc_intra_pred_chroma_horz_fptr; 956 ps_codec->apf_intra_pred_chroma[6] = (pf_intra_pred)ps_codec->s_func_selector.ihevc_intra_pred_chroma_mode_11_to_17_fptr; 957 ps_codec->apf_intra_pred_chroma[7] = (pf_intra_pred)ps_codec->s_func_selector.ihevc_intra_pred_chroma_mode_18_34_fptr; 958 ps_codec->apf_intra_pred_chroma[8] = (pf_intra_pred)ps_codec->s_func_selector.ihevc_intra_pred_chroma_mode_19_to_25_fptr; 959 ps_codec->apf_intra_pred_chroma[9] = (pf_intra_pred)ps_codec->s_func_selector.ihevc_intra_pred_chroma_ver_fptr; 960 ps_codec->apf_intra_pred_chroma[10] = (pf_intra_pred)ps_codec->s_func_selector.ihevc_intra_pred_chroma_mode_27_to_33_fptr; 961 962 /* Init itrans_recon function array */ 963 ps_codec->apf_itrans_recon[0] = (pf_itrans_recon)ps_codec->s_func_selector.ihevc_itrans_recon_4x4_ttype1_fptr; 964 ps_codec->apf_itrans_recon[1] = (pf_itrans_recon)ps_codec->s_func_selector.ihevc_itrans_recon_4x4_fptr; 965 ps_codec->apf_itrans_recon[2] = (pf_itrans_recon)ps_codec->s_func_selector.ihevc_itrans_recon_8x8_fptr; 966 ps_codec->apf_itrans_recon[3] = (pf_itrans_recon)ps_codec->s_func_selector.ihevc_itrans_recon_16x16_fptr; 967 ps_codec->apf_itrans_recon[4] = (pf_itrans_recon)ps_codec->s_func_selector.ihevc_itrans_recon_32x32_fptr; 968 ps_codec->apf_itrans_recon[5] = (pf_itrans_recon)ps_codec->s_func_selector.ihevc_chroma_itrans_recon_4x4_fptr; 969 ps_codec->apf_itrans_recon[6] = (pf_itrans_recon)ps_codec->s_func_selector.ihevc_chroma_itrans_recon_8x8_fptr; 970 ps_codec->apf_itrans_recon[7] = (pf_itrans_recon)ps_codec->s_func_selector.ihevc_chroma_itrans_recon_16x16_fptr; 971 972 /* Init recon function array */ 973 ps_codec->apf_recon[0] = (pf_recon)ps_codec->s_func_selector.ihevc_recon_4x4_ttype1_fptr; 974 ps_codec->apf_recon[1] = (pf_recon)ps_codec->s_func_selector.ihevc_recon_4x4_fptr; 975 ps_codec->apf_recon[2] = (pf_recon)ps_codec->s_func_selector.ihevc_recon_8x8_fptr; 976 ps_codec->apf_recon[3] = (pf_recon)ps_codec->s_func_selector.ihevc_recon_16x16_fptr; 977 ps_codec->apf_recon[4] = (pf_recon)ps_codec->s_func_selector.ihevc_recon_32x32_fptr; 978 ps_codec->apf_recon[5] = (pf_recon)ps_codec->s_func_selector.ihevc_chroma_recon_4x4_fptr; 979 ps_codec->apf_recon[6] = (pf_recon)ps_codec->s_func_selector.ihevc_chroma_recon_8x8_fptr; 980 ps_codec->apf_recon[7] = (pf_recon)ps_codec->s_func_selector.ihevc_chroma_recon_16x16_fptr; 981 982 /* Init itrans_recon_dc function array */ 983 ps_codec->apf_itrans_recon_dc[0] = (pf_itrans_recon_dc)ps_codec->s_func_selector.ihevcd_itrans_recon_dc_luma_fptr; 984 ps_codec->apf_itrans_recon_dc[1] = (pf_itrans_recon_dc)ps_codec->s_func_selector.ihevcd_itrans_recon_dc_chroma_fptr; 985 986 /* Init sao function array */ 987 ps_codec->apf_sao_luma[0] = (pf_sao_luma)ps_codec->s_func_selector.ihevc_sao_edge_offset_class0_fptr; 988 ps_codec->apf_sao_luma[1] = (pf_sao_luma)ps_codec->s_func_selector.ihevc_sao_edge_offset_class1_fptr; 989 ps_codec->apf_sao_luma[2] = (pf_sao_luma)ps_codec->s_func_selector.ihevc_sao_edge_offset_class2_fptr; 990 ps_codec->apf_sao_luma[3] = (pf_sao_luma)ps_codec->s_func_selector.ihevc_sao_edge_offset_class3_fptr; 991 992 ps_codec->apf_sao_chroma[0] = (pf_sao_chroma)ps_codec->s_func_selector.ihevc_sao_edge_offset_class0_chroma_fptr; 993 ps_codec->apf_sao_chroma[1] = (pf_sao_chroma)ps_codec->s_func_selector.ihevc_sao_edge_offset_class1_chroma_fptr; 994 ps_codec->apf_sao_chroma[2] = (pf_sao_chroma)ps_codec->s_func_selector.ihevc_sao_edge_offset_class2_chroma_fptr; 995 ps_codec->apf_sao_chroma[3] = (pf_sao_chroma)ps_codec->s_func_selector.ihevc_sao_edge_offset_class3_chroma_fptr; 996} 997/** 998******************************************************************************* 999* 1000* @brief 1001* Initialize the context. This will be called by create and during 1002* reset 1003* 1004* @par Description: 1005* Initializes the context 1006* 1007* @param[in] ps_codec 1008* Codec context pointer 1009* 1010* @returns Status 1011* 1012* @remarks 1013* 1014* 1015******************************************************************************* 1016*/ 1017WORD32 ihevcd_init(codec_t *ps_codec) 1018{ 1019 WORD32 status = IV_SUCCESS; 1020 WORD32 i; 1021 1022 /* Free any dynamic buffers that are allocated */ 1023 ihevcd_free_dynamic_bufs(ps_codec); 1024 1025 ps_codec->u4_allocate_dynamic_done = 0; 1026 ps_codec->i4_num_disp_bufs = 1; 1027 ps_codec->i4_flush_mode = 0; 1028 1029 ps_codec->i4_ht = ps_codec->i4_disp_ht = 0; 1030 ps_codec->i4_wd = ps_codec->i4_disp_wd = 0; 1031 ps_codec->i4_strd = 0; 1032 ps_codec->i4_disp_strd = 0; 1033 ps_codec->i4_num_cores = 1; 1034 1035 ps_codec->u4_pic_cnt = 0; 1036 ps_codec->u4_disp_cnt = 0; 1037 1038 ps_codec->i4_header_mode = 0; 1039 ps_codec->i4_header_in_slice_mode = 0; 1040 ps_codec->i4_sps_done = 0; 1041 ps_codec->i4_pps_done = 0; 1042 ps_codec->i4_init_done = 1; 1043 ps_codec->i4_first_pic_done = 0; 1044 ps_codec->s_parse.i4_first_pic_init = 0; 1045 ps_codec->i4_error_code = 0; 1046 ps_codec->i4_reset_flag = 0; 1047 ps_codec->i4_cra_as_first_pic = 1; 1048 ps_codec->i4_rasl_output_flag = 0; 1049 1050 ps_codec->i4_prev_poc_msb = 0; 1051 ps_codec->i4_prev_poc_lsb = -1; 1052 ps_codec->i4_max_prev_poc_lsb = -1; 1053 ps_codec->s_parse.i4_abs_pic_order_cnt = -1; 1054 1055 /* Set ref chroma format by default to 420SP UV interleaved */ 1056 ps_codec->e_ref_chroma_fmt = IV_YUV_420SP_UV; 1057 1058 /* If the codec is in shared mode and required format is 420 SP VU interleaved then change 1059 * reference buffers chroma format 1060 */ 1061 if(IV_YUV_420SP_VU == ps_codec->e_chroma_fmt) 1062 { 1063 ps_codec->e_ref_chroma_fmt = IV_YUV_420SP_VU; 1064 } 1065 1066 1067 1068 ps_codec->i4_disable_deblk_pic = 0; 1069 1070 ps_codec->i4_degrade_pic_cnt = 0; 1071 ps_codec->i4_degrade_pics = 0; 1072 ps_codec->i4_degrade_type = 0; 1073 ps_codec->i4_disable_sao_pic = 0; 1074 ps_codec->i4_fullpel_inter_pred = 0; 1075 ps_codec->u4_enable_fmt_conv_ahead = 0; 1076 ps_codec->i4_share_disp_buf_cnt = 0; 1077 1078 { 1079 sps_t *ps_sps = ps_codec->ps_sps_base; 1080 pps_t *ps_pps = ps_codec->ps_pps_base; 1081 1082 for(i = 0; i < MAX_SPS_CNT; i++) 1083 { 1084 ps_sps->i1_sps_valid = 0; 1085 ps_sps++; 1086 } 1087 1088 for(i = 0; i < MAX_PPS_CNT; i++) 1089 { 1090 ps_pps->i1_pps_valid = 0; 1091 ps_pps++; 1092 } 1093 } 1094 1095 ihevcd_set_default_params(ps_codec); 1096 /* Initialize MV Bank buffer manager */ 1097 ihevc_buf_mgr_init((buf_mgr_t *)ps_codec->pv_mv_buf_mgr); 1098 1099 /* Initialize Picture buffer manager */ 1100 ihevc_buf_mgr_init((buf_mgr_t *)ps_codec->pv_pic_buf_mgr); 1101 1102 ps_codec->ps_pic_buf = (pic_buf_t *)ps_codec->pv_pic_buf_base; 1103 1104 memset(ps_codec->ps_pic_buf, 0, BUF_MGR_MAX_CNT * sizeof(pic_buf_t)); 1105 1106 1107 1108 /* Initialize display buffer manager */ 1109 ihevc_disp_mgr_init((disp_mgr_t *)ps_codec->pv_disp_buf_mgr); 1110 1111 /* Initialize dpb manager */ 1112 ihevc_dpb_mgr_init((dpb_mgr_t *)ps_codec->pv_dpb_mgr); 1113 1114 ps_codec->e_processor_soc = SOC_GENERIC; 1115 /* The following can be over-ridden using soc parameter as a hack */ 1116 ps_codec->u4_nctb = 0x7FFFFFFF; 1117 ihevcd_init_arch(ps_codec); 1118 1119 ihevcd_init_function_ptr(ps_codec); 1120 1121 ihevcd_update_function_ptr(ps_codec); 1122 1123 return status; 1124} 1125 1126/** 1127******************************************************************************* 1128* 1129* @brief 1130* Allocate static memory for the codec 1131* 1132* @par Description: 1133* Allocates static memory for the codec 1134* 1135* @param[in] pv_api_ip 1136* Pointer to input argument structure 1137* 1138* @param[out] pv_api_op 1139* Pointer to output argument structure 1140* 1141* @returns Status 1142* 1143* @remarks 1144* 1145* 1146******************************************************************************* 1147*/ 1148WORD32 ihevcd_allocate_static_bufs(iv_obj_t **pps_codec_obj, 1149 ihevcd_cxa_create_ip_t *ps_create_ip, 1150 ihevcd_cxa_create_op_t *ps_create_op) 1151{ 1152 WORD32 size; 1153 void *pv_buf; 1154 UWORD8 *pu1_buf; 1155 WORD32 i; 1156 codec_t *ps_codec; 1157 IV_API_CALL_STATUS_T status = IV_SUCCESS; 1158 void *(*pf_aligned_alloc)(void *pv_mem_ctxt, WORD32 alignment, WORD32 size); 1159 void (*pf_aligned_free)(void *pv_mem_ctxt, void *pv_buf); 1160 void *pv_mem_ctxt; 1161 1162 /* Request memory for HEVCD object */ 1163 ps_create_op->s_ivd_create_op_t.pv_handle = NULL; 1164 1165 pf_aligned_alloc = ps_create_ip->s_ivd_create_ip_t.pf_aligned_alloc; 1166 pf_aligned_free = ps_create_ip->s_ivd_create_ip_t.pf_aligned_free; 1167 pv_mem_ctxt = ps_create_ip->s_ivd_create_ip_t.pv_mem_ctxt; 1168 1169 1170 pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, sizeof(iv_obj_t)); 1171 RETURN_IF((NULL == pv_buf), IV_FAIL); 1172 *pps_codec_obj = (iv_obj_t *)pv_buf; 1173 ps_create_op->s_ivd_create_op_t.pv_handle = *pps_codec_obj; 1174 1175 1176 (*pps_codec_obj)->pv_codec_handle = NULL; 1177 pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, sizeof(codec_t)); 1178 RETURN_IF((NULL == pv_buf), IV_FAIL); 1179 (*pps_codec_obj)->pv_codec_handle = (codec_t *)pv_buf; 1180 ps_codec = (codec_t *)pv_buf; 1181 1182 memset(ps_codec, 0, sizeof(codec_t)); 1183 1184#ifndef LOGO_EN 1185 ps_codec->i4_share_disp_buf = ps_create_ip->s_ivd_create_ip_t.u4_share_disp_buf; 1186#else 1187 ps_codec->i4_share_disp_buf = 0; 1188#endif 1189 1190 /* Shared display mode is supported only for 420SP and 420P formats */ 1191 if((ps_create_ip->s_ivd_create_ip_t.e_output_format != IV_YUV_420P) && 1192 (ps_create_ip->s_ivd_create_ip_t.e_output_format != IV_YUV_420SP_UV) && 1193 (ps_create_ip->s_ivd_create_ip_t.e_output_format != IV_YUV_420SP_VU)) 1194 { 1195 ps_codec->i4_share_disp_buf = 0; 1196 } 1197 1198 ps_codec->e_chroma_fmt = ps_create_ip->s_ivd_create_ip_t.e_output_format; 1199 1200 ps_codec->pf_aligned_alloc = pf_aligned_alloc; 1201 ps_codec->pf_aligned_free = pf_aligned_free; 1202 ps_codec->pv_mem_ctxt = pv_mem_ctxt; 1203 1204 /* Request memory to hold thread handles for each processing thread */ 1205 size = MAX_PROCESS_THREADS * ithread_get_handle_size(); 1206 pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size); 1207 RETURN_IF((NULL == pv_buf), IV_FAIL); 1208 1209 for(i = 0; i < MAX_PROCESS_THREADS; i++) 1210 { 1211 WORD32 handle_size = ithread_get_handle_size(); 1212 ps_codec->apv_process_thread_handle[i] = 1213 (UWORD8 *)pv_buf + (i * handle_size); 1214 } 1215 1216 /* Request memory for static bitstream buffer which holds bitstream after emulation prevention */ 1217 size = MIN_BITSBUF_SIZE; 1218 pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size + 16); //Alloc extra for parse optimization 1219 RETURN_IF((NULL == pv_buf), IV_FAIL); 1220 ps_codec->pu1_bitsbuf_static = pv_buf; 1221 ps_codec->u4_bitsbuf_size_static = size; 1222 1223 /* size for holding display manager context */ 1224 size = sizeof(buf_mgr_t); 1225 pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size); 1226 RETURN_IF((NULL == pv_buf), IV_FAIL); 1227 ps_codec->pv_disp_buf_mgr = pv_buf; 1228 1229 /* size for holding dpb manager context */ 1230 size = sizeof(dpb_mgr_t); 1231 pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size); 1232 RETURN_IF((NULL == pv_buf), IV_FAIL); 1233 ps_codec->pv_dpb_mgr = pv_buf; 1234 1235 /* size for holding buffer manager context */ 1236 size = sizeof(buf_mgr_t); 1237 pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size); 1238 RETURN_IF((NULL == pv_buf), IV_FAIL); 1239 ps_codec->pv_pic_buf_mgr = pv_buf; 1240 1241 /* size for holding mv buffer manager context */ 1242 size = sizeof(buf_mgr_t); 1243 pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size); 1244 RETURN_IF((NULL == pv_buf), IV_FAIL); 1245 ps_codec->pv_mv_buf_mgr = pv_buf; 1246 1247 size = MAX_VPS_CNT * sizeof(vps_t); 1248 pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size); 1249 RETURN_IF((NULL == pv_buf), IV_FAIL); 1250 ps_codec->ps_vps_base = pv_buf; 1251 ps_codec->s_parse.ps_vps_base = ps_codec->ps_vps_base; 1252 1253 size = MAX_SPS_CNT * sizeof(sps_t); 1254 pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size); 1255 RETURN_IF((NULL == pv_buf), IV_FAIL); 1256 ps_codec->ps_sps_base = pv_buf; 1257 ps_codec->s_parse.ps_sps_base = ps_codec->ps_sps_base; 1258 1259 size = MAX_PPS_CNT * sizeof(pps_t); 1260 pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size); 1261 RETURN_IF((NULL == pv_buf), IV_FAIL); 1262 ps_codec->ps_pps_base = pv_buf; 1263 ps_codec->s_parse.ps_pps_base = ps_codec->ps_pps_base; 1264 1265 size = MAX_SLICE_HDR_CNT * sizeof(slice_header_t); 1266 pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size); 1267 RETURN_IF((NULL == pv_buf), IV_FAIL); 1268 memset(pv_buf, 0, size); 1269 ps_codec->ps_slice_hdr_base = (slice_header_t *)pv_buf; 1270 ps_codec->s_parse.ps_slice_hdr_base = ps_codec->ps_slice_hdr_base; 1271 1272 1273 SCALING_MAT_SIZE(size) 1274 size = (MAX_SPS_CNT + MAX_PPS_CNT) * size * sizeof(WORD16); 1275 pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size); 1276 RETURN_IF((NULL == pv_buf), IV_FAIL); 1277 ps_codec->pi2_scaling_mat = (WORD16 *)pv_buf; 1278 1279 1280 /* Size for holding pic_buf_t for each reference picture 1281 * Since this is only a structure allocation and not actual buffer allocation, 1282 * it is allocated for BUF_MGR_MAX_CNT entries 1283 */ 1284 size = BUF_MGR_MAX_CNT * sizeof(pic_buf_t); 1285 pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size); 1286 RETURN_IF((NULL == pv_buf), IV_FAIL); 1287 ps_codec->pv_pic_buf_base = (UWORD8 *)pv_buf; 1288 1289 /* TO hold scratch buffers needed for each SAO context */ 1290 size = 4 * MAX_CTB_SIZE * MAX_CTB_SIZE; 1291 1292 /* 2 temporary buffers*/ 1293 size *= 2; 1294 size *= MAX_PROCESS_THREADS; 1295 1296 pu1_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size); 1297 RETURN_IF((NULL == pu1_buf), IV_FAIL); 1298 1299 for(i = 0; i < MAX_PROCESS_THREADS; i++) 1300 { 1301 ps_codec->as_process[i].s_sao_ctxt.pu1_tmp_buf_luma = (UWORD8 *)pu1_buf; 1302 pu1_buf += 4 * MAX_CTB_SIZE * MAX_CTB_SIZE * sizeof(UWORD8); 1303 1304 ps_codec->as_process[i].s_sao_ctxt.pu1_tmp_buf_chroma = (UWORD8 *)pu1_buf; 1305 pu1_buf += 4 * MAX_CTB_SIZE * MAX_CTB_SIZE * sizeof(UWORD8); 1306 } 1307 1308 /* Allocate intra pred modes buffer */ 1309 /* 8 bits per 4x4 */ 1310 /* 16 bytes each for top and left 64 pixels and 16 bytes for default mode */ 1311 size = 3 * 16 * sizeof(UWORD8); 1312 pu1_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size); 1313 RETURN_IF((NULL == pu1_buf), IV_FAIL); 1314 ps_codec->s_parse.pu1_luma_intra_pred_mode_left = pu1_buf; 1315 ps_codec->s_parse.pu1_luma_intra_pred_mode_top = pu1_buf + 16; 1316 1317 { 1318 WORD32 inter_pred_tmp_buf_size, ntaps_luma; 1319 WORD32 pic_pu_idx_map_size; 1320 1321 /* Max inter pred size */ 1322 ntaps_luma = 8; 1323 inter_pred_tmp_buf_size = sizeof(WORD16) * (MAX_CTB_SIZE + ntaps_luma) * MAX_CTB_SIZE; 1324 1325 inter_pred_tmp_buf_size = ALIGN64(inter_pred_tmp_buf_size); 1326 1327 /* To hold pu_index w.r.t. frame level pu_t array for a CTB */ 1328 pic_pu_idx_map_size = sizeof(WORD32) * (18 * 18); 1329 pic_pu_idx_map_size = ALIGN64(pic_pu_idx_map_size); 1330 1331 size = inter_pred_tmp_buf_size * 2; 1332 size += pic_pu_idx_map_size; 1333 size *= MAX_PROCESS_THREADS; 1334 1335 pu1_buf = ps_codec->pf_aligned_alloc(pv_mem_ctxt, 128, size); 1336 RETURN_IF((NULL == pu1_buf), IV_FAIL); 1337 memset(pu1_buf, 0, size); 1338 1339 for(i = 0; i < MAX_PROCESS_THREADS; i++) 1340 { 1341 ps_codec->as_process[i].pi2_inter_pred_tmp_buf1 = (WORD16 *)pu1_buf; 1342 pu1_buf += inter_pred_tmp_buf_size; 1343 1344 ps_codec->as_process[i].pi2_inter_pred_tmp_buf2 = (WORD16 *)pu1_buf; 1345 pu1_buf += inter_pred_tmp_buf_size; 1346 1347 /* Inverse transform intermediate and inverse scan output buffers reuse inter pred scratch buffers */ 1348 ps_codec->as_process[i].pi2_itrans_intrmd_buf = 1349 ps_codec->as_process[i].pi2_inter_pred_tmp_buf2; 1350 ps_codec->as_process[i].pi2_invscan_out = 1351 ps_codec->as_process[i].pi2_inter_pred_tmp_buf1; 1352 1353 ps_codec->as_process[i].pu4_pic_pu_idx_map = (UWORD32 *)pu1_buf; 1354 ps_codec->as_process[i].s_bs_ctxt.pu4_pic_pu_idx_map = 1355 (UWORD32 *)pu1_buf; 1356 pu1_buf += pic_pu_idx_map_size; 1357 1358 // ps_codec->as_process[i].pi2_inter_pred_tmp_buf3 = (WORD16 *)pu1_buf; 1359 // pu1_buf += inter_pred_tmp_buf_size; 1360 1361 ps_codec->as_process[i].i4_inter_pred_tmp_buf_strd = MAX_CTB_SIZE; 1362 1363 } 1364 } 1365 /* Initialize pointers in PPS structures */ 1366 { 1367 sps_t *ps_sps = ps_codec->ps_sps_base; 1368 pps_t *ps_pps = ps_codec->ps_pps_base; 1369 WORD16 *pi2_scaling_mat = ps_codec->pi2_scaling_mat; 1370 WORD32 scaling_mat_size; 1371 1372 SCALING_MAT_SIZE(scaling_mat_size); 1373 1374 for(i = 0; i < MAX_SPS_CNT; i++) 1375 { 1376 ps_sps->pi2_scaling_mat = pi2_scaling_mat; 1377 pi2_scaling_mat += scaling_mat_size; 1378 ps_sps++; 1379 } 1380 1381 for(i = 0; i < MAX_PPS_CNT; i++) 1382 { 1383 ps_pps->pi2_scaling_mat = pi2_scaling_mat; 1384 pi2_scaling_mat += scaling_mat_size; 1385 ps_pps++; 1386 } 1387 } 1388 1389 return (status); 1390} 1391 1392/** 1393******************************************************************************* 1394* 1395* @brief 1396* Free static memory for the codec 1397* 1398* @par Description: 1399* Free static memory for the codec 1400* 1401* @param[in] ps_codec 1402* Pointer to codec context 1403* 1404* @returns Status 1405* 1406* @remarks 1407* 1408* 1409******************************************************************************* 1410*/ 1411WORD32 ihevcd_free_static_bufs(iv_obj_t *ps_codec_obj) 1412{ 1413 codec_t *ps_codec; 1414 1415 void (*pf_aligned_free)(void *pv_mem_ctxt, void *pv_buf); 1416 void *pv_mem_ctxt; 1417 1418 ps_codec = (codec_t *)ps_codec_obj->pv_codec_handle; 1419 pf_aligned_free = ps_codec->pf_aligned_free; 1420 pv_mem_ctxt = ps_codec->pv_mem_ctxt; 1421 1422 1423 ALIGNED_FREE(ps_codec, ps_codec->apv_process_thread_handle[0]); 1424 ALIGNED_FREE(ps_codec, ps_codec->pu1_bitsbuf_static); 1425 1426 ALIGNED_FREE(ps_codec, ps_codec->pv_disp_buf_mgr); 1427 ALIGNED_FREE(ps_codec, ps_codec->pv_dpb_mgr); 1428 ALIGNED_FREE(ps_codec, ps_codec->pv_pic_buf_mgr); 1429 ALIGNED_FREE(ps_codec, ps_codec->pv_mv_buf_mgr); 1430 ALIGNED_FREE(ps_codec, ps_codec->ps_vps_base); 1431 ALIGNED_FREE(ps_codec, ps_codec->ps_sps_base); 1432 ALIGNED_FREE(ps_codec, ps_codec->ps_pps_base); 1433 ALIGNED_FREE(ps_codec, ps_codec->ps_slice_hdr_base); 1434 ALIGNED_FREE(ps_codec, ps_codec->pi2_scaling_mat); 1435 ALIGNED_FREE(ps_codec, ps_codec->pv_pic_buf_base); 1436 ALIGNED_FREE(ps_codec, ps_codec->s_parse.pu1_luma_intra_pred_mode_left); 1437 ALIGNED_FREE(ps_codec, ps_codec->as_process[0].s_sao_ctxt.pu1_tmp_buf_luma); 1438 ALIGNED_FREE(ps_codec, ps_codec->as_process[0].pi2_inter_pred_tmp_buf1); 1439 ALIGNED_FREE(ps_codec, ps_codec_obj->pv_codec_handle); 1440 1441 if(ps_codec_obj) 1442 { 1443 pf_aligned_free(pv_mem_ctxt, ps_codec_obj); 1444 } 1445 1446 return IV_SUCCESS; 1447 1448} 1449 1450 1451/** 1452******************************************************************************* 1453* 1454* @brief 1455* Allocate dynamic memory for the codec 1456* 1457* @par Description: 1458* Allocates dynamic memory for the codec 1459* 1460* @param[in] ps_codec 1461* Pointer to codec context 1462* 1463* @returns Status 1464* 1465* @remarks 1466* 1467* 1468******************************************************************************* 1469*/ 1470WORD32 ihevcd_allocate_dynamic_bufs(codec_t *ps_codec) 1471{ 1472 WORD32 max_tile_cols, max_tile_rows; 1473 WORD32 max_ctb_rows, max_ctb_cols; 1474 WORD32 max_num_cu_cols; 1475 WORD32 max_num_cu_rows; 1476 WORD32 max_num_4x4_cols; 1477 WORD32 max_ctb_cnt; 1478 WORD32 wd; 1479 WORD32 ht; 1480 WORD32 i; 1481 WORD32 max_dpb_size; 1482 void *pv_mem_ctxt = ps_codec->pv_mem_ctxt; 1483 void *pv_buf; 1484 UWORD8 *pu1_buf; 1485 WORD32 size; 1486 1487 wd = ALIGN64(ps_codec->i4_wd); 1488 ht = ALIGN64(ps_codec->i4_ht); 1489 1490 max_tile_cols = (wd + MIN_TILE_WD - 1) / MIN_TILE_WD; 1491 max_tile_rows = (ht + MIN_TILE_HT - 1) / MIN_TILE_HT; 1492 max_ctb_rows = ht / MIN_CTB_SIZE; 1493 max_ctb_cols = wd / MIN_CTB_SIZE; 1494 max_ctb_cnt = max_ctb_rows * max_ctb_cols; 1495 max_num_cu_cols = wd / MIN_CU_SIZE; 1496 max_num_cu_rows = ht / MIN_CU_SIZE; 1497 max_num_4x4_cols = wd / 4; 1498 1499 /* Allocate tile structures */ 1500 size = max_tile_cols * max_tile_rows; 1501 size *= sizeof(tile_t); 1502 size *= MAX_PPS_CNT; 1503 1504 pv_buf = ps_codec->pf_aligned_alloc(pv_mem_ctxt, 128, size); 1505 RETURN_IF((NULL == pv_buf), IV_FAIL); 1506 memset(pv_buf, 0, size); 1507 ps_codec->ps_tile = (tile_t *)pv_buf; 1508 1509 1510 /* Allocate memory to hold entry point offsets */ 1511 /* One entry point per tile */ 1512 size = max_tile_cols * max_tile_rows; 1513 1514 /* One entry point per row of CTBs */ 1515 /*********************************************************************/ 1516 /* Only tiles or entropy sync is enabled at a time in main */ 1517 /* profile, but since memory required does not increase too much, */ 1518 /* this allocation is done to handle both cases */ 1519 /*********************************************************************/ 1520 size += max_ctb_rows; 1521 size *= sizeof(WORD32); 1522 1523 pv_buf = ps_codec->pf_aligned_alloc(pv_mem_ctxt, 128, size); 1524 RETURN_IF((NULL == pv_buf), IV_FAIL); 1525 memset(pv_buf, 0, size); 1526 ps_codec->pi4_entry_ofst = (WORD32 *)pv_buf; 1527 1528 /* Allocate parse skip flag buffer */ 1529 /* 1 bit per 8x8 */ 1530 size = max_num_cu_cols / 8; 1531 size = ALIGN4(size); 1532 pv_buf = ps_codec->pf_aligned_alloc(pv_mem_ctxt, 128, size); 1533 RETURN_IF((NULL == pv_buf), IV_FAIL); 1534 memset(pv_buf, 0, size); 1535 ps_codec->s_parse.pu4_skip_cu_top = (UWORD32 *)pv_buf; 1536 1537 /* Allocate parse coding tree depth buffer */ 1538 /* 2 bits per 8x8 */ 1539 size = max_num_cu_cols / 4; 1540 size = ALIGN4(size); 1541 pv_buf = ps_codec->pf_aligned_alloc(pv_mem_ctxt, 128, size); 1542 RETURN_IF((NULL == pv_buf), IV_FAIL); 1543 memset(pv_buf, 0, size); 1544 ps_codec->s_parse.pu4_ct_depth_top = (UWORD32 *)pv_buf; 1545 1546 /* Allocate intra flag buffer */ 1547 /* 1 bit per 8x8 */ 1548 size = max_num_cu_cols * max_num_cu_rows / 8; 1549 size = ALIGN4(size); 1550 pv_buf = ps_codec->pf_aligned_alloc(pv_mem_ctxt, 128, size); 1551 RETURN_IF((NULL == pv_buf), IV_FAIL); 1552 memset(pv_buf, 0, size); 1553 ps_codec->pu1_pic_intra_flag = (UWORD8 *)pv_buf; 1554 ps_codec->s_parse.pu1_pic_intra_flag = ps_codec->pu1_pic_intra_flag; 1555 1556 /* Allocate transquant bypass flag buffer */ 1557 /* 1 bit per 8x8 */ 1558 /* Extra row and column are allocated for easy processing of top and left blocks while loop filtering */ 1559 size = ((max_num_cu_cols + 8) * (max_num_cu_rows + 8)) / 8; 1560 size = ALIGN4(size); 1561 pv_buf = ps_codec->pf_aligned_alloc(pv_mem_ctxt, 128, size); 1562 RETURN_IF((NULL == pv_buf), IV_FAIL); 1563 memset(pv_buf, 1, size); 1564 { 1565 WORD32 loop_filter_strd = (wd + 63) >> 6; 1566 ps_codec->pu1_pic_no_loop_filter_flag_base = pv_buf; 1567 /* The offset is added for easy processing of top and left blocks while loop filtering */ 1568 ps_codec->pu1_pic_no_loop_filter_flag = (UWORD8 *)pv_buf + loop_filter_strd + 1; 1569 ps_codec->s_parse.pu1_pic_no_loop_filter_flag = ps_codec->pu1_pic_no_loop_filter_flag; 1570 ps_codec->s_parse.s_deblk_ctxt.pu1_pic_no_loop_filter_flag = ps_codec->pu1_pic_no_loop_filter_flag; 1571 ps_codec->s_parse.s_sao_ctxt.pu1_pic_no_loop_filter_flag = ps_codec->pu1_pic_no_loop_filter_flag; 1572 } 1573 1574 /* Initialize pointers in PPS structures */ 1575 { 1576 pps_t *ps_pps = ps_codec->ps_pps_base; 1577 tile_t *ps_tile = ps_codec->ps_tile; 1578 1579 for(i = 0; i < MAX_PPS_CNT; i++) 1580 { 1581 ps_pps->ps_tile = ps_tile; 1582 ps_tile += (max_tile_cols * max_tile_rows); 1583 ps_pps++; 1584 } 1585 1586 } 1587 1588 /* Allocate memory for job queue */ 1589 1590 /* One job per row of CTBs */ 1591 size = max_ctb_rows; 1592 1593 /* One each tile a row of CTBs, num_jobs has to incremented */ 1594 size *= max_tile_cols; 1595 1596 /* One format convert/frame copy job per row of CTBs for non-shared mode*/ 1597 size += max_ctb_rows; 1598 1599 size *= sizeof(proc_job_t); 1600 1601 size += ihevcd_jobq_ctxt_size(); 1602 size = ALIGN4(size); 1603 1604 pv_buf = ps_codec->pf_aligned_alloc(pv_mem_ctxt, 128, size); 1605 RETURN_IF((NULL == pv_buf), IV_FAIL); 1606 ps_codec->pv_proc_jobq_buf = pv_buf; 1607 ps_codec->i4_proc_jobq_buf_size = size; 1608 1609 size = max_ctb_cnt; 1610 size = ALIGN4(size); 1611 pv_buf = ps_codec->pf_aligned_alloc(pv_mem_ctxt, 128, size); 1612 RETURN_IF((NULL == pv_buf), IV_FAIL); 1613 memset(pv_buf, 0, size); 1614 ps_codec->pu1_parse_map = (UWORD8 *)pv_buf; 1615 1616 size = max_ctb_cnt; 1617 size = ALIGN4(size); 1618 pv_buf = ps_codec->pf_aligned_alloc(pv_mem_ctxt, 128, size); 1619 RETURN_IF((NULL == pv_buf), IV_FAIL); 1620 memset(pv_buf, 0, size); 1621 ps_codec->pu1_proc_map = (UWORD8 *)pv_buf; 1622 1623 /** Holds top and left neighbor's pu idx into picture level pu array */ 1624 /* Only one top row is enough but left has to be replicated for each process context */ 1625 size = (max_num_4x4_cols /* left */ + MAX_PROCESS_THREADS * (MAX_CTB_SIZE / 4)/* top */ + 1/* top right */) * sizeof(WORD32); 1626 size = ALIGN4(size); 1627 pv_buf = ps_codec->pf_aligned_alloc(pv_mem_ctxt, 128, size); 1628 RETURN_IF((NULL == pv_buf), IV_FAIL); 1629 memset(pv_buf, 0, size); 1630 1631 for(i = 0; i < MAX_PROCESS_THREADS; i++) 1632 { 1633 UWORD32 *pu4_buf = (UWORD32 *)pv_buf; 1634 ps_codec->as_process[i].pu4_pic_pu_idx_left = pu4_buf + i * (MAX_CTB_SIZE / 4); 1635 memset(ps_codec->as_process[i].pu4_pic_pu_idx_left, 0, sizeof(UWORD32) * MAX_CTB_SIZE / 4); 1636 ps_codec->as_process[i].pu4_pic_pu_idx_top = pu4_buf + MAX_PROCESS_THREADS * (MAX_CTB_SIZE / 4); 1637 } 1638 memset(ps_codec->as_process[0].pu4_pic_pu_idx_top, 0, sizeof(UWORD32) * (wd / 4 + 1)); 1639 1640 { 1641 /* To hold SAO left buffer for luma */ 1642 size = sizeof(UWORD8) * (MAX(ht, wd)); 1643 1644 /* To hold SAO left buffer for chroma */ 1645 size += sizeof(UWORD8) * (MAX(ht, wd)); 1646 1647 /* To hold SAO top buffer for luma */ 1648 size += sizeof(UWORD8) * wd; 1649 1650 /* To hold SAO top buffer for chroma */ 1651 size += sizeof(UWORD8) * wd; 1652 1653 /* To hold SAO top left luma pixel value for last output ctb in a row*/ 1654 size += sizeof(UWORD8) * max_ctb_rows; 1655 1656 /* To hold SAO top left chroma pixel value last output ctb in a row*/ 1657 size += sizeof(UWORD8) * max_ctb_rows * 2; 1658 1659 /* To hold SAO top left pixel luma for current ctb - column array*/ 1660 size += sizeof(UWORD8) * max_ctb_rows; 1661 1662 /* To hold SAO top left pixel chroma for current ctb-column array*/ 1663 size += sizeof(UWORD8) * max_ctb_rows * 2; 1664 1665 /* To hold SAO top right pixel luma pixel value last output ctb in a row*/ 1666 size += sizeof(UWORD8) * max_ctb_cols; 1667 1668 /* To hold SAO top right pixel chroma pixel value last output ctb in a row*/ 1669 size += sizeof(UWORD8) * max_ctb_cols * 2; 1670 1671 /*To hold SAO botton bottom left pixels for luma*/ 1672 size += sizeof(UWORD8) * max_ctb_rows; 1673 1674 /*To hold SAO botton bottom left pixels for luma*/ 1675 size += sizeof(UWORD8) * max_ctb_rows * 2; 1676 size = ALIGN64(size); 1677 1678 pu1_buf = ps_codec->pf_aligned_alloc(pv_mem_ctxt, 128, size); 1679 RETURN_IF((NULL == pu1_buf), IV_FAIL); 1680 memset(pu1_buf, 0, size); 1681 1682 for(i = 0; i < MAX_PROCESS_THREADS; i++) 1683 { 1684 ps_codec->as_process[i].s_sao_ctxt.pu1_sao_src_left_luma = (UWORD8 *)pu1_buf; 1685 } 1686 ps_codec->s_parse.s_sao_ctxt.pu1_sao_src_left_luma = (UWORD8 *)pu1_buf; 1687 pu1_buf += MAX(ht, wd); 1688 1689 for(i = 0; i < MAX_PROCESS_THREADS; i++) 1690 { 1691 ps_codec->as_process[i].s_sao_ctxt.pu1_sao_src_left_chroma = (UWORD8 *)pu1_buf; 1692 } 1693 ps_codec->s_parse.s_sao_ctxt.pu1_sao_src_left_chroma = (UWORD8 *)pu1_buf; 1694 pu1_buf += MAX(ht, wd); 1695 for(i = 0; i < MAX_PROCESS_THREADS; i++) 1696 { 1697 ps_codec->as_process[i].s_sao_ctxt.pu1_sao_src_top_luma = (UWORD8 *)pu1_buf; 1698 } 1699 ps_codec->s_parse.s_sao_ctxt.pu1_sao_src_top_luma = (UWORD8 *)pu1_buf; 1700 pu1_buf += wd; 1701 1702 for(i = 0; i < MAX_PROCESS_THREADS; i++) 1703 { 1704 ps_codec->as_process[i].s_sao_ctxt.pu1_sao_src_top_chroma = (UWORD8 *)pu1_buf; 1705 } 1706 ps_codec->s_parse.s_sao_ctxt.pu1_sao_src_top_chroma = (UWORD8 *)pu1_buf; 1707 pu1_buf += wd; 1708 for(i = 0; i < MAX_PROCESS_THREADS; i++) 1709 { 1710 ps_codec->as_process[i].s_sao_ctxt.pu1_sao_src_luma_top_left_ctb = (UWORD8 *)pu1_buf; 1711 } 1712 ps_codec->s_parse.s_sao_ctxt.pu1_sao_src_luma_top_left_ctb = (UWORD8 *)pu1_buf; 1713 pu1_buf += ht / MIN_CTB_SIZE; 1714 1715 for(i = 0; i < MAX_PROCESS_THREADS; i++) 1716 { 1717 ps_codec->as_process[i].s_sao_ctxt.pu1_sao_src_chroma_top_left_ctb = (UWORD8 *)pu1_buf; 1718 } 1719 ps_codec->s_parse.s_sao_ctxt.pu1_sao_src_chroma_top_left_ctb = (UWORD8 *)pu1_buf; 1720 pu1_buf += (ht / MIN_CTB_SIZE) * 2; 1721 1722 for(i = 0; i < MAX_PROCESS_THREADS; i++) 1723 { 1724 ps_codec->as_process[i].s_sao_ctxt.pu1_sao_src_top_left_luma_curr_ctb = (UWORD8 *)pu1_buf; 1725 } 1726 ps_codec->s_parse.s_sao_ctxt.pu1_sao_src_top_left_luma_curr_ctb = (UWORD8 *)pu1_buf; 1727 pu1_buf += ht / MIN_CTB_SIZE; 1728 1729 for(i = 0; i < MAX_PROCESS_THREADS; i++) 1730 { 1731 ps_codec->as_process[i].s_sao_ctxt.pu1_sao_src_top_left_chroma_curr_ctb = (UWORD8 *)pu1_buf; 1732 } 1733 ps_codec->s_parse.s_sao_ctxt.pu1_sao_src_top_left_chroma_curr_ctb = (UWORD8 *)pu1_buf; 1734 1735 pu1_buf += (ht / MIN_CTB_SIZE) * 2; 1736 for(i = 0; i < MAX_PROCESS_THREADS; i++) 1737 { 1738 ps_codec->as_process[i].s_sao_ctxt.pu1_sao_src_top_left_luma_top_right = (UWORD8 *)pu1_buf; 1739 } 1740 ps_codec->s_parse.s_sao_ctxt.pu1_sao_src_top_left_luma_top_right = (UWORD8 *)pu1_buf; 1741 1742 pu1_buf += wd / MIN_CTB_SIZE; 1743 for(i = 0; i < MAX_PROCESS_THREADS; i++) 1744 { 1745 ps_codec->as_process[i].s_sao_ctxt.pu1_sao_src_top_left_chroma_top_right = (UWORD8 *)pu1_buf; 1746 } 1747 ps_codec->s_parse.s_sao_ctxt.pu1_sao_src_top_left_chroma_top_right = (UWORD8 *)pu1_buf; 1748 1749 pu1_buf += (wd / MIN_CTB_SIZE) * 2; 1750 1751 /*Per CTB, Store 1 value for luma , 2 values for chroma*/ 1752 for(i = 0; i < MAX_PROCESS_THREADS; i++) 1753 { 1754 ps_codec->as_process[i].s_sao_ctxt.pu1_sao_src_top_left_luma_bot_left = (UWORD8 *)pu1_buf; 1755 } 1756 ps_codec->s_parse.s_sao_ctxt.pu1_sao_src_top_left_luma_bot_left = (UWORD8 *)pu1_buf; 1757 1758 pu1_buf += (ht / MIN_CTB_SIZE); 1759 1760 for(i = 0; i < MAX_PROCESS_THREADS; i++) 1761 { 1762 ps_codec->as_process[i].s_sao_ctxt.pu1_sao_src_top_left_chroma_bot_left = (UWORD8 *)pu1_buf; 1763 } 1764 ps_codec->s_parse.s_sao_ctxt.pu1_sao_src_top_left_chroma_bot_left = (UWORD8 *)pu1_buf; 1765 1766 pu1_buf += (ht / MIN_CTB_SIZE) * 2; 1767 } 1768 1769 1770 { 1771 UWORD8 *pu1_buf = (UWORD8 *)pv_buf; 1772 WORD32 vert_bs_size, horz_bs_size; 1773 WORD32 qp_const_flag_size; 1774 WORD32 qp_size; 1775 WORD32 num_8x8; 1776 1777 /* Max Number of vertical edges */ 1778 vert_bs_size = wd / 8 + 2 * MAX_CTB_SIZE / 8; 1779 1780 /* Max Number of horizontal edges - extra MAX_CTB_SIZE / 8 to handle the last 4 rows separately(shifted CTB processing) */ 1781 vert_bs_size *= (ht + MAX_CTB_SIZE) / MIN_TU_SIZE; 1782 1783 /* Number of bytes */ 1784 vert_bs_size /= 8; 1785 1786 /* Two bits per edge */ 1787 vert_bs_size *= 2; 1788 1789 /* Max Number of horizontal edges */ 1790 horz_bs_size = ht / 8 + MAX_CTB_SIZE / 8; 1791 1792 /* Max Number of vertical edges - extra MAX_CTB_SIZE / 8 to handle the last 4 columns separately(shifted CTB processing) */ 1793 horz_bs_size *= (wd + MAX_CTB_SIZE) / MIN_TU_SIZE; 1794 1795 /* Number of bytes */ 1796 horz_bs_size /= 8; 1797 1798 /* Two bits per edge */ 1799 horz_bs_size *= 2; 1800 1801 /* Max CTBs in a row */ 1802 qp_const_flag_size = wd / MIN_CTB_SIZE + 1 /* The last ctb row deblk is done in last ctb + 1 row.*/; 1803 1804 /* Max CTBs in a column */ 1805 qp_const_flag_size *= ht / MIN_CTB_SIZE; 1806 1807 /* Number of bytes */ 1808 qp_const_flag_size /= 8; 1809 1810 /* QP changes at CU level - So store at 8x8 level */ 1811 num_8x8 = (ht * wd) / (MIN_CU_SIZE * MIN_CU_SIZE); 1812 qp_size = num_8x8; 1813 1814 /* To hold vertical boundary strength */ 1815 size += vert_bs_size; 1816 1817 /* To hold horizontal boundary strength */ 1818 size += horz_bs_size; 1819 1820 /* To hold QP */ 1821 size += qp_size; 1822 1823 /* To hold QP const in CTB flags */ 1824 size += qp_const_flag_size; 1825 1826 pu1_buf = ps_codec->pf_aligned_alloc(pv_mem_ctxt, 128, size); 1827 RETURN_IF((NULL == pu1_buf), IV_FAIL); 1828 1829 memset(pu1_buf, 0, size); 1830 1831 for(i = 0; i < MAX_PROCESS_THREADS; i++) 1832 { 1833 ps_codec->as_process[i].s_bs_ctxt.pu4_pic_vert_bs = (UWORD32 *)pu1_buf; 1834 ps_codec->as_process[i].s_deblk_ctxt.s_bs_ctxt.pu4_pic_vert_bs = (UWORD32 *)pu1_buf; 1835 ps_codec->s_parse.s_deblk_ctxt.s_bs_ctxt.pu4_pic_vert_bs = (UWORD32 *)pu1_buf; 1836 pu1_buf += vert_bs_size; 1837 1838 ps_codec->as_process[i].s_bs_ctxt.pu4_pic_horz_bs = (UWORD32 *)pu1_buf; 1839 ps_codec->as_process[i].s_deblk_ctxt.s_bs_ctxt.pu4_pic_horz_bs = (UWORD32 *)pu1_buf; 1840 ps_codec->s_parse.s_deblk_ctxt.s_bs_ctxt.pu4_pic_horz_bs = (UWORD32 *)pu1_buf; 1841 pu1_buf += horz_bs_size; 1842 1843 ps_codec->as_process[i].s_bs_ctxt.pu1_pic_qp = (UWORD8 *)pu1_buf; 1844 ps_codec->as_process[i].s_deblk_ctxt.s_bs_ctxt.pu1_pic_qp = (UWORD8 *)pu1_buf; 1845 ps_codec->s_parse.s_deblk_ctxt.s_bs_ctxt.pu1_pic_qp = (UWORD8 *)pu1_buf; 1846 pu1_buf += qp_size; 1847 1848 ps_codec->as_process[i].s_bs_ctxt.pu1_pic_qp_const_in_ctb = (UWORD8 *)pu1_buf; 1849 ps_codec->as_process[i].s_deblk_ctxt.s_bs_ctxt.pu1_pic_qp_const_in_ctb = (UWORD8 *)pu1_buf; 1850 ps_codec->s_parse.s_deblk_ctxt.s_bs_ctxt.pu1_pic_qp_const_in_ctb = (UWORD8 *)pu1_buf; 1851 pu1_buf += qp_const_flag_size; 1852 1853 pu1_buf -= (vert_bs_size + horz_bs_size + qp_size + qp_const_flag_size); 1854 } 1855 ps_codec->s_parse.s_bs_ctxt.pu4_pic_vert_bs = (UWORD32 *)pu1_buf; 1856 pu1_buf += vert_bs_size; 1857 1858 ps_codec->s_parse.s_bs_ctxt.pu4_pic_horz_bs = (UWORD32 *)pu1_buf; 1859 pu1_buf += horz_bs_size; 1860 1861 ps_codec->s_parse.s_bs_ctxt.pu1_pic_qp = (UWORD8 *)pu1_buf; 1862 pu1_buf += qp_size; 1863 1864 ps_codec->s_parse.s_bs_ctxt.pu1_pic_qp_const_in_ctb = (UWORD8 *)pu1_buf; 1865 pu1_buf += qp_const_flag_size; 1866 1867 } 1868 1869 /* Max CTBs in a row */ 1870 size = wd / MIN_CTB_SIZE; 1871 /* Max CTBs in a column */ 1872 size *= (ht / MIN_CTB_SIZE + 2) /* Top row and bottom row extra. This ensures accessing left,top in first row 1873 and right in last row will not result in invalid access*/; 1874 1875 size *= sizeof(UWORD16); 1876 pv_buf = ps_codec->pf_aligned_alloc(pv_mem_ctxt, 128, size); 1877 RETURN_IF((NULL == pv_buf), IV_FAIL); 1878 memset(pv_buf, 0, size); 1879 1880 ps_codec->pu1_tile_idx_base = pv_buf; 1881 for(i = 0; i < MAX_PROCESS_THREADS; i++) 1882 { 1883 ps_codec->as_process[i].pu1_tile_idx = (UWORD16 *)pv_buf + wd / MIN_CTB_SIZE /* Offset 1 row */; 1884 } 1885 1886 /* 4 bytes per color component per CTB */ 1887 size = 3 * 4; 1888 1889 /* MAX number of CTBs in a row */ 1890 size *= wd / MIN_CTB_SIZE; 1891 1892 /* MAX number of CTBs in a column */ 1893 size *= ht / MIN_CTB_SIZE; 1894 pv_buf = ps_codec->pf_aligned_alloc(pv_mem_ctxt, 128, size); 1895 RETURN_IF((NULL == pv_buf), IV_FAIL); 1896 memset(pv_buf, 0, size); 1897 1898 ps_codec->s_parse.ps_pic_sao = (sao_t *)pv_buf; 1899 ps_codec->s_parse.s_sao_ctxt.ps_pic_sao = (sao_t *)pv_buf; 1900 for(i = 0; i < MAX_PROCESS_THREADS; i++) 1901 { 1902 ps_codec->as_process[i].s_sao_ctxt.ps_pic_sao = ps_codec->s_parse.ps_pic_sao; 1903 } 1904 1905 /* Only if width * height * 3 / 2 is greater than MIN_BITSBUF_SIZE, 1906 then allocate dynamic bistream buffer */ 1907 ps_codec->pu1_bitsbuf_dynamic = NULL; 1908 size = wd * ht; 1909 if(size > MIN_BITSBUF_SIZE) 1910 { 1911 pv_buf = ps_codec->pf_aligned_alloc(pv_mem_ctxt, 128, size + 16); //Alloc extra for parse optimization 1912 RETURN_IF((NULL == pv_buf), IV_FAIL); 1913 ps_codec->pu1_bitsbuf_dynamic = pv_buf; 1914 ps_codec->u4_bitsbuf_size_dynamic = size; 1915 } 1916 1917 size = ihevcd_get_tu_data_size(wd * ht); 1918 pv_buf = ps_codec->pf_aligned_alloc(pv_mem_ctxt, 128, size); 1919 RETURN_IF((NULL == pv_buf), IV_FAIL); 1920 ps_codec->pv_tu_data = pv_buf; 1921 1922 { 1923 sps_t *ps_sps = (ps_codec->s_parse.ps_sps_base + ps_codec->i4_sps_id); 1924 1925 1926 /* Allocate for pu_map, pu_t and pic_pu_idx for each MV bank */ 1927 /* Note: Number of luma samples is not max_wd * max_ht here, instead it is 1928 * set to maximum number of luma samples allowed at the given level. 1929 * This is done to ensure that any stream with width and height lesser 1930 * than max_wd and max_ht is supported. Number of buffers required can be greater 1931 * for lower width and heights at a given level and this increased number of buffers 1932 * might require more memory than what max_wd and max_ht buffer would have required 1933 * Also note one extra buffer is allocted to store current pictures MV bank 1934 * In case of asynchronous parsing and processing, number of buffers should increase here 1935 * based on when parsing and processing threads are synchronized 1936 */ 1937 max_dpb_size = ps_sps->ai1_sps_max_dec_pic_buffering[ps_sps->i1_sps_max_sub_layers - 1]; 1938 /* Size for holding mv_buf_t for each MV Bank 1939 * One extra MV Bank is needed to hold current pics MV bank. 1940 */ 1941 size = (max_dpb_size + 1) * sizeof(mv_buf_t); 1942 1943 size += (max_dpb_size + 1) * 1944 ihevcd_get_pic_mv_bank_size(wd * ht); 1945 1946 pv_buf = ps_codec->pf_aligned_alloc(pv_mem_ctxt, 128, size); 1947 RETURN_IF((NULL == pv_buf), IV_FAIL); 1948 1949 ps_codec->pv_mv_bank_buf_base = pv_buf; 1950 ps_codec->i4_total_mv_bank_size = size; 1951 1952 } 1953 1954 /* In case of non-shared mode allocate for reference picture buffers */ 1955 /* In case of shared and 420p output, allocate for chroma samples */ 1956 if(0 == ps_codec->i4_share_disp_buf) 1957 { 1958 /* Number of buffers is doubled in order to return one frame at a time instead of sending 1959 * multiple outputs during dpb full case. 1960 * Also note one extra buffer is allocted to store current picture 1961 * In case of asynchronous parsing and processing, number of buffers should increase here 1962 * based on when parsing and processing threads are synchronized 1963 */ 1964 size = ihevcd_get_total_pic_buf_size(ps_codec, wd, ht); 1965 pv_buf = ps_codec->pf_aligned_alloc(pv_mem_ctxt, 128, size); 1966 RETURN_IF((NULL == pv_buf), IV_FAIL); 1967 1968 1969 ps_codec->i4_total_pic_buf_size = size; 1970 ps_codec->pu1_ref_pic_buf_base = (UWORD8 *)pv_buf; 1971 } 1972 1973 ps_codec->pv_proc_jobq = ihevcd_jobq_init(ps_codec->pv_proc_jobq_buf, ps_codec->i4_proc_jobq_buf_size); 1974 RETURN_IF((ps_codec->pv_proc_jobq == NULL), IV_FAIL); 1975 1976 /* Update the jobq context to all the threads */ 1977 ps_codec->s_parse.pv_proc_jobq = ps_codec->pv_proc_jobq; 1978 for(i = 0; i < MAX_PROCESS_THREADS; i++) 1979 { 1980 ps_codec->as_process[i].pv_proc_jobq = ps_codec->pv_proc_jobq; 1981 ps_codec->as_process[i].i4_id = i; 1982 ps_codec->as_process[i].ps_codec = ps_codec; 1983 1984 /* Set the following to zero assuming it is a single core solution 1985 * When threads are launched these will be set appropriately 1986 */ 1987 ps_codec->as_process[i].i4_check_parse_status = 0; 1988 ps_codec->as_process[i].i4_check_proc_status = 0; 1989 } 1990 1991 ps_codec->u4_allocate_dynamic_done = 1; 1992 1993 return IV_SUCCESS; 1994} 1995 1996/** 1997******************************************************************************* 1998* 1999* @brief 2000* Free dynamic memory for the codec 2001* 2002* @par Description: 2003* Free dynamic memory for the codec 2004* 2005* @param[in] ps_codec 2006* Pointer to codec context 2007* 2008* @returns Status 2009* 2010* @remarks 2011* 2012* 2013******************************************************************************* 2014*/ 2015WORD32 ihevcd_free_dynamic_bufs(codec_t *ps_codec) 2016{ 2017 2018 if(ps_codec->pv_proc_jobq) 2019 { 2020 ihevcd_jobq_deinit(ps_codec->pv_proc_jobq); 2021 ps_codec->pv_proc_jobq = NULL; 2022 } 2023 2024 ALIGNED_FREE(ps_codec, ps_codec->ps_tile); 2025 ALIGNED_FREE(ps_codec, ps_codec->pi4_entry_ofst); 2026 ALIGNED_FREE(ps_codec, ps_codec->s_parse.pu4_skip_cu_top); 2027 ALIGNED_FREE(ps_codec, ps_codec->s_parse.pu4_ct_depth_top); 2028 ALIGNED_FREE(ps_codec, ps_codec->pu1_pic_intra_flag); 2029 ALIGNED_FREE(ps_codec, ps_codec->pu1_pic_no_loop_filter_flag_base); 2030 ALIGNED_FREE(ps_codec, ps_codec->pv_proc_jobq_buf); 2031 ALIGNED_FREE(ps_codec, ps_codec->pu1_parse_map); 2032 ALIGNED_FREE(ps_codec, ps_codec->pu1_proc_map); 2033 ALIGNED_FREE(ps_codec, ps_codec->as_process[0].pu4_pic_pu_idx_left); 2034 ALIGNED_FREE(ps_codec, ps_codec->as_process[0].s_sao_ctxt.pu1_sao_src_left_luma); 2035 ALIGNED_FREE(ps_codec, ps_codec->as_process[0].s_bs_ctxt.pu4_pic_vert_bs); 2036 ALIGNED_FREE(ps_codec, ps_codec->pu1_tile_idx_base); 2037 ALIGNED_FREE(ps_codec, ps_codec->s_parse.ps_pic_sao); 2038 ALIGNED_FREE(ps_codec, ps_codec->pu1_bitsbuf_dynamic); 2039 ALIGNED_FREE(ps_codec, ps_codec->pv_tu_data); 2040 ALIGNED_FREE(ps_codec, ps_codec->pv_mv_bank_buf_base); 2041 ALIGNED_FREE(ps_codec, ps_codec->pu1_ref_pic_buf_base); 2042 ALIGNED_FREE(ps_codec, ps_codec->pu1_cur_chroma_ref_buf); 2043 2044 ps_codec->u4_allocate_dynamic_done = 0; 2045 return IV_SUCCESS; 2046} 2047 2048 2049/** 2050******************************************************************************* 2051* 2052* @brief 2053* Initializes from mem records passed to the codec 2054* 2055* @par Description: 2056* Initializes pointers based on mem records passed 2057* 2058* @param[in] ps_codec_obj 2059* Pointer to codec object at API level 2060* 2061* @param[in] pv_api_ip 2062* Pointer to input argument structure 2063* 2064* @param[out] pv_api_op 2065* Pointer to output argument structure 2066* 2067* @returns Status 2068* 2069* @remarks 2070* 2071* 2072******************************************************************************* 2073*/ 2074WORD32 ihevcd_create(iv_obj_t *ps_codec_obj, 2075 void *pv_api_ip, 2076 void *pv_api_op) 2077{ 2078 2079 ihevcd_cxa_create_op_t *ps_create_op; 2080 2081 WORD32 ret; 2082 codec_t *ps_codec; 2083 ps_create_op = (ihevcd_cxa_create_op_t *)pv_api_op; 2084 2085 ps_create_op->s_ivd_create_op_t.u4_error_code = 0; 2086 2087 ret = ihevcd_allocate_static_bufs(&ps_codec_obj, pv_api_ip, pv_api_op); 2088 2089 /* If allocation of some buffer fails, then free buffers allocated till then */ 2090 if((IV_FAIL == ret) && (NULL != ps_codec_obj)) 2091 { 2092 ihevcd_free_static_bufs(ps_codec_obj); 2093 ps_create_op->s_ivd_create_op_t.u4_error_code = IVD_MEM_ALLOC_FAILED; 2094 ps_create_op->s_ivd_create_op_t.u4_error_code = 1 << IVD_FATALERROR; 2095 2096 return IV_FAIL; 2097 } 2098 ps_codec = (codec_t *)ps_codec_obj->pv_codec_handle; 2099 ret = ihevcd_init(ps_codec); 2100 2101 TRACE_INIT(NULL); 2102 STATS_INIT(); 2103 2104 return ret; 2105} 2106/** 2107******************************************************************************* 2108* 2109* @brief 2110* Delete codec 2111* 2112* @par Description: 2113* Delete codec 2114* 2115* @param[in] ps_codec_obj 2116* Pointer to codec object at API level 2117* 2118* @param[in] pv_api_ip 2119* Pointer to input argument structure 2120* 2121* @param[out] pv_api_op 2122* Pointer to output argument structure 2123* 2124* @returns Status 2125* 2126* @remarks 2127* 2128* 2129******************************************************************************* 2130*/ 2131WORD32 ihevcd_delete(iv_obj_t *ps_codec_obj, void *pv_api_ip, void *pv_api_op) 2132{ 2133 codec_t *ps_dec; 2134 ihevcd_cxa_delete_ip_t *ps_ip = (ihevcd_cxa_delete_ip_t *)pv_api_ip; 2135 ihevcd_cxa_delete_op_t *ps_op = (ihevcd_cxa_delete_op_t *)pv_api_op; 2136 2137 ps_dec = (codec_t *)(ps_codec_obj->pv_codec_handle); 2138 UNUSED(ps_ip); 2139 ps_op->s_ivd_delete_op_t.u4_error_code = 0; 2140 ihevcd_free_dynamic_bufs(ps_dec); 2141 ihevcd_free_static_bufs(ps_codec_obj); 2142 return IV_SUCCESS; 2143} 2144 2145 2146/** 2147******************************************************************************* 2148* 2149* @brief 2150* Passes display buffer from application to codec 2151* 2152* @par Description: 2153* Adds display buffer to the codec 2154* 2155* @param[in] ps_codec_obj 2156* Pointer to codec object at API level 2157* 2158* @param[in] pv_api_ip 2159* Pointer to input argument structure 2160* 2161* @param[out] pv_api_op 2162* Pointer to output argument structure 2163* 2164* @returns Status 2165* 2166* @remarks 2167* 2168* 2169******************************************************************************* 2170*/ 2171WORD32 ihevcd_set_display_frame(iv_obj_t *ps_codec_obj, 2172 void *pv_api_ip, 2173 void *pv_api_op) 2174{ 2175 WORD32 ret = IV_SUCCESS; 2176 2177 ivd_set_display_frame_ip_t *ps_dec_disp_ip; 2178 ivd_set_display_frame_op_t *ps_dec_disp_op; 2179 2180 WORD32 i; 2181 2182 codec_t *ps_codec = (codec_t *)(ps_codec_obj->pv_codec_handle); 2183 2184 ps_dec_disp_ip = (ivd_set_display_frame_ip_t *)pv_api_ip; 2185 ps_dec_disp_op = (ivd_set_display_frame_op_t *)pv_api_op; 2186 2187 ps_codec->i4_num_disp_bufs = 0; 2188 if(ps_codec->i4_share_disp_buf) 2189 { 2190 UWORD32 num_bufs = ps_dec_disp_ip->num_disp_bufs; 2191 pic_buf_t *ps_pic_buf; 2192 UWORD8 *pu1_buf; 2193 WORD32 buf_ret; 2194 2195 UWORD8 *pu1_chroma_buf = NULL; 2196 num_bufs = MIN(num_bufs, BUF_MGR_MAX_CNT); 2197 ps_codec->i4_num_disp_bufs = num_bufs; 2198 2199 ps_pic_buf = (pic_buf_t *)ps_codec->ps_pic_buf; 2200 2201 /* If color format is 420P, then allocate chroma buffers to hold semiplanar 2202 * chroma data */ 2203 if(ps_codec->e_chroma_fmt == IV_YUV_420P) 2204 { 2205 WORD32 num_samples = ps_dec_disp_ip->s_disp_buffer[0].u4_min_out_buf_size[1] << 1; 2206 WORD32 size = num_samples * num_bufs; 2207 void *pv_mem_ctxt = ps_codec->pv_mem_ctxt; 2208 2209 pu1_chroma_buf = ps_codec->pf_aligned_alloc(pv_mem_ctxt, 128, size); 2210 RETURN_IF((NULL == pu1_chroma_buf), IV_FAIL); 2211 2212 ps_codec->pu1_cur_chroma_ref_buf = pu1_chroma_buf; 2213 } 2214 for(i = 0; i < (WORD32)num_bufs; i++) 2215 { 2216 /* Stride is not available in some cases here. 2217 So store base pointers to buffer manager now, 2218 and update these pointers once header is decoded */ 2219 pu1_buf = ps_dec_disp_ip->s_disp_buffer[i].pu1_bufs[0]; 2220 ps_pic_buf->pu1_luma = pu1_buf; 2221 2222 if(ps_codec->e_chroma_fmt == IV_YUV_420P) 2223 { 2224 pu1_buf = pu1_chroma_buf; 2225 pu1_chroma_buf += ps_dec_disp_ip->s_disp_buffer[0].u4_min_out_buf_size[1] << 1; 2226 } 2227 else 2228 { 2229 /* For YUV 420SP case use display buffer itself as chroma ref buffer */ 2230 pu1_buf = ps_dec_disp_ip->s_disp_buffer[i].pu1_bufs[1]; 2231 } 2232 2233 ps_pic_buf->pu1_chroma = pu1_buf; 2234 2235 buf_ret = ihevc_buf_mgr_add((buf_mgr_t *)ps_codec->pv_pic_buf_mgr, ps_pic_buf, i); 2236 2237 if(0 != buf_ret) 2238 { 2239 ps_codec->i4_error_code = IHEVCD_BUF_MGR_ERROR; 2240 return IHEVCD_BUF_MGR_ERROR; 2241 } 2242 2243 /* Mark pic buf as needed for display */ 2244 /* This ensures that till the buffer is explicitly passed to the codec, 2245 * application owns the buffer. Decoder is allowed to use a buffer only 2246 * when application sends it through fill this buffer call in OMX 2247 */ 2248 ihevc_buf_mgr_set_status((buf_mgr_t *)ps_codec->pv_pic_buf_mgr, i, BUF_MGR_DISP); 2249 2250 ps_pic_buf++; 2251 2252 /* Store display buffers in codec context. Needed for 420p output */ 2253 memcpy(&ps_codec->s_disp_buffer[ps_codec->i4_share_disp_buf_cnt], 2254 &ps_dec_disp_ip->s_disp_buffer[i], 2255 sizeof(ps_dec_disp_ip->s_disp_buffer[i])); 2256 2257 ps_codec->i4_share_disp_buf_cnt++; 2258 2259 } 2260 } 2261 2262 ps_dec_disp_op->u4_error_code = 0; 2263 return ret; 2264 2265} 2266 2267/** 2268******************************************************************************* 2269* 2270* @brief 2271* Sets the decoder in flush mode. Decoder will come out of flush only 2272* after returning all the buffers or at reset 2273* 2274* @par Description: 2275* Sets the decoder in flush mode 2276* 2277* @param[in] ps_codec_obj 2278* Pointer to codec object at API level 2279* 2280* @param[in] pv_api_ip 2281* Pointer to input argument structure 2282* 2283* @param[out] pv_api_op 2284* Pointer to output argument structure 2285* 2286* @returns Status 2287* 2288* @remarks 2289* 2290* 2291******************************************************************************* 2292*/ 2293WORD32 ihevcd_set_flush_mode(iv_obj_t *ps_codec_obj, 2294 void *pv_api_ip, 2295 void *pv_api_op) 2296{ 2297 2298 codec_t *ps_codec; 2299 ivd_ctl_flush_op_t *ps_ctl_op = (ivd_ctl_flush_op_t *)pv_api_op; 2300 UNUSED(pv_api_ip); 2301 ps_codec = (codec_t *)(ps_codec_obj->pv_codec_handle); 2302 2303 /* Signal flush frame control call */ 2304 ps_codec->i4_flush_mode = 1; 2305 2306 ps_ctl_op->u4_error_code = 0; 2307 2308 /* Set pic count to zero, so that decoder starts buffering again */ 2309 /* once it comes out of flush mode */ 2310 ps_codec->u4_pic_cnt = 0; 2311 ps_codec->u4_disp_cnt = 0; 2312 return IV_SUCCESS; 2313 2314 2315} 2316 2317/** 2318******************************************************************************* 2319* 2320* @brief 2321* Gets decoder status and buffer requirements 2322* 2323* @par Description: 2324* Gets the decoder status 2325* 2326* @param[in] ps_codec_obj 2327* Pointer to codec object at API level 2328* 2329* @param[in] pv_api_ip 2330* Pointer to input argument structure 2331* 2332* @param[out] pv_api_op 2333* Pointer to output argument structure 2334* 2335* @returns Status 2336* 2337* @remarks 2338* 2339* 2340******************************************************************************* 2341*/ 2342 2343WORD32 ihevcd_get_status(iv_obj_t *ps_codec_obj, 2344 void *pv_api_ip, 2345 void *pv_api_op) 2346{ 2347 2348 WORD32 i; 2349 codec_t *ps_codec; 2350 WORD32 wd, ht; 2351 ivd_ctl_getstatus_op_t *ps_ctl_op = (ivd_ctl_getstatus_op_t *)pv_api_op; 2352 2353 UNUSED(pv_api_ip); 2354 2355 ps_ctl_op->u4_error_code = 0; 2356 2357 ps_codec = (codec_t *)(ps_codec_obj->pv_codec_handle); 2358 2359 ps_ctl_op->u4_min_num_in_bufs = MIN_IN_BUFS; 2360 if(ps_codec->e_chroma_fmt == IV_YUV_420P) 2361 ps_ctl_op->u4_min_num_out_bufs = MIN_OUT_BUFS_420; 2362 else if(ps_codec->e_chroma_fmt == IV_YUV_422ILE) 2363 ps_ctl_op->u4_min_num_out_bufs = MIN_OUT_BUFS_422ILE; 2364 else if(ps_codec->e_chroma_fmt == IV_RGB_565) 2365 ps_ctl_op->u4_min_num_out_bufs = MIN_OUT_BUFS_RGB565; 2366 else if(ps_codec->e_chroma_fmt == IV_RGBA_8888) 2367 ps_ctl_op->u4_min_num_out_bufs = MIN_OUT_BUFS_RGBA8888; 2368 else if((ps_codec->e_chroma_fmt == IV_YUV_420SP_UV) 2369 || (ps_codec->e_chroma_fmt == IV_YUV_420SP_VU)) 2370 ps_ctl_op->u4_min_num_out_bufs = MIN_OUT_BUFS_420SP; 2371 2372 ps_ctl_op->u4_num_disp_bufs = 1; 2373 2374 for(i = 0; i < (WORD32)ps_ctl_op->u4_min_num_in_bufs; i++) 2375 { 2376 wd = ALIGN64(ps_codec->i4_wd); 2377 ht = ALIGN64(ps_codec->i4_ht); 2378 ps_ctl_op->u4_min_in_buf_size[i] = MAX((wd * ht), MIN_BITSBUF_SIZE); 2379 } 2380 2381 wd = ps_codec->i4_wd; 2382 ht = ps_codec->i4_ht; 2383 2384 if(ps_codec->i4_sps_done) 2385 { 2386 if(0 == ps_codec->i4_share_disp_buf) 2387 { 2388 wd = ps_codec->i4_disp_wd; 2389 ht = ps_codec->i4_disp_ht; 2390 2391 } 2392 else 2393 { 2394 wd = ps_codec->i4_disp_strd; 2395 ht = ps_codec->i4_ht + PAD_HT; 2396 } 2397 } 2398 2399 if(ps_codec->i4_disp_strd > wd) 2400 wd = ps_codec->i4_disp_strd; 2401 2402 if(0 == ps_codec->i4_share_disp_buf) 2403 ps_ctl_op->u4_num_disp_bufs = 1; 2404 else 2405 { 2406 if(ps_codec->i4_sps_done) 2407 { 2408 sps_t *ps_sps = (ps_codec->s_parse.ps_sps_base + ps_codec->i4_sps_id); 2409 WORD32 reorder_pic_cnt, ref_pic_cnt; 2410 reorder_pic_cnt = 0; 2411 if(ps_codec->e_frm_out_mode != IVD_DECODE_FRAME_OUT) 2412 reorder_pic_cnt = ps_sps->ai1_sps_max_num_reorder_pics[ps_sps->i1_sps_max_sub_layers - 1]; 2413 ref_pic_cnt = ps_sps->ai1_sps_max_dec_pic_buffering[ps_sps->i1_sps_max_sub_layers - 1]; 2414 2415 ps_ctl_op->u4_num_disp_bufs = reorder_pic_cnt; 2416 2417 ps_ctl_op->u4_num_disp_bufs += ref_pic_cnt + 1; 2418 } 2419 else 2420 { 2421 ps_ctl_op->u4_num_disp_bufs = MAX_REF_CNT; 2422 } 2423 2424 ps_ctl_op->u4_num_disp_bufs = MIN( 2425 ps_ctl_op->u4_num_disp_bufs, 32); 2426 } 2427 2428 /*!*/ 2429 if(ps_codec->e_chroma_fmt == IV_YUV_420P) 2430 { 2431 ps_ctl_op->u4_min_out_buf_size[0] = (wd * ht); 2432 ps_ctl_op->u4_min_out_buf_size[1] = (wd * ht) >> 2; 2433 ps_ctl_op->u4_min_out_buf_size[2] = (wd * ht) >> 2; 2434 } 2435 else if(ps_codec->e_chroma_fmt == IV_YUV_422ILE) 2436 { 2437 ps_ctl_op->u4_min_out_buf_size[0] = (wd * ht) * 2; 2438 ps_ctl_op->u4_min_out_buf_size[1] = 2439 ps_ctl_op->u4_min_out_buf_size[2] = 0; 2440 } 2441 else if(ps_codec->e_chroma_fmt == IV_RGB_565) 2442 { 2443 ps_ctl_op->u4_min_out_buf_size[0] = (wd * ht) * 2; 2444 ps_ctl_op->u4_min_out_buf_size[1] = 2445 ps_ctl_op->u4_min_out_buf_size[2] = 0; 2446 } 2447 else if(ps_codec->e_chroma_fmt == IV_RGBA_8888) 2448 { 2449 ps_ctl_op->u4_min_out_buf_size[0] = (wd * ht) * 4; 2450 ps_ctl_op->u4_min_out_buf_size[1] = 2451 ps_ctl_op->u4_min_out_buf_size[2] = 0; 2452 } 2453 else if((ps_codec->e_chroma_fmt == IV_YUV_420SP_UV) 2454 || (ps_codec->e_chroma_fmt == IV_YUV_420SP_VU)) 2455 { 2456 ps_ctl_op->u4_min_out_buf_size[0] = (wd * ht); 2457 ps_ctl_op->u4_min_out_buf_size[1] = (wd * ht) >> 1; 2458 ps_ctl_op->u4_min_out_buf_size[2] = 0; 2459 } 2460 ps_ctl_op->u4_pic_ht = ht; 2461 ps_ctl_op->u4_pic_wd = wd; 2462 ps_ctl_op->u4_frame_rate = 30000; 2463 ps_ctl_op->u4_bit_rate = 1000000; 2464 ps_ctl_op->e_content_type = IV_PROGRESSIVE; 2465 ps_ctl_op->e_output_chroma_format = ps_codec->e_chroma_fmt; 2466 ps_codec->i4_num_disp_bufs = ps_ctl_op->u4_num_disp_bufs; 2467 2468 if(ps_ctl_op->u4_size == sizeof(ihevcd_cxa_ctl_getstatus_op_t)) 2469 { 2470 ihevcd_cxa_ctl_getstatus_op_t *ps_ext_ctl_op = (ihevcd_cxa_ctl_getstatus_op_t *)ps_ctl_op; 2471 ps_ext_ctl_op->u4_coded_pic_wd = ps_codec->i4_wd; 2472 ps_ext_ctl_op->u4_coded_pic_wd = ps_codec->i4_ht; 2473 } 2474 return IV_SUCCESS; 2475} 2476/** 2477******************************************************************************* 2478* 2479* @brief 2480* Gets decoder buffer requirements 2481* 2482* @par Description: 2483* Gets the decoder buffer requirements. If called before header decoder, 2484* buffer requirements are based on max_wd and max_ht else actual width and 2485* height will be used 2486* 2487* @param[in] ps_codec_obj 2488* Pointer to codec object at API level 2489* 2490* @param[in] pv_api_ip 2491* Pointer to input argument structure 2492* 2493* @param[out] pv_api_op 2494* Pointer to output argument structure 2495* 2496* @returns Status 2497* 2498* @remarks 2499* 2500* 2501******************************************************************************* 2502*/ 2503WORD32 ihevcd_get_buf_info(iv_obj_t *ps_codec_obj, 2504 void *pv_api_ip, 2505 void *pv_api_op) 2506{ 2507 2508 codec_t *ps_codec; 2509 UWORD32 i = 0; 2510 WORD32 wd, ht; 2511 ivd_ctl_getbufinfo_op_t *ps_ctl_op = 2512 (ivd_ctl_getbufinfo_op_t *)pv_api_op; 2513 2514 UNUSED(pv_api_ip); 2515 ps_ctl_op->u4_error_code = 0; 2516 2517 ps_codec = (codec_t *)(ps_codec_obj->pv_codec_handle); 2518 2519 ps_ctl_op->u4_min_num_in_bufs = MIN_IN_BUFS; 2520 if(ps_codec->e_chroma_fmt == IV_YUV_420P) 2521 ps_ctl_op->u4_min_num_out_bufs = MIN_OUT_BUFS_420; 2522 else if(ps_codec->e_chroma_fmt == IV_YUV_422ILE) 2523 ps_ctl_op->u4_min_num_out_bufs = MIN_OUT_BUFS_422ILE; 2524 else if(ps_codec->e_chroma_fmt == IV_RGB_565) 2525 ps_ctl_op->u4_min_num_out_bufs = MIN_OUT_BUFS_RGB565; 2526 else if(ps_codec->e_chroma_fmt == IV_RGBA_8888) 2527 ps_ctl_op->u4_min_num_out_bufs = MIN_OUT_BUFS_RGBA8888; 2528 else if((ps_codec->e_chroma_fmt == IV_YUV_420SP_UV) 2529 || (ps_codec->e_chroma_fmt == IV_YUV_420SP_VU)) 2530 ps_ctl_op->u4_min_num_out_bufs = MIN_OUT_BUFS_420SP; 2531 2532 ps_ctl_op->u4_num_disp_bufs = 1; 2533 2534 for(i = 0; i < ps_ctl_op->u4_min_num_in_bufs; i++) 2535 { 2536 wd = ALIGN64(ps_codec->i4_wd); 2537 ht = ALIGN64(ps_codec->i4_ht); 2538 2539 ps_ctl_op->u4_min_in_buf_size[i] = MAX((wd * ht), MIN_BITSBUF_SIZE); 2540 } 2541 2542 wd = 0; 2543 ht = 0; 2544 2545 if(ps_codec->i4_sps_done) 2546 { 2547 if(0 == ps_codec->i4_share_disp_buf) 2548 { 2549 wd = ps_codec->i4_disp_wd; 2550 ht = ps_codec->i4_disp_ht; 2551 2552 } 2553 else 2554 { 2555 wd = ps_codec->i4_disp_strd; 2556 ht = ps_codec->i4_ht + PAD_HT; 2557 } 2558 } 2559 else 2560 { 2561 if(1 == ps_codec->i4_share_disp_buf) 2562 { 2563 wd = ALIGN32(wd + PAD_WD); 2564 ht += PAD_HT; 2565 } 2566 } 2567 2568 if(ps_codec->i4_disp_strd > wd) 2569 wd = ps_codec->i4_disp_strd; 2570 2571 if(0 == ps_codec->i4_share_disp_buf) 2572 ps_ctl_op->u4_num_disp_bufs = 1; 2573 else 2574 { 2575 if(ps_codec->i4_sps_done) 2576 { 2577 sps_t *ps_sps = (ps_codec->s_parse.ps_sps_base + ps_codec->i4_sps_id); 2578 WORD32 reorder_pic_cnt, ref_pic_cnt; 2579 reorder_pic_cnt = 0; 2580 if(ps_codec->e_frm_out_mode != IVD_DECODE_FRAME_OUT) 2581 reorder_pic_cnt = ps_sps->ai1_sps_max_num_reorder_pics[ps_sps->i1_sps_max_sub_layers - 1]; 2582 ref_pic_cnt = ps_sps->ai1_sps_max_dec_pic_buffering[ps_sps->i1_sps_max_sub_layers - 1]; 2583 2584 ps_ctl_op->u4_num_disp_bufs = reorder_pic_cnt; 2585 2586 ps_ctl_op->u4_num_disp_bufs += ref_pic_cnt + 1; 2587 } 2588 else 2589 { 2590 ps_ctl_op->u4_num_disp_bufs = MAX_REF_CNT; 2591 } 2592 2593 ps_ctl_op->u4_num_disp_bufs = MIN( 2594 ps_ctl_op->u4_num_disp_bufs, 32); 2595 2596 } 2597 2598 /*!*/ 2599 if(ps_codec->e_chroma_fmt == IV_YUV_420P) 2600 { 2601 ps_ctl_op->u4_min_out_buf_size[0] = (wd * ht); 2602 ps_ctl_op->u4_min_out_buf_size[1] = (wd * ht) >> 2; 2603 ps_ctl_op->u4_min_out_buf_size[2] = (wd * ht) >> 2; 2604 } 2605 else if(ps_codec->e_chroma_fmt == IV_YUV_422ILE) 2606 { 2607 ps_ctl_op->u4_min_out_buf_size[0] = (wd * ht) * 2; 2608 ps_ctl_op->u4_min_out_buf_size[1] = 2609 ps_ctl_op->u4_min_out_buf_size[2] = 0; 2610 } 2611 else if(ps_codec->e_chroma_fmt == IV_RGB_565) 2612 { 2613 ps_ctl_op->u4_min_out_buf_size[0] = (wd * ht) * 2; 2614 ps_ctl_op->u4_min_out_buf_size[1] = 2615 ps_ctl_op->u4_min_out_buf_size[2] = 0; 2616 } 2617 else if(ps_codec->e_chroma_fmt == IV_RGBA_8888) 2618 { 2619 ps_ctl_op->u4_min_out_buf_size[0] = (wd * ht) * 4; 2620 ps_ctl_op->u4_min_out_buf_size[1] = 2621 ps_ctl_op->u4_min_out_buf_size[2] = 0; 2622 } 2623 else if((ps_codec->e_chroma_fmt == IV_YUV_420SP_UV) 2624 || (ps_codec->e_chroma_fmt == IV_YUV_420SP_VU)) 2625 { 2626 ps_ctl_op->u4_min_out_buf_size[0] = (wd * ht); 2627 ps_ctl_op->u4_min_out_buf_size[1] = (wd * ht) >> 1; 2628 ps_ctl_op->u4_min_out_buf_size[2] = 0; 2629 } 2630 ps_codec->i4_num_disp_bufs = ps_ctl_op->u4_num_disp_bufs; 2631 2632 return IV_SUCCESS; 2633} 2634 2635 2636/** 2637******************************************************************************* 2638* 2639* @brief 2640* Sets dynamic parameters 2641* 2642* @par Description: 2643* Sets dynamic parameters. Note Frame skip, decode header mode are dynamic 2644* Dynamic change in stride is not supported 2645* 2646* @param[in] ps_codec_obj 2647* Pointer to codec object at API level 2648* 2649* @param[in] pv_api_ip 2650* Pointer to input argument structure 2651* 2652* @param[out] pv_api_op 2653* Pointer to output argument structure 2654* 2655* @returns Status 2656* 2657* @remarks 2658* 2659* 2660******************************************************************************* 2661*/ 2662WORD32 ihevcd_set_params(iv_obj_t *ps_codec_obj, 2663 void *pv_api_ip, 2664 void *pv_api_op) 2665{ 2666 2667 codec_t *ps_codec; 2668 WORD32 ret = IV_SUCCESS; 2669 WORD32 strd; 2670 ivd_ctl_set_config_ip_t *s_ctl_dynparams_ip = 2671 (ivd_ctl_set_config_ip_t *)pv_api_ip; 2672 ivd_ctl_set_config_op_t *s_ctl_dynparams_op = 2673 (ivd_ctl_set_config_op_t *)pv_api_op; 2674 2675 ps_codec = (codec_t *)(ps_codec_obj->pv_codec_handle); 2676 2677 s_ctl_dynparams_op->u4_error_code = 0; 2678 2679 ps_codec->e_pic_skip_mode = s_ctl_dynparams_ip->e_frm_skip_mode; 2680 2681 if(s_ctl_dynparams_ip->e_frm_skip_mode != IVD_SKIP_NONE) 2682 { 2683 2684 if((s_ctl_dynparams_ip->e_frm_skip_mode != IVD_SKIP_P) && 2685 (s_ctl_dynparams_ip->e_frm_skip_mode != IVD_SKIP_B) && 2686 (s_ctl_dynparams_ip->e_frm_skip_mode != IVD_SKIP_PB)) 2687 { 2688 s_ctl_dynparams_op->u4_error_code = (1 << IVD_UNSUPPORTEDPARAM); 2689 ret = IV_FAIL; 2690 } 2691 } 2692 2693 strd = ps_codec->i4_disp_strd; 2694 if(1 == ps_codec->i4_share_disp_buf) 2695 { 2696 strd = ps_codec->i4_strd; 2697 } 2698 2699 2700 { 2701 if((WORD32)s_ctl_dynparams_ip->u4_disp_wd >= ps_codec->i4_disp_wd) 2702 { 2703 strd = s_ctl_dynparams_ip->u4_disp_wd; 2704 } 2705 else if(0 == ps_codec->i4_sps_done) 2706 { 2707 strd = s_ctl_dynparams_ip->u4_disp_wd; 2708 } 2709 else if(s_ctl_dynparams_ip->u4_disp_wd == 0) 2710 { 2711 strd = ps_codec->i4_disp_strd; 2712 } 2713 else 2714 { 2715 strd = 0; 2716 s_ctl_dynparams_op->u4_error_code |= (1 << IVD_UNSUPPORTEDPARAM); 2717 s_ctl_dynparams_op->u4_error_code |= IHEVCD_INVALID_DISP_STRD; 2718 ret = IV_FAIL; 2719 } 2720 } 2721 2722 ps_codec->i4_disp_strd = strd; 2723 if(1 == ps_codec->i4_share_disp_buf) 2724 { 2725 ps_codec->i4_strd = strd; 2726 } 2727 2728 if(s_ctl_dynparams_ip->e_vid_dec_mode == IVD_DECODE_FRAME) 2729 ps_codec->i4_header_mode = 0; 2730 else if(s_ctl_dynparams_ip->e_vid_dec_mode == IVD_DECODE_HEADER) 2731 ps_codec->i4_header_mode = 1; 2732 else 2733 { 2734 2735 s_ctl_dynparams_op->u4_error_code = (1 << IVD_UNSUPPORTEDPARAM); 2736 ps_codec->i4_header_mode = 1; 2737 ret = IV_FAIL; 2738 } 2739 2740 ps_codec->e_frm_out_mode = IVD_DISPLAY_FRAME_OUT; 2741 2742 if((s_ctl_dynparams_ip->e_frm_out_mode != IVD_DECODE_FRAME_OUT) && 2743 (s_ctl_dynparams_ip->e_frm_out_mode != IVD_DISPLAY_FRAME_OUT)) 2744 { 2745 s_ctl_dynparams_op->u4_error_code = (1 << IVD_UNSUPPORTEDPARAM); 2746 ret = IV_FAIL; 2747 } 2748 ps_codec->e_frm_out_mode = s_ctl_dynparams_ip->e_frm_out_mode; 2749 2750 return ret; 2751 2752} 2753/** 2754******************************************************************************* 2755* 2756* @brief 2757* Resets the decoder state 2758* 2759* @par Description: 2760* Resets the decoder state by calling ihevcd_init() 2761* 2762* @param[in] ps_codec_obj 2763* Pointer to codec object at API level 2764* 2765* @param[in] pv_api_ip 2766* Pointer to input argument structure 2767* 2768* @param[out] pv_api_op 2769* Pointer to output argument structure 2770* 2771* @returns Status 2772* 2773* @remarks 2774* 2775* 2776******************************************************************************* 2777*/ 2778WORD32 ihevcd_reset(iv_obj_t *ps_codec_obj, void *pv_api_ip, void *pv_api_op) 2779{ 2780 codec_t *ps_codec; 2781 ivd_ctl_reset_op_t *s_ctl_reset_op = (ivd_ctl_reset_op_t *)pv_api_op; 2782 UNUSED(pv_api_ip); 2783 ps_codec = (codec_t *)(ps_codec_obj->pv_codec_handle); 2784 2785 if(ps_codec != NULL) 2786 { 2787 DEBUG("\nReset called \n"); 2788 ihevcd_init(ps_codec); 2789 } 2790 else 2791 { 2792 DEBUG("\nReset called without Initializing the decoder\n"); 2793 s_ctl_reset_op->u4_error_code = IHEVCD_INIT_NOT_DONE; 2794 } 2795 2796 return IV_SUCCESS; 2797} 2798 2799/** 2800******************************************************************************* 2801* 2802* @brief 2803* Releases display buffer from application to codec to signal to the codec 2804* that it can write to this buffer if required. Till release is called, 2805* codec can not write to this buffer 2806* 2807* @par Description: 2808* Marks the buffer as display done 2809* 2810* @param[in] ps_codec_obj 2811* Pointer to codec object at API level 2812* 2813* @param[in] pv_api_ip 2814* Pointer to input argument structure 2815* 2816* @param[out] pv_api_op 2817* Pointer to output argument structure 2818* 2819* @returns Status 2820* 2821* @remarks 2822* 2823* 2824******************************************************************************* 2825*/ 2826 2827WORD32 ihevcd_rel_display_frame(iv_obj_t *ps_codec_obj, 2828 void *pv_api_ip, 2829 void *pv_api_op) 2830{ 2831 2832 ivd_rel_display_frame_ip_t *ps_dec_rel_disp_ip; 2833 ivd_rel_display_frame_op_t *ps_dec_rel_disp_op; 2834 2835 codec_t *ps_codec = (codec_t *)ps_codec_obj->pv_codec_handle; 2836 2837 ps_dec_rel_disp_ip = (ivd_rel_display_frame_ip_t *)pv_api_ip; 2838 ps_dec_rel_disp_op = (ivd_rel_display_frame_op_t *)pv_api_op; 2839 2840 UNUSED(ps_dec_rel_disp_op); 2841 2842 if(0 == ps_codec->i4_share_disp_buf) 2843 { 2844 return IV_SUCCESS; 2845 } 2846 2847 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); 2848 2849 return IV_SUCCESS; 2850} 2851/** 2852******************************************************************************* 2853* 2854* @brief 2855* Sets degrade params 2856* 2857* @par Description: 2858* Sets degrade params. 2859* Refer to ihevcd_cxa_ctl_degrade_ip_t definition for details 2860* 2861* @param[in] ps_codec_obj 2862* Pointer to codec object at API level 2863* 2864* @param[in] pv_api_ip 2865* Pointer to input argument structure 2866* 2867* @param[out] pv_api_op 2868* Pointer to output argument structure 2869* 2870* @returns Status 2871* 2872* @remarks 2873* 2874* 2875******************************************************************************* 2876*/ 2877 2878WORD32 ihevcd_set_degrade(iv_obj_t *ps_codec_obj, 2879 void *pv_api_ip, 2880 void *pv_api_op) 2881{ 2882 ihevcd_cxa_ctl_degrade_ip_t *ps_ip; 2883 ihevcd_cxa_ctl_degrade_op_t *ps_op; 2884 codec_t *ps_codec = (codec_t *)ps_codec_obj->pv_codec_handle; 2885 2886 ps_ip = (ihevcd_cxa_ctl_degrade_ip_t *)pv_api_ip; 2887 ps_op = (ihevcd_cxa_ctl_degrade_op_t *)pv_api_op; 2888 2889 ps_codec->i4_degrade_type = ps_ip->i4_degrade_type; 2890 ps_codec->i4_nondegrade_interval = ps_ip->i4_nondegrade_interval; 2891 ps_codec->i4_degrade_pics = ps_ip->i4_degrade_pics; 2892 2893 ps_op->u4_error_code = 0; 2894 ps_codec->i4_degrade_pic_cnt = 0; 2895 2896 return IV_SUCCESS; 2897} 2898 2899 2900/** 2901******************************************************************************* 2902* 2903* @brief 2904* Gets frame dimensions/offsets 2905* 2906* @par Description: 2907* Gets frame buffer chararacteristics such a x & y offsets display and 2908* buffer dimensions 2909* 2910* @param[in] ps_codec_obj 2911* Pointer to codec object at API level 2912* 2913* @param[in] pv_api_ip 2914* Pointer to input argument structure 2915* 2916* @param[out] pv_api_op 2917* Pointer to output argument structure 2918* 2919* @returns Status 2920* 2921* @remarks 2922* 2923* 2924******************************************************************************* 2925*/ 2926 2927WORD32 ihevcd_get_frame_dimensions(iv_obj_t *ps_codec_obj, 2928 void *pv_api_ip, 2929 void *pv_api_op) 2930{ 2931 ihevcd_cxa_ctl_get_frame_dimensions_ip_t *ps_ip; 2932 ihevcd_cxa_ctl_get_frame_dimensions_op_t *ps_op; 2933 codec_t *ps_codec = (codec_t *)ps_codec_obj->pv_codec_handle; 2934 WORD32 disp_wd, disp_ht, buffer_wd, buffer_ht, x_offset, y_offset; 2935 ps_ip = (ihevcd_cxa_ctl_get_frame_dimensions_ip_t *)pv_api_ip; 2936 ps_op = (ihevcd_cxa_ctl_get_frame_dimensions_op_t *)pv_api_op; 2937 UNUSED(ps_ip); 2938 if(ps_codec->i4_sps_done) 2939 { 2940 disp_wd = ps_codec->i4_disp_wd; 2941 disp_ht = ps_codec->i4_disp_ht; 2942 2943 if(0 == ps_codec->i4_share_disp_buf) 2944 { 2945 buffer_wd = disp_wd; 2946 buffer_ht = disp_ht; 2947 } 2948 else 2949 { 2950 buffer_wd = ps_codec->i4_strd; 2951 buffer_ht = ps_codec->i4_ht + PAD_HT; 2952 } 2953 } 2954 else 2955 { 2956 2957 disp_wd = 0; 2958 disp_ht = 0; 2959 2960 if(0 == ps_codec->i4_share_disp_buf) 2961 { 2962 buffer_wd = disp_wd; 2963 buffer_ht = disp_ht; 2964 } 2965 else 2966 { 2967 buffer_wd = ALIGN16(disp_wd) + PAD_WD; 2968 buffer_ht = ALIGN16(disp_ht) + PAD_HT; 2969 2970 } 2971 } 2972 if(ps_codec->i4_strd > buffer_wd) 2973 buffer_wd = ps_codec->i4_strd; 2974 2975 if(0 == ps_codec->i4_share_disp_buf) 2976 { 2977 x_offset = 0; 2978 y_offset = 0; 2979 } 2980 else 2981 { 2982 y_offset = PAD_TOP; 2983 x_offset = PAD_LEFT; 2984 } 2985 2986 ps_op->u4_disp_wd[0] = disp_wd; 2987 ps_op->u4_disp_ht[0] = disp_ht; 2988 ps_op->u4_buffer_wd[0] = buffer_wd; 2989 ps_op->u4_buffer_ht[0] = buffer_ht; 2990 ps_op->u4_x_offset[0] = x_offset; 2991 ps_op->u4_y_offset[0] = y_offset; 2992 2993 ps_op->u4_disp_wd[1] = ps_op->u4_disp_wd[2] = ((ps_op->u4_disp_wd[0] + 1) 2994 >> 1); 2995 ps_op->u4_disp_ht[1] = ps_op->u4_disp_ht[2] = ((ps_op->u4_disp_ht[0] + 1) 2996 >> 1); 2997 ps_op->u4_buffer_wd[1] = ps_op->u4_buffer_wd[2] = (ps_op->u4_buffer_wd[0] 2998 >> 1); 2999 ps_op->u4_buffer_ht[1] = ps_op->u4_buffer_ht[2] = (ps_op->u4_buffer_ht[0] 3000 >> 1); 3001 ps_op->u4_x_offset[1] = ps_op->u4_x_offset[2] = (ps_op->u4_x_offset[0] 3002 >> 1); 3003 ps_op->u4_y_offset[1] = ps_op->u4_y_offset[2] = (ps_op->u4_y_offset[0] 3004 >> 1); 3005 3006 if((ps_codec->e_chroma_fmt == IV_YUV_420SP_UV) 3007 || (ps_codec->e_chroma_fmt == IV_YUV_420SP_VU)) 3008 { 3009 ps_op->u4_disp_wd[2] = 0; 3010 ps_op->u4_disp_ht[2] = 0; 3011 ps_op->u4_buffer_wd[2] = 0; 3012 ps_op->u4_buffer_ht[2] = 0; 3013 ps_op->u4_x_offset[2] = 0; 3014 ps_op->u4_y_offset[2] = 0; 3015 3016 ps_op->u4_disp_wd[1] <<= 1; 3017 ps_op->u4_buffer_wd[1] <<= 1; 3018 ps_op->u4_x_offset[1] <<= 1; 3019 } 3020 3021 return IV_SUCCESS; 3022 3023} 3024 3025 3026/** 3027******************************************************************************* 3028* 3029* @brief 3030* Gets vui parameters 3031* 3032* @par Description: 3033* Gets VUI parameters 3034* 3035* @param[in] ps_codec_obj 3036* Pointer to codec object at API level 3037* 3038* @param[in] pv_api_ip 3039* Pointer to input argument structure 3040* 3041* @param[out] pv_api_op 3042* Pointer to output argument structure 3043* 3044* @returns Status 3045* 3046* @remarks 3047* 3048* 3049******************************************************************************* 3050*/ 3051WORD32 ihevcd_get_vui_params(iv_obj_t *ps_codec_obj, 3052 void *pv_api_ip, 3053 void *pv_api_op) 3054{ 3055 ihevcd_cxa_ctl_get_vui_params_ip_t *ps_ip; 3056 ihevcd_cxa_ctl_get_vui_params_op_t *ps_op; 3057 codec_t *ps_codec = (codec_t *)ps_codec_obj->pv_codec_handle; 3058 sps_t *ps_sps; 3059 vui_t *ps_vui; 3060 WORD32 i; 3061 3062 ps_ip = (ihevcd_cxa_ctl_get_vui_params_ip_t *)pv_api_ip; 3063 ps_op = (ihevcd_cxa_ctl_get_vui_params_op_t *)pv_api_op; 3064 3065 if(0 == ps_codec->i4_sps_done) 3066 { 3067 ps_op->u4_error_code = IHEVCD_VUI_PARAMS_NOT_FOUND; 3068 return IV_FAIL; 3069 } 3070 3071 ps_sps = ps_codec->s_parse.ps_sps; 3072 if(0 == ps_sps->i1_sps_valid || 0 == ps_sps->i1_vui_parameters_present_flag) 3073 { 3074 WORD32 sps_idx = 0; 3075 ps_sps = ps_codec->ps_sps_base; 3076 3077 while((0 == ps_sps->i1_sps_valid) || (0 == ps_sps->i1_vui_parameters_present_flag)) 3078 { 3079 sps_idx++; 3080 ps_sps++; 3081 3082 if(sps_idx == MAX_SPS_CNT - 1) 3083 { 3084 ps_op->u4_error_code = IHEVCD_VUI_PARAMS_NOT_FOUND; 3085 return IV_FAIL; 3086 } 3087 } 3088 } 3089 3090 ps_vui = &ps_sps->s_vui_parameters; 3091 UNUSED(ps_ip); 3092 3093 ps_op->u1_aspect_ratio_info_present_flag = ps_vui->u1_aspect_ratio_info_present_flag; 3094 ps_op->u1_aspect_ratio_idc = ps_vui->u1_aspect_ratio_idc; 3095 ps_op->u2_sar_width = ps_vui->u2_sar_width; 3096 ps_op->u2_sar_height = ps_vui->u2_sar_height; 3097 ps_op->u1_overscan_info_present_flag = ps_vui->u1_overscan_info_present_flag; 3098 ps_op->u1_overscan_appropriate_flag = ps_vui->u1_overscan_appropriate_flag; 3099 ps_op->u1_video_signal_type_present_flag = ps_vui->u1_video_signal_type_present_flag; 3100 ps_op->u1_video_format = ps_vui->u1_video_format; 3101 ps_op->u1_video_full_range_flag = ps_vui->u1_video_full_range_flag; 3102 ps_op->u1_colour_description_present_flag = ps_vui->u1_colour_description_present_flag; 3103 ps_op->u1_colour_primaries = ps_vui->u1_colour_primaries; 3104 ps_op->u1_transfer_characteristics = ps_vui->u1_transfer_characteristics; 3105 ps_op->u1_matrix_coefficients = ps_vui->u1_matrix_coefficients; 3106 ps_op->u1_chroma_loc_info_present_flag = ps_vui->u1_chroma_loc_info_present_flag; 3107 ps_op->u1_chroma_sample_loc_type_top_field = ps_vui->u1_chroma_sample_loc_type_top_field; 3108 ps_op->u1_chroma_sample_loc_type_bottom_field = ps_vui->u1_chroma_sample_loc_type_bottom_field; 3109 ps_op->u1_neutral_chroma_indication_flag = ps_vui->u1_neutral_chroma_indication_flag; 3110 ps_op->u1_field_seq_flag = ps_vui->u1_field_seq_flag; 3111 ps_op->u1_frame_field_info_present_flag = ps_vui->u1_frame_field_info_present_flag; 3112 ps_op->u1_default_display_window_flag = ps_vui->u1_default_display_window_flag; 3113 ps_op->u4_def_disp_win_left_offset = ps_vui->u4_def_disp_win_left_offset; 3114 ps_op->u4_def_disp_win_right_offset = ps_vui->u4_def_disp_win_right_offset; 3115 ps_op->u4_def_disp_win_top_offset = ps_vui->u4_def_disp_win_top_offset; 3116 ps_op->u4_def_disp_win_bottom_offset = ps_vui->u4_def_disp_win_bottom_offset; 3117 ps_op->u1_vui_hrd_parameters_present_flag = ps_vui->u1_vui_hrd_parameters_present_flag; 3118 ps_op->u1_vui_timing_info_present_flag = ps_vui->u1_vui_timing_info_present_flag; 3119 ps_op->u4_vui_num_units_in_tick = ps_vui->u4_vui_num_units_in_tick; 3120 ps_op->u4_vui_time_scale = ps_vui->u4_vui_time_scale; 3121 ps_op->u1_poc_proportional_to_timing_flag = ps_vui->u1_poc_proportional_to_timing_flag; 3122 ps_op->u1_num_ticks_poc_diff_one_minus1 = ps_vui->u1_num_ticks_poc_diff_one_minus1; 3123 ps_op->u1_bitstream_restriction_flag = ps_vui->u1_bitstream_restriction_flag; 3124 ps_op->u1_tiles_fixed_structure_flag = ps_vui->u1_tiles_fixed_structure_flag; 3125 ps_op->u1_motion_vectors_over_pic_boundaries_flag = ps_vui->u1_motion_vectors_over_pic_boundaries_flag; 3126 ps_op->u1_restricted_ref_pic_lists_flag = ps_vui->u1_restricted_ref_pic_lists_flag; 3127 ps_op->u4_min_spatial_segmentation_idc = ps_vui->u4_min_spatial_segmentation_idc; 3128 ps_op->u1_max_bytes_per_pic_denom = ps_vui->u1_max_bytes_per_pic_denom; 3129 ps_op->u1_max_bits_per_mincu_denom = ps_vui->u1_max_bits_per_mincu_denom; 3130 ps_op->u1_log2_max_mv_length_horizontal = ps_vui->u1_log2_max_mv_length_horizontal; 3131 ps_op->u1_log2_max_mv_length_vertical = ps_vui->u1_log2_max_mv_length_vertical; 3132 3133 3134 /* HRD parameters */ 3135 ps_op->u1_timing_info_present_flag = ps_vui->s_vui_hrd_parameters.u1_timing_info_present_flag; 3136 ps_op->u4_num_units_in_tick = ps_vui->s_vui_hrd_parameters.u4_num_units_in_tick; 3137 ps_op->u4_time_scale = ps_vui->s_vui_hrd_parameters.u4_time_scale; 3138 ps_op->u1_nal_hrd_parameters_present_flag = ps_vui->s_vui_hrd_parameters.u1_nal_hrd_parameters_present_flag; 3139 ps_op->u1_vcl_hrd_parameters_present_flag = ps_vui->s_vui_hrd_parameters.u1_vcl_hrd_parameters_present_flag; 3140 ps_op->u1_cpbdpb_delays_present_flag = ps_vui->s_vui_hrd_parameters.u1_cpbdpb_delays_present_flag; 3141 ps_op->u1_sub_pic_cpb_params_present_flag = ps_vui->s_vui_hrd_parameters.u1_sub_pic_cpb_params_present_flag; 3142 ps_op->u1_tick_divisor_minus2 = ps_vui->s_vui_hrd_parameters.u1_tick_divisor_minus2; 3143 ps_op->u1_du_cpb_removal_delay_increment_length_minus1 = ps_vui->s_vui_hrd_parameters.u1_du_cpb_removal_delay_increment_length_minus1; 3144 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; 3145 ps_op->u1_dpb_output_delay_du_length_minus1 = ps_vui->s_vui_hrd_parameters.u1_dpb_output_delay_du_length_minus1; 3146 ps_op->u4_bit_rate_scale = ps_vui->s_vui_hrd_parameters.u4_bit_rate_scale; 3147 ps_op->u4_cpb_size_scale = ps_vui->s_vui_hrd_parameters.u4_cpb_size_scale; 3148 ps_op->u4_cpb_size_du_scale = ps_vui->s_vui_hrd_parameters.u4_cpb_size_du_scale; 3149 ps_op->u1_initial_cpb_removal_delay_length_minus1 = ps_vui->s_vui_hrd_parameters.u1_initial_cpb_removal_delay_length_minus1; 3150 ps_op->u1_au_cpb_removal_delay_length_minus1 = ps_vui->s_vui_hrd_parameters.u1_au_cpb_removal_delay_length_minus1; 3151 ps_op->u1_dpb_output_delay_length_minus1 = ps_vui->s_vui_hrd_parameters.u1_dpb_output_delay_length_minus1; 3152 3153 for(i = 0; i < 6; i++) 3154 { 3155 ps_op->au1_fixed_pic_rate_general_flag[i] = ps_vui->s_vui_hrd_parameters.au1_fixed_pic_rate_general_flag[i]; 3156 ps_op->au1_fixed_pic_rate_within_cvs_flag[i] = ps_vui->s_vui_hrd_parameters.au1_fixed_pic_rate_within_cvs_flag[i]; 3157 ps_op->au1_elemental_duration_in_tc_minus1[i] = ps_vui->s_vui_hrd_parameters.au1_elemental_duration_in_tc_minus1[i]; 3158 ps_op->au1_low_delay_hrd_flag[i] = ps_vui->s_vui_hrd_parameters.au1_low_delay_hrd_flag[i]; 3159 ps_op->au1_cpb_cnt_minus1[i] = ps_vui->s_vui_hrd_parameters.au1_cpb_cnt_minus1[i]; 3160 } 3161 3162 3163 return IV_SUCCESS; 3164} 3165 3166/** 3167******************************************************************************* 3168* 3169* @brief 3170* Gets SEI mastering display color volume parameters 3171* 3172* @par Description: 3173* Gets SEI mastering display color volume parameters 3174* 3175* @param[in] ps_codec_obj 3176* Pointer to codec object at API level 3177* 3178* @param[in] pv_api_ip 3179* Pointer to input argument structure 3180* 3181* @param[out] pv_api_op 3182* Pointer to output argument structure 3183* 3184* @returns Status 3185* 3186* @remarks 3187* 3188* 3189******************************************************************************* 3190*/ 3191WORD32 ihevcd_get_sei_mastering_params(iv_obj_t *ps_codec_obj, 3192 void *pv_api_ip, 3193 void *pv_api_op) 3194{ 3195 ihevcd_cxa_ctl_get_sei_mastering_params_ip_t *ps_ip; 3196 ihevcd_cxa_ctl_get_sei_mastering_params_op_t *ps_op; 3197 codec_t *ps_codec = (codec_t *)ps_codec_obj->pv_codec_handle; 3198 sei_params_t *ps_sei; 3199 mastering_dis_col_vol_sei_params_t *ps_mastering_dis_col_vol; 3200 WORD32 i; 3201 3202 ps_ip = (ihevcd_cxa_ctl_get_sei_mastering_params_ip_t *)pv_api_ip; 3203 ps_op = (ihevcd_cxa_ctl_get_sei_mastering_params_op_t *)pv_api_op; 3204 UNUSED(ps_ip); 3205 if(NULL == ps_codec->ps_disp_buf) 3206 { 3207 ps_op->u4_error_code = IHEVCD_SEI_MASTERING_PARAMS_NOT_FOUND; 3208 return IV_FAIL; 3209 } 3210 ps_sei = &ps_codec->ps_disp_buf->s_sei_params; 3211 if((0 == ps_sei->i4_sei_mastering_disp_colour_vol_params_present_flags) 3212 || (0 == ps_sei->i1_sei_parameters_present_flag)) 3213 { 3214 ps_op->u4_error_code = IHEVCD_SEI_MASTERING_PARAMS_NOT_FOUND; 3215 return IV_FAIL; 3216 } 3217 3218 ps_mastering_dis_col_vol = &ps_sei->s_mastering_dis_col_vol_sei_params; 3219 3220 for(i = 0; i < 3; i++) 3221 { 3222 ps_op->au2_display_primaries_x[i] = 3223 ps_mastering_dis_col_vol->au2_display_primaries_x[i]; 3224 3225 ps_op->au2_display_primaries_y[i] = 3226 ps_mastering_dis_col_vol->au2_display_primaries_y[i]; 3227 } 3228 3229 ps_op->u2_white_point_x = ps_mastering_dis_col_vol->u2_white_point_x; 3230 3231 ps_op->u2_white_point_y = ps_mastering_dis_col_vol->u2_white_point_y; 3232 3233 ps_op->u4_max_display_mastering_luminance = 3234 ps_mastering_dis_col_vol->u4_max_display_mastering_luminance; 3235 3236 ps_op->u4_min_display_mastering_luminance = 3237 ps_mastering_dis_col_vol->u4_min_display_mastering_luminance; 3238 3239 return IV_SUCCESS; 3240} 3241 3242/** 3243******************************************************************************* 3244* 3245* @brief 3246* Sets Processor type 3247* 3248* @par Description: 3249* Sets Processor type 3250* 3251* @param[in] ps_codec_obj 3252* Pointer to codec object at API level 3253* 3254* @param[in] pv_api_ip 3255* Pointer to input argument structure 3256* 3257* @param[out] pv_api_op 3258* Pointer to output argument structure 3259* 3260* @returns Status 3261* 3262* @remarks 3263* 3264* 3265******************************************************************************* 3266*/ 3267 3268WORD32 ihevcd_set_processor(iv_obj_t *ps_codec_obj, 3269 void *pv_api_ip, 3270 void *pv_api_op) 3271{ 3272 ihevcd_cxa_ctl_set_processor_ip_t *ps_ip; 3273 ihevcd_cxa_ctl_set_processor_op_t *ps_op; 3274 codec_t *ps_codec = (codec_t *)ps_codec_obj->pv_codec_handle; 3275 3276 ps_ip = (ihevcd_cxa_ctl_set_processor_ip_t *)pv_api_ip; 3277 ps_op = (ihevcd_cxa_ctl_set_processor_op_t *)pv_api_op; 3278 3279 ps_codec->e_processor_arch = (IVD_ARCH_T)ps_ip->u4_arch; 3280 ps_codec->e_processor_soc = (IVD_SOC_T)ps_ip->u4_soc; 3281 3282 ihevcd_init_function_ptr(ps_codec); 3283 3284 ihevcd_update_function_ptr(ps_codec); 3285 3286 if(ps_codec->e_processor_soc && (ps_codec->e_processor_soc <= SOC_HISI_37X)) 3287 { 3288 /* 8th bit indicates if format conversion is to be done ahead */ 3289 if(ps_codec->e_processor_soc & 0x80) 3290 ps_codec->u4_enable_fmt_conv_ahead = 1; 3291 3292 /* Lower 7 bit indicate NCTB - if non-zero */ 3293 ps_codec->e_processor_soc &= 0x7F; 3294 3295 if(ps_codec->e_processor_soc) 3296 ps_codec->u4_nctb = ps_codec->e_processor_soc; 3297 3298 3299 } 3300 3301 if((ps_codec->e_processor_soc == SOC_HISI_37X) && (ps_codec->i4_num_cores == 2)) 3302 { 3303 ps_codec->u4_nctb = 2; 3304 } 3305 3306 3307 ps_op->u4_error_code = 0; 3308 return IV_SUCCESS; 3309} 3310 3311/** 3312******************************************************************************* 3313* 3314* @brief 3315* Sets Number of cores that can be used in the codec. Codec uses these many 3316* threads for decoding 3317* 3318* @par Description: 3319* Sets number of cores 3320* 3321* @param[in] ps_codec_obj 3322* Pointer to codec object at API level 3323* 3324* @param[in] pv_api_ip 3325* Pointer to input argument structure 3326* 3327* @param[out] pv_api_op 3328* Pointer to output argument structure 3329* 3330* @returns Status 3331* 3332* @remarks 3333* 3334* 3335******************************************************************************* 3336*/ 3337 3338WORD32 ihevcd_set_num_cores(iv_obj_t *ps_codec_obj, 3339 void *pv_api_ip, 3340 void *pv_api_op) 3341{ 3342 ihevcd_cxa_ctl_set_num_cores_ip_t *ps_ip; 3343 ihevcd_cxa_ctl_set_num_cores_op_t *ps_op; 3344 codec_t *ps_codec = (codec_t *)ps_codec_obj->pv_codec_handle; 3345 3346 ps_ip = (ihevcd_cxa_ctl_set_num_cores_ip_t *)pv_api_ip; 3347 ps_op = (ihevcd_cxa_ctl_set_num_cores_op_t *)pv_api_op; 3348 3349#ifdef MULTICORE 3350 ps_codec->i4_num_cores = ps_ip->u4_num_cores; 3351#else 3352 ps_codec->i4_num_cores = 1; 3353#endif 3354 ps_op->u4_error_code = 0; 3355 return IV_SUCCESS; 3356} 3357/** 3358******************************************************************************* 3359* 3360* @brief 3361* Codec control call 3362* 3363* @par Description: 3364* Codec control call which in turn calls appropriate calls based on 3365* subcommand 3366* 3367* @param[in] ps_codec_obj 3368* Pointer to codec object at API level 3369* 3370* @param[in] pv_api_ip 3371* Pointer to input argument structure 3372* 3373* @param[out] pv_api_op 3374* Pointer to output argument structure 3375* 3376* @returns Status 3377* 3378* @remarks 3379* 3380* 3381******************************************************************************* 3382*/ 3383 3384WORD32 ihevcd_ctl(iv_obj_t *ps_codec_obj, void *pv_api_ip, void *pv_api_op) 3385{ 3386 ivd_ctl_set_config_ip_t *ps_ctl_ip; 3387 ivd_ctl_set_config_op_t *ps_ctl_op; 3388 WORD32 ret = 0; 3389 WORD32 subcommand; 3390 codec_t *ps_codec = (codec_t *)ps_codec_obj->pv_codec_handle; 3391 3392 ps_ctl_ip = (ivd_ctl_set_config_ip_t *)pv_api_ip; 3393 ps_ctl_op = (ivd_ctl_set_config_op_t *)pv_api_op; 3394 3395 if(ps_codec->i4_init_done != 1) 3396 { 3397 ps_ctl_op->u4_error_code |= 1 << IVD_FATALERROR; 3398 ps_ctl_op->u4_error_code |= IHEVCD_INIT_NOT_DONE; 3399 return IV_FAIL; 3400 } 3401 subcommand = ps_ctl_ip->e_sub_cmd; 3402 3403 switch(subcommand) 3404 { 3405 case IVD_CMD_CTL_GETPARAMS: 3406 ret = ihevcd_get_status(ps_codec_obj, (void *)pv_api_ip, 3407 (void *)pv_api_op); 3408 break; 3409 case IVD_CMD_CTL_SETPARAMS: 3410 ret = ihevcd_set_params(ps_codec_obj, (void *)pv_api_ip, 3411 (void *)pv_api_op); 3412 break; 3413 case IVD_CMD_CTL_RESET: 3414 ret = ihevcd_reset(ps_codec_obj, (void *)pv_api_ip, 3415 (void *)pv_api_op); 3416 break; 3417 case IVD_CMD_CTL_SETDEFAULT: 3418 { 3419 ivd_ctl_set_config_op_t *s_ctl_dynparams_op = 3420 (ivd_ctl_set_config_op_t *)pv_api_op; 3421 3422 ret = ihevcd_set_default_params(ps_codec); 3423 if(IV_SUCCESS == ret) 3424 s_ctl_dynparams_op->u4_error_code = 0; 3425 break; 3426 } 3427 case IVD_CMD_CTL_FLUSH: 3428 ret = ihevcd_set_flush_mode(ps_codec_obj, (void *)pv_api_ip, 3429 (void *)pv_api_op); 3430 break; 3431 case IVD_CMD_CTL_GETBUFINFO: 3432 ret = ihevcd_get_buf_info(ps_codec_obj, (void *)pv_api_ip, 3433 (void *)pv_api_op); 3434 break; 3435 case IVD_CMD_CTL_GETVERSION: 3436 { 3437 ivd_ctl_getversioninfo_ip_t *ps_ip; 3438 ivd_ctl_getversioninfo_op_t *ps_op; 3439 IV_API_CALL_STATUS_T ret; 3440 ps_ip = (ivd_ctl_getversioninfo_ip_t *)pv_api_ip; 3441 ps_op = (ivd_ctl_getversioninfo_op_t *)pv_api_op; 3442 3443 ps_op->u4_error_code = IV_SUCCESS; 3444 3445 if((WORD32)ps_ip->u4_version_buffer_size <= 0) 3446 { 3447 ps_op->u4_error_code = IHEVCD_CXA_VERS_BUF_INSUFFICIENT; 3448 ret = IV_FAIL; 3449 } 3450 else 3451 { 3452 ret = ihevcd_get_version((CHAR *)ps_ip->pv_version_buffer, 3453 ps_ip->u4_version_buffer_size); 3454 if(ret != IV_SUCCESS) 3455 { 3456 ps_op->u4_error_code = IHEVCD_CXA_VERS_BUF_INSUFFICIENT; 3457 ret = IV_FAIL; 3458 } 3459 } 3460 } 3461 break; 3462 case IHEVCD_CXA_CMD_CTL_DEGRADE: 3463 ret = ihevcd_set_degrade(ps_codec_obj, (void *)pv_api_ip, 3464 (void *)pv_api_op); 3465 break; 3466 case IHEVCD_CXA_CMD_CTL_SET_NUM_CORES: 3467 ret = ihevcd_set_num_cores(ps_codec_obj, (void *)pv_api_ip, 3468 (void *)pv_api_op); 3469 break; 3470 case IHEVCD_CXA_CMD_CTL_GET_BUFFER_DIMENSIONS: 3471 ret = ihevcd_get_frame_dimensions(ps_codec_obj, (void *)pv_api_ip, 3472 (void *)pv_api_op); 3473 break; 3474 case IHEVCD_CXA_CMD_CTL_GET_VUI_PARAMS: 3475 ret = ihevcd_get_vui_params(ps_codec_obj, (void *)pv_api_ip, 3476 (void *)pv_api_op); 3477 break; 3478 case IHEVCD_CXA_CMD_CTL_GET_SEI_MASTERING_PARAMS: 3479 ret = ihevcd_get_sei_mastering_params(ps_codec_obj, (void *)pv_api_ip, 3480 (void *)pv_api_op); 3481 break; 3482 case IHEVCD_CXA_CMD_CTL_SET_PROCESSOR: 3483 ret = ihevcd_set_processor(ps_codec_obj, (void *)pv_api_ip, 3484 (void *)pv_api_op); 3485 break; 3486 default: 3487 DEBUG("\nDo nothing\n"); 3488 break; 3489 } 3490 3491 return ret; 3492} 3493 3494/** 3495******************************************************************************* 3496* 3497* @brief 3498* Codecs entry point function. All the function calls to the codec are 3499* done using this function with different values specified in command 3500* 3501* @par Description: 3502* Arguments are tested for validity and then based on the command 3503* appropriate function is called 3504* 3505* @param[in] ps_handle 3506* API level handle for codec 3507* 3508* @param[in] pv_api_ip 3509* Input argument structure 3510* 3511* @param[out] pv_api_op 3512* Output argument structure 3513* 3514* @returns Status of the function corresponding to command 3515* 3516* @remarks 3517* 3518* 3519******************************************************************************* 3520*/ 3521IV_API_CALL_STATUS_T ihevcd_cxa_api_function(iv_obj_t *ps_handle, 3522 void *pv_api_ip, 3523 void *pv_api_op) 3524{ 3525 WORD32 command; 3526 UWORD32 *pu4_ptr_cmd; 3527 WORD32 ret = 0; 3528 IV_API_CALL_STATUS_T e_status; 3529 e_status = api_check_struct_sanity(ps_handle, pv_api_ip, pv_api_op); 3530 3531 if(e_status != IV_SUCCESS) 3532 { 3533 DEBUG("error code = %d\n", *((UWORD32 *)pv_api_op + 1)); 3534 return IV_FAIL; 3535 } 3536 3537 pu4_ptr_cmd = (UWORD32 *)pv_api_ip; 3538 pu4_ptr_cmd++; 3539 3540 command = *pu4_ptr_cmd; 3541 3542 switch(command) 3543 { 3544 case IVD_CMD_CREATE: 3545 ret = ihevcd_create(ps_handle, (void *)pv_api_ip, (void *)pv_api_op); 3546 break; 3547 case IVD_CMD_DELETE: 3548 ret = ihevcd_delete(ps_handle, (void *)pv_api_ip, (void *)pv_api_op); 3549 break; 3550 3551 case IVD_CMD_VIDEO_DECODE: 3552 ret = ihevcd_decode(ps_handle, (void *)pv_api_ip, (void *)pv_api_op); 3553 break; 3554 3555 case IVD_CMD_GET_DISPLAY_FRAME: 3556 //ret = ihevcd_get_display_frame(ps_handle,(void *)pv_api_ip,(void *)pv_api_op); 3557 break; 3558 3559 case IVD_CMD_SET_DISPLAY_FRAME: 3560 ret = ihevcd_set_display_frame(ps_handle, (void *)pv_api_ip, 3561 (void *)pv_api_op); 3562 3563 break; 3564 3565 case IVD_CMD_REL_DISPLAY_FRAME: 3566 ret = ihevcd_rel_display_frame(ps_handle, (void *)pv_api_ip, 3567 (void *)pv_api_op); 3568 break; 3569 3570 case IVD_CMD_VIDEO_CTL: 3571 ret = ihevcd_ctl(ps_handle, (void *)pv_api_ip, (void *)pv_api_op); 3572 break; 3573 default: 3574 ret = IV_FAIL; 3575 break; 3576 } 3577 3578 return (IV_API_CALL_STATUS_T)ret; 3579} 3580 3581