1 /****************************************************************************** 2 * 3 * Copyright (C) 2015 The Android Open Source Project 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 * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore 19 */ 20 21 /** 22 ******************************************************************************* 23 * @file 24 * ih264e_api.c 25 * 26 * @brief 27 * Contains api function definitions for H264 encoder 28 * 29 * @author 30 * ittiam 31 * 32 * @par List of Functions: 33 * - api_check_struct_sanity() 34 * - ih264e_codec_update_config() 35 * - ih264e_set_default_params() 36 * - ih264e_init() 37 * - ih264e_get_num_rec() 38 * - ih264e_fill_num_mem_rec() 39 * - ih264e_init_mem_rec() 40 * - ih264e_retrieve_memrec() 41 * - ih264e_set_flush_mode() 42 * - ih264e_get_buf_info() 43 * - ih264e_set_dimensions() 44 * - ih264e_set_frame_rate() 45 * - ih264e_set_bit_rate() 46 * - ih264e_set_frame_type() 47 * - ih264e_set_qp() 48 * - ih264e_set_enc_mode() 49 * - ih264e_set_vbv_params() 50 * - ih264_set_air_params() 51 * - ih264_set_me_params() 52 * - ih264_set_ipe_params() 53 * - ih264_set_gop_params() 54 * - ih264_set_profile_params() 55 * - ih264_set_deblock_params() 56 * - ih264e_set_num_cores() 57 * - ih264e_reset() 58 * - ih264e_ctl() 59 * - ih264e_api_function() 60 * 61 * @remarks 62 * None 63 * 64 ******************************************************************************* 65 */ 66 67 /*****************************************************************************/ 68 /* File Includes */ 69 /*****************************************************************************/ 70 71 /* System Include Files */ 72 #include <stdio.h> 73 #include <stddef.h> 74 #include <stdlib.h> 75 #include <string.h> 76 #include <assert.h> 77 78 /* User Include Files */ 79 #include "ih264e_config.h" 80 #include "ih264_typedefs.h" 81 #include "ih264_size_defs.h" 82 #include "iv2.h" 83 #include "ive2.h" 84 #include "ih264e.h" 85 #include "ithread.h" 86 #include "ih264_debug.h" 87 #include "ih264_defs.h" 88 #include "ih264_error.h" 89 #include "ih264_structs.h" 90 #include "ih264_trans_quant_itrans_iquant.h" 91 #include "ih264_inter_pred_filters.h" 92 #include "ih264_mem_fns.h" 93 #include "ih264_padding.h" 94 #include "ih264_intra_pred_filters.h" 95 #include "ih264_deblk_edge_filters.h" 96 #include "ih264_cabac_tables.h" 97 #include "ih264_macros.h" 98 #include "ih264e_defs.h" 99 #include "ih264e_globals.h" 100 #include "ih264_buf_mgr.h" 101 #include "irc_mem_req_and_acq.h" 102 #include "irc_cntrl_param.h" 103 #include "irc_frame_info_collector.h" 104 #include "irc_rate_control_api.h" 105 #include "ih264e_time_stamp.h" 106 #include "ih264e_modify_frm_rate.h" 107 #include "ih264e_rate_control.h" 108 #include "ih264e_error.h" 109 #include "ih264e_bitstream.h" 110 #include "ime_defs.h" 111 #include "ime_distortion_metrics.h" 112 #include "ime_structs.h" 113 #include "ih264e_cabac_structs.h" 114 #include "ih264e_structs.h" 115 #include "ih264e_utils.h" 116 #include "ih264e_core_coding.h" 117 #include "ih264_platform_macros.h" 118 #include "ih264e_platform_macros.h" 119 #include "ih264_list.h" 120 #include "ih264_dpb_mgr.h" 121 #include "ih264_cavlc_tables.h" 122 #include "ih264e_cavlc.h" 123 #include "ih264_common_tables.h" 124 #include "ih264e_master.h" 125 #include "ih264e_fmt_conv.h" 126 #include "ih264e_version.h" 127 128 129 /*****************************************************************************/ 130 /* Function Declarations */ 131 /*****************************************************************************/ 132 WORD32 ih264e_get_rate_control_mem_tab(void *pv_rate_control, 133 iv_mem_rec_t *ps_mem, 134 ITT_FUNC_TYPE_E e_func_type); 135 136 137 /*****************************************************************************/ 138 /* Function Definitions */ 139 /*****************************************************************************/ 140 141 /** 142 ******************************************************************************* 143 * 144 * @brief 145 * Used to test arguments for corresponding API call 146 * 147 * @par Description: 148 * For each command the arguments are validated 149 * 150 * @param[in] ps_handle 151 * Codec handle at API level 152 * 153 * @param[in] pv_api_ip 154 * Pointer to input structure 155 * 156 * @param[out] pv_api_op 157 * Pointer to output structure 158 * 159 * @returns error status 160 * 161 * @remarks none 162 * 163 ******************************************************************************* 164 */ 165 static IV_STATUS_T api_check_struct_sanity(iv_obj_t *ps_handle, 166 void *pv_api_ip, 167 void *pv_api_op) 168 { 169 /* api call */ 170 WORD32 command = IV_CMD_NA; 171 172 /* input structure expected by the api call */ 173 UWORD32 *pu4_api_ip = pv_api_ip; 174 175 /* output structure expected by the api call */ 176 UWORD32 *pu4_api_op = pv_api_op; 177 178 /* temp var */ 179 WORD32 i, j; 180 181 if (NULL == pv_api_op || NULL == pv_api_ip) 182 { 183 return (IV_FAIL); 184 } 185 186 /* get command */ 187 command = pu4_api_ip[1]; 188 189 /* set error code */ 190 pu4_api_op[1] = 0; 191 192 /* error checks on handle */ 193 switch (command) 194 { 195 case IV_CMD_GET_NUM_MEM_REC: 196 case IV_CMD_FILL_NUM_MEM_REC: 197 break; 198 199 case IV_CMD_INIT: 200 if (ps_handle == NULL) 201 { 202 *(pu4_api_op + 1) |= 1 << IVE_UNSUPPORTEDPARAM; 203 *(pu4_api_op + 1) |= IVE_ERR_HANDLE_NULL; 204 return IV_FAIL; 205 } 206 207 if (ps_handle->u4_size != sizeof(iv_obj_t)) 208 { 209 *(pu4_api_op + 1) |= 1 << IVE_UNSUPPORTEDPARAM; 210 *(pu4_api_op + 1) |= IVE_ERR_HANDLE_STRUCT_SIZE_INCORRECT; 211 return IV_FAIL; 212 } 213 break; 214 215 case IVE_CMD_QUEUE_INPUT: 216 case IVE_CMD_QUEUE_OUTPUT: 217 case IVE_CMD_DEQUEUE_OUTPUT: 218 case IVE_CMD_GET_RECON: 219 case IV_CMD_RETRIEVE_MEMREC: 220 case IVE_CMD_VIDEO_CTL: 221 case IVE_CMD_VIDEO_ENCODE: 222 223 if (ps_handle == NULL) 224 { 225 *(pu4_api_op + 1) |= 1 << IVE_UNSUPPORTEDPARAM; 226 *(pu4_api_op + 1) |= IVE_ERR_HANDLE_NULL; 227 return IV_FAIL; 228 } 229 230 if (ps_handle->u4_size != sizeof(iv_obj_t)) 231 { 232 *(pu4_api_op + 1) |= 1 << IVE_UNSUPPORTEDPARAM; 233 *(pu4_api_op + 1) |= IVE_ERR_HANDLE_STRUCT_SIZE_INCORRECT; 234 return IV_FAIL; 235 } 236 237 if (ps_handle->pv_fxns != ih264e_api_function) 238 { 239 *(pu4_api_op + 1) |= 1 << IVE_UNSUPPORTEDPARAM; 240 *(pu4_api_op + 1) |= IVE_ERR_API_FUNCTION_PTR_NULL; 241 return IV_FAIL; 242 } 243 244 if (ps_handle->pv_codec_handle == NULL) 245 { 246 *(pu4_api_op + 1) |= 1 << IVE_UNSUPPORTEDPARAM; 247 *(pu4_api_op + 1) |= IVE_ERR_INVALID_CODEC_HANDLE; 248 return IV_FAIL; 249 } 250 break; 251 252 default: 253 *(pu4_api_op + 1) |= 1 << IVE_UNSUPPORTEDPARAM; 254 *(pu4_api_op + 1) |= IVE_ERR_INVALID_API_CMD; 255 return IV_FAIL; 256 } 257 258 /* error checks on input output structures */ 259 switch (command) 260 { 261 case IV_CMD_GET_NUM_MEM_REC: 262 { 263 ih264e_num_mem_rec_ip_t *ps_ip = pv_api_ip; 264 ih264e_num_mem_rec_op_t *ps_op = pv_api_op; 265 266 ps_op->s_ive_op.u4_error_code = 0; 267 268 if (ps_ip->s_ive_ip.u4_size != sizeof(ih264e_num_mem_rec_ip_t)) 269 { 270 ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM; 271 ps_op->s_ive_op.u4_error_code |= 272 IVE_ERR_IP_GET_MEM_REC_API_STRUCT_SIZE_INCORRECT; 273 return (IV_FAIL); 274 } 275 276 if (ps_op->s_ive_op.u4_size != sizeof(ih264e_num_mem_rec_op_t)) 277 { 278 ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM; 279 ps_op->s_ive_op.u4_error_code |= 280 IVE_ERR_OP_GET_MEM_REC_API_STRUCT_SIZE_INCORRECT; 281 return (IV_FAIL); 282 } 283 break; 284 } 285 286 case IV_CMD_FILL_NUM_MEM_REC: 287 { 288 ih264e_fill_mem_rec_ip_t *ps_ip = pv_api_ip; 289 ih264e_fill_mem_rec_op_t *ps_op = pv_api_op; 290 291 iv_mem_rec_t *ps_mem_rec = NULL; 292 293 WORD32 max_wd = ALIGN16(ps_ip->s_ive_ip.u4_max_wd); 294 WORD32 max_ht = ALIGN16(ps_ip->s_ive_ip.u4_max_ht); 295 296 ps_op->s_ive_op.u4_error_code = 0; 297 298 if (ps_ip->s_ive_ip.u4_size != sizeof(ih264e_fill_mem_rec_ip_t)) 299 { 300 ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM; 301 ps_op->s_ive_op.u4_error_code |= 302 IVE_ERR_IP_FILL_MEM_REC_API_STRUCT_SIZE_INCORRECT; 303 return (IV_FAIL); 304 } 305 306 if (ps_op->s_ive_op.u4_size != sizeof(ih264e_fill_mem_rec_op_t)) 307 { 308 ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM; 309 ps_op->s_ive_op.u4_error_code |= 310 IVE_ERR_OP_FILL_MEM_REC_API_STRUCT_SIZE_INCORRECT; 311 return (IV_FAIL); 312 } 313 314 if (max_wd < MIN_WD || max_wd > MAX_WD) 315 { 316 ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM; 317 ps_op->s_ive_op.u4_error_code |= IH264E_WIDTH_NOT_SUPPORTED; 318 return (IV_FAIL); 319 } 320 321 if (max_ht < MIN_HT || max_ht > MAX_HT) 322 { 323 ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM; 324 ps_op->s_ive_op.u4_error_code |= IH264E_HEIGHT_NOT_SUPPORTED; 325 return (IV_FAIL); 326 } 327 328 /* verify number of mem rec ptr */ 329 if (NULL == ps_ip->s_ive_ip.ps_mem_rec) 330 { 331 ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM; 332 ps_op->s_ive_op.u4_error_code |= 333 IVE_ERR_FILL_NUM_MEM_RECS_POINTER_NULL; 334 return (IV_FAIL); 335 } 336 337 /* verify number of mem records */ 338 if (ps_ip->s_ive_ip.u4_num_mem_rec != MEM_REC_CNT) 339 { 340 ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM; 341 ps_op->s_ive_op.u4_error_code |= 342 IVE_ERR_NUM_MEM_REC_NOT_SUFFICIENT; 343 return IV_FAIL; 344 } 345 346 /* check mem records sizes are correct */ 347 ps_mem_rec = ps_ip->s_ive_ip.ps_mem_rec; 348 for (i = 0; i < MEM_REC_CNT; i++) 349 { 350 if (ps_mem_rec[i].u4_size != sizeof(iv_mem_rec_t)) 351 { 352 ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM; 353 ps_op->s_ive_op.u4_error_code |= 354 IVE_ERR_MEM_REC_STRUCT_SIZE_INCORRECT; 355 return IV_FAIL; 356 } 357 } 358 break; 359 } 360 361 case IV_CMD_INIT: 362 { 363 ih264e_init_ip_t *ps_ip = pv_api_ip; 364 ih264e_init_op_t *ps_op = pv_api_op; 365 366 iv_mem_rec_t *ps_mem_rec = NULL; 367 368 WORD32 max_wd = ALIGN16(ps_ip->s_ive_ip.u4_max_wd); 369 WORD32 max_ht = ALIGN16(ps_ip->s_ive_ip.u4_max_ht); 370 371 ps_op->s_ive_op.u4_error_code = 0; 372 373 if (ps_ip->s_ive_ip.u4_size != sizeof(ih264e_init_ip_t)) 374 { 375 ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM; 376 ps_op->s_ive_op.u4_error_code |= 377 IVE_ERR_IP_INIT_API_STRUCT_SIZE_INCORRECT; 378 return (IV_FAIL); 379 } 380 381 if (ps_op->s_ive_op.u4_size != sizeof(ih264e_init_op_t)) 382 { 383 ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM; 384 ps_op->s_ive_op.u4_error_code |= 385 IVE_ERR_OP_INIT_API_STRUCT_SIZE_INCORRECT; 386 return (IV_FAIL); 387 } 388 389 if (max_wd < MIN_WD || max_wd > MAX_WD) 390 { 391 ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM; 392 ps_op->s_ive_op.u4_error_code |= IH264E_WIDTH_NOT_SUPPORTED; 393 return (IV_FAIL); 394 } 395 396 if (max_ht < MIN_HT || max_ht > MAX_HT) 397 { 398 ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM; 399 ps_op->s_ive_op.u4_error_code |= IH264E_HEIGHT_NOT_SUPPORTED; 400 return (IV_FAIL); 401 } 402 403 if (ps_ip->s_ive_ip.u4_max_ref_cnt > MAX_REF_PIC_CNT || 404 ps_ip->s_ive_ip.u4_max_ref_cnt < MIN_REF_PIC_CNT) 405 { 406 ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM; 407 ps_op->s_ive_op.u4_error_code |= IH264E_NUM_REF_UNSUPPORTED; 408 return (IV_FAIL); 409 } 410 411 if (ps_ip->s_ive_ip.u4_max_reorder_cnt != 0) 412 { 413 ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM; 414 ps_op->s_ive_op.u4_error_code |= IH264E_NUM_REORDER_UNSUPPORTED; 415 return (IV_FAIL); 416 } 417 418 if ((ps_ip->s_ive_ip.u4_max_level != IH264_LEVEL_10) 419 && (ps_ip->s_ive_ip.u4_max_level != IH264_LEVEL_1B) 420 && (ps_ip->s_ive_ip.u4_max_level != IH264_LEVEL_11) 421 && (ps_ip->s_ive_ip.u4_max_level != IH264_LEVEL_12) 422 && (ps_ip->s_ive_ip.u4_max_level != IH264_LEVEL_13) 423 && (ps_ip->s_ive_ip.u4_max_level != IH264_LEVEL_20) 424 && (ps_ip->s_ive_ip.u4_max_level != IH264_LEVEL_21) 425 && (ps_ip->s_ive_ip.u4_max_level != IH264_LEVEL_22) 426 && (ps_ip->s_ive_ip.u4_max_level != IH264_LEVEL_30) 427 && (ps_ip->s_ive_ip.u4_max_level != IH264_LEVEL_31) 428 && (ps_ip->s_ive_ip.u4_max_level != IH264_LEVEL_32) 429 && (ps_ip->s_ive_ip.u4_max_level != IH264_LEVEL_40) 430 && (ps_ip->s_ive_ip.u4_max_level != IH264_LEVEL_41) 431 && (ps_ip->s_ive_ip.u4_max_level != IH264_LEVEL_42) 432 && (ps_ip->s_ive_ip.u4_max_level != IH264_LEVEL_50) 433 && (ps_ip->s_ive_ip.u4_max_level != IH264_LEVEL_51)) 434 { 435 ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM; 436 ps_op->s_ive_op.u4_error_code |= 437 IH264E_CODEC_LEVEL_NOT_SUPPORTED; 438 return (IV_FAIL); 439 } 440 441 if ((ps_ip->s_ive_ip.e_inp_color_fmt != IV_YUV_420P) 442 && (ps_ip->s_ive_ip.e_inp_color_fmt != IV_YUV_422ILE) 443 && (ps_ip->s_ive_ip.e_inp_color_fmt != IV_YUV_420SP_UV) 444 && (ps_ip->s_ive_ip.e_inp_color_fmt != IV_YUV_420SP_VU)) 445 { 446 ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM; 447 ps_op->s_ive_op.u4_error_code |= 448 IH264E_INPUT_CHROMA_FORMAT_NOT_SUPPORTED; 449 return (IV_FAIL); 450 } 451 452 if ((ps_ip->s_ive_ip.e_recon_color_fmt != IV_YUV_420P) 453 && (ps_ip->s_ive_ip.e_recon_color_fmt != IV_YUV_420SP_UV) 454 && (ps_ip->s_ive_ip.e_recon_color_fmt != IV_YUV_420SP_VU)) 455 { 456 ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM; 457 ps_op->s_ive_op.u4_error_code |= 458 IH264E_RECON_CHROMA_FORMAT_NOT_SUPPORTED; 459 return (IV_FAIL); 460 } 461 462 if ((ps_ip->s_ive_ip.e_rc_mode != IVE_RC_NONE) 463 && (ps_ip->s_ive_ip.e_rc_mode != IVE_RC_STORAGE) 464 && (ps_ip->s_ive_ip.e_rc_mode != IVE_RC_CBR_NON_LOW_DELAY)) 465 { 466 ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM; 467 ps_op->s_ive_op.u4_error_code |= 468 IH264E_RATE_CONTROL_MODE_NOT_SUPPORTED; 469 return (IV_FAIL); 470 } 471 472 if (ps_ip->s_ive_ip.u4_max_framerate > DEFAULT_MAX_FRAMERATE) 473 { 474 ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM; 475 ps_op->s_ive_op.u4_error_code |= 476 IH264E_FRAME_RATE_NOT_SUPPORTED; 477 return (IV_FAIL); 478 } 479 480 if (ps_ip->s_ive_ip.u4_max_bitrate > DEFAULT_MAX_BITRATE) 481 { 482 ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM; 483 ps_op->s_ive_op.u4_error_code |= IH264E_BITRATE_NOT_SUPPORTED; 484 return (IV_FAIL); 485 } 486 487 if (ps_ip->s_ive_ip.u4_num_bframes > MAX_NUM_BFRAMES) 488 { 489 ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM; 490 ps_op->s_ive_op.u4_error_code |= IH264E_BFRAMES_NOT_SUPPORTED; 491 return (IV_FAIL); 492 } 493 494 if (ps_ip->s_ive_ip.u4_num_bframes 495 && (ps_ip->s_ive_ip.u4_max_ref_cnt < 2)) 496 { 497 ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM; 498 ps_op->s_ive_op.u4_error_code |= IH264E_BFRAMES_NOT_SUPPORTED; 499 return (IV_FAIL); 500 } 501 502 if (ps_ip->s_ive_ip.e_content_type != IV_PROGRESSIVE) 503 { 504 ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM; 505 ps_op->s_ive_op.u4_error_code |= 506 IH264E_CONTENT_TYPE_NOT_SUPPORTED; 507 return (IV_FAIL); 508 } 509 510 if (ps_ip->s_ive_ip.u4_max_srch_rng_x > DEFAULT_MAX_SRCH_RANGE_X) 511 { 512 ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM; 513 ps_op->s_ive_op.u4_error_code |= 514 IH264E_HORIZONTAL_SEARCH_RANGE_NOT_SUPPORTED; 515 return (IV_FAIL); 516 } 517 518 if (ps_ip->s_ive_ip.u4_max_srch_rng_y > DEFAULT_MAX_SRCH_RANGE_Y) 519 { 520 ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM; 521 ps_op->s_ive_op.u4_error_code |= 522 IH264E_VERTICAL_SEARCH_RANGE_NOT_SUPPORTED; 523 return (IV_FAIL); 524 } 525 526 if ((ps_ip->s_ive_ip.e_slice_mode != IVE_SLICE_MODE_NONE) 527 && (ps_ip->s_ive_ip.e_slice_mode != IVE_SLICE_MODE_BLOCKS)) 528 { 529 ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM; 530 ps_op->s_ive_op.u4_error_code |= 531 IH264E_SLICE_TYPE_INPUT_INVALID; 532 return (IV_FAIL); 533 } 534 535 if (ps_ip->s_ive_ip.e_slice_mode == IVE_SLICE_MODE_BLOCKS) 536 { 537 if (ps_ip->s_ive_ip.u4_slice_param == 0 538 || ps_ip->s_ive_ip.u4_slice_param > ((UWORD32)max_ht >> 4)) 539 { 540 ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM; 541 ps_op->s_ive_op.u4_error_code |= 542 IH264E_SLICE_PARAM_INPUT_INVALID; 543 return (IV_FAIL); 544 } 545 } 546 547 if (NULL == ps_ip->s_ive_ip.ps_mem_rec) 548 { 549 ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM; 550 ps_op->s_ive_op.u4_error_code |= 551 IVE_ERR_FILL_NUM_MEM_RECS_POINTER_NULL; 552 return (IV_FAIL); 553 } 554 555 /* verify number of mem records */ 556 if (ps_ip->s_ive_ip.u4_num_mem_rec != MEM_REC_CNT) 557 { 558 ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM; 559 ps_op->s_ive_op.u4_error_code |= 560 IVE_ERR_NUM_MEM_REC_NOT_SUFFICIENT; 561 return (IV_FAIL); 562 } 563 564 ps_mem_rec = ps_ip->s_ive_ip.ps_mem_rec; 565 566 /* check memrecords sizes are correct */ 567 for (i = 0; i <((WORD32)ps_ip->s_ive_ip.u4_num_mem_rec); i++) 568 { 569 if (ps_mem_rec[i].u4_size != sizeof(iv_mem_rec_t)) 570 { 571 ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM; 572 ps_op->s_ive_op.u4_error_code |= 573 IVE_ERR_MEM_REC_STRUCT_SIZE_INCORRECT; 574 return IV_FAIL; 575 } 576 577 /* check memrecords pointers are not NULL */ 578 if (ps_mem_rec[i].pv_base == NULL) 579 { 580 ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM; 581 ps_op->s_ive_op.u4_error_code |= 582 IVE_ERR_MEM_REC_BASE_POINTER_NULL; 583 return IV_FAIL; 584 } 585 } 586 587 /* verify memtabs for overlapping regions */ 588 { 589 void *start[MEM_REC_CNT]; 590 void *end[MEM_REC_CNT]; 591 592 start[0] = (ps_mem_rec[0].pv_base); 593 end[0] = ((UWORD8 *) ps_mem_rec[0].pv_base) 594 + ps_mem_rec[0].u4_mem_size - 1; 595 596 for (i = 1; i < MEM_REC_CNT; i++) 597 { 598 /* This array is populated to check memtab overlap */ 599 start[i] = (ps_mem_rec[i].pv_base); 600 end[i] = ((UWORD8 *) ps_mem_rec[i].pv_base) 601 + ps_mem_rec[i].u4_mem_size - 1; 602 603 for (j = 0; j < i; j++) 604 { 605 if ((start[i] >= start[j]) && (start[i] <= end[j])) 606 { 607 ps_op->s_ive_op.u4_error_code |= 1 608 << IVE_UNSUPPORTEDPARAM; 609 ps_op->s_ive_op.u4_error_code |= 610 IVE_ERR_MEM_REC_OVERLAP_ERR; 611 return IV_FAIL; 612 } 613 614 if ((end[i] >= start[j]) && (end[i] <= end[j])) 615 { 616 ps_op->s_ive_op.u4_error_code |= 1 617 << IVE_UNSUPPORTEDPARAM; 618 ps_op->s_ive_op.u4_error_code |= 619 IVE_ERR_MEM_REC_OVERLAP_ERR; 620 return IV_FAIL; 621 } 622 623 if ((start[i] < start[j]) && (end[i] > end[j])) 624 { 625 ps_op->s_ive_op.u4_error_code |= 1 626 << IVE_UNSUPPORTEDPARAM; 627 ps_op->s_ive_op.u4_error_code |= 628 IVE_ERR_MEM_REC_OVERLAP_ERR; 629 return IV_FAIL; 630 } 631 } 632 } 633 } 634 635 /* re-validate mem records with init config */ 636 { 637 /* mem records */ 638 iv_mem_rec_t s_mem_rec_ittiam_api[MEM_REC_CNT]; 639 640 /* api interface structs */ 641 ih264e_fill_mem_rec_ip_t s_ip; 642 ih264e_fill_mem_rec_op_t s_op; 643 644 /* error status */ 645 IV_STATUS_T e_status; 646 647 /* temp var */ 648 WORD32 i; 649 650 s_ip.s_ive_ip.u4_size = sizeof(ih264e_fill_mem_rec_ip_t); 651 s_op.s_ive_op.u4_size = sizeof(ih264e_fill_mem_rec_op_t); 652 653 s_ip.s_ive_ip.e_cmd = IV_CMD_FILL_NUM_MEM_REC; 654 s_ip.s_ive_ip.ps_mem_rec = s_mem_rec_ittiam_api; 655 s_ip.s_ive_ip.u4_max_wd = max_wd; 656 s_ip.s_ive_ip.u4_max_ht = max_ht; 657 s_ip.s_ive_ip.u4_num_mem_rec = ps_ip->s_ive_ip.u4_num_mem_rec; 658 s_ip.s_ive_ip.u4_max_level = ps_ip->s_ive_ip.u4_max_level; 659 s_ip.s_ive_ip.u4_max_ref_cnt = ps_ip->s_ive_ip.u4_max_ref_cnt; 660 s_ip.s_ive_ip.u4_max_reorder_cnt = 661 ps_ip->s_ive_ip.u4_max_reorder_cnt; 662 s_ip.s_ive_ip.e_color_format = ps_ip->s_ive_ip.e_inp_color_fmt; 663 s_ip.s_ive_ip.u4_max_srch_rng_x = 664 ps_ip->s_ive_ip.u4_max_srch_rng_x; 665 s_ip.s_ive_ip.u4_max_srch_rng_y = 666 ps_ip->s_ive_ip.u4_max_srch_rng_y; 667 668 for (i = 0; i < MEM_REC_CNT; i++) 669 { 670 s_mem_rec_ittiam_api[i].u4_size = sizeof(iv_mem_rec_t); 671 } 672 673 /* fill mem records */ 674 e_status = ih264e_api_function(NULL, (void *) &s_ip, 675 (void *) &s_op); 676 677 if (IV_FAIL == e_status) 678 { 679 ps_op->s_ive_op.u4_error_code = s_op.s_ive_op.u4_error_code; 680 return (IV_FAIL); 681 } 682 683 /* verify mem records */ 684 for (i = 0; i < MEM_REC_CNT; i++) 685 { 686 if (ps_mem_rec[i].u4_mem_size 687 < s_mem_rec_ittiam_api[i].u4_mem_size) 688 { 689 ps_op->s_ive_op.u4_error_code |= 1 690 << IVE_UNSUPPORTEDPARAM; 691 ps_op->s_ive_op.u4_error_code |= 692 IVE_ERR_MEM_REC_INSUFFICIENT_SIZE; 693 694 return IV_FAIL; 695 } 696 697 if (ps_mem_rec[i].u4_mem_alignment 698 != s_mem_rec_ittiam_api[i].u4_mem_alignment) 699 { 700 ps_op->s_ive_op.u4_error_code |= 1 701 << IVE_UNSUPPORTEDPARAM; 702 ps_op->s_ive_op.u4_error_code |= 703 IVE_ERR_MEM_REC_ALIGNMENT_ERR; 704 705 return IV_FAIL; 706 } 707 708 if (ps_mem_rec[i].e_mem_type 709 != s_mem_rec_ittiam_api[i].e_mem_type) 710 { 711 UWORD32 check = IV_SUCCESS; 712 UWORD32 diff = s_mem_rec_ittiam_api[i].e_mem_type 713 - ps_mem_rec[i].e_mem_type; 714 715 if ((ps_mem_rec[i].e_mem_type 716 <= IV_EXTERNAL_CACHEABLE_SCRATCH_MEM) 717 && (s_mem_rec_ittiam_api[i].e_mem_type 718 >= IV_INTERNAL_NONCACHEABLE_PERSISTENT_MEM)) 719 { 720 check = IV_FAIL; 721 } 722 723 if (3 != (s_mem_rec_ittiam_api[i].e_mem_type % 4)) 724 { 725 /* It is not IV_EXTERNAL_NONCACHEABLE_PERSISTENT_MEM or 726 * IV_EXTERNAL_CACHEABLE_PERSISTENT_MEM */ 727 728 if ((diff < 1) || (diff > 3)) 729 { 730 /* Difference between 1 and 3 is okay for all cases other than the 731 * two filtered with the MOD condition above */ 732 check = IV_FAIL; 733 } 734 } 735 else 736 { 737 if (diff == 1) 738 { 739 /* This particular case is when codec asked for External Persistent, 740 * but got Internal Scratch */ 741 check = IV_FAIL; 742 } 743 if ((diff != 2) && (diff != 3)) 744 { 745 check = IV_FAIL; 746 } 747 } 748 749 if (check == IV_FAIL) 750 { 751 ps_op->s_ive_op.u4_error_code |= 1 752 << IVE_UNSUPPORTEDPARAM; 753 ps_op->s_ive_op.u4_error_code |= 754 IVE_ERR_MEM_REC_INCORRECT_TYPE; 755 756 return IV_FAIL; 757 } 758 } 759 } 760 } 761 break; 762 } 763 764 case IVE_CMD_QUEUE_INPUT: 765 case IVE_CMD_QUEUE_OUTPUT: 766 case IVE_CMD_DEQUEUE_OUTPUT: 767 case IVE_CMD_GET_RECON: 768 break; 769 770 case IV_CMD_RETRIEVE_MEMREC: 771 { 772 ih264e_retrieve_mem_rec_ip_t *ps_ip = pv_api_ip; 773 ih264e_retrieve_mem_rec_op_t *ps_op = pv_api_op; 774 775 iv_mem_rec_t *ps_mem_rec = NULL; 776 777 ps_op->s_ive_op.u4_error_code = 0; 778 779 if (ps_ip->s_ive_ip.u4_size != sizeof(ih264e_retrieve_mem_rec_ip_t)) 780 { 781 ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM; 782 ps_op->s_ive_op.u4_error_code |= 783 IVE_ERR_IP_RETRIEVE_MEM_REC_API_STRUCT_SIZE_INCORRECT; 784 return (IV_FAIL); 785 } 786 787 if (ps_op->s_ive_op.u4_size != sizeof(ih264e_retrieve_mem_rec_op_t)) 788 { 789 ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM; 790 ps_op->s_ive_op.u4_error_code |= 791 IVE_ERR_OP_RETRIEVE_MEM_REC_API_STRUCT_SIZE_INCORRECT; 792 return (IV_FAIL); 793 } 794 795 if (NULL == ps_ip->s_ive_ip.ps_mem_rec) 796 { 797 ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM; 798 ps_op->s_ive_op.u4_error_code |= 799 IVE_ERR_FILL_NUM_MEM_RECS_POINTER_NULL; 800 return (IV_FAIL); 801 } 802 803 ps_mem_rec = ps_ip->s_ive_ip.ps_mem_rec; 804 805 /* check memrecords sizes are correct */ 806 for (i = 0; i < MEM_REC_CNT; i++) 807 { 808 if (ps_mem_rec[i].u4_size != sizeof(iv_mem_rec_t)) 809 { 810 ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM; 811 ps_op->s_ive_op.u4_error_code |= 812 IVE_ERR_MEM_REC_STRUCT_SIZE_INCORRECT; 813 return IV_FAIL; 814 } 815 } 816 break; 817 } 818 819 case IVE_CMD_VIDEO_ENCODE: 820 { 821 ih264e_video_encode_ip_t *ps_ip = pv_api_ip; 822 ih264e_video_encode_op_t *ps_op = pv_api_op; 823 824 if (ps_ip->s_ive_ip.u4_size != sizeof(ih264e_video_encode_ip_t)) 825 { 826 ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM; 827 ps_op->s_ive_op.u4_error_code |= 828 IVE_ERR_IP_ENCODE_API_STRUCT_SIZE_INCORRECT; 829 return (IV_FAIL); 830 } 831 832 if (ps_op->s_ive_op.u4_size != sizeof(ih264e_video_encode_op_t)) 833 { 834 ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM; 835 ps_op->s_ive_op.u4_error_code |= 836 IVE_ERR_OP_ENCODE_API_STRUCT_SIZE_INCORRECT; 837 return (IV_FAIL); 838 } 839 break; 840 } 841 842 case IVE_CMD_VIDEO_CTL: 843 { 844 /* ptr to input structure */ 845 WORD32 *pu4_ptr_cmd = pv_api_ip; 846 847 /* sub command */ 848 WORD32 sub_command = pu4_ptr_cmd[2]; 849 850 switch (sub_command) 851 { 852 case IVE_CMD_CTL_SETDEFAULT: 853 { 854 ih264e_ctl_setdefault_ip_t *ps_ip = pv_api_ip; 855 ih264e_ctl_setdefault_op_t *ps_op = pv_api_op; 856 857 if (ps_ip->s_ive_ip.u4_size 858 != sizeof(ih264e_ctl_setdefault_ip_t)) 859 { 860 ps_op->s_ive_op.u4_error_code |= 1 861 << IVE_UNSUPPORTEDPARAM; 862 ps_op->s_ive_op.u4_error_code |= 863 IVE_ERR_IP_CTL_SETDEF_API_STRUCT_SIZE_INCORRECT; 864 return IV_FAIL; 865 } 866 867 if (ps_op->s_ive_op.u4_size 868 != sizeof(ih264e_ctl_setdefault_op_t)) 869 { 870 ps_op->s_ive_op.u4_error_code |= 1 871 << IVE_UNSUPPORTEDPARAM; 872 ps_op->s_ive_op.u4_error_code |= 873 IVE_ERR_OP_CTL_SETDEF_API_STRUCT_SIZE_INCORRECT; 874 return IV_FAIL; 875 } 876 break; 877 } 878 879 case IVE_CMD_CTL_GETBUFINFO: 880 { 881 codec_t *ps_codec = (codec_t *) (ps_handle->pv_codec_handle); 882 883 ih264e_ctl_getbufinfo_ip_t *ps_ip = pv_api_ip; 884 ih264e_ctl_getbufinfo_op_t *ps_op = pv_api_op; 885 886 if (ps_ip->s_ive_ip.u4_size 887 != sizeof(ih264e_ctl_getbufinfo_ip_t)) 888 { 889 ps_op->s_ive_op.u4_error_code |= 1 890 << IVE_UNSUPPORTEDPARAM; 891 ps_op->s_ive_op.u4_error_code |= 892 IVE_ERR_IP_CTL_GETBUFINFO_API_STRUCT_SIZE_INCORRECT; 893 return IV_FAIL; 894 } 895 896 if (ps_op->s_ive_op.u4_size 897 != sizeof(ih264e_ctl_getbufinfo_op_t)) 898 { 899 ps_op->s_ive_op.u4_error_code |= 1 900 << IVE_UNSUPPORTEDPARAM; 901 ps_op->s_ive_op.u4_error_code |= 902 IVE_ERR_OP_CTL_GETBUFINFO_API_STRUCT_SIZE_INCORRECT; 903 return IV_FAIL; 904 } 905 906 if (ps_ip->s_ive_ip.u4_max_wd < MIN_WD) 907 { 908 ps_op->s_ive_op.u4_error_code |= 1 909 << IVE_UNSUPPORTEDPARAM; 910 ps_op->s_ive_op.u4_error_code |= 911 IH264E_WIDTH_NOT_SUPPORTED; 912 return (IV_FAIL); 913 } 914 915 if (ps_ip->s_ive_ip.u4_max_wd > ps_codec->s_cfg.u4_max_wd) 916 { 917 ps_op->s_ive_op.u4_error_code |= 1 918 << IVE_UNSUPPORTEDPARAM; 919 ps_op->s_ive_op.u4_error_code |= 920 IH264E_WIDTH_NOT_SUPPORTED; 921 return (IV_FAIL); 922 } 923 924 if (ps_ip->s_ive_ip.u4_max_ht < MIN_HT) 925 { 926 ps_op->s_ive_op.u4_error_code |= 1 927 << IVE_UNSUPPORTEDPARAM; 928 ps_op->s_ive_op.u4_error_code |= 929 IH264E_HEIGHT_NOT_SUPPORTED; 930 return (IV_FAIL); 931 } 932 933 if (ps_ip->s_ive_ip.u4_max_ht > ps_codec->s_cfg.u4_max_ht) 934 { 935 ps_op->s_ive_op.u4_error_code |= 1 936 << IVE_UNSUPPORTEDPARAM; 937 ps_op->s_ive_op.u4_error_code |= 938 IH264E_HEIGHT_NOT_SUPPORTED; 939 return (IV_FAIL); 940 } 941 942 if ((ps_ip->s_ive_ip.e_inp_color_fmt != IV_YUV_420P) 943 && (ps_ip->s_ive_ip.e_inp_color_fmt != IV_YUV_422ILE) 944 && (ps_ip->s_ive_ip.e_inp_color_fmt != IV_YUV_420SP_UV) 945 && (ps_ip->s_ive_ip.e_inp_color_fmt != IV_YUV_420SP_VU)) 946 { 947 ps_op->s_ive_op.u4_error_code |= 1 948 << IVE_UNSUPPORTEDPARAM; 949 ps_op->s_ive_op.u4_error_code |= 950 IH264E_INPUT_CHROMA_FORMAT_NOT_SUPPORTED; 951 return (IV_FAIL); 952 } 953 break; 954 } 955 956 case IVE_CMD_CTL_GETVERSION: 957 { 958 ih264e_ctl_getversioninfo_ip_t *ps_ip = pv_api_ip; 959 ih264e_ctl_getversioninfo_op_t *ps_op = pv_api_op; 960 961 if (ps_ip->s_ive_ip.u4_size 962 != sizeof(ih264e_ctl_getversioninfo_ip_t)) 963 { 964 ps_op->s_ive_op.u4_error_code |= 1 965 << IVE_UNSUPPORTEDPARAM; 966 ps_op->s_ive_op.u4_error_code |= 967 IVE_ERR_IP_CTL_GETVERSION_API_STRUCT_SIZE_INCORRECT; 968 return IV_FAIL; 969 } 970 971 if (ps_op->s_ive_op.u4_size 972 != sizeof(ih264e_ctl_getversioninfo_op_t)) 973 { 974 ps_op->s_ive_op.u4_error_code |= 1 975 << IVE_UNSUPPORTEDPARAM; 976 ps_op->s_ive_op.u4_error_code |= 977 IVE_ERR_OP_CTL_GETVERSION_API_STRUCT_SIZE_INCORRECT; 978 return IV_FAIL; 979 } 980 981 if (ps_ip->s_ive_ip.pu1_version == NULL) 982 { 983 ps_op->s_ive_op.u4_error_code |= 1 984 << IVE_UNSUPPORTEDPARAM; 985 ps_op->s_ive_op.u4_error_code |= 986 IVE_ERR_CTL_GET_VERSION_BUFFER_IS_NULL; 987 return IV_FAIL; 988 } 989 990 break; 991 } 992 993 case IVE_CMD_CTL_FLUSH: 994 { 995 ih264e_ctl_flush_ip_t *ps_ip = pv_api_ip; 996 ih264e_ctl_flush_op_t *ps_op = pv_api_op; 997 998 if (ps_ip->s_ive_ip.u4_size 999 != sizeof(ih264e_ctl_flush_ip_t)) 1000 { 1001 ps_op->s_ive_op.u4_error_code |= 1 1002 << IVE_UNSUPPORTEDPARAM; 1003 ps_op->s_ive_op.u4_error_code |= 1004 IVE_ERR_IP_CTL_FLUSH_API_STRUCT_SIZE_INCORRECT; 1005 return IV_FAIL; 1006 } 1007 1008 if (ps_op->s_ive_op.u4_size 1009 != sizeof(ih264e_ctl_flush_op_t)) 1010 { 1011 ps_op->s_ive_op.u4_error_code |= 1 1012 << IVE_UNSUPPORTEDPARAM; 1013 ps_op->s_ive_op.u4_error_code |= 1014 IVE_ERR_OP_CTL_FLUSH_API_STRUCT_SIZE_INCORRECT; 1015 return IV_FAIL; 1016 } 1017 1018 break; 1019 } 1020 1021 case IVE_CMD_CTL_RESET: 1022 { 1023 ih264e_ctl_reset_ip_t *ps_ip = pv_api_ip; 1024 ih264e_ctl_reset_op_t *ps_op = pv_api_op; 1025 1026 if (ps_ip->s_ive_ip.u4_size 1027 != sizeof(ih264e_ctl_reset_ip_t)) 1028 { 1029 ps_op->s_ive_op.u4_error_code |= 1 1030 << IVE_UNSUPPORTEDPARAM; 1031 ps_op->s_ive_op.u4_error_code |= 1032 IVE_ERR_IP_CTL_RESET_API_STRUCT_SIZE_INCORRECT; 1033 return IV_FAIL; 1034 } 1035 1036 if (ps_op->s_ive_op.u4_size 1037 != sizeof(ih264e_ctl_reset_op_t)) 1038 { 1039 ps_op->s_ive_op.u4_error_code |= 1 1040 << IVE_UNSUPPORTEDPARAM; 1041 ps_op->s_ive_op.u4_error_code |= 1042 IVE_ERR_OP_CTL_RESET_API_STRUCT_SIZE_INCORRECT; 1043 return IV_FAIL; 1044 } 1045 1046 break; 1047 } 1048 1049 case IVE_CMD_CTL_SET_NUM_CORES: 1050 { 1051 ih264e_ctl_set_num_cores_ip_t *ps_ip = pv_api_ip; 1052 ih264e_ctl_set_num_cores_op_t *ps_op = pv_api_op; 1053 1054 if (ps_ip->s_ive_ip.u4_size 1055 != sizeof(ih264e_ctl_set_num_cores_ip_t)) 1056 { 1057 ps_op->s_ive_op.u4_error_code |= 1 1058 << IVE_UNSUPPORTEDPARAM; 1059 ps_op->s_ive_op.u4_error_code |= 1060 IVE_ERR_IP_CTL_SETCORES_API_STRUCT_SIZE_INCORRECT; 1061 return IV_FAIL; 1062 } 1063 1064 if (ps_op->s_ive_op.u4_size 1065 != sizeof(ih264e_ctl_set_num_cores_op_t)) 1066 { 1067 ps_op->s_ive_op.u4_error_code |= 1 1068 << IVE_UNSUPPORTEDPARAM; 1069 ps_op->s_ive_op.u4_error_code |= 1070 IVE_ERR_OP_CTL_SETCORES_API_STRUCT_SIZE_INCORRECT; 1071 return IV_FAIL; 1072 } 1073 1074 if ((ps_ip->s_ive_ip.u4_num_cores < 1) 1075 || (ps_ip->s_ive_ip.u4_num_cores > MAX_NUM_CORES)) 1076 { 1077 ps_op->s_ive_op.u4_error_code |= 1 1078 << IVE_UNSUPPORTEDPARAM; 1079 ps_op->s_ive_op.u4_error_code |= 1080 IH264E_INVALID_NUM_CORES; 1081 return IV_FAIL; 1082 } 1083 1084 break; 1085 } 1086 1087 case IVE_CMD_CTL_SET_DIMENSIONS: 1088 { 1089 codec_t *ps_codec = (codec_t *) (ps_handle->pv_codec_handle); 1090 1091 ih264e_ctl_set_dimensions_ip_t *ps_ip = pv_api_ip; 1092 ih264e_ctl_set_dimensions_op_t *ps_op = pv_api_op; 1093 1094 if (ps_ip->s_ive_ip.u4_size 1095 != sizeof(ih264e_ctl_set_dimensions_ip_t)) 1096 { 1097 ps_op->s_ive_op.u4_error_code |= 1 1098 << IVE_UNSUPPORTEDPARAM; 1099 ps_op->s_ive_op.u4_error_code |= 1100 IVE_ERR_IP_CTL_SETDIM_API_STRUCT_SIZE_INCORRECT; 1101 return IV_FAIL; 1102 } 1103 1104 if (ps_op->s_ive_op.u4_size 1105 != sizeof(ih264e_ctl_set_dimensions_op_t)) 1106 { 1107 ps_op->s_ive_op.u4_error_code |= 1 1108 << IVE_UNSUPPORTEDPARAM; 1109 ps_op->s_ive_op.u4_error_code |= 1110 IVE_ERR_OP_CTL_SETDIM_API_STRUCT_SIZE_INCORRECT; 1111 return IV_FAIL; 1112 } 1113 1114 if (ps_ip->s_ive_ip.u4_wd < MIN_WD) 1115 { 1116 ps_op->s_ive_op.u4_error_code |= 1 1117 << IVE_UNSUPPORTEDPARAM; 1118 ps_op->s_ive_op.u4_error_code |= 1119 IH264E_WIDTH_NOT_SUPPORTED; 1120 return (IV_FAIL); 1121 } 1122 1123 if (ps_ip->s_ive_ip.u4_wd > ps_codec->s_cfg.u4_max_wd) 1124 { 1125 ps_op->s_ive_op.u4_error_code |= 1 1126 << IVE_UNSUPPORTEDPARAM; 1127 ps_op->s_ive_op.u4_error_code |= 1128 IH264E_WIDTH_NOT_SUPPORTED; 1129 return (IV_FAIL); 1130 } 1131 1132 if (ps_ip->s_ive_ip.u4_ht < MIN_HT) 1133 { 1134 ps_op->s_ive_op.u4_error_code |= 1 1135 << IVE_UNSUPPORTEDPARAM; 1136 ps_op->s_ive_op.u4_error_code |= 1137 IH264E_HEIGHT_NOT_SUPPORTED; 1138 return (IV_FAIL); 1139 } 1140 1141 if (ps_ip->s_ive_ip.u4_ht > ps_codec->s_cfg.u4_max_ht) 1142 { 1143 ps_op->s_ive_op.u4_error_code |= 1 1144 << IVE_UNSUPPORTEDPARAM; 1145 ps_op->s_ive_op.u4_error_code |= 1146 IH264E_HEIGHT_NOT_SUPPORTED; 1147 return (IV_FAIL); 1148 } 1149 1150 break; 1151 } 1152 1153 case IVE_CMD_CTL_SET_FRAMERATE: 1154 { 1155 ih264e_ctl_set_frame_rate_ip_t *ps_ip = pv_api_ip; 1156 ih264e_ctl_set_frame_rate_op_t *ps_op = pv_api_op; 1157 1158 if (ps_ip->s_ive_ip.u4_size 1159 != sizeof(ih264e_ctl_set_frame_rate_ip_t)) 1160 { 1161 ps_op->s_ive_op.u4_error_code |= 1 1162 << IVE_UNSUPPORTEDPARAM; 1163 ps_op->s_ive_op.u4_error_code |= 1164 IVE_ERR_IP_CTL_SETFRAMERATE_API_STRUCT_SIZE_INCORRECT; 1165 return IV_FAIL; 1166 } 1167 1168 if (ps_op->s_ive_op.u4_size 1169 != sizeof(ih264e_ctl_set_frame_rate_op_t)) 1170 { 1171 ps_op->s_ive_op.u4_error_code |= 1 1172 << IVE_UNSUPPORTEDPARAM; 1173 ps_op->s_ive_op.u4_error_code |= 1174 IVE_ERR_OP_CTL_SETFRAMERATE_API_STRUCT_SIZE_INCORRECT; 1175 return IV_FAIL; 1176 } 1177 1178 if (((ps_ip->s_ive_ip.u4_src_frame_rate * 1000) > DEFAULT_MAX_FRAMERATE) 1179 || ((ps_ip->s_ive_ip.u4_tgt_frame_rate * 1000) > DEFAULT_MAX_FRAMERATE)) 1180 { 1181 ps_op->s_ive_op.u4_error_code |= 1 1182 << IVE_UNSUPPORTEDPARAM; 1183 ps_op->s_ive_op.u4_error_code |= 1184 IH264E_FRAME_RATE_NOT_SUPPORTED; 1185 return (IV_FAIL); 1186 } 1187 1188 if ((ps_ip->s_ive_ip.u4_src_frame_rate == 0) 1189 || (ps_ip->s_ive_ip.u4_tgt_frame_rate == 0)) 1190 { 1191 ps_op->s_ive_op.u4_error_code |= 1 1192 << IVE_UNSUPPORTEDPARAM; 1193 ps_op->s_ive_op.u4_error_code |= 1194 IH264E_FRAME_RATE_NOT_SUPPORTED; 1195 return (IV_FAIL); 1196 } 1197 1198 if (ps_ip->s_ive_ip.u4_tgt_frame_rate 1199 > ps_ip->s_ive_ip.u4_src_frame_rate) 1200 { 1201 ps_op->s_ive_op.u4_error_code |= 1 1202 << IVE_UNSUPPORTEDPARAM; 1203 ps_op->s_ive_op.u4_error_code |= 1204 IH264E_TGT_FRAME_RATE_EXCEEDS_SRC_FRAME_RATE; 1205 return (IV_FAIL); 1206 } 1207 1208 break; 1209 } 1210 1211 case IVE_CMD_CTL_SET_BITRATE: 1212 { 1213 ih264e_ctl_set_bitrate_ip_t *ps_ip = pv_api_ip; 1214 ih264e_ctl_set_bitrate_op_t *ps_op = pv_api_op; 1215 1216 if (ps_ip->s_ive_ip.u4_size 1217 != sizeof(ih264e_ctl_set_bitrate_ip_t)) 1218 { 1219 ps_op->s_ive_op.u4_error_code |= 1 1220 << IVE_UNSUPPORTEDPARAM; 1221 ps_op->s_ive_op.u4_error_code |= 1222 IVE_ERR_IP_CTL_SETBITRATE_API_STRUCT_SIZE_INCORRECT; 1223 return IV_FAIL; 1224 } 1225 1226 if (ps_op->s_ive_op.u4_size 1227 != sizeof(ih264e_ctl_set_bitrate_op_t)) 1228 { 1229 ps_op->s_ive_op.u4_error_code |= 1 1230 << IVE_UNSUPPORTEDPARAM; 1231 ps_op->s_ive_op.u4_error_code |= 1232 IVE_ERR_OP_CTL_SETBITRATE_API_STRUCT_SIZE_INCORRECT; 1233 return IV_FAIL; 1234 } 1235 1236 if ((ps_ip->s_ive_ip.u4_target_bitrate > DEFAULT_MAX_BITRATE) 1237 || (ps_ip->s_ive_ip.u4_target_bitrate == 0)) 1238 { 1239 ps_op->s_ive_op.u4_error_code |= 1 1240 << IVE_UNSUPPORTEDPARAM; 1241 ps_op->s_ive_op.u4_error_code |= 1242 IH264E_BITRATE_NOT_SUPPORTED; 1243 return (IV_FAIL); 1244 } 1245 1246 break; 1247 } 1248 1249 case IVE_CMD_CTL_SET_FRAMETYPE: 1250 { 1251 ih264e_ctl_set_frame_type_ip_t *ps_ip = pv_api_ip; 1252 ih264e_ctl_set_frame_type_op_t *ps_op = pv_api_op; 1253 1254 if (ps_ip->s_ive_ip.u4_size 1255 != sizeof(ih264e_ctl_set_frame_type_ip_t)) 1256 { 1257 ps_op->s_ive_op.u4_error_code |= 1 1258 << IVE_UNSUPPORTEDPARAM; 1259 ps_op->s_ive_op.u4_error_code |= 1260 IVE_ERR_IP_CTL_SETFRAMETYPE_API_STRUCT_SIZE_INCORRECT; 1261 return IV_FAIL; 1262 } 1263 1264 if (ps_op->s_ive_op.u4_size 1265 != sizeof(ih264e_ctl_set_frame_type_op_t)) 1266 { 1267 ps_op->s_ive_op.u4_error_code |= 1 1268 << IVE_UNSUPPORTEDPARAM; 1269 ps_op->s_ive_op.u4_error_code |= 1270 IVE_ERR_OP_CTL_SETFRAMETYPE_API_STRUCT_SIZE_INCORRECT; 1271 return IV_FAIL; 1272 } 1273 1274 if ((ps_ip->s_ive_ip.e_frame_type != IV_NA_FRAME) 1275 && (ps_ip->s_ive_ip.e_frame_type != IV_I_FRAME) 1276 && (ps_ip->s_ive_ip.e_frame_type != IV_P_FRAME) 1277 && (ps_ip->s_ive_ip.e_frame_type != IV_IDR_FRAME)) 1278 { 1279 ps_op->s_ive_op.u4_error_code |= 1 1280 << IVE_UNSUPPORTEDPARAM; 1281 ps_op->s_ive_op.u4_error_code |= 1282 IH264E_INVALID_FORCE_FRAME_INPUT; 1283 return IV_FAIL; 1284 } 1285 break; 1286 } 1287 1288 case IVE_CMD_CTL_SET_ME_PARAMS: 1289 { 1290 codec_t *ps_codec = (codec_t *) (ps_handle->pv_codec_handle); 1291 1292 ih264e_ctl_set_me_params_ip_t *ps_ip = pv_api_ip; 1293 ih264e_ctl_set_me_params_op_t *ps_op = pv_api_op; 1294 1295 if (ps_ip->s_ive_ip.u4_size 1296 != sizeof(ih264e_ctl_set_me_params_ip_t)) 1297 { 1298 ps_op->s_ive_op.u4_error_code |= 1 1299 << IVE_UNSUPPORTEDPARAM; 1300 ps_op->s_ive_op.u4_error_code |= 1301 IVE_ERR_IP_CTL_SETMEPARAMS_API_STRUCT_SIZE_INCORRECT; 1302 return IV_FAIL; 1303 } 1304 1305 if (ps_op->s_ive_op.u4_size 1306 != sizeof(ih264e_ctl_set_me_params_op_t)) 1307 { 1308 ps_op->s_ive_op.u4_error_code |= 1 1309 << IVE_UNSUPPORTEDPARAM; 1310 ps_op->s_ive_op.u4_error_code |= 1311 IVE_ERR_OP_CTL_SETMEPARAMS_API_STRUCT_SIZE_INCORRECT; 1312 return IV_FAIL; 1313 } 1314 1315 if ((ps_ip->s_ive_ip.u4_me_speed_preset != FULL_SRCH) 1316 && (ps_ip->s_ive_ip.u4_me_speed_preset != DMND_SRCH) 1317 && (ps_ip->s_ive_ip.u4_me_speed_preset != HEX_SRCH)) 1318 { 1319 ps_op->s_ive_op.u4_error_code |= 1 1320 << IVE_UNSUPPORTEDPARAM; 1321 ps_op->s_ive_op.u4_error_code |= 1322 IH264E_INVALID_ME_SPEED_PRESET; 1323 return IV_FAIL; 1324 } 1325 1326 if ((ps_ip->s_ive_ip.u4_enable_hpel != 0) 1327 && (ps_ip->s_ive_ip.u4_enable_hpel != 1)) 1328 { 1329 ps_op->s_ive_op.u4_error_code |= 1 1330 << IVE_UNSUPPORTEDPARAM; 1331 ps_op->s_ive_op.u4_error_code |= 1332 IH264E_INVALID_HALFPEL_OPTION; 1333 return IV_FAIL; 1334 } 1335 1336 if ((ps_ip->s_ive_ip.u4_enable_qpel != 0) 1337 && (ps_ip->s_ive_ip.u4_enable_qpel != 1)) 1338 { 1339 ps_op->s_ive_op.u4_error_code |= 1 1340 << IVE_UNSUPPORTEDPARAM; 1341 ps_op->s_ive_op.u4_error_code |= 1342 IH264E_INVALID_QPEL_OPTION; 1343 return IV_FAIL; 1344 } 1345 1346 if ((ps_ip->s_ive_ip.u4_enable_fast_sad != 0) 1347 && (ps_ip->s_ive_ip.u4_enable_fast_sad != 1)) 1348 { 1349 ps_op->s_ive_op.u4_error_code |= 1 1350 << IVE_UNSUPPORTEDPARAM; 1351 ps_op->s_ive_op.u4_error_code |= 1352 IH264E_INVALID_FAST_SAD_OPTION; 1353 return IV_FAIL; 1354 } 1355 1356 if (ps_ip->s_ive_ip.u4_enable_alt_ref > 255) 1357 { 1358 ps_op->s_ive_op.u4_error_code |= 1 1359 << IVE_UNSUPPORTEDPARAM; 1360 ps_op->s_ive_op.u4_error_code |= 1361 IH264E_INVALID_ALT_REF_OPTION; 1362 return IV_FAIL; 1363 } 1364 1365 if (ps_ip->s_ive_ip.u4_srch_rng_x 1366 > ps_codec->s_cfg.u4_max_srch_rng_x) 1367 { 1368 ps_op->s_ive_op.u4_error_code |= 1 1369 << IVE_UNSUPPORTEDPARAM; 1370 ps_op->s_ive_op.u4_error_code |= 1371 IH264E_HORIZONTAL_SEARCH_RANGE_NOT_SUPPORTED; 1372 return (IV_FAIL); 1373 } 1374 1375 if (ps_ip->s_ive_ip.u4_srch_rng_y 1376 > ps_codec->s_cfg.u4_max_srch_rng_y) 1377 { 1378 ps_op->s_ive_op.u4_error_code |= 1 1379 << IVE_UNSUPPORTEDPARAM; 1380 ps_op->s_ive_op.u4_error_code |= 1381 IH264E_VERTICAL_SEARCH_RANGE_NOT_SUPPORTED; 1382 return (IV_FAIL); 1383 } 1384 1385 break; 1386 } 1387 1388 case IVE_CMD_CTL_SET_IPE_PARAMS: 1389 { 1390 ih264e_ctl_set_ipe_params_ip_t *ps_ip = pv_api_ip; 1391 ih264e_ctl_set_ipe_params_op_t *ps_op = pv_api_op; 1392 1393 if (ps_ip->s_ive_ip.u4_size 1394 != sizeof(ih264e_ctl_set_ipe_params_ip_t)) 1395 { 1396 ps_op->s_ive_op.u4_error_code |= 1 1397 << IVE_UNSUPPORTEDPARAM; 1398 ps_op->s_ive_op.u4_error_code |= 1399 IVE_ERR_IP_CTL_SETIPEPARAMS_API_STRUCT_SIZE_INCORRECT; 1400 return IV_FAIL; 1401 } 1402 1403 if (ps_op->s_ive_op.u4_size 1404 != sizeof(ih264e_ctl_set_ipe_params_op_t)) 1405 { 1406 ps_op->s_ive_op.u4_error_code |= 1 1407 << IVE_UNSUPPORTEDPARAM; 1408 ps_op->s_ive_op.u4_error_code |= 1409 IVE_ERR_OP_CTL_SETIPEPARAMS_API_STRUCT_SIZE_INCORRECT; 1410 return IV_FAIL; 1411 } 1412 1413 if ((ps_ip->s_ive_ip.u4_enable_intra_4x4 != 0) 1414 && (ps_ip->s_ive_ip.u4_enable_intra_4x4 != 1)) 1415 { 1416 ps_op->s_ive_op.u4_error_code |= 1 1417 << IVE_UNSUPPORTEDPARAM; 1418 ps_op->s_ive_op.u4_error_code |= 1419 IH264E_INVALID_INTRA4x4_OPTION; 1420 return IV_FAIL; 1421 } 1422 1423 if ((ps_ip->s_ive_ip.u4_constrained_intra_pred != 0) 1424 && (ps_ip->s_ive_ip.u4_constrained_intra_pred != 1)) 1425 { 1426 ps_op->s_ive_op.u4_error_code |= 1 1427 << IVE_UNSUPPORTEDPARAM; 1428 ps_op->s_ive_op.u4_error_code |= 1429 IH264E_INVALID_CONSTRAINED_INTRA_PREDICTION_MODE; 1430 return IV_FAIL; 1431 } 1432 1433 if ((ps_ip->s_ive_ip.u4_enc_speed_preset != IVE_CONFIG) 1434 && (ps_ip->s_ive_ip.u4_enc_speed_preset != IVE_SLOWEST) 1435 && (ps_ip->s_ive_ip.u4_enc_speed_preset != IVE_NORMAL) 1436 && (ps_ip->s_ive_ip.u4_enc_speed_preset != IVE_FAST) 1437 && (ps_ip->s_ive_ip.u4_enc_speed_preset != IVE_HIGH_SPEED) 1438 && (ps_ip->s_ive_ip.u4_enc_speed_preset != IVE_FASTEST)) 1439 { 1440 ps_op->s_ive_op.u4_error_code |= 1 1441 << IVE_UNSUPPORTEDPARAM; 1442 ps_op->s_ive_op.u4_error_code |= 1443 IH264E_INVALID_ENC_SPEED_PRESET; 1444 return IV_FAIL; 1445 } 1446 1447 break; 1448 } 1449 1450 case IVE_CMD_CTL_SET_GOP_PARAMS: 1451 { 1452 ih264e_ctl_set_gop_params_ip_t *ps_ip = pv_api_ip; 1453 ih264e_ctl_set_gop_params_op_t *ps_op = pv_api_op; 1454 1455 if (ps_ip->s_ive_ip.u4_size 1456 != sizeof(ih264e_ctl_set_gop_params_ip_t)) 1457 { 1458 ps_op->s_ive_op.u4_error_code |= 1 1459 << IVE_UNSUPPORTEDPARAM; 1460 ps_op->s_ive_op.u4_error_code |= 1461 IVE_ERR_IP_CTL_SETGOPPARAMS_API_STRUCT_SIZE_INCORRECT; 1462 return IV_FAIL; 1463 } 1464 1465 if (ps_op->s_ive_op.u4_size 1466 != sizeof(ih264e_ctl_set_gop_params_op_t)) 1467 { 1468 ps_op->s_ive_op.u4_error_code |= 1 1469 << IVE_UNSUPPORTEDPARAM; 1470 ps_op->s_ive_op.u4_error_code |= 1471 IVE_ERR_OP_CTL_SETGOPPARAMS_API_STRUCT_SIZE_INCORRECT; 1472 return IV_FAIL; 1473 } 1474 1475 if ((ps_ip->s_ive_ip.u4_i_frm_interval < DEFAULT_MIN_INTRA_FRAME_RATE) 1476 || (ps_ip->s_ive_ip.u4_i_frm_interval > DEFAULT_MAX_INTRA_FRAME_RATE)) 1477 { 1478 ps_op->s_ive_op.u4_error_code |= 1 1479 << IVE_UNSUPPORTEDPARAM; 1480 ps_op->s_ive_op.u4_error_code |= 1481 IH264E_INVALID_INTRA_FRAME_INTERVAL; 1482 return IV_FAIL; 1483 } 1484 1485 if ((ps_ip->s_ive_ip.u4_idr_frm_interval < DEFAULT_MIN_INTRA_FRAME_RATE) 1486 || (ps_ip->s_ive_ip.u4_idr_frm_interval > DEFAULT_MAX_INTRA_FRAME_RATE)) 1487 { 1488 ps_op->s_ive_op.u4_error_code |= 1 1489 << IVE_UNSUPPORTEDPARAM; 1490 ps_op->s_ive_op.u4_error_code |= 1491 IH264E_INVALID_IDR_FRAME_INTERVAL; 1492 return IV_FAIL; 1493 } 1494 1495 break; 1496 } 1497 1498 case IVE_CMD_CTL_SET_DEBLOCK_PARAMS: 1499 { 1500 ih264e_ctl_set_deblock_params_ip_t *ps_ip = pv_api_ip; 1501 ih264e_ctl_set_deblock_params_op_t *ps_op = pv_api_op; 1502 1503 if (ps_ip->s_ive_ip.u4_size 1504 != sizeof(ih264e_ctl_set_deblock_params_ip_t)) 1505 { 1506 ps_op->s_ive_op.u4_error_code |= 1 1507 << IVE_UNSUPPORTEDPARAM; 1508 ps_op->s_ive_op.u4_error_code |= 1509 IVE_ERR_IP_CTL_SETDEBLKPARAMS_API_STRUCT_SIZE_INCORRECT; 1510 return IV_FAIL; 1511 } 1512 1513 if (ps_op->s_ive_op.u4_size 1514 != sizeof(ih264e_ctl_set_deblock_params_op_t)) 1515 { 1516 ps_op->s_ive_op.u4_error_code |= 1 1517 << IVE_UNSUPPORTEDPARAM; 1518 ps_op->s_ive_op.u4_error_code |= 1519 IVE_ERR_OP_CTL_SETDEBLKPARAMS_API_STRUCT_SIZE_INCORRECT; 1520 return IV_FAIL; 1521 } 1522 1523 if ((ps_ip->s_ive_ip.u4_disable_deblock_level != DISABLE_DEBLK_LEVEL_0) 1524 && (ps_ip->s_ive_ip.u4_disable_deblock_level != DISABLE_DEBLK_LEVEL_2) 1525 && (ps_ip->s_ive_ip.u4_disable_deblock_level != DISABLE_DEBLK_LEVEL_3) 1526 && (ps_ip->s_ive_ip.u4_disable_deblock_level != DISABLE_DEBLK_LEVEL_4)) 1527 { 1528 ps_op->s_ive_op.u4_error_code |= 1 1529 << IVE_UNSUPPORTEDPARAM; 1530 ps_op->s_ive_op.u4_error_code |= 1531 IH264E_INVALID_DEBLOCKING_TYPE_INPUT; 1532 return IV_FAIL; 1533 } 1534 1535 break; 1536 } 1537 1538 case IVE_CMD_CTL_SET_QP: 1539 { 1540 ih264e_ctl_set_qp_ip_t *ps_ip = pv_api_ip; 1541 ih264e_ctl_set_qp_op_t *ps_op = pv_api_op; 1542 1543 if (ps_ip->s_ive_ip.u4_size 1544 != sizeof(ih264e_ctl_set_qp_ip_t)) 1545 { 1546 ps_op->s_ive_op.u4_error_code |= 1 1547 << IVE_UNSUPPORTEDPARAM; 1548 ps_op->s_ive_op.u4_error_code |= 1549 IVE_ERR_IP_CTL_SETQPPARAMS_API_STRUCT_SIZE_INCORRECT; 1550 return IV_FAIL; 1551 } 1552 1553 if (ps_op->s_ive_op.u4_size 1554 != sizeof(ih264e_ctl_set_qp_op_t)) 1555 { 1556 ps_op->s_ive_op.u4_error_code |= 1 1557 << IVE_UNSUPPORTEDPARAM; 1558 ps_op->s_ive_op.u4_error_code |= 1559 IVE_ERR_OP_CTL_SETQPPARAMS_API_STRUCT_SIZE_INCORRECT; 1560 return IV_FAIL; 1561 } 1562 1563 if ((ps_ip->s_ive_ip.u4_i_qp_max > MAX_H264_QP) 1564 || (ps_ip->s_ive_ip.u4_p_qp_max > MAX_H264_QP) 1565 || (ps_ip->s_ive_ip.u4_b_qp_max > MAX_H264_QP)) 1566 { 1567 ps_op->s_ive_op.u4_error_code |= 1 1568 << IVE_UNSUPPORTEDPARAM; 1569 ps_op->s_ive_op.u4_error_code |= 1570 IH264E_INVALID_MAX_FRAME_QP; 1571 return IV_FAIL; 1572 } 1573 1574 /* We donot support QP < 4 */ 1575 if ((ps_ip->s_ive_ip.u4_i_qp_min < 4) 1576 || (ps_ip->s_ive_ip.u4_p_qp_min < 4) 1577 || (ps_ip->s_ive_ip.u4_b_qp_min < 4) 1578 || (ps_ip->s_ive_ip.u4_i_qp_min > ps_ip->s_ive_ip.u4_i_qp_max) 1579 || (ps_ip->s_ive_ip.u4_p_qp_min > ps_ip->s_ive_ip.u4_p_qp_max) 1580 || (ps_ip->s_ive_ip.u4_b_qp_min > ps_ip->s_ive_ip.u4_b_qp_max)) 1581 { 1582 ps_op->s_ive_op.u4_error_code |= 1 1583 << IVE_UNSUPPORTEDPARAM; 1584 ps_op->s_ive_op.u4_error_code |= 1585 IH264E_INVALID_MIN_FRAME_QP; 1586 return IV_FAIL; 1587 } 1588 1589 if ((ps_ip->s_ive_ip.u4_i_qp > ps_ip->s_ive_ip.u4_i_qp_max) 1590 || (ps_ip->s_ive_ip.u4_p_qp > ps_ip->s_ive_ip.u4_p_qp_max) 1591 || (ps_ip->s_ive_ip.u4_b_qp > ps_ip->s_ive_ip.u4_b_qp_max)) 1592 { 1593 ps_op->s_ive_op.u4_error_code |= 1 1594 << IVE_UNSUPPORTEDPARAM; 1595 ps_op->s_ive_op.u4_error_code |= IH264E_INVALID_INIT_QP; 1596 return IV_FAIL; 1597 } 1598 1599 if ((ps_ip->s_ive_ip.u4_i_qp < ps_ip->s_ive_ip.u4_i_qp_min) 1600 || (ps_ip->s_ive_ip.u4_p_qp < ps_ip->s_ive_ip.u4_p_qp_min) 1601 || (ps_ip->s_ive_ip.u4_b_qp < ps_ip->s_ive_ip.u4_b_qp_min)) 1602 { 1603 ps_op->s_ive_op.u4_error_code |= 1 1604 << IVE_UNSUPPORTEDPARAM; 1605 ps_op->s_ive_op.u4_error_code |= IH264E_INVALID_INIT_QP; 1606 return IV_FAIL; 1607 } 1608 1609 break; 1610 } 1611 1612 case IVE_CMD_CTL_SET_ENC_MODE: 1613 { 1614 ih264e_ctl_set_enc_mode_ip_t *ps_ip = pv_api_ip; 1615 ih264e_ctl_set_enc_mode_op_t *ps_op = pv_api_op; 1616 1617 if (ps_ip->s_ive_ip.u4_size 1618 != sizeof(ih264e_ctl_set_enc_mode_ip_t)) 1619 { 1620 ps_op->s_ive_op.u4_error_code |= 1 1621 << IVE_UNSUPPORTEDPARAM; 1622 ps_op->s_ive_op.u4_error_code |= 1623 IVE_ERR_IP_CTL_SETENCMODE_API_STRUCT_SIZE_INCORRECT; 1624 return IV_FAIL; 1625 } 1626 1627 if (ps_op->s_ive_op.u4_size 1628 != sizeof(ih264e_ctl_set_enc_mode_op_t)) 1629 { 1630 ps_op->s_ive_op.u4_error_code |= 1 1631 << IVE_UNSUPPORTEDPARAM; 1632 ps_op->s_ive_op.u4_error_code |= 1633 IVE_ERR_OP_CTL_SETENCMODE_API_STRUCT_SIZE_INCORRECT; 1634 return IV_FAIL; 1635 } 1636 1637 if ((ps_ip->s_ive_ip.e_enc_mode != IVE_ENC_MODE_HEADER) 1638 && (ps_ip->s_ive_ip.e_enc_mode != IVE_ENC_MODE_PICTURE)) 1639 { 1640 ps_op->s_ive_op.u4_error_code |= 1 1641 << IVE_UNSUPPORTEDPARAM; 1642 ps_op->s_ive_op.u4_error_code |= 1643 IH264E_INVALID_ENC_OPERATION_MODE; 1644 return IV_FAIL; 1645 } 1646 1647 break; 1648 } 1649 1650 case IVE_CMD_CTL_SET_VBV_PARAMS: 1651 { 1652 ih264e_ctl_set_vbv_params_ip_t *ps_ip = pv_api_ip; 1653 ih264e_ctl_set_vbv_params_op_t *ps_op = pv_api_op; 1654 1655 if (ps_ip->s_ive_ip.u4_size 1656 != sizeof(ih264e_ctl_set_vbv_params_ip_t)) 1657 { 1658 ps_op->s_ive_op.u4_error_code |= 1 1659 << IVE_UNSUPPORTEDPARAM; 1660 ps_op->s_ive_op.u4_error_code |= 1661 IVE_ERR_IP_CTL_SETVBVPARAMS_API_STRUCT_SIZE_INCORRECT; 1662 return IV_FAIL; 1663 } 1664 1665 if (ps_op->s_ive_op.u4_size 1666 != sizeof(ih264e_ctl_set_vbv_params_op_t)) 1667 { 1668 ps_op->s_ive_op.u4_error_code |= 1 1669 << IVE_UNSUPPORTEDPARAM; 1670 ps_op->s_ive_op.u4_error_code |= 1671 IVE_ERR_OP_CTL_SETVBVPARAMS_API_STRUCT_SIZE_INCORRECT; 1672 return IV_FAIL; 1673 } 1674 1675 if ((ps_ip->s_ive_ip.u4_vbv_buffer_delay < DEFAULT_MIN_BUFFER_DELAY) 1676 || (ps_ip->s_ive_ip.u4_vbv_buffer_delay > DEFAULT_MAX_BUFFER_DELAY)) 1677 { 1678 ps_op->s_ive_op.u4_error_code |= 1 1679 << IVE_UNSUPPORTEDPARAM; 1680 ps_op->s_ive_op.u4_error_code |= 1681 IH264E_INVALID_BUFFER_DELAY; 1682 return IV_FAIL; 1683 } 1684 1685 break; 1686 } 1687 1688 case IVE_CMD_CTL_SET_AIR_PARAMS: 1689 { 1690 ih264e_ctl_set_air_params_ip_t *ps_ip = pv_api_ip; 1691 ih264e_ctl_set_air_params_op_t *ps_op = pv_api_op; 1692 1693 if (ps_ip->s_ive_ip.u4_size 1694 != sizeof(ih264e_ctl_set_air_params_ip_t)) 1695 { 1696 ps_op->s_ive_op.u4_error_code |= 1 1697 << IVE_UNSUPPORTEDPARAM; 1698 ps_op->s_ive_op.u4_error_code |= 1699 IVE_ERR_IP_CTL_SETAIRPARAMS_API_STRUCT_SIZE_INCORRECT; 1700 return IV_FAIL; 1701 } 1702 1703 if (ps_op->s_ive_op.u4_size 1704 != sizeof(ih264e_ctl_set_air_params_op_t)) 1705 { 1706 ps_op->s_ive_op.u4_error_code |= 1 1707 << IVE_UNSUPPORTEDPARAM; 1708 ps_op->s_ive_op.u4_error_code |= 1709 IVE_ERR_OP_CTL_SETAIRPARAMS_API_STRUCT_SIZE_INCORRECT; 1710 return IV_FAIL; 1711 } 1712 1713 if ((ps_ip->s_ive_ip.e_air_mode != IVE_AIR_MODE_NONE) 1714 && (ps_ip->s_ive_ip.e_air_mode != IVE_AIR_MODE_CYCLIC) 1715 && (ps_ip->s_ive_ip.e_air_mode != IVE_AIR_MODE_RANDOM)) 1716 { 1717 ps_op->s_ive_op.u4_error_code |= 1 1718 << IVE_UNSUPPORTEDPARAM; 1719 ps_op->s_ive_op.u4_error_code |= 1720 IH264E_INVALID_AIR_MODE; 1721 return IV_FAIL; 1722 } 1723 1724 if (ps_ip->s_ive_ip.u4_air_refresh_period == 0) 1725 { 1726 ps_op->s_ive_op.u4_error_code |= 1 1727 << IVE_UNSUPPORTEDPARAM; 1728 ps_op->s_ive_op.u4_error_code |= 1729 IH264E_INVALID_AIR_REFRESH_PERIOD; 1730 return IV_FAIL; 1731 } 1732 1733 break; 1734 } 1735 1736 case IVE_CMD_CTL_SET_PROFILE_PARAMS: 1737 { 1738 ih264e_ctl_set_profile_params_ip_t *ps_ip = pv_api_ip; 1739 ih264e_ctl_set_profile_params_op_t *ps_op = pv_api_op; 1740 1741 if (ps_ip->s_ive_ip.u4_size 1742 != sizeof(ih264e_ctl_set_profile_params_ip_t)) 1743 { 1744 ps_op->s_ive_op.u4_error_code |= 1 1745 << IVE_UNSUPPORTEDPARAM; 1746 ps_op->s_ive_op.u4_error_code |= 1747 IVE_ERR_IP_CTL_SETPROFILE_API_STRUCT_SIZE_INCORRECT; 1748 return IV_FAIL; 1749 } 1750 1751 if (ps_op->s_ive_op.u4_size 1752 != sizeof(ih264e_ctl_set_profile_params_op_t)) 1753 { 1754 ps_op->s_ive_op.u4_error_code |= 1 1755 << IVE_UNSUPPORTEDPARAM; 1756 ps_op->s_ive_op.u4_error_code |= 1757 IVE_ERR_OP_CTL_SETPROFILE_API_STRUCT_SIZE_INCORRECT; 1758 return IV_FAIL; 1759 } 1760 1761 if (ps_ip->s_ive_ip.e_profile != IV_PROFILE_BASE && 1762 ps_ip->s_ive_ip.e_profile != IV_PROFILE_MAIN) 1763 { 1764 ps_op->s_ive_op.u4_error_code |= 1 1765 << IVE_UNSUPPORTEDPARAM; 1766 ps_op->s_ive_op.u4_error_code |= 1767 IH264E_PROFILE_NOT_SUPPORTED; 1768 return IV_FAIL; 1769 } 1770 1771 if (ps_ip->s_ive_ip.u4_entropy_coding_mode > 1) 1772 { 1773 ps_op->s_ive_op.u4_error_code |= 1 1774 << IVE_UNSUPPORTEDPARAM; 1775 ps_op->s_ive_op.u4_error_code |= 1776 IH264E_INVALID_ENTROPY_CODING_MODE; 1777 return IV_FAIL; 1778 } 1779 1780 break; 1781 } 1782 1783 default: 1784 *(pu4_api_op + 1) |= 1 << IVE_UNSUPPORTEDPARAM; 1785 *(pu4_api_op + 1) |= IVE_ERR_INVALID_API_SUB_CMD; 1786 return IV_FAIL; 1787 } 1788 1789 break; 1790 } 1791 1792 default: 1793 *(pu4_api_op + 1) |= 1 << IVE_UNSUPPORTEDPARAM; 1794 *(pu4_api_op + 1) |= IVE_ERR_INVALID_API_CMD; 1795 return IV_FAIL; 1796 } 1797 1798 return IV_SUCCESS; 1799 } 1800 1801 /** 1802 ******************************************************************************* 1803 * 1804 * @brief update encoder configuration parameters 1805 * 1806 * @par Description: 1807 * updates encoder configuration parameters from the given config set. 1808 * Initialize/reinitialize codec parameters according to new configurations. 1809 * 1810 * @param[in] ps_codec 1811 * Pointer to codec context 1812 * 1813 * @param[in] ps_cfg 1814 * Pointer to config param set 1815 * 1816 * @remarks none 1817 * 1818 ******************************************************************************* 1819 */ 1820 IH264E_ERROR_T ih264e_codec_update_config(codec_t *ps_codec, 1821 cfg_params_t *ps_cfg) 1822 { 1823 /* config params */ 1824 cfg_params_t *ps_curr_cfg = &ps_codec->s_cfg; 1825 1826 /* error status */ 1827 IH264E_ERROR_T err = IH264E_SUCCESS; 1828 1829 /* temp var */ 1830 UWORD32 u4_init_rc = 0; 1831 1832 /***********************/ 1833 /* UPDATE CODEC CONFIG */ 1834 /***********************/ 1835 if (ps_cfg->e_cmd == IVE_CMD_CTL_SET_DIMENSIONS) 1836 { 1837 UWORD32 wd_aln = ALIGN16(ps_cfg->u4_wd); 1838 UWORD32 ht_aln = ALIGN16(ps_cfg->u4_ht); 1839 1840 if (ps_curr_cfg->u4_wd != wd_aln || ps_curr_cfg->u4_ht != ht_aln 1841 || ps_curr_cfg->u4_disp_wd != ps_cfg->u4_disp_wd 1842 || ps_curr_cfg->u4_disp_ht != ps_cfg->u4_disp_ht) 1843 { 1844 ps_curr_cfg->u4_wd = wd_aln; 1845 ps_curr_cfg->u4_ht = ht_aln; 1846 1847 ps_curr_cfg->u4_disp_wd = ps_cfg->u4_disp_wd; 1848 ps_curr_cfg->u4_disp_ht = ps_cfg->u4_disp_ht; 1849 1850 ps_curr_cfg->i4_wd_mbs = ps_curr_cfg->u4_wd >> 4; 1851 ps_curr_cfg->i4_ht_mbs = ps_curr_cfg->u4_ht >> 4; 1852 1853 ps_codec->i4_rec_strd = ALIGN16(ps_cfg->u4_wd) + PAD_WD; 1854 1855 /* If number of MBs in a frame changes the air map also changes. 1856 * Hence recompute air map also reset air pic cnt */ 1857 if (ps_codec->s_cfg.e_air_mode != IVE_AIR_MODE_NONE) 1858 { 1859 /* re-init the air map */ 1860 ih264e_init_air_map(ps_codec); 1861 1862 /* reset air counter */ 1863 ps_codec->i4_air_pic_cnt = -1; 1864 } 1865 1866 /* initialize mv bank buffer manager */ 1867 err = ih264e_mv_buf_mgr_add_bufs(ps_codec); 1868 if (err != IH264E_SUCCESS) 1869 return err; 1870 1871 /* initialize ref bank buffer manager */ 1872 err = ih264e_pic_buf_mgr_add_bufs(ps_codec); 1873 if (err != IH264E_SUCCESS) 1874 return err; 1875 1876 /* since dimension changed, start new sequence by forcing IDR */ 1877 ps_codec->force_curr_frame_type = IV_IDR_FRAME; 1878 1879 /* in case dimension changes, we need to reinitialize RC as the 1880 * old model shall not fit further */ 1881 u4_init_rc = 1; 1882 1883 /* when the dimension changes, the header needs to be regenerated */ 1884 ps_codec->i4_gen_header = 1; 1885 } 1886 } 1887 else if (ps_cfg->e_cmd == IVE_CMD_CTL_SET_FRAMERATE) 1888 { 1889 /* temp var */ 1890 UWORD32 u4_src_ticks, u4_tgt_ticks; 1891 1892 u4_src_ticks = ih264e_frame_time_get_src_ticks( 1893 ps_codec->s_rate_control.pps_frame_time); 1894 1895 u4_tgt_ticks = ih264e_frame_time_get_tgt_ticks( 1896 ps_codec->s_rate_control.pps_frame_time); 1897 1898 /* Change frame rate */ 1899 if (ps_codec->s_cfg.u4_src_frame_rate 1900 != ps_cfg->u4_src_frame_rate * 1000) 1901 { 1902 ps_codec->s_cfg.u4_src_frame_rate = ps_cfg->u4_src_frame_rate 1903 * 1000; 1904 1905 ih264e_frame_time_update_src_frame_rate( 1906 ps_codec->s_rate_control.pps_frame_time, 1907 ps_codec->s_cfg.u4_src_frame_rate); 1908 1909 ih264_time_stamp_update_frame_rate( 1910 ps_codec->s_rate_control.pps_time_stamp, 1911 ps_codec->s_cfg.u4_src_frame_rate); 1912 1913 irc_change_frame_rate(ps_codec->s_rate_control.pps_rate_control_api, 1914 ps_codec->s_cfg.u4_src_frame_rate, 1915 u4_src_ticks, u4_tgt_ticks); 1916 } 1917 1918 if (ps_codec->s_cfg.u4_tgt_frame_rate 1919 != ps_cfg->u4_tgt_frame_rate * 1000) 1920 { 1921 ps_codec->s_cfg.u4_tgt_frame_rate = ps_cfg->u4_tgt_frame_rate 1922 * 1000; 1923 1924 ih264e_frame_time_update_tgt_frame_rate( 1925 ps_codec->s_rate_control.pps_frame_time, 1926 ps_codec->s_cfg.u4_tgt_frame_rate); 1927 1928 irc_change_frame_rate(ps_codec->s_rate_control.pps_rate_control_api, 1929 ps_codec->s_cfg.u4_src_frame_rate, 1930 u4_src_ticks, u4_tgt_ticks); 1931 1932 irc_change_frm_rate_for_bit_alloc( 1933 ps_codec->s_rate_control.pps_rate_control_api, 1934 ps_codec->s_cfg.u4_tgt_frame_rate); 1935 } 1936 1937 } 1938 else if (ps_cfg->e_cmd == IVE_CMD_CTL_SET_BITRATE) 1939 { 1940 if (ps_curr_cfg->u4_target_bitrate != ps_cfg->u4_target_bitrate) 1941 { 1942 if (IVE_RC_NONE != ps_curr_cfg->e_rc_mode) 1943 irc_change_avg_bit_rate( 1944 ps_codec->s_rate_control.pps_rate_control_api, 1945 ps_cfg->u4_target_bitrate); 1946 1947 ps_curr_cfg->u4_target_bitrate = ps_cfg->u4_target_bitrate; 1948 } 1949 } 1950 else if (ps_cfg->e_cmd == IVE_CMD_CTL_SET_FRAMETYPE) 1951 { 1952 switch (ps_cfg->e_frame_type) 1953 { 1954 case IV_I_FRAME: 1955 ps_codec->force_curr_frame_type = IV_I_FRAME; 1956 break; 1957 1958 case IV_IDR_FRAME: 1959 ps_codec->force_curr_frame_type = IV_IDR_FRAME; 1960 break; 1961 1962 case IV_P_FRAME: 1963 default: 1964 break; 1965 } 1966 } 1967 else if (ps_cfg->e_cmd == IVE_CMD_CTL_SET_ME_PARAMS) 1968 { 1969 if (ps_curr_cfg->u4_enc_speed_preset == IVE_CONFIG) 1970 { 1971 ps_codec->s_cfg.u4_enable_hpel = ps_cfg->u4_enable_hpel; 1972 ps_codec->s_cfg.u4_enable_fast_sad = ps_cfg->u4_enable_fast_sad; 1973 ps_codec->s_cfg.u4_me_speed_preset = ps_cfg->u4_me_speed_preset; 1974 ps_codec->s_cfg.u4_enable_qpel = ps_cfg->u4_enable_qpel; 1975 } 1976 else if (ps_curr_cfg->u4_enc_speed_preset == IVE_FASTEST) 1977 { 1978 ps_codec->s_cfg.u4_enable_fast_sad = ps_cfg->u4_enable_fast_sad; 1979 } 1980 ps_codec->s_cfg.u4_srch_rng_x = ps_cfg->u4_srch_rng_x; 1981 ps_codec->s_cfg.u4_srch_rng_y = ps_cfg->u4_srch_rng_y; 1982 1983 if (ps_codec->s_cfg.u4_enable_alt_ref != ps_cfg->u4_enable_alt_ref) 1984 { 1985 ps_codec->s_cfg.u4_enable_alt_ref = ps_cfg->u4_enable_alt_ref; 1986 ps_codec->u4_is_curr_frm_ref = 1; 1987 } 1988 } 1989 else if (ps_cfg->e_cmd == IVE_CMD_CTL_SET_IPE_PARAMS) 1990 { 1991 ps_curr_cfg->u4_enc_speed_preset = ps_cfg->u4_enc_speed_preset; 1992 ps_curr_cfg->u4_constrained_intra_pred = ps_cfg->u4_constrained_intra_pred; 1993 if (ps_curr_cfg->u4_enc_speed_preset == IVE_SLOWEST) 1994 {/* high quality */ 1995 /* enable diamond search */ 1996 ps_curr_cfg->u4_me_speed_preset = DMND_SRCH; 1997 ps_curr_cfg->u4_enable_fast_sad = 0; 1998 1999 /* disable intra 4x4 */ 2000 ps_curr_cfg->u4_enable_intra_4x4 = 1; 2001 ps_codec->luma_energy_compaction[1] = 2002 ih264e_code_luma_intra_macroblock_4x4_rdopt_on; 2003 2004 /* sub pel off */ 2005 ps_curr_cfg->u4_enable_hpel = 1; 2006 2007 /* deblocking off */ 2008 ps_curr_cfg->u4_disable_deblock_level = DISABLE_DEBLK_LEVEL_0; 2009 2010 /* disabled intra inter gating in Inter slices */ 2011 ps_codec->u4_inter_gate = 0; 2012 } 2013 else if (ps_curr_cfg->u4_enc_speed_preset == IVE_NORMAL) 2014 {/* normal */ 2015 /* enable diamond search */ 2016 ps_curr_cfg->u4_me_speed_preset = DMND_SRCH; 2017 ps_curr_cfg->u4_enable_fast_sad = 0; 2018 2019 /* disable intra 4x4 */ 2020 ps_curr_cfg->u4_enable_intra_4x4 = 1; 2021 2022 /* sub pel off */ 2023 ps_curr_cfg->u4_enable_hpel = 1; 2024 2025 /* deblocking off */ 2026 ps_curr_cfg->u4_disable_deblock_level = DISABLE_DEBLK_LEVEL_0; 2027 2028 /* disabled intra inter gating in Inter slices */ 2029 ps_codec->u4_inter_gate = 0; 2030 } 2031 else if (ps_curr_cfg->u4_enc_speed_preset == IVE_FAST) 2032 {/* normal */ 2033 /* enable diamond search */ 2034 ps_curr_cfg->u4_me_speed_preset = DMND_SRCH; 2035 ps_curr_cfg->u4_enable_fast_sad = 0; 2036 2037 /* disable intra 4x4 */ 2038 ps_curr_cfg->u4_enable_intra_4x4 = 0; 2039 2040 /* sub pel off */ 2041 ps_curr_cfg->u4_enable_hpel = 1; 2042 2043 /* deblocking off */ 2044 ps_curr_cfg->u4_disable_deblock_level = DISABLE_DEBLK_LEVEL_0; 2045 2046 /* disabled intra inter gating in Inter slices */ 2047 ps_codec->u4_inter_gate = 1; 2048 } 2049 else if (ps_curr_cfg->u4_enc_speed_preset == IVE_HIGH_SPEED) 2050 {/* fast */ 2051 /* enable diamond search */ 2052 ps_curr_cfg->u4_me_speed_preset = DMND_SRCH; 2053 ps_curr_cfg->u4_enable_fast_sad = 0; 2054 2055 /* disable intra 4x4 */ 2056 ps_curr_cfg->u4_enable_intra_4x4 = 0; 2057 2058 /* sub pel off */ 2059 ps_curr_cfg->u4_enable_hpel = 0; 2060 2061 /* deblocking off */ 2062 ps_curr_cfg->u4_disable_deblock_level = DISABLE_DEBLK_LEVEL_4; 2063 2064 /* disabled intra inter gating in Inter slices */ 2065 ps_codec->u4_inter_gate = 0; 2066 } 2067 else if (ps_curr_cfg->u4_enc_speed_preset == IVE_FASTEST) 2068 {/* fastest */ 2069 /* enable diamond search */ 2070 ps_curr_cfg->u4_me_speed_preset = DMND_SRCH; 2071 //u4_num_layers = 4; 2072 2073 /* disable intra 4x4 */ 2074 ps_curr_cfg->u4_enable_intra_4x4 = 0; 2075 2076 /* sub pel off */ 2077 ps_curr_cfg->u4_enable_hpel = 0; 2078 2079 /* deblocking off */ 2080 ps_curr_cfg->u4_disable_deblock_level = DISABLE_DEBLK_LEVEL_4; 2081 2082 /* disabled intra inter gating in Inter slices */ 2083 ps_codec->u4_inter_gate = 1; 2084 } 2085 else if (ps_curr_cfg->u4_enc_speed_preset == IVE_CONFIG) 2086 { 2087 ps_curr_cfg->u4_enable_intra_4x4 = ps_cfg->u4_enable_intra_4x4; 2088 } 2089 } 2090 else if (ps_cfg->e_cmd == IVE_CMD_CTL_SET_GOP_PARAMS) 2091 { 2092 if (ps_curr_cfg->u4_i_frm_interval != ps_cfg->u4_i_frm_interval) 2093 { 2094 ps_curr_cfg->u4_i_frm_interval = ps_cfg->u4_i_frm_interval; 2095 2096 /* reset air counter */ 2097 ps_codec->i4_air_pic_cnt = -1; 2098 2099 /* re-init air map */ 2100 ih264e_init_air_map(ps_codec); 2101 2102 /*Effect intra frame interval change*/ 2103 2104 irc_change_intra_frm_int_call( 2105 ps_codec->s_rate_control.pps_rate_control_api, 2106 ps_curr_cfg->u4_i_frm_interval); 2107 } 2108 2109 ps_curr_cfg->u4_idr_frm_interval = ps_cfg->u4_idr_frm_interval; 2110 2111 } 2112 else if (ps_cfg->e_cmd == IVE_CMD_CTL_SET_DEBLOCK_PARAMS) 2113 { 2114 if (ps_curr_cfg->u4_enc_speed_preset == IVE_CONFIG) 2115 { 2116 ps_curr_cfg->u4_disable_deblock_level = 2117 ps_cfg->u4_disable_deblock_level; 2118 } 2119 } 2120 else if (ps_cfg->e_cmd == IVE_CMD_CTL_SET_QP) 2121 { 2122 UWORD8 au1_init_qp[MAX_PIC_TYPE]; 2123 UWORD8 au1_min_max_qp[2 * MAX_PIC_TYPE]; 2124 2125 ps_codec->s_cfg.u4_i_qp_max = ps_cfg->u4_i_qp_max; 2126 ps_codec->s_cfg.u4_i_qp_min = ps_cfg->u4_i_qp_min; 2127 ps_codec->s_cfg.u4_i_qp = ps_cfg->u4_i_qp; 2128 2129 ps_codec->s_cfg.u4_p_qp_max = ps_cfg->u4_p_qp_max; 2130 ps_codec->s_cfg.u4_p_qp_min = ps_cfg->u4_p_qp_min; 2131 ps_codec->s_cfg.u4_p_qp = ps_cfg->u4_p_qp; 2132 2133 ps_codec->s_cfg.u4_b_qp_max = ps_cfg->u4_b_qp_max; 2134 ps_codec->s_cfg.u4_b_qp_min = ps_cfg->u4_b_qp_min; 2135 ps_codec->s_cfg.u4_b_qp = ps_cfg->u4_b_qp; 2136 2137 /* update rc lib with modified qp */ 2138 au1_init_qp[0] = gau1_h264_to_mpeg2_qmap[ps_codec->s_cfg.u4_i_qp]; 2139 au1_init_qp[1] = gau1_h264_to_mpeg2_qmap[ps_codec->s_cfg.u4_p_qp]; 2140 au1_init_qp[2] = gau1_h264_to_mpeg2_qmap[ps_codec->s_cfg.u4_b_qp]; 2141 2142 irc_change_init_qp(ps_codec->s_rate_control.pps_rate_control_api, 2143 au1_init_qp); 2144 2145 au1_min_max_qp[2 * I_PIC] = 2146 gau1_h264_to_mpeg2_qmap[ps_codec->s_cfg.u4_i_qp_min]; 2147 au1_min_max_qp[2 * I_PIC + 1] = 2148 gau1_h264_to_mpeg2_qmap[ps_codec->s_cfg.u4_i_qp_max]; 2149 2150 au1_min_max_qp[2 * P_PIC] = 2151 gau1_h264_to_mpeg2_qmap[ps_codec->s_cfg.u4_p_qp_min]; 2152 au1_min_max_qp[2 * P_PIC + 1] = 2153 gau1_h264_to_mpeg2_qmap[ps_codec->s_cfg.u4_p_qp_max]; 2154 2155 au1_min_max_qp[2 * B_PIC] = 2156 gau1_h264_to_mpeg2_qmap[ps_codec->s_cfg.u4_b_qp_min]; 2157 au1_min_max_qp[2 * B_PIC + 1] = 2158 gau1_h264_to_mpeg2_qmap[ps_codec->s_cfg.u4_b_qp_max]; 2159 2160 irc_change_min_max_qp(ps_codec->s_rate_control.pps_rate_control_api, 2161 au1_min_max_qp); 2162 } 2163 else if (ps_cfg->e_cmd == IVE_CMD_CTL_SET_ENC_MODE) 2164 { 2165 ps_codec->s_cfg.e_enc_mode = ps_cfg->e_enc_mode; 2166 2167 if (ps_codec->s_cfg.e_enc_mode == IVE_ENC_MODE_HEADER) 2168 { 2169 ps_codec->i4_header_mode = 1; 2170 ps_codec->s_cfg.e_enc_mode = IVE_ENC_MODE_PICTURE; 2171 } 2172 else 2173 { 2174 ps_codec->i4_header_mode = 0; 2175 } 2176 } 2177 else if (ps_cfg->e_cmd == IVE_CMD_CTL_SET_VBV_PARAMS 2178 && IVE_RC_NONE != ps_codec->s_cfg.e_rc_mode) 2179 { 2180 ps_codec->s_cfg.u4_vbv_buf_size = ps_cfg->u4_vbv_buf_size; 2181 ps_codec->s_cfg.u4_vbv_buffer_delay = ps_cfg->u4_vbv_buffer_delay; 2182 2183 // irc_change_buffer_delay(ps_codec->s_rate_control.pps_rate_control_api, ps_codec->s_cfg.u4_vbv_buffer_delay); 2184 2185 // TODO: remove this when the support for changing buffer dynamically 2186 // is yet to be added. 2187 u4_init_rc = 1; 2188 } 2189 else if (ps_cfg->e_cmd == IVE_CMD_CTL_SET_AIR_PARAMS) 2190 { 2191 if (ps_curr_cfg->e_air_mode != ps_cfg->e_air_mode 2192 || ps_curr_cfg->u4_air_refresh_period 2193 != ps_cfg->u4_air_refresh_period) 2194 { 2195 ps_curr_cfg->e_air_mode = ps_cfg->e_air_mode; 2196 ps_curr_cfg->u4_air_refresh_period = ps_cfg->u4_air_refresh_period; 2197 2198 ih264e_init_air_map(ps_codec); 2199 2200 /* reset air counter */ 2201 ps_codec->i4_air_pic_cnt = -1; 2202 } 2203 } 2204 else if (ps_cfg->e_cmd == IVE_CMD_CTL_SET_PROFILE_PARAMS) 2205 { 2206 ps_codec->s_cfg.e_profile = ps_cfg->e_profile; 2207 ps_codec->s_cfg.u4_entropy_coding_mode = ps_cfg->u4_entropy_coding_mode; 2208 } 2209 else if (ps_cfg->e_cmd == IVE_CMD_CTL_SET_NUM_CORES) 2210 { 2211 ps_codec->s_cfg.u4_num_cores = ps_cfg->u4_num_cores; 2212 } 2213 2214 /* reset RC model */ 2215 if (u4_init_rc) 2216 { 2217 /* init qp */ 2218 UWORD8 au1_init_qp[MAX_PIC_TYPE]; 2219 2220 /* min max qp */ 2221 UWORD8 au1_min_max_qp[2 * MAX_PIC_TYPE]; 2222 2223 /* init i,p,b qp */ 2224 au1_init_qp[0] = gau1_h264_to_mpeg2_qmap[ps_codec->s_cfg.u4_i_qp]; 2225 au1_init_qp[1] = gau1_h264_to_mpeg2_qmap[ps_codec->s_cfg.u4_p_qp]; 2226 au1_init_qp[2] = gau1_h264_to_mpeg2_qmap[ps_codec->s_cfg.u4_b_qp]; 2227 2228 /* init min max qp */ 2229 au1_min_max_qp[2 * I_PIC] = 2230 gau1_h264_to_mpeg2_qmap[ps_codec->s_cfg.u4_i_qp_min]; 2231 au1_min_max_qp[2 * I_PIC + 1] = 2232 gau1_h264_to_mpeg2_qmap[ps_codec->s_cfg.u4_i_qp_max]; 2233 2234 au1_min_max_qp[2 * P_PIC] = 2235 gau1_h264_to_mpeg2_qmap[ps_codec->s_cfg.u4_p_qp_min]; 2236 au1_min_max_qp[2 * P_PIC + 1] = 2237 gau1_h264_to_mpeg2_qmap[ps_codec->s_cfg.u4_p_qp_max]; 2238 2239 au1_min_max_qp[2 * B_PIC] = 2240 gau1_h264_to_mpeg2_qmap[ps_codec->s_cfg.u4_b_qp_min]; 2241 au1_min_max_qp[2 * B_PIC + 1] = 2242 gau1_h264_to_mpeg2_qmap[ps_codec->s_cfg.u4_b_qp_max]; 2243 2244 /* get rc mode */ 2245 switch (ps_codec->s_cfg.e_rc_mode) 2246 { 2247 case IVE_RC_STORAGE: 2248 ps_codec->s_rate_control.e_rc_type = VBR_STORAGE; 2249 break; 2250 2251 case IVE_RC_CBR_NON_LOW_DELAY: 2252 ps_codec->s_rate_control.e_rc_type = CBR_NLDRC; 2253 break; 2254 2255 case IVE_RC_CBR_LOW_DELAY: 2256 ps_codec->s_rate_control.e_rc_type = CBR_LDRC; 2257 break; 2258 2259 case IVE_RC_NONE: 2260 ps_codec->s_rate_control.e_rc_type = CONST_QP; 2261 break; 2262 2263 default: 2264 break; 2265 } 2266 2267 /* init rate control */ 2268 ih264e_rc_init(ps_codec->s_rate_control.pps_rate_control_api, 2269 ps_codec->s_rate_control.pps_frame_time, 2270 ps_codec->s_rate_control.pps_time_stamp, 2271 ps_codec->s_rate_control.pps_pd_frm_rate, 2272 ps_codec->s_cfg.u4_max_framerate, 2273 ps_codec->s_cfg.u4_src_frame_rate, 2274 ps_codec->s_cfg.u4_tgt_frame_rate, 2275 ps_codec->s_rate_control.e_rc_type, 2276 ps_codec->s_cfg.u4_target_bitrate, 2277 ps_codec->s_cfg.u4_max_bitrate, 2278 ps_codec->s_cfg.u4_vbv_buffer_delay, 2279 ps_codec->s_cfg.u4_i_frm_interval, 2280 ps_codec->s_cfg.u4_num_bframes + 1, au1_init_qp, 2281 ps_codec->s_cfg.u4_num_bframes + 2, au1_min_max_qp, 2282 ps_codec->s_cfg.u4_max_level); 2283 } 2284 2285 return err; 2286 } 2287 2288 /** 2289 ******************************************************************************* 2290 * 2291 * @brief 2292 * Sets default encoder config parameters 2293 * 2294 * @par Description: 2295 * Sets default dynamic parameters. Will be called in ih264e_init() to ensure 2296 * that even if set_params is not called, codec continues to work 2297 * 2298 * @param[in] ps_cfg 2299 * Pointer to encoder config params 2300 * 2301 * @returns error status 2302 * 2303 * @remarks none 2304 * 2305 ******************************************************************************* 2306 */ 2307 static WORD32 ih264e_set_default_params(cfg_params_t *ps_cfg) 2308 { 2309 WORD32 ret = IV_SUCCESS; 2310 2311 ps_cfg->u4_max_wd = MAX_WD; 2312 ps_cfg->u4_max_ht = MAX_HT; 2313 ps_cfg->u4_max_ref_cnt = MAX_REF_CNT; 2314 ps_cfg->u4_max_reorder_cnt = MAX_REF_CNT; 2315 ps_cfg->u4_max_level = DEFAULT_MAX_LEVEL; 2316 ps_cfg->e_inp_color_fmt = IV_YUV_420SP_UV; 2317 ps_cfg->u4_enable_recon = DEFAULT_RECON_ENABLE; 2318 ps_cfg->e_recon_color_fmt = IV_YUV_420P; 2319 ps_cfg->u4_enc_speed_preset = IVE_FASTEST; 2320 ps_cfg->e_rc_mode = DEFAULT_RC; 2321 ps_cfg->u4_max_framerate = DEFAULT_MAX_FRAMERATE; 2322 ps_cfg->u4_max_bitrate = DEFAULT_MAX_BITRATE; 2323 ps_cfg->u4_num_bframes = DEFAULT_MAX_NUM_BFRAMES; 2324 ps_cfg->e_content_type = IV_PROGRESSIVE; 2325 ps_cfg->u4_max_srch_rng_x = DEFAULT_MAX_SRCH_RANGE_X; 2326 ps_cfg->u4_max_srch_rng_y = DEFAULT_MAX_SRCH_RANGE_Y; 2327 ps_cfg->e_slice_mode = IVE_SLICE_MODE_NONE; 2328 ps_cfg->u4_slice_param = DEFAULT_SLICE_PARAM; 2329 ps_cfg->e_arch = ih264e_default_arch(); 2330 ps_cfg->e_soc = SOC_GENERIC; 2331 ps_cfg->u4_disp_wd = MAX_WD; 2332 ps_cfg->u4_disp_ht = MAX_HT; 2333 ps_cfg->u4_wd = MAX_WD; 2334 ps_cfg->u4_ht = MAX_HT; 2335 ps_cfg->u4_src_frame_rate = DEFAULT_SRC_FRAME_RATE; 2336 ps_cfg->u4_tgt_frame_rate = DEFAULT_TGT_FRAME_RATE; 2337 ps_cfg->u4_target_bitrate = DEFAULT_BITRATE; 2338 ps_cfg->e_frame_type = IV_NA_FRAME; 2339 ps_cfg->e_enc_mode = IVE_ENC_MODE_DEFAULT; 2340 ps_cfg->u4_i_qp = DEFAULT_I_QP; 2341 ps_cfg->u4_p_qp = DEFAULT_P_QP; 2342 ps_cfg->u4_b_qp = DEFAULT_B_QP; 2343 ps_cfg->u4_i_qp_min = DEFAULT_QP_MIN; 2344 ps_cfg->u4_i_qp_max = DEFAULT_QP_MAX; 2345 ps_cfg->u4_p_qp_min = DEFAULT_QP_MIN; 2346 ps_cfg->u4_p_qp_max = DEFAULT_QP_MAX; 2347 ps_cfg->u4_b_qp_min = DEFAULT_QP_MIN; 2348 ps_cfg->u4_b_qp_max = DEFAULT_QP_MAX; 2349 ps_cfg->e_air_mode = DEFAULT_AIR_MODE; 2350 ps_cfg->u4_air_refresh_period = DEFAULT_AIR_REFRESH_PERIOD; 2351 ps_cfg->u4_vbv_buffer_delay = DEFAULT_VBV_DELAY; 2352 ps_cfg->u4_vbv_buf_size = DEFAULT_VBV_SIZE; 2353 ps_cfg->u4_num_cores = DEFAULT_NUM_CORES; 2354 ps_cfg->u4_me_speed_preset = DEFAULT_ME_SPEED_PRESET; 2355 ps_cfg->u4_enable_hpel = DEFAULT_HPEL; 2356 ps_cfg->u4_enable_qpel = DEFAULT_QPEL; 2357 ps_cfg->u4_enable_intra_4x4 = DEFAULT_I4; 2358 ps_cfg->u4_enable_intra_8x8 = DEFAULT_I8; 2359 ps_cfg->u4_enable_intra_16x16 = DEFAULT_I16; 2360 ps_cfg->u4_enable_fast_sad = DEFAULT_ENABLE_FAST_SAD; 2361 ps_cfg->u4_enable_satqd = DEFAULT_ENABLE_SATQD; 2362 ps_cfg->i4_min_sad = 2363 (ps_cfg->u4_enable_satqd == DEFAULT_ENABLE_SATQD) ? 2364 DEFAULT_MIN_SAD_ENABLE : 2365 DEFAULT_MIN_SAD_DISABLE; 2366 ps_cfg->u4_srch_rng_x = DEFAULT_SRCH_RNG_X; 2367 ps_cfg->u4_srch_rng_y = DEFAULT_SRCH_RNG_Y; 2368 ps_cfg->u4_i_frm_interval = DEFAULT_I_INTERVAL; 2369 ps_cfg->u4_idr_frm_interval = DEFAULT_IDR_INTERVAL; 2370 ps_cfg->u4_disable_deblock_level = DEFAULT_DISABLE_DEBLK_LEVEL; 2371 ps_cfg->e_profile = DEFAULT_PROFILE; 2372 ps_cfg->u4_timestamp_low = 0; 2373 ps_cfg->u4_timestamp_high = 0; 2374 ps_cfg->u4_is_valid = 1; 2375 ps_cfg->e_cmd = IVE_CMD_CT_NA; 2376 ps_cfg->i4_wd_mbs = ps_cfg->u4_max_wd >> 4; 2377 ps_cfg->i4_ht_mbs = ps_cfg->u4_max_ht >> 4; 2378 ps_cfg->u4_entropy_coding_mode = CAVLC; 2379 ps_cfg->u4_weighted_prediction = 0; 2380 ps_cfg->u4_constrained_intra_pred = 0; 2381 ps_cfg->u4_pic_info_type = 0; 2382 ps_cfg->u4_mb_info_type = 0; 2383 2384 return ret; 2385 } 2386 2387 /** 2388 ******************************************************************************* 2389 * 2390 * @brief 2391 * Initialize encoder context. This will be called by init_mem_rec and during 2392 * codec reset 2393 * 2394 * @par Description: 2395 * Initializes the context 2396 * 2397 * @param[in] ps_codec 2398 * Codec context pointer 2399 * 2400 * @returns error status 2401 * 2402 * @remarks none 2403 * 2404 ******************************************************************************* 2405 */ 2406 static WORD32 ih264e_init(codec_t *ps_codec) 2407 { 2408 /* enc config param set */ 2409 cfg_params_t *ps_cfg = &(ps_codec->s_cfg); 2410 2411 /* temp var */ 2412 WORD32 i; 2413 2414 /* coded pic count */ 2415 ps_codec->i4_poc = 0; 2416 2417 /* Number of API calls to encode are made */ 2418 ps_codec->i4_encode_api_call_cnt = -1; 2419 2420 /* Indicates no header has been generated yet */ 2421 ps_codec->u4_header_generated = 0; 2422 2423 /* Number of pictures encoded */ 2424 ps_codec->i4_pic_cnt = -1; 2425 2426 /* Number of threads created */ 2427 ps_codec->i4_proc_thread_cnt = 0; 2428 2429 /* ctl mutex init */ 2430 ithread_mutex_init(ps_codec->pv_ctl_mutex); 2431 2432 /* Set encoder chroma format */ 2433 ps_codec->e_codec_color_format = 2434 (ps_cfg->e_inp_color_fmt == IV_YUV_420SP_VU) ? 2435 IV_YUV_420SP_VU : IV_YUV_420SP_UV; 2436 2437 /* Number of continuous frames where deblocking was disabled */ 2438 ps_codec->i4_disable_deblk_pic_cnt = 0; 2439 2440 /* frame num */ 2441 ps_codec->i4_frame_num = 0; 2442 2443 /* set the current frame type to I frame, since we are going to start encoding*/ 2444 ps_codec->force_curr_frame_type = IV_NA_FRAME; 2445 2446 /* idr_pic_id */ 2447 ps_codec->i4_idr_pic_id = -1; 2448 2449 /* Flush mode */ 2450 ps_codec->i4_flush_mode = 0; 2451 2452 /* Encode header mode */ 2453 ps_codec->i4_header_mode = 0; 2454 2455 /* Encode generate header */ 2456 ps_codec->i4_gen_header = 0; 2457 2458 /* To signal successful completion of init */ 2459 ps_codec->i4_init_done = 1; 2460 2461 /* To signal that at least one picture was decoded */ 2462 ps_codec->i4_first_pic_done = 0; 2463 2464 /* Reset Codec */ 2465 ps_codec->i4_reset_flag = 0; 2466 2467 /* Current error code */ 2468 ps_codec->i4_error_code = IH264E_SUCCESS; 2469 2470 /* threshold residue */ 2471 ps_codec->u4_thres_resi = 1; 2472 2473 /* inter gating enable */ 2474 ps_codec->u4_inter_gate = 0; 2475 2476 /* entropy mutex init */ 2477 ithread_mutex_init(ps_codec->pv_entropy_mutex); 2478 2479 /* sps id */ 2480 ps_codec->i4_sps_id = 0; 2481 2482 /* sps id */ 2483 ps_codec->i4_pps_id = 0; 2484 2485 /* Process thread created status */ 2486 memset(ps_codec->ai4_process_thread_created, 0, MAX_PROCESS_THREADS); 2487 2488 /* Number of MBs processed together */ 2489 ps_codec->i4_proc_nmb = 8; 2490 2491 /* Previous POC msb */ 2492 ps_codec->i4_prev_poc_msb = 0; 2493 2494 /* Previous POC lsb */ 2495 ps_codec->i4_prev_poc_lsb = -1; 2496 2497 /* max Previous POC lsb */ 2498 ps_codec->i4_max_prev_poc_lsb = -1; 2499 2500 /* sps, pps status */ 2501 { 2502 sps_t *ps_sps = ps_codec->ps_sps_base; 2503 pps_t *ps_pps = ps_codec->ps_pps_base; 2504 2505 for (i = 0; i < MAX_SPS_CNT; i++) 2506 { 2507 ps_sps->i1_sps_valid = 0; 2508 ps_sps++; 2509 } 2510 2511 for (i = 0; i < MAX_PPS_CNT; i++) 2512 { 2513 ps_pps->i1_pps_valid = 0; 2514 ps_pps++; 2515 } 2516 } 2517 2518 { 2519 WORD32 max_mb_rows = ps_cfg->i4_ht_mbs; 2520 2521 WORD32 num_jobs = max_mb_rows * MAX_CTXT_SETS; 2522 WORD32 clz; 2523 2524 /* Use next power of two number of entries*/ 2525 clz = CLZ(num_jobs); 2526 num_jobs = 1 << (32 - clz); 2527 2528 /* init process jobq */ 2529 ps_codec->pv_proc_jobq = ih264_list_init( 2530 ps_codec->pv_proc_jobq_buf, 2531 ps_codec->i4_proc_jobq_buf_size, num_jobs, 2532 sizeof(job_t), 10); 2533 RETURN_IF((ps_codec->pv_proc_jobq == NULL), IV_FAIL); 2534 ih264_list_reset(ps_codec->pv_proc_jobq); 2535 2536 /* init entropy jobq */ 2537 ps_codec->pv_entropy_jobq = ih264_list_init( 2538 ps_codec->pv_entropy_jobq_buf, 2539 ps_codec->i4_entropy_jobq_buf_size, num_jobs, 2540 sizeof(job_t), 10); 2541 RETURN_IF((ps_codec->pv_entropy_jobq == NULL), IV_FAIL); 2542 ih264_list_reset(ps_codec->pv_entropy_jobq); 2543 } 2544 2545 /* Update the jobq context to all the threads */ 2546 for (i = 0; i < MAX_PROCESS_CTXT; i++) 2547 { 2548 ps_codec->as_process[i].pv_proc_jobq = ps_codec->pv_proc_jobq; 2549 ps_codec->as_process[i].pv_entropy_jobq = ps_codec->pv_entropy_jobq; 2550 2551 /* i4_id always stays between 0 and MAX_PROCESS_THREADS */ 2552 ps_codec->as_process[i].i4_id = 2553 (i >= MAX_PROCESS_THREADS) ? 2554 (i - MAX_PROCESS_THREADS) : i; 2555 ps_codec->as_process[i].ps_codec = ps_codec; 2556 2557 ps_codec->as_process[i].s_entropy.pv_proc_jobq = ps_codec->pv_proc_jobq; 2558 ps_codec->as_process[i].s_entropy.pv_entropy_jobq = 2559 ps_codec->pv_entropy_jobq; 2560 ps_codec->as_process[i].s_entropy.i4_abs_pic_order_cnt = -1; 2561 } 2562 2563 /* Initialize MV Bank buffer manager */ 2564 ps_codec->pv_mv_buf_mgr = ih264_buf_mgr_init(ps_codec->pv_mv_buf_mgr_base); 2565 2566 /* Initialize Picture buffer manager for reference buffers*/ 2567 ps_codec->pv_ref_buf_mgr = ih264_buf_mgr_init( 2568 ps_codec->pv_ref_buf_mgr_base); 2569 2570 /* Initialize Picture buffer manager for input buffers*/ 2571 ps_codec->pv_inp_buf_mgr = ih264_buf_mgr_init( 2572 ps_codec->pv_inp_buf_mgr_base); 2573 2574 /* Initialize buffer manager for output buffers*/ 2575 ps_codec->pv_out_buf_mgr = ih264_buf_mgr_init( 2576 ps_codec->pv_out_buf_mgr_base); 2577 2578 /* buffer cnt in buffer manager */ 2579 ps_codec->i4_inp_buf_cnt = 0; 2580 ps_codec->i4_out_buf_cnt = 0; 2581 ps_codec->i4_ref_buf_cnt = 0; 2582 2583 ps_codec->ps_pic_buf = (pic_buf_t *) ps_codec->pv_pic_buf_base; 2584 memset(ps_codec->ps_pic_buf, 0, BUF_MGR_MAX_CNT * sizeof(pic_buf_t)); 2585 2586 /* Initialize dpb manager */ 2587 ih264_dpb_mgr_init((dpb_mgr_t*) ps_codec->pv_dpb_mgr); 2588 2589 memset(ps_codec->as_ref_set, 0, 2590 sizeof(ref_set_t) * (MAX_DPB_SIZE + MAX_CTXT_SETS)); 2591 for (i = 0; i < (MAX_DPB_SIZE + MAX_CTXT_SETS); i++) 2592 { 2593 ps_codec->as_ref_set[i].i4_pic_cnt = -1; 2594 } 2595 2596 /* fn ptr init */ 2597 ih264e_init_function_ptr(ps_codec); 2598 2599 /* reset status flags */ 2600 for (i = 0; i < MAX_CTXT_SETS; i++) 2601 { 2602 ps_codec->au4_entropy_thread_active[i] = 0; 2603 ps_codec->ai4_pic_cnt[i] = -1; 2604 2605 ps_codec->s_rate_control.pre_encode_skip[i] = 0; 2606 ps_codec->s_rate_control.post_encode_skip[i] = 0; 2607 } 2608 2609 ps_codec->s_rate_control.num_intra_in_prev_frame = 0; 2610 ps_codec->s_rate_control.i4_avg_activity = 0; 2611 2612 return IV_SUCCESS; 2613 } 2614 2615 /** 2616 ******************************************************************************* 2617 * 2618 * @brief 2619 * Gets number of memory records required by the codec 2620 * 2621 * @par Description: 2622 * Gets codec memory requirements 2623 * 2624 * @param[in] pv_api_ip 2625 * Pointer to input argument structure 2626 * 2627 * @param[out] pv_api_op 2628 * Pointer to output argument structure 2629 * 2630 * @returns status 2631 * 2632 * @remarks 2633 * 2634 ******************************************************************************* 2635 */ 2636 static WORD32 ih264e_get_num_rec(void *pv_api_ip, void *pv_api_op) 2637 { 2638 /* api call I/O structures */ 2639 ih264e_num_mem_rec_op_t *ps_op = pv_api_op; 2640 2641 UNUSED(pv_api_ip); 2642 2643 ps_op->s_ive_op.u4_num_mem_rec = MEM_REC_CNT; 2644 2645 return IV_SUCCESS; 2646 } 2647 2648 /** 2649 ******************************************************************************* 2650 * 2651 * @brief 2652 * Fills memory records of the codec 2653 * 2654 * @par Description: 2655 * Fills codec memory requirements 2656 * 2657 * @param[in] pv_api_ip 2658 * Pointer to input argument structure 2659 * 2660 * @param[out] pv_api_op 2661 * Pointer to output argument structure 2662 * 2663 * @returns error status 2664 * 2665 * @remarks none 2666 * 2667 ******************************************************************************* 2668 */ 2669 static WORD32 ih264e_fill_num_mem_rec(void *pv_api_ip, void *pv_api_op) 2670 { 2671 /* api call I/O structures */ 2672 ih264e_fill_mem_rec_ip_t *ps_ip = pv_api_ip; 2673 ih264e_fill_mem_rec_op_t *ps_op = pv_api_op; 2674 2675 /* profile / level info */ 2676 WORD32 level; 2677 WORD32 num_reorder_frames; 2678 WORD32 num_ref_frames; 2679 2680 /* mem records */ 2681 WORD32 no_of_mem_rec; 2682 iv_mem_rec_t *ps_mem_rec_base, *ps_mem_rec; 2683 2684 /* frame dimensions */ 2685 WORD32 max_wd_luma, max_ht_luma; 2686 WORD32 max_mb_rows, max_mb_cols, max_mb_cnt; 2687 2688 /* temp var */ 2689 WORD32 i; 2690 2691 /* error status */ 2692 IV_STATUS_T status = IV_SUCCESS; 2693 2694 num_reorder_frames = ps_ip->s_ive_ip.u4_max_reorder_cnt; 2695 num_ref_frames = ps_ip->s_ive_ip.u4_max_ref_cnt; 2696 2697 /* mem records */ 2698 ps_mem_rec_base = ps_ip->s_ive_ip.ps_mem_rec; 2699 no_of_mem_rec = ps_ip->s_ive_ip.u4_num_mem_rec; 2700 2701 /* frame dimensions */ 2702 max_ht_luma = ps_ip->s_ive_ip.u4_max_ht; 2703 max_wd_luma = ps_ip->s_ive_ip.u4_max_wd; 2704 max_ht_luma = ALIGN16(max_ht_luma); 2705 max_wd_luma = ALIGN16(max_wd_luma); 2706 max_mb_rows = max_ht_luma / MB_SIZE; 2707 max_mb_cols = max_wd_luma / MB_SIZE; 2708 max_mb_cnt = max_mb_rows * max_mb_cols; 2709 2710 /* profile / level info */ 2711 level = ih264e_get_min_level(max_ht_luma, max_wd_luma); 2712 2713 /* validate params */ 2714 if ((level < MIN_LEVEL) || (level > MAX_LEVEL)) 2715 { 2716 ps_op->s_ive_op.u4_error_code |= IH264E_CODEC_LEVEL_NOT_SUPPORTED; 2717 level = MAX_LEVEL; 2718 } 2719 2720 if (num_ref_frames > MAX_REF_CNT) 2721 { 2722 ps_op->s_ive_op.u4_error_code |= IH264E_NUM_REF_UNSUPPORTED; 2723 num_ref_frames = MAX_REF_CNT; 2724 } 2725 2726 if (num_reorder_frames > MAX_REF_CNT) 2727 { 2728 ps_op->s_ive_op.u4_error_code |= IH264E_NUM_REORDER_UNSUPPORTED; 2729 num_reorder_frames = MAX_REF_CNT; 2730 } 2731 2732 /* Set all memory records as persistent and alignment as 128 by default */ 2733 ps_mem_rec = ps_mem_rec_base; 2734 for (i = 0; i < no_of_mem_rec; i++) 2735 { 2736 ps_mem_rec->u4_mem_alignment = 128; 2737 ps_mem_rec->e_mem_type = IV_EXTERNAL_CACHEABLE_PERSISTENT_MEM; 2738 ps_mem_rec++; 2739 } 2740 2741 /************************************************************************ 2742 * Request memory for h264 encoder handle * 2743 ***********************************************************************/ 2744 ps_mem_rec = &ps_mem_rec_base[MEM_REC_IV_OBJ]; 2745 { 2746 ps_mem_rec->u4_mem_size = sizeof(iv_obj_t); 2747 } 2748 DEBUG("\nMemory record Id %d = %d \n", MEM_REC_IV_OBJ, ps_mem_rec->u4_mem_size); 2749 2750 /************************************************************************ 2751 * Request memory for h264 encoder context * 2752 ***********************************************************************/ 2753 ps_mem_rec = &ps_mem_rec_base[MEM_REC_CODEC]; 2754 { 2755 ps_mem_rec->u4_mem_size = sizeof(codec_t); 2756 } 2757 DEBUG("\nMemory record Id %d = %d \n", MEM_REC_CODEC, ps_mem_rec->u4_mem_size); 2758 2759 /************************************************************************ 2760 * Request memory for CABAC context * 2761 ***********************************************************************/ 2762 ps_mem_rec = &ps_mem_rec_base[MEM_REC_CABAC]; 2763 { 2764 ps_mem_rec->u4_mem_size = sizeof(cabac_ctxt_t); 2765 } 2766 DEBUG("\nMemory record Id %d = %d \n", MEM_REC_CABAC, ps_mem_rec->u4_mem_size); 2767 2768 /************************************************************************ 2769 * Request memory for CABAC MB info * 2770 ***********************************************************************/ 2771 ps_mem_rec = &ps_mem_rec_base[MEM_REC_CABAC_MB_INFO]; 2772 { 2773 ps_mem_rec->u4_mem_size = ((max_mb_cols + 1) + 1) 2774 * sizeof(mb_info_ctxt_t); 2775 } 2776 DEBUG("\nMemory record Id %d = %d \n", MEM_REC_CABAC_MB_INFO, ps_mem_rec->u4_mem_size); 2777 2778 2779 /************************************************************************ 2780 * Request memory for entropy context * 2781 * In multi core encoding, each row is assumed to be launched on a * 2782 * thread. The rows below can only start after its neighbors are coded * 2783 * The status of an mb coded/uncoded is signaled via entropy map. * 2784 * 1. One word32 to store skip run cnt * 2785 * 2. mb entropy map (mb status entropy coded/uncoded). The size* 2786 * of the entropy map is max mb cols. Further allocate one * 2787 * more additional row to evade checking for row -1. * 2788 * 3. size of bit stream buffer to store bit stream ctxt. * 2789 * 4. Entropy coding is dependent on nnz coefficient count for * 2790 * the neighbor blocks. It is sufficient to maintain one row * 2791 * worth of nnz as entropy for lower row waits on entropy map* 2792 ************************************************************************/ 2793 ps_mem_rec = &ps_mem_rec_base[MEM_REC_ENTROPY]; 2794 { 2795 /* total size of the mem record */ 2796 WORD32 total_size = 0; 2797 2798 /* size of skip mb run */ 2799 total_size += sizeof(WORD32); 2800 total_size = ALIGN8(total_size); 2801 2802 /* size in bytes to store entropy status of an entire frame */ 2803 total_size += (max_mb_cols * max_mb_rows); 2804 /* add an additional 1 row of bytes to evade the special case of row 0 */ 2805 total_size += max_mb_cols; 2806 total_size = ALIGN128(total_size); 2807 2808 /* size of bit stream buffer */ 2809 total_size += sizeof(bitstrm_t); 2810 total_size = ALIGN128(total_size); 2811 2812 /* top nnz luma */ 2813 total_size += (max_mb_cols * 4 * sizeof(UWORD8)); 2814 total_size = ALIGN128(total_size); 2815 2816 /* top nnz cbcr */ 2817 total_size += (max_mb_cols * 4 * sizeof(UWORD8)); 2818 total_size = ALIGN128(total_size); 2819 2820 /* total size per each proc ctxt */ 2821 total_size *= MAX_CTXT_SETS; 2822 2823 ps_mem_rec->u4_mem_size = total_size; 2824 } 2825 DEBUG("\nMemory record Id %d = %d \n", MEM_REC_ENTROPY, ps_mem_rec->u4_mem_size); 2826 2827 /************************************************************************ 2828 * The residue coefficients that needs to be entropy coded are packed * 2829 * at a buffer space by the proc threads. The entropy thread shall * 2830 * read from the buffer space, unpack them and encode the same. The * 2831 * buffer space required to pack a row of mbs are as follows. * 2832 * Assuming transform_8x8_flag is disabled, * 2833 * In the worst case, 1 mb contains 1 dc 4x4 luma sub block, followed * 2834 * by 16 ac 4x4 luma sub blocks, 2 dc chroma 2x2 sub blocks, followed * 2835 * by 8 ac 4x4 chroma sub blocks. * 2836 * For the sake of simplicity we assume that all sub blocks are of * 2837 * type 4x4. The packing of each 4x4 is depicted by the structure * 2838 * tu_sblk_coeff_data_t * 2839 ************************************************************************/ 2840 ps_mem_rec = &ps_mem_rec_base[MEM_REC_MB_COEFF_DATA]; 2841 { 2842 /* temp var */ 2843 WORD32 size = 0; 2844 2845 /* size of coeff data of 1 mb */ 2846 size += sizeof(tu_sblk_coeff_data_t) * MAX_4x4_SUBBLKS; 2847 2848 /* size of coeff data of 1 row of mb's */ 2849 size *= max_mb_cols; 2850 2851 /* align to avoid any false sharing across threads */ 2852 size = ALIGN64(size); 2853 2854 /* size for one full frame */ 2855 size *= max_mb_rows; 2856 2857 /* size of each proc buffer set (ping, pong) */ 2858 size *= MAX_CTXT_SETS; 2859 2860 ps_mem_rec->u4_mem_size = size; 2861 } 2862 DEBUG("\nMemory record Id %d = %d \n", MEM_REC_MB_COEFF_DATA, ps_mem_rec->u4_mem_size); 2863 2864 /************************************************************************ 2865 * while encoding an mb, the mb header data is signaled to the entropy* 2866 * thread by writing to a buffer space. the size of header data per mb * 2867 * is assumed to be 40 bytes * 2868 * TODO: revisit this inference * 2869 ************************************************************************/ 2870 ps_mem_rec = &ps_mem_rec_base[MEM_REC_MB_HEADER_DATA]; 2871 { 2872 /* temp var */ 2873 WORD32 size; 2874 2875 /* size per MB */ 2876 size = 40; 2877 2878 /* size for 1 row of mbs */ 2879 size = size * max_mb_cols; 2880 2881 /* align to avoid any false sharing across threads */ 2882 size = ALIGN64(size); 2883 2884 /* size for one full frame */ 2885 size *= max_mb_rows; 2886 2887 /* size of each proc buffer set (ping, pong) */ 2888 size *= MAX_CTXT_SETS; 2889 2890 ps_mem_rec->u4_mem_size = size; 2891 } 2892 DEBUG("\nMemory record Id %d = %d \n", MEM_REC_MB_HEADER_DATA, ps_mem_rec->u4_mem_size); 2893 2894 /************************************************************************ 2895 * Size for holding mv_buf_t for each MV Bank. * 2896 * Note this allocation is done for BUF_MGR_MAX_CNT instead of * 2897 * MAX_DPB_SIZE or max_dpb_size for following reasons * 2898 * max_dpb_size will be based on max_wd and max_ht * 2899 * For higher max_wd and max_ht this number will be smaller than * 2900 * MAX_DPB_SIZE But during actual initialization number of buffers * 2901 * allocated can be more. * 2902 * * 2903 * One extra MV Bank is needed to hold current pics MV bank. * 2904 * Since this is only a structure allocation and not actual buffer * 2905 * allocation, it is allocated for BUF_MGR_MAX_CNT entries * 2906 ************************************************************************/ 2907 ps_mem_rec = &ps_mem_rec_base[MEM_REC_MVBANK]; 2908 { 2909 /* max luma samples */ 2910 WORD32 max_luma_samples = 0; 2911 2912 /* determine max luma samples */ 2913 for (i = 0; i < 16; i++) 2914 if (level ==(WORD32)gas_ih264_lvl_tbl[i].u4_level_idc) 2915 max_luma_samples = gas_ih264_lvl_tbl[i].u4_max_fs 2916 << (BLK_SIZE + BLK_SIZE); 2917 2918 ps_mem_rec->u4_mem_size = ih264_buf_mgr_size(); 2919 2920 /************************************************************************ 2921 * Allocate for pu_map, enc_pu_t and pic_pu_idx for each MV bank * 2922 * Note: Number of luma samples is not max_wd * max_ht here, instead it * 2923 * is set to maximum number of luma samples allowed at the given level. * 2924 * This is done to ensure that any stream with width and height lesser * 2925 * than max_wd and max_ht is supported. Number of buffers required can * 2926 * be greater for lower width and heights at a given level and this * 2927 * increased number of buffers might require more memory than what * 2928 * max_wd and max_ht buffer would have required Also note one extra * 2929 * buffer is allocated to store current pictures MV bank. * 2930 ***********************************************************************/ 2931 2932 ps_mem_rec->u4_mem_size += BUF_MGR_MAX_CNT * sizeof(mv_buf_t); 2933 2934 ps_mem_rec->u4_mem_size += (num_ref_frames + num_reorder_frames 2935 + MAX_CTXT_SETS) 2936 * ih264e_get_pic_mv_bank_size(max_luma_samples); 2937 } 2938 DEBUG("\nMemory record Id %d = %d \n", MEM_REC_MVBANK, ps_mem_rec->u4_mem_size); 2939 2940 /************************************************************************ 2941 * While encoding inter slices, to compute the cost of encoding an mb * 2942 * with the mv's at hand, we employ the expression cost = sad + lambda * 2943 * x mv_bits. Here mv_bits is the total number of bits taken to represe* 2944 * nt the mv in the stream. The mv bits for all the possible mv are * 2945 * stored in the look up table. The mem record for this look up table * 2946 * is given below. * 2947 ************************************************************************/ 2948 ps_mem_rec = &ps_mem_rec_base[MEM_REC_MVBITS]; 2949 { 2950 /* max srch range x */ 2951 UWORD32 u4_srch_range_x = ps_ip->s_ive_ip.u4_max_srch_rng_x; 2952 2953 /* max srch range y */ 2954 UWORD32 u4_srch_range_y = ps_ip->s_ive_ip.u4_max_srch_rng_y; 2955 2956 /* max srch range */ 2957 UWORD32 u4_max_srch_range = MAX(u4_srch_range_x, u4_srch_range_y); 2958 2959 /* due to subpel */ 2960 u4_max_srch_range <<= 2; 2961 2962 /* due to mv on either direction */ 2963 u4_max_srch_range = (u4_max_srch_range << 1); 2964 2965 /* due to pred mv + zero */ 2966 u4_max_srch_range = (u4_max_srch_range << 1) + 1; 2967 2968 u4_max_srch_range = ALIGN128(u4_max_srch_range); 2969 2970 ps_mem_rec->u4_mem_size = u4_max_srch_range; 2971 } 2972 DEBUG("\nMemory record Id %d = %d \n", MEM_REC_MVBITS, ps_mem_rec->u4_mem_size); 2973 2974 /************************************************************************ 2975 * Request memory for SPS * 2976 ***********************************************************************/ 2977 ps_mem_rec = &ps_mem_rec_base[MEM_REC_SPS]; 2978 { 2979 ps_mem_rec->u4_mem_size = MAX_SPS_CNT * sizeof(sps_t); 2980 } 2981 DEBUG("\nMemory record Id %d = %d \n", MEM_REC_SPS, ps_mem_rec->u4_mem_size); 2982 2983 /************************************************************************ 2984 * Request memory for PPS * 2985 ***********************************************************************/ 2986 ps_mem_rec = &ps_mem_rec_base[MEM_REC_PPS]; 2987 { 2988 ps_mem_rec->u4_mem_size = MAX_PPS_CNT * sizeof(pps_t); 2989 } 2990 DEBUG("\nMemory record Id %d = %d \n", MEM_REC_PPS, ps_mem_rec->u4_mem_size); 2991 2992 /************************************************************************ 2993 * Request memory for Slice Header * 2994 ***********************************************************************/ 2995 ps_mem_rec = &ps_mem_rec_base[MEM_REC_SLICE_HDR]; 2996 { 2997 ps_mem_rec->u4_mem_size = MAX_CTXT_SETS * MAX_SLICE_HDR_CNT 2998 * sizeof(slice_header_t); 2999 } 3000 DEBUG("\nMemory record Id %d = %d \n", MEM_REC_SLICE_HDR, ps_mem_rec->u4_mem_size); 3001 3002 /************************************************************************ 3003 * Request memory for Adaptive Intra Refresh * 3004 ***********************************************************************/ 3005 ps_mem_rec = &ps_mem_rec_base[MEM_REC_AIR_MAP]; 3006 { 3007 /* total size of the mem record */ 3008 WORD32 total_size = 0; 3009 3010 /* intra coded map */ 3011 total_size += max_mb_cnt; 3012 total_size *= MAX_CTXT_SETS; 3013 3014 /* mb refresh map */ 3015 total_size += sizeof(UWORD16) * max_mb_cnt; 3016 3017 /* alignment */ 3018 total_size = ALIGN128(total_size); 3019 3020 ps_mem_rec->u4_mem_size = total_size; 3021 } 3022 DEBUG("\nMemory record Id %d = %d \n", MEM_REC_AIR_MAP, ps_mem_rec->u4_mem_size); 3023 3024 /************************************************************************ 3025 * In multi slice encoding, this memory record helps tracking the start* 3026 * of slice with reference to mb. * 3027 * MEM RECORD for holding * 3028 * 1. mb slice map * 3029 ************************************************************************/ 3030 ps_mem_rec = &ps_mem_rec_base[MEM_REC_SLICE_MAP]; 3031 { 3032 /* total size of the mem record */ 3033 WORD32 total_size = 0; 3034 3035 /* size in bytes to slice index of all mbs of a frame */ 3036 total_size = ALIGN64(max_mb_cnt); 3037 3038 /* ih264e_update_proc_ctxt can overread by 1 at the end */ 3039 total_size += 1; 3040 3041 /* total size per each proc ctxt */ 3042 total_size *= MAX_CTXT_SETS; 3043 ps_mem_rec->u4_mem_size = total_size; 3044 } 3045 DEBUG("\nMemory record Id %d = %d \n", MEM_REC_SLICE_MAP, ps_mem_rec->u4_mem_size); 3046 3047 /************************************************************************ 3048 * Request memory to hold thread handles for each processing thread * 3049 ************************************************************************/ 3050 ps_mem_rec = &ps_mem_rec_base[MEM_REC_THREAD_HANDLE]; 3051 { 3052 WORD32 handle_size = ithread_get_handle_size(); 3053 3054 ps_mem_rec->u4_mem_size = MAX_PROCESS_THREADS * handle_size; 3055 } 3056 DEBUG("\nMemory record Id %d = %d \n", MEM_REC_THREAD_HANDLE, ps_mem_rec->u4_mem_size); 3057 3058 /************************************************************************ 3059 * Request memory to hold mutex for control calls * 3060 ************************************************************************/ 3061 ps_mem_rec = &ps_mem_rec_base[MEM_REC_CTL_MUTEX]; 3062 { 3063 ps_mem_rec->u4_mem_size = ithread_get_mutex_lock_size(); 3064 } 3065 DEBUG("\nMemory record Id %d = %d \n", MEM_REC_CTL_MUTEX, ps_mem_rec->u4_mem_size); 3066 3067 /************************************************************************ 3068 * Request memory to hold mutex for entropy calls * 3069 ************************************************************************/ 3070 ps_mem_rec = &ps_mem_rec_base[MEM_REC_ENTROPY_MUTEX]; 3071 { 3072 ps_mem_rec->u4_mem_size = ithread_get_mutex_lock_size(); 3073 } 3074 DEBUG("\nMemory record Id %d = %d \n", MEM_REC_ENTROPY_MUTEX, ps_mem_rec->u4_mem_size); 3075 3076 /************************************************************************ 3077 * Request memory to hold process jobs * 3078 ***********************************************************************/ 3079 ps_mem_rec = &ps_mem_rec_base[MEM_REC_PROC_JOBQ]; 3080 { 3081 /* One process job per row of MBs */ 3082 /* Allocate for two pictures, so that wrap around can be handled easily */ 3083 WORD32 num_jobs = max_mb_rows * MAX_CTXT_SETS; 3084 3085 WORD32 job_queue_size = ih264_list_size(num_jobs, sizeof(job_t)); 3086 3087 ps_mem_rec->u4_mem_size = job_queue_size; 3088 } 3089 DEBUG("\nMemory record Id %d = %d \n", MEM_REC_PROC_JOBQ, ps_mem_rec->u4_mem_size); 3090 3091 /************************************************************************ 3092 * Request memory to hold entropy jobs * 3093 ***********************************************************************/ 3094 ps_mem_rec = &ps_mem_rec_base[MEM_REC_ENTROPY_JOBQ]; 3095 { 3096 /* One process job per row of MBs */ 3097 /* Allocate for two pictures, so that wrap around can be handled easily */ 3098 WORD32 num_jobs = max_mb_rows * MAX_CTXT_SETS; 3099 3100 WORD32 job_queue_size = ih264_list_size(num_jobs, sizeof(job_t)); 3101 3102 ps_mem_rec->u4_mem_size = job_queue_size; 3103 } 3104 DEBUG("\nMemory record Id %d = %d \n", MEM_REC_ENTROPY_JOBQ, ps_mem_rec->u4_mem_size); 3105 3106 /************************************************************************ 3107 * In multi core encoding, each row is assumed to be launched on a * 3108 * thread. The rows below can only start after its neighbors are coded * 3109 * The status of an mb coded/uncoded is signaled via proc map. * 3110 * MEM RECORD for holding * 3111 * 1. mb proc map (mb status core coded/uncoded) * 3112 ************************************************************************/ 3113 ps_mem_rec = &ps_mem_rec_base[MEM_REC_PROC_MAP]; 3114 { 3115 /* total size of the mem record */ 3116 WORD32 total_size = 0; 3117 3118 /* size in bytes to mb core coding status of an entire frame */ 3119 total_size = max_mb_cnt; 3120 3121 /* add an additional 1 row of bytes to evade the special case of row 0 */ 3122 total_size += max_mb_cols; 3123 3124 /* total size per each proc ctxt */ 3125 total_size *= MAX_CTXT_SETS; 3126 ps_mem_rec->u4_mem_size = total_size; 3127 } 3128 DEBUG("\nMemory record Id %d = %d \n", MEM_REC_PROC_MAP, ps_mem_rec->u4_mem_size); 3129 3130 /************************************************************************ 3131 * mem record for holding a particular MB is deblocked or not * 3132 * 1. mb deblk map (mb status deblocked/not deblocked) * 3133 ************************************************************************/ 3134 ps_mem_rec = &ps_mem_rec_base[MEM_REC_DBLK_MAP]; 3135 { 3136 /* total size of the mem record */ 3137 WORD32 total_size = 0; 3138 3139 /* size in bytes to mb core coding status of an entire frame */ 3140 total_size = max_mb_cnt; 3141 3142 /* add an additional 1 row of bytes to evade the special case of row 0 */ 3143 total_size += max_mb_cols; 3144 3145 total_size = ALIGN64(total_size); 3146 3147 /* total size per each proc ctxt */ 3148 total_size *= MAX_CTXT_SETS; 3149 ps_mem_rec->u4_mem_size = total_size; 3150 } 3151 DEBUG("\nMemory record Id %d = %d \n", MEM_REC_DBLK_MAP, ps_mem_rec->u4_mem_size); 3152 3153 /************************************************************************ 3154 * mem record for holding a particular MB's me is done or not * 3155 * 1. mb me map * 3156 ************************************************************************/ 3157 ps_mem_rec = &ps_mem_rec_base[MEM_REC_ME_MAP]; 3158 { 3159 /* total size of the mem record */ 3160 WORD32 total_size = 0; 3161 3162 /* size in bytes to mb core coding status of an entire frame */ 3163 total_size = max_mb_cnt; 3164 3165 /* add an additional 1 row of bytes to evade the special case of row 0 */ 3166 total_size += max_mb_cols; 3167 3168 /* total size per each proc ctxt */ 3169 total_size *= MAX_CTXT_SETS; 3170 3171 ps_mem_rec->u4_mem_size = total_size; 3172 } 3173 DEBUG("\nMemory record Id %d = %d \n", MEM_REC_ME_MAP, ps_mem_rec->u4_mem_size); 3174 3175 /************************************************************************ 3176 * size for holding dpb manager context * 3177 ************************************************************************/ 3178 ps_mem_rec = &ps_mem_rec_base[MEM_REC_DPB_MGR]; 3179 { 3180 ps_mem_rec->u4_mem_size = sizeof(dpb_mgr_t); 3181 } 3182 DEBUG("\nMemory record Id %d = %d \n", MEM_REC_DPB_MGR, ps_mem_rec->u4_mem_size); 3183 3184 /************************************************************************ 3185 * luma or chroma core coding involves mb estimation, error computation* 3186 * between the estimated singnal and the actual signal, transform the * 3187 * error, quantize the error, then inverse transform and inverse quant * 3188 * ize the residue and add the result back to estimated signal. * 3189 * To perform all these, a set of temporary buffers are needed. * 3190 * MEM RECORD for holding scratch buffers * 3191 * 1. prediction buffer used during mb mode analysis * 3192 * 2 temp. reference buffer when intra 4x4 with rdopt on is * 3193 * enabled * 3194 * - when intra 4x4 is enabled, rdopt is on, to store the * 3195 * reconstructed values and use them later this temp. buffer * 3196 * is used. * 3197 * 3. prediction buffer used during intra mode analysis * 3198 * 4. prediction buffer used during intra 16x16 plane mode * 3199 * analysis 3200 * 5. prediction buffer used during intra chroma mode analysis * 3201 * 6. prediction buffer used during intra chroma 16x16 plane * 3202 * mode analysis 3203 * 7. forward transform output buffer * 3204 * - to store the error between estimated and the actual inp * 3205 * ut and to store the fwd transformed quantized output * 3206 * 8. forward transform output buffer * 3207 * - when intra 4x4 is enabled, rdopt is on, to store the * 3208 * fwd transform values and use them later this temp. buffer * 3209 * is used. * 3210 * 9. temporary buffer for inverse transform * 3211 * - temporary buffer used in inverse transform and inverse * 3212 * quantization * 3213 * A. Buffers for holding half_x , half_y and half_xy planes * 3214 ************************************************************************/ 3215 ps_mem_rec = &ps_mem_rec_base[MEM_REC_PROC_SCRATCH]; 3216 { 3217 WORD32 total_size = 0; 3218 WORD32 i4_tmp_size; 3219 3220 /* size to hold prediction buffer */ 3221 total_size += sizeof(UWORD8) * 16 * 16; 3222 total_size = ALIGN64(total_size); 3223 3224 /* size to hold recon for intra 4x4 buffer */ 3225 total_size += sizeof(UWORD8) * 16 * 16; 3226 total_size = ALIGN64(total_size); 3227 3228 /* prediction buffer intra 16x16 */ 3229 total_size += sizeof(UWORD8) * 16 * 16; 3230 total_size = ALIGN64(total_size); 3231 3232 /* prediction buffer intra 16x16 plane*/ 3233 total_size += sizeof(UWORD8) * 16 * 16; 3234 total_size = ALIGN64(total_size); 3235 3236 /* prediction buffer intra chroma*/ 3237 total_size += sizeof(UWORD8) * 16 * 8; 3238 total_size = ALIGN64(total_size); 3239 3240 /* prediction buffer intra chroma plane*/ 3241 total_size += sizeof(UWORD8) * 16 * 8; 3242 total_size = ALIGN64(total_size); 3243 3244 /* size to hold fwd transform output */ 3245 total_size += sizeof(WORD16) * SIZE_TRANS_BUFF; 3246 total_size = ALIGN64(total_size); 3247 3248 /* size to hold fwd transform output */ 3249 total_size += sizeof(WORD16) * SIZE_TRANS_BUFF; 3250 total_size = ALIGN64(total_size); 3251 3252 /* size to hold temporary data during inverse transform */ 3253 total_size += sizeof(WORD32) * SIZE_TMP_BUFF_ITRANS; 3254 total_size = ALIGN64(total_size); 3255 3256 /* Buffers for holding half_x , half_y and half_xy planes */ 3257 i4_tmp_size = sizeof(UWORD8) * (HP_BUFF_WD * HP_BUFF_HT); 3258 total_size += (ALIGN64(i4_tmp_size) * SUBPEL_BUFF_CNT); 3259 3260 /* Allocate for each process thread */ 3261 total_size *= MAX_PROCESS_CTXT; 3262 3263 ps_mem_rec->u4_mem_size = total_size; 3264 } 3265 DEBUG("\nMemory record Id %d = %d \n", MEM_REC_PROC_SCRATCH, ps_mem_rec->u4_mem_size); 3266 3267 /************************************************************************ 3268 * When transform_8x8_flag is disabled, the size of a sub block is * 3269 * 4x4 and when the transform_8x8_flag is enabled the size of the sub * 3270 * block is 8x8. The threshold matrix and the forward scaling list * 3271 * is of the size of the sub block. * 3272 * MEM RECORD for holding * 3273 * 1. quantization parameters for plane y, cb, cr * 3274 * - threshold matrix for quantization * 3275 * - forward weight matrix * 3276 * - satqd threshold matrix * 3277 ************************************************************************/ 3278 ps_mem_rec = &ps_mem_rec_base[MEM_REC_QUANT_PARAM]; 3279 { 3280 /* total size of the mem record */ 3281 WORD32 total_size = 0; 3282 3283 /* quantization parameter list for planes y,cb and cr */ 3284 total_size += ALIGN64(sizeof(quant_params_t)) * 3; 3285 3286 /* size of threshold matrix for quantization 3287 * (assuming the transform_8x8_flag is disabled). 3288 * for all 3 planes */ 3289 total_size += ALIGN64(sizeof(WORD16) * 4 * 4) * 3; 3290 3291 /* size of forward weight matrix for quantization 3292 * (assuming the transform_8x8_flag is disabled). 3293 * for all 3 planes */ 3294 total_size += ALIGN64(sizeof(WORD16) * 4 * 4) * 3; 3295 3296 /* Size for SATDQ threshold matrix for palnes y, cb and cr */ 3297 total_size += ALIGN64(sizeof(UWORD16) * 9) * 3; 3298 3299 /* total size per each proc thread */ 3300 total_size *= MAX_PROCESS_CTXT; 3301 3302 ps_mem_rec->u4_mem_size = total_size; 3303 } 3304 DEBUG("\nMemory record Id %d = %d \n", MEM_REC_QUANT_PARAM, ps_mem_rec->u4_mem_size); 3305 3306 /************************************************************************ 3307 * While computing blocking strength for the current mb, the csbp, mb * 3308 * type for the neighboring mbs are necessary. memtab for storing top * 3309 * row mbtype and csbp is evaluated here. * 3310 * * 3311 * when encoding intra 4x4 or intra 8x8 the submb types are estimated * 3312 * and sent. The estimation is dependent on neighbor mbs. For this * 3313 * store the top row sub mb types for intra mbs * 3314 * * 3315 * During motion vector prediction, the curr mb mv is predicted from * 3316 * neigbors left, top, top right and sometimes top left depending on * 3317 * the availability. The top and top right content is accessed from * 3318 * the memtab specified below. * 3319 ************************************************************************/ 3320 ps_mem_rec = &ps_mem_rec_base[MEM_REC_TOP_ROW_SYN_INFO]; 3321 { 3322 /* total size of the mem record */ 3323 WORD32 total_size = 0; 3324 3325 /* size in bytes to store 1 row of mb_info_t */ 3326 /* one additional mb, to avoid checking end of row condition */ 3327 total_size += (max_mb_cols + 1) * sizeof(mb_info_t); 3328 3329 /* size in bytes to store 1 row of intra macroblock sub modes */ 3330 total_size += max_mb_cols * sizeof(UWORD8) * 16; 3331 3332 /* size in bytes to store 1 row + 1 of enc_pu_t */ 3333 /* one additional mb, to avoid checking end of row condition */ 3334 total_size += (max_mb_cols + 1) * sizeof(enc_pu_t); 3335 3336 /* total size per proc ctxt */ 3337 total_size = ALIGN128(total_size); 3338 3339 /* total size per each proc ctxt */ 3340 total_size *= MAX_CTXT_SETS; 3341 ps_mem_rec->u4_mem_size = total_size; 3342 } 3343 DEBUG("\nMemory record Id %d = %d \n", MEM_REC_TOP_ROW_SYN_INFO, ps_mem_rec->u4_mem_size); 3344 3345 /************************************************************************ 3346 * When transform_8x8_flag is disabled, the mb is partitioned into * 3347 * 4 sub blocks. This corresponds to 1 vertical left edge and 1 * 3348 * vertical inner edge, 1 horizontal top edge and 1 horizontal * 3349 * inner edge per mb. Further, When transform_8x8_flag is enabled, * 3350 * the mb is partitioned in to 16 sub blocks. This corresponds to * 3351 * 1 vertical left edge and 3 vertical inner edges, 1 horizontal top * 3352 * edge and 3 horizontal inner edges per mb. * 3353 * MEM RECORD for holding * 3354 * 1. vertical edge blocking strength * 3355 * 2. horizontal edge blocking strength * 3356 * 3. mb qp * 3357 * all are frame level * 3358 ************************************************************************/ 3359 ps_mem_rec = &ps_mem_rec_base[MEM_REC_BS_QP]; 3360 { 3361 /* total size of the mem record */ 3362 WORD32 total_size = 0; 3363 3364 /* size in bytes to store vertical edge bs, horizontal edge bs and qp of every mb*/ 3365 WORD32 vert_bs_size, horz_bs_size, qp_size; 3366 3367 /* vertical edge bs = total number of vertical edges * number of bytes per each edge */ 3368 /* total num of v edges = total mb * 4 (assuming transform_8x8_flag = 0), 3369 * each edge is formed by 4 pairs of subblks, requiring 4 bytes to storing bs */ 3370 vert_bs_size = ALIGN64(max_mb_cnt * 4 * 4); 3371 3372 /* horizontal edge bs = total number of horizontal edges * number of bytes per each edge */ 3373 /* total num of h edges = total mb * 4 (assuming transform_8x8_flag = 0), 3374 * each edge is formed by 4 pairs of subblks, requiring 4 bytes to storing bs */ 3375 horz_bs_size = ALIGN64(max_mb_cnt * 4 * 4); 3376 3377 /* qp of each mb requires 1 byte */ 3378 qp_size = ALIGN64(max_mb_cnt); 3379 3380 /* total size */ 3381 total_size = vert_bs_size + horz_bs_size + qp_size; 3382 3383 /* total size per each proc ctxt */ 3384 total_size *= MAX_CTXT_SETS; 3385 3386 ps_mem_rec->u4_mem_size = total_size; 3387 } 3388 DEBUG("\nMemory record Id %d = %d \n", MEM_REC_BS_QP, ps_mem_rec->u4_mem_size); 3389 3390 /************************************************************************ 3391 * size for holding dpb manager context * 3392 ************************************************************************/ 3393 ps_mem_rec = &ps_mem_rec_base[MEM_REC_INP_PIC]; 3394 { 3395 ps_mem_rec->u4_mem_size = ih264_buf_mgr_size(); 3396 } 3397 DEBUG("\nMemory record Id %d = %d \n", MEM_REC_INP_PIC, ps_mem_rec->u4_mem_size); 3398 3399 /************************************************************************ 3400 * size for holding dpb manager context * 3401 ************************************************************************/ 3402 ps_mem_rec = &ps_mem_rec_base[MEM_REC_OUT]; 3403 { 3404 ps_mem_rec->u4_mem_size = ih264_buf_mgr_size(); 3405 } 3406 DEBUG("\nMemory record Id %d = %d \n", MEM_REC_OUT, ps_mem_rec->u4_mem_size); 3407 3408 /************************************************************************ 3409 * Size for color space conversion * 3410 ************************************************************************/ 3411 ps_mem_rec = &ps_mem_rec_base[MEM_REC_CSC]; 3412 { 3413 /* We need a total a memory for a single frame of 420 sp, ie 3414 * (wd * ht) for luma and (wd * ht / 2) for chroma*/ 3415 ps_mem_rec->u4_mem_size = MAX_CTXT_SETS 3416 * ((3 * max_ht_luma * max_wd_luma) >> 1); 3417 /* Allocate an extra row, since inverse transform functions for 3418 * chroma access(only read, not used) few extra bytes due to 3419 * interleaved input 3420 */ 3421 ps_mem_rec->u4_mem_size += max_wd_luma; 3422 } 3423 DEBUG("\nMemory record Id %d = %d \n", MEM_REC_CSC, ps_mem_rec->u4_mem_size); 3424 3425 /************************************************************************ 3426 * Size for holding pic_buf_t for each reference picture * 3427 * Note this allocation is done for BUF_MGR_MAX_CNT instead of * 3428 * MAX_DPB_SIZE or max_dpb_size for following reasons * 3429 * max_dpb_size will be based on max_wd and max_ht * 3430 * For higher max_wd and max_ht this number will be smaller than * 3431 * MAX_DPB_SIZE But during actual initialization number of buffers * 3432 * allocated can be more. * 3433 * * 3434 * Also to handle display depth application can allocate more than * 3435 * what codec asks for in case of non-shared mode * 3436 * Since this is only a structure allocation and not actual buffer * 3437 * allocation, it is allocated for BUF_MGR_MAX_CNT entries * 3438 ************************************************************************/ 3439 ps_mem_rec = &ps_mem_rec_base[MEM_REC_REF_PIC]; 3440 { 3441 ps_mem_rec->u4_mem_size = ih264_buf_mgr_size(); 3442 ps_mem_rec->u4_mem_size += BUF_MGR_MAX_CNT * sizeof(pic_buf_t); 3443 3444 /************************************************************************ 3445 * Note: Number of luma samples is not max_wd * max_ht here, instead it * 3446 * is set to maximum number of luma samples allowed at the given level. * 3447 * This is done to ensure that any stream with width and height lesser * 3448 * than max_wd and max_ht is supported. Number of buffers required can * 3449 * be greater for lower width and heights at a given level and this * 3450 * increased number of buffers might require more memory than what * 3451 * max_wd and max_ht buffer would have required. Number of buffers is * 3452 * doubled in order to return one frame at a time instead of sending * 3453 * multiple outputs during dpb full case. Also note one extra buffer is * 3454 * allocted to store current picture. * 3455 * * 3456 * Half-pel planes for each reference buffer are allocated along with * 3457 * the reference buffer. So each reference buffer is 4 times the * 3458 * required size. This way buffer management for the half-pel planes is * 3459 * easier and while using the half-pel planes in MC, an offset can be * 3460 * used from a single pointer * 3461 ***********************************************************************/ 3462 ps_mem_rec->u4_mem_size += HPEL_PLANES_CNT 3463 * ih264e_get_total_pic_buf_size( 3464 max_wd_luma * max_ht_luma, level, 3465 PAD_WD, PAD_HT, num_ref_frames, 3466 num_reorder_frames); 3467 } 3468 DEBUG("\nMemory record Id %d = %d \n", MEM_REC_REF_PIC, ps_mem_rec->u4_mem_size); 3469 3470 /************************************************************************ 3471 * Request memory to hold mem recs to be returned during retrieve call * 3472 ************************************************************************/ 3473 ps_mem_rec = &ps_mem_rec_base[MEM_REC_BACKUP]; 3474 { 3475 ps_mem_rec->u4_mem_size = MEM_REC_CNT * sizeof(iv_mem_rec_t); 3476 } 3477 DEBUG("\nMemory record Id %d = %d \n", MEM_REC_BACKUP, ps_mem_rec->u4_mem_size); 3478 3479 /************************************************************************ 3480 * size for memory required by NMB info structs and buffer for storing * 3481 * half pel plane * 3482 ************************************************************************/ 3483 ps_mem_rec = &ps_mem_rec_base[MEM_REC_MB_INFO_NMB]; 3484 { 3485 ps_mem_rec->u4_mem_size = MAX_PROCESS_CTXT * max_mb_cols * 3486 (sizeof(mb_info_nmb_t) + MB_SIZE * MB_SIZE 3487 * sizeof(UWORD8)); 3488 } 3489 DEBUG("\nMemory record Id %d = %d \n", MEM_REC_MB_INFO_NMB, ps_mem_rec->u4_mem_size); 3490 3491 /************************************************************************ 3492 * RC mem records * 3493 ************************************************************************/ 3494 ps_mem_rec = &ps_mem_rec_base[MEM_REC_RC]; 3495 { 3496 ih264e_get_rate_control_mem_tab(NULL, ps_mem_rec, FILL_MEMTAB); 3497 } 3498 DEBUG("\nMemory record Id %d = %d \n", MEM_REC_RC, ps_mem_rec->u4_mem_size); 3499 3500 /* Each memtab size is aligned to next multiple of 128 bytes */ 3501 /* This is to ensure all the memtabs start at different cache lines */ 3502 ps_mem_rec = ps_mem_rec_base; 3503 for (i = 0; i < MEM_REC_CNT; i++) 3504 { 3505 ps_mem_rec->u4_mem_size = ALIGN128(ps_mem_rec->u4_mem_size); 3506 ps_mem_rec++; 3507 } 3508 3509 ps_op->s_ive_op.u4_num_mem_rec = MEM_REC_CNT; 3510 3511 DEBUG("Num mem recs in fill call : %d\n", ps_op->s_ive_op.u4_num_mem_rec); 3512 3513 return (status); 3514 } 3515 3516 /** 3517 ******************************************************************************* 3518 * 3519 * @brief 3520 * Initializes from mem records passed to the codec 3521 * 3522 * @par Description: 3523 * Initializes pointers based on mem records passed 3524 * 3525 * @param[in] ps_codec_obj 3526 * Pointer to codec object at API level 3527 * 3528 * @param[in] pv_api_ip 3529 * Pointer to input argument structure 3530 * 3531 * @param[out] pv_api_op 3532 * Pointer to output argument structure 3533 * 3534 * @returns error status 3535 * 3536 * @remarks none 3537 * 3538 ******************************************************************************* 3539 */ 3540 static WORD32 ih264e_init_mem_rec(iv_obj_t *ps_codec_obj, 3541 void *pv_api_ip, 3542 void *pv_api_op) 3543 { 3544 /* api call I/O structures */ 3545 ih264e_init_ip_t *ps_ip = pv_api_ip; 3546 ih264e_init_op_t *ps_op = pv_api_op; 3547 3548 /* mem records */ 3549 iv_mem_rec_t *ps_mem_rec_base, *ps_mem_rec; 3550 3551 /* codec variables */ 3552 codec_t * ps_codec; 3553 cabac_ctxt_t *ps_cabac; 3554 mb_info_ctxt_t *ps_mb_map_ctxt_inc; 3555 3556 cfg_params_t *ps_cfg; 3557 3558 /* frame dimensions */ 3559 WORD32 max_wd_luma, max_ht_luma; 3560 WORD32 max_mb_rows, max_mb_cols, max_mb_cnt; 3561 3562 /* temp var */ 3563 WORD32 i, j; 3564 WORD32 status = IV_SUCCESS; 3565 3566 /* frame dimensions */ 3567 max_ht_luma = ALIGN16(ps_ip->s_ive_ip.u4_max_ht); 3568 max_wd_luma = ALIGN16(ps_ip->s_ive_ip.u4_max_wd); 3569 max_mb_rows = max_ht_luma / MB_SIZE; 3570 max_mb_cols = max_wd_luma / MB_SIZE; 3571 max_mb_cnt = max_mb_rows * max_mb_cols; 3572 3573 /* mem records */ 3574 ps_mem_rec_base = ps_ip->s_ive_ip.ps_mem_rec; 3575 3576 /* Init mem records */ 3577 ps_mem_rec = &ps_mem_rec_base[MEM_REC_CODEC]; 3578 { 3579 ps_codec_obj->pv_codec_handle = ps_mem_rec->pv_base; 3580 ps_codec = (codec_t *) (ps_codec_obj->pv_codec_handle); 3581 } 3582 /* Init mem records_cabac ctxt */ 3583 ps_mem_rec = &ps_mem_rec_base[MEM_REC_CABAC]; 3584 { 3585 ps_cabac = (cabac_ctxt_t *)(ps_mem_rec->pv_base); 3586 } 3587 3588 /* Init mem records mb info array for CABAC */ 3589 ps_mem_rec = &ps_mem_rec_base[MEM_REC_CABAC_MB_INFO]; 3590 { 3591 ps_mb_map_ctxt_inc = (mb_info_ctxt_t *)(ps_mem_rec->pv_base); 3592 } 3593 3594 /* Note this memset can not be done in init() call, since init will called 3595 during reset as well. And calling this during reset will mean all pointers 3596 need to reinitialized */ 3597 memset(ps_codec, 0, sizeof(codec_t)); 3598 memset(ps_cabac, 0, sizeof(cabac_ctxt_t)); 3599 3600 /* Set default Config Params */ 3601 ps_cfg = &ps_codec->s_cfg; 3602 ih264e_set_default_params(ps_cfg); 3603 3604 /* Update config params as per input */ 3605 ps_cfg->u4_max_wd = ALIGN16(ps_ip->s_ive_ip.u4_max_wd); 3606 ps_cfg->u4_max_ht = ALIGN16(ps_ip->s_ive_ip.u4_max_ht); 3607 ps_cfg->i4_wd_mbs = ps_cfg->u4_max_wd >> 4; 3608 ps_cfg->i4_ht_mbs = ps_cfg->u4_max_ht >> 4; 3609 ps_cfg->u4_max_ref_cnt = ps_ip->s_ive_ip.u4_max_ref_cnt; 3610 ps_cfg->u4_max_reorder_cnt = ps_ip->s_ive_ip.u4_max_reorder_cnt; 3611 ps_cfg->u4_max_level = ps_ip->s_ive_ip.u4_max_level; 3612 ps_cfg->e_inp_color_fmt = ps_ip->s_ive_ip.e_inp_color_fmt; 3613 ps_cfg->e_recon_color_fmt = ps_ip->s_ive_ip.e_recon_color_fmt; 3614 ps_cfg->u4_max_framerate = ps_ip->s_ive_ip.u4_max_framerate; 3615 ps_cfg->u4_max_bitrate = ps_ip->s_ive_ip.u4_max_bitrate; 3616 ps_cfg->u4_num_bframes = ps_ip->s_ive_ip.u4_num_bframes; 3617 ps_cfg->e_content_type = ps_ip->s_ive_ip.e_content_type; 3618 ps_cfg->u4_max_srch_rng_x = ps_ip->s_ive_ip.u4_max_srch_rng_x; 3619 ps_cfg->u4_max_srch_rng_y = ps_ip->s_ive_ip.u4_max_srch_rng_y; 3620 ps_cfg->e_slice_mode = ps_ip->s_ive_ip.e_slice_mode; 3621 ps_cfg->u4_slice_param = ps_ip->s_ive_ip.u4_slice_param; 3622 ps_cfg->e_arch = ps_ip->s_ive_ip.e_arch; 3623 ps_cfg->e_soc = ps_ip->s_ive_ip.e_soc; 3624 ps_cfg->u4_enable_recon = ps_ip->s_ive_ip.u4_enable_recon; 3625 ps_cfg->e_rc_mode = ps_ip->s_ive_ip.e_rc_mode; 3626 3627 /* Validate params */ 3628 if ((ps_ip->s_ive_ip.u4_max_level < MIN_LEVEL) 3629 || (ps_ip->s_ive_ip.u4_max_level > MAX_LEVEL)) 3630 { 3631 ps_op->s_ive_op.u4_error_code |= IH264E_CODEC_LEVEL_NOT_SUPPORTED; 3632 ps_cfg->u4_max_level = DEFAULT_MAX_LEVEL; 3633 } 3634 3635 if (ps_ip->s_ive_ip.u4_max_ref_cnt > MAX_REF_CNT) 3636 { 3637 ps_op->s_ive_op.u4_error_code |= IH264E_NUM_REF_UNSUPPORTED; 3638 ps_cfg->u4_max_ref_cnt = MAX_REF_CNT; 3639 } 3640 3641 if (ps_ip->s_ive_ip.u4_max_reorder_cnt > MAX_REF_CNT) 3642 { 3643 ps_op->s_ive_op.u4_error_code |= IH264E_NUM_REORDER_UNSUPPORTED; 3644 ps_cfg->u4_max_reorder_cnt = MAX_REF_CNT; 3645 } 3646 3647 ps_mem_rec = &ps_mem_rec_base[MEM_REC_BACKUP]; 3648 { 3649 ps_codec->ps_mem_rec_backup = (iv_mem_rec_t *) ps_mem_rec->pv_base; 3650 3651 memcpy(ps_codec->ps_mem_rec_backup, ps_mem_rec_base, 3652 MEM_REC_CNT * sizeof(iv_mem_rec_t)); 3653 } 3654 3655 ps_mem_rec = &ps_mem_rec_base[MEM_REC_ENTROPY]; 3656 { 3657 /* temp var */ 3658 WORD32 size = 0, offset; 3659 3660 for (i = 0; i < MAX_PROCESS_CTXT; i++) 3661 { 3662 if (i < MAX_PROCESS_CTXT / MAX_CTXT_SETS) 3663 { 3664 /* base ptr */ 3665 UWORD8 *pu1_buf = ps_mem_rec->pv_base; 3666 3667 /* reset size */ 3668 size = 0; 3669 3670 /* skip mb run */ 3671 ps_codec->as_process[i].s_entropy.pi4_mb_skip_run = 3672 (void *) (pu1_buf + size); 3673 size += sizeof(WORD32); 3674 size = ALIGN8(size); 3675 3676 /* entropy map */ 3677 ps_codec->as_process[i].s_entropy.pu1_entropy_map = 3678 (void *) (pu1_buf + size + max_mb_cols); 3679 /* size in bytes to store entropy status of an entire frame */ 3680 size += (max_mb_cols * max_mb_rows); 3681 /* add an additional 1 row of bytes to evade the special case of row 0 */ 3682 size += max_mb_cols; 3683 size = ALIGN128(size); 3684 3685 /* bit stream ptr */ 3686 ps_codec->as_process[i].s_entropy.ps_bitstrm = (void *) (pu1_buf 3687 + size); 3688 size += sizeof(bitstrm_t); 3689 size = ALIGN128(size); 3690 3691 /* nnz luma */ 3692 ps_codec->as_process[i].s_entropy.pu1_top_nnz_luma = 3693 (void *) (pu1_buf + size); 3694 size += (max_mb_cols * 4 * sizeof(UWORD8)); 3695 size = ALIGN128(size); 3696 3697 /* nnz chroma */ 3698 ps_codec->as_process[i].s_entropy.pu1_top_nnz_cbcr = 3699 (void *) (pu1_buf + size); 3700 size += (max_mb_cols * 4 * sizeof(UWORD8)); 3701 size = ALIGN128(size); 3702 offset = size; 3703 /* cabac Context */ 3704 ps_codec->as_process[i].s_entropy.ps_cabac = ps_cabac; 3705 } 3706 else 3707 { 3708 /* base ptr */ 3709 UWORD8 *pu1_buf = ps_mem_rec->pv_base; 3710 3711 /* reset size */ 3712 size = offset; 3713 3714 /* skip mb run */ 3715 ps_codec->as_process[i].s_entropy.pi4_mb_skip_run = 3716 (void *) (pu1_buf + size); 3717 size += sizeof(WORD32); 3718 size = ALIGN8(size); 3719 3720 /* entropy map */ 3721 ps_codec->as_process[i].s_entropy.pu1_entropy_map = 3722 (void *) (pu1_buf + size + max_mb_cols); 3723 /* size in bytes to store entropy status of an entire frame */ 3724 size += (max_mb_cols * max_mb_rows); 3725 /* add an additional 1 row of bytes to evade the special case of row 0 */ 3726 size += max_mb_cols; 3727 size = ALIGN128(size); 3728 3729 /* bit stream ptr */ 3730 ps_codec->as_process[i].s_entropy.ps_bitstrm = (void *) (pu1_buf 3731 + size); 3732 size += sizeof(bitstrm_t); 3733 size = ALIGN128(size); 3734 3735 /* nnz luma */ 3736 ps_codec->as_process[i].s_entropy.pu1_top_nnz_luma = 3737 (void *) (pu1_buf + size); 3738 size += (max_mb_cols * 4 * sizeof(UWORD8)); 3739 size = ALIGN128(size); 3740 3741 /* nnz chroma */ 3742 ps_codec->as_process[i].s_entropy.pu1_top_nnz_cbcr = 3743 (void *) (pu1_buf + size); 3744 size += (max_mb_cols * 4 * sizeof(UWORD8)); 3745 size = ALIGN128(size); 3746 /* cabac Context */ 3747 ps_codec->as_process[i].s_entropy.ps_cabac = ps_cabac; 3748 } 3749 } 3750 ps_codec->as_process[0].s_entropy.ps_cabac->ps_mb_map_ctxt_inc_base = 3751 ps_mb_map_ctxt_inc; 3752 } 3753 3754 ps_mem_rec = &ps_mem_rec_base[MEM_REC_MB_COEFF_DATA]; 3755 { 3756 /* temp var */ 3757 WORD32 size = 0, size_of_row; 3758 UWORD8 *pu1_buf = ps_mem_rec->pv_base; 3759 3760 /* size of coeff data of 1 mb */ 3761 size += sizeof(tu_sblk_coeff_data_t) * MAX_4x4_SUBBLKS; 3762 3763 /* size of coeff data of 1 row of mb's */ 3764 size *= max_mb_cols; 3765 3766 /* align to avoid false sharing */ 3767 size = ALIGN64(size); 3768 size_of_row = size; 3769 3770 /* size for one full frame */ 3771 size *= max_mb_rows; 3772 3773 ps_codec->u4_size_coeff_data = size_of_row; 3774 3775 for (i = 0; i < MAX_PROCESS_CTXT; i++) 3776 { 3777 if (i < MAX_PROCESS_CTXT / MAX_CTXT_SETS) 3778 { 3779 ps_codec->as_process[i].pv_pic_mb_coeff_data = pu1_buf; 3780 ps_codec->as_process[i].s_entropy.pv_pic_mb_coeff_data = 3781 pu1_buf; 3782 } 3783 else 3784 { 3785 ps_codec->as_process[i].pv_pic_mb_coeff_data = pu1_buf + size; 3786 ps_codec->as_process[i].s_entropy.pv_pic_mb_coeff_data = pu1_buf 3787 + size; 3788 } 3789 } 3790 } 3791 3792 ps_mem_rec = &ps_mem_rec_base[MEM_REC_MB_HEADER_DATA]; 3793 { 3794 /* temp var */ 3795 WORD32 size, size_of_row; 3796 UWORD8 *pu1_buf = ps_mem_rec->pv_base; 3797 3798 /* size of header data of 1 mb */ 3799 size = 40; 3800 3801 /* size for 1 row of mbs */ 3802 size = size * max_mb_cols; 3803 3804 /* align to avoid any false sharing across threads */ 3805 size = ALIGN64(size); 3806 size_of_row = size; 3807 3808 /* size for one full frame */ 3809 size *= max_mb_rows; 3810 3811 ps_codec->u4_size_header_data = size_of_row; 3812 3813 for (i = 0; i < MAX_PROCESS_CTXT; i++) 3814 { 3815 if (i < MAX_PROCESS_CTXT / MAX_CTXT_SETS) 3816 { 3817 ps_codec->as_process[i].pv_pic_mb_header_data = pu1_buf; 3818 ps_codec->as_process[i].s_entropy.pv_pic_mb_header_data = 3819 pu1_buf; 3820 } 3821 else 3822 { 3823 ps_codec->as_process[i].pv_pic_mb_header_data = pu1_buf + size; 3824 ps_codec->as_process[i].s_entropy.pv_pic_mb_header_data = 3825 pu1_buf + size; 3826 } 3827 } 3828 } 3829 3830 ps_mem_rec = &ps_mem_rec_base[MEM_REC_MVBANK]; 3831 { 3832 /* size of buf mgr struct */ 3833 WORD32 size = ih264_buf_mgr_size(); 3834 3835 /* temp var */ 3836 UWORD8 *pu1_buf = ps_mem_rec->pv_base; 3837 3838 /* mv buffer mgr */ 3839 ps_codec->pv_mv_buf_mgr_base = pu1_buf; 3840 3841 /* mv bank */ 3842 ps_codec->pv_mv_bank_buf_base = pu1_buf + size; 3843 ps_codec->i4_total_mv_bank_size = ps_mem_rec->u4_mem_size - size; 3844 } 3845 3846 ps_mem_rec = &ps_mem_rec_base[MEM_REC_MVBITS]; 3847 { 3848 /* max srch range x */ 3849 UWORD32 u4_srch_range_x = ps_ip->s_ive_ip.u4_max_srch_rng_x; 3850 3851 /* max srch range y */ 3852 UWORD32 u4_srch_range_y = ps_ip->s_ive_ip.u4_max_srch_rng_y; 3853 3854 /* max srch range */ 3855 UWORD32 u4_max_srch_range = MAX(u4_srch_range_x, u4_srch_range_y); 3856 3857 /* temp var */ 3858 UWORD8 *pu1_buf = ps_mem_rec->pv_base; 3859 3860 /* due to subpel */ 3861 u4_max_srch_range <<= 2; 3862 3863 // /* due to mv on either direction */ 3864 // u4_max_srch_range = (u4_max_srch_range << 1); 3865 3866 /* due to pred mv + zero */ 3867 u4_max_srch_range = (u4_max_srch_range << 1) + 1; 3868 3869 for (i = 0; i < MAX_PROCESS_CTXT; i++) 3870 { 3871 /* me ctxt */ 3872 me_ctxt_t *ps_mem_ctxt = &(ps_codec->as_process[i].s_me_ctxt); 3873 3874 /* init at zero mv */ 3875 ps_mem_ctxt->pu1_mv_bits = pu1_buf + u4_max_srch_range; 3876 } 3877 } 3878 3879 ps_mem_rec = &ps_mem_rec_base[MEM_REC_SPS]; 3880 { 3881 ps_codec->ps_sps_base = (sps_t *) ps_mem_rec->pv_base; 3882 } 3883 3884 ps_mem_rec = &ps_mem_rec_base[MEM_REC_PPS]; 3885 { 3886 ps_codec->ps_pps_base = (pps_t *) ps_mem_rec->pv_base; 3887 } 3888 3889 ps_mem_rec = &ps_mem_rec_base[MEM_REC_SLICE_HDR]; 3890 { 3891 ps_codec->ps_slice_hdr_base = ps_mem_rec->pv_base; 3892 3893 for (i = 0; i < MAX_PROCESS_CTXT; i++) 3894 { 3895 if (i < MAX_PROCESS_CTXT / MAX_CTXT_SETS) 3896 { 3897 ps_codec->as_process[i].ps_slice_hdr_base = ps_mem_rec->pv_base; 3898 } 3899 else 3900 { 3901 /* temp var */ 3902 WORD32 size = MAX_SLICE_HDR_CNT * sizeof(slice_header_t); 3903 void *pv_buf = (UWORD8 *) ps_mem_rec->pv_base + size; 3904 3905 ps_codec->as_process[i].ps_slice_hdr_base = pv_buf; 3906 } 3907 } 3908 } 3909 3910 ps_mem_rec = &ps_mem_rec_base[MEM_REC_AIR_MAP]; 3911 { 3912 /* temp var */ 3913 UWORD8 *pu1_buf = ps_mem_rec->pv_base; 3914 3915 for (i = 0; i < MAX_PROCESS_CTXT; i++) 3916 { 3917 if (i < MAX_PROCESS_CTXT / MAX_CTXT_SETS) 3918 { 3919 ps_codec->as_process[i].pu1_is_intra_coded = pu1_buf; 3920 } 3921 else 3922 { 3923 ps_codec->as_process[i].pu1_is_intra_coded = pu1_buf 3924 + max_mb_cnt; 3925 } 3926 } 3927 3928 ps_codec->pu2_intr_rfrsh_map = (UWORD16 *) (pu1_buf + max_mb_cnt * MAX_CTXT_SETS); 3929 } 3930 3931 ps_mem_rec = &ps_mem_rec_base[MEM_REC_SLICE_MAP]; 3932 { 3933 /* pointer to storage space */ 3934 UWORD8 *pu1_buf_ping, *pu1_buf_pong; 3935 3936 /* init pointer */ 3937 pu1_buf_ping = ps_mem_rec->pv_base; 3938 pu1_buf_pong = pu1_buf_ping + ALIGN64(max_mb_cnt); 3939 3940 for (i = 0; i < MAX_PROCESS_CTXT; i++) 3941 { 3942 if (i < MAX_PROCESS_CTXT / MAX_CTXT_SETS) 3943 { 3944 ps_codec->as_process[i].pu1_slice_idx = pu1_buf_ping; 3945 } 3946 else 3947 { 3948 ps_codec->as_process[i].pu1_slice_idx = pu1_buf_pong; 3949 } 3950 } 3951 } 3952 3953 ps_mem_rec = &ps_mem_rec_base[MEM_REC_THREAD_HANDLE]; 3954 { 3955 WORD32 handle_size = ithread_get_handle_size(); 3956 3957 for (i = 0; i < MAX_PROCESS_THREADS; i++) 3958 { 3959 ps_codec->apv_proc_thread_handle[i] = (UWORD8 *) ps_mem_rec->pv_base 3960 + (i * handle_size); 3961 } 3962 } 3963 3964 ps_mem_rec = &ps_mem_rec_base[MEM_REC_CTL_MUTEX]; 3965 { 3966 ps_codec->pv_ctl_mutex = ps_mem_rec->pv_base; 3967 } 3968 3969 ps_mem_rec = &ps_mem_rec_base[MEM_REC_ENTROPY_MUTEX]; 3970 { 3971 ps_codec->pv_entropy_mutex = ps_mem_rec->pv_base; 3972 } 3973 3974 ps_mem_rec = &ps_mem_rec_base[MEM_REC_PROC_JOBQ]; 3975 { 3976 ps_codec->pv_proc_jobq_buf = ps_mem_rec->pv_base; 3977 ps_codec->i4_proc_jobq_buf_size = ps_mem_rec->u4_mem_size; 3978 } 3979 3980 ps_mem_rec = &ps_mem_rec_base[MEM_REC_ENTROPY_JOBQ]; 3981 { 3982 ps_codec->pv_entropy_jobq_buf = ps_mem_rec->pv_base; 3983 ps_codec->i4_entropy_jobq_buf_size = ps_mem_rec->u4_mem_size; 3984 } 3985 3986 ps_mem_rec = &ps_mem_rec_base[MEM_REC_PROC_MAP]; 3987 { 3988 /* pointer to storage space */ 3989 UWORD8 *pu1_buf = ps_mem_rec->pv_base; 3990 3991 /* total size of the mem record */ 3992 WORD32 total_size = 0; 3993 3994 /* size in bytes to mb core coding status of an entire frame */ 3995 total_size = max_mb_cnt; 3996 3997 /* add an additional 1 row of bytes to evade the special case of row 0 */ 3998 total_size += max_mb_cols; 3999 4000 for (i = 0; i < MAX_PROCESS_CTXT; i++) 4001 { 4002 if (i < MAX_PROCESS_CTXT / MAX_CTXT_SETS) 4003 { 4004 ps_codec->as_process[i].pu1_proc_map = pu1_buf + max_mb_cols; 4005 } 4006 else 4007 { 4008 ps_codec->as_process[i].pu1_proc_map = pu1_buf + total_size 4009 + max_mb_cols; 4010 } 4011 } 4012 } 4013 4014 ps_mem_rec = &ps_mem_rec_base[MEM_REC_DBLK_MAP]; 4015 { 4016 /* pointer to storage space */ 4017 UWORD8 *pu1_buf = ps_mem_rec->pv_base; 4018 4019 /* total size of the mem record */ 4020 WORD32 total_size = 0; 4021 4022 /* size in bytes to mb core coding status of an entire frame */ 4023 total_size = max_mb_cnt; 4024 4025 /* add an additional 1 row of bytes to evade the special case of row 0 */ 4026 total_size += max_mb_cols; 4027 4028 /*Align the memory offsets*/ 4029 total_size = ALIGN64(total_size); 4030 4031 for (i = 0; i < MAX_PROCESS_CTXT; i++) 4032 { 4033 if (i < MAX_PROCESS_CTXT / MAX_CTXT_SETS) 4034 { 4035 ps_codec->as_process[i].pu1_deblk_map = pu1_buf + max_mb_cols; 4036 4037 } 4038 else 4039 { 4040 ps_codec->as_process[i].pu1_deblk_map = pu1_buf + total_size 4041 + max_mb_cols; 4042 4043 } 4044 } 4045 } 4046 4047 ps_mem_rec = &ps_mem_rec_base[MEM_REC_ME_MAP]; 4048 { 4049 /* pointer to storage space */ 4050 UWORD8 *pu1_buf = (UWORD8 *) ps_mem_rec->pv_base; 4051 4052 /* total size of the mem record */ 4053 WORD32 total_size = 0; 4054 4055 /* size in bytes to mb core coding status of an entire frame */ 4056 total_size = max_mb_cnt; 4057 4058 /* add an additional 1 row of bytes to evade the special case of row 0 */ 4059 total_size += max_mb_cols; 4060 4061 for (i = 0; i < MAX_PROCESS_CTXT; i++) 4062 { 4063 if (i < MAX_PROCESS_CTXT / MAX_CTXT_SETS) 4064 { 4065 ps_codec->as_process[i].pu1_me_map = pu1_buf + max_mb_cols; 4066 } 4067 else 4068 { 4069 ps_codec->as_process[i].pu1_me_map = pu1_buf + total_size 4070 + max_mb_cols; 4071 } 4072 } 4073 } 4074 4075 ps_mem_rec = &ps_mem_rec_base[MEM_REC_DPB_MGR]; 4076 { 4077 ps_codec->pv_dpb_mgr = ps_mem_rec->pv_base; 4078 } 4079 4080 ps_mem_rec = &ps_mem_rec_base[MEM_REC_PROC_SCRATCH]; 4081 { 4082 /* pointer to storage space */ 4083 UWORD8 *pu1_buf = (UWORD8 *) ps_mem_rec->pv_base; 4084 4085 /* size of pred buffer, fwd transform output, temp buffer for inv tra */ 4086 WORD32 size_pred_luma, size_pred_chroma, size_fwd, size_inv, size_hp; 4087 4088 /* temp var */ 4089 WORD32 size = 0; 4090 4091 /* size to hold intra/inter prediction buffer */ 4092 size_pred_luma = sizeof(UWORD8) * 16 * 16; 4093 size_pred_chroma = sizeof(UWORD8) * 8 * 16; 4094 4095 /* size to hold fwd transform output */ 4096 size_fwd = sizeof(WORD16) * SIZE_TRANS_BUFF; 4097 4098 /* size to hold temporary data during inverse transform */ 4099 size_inv = sizeof(WORD32) * SIZE_TMP_BUFF_ITRANS; 4100 4101 /* size to hold half pel plane buffers */ 4102 size_hp = sizeof(UWORD8) * (HP_BUFF_WD * HP_BUFF_HT); 4103 4104 for (i = 0; i < MAX_PROCESS_CTXT; i++) 4105 { 4106 /* prediction buffer */ 4107 ps_codec->as_process[i].pu1_pred_mb = (void *) (pu1_buf + size); 4108 ps_codec->as_process[i].i4_pred_strd = 16; 4109 size += size_pred_luma; 4110 size = ALIGN64(size); 4111 4112 /* prediction buffer */ 4113 ps_codec->as_process[i].pu1_ref_mb_intra_4x4 = (void *) (pu1_buf 4114 + size); 4115 size += size_pred_luma; 4116 size = ALIGN64(size); 4117 4118 /* prediction buffer intra 16x16 */ 4119 ps_codec->as_process[i].pu1_pred_mb_intra_16x16 = (void *) (pu1_buf 4120 + size); 4121 size += size_pred_luma; 4122 size = ALIGN64(size); 4123 4124 /* prediction buffer intra 16x16 plane*/ 4125 ps_codec->as_process[i].pu1_pred_mb_intra_16x16_plane = 4126 (void *) (pu1_buf + size); 4127 size += size_pred_luma; 4128 size = ALIGN64(size); 4129 4130 /* prediction buffer intra chroma*/ 4131 ps_codec->as_process[i].pu1_pred_mb_intra_chroma = (void *) (pu1_buf 4132 + size); 4133 size += size_pred_chroma; 4134 size = ALIGN64(size); 4135 4136 /* prediction buffer intra chroma plane*/ 4137 ps_codec->as_process[i].pu1_pred_mb_intra_chroma_plane = 4138 (void *) (pu1_buf + size); 4139 size += size_pred_chroma; 4140 size = ALIGN64(size); 4141 4142 /* Fwd transform output */ 4143 ps_codec->as_process[i].pi2_res_buf = (void *) (pu1_buf + size); 4144 ps_codec->as_process[i].i4_res_strd = 16; 4145 size += size_fwd; 4146 size = ALIGN64(size); 4147 4148 /* Fwd transform output */ 4149 ps_codec->as_process[i].pi2_res_buf_intra_4x4 = (void *) (pu1_buf 4150 + size); 4151 size += size_fwd; 4152 size = ALIGN64(size); 4153 4154 /* scratch buffer used during inverse transform */ 4155 ps_codec->as_process[i].pv_scratch_buff = (void *) (pu1_buf + size); 4156 size += size_inv; 4157 size = ALIGN64(size); 4158 4159 for (j = 0; j < SUBPEL_BUFF_CNT; j++) 4160 { 4161 ps_codec->as_process[i].apu1_subpel_buffs[j] = (pu1_buf + size); 4162 size += ALIGN64(size_hp); 4163 } 4164 } 4165 } 4166 4167 ps_mem_rec = &ps_mem_rec_base[MEM_REC_QUANT_PARAM]; 4168 { 4169 /* pointer to storage space */ 4170 UWORD8 *pu1_buf = (UWORD8 *) ps_mem_rec->pv_base; 4171 4172 /* size of qp, threshold matrix, fwd scaling list for one plane */ 4173 WORD32 size_quant_param, size_thres_mat, size_fwd_weight_mat, 4174 size_satqd_weight_mat; 4175 4176 /* temp var */ 4177 WORD32 total_size = 0; 4178 4179 /* size of quantization parameter list of 1 plane */ 4180 size_quant_param = ALIGN64(sizeof(quant_params_t)); 4181 4182 /* size of threshold matrix for quantization 4183 * (assuming the transform_8x8_flag is disabled). 4184 * for 1 plane */ 4185 size_thres_mat = ALIGN64(sizeof(WORD16) * 4 * 4); 4186 4187 /* size of forward weight matrix for quantization 4188 * (assuming the transform_8x8_flag is disabled). 4189 * for 1 plane */ 4190 size_fwd_weight_mat = ALIGN64(sizeof(WORD16) * 4 * 4); 4191 4192 /* size of SATQD matrix*/ 4193 size_satqd_weight_mat = ALIGN64(sizeof(UWORD16) * 9); 4194 4195 for (i = 0; i < MAX_PROCESS_CTXT; i++) 4196 { 4197 quant_params_t **ps_qp_params = ps_codec->as_process[i].ps_qp_params; 4198 4199 /* quantization param structure */ 4200 ps_qp_params[0] = (quant_params_t *) (pu1_buf + total_size); 4201 total_size = total_size + size_quant_param; 4202 ps_qp_params[1] = (quant_params_t *) (pu1_buf + total_size); 4203 total_size = total_size + size_quant_param; 4204 ps_qp_params[2] = (quant_params_t *) (pu1_buf + total_size); 4205 total_size = total_size + size_quant_param; 4206 4207 /* threshold matrix for quantization */ 4208 ps_qp_params[0]->pu2_thres_mat = (void *) (pu1_buf + total_size); 4209 total_size = total_size + size_thres_mat; 4210 ps_qp_params[1]->pu2_thres_mat = (void *) (pu1_buf + total_size); 4211 total_size = total_size + size_thres_mat; 4212 ps_qp_params[2]->pu2_thres_mat = (void *) (pu1_buf + total_size); 4213 total_size = total_size + size_thres_mat; 4214 4215 /* fwd weight matrix */ 4216 ps_qp_params[0]->pu2_weigh_mat = (void *) (pu1_buf + total_size); 4217 total_size = total_size + size_fwd_weight_mat; 4218 ps_qp_params[1]->pu2_weigh_mat = (void *) (pu1_buf + total_size); 4219 total_size = total_size + size_fwd_weight_mat; 4220 ps_qp_params[2]->pu2_weigh_mat = (void *) (pu1_buf + total_size); 4221 total_size = total_size + size_fwd_weight_mat; 4222 4223 /* threshold matrix for SATQD */ 4224 ps_qp_params[0]->pu2_sad_thrsh = (void *) (pu1_buf + total_size); 4225 total_size = total_size + size_satqd_weight_mat; 4226 ps_qp_params[1]->pu2_sad_thrsh = (void *) (pu1_buf + total_size); 4227 total_size = total_size + size_satqd_weight_mat; 4228 ps_qp_params[2]->pu2_sad_thrsh = (void *) (pu1_buf + total_size); 4229 total_size = total_size + size_satqd_weight_mat; 4230 4231 total_size = ALIGN128(total_size); 4232 } 4233 } 4234 4235 ps_mem_rec = &ps_mem_rec_base[MEM_REC_TOP_ROW_SYN_INFO]; 4236 { 4237 /* total size of the mem record */ 4238 WORD32 total_size = 0, size_csbp, size_intra_modes, size_mv; 4239 4240 /* pointer to buffer */ 4241 UWORD8 *pu1_buf = ps_mem_rec->pv_base; 4242 4243 /* size in bytes to store 1 row of mb_info_t */ 4244 /* one additional mb, to avoid checking end of row condition */ 4245 size_csbp = (max_mb_cols + 1) * sizeof(mb_info_t); 4246 4247 /* size in bytes to store 1 row of intra macroblock sub modes */ 4248 size_intra_modes = max_mb_cols * sizeof(UWORD8) * 16; 4249 4250 /* size in bytes to store 1 row + 1 of enc_pu_t */ 4251 /* one additional mb, to avoid checking end of row condition */ 4252 size_mv = (max_mb_cols + 1) * sizeof(enc_pu_t); 4253 4254 /* total size per proc ctxt */ 4255 total_size = size_csbp + size_intra_modes + size_mv; 4256 4257 for (i = 0; i < MAX_PROCESS_CTXT; i++) 4258 { 4259 if (i < MAX_PROCESS_CTXT / MAX_CTXT_SETS) 4260 { 4261 ps_codec->as_process[i].ps_top_row_mb_syntax_ele_base = 4262 (mb_info_t *) pu1_buf; 4263 ps_codec->as_process[i].pu1_top_mb_intra_modes_base = pu1_buf 4264 + size_csbp; 4265 ps_codec->as_process[i].ps_top_row_pu_base = 4266 (enc_pu_t *) (pu1_buf + size_csbp 4267 + size_intra_modes); 4268 } 4269 else 4270 { 4271 ps_codec->as_process[i].ps_top_row_mb_syntax_ele_base = 4272 (mb_info_t *) (pu1_buf + total_size); 4273 ps_codec->as_process[i].pu1_top_mb_intra_modes_base = pu1_buf 4274 + total_size + size_csbp; 4275 ps_codec->as_process[i].ps_top_row_pu_base = 4276 (enc_pu_t *) (pu1_buf + total_size + size_csbp 4277 + size_intra_modes); 4278 } 4279 } 4280 } 4281 4282 ps_mem_rec = &ps_mem_rec_base[MEM_REC_BS_QP]; 4283 { 4284 UWORD8 *pu1_buf_ping, *pu1_buf_pong; 4285 4286 /* total size of the mem record */ 4287 WORD32 total_size = 0; 4288 4289 /* size in bytes to store vertical edge bs, horizontal edge bs and qp of every mb*/ 4290 WORD32 vert_bs_size, horz_bs_size, qp_size; 4291 4292 /* vertical edge bs = total number of vertical edges * number of bytes per each edge */ 4293 /* total num of v edges = total mb * 4 (assuming transform_8x8_flag = 0), 4294 * each edge is formed by 4 pairs of subblks, requiring 4 bytes to storing bs */ 4295 vert_bs_size = ALIGN64(max_mb_cnt * 4 * 4); 4296 4297 /* horizontal edge bs = total number of horizontal edges * number of bytes per each edge */ 4298 /* total num of h edges = total mb * 4 (assuming transform_8x8_flag = 0), 4299 * each edge is formed by 4 pairs of subblks, requiring 4 bytes to storing bs */ 4300 horz_bs_size = ALIGN64(max_mb_cnt * 4 * 4); 4301 4302 /* qp of each mb requires 1 byte */ 4303 qp_size = ALIGN64(max_mb_cnt); 4304 4305 /* total size */ 4306 total_size = vert_bs_size + horz_bs_size + qp_size; 4307 4308 for (i = 0; i < MAX_PROCESS_CTXT; i++) 4309 { 4310 if (i < MAX_PROCESS_CTXT / MAX_CTXT_SETS) 4311 { 4312 pu1_buf_ping = (UWORD8 *) ps_mem_rec->pv_base; 4313 4314 /* vertical edge bs storage space */ 4315 ps_codec->as_process[i].s_deblk_ctxt.s_bs_ctxt.pu4_pic_vert_bs = 4316 (UWORD32 *) pu1_buf_ping; 4317 pu1_buf_ping += vert_bs_size; 4318 4319 /* horizontal edge bs storage space */ 4320 ps_codec->as_process[i].s_deblk_ctxt.s_bs_ctxt.pu4_pic_horz_bs = 4321 (UWORD32 *) pu1_buf_ping; 4322 pu1_buf_ping += horz_bs_size; 4323 4324 /* qp */ 4325 ps_codec->as_process[i].s_deblk_ctxt.s_bs_ctxt.pu1_pic_qp = 4326 (UWORD8 *) pu1_buf_ping; 4327 pu1_buf_ping += qp_size; 4328 } 4329 else 4330 { 4331 pu1_buf_pong = (UWORD8 *) ps_mem_rec->pv_base; 4332 pu1_buf_pong += total_size; 4333 4334 /* vertical edge bs storage space */ 4335 ps_codec->as_process[i].s_deblk_ctxt.s_bs_ctxt.pu4_pic_vert_bs = 4336 (UWORD32 *) pu1_buf_pong; 4337 pu1_buf_pong += vert_bs_size; 4338 4339 /* horizontal edge bs storage space */ 4340 ps_codec->as_process[i].s_deblk_ctxt.s_bs_ctxt.pu4_pic_horz_bs = 4341 (UWORD32 *) pu1_buf_pong; 4342 pu1_buf_pong += horz_bs_size; 4343 4344 /* qp */ 4345 ps_codec->as_process[i].s_deblk_ctxt.s_bs_ctxt.pu1_pic_qp = 4346 (UWORD8 *) pu1_buf_pong; 4347 pu1_buf_pong += qp_size; 4348 } 4349 } 4350 } 4351 4352 ps_mem_rec = &ps_mem_rec_base[MEM_REC_INP_PIC]; 4353 { 4354 ps_codec->pv_inp_buf_mgr_base = ps_mem_rec->pv_base; 4355 } 4356 4357 ps_mem_rec = &ps_mem_rec_base[MEM_REC_OUT]; 4358 { 4359 ps_codec->pv_out_buf_mgr_base = ps_mem_rec->pv_base; 4360 } 4361 4362 ps_mem_rec = &ps_mem_rec_base[MEM_REC_CSC]; 4363 { 4364 ps_codec->pu1_y_csc_buf_base = ps_mem_rec->pv_base; 4365 ps_codec->pu1_uv_csc_buf_base = (UWORD8 *) ps_mem_rec->pv_base 4366 + (max_ht_luma * max_wd_luma); 4367 } 4368 4369 ps_mem_rec = &ps_mem_rec_base[MEM_REC_REF_PIC]; 4370 { 4371 /* size of buf mgr struct */ 4372 WORD32 size = ih264_buf_mgr_size(); 4373 4374 /* temp var */ 4375 UWORD8 *pu1_buf = ps_mem_rec->pv_base; 4376 4377 /* pic buffer mgr */ 4378 ps_codec->pv_ref_buf_mgr_base = pu1_buf; 4379 4380 /* picture bank */ 4381 ps_codec->pv_pic_buf_base = pu1_buf + size; 4382 ps_codec->i4_total_pic_buf_size = ps_mem_rec->u4_mem_size - size; 4383 } 4384 4385 ps_mem_rec = &ps_mem_rec_base[MEM_REC_MB_INFO_NMB]; 4386 { 4387 /* temp var */ 4388 UWORD8 *pu1_buf = ps_mem_rec->pv_base; 4389 4390 /* size of nmb ctxt */ 4391 WORD32 size = max_mb_cols * sizeof(mb_info_nmb_t); 4392 4393 WORD32 nmb_cntr, subpel_buf_size; 4394 4395 /* init nmb info structure pointer in all proc ctxts */ 4396 for (i = 0; i < MAX_PROCESS_CTXT; i++) 4397 { 4398 ps_codec->as_process[i].ps_nmb_info = (mb_info_nmb_t *) (pu1_buf); 4399 4400 pu1_buf += size; 4401 } 4402 4403 subpel_buf_size = MB_SIZE * MB_SIZE * sizeof(UWORD8); 4404 4405 /* adjusting pointers for nmb halfpel buffer */ 4406 for (i = 0; i < MAX_PROCESS_CTXT; i++) 4407 { 4408 mb_info_nmb_t* ps_mb_info_nmb = 4409 &ps_codec->as_process[i].ps_nmb_info[0]; 4410 4411 for (nmb_cntr = 0; nmb_cntr < max_mb_cols; nmb_cntr++) 4412 { 4413 ps_mb_info_nmb[nmb_cntr].pu1_best_sub_pel_buf = pu1_buf; 4414 4415 pu1_buf = pu1_buf + subpel_buf_size; 4416 4417 ps_mb_info_nmb[nmb_cntr].u4_bst_spel_buf_strd = MB_SIZE; 4418 } 4419 } 4420 } 4421 4422 ps_mem_rec = &ps_mem_rec_base[MEM_REC_RC]; 4423 { 4424 ih264e_get_rate_control_mem_tab(&ps_codec->s_rate_control, ps_mem_rec, 4425 USE_BASE); 4426 } 4427 4428 /* init codec ctxt */ 4429 status = ih264e_init(ps_codec); 4430 4431 return status; 4432 } 4433 4434 /** 4435 ******************************************************************************* 4436 * 4437 * @brief 4438 * Retrieves mem records passed to the codec 4439 * 4440 * @par Description: 4441 * Retrieves mem recs passed during init 4442 * 4443 * @param[in] ps_codec_obj 4444 * Pointer to codec object at API level 4445 * 4446 * @param[in] pv_api_ip 4447 * Pointer to input argument structure 4448 * 4449 * @param[out] pv_api_op 4450 * Pointer to output argument structure 4451 * 4452 * @returns error status 4453 * 4454 * @remarks none 4455 * 4456 ******************************************************************************* 4457 */ 4458 static WORD32 ih264e_retrieve_memrec(iv_obj_t *ps_codec_obj, 4459 void *pv_api_ip, 4460 void *pv_api_op) 4461 { 4462 /* codec ctxt */ 4463 codec_t *ps_codec = (codec_t *) ps_codec_obj->pv_codec_handle; 4464 4465 /* ctrl call I/O structures */ 4466 ih264e_retrieve_mem_rec_ip_t *ps_ip = pv_api_ip; 4467 ih264e_retrieve_mem_rec_op_t *ps_op = pv_api_op; 4468 4469 if (ps_codec->i4_init_done != 1) 4470 { 4471 ps_op->s_ive_op.u4_error_code |= 1 << IVE_FATALERROR; 4472 ps_op->s_ive_op.u4_error_code |= IH264E_INIT_NOT_DONE; 4473 return IV_FAIL; 4474 } 4475 4476 /* join threads upon at end of sequence */ 4477 ih264e_join_threads(ps_codec); 4478 4479 /* collect list of memory records used by the encoder library */ 4480 memcpy(ps_ip->s_ive_ip.ps_mem_rec, ps_codec->ps_mem_rec_backup, 4481 MEM_REC_CNT * (sizeof(iv_mem_rec_t))); 4482 ps_op->s_ive_op.u4_num_mem_rec_filled = MEM_REC_CNT; 4483 4484 /* clean up mutex memory */ 4485 ih264_list_free(ps_codec->pv_entropy_jobq); 4486 ih264_list_free(ps_codec->pv_proc_jobq); 4487 ithread_mutex_destroy(ps_codec->pv_ctl_mutex); 4488 ithread_mutex_destroy(ps_codec->pv_entropy_mutex); 4489 4490 4491 ih264_buf_mgr_free((buf_mgr_t *)ps_codec->pv_mv_buf_mgr); 4492 ih264_buf_mgr_free((buf_mgr_t *)ps_codec->pv_ref_buf_mgr); 4493 ih264_buf_mgr_free((buf_mgr_t *)ps_codec->pv_inp_buf_mgr); 4494 ih264_buf_mgr_free((buf_mgr_t *)ps_codec->pv_out_buf_mgr); 4495 4496 return IV_SUCCESS; 4497 } 4498 4499 /** 4500 ******************************************************************************* 4501 * 4502 * @brief 4503 * Sets the encoder in flush mode. 4504 * 4505 * @par Description: 4506 * Sets the encoder in flush mode 4507 * 4508 * @param[in] ps_codec_obj 4509 * Pointer to codec object at API level 4510 * 4511 * @param[in] pv_api_ip 4512 * Pointer to input argument structure 4513 * 4514 * @param[out] pv_api_op 4515 * Pointer to output argument structure 4516 * 4517 * @returns error status 4518 * 4519 * @remarks This call has no real effect on encoder 4520 * 4521 ******************************************************************************* 4522 */ 4523 static WORD32 ih264e_set_flush_mode(iv_obj_t *ps_codec_obj, 4524 void *pv_api_ip, 4525 void *pv_api_op) 4526 { 4527 /* codec ctxt */ 4528 codec_t *ps_codec = (codec_t *) ps_codec_obj->pv_codec_handle; 4529 4530 /* ctrl call I/O structures */ 4531 ih264e_ctl_flush_op_t *ps_ctl_op = pv_api_op; 4532 4533 UNUSED(pv_api_ip); 4534 4535 ps_ctl_op->s_ive_op.u4_error_code = 0; 4536 4537 /* signal flush frame control call */ 4538 ps_codec->i4_flush_mode = 1; 4539 4540 return IV_SUCCESS; 4541 } 4542 4543 /** 4544 ******************************************************************************* 4545 * 4546 * @brief 4547 * Gets encoder buffer requirements 4548 * 4549 * @par Description: 4550 * Gets the encoder buffer requirements. Basing on max width and max height 4551 * configuration settings, this routine, computes the sizes of necessary input, 4552 * output buffers returns this info to callee. 4553 * 4554 * @param[in] ps_codec_obj 4555 * Pointer to codec object at API level 4556 * 4557 * @param[in] pv_api_ip 4558 * Pointer to input argument structure 4559 * 4560 * @param[out] pv_api_op 4561 * Pointer to output argument structure 4562 * 4563 * @returns error status 4564 * 4565 * @remarks none 4566 * 4567 ******************************************************************************* 4568 */ 4569 static WORD32 ih264e_get_buf_info(iv_obj_t *ps_codec_obj, 4570 void *pv_api_ip, 4571 void *pv_api_op) 4572 { 4573 /* ctrl call I/O structures */ 4574 ih264e_ctl_getbufinfo_ip_t *ps_ip = pv_api_ip; 4575 ih264e_ctl_getbufinfo_op_t *ps_op = pv_api_op; 4576 4577 /* temp var */ 4578 WORD32 wd = ALIGN16(ps_ip->s_ive_ip.u4_max_wd); 4579 WORD32 ht = ALIGN16(ps_ip->s_ive_ip.u4_max_ht); 4580 WORD32 i; 4581 4582 UNUSED(ps_codec_obj); 4583 4584 ps_op->s_ive_op.u4_error_code = 0; 4585 4586 /* Number of components in input buffers required for codec & 4587 * Minimum sizes of each component in input buffer required */ 4588 if (ps_ip->s_ive_ip.e_inp_color_fmt == IV_YUV_420P) 4589 { 4590 ps_op->s_ive_op.u4_inp_comp_cnt = MIN_RAW_BUFS_420_COMP; 4591 4592 ps_op->s_ive_op.au4_min_in_buf_size[0] = wd * ht; 4593 ps_op->s_ive_op.au4_min_in_buf_size[1] = (wd >> 1) * (ht >> 1); 4594 ps_op->s_ive_op.au4_min_in_buf_size[2] = (wd >> 1) * (ht >> 1); 4595 } 4596 else if (ps_ip->s_ive_ip.e_inp_color_fmt == IV_YUV_422ILE) 4597 { 4598 ps_op->s_ive_op.u4_inp_comp_cnt = MIN_RAW_BUFS_422ILE_COMP; 4599 4600 ps_op->s_ive_op.au4_min_in_buf_size[0] = wd * ht * 2; 4601 ps_op->s_ive_op.au4_min_in_buf_size[1] = 4602 ps_op->s_ive_op.au4_min_in_buf_size[2] = 0; 4603 } 4604 else if (ps_ip->s_ive_ip.e_inp_color_fmt == IV_RGB_565) 4605 { 4606 ps_op->s_ive_op.u4_inp_comp_cnt = MIN_RAW_BUFS_RGB565_COMP; 4607 4608 ps_op->s_ive_op.au4_min_in_buf_size[0] = wd * ht * 2; 4609 ps_op->s_ive_op.au4_min_in_buf_size[1] = 4610 ps_op->s_ive_op.au4_min_in_buf_size[2] = 0; 4611 } 4612 else if (ps_ip->s_ive_ip.e_inp_color_fmt == IV_RGBA_8888) 4613 { 4614 ps_op->s_ive_op.u4_inp_comp_cnt = MIN_RAW_BUFS_RGBA8888_COMP; 4615 4616 ps_op->s_ive_op.au4_min_in_buf_size[0] = wd * ht * 4; 4617 ps_op->s_ive_op.au4_min_in_buf_size[1] = 4618 ps_op->s_ive_op.au4_min_in_buf_size[2] = 0; 4619 } 4620 else if ((ps_ip->s_ive_ip.e_inp_color_fmt == IV_YUV_420SP_UV) 4621 || (ps_ip->s_ive_ip.e_inp_color_fmt == IV_YUV_420SP_VU)) 4622 { 4623 ps_op->s_ive_op.u4_inp_comp_cnt = MIN_RAW_BUFS_420SP_COMP; 4624 4625 ps_op->s_ive_op.au4_min_in_buf_size[0] = wd * ht; 4626 ps_op->s_ive_op.au4_min_in_buf_size[1] = wd * (ht >> 1); 4627 ps_op->s_ive_op.au4_min_in_buf_size[2] = 0; 4628 } 4629 4630 /* Number of components in output buffers required for codec & 4631 * Minimum sizes of each component in output buffer required */ 4632 ps_op->s_ive_op.u4_out_comp_cnt = MIN_BITS_BUFS_COMP; 4633 4634 for (i = 0; i < (WORD32) ps_op->s_ive_op.u4_out_comp_cnt; i++) 4635 { 4636 ps_op->s_ive_op.au4_min_out_buf_size[i] = MAX(((wd * ht * 3) >> 1), MIN_STREAM_SIZE); 4637 } 4638 4639 ps_op->s_ive_op.u4_min_inp_bufs = MIN_INP_BUFS; 4640 ps_op->s_ive_op.u4_min_out_bufs = MIN_OUT_BUFS; 4641 4642 return IV_SUCCESS; 4643 } 4644 4645 /** 4646 ******************************************************************************* 4647 * 4648 * @brief 4649 * Sets the picture dimensions 4650 * 4651 * @par Description: 4652 * Sets width, height, display width, display height and strides 4653 * 4654 * @param[in] pv_api_ip 4655 * Pointer to input argument structure 4656 * 4657 * @param[out] pv_api_op 4658 * Pointer to output argument structure 4659 * 4660 * @param[out] ps_cfg 4661 * Pointer to config structure to be updated 4662 * 4663 * @returns error status 4664 * 4665 * @remarks none 4666 * 4667 ******************************************************************************* 4668 */ 4669 static IV_STATUS_T ih264e_set_dimensions(void *pv_api_ip, 4670 void *pv_api_op, 4671 cfg_params_t *ps_cfg) 4672 { 4673 /* ctrl call I/O structures */ 4674 ih264e_ctl_set_dimensions_ip_t *ps_ip = pv_api_ip; 4675 ih264e_ctl_set_dimensions_op_t *ps_op = pv_api_op; 4676 4677 ps_op->s_ive_op.u4_error_code = 0; 4678 4679 ps_cfg->u4_wd = ALIGN16(ps_ip->s_ive_ip.u4_wd); 4680 ps_cfg->u4_ht = ALIGN16(ps_ip->s_ive_ip.u4_ht); 4681 ps_cfg->i4_wd_mbs = ps_cfg->u4_wd >> 4; 4682 ps_cfg->i4_ht_mbs = ps_cfg->u4_ht >> 4; 4683 ps_cfg->u4_disp_wd = ps_ip->s_ive_ip.u4_wd; 4684 ps_cfg->u4_disp_ht = ps_ip->s_ive_ip.u4_ht; 4685 4686 ps_cfg->u4_timestamp_high = ps_ip->s_ive_ip.u4_timestamp_high; 4687 ps_cfg->u4_timestamp_low = ps_ip->s_ive_ip.u4_timestamp_low; 4688 4689 return IV_SUCCESS; 4690 } 4691 4692 /** 4693 ******************************************************************************* 4694 * 4695 * @brief 4696 * Sets source and target frame rates 4697 * 4698 * @par Description: 4699 * Sets source and target frame rates 4700 * 4701 * @param[in] pv_api_ip 4702 * Pointer to input argument structure 4703 * 4704 * @param[out] pv_api_op 4705 * Pointer to output argument structure 4706 * 4707 * @param[out] ps_cfg 4708 * Pointer to config structure to be updated 4709 * 4710 * @returns error status 4711 * 4712 * @remarks none 4713 * 4714 ******************************************************************************* 4715 */ 4716 static IV_STATUS_T ih264e_set_frame_rate(void *pv_api_ip, 4717 void *pv_api_op, 4718 cfg_params_t *ps_cfg) 4719 { 4720 /* ctrl call I/O structures */ 4721 ih264e_ctl_set_frame_rate_ip_t *ps_ip = pv_api_ip; 4722 ih264e_ctl_set_frame_rate_op_t *ps_op = pv_api_op; 4723 4724 ps_op->s_ive_op.u4_error_code = 0; 4725 4726 ps_cfg->u4_src_frame_rate = ps_ip->s_ive_ip.u4_src_frame_rate; 4727 ps_cfg->u4_tgt_frame_rate = ps_ip->s_ive_ip.u4_tgt_frame_rate; 4728 4729 ps_cfg->u4_timestamp_high = ps_ip->s_ive_ip.u4_timestamp_high; 4730 ps_cfg->u4_timestamp_low = ps_ip->s_ive_ip.u4_timestamp_low; 4731 4732 return IV_SUCCESS; 4733 } 4734 4735 /** 4736 ******************************************************************************* 4737 * 4738 * @brief 4739 * Sets target bit rate 4740 * 4741 * @par Description: 4742 * Sets target bit rate 4743 * 4744 * @param[in] pv_api_ip 4745 * Pointer to input argument structure 4746 * 4747 * @param[out] pv_api_op 4748 * Pointer to output argument structure 4749 * 4750 * @param[out] ps_cfg 4751 * Pointer to config structure to be updated 4752 * 4753 * @returns error status 4754 * 4755 * @remarks none 4756 * 4757 ******************************************************************************* 4758 */ 4759 static IV_STATUS_T ih264e_set_bit_rate(void *pv_api_ip, 4760 void *pv_api_op, 4761 cfg_params_t *ps_cfg) 4762 { 4763 /* ctrl call I/O structures */ 4764 ih264e_ctl_set_bitrate_ip_t *ps_ip = pv_api_ip; 4765 ih264e_ctl_set_bitrate_op_t *ps_op = pv_api_op; 4766 4767 ps_op->s_ive_op.u4_error_code = 0; 4768 4769 ps_cfg->u4_target_bitrate = ps_ip->s_ive_ip.u4_target_bitrate; 4770 4771 ps_cfg->u4_timestamp_high = ps_ip->s_ive_ip.u4_timestamp_high; 4772 ps_cfg->u4_timestamp_low = ps_ip->s_ive_ip.u4_timestamp_low; 4773 4774 return IV_SUCCESS; 4775 } 4776 4777 /** 4778 ******************************************************************************* 4779 * 4780 * @brief 4781 * Sets frame type 4782 * 4783 * @par Description: 4784 * Sets frame type 4785 * 4786 * @param[in] pv_api_ip 4787 * Pointer to input argument structure 4788 * 4789 * @param[out] pv_api_op 4790 * Pointer to output argument structure 4791 * 4792 * @param[out] ps_cfg 4793 * Pointer to config structure to be updated 4794 * 4795 * @returns error status 4796 * 4797 * @remarks not a sticky tag 4798 * 4799 ******************************************************************************* 4800 */ 4801 static IV_STATUS_T ih264e_set_frame_type(void *pv_api_ip, 4802 void *pv_api_op, 4803 cfg_params_t *ps_cfg) 4804 { 4805 /* ctrl call I/O structures */ 4806 ih264e_ctl_set_frame_type_ip_t *ps_ip = pv_api_ip; 4807 ih264e_ctl_set_frame_type_op_t *ps_op = pv_api_op; 4808 4809 ps_op->s_ive_op.u4_error_code = 0; 4810 4811 ps_cfg->e_frame_type = ps_ip->s_ive_ip.e_frame_type; 4812 4813 ps_cfg->u4_timestamp_high = ps_ip->s_ive_ip.u4_timestamp_high; 4814 ps_cfg->u4_timestamp_low = ps_ip->s_ive_ip.u4_timestamp_low; 4815 4816 return IV_SUCCESS; 4817 } 4818 4819 /** 4820 ******************************************************************************* 4821 * 4822 * @brief 4823 * Sets quantization params 4824 * 4825 * @par Description: 4826 * Sets the max, min and default qp for I frame, P frame and B frame 4827 * 4828 * @param[in] pv_api_ip 4829 * Pointer to input argument structure 4830 * 4831 * @param[out] pv_api_op 4832 * Pointer to output argument structure 4833 * 4834 * @param[out] ps_cfg 4835 * Pointer to config structure to be updated 4836 * 4837 * @returns error status 4838 * 4839 * @remarks none 4840 * 4841 ******************************************************************************* 4842 */ 4843 static IV_STATUS_T ih264e_set_qp(void *pv_api_ip, 4844 void *pv_api_op, 4845 cfg_params_t *ps_cfg) 4846 { 4847 /* ctrl call I/O structures */ 4848 ih264e_ctl_set_qp_ip_t *ps_set_qp_ip = pv_api_ip; 4849 ih264e_ctl_set_qp_op_t *ps_set_qp_op = pv_api_op; 4850 4851 ps_set_qp_op->s_ive_op.u4_error_code = 0; 4852 4853 ps_cfg->u4_i_qp_max = ps_set_qp_ip->s_ive_ip.u4_i_qp_max; 4854 ps_cfg->u4_i_qp_min = ps_set_qp_ip->s_ive_ip.u4_i_qp_min; 4855 ps_cfg->u4_i_qp = ps_set_qp_ip->s_ive_ip.u4_i_qp; 4856 ps_cfg->u4_p_qp_max = ps_set_qp_ip->s_ive_ip.u4_p_qp_max; 4857 ps_cfg->u4_p_qp_min = ps_set_qp_ip->s_ive_ip.u4_p_qp_min; 4858 ps_cfg->u4_p_qp = ps_set_qp_ip->s_ive_ip.u4_p_qp; 4859 ps_cfg->u4_b_qp_max = ps_set_qp_ip->s_ive_ip.u4_b_qp_max; 4860 ps_cfg->u4_b_qp_min = ps_set_qp_ip->s_ive_ip.u4_b_qp_min; 4861 ps_cfg->u4_b_qp = ps_set_qp_ip->s_ive_ip.u4_b_qp; 4862 4863 ps_cfg->u4_timestamp_high = ps_set_qp_ip->s_ive_ip.u4_timestamp_high; 4864 ps_cfg->u4_timestamp_low = ps_set_qp_ip->s_ive_ip.u4_timestamp_low; 4865 4866 return IV_SUCCESS; 4867 } 4868 4869 /** 4870 ******************************************************************************* 4871 * 4872 * @brief 4873 * Sets encoding mode 4874 * 4875 * @par Description: 4876 * Sets encoding mode 4877 * 4878 * @param[in] pv_api_ip 4879 * Pointer to input argument structure 4880 * 4881 * @param[out] pv_api_op 4882 * Pointer to output argument structure 4883 * 4884 * @param[out] ps_cfg 4885 * Pointer to config structure to be updated 4886 * 4887 * @returns error status 4888 * 4889 * @remarks none 4890 * 4891 ******************************************************************************* 4892 */ 4893 static IV_STATUS_T ih264e_set_enc_mode(void *pv_api_ip, 4894 void *pv_api_op, 4895 cfg_params_t *ps_cfg) 4896 { 4897 /* ctrl call I/O structures */ 4898 ih264e_ctl_set_enc_mode_ip_t *ps_ip = pv_api_ip; 4899 ih264e_ctl_set_enc_mode_op_t *ps_op = pv_api_op; 4900 4901 ps_op->s_ive_op.u4_error_code = 0; 4902 4903 ps_cfg->e_enc_mode = ps_ip->s_ive_ip.e_enc_mode; 4904 4905 ps_cfg->u4_timestamp_high = ps_ip->s_ive_ip.u4_timestamp_high; 4906 ps_cfg->u4_timestamp_low = ps_ip->s_ive_ip.u4_timestamp_low; 4907 4908 return IV_SUCCESS; 4909 } 4910 4911 /** 4912 ******************************************************************************* 4913 * 4914 * @brief 4915 * Sets vbv parameters 4916 * 4917 * @par Description: 4918 * Sets vbv parameters 4919 * 4920 * @param[in] pv_api_ip 4921 * Pointer to input argument structure 4922 * 4923 * @param[out] pv_api_op 4924 * Pointer to output argument structure 4925 * 4926 * @param[out] ps_cfg 4927 * Pointer to config structure to be updated 4928 * 4929 * @returns error status 4930 * 4931 * @remarks none 4932 * 4933 ******************************************************************************* 4934 */ 4935 static IV_STATUS_T ih264e_set_vbv_params(void *pv_api_ip, 4936 void *pv_api_op, 4937 cfg_params_t *ps_cfg) 4938 { 4939 /* ctrl call I/O structures */ 4940 ih264e_ctl_set_vbv_params_ip_t *ps_ip = pv_api_ip; 4941 ih264e_ctl_set_vbv_params_op_t *ps_op = pv_api_op; 4942 4943 ps_op->s_ive_op.u4_error_code = 0; 4944 4945 ps_cfg->u4_vbv_buf_size = ps_ip->s_ive_ip.u4_vbv_buf_size; 4946 ps_cfg->u4_vbv_buffer_delay = ps_ip->s_ive_ip.u4_vbv_buffer_delay; 4947 4948 ps_cfg->u4_timestamp_high = ps_ip->s_ive_ip.u4_timestamp_high; 4949 ps_cfg->u4_timestamp_low = ps_ip->s_ive_ip.u4_timestamp_low; 4950 4951 return IV_SUCCESS; 4952 } 4953 4954 /** 4955 ******************************************************************************* 4956 * 4957 * @brief 4958 * Sets AIR parameters 4959 * 4960 * @par Description: 4961 * Sets AIR parameters 4962 * 4963 * @param[in] pv_api_ip 4964 * Pointer to input argument structure 4965 * 4966 * @param[out] pv_api_op 4967 * Pointer to output argument structure 4968 * 4969 * @param[out] ps_cfg 4970 * Pointer to config structure to be updated 4971 * 4972 * @returns error status 4973 * 4974 * @remarks none 4975 * 4976 ******************************************************************************* 4977 */ 4978 static IV_STATUS_T ih264_set_air_params(void *pv_api_ip, 4979 void *pv_api_op, 4980 cfg_params_t *ps_cfg) 4981 { 4982 /* ctrl call I/O structures */ 4983 ih264e_ctl_set_air_params_ip_t *ps_ip = pv_api_ip; 4984 ih264e_ctl_set_air_params_op_t *ps_op = pv_api_op; 4985 4986 ps_op->s_ive_op.u4_error_code = 0; 4987 4988 ps_cfg->e_air_mode = ps_ip->s_ive_ip.e_air_mode; 4989 ps_cfg->u4_air_refresh_period = ps_ip->s_ive_ip.u4_air_refresh_period; 4990 4991 ps_cfg->u4_timestamp_high = ps_ip->s_ive_ip.u4_timestamp_high; 4992 ps_cfg->u4_timestamp_low = ps_ip->s_ive_ip.u4_timestamp_low; 4993 4994 return IV_SUCCESS; 4995 } 4996 4997 /** 4998 ******************************************************************************* 4999 * 5000 * @brief 5001 * Sets motion estimation parameters 5002 * 5003 * @par Description: 5004 * Sets motion estimation parameters 5005 * 5006 * @param[in] pv_api_ip 5007 * Pointer to input argument structure 5008 * 5009 * @param[out] pv_api_op 5010 * Pointer to output argument structure 5011 * 5012 * @param[out] ps_cfg 5013 * Pointer to config structure to be updated 5014 * 5015 * @returns error status 5016 * 5017 * @remarks none 5018 * 5019 ******************************************************************************* 5020 */ 5021 static IV_STATUS_T ih264_set_me_params(void *pv_api_ip, 5022 void *pv_api_op, 5023 cfg_params_t *ps_cfg) 5024 { 5025 /* ctrl call I/O structures */ 5026 ih264e_ctl_set_me_params_ip_t *ps_ip = pv_api_ip; 5027 ih264e_ctl_set_me_params_op_t *ps_op = pv_api_op; 5028 5029 ps_op->s_ive_op.u4_error_code = 0; 5030 5031 ps_cfg->u4_enable_hpel = ps_ip->s_ive_ip.u4_enable_hpel; 5032 ps_cfg->u4_enable_qpel = ps_ip->s_ive_ip.u4_enable_qpel; 5033 ps_cfg->u4_enable_fast_sad = ps_ip->s_ive_ip.u4_enable_fast_sad; 5034 ps_cfg->u4_enable_alt_ref = ps_ip->s_ive_ip.u4_enable_alt_ref; 5035 ps_cfg->u4_srch_rng_x = ps_ip->s_ive_ip.u4_srch_rng_x; 5036 ps_cfg->u4_srch_rng_y = ps_ip->s_ive_ip.u4_srch_rng_y; 5037 ps_cfg->u4_me_speed_preset = ps_ip->s_ive_ip.u4_me_speed_preset; 5038 5039 ps_cfg->u4_timestamp_high = ps_ip->s_ive_ip.u4_timestamp_high; 5040 ps_cfg->u4_timestamp_low = ps_ip->s_ive_ip.u4_timestamp_low; 5041 5042 return IV_SUCCESS; 5043 } 5044 5045 /** 5046 ******************************************************************************* 5047 * 5048 * @brief 5049 * Sets Intra/Inter Prediction estimation parameters 5050 * 5051 * @par Description: 5052 * Sets Intra/Inter Prediction estimation parameters 5053 * 5054 * @param[in] pv_api_ip 5055 * Pointer to input argument structure 5056 * 5057 * @param[out] pv_api_op 5058 * Pointer to output argument structure 5059 * 5060 * @param[out] ps_cfg 5061 * Pointer to config structure to be updated 5062 * 5063 * @returns error status 5064 * 5065 * @remarks none 5066 * 5067 ******************************************************************************* 5068 */ 5069 static IV_STATUS_T ih264_set_ipe_params(void *pv_api_ip, 5070 void *pv_api_op, 5071 cfg_params_t *ps_cfg) 5072 { 5073 /* ctrl call I/O structures */ 5074 ih264e_ctl_set_ipe_params_ip_t *ps_ip = pv_api_ip; 5075 ih264e_ctl_set_ipe_params_op_t *ps_op = pv_api_op; 5076 5077 ps_op->s_ive_op.u4_error_code = 0; 5078 5079 ps_cfg->u4_enable_intra_4x4 = ps_ip->s_ive_ip.u4_enable_intra_4x4; 5080 ps_cfg->u4_enc_speed_preset = ps_ip->s_ive_ip.u4_enc_speed_preset; 5081 5082 ps_cfg->u4_constrained_intra_pred = ps_ip->s_ive_ip.u4_constrained_intra_pred; 5083 5084 ps_cfg->u4_timestamp_high = ps_ip->s_ive_ip.u4_timestamp_high; 5085 ps_cfg->u4_timestamp_low = ps_ip->s_ive_ip.u4_timestamp_low; 5086 5087 return IV_SUCCESS; 5088 } 5089 5090 /** 5091 ******************************************************************************* 5092 * 5093 * @brief 5094 * Sets GOP parameters 5095 * 5096 * @par Description: 5097 * Sets GOP parameters 5098 * 5099 * @param[in] pv_api_ip 5100 * Pointer to input argument structure 5101 * 5102 * @param[out] pv_api_op 5103 * Pointer to output argument structure 5104 * 5105 * @param[out] ps_cfg 5106 * Pointer to config structure to be updated 5107 * 5108 * @returns error status 5109 * 5110 * @remarks none 5111 * 5112 ******************************************************************************* 5113 */ 5114 static IV_STATUS_T ih264_set_gop_params(void *pv_api_ip, 5115 void *pv_api_op, 5116 cfg_params_t *ps_cfg) 5117 { 5118 /* ctrl call I/O structures */ 5119 ih264e_ctl_set_gop_params_ip_t *ps_ip = pv_api_ip; 5120 ih264e_ctl_set_gop_params_op_t *ps_op = pv_api_op; 5121 5122 ps_op->s_ive_op.u4_error_code = 0; 5123 5124 ps_cfg->u4_i_frm_interval = ps_ip->s_ive_ip.u4_i_frm_interval; 5125 ps_cfg->u4_idr_frm_interval = ps_ip->s_ive_ip.u4_idr_frm_interval; 5126 5127 ps_cfg->u4_timestamp_high = ps_ip->s_ive_ip.u4_timestamp_high; 5128 ps_cfg->u4_timestamp_low = ps_ip->s_ive_ip.u4_timestamp_low; 5129 5130 return IV_SUCCESS; 5131 } 5132 5133 /** 5134 ******************************************************************************* 5135 * 5136 * @brief 5137 * Sets profile parameters 5138 * 5139 * @par Description: 5140 * Sets profile parameters 5141 * 5142 * @param[in] pv_api_ip 5143 * Pointer to input argument structure 5144 * 5145 * @param[out] pv_api_op 5146 * Pointer to output argument structure 5147 * 5148 * @param[out] ps_cfg 5149 * Pointer to config structure to be updated 5150 * 5151 * @returns error status 5152 * 5153 * @remarks none 5154 * 5155 ******************************************************************************* 5156 */ 5157 static IV_STATUS_T ih264_set_profile_params(void *pv_api_ip, 5158 void *pv_api_op, 5159 cfg_params_t *ps_cfg) 5160 { 5161 /* ctrl call I/O structures */ 5162 ih264e_ctl_set_profile_params_ip_t *ps_ip = pv_api_ip; 5163 ih264e_ctl_set_profile_params_op_t *ps_op = pv_api_op; 5164 5165 ps_op->s_ive_op.u4_error_code = 0; 5166 5167 ps_cfg->e_profile = ps_ip->s_ive_ip.e_profile; 5168 5169 ps_cfg->u4_entropy_coding_mode = ps_ip->s_ive_ip.u4_entropy_coding_mode; 5170 5171 ps_cfg->u4_timestamp_high = ps_ip->s_ive_ip.u4_timestamp_high; 5172 ps_cfg->u4_timestamp_low = ps_ip->s_ive_ip.u4_timestamp_low; 5173 5174 return IV_SUCCESS; 5175 } 5176 5177 /** 5178 ******************************************************************************* 5179 * 5180 * @brief 5181 * Sets disable deblock level 5182 * 5183 * @par Description: 5184 * Sets disable deblock level. Level 0 means no disabling and level 4 means 5185 * disable completely. 1, 2, 3 are intermediate levels that control amount 5186 * of deblocking done. 5187 * 5188 * @param[in] ps_codec_obj 5189 * Pointer to codec object at API level 5190 * 5191 * @param[in] pv_api_ip 5192 * Pointer to input argument structure 5193 * 5194 * @param[out] pv_api_op 5195 * Pointer to output argument structure 5196 * 5197 * @returns error status 5198 * 5199 * @remarks none 5200 * 5201 ******************************************************************************* 5202 */ 5203 static WORD32 ih264_set_deblock_params(void *pv_api_ip, 5204 void *pv_api_op, 5205 cfg_params_t *ps_cfg) 5206 { 5207 /* ctrl call I/O structures */ 5208 ih264e_ctl_set_deblock_params_ip_t *ps_ip = pv_api_ip; 5209 ih264e_ctl_set_deblock_params_op_t *ps_op = pv_api_op; 5210 5211 ps_op->s_ive_op.u4_error_code = 0; 5212 5213 ps_cfg->u4_disable_deblock_level = ps_ip->s_ive_ip.u4_disable_deblock_level; 5214 5215 ps_cfg->u4_timestamp_high = ps_ip->s_ive_ip.u4_timestamp_high; 5216 ps_cfg->u4_timestamp_low = ps_ip->s_ive_ip.u4_timestamp_low; 5217 5218 return IV_SUCCESS; 5219 } 5220 5221 /** 5222 ******************************************************************************* 5223 * 5224 * @brief 5225 * Sets number of cores 5226 * 5227 * @par Description: 5228 * Sets number of cores 5229 * 5230 * @param[in] ps_codec_obj 5231 * Pointer to codec object at API level 5232 * 5233 * @param[in] pv_api_ip 5234 * Pointer to input argument structure 5235 * 5236 * @param[out] pv_api_op 5237 * Pointer to output argument structure 5238 * 5239 * @returns error status 5240 * 5241 * @remarks The number of encoder threads is limited to MAX_PROCESS_THREADS 5242 * 5243 ******************************************************************************* 5244 */ 5245 static WORD32 ih264e_set_num_cores(void *pv_api_ip, 5246 void *pv_api_op, 5247 cfg_params_t *ps_cfg) 5248 { 5249 /* ctrl call I/O structures */ 5250 ih264e_ctl_set_num_cores_ip_t *ps_ip = pv_api_ip; 5251 ih264e_ctl_set_num_cores_op_t *ps_op = pv_api_op; 5252 5253 ps_op->s_ive_op.u4_error_code = 0; 5254 5255 ps_cfg->u4_num_cores = MIN(ps_ip->s_ive_ip.u4_num_cores, MAX_PROCESS_THREADS); 5256 5257 ps_cfg->u4_timestamp_high = ps_ip->s_ive_ip.u4_timestamp_high; 5258 ps_cfg->u4_timestamp_low = ps_ip->s_ive_ip.u4_timestamp_low; 5259 5260 return IV_SUCCESS; 5261 } 5262 5263 /** 5264 ******************************************************************************* 5265 * 5266 * @brief 5267 * Resets encoder state 5268 * 5269 * @par Description: 5270 * Resets encoder state by calling ih264e_init() 5271 * 5272 * @param[in] ps_codec_obj 5273 * Pointer to codec object at API level 5274 * 5275 * @param[in] pv_api_ip 5276 * Pointer to input argument structure 5277 * 5278 * @param[out] pv_api_op 5279 * Pointer to output argument structure 5280 * 5281 * @returns error status 5282 * 5283 * @remarks none 5284 * 5285 ******************************************************************************* 5286 */ 5287 static WORD32 ih264e_reset(iv_obj_t *ps_codec_obj, 5288 void *pv_api_ip, 5289 void *pv_api_op) 5290 { 5291 /* codec ctxt */ 5292 codec_t * ps_codec = (codec_t *) (ps_codec_obj->pv_codec_handle); 5293 5294 /* ctrl call I/O structures */ 5295 ih264e_ctl_reset_op_t *ps_op = pv_api_op; 5296 5297 UNUSED(pv_api_ip); 5298 5299 ps_op->s_ive_op.u4_error_code = 0; 5300 5301 if (ps_codec != NULL) 5302 { 5303 ih264e_init(ps_codec); 5304 } 5305 else 5306 { 5307 ps_op->s_ive_op.u4_error_code = IH264E_INIT_NOT_DONE; 5308 } 5309 5310 return IV_SUCCESS; 5311 } 5312 5313 /** 5314 ******************************************************************************* 5315 * 5316 * @brief 5317 * Codec control call 5318 * 5319 * @par Description: 5320 * Codec control call which in turn calls appropriate calls based on sub-command 5321 * 5322 * @param[in] ps_codec_obj 5323 * Pointer to codec object at API level 5324 * 5325 * @param[in] pv_api_ip 5326 * Pointer to input argument structure 5327 * 5328 * @param[out] pv_api_op 5329 * Pointer to output argument structure 5330 * 5331 * @returns error status 5332 * 5333 * @remarks none 5334 * 5335 ******************************************************************************* 5336 */ 5337 static WORD32 ih264e_ctl(iv_obj_t *ps_codec_obj, 5338 void *pv_api_ip, 5339 void *pv_api_op) 5340 { 5341 /* codec ctxt */ 5342 codec_t *ps_codec = (codec_t *) ps_codec_obj->pv_codec_handle; 5343 5344 /* ctrl call I/O structures */ 5345 ih264e_ctl_setdefault_ip_t *ps_ctl_ip = pv_api_ip; 5346 ih264e_ctl_setdefault_op_t *ps_ctl_op = pv_api_op; 5347 5348 /* ctrl call sub cmd */ 5349 IVE_CONTROL_API_COMMAND_TYPE_T sub_cmd = ps_ctl_ip->s_ive_ip.e_sub_cmd; 5350 5351 /* error status */ 5352 IV_STATUS_T ret = IV_SUCCESS; 5353 5354 /* temp var */ 5355 WORD32 i; 5356 cfg_params_t *ps_cfg = NULL; 5357 5358 /* control call is for configuring encoding params, this is not to be called 5359 * before a successful init call */ 5360 if (ps_codec->i4_init_done != 1) 5361 { 5362 ps_ctl_op->s_ive_op.u4_error_code |= 1 << IVE_FATALERROR; 5363 ps_ctl_op->s_ive_op.u4_error_code |= IH264E_INIT_NOT_DONE; 5364 return IV_FAIL; 5365 } 5366 5367 /* make it thread safe */ 5368 ithread_mutex_lock(ps_codec->pv_ctl_mutex); 5369 5370 /* find a free config param set to hold current parameters */ 5371 for (i = 0; i < MAX_ACTIVE_CONFIG_PARAMS; i++) 5372 { 5373 if (0 == ps_codec->as_cfg[i].u4_is_valid) 5374 { 5375 ps_cfg = &ps_codec->as_cfg[i]; 5376 break; 5377 } 5378 } 5379 5380 /* If all are invalid, then start overwriting from the head config params */ 5381 if (NULL == ps_cfg) 5382 { 5383 ps_cfg = &ps_codec->as_cfg[0]; 5384 } 5385 5386 ps_cfg->u4_is_valid = 1; 5387 5388 ps_cfg->e_cmd = sub_cmd; 5389 5390 switch (sub_cmd) 5391 { 5392 case IVE_CMD_CTL_SET_DIMENSIONS: 5393 ret = ih264e_set_dimensions(pv_api_ip, pv_api_op, ps_cfg); 5394 break; 5395 5396 case IVE_CMD_CTL_SET_FRAMERATE: 5397 ret = ih264e_set_frame_rate(pv_api_ip, pv_api_op, ps_cfg); 5398 break; 5399 5400 case IVE_CMD_CTL_SET_BITRATE: 5401 ret = ih264e_set_bit_rate(pv_api_ip, pv_api_op, ps_cfg); 5402 break; 5403 5404 case IVE_CMD_CTL_SET_FRAMETYPE: 5405 ret = ih264e_set_frame_type(pv_api_ip, pv_api_op, ps_cfg); 5406 break; 5407 5408 case IVE_CMD_CTL_SET_QP: 5409 ret = ih264e_set_qp(pv_api_ip, pv_api_op, ps_cfg); 5410 break; 5411 5412 case IVE_CMD_CTL_SET_ENC_MODE: 5413 ret = ih264e_set_enc_mode(pv_api_ip, pv_api_op, ps_cfg); 5414 break; 5415 5416 case IVE_CMD_CTL_SET_VBV_PARAMS: 5417 ret = ih264e_set_vbv_params(pv_api_ip, pv_api_op, ps_cfg); 5418 break; 5419 5420 case IVE_CMD_CTL_SET_AIR_PARAMS: 5421 ret = ih264_set_air_params(pv_api_ip, pv_api_op, ps_cfg); 5422 break; 5423 5424 case IVE_CMD_CTL_SET_ME_PARAMS: 5425 ret = ih264_set_me_params(pv_api_ip, pv_api_op, ps_cfg); 5426 break; 5427 5428 case IVE_CMD_CTL_SET_IPE_PARAMS: 5429 ret = ih264_set_ipe_params(pv_api_ip, pv_api_op, ps_cfg); 5430 break; 5431 5432 case IVE_CMD_CTL_SET_GOP_PARAMS: 5433 ret = ih264_set_gop_params(pv_api_ip, pv_api_op, ps_cfg); 5434 break; 5435 5436 case IVE_CMD_CTL_SET_PROFILE_PARAMS: 5437 ret = ih264_set_profile_params(pv_api_ip, pv_api_op, ps_cfg); 5438 break; 5439 5440 case IVE_CMD_CTL_SET_DEBLOCK_PARAMS: 5441 ret = ih264_set_deblock_params(pv_api_ip, pv_api_op, ps_cfg); 5442 break; 5443 5444 case IVE_CMD_CTL_RESET: 5445 5446 /* invalidate config param struct as it is being served right away */ 5447 ps_codec->as_cfg[i].u4_is_valid = 0; 5448 5449 ret = ih264e_reset(ps_codec_obj, pv_api_ip, pv_api_op); 5450 break; 5451 5452 case IVE_CMD_CTL_SETDEFAULT: 5453 { 5454 /* ctrl call I/O structures */ 5455 ih264e_ctl_setdefault_op_t *ps_op = pv_api_op; 5456 5457 /* invalidate config param struct as it is being served right away */ 5458 ps_codec->as_cfg[i].u4_is_valid = 0; 5459 5460 /* error status */ 5461 ret = ih264e_set_default_params(ps_cfg); 5462 5463 ps_op->s_ive_op.u4_error_code = ret; 5464 5465 break; 5466 } 5467 5468 case IVE_CMD_CTL_FLUSH: 5469 5470 /* invalidate config param struct as it is being served right away */ 5471 ps_codec->as_cfg[i].u4_is_valid = 0; 5472 5473 ret = ih264e_set_flush_mode(ps_codec_obj, pv_api_ip, pv_api_op); 5474 break; 5475 5476 case IVE_CMD_CTL_GETBUFINFO: 5477 5478 /* invalidate config param struct as it is being served right away */ 5479 ps_codec->as_cfg[i].u4_is_valid = 0; 5480 5481 ret = ih264e_get_buf_info(ps_codec_obj, pv_api_ip, pv_api_op); 5482 break; 5483 5484 case IVE_CMD_CTL_GETVERSION: 5485 { 5486 /* ctrl call I/O structures */ 5487 ih264e_ctl_getversioninfo_ip_t *ps_ip = pv_api_ip; 5488 ih264e_ctl_getversioninfo_op_t *ps_op = pv_api_op; 5489 5490 /* invalidate config param struct as it is being served right away */ 5491 ps_codec->as_cfg[i].u4_is_valid = 0; 5492 5493 /* error status */ 5494 ps_op->s_ive_op.u4_error_code = IV_SUCCESS; 5495 5496 if (ps_ip->s_ive_ip.u4_version_bufsize <= 0) 5497 { 5498 ps_op->s_ive_op.u4_error_code = 5499 IH264E_CXA_VERS_BUF_INSUFFICIENT; 5500 ret = IV_FAIL; 5501 } 5502 else 5503 { 5504 ret = ih264e_get_version((CHAR *) ps_ip->s_ive_ip.pu1_version, 5505 ps_ip->s_ive_ip.u4_version_bufsize); 5506 5507 if (ret != IV_SUCCESS) 5508 { 5509 ps_op->s_ive_op.u4_error_code = 5510 IH264E_CXA_VERS_BUF_INSUFFICIENT; 5511 ret = IV_FAIL; 5512 } 5513 } 5514 break; 5515 } 5516 5517 case IVE_CMD_CTL_SET_NUM_CORES: 5518 ret = ih264e_set_num_cores(pv_api_ip, pv_api_op, ps_cfg); 5519 break; 5520 5521 default: 5522 /* invalidate config param struct as it is being served right away */ 5523 ps_codec->as_cfg[i].u4_is_valid = 0; 5524 5525 DEBUG("Warning !! unrecognized control api command \n"); 5526 break; 5527 } 5528 5529 ithread_mutex_unlock(ps_codec->pv_ctl_mutex); 5530 5531 return ret; 5532 } 5533 5534 /** 5535 ******************************************************************************* 5536 * 5537 * @brief 5538 * Codec entry point function. All the function calls to the codec are done 5539 * using this function with different values specified in command 5540 * 5541 * @par Description: 5542 * Arguments are tested for validity and then based on the command 5543 * appropriate function is called 5544 * 5545 * @param[in] ps_handle 5546 * API level handle for codec 5547 * 5548 * @param[in] pv_api_ip 5549 * Input argument structure 5550 * 5551 * @param[out] pv_api_op 5552 * Output argument structure 5553 * 5554 * @returns error_status 5555 * 5556 * @remarks 5557 * 5558 ******************************************************************************* 5559 */ 5560 IV_STATUS_T ih264e_api_function(iv_obj_t *ps_handle, 5561 void *pv_api_ip, 5562 void *pv_api_op) 5563 { 5564 /* api command */ 5565 WORD32 command = IV_CMD_NA; 5566 5567 /* error status */ 5568 IV_STATUS_T e_status; 5569 WORD32 ret; 5570 5571 /* tmp var */ 5572 WORD32 *pu4_ptr_cmd = (WORD32 *) pv_api_ip; 5573 5574 /* validate input / output structures */ 5575 e_status = api_check_struct_sanity(ps_handle, pv_api_ip, pv_api_op); 5576 5577 if (e_status != IV_SUCCESS) 5578 { 5579 DEBUG("error code = %d\n", *((UWORD32 *)pv_api_op + 1)); 5580 return IV_FAIL; 5581 } 5582 5583 pu4_ptr_cmd++; 5584 5585 command = *pu4_ptr_cmd; 5586 5587 switch (command) 5588 { 5589 case IV_CMD_GET_NUM_MEM_REC: 5590 ret = ih264e_get_num_rec(pv_api_ip, pv_api_op); 5591 break; 5592 5593 case IV_CMD_FILL_NUM_MEM_REC: 5594 ret = ih264e_fill_num_mem_rec(pv_api_ip, pv_api_op); 5595 break; 5596 5597 case IV_CMD_INIT: 5598 ret = ih264e_init_mem_rec(ps_handle, pv_api_ip, pv_api_op); 5599 break; 5600 5601 case IV_CMD_RETRIEVE_MEMREC: 5602 ret = ih264e_retrieve_memrec(ps_handle, pv_api_ip, pv_api_op); 5603 break; 5604 5605 case IVE_CMD_VIDEO_CTL: 5606 ret = ih264e_ctl(ps_handle, pv_api_ip, pv_api_op); 5607 break; 5608 5609 case IVE_CMD_VIDEO_ENCODE: 5610 ret = ih264e_encode(ps_handle, pv_api_ip, pv_api_op); 5611 break; 5612 5613 default: 5614 ret = IV_FAIL; 5615 break; 5616 } 5617 5618 return (IV_STATUS_T) ret; 5619 } 5620