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_SET_NUM_CORES: 762 { 763 ihevcd_cxa_ctl_set_num_cores_ip_t *ps_ip; 764 ihevcd_cxa_ctl_set_num_cores_op_t *ps_op; 765 766 ps_ip = (ihevcd_cxa_ctl_set_num_cores_ip_t *)pv_api_ip; 767 ps_op = (ihevcd_cxa_ctl_set_num_cores_op_t *)pv_api_op; 768 769 if(ps_ip->u4_size 770 != sizeof(ihevcd_cxa_ctl_set_num_cores_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_set_num_cores_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#ifdef MULTICORE 788 if((ps_ip->u4_num_cores < 1) || (ps_ip->u4_num_cores > MAX_NUM_CORES)) 789#else 790 if(ps_ip->u4_num_cores != 1) 791#endif 792 { 793 ps_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM; 794 return IV_FAIL; 795 } 796 break; 797 } 798 case IHEVCD_CXA_CMD_CTL_SET_PROCESSOR: 799 { 800 ihevcd_cxa_ctl_set_processor_ip_t *ps_ip; 801 ihevcd_cxa_ctl_set_processor_op_t *ps_op; 802 803 ps_ip = (ihevcd_cxa_ctl_set_processor_ip_t *)pv_api_ip; 804 ps_op = (ihevcd_cxa_ctl_set_processor_op_t *)pv_api_op; 805 806 if(ps_ip->u4_size 807 != sizeof(ihevcd_cxa_ctl_set_processor_ip_t)) 808 { 809 ps_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM; 810 ps_op->u4_error_code |= 811 IVD_IP_API_STRUCT_SIZE_INCORRECT; 812 return IV_FAIL; 813 } 814 815 if(ps_op->u4_size 816 != sizeof(ihevcd_cxa_ctl_set_processor_op_t)) 817 { 818 ps_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM; 819 ps_op->u4_error_code |= 820 IVD_OP_API_STRUCT_SIZE_INCORRECT; 821 return IV_FAIL; 822 } 823 824 break; 825 } 826 default: 827 *(pu4_api_op + 1) |= 1 << IVD_UNSUPPORTEDPARAM; 828 *(pu4_api_op + 1) |= IVD_UNSUPPORTED_API_CMD; 829 return IV_FAIL; 830 } 831 } 832 break; 833 default: 834 *(pu4_api_op + 1) |= 1 << IVD_UNSUPPORTEDPARAM; 835 *(pu4_api_op + 1) |= IVD_UNSUPPORTED_API_CMD; 836 return IV_FAIL; 837 } 838 839 return IV_SUCCESS; 840} 841 842 843/** 844******************************************************************************* 845* 846* @brief 847* Sets default dynamic parameters 848* 849* @par Description: 850* Sets default dynamic parameters. Will be called in ihevcd_init() to ensure 851* that even if set_params is not called, codec continues to work 852* 853* @param[in] ps_codec_obj 854* Pointer to codec object at API level 855* 856* @param[in] pv_api_ip 857* Pointer to input argument structure 858* 859* @param[out] pv_api_op 860* Pointer to output argument structure 861* 862* @returns Status 863* 864* @remarks 865* 866* 867******************************************************************************* 868*/ 869WORD32 ihevcd_set_default_params(codec_t *ps_codec) 870{ 871 872 WORD32 ret = IV_SUCCESS; 873 874 ps_codec->e_pic_skip_mode = IVD_SKIP_NONE; 875 ps_codec->i4_strd = 0; 876 ps_codec->i4_disp_strd = 0; 877 ps_codec->i4_header_mode = 0; 878 ps_codec->e_pic_out_order = IVD_DISPLAY_FRAME_OUT; 879 return ret; 880} 881 882void ihevcd_update_function_ptr(codec_t *ps_codec) 883{ 884 885 /* Init inter pred function array */ 886 ps_codec->apf_inter_pred[0] = NULL; 887 ps_codec->apf_inter_pred[1] = (pf_inter_pred)ps_codec->s_func_selector.ihevc_inter_pred_luma_copy_fptr; 888 ps_codec->apf_inter_pred[2] = (pf_inter_pred)ps_codec->s_func_selector.ihevc_inter_pred_luma_vert_fptr; 889 ps_codec->apf_inter_pred[3] = (pf_inter_pred)ps_codec->s_func_selector.ihevc_inter_pred_luma_horz_fptr; 890 ps_codec->apf_inter_pred[4] = (pf_inter_pred)ps_codec->s_func_selector.ihevc_inter_pred_luma_horz_w16out_fptr; 891 ps_codec->apf_inter_pred[5] = (pf_inter_pred)ps_codec->s_func_selector.ihevc_inter_pred_luma_copy_w16out_fptr; 892 ps_codec->apf_inter_pred[6] = (pf_inter_pred)ps_codec->s_func_selector.ihevc_inter_pred_luma_vert_w16out_fptr; 893 ps_codec->apf_inter_pred[7] = (pf_inter_pred)ps_codec->s_func_selector.ihevc_inter_pred_luma_horz_w16out_fptr; 894 ps_codec->apf_inter_pred[8] = (pf_inter_pred)ps_codec->s_func_selector.ihevc_inter_pred_luma_horz_w16out_fptr; 895 ps_codec->apf_inter_pred[9] = (pf_inter_pred)ps_codec->s_func_selector.ihevc_inter_pred_luma_vert_w16inp_fptr; 896 ps_codec->apf_inter_pred[10] = (pf_inter_pred)ps_codec->s_func_selector.ihevc_inter_pred_luma_vert_w16inp_w16out_fptr; 897 ps_codec->apf_inter_pred[11] = NULL; 898 ps_codec->apf_inter_pred[12] = (pf_inter_pred)ps_codec->s_func_selector.ihevc_inter_pred_chroma_copy_fptr; 899 ps_codec->apf_inter_pred[13] = (pf_inter_pred)ps_codec->s_func_selector.ihevc_inter_pred_chroma_vert_fptr; 900 ps_codec->apf_inter_pred[14] = (pf_inter_pred)ps_codec->s_func_selector.ihevc_inter_pred_chroma_horz_fptr; 901 ps_codec->apf_inter_pred[15] = (pf_inter_pred)ps_codec->s_func_selector.ihevc_inter_pred_chroma_horz_w16out_fptr; 902 ps_codec->apf_inter_pred[16] = (pf_inter_pred)ps_codec->s_func_selector.ihevc_inter_pred_chroma_copy_w16out_fptr; 903 ps_codec->apf_inter_pred[17] = (pf_inter_pred)ps_codec->s_func_selector.ihevc_inter_pred_chroma_vert_w16out_fptr; 904 ps_codec->apf_inter_pred[18] = (pf_inter_pred)ps_codec->s_func_selector.ihevc_inter_pred_chroma_horz_w16out_fptr; 905 ps_codec->apf_inter_pred[19] = (pf_inter_pred)ps_codec->s_func_selector.ihevc_inter_pred_chroma_horz_w16out_fptr; 906 ps_codec->apf_inter_pred[20] = (pf_inter_pred)ps_codec->s_func_selector.ihevc_inter_pred_chroma_vert_w16inp_fptr; 907 ps_codec->apf_inter_pred[21] = (pf_inter_pred)ps_codec->s_func_selector.ihevc_inter_pred_chroma_vert_w16inp_w16out_fptr; 908 909 /* Init intra pred function array */ 910 ps_codec->apf_intra_pred_luma[0] = (pf_intra_pred)NULL; 911 ps_codec->apf_intra_pred_luma[1] = (pf_intra_pred)ps_codec->s_func_selector.ihevc_intra_pred_luma_planar_fptr; 912 ps_codec->apf_intra_pred_luma[2] = (pf_intra_pred)ps_codec->s_func_selector.ihevc_intra_pred_luma_dc_fptr; 913 ps_codec->apf_intra_pred_luma[3] = (pf_intra_pred)ps_codec->s_func_selector.ihevc_intra_pred_luma_mode2_fptr; 914 ps_codec->apf_intra_pred_luma[4] = (pf_intra_pred)ps_codec->s_func_selector.ihevc_intra_pred_luma_mode_3_to_9_fptr; 915 ps_codec->apf_intra_pred_luma[5] = (pf_intra_pred)ps_codec->s_func_selector.ihevc_intra_pred_luma_horz_fptr; 916 ps_codec->apf_intra_pred_luma[6] = (pf_intra_pred)ps_codec->s_func_selector.ihevc_intra_pred_luma_mode_11_to_17_fptr; 917 ps_codec->apf_intra_pred_luma[7] = (pf_intra_pred)ps_codec->s_func_selector.ihevc_intra_pred_luma_mode_18_34_fptr; 918 ps_codec->apf_intra_pred_luma[8] = (pf_intra_pred)ps_codec->s_func_selector.ihevc_intra_pred_luma_mode_19_to_25_fptr; 919 ps_codec->apf_intra_pred_luma[9] = (pf_intra_pred)ps_codec->s_func_selector.ihevc_intra_pred_luma_ver_fptr; 920 ps_codec->apf_intra_pred_luma[10] = (pf_intra_pred)ps_codec->s_func_selector.ihevc_intra_pred_luma_mode_27_to_33_fptr; 921 922 ps_codec->apf_intra_pred_chroma[0] = (pf_intra_pred)NULL; 923 ps_codec->apf_intra_pred_chroma[1] = (pf_intra_pred)ps_codec->s_func_selector.ihevc_intra_pred_chroma_planar_fptr; 924 ps_codec->apf_intra_pred_chroma[2] = (pf_intra_pred)ps_codec->s_func_selector.ihevc_intra_pred_chroma_dc_fptr; 925 ps_codec->apf_intra_pred_chroma[3] = (pf_intra_pred)ps_codec->s_func_selector.ihevc_intra_pred_chroma_mode2_fptr; 926 ps_codec->apf_intra_pred_chroma[4] = (pf_intra_pred)ps_codec->s_func_selector.ihevc_intra_pred_chroma_mode_3_to_9_fptr; 927 ps_codec->apf_intra_pred_chroma[5] = (pf_intra_pred)ps_codec->s_func_selector.ihevc_intra_pred_chroma_horz_fptr; 928 ps_codec->apf_intra_pred_chroma[6] = (pf_intra_pred)ps_codec->s_func_selector.ihevc_intra_pred_chroma_mode_11_to_17_fptr; 929 ps_codec->apf_intra_pred_chroma[7] = (pf_intra_pred)ps_codec->s_func_selector.ihevc_intra_pred_chroma_mode_18_34_fptr; 930 ps_codec->apf_intra_pred_chroma[8] = (pf_intra_pred)ps_codec->s_func_selector.ihevc_intra_pred_chroma_mode_19_to_25_fptr; 931 ps_codec->apf_intra_pred_chroma[9] = (pf_intra_pred)ps_codec->s_func_selector.ihevc_intra_pred_chroma_ver_fptr; 932 ps_codec->apf_intra_pred_chroma[10] = (pf_intra_pred)ps_codec->s_func_selector.ihevc_intra_pred_chroma_mode_27_to_33_fptr; 933 934 /* Init itrans_recon function array */ 935 ps_codec->apf_itrans_recon[0] = (pf_itrans_recon)ps_codec->s_func_selector.ihevc_itrans_recon_4x4_ttype1_fptr; 936 ps_codec->apf_itrans_recon[1] = (pf_itrans_recon)ps_codec->s_func_selector.ihevc_itrans_recon_4x4_fptr; 937 ps_codec->apf_itrans_recon[2] = (pf_itrans_recon)ps_codec->s_func_selector.ihevc_itrans_recon_8x8_fptr; 938 ps_codec->apf_itrans_recon[3] = (pf_itrans_recon)ps_codec->s_func_selector.ihevc_itrans_recon_16x16_fptr; 939 ps_codec->apf_itrans_recon[4] = (pf_itrans_recon)ps_codec->s_func_selector.ihevc_itrans_recon_32x32_fptr; 940 ps_codec->apf_itrans_recon[5] = (pf_itrans_recon)ps_codec->s_func_selector.ihevc_chroma_itrans_recon_4x4_fptr; 941 ps_codec->apf_itrans_recon[6] = (pf_itrans_recon)ps_codec->s_func_selector.ihevc_chroma_itrans_recon_8x8_fptr; 942 ps_codec->apf_itrans_recon[7] = (pf_itrans_recon)ps_codec->s_func_selector.ihevc_chroma_itrans_recon_16x16_fptr; 943 944 /* Init recon function array */ 945 ps_codec->apf_recon[0] = (pf_recon)ps_codec->s_func_selector.ihevc_recon_4x4_ttype1_fptr; 946 ps_codec->apf_recon[1] = (pf_recon)ps_codec->s_func_selector.ihevc_recon_4x4_fptr; 947 ps_codec->apf_recon[2] = (pf_recon)ps_codec->s_func_selector.ihevc_recon_8x8_fptr; 948 ps_codec->apf_recon[3] = (pf_recon)ps_codec->s_func_selector.ihevc_recon_16x16_fptr; 949 ps_codec->apf_recon[4] = (pf_recon)ps_codec->s_func_selector.ihevc_recon_32x32_fptr; 950 ps_codec->apf_recon[5] = (pf_recon)ps_codec->s_func_selector.ihevc_chroma_recon_4x4_fptr; 951 ps_codec->apf_recon[6] = (pf_recon)ps_codec->s_func_selector.ihevc_chroma_recon_8x8_fptr; 952 ps_codec->apf_recon[7] = (pf_recon)ps_codec->s_func_selector.ihevc_chroma_recon_16x16_fptr; 953 954 /* Init itrans_recon_dc function array */ 955 ps_codec->apf_itrans_recon_dc[0] = (pf_itrans_recon_dc)ps_codec->s_func_selector.ihevcd_itrans_recon_dc_luma_fptr; 956 ps_codec->apf_itrans_recon_dc[1] = (pf_itrans_recon_dc)ps_codec->s_func_selector.ihevcd_itrans_recon_dc_chroma_fptr; 957 958 /* Init sao function array */ 959 ps_codec->apf_sao_luma[0] = (pf_sao_luma)ps_codec->s_func_selector.ihevc_sao_edge_offset_class0_fptr; 960 ps_codec->apf_sao_luma[1] = (pf_sao_luma)ps_codec->s_func_selector.ihevc_sao_edge_offset_class1_fptr; 961 ps_codec->apf_sao_luma[2] = (pf_sao_luma)ps_codec->s_func_selector.ihevc_sao_edge_offset_class2_fptr; 962 ps_codec->apf_sao_luma[3] = (pf_sao_luma)ps_codec->s_func_selector.ihevc_sao_edge_offset_class3_fptr; 963 964 ps_codec->apf_sao_chroma[0] = (pf_sao_chroma)ps_codec->s_func_selector.ihevc_sao_edge_offset_class0_chroma_fptr; 965 ps_codec->apf_sao_chroma[1] = (pf_sao_chroma)ps_codec->s_func_selector.ihevc_sao_edge_offset_class1_chroma_fptr; 966 ps_codec->apf_sao_chroma[2] = (pf_sao_chroma)ps_codec->s_func_selector.ihevc_sao_edge_offset_class2_chroma_fptr; 967 ps_codec->apf_sao_chroma[3] = (pf_sao_chroma)ps_codec->s_func_selector.ihevc_sao_edge_offset_class3_chroma_fptr; 968} 969/** 970******************************************************************************* 971* 972* @brief 973* Initialize the context. This will be called by create and during 974* reset 975* 976* @par Description: 977* Initializes the context 978* 979* @param[in] ps_codec 980* Codec context pointer 981* 982* @returns Status 983* 984* @remarks 985* 986* 987******************************************************************************* 988*/ 989WORD32 ihevcd_init(codec_t *ps_codec) 990{ 991 WORD32 status = IV_SUCCESS; 992 WORD32 i; 993 994 /* Free any dynamic buffers that are allocated */ 995 ihevcd_free_dynamic_bufs(ps_codec); 996 997 ps_codec->u4_allocate_dynamic_done = 0; 998 ps_codec->i4_num_disp_bufs = 1; 999 ps_codec->i4_flush_mode = 0; 1000 1001 ps_codec->i4_ht = ps_codec->i4_disp_ht = 0; 1002 ps_codec->i4_wd = ps_codec->i4_disp_wd = 0; 1003 ps_codec->i4_strd = 0; 1004 ps_codec->i4_disp_strd = 0; 1005 ps_codec->i4_num_cores = 1; 1006 1007 ps_codec->u4_pic_cnt = 0; 1008 ps_codec->u4_disp_cnt = 0; 1009 1010 ps_codec->i4_header_mode = 0; 1011 ps_codec->i4_header_in_slice_mode = 0; 1012 ps_codec->i4_sps_done = 0; 1013 ps_codec->i4_pps_done = 0; 1014 ps_codec->i4_init_done = 1; 1015 ps_codec->i4_first_pic_done = 0; 1016 ps_codec->s_parse.i4_first_pic_init = 0; 1017 ps_codec->i4_error_code = 0; 1018 ps_codec->i4_reset_flag = 0; 1019 ps_codec->i4_cra_as_first_pic = 1; 1020 ps_codec->i4_rasl_output_flag = 0; 1021 1022 ps_codec->i4_prev_poc_msb = 0; 1023 ps_codec->i4_prev_poc_lsb = -1; 1024 ps_codec->i4_max_prev_poc_lsb = -1; 1025 ps_codec->s_parse.i4_abs_pic_order_cnt = -1; 1026 1027 /* Set ref chroma format by default to 420SP UV interleaved */ 1028 ps_codec->e_ref_chroma_fmt = IV_YUV_420SP_UV; 1029 1030 /* If the codec is in shared mode and required format is 420 SP VU interleaved then change 1031 * reference buffers chroma format 1032 */ 1033 if(IV_YUV_420SP_VU == ps_codec->e_chroma_fmt) 1034 { 1035 ps_codec->e_ref_chroma_fmt = IV_YUV_420SP_VU; 1036 } 1037 1038 1039 1040 ps_codec->i4_disable_deblk_pic = 0; 1041 1042 ps_codec->i4_degrade_pic_cnt = 0; 1043 ps_codec->i4_degrade_pics = 0; 1044 ps_codec->i4_degrade_type = 0; 1045 ps_codec->i4_disable_sao_pic = 0; 1046 ps_codec->i4_fullpel_inter_pred = 0; 1047 ps_codec->u4_enable_fmt_conv_ahead = 0; 1048 ps_codec->i4_share_disp_buf_cnt = 0; 1049 1050 { 1051 sps_t *ps_sps = ps_codec->ps_sps_base; 1052 pps_t *ps_pps = ps_codec->ps_pps_base; 1053 1054 for(i = 0; i < MAX_SPS_CNT; i++) 1055 { 1056 ps_sps->i1_sps_valid = 0; 1057 ps_sps++; 1058 } 1059 1060 for(i = 0; i < MAX_PPS_CNT; i++) 1061 { 1062 ps_pps->i1_pps_valid = 0; 1063 ps_pps++; 1064 } 1065 } 1066 1067 ihevcd_set_default_params(ps_codec); 1068 /* Initialize MV Bank buffer manager */ 1069 ihevc_buf_mgr_init((buf_mgr_t *)ps_codec->pv_mv_buf_mgr); 1070 1071 /* Initialize Picture buffer manager */ 1072 ihevc_buf_mgr_init((buf_mgr_t *)ps_codec->pv_pic_buf_mgr); 1073 1074 ps_codec->ps_pic_buf = (pic_buf_t *)ps_codec->pv_pic_buf_base; 1075 1076 memset(ps_codec->ps_pic_buf, 0, BUF_MGR_MAX_CNT * sizeof(pic_buf_t)); 1077 1078 1079 1080 /* Initialize display buffer manager */ 1081 ihevc_disp_mgr_init((disp_mgr_t *)ps_codec->pv_disp_buf_mgr); 1082 1083 /* Initialize dpb manager */ 1084 ihevc_dpb_mgr_init((dpb_mgr_t *)ps_codec->pv_dpb_mgr); 1085 1086 ps_codec->e_processor_soc = SOC_GENERIC; 1087 /* The following can be over-ridden using soc parameter as a hack */ 1088 ps_codec->u4_nctb = 0x7FFFFFFF; 1089 ihevcd_init_arch(ps_codec); 1090 1091 ihevcd_init_function_ptr(ps_codec); 1092 1093 ihevcd_update_function_ptr(ps_codec); 1094 1095 return status; 1096} 1097 1098/** 1099******************************************************************************* 1100* 1101* @brief 1102* Allocate static memory for the codec 1103* 1104* @par Description: 1105* Allocates static memory for the codec 1106* 1107* @param[in] pv_api_ip 1108* Pointer to input argument structure 1109* 1110* @param[out] pv_api_op 1111* Pointer to output argument structure 1112* 1113* @returns Status 1114* 1115* @remarks 1116* 1117* 1118******************************************************************************* 1119*/ 1120WORD32 ihevcd_allocate_static_bufs(iv_obj_t **pps_codec_obj, 1121 ihevcd_cxa_create_ip_t *ps_create_ip, 1122 ihevcd_cxa_create_op_t *ps_create_op) 1123{ 1124 WORD32 size; 1125 void *pv_buf; 1126 UWORD8 *pu1_buf; 1127 WORD32 i; 1128 codec_t *ps_codec; 1129 IV_API_CALL_STATUS_T status = IV_SUCCESS; 1130 void *(*pf_aligned_alloc)(void *pv_mem_ctxt, WORD32 alignment, WORD32 size); 1131 void (*pf_aligned_free)(void *pv_mem_ctxt, void *pv_buf); 1132 void *pv_mem_ctxt; 1133 1134 /* Request memory for HEVCD object */ 1135 ps_create_op->s_ivd_create_op_t.pv_handle = NULL; 1136 1137 pf_aligned_alloc = ps_create_ip->s_ivd_create_ip_t.pf_aligned_alloc; 1138 pf_aligned_free = ps_create_ip->s_ivd_create_ip_t.pf_aligned_free; 1139 pv_mem_ctxt = ps_create_ip->s_ivd_create_ip_t.pv_mem_ctxt; 1140 1141 1142 pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, sizeof(iv_obj_t)); 1143 RETURN_IF((NULL == pv_buf), IV_FAIL); 1144 *pps_codec_obj = (iv_obj_t *)pv_buf; 1145 ps_create_op->s_ivd_create_op_t.pv_handle = *pps_codec_obj; 1146 1147 1148 (*pps_codec_obj)->pv_codec_handle = NULL; 1149 pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, sizeof(codec_t)); 1150 RETURN_IF((NULL == pv_buf), IV_FAIL); 1151 (*pps_codec_obj)->pv_codec_handle = (codec_t *)pv_buf; 1152 ps_codec = (codec_t *)pv_buf; 1153 1154 memset(ps_codec, 0, sizeof(codec_t)); 1155 1156#ifndef LOGO_EN 1157 ps_codec->i4_share_disp_buf = ps_create_ip->s_ivd_create_ip_t.u4_share_disp_buf; 1158#else 1159 ps_codec->i4_share_disp_buf = 0; 1160#endif 1161 1162 /* Shared display mode is supported only for 420SP and 420P formats */ 1163 if((ps_create_ip->s_ivd_create_ip_t.e_output_format != IV_YUV_420P) && 1164 (ps_create_ip->s_ivd_create_ip_t.e_output_format != IV_YUV_420SP_UV) && 1165 (ps_create_ip->s_ivd_create_ip_t.e_output_format != IV_YUV_420SP_VU)) 1166 { 1167 ps_codec->i4_share_disp_buf = 0; 1168 } 1169 1170 ps_codec->e_chroma_fmt = ps_create_ip->s_ivd_create_ip_t.e_output_format; 1171 1172 ps_codec->pf_aligned_alloc = pf_aligned_alloc; 1173 ps_codec->pf_aligned_free = pf_aligned_free; 1174 ps_codec->pv_mem_ctxt = pv_mem_ctxt; 1175 1176 /* Request memory to hold thread handles for each processing thread */ 1177 size = MAX_PROCESS_THREADS * ithread_get_handle_size(); 1178 pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size); 1179 RETURN_IF((NULL == pv_buf), IV_FAIL); 1180 1181 for(i = 0; i < MAX_PROCESS_THREADS; i++) 1182 { 1183 WORD32 handle_size = ithread_get_handle_size(); 1184 ps_codec->apv_process_thread_handle[i] = 1185 (UWORD8 *)pv_buf + (i * handle_size); 1186 } 1187 1188 /* Request memory for static bitstream buffer which holds bitstream after emulation prevention */ 1189 size = MIN_BITSBUF_SIZE; 1190 pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size); 1191 RETURN_IF((NULL == pv_buf), IV_FAIL); 1192 ps_codec->pu1_bitsbuf_static = pv_buf; 1193 ps_codec->u4_bitsbuf_size_static = size; 1194 1195 /* size for holding display manager context */ 1196 size = sizeof(buf_mgr_t); 1197 pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size); 1198 RETURN_IF((NULL == pv_buf), IV_FAIL); 1199 ps_codec->pv_disp_buf_mgr = pv_buf; 1200 1201 /* size for holding dpb manager context */ 1202 size = sizeof(dpb_mgr_t); 1203 pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size); 1204 RETURN_IF((NULL == pv_buf), IV_FAIL); 1205 ps_codec->pv_dpb_mgr = pv_buf; 1206 1207 /* size for holding buffer manager context */ 1208 size = sizeof(buf_mgr_t); 1209 pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size); 1210 RETURN_IF((NULL == pv_buf), IV_FAIL); 1211 ps_codec->pv_pic_buf_mgr = pv_buf; 1212 1213 /* size for holding mv buffer manager context */ 1214 size = sizeof(buf_mgr_t); 1215 pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size); 1216 RETURN_IF((NULL == pv_buf), IV_FAIL); 1217 ps_codec->pv_mv_buf_mgr = pv_buf; 1218 1219 size = MAX_VPS_CNT * sizeof(vps_t); 1220 pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size); 1221 RETURN_IF((NULL == pv_buf), IV_FAIL); 1222 ps_codec->ps_vps_base = pv_buf; 1223 ps_codec->s_parse.ps_vps_base = ps_codec->ps_vps_base; 1224 1225 size = MAX_SPS_CNT * sizeof(sps_t); 1226 pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size); 1227 RETURN_IF((NULL == pv_buf), IV_FAIL); 1228 ps_codec->ps_sps_base = pv_buf; 1229 ps_codec->s_parse.ps_sps_base = ps_codec->ps_sps_base; 1230 1231 size = MAX_PPS_CNT * sizeof(pps_t); 1232 pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size); 1233 RETURN_IF((NULL == pv_buf), IV_FAIL); 1234 ps_codec->ps_pps_base = pv_buf; 1235 ps_codec->s_parse.ps_pps_base = ps_codec->ps_pps_base; 1236 1237 size = MAX_SLICE_HDR_CNT * sizeof(slice_header_t); 1238 pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size); 1239 RETURN_IF((NULL == pv_buf), IV_FAIL); 1240 memset(pv_buf, 0, size); 1241 ps_codec->ps_slice_hdr_base = (slice_header_t *)pv_buf; 1242 ps_codec->s_parse.ps_slice_hdr_base = ps_codec->ps_slice_hdr_base; 1243 1244 1245 SCALING_MAT_SIZE(size) 1246 size = (MAX_SPS_CNT + MAX_PPS_CNT) * size * sizeof(WORD16); 1247 pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size); 1248 RETURN_IF((NULL == pv_buf), IV_FAIL); 1249 ps_codec->pi2_scaling_mat = (WORD16 *)pv_buf; 1250 1251 1252 /* Size for holding pic_buf_t for each reference picture 1253 * Since this is only a structure allocation and not actual buffer allocation, 1254 * it is allocated for BUF_MGR_MAX_CNT entries 1255 */ 1256 size = BUF_MGR_MAX_CNT * sizeof(pic_buf_t); 1257 pv_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size); 1258 RETURN_IF((NULL == pv_buf), IV_FAIL); 1259 ps_codec->pv_pic_buf_base = (UWORD8 *)pv_buf; 1260 1261 /* TO hold scratch buffers needed for each SAO context */ 1262 size = 4 * MAX_CTB_SIZE * MAX_CTB_SIZE; 1263 1264 /* 2 temporary buffers*/ 1265 size *= 2; 1266 size *= MAX_PROCESS_THREADS; 1267 1268 pu1_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size); 1269 RETURN_IF((NULL == pu1_buf), IV_FAIL); 1270 1271 for(i = 0; i < MAX_PROCESS_THREADS; i++) 1272 { 1273 ps_codec->as_process[i].s_sao_ctxt.pu1_tmp_buf_luma = (UWORD8 *)pu1_buf; 1274 pu1_buf += 4 * MAX_CTB_SIZE * MAX_CTB_SIZE * sizeof(UWORD8); 1275 1276 ps_codec->as_process[i].s_sao_ctxt.pu1_tmp_buf_chroma = (UWORD8 *)pu1_buf; 1277 pu1_buf += 4 * MAX_CTB_SIZE * MAX_CTB_SIZE * sizeof(UWORD8); 1278 } 1279 1280 /* Allocate intra pred modes buffer */ 1281 /* 8 bits per 4x4 */ 1282 /* 16 bytes each for top and left 64 pixels and 16 bytes for default mode */ 1283 size = 3 * 16 * sizeof(UWORD8); 1284 pu1_buf = pf_aligned_alloc(pv_mem_ctxt, 128, size); 1285 RETURN_IF((NULL == pu1_buf), IV_FAIL); 1286 ps_codec->s_parse.pu1_luma_intra_pred_mode_left = pu1_buf; 1287 ps_codec->s_parse.pu1_luma_intra_pred_mode_top = pu1_buf + 16; 1288 1289 { 1290 WORD32 inter_pred_tmp_buf_size, ntaps_luma; 1291 WORD32 pic_pu_idx_map_size; 1292 1293 /* Max inter pred size */ 1294 ntaps_luma = 8; 1295 inter_pred_tmp_buf_size = sizeof(WORD16) * (MAX_CTB_SIZE + ntaps_luma) * MAX_CTB_SIZE; 1296 1297 inter_pred_tmp_buf_size = ALIGN64(inter_pred_tmp_buf_size); 1298 1299 /* To hold pu_index w.r.t. frame level pu_t array for a CTB */ 1300 pic_pu_idx_map_size = sizeof(WORD32) * (18 * 18); 1301 pic_pu_idx_map_size = ALIGN64(pic_pu_idx_map_size); 1302 1303 size = inter_pred_tmp_buf_size * 2; 1304 size += pic_pu_idx_map_size; 1305 size *= MAX_PROCESS_THREADS; 1306 1307 pu1_buf = ps_codec->pf_aligned_alloc(pv_mem_ctxt, 128, size); 1308 RETURN_IF((NULL == pu1_buf), IV_FAIL); 1309 memset(pu1_buf, 0, size); 1310 1311 for(i = 0; i < MAX_PROCESS_THREADS; i++) 1312 { 1313 ps_codec->as_process[i].pi2_inter_pred_tmp_buf1 = (WORD16 *)pu1_buf; 1314 pu1_buf += inter_pred_tmp_buf_size; 1315 1316 ps_codec->as_process[i].pi2_inter_pred_tmp_buf2 = (WORD16 *)pu1_buf; 1317 pu1_buf += inter_pred_tmp_buf_size; 1318 1319 /* Inverse transform intermediate and inverse scan output buffers reuse inter pred scratch buffers */ 1320 ps_codec->as_process[i].pi2_itrans_intrmd_buf = 1321 ps_codec->as_process[i].pi2_inter_pred_tmp_buf2; 1322 ps_codec->as_process[i].pi2_invscan_out = 1323 ps_codec->as_process[i].pi2_inter_pred_tmp_buf1; 1324 1325 ps_codec->as_process[i].pu4_pic_pu_idx_map = (UWORD32 *)pu1_buf; 1326 ps_codec->as_process[i].s_bs_ctxt.pu4_pic_pu_idx_map = 1327 (UWORD32 *)pu1_buf; 1328 pu1_buf += pic_pu_idx_map_size; 1329 1330 // ps_codec->as_process[i].pi2_inter_pred_tmp_buf3 = (WORD16 *)pu1_buf; 1331 // pu1_buf += inter_pred_tmp_buf_size; 1332 1333 ps_codec->as_process[i].i4_inter_pred_tmp_buf_strd = MAX_CTB_SIZE; 1334 1335 } 1336 } 1337 /* Initialize pointers in PPS structures */ 1338 { 1339 sps_t *ps_sps = ps_codec->ps_sps_base; 1340 pps_t *ps_pps = ps_codec->ps_pps_base; 1341 WORD16 *pi2_scaling_mat = ps_codec->pi2_scaling_mat; 1342 WORD32 scaling_mat_size; 1343 1344 SCALING_MAT_SIZE(scaling_mat_size); 1345 1346 for(i = 0; i < MAX_SPS_CNT; i++) 1347 { 1348 ps_sps->pi2_scaling_mat = pi2_scaling_mat; 1349 pi2_scaling_mat += scaling_mat_size; 1350 ps_sps++; 1351 } 1352 1353 for(i = 0; i < MAX_PPS_CNT; i++) 1354 { 1355 ps_pps->pi2_scaling_mat = pi2_scaling_mat; 1356 pi2_scaling_mat += scaling_mat_size; 1357 ps_pps++; 1358 } 1359 } 1360 1361 return (status); 1362} 1363 1364/** 1365******************************************************************************* 1366* 1367* @brief 1368* Free static memory for the codec 1369* 1370* @par Description: 1371* Free static memory for the codec 1372* 1373* @param[in] ps_codec 1374* Pointer to codec context 1375* 1376* @returns Status 1377* 1378* @remarks 1379* 1380* 1381******************************************************************************* 1382*/ 1383WORD32 ihevcd_free_static_bufs(iv_obj_t *ps_codec_obj) 1384{ 1385 codec_t *ps_codec; 1386 1387 void (*pf_aligned_free)(void *pv_mem_ctxt, void *pv_buf); 1388 void *pv_mem_ctxt; 1389 1390 ps_codec = (codec_t *)ps_codec_obj->pv_codec_handle; 1391 pf_aligned_free = ps_codec->pf_aligned_free; 1392 pv_mem_ctxt = ps_codec->pv_mem_ctxt; 1393 1394 1395 ALIGNED_FREE(ps_codec, ps_codec->apv_process_thread_handle[0]); 1396 ALIGNED_FREE(ps_codec, ps_codec->pu1_bitsbuf_static); 1397 1398 ALIGNED_FREE(ps_codec, ps_codec->pv_disp_buf_mgr); 1399 ALIGNED_FREE(ps_codec, ps_codec->pv_dpb_mgr); 1400 ALIGNED_FREE(ps_codec, ps_codec->pv_pic_buf_mgr); 1401 ALIGNED_FREE(ps_codec, ps_codec->pv_mv_buf_mgr); 1402 ALIGNED_FREE(ps_codec, ps_codec->ps_vps_base); 1403 ALIGNED_FREE(ps_codec, ps_codec->ps_sps_base); 1404 ALIGNED_FREE(ps_codec, ps_codec->ps_pps_base); 1405 ALIGNED_FREE(ps_codec, ps_codec->ps_slice_hdr_base); 1406 ALIGNED_FREE(ps_codec, ps_codec->pi2_scaling_mat); 1407 ALIGNED_FREE(ps_codec, ps_codec->pv_pic_buf_base); 1408 ALIGNED_FREE(ps_codec, ps_codec->s_parse.pu1_luma_intra_pred_mode_left); 1409 ALIGNED_FREE(ps_codec, ps_codec->as_process[0].s_sao_ctxt.pu1_tmp_buf_luma); 1410 ALIGNED_FREE(ps_codec, ps_codec->as_process[0].pi2_inter_pred_tmp_buf1); 1411 ALIGNED_FREE(ps_codec, ps_codec_obj->pv_codec_handle); 1412 1413 if(ps_codec_obj) 1414 { 1415 pf_aligned_free(pv_mem_ctxt, ps_codec_obj); 1416 } 1417 1418 return IV_SUCCESS; 1419 1420} 1421 1422 1423/** 1424******************************************************************************* 1425* 1426* @brief 1427* Allocate dynamic memory for the codec 1428* 1429* @par Description: 1430* Allocates dynamic memory for the codec 1431* 1432* @param[in] ps_codec 1433* Pointer to codec context 1434* 1435* @returns Status 1436* 1437* @remarks 1438* 1439* 1440******************************************************************************* 1441*/ 1442WORD32 ihevcd_allocate_dynamic_bufs(codec_t *ps_codec) 1443{ 1444 WORD32 max_tile_cols, max_tile_rows; 1445 WORD32 max_ctb_rows, max_ctb_cols; 1446 WORD32 max_num_cu_cols; 1447 WORD32 max_num_cu_rows; 1448 WORD32 max_num_4x4_cols; 1449 WORD32 max_ctb_cnt; 1450 WORD32 wd; 1451 WORD32 ht; 1452 WORD32 i; 1453 WORD32 max_dpb_size; 1454 void *pv_mem_ctxt = ps_codec->pv_mem_ctxt; 1455 void *pv_buf; 1456 UWORD8 *pu1_buf; 1457 WORD32 size; 1458 1459 wd = ALIGN64(ps_codec->i4_wd); 1460 ht = ALIGN64(ps_codec->i4_ht); 1461 1462 max_tile_cols = (wd + MIN_TILE_WD - 1) / MIN_TILE_WD; 1463 max_tile_rows = (ht + MIN_TILE_HT - 1) / MIN_TILE_HT; 1464 max_ctb_rows = ht / MIN_CTB_SIZE; 1465 max_ctb_cols = wd / MIN_CTB_SIZE; 1466 max_ctb_cnt = max_ctb_rows * max_ctb_cols; 1467 max_num_cu_cols = wd / MIN_CU_SIZE; 1468 max_num_cu_rows = ht / MIN_CU_SIZE; 1469 max_num_4x4_cols = wd / 4; 1470 1471 /* Allocate tile structures */ 1472 size = max_tile_cols * max_tile_rows; 1473 size *= sizeof(tile_t); 1474 size *= MAX_PPS_CNT; 1475 1476 pv_buf = ps_codec->pf_aligned_alloc(pv_mem_ctxt, 128, size); 1477 RETURN_IF((NULL == pv_buf), IV_FAIL); 1478 memset(pv_buf, 0, size); 1479 ps_codec->ps_tile = (tile_t *)pv_buf; 1480 1481 1482 /* Allocate memory to hold entry point offsets */ 1483 /* One entry point per tile */ 1484 size = max_tile_cols * max_tile_rows; 1485 1486 /* One entry point per row of CTBs */ 1487 /*********************************************************************/ 1488 /* Only tiles or entropy sync is enabled at a time in main */ 1489 /* profile, but since memory required does not increase too much, */ 1490 /* this allocation is done to handle both cases */ 1491 /*********************************************************************/ 1492 size += max_ctb_rows; 1493 size *= sizeof(WORD32); 1494 1495 pv_buf = ps_codec->pf_aligned_alloc(pv_mem_ctxt, 128, size); 1496 RETURN_IF((NULL == pv_buf), IV_FAIL); 1497 memset(pv_buf, 0, size); 1498 ps_codec->pi4_entry_ofst = (WORD32 *)pv_buf; 1499 1500 /* Allocate parse skip flag buffer */ 1501 /* 1 bit per 8x8 */ 1502 size = max_num_cu_cols / 8; 1503 size = ALIGN4(size); 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->s_parse.pu4_skip_cu_top = (UWORD32 *)pv_buf; 1508 1509 /* Allocate parse coding tree depth buffer */ 1510 /* 2 bits per 8x8 */ 1511 size = max_num_cu_cols / 4; 1512 size = ALIGN4(size); 1513 pv_buf = ps_codec->pf_aligned_alloc(pv_mem_ctxt, 128, size); 1514 RETURN_IF((NULL == pv_buf), IV_FAIL); 1515 memset(pv_buf, 0, size); 1516 ps_codec->s_parse.pu4_ct_depth_top = (UWORD32 *)pv_buf; 1517 1518 /* Allocate intra flag buffer */ 1519 /* 1 bit per 8x8 */ 1520 size = max_num_cu_cols * max_num_cu_rows / 8; 1521 size = ALIGN4(size); 1522 pv_buf = ps_codec->pf_aligned_alloc(pv_mem_ctxt, 128, size); 1523 RETURN_IF((NULL == pv_buf), IV_FAIL); 1524 memset(pv_buf, 0, size); 1525 ps_codec->pu1_pic_intra_flag = (UWORD8 *)pv_buf; 1526 ps_codec->s_parse.pu1_pic_intra_flag = ps_codec->pu1_pic_intra_flag; 1527 1528 /* Allocate transquant bypass flag buffer */ 1529 /* 1 bit per 8x8 */ 1530 /* Extra row and column are allocated for easy processing of top and left blocks while loop filtering */ 1531 size = ((max_num_cu_cols + 8) * (max_num_cu_rows + 8)) / 8; 1532 size = ALIGN4(size); 1533 pv_buf = ps_codec->pf_aligned_alloc(pv_mem_ctxt, 128, size); 1534 RETURN_IF((NULL == pv_buf), IV_FAIL); 1535 memset(pv_buf, 1, size); 1536 { 1537 WORD32 loop_filter_strd = (wd + 63) >> 6; 1538 ps_codec->pu1_pic_no_loop_filter_flag_base = pv_buf; 1539 /* The offset is added for easy processing of top and left blocks while loop filtering */ 1540 ps_codec->pu1_pic_no_loop_filter_flag = (UWORD8 *)pv_buf + loop_filter_strd + 1; 1541 ps_codec->s_parse.pu1_pic_no_loop_filter_flag = ps_codec->pu1_pic_no_loop_filter_flag; 1542 ps_codec->s_parse.s_deblk_ctxt.pu1_pic_no_loop_filter_flag = ps_codec->pu1_pic_no_loop_filter_flag; 1543 ps_codec->s_parse.s_sao_ctxt.pu1_pic_no_loop_filter_flag = ps_codec->pu1_pic_no_loop_filter_flag; 1544 } 1545 1546 /* Initialize pointers in PPS structures */ 1547 { 1548 pps_t *ps_pps = ps_codec->ps_pps_base; 1549 tile_t *ps_tile = ps_codec->ps_tile; 1550 1551 for(i = 0; i < MAX_PPS_CNT; i++) 1552 { 1553 ps_pps->ps_tile = ps_tile; 1554 ps_tile += (max_tile_cols * max_tile_rows); 1555 ps_pps++; 1556 } 1557 1558 } 1559 1560 /* Allocate memory for job queue */ 1561 1562 /* One job per row of CTBs */ 1563 size = max_ctb_rows; 1564 1565 /* One each tile a row of CTBs, num_jobs has to incremented */ 1566 size *= max_tile_cols; 1567 1568 /* One format convert/frame copy job per row of CTBs for non-shared mode*/ 1569 size += max_ctb_rows; 1570 1571 size *= sizeof(proc_job_t); 1572 1573 size += ihevcd_jobq_ctxt_size(); 1574 size = ALIGN4(size); 1575 1576 pv_buf = ps_codec->pf_aligned_alloc(pv_mem_ctxt, 128, size); 1577 RETURN_IF((NULL == pv_buf), IV_FAIL); 1578 ps_codec->pv_proc_jobq_buf = pv_buf; 1579 ps_codec->i4_proc_jobq_buf_size = size; 1580 1581 size = max_ctb_cnt; 1582 size = ALIGN4(size); 1583 pv_buf = ps_codec->pf_aligned_alloc(pv_mem_ctxt, 128, size); 1584 RETURN_IF((NULL == pv_buf), IV_FAIL); 1585 memset(pv_buf, 0, size); 1586 ps_codec->pu1_parse_map = (UWORD8 *)pv_buf; 1587 1588 size = max_ctb_cnt; 1589 size = ALIGN4(size); 1590 pv_buf = ps_codec->pf_aligned_alloc(pv_mem_ctxt, 128, size); 1591 RETURN_IF((NULL == pv_buf), IV_FAIL); 1592 memset(pv_buf, 0, size); 1593 ps_codec->pu1_proc_map = (UWORD8 *)pv_buf; 1594 1595 /** Holds top and left neighbor's pu idx into picture level pu array */ 1596 /* Only one top row is enough but left has to be replicated for each process context */ 1597 size = (max_num_4x4_cols /* left */ + MAX_PROCESS_THREADS * (MAX_CTB_SIZE / 4)/* top */ + 1/* top right */) * sizeof(WORD32); 1598 size = ALIGN4(size); 1599 pv_buf = ps_codec->pf_aligned_alloc(pv_mem_ctxt, 128, size); 1600 RETURN_IF((NULL == pv_buf), IV_FAIL); 1601 memset(pv_buf, 0, size); 1602 1603 for(i = 0; i < MAX_PROCESS_THREADS; i++) 1604 { 1605 UWORD32 *pu4_buf = (UWORD32 *)pv_buf; 1606 ps_codec->as_process[i].pu4_pic_pu_idx_left = pu4_buf + i * (MAX_CTB_SIZE / 4); 1607 memset(ps_codec->as_process[i].pu4_pic_pu_idx_left, 0, sizeof(UWORD32) * MAX_CTB_SIZE / 4); 1608 ps_codec->as_process[i].pu4_pic_pu_idx_top = pu4_buf + MAX_PROCESS_THREADS * (MAX_CTB_SIZE / 4); 1609 } 1610 memset(ps_codec->as_process[0].pu4_pic_pu_idx_top, 0, sizeof(UWORD32) * (wd / 4 + 1)); 1611 1612 { 1613 /* To hold SAO left buffer for luma */ 1614 size = sizeof(UWORD8) * (MAX(ht, wd)); 1615 1616 /* To hold SAO left buffer for chroma */ 1617 size += sizeof(UWORD8) * (MAX(ht, wd)); 1618 1619 /* To hold SAO top buffer for luma */ 1620 size += sizeof(UWORD8) * wd; 1621 1622 /* To hold SAO top buffer for chroma */ 1623 size += sizeof(UWORD8) * wd; 1624 1625 /* To hold SAO top left luma pixel value for last output ctb in a row*/ 1626 size += sizeof(UWORD8) * max_ctb_rows; 1627 1628 /* To hold SAO top left chroma pixel value last output ctb in a row*/ 1629 size += sizeof(UWORD8) * max_ctb_rows * 2; 1630 1631 /* To hold SAO top left pixel luma for current ctb - column array*/ 1632 size += sizeof(UWORD8) * max_ctb_rows; 1633 1634 /* To hold SAO top left pixel chroma for current ctb-column array*/ 1635 size += sizeof(UWORD8) * max_ctb_rows * 2; 1636 1637 /* To hold SAO top right pixel luma pixel value last output ctb in a row*/ 1638 size += sizeof(UWORD8) * max_ctb_cols; 1639 1640 /* To hold SAO top right pixel chroma pixel value last output ctb in a row*/ 1641 size += sizeof(UWORD8) * max_ctb_cols * 2; 1642 1643 /*To hold SAO botton bottom left pixels for luma*/ 1644 size += sizeof(UWORD8) * max_ctb_rows; 1645 1646 /*To hold SAO botton bottom left pixels for luma*/ 1647 size += sizeof(UWORD8) * max_ctb_rows * 2; 1648 size = ALIGN64(size); 1649 1650 pu1_buf = ps_codec->pf_aligned_alloc(pv_mem_ctxt, 128, size); 1651 RETURN_IF((NULL == pu1_buf), IV_FAIL); 1652 memset(pu1_buf, 0, size); 1653 1654 for(i = 0; i < MAX_PROCESS_THREADS; i++) 1655 { 1656 ps_codec->as_process[i].s_sao_ctxt.pu1_sao_src_left_luma = (UWORD8 *)pu1_buf; 1657 } 1658 ps_codec->s_parse.s_sao_ctxt.pu1_sao_src_left_luma = (UWORD8 *)pu1_buf; 1659 pu1_buf += MAX(ht, wd); 1660 1661 for(i = 0; i < MAX_PROCESS_THREADS; i++) 1662 { 1663 ps_codec->as_process[i].s_sao_ctxt.pu1_sao_src_left_chroma = (UWORD8 *)pu1_buf; 1664 } 1665 ps_codec->s_parse.s_sao_ctxt.pu1_sao_src_left_chroma = (UWORD8 *)pu1_buf; 1666 pu1_buf += MAX(ht, wd); 1667 for(i = 0; i < MAX_PROCESS_THREADS; i++) 1668 { 1669 ps_codec->as_process[i].s_sao_ctxt.pu1_sao_src_top_luma = (UWORD8 *)pu1_buf; 1670 } 1671 ps_codec->s_parse.s_sao_ctxt.pu1_sao_src_top_luma = (UWORD8 *)pu1_buf; 1672 pu1_buf += wd; 1673 1674 for(i = 0; i < MAX_PROCESS_THREADS; i++) 1675 { 1676 ps_codec->as_process[i].s_sao_ctxt.pu1_sao_src_top_chroma = (UWORD8 *)pu1_buf; 1677 } 1678 ps_codec->s_parse.s_sao_ctxt.pu1_sao_src_top_chroma = (UWORD8 *)pu1_buf; 1679 pu1_buf += wd; 1680 for(i = 0; i < MAX_PROCESS_THREADS; i++) 1681 { 1682 ps_codec->as_process[i].s_sao_ctxt.pu1_sao_src_luma_top_left_ctb = (UWORD8 *)pu1_buf; 1683 } 1684 ps_codec->s_parse.s_sao_ctxt.pu1_sao_src_luma_top_left_ctb = (UWORD8 *)pu1_buf; 1685 pu1_buf += ht / MIN_CTB_SIZE; 1686 1687 for(i = 0; i < MAX_PROCESS_THREADS; i++) 1688 { 1689 ps_codec->as_process[i].s_sao_ctxt.pu1_sao_src_chroma_top_left_ctb = (UWORD8 *)pu1_buf; 1690 } 1691 ps_codec->s_parse.s_sao_ctxt.pu1_sao_src_chroma_top_left_ctb = (UWORD8 *)pu1_buf; 1692 pu1_buf += (ht / MIN_CTB_SIZE) * 2; 1693 1694 for(i = 0; i < MAX_PROCESS_THREADS; i++) 1695 { 1696 ps_codec->as_process[i].s_sao_ctxt.pu1_sao_src_top_left_luma_curr_ctb = (UWORD8 *)pu1_buf; 1697 } 1698 ps_codec->s_parse.s_sao_ctxt.pu1_sao_src_top_left_luma_curr_ctb = (UWORD8 *)pu1_buf; 1699 pu1_buf += ht / MIN_CTB_SIZE; 1700 1701 for(i = 0; i < MAX_PROCESS_THREADS; i++) 1702 { 1703 ps_codec->as_process[i].s_sao_ctxt.pu1_sao_src_top_left_chroma_curr_ctb = (UWORD8 *)pu1_buf; 1704 } 1705 ps_codec->s_parse.s_sao_ctxt.pu1_sao_src_top_left_chroma_curr_ctb = (UWORD8 *)pu1_buf; 1706 1707 pu1_buf += (ht / MIN_CTB_SIZE) * 2; 1708 for(i = 0; i < MAX_PROCESS_THREADS; i++) 1709 { 1710 ps_codec->as_process[i].s_sao_ctxt.pu1_sao_src_top_left_luma_top_right = (UWORD8 *)pu1_buf; 1711 } 1712 ps_codec->s_parse.s_sao_ctxt.pu1_sao_src_top_left_luma_top_right = (UWORD8 *)pu1_buf; 1713 1714 pu1_buf += wd / MIN_CTB_SIZE; 1715 for(i = 0; i < MAX_PROCESS_THREADS; i++) 1716 { 1717 ps_codec->as_process[i].s_sao_ctxt.pu1_sao_src_top_left_chroma_top_right = (UWORD8 *)pu1_buf; 1718 } 1719 ps_codec->s_parse.s_sao_ctxt.pu1_sao_src_top_left_chroma_top_right = (UWORD8 *)pu1_buf; 1720 1721 pu1_buf += (wd / MIN_CTB_SIZE) * 2; 1722 1723 /*Per CTB, Store 1 value for luma , 2 values for chroma*/ 1724 for(i = 0; i < MAX_PROCESS_THREADS; i++) 1725 { 1726 ps_codec->as_process[i].s_sao_ctxt.pu1_sao_src_top_left_luma_bot_left = (UWORD8 *)pu1_buf; 1727 } 1728 ps_codec->s_parse.s_sao_ctxt.pu1_sao_src_top_left_luma_bot_left = (UWORD8 *)pu1_buf; 1729 1730 pu1_buf += (ht / MIN_CTB_SIZE); 1731 1732 for(i = 0; i < MAX_PROCESS_THREADS; i++) 1733 { 1734 ps_codec->as_process[i].s_sao_ctxt.pu1_sao_src_top_left_chroma_bot_left = (UWORD8 *)pu1_buf; 1735 } 1736 ps_codec->s_parse.s_sao_ctxt.pu1_sao_src_top_left_chroma_bot_left = (UWORD8 *)pu1_buf; 1737 1738 pu1_buf += (ht / MIN_CTB_SIZE) * 2; 1739 } 1740 1741 1742 { 1743 UWORD8 *pu1_buf = (UWORD8 *)pv_buf; 1744 WORD32 vert_bs_size, horz_bs_size; 1745 WORD32 qp_const_flag_size; 1746 WORD32 qp_size; 1747 WORD32 num_8x8; 1748 1749 /* Max Number of vertical edges */ 1750 vert_bs_size = wd / 8 + 2 * MAX_CTB_SIZE / 8; 1751 1752 /* Max Number of horizontal edges - extra MAX_CTB_SIZE / 8 to handle the last 4 rows separately(shifted CTB processing) */ 1753 vert_bs_size *= (ht + MAX_CTB_SIZE) / MIN_TU_SIZE; 1754 1755 /* Number of bytes */ 1756 vert_bs_size /= 8; 1757 1758 /* Two bits per edge */ 1759 vert_bs_size *= 2; 1760 1761 /* Max Number of horizontal edges */ 1762 horz_bs_size = ht / 8 + MAX_CTB_SIZE / 8; 1763 1764 /* Max Number of vertical edges - extra MAX_CTB_SIZE / 8 to handle the last 4 columns separately(shifted CTB processing) */ 1765 horz_bs_size *= (wd + MAX_CTB_SIZE) / MIN_TU_SIZE; 1766 1767 /* Number of bytes */ 1768 horz_bs_size /= 8; 1769 1770 /* Two bits per edge */ 1771 horz_bs_size *= 2; 1772 1773 /* Max CTBs in a row */ 1774 qp_const_flag_size = wd / MIN_CTB_SIZE + 1 /* The last ctb row deblk is done in last ctb + 1 row.*/; 1775 1776 /* Max CTBs in a column */ 1777 qp_const_flag_size *= ht / MIN_CTB_SIZE; 1778 1779 /* Number of bytes */ 1780 qp_const_flag_size /= 8; 1781 1782 /* QP changes at CU level - So store at 8x8 level */ 1783 num_8x8 = (ht * wd) / (MIN_CU_SIZE * MIN_CU_SIZE); 1784 qp_size = num_8x8; 1785 1786 /* To hold vertical boundary strength */ 1787 size += vert_bs_size; 1788 1789 /* To hold horizontal boundary strength */ 1790 size += horz_bs_size; 1791 1792 /* To hold QP */ 1793 size += qp_size; 1794 1795 /* To hold QP const in CTB flags */ 1796 size += qp_const_flag_size; 1797 1798 pu1_buf = ps_codec->pf_aligned_alloc(pv_mem_ctxt, 128, size); 1799 RETURN_IF((NULL == pu1_buf), IV_FAIL); 1800 1801 memset(pu1_buf, 0, size); 1802 1803 for(i = 0; i < MAX_PROCESS_THREADS; i++) 1804 { 1805 ps_codec->as_process[i].s_bs_ctxt.pu4_pic_vert_bs = (UWORD32 *)pu1_buf; 1806 ps_codec->as_process[i].s_deblk_ctxt.s_bs_ctxt.pu4_pic_vert_bs = (UWORD32 *)pu1_buf; 1807 ps_codec->s_parse.s_deblk_ctxt.s_bs_ctxt.pu4_pic_vert_bs = (UWORD32 *)pu1_buf; 1808 pu1_buf += vert_bs_size; 1809 1810 ps_codec->as_process[i].s_bs_ctxt.pu4_pic_horz_bs = (UWORD32 *)pu1_buf; 1811 ps_codec->as_process[i].s_deblk_ctxt.s_bs_ctxt.pu4_pic_horz_bs = (UWORD32 *)pu1_buf; 1812 ps_codec->s_parse.s_deblk_ctxt.s_bs_ctxt.pu4_pic_horz_bs = (UWORD32 *)pu1_buf; 1813 pu1_buf += horz_bs_size; 1814 1815 ps_codec->as_process[i].s_bs_ctxt.pu1_pic_qp = (UWORD8 *)pu1_buf; 1816 ps_codec->as_process[i].s_deblk_ctxt.s_bs_ctxt.pu1_pic_qp = (UWORD8 *)pu1_buf; 1817 ps_codec->s_parse.s_deblk_ctxt.s_bs_ctxt.pu1_pic_qp = (UWORD8 *)pu1_buf; 1818 pu1_buf += qp_size; 1819 1820 ps_codec->as_process[i].s_bs_ctxt.pu1_pic_qp_const_in_ctb = (UWORD8 *)pu1_buf; 1821 ps_codec->as_process[i].s_deblk_ctxt.s_bs_ctxt.pu1_pic_qp_const_in_ctb = (UWORD8 *)pu1_buf; 1822 ps_codec->s_parse.s_deblk_ctxt.s_bs_ctxt.pu1_pic_qp_const_in_ctb = (UWORD8 *)pu1_buf; 1823 pu1_buf += qp_const_flag_size; 1824 1825 pu1_buf -= (vert_bs_size + horz_bs_size + qp_size + qp_const_flag_size); 1826 } 1827 ps_codec->s_parse.s_bs_ctxt.pu4_pic_vert_bs = (UWORD32 *)pu1_buf; 1828 pu1_buf += vert_bs_size; 1829 1830 ps_codec->s_parse.s_bs_ctxt.pu4_pic_horz_bs = (UWORD32 *)pu1_buf; 1831 pu1_buf += horz_bs_size; 1832 1833 ps_codec->s_parse.s_bs_ctxt.pu1_pic_qp = (UWORD8 *)pu1_buf; 1834 pu1_buf += qp_size; 1835 1836 ps_codec->s_parse.s_bs_ctxt.pu1_pic_qp_const_in_ctb = (UWORD8 *)pu1_buf; 1837 pu1_buf += qp_const_flag_size; 1838 1839 } 1840 1841 /* Max CTBs in a row */ 1842 size = wd / MIN_CTB_SIZE + 2 /* Top row and bottom row extra. This ensures accessing left,top in first row 1843 and right in last row will not result in invalid access*/; 1844 /* Max CTBs in a column */ 1845 size *= ht / MIN_CTB_SIZE; 1846 1847 size *= sizeof(UWORD16); 1848 pv_buf = ps_codec->pf_aligned_alloc(pv_mem_ctxt, 128, size); 1849 RETURN_IF((NULL == pv_buf), IV_FAIL); 1850 memset(pv_buf, 0, size); 1851 1852 ps_codec->pu1_tile_idx_base = pv_buf; 1853 for(i = 0; i < MAX_PROCESS_THREADS; i++) 1854 { 1855 ps_codec->as_process[i].pu1_tile_idx = (UWORD16 *)pv_buf + wd / MIN_CTB_SIZE /* Offset 1 row */; 1856 } 1857 1858 /* 4 bytes per color component per CTB */ 1859 size = 3 * 4; 1860 1861 /* MAX number of CTBs in a row */ 1862 size *= wd / MIN_CTB_SIZE; 1863 1864 /* MAX number of CTBs in a column */ 1865 size *= ht / MIN_CTB_SIZE; 1866 pv_buf = ps_codec->pf_aligned_alloc(pv_mem_ctxt, 128, size); 1867 RETURN_IF((NULL == pv_buf), IV_FAIL); 1868 memset(pv_buf, 0, size); 1869 1870 ps_codec->s_parse.ps_pic_sao = (sao_t *)pv_buf; 1871 ps_codec->s_parse.s_sao_ctxt.ps_pic_sao = (sao_t *)pv_buf; 1872 for(i = 0; i < MAX_PROCESS_THREADS; i++) 1873 { 1874 ps_codec->as_process[i].s_sao_ctxt.ps_pic_sao = ps_codec->s_parse.ps_pic_sao; 1875 } 1876 1877 /* Only if width * height * 3 / 2 is greater than MIN_BITSBUF_SIZE, 1878 then allocate dynamic bistream buffer */ 1879 ps_codec->pu1_bitsbuf_dynamic = NULL; 1880 size = wd * ht; 1881 if(size > MIN_BITSBUF_SIZE) 1882 { 1883 pv_buf = ps_codec->pf_aligned_alloc(pv_mem_ctxt, 128, size); 1884 RETURN_IF((NULL == pv_buf), IV_FAIL); 1885 ps_codec->pu1_bitsbuf_dynamic = pv_buf; 1886 ps_codec->u4_bitsbuf_size_dynamic = size; 1887 } 1888 1889 size = ihevcd_get_tu_data_size(wd * ht); 1890 pv_buf = ps_codec->pf_aligned_alloc(pv_mem_ctxt, 128, size); 1891 RETURN_IF((NULL == pv_buf), IV_FAIL); 1892 ps_codec->pv_tu_data = pv_buf; 1893 1894 { 1895 sps_t *ps_sps = (ps_codec->s_parse.ps_sps_base + ps_codec->i4_sps_id); 1896 1897 1898 /* Allocate for pu_map, pu_t and pic_pu_idx for each MV bank */ 1899 /* Note: Number of luma samples is not max_wd * max_ht here, instead it is 1900 * set to maximum number of luma samples allowed at the given level. 1901 * This is done to ensure that any stream with width and height lesser 1902 * than max_wd and max_ht is supported. Number of buffers required can be greater 1903 * for lower width and heights at a given level and this increased number of buffers 1904 * might require more memory than what max_wd and max_ht buffer would have required 1905 * Also note one extra buffer is allocted to store current pictures MV bank 1906 * In case of asynchronous parsing and processing, number of buffers should increase here 1907 * based on when parsing and processing threads are synchronized 1908 */ 1909 max_dpb_size = ps_sps->ai1_sps_max_dec_pic_buffering[ps_sps->i1_sps_max_sub_layers - 1]; 1910 /* Size for holding mv_buf_t for each MV Bank 1911 * One extra MV Bank is needed to hold current pics MV bank. 1912 */ 1913 size = (max_dpb_size + 1) * sizeof(mv_buf_t); 1914 1915 size += (max_dpb_size + 1) * 1916 ihevcd_get_pic_mv_bank_size(wd * ht); 1917 1918 pv_buf = ps_codec->pf_aligned_alloc(pv_mem_ctxt, 128, size); 1919 RETURN_IF((NULL == pv_buf), IV_FAIL); 1920 1921 ps_codec->pv_mv_bank_buf_base = pv_buf; 1922 ps_codec->i4_total_mv_bank_size = size; 1923 1924 } 1925 1926 /* In case of non-shared mode allocate for reference picture buffers */ 1927 /* In case of shared and 420p output, allocate for chroma samples */ 1928 if(0 == ps_codec->i4_share_disp_buf) 1929 { 1930 /* Number of buffers is doubled in order to return one frame at a time instead of sending 1931 * multiple outputs during dpb full case. 1932 * Also note one extra buffer is allocted to store current picture 1933 * In case of asynchronous parsing and processing, number of buffers should increase here 1934 * based on when parsing and processing threads are synchronized 1935 */ 1936 size = ihevcd_get_total_pic_buf_size(ps_codec, wd, ht); 1937 pv_buf = ps_codec->pf_aligned_alloc(pv_mem_ctxt, 128, size); 1938 RETURN_IF((NULL == pv_buf), IV_FAIL); 1939 1940 1941 ps_codec->i4_total_pic_buf_size = size; 1942 ps_codec->pu1_ref_pic_buf_base = (UWORD8 *)pv_buf; 1943 } 1944 1945 ps_codec->pv_proc_jobq = ihevcd_jobq_init(ps_codec->pv_proc_jobq_buf, ps_codec->i4_proc_jobq_buf_size); 1946 RETURN_IF((ps_codec->pv_proc_jobq == NULL), IV_FAIL); 1947 1948 /* Update the jobq context to all the threads */ 1949 ps_codec->s_parse.pv_proc_jobq = ps_codec->pv_proc_jobq; 1950 for(i = 0; i < MAX_PROCESS_THREADS; i++) 1951 { 1952 ps_codec->as_process[i].pv_proc_jobq = ps_codec->pv_proc_jobq; 1953 ps_codec->as_process[i].i4_id = i; 1954 ps_codec->as_process[i].ps_codec = ps_codec; 1955 1956 /* Set the following to zero assuming it is a single core solution 1957 * When threads are launched these will be set appropriately 1958 */ 1959 ps_codec->as_process[i].i4_check_parse_status = 0; 1960 ps_codec->as_process[i].i4_check_proc_status = 0; 1961 } 1962 1963 ps_codec->u4_allocate_dynamic_done = 1; 1964 1965 return IV_SUCCESS; 1966} 1967 1968/** 1969******************************************************************************* 1970* 1971* @brief 1972* Free dynamic memory for the codec 1973* 1974* @par Description: 1975* Free dynamic memory for the codec 1976* 1977* @param[in] ps_codec 1978* Pointer to codec context 1979* 1980* @returns Status 1981* 1982* @remarks 1983* 1984* 1985******************************************************************************* 1986*/ 1987WORD32 ihevcd_free_dynamic_bufs(codec_t *ps_codec) 1988{ 1989 1990 if(ps_codec->pv_proc_jobq) 1991 { 1992 ihevcd_jobq_deinit(ps_codec->pv_proc_jobq); 1993 ps_codec->pv_proc_jobq = NULL; 1994 } 1995 1996 ALIGNED_FREE(ps_codec, ps_codec->ps_tile); 1997 ALIGNED_FREE(ps_codec, ps_codec->pi4_entry_ofst); 1998 ALIGNED_FREE(ps_codec, ps_codec->s_parse.pu4_skip_cu_top); 1999 ALIGNED_FREE(ps_codec, ps_codec->s_parse.pu4_ct_depth_top); 2000 ALIGNED_FREE(ps_codec, ps_codec->pu1_pic_intra_flag); 2001 ALIGNED_FREE(ps_codec, ps_codec->pu1_pic_no_loop_filter_flag_base); 2002 ALIGNED_FREE(ps_codec, ps_codec->pv_proc_jobq_buf); 2003 ALIGNED_FREE(ps_codec, ps_codec->pu1_parse_map); 2004 ALIGNED_FREE(ps_codec, ps_codec->pu1_proc_map); 2005 ALIGNED_FREE(ps_codec, ps_codec->as_process[0].pu4_pic_pu_idx_left); 2006 ALIGNED_FREE(ps_codec, ps_codec->as_process[0].s_sao_ctxt.pu1_sao_src_left_luma); 2007 ALIGNED_FREE(ps_codec, ps_codec->as_process[0].s_bs_ctxt.pu4_pic_vert_bs); 2008 ALIGNED_FREE(ps_codec, ps_codec->pu1_tile_idx_base); 2009 ALIGNED_FREE(ps_codec, ps_codec->s_parse.ps_pic_sao); 2010 ALIGNED_FREE(ps_codec, ps_codec->pu1_bitsbuf_dynamic); 2011 ALIGNED_FREE(ps_codec, ps_codec->pv_tu_data); 2012 ALIGNED_FREE(ps_codec, ps_codec->pv_mv_bank_buf_base); 2013 ALIGNED_FREE(ps_codec, ps_codec->pu1_ref_pic_buf_base); 2014 ALIGNED_FREE(ps_codec, ps_codec->pu1_cur_chroma_ref_buf); 2015 2016 ps_codec->u4_allocate_dynamic_done = 0; 2017 return IV_SUCCESS; 2018} 2019 2020 2021/** 2022******************************************************************************* 2023* 2024* @brief 2025* Initializes from mem records passed to the codec 2026* 2027* @par Description: 2028* Initializes pointers based on mem records passed 2029* 2030* @param[in] ps_codec_obj 2031* Pointer to codec object at API level 2032* 2033* @param[in] pv_api_ip 2034* Pointer to input argument structure 2035* 2036* @param[out] pv_api_op 2037* Pointer to output argument structure 2038* 2039* @returns Status 2040* 2041* @remarks 2042* 2043* 2044******************************************************************************* 2045*/ 2046WORD32 ihevcd_create(iv_obj_t *ps_codec_obj, 2047 void *pv_api_ip, 2048 void *pv_api_op) 2049{ 2050 2051 ihevcd_cxa_create_op_t *ps_create_op; 2052 2053 WORD32 ret; 2054 codec_t *ps_codec; 2055 ps_create_op = (ihevcd_cxa_create_op_t *)pv_api_op; 2056 2057 ps_create_op->s_ivd_create_op_t.u4_error_code = 0; 2058 2059 ret = ihevcd_allocate_static_bufs(&ps_codec_obj, pv_api_ip, pv_api_op); 2060 2061 /* If allocation of some buffer fails, then free buffers allocated till then */ 2062 if((IV_FAIL == ret) && (NULL != ps_codec_obj)) 2063 { 2064 ihevcd_free_static_bufs(ps_codec_obj); 2065 ps_create_op->s_ivd_create_op_t.u4_error_code = IVD_MEM_ALLOC_FAILED; 2066 ps_create_op->s_ivd_create_op_t.u4_error_code = 1 << IVD_FATALERROR; 2067 2068 return IV_FAIL; 2069 } 2070 ps_codec = (codec_t *)ps_codec_obj->pv_codec_handle; 2071 ret = ihevcd_init(ps_codec); 2072 2073 TRACE_INIT(NULL); 2074 STATS_INIT(); 2075 2076 return ret; 2077} 2078/** 2079******************************************************************************* 2080* 2081* @brief 2082* Delete codec 2083* 2084* @par Description: 2085* Delete codec 2086* 2087* @param[in] ps_codec_obj 2088* Pointer to codec object at API level 2089* 2090* @param[in] pv_api_ip 2091* Pointer to input argument structure 2092* 2093* @param[out] pv_api_op 2094* Pointer to output argument structure 2095* 2096* @returns Status 2097* 2098* @remarks 2099* 2100* 2101******************************************************************************* 2102*/ 2103WORD32 ihevcd_delete(iv_obj_t *ps_codec_obj, void *pv_api_ip, void *pv_api_op) 2104{ 2105 codec_t *ps_dec; 2106 ihevcd_cxa_delete_ip_t *ps_ip = (ihevcd_cxa_delete_ip_t *)pv_api_ip; 2107 ihevcd_cxa_delete_op_t *ps_op = (ihevcd_cxa_delete_op_t *)pv_api_op; 2108 2109 ps_dec = (codec_t *)(ps_codec_obj->pv_codec_handle); 2110 UNUSED(ps_ip); 2111 ps_op->s_ivd_delete_op_t.u4_error_code = 0; 2112 ihevcd_free_dynamic_bufs(ps_dec); 2113 ihevcd_free_static_bufs(ps_codec_obj); 2114 return IV_SUCCESS; 2115} 2116 2117 2118/** 2119******************************************************************************* 2120* 2121* @brief 2122* Passes display buffer from application to codec 2123* 2124* @par Description: 2125* Adds display buffer to the codec 2126* 2127* @param[in] ps_codec_obj 2128* Pointer to codec object at API level 2129* 2130* @param[in] pv_api_ip 2131* Pointer to input argument structure 2132* 2133* @param[out] pv_api_op 2134* Pointer to output argument structure 2135* 2136* @returns Status 2137* 2138* @remarks 2139* 2140* 2141******************************************************************************* 2142*/ 2143WORD32 ihevcd_set_display_frame(iv_obj_t *ps_codec_obj, 2144 void *pv_api_ip, 2145 void *pv_api_op) 2146{ 2147 WORD32 ret = IV_SUCCESS; 2148 2149 ivd_set_display_frame_ip_t *ps_dec_disp_ip; 2150 ivd_set_display_frame_op_t *ps_dec_disp_op; 2151 2152 WORD32 i; 2153 2154 codec_t *ps_codec = (codec_t *)(ps_codec_obj->pv_codec_handle); 2155 2156 ps_dec_disp_ip = (ivd_set_display_frame_ip_t *)pv_api_ip; 2157 ps_dec_disp_op = (ivd_set_display_frame_op_t *)pv_api_op; 2158 2159 ps_codec->i4_num_disp_bufs = 0; 2160 if(ps_codec->i4_share_disp_buf) 2161 { 2162 UWORD32 num_bufs = ps_dec_disp_ip->num_disp_bufs; 2163 pic_buf_t *ps_pic_buf; 2164 UWORD8 *pu1_buf; 2165 WORD32 buf_ret; 2166 2167 UWORD8 *pu1_chroma_buf = NULL; 2168 num_bufs = MIN(num_bufs, BUF_MGR_MAX_CNT); 2169 ps_codec->i4_num_disp_bufs = num_bufs; 2170 2171 ps_pic_buf = (pic_buf_t *)ps_codec->ps_pic_buf; 2172 2173 /* If color format is 420P, then allocate chroma buffers to hold semiplanar 2174 * chroma data */ 2175 if(ps_codec->e_chroma_fmt == IV_YUV_420P) 2176 { 2177 WORD32 num_samples = ps_dec_disp_ip->s_disp_buffer[0].u4_min_out_buf_size[1] << 1; 2178 WORD32 size = num_samples * num_bufs; 2179 void *pv_mem_ctxt = ps_codec->pv_mem_ctxt; 2180 2181 pu1_chroma_buf = ps_codec->pf_aligned_alloc(pv_mem_ctxt, 128, size); 2182 RETURN_IF((NULL == pu1_chroma_buf), IV_FAIL); 2183 2184 ps_codec->pu1_cur_chroma_ref_buf = pu1_chroma_buf; 2185 } 2186 for(i = 0; i < (WORD32)num_bufs; i++) 2187 { 2188 /* Stride is not available in some cases here. 2189 So store base pointers to buffer manager now, 2190 and update these pointers once header is decoded */ 2191 pu1_buf = ps_dec_disp_ip->s_disp_buffer[i].pu1_bufs[0]; 2192 ps_pic_buf->pu1_luma = pu1_buf; 2193 2194 if(ps_codec->e_chroma_fmt == IV_YUV_420P) 2195 { 2196 pu1_buf = pu1_chroma_buf; 2197 pu1_chroma_buf += ps_dec_disp_ip->s_disp_buffer[0].u4_min_out_buf_size[1] << 1; 2198 } 2199 else 2200 { 2201 /* For YUV 420SP case use display buffer itself as chroma ref buffer */ 2202 pu1_buf = ps_dec_disp_ip->s_disp_buffer[i].pu1_bufs[1]; 2203 } 2204 2205 ps_pic_buf->pu1_chroma = pu1_buf; 2206 2207 buf_ret = ihevc_buf_mgr_add((buf_mgr_t *)ps_codec->pv_pic_buf_mgr, ps_pic_buf, i); 2208 2209 if(0 != buf_ret) 2210 { 2211 ps_codec->i4_error_code = IHEVCD_BUF_MGR_ERROR; 2212 return IHEVCD_BUF_MGR_ERROR; 2213 } 2214 2215 /* Mark pic buf as needed for display */ 2216 /* This ensures that till the buffer is explicitly passed to the codec, 2217 * application owns the buffer. Decoder is allowed to use a buffer only 2218 * when application sends it through fill this buffer call in OMX 2219 */ 2220 ihevc_buf_mgr_set_status((buf_mgr_t *)ps_codec->pv_pic_buf_mgr, i, BUF_MGR_DISP); 2221 2222 ps_pic_buf++; 2223 2224 /* Store display buffers in codec context. Needed for 420p output */ 2225 memcpy(&ps_codec->s_disp_buffer[ps_codec->i4_share_disp_buf_cnt], 2226 &ps_dec_disp_ip->s_disp_buffer[i], 2227 sizeof(ps_dec_disp_ip->s_disp_buffer[i])); 2228 2229 ps_codec->i4_share_disp_buf_cnt++; 2230 2231 } 2232 } 2233 2234 ps_dec_disp_op->u4_error_code = 0; 2235 return ret; 2236 2237} 2238 2239/** 2240******************************************************************************* 2241* 2242* @brief 2243* Sets the decoder in flush mode. Decoder will come out of flush only 2244* after returning all the buffers or at reset 2245* 2246* @par Description: 2247* Sets the decoder in flush mode 2248* 2249* @param[in] ps_codec_obj 2250* Pointer to codec object at API level 2251* 2252* @param[in] pv_api_ip 2253* Pointer to input argument structure 2254* 2255* @param[out] pv_api_op 2256* Pointer to output argument structure 2257* 2258* @returns Status 2259* 2260* @remarks 2261* 2262* 2263******************************************************************************* 2264*/ 2265WORD32 ihevcd_set_flush_mode(iv_obj_t *ps_codec_obj, 2266 void *pv_api_ip, 2267 void *pv_api_op) 2268{ 2269 2270 codec_t *ps_codec; 2271 ivd_ctl_flush_op_t *ps_ctl_op = (ivd_ctl_flush_op_t *)pv_api_op; 2272 UNUSED(pv_api_ip); 2273 ps_codec = (codec_t *)(ps_codec_obj->pv_codec_handle); 2274 2275 /* Signal flush frame control call */ 2276 ps_codec->i4_flush_mode = 1; 2277 2278 ps_ctl_op->u4_error_code = 0; 2279 2280 /* Set pic count to zero, so that decoder starts buffering again */ 2281 /* once it comes out of flush mode */ 2282 ps_codec->u4_pic_cnt = 0; 2283 ps_codec->u4_disp_cnt = 0; 2284 return IV_SUCCESS; 2285 2286 2287} 2288 2289/** 2290******************************************************************************* 2291* 2292* @brief 2293* Gets decoder status and buffer requirements 2294* 2295* @par Description: 2296* Gets the decoder status 2297* 2298* @param[in] ps_codec_obj 2299* Pointer to codec object at API level 2300* 2301* @param[in] pv_api_ip 2302* Pointer to input argument structure 2303* 2304* @param[out] pv_api_op 2305* Pointer to output argument structure 2306* 2307* @returns Status 2308* 2309* @remarks 2310* 2311* 2312******************************************************************************* 2313*/ 2314 2315WORD32 ihevcd_get_status(iv_obj_t *ps_codec_obj, 2316 void *pv_api_ip, 2317 void *pv_api_op) 2318{ 2319 2320 WORD32 i; 2321 codec_t *ps_codec; 2322 WORD32 wd, ht; 2323 ivd_ctl_getstatus_op_t *ps_ctl_op = (ivd_ctl_getstatus_op_t *)pv_api_op; 2324 2325 UNUSED(pv_api_ip); 2326 2327 ps_ctl_op->u4_error_code = 0; 2328 2329 ps_codec = (codec_t *)(ps_codec_obj->pv_codec_handle); 2330 2331 ps_ctl_op->u4_min_num_in_bufs = MIN_IN_BUFS; 2332 if(ps_codec->e_chroma_fmt == IV_YUV_420P) 2333 ps_ctl_op->u4_min_num_out_bufs = MIN_OUT_BUFS_420; 2334 else if(ps_codec->e_chroma_fmt == IV_YUV_422ILE) 2335 ps_ctl_op->u4_min_num_out_bufs = MIN_OUT_BUFS_422ILE; 2336 else if(ps_codec->e_chroma_fmt == IV_RGB_565) 2337 ps_ctl_op->u4_min_num_out_bufs = MIN_OUT_BUFS_RGB565; 2338 else if(ps_codec->e_chroma_fmt == IV_RGBA_8888) 2339 ps_ctl_op->u4_min_num_out_bufs = MIN_OUT_BUFS_RGBA8888; 2340 else if((ps_codec->e_chroma_fmt == IV_YUV_420SP_UV) 2341 || (ps_codec->e_chroma_fmt == IV_YUV_420SP_VU)) 2342 ps_ctl_op->u4_min_num_out_bufs = MIN_OUT_BUFS_420SP; 2343 2344 ps_ctl_op->u4_num_disp_bufs = 1; 2345 2346 for(i = 0; i < (WORD32)ps_ctl_op->u4_min_num_in_bufs; i++) 2347 { 2348 wd = ALIGN64(ps_codec->i4_wd); 2349 ht = ALIGN64(ps_codec->i4_ht); 2350 ps_ctl_op->u4_min_in_buf_size[i] = MAX((wd * ht), MIN_BITSBUF_SIZE); 2351 } 2352 2353 wd = ps_codec->i4_wd; 2354 ht = ps_codec->i4_ht; 2355 2356 if(ps_codec->i4_sps_done) 2357 { 2358 if(0 == ps_codec->i4_share_disp_buf) 2359 { 2360 wd = ps_codec->i4_disp_wd; 2361 ht = ps_codec->i4_disp_ht; 2362 2363 } 2364 else 2365 { 2366 wd = ps_codec->i4_disp_strd; 2367 ht = ps_codec->i4_ht + PAD_HT; 2368 } 2369 } 2370 2371 if(ps_codec->i4_disp_strd > wd) 2372 wd = ps_codec->i4_disp_strd; 2373 2374 if(0 == ps_codec->i4_share_disp_buf) 2375 ps_ctl_op->u4_num_disp_bufs = 1; 2376 else 2377 { 2378 if(ps_codec->i4_sps_done) 2379 { 2380 sps_t *ps_sps = (ps_codec->s_parse.ps_sps_base + ps_codec->i4_sps_id); 2381 WORD32 reorder_pic_cnt, ref_pic_cnt; 2382 reorder_pic_cnt = 0; 2383 if(ps_codec->e_frm_out_mode != IVD_DECODE_FRAME_OUT) 2384 reorder_pic_cnt = ps_sps->ai1_sps_max_num_reorder_pics[ps_sps->i1_sps_max_sub_layers - 1]; 2385 ref_pic_cnt = ps_sps->ai1_sps_max_dec_pic_buffering[ps_sps->i1_sps_max_sub_layers - 1]; 2386 2387 ps_ctl_op->u4_num_disp_bufs = reorder_pic_cnt; 2388 2389 ps_ctl_op->u4_num_disp_bufs += ref_pic_cnt + 1; 2390 } 2391 else 2392 { 2393 ps_ctl_op->u4_num_disp_bufs = MAX_REF_CNT; 2394 } 2395 2396 ps_ctl_op->u4_num_disp_bufs = MIN( 2397 ps_ctl_op->u4_num_disp_bufs, 32); 2398 } 2399 2400 /*!*/ 2401 if(ps_codec->e_chroma_fmt == IV_YUV_420P) 2402 { 2403 ps_ctl_op->u4_min_out_buf_size[0] = (wd * ht); 2404 ps_ctl_op->u4_min_out_buf_size[1] = (wd * ht) >> 2; 2405 ps_ctl_op->u4_min_out_buf_size[2] = (wd * ht) >> 2; 2406 } 2407 else if(ps_codec->e_chroma_fmt == IV_YUV_422ILE) 2408 { 2409 ps_ctl_op->u4_min_out_buf_size[0] = (wd * ht) * 2; 2410 ps_ctl_op->u4_min_out_buf_size[1] = 2411 ps_ctl_op->u4_min_out_buf_size[2] = 0; 2412 } 2413 else if(ps_codec->e_chroma_fmt == IV_RGB_565) 2414 { 2415 ps_ctl_op->u4_min_out_buf_size[0] = (wd * ht) * 2; 2416 ps_ctl_op->u4_min_out_buf_size[1] = 2417 ps_ctl_op->u4_min_out_buf_size[2] = 0; 2418 } 2419 else if(ps_codec->e_chroma_fmt == IV_RGBA_8888) 2420 { 2421 ps_ctl_op->u4_min_out_buf_size[0] = (wd * ht) * 4; 2422 ps_ctl_op->u4_min_out_buf_size[1] = 2423 ps_ctl_op->u4_min_out_buf_size[2] = 0; 2424 } 2425 else if((ps_codec->e_chroma_fmt == IV_YUV_420SP_UV) 2426 || (ps_codec->e_chroma_fmt == IV_YUV_420SP_VU)) 2427 { 2428 ps_ctl_op->u4_min_out_buf_size[0] = (wd * ht); 2429 ps_ctl_op->u4_min_out_buf_size[1] = (wd * ht) >> 1; 2430 ps_ctl_op->u4_min_out_buf_size[2] = 0; 2431 } 2432 ps_ctl_op->u4_pic_ht = ht; 2433 ps_ctl_op->u4_pic_wd = wd; 2434 ps_ctl_op->u4_frame_rate = 30000; 2435 ps_ctl_op->u4_bit_rate = 1000000; 2436 ps_ctl_op->e_content_type = IV_PROGRESSIVE; 2437 ps_ctl_op->e_output_chroma_format = ps_codec->e_chroma_fmt; 2438 ps_codec->i4_num_disp_bufs = ps_ctl_op->u4_num_disp_bufs; 2439 2440 if(ps_ctl_op->u4_size == sizeof(ihevcd_cxa_ctl_getstatus_op_t)) 2441 { 2442 ihevcd_cxa_ctl_getstatus_op_t *ps_ext_ctl_op = (ihevcd_cxa_ctl_getstatus_op_t *)ps_ctl_op; 2443 ps_ext_ctl_op->u4_coded_pic_wd = ps_codec->i4_wd; 2444 ps_ext_ctl_op->u4_coded_pic_wd = ps_codec->i4_ht; 2445 } 2446 return IV_SUCCESS; 2447} 2448/** 2449******************************************************************************* 2450* 2451* @brief 2452* Gets decoder buffer requirements 2453* 2454* @par Description: 2455* Gets the decoder buffer requirements. If called before header decoder, 2456* buffer requirements are based on max_wd and max_ht else actual width and 2457* height will be used 2458* 2459* @param[in] ps_codec_obj 2460* Pointer to codec object at API level 2461* 2462* @param[in] pv_api_ip 2463* Pointer to input argument structure 2464* 2465* @param[out] pv_api_op 2466* Pointer to output argument structure 2467* 2468* @returns Status 2469* 2470* @remarks 2471* 2472* 2473******************************************************************************* 2474*/ 2475WORD32 ihevcd_get_buf_info(iv_obj_t *ps_codec_obj, 2476 void *pv_api_ip, 2477 void *pv_api_op) 2478{ 2479 2480 codec_t *ps_codec; 2481 UWORD32 i = 0; 2482 WORD32 wd, ht; 2483 ivd_ctl_getbufinfo_op_t *ps_ctl_op = 2484 (ivd_ctl_getbufinfo_op_t *)pv_api_op; 2485 2486 UNUSED(pv_api_ip); 2487 ps_ctl_op->u4_error_code = 0; 2488 2489 ps_codec = (codec_t *)(ps_codec_obj->pv_codec_handle); 2490 2491 ps_ctl_op->u4_min_num_in_bufs = MIN_IN_BUFS; 2492 if(ps_codec->e_chroma_fmt == IV_YUV_420P) 2493 ps_ctl_op->u4_min_num_out_bufs = MIN_OUT_BUFS_420; 2494 else if(ps_codec->e_chroma_fmt == IV_YUV_422ILE) 2495 ps_ctl_op->u4_min_num_out_bufs = MIN_OUT_BUFS_422ILE; 2496 else if(ps_codec->e_chroma_fmt == IV_RGB_565) 2497 ps_ctl_op->u4_min_num_out_bufs = MIN_OUT_BUFS_RGB565; 2498 else if(ps_codec->e_chroma_fmt == IV_RGBA_8888) 2499 ps_ctl_op->u4_min_num_out_bufs = MIN_OUT_BUFS_RGBA8888; 2500 else if((ps_codec->e_chroma_fmt == IV_YUV_420SP_UV) 2501 || (ps_codec->e_chroma_fmt == IV_YUV_420SP_VU)) 2502 ps_ctl_op->u4_min_num_out_bufs = MIN_OUT_BUFS_420SP; 2503 2504 ps_ctl_op->u4_num_disp_bufs = 1; 2505 2506 for(i = 0; i < ps_ctl_op->u4_min_num_in_bufs; i++) 2507 { 2508 wd = ALIGN64(ps_codec->i4_wd); 2509 ht = ALIGN64(ps_codec->i4_ht); 2510 2511 ps_ctl_op->u4_min_in_buf_size[i] = MAX((wd * ht), MIN_BITSBUF_SIZE); 2512 } 2513 2514 wd = 0; 2515 ht = 0; 2516 2517 if(ps_codec->i4_sps_done) 2518 { 2519 if(0 == ps_codec->i4_share_disp_buf) 2520 { 2521 wd = ps_codec->i4_disp_wd; 2522 ht = ps_codec->i4_disp_ht; 2523 2524 } 2525 else 2526 { 2527 wd = ps_codec->i4_disp_strd; 2528 ht = ps_codec->i4_ht + PAD_HT; 2529 } 2530 } 2531 else 2532 { 2533 if(1 == ps_codec->i4_share_disp_buf) 2534 { 2535 wd = ALIGN32(wd + PAD_WD); 2536 ht += PAD_HT; 2537 } 2538 } 2539 2540 if(ps_codec->i4_disp_strd > wd) 2541 wd = ps_codec->i4_disp_strd; 2542 2543 if(0 == ps_codec->i4_share_disp_buf) 2544 ps_ctl_op->u4_num_disp_bufs = 1; 2545 else 2546 { 2547 if(ps_codec->i4_sps_done) 2548 { 2549 sps_t *ps_sps = (ps_codec->s_parse.ps_sps_base + ps_codec->i4_sps_id); 2550 WORD32 reorder_pic_cnt, ref_pic_cnt; 2551 reorder_pic_cnt = 0; 2552 if(ps_codec->e_frm_out_mode != IVD_DECODE_FRAME_OUT) 2553 reorder_pic_cnt = ps_sps->ai1_sps_max_num_reorder_pics[ps_sps->i1_sps_max_sub_layers - 1]; 2554 ref_pic_cnt = ps_sps->ai1_sps_max_dec_pic_buffering[ps_sps->i1_sps_max_sub_layers - 1]; 2555 2556 ps_ctl_op->u4_num_disp_bufs = reorder_pic_cnt; 2557 2558 ps_ctl_op->u4_num_disp_bufs += ref_pic_cnt + 1; 2559 } 2560 else 2561 { 2562 ps_ctl_op->u4_num_disp_bufs = MAX_REF_CNT; 2563 } 2564 2565 ps_ctl_op->u4_num_disp_bufs = MIN( 2566 ps_ctl_op->u4_num_disp_bufs, 32); 2567 2568 } 2569 2570 /*!*/ 2571 if(ps_codec->e_chroma_fmt == IV_YUV_420P) 2572 { 2573 ps_ctl_op->u4_min_out_buf_size[0] = (wd * ht); 2574 ps_ctl_op->u4_min_out_buf_size[1] = (wd * ht) >> 2; 2575 ps_ctl_op->u4_min_out_buf_size[2] = (wd * ht) >> 2; 2576 } 2577 else if(ps_codec->e_chroma_fmt == IV_YUV_422ILE) 2578 { 2579 ps_ctl_op->u4_min_out_buf_size[0] = (wd * ht) * 2; 2580 ps_ctl_op->u4_min_out_buf_size[1] = 2581 ps_ctl_op->u4_min_out_buf_size[2] = 0; 2582 } 2583 else if(ps_codec->e_chroma_fmt == IV_RGB_565) 2584 { 2585 ps_ctl_op->u4_min_out_buf_size[0] = (wd * ht) * 2; 2586 ps_ctl_op->u4_min_out_buf_size[1] = 2587 ps_ctl_op->u4_min_out_buf_size[2] = 0; 2588 } 2589 else if(ps_codec->e_chroma_fmt == IV_RGBA_8888) 2590 { 2591 ps_ctl_op->u4_min_out_buf_size[0] = (wd * ht) * 4; 2592 ps_ctl_op->u4_min_out_buf_size[1] = 2593 ps_ctl_op->u4_min_out_buf_size[2] = 0; 2594 } 2595 else if((ps_codec->e_chroma_fmt == IV_YUV_420SP_UV) 2596 || (ps_codec->e_chroma_fmt == IV_YUV_420SP_VU)) 2597 { 2598 ps_ctl_op->u4_min_out_buf_size[0] = (wd * ht); 2599 ps_ctl_op->u4_min_out_buf_size[1] = (wd * ht) >> 1; 2600 ps_ctl_op->u4_min_out_buf_size[2] = 0; 2601 } 2602 ps_codec->i4_num_disp_bufs = ps_ctl_op->u4_num_disp_bufs; 2603 2604 return IV_SUCCESS; 2605} 2606 2607 2608/** 2609******************************************************************************* 2610* 2611* @brief 2612* Sets dynamic parameters 2613* 2614* @par Description: 2615* Sets dynamic parameters. Note Frame skip, decode header mode are dynamic 2616* Dynamic change in stride is not supported 2617* 2618* @param[in] ps_codec_obj 2619* Pointer to codec object at API level 2620* 2621* @param[in] pv_api_ip 2622* Pointer to input argument structure 2623* 2624* @param[out] pv_api_op 2625* Pointer to output argument structure 2626* 2627* @returns Status 2628* 2629* @remarks 2630* 2631* 2632******************************************************************************* 2633*/ 2634WORD32 ihevcd_set_params(iv_obj_t *ps_codec_obj, 2635 void *pv_api_ip, 2636 void *pv_api_op) 2637{ 2638 2639 codec_t *ps_codec; 2640 WORD32 ret = IV_SUCCESS; 2641 WORD32 strd; 2642 ivd_ctl_set_config_ip_t *s_ctl_dynparams_ip = 2643 (ivd_ctl_set_config_ip_t *)pv_api_ip; 2644 ivd_ctl_set_config_op_t *s_ctl_dynparams_op = 2645 (ivd_ctl_set_config_op_t *)pv_api_op; 2646 2647 ps_codec = (codec_t *)(ps_codec_obj->pv_codec_handle); 2648 2649 s_ctl_dynparams_op->u4_error_code = 0; 2650 2651 ps_codec->e_pic_skip_mode = s_ctl_dynparams_ip->e_frm_skip_mode; 2652 2653 if(s_ctl_dynparams_ip->e_frm_skip_mode != IVD_SKIP_NONE) 2654 { 2655 2656 if((s_ctl_dynparams_ip->e_frm_skip_mode != IVD_SKIP_P) && 2657 (s_ctl_dynparams_ip->e_frm_skip_mode != IVD_SKIP_B) && 2658 (s_ctl_dynparams_ip->e_frm_skip_mode != IVD_SKIP_PB)) 2659 { 2660 s_ctl_dynparams_op->u4_error_code = (1 << IVD_UNSUPPORTEDPARAM); 2661 ret = IV_FAIL; 2662 } 2663 } 2664 2665 strd = ps_codec->i4_disp_strd; 2666 if(1 == ps_codec->i4_share_disp_buf) 2667 { 2668 strd = ps_codec->i4_strd; 2669 } 2670 2671 2672 { 2673 if((WORD32)s_ctl_dynparams_ip->u4_disp_wd >= ps_codec->i4_disp_wd) 2674 { 2675 strd = s_ctl_dynparams_ip->u4_disp_wd; 2676 } 2677 else if(0 == ps_codec->i4_sps_done) 2678 { 2679 strd = s_ctl_dynparams_ip->u4_disp_wd; 2680 } 2681 else if(s_ctl_dynparams_ip->u4_disp_wd == 0) 2682 { 2683 strd = ps_codec->i4_disp_strd; 2684 } 2685 else 2686 { 2687 strd = 0; 2688 s_ctl_dynparams_op->u4_error_code |= (1 << IVD_UNSUPPORTEDPARAM); 2689 s_ctl_dynparams_op->u4_error_code |= IHEVCD_INVALID_DISP_STRD; 2690 ret = IV_FAIL; 2691 } 2692 } 2693 2694 ps_codec->i4_disp_strd = strd; 2695 if(1 == ps_codec->i4_share_disp_buf) 2696 { 2697 ps_codec->i4_strd = strd; 2698 } 2699 2700 if(s_ctl_dynparams_ip->e_vid_dec_mode == IVD_DECODE_FRAME) 2701 ps_codec->i4_header_mode = 0; 2702 else if(s_ctl_dynparams_ip->e_vid_dec_mode == IVD_DECODE_HEADER) 2703 ps_codec->i4_header_mode = 1; 2704 else 2705 { 2706 2707 s_ctl_dynparams_op->u4_error_code = (1 << IVD_UNSUPPORTEDPARAM); 2708 ps_codec->i4_header_mode = 1; 2709 ret = IV_FAIL; 2710 } 2711 2712 ps_codec->e_frm_out_mode = IVD_DISPLAY_FRAME_OUT; 2713 2714 if((s_ctl_dynparams_ip->e_frm_out_mode != IVD_DECODE_FRAME_OUT) && 2715 (s_ctl_dynparams_ip->e_frm_out_mode != IVD_DISPLAY_FRAME_OUT)) 2716 { 2717 s_ctl_dynparams_op->u4_error_code = (1 << IVD_UNSUPPORTEDPARAM); 2718 ret = IV_FAIL; 2719 } 2720 ps_codec->e_frm_out_mode = s_ctl_dynparams_ip->e_frm_out_mode; 2721 2722 return ret; 2723 2724} 2725/** 2726******************************************************************************* 2727* 2728* @brief 2729* Resets the decoder state 2730* 2731* @par Description: 2732* Resets the decoder state by calling ihevcd_init() 2733* 2734* @param[in] ps_codec_obj 2735* Pointer to codec object at API level 2736* 2737* @param[in] pv_api_ip 2738* Pointer to input argument structure 2739* 2740* @param[out] pv_api_op 2741* Pointer to output argument structure 2742* 2743* @returns Status 2744* 2745* @remarks 2746* 2747* 2748******************************************************************************* 2749*/ 2750WORD32 ihevcd_reset(iv_obj_t *ps_codec_obj, void *pv_api_ip, void *pv_api_op) 2751{ 2752 codec_t *ps_codec; 2753 ivd_ctl_reset_op_t *s_ctl_reset_op = (ivd_ctl_reset_op_t *)pv_api_op; 2754 UNUSED(pv_api_ip); 2755 ps_codec = (codec_t *)(ps_codec_obj->pv_codec_handle); 2756 2757 if(ps_codec != NULL) 2758 { 2759 DEBUG("\nReset called \n"); 2760 ihevcd_init(ps_codec); 2761 } 2762 else 2763 { 2764 DEBUG("\nReset called without Initializing the decoder\n"); 2765 s_ctl_reset_op->u4_error_code = IHEVCD_INIT_NOT_DONE; 2766 } 2767 2768 return IV_SUCCESS; 2769} 2770 2771/** 2772******************************************************************************* 2773* 2774* @brief 2775* Releases display buffer from application to codec to signal to the codec 2776* that it can write to this buffer if required. Till release is called, 2777* codec can not write to this buffer 2778* 2779* @par Description: 2780* Marks the buffer as display done 2781* 2782* @param[in] ps_codec_obj 2783* Pointer to codec object at API level 2784* 2785* @param[in] pv_api_ip 2786* Pointer to input argument structure 2787* 2788* @param[out] pv_api_op 2789* Pointer to output argument structure 2790* 2791* @returns Status 2792* 2793* @remarks 2794* 2795* 2796******************************************************************************* 2797*/ 2798 2799WORD32 ihevcd_rel_display_frame(iv_obj_t *ps_codec_obj, 2800 void *pv_api_ip, 2801 void *pv_api_op) 2802{ 2803 2804 ivd_rel_display_frame_ip_t *ps_dec_rel_disp_ip; 2805 ivd_rel_display_frame_op_t *ps_dec_rel_disp_op; 2806 2807 codec_t *ps_codec = (codec_t *)ps_codec_obj->pv_codec_handle; 2808 2809 ps_dec_rel_disp_ip = (ivd_rel_display_frame_ip_t *)pv_api_ip; 2810 ps_dec_rel_disp_op = (ivd_rel_display_frame_op_t *)pv_api_op; 2811 2812 UNUSED(ps_dec_rel_disp_op); 2813 2814 if(0 == ps_codec->i4_share_disp_buf) 2815 { 2816 return IV_SUCCESS; 2817 } 2818 2819 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); 2820 2821 return IV_SUCCESS; 2822} 2823/** 2824******************************************************************************* 2825* 2826* @brief 2827* Sets degrade params 2828* 2829* @par Description: 2830* Sets degrade params. 2831* Refer to ihevcd_cxa_ctl_degrade_ip_t definition for details 2832* 2833* @param[in] ps_codec_obj 2834* Pointer to codec object at API level 2835* 2836* @param[in] pv_api_ip 2837* Pointer to input argument structure 2838* 2839* @param[out] pv_api_op 2840* Pointer to output argument structure 2841* 2842* @returns Status 2843* 2844* @remarks 2845* 2846* 2847******************************************************************************* 2848*/ 2849 2850WORD32 ihevcd_set_degrade(iv_obj_t *ps_codec_obj, 2851 void *pv_api_ip, 2852 void *pv_api_op) 2853{ 2854 ihevcd_cxa_ctl_degrade_ip_t *ps_ip; 2855 ihevcd_cxa_ctl_degrade_op_t *ps_op; 2856 codec_t *ps_codec = (codec_t *)ps_codec_obj->pv_codec_handle; 2857 2858 ps_ip = (ihevcd_cxa_ctl_degrade_ip_t *)pv_api_ip; 2859 ps_op = (ihevcd_cxa_ctl_degrade_op_t *)pv_api_op; 2860 2861 ps_codec->i4_degrade_type = ps_ip->i4_degrade_type; 2862 ps_codec->i4_nondegrade_interval = ps_ip->i4_nondegrade_interval; 2863 ps_codec->i4_degrade_pics = ps_ip->i4_degrade_pics; 2864 2865 ps_op->u4_error_code = 0; 2866 ps_codec->i4_degrade_pic_cnt = 0; 2867 2868 return IV_SUCCESS; 2869} 2870 2871 2872/** 2873******************************************************************************* 2874* 2875* @brief 2876* Gets frame dimensions/offsets 2877* 2878* @par Description: 2879* Gets frame buffer chararacteristics such a x & y offsets display and 2880* buffer dimensions 2881* 2882* @param[in] ps_codec_obj 2883* Pointer to codec object at API level 2884* 2885* @param[in] pv_api_ip 2886* Pointer to input argument structure 2887* 2888* @param[out] pv_api_op 2889* Pointer to output argument structure 2890* 2891* @returns Status 2892* 2893* @remarks 2894* 2895* 2896******************************************************************************* 2897*/ 2898 2899WORD32 ihevcd_get_frame_dimensions(iv_obj_t *ps_codec_obj, 2900 void *pv_api_ip, 2901 void *pv_api_op) 2902{ 2903 ihevcd_cxa_ctl_get_frame_dimensions_ip_t *ps_ip; 2904 ihevcd_cxa_ctl_get_frame_dimensions_op_t *ps_op; 2905 codec_t *ps_codec = (codec_t *)ps_codec_obj->pv_codec_handle; 2906 WORD32 disp_wd, disp_ht, buffer_wd, buffer_ht, x_offset, y_offset; 2907 ps_ip = (ihevcd_cxa_ctl_get_frame_dimensions_ip_t *)pv_api_ip; 2908 ps_op = (ihevcd_cxa_ctl_get_frame_dimensions_op_t *)pv_api_op; 2909 UNUSED(ps_ip); 2910 if(ps_codec->i4_sps_done) 2911 { 2912 disp_wd = ps_codec->i4_disp_wd; 2913 disp_ht = ps_codec->i4_disp_ht; 2914 2915 if(0 == ps_codec->i4_share_disp_buf) 2916 { 2917 buffer_wd = disp_wd; 2918 buffer_ht = disp_ht; 2919 } 2920 else 2921 { 2922 buffer_wd = ps_codec->i4_strd; 2923 buffer_ht = ps_codec->i4_ht + PAD_HT; 2924 } 2925 } 2926 else 2927 { 2928 2929 disp_wd = 0; 2930 disp_ht = 0; 2931 2932 if(0 == ps_codec->i4_share_disp_buf) 2933 { 2934 buffer_wd = disp_wd; 2935 buffer_ht = disp_ht; 2936 } 2937 else 2938 { 2939 buffer_wd = ALIGN16(disp_wd) + PAD_WD; 2940 buffer_ht = ALIGN16(disp_ht) + PAD_HT; 2941 2942 } 2943 } 2944 if(ps_codec->i4_strd > buffer_wd) 2945 buffer_wd = ps_codec->i4_strd; 2946 2947 if(0 == ps_codec->i4_share_disp_buf) 2948 { 2949 x_offset = 0; 2950 y_offset = 0; 2951 } 2952 else 2953 { 2954 y_offset = PAD_TOP; 2955 x_offset = PAD_LEFT; 2956 } 2957 2958 ps_op->u4_disp_wd[0] = disp_wd; 2959 ps_op->u4_disp_ht[0] = disp_ht; 2960 ps_op->u4_buffer_wd[0] = buffer_wd; 2961 ps_op->u4_buffer_ht[0] = buffer_ht; 2962 ps_op->u4_x_offset[0] = x_offset; 2963 ps_op->u4_y_offset[0] = y_offset; 2964 2965 ps_op->u4_disp_wd[1] = ps_op->u4_disp_wd[2] = ((ps_op->u4_disp_wd[0] + 1) 2966 >> 1); 2967 ps_op->u4_disp_ht[1] = ps_op->u4_disp_ht[2] = ((ps_op->u4_disp_ht[0] + 1) 2968 >> 1); 2969 ps_op->u4_buffer_wd[1] = ps_op->u4_buffer_wd[2] = (ps_op->u4_buffer_wd[0] 2970 >> 1); 2971 ps_op->u4_buffer_ht[1] = ps_op->u4_buffer_ht[2] = (ps_op->u4_buffer_ht[0] 2972 >> 1); 2973 ps_op->u4_x_offset[1] = ps_op->u4_x_offset[2] = (ps_op->u4_x_offset[0] 2974 >> 1); 2975 ps_op->u4_y_offset[1] = ps_op->u4_y_offset[2] = (ps_op->u4_y_offset[0] 2976 >> 1); 2977 2978 if((ps_codec->e_chroma_fmt == IV_YUV_420SP_UV) 2979 || (ps_codec->e_chroma_fmt == IV_YUV_420SP_VU)) 2980 { 2981 ps_op->u4_disp_wd[2] = 0; 2982 ps_op->u4_disp_ht[2] = 0; 2983 ps_op->u4_buffer_wd[2] = 0; 2984 ps_op->u4_buffer_ht[2] = 0; 2985 ps_op->u4_x_offset[2] = 0; 2986 ps_op->u4_y_offset[2] = 0; 2987 2988 ps_op->u4_disp_wd[1] <<= 1; 2989 ps_op->u4_buffer_wd[1] <<= 1; 2990 ps_op->u4_x_offset[1] <<= 1; 2991 } 2992 2993 return IV_SUCCESS; 2994 2995} 2996 2997 2998/** 2999******************************************************************************* 3000* 3001* @brief 3002* Gets vui parameters 3003* 3004* @par Description: 3005* Gets VUI parameters 3006* 3007* @param[in] ps_codec_obj 3008* Pointer to codec object at API level 3009* 3010* @param[in] pv_api_ip 3011* Pointer to input argument structure 3012* 3013* @param[out] pv_api_op 3014* Pointer to output argument structure 3015* 3016* @returns Status 3017* 3018* @remarks 3019* 3020* 3021******************************************************************************* 3022*/ 3023WORD32 ihevcd_get_vui_params(iv_obj_t *ps_codec_obj, 3024 void *pv_api_ip, 3025 void *pv_api_op) 3026{ 3027 ihevcd_cxa_ctl_get_vui_params_ip_t *ps_ip; 3028 ihevcd_cxa_ctl_get_vui_params_op_t *ps_op; 3029 codec_t *ps_codec = (codec_t *)ps_codec_obj->pv_codec_handle; 3030 sps_t *ps_sps; 3031 vui_t *ps_vui; 3032 WORD32 i; 3033 3034 ps_ip = (ihevcd_cxa_ctl_get_vui_params_ip_t *)pv_api_ip; 3035 ps_op = (ihevcd_cxa_ctl_get_vui_params_op_t *)pv_api_op; 3036 3037 if(0 == ps_codec->i4_sps_done) 3038 { 3039 ps_op->u4_error_code = IHEVCD_VUI_PARAMS_NOT_FOUND; 3040 return IV_FAIL; 3041 } 3042 3043 ps_sps = ps_codec->s_parse.ps_sps; 3044 if(0 == ps_sps->i1_sps_valid || 0 == ps_sps->i1_vui_parameters_present_flag) 3045 { 3046 WORD32 sps_idx = 0; 3047 ps_sps = ps_codec->ps_sps_base; 3048 3049 while((0 == ps_sps->i1_sps_valid) || (0 == ps_sps->i1_vui_parameters_present_flag)) 3050 { 3051 sps_idx++; 3052 ps_sps++; 3053 3054 if(sps_idx == MAX_SPS_CNT - 1) 3055 { 3056 ps_op->u4_error_code = IHEVCD_VUI_PARAMS_NOT_FOUND; 3057 return IV_FAIL; 3058 } 3059 } 3060 } 3061 3062 ps_vui = &ps_sps->s_vui_parameters; 3063 UNUSED(ps_ip); 3064 3065 ps_op->u1_aspect_ratio_info_present_flag = ps_vui->u1_aspect_ratio_info_present_flag; 3066 ps_op->u1_aspect_ratio_idc = ps_vui->u1_aspect_ratio_idc; 3067 ps_op->u2_sar_width = ps_vui->u2_sar_width; 3068 ps_op->u2_sar_height = ps_vui->u2_sar_height; 3069 ps_op->u1_overscan_info_present_flag = ps_vui->u1_overscan_info_present_flag; 3070 ps_op->u1_overscan_appropriate_flag = ps_vui->u1_overscan_appropriate_flag; 3071 ps_op->u1_video_signal_type_present_flag = ps_vui->u1_video_signal_type_present_flag; 3072 ps_op->u1_video_format = ps_vui->u1_video_format; 3073 ps_op->u1_video_full_range_flag = ps_vui->u1_video_full_range_flag; 3074 ps_op->u1_colour_description_present_flag = ps_vui->u1_colour_description_present_flag; 3075 ps_op->u1_colour_primaries = ps_vui->u1_colour_primaries; 3076 ps_op->u1_transfer_characteristics = ps_vui->u1_transfer_characteristics; 3077 ps_op->u1_matrix_coefficients = ps_vui->u1_matrix_coefficients; 3078 ps_op->u1_chroma_loc_info_present_flag = ps_vui->u1_chroma_loc_info_present_flag; 3079 ps_op->u1_chroma_sample_loc_type_top_field = ps_vui->u1_chroma_sample_loc_type_top_field; 3080 ps_op->u1_chroma_sample_loc_type_bottom_field = ps_vui->u1_chroma_sample_loc_type_bottom_field; 3081 ps_op->u1_neutral_chroma_indication_flag = ps_vui->u1_neutral_chroma_indication_flag; 3082 ps_op->u1_field_seq_flag = ps_vui->u1_field_seq_flag; 3083 ps_op->u1_frame_field_info_present_flag = ps_vui->u1_frame_field_info_present_flag; 3084 ps_op->u1_default_display_window_flag = ps_vui->u1_default_display_window_flag; 3085 ps_op->u4_def_disp_win_left_offset = ps_vui->u4_def_disp_win_left_offset; 3086 ps_op->u4_def_disp_win_right_offset = ps_vui->u4_def_disp_win_right_offset; 3087 ps_op->u4_def_disp_win_top_offset = ps_vui->u4_def_disp_win_top_offset; 3088 ps_op->u4_def_disp_win_bottom_offset = ps_vui->u4_def_disp_win_bottom_offset; 3089 ps_op->u1_vui_hrd_parameters_present_flag = ps_vui->u1_vui_hrd_parameters_present_flag; 3090 ps_op->u1_vui_timing_info_present_flag = ps_vui->u1_vui_timing_info_present_flag; 3091 ps_op->u4_vui_num_units_in_tick = ps_vui->u4_vui_num_units_in_tick; 3092 ps_op->u4_vui_time_scale = ps_vui->u4_vui_time_scale; 3093 ps_op->u1_poc_proportional_to_timing_flag = ps_vui->u1_poc_proportional_to_timing_flag; 3094 ps_op->u1_num_ticks_poc_diff_one_minus1 = ps_vui->u1_num_ticks_poc_diff_one_minus1; 3095 ps_op->u1_bitstream_restriction_flag = ps_vui->u1_bitstream_restriction_flag; 3096 ps_op->u1_tiles_fixed_structure_flag = ps_vui->u1_tiles_fixed_structure_flag; 3097 ps_op->u1_motion_vectors_over_pic_boundaries_flag = ps_vui->u1_motion_vectors_over_pic_boundaries_flag; 3098 ps_op->u1_restricted_ref_pic_lists_flag = ps_vui->u1_restricted_ref_pic_lists_flag; 3099 ps_op->u4_min_spatial_segmentation_idc = ps_vui->u4_min_spatial_segmentation_idc; 3100 ps_op->u1_max_bytes_per_pic_denom = ps_vui->u1_max_bytes_per_pic_denom; 3101 ps_op->u1_max_bits_per_mincu_denom = ps_vui->u1_max_bits_per_mincu_denom; 3102 ps_op->u1_log2_max_mv_length_horizontal = ps_vui->u1_log2_max_mv_length_horizontal; 3103 ps_op->u1_log2_max_mv_length_vertical = ps_vui->u1_log2_max_mv_length_vertical; 3104 3105 3106 /* HRD parameters */ 3107 ps_op->u1_timing_info_present_flag = ps_vui->s_vui_hrd_parameters.u1_timing_info_present_flag; 3108 ps_op->u4_num_units_in_tick = ps_vui->s_vui_hrd_parameters.u4_num_units_in_tick; 3109 ps_op->u4_time_scale = ps_vui->s_vui_hrd_parameters.u4_time_scale; 3110 ps_op->u1_nal_hrd_parameters_present_flag = ps_vui->s_vui_hrd_parameters.u1_nal_hrd_parameters_present_flag; 3111 ps_op->u1_vcl_hrd_parameters_present_flag = ps_vui->s_vui_hrd_parameters.u1_vcl_hrd_parameters_present_flag; 3112 ps_op->u1_cpbdpb_delays_present_flag = ps_vui->s_vui_hrd_parameters.u1_cpbdpb_delays_present_flag; 3113 ps_op->u1_sub_pic_cpb_params_present_flag = ps_vui->s_vui_hrd_parameters.u1_sub_pic_cpb_params_present_flag; 3114 ps_op->u1_tick_divisor_minus2 = ps_vui->s_vui_hrd_parameters.u1_tick_divisor_minus2; 3115 ps_op->u1_du_cpb_removal_delay_increment_length_minus1 = ps_vui->s_vui_hrd_parameters.u1_du_cpb_removal_delay_increment_length_minus1; 3116 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; 3117 ps_op->u1_dpb_output_delay_du_length_minus1 = ps_vui->s_vui_hrd_parameters.u1_dpb_output_delay_du_length_minus1; 3118 ps_op->u4_bit_rate_scale = ps_vui->s_vui_hrd_parameters.u4_bit_rate_scale; 3119 ps_op->u4_cpb_size_scale = ps_vui->s_vui_hrd_parameters.u4_cpb_size_scale; 3120 ps_op->u4_cpb_size_du_scale = ps_vui->s_vui_hrd_parameters.u4_cpb_size_du_scale; 3121 ps_op->u1_initial_cpb_removal_delay_length_minus1 = ps_vui->s_vui_hrd_parameters.u1_initial_cpb_removal_delay_length_minus1; 3122 ps_op->u1_au_cpb_removal_delay_length_minus1 = ps_vui->s_vui_hrd_parameters.u1_au_cpb_removal_delay_length_minus1; 3123 ps_op->u1_dpb_output_delay_length_minus1 = ps_vui->s_vui_hrd_parameters.u1_dpb_output_delay_length_minus1; 3124 3125 for(i = 0; i < 6; i++) 3126 { 3127 ps_op->au1_fixed_pic_rate_general_flag[i] = ps_vui->s_vui_hrd_parameters.au1_fixed_pic_rate_general_flag[i]; 3128 ps_op->au1_fixed_pic_rate_within_cvs_flag[i] = ps_vui->s_vui_hrd_parameters.au1_fixed_pic_rate_within_cvs_flag[i]; 3129 ps_op->au1_elemental_duration_in_tc_minus1[i] = ps_vui->s_vui_hrd_parameters.au1_elemental_duration_in_tc_minus1[i]; 3130 ps_op->au1_low_delay_hrd_flag[i] = ps_vui->s_vui_hrd_parameters.au1_low_delay_hrd_flag[i]; 3131 ps_op->au1_cpb_cnt_minus1[i] = ps_vui->s_vui_hrd_parameters.au1_cpb_cnt_minus1[i]; 3132 } 3133 3134 3135 return IV_SUCCESS; 3136} 3137 3138/** 3139******************************************************************************* 3140* 3141* @brief 3142* Sets Processor type 3143* 3144* @par Description: 3145* Sets Processor type 3146* 3147* @param[in] ps_codec_obj 3148* Pointer to codec object at API level 3149* 3150* @param[in] pv_api_ip 3151* Pointer to input argument structure 3152* 3153* @param[out] pv_api_op 3154* Pointer to output argument structure 3155* 3156* @returns Status 3157* 3158* @remarks 3159* 3160* 3161******************************************************************************* 3162*/ 3163 3164WORD32 ihevcd_set_processor(iv_obj_t *ps_codec_obj, 3165 void *pv_api_ip, 3166 void *pv_api_op) 3167{ 3168 ihevcd_cxa_ctl_set_processor_ip_t *ps_ip; 3169 ihevcd_cxa_ctl_set_processor_op_t *ps_op; 3170 codec_t *ps_codec = (codec_t *)ps_codec_obj->pv_codec_handle; 3171 3172 ps_ip = (ihevcd_cxa_ctl_set_processor_ip_t *)pv_api_ip; 3173 ps_op = (ihevcd_cxa_ctl_set_processor_op_t *)pv_api_op; 3174 3175 ps_codec->e_processor_arch = (IVD_ARCH_T)ps_ip->u4_arch; 3176 ps_codec->e_processor_soc = (IVD_SOC_T)ps_ip->u4_soc; 3177 3178 ihevcd_init_function_ptr(ps_codec); 3179 3180 ihevcd_update_function_ptr(ps_codec); 3181 3182 if(ps_codec->e_processor_soc && (ps_codec->e_processor_soc <= SOC_HISI_37X)) 3183 { 3184 /* 8th bit indicates if format conversion is to be done ahead */ 3185 if(ps_codec->e_processor_soc & 0x80) 3186 ps_codec->u4_enable_fmt_conv_ahead = 1; 3187 3188 /* Lower 7 bit indicate NCTB - if non-zero */ 3189 ps_codec->e_processor_soc &= 0x7F; 3190 3191 if(ps_codec->e_processor_soc) 3192 ps_codec->u4_nctb = ps_codec->e_processor_soc; 3193 3194 3195 } 3196 3197 if((ps_codec->e_processor_soc == SOC_HISI_37X) && (ps_codec->i4_num_cores == 2)) 3198 { 3199 ps_codec->u4_nctb = 2; 3200 } 3201 3202 3203 ps_op->u4_error_code = 0; 3204 return IV_SUCCESS; 3205} 3206 3207/** 3208******************************************************************************* 3209* 3210* @brief 3211* Sets Number of cores that can be used in the codec. Codec uses these many 3212* threads for decoding 3213* 3214* @par Description: 3215* Sets number of cores 3216* 3217* @param[in] ps_codec_obj 3218* Pointer to codec object at API level 3219* 3220* @param[in] pv_api_ip 3221* Pointer to input argument structure 3222* 3223* @param[out] pv_api_op 3224* Pointer to output argument structure 3225* 3226* @returns Status 3227* 3228* @remarks 3229* 3230* 3231******************************************************************************* 3232*/ 3233 3234WORD32 ihevcd_set_num_cores(iv_obj_t *ps_codec_obj, 3235 void *pv_api_ip, 3236 void *pv_api_op) 3237{ 3238 ihevcd_cxa_ctl_set_num_cores_ip_t *ps_ip; 3239 ihevcd_cxa_ctl_set_num_cores_op_t *ps_op; 3240 codec_t *ps_codec = (codec_t *)ps_codec_obj->pv_codec_handle; 3241 3242 ps_ip = (ihevcd_cxa_ctl_set_num_cores_ip_t *)pv_api_ip; 3243 ps_op = (ihevcd_cxa_ctl_set_num_cores_op_t *)pv_api_op; 3244 3245#ifdef MULTICORE 3246 ps_codec->i4_num_cores = ps_ip->u4_num_cores; 3247#else 3248 ps_codec->i4_num_cores = 1; 3249#endif 3250 ps_op->u4_error_code = 0; 3251 return IV_SUCCESS; 3252} 3253/** 3254******************************************************************************* 3255* 3256* @brief 3257* Codec control call 3258* 3259* @par Description: 3260* Codec control call which in turn calls appropriate calls based on 3261* subcommand 3262* 3263* @param[in] ps_codec_obj 3264* Pointer to codec object at API level 3265* 3266* @param[in] pv_api_ip 3267* Pointer to input argument structure 3268* 3269* @param[out] pv_api_op 3270* Pointer to output argument structure 3271* 3272* @returns Status 3273* 3274* @remarks 3275* 3276* 3277******************************************************************************* 3278*/ 3279 3280WORD32 ihevcd_ctl(iv_obj_t *ps_codec_obj, void *pv_api_ip, void *pv_api_op) 3281{ 3282 ivd_ctl_set_config_ip_t *ps_ctl_ip; 3283 ivd_ctl_set_config_op_t *ps_ctl_op; 3284 WORD32 ret = 0; 3285 WORD32 subcommand; 3286 codec_t *ps_codec = (codec_t *)ps_codec_obj->pv_codec_handle; 3287 3288 ps_ctl_ip = (ivd_ctl_set_config_ip_t *)pv_api_ip; 3289 ps_ctl_op = (ivd_ctl_set_config_op_t *)pv_api_op; 3290 3291 if(ps_codec->i4_init_done != 1) 3292 { 3293 ps_ctl_op->u4_error_code |= 1 << IVD_FATALERROR; 3294 ps_ctl_op->u4_error_code |= IHEVCD_INIT_NOT_DONE; 3295 return IV_FAIL; 3296 } 3297 subcommand = ps_ctl_ip->e_sub_cmd; 3298 3299 switch(subcommand) 3300 { 3301 case IVD_CMD_CTL_GETPARAMS: 3302 ret = ihevcd_get_status(ps_codec_obj, (void *)pv_api_ip, 3303 (void *)pv_api_op); 3304 break; 3305 case IVD_CMD_CTL_SETPARAMS: 3306 ret = ihevcd_set_params(ps_codec_obj, (void *)pv_api_ip, 3307 (void *)pv_api_op); 3308 break; 3309 case IVD_CMD_CTL_RESET: 3310 ret = ihevcd_reset(ps_codec_obj, (void *)pv_api_ip, 3311 (void *)pv_api_op); 3312 break; 3313 case IVD_CMD_CTL_SETDEFAULT: 3314 { 3315 ivd_ctl_set_config_op_t *s_ctl_dynparams_op = 3316 (ivd_ctl_set_config_op_t *)pv_api_op; 3317 3318 ret = ihevcd_set_default_params(ps_codec); 3319 if(IV_SUCCESS == ret) 3320 s_ctl_dynparams_op->u4_error_code = 0; 3321 break; 3322 } 3323 case IVD_CMD_CTL_FLUSH: 3324 ret = ihevcd_set_flush_mode(ps_codec_obj, (void *)pv_api_ip, 3325 (void *)pv_api_op); 3326 break; 3327 case IVD_CMD_CTL_GETBUFINFO: 3328 ret = ihevcd_get_buf_info(ps_codec_obj, (void *)pv_api_ip, 3329 (void *)pv_api_op); 3330 break; 3331 case IVD_CMD_CTL_GETVERSION: 3332 { 3333 ivd_ctl_getversioninfo_ip_t *ps_ip; 3334 ivd_ctl_getversioninfo_op_t *ps_op; 3335 IV_API_CALL_STATUS_T ret; 3336 ps_ip = (ivd_ctl_getversioninfo_ip_t *)pv_api_ip; 3337 ps_op = (ivd_ctl_getversioninfo_op_t *)pv_api_op; 3338 3339 ps_op->u4_error_code = IV_SUCCESS; 3340 3341 if((WORD32)ps_ip->u4_version_buffer_size <= 0) 3342 { 3343 ps_op->u4_error_code = IHEVCD_CXA_VERS_BUF_INSUFFICIENT; 3344 ret = IV_FAIL; 3345 } 3346 else 3347 { 3348 ret = ihevcd_get_version((CHAR *)ps_ip->pv_version_buffer, 3349 ps_ip->u4_version_buffer_size); 3350 if(ret != IV_SUCCESS) 3351 { 3352 ps_op->u4_error_code = IHEVCD_CXA_VERS_BUF_INSUFFICIENT; 3353 ret = IV_FAIL; 3354 } 3355 } 3356 } 3357 break; 3358 case IHEVCD_CXA_CMD_CTL_DEGRADE: 3359 ret = ihevcd_set_degrade(ps_codec_obj, (void *)pv_api_ip, 3360 (void *)pv_api_op); 3361 break; 3362 case IHEVCD_CXA_CMD_CTL_SET_NUM_CORES: 3363 ret = ihevcd_set_num_cores(ps_codec_obj, (void *)pv_api_ip, 3364 (void *)pv_api_op); 3365 break; 3366 case IHEVCD_CXA_CMD_CTL_GET_BUFFER_DIMENSIONS: 3367 ret = ihevcd_get_frame_dimensions(ps_codec_obj, (void *)pv_api_ip, 3368 (void *)pv_api_op); 3369 break; 3370 case IHEVCD_CXA_CMD_CTL_GET_VUI_PARAMS: 3371 ret = ihevcd_get_vui_params(ps_codec_obj, (void *)pv_api_ip, 3372 (void *)pv_api_op); 3373 break; 3374 case IHEVCD_CXA_CMD_CTL_SET_PROCESSOR: 3375 ret = ihevcd_set_processor(ps_codec_obj, (void *)pv_api_ip, 3376 (void *)pv_api_op); 3377 break; 3378 default: 3379 DEBUG("\nDo nothing\n"); 3380 break; 3381 } 3382 3383 return ret; 3384} 3385 3386/** 3387******************************************************************************* 3388* 3389* @brief 3390* Codecs entry point function. All the function calls to the codec are 3391* done using this function with different values specified in command 3392* 3393* @par Description: 3394* Arguments are tested for validity and then based on the command 3395* appropriate function is called 3396* 3397* @param[in] ps_handle 3398* API level handle for codec 3399* 3400* @param[in] pv_api_ip 3401* Input argument structure 3402* 3403* @param[out] pv_api_op 3404* Output argument structure 3405* 3406* @returns Status of the function corresponding to command 3407* 3408* @remarks 3409* 3410* 3411******************************************************************************* 3412*/ 3413IV_API_CALL_STATUS_T ihevcd_cxa_api_function(iv_obj_t *ps_handle, 3414 void *pv_api_ip, 3415 void *pv_api_op) 3416{ 3417 WORD32 command; 3418 UWORD32 *pu4_ptr_cmd; 3419 WORD32 ret = 0; 3420 IV_API_CALL_STATUS_T e_status; 3421 e_status = api_check_struct_sanity(ps_handle, pv_api_ip, pv_api_op); 3422 3423 if(e_status != IV_SUCCESS) 3424 { 3425 DEBUG("error code = %d\n", *((UWORD32 *)pv_api_op + 1)); 3426 return IV_FAIL; 3427 } 3428 3429 pu4_ptr_cmd = (UWORD32 *)pv_api_ip; 3430 pu4_ptr_cmd++; 3431 3432 command = *pu4_ptr_cmd; 3433 3434 switch(command) 3435 { 3436 case IVD_CMD_CREATE: 3437 ret = ihevcd_create(ps_handle, (void *)pv_api_ip, (void *)pv_api_op); 3438 break; 3439 case IVD_CMD_DELETE: 3440 ret = ihevcd_delete(ps_handle, (void *)pv_api_ip, (void *)pv_api_op); 3441 break; 3442 3443 case IVD_CMD_VIDEO_DECODE: 3444 ret = ihevcd_decode(ps_handle, (void *)pv_api_ip, (void *)pv_api_op); 3445 break; 3446 3447 case IVD_CMD_GET_DISPLAY_FRAME: 3448 //ret = ihevcd_get_display_frame(ps_handle,(void *)pv_api_ip,(void *)pv_api_op); 3449 break; 3450 3451 case IVD_CMD_SET_DISPLAY_FRAME: 3452 ret = ihevcd_set_display_frame(ps_handle, (void *)pv_api_ip, 3453 (void *)pv_api_op); 3454 3455 break; 3456 3457 case IVD_CMD_REL_DISPLAY_FRAME: 3458 ret = ihevcd_rel_display_frame(ps_handle, (void *)pv_api_ip, 3459 (void *)pv_api_op); 3460 break; 3461 3462 case IVD_CMD_VIDEO_CTL: 3463 ret = ihevcd_ctl(ps_handle, (void *)pv_api_ip, (void *)pv_api_op); 3464 break; 3465 default: 3466 ret = IV_FAIL; 3467 break; 3468 } 3469 3470 return (IV_API_CALL_STATUS_T)ret; 3471} 3472 3473