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 /* File Includes */ 23 /*****************************************************************************/ 24 25 /* System include files */ 26 #include <stdio.h> 27 #include <stdlib.h> 28 #include <stddef.h> 29 #include <assert.h> 30 #include <string.h> 31 32 #ifndef IOS 33 #include <malloc.h> 34 #endif 35 36 #ifdef WINDOWS_TIMER 37 #include "windows.h" 38 #else 39 #include <sys/time.h> 40 #endif 41 /* User include files */ 42 #include "ih264_typedefs.h" 43 #include "iv2.h" 44 #include "ive2.h" 45 #include "ih264e.h" 46 #include "app.h" 47 #include "psnr.h" 48 49 /* Function declarations */ 50 #ifndef MD5_DISABLE 51 void calc_md5_cksum(UWORD8 *pu1_inbuf,UWORD32 u4_stride,UWORD32 u4_width,UWORD32 u4_height,UWORD8 *pu1_cksum_p ); 52 #else 53 #define calc_md5_cksum(a, b, c, d, e) 54 #endif 55 56 /*****************************************************************************/ 57 /* Enums */ 58 /*****************************************************************************/ 59 typedef enum 60 { 61 INVALID, 62 HELP, 63 INPUT_FILE, 64 OUTPUT_FILE, 65 RECON_FILE, 66 RECON_ENABLE, 67 CHKSUM_ENABLE, 68 CHKSUM_FILE, 69 INPUT_CHROMA_FORMAT, 70 RECON_CHROMA_FORMAT, 71 MAX_WD, 72 MAX_HT, 73 WD, 74 HT, 75 MAX_LEVEL, 76 ENC_SPEED, 77 ME_SPEED, 78 START_FRM, 79 NUM_FRMS, 80 MAX_FRAMERATE, 81 SRC_FRAMERATE, 82 TGT_FRAMERATE, 83 RC, 84 MAX_BITRATE, 85 BITRATE, 86 I_QP, 87 P_QP, 88 B_QP, 89 I_QP_MAX, 90 P_QP_MAX, 91 B_QP_MAX, 92 I_QP_MIN, 93 P_QP_MIN, 94 B_QP_MIN, 95 ENTROPY, 96 AIR, 97 AIR_REFRESH_PERIOD, 98 ARCH, 99 SOC, 100 NUMCORES, 101 PRE_ENC_ME, 102 PRE_ENC_IPE, 103 HPEL, 104 QPEL, 105 SRCH_RNG_X, 106 SRCH_RNG_Y, 107 I_INTERVAL, 108 IDR_INTERVAL, 109 CONSTRAINED_INTRA_PRED, 110 B_FRMS, 111 NUM_B_FRMS, 112 DISABLE_DBLK, 113 PROFILE, 114 FAST_SAD, 115 ALT_REF, 116 DISABLE_DEBLOCK_LEVEL, 117 PSNR, 118 SLICE_MODE, 119 SLICE_PARAM, 120 CONFIG, 121 LOOPBACK, 122 VBV_DELAY, 123 VBV_SIZE, 124 INTRA_4x4_ENABLE, 125 MB_INFO_FILE, 126 MB_INFO_TYPE, 127 PIC_INFO_FILE, 128 PIC_INFO_TYPE, 129 } ARGUMENT_T; 130 131 typedef struct 132 { 133 CHAR argument_shortname[8]; 134 CHAR argument_name[128]; 135 ARGUMENT_T argument; 136 CHAR description[512]; 137 } argument_t; 138 139 static const argument_t argument_mapping[] = 140 { 141 { "--", "--help", HELP, "Print this help\n" }, 142 { "-i", "--input", INPUT_FILE, "Input file\n" }, 143 { "-o", "--output", OUTPUT_FILE, "Output file\n" }, 144 { "--", "--recon_enable", RECON_ENABLE, "Recon enable flag\n" }, 145 { "-r", "--recon", RECON_FILE, "Recon file \n" }, 146 { "--", "--input_chroma_format", INPUT_CHROMA_FORMAT, 147 "Input Chroma format Supported values YUV_420P, YUV_420SP_UV, YUV_420SP_VU\n" }, 148 { "--", "--recon_chroma_format", RECON_CHROMA_FORMAT, 149 "Recon Chroma format Supported values YUV_420P, YUV_420SP_UV, YUV_420SP_VU\n" }, 150 { "-w", "--width", WD, "Width of input file\n" }, 151 { "-h", "--height", HT, "Height file\n" }, 152 { "--", "--start_frame", START_FRM, "Starting frame number\n" }, 153 { "-f", "--num_frames", NUM_FRMS, "Number of frames to be encoded\n" }, 154 { "--", "--rc", RC, "Rate control mode 0: Constant Qp, 1: Storage, 2: CBR non low delay, 3: CBR low delay \n" }, 155 { "--", "--max_framerate", MAX_FRAMERATE, "Maximum frame rate \n" }, 156 { "--", "--tgt_framerate", TGT_FRAMERATE, "Target frame rate \n" }, 157 { "--", "--src_framerate", SRC_FRAMERATE, "Source frame rate \n" }, 158 { "--", "--i_interval", I_INTERVAL, "Intra frame interval \n" }, 159 { "--", "--idr_interval", IDR_INTERVAL, "IDR frame interval \n" }, 160 { "--", "--constrained_intrapred", CONSTRAINED_INTRA_PRED, "Constrained IntraPrediction Flag \n" }, 161 { "--", "--bframes", NUM_B_FRMS, "Maximum number of consecutive B frames \n" }, 162 { "--", "--speed", ENC_SPEED, "Encoder speed preset 0 (slowest) and 100 (fastest)\n" }, 163 { "--", "--me_speed", ME_SPEED, "Encoder speed preset 0 (slowest) and 100 (fastest)\n" }, 164 { "--", "--fast_sad", FAST_SAD, " Flag for faster sad execution\n" }, 165 { "--", "--alt_ref", ALT_REF , "Flag to enable alternate refernce frames"}, 166 { "--", "--hpel", HPEL, "Flag to enable/disable Quarter pel estimation \n" }, 167 { "--", "--qpel", QPEL, "Flag to enable/disable Quarter pel estimation \n" }, 168 { "--", "--disable_deblock_level", DISABLE_DEBLOCK_LEVEL, 169 "Disable deblock level - 0 : Enables deblock completely, 1: enables for I and 8th frame , 2: Enables for I only, 3 : disables completely\n" }, 170 { "--", "--search_range_x", SRCH_RNG_X, "Search range for X \n" }, 171 { "--", "--search_range_y", SRCH_RNG_Y, "Search range for Y \n" }, 172 { "--", "--psnr", PSNR, "Enable PSNR computation (Disable while benchmarking performance) \n" }, 173 { "--", "--pre_enc_me", PRE_ENC_ME, "Flag to enable/disable Pre Enc Motion Estimation\n" }, 174 { "--", "--pre_enc_ipe", PRE_ENC_IPE, "Flag to enable/disable Pre Enc Intra prediction Estimation\n" }, 175 { "-n", "--num_cores", NUMCORES, "Number of cores to be used\n" }, 176 { "--", "--adaptive_intra_refresh", AIR ,"Adaptive Intra Refresh enable/disable\n"}, 177 { "--", "--air_refresh_period", AIR_REFRESH_PERIOD,"adaptive intra refresh period\n"}, 178 { "--", "--slice", SLICE_MODE, "Slice mode- 0 :No slice, 1: Bytes per slice, 2: MB/CTB per slice \n" }, 179 { "--", "--slice_param", SLICE_PARAM, "Slice param value based on slice mode. Slice mode of 1 implies number of bytes per slice, 2 implies number of MBs/CTBs, for 0 value is neglected \n" }, 180 { "--", "--max_wd", MAX_WD, "Maximum width (Default: 1920) \n" }, 181 { "--", "--max_ht", MAX_HT, "Maximum height (Default: 1088)\n" }, 182 { "--", "--max_level", MAX_LEVEL, "Maximum Level (Default: 50)\n" }, 183 { "--", "--arch", ARCH, "Set Architecture. Supported values ARM_NONEON, ARM_A9Q, ARM_A7, ARM_A5, ARM_NEONINTR, X86_GENERIC, X86_SSSE3, X86_SSE4 \n" }, 184 { "--", "--soc", SOC, "Set SOC. Supported values GENERIC, HISI_37X \n" }, 185 { "--", "--chksum", CHKSUM_FILE, "Save Check sum file for recon data\n" }, 186 { "--", "--chksum_enable", CHKSUM_ENABLE, "Recon MD5 Checksum file\n"}, 187 { "-c", "--config", CONFIG, "config file (Default: enc.cfg)\n" }, 188 { "--", "--loopback", LOOPBACK, "Enable encoding in a loop\n" }, 189 { "--", "--profile", PROFILE, "Profile mode: Supported values BASE, MAIN, HIGH\n" }, 190 { "--", "--max_bitrate", MAX_BITRATE, "Max bitrate\n"}, 191 { "--", "--bitrate", BITRATE, "Target bitrate\n"}, 192 { "--", "--qp_i", I_QP, "QP for I frames\n"}, 193 { "--", "--qp_p", P_QP, "QP for P frames\n"}, 194 { "--", "--qp_b", B_QP, "QP for B frames\n"}, 195 { "--", "--qp_i_max", I_QP_MAX, "Max QP for I frames\n"}, 196 { "--", "--qp_p_max", P_QP_MAX, "Max QP for P frames\n"}, 197 { "--", "--qp_b_max", B_QP_MAX, "Max QP for B frames\n"}, 198 { "--", "--qp_i_min", I_QP_MIN, "Min QP for I frames\n"}, 199 { "--", "--qp_p_min", P_QP_MIN, "Min QP for P frames\n"}, 200 { "--", "--qp_b_min", B_QP_MIN, "Min QP for B frames\n"}, 201 { "--", "--entropy", ENTROPY, "Entropy coding mode(0: CAVLC or 1: CABAC)\n"}, 202 { "--", "--vbv_delay", VBV_DELAY, "VBV buffer delay\n"}, 203 { "--", "--vbv_size", VBV_SIZE, "VBV buffer size\n"}, 204 { "-i4", "--intra_4x4_enable", INTRA_4x4_ENABLE, "Intra 4x4 enable \n" }, 205 { "--", "--mb_info_file", MB_INFO_FILE, "MB info file\n"}, 206 { "--", "--mb_info_type", MB_INFO_TYPE, "MB info type\n"}, 207 { "--", "--pic_info_file", PIC_INFO_FILE, "Pic info file\n"}, 208 { "--", "--pic_info_type", PIC_INFO_TYPE, "Pic info type\n"}, 209 }; 210 211 212 213 /*****************************************************************************/ 214 /* Function Declarations */ 215 /*****************************************************************************/ 216 217 218 219 /*****************************************************************************/ 220 /* Function Definitions */ 221 /*****************************************************************************/ 222 223 224 #if(defined X86) && (defined X86_MINGW) 225 /*****************************************************************************/ 226 /* Function to print library calls */ 227 /*****************************************************************************/ 228 /*****************************************************************************/ 229 /* */ 230 /* Function Name : memalign */ 231 /* */ 232 /* Description : Returns malloc data. Ideally should return aligned memory*/ 233 /* support alignment will be added later */ 234 /* */ 235 /* Inputs : alignment */ 236 /* size */ 237 /* Globals : */ 238 /* Processing : */ 239 /* */ 240 /* Outputs : */ 241 /* Returns : */ 242 /* */ 243 /* Issues : */ 244 /* */ 245 /* Revision History: */ 246 /* */ 247 /* DD MM YYYY Author(s) Changes */ 248 /* 07 09 2012 100189 Initial Version */ 249 /* */ 250 /*****************************************************************************/ 251 252 void * ih264a_aligned_malloc(WORD32 alignment, WORD32 size) 253 { 254 return _aligned_malloc(size, alignment); 255 } 256 257 void ih264a_aligned_free(void *pv_buf) 258 { 259 _aligned_free(pv_buf); 260 return; 261 } 262 263 #elif IOS 264 265 void * ih264a_aligned_malloc(WORD32 alignment, WORD32 size) 266 { 267 return malloc(size); 268 } 269 270 void ih264a_aligned_free(void *pv_buf) 271 { 272 free(pv_buf); 273 return; 274 } 275 276 #else 277 278 void * ih264a_aligned_malloc(WORD32 alignment, WORD32 size) 279 { 280 return memalign(alignment, size); 281 } 282 283 void ih264a_aligned_free(void *pv_buf) 284 { 285 free(pv_buf); 286 return; 287 } 288 289 #endif 290 291 /*****************************************************************************/ 292 /* */ 293 /* Function Name : codec_exit */ 294 /* */ 295 /* Description : handles unrecoverable errors */ 296 /* Inputs : Error message */ 297 /* Globals : None */ 298 /* Processing : Prints error message to console and exits. */ 299 /* Outputs : Error message to the console */ 300 /* Returns : None */ 301 /* */ 302 /* Issues : */ 303 /* */ 304 /* Revision History: */ 305 /* */ 306 /* DD MM YYYY Author(s) Changes (Describe the changes made) */ 307 /* 07 06 2006 Sankar Creation */ 308 /* */ 309 /*****************************************************************************/ 310 void codec_exit(CHAR *pc_err_message) 311 { 312 printf("%s\n", pc_err_message); 313 exit(-1); 314 } 315 316 /*****************************************************************************/ 317 /* */ 318 /* Function Name : codec_exit */ 319 /* */ 320 /* Description : handles unrecoverable errors */ 321 /* Inputs : Error message */ 322 /* Globals : None */ 323 /* Processing : Prints error message to console and exits. */ 324 /* Outputs : Error mesage to the console */ 325 /* Returns : None */ 326 /* */ 327 /* Issues : */ 328 /* */ 329 /* Revision History: */ 330 /* */ 331 /* DD MM YYYY Author(s) Changes (Describe the changes made) */ 332 /* 07 06 2006 Sankar Creation */ 333 /* */ 334 /*****************************************************************************/ 335 IV_COLOR_FORMAT_T get_chroma_fmt(CHAR *value) 336 { 337 IV_COLOR_FORMAT_T e_chroma_format; 338 if((strcmp(value, "YUV_420P")) == 0) 339 e_chroma_format = IV_YUV_420P; 340 else if((strcmp(value, "YUV_422ILE")) == 0) 341 e_chroma_format = IV_YUV_422ILE; 342 else if((strcmp(value, "RGB_565")) == 0) 343 e_chroma_format = IV_RGB_565; 344 else if((strcmp(value, "RGBA_8888")) == 0) 345 e_chroma_format = IV_RGBA_8888; 346 else if((strcmp(value, "YUV_420SP_UV")) == 0) 347 e_chroma_format = IV_YUV_420SP_UV; 348 else if((strcmp(value, "YUV_420SP_VU")) == 0) 349 e_chroma_format = IV_YUV_420SP_VU; 350 else 351 { 352 printf("\nInvalid colour format setting it to IV_YUV_420P\n"); 353 e_chroma_format = IV_YUV_420P; 354 } 355 return e_chroma_format; 356 } 357 358 /*****************************************************************************/ 359 /* */ 360 /* Function Name : codec_exit */ 361 /* */ 362 /* Description : handles unrecoverable errors */ 363 /* Inputs : Error message */ 364 /* Globals : None */ 365 /* Processing : Prints error message to console and exits. */ 366 /* Outputs : Error mesage to the console */ 367 /* Returns : None */ 368 /* */ 369 /* Issues : */ 370 /* */ 371 /* Revision History: */ 372 /* */ 373 /* DD MM YYYY Author(s) Changes (Describe the changes made) */ 374 /* 07 06 2006 Sankar Creation */ 375 /* */ 376 /*****************************************************************************/ 377 IVE_SPEED_CONFIG get_speed_preset(CHAR *value) 378 { 379 IVE_SPEED_CONFIG e_enc_speed_preset; 380 if((strcmp(value, "CONFIG")) == 0) 381 e_enc_speed_preset = IVE_CONFIG; 382 else if((strcmp(value, "SLOWEST")) == 0) 383 e_enc_speed_preset = IVE_SLOWEST; 384 else if((strcmp(value, "NORMAL")) == 0) 385 e_enc_speed_preset = IVE_NORMAL; 386 else if((strcmp(value, "FAST")) == 0) 387 e_enc_speed_preset = IVE_FAST; 388 else if((strcmp(value, "HIGH_SPEED")) == 0) 389 e_enc_speed_preset = IVE_HIGH_SPEED; 390 else if((strcmp(value, "FASTEST")) == 0) 391 e_enc_speed_preset = IVE_FASTEST; 392 else 393 { 394 printf("\nInvalid speed preset, setting it to IVE_FASTEST\n"); 395 e_enc_speed_preset = IVE_FASTEST; 396 } 397 return e_enc_speed_preset; 398 } 399 400 /*****************************************************************************/ 401 /* */ 402 /* Function Name : print_usage */ 403 /* */ 404 /* Description : Prints argument format */ 405 /* */ 406 /* */ 407 /* Inputs : */ 408 /* Globals : */ 409 /* Processing : Prints argument format */ 410 /* */ 411 /* Outputs : */ 412 /* Returns : */ 413 /* */ 414 /* Issues : */ 415 /* */ 416 /* Revision History: */ 417 /* */ 418 /* DD MM YYYY Author(s) Changes */ 419 /* 07 09 2012 100189 Initial Version */ 420 /* */ 421 /*****************************************************************************/ 422 423 void print_usage(void) 424 { 425 WORD32 i = 0; 426 WORD32 num_entries = sizeof(argument_mapping) / sizeof(argument_t); 427 printf("\nUsage:\n"); 428 while(i < num_entries) 429 { 430 printf("%-32s\t %s", argument_mapping[i].argument_name, 431 argument_mapping[i].description); 432 i++; 433 } 434 } 435 436 /*****************************************************************************/ 437 /* */ 438 /* Function Name : get_argument */ 439 /* */ 440 /* Description : Gets argument for a given string */ 441 /* */ 442 /* */ 443 /* Inputs : name */ 444 /* Globals : */ 445 /* Processing : Searches the given string in the array and returns */ 446 /* appropriate argument ID */ 447 /* */ 448 /* Outputs : Argument ID */ 449 /* Returns : Argument ID */ 450 /* */ 451 /* Issues : */ 452 /* */ 453 /* Revision History: */ 454 /* */ 455 /* DD MM YYYY Author(s) Changes */ 456 /* 07 09 2012 100189 Initial Version */ 457 /* */ 458 /*****************************************************************************/ 459 ARGUMENT_T get_argument(CHAR *name) 460 { 461 WORD32 i = 0; 462 WORD32 num_entries = sizeof(argument_mapping) / sizeof(argument_t); 463 while(i < num_entries) 464 { 465 if((0 == strcmp(argument_mapping[i].argument_name, name)) || 466 ((0 == strcmp(argument_mapping[i].argument_shortname, name)) && 467 (0 != strcmp(argument_mapping[i].argument_shortname, "--")))) 468 { 469 return argument_mapping[i].argument; 470 } 471 i++; 472 } 473 return INVALID; 474 } 475 476 /*****************************************************************************/ 477 /* */ 478 /* Function Name : get_argument */ 479 /* */ 480 /* Description : Gets argument for a given string */ 481 /* */ 482 /* */ 483 /* Inputs : name */ 484 /* Globals : */ 485 /* Processing : Searches the given string in the array and returns */ 486 /* appropriate argument ID */ 487 /* */ 488 /* Outputs : Argument ID */ 489 /* Returns : Argument ID */ 490 /* */ 491 /* Issues : */ 492 /* */ 493 /* Revision History: */ 494 /* */ 495 /* DD MM YYYY Author(s) Changes */ 496 /* 07 09 2012 100189 Initial Version */ 497 /* */ 498 /*****************************************************************************/ 499 void parse_argument(app_ctxt_t *ps_app_ctxt, CHAR *argument, CHAR *value) 500 { 501 ARGUMENT_T arg; 502 503 arg = get_argument(argument); 504 switch(arg) 505 { 506 case HELP: 507 print_usage(); 508 exit(-1); 509 break; 510 case SLICE_MODE: 511 sscanf(value, "%d", &ps_app_ctxt->u4_slice_mode); 512 break; 513 case SLICE_PARAM: 514 sscanf(value, "%d", &ps_app_ctxt->u4_slice_param); 515 break; 516 case INPUT_FILE: 517 sscanf(value, "%s", ps_app_ctxt->ac_ip_fname); 518 break; 519 520 case OUTPUT_FILE: 521 sscanf(value, "%s", ps_app_ctxt->ac_op_fname); 522 break; 523 524 case RECON_FILE: 525 sscanf(value, "%s", ps_app_ctxt->ac_recon_fname); 526 break; 527 528 case RECON_ENABLE: 529 sscanf(value, "%d", &ps_app_ctxt->u4_recon_enable); 530 break; 531 532 case CHKSUM_FILE: 533 sscanf(value, "%s", ps_app_ctxt->ac_chksum_fname); 534 break; 535 536 case CHKSUM_ENABLE: 537 sscanf(value, "%d", &ps_app_ctxt->u4_chksum_enable); 538 break; 539 540 case MB_INFO_FILE: 541 sscanf(value, "%s", ps_app_ctxt->ac_mb_info_fname); 542 break; 543 544 case MB_INFO_TYPE: 545 sscanf(value, "%d", &ps_app_ctxt->u4_mb_info_type); 546 break; 547 548 case PIC_INFO_FILE: 549 sscanf(value, "%s", ps_app_ctxt->ac_pic_info_fname); 550 break; 551 552 case PIC_INFO_TYPE: 553 sscanf(value, "%d", &ps_app_ctxt->u4_pic_info_type); 554 break; 555 556 case INPUT_CHROMA_FORMAT: 557 ps_app_ctxt->e_inp_color_fmt = get_chroma_fmt(value); 558 break; 559 560 case RECON_CHROMA_FORMAT: 561 ps_app_ctxt->e_recon_color_fmt = get_chroma_fmt(value); 562 break; 563 564 case MAX_WD: 565 sscanf(value, "%d", &ps_app_ctxt->u4_max_wd); 566 break; 567 568 case MAX_HT: 569 sscanf(value, "%d", &ps_app_ctxt->u4_max_ht); 570 break; 571 572 case WD: 573 sscanf(value, "%d", &ps_app_ctxt->u4_wd); 574 break; 575 576 case HT: 577 sscanf(value, "%d", &ps_app_ctxt->u4_ht); 578 break; 579 580 case MAX_LEVEL: 581 sscanf(value, "%d", &ps_app_ctxt->u4_max_level); 582 break; 583 584 case ENC_SPEED: 585 ps_app_ctxt->u4_enc_speed = get_speed_preset(value); 586 break; 587 588 case ME_SPEED: 589 sscanf(value, "%d", &ps_app_ctxt->u4_me_speed); 590 break; 591 592 case START_FRM: 593 sscanf(value, "%d", &ps_app_ctxt->u4_start_frm); 594 break; 595 596 case NUM_FRMS: 597 sscanf(value, "%d", &ps_app_ctxt->u4_max_num_frms); 598 break; 599 600 case MAX_FRAMERATE: 601 sscanf(value, "%d", &ps_app_ctxt->u4_max_frame_rate); 602 if(ps_app_ctxt->u4_max_frame_rate <= 0) 603 ps_app_ctxt->u4_max_frame_rate = DEFAULT_MAX_FRAMERATE; 604 break; 605 606 case SRC_FRAMERATE: 607 sscanf(value, "%d", &ps_app_ctxt->u4_src_frame_rate); 608 if(ps_app_ctxt->u4_src_frame_rate <= 0) 609 ps_app_ctxt->u4_src_frame_rate = DEFAULT_SRC_FRAME_RATE; 610 break; 611 612 case TGT_FRAMERATE: 613 sscanf(value, "%d", &ps_app_ctxt->u4_tgt_frame_rate); 614 if(ps_app_ctxt->u4_tgt_frame_rate <= 0) 615 ps_app_ctxt->u4_tgt_frame_rate = DEFAULT_TGT_FRAME_RATE; 616 break; 617 618 case RC: 619 sscanf(value, "%d", &ps_app_ctxt->u4_rc); 620 break; 621 622 case MAX_BITRATE: 623 sscanf(value, "%d", &ps_app_ctxt->u4_max_bitrate); 624 break; 625 626 case BITRATE: 627 sscanf(value, "%d", &ps_app_ctxt->u4_bitrate); 628 break; 629 630 case I_QP: 631 sscanf(value, "%d", &ps_app_ctxt->u4_i_qp); 632 break; 633 634 case I_QP_MAX: 635 sscanf(value, "%d", &ps_app_ctxt->u4_i_qp_max); 636 break; 637 638 case I_QP_MIN: 639 sscanf(value, "%d", &ps_app_ctxt->u4_i_qp_min); 640 break; 641 642 case P_QP: 643 sscanf(value, "%d", &ps_app_ctxt->u4_p_qp); 644 break; 645 646 case P_QP_MAX: 647 sscanf(value, "%d", &ps_app_ctxt->u4_p_qp_max); 648 break; 649 650 case P_QP_MIN: 651 sscanf(value, "%d", &ps_app_ctxt->u4_p_qp_min); 652 break; 653 654 case B_QP: 655 sscanf(value, "%d", &ps_app_ctxt->u4_b_qp); 656 break; 657 658 case B_QP_MAX: 659 sscanf(value, "%d", &ps_app_ctxt->u4_b_qp_max); 660 break; 661 662 case B_QP_MIN: 663 sscanf(value, "%d", &ps_app_ctxt->u4_b_qp_min); 664 break; 665 666 case ENTROPY: 667 sscanf(value, "%d", &ps_app_ctxt->u4_entropy_coding_mode); 668 break; 669 670 case AIR: 671 sscanf(value, "%d", &ps_app_ctxt->u4_air); 672 break; 673 674 case ARCH: 675 if((strcmp(value, "ARM_NONEON")) == 0) 676 ps_app_ctxt->e_arch = ARCH_ARM_NONEON; 677 else if((strcmp(value, "ARM_A9Q")) == 0) 678 ps_app_ctxt->e_arch = ARCH_ARM_A9Q; 679 else if((strcmp(value, "ARM_A7")) == 0) 680 ps_app_ctxt->e_arch = ARCH_ARM_A7; 681 else if((strcmp(value, "ARM_A5")) == 0) 682 ps_app_ctxt->e_arch = ARCH_ARM_A5; 683 else if((strcmp(value, "ARM_NEONINTR")) == 0) 684 ps_app_ctxt->e_arch = ARCH_ARM_NEONINTR; 685 else if((strcmp(value, "X86_GENERIC")) == 0) 686 ps_app_ctxt->e_arch = ARCH_X86_GENERIC; 687 else if((strcmp(value, "X86_SSSE3")) == 0) 688 ps_app_ctxt->e_arch = ARCH_X86_SSSE3; 689 else if((strcmp(value, "X86_SSE42")) == 0) 690 ps_app_ctxt->e_arch = ARCH_X86_SSE42; 691 else if((strcmp(value, "ARM_A53")) == 0) 692 ps_app_ctxt->e_arch = ARCH_ARM_A53; 693 else if((strcmp(value, "ARM_A57")) == 0) 694 ps_app_ctxt->e_arch = ARCH_ARM_A57; 695 else if((strcmp(value, "ARM_V8_NEON")) == 0) 696 ps_app_ctxt->e_arch = ARCH_ARM_V8_NEON; 697 else 698 { 699 printf("\nInvalid Arch. Setting it to ARM_A9Q\n"); 700 ps_app_ctxt->e_arch = ARCH_ARM_A9Q; 701 } 702 703 break; 704 case SOC: 705 if((strcmp(value, "GENERIC")) == 0) 706 ps_app_ctxt->e_soc = SOC_GENERIC; 707 else if((strcmp(value, "HISI_37X")) == 0) 708 ps_app_ctxt->e_soc = SOC_HISI_37X; 709 else 710 { 711 ps_app_ctxt->e_soc = SOC_GENERIC; 712 } 713 break; 714 715 case NUMCORES: 716 sscanf(value, "%d", &ps_app_ctxt->u4_num_cores); 717 break; 718 719 case LOOPBACK: 720 sscanf(value, "%d", &ps_app_ctxt->u4_loopback); 721 break; 722 723 case PRE_ENC_ME: 724 sscanf(value, "%d", &ps_app_ctxt->u4_pre_enc_me); 725 break; 726 727 case PRE_ENC_IPE: 728 sscanf(value, "%d", &ps_app_ctxt->u4_pre_enc_ipe); 729 break; 730 731 case HPEL: 732 sscanf(value, "%d", &ps_app_ctxt->u4_hpel); 733 break; 734 735 case QPEL: 736 sscanf(value, "%d", &ps_app_ctxt->u4_qpel); 737 break; 738 739 case SRCH_RNG_X: 740 sscanf(value, "%d", &ps_app_ctxt->u4_srch_rng_x); 741 break; 742 743 case SRCH_RNG_Y: 744 sscanf(value, "%d", &ps_app_ctxt->u4_srch_rng_y); 745 break; 746 747 case I_INTERVAL: 748 sscanf(value, "%d", &ps_app_ctxt->u4_i_interval); 749 break; 750 751 case IDR_INTERVAL: 752 sscanf(value, "%d", &ps_app_ctxt->u4_idr_interval); 753 break; 754 755 case CONSTRAINED_INTRA_PRED: 756 sscanf(value, "%d", &ps_app_ctxt->u4_constrained_intra_pred); 757 break; 758 759 case NUM_B_FRMS: 760 sscanf(value, "%d", &ps_app_ctxt->u4_num_bframes); 761 break; 762 763 case DISABLE_DEBLOCK_LEVEL: 764 sscanf(value, "%d", &ps_app_ctxt->u4_disable_deblk_level); 765 break; 766 767 case VBV_DELAY: 768 sscanf(value, "%d", &ps_app_ctxt->u4_vbv_buffer_delay); 769 break; 770 771 case VBV_SIZE: 772 sscanf(value, "%d", &ps_app_ctxt->u4_vbv_buf_size); 773 break; 774 775 case FAST_SAD: 776 sscanf(value, "%d", &ps_app_ctxt->u4_enable_fast_sad); 777 break; 778 779 case ALT_REF: 780 sscanf(value, "%d", &ps_app_ctxt->u4_enable_alt_ref); 781 break; 782 783 case AIR_REFRESH_PERIOD: 784 sscanf(value, "%d", &ps_app_ctxt->u4_air_refresh_period); 785 break; 786 787 case PROFILE: 788 if((strcmp(value, "BASE")) == 0) 789 ps_app_ctxt->e_profile = IV_PROFILE_BASE; 790 else if((strcmp(value, "MAIN")) == 0) 791 ps_app_ctxt->e_profile = IV_PROFILE_MAIN; 792 else if((strcmp(value, "HIGH")) == 0) 793 ps_app_ctxt->e_profile = IV_PROFILE_HIGH; 794 else 795 { 796 printf("\nInvalid profile. Setting it to BASE\n"); 797 ps_app_ctxt->e_profile = IV_PROFILE_BASE; 798 } 799 break; 800 801 case PSNR: 802 sscanf(value, "%d", &ps_app_ctxt->u4_psnr_enable); 803 break; 804 805 case INTRA_4x4_ENABLE: 806 sscanf(value, "%d", &ps_app_ctxt->u4_enable_intra_4x4); 807 break; 808 809 810 case INVALID: 811 default: 812 printf("Ignoring argument : %s\n", argument); 813 break; 814 } 815 } 816 817 /*****************************************************************************/ 818 /* */ 819 /* Function Name : read_cfg_file */ 820 /* */ 821 /* Description : Reads arguments from a configuration file */ 822 /* */ 823 /* */ 824 /* Inputs : ps_app_ctxt : Application context */ 825 /* fp_cfg_file : Configuration file handle */ 826 /* Globals : */ 827 /* Processing : Parses the arguments and fills in the application context*/ 828 /* */ 829 /* Outputs : Arguments parsed */ 830 /* Returns : None */ 831 /* */ 832 /* Issues : */ 833 /* */ 834 /* Revision History: */ 835 /* */ 836 /* DD MM YYYY Author(s) Changes */ 837 /* 07 09 2012 100189 Initial Version */ 838 /* */ 839 /*****************************************************************************/ 840 void read_cfg_file(app_ctxt_t *ps_app_ctxt, FILE *fp_cfg) 841 { 842 CHAR line[STRLENGTH]; 843 CHAR description[STRLENGTH]; 844 CHAR value[STRLENGTH]; 845 CHAR argument[STRLENGTH]; 846 847 while(0 == (feof(fp_cfg))) 848 { 849 line[0] = '\0'; 850 fgets(line, STRLENGTH, fp_cfg); 851 argument[0] = '\0'; 852 /* Reading Input File Name */ 853 sscanf(line, "%s %s %s", argument, value, description); 854 if(argument[0] == '\0') 855 continue; 856 857 parse_argument(ps_app_ctxt, argument, value); 858 } 859 } 860 861 void invalid_argument_exit(CHAR *pc_err_message) 862 { 863 print_usage(); 864 codec_exit(pc_err_message); 865 } 866 867 void validate_params(app_ctxt_t *ps_app_ctxt) 868 { 869 CHAR ac_error[STRLENGTH]; 870 871 if(ps_app_ctxt->ac_ip_fname[0] == '\0') 872 { 873 invalid_argument_exit("Specify input file"); 874 } 875 if(ps_app_ctxt->ac_op_fname[0] == '\0') 876 { 877 invalid_argument_exit("Specify output file"); 878 } 879 if((1 == ps_app_ctxt->u4_recon_enable) && (ps_app_ctxt->ac_recon_fname[0] == '\0')) 880 { 881 invalid_argument_exit("Specify recon file"); 882 } 883 if((1 == ps_app_ctxt->u4_chksum_enable) && (ps_app_ctxt->ac_chksum_fname[0] == '\0')) 884 { 885 invalid_argument_exit("Specify checksum file"); 886 } 887 if(0 >= (WORD32)ps_app_ctxt->u4_wd) 888 { 889 sprintf(ac_error, "Invalid width: %d", ps_app_ctxt->u4_wd); 890 invalid_argument_exit(ac_error); 891 } 892 if(0 >= (WORD32)ps_app_ctxt->u4_ht) 893 { 894 sprintf(ac_error, "Invalid height: %d", ps_app_ctxt->u4_ht); 895 invalid_argument_exit(ac_error); 896 } 897 898 if(0 == (WORD32)ps_app_ctxt->u4_max_num_frms) 899 { 900 sprintf(ac_error, "Invalid number of frames to be encoded: %d", ps_app_ctxt->u4_max_num_frms); 901 invalid_argument_exit(ac_error); 902 } 903 if ((0 != (WORD32)ps_app_ctxt->u4_entropy_coding_mode) 904 && (1 != (WORD32)ps_app_ctxt->u4_entropy_coding_mode)) 905 { 906 sprintf(ac_error, "Invalid entropy codeing mode: %d", 907 ps_app_ctxt->u4_entropy_coding_mode); 908 invalid_argument_exit(ac_error); 909 } 910 return; 911 } 912 913 void init_default_params(app_ctxt_t *ps_app_ctxt) 914 { 915 916 ps_app_ctxt->ps_enc = NULL; 917 ps_app_ctxt->ps_mem_rec = NULL; 918 ps_app_ctxt->u4_num_mem_rec = DEFAULT_MEM_REC_CNT; 919 ps_app_ctxt->u4_recon_enable = DEFAULT_RECON_ENABLE; 920 ps_app_ctxt->u4_chksum_enable = DEFAULT_CHKSUM_ENABLE; 921 ps_app_ctxt->u4_mb_info_type = 0; 922 ps_app_ctxt->u4_pic_info_type = 0; 923 ps_app_ctxt->u4_mb_info_size = 0; 924 ps_app_ctxt->u4_pic_info_size = 0; 925 ps_app_ctxt->u4_start_frm = DEFAULT_START_FRM; 926 ps_app_ctxt->u4_max_num_frms = DEFAULT_NUM_FRMS; 927 ps_app_ctxt->avg_time = 0; 928 ps_app_ctxt->u4_total_bytes = 0; 929 ps_app_ctxt->u4_pics_cnt = 0; 930 ps_app_ctxt->e_inp_color_fmt = DEFAULT_INP_COLOR_FMT; 931 ps_app_ctxt->e_recon_color_fmt = DEFAULT_RECON_COLOR_FMT; 932 ps_app_ctxt->e_arch = ARCH_ARM_A9Q; 933 ps_app_ctxt->e_soc = SOC_GENERIC; 934 ps_app_ctxt->header_generated = 0; 935 ps_app_ctxt->pv_codec_obj = NULL; 936 ps_app_ctxt->u4_num_cores = DEFAULT_NUM_CORES; 937 ps_app_ctxt->u4_pre_enc_me = 0; 938 ps_app_ctxt->u4_pre_enc_ipe = 0; 939 ps_app_ctxt->ac_ip_fname[0] = '\0'; 940 ps_app_ctxt->ac_op_fname[0] = '\0'; 941 ps_app_ctxt->ac_recon_fname[0] = '\0'; 942 ps_app_ctxt->ac_chksum_fname[0] = '\0'; 943 ps_app_ctxt->ac_mb_info_fname[0] = '\0'; 944 ps_app_ctxt->fp_ip = NULL; 945 ps_app_ctxt->fp_op = NULL; 946 ps_app_ctxt->fp_recon = NULL; 947 ps_app_ctxt->fp_chksum = NULL; 948 ps_app_ctxt->fp_psnr_ip = NULL; 949 ps_app_ctxt->fp_mb_info = NULL; 950 ps_app_ctxt->fp_pic_info = NULL; 951 ps_app_ctxt->u4_loopback = DEFAULT_LOOPBACK; 952 ps_app_ctxt->u4_max_frame_rate = DEFAULT_MAX_FRAMERATE; 953 ps_app_ctxt->u4_src_frame_rate = DEFAULT_SRC_FRAME_RATE; 954 ps_app_ctxt->u4_tgt_frame_rate = DEFAULT_TGT_FRAME_RATE; 955 ps_app_ctxt->u4_max_wd = DEFAULT_MAX_WD; 956 ps_app_ctxt->u4_max_ht = DEFAULT_MAX_HT; 957 ps_app_ctxt->u4_max_level = DEFAULT_MAX_LEVEL; 958 ps_app_ctxt->u4_strd = DEFAULT_STRIDE; 959 ps_app_ctxt->u4_wd = DEFAULT_WD; 960 ps_app_ctxt->u4_ht = DEFAULT_HT; 961 ps_app_ctxt->u4_psnr_enable = DEFAULT_PSNR_ENABLE; 962 ps_app_ctxt->u4_enc_speed = IVE_FASTEST; 963 ps_app_ctxt->u4_me_speed = DEFAULT_ME_SPEED; 964 ps_app_ctxt->u4_enable_fast_sad = DEFAULT_ENABLE_FAST_SAD; 965 ps_app_ctxt->u4_enable_alt_ref = DEFAULT_ENABLE_ALT_REF; 966 ps_app_ctxt->u4_rc = DEFAULT_RC; 967 ps_app_ctxt->u4_max_bitrate = DEFAULT_MAX_BITRATE; 968 ps_app_ctxt->u4_num_bframes = DEFAULT_NUM_BFRAMES; 969 ps_app_ctxt->u4_bitrate = DEFAULT_BITRATE; 970 ps_app_ctxt->u4_i_qp = DEFAULT_I_QP; 971 ps_app_ctxt->u4_p_qp = DEFAULT_P_QP; 972 ps_app_ctxt->u4_b_qp = DEFAULT_B_QP; 973 ps_app_ctxt->u4_i_qp_min = DEFAULT_QP_MIN; 974 ps_app_ctxt->u4_i_qp_max = DEFAULT_QP_MAX; 975 ps_app_ctxt->u4_p_qp_min = DEFAULT_QP_MIN; 976 ps_app_ctxt->u4_p_qp_max = DEFAULT_QP_MAX; 977 ps_app_ctxt->u4_b_qp_min = DEFAULT_QP_MIN; 978 ps_app_ctxt->u4_b_qp_max = DEFAULT_QP_MAX; 979 ps_app_ctxt->u4_air = DEFAULT_AIR; 980 ps_app_ctxt->u4_air_refresh_period = DEFAULT_AIR_REFRESH_PERIOD; 981 ps_app_ctxt->u4_srch_rng_x = DEFAULT_SRCH_RNG_X; 982 ps_app_ctxt->u4_srch_rng_y = DEFAULT_SRCH_RNG_Y; 983 ps_app_ctxt->u4_i_interval = DEFAULT_I_INTERVAL; 984 ps_app_ctxt->u4_idr_interval = DEFAULT_IDR_INTERVAL; 985 ps_app_ctxt->u4_constrained_intra_pred = DEFAULT_CONSTRAINED_INTRAPRED; 986 ps_app_ctxt->u4_disable_deblk_level = DEFAULT_DISABLE_DEBLK_LEVEL; 987 ps_app_ctxt->u4_hpel = DEFAULT_HPEL; 988 ps_app_ctxt->u4_qpel = DEFAULT_QPEL; 989 ps_app_ctxt->u4_enable_intra_4x4 = DEFAULT_I4; 990 ps_app_ctxt->e_profile = DEFAULT_EPROFILE; 991 ps_app_ctxt->u4_slice_mode = DEFAULT_SLICE_MODE; 992 ps_app_ctxt->u4_slice_param = DEFAULT_SLICE_PARAM; 993 ps_app_ctxt->pv_input_thread_handle = NULL; 994 ps_app_ctxt->pv_output_thread_handle = NULL; 995 ps_app_ctxt->pv_recon_thread_handle = NULL; 996 ps_app_ctxt->u4_vbv_buf_size = 0; 997 ps_app_ctxt->u4_vbv_buffer_delay = 1000; 998 ps_app_ctxt->adbl_psnr[0] = 0.0; 999 ps_app_ctxt->adbl_psnr[1] = 0.0; 1000 ps_app_ctxt->adbl_psnr[2] = 0.0; 1001 ps_app_ctxt->u4_psnr_cnt = 0; 1002 ps_app_ctxt->pu1_psnr_buf = NULL; 1003 ps_app_ctxt->u4_psnr_buf_size = 0; 1004 ps_app_ctxt->u4_entropy_coding_mode = DEFAULT_ENTROPY_CODING_MODE; 1005 1006 return; 1007 } 1008 1009 void set_dimensions(app_ctxt_t *ps_app_ctxt, 1010 UWORD32 u4_timestamp_low, 1011 UWORD32 u4_timestamp_high) 1012 { 1013 ih264e_ctl_set_dimensions_ip_t s_frame_dimensions_ip; 1014 ih264e_ctl_set_dimensions_op_t s_frame_dimensions_op; 1015 IV_STATUS_T status; 1016 1017 s_frame_dimensions_ip.s_ive_ip.e_cmd = IVE_CMD_VIDEO_CTL; 1018 s_frame_dimensions_ip.s_ive_ip.e_sub_cmd = IVE_CMD_CTL_SET_DIMENSIONS; 1019 1020 s_frame_dimensions_ip.s_ive_ip.u4_ht = ps_app_ctxt->u4_ht; 1021 s_frame_dimensions_ip.s_ive_ip.u4_wd = ps_app_ctxt->u4_wd; 1022 1023 s_frame_dimensions_ip.s_ive_ip.u4_timestamp_high = u4_timestamp_high; 1024 s_frame_dimensions_ip.s_ive_ip.u4_timestamp_low = u4_timestamp_low; 1025 1026 s_frame_dimensions_ip.s_ive_ip.u4_size = 1027 sizeof(ih264e_ctl_set_dimensions_ip_t); 1028 s_frame_dimensions_op.s_ive_op.u4_size = 1029 sizeof(ih264e_ctl_set_dimensions_op_t); 1030 1031 status = ih264e_api_function(ps_app_ctxt->ps_enc, 1032 &s_frame_dimensions_ip, 1033 &s_frame_dimensions_op); 1034 if(status != IV_SUCCESS) 1035 { 1036 CHAR ac_error[STRLENGTH]; 1037 sprintf(ac_error, "Unable to set frame dimensions = 0x%x\n", 1038 s_frame_dimensions_op.s_ive_op.u4_error_code); 1039 codec_exit(ac_error); 1040 } 1041 return; 1042 } 1043 1044 void set_frame_rate(app_ctxt_t *ps_app_ctxt, 1045 UWORD32 u4_timestamp_low, 1046 UWORD32 u4_timestamp_high) 1047 { 1048 ih264e_ctl_set_frame_rate_ip_t s_frame_rate_ip; 1049 ih264e_ctl_set_frame_rate_op_t s_frame_rate_op; 1050 IV_STATUS_T status; 1051 1052 s_frame_rate_ip.s_ive_ip.e_cmd = IVE_CMD_VIDEO_CTL; 1053 s_frame_rate_ip.s_ive_ip.e_sub_cmd = IVE_CMD_CTL_SET_FRAMERATE; 1054 1055 s_frame_rate_ip.s_ive_ip.u4_src_frame_rate = 1056 ps_app_ctxt->u4_src_frame_rate; 1057 s_frame_rate_ip.s_ive_ip.u4_tgt_frame_rate = 1058 ps_app_ctxt->u4_tgt_frame_rate; 1059 1060 s_frame_rate_ip.s_ive_ip.u4_timestamp_high = u4_timestamp_high; 1061 s_frame_rate_ip.s_ive_ip.u4_timestamp_low = u4_timestamp_low; 1062 1063 s_frame_rate_ip.s_ive_ip.u4_size = sizeof(ih264e_ctl_set_frame_rate_ip_t); 1064 s_frame_rate_op.s_ive_op.u4_size = sizeof(ih264e_ctl_set_frame_rate_op_t); 1065 1066 status = ih264e_api_function(ps_app_ctxt->ps_enc,&s_frame_rate_ip,&s_frame_rate_op); 1067 if(status != IV_SUCCESS) 1068 { 1069 CHAR ac_error[STRLENGTH]; 1070 sprintf(ac_error, "Unable to set frame rate = 0x%x\n", 1071 s_frame_rate_op.s_ive_op.u4_error_code); 1072 codec_exit(ac_error); 1073 } 1074 return; 1075 } 1076 1077 1078 void set_ipe_params(app_ctxt_t *ps_app_ctxt, 1079 UWORD32 u4_timestamp_low, 1080 UWORD32 u4_timestamp_high) 1081 { 1082 ih264e_ctl_set_ipe_params_ip_t s_ipe_params_ip; 1083 ih264e_ctl_set_ipe_params_op_t s_ipe_params_op; 1084 IV_STATUS_T status; 1085 1086 s_ipe_params_ip.s_ive_ip.e_cmd = IVE_CMD_VIDEO_CTL; 1087 s_ipe_params_ip.s_ive_ip.e_sub_cmd = IVE_CMD_CTL_SET_IPE_PARAMS; 1088 1089 s_ipe_params_ip.s_ive_ip.u4_enable_intra_4x4 = ps_app_ctxt->u4_enable_intra_4x4; 1090 s_ipe_params_ip.s_ive_ip.u4_enc_speed_preset = ps_app_ctxt->u4_enc_speed; 1091 1092 s_ipe_params_ip.s_ive_ip.u4_timestamp_high = u4_timestamp_high; 1093 s_ipe_params_ip.s_ive_ip.u4_timestamp_low = u4_timestamp_low; 1094 1095 s_ipe_params_ip.s_ive_ip.u4_size = sizeof(ih264e_ctl_set_ipe_params_ip_t); 1096 s_ipe_params_op.s_ive_op.u4_size = sizeof(ih264e_ctl_set_ipe_params_op_t); 1097 1098 s_ipe_params_ip.s_ive_ip.u4_constrained_intra_pred = 1099 ps_app_ctxt->u4_constrained_intra_pred; 1100 1101 status = ih264e_api_function(ps_app_ctxt->ps_enc,&s_ipe_params_ip,&s_ipe_params_op); 1102 if(status != IV_SUCCESS) 1103 { 1104 CHAR ac_error[STRLENGTH]; 1105 sprintf(ac_error, "Unable to set ipe params = 0x%x\n", 1106 s_ipe_params_op.s_ive_op.u4_error_code); 1107 codec_exit(ac_error); 1108 } 1109 return; 1110 } 1111 1112 void set_bit_rate(app_ctxt_t *ps_app_ctxt, 1113 UWORD32 u4_timestamp_low, UWORD32 u4_timestamp_high) 1114 { 1115 ih264e_ctl_set_bitrate_ip_t s_bitrate_ip; 1116 ih264e_ctl_set_bitrate_op_t s_bitrate_op; 1117 IV_STATUS_T status; 1118 1119 s_bitrate_ip.s_ive_ip.e_cmd = IVE_CMD_VIDEO_CTL; 1120 s_bitrate_ip.s_ive_ip.e_sub_cmd = IVE_CMD_CTL_SET_BITRATE; 1121 1122 s_bitrate_ip.s_ive_ip.u4_target_bitrate = ps_app_ctxt->u4_bitrate; 1123 1124 s_bitrate_ip.s_ive_ip.u4_timestamp_high = u4_timestamp_high; 1125 s_bitrate_ip.s_ive_ip.u4_timestamp_low = u4_timestamp_low; 1126 1127 s_bitrate_ip.s_ive_ip.u4_size = sizeof(ih264e_ctl_set_bitrate_ip_t); 1128 s_bitrate_op.s_ive_op.u4_size = sizeof(ih264e_ctl_set_bitrate_op_t); 1129 1130 status = ih264e_api_function(ps_app_ctxt->ps_enc,&s_bitrate_ip,&s_bitrate_op); 1131 if(status != IV_SUCCESS) 1132 { 1133 CHAR ac_error[STRLENGTH]; 1134 sprintf(ac_error, "Unable to set bit rate = 0x%x\n", 1135 s_bitrate_op.s_ive_op.u4_error_code); 1136 codec_exit(ac_error); 1137 } 1138 return; 1139 } 1140 1141 1142 void set_frame_type(app_ctxt_t *ps_app_ctxt, 1143 UWORD32 u4_timestamp_low, 1144 UWORD32 u4_timestamp_high, 1145 IV_PICTURE_CODING_TYPE_T e_frame_type) 1146 { 1147 ih264e_ctl_set_frame_type_ip_t s_frame_type_ip; 1148 ih264e_ctl_set_frame_type_op_t s_frame_type_op; 1149 IV_STATUS_T status; 1150 1151 s_frame_type_ip.s_ive_ip.e_cmd = IVE_CMD_VIDEO_CTL; 1152 s_frame_type_ip.s_ive_ip.e_sub_cmd = IVE_CMD_CTL_SET_FRAMETYPE; 1153 1154 s_frame_type_ip.s_ive_ip.e_frame_type = e_frame_type; 1155 1156 s_frame_type_ip.s_ive_ip.u4_timestamp_high = u4_timestamp_high; 1157 s_frame_type_ip.s_ive_ip.u4_timestamp_low = u4_timestamp_low; 1158 1159 s_frame_type_ip.s_ive_ip.u4_size = sizeof(ih264e_ctl_set_frame_type_ip_t); 1160 s_frame_type_op.s_ive_op.u4_size = sizeof(ih264e_ctl_set_frame_type_op_t); 1161 1162 status = ih264e_api_function(ps_app_ctxt->ps_enc,&s_frame_type_ip,&s_frame_type_op); 1163 if(status != IV_SUCCESS) 1164 { 1165 CHAR ac_error[STRLENGTH]; 1166 sprintf(ac_error, "Unable to set frame type = 0x%x\n", 1167 s_frame_type_op.s_ive_op.u4_error_code); 1168 codec_exit(ac_error); 1169 } 1170 return; 1171 } 1172 1173 void set_qp(app_ctxt_t *ps_app_ctxt, 1174 UWORD32 u4_timestamp_low, UWORD32 u4_timestamp_high) 1175 { 1176 ih264e_ctl_set_qp_ip_t s_qp_ip; 1177 ih264e_ctl_set_qp_op_t s_qp_op; 1178 IV_STATUS_T status; 1179 1180 s_qp_ip.s_ive_ip.e_cmd = IVE_CMD_VIDEO_CTL; 1181 s_qp_ip.s_ive_ip.e_sub_cmd = IVE_CMD_CTL_SET_QP; 1182 1183 s_qp_ip.s_ive_ip.u4_i_qp = ps_app_ctxt->u4_i_qp; 1184 s_qp_ip.s_ive_ip.u4_i_qp_max = ps_app_ctxt->u4_i_qp_max; 1185 s_qp_ip.s_ive_ip.u4_i_qp_min = ps_app_ctxt->u4_i_qp_min; 1186 1187 s_qp_ip.s_ive_ip.u4_p_qp = ps_app_ctxt->u4_p_qp; 1188 s_qp_ip.s_ive_ip.u4_p_qp_max = ps_app_ctxt->u4_p_qp_max; 1189 s_qp_ip.s_ive_ip.u4_p_qp_min = ps_app_ctxt->u4_p_qp_min; 1190 1191 s_qp_ip.s_ive_ip.u4_b_qp = ps_app_ctxt->u4_b_qp; 1192 s_qp_ip.s_ive_ip.u4_b_qp_max = ps_app_ctxt->u4_b_qp_max; 1193 s_qp_ip.s_ive_ip.u4_b_qp_min = ps_app_ctxt->u4_b_qp_min; 1194 1195 s_qp_ip.s_ive_ip.u4_timestamp_high = u4_timestamp_high; 1196 s_qp_ip.s_ive_ip.u4_timestamp_low = u4_timestamp_low; 1197 1198 s_qp_ip.s_ive_ip.u4_size = sizeof(ih264e_ctl_set_qp_ip_t); 1199 s_qp_op.s_ive_op.u4_size = sizeof(ih264e_ctl_set_qp_op_t); 1200 1201 status = ih264e_api_function(ps_app_ctxt->ps_enc,&s_qp_ip,&s_qp_op); 1202 if(status != IV_SUCCESS) 1203 { 1204 CHAR ac_error[STRLENGTH]; 1205 sprintf(ac_error, "Unable to set qp 0x%x\n", 1206 s_qp_op.s_ive_op.u4_error_code); 1207 codec_exit(ac_error); 1208 } 1209 return; 1210 } 1211 1212 void set_enc_mode(app_ctxt_t *ps_app_ctxt, 1213 UWORD32 u4_timestamp_low, UWORD32 u4_timestamp_high, 1214 IVE_ENC_MODE_T e_enc_mode) 1215 { 1216 IV_STATUS_T status; 1217 1218 ih264e_ctl_set_enc_mode_ip_t s_enc_mode_ip; 1219 ih264e_ctl_set_enc_mode_op_t s_enc_mode_op; 1220 1221 s_enc_mode_ip.s_ive_ip.e_cmd = IVE_CMD_VIDEO_CTL; 1222 s_enc_mode_ip.s_ive_ip.e_sub_cmd = IVE_CMD_CTL_SET_ENC_MODE; 1223 1224 s_enc_mode_ip.s_ive_ip.e_enc_mode = e_enc_mode; 1225 1226 s_enc_mode_ip.s_ive_ip.u4_timestamp_high = u4_timestamp_high; 1227 s_enc_mode_ip.s_ive_ip.u4_timestamp_low = u4_timestamp_low; 1228 1229 s_enc_mode_ip.s_ive_ip.u4_size = sizeof(ih264e_ctl_set_enc_mode_ip_t); 1230 s_enc_mode_op.s_ive_op.u4_size = sizeof(ih264e_ctl_set_enc_mode_op_t); 1231 1232 status = ih264e_api_function(ps_app_ctxt->ps_enc, &s_enc_mode_ip, 1233 &s_enc_mode_op); 1234 if(status != IV_SUCCESS) 1235 { 1236 CHAR ac_error[STRLENGTH]; 1237 sprintf(ac_error, "Unable to set in header encode mode = 0x%x\n", 1238 s_enc_mode_op.s_ive_op.u4_error_code); 1239 codec_exit(ac_error); 1240 } 1241 return; 1242 } 1243 1244 1245 void set_vbv_params(app_ctxt_t *ps_app_ctxt, 1246 UWORD32 u4_timestamp_low, 1247 UWORD32 u4_timestamp_high) 1248 { 1249 ih264e_ctl_set_vbv_params_ip_t s_vbv_ip; 1250 ih264e_ctl_set_vbv_params_op_t s_vbv_op; 1251 IV_STATUS_T status; 1252 1253 s_vbv_ip.s_ive_ip.e_cmd = IVE_CMD_VIDEO_CTL; 1254 s_vbv_ip.s_ive_ip.e_sub_cmd = IVE_CMD_CTL_SET_VBV_PARAMS; 1255 1256 s_vbv_ip.s_ive_ip.u4_vbv_buf_size = ps_app_ctxt->u4_vbv_buf_size; 1257 s_vbv_ip.s_ive_ip.u4_vbv_buffer_delay = 1258 ps_app_ctxt->u4_vbv_buffer_delay; 1259 1260 s_vbv_ip.s_ive_ip.u4_timestamp_high = u4_timestamp_high; 1261 s_vbv_ip.s_ive_ip.u4_timestamp_low = u4_timestamp_low; 1262 1263 s_vbv_ip.s_ive_ip.u4_size = sizeof(ih264e_ctl_set_vbv_params_ip_t); 1264 s_vbv_op.s_ive_op.u4_size = sizeof(ih264e_ctl_set_vbv_params_op_t); 1265 1266 status = ih264e_api_function(ps_app_ctxt->ps_enc,&s_vbv_ip,&s_vbv_op); 1267 if(status != IV_SUCCESS) 1268 { 1269 CHAR ac_error[STRLENGTH]; 1270 sprintf(ac_error, "Unable to set VBC params = 0x%x\n", 1271 s_vbv_op.s_ive_op.u4_error_code); 1272 codec_exit(ac_error); 1273 } 1274 return; 1275 } 1276 1277 void set_air_params(app_ctxt_t *ps_app_ctxt, 1278 UWORD32 u4_timestamp_low, 1279 UWORD32 u4_timestamp_high) 1280 { 1281 ih264e_ctl_set_air_params_ip_t s_air_ip; 1282 ih264e_ctl_set_air_params_op_t s_air_op; 1283 IV_STATUS_T status; 1284 1285 s_air_ip.s_ive_ip.e_cmd = IVE_CMD_VIDEO_CTL; 1286 s_air_ip.s_ive_ip.e_sub_cmd = IVE_CMD_CTL_SET_AIR_PARAMS; 1287 1288 s_air_ip.s_ive_ip.e_air_mode = ps_app_ctxt->u4_air; 1289 s_air_ip.s_ive_ip.u4_air_refresh_period = ps_app_ctxt->u4_air_refresh_period; 1290 1291 s_air_ip.s_ive_ip.u4_timestamp_high = u4_timestamp_high; 1292 s_air_ip.s_ive_ip.u4_timestamp_low = u4_timestamp_low; 1293 1294 s_air_ip.s_ive_ip.u4_size = sizeof(ih264e_ctl_set_air_params_ip_t); 1295 s_air_op.s_ive_op.u4_size = sizeof(ih264e_ctl_set_air_params_op_t); 1296 1297 status = ih264e_api_function(ps_app_ctxt->ps_enc,&s_air_ip,&s_air_op); 1298 if(status != IV_SUCCESS) 1299 { 1300 CHAR ac_error[STRLENGTH]; 1301 sprintf(ac_error, "Unable to set air params = 0x%x\n", 1302 s_air_op.s_ive_op.u4_error_code); 1303 codec_exit(ac_error); 1304 } 1305 return; 1306 } 1307 1308 void set_me_params(app_ctxt_t *ps_app_ctxt, 1309 UWORD32 u4_timestamp_low, 1310 UWORD32 u4_timestamp_high) 1311 { 1312 IV_STATUS_T status; 1313 1314 ih264e_ctl_set_me_params_ip_t s_me_params_ip; 1315 ih264e_ctl_set_me_params_op_t s_me_params_op; 1316 1317 s_me_params_ip.s_ive_ip.e_cmd = IVE_CMD_VIDEO_CTL; 1318 s_me_params_ip.s_ive_ip.e_sub_cmd = IVE_CMD_CTL_SET_ME_PARAMS; 1319 1320 s_me_params_ip.s_ive_ip.u4_enable_fast_sad = ps_app_ctxt->u4_enable_fast_sad; 1321 s_me_params_ip.s_ive_ip.u4_enable_alt_ref = ps_app_ctxt->u4_enable_alt_ref; 1322 1323 s_me_params_ip.s_ive_ip.u4_enable_hpel = ps_app_ctxt->u4_hpel; 1324 s_me_params_ip.s_ive_ip.u4_enable_qpel = ps_app_ctxt->u4_qpel; 1325 s_me_params_ip.s_ive_ip.u4_me_speed_preset = ps_app_ctxt->u4_me_speed; 1326 s_me_params_ip.s_ive_ip.u4_srch_rng_x = ps_app_ctxt->u4_srch_rng_x; 1327 s_me_params_ip.s_ive_ip.u4_srch_rng_y = ps_app_ctxt->u4_srch_rng_y; 1328 1329 s_me_params_ip.s_ive_ip.u4_timestamp_high = u4_timestamp_high; 1330 s_me_params_ip.s_ive_ip.u4_timestamp_low = u4_timestamp_low; 1331 1332 s_me_params_ip.s_ive_ip.u4_size = sizeof(ih264e_ctl_set_me_params_ip_t); 1333 s_me_params_op.s_ive_op.u4_size = sizeof(ih264e_ctl_set_me_params_op_t); 1334 1335 status = ih264e_api_function(ps_app_ctxt->ps_enc, &s_me_params_ip, 1336 &s_me_params_op); 1337 if(status != IV_SUCCESS) 1338 { 1339 CHAR ac_error[STRLENGTH]; 1340 sprintf(ac_error, "Unable to set me params = 0x%x\n", 1341 s_me_params_op.s_ive_op.u4_error_code); 1342 codec_exit(ac_error); 1343 } 1344 return; 1345 } 1346 1347 1348 void set_gop_params(app_ctxt_t *ps_app_ctxt, 1349 UWORD32 u4_timestamp_low, 1350 UWORD32 u4_timestamp_high) 1351 { 1352 IV_STATUS_T status; 1353 1354 ih264e_ctl_set_gop_params_ip_t s_gop_params_ip; 1355 ih264e_ctl_set_gop_params_op_t s_gop_params_op; 1356 1357 s_gop_params_ip.s_ive_ip.e_cmd = IVE_CMD_VIDEO_CTL; 1358 s_gop_params_ip.s_ive_ip.e_sub_cmd = IVE_CMD_CTL_SET_GOP_PARAMS; 1359 1360 s_gop_params_ip.s_ive_ip.u4_i_frm_interval = ps_app_ctxt->u4_i_interval; 1361 s_gop_params_ip.s_ive_ip.u4_idr_frm_interval = ps_app_ctxt->u4_idr_interval; 1362 1363 s_gop_params_ip.s_ive_ip.u4_timestamp_high = u4_timestamp_high; 1364 s_gop_params_ip.s_ive_ip.u4_timestamp_low = u4_timestamp_low; 1365 1366 s_gop_params_ip.s_ive_ip.u4_size = sizeof(ih264e_ctl_set_gop_params_ip_t); 1367 s_gop_params_op.s_ive_op.u4_size = sizeof(ih264e_ctl_set_gop_params_op_t); 1368 1369 status = ih264e_api_function(ps_app_ctxt->ps_enc, &s_gop_params_ip, 1370 &s_gop_params_op); 1371 if(status != IV_SUCCESS) 1372 { 1373 CHAR ac_error[STRLENGTH]; 1374 sprintf(ac_error, "Unable to set ME params = 0x%x\n", 1375 s_gop_params_op.s_ive_op.u4_error_code); 1376 codec_exit(ac_error); 1377 } 1378 return; 1379 } 1380 1381 void set_profile_params(app_ctxt_t *ps_app_ctxt, 1382 UWORD32 u4_timestamp_low, 1383 UWORD32 u4_timestamp_high) 1384 { 1385 IV_STATUS_T status; 1386 1387 ih264e_ctl_set_profile_params_ip_t s_profile_params_ip; 1388 ih264e_ctl_set_profile_params_op_t s_profile_params_op; 1389 1390 s_profile_params_ip.s_ive_ip.e_cmd = IVE_CMD_VIDEO_CTL; 1391 s_profile_params_ip.s_ive_ip.e_sub_cmd = IVE_CMD_CTL_SET_PROFILE_PARAMS; 1392 1393 s_profile_params_ip.s_ive_ip.e_profile = ps_app_ctxt->e_profile; 1394 1395 s_profile_params_ip.s_ive_ip.u4_entropy_coding_mode = ps_app_ctxt->u4_entropy_coding_mode; 1396 1397 s_profile_params_ip.s_ive_ip.u4_timestamp_high = u4_timestamp_high; 1398 s_profile_params_ip.s_ive_ip.u4_timestamp_low = u4_timestamp_low; 1399 1400 s_profile_params_ip.s_ive_ip.u4_size = sizeof(ih264e_ctl_set_profile_params_ip_t); 1401 s_profile_params_op.s_ive_op.u4_size = sizeof(ih264e_ctl_set_profile_params_op_t); 1402 1403 status = ih264e_api_function(ps_app_ctxt->ps_enc, &s_profile_params_ip, 1404 &s_profile_params_op); 1405 if(status != IV_SUCCESS) 1406 { 1407 CHAR ac_error[STRLENGTH]; 1408 sprintf(ac_error, "Unable to set profile params = 0x%x\n", 1409 s_profile_params_op.s_ive_op.u4_error_code); 1410 codec_exit(ac_error); 1411 } 1412 return; 1413 } 1414 1415 void set_deblock_params(app_ctxt_t *ps_app_ctxt, 1416 UWORD32 u4_timestamp_low, 1417 UWORD32 u4_timestamp_high) 1418 { 1419 IV_STATUS_T status; 1420 1421 ih264e_ctl_set_deblock_params_ip_t s_deblock_params_ip; 1422 ih264e_ctl_set_deblock_params_op_t s_deblock_params_op; 1423 1424 s_deblock_params_ip.s_ive_ip.e_cmd = IVE_CMD_VIDEO_CTL; 1425 s_deblock_params_ip.s_ive_ip.e_sub_cmd = IVE_CMD_CTL_SET_DEBLOCK_PARAMS; 1426 1427 s_deblock_params_ip.s_ive_ip.u4_disable_deblock_level = 1428 ps_app_ctxt->u4_disable_deblk_level; 1429 1430 s_deblock_params_ip.s_ive_ip.u4_timestamp_high = u4_timestamp_high; 1431 s_deblock_params_ip.s_ive_ip.u4_timestamp_low = u4_timestamp_low; 1432 1433 s_deblock_params_ip.s_ive_ip.u4_size = sizeof(ih264e_ctl_set_deblock_params_ip_t); 1434 s_deblock_params_op.s_ive_op.u4_size = sizeof(ih264e_ctl_set_deblock_params_op_t); 1435 1436 status = ih264e_api_function(ps_app_ctxt->ps_enc, &s_deblock_params_ip, 1437 &s_deblock_params_op); 1438 if(status != IV_SUCCESS) 1439 { 1440 CHAR ac_error[STRLENGTH]; 1441 sprintf(ac_error, "Unable to enable/disable deblock params = 0x%x\n", 1442 s_deblock_params_op.s_ive_op.u4_error_code); 1443 codec_exit(ac_error); 1444 } 1445 return; 1446 } 1447 1448 #define PEAK_WINDOW_SIZE 8 1449 1450 void synchronous_encode(iv_obj_t *ps_enc, app_ctxt_t *ps_app_ctxt) 1451 { 1452 ih264e_video_encode_ip_t ih264e_video_encode_ip; 1453 ih264e_video_encode_op_t ih264e_video_encode_op; 1454 1455 ive_video_encode_ip_t *ps_video_encode_ip = &ih264e_video_encode_ip.s_ive_ip; 1456 ive_video_encode_op_t *ps_video_encode_op = &ih264e_video_encode_op.s_ive_op; 1457 1458 iv_raw_buf_t *ps_inp_raw_buf = &ps_video_encode_ip->s_inp_buf; 1459 1460 IV_STATUS_T status = IV_SUCCESS; 1461 1462 WORD32 i, is_last = 0, buff_size = 0, num_bytes = 0; 1463 UWORD32 u4_total_time = 0; 1464 UWORD8 *pu1_buf = NULL; 1465 UWORD32 u4_timestamp_low, u4_timestamp_high; 1466 void *pv_mb_info = NULL, *pv_pic_info = NULL; 1467 1468 TIMER curtime ; 1469 #ifdef WINDOWS_TIMER 1470 TIMER frequency; 1471 #endif 1472 WORD32 peak_window[PEAK_WINDOW_SIZE] = {0}; 1473 WORD32 peak_window_idx = 0; 1474 WORD32 peak_avg_max = 0, timetaken = 0; 1475 iv_raw_buf_t s_inp_buf, s_recon_buf; 1476 CHAR ac_error[STRLENGTH]; 1477 WORD32 end_of_frames=0; 1478 WORD32 i4_inp_done =0; 1479 1480 u4_timestamp_low = 0; 1481 u4_timestamp_high = 0; 1482 1483 /*************************************************************************/ 1484 /* Allocate I/O Buffers */ 1485 /*************************************************************************/ 1486 allocate_input(ps_app_ctxt); 1487 allocate_output(ps_app_ctxt); 1488 allocate_recon(ps_app_ctxt); 1489 1490 /* init psnr */ 1491 init_psnr(ps_app_ctxt); 1492 1493 /* open file pointers */ 1494 ps_app_ctxt->fp_ip = fopen(ps_app_ctxt->ac_ip_fname, "rb"); 1495 if(NULL == ps_app_ctxt->fp_ip) 1496 { 1497 sprintf(ac_error, "Unable to open input file for reading: %s", ps_app_ctxt->ac_ip_fname); 1498 invalid_argument_exit(ac_error); 1499 } 1500 1501 ps_app_ctxt->fp_op = fopen(ps_app_ctxt->ac_op_fname, "wb"); 1502 if(NULL == ps_app_ctxt->fp_op) 1503 { 1504 sprintf(ac_error, "Unable to open output file for writing: %s", ps_app_ctxt->ac_op_fname); 1505 invalid_argument_exit(ac_error); 1506 } 1507 1508 if(1 == ps_app_ctxt->u4_recon_enable) 1509 { 1510 ps_app_ctxt->fp_recon = fopen(ps_app_ctxt->ac_recon_fname, "wb"); 1511 if(NULL == ps_app_ctxt->fp_recon) 1512 { 1513 sprintf(ac_error, "Unable to open recon file for writing: %s", ps_app_ctxt->ac_recon_fname); 1514 invalid_argument_exit(ac_error); 1515 } 1516 } 1517 1518 if(1 == ps_app_ctxt->u4_chksum_enable) 1519 { 1520 ps_app_ctxt->fp_chksum = fopen(ps_app_ctxt->ac_chksum_fname, "wb"); 1521 if(NULL == ps_app_ctxt->fp_chksum) 1522 { 1523 sprintf(ac_error, "Unable to open checksum file for writing: %s", ps_app_ctxt->ac_chksum_fname); 1524 invalid_argument_exit(ac_error); 1525 } 1526 } 1527 1528 /* If PSNR is enabled, open input file again and hold a different file pointer 1529 * This makes it easy to compute PSNR without adding dependency between input and recon threads 1530 */ 1531 if(1 == ps_app_ctxt->u4_psnr_enable) 1532 { 1533 ps_app_ctxt->fp_psnr_ip = fopen(ps_app_ctxt->ac_ip_fname, "rb"); 1534 if(NULL == ps_app_ctxt->fp_psnr_ip) 1535 { 1536 sprintf(ac_error, "Unable to open input file for reading: %s", ps_app_ctxt->ac_ip_fname); 1537 invalid_argument_exit(ac_error); 1538 } 1539 } 1540 1541 if(0 != ps_app_ctxt->u4_mb_info_type) 1542 { 1543 ps_app_ctxt->fp_mb_info = fopen(ps_app_ctxt->ac_mb_info_fname, "rb"); 1544 if(NULL == ps_app_ctxt->fp_mb_info) 1545 { 1546 sprintf(ac_error, "Unable to open MB info file for reading: %s", ps_app_ctxt->ac_mb_info_fname); 1547 invalid_argument_exit(ac_error); 1548 } 1549 } 1550 if (ps_app_ctxt->u4_pic_info_type) 1551 { 1552 ps_app_ctxt->fp_pic_info = fopen(ps_app_ctxt->ac_pic_info_fname, "rb"); 1553 if(NULL == ps_app_ctxt->fp_pic_info) 1554 { 1555 sprintf(ac_error, "Unable to open Pic info file for reading: %s", ps_app_ctxt->ac_pic_info_fname); 1556 invalid_argument_exit(ac_error); 1557 } 1558 } 1559 1560 GETTIME(&ps_app_ctxt->enc_start_time); 1561 ps_app_ctxt->enc_last_time = ps_app_ctxt->enc_start_time; 1562 1563 while(1) 1564 { 1565 1566 /******************************************************************************/ 1567 /****************** Input Initialization **************************************/ 1568 /******************************************************************************/ 1569 1570 for(i = 0; i < DEFAULT_MAX_INPUT_BUFS; i++) 1571 { 1572 if(ps_app_ctxt->as_input_buf[i].u4_is_free) 1573 { 1574 pu1_buf = ps_app_ctxt->as_input_buf[i].pu1_buf; 1575 pv_mb_info = ps_app_ctxt->as_input_buf[i].pv_mb_info; 1576 pv_pic_info = ps_app_ctxt->as_input_buf[i].pv_pic_info; 1577 ps_app_ctxt->as_input_buf[i].u4_is_free = 0; 1578 break; 1579 } 1580 } 1581 1582 if (i == DEFAULT_MAX_INPUT_BUFS) 1583 { 1584 printf("\n Unable to find a free input buffer!!"); 1585 exit(0); 1586 } 1587 1588 ps_video_encode_ip->u4_size = sizeof(ih264e_video_encode_ip_t); 1589 ps_video_encode_op->u4_size = sizeof(ih264e_video_encode_op_t); 1590 1591 ps_video_encode_ip->e_cmd = IVE_CMD_VIDEO_ENCODE; 1592 ps_video_encode_ip->pv_bufs = pu1_buf; 1593 ps_video_encode_ip->pv_mb_info = pv_mb_info; 1594 ps_video_encode_ip->pv_pic_info = pv_pic_info; 1595 ps_video_encode_ip->u4_pic_info_type = ps_app_ctxt->u4_pic_info_type; 1596 /* 1597 * Since the buffers are used for reading, 1598 * And after each row we have a stride we nned to calculate 1599 * the luma size according to the stride 1600 */ 1601 ps_inp_raw_buf->e_color_fmt = ps_app_ctxt->e_inp_color_fmt; 1602 1603 /* Initialize for 420SP */ 1604 if(IV_YUV_420SP_UV == ps_app_ctxt->e_inp_color_fmt|| 1605 IV_YUV_420SP_VU == ps_app_ctxt->e_inp_color_fmt) 1606 { 1607 /*init luma buffer*/ 1608 ps_inp_raw_buf->apv_bufs[0] = pu1_buf; 1609 1610 /*Init chroma buffer*/ 1611 pu1_buf += ps_app_ctxt->u4_strd * ps_app_ctxt->u4_ht; 1612 ps_inp_raw_buf->apv_bufs[1] = pu1_buf; 1613 1614 ps_inp_raw_buf->au4_wd[0] = ps_app_ctxt->u4_wd; 1615 ps_inp_raw_buf->au4_wd[1] = ps_app_ctxt->u4_wd; 1616 1617 ps_inp_raw_buf->au4_ht[0] = ps_app_ctxt->u4_ht; 1618 ps_inp_raw_buf->au4_ht[1] = ps_app_ctxt->u4_ht / 2; 1619 1620 ps_inp_raw_buf->au4_strd[0] = ps_app_ctxt->u4_strd; 1621 ps_inp_raw_buf->au4_strd[1] = ps_app_ctxt->u4_strd; 1622 } 1623 else if(IV_YUV_420P == ps_app_ctxt->e_inp_color_fmt) 1624 { 1625 /* init buffers */ 1626 ps_inp_raw_buf->apv_bufs[0] = pu1_buf; 1627 pu1_buf += (ps_app_ctxt->u4_wd) * ps_app_ctxt->u4_ht; 1628 ps_inp_raw_buf->apv_bufs[1] = pu1_buf; 1629 pu1_buf += (ps_app_ctxt->u4_wd >> 1) * (ps_app_ctxt->u4_ht >> 1); 1630 ps_inp_raw_buf->apv_bufs[2] = pu1_buf; 1631 1632 ps_inp_raw_buf->au4_wd[0] = ps_app_ctxt->u4_wd; 1633 ps_inp_raw_buf->au4_wd[1] = ps_app_ctxt->u4_wd / 2; 1634 ps_inp_raw_buf->au4_wd[2] = ps_app_ctxt->u4_wd / 2; 1635 1636 ps_inp_raw_buf->au4_ht[0] = ps_app_ctxt->u4_ht; 1637 ps_inp_raw_buf->au4_ht[1] = ps_app_ctxt->u4_ht / 2; 1638 ps_inp_raw_buf->au4_ht[2] = ps_app_ctxt->u4_ht / 2; 1639 1640 ps_inp_raw_buf->au4_strd[0] = ps_app_ctxt->u4_strd; 1641 ps_inp_raw_buf->au4_strd[1] = ps_app_ctxt->u4_strd / 2; 1642 ps_inp_raw_buf->au4_strd[2] = ps_app_ctxt->u4_strd / 2; 1643 1644 } 1645 else if(IV_YUV_422ILE == ps_app_ctxt->e_inp_color_fmt) 1646 { 1647 /*init luma buffer*/ 1648 ps_inp_raw_buf->apv_bufs[0] = pu1_buf; 1649 1650 ps_inp_raw_buf->au4_wd[0] = ps_app_ctxt->u4_wd * 2; 1651 1652 ps_inp_raw_buf->au4_ht[0] = ps_app_ctxt->u4_ht; 1653 1654 ps_inp_raw_buf->au4_strd[0] = ps_app_ctxt->u4_strd *2; 1655 } 1656 1657 /* 1658 * Here we read input and other associated buffers. Regardless of success 1659 * we will proceed from here as we will need extra calls to flush out 1660 * input queue in encoder. Note that this is not necessary. You can just 1661 * send encode calls till with valid output and recon buffers till the 1662 * queue is flushed. 1663 */ 1664 while(1) 1665 { 1666 IV_STATUS_T mb_info_status = IV_SUCCESS, pic_info_status = IV_SUCCESS; 1667 1668 status = read_input(ps_app_ctxt->fp_ip, ps_inp_raw_buf); 1669 1670 if (ps_app_ctxt->u4_mb_info_type != 0) 1671 { 1672 mb_info_status = read_mb_info(ps_app_ctxt, pv_mb_info); 1673 } 1674 if (ps_app_ctxt->u4_pic_info_type != 0) 1675 { 1676 pic_info_status = read_pic_info(ps_app_ctxt, pv_pic_info); 1677 } 1678 if((IV_SUCCESS != status) || (IV_SUCCESS != mb_info_status) 1679 || (IV_SUCCESS != pic_info_status)) 1680 { 1681 if(0 == ps_app_ctxt->u4_loopback) 1682 { 1683 is_last = 1; 1684 break; 1685 } 1686 else 1687 fseek(ps_app_ctxt->fp_ip, 0, SEEK_SET); 1688 } 1689 break; 1690 } 1691 1692 /******************************************************************************/ 1693 /****************** Output Initialization *************************************/ 1694 /******************************************************************************/ 1695 1696 for(i = 0; i < DEFAULT_MAX_OUTPUT_BUFS; i++) 1697 { 1698 if(ps_app_ctxt->as_output_buf[i].u4_is_free) 1699 { 1700 pu1_buf = ps_app_ctxt->as_output_buf[i].pu1_buf; 1701 buff_size = ps_app_ctxt->as_output_buf[i].u4_buf_size; 1702 ps_app_ctxt->as_output_buf[i].u4_is_free = 0; 1703 break; 1704 } 1705 } 1706 ps_video_encode_ip->s_out_buf.pv_buf = pu1_buf; 1707 ps_video_encode_ip->s_out_buf.u4_bytes = 0; 1708 ps_video_encode_ip->s_out_buf.u4_bufsize = buff_size; 1709 1710 /******************************************************************************/ 1711 /****************** Recon Initialization **************************************/ 1712 /******************************************************************************/ 1713 init_raw_buf_descr(ps_app_ctxt, &s_recon_buf, ps_app_ctxt->as_recon_buf[0].pu1_buf, ps_app_ctxt->e_recon_color_fmt); 1714 1715 if(ps_app_ctxt->u4_psnr_enable) 1716 init_raw_buf_descr(ps_app_ctxt, &s_inp_buf, ps_app_ctxt->pu1_psnr_buf, ps_app_ctxt->e_inp_color_fmt); 1717 1718 ps_video_encode_ip->s_recon_buf = s_recon_buf; 1719 1720 /******************************************************************************/ 1721 /************************* Un Initialized *************************************/ 1722 /******************************************************************************/ 1723 if(0 == ps_app_ctxt->u4_loopback) 1724 { 1725 /* If input file is read completely and loopback is not enabled, 1726 * then exit the loop */ 1727 if(feof(ps_app_ctxt->fp_ip)) 1728 { 1729 is_last = 1; 1730 } 1731 } 1732 1733 1734 /* If last frame, send input null to get back encoded frames */ 1735 if ( is_last == 1 || ((ps_app_ctxt->u4_max_num_frms) <= u4_timestamp_low) ) 1736 { 1737 is_last = 1; 1738 ps_inp_raw_buf->apv_bufs[0] = NULL; 1739 ps_inp_raw_buf->apv_bufs[1] = NULL; 1740 ps_inp_raw_buf->apv_bufs[2] = NULL; 1741 } 1742 1743 ps_video_encode_ip->u4_is_last = is_last; 1744 ps_video_encode_ip->u4_mb_info_type = ps_app_ctxt->u4_mb_info_type; 1745 ps_video_encode_ip->u4_pic_info_type = ps_app_ctxt->u4_pic_info_type;; 1746 ps_video_encode_op->s_out_buf.pv_buf= NULL; 1747 ps_video_encode_ip->u4_timestamp_high = u4_timestamp_high; 1748 ps_video_encode_ip->u4_timestamp_low = u4_timestamp_low; 1749 1750 1751 GETTIME(&ps_app_ctxt->enc_last_time); 1752 1753 status = ih264e_api_function(ps_enc, &ih264e_video_encode_ip, &ih264e_video_encode_op); 1754 1755 if (IV_SUCCESS != status) 1756 { 1757 printf("Encode Frame failed = 0x%x\n", ih264e_video_encode_op.s_ive_op.u4_error_code); 1758 break; 1759 } 1760 1761 #ifdef WINDOWS_TIMER 1762 QueryPerformanceFrequency ( &frequency); 1763 #endif 1764 GETTIME(&curtime); 1765 ELAPSEDTIME(ps_app_ctxt->enc_last_time, curtime, timetaken, frequency); 1766 ps_app_ctxt->enc_last_time = curtime; 1767 1768 #ifdef PROFILE_ENABLE 1769 { 1770 WORD32 peak_avg, id; 1771 u4_total_time += timetaken; 1772 peak_window[peak_window_idx++] = timetaken; 1773 if(peak_window_idx == PEAK_WINDOW_SIZE) 1774 peak_window_idx = 0; 1775 peak_avg = 0; 1776 for(id = 0; id < PEAK_WINDOW_SIZE; id++) 1777 { 1778 peak_avg += peak_window[id]; 1779 } 1780 peak_avg /= PEAK_WINDOW_SIZE; 1781 if (peak_avg > peak_avg_max) 1782 peak_avg_max = peak_avg; 1783 } 1784 #endif 1785 1786 /******************************************************************************/ 1787 /****************** Writing Output ********************************************/ 1788 /******************************************************************************/ 1789 num_bytes = 0; 1790 1791 if(1 == ps_video_encode_op->output_present) 1792 { 1793 num_bytes = ps_video_encode_op->s_out_buf.u4_bytes; 1794 buff_size = ps_video_encode_op->s_out_buf.u4_bufsize; 1795 pu1_buf = (UWORD8*)ps_video_encode_op->s_out_buf.pv_buf; 1796 1797 status = write_output(ps_app_ctxt->fp_op, pu1_buf, num_bytes); 1798 if(IV_SUCCESS != status) 1799 { 1800 printf("Error: Unable to write to output file\n"); 1801 break; 1802 } 1803 } 1804 1805 /* free input bufer if codec returns a valid input buffer */ 1806 if (ps_video_encode_op->s_inp_buf.apv_bufs[0]) 1807 { 1808 /* Reuse of freed input buffer */ 1809 for(i = 0; i < DEFAULT_MAX_INPUT_BUFS; i++) 1810 { 1811 if(ps_app_ctxt->as_input_buf[i].pu1_buf == ps_video_encode_op->s_inp_buf.apv_bufs[0]) 1812 { 1813 ps_app_ctxt->as_input_buf[i].u4_is_free = 1; 1814 break; 1815 } 1816 } 1817 } 1818 1819 /* free output buffer if codec returns a valid output buffer */ 1820 // if(ps_video_encode_op->s_out_buf.pv_buf) 1821 { 1822 for(i = 0; i < DEFAULT_MAX_OUTPUT_BUFS; i++) 1823 { 1824 if(ps_app_ctxt->as_output_buf[i].pu1_buf == ps_video_encode_op->s_out_buf.pv_buf) 1825 { 1826 ps_app_ctxt->as_output_buf[i].u4_is_free = 1; 1827 break; 1828 } 1829 } 1830 } 1831 1832 /********************************************************************** 1833 * Print stats 1834 **********************************************************************/ 1835 { 1836 UWORD8 u1_pic_type[][5] = 1837 { "IDR", "I", "P", "B", "NA" }; 1838 WORD32 lookup_idx = 0; 1839 1840 if (ih264e_video_encode_op.s_ive_op.u4_encoded_frame_type 1841 == IV_IDR_FRAME) 1842 { 1843 lookup_idx = 0; 1844 } 1845 else if(ih264e_video_encode_op.s_ive_op.u4_encoded_frame_type 1846 == IV_I_FRAME) 1847 { 1848 lookup_idx = 1; 1849 } 1850 else if(ih264e_video_encode_op.s_ive_op.u4_encoded_frame_type 1851 == IV_P_FRAME) 1852 { 1853 lookup_idx = 2; 1854 } 1855 else if(ih264e_video_encode_op.s_ive_op.u4_encoded_frame_type 1856 == IV_B_FRAME) 1857 { 1858 lookup_idx = 3; 1859 } 1860 else if(ih264e_video_encode_op.s_ive_op.u4_encoded_frame_type 1861 == IV_NA_FRAME) 1862 { 1863 lookup_idx = 4; 1864 } 1865 1866 if (ih264e_video_encode_op.s_ive_op.u4_encoded_frame_type 1867 != IV_NA_FRAME) 1868 { 1869 ps_app_ctxt->u4_pics_cnt++; 1870 ps_app_ctxt->avg_time = u4_total_time / ps_app_ctxt->u4_pics_cnt; 1871 ps_app_ctxt->u4_total_bytes += num_bytes; 1872 } 1873 1874 if (ps_app_ctxt->u4_psnr_enable == 0) 1875 { 1876 printf("[%s] PicNum %4d Bytes Generated %6d TimeTaken(microsec): %6d AvgTime: %6d PeakAvgTimeMax: %6d\n", 1877 u1_pic_type[lookup_idx], ps_app_ctxt->u4_pics_cnt, 1878 num_bytes, timetaken, ps_app_ctxt->avg_time, 1879 peak_avg_max); 1880 } 1881 } 1882 1883 1884 /* For psnr computation, we need to read the correct input frame and 1885 * compare with recon. The difficulty with doing it is that we only know 1886 * that the frame number of recon is monotonically increasing. There 1887 * may be gaps in the recon if any pre or post enc skip happens. There are 1888 * 3 senarios 1889 * 1) A frame is encoded -> returns the pic type 1890 * 2) A frame is not encoded -> Encoder is waiting, the frame may get 1891 * encoded later 1892 * 3) A frame is not encoded -> A post enc or pre enc skip happend. The 1893 * frame is not going to be encoded 1894 * 1895 * The 1st and 2nd scenarios are easy, since we just needs to increment 1896 * recon cnt whenever we get a valid recon. This cnt can we used to 1897 * sync the recon and input 1898 * 3rd scenario in conjuction with 2nd will pose problems. Even if 1899 * the returning frame is NA, we donot know we should increment the 1900 * recon cnt or not becasue it can be case 2 or case 3. 1901 * 1902 * Solutions: 1903 * ------------------------- 1904 * One way to over come this will be to return more information as of 1905 * the frame type. We can send if a frame was skipped as a part of the 1906 * return frame type. 1907 * This will not work. Since the output and recon are not in sync, we 1908 * cannot use the current output frame type to determine if a recon 1909 * is present currently or not. We need some other way to acheive this. 1910 * 1911 * Other way to do this which is cleaner and maintains the seperation 1912 * between recon and the ouptut is to set the width [& height] of output recon 1913 * buffer to be zero. Hence we will in effect be saying :"look there 1914 * is a recon, but due to frame not being encoded it is having a width 0". 1915 * To be more clear we need to make height also to be zero. 1916 * 1917 * But are we using these variables for allocating and deallocating 1918 * the buffers some where ? No we are not. The buffer gets re-init 1919 * at every encode call 1920 * 1921 * Fixes 1922 * ------------------------ 1923 * Currently the recon buff width and height are set in the encoder. 1924 * This will not work now because since recon and input are not 1925 * in sync. Hence a recon buff sent at time stamp x will get used to 1926 * fill recon of input at time stamp y (x > y). If we reduced the 1927 * frame dimensions in between, the recon buffer will not have enough 1928 * space. Hence we need to set the with and height appropriatley inside 1929 * lib itself. 1930 */ 1931 1932 if (ps_app_ctxt->u4_recon_enable || ps_app_ctxt->u4_chksum_enable 1933 || ps_app_ctxt->u4_psnr_enable) 1934 { 1935 if (ps_video_encode_op->dump_recon) 1936 { 1937 s_recon_buf = ps_video_encode_op->s_recon_buf; 1938 1939 /* Read input for psnr computuation */ 1940 if (ps_app_ctxt->u4_psnr_enable) 1941 read_input(ps_app_ctxt->fp_psnr_ip, &s_inp_buf); 1942 1943 /* if we have a valid recon buffer do the assocated tasks */ 1944 if (s_recon_buf.au4_wd[0]) 1945 { 1946 /* Dump recon when enabled, and output bytes != 0 */ 1947 if (ps_app_ctxt->u4_recon_enable) 1948 { 1949 status = write_recon(ps_app_ctxt->fp_recon, &s_recon_buf); 1950 if (IV_SUCCESS != status) 1951 { 1952 printf("Error: Unable to write to recon file\n"); 1953 break; 1954 } 1955 } 1956 1957 if (ps_app_ctxt->u4_psnr_enable) 1958 { 1959 compute_psnr(ps_app_ctxt, &s_recon_buf, &s_inp_buf); 1960 } 1961 1962 1963 if (ps_app_ctxt->u4_chksum_enable) 1964 { 1965 WORD32 comp, num_comp = 2; 1966 1967 if (IV_YUV_420P == s_recon_buf.e_color_fmt) 1968 num_comp = 3; 1969 1970 for (comp = 0; comp < num_comp; comp++) 1971 { 1972 UWORD8 au1_chksum[16]; 1973 calc_md5_cksum((UWORD8 *)s_recon_buf.apv_bufs[comp], 1974 s_recon_buf.au4_strd[comp], 1975 s_recon_buf.au4_wd[comp], 1976 s_recon_buf.au4_ht[comp], 1977 au1_chksum); 1978 fwrite(au1_chksum, sizeof(UWORD8), 16, ps_app_ctxt->fp_chksum); 1979 } 1980 } 1981 } 1982 } 1983 } 1984 1985 u4_timestamp_low++; 1986 1987 /* Break if all the encoded frames are taken from encoder */ 1988 if (1 == ps_video_encode_op->u4_is_last) 1989 { 1990 break; 1991 } 1992 } 1993 1994 /* Pic count is 1 more than actual num frames encoded, because last call is to just get the output */ 1995 ps_app_ctxt->u4_pics_cnt--; 1996 1997 if(ps_app_ctxt->u4_psnr_enable) 1998 { 1999 print_average_psnr(ps_app_ctxt); 2000 } 2001 2002 /* house keeping operations */ 2003 fclose(ps_app_ctxt->fp_ip); 2004 fclose(ps_app_ctxt->fp_op); 2005 if(1 == ps_app_ctxt->u4_recon_enable) 2006 { 2007 fclose(ps_app_ctxt->fp_recon); 2008 } 2009 if(1 == ps_app_ctxt->u4_chksum_enable) 2010 { 2011 fclose(ps_app_ctxt->fp_chksum); 2012 } 2013 if(1 == ps_app_ctxt->u4_psnr_enable) 2014 { 2015 fclose(ps_app_ctxt->fp_psnr_ip); 2016 } 2017 2018 if(0 != ps_app_ctxt->u4_mb_info_type) 2019 { 2020 fclose(ps_app_ctxt->fp_mb_info); 2021 } 2022 if (ps_app_ctxt->u4_pic_info_type) 2023 { 2024 fclose(ps_app_ctxt->fp_pic_info); 2025 } 2026 2027 free_input(ps_app_ctxt); 2028 free_output(ps_app_ctxt); 2029 free_recon(ps_app_ctxt); 2030 } 2031 2032 /*****************************************************************************/ 2033 /* */ 2034 /* Function Name : main */ 2035 /* */ 2036 /* Description : Application to demonstrate codec API */ 2037 /* */ 2038 /* */ 2039 /* Inputs : argc - Number of arguments */ 2040 /* argv[] - Arguments */ 2041 /* Globals : */ 2042 /* Processing : Shows how to use create, process, control and delete */ 2043 /* */ 2044 /* Outputs : Codec output in a file */ 2045 /* Returns : */ 2046 /* */ 2047 /* Issues : Assumes both PROFILE_ENABLE to be */ 2048 /* defined for multithread decode-display working */ 2049 /* */ 2050 /* Revision History: */ 2051 /* */ 2052 /* DD MM YYYY Author(s) Changes */ 2053 /* 20 11 2013 100189 Initial Version */ 2054 /*****************************************************************************/ 2055 #ifdef IOS 2056 int h264enc_main(char * homedir,char *documentdir, int screen_wd, int screen_ht) 2057 #else 2058 int main(int argc, char *argv[]) 2059 #endif 2060 { 2061 /* Config Parameters for Encoding */ 2062 app_ctxt_t s_app_ctxt; 2063 2064 /* error string */ 2065 CHAR ac_error[STRLENGTH]; 2066 2067 /* config file name */ 2068 CHAR ac_cfg_fname[STRLENGTH]; 2069 2070 /* error status */ 2071 IV_STATUS_T status = IV_SUCCESS; 2072 #ifdef IOS 2073 /* temp var */ 2074 CHAR filename_with_path[STRLENGTH]; 2075 #endif 2076 WORD32 num_mem_recs; 2077 iv_obj_t *ps_enc; 2078 WORD32 i; 2079 FILE *fp_cfg = NULL; 2080 2081 #ifdef X86_MINGW 2082 2083 /* For getting printfs without any delay in eclipse */ 2084 setvbuf(stdout, NULL, _IONBF, 0); 2085 setvbuf(stderr, NULL, _IONBF, 0); 2086 2087 #endif 2088 2089 init_default_params(&s_app_ctxt); 2090 2091 #ifndef IOS 2092 2093 /* Usage */ 2094 if(argc < 2) 2095 { 2096 printf("Using enc.cfg as configuration file \n"); 2097 strcpy(ac_cfg_fname, "enc.cfg"); 2098 } 2099 else if(argc == 2) 2100 { 2101 if (!strcmp(argv[1], "--help")) 2102 { 2103 print_usage(); 2104 exit(-1); 2105 } 2106 strcpy(ac_cfg_fname, argv[1]); 2107 } 2108 2109 #else 2110 strcpy(ac_cfg_fname, "test.cfg"); 2111 2112 #endif 2113 2114 /*************************************************************************/ 2115 /* Parse arguments */ 2116 /*************************************************************************/ 2117 2118 #ifndef IOS 2119 2120 /* Read command line arguments */ 2121 if(argc > 2) 2122 { 2123 for(i = 1; i + 1 < argc; i += 2) 2124 { 2125 if(CONFIG == get_argument(argv[i])) 2126 { 2127 strcpy(ac_cfg_fname, argv[i + 1]); 2128 if((fp_cfg = fopen(ac_cfg_fname, "r")) == NULL) 2129 { 2130 sprintf(ac_error, 2131 "Could not open Configuration file %s", 2132 ac_cfg_fname); 2133 codec_exit(ac_error); 2134 } 2135 read_cfg_file(&s_app_ctxt, fp_cfg); 2136 fclose(fp_cfg); 2137 } 2138 else 2139 { 2140 parse_argument(&s_app_ctxt, argv[i], argv[i + 1]); 2141 } 2142 } 2143 } 2144 else 2145 { 2146 if((fp_cfg = fopen(ac_cfg_fname, "r")) == NULL) 2147 { 2148 sprintf(ac_error, "Could not open Configuration file %s", 2149 ac_cfg_fname); 2150 codec_exit(ac_error); 2151 } 2152 read_cfg_file(&s_app_ctxt, fp_cfg); 2153 fclose(fp_cfg); 2154 } 2155 2156 #else 2157 2158 sprintf(filename_with_path, "%s/%s", homedir, "enc.cfg"); 2159 if((fp_cfg = fopen(filename_with_path, "r")) == NULL) 2160 { 2161 sprintf(ac_error, "Could not open Configuration file %s", 2162 ac_cfg_fname); 2163 codec_exit(ac_error); 2164 2165 } 2166 read_cfg_file(&s_app_ctxt, fp_cfg); 2167 fclose(fp_cfg); 2168 2169 #endif 2170 2171 2172 validate_params(&s_app_ctxt); 2173 2174 2175 /*************************************************************************/ 2176 /* Getting Number of MemRecords */ 2177 /*************************************************************************/ 2178 { 2179 ih264e_num_mem_rec_ip_t s_num_mem_rec_ip; 2180 ih264e_num_mem_rec_op_t s_num_mem_rec_op; 2181 2182 s_num_mem_rec_ip.s_ive_ip.u4_size = sizeof(ih264e_num_mem_rec_ip_t); 2183 s_num_mem_rec_op.s_ive_op.u4_size = sizeof(ih264e_num_mem_rec_op_t); 2184 2185 s_num_mem_rec_ip.s_ive_ip.e_cmd = IV_CMD_GET_NUM_MEM_REC; 2186 2187 status = ih264e_api_function(0, &s_num_mem_rec_ip, &s_num_mem_rec_op); 2188 2189 if(status != IV_SUCCESS) 2190 { 2191 sprintf(ac_error, "Get number of memory records failed = 0x%x\n", s_num_mem_rec_op.s_ive_op.u4_error_code); 2192 codec_exit(ac_error); 2193 } 2194 2195 s_app_ctxt.u4_num_mem_rec = num_mem_recs = s_num_mem_rec_op.s_ive_op.u4_num_mem_rec; 2196 } 2197 2198 /* Allocate array to hold memory records */ 2199 s_app_ctxt.ps_mem_rec = (iv_mem_rec_t *) malloc(num_mem_recs * sizeof(iv_mem_rec_t)); 2200 if(NULL == s_app_ctxt.ps_mem_rec) 2201 { 2202 2203 sprintf(ac_error, "Unable to allocate memory for hold memory records: Size %d", (WORD32)(num_mem_recs * sizeof(iv_mem_rec_t))); 2204 codec_exit(ac_error); 2205 } 2206 2207 { 2208 iv_mem_rec_t *ps_mem_rec; 2209 ps_mem_rec = s_app_ctxt.ps_mem_rec; 2210 for(i = 0; i < num_mem_recs; i++) 2211 { 2212 ps_mem_rec->u4_size = sizeof(iv_mem_rec_t); 2213 ps_mem_rec->pv_base = NULL; 2214 ps_mem_rec->u4_mem_size = 0; 2215 ps_mem_rec->u4_mem_alignment = 0; 2216 ps_mem_rec->e_mem_type = IV_NA_MEM_TYPE; 2217 2218 ps_mem_rec++; 2219 } 2220 } 2221 2222 /*************************************************************************/ 2223 /* Getting MemRecords Attributes */ 2224 /*************************************************************************/ 2225 { 2226 ih264e_fill_mem_rec_ip_t s_fill_mem_rec_ip; 2227 ih264e_fill_mem_rec_op_t s_fill_mem_rec_op; 2228 2229 s_fill_mem_rec_ip.s_ive_ip.u4_size = sizeof(ih264e_fill_mem_rec_ip_t); 2230 s_fill_mem_rec_op.s_ive_op.u4_size = sizeof(ih264e_fill_mem_rec_op_t); 2231 2232 s_fill_mem_rec_ip.s_ive_ip.e_cmd = IV_CMD_FILL_NUM_MEM_REC; 2233 s_fill_mem_rec_ip.s_ive_ip.ps_mem_rec = s_app_ctxt.ps_mem_rec; 2234 s_fill_mem_rec_ip.s_ive_ip.u4_num_mem_rec = s_app_ctxt.u4_num_mem_rec; 2235 s_fill_mem_rec_ip.s_ive_ip.u4_max_wd = s_app_ctxt.u4_max_wd; 2236 s_fill_mem_rec_ip.s_ive_ip.u4_max_ht = s_app_ctxt.u4_max_ht; 2237 s_fill_mem_rec_ip.s_ive_ip.u4_max_level = s_app_ctxt.u4_max_level; 2238 s_fill_mem_rec_ip.s_ive_ip.e_color_format = DEFAULT_INP_COLOR_FMT; 2239 s_fill_mem_rec_ip.s_ive_ip.u4_max_ref_cnt = DEFAULT_MAX_REF_FRM; 2240 s_fill_mem_rec_ip.s_ive_ip.u4_max_reorder_cnt = DEFAULT_MAX_REORDER_FRM; 2241 s_fill_mem_rec_ip.s_ive_ip.u4_max_srch_rng_x = DEFAULT_MAX_SRCH_RANGE_X; 2242 s_fill_mem_rec_ip.s_ive_ip.u4_max_srch_rng_y = DEFAULT_MAX_SRCH_RANGE_Y; 2243 2244 status = ih264e_api_function(0, &s_fill_mem_rec_ip, &s_fill_mem_rec_op); 2245 2246 if(status != IV_SUCCESS) 2247 { 2248 sprintf(ac_error, "Fill memory records failed = 0x%x\n", 2249 s_fill_mem_rec_op.s_ive_op.u4_error_code); 2250 codec_exit(ac_error); 2251 } 2252 } 2253 2254 /*************************************************************************/ 2255 /* Allocating Memory for Mem Records */ 2256 /*************************************************************************/ 2257 { 2258 WORD32 total_size; 2259 iv_mem_rec_t *ps_mem_rec; 2260 total_size = 0; 2261 2262 ps_mem_rec = s_app_ctxt.ps_mem_rec; 2263 for(i = 0; i < num_mem_recs; i++) 2264 { 2265 ps_mem_rec->pv_base = ih264a_aligned_malloc(ps_mem_rec->u4_mem_alignment, 2266 ps_mem_rec->u4_mem_size); 2267 if(ps_mem_rec->pv_base == NULL) 2268 { 2269 sprintf(ac_error, "Allocation failure for mem record id %d size %d\n", 2270 i, ps_mem_rec->u4_mem_size); 2271 codec_exit(ac_error); 2272 } 2273 total_size += ps_mem_rec->u4_mem_size; 2274 2275 ps_mem_rec++; 2276 } 2277 printf("\nTotal memory for codec %d\n", total_size); 2278 } 2279 2280 2281 /*************************************************************************/ 2282 /* Codec Instance Creation */ 2283 /*************************************************************************/ 2284 { 2285 ih264e_init_ip_t s_init_ip; 2286 ih264e_init_op_t s_init_op; 2287 2288 ps_enc = s_app_ctxt.ps_mem_rec[0].pv_base; 2289 ps_enc->u4_size = sizeof(iv_obj_t); 2290 ps_enc->pv_fxns = ih264e_api_function; 2291 s_app_ctxt.ps_enc = ps_enc; 2292 2293 s_init_ip.s_ive_ip.u4_size = sizeof(ih264e_init_ip_t); 2294 s_init_op.s_ive_op.u4_size = sizeof(ih264e_init_op_t); 2295 2296 s_init_ip.s_ive_ip.e_cmd = IV_CMD_INIT; 2297 s_init_ip.s_ive_ip.u4_num_mem_rec = s_app_ctxt.u4_num_mem_rec; 2298 s_init_ip.s_ive_ip.ps_mem_rec = s_app_ctxt.ps_mem_rec; 2299 s_init_ip.s_ive_ip.u4_max_wd = s_app_ctxt.u4_max_wd; 2300 s_init_ip.s_ive_ip.u4_max_ht = s_app_ctxt.u4_max_ht; 2301 s_init_ip.s_ive_ip.u4_max_ref_cnt = DEFAULT_MAX_REF_FRM; 2302 s_init_ip.s_ive_ip.u4_max_reorder_cnt = DEFAULT_MAX_REORDER_FRM; 2303 s_init_ip.s_ive_ip.u4_max_level = s_app_ctxt.u4_max_level; 2304 s_init_ip.s_ive_ip.e_inp_color_fmt = s_app_ctxt.e_inp_color_fmt; 2305 if(s_app_ctxt.u4_recon_enable || s_app_ctxt.u4_psnr_enable || s_app_ctxt.u4_chksum_enable) 2306 { 2307 s_init_ip.s_ive_ip.u4_enable_recon = 1; 2308 } 2309 else 2310 { 2311 s_init_ip.s_ive_ip.u4_enable_recon = 0; 2312 } 2313 s_init_ip.s_ive_ip.e_recon_color_fmt = s_app_ctxt.e_recon_color_fmt; 2314 s_init_ip.s_ive_ip.e_rc_mode = s_app_ctxt.u4_rc; 2315 s_init_ip.s_ive_ip.u4_max_framerate = s_app_ctxt.u4_max_frame_rate; 2316 s_init_ip.s_ive_ip.u4_max_bitrate = s_app_ctxt.u4_max_bitrate; 2317 s_init_ip.s_ive_ip.u4_num_bframes = s_app_ctxt.u4_num_bframes; 2318 s_init_ip.s_ive_ip.e_content_type = IV_PROGRESSIVE; 2319 s_init_ip.s_ive_ip.u4_max_srch_rng_x = DEFAULT_MAX_SRCH_RANGE_X; 2320 s_init_ip.s_ive_ip.u4_max_srch_rng_y = DEFAULT_MAX_SRCH_RANGE_Y; 2321 s_init_ip.s_ive_ip.e_slice_mode = s_app_ctxt.u4_slice_mode; 2322 s_init_ip.s_ive_ip.u4_slice_param = s_app_ctxt.u4_slice_param; 2323 s_init_ip.s_ive_ip.e_arch = s_app_ctxt.e_arch; 2324 s_init_ip.s_ive_ip.e_soc = s_app_ctxt.e_soc; 2325 2326 status = ih264e_api_function(ps_enc, &s_init_ip, &s_init_op); 2327 2328 if(status != IV_SUCCESS) 2329 { 2330 sprintf(ac_error, "Init memory records failed = 0x%x\n", 2331 s_init_op.s_ive_op.u4_error_code); 2332 codec_exit(ac_error); 2333 } 2334 } 2335 2336 /*************************************************************************/ 2337 /* set processor details */ 2338 /*************************************************************************/ 2339 { 2340 ih264e_ctl_set_num_cores_ip_t s_ctl_set_num_cores_ip; 2341 ih264e_ctl_set_num_cores_op_t s_ctl_set_num_cores_op; 2342 s_ctl_set_num_cores_ip.s_ive_ip.e_cmd = IVE_CMD_VIDEO_CTL; 2343 s_ctl_set_num_cores_ip.s_ive_ip.e_sub_cmd = IVE_CMD_CTL_SET_NUM_CORES; 2344 s_ctl_set_num_cores_ip.s_ive_ip.u4_num_cores = s_app_ctxt.u4_num_cores; 2345 s_ctl_set_num_cores_ip.s_ive_ip.u4_timestamp_high = 0; 2346 s_ctl_set_num_cores_ip.s_ive_ip.u4_timestamp_low = 0; 2347 s_ctl_set_num_cores_ip.s_ive_ip.u4_size = sizeof(ih264e_ctl_set_num_cores_ip_t); 2348 2349 s_ctl_set_num_cores_op.s_ive_op.u4_size = sizeof(ih264e_ctl_set_num_cores_op_t); 2350 2351 status = ih264e_api_function(ps_enc, (void *) &s_ctl_set_num_cores_ip, 2352 (void *) &s_ctl_set_num_cores_op); 2353 if(status != IV_SUCCESS) 2354 { 2355 sprintf(ac_error, "Unable to set processor params = 0x%x\n", 2356 s_ctl_set_num_cores_op.s_ive_op.u4_error_code); 2357 codec_exit(ac_error); 2358 } 2359 2360 } 2361 2362 /*************************************************************************/ 2363 /* Get Codec Version */ 2364 /*************************************************************************/ 2365 { 2366 ih264e_ctl_getversioninfo_ip_t s_ctl_set_getversioninfo_ip; 2367 ih264e_ctl_getversioninfo_op_t s_ctl_set_getversioninfo_op; 2368 CHAR ac_version_string[STRLENGTH]; 2369 s_ctl_set_getversioninfo_ip.s_ive_ip.e_cmd = IVE_CMD_VIDEO_CTL; 2370 s_ctl_set_getversioninfo_ip.s_ive_ip.e_sub_cmd = IVE_CMD_CTL_GETVERSION; 2371 s_ctl_set_getversioninfo_ip.s_ive_ip.pu1_version = (UWORD8 *)ac_version_string; 2372 s_ctl_set_getversioninfo_ip.s_ive_ip.u4_version_bufsize = sizeof(ac_version_string); 2373 s_ctl_set_getversioninfo_ip.s_ive_ip.u4_size = sizeof(ih264e_ctl_getversioninfo_ip_t); 2374 s_ctl_set_getversioninfo_op.s_ive_op.u4_size = sizeof(ih264e_ctl_getversioninfo_op_t); 2375 2376 status = ih264e_api_function(ps_enc, (void *) &s_ctl_set_getversioninfo_ip, 2377 (void *) &s_ctl_set_getversioninfo_op); 2378 if(status != IV_SUCCESS) 2379 { 2380 sprintf(ac_error, "Unable to get codec version = 0x%x\n", 2381 s_ctl_set_getversioninfo_op.s_ive_op.u4_error_code); 2382 codec_exit(ac_error); 2383 } 2384 printf("CODEC VERSION %s\n", ac_version_string); 2385 } 2386 2387 /*************************************************************************/ 2388 /* Get I/O Buffer Requirement */ 2389 /*************************************************************************/ 2390 { 2391 ih264e_ctl_getbufinfo_ip_t s_get_buf_info_ip; 2392 ih264e_ctl_getbufinfo_op_t s_get_buf_info_op; 2393 2394 s_get_buf_info_ip.s_ive_ip.u4_size = sizeof(ih264e_ctl_getbufinfo_ip_t); 2395 s_get_buf_info_op.s_ive_op.u4_size = sizeof(ih264e_ctl_getbufinfo_op_t); 2396 2397 s_get_buf_info_ip.s_ive_ip.e_cmd = IVE_CMD_VIDEO_CTL; 2398 s_get_buf_info_ip.s_ive_ip.e_sub_cmd = IVE_CMD_CTL_GETBUFINFO; 2399 s_get_buf_info_ip.s_ive_ip.u4_max_ht = s_app_ctxt.u4_max_ht; 2400 s_get_buf_info_ip.s_ive_ip.u4_max_wd = s_app_ctxt.u4_max_wd; 2401 s_get_buf_info_ip.s_ive_ip.e_inp_color_fmt = s_app_ctxt.e_inp_color_fmt; 2402 2403 status = ih264e_api_function(ps_enc, &s_get_buf_info_ip, &s_get_buf_info_op); 2404 2405 if (status != IV_SUCCESS) 2406 { 2407 sprintf(ac_error, "Unable to get I/O buffer requirements = 0x%x\n", 2408 s_get_buf_info_op.s_ive_op.u4_error_code); 2409 codec_exit(ac_error); 2410 } 2411 s_app_ctxt.s_get_buf_info_op = s_get_buf_info_op; 2412 } 2413 2414 /*****************************************************************************/ 2415 /* Add the following initializations based on the parameters in context */ 2416 /*****************************************************************************/ 2417 2418 2419 /*****************************************************************************/ 2420 /* Video control Set Frame dimensions */ 2421 /*****************************************************************************/ 2422 s_app_ctxt.u4_strd = s_app_ctxt.u4_wd; 2423 set_dimensions(&s_app_ctxt, 0, 0); 2424 2425 /*****************************************************************************/ 2426 /* Video control Set Frame rates */ 2427 /*****************************************************************************/ 2428 set_frame_rate(&s_app_ctxt, 0, 0); 2429 2430 /*****************************************************************************/ 2431 /* Video control Set IPE Params */ 2432 /*****************************************************************************/ 2433 set_ipe_params(&s_app_ctxt, 0, 0); 2434 2435 /*****************************************************************************/ 2436 /* Video control Set Bitrate */ 2437 /*****************************************************************************/ 2438 set_bit_rate(&s_app_ctxt, 0, 0); 2439 2440 /*****************************************************************************/ 2441 /* Video control Set QP */ 2442 /*****************************************************************************/ 2443 set_qp(&s_app_ctxt,0,0); 2444 2445 /*****************************************************************************/ 2446 /* Video control Set AIR params */ 2447 /*****************************************************************************/ 2448 set_air_params(&s_app_ctxt,0,0); 2449 2450 /*****************************************************************************/ 2451 /* Video control Set VBV params */ 2452 /*****************************************************************************/ 2453 set_vbv_params(&s_app_ctxt,0,0); 2454 2455 /*****************************************************************************/ 2456 /* Video control Set Motion estimation params */ 2457 /*****************************************************************************/ 2458 set_me_params(&s_app_ctxt,0,0); 2459 2460 /*****************************************************************************/ 2461 /* Video control Set GOP params */ 2462 /*****************************************************************************/ 2463 set_gop_params(&s_app_ctxt, 0, 0); 2464 2465 /*****************************************************************************/ 2466 /* Video control Set Deblock params */ 2467 /*****************************************************************************/ 2468 set_deblock_params(&s_app_ctxt, 0, 0); 2469 2470 /*****************************************************************************/ 2471 /* Video control Set Profile params */ 2472 /*****************************************************************************/ 2473 set_profile_params(&s_app_ctxt, 0, 0); 2474 2475 /*****************************************************************************/ 2476 /* Video control Set in Encode header mode */ 2477 /*****************************************************************************/ 2478 set_enc_mode(&s_app_ctxt, 0, 0, IVE_ENC_MODE_PICTURE); 2479 2480 #ifdef IOS 2481 /* Correct file paths */ 2482 sprintf(filename_with_path, "%s/%s", documentdir, s_app_ctxt.ac_ip_fname); 2483 strcpy (s_app_ctxt.ac_ip_fname, filename_with_path); 2484 2485 sprintf(filename_with_path, "%s/%s", documentdir, s_app_ctxt.ac_op_fname); 2486 strcpy (s_app_ctxt.ac_op_fname, filename_with_path); 2487 2488 sprintf(filename_with_path, "%s/%s", documentdir, s_app_ctxt.ac_recon_fname); 2489 strcpy (s_app_ctxt.ac_recon_fname, filename_with_path); 2490 2491 sprintf(filename_with_path, "%s/%s", documentdir, s_app_ctxt.ac_chksum_fname); 2492 strcpy (s_app_ctxt.ac_chksum_fname, filename_with_path); 2493 2494 sprintf(filename_with_path, "%s/%s", documentdir, s_app_ctxt.ac_mb_info_fname); 2495 strcpy (s_app_ctxt.ac_mb_info_fname, filename_with_path); 2496 2497 sprintf(filename_with_path, "%s/%s", documentdir, s_app_ctxt.ac_pic_info_fname); 2498 strcpy (s_app_ctxt.ac_pic_info_fname, filename_with_path); 2499 #endif 2500 2501 /*************************************************************************/ 2502 /* begin encoding */ 2503 /*************************************************************************/ 2504 2505 synchronous_encode(ps_enc, &s_app_ctxt); 2506 2507 { 2508 DOUBLE bytes_per_frame; 2509 DOUBLE bytes_per_second; 2510 WORD32 achieved_bitrate; 2511 2512 if(s_app_ctxt.u4_pics_cnt != 0) 2513 { 2514 bytes_per_frame = (s_app_ctxt.u4_total_bytes) / (s_app_ctxt.u4_pics_cnt); 2515 } 2516 else 2517 { 2518 bytes_per_frame = 0; 2519 } 2520 bytes_per_second = (bytes_per_frame * s_app_ctxt.u4_tgt_frame_rate); 2521 2522 achieved_bitrate = bytes_per_second * 8; 2523 2524 printf("\nEncoding Completed\n"); 2525 printf("Summary\n"); 2526 printf("Input filename : %s\n", s_app_ctxt.ac_ip_fname); 2527 printf("Output filename : %s\n", s_app_ctxt.ac_op_fname); 2528 printf("Output Width : %-4d\n", s_app_ctxt.u4_wd); 2529 printf("Output Height : %-4d\n", s_app_ctxt.u4_ht); 2530 printf("Target Bitrate (bps) : %-4d\n", s_app_ctxt.u4_bitrate); 2531 printf("Achieved Bitrate (bps) : %-4d\n", achieved_bitrate); 2532 printf("Average Time per Frame : %-4d\n", s_app_ctxt.avg_time); 2533 printf("Achieved FPS : %-4.2f\n", 1000000.0 / s_app_ctxt.avg_time); 2534 } 2535 2536 2537 /*************************************************************************/ 2538 /* Close Codec Instance */ 2539 /*************************************************************************/ 2540 { 2541 ih264e_retrieve_mem_rec_ip_t s_retrieve_mem_ip; 2542 ih264e_retrieve_mem_rec_op_t s_retrieve_mem_op; 2543 iv_mem_rec_t *ps_mem_rec; 2544 s_retrieve_mem_ip.s_ive_ip.u4_size = 2545 sizeof(ih264e_retrieve_mem_rec_ip_t); 2546 s_retrieve_mem_op.s_ive_op.u4_size = 2547 sizeof(ih264e_retrieve_mem_rec_op_t); 2548 2549 s_retrieve_mem_ip.s_ive_ip.e_cmd = IV_CMD_RETRIEVE_MEMREC; 2550 s_retrieve_mem_ip.s_ive_ip.ps_mem_rec = s_app_ctxt.ps_mem_rec; 2551 2552 status = ih264e_api_function(ps_enc, &s_retrieve_mem_ip, 2553 &s_retrieve_mem_op); 2554 2555 if(status != IV_SUCCESS) 2556 { 2557 sprintf(ac_error, "Unable to retrieve memory records = 0x%x\n", 2558 s_retrieve_mem_op.s_ive_op.u4_error_code); 2559 codec_exit(ac_error); 2560 } 2561 2562 /* Free memory records */ 2563 ps_mem_rec = s_app_ctxt.ps_mem_rec; 2564 for(i = 0; i < num_mem_recs; i++) 2565 { 2566 ih264a_aligned_free(ps_mem_rec->pv_base); 2567 ps_mem_rec++; 2568 } 2569 2570 free(s_app_ctxt.ps_mem_rec); 2571 2572 } 2573 2574 return 0; 2575 } 2576 2577 2578 #ifdef ANDROID_NDK 2579 int raise(int a) 2580 { 2581 printf("Divide by zero\n"); 2582 return 0; 2583 } 2584 void __aeabi_assert(const char *assertion, const char *file, unsigned int line) 2585 { 2586 return; 2587 } 2588 #endif 2589