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 Name : main.c */ 23 /* */ 24 /* Description : Contains an application that demonstrates use of H264*/ 25 /* decoder API */ 26 /* */ 27 /* List of Functions : */ 28 /* */ 29 /* Issues / Problems : None */ 30 /* */ 31 /* Revision History : */ 32 /* */ 33 /* DD MM YYYY Author(s) Changes */ 34 /* 07 09 2012 Harish Initial Version */ 35 /*****************************************************************************/ 36 /*****************************************************************************/ 37 /* File Includes */ 38 /*****************************************************************************/ 39 #include <stdio.h> 40 #include <string.h> 41 #include <stdlib.h> 42 43 #ifdef X86_MINGW 44 #include <signal.h> 45 #endif 46 47 #ifndef IOS 48 #include <malloc.h> 49 #endif 50 #ifdef IOS_DISPLAY 51 #include "cast_types.h" 52 #else 53 #include "ih264_typedefs.h" 54 #endif 55 56 #include "iv.h" 57 #include "ivd.h" 58 #include "ih264d.h" 59 #include "ithread.h" 60 61 #ifdef WINDOWS_TIMER 62 #include <windows.h> 63 #else 64 #include <sys/time.h> 65 #endif 66 67 68 69 #define ALIGN8(x) ((((x) + 7) >> 3) << 3) 70 #define NUM_DISPLAY_BUFFERS 4 71 #define DEFAULT_FPS 30 72 73 #define ENABLE_DEGRADE 0 74 #define MAX_DISP_BUFFERS 64 75 #define EXTRA_DISP_BUFFERS 8 76 #define STRLENGTH 1000 77 78 //#define TEST_FLUSH 79 #define FLUSH_FRM_CNT 100 80 //#define APP_EXTRA_BUFS 1 81 82 #ifdef IOS 83 #define PATHLENMAX 500 84 char filename_with_path[PATHLENMAX]; 85 #endif 86 87 #ifdef PROFILE_ENABLE 88 #ifdef WINDOWS_TIMER 89 typedef LARGE_INTEGER TIMER; 90 #else 91 //#ifdef GCC_TIMER 92 typedef struct timeval TIMER; 93 //#endif 94 #endif 95 #else 96 typedef WORD32 TIMER; 97 #endif 98 99 #ifdef PROFILE_ENABLE 100 #ifdef WINDOWS_TIMER 101 #define GETTIME(timer) QueryPerformanceCounter(timer); 102 #else 103 //#ifdef GCC_TIMER 104 #define GETTIME(timer) gettimeofday(timer,NULL); 105 //#endif 106 #endif 107 108 #ifdef WINDOWS_TIMER 109 #define ELAPSEDTIME(s_start_timer,s_end_timer, s_elapsed_time, frequency) \ 110 { \ 111 TIMER s_temp_time; \ 112 s_temp_time.LowPart = s_end_timer.LowPart - s_start_timer.LowPart ; \ 113 s_elapsed_time = (UWORD32) ( ((DOUBLE)s_temp_time.LowPart / (DOUBLE)frequency.LowPart ) * 1000000); \ 114 } 115 #else 116 //#ifdef GCC_TIMER 117 #define ELAPSEDTIME(s_start_timer,s_end_timer, s_elapsed_time, frequency) \ 118 s_elapsed_time = ((s_end_timer.tv_sec - s_start_timer.tv_sec) * 1000000) + (s_end_timer.tv_usec - s_start_timer.tv_usec); 119 //#endif 120 #endif 121 122 #else 123 #define GETTIME(timer) 124 #define ELAPSEDTIME(s_start_timer,s_end_timer, s_elapsed_time, frequency) 125 #endif 126 127 128 /* Function declarations */ 129 #ifndef MD5_DISABLE 130 void calc_md5_cksum(UWORD8 *pu1_inbuf,UWORD32 u4_stride,UWORD32 u4_width,UWORD32 u4_height,UWORD8 *pu1_cksum_p ); 131 #else 132 #define calc_md5_cksum(a, b, c, d, e) 133 #endif 134 #ifdef SDL_DISPLAY 135 void* sdl_disp_init(UWORD32, UWORD32, WORD32, WORD32, WORD32, WORD32, WORD32, WORD32 *, WORD32 *); 136 void sdl_alloc_disp_buffers(void *); 137 void sdl_display(void *, WORD32 ); 138 void sdl_set_disp_buffers(void *, WORD32, UWORD8 **, UWORD8 **, UWORD8 **); 139 void sdl_disp_deinit(void *); 140 void sdl_disp_usleep(UWORD32); 141 IV_COLOR_FORMAT_T sdl_get_color_fmt(void); 142 UWORD32 sdl_get_stride(void); 143 #endif 144 145 #ifdef INTEL_CE5300 146 void* gdl_disp_init(UWORD32, UWORD32, WORD32, WORD32, WORD32, WORD32, WORD32, WORD32 *, WORD32 *); 147 void gdl_alloc_disp_buffers(void *); 148 void gdl_display(void *, WORD32 ); 149 void gdl_set_disp_buffers(void *, WORD32, UWORD8 **, UWORD8 **, UWORD8 **); 150 void gdl_disp_deinit(void *); 151 void gdl_disp_usleep(UWORD32); 152 IV_COLOR_FORMAT_T gdl_get_color_fmt(void); 153 UWORD32 gdl_get_stride(void); 154 #endif 155 156 #ifdef FBDEV_DISPLAY 157 void* fbd_disp_init(UWORD32, UWORD32, WORD32, WORD32, WORD32, WORD32, WORD32, WORD32 *, WORD32 *); 158 void fbd_alloc_disp_buffers(void *); 159 void fbd_display(void *, WORD32 ); 160 void fbd_set_disp_buffers(void *, WORD32, UWORD8 **, UWORD8 **, UWORD8 **); 161 void fbd_disp_deinit(void *); 162 void fbd_disp_usleep(UWORD32); 163 IV_COLOR_FORMAT_T fbd_get_color_fmt(void); 164 UWORD32 fbd_get_stride(void); 165 #endif 166 167 #ifdef IOS_DISPLAY 168 void* ios_disp_init(UWORD32, UWORD32, WORD32, WORD32, WORD32, WORD32, WORD32, WORD32 *, WORD32 *); 169 void ios_alloc_disp_buffers(void *); 170 void ios_display(void *, WORD32 ); 171 void ios_set_disp_buffers(void *, WORD32, UWORD8 **, UWORD8 **, UWORD8 **); 172 void ios_disp_deinit(void *); 173 void ios_disp_usleep(UWORD32); 174 IV_COLOR_FORMAT_T ios_get_color_fmt(void); 175 UWORD32 ios_get_stride(void); 176 #endif 177 178 typedef struct 179 { 180 UWORD32 u4_piclen_flag; 181 UWORD32 u4_file_save_flag; 182 UWORD32 u4_chksum_save_flag; 183 UWORD32 u4_max_frm_ts; 184 IV_COLOR_FORMAT_T e_output_chroma_format; 185 IVD_ARCH_T e_arch; 186 IVD_SOC_T e_soc; 187 UWORD32 dump_q_rd_idx; 188 UWORD32 dump_q_wr_idx; 189 WORD32 disp_q_wr_idx; 190 WORD32 disp_q_rd_idx; 191 192 void *cocodec_obj; 193 UWORD32 u4_share_disp_buf; 194 UWORD32 num_disp_buf; 195 UWORD32 b_pic_present; 196 UWORD32 u4_disable_dblk_level; 197 WORD32 i4_degrade_type; 198 WORD32 i4_degrade_pics; 199 UWORD32 u4_num_cores; 200 UWORD32 disp_delay; 201 WORD32 trace_enable; 202 CHAR ac_trace_fname[STRLENGTH]; 203 CHAR ac_piclen_fname[STRLENGTH]; 204 CHAR ac_ip_fname[STRLENGTH]; 205 CHAR ac_op_fname[STRLENGTH]; 206 CHAR ac_op_chksum_fname[STRLENGTH]; 207 ivd_out_bufdesc_t s_disp_buffers[MAX_DISP_BUFFERS]; 208 iv_yuv_buf_t s_disp_frm_queue[MAX_DISP_BUFFERS]; 209 UWORD32 s_disp_frm_id_queue[MAX_DISP_BUFFERS]; 210 UWORD32 loopback; 211 UWORD32 display; 212 UWORD32 full_screen; 213 UWORD32 fps; 214 UWORD32 max_wd; 215 UWORD32 max_ht; 216 UWORD32 max_level; 217 218 UWORD32 u4_strd; 219 220 /* For signalling to display thread */ 221 UWORD32 u4_pic_wd; 222 UWORD32 u4_pic_ht; 223 224 /* For IOS diplay */ 225 WORD32 i4_screen_wd; 226 WORD32 i4_screen_ht; 227 228 //UWORD32 u4_output_present; 229 WORD32 quit; 230 WORD32 paused; 231 232 233 void *pv_disp_ctx; 234 void *display_thread_handle; 235 WORD32 display_thread_created; 236 volatile WORD32 display_init_done; 237 volatile WORD32 display_deinit_flag; 238 239 void *(*disp_init)(UWORD32, UWORD32, WORD32, WORD32, WORD32, WORD32, WORD32, WORD32 *, WORD32 *); 240 void (*alloc_disp_buffers)(void *); 241 void (*display_buffer)(void *, WORD32); 242 void (*set_disp_buffers)(void *, WORD32, UWORD8 **, UWORD8 **, UWORD8 **); 243 void (*disp_deinit)(void *); 244 void (*disp_usleep)(UWORD32); 245 IV_COLOR_FORMAT_T (*get_color_fmt)(void); 246 UWORD32 (*get_stride)(void); 247 } vid_dec_ctx_t; 248 249 250 251 typedef enum 252 { 253 INVALID, 254 HELP, 255 VERSION, 256 INPUT_FILE, 257 OUTPUT, 258 CHKSUM, 259 SAVE_OUTPUT, 260 SAVE_CHKSUM, 261 CHROMA_FORMAT, 262 NUM_FRAMES, 263 NUM_CORES, 264 DISABLE_DEBLOCK_LEVEL, 265 SHARE_DISPLAY_BUF, 266 LOOPBACK, 267 DISPLAY, 268 FULLSCREEN, 269 FPS, 270 TRACE, 271 MAX_WD, 272 MAX_HT, 273 MAX_LEVEL, 274 CONFIG, 275 276 DEGRADE_TYPE, 277 DEGRADE_PICS, 278 ARCH, 279 SOC, 280 PICLEN, 281 PICLEN_FILE, 282 } ARGUMENT_T; 283 284 typedef struct 285 { 286 CHAR argument_shortname[4]; 287 CHAR argument_name[128]; 288 ARGUMENT_T argument; 289 CHAR description[512]; 290 } argument_t; 291 292 static const argument_t argument_mapping[] = 293 { 294 {"-h", "--help", HELP, 295 "Print this help\n"}, 296 { "-c", "--config", CONFIG, 297 "config file (Default: test.cfg)\n" }, 298 299 {"-v", "--version", VERSION, 300 "Version information\n"}, 301 {"-i", "--input", INPUT_FILE, 302 "Input file\n"}, 303 {"-o", "--output", OUTPUT, 304 "Output file\n"}, 305 {"--", "--piclen", PICLEN, 306 "Flag to signal if the decoder has to use a file containing number of bytes in each picture to be fed in each call\n"}, 307 {"--", "--piclen_file", PICLEN_FILE, 308 "File containing number of bytes in each picture - each line containing one i4_size\n"}, 309 {"--", "--chksum", CHKSUM, 310 "Output MD5 Checksum file\n"}, 311 { "-s", "--save_output", SAVE_OUTPUT, 312 "Save Output file\n" }, 313 { "--", "--save_chksum", SAVE_CHKSUM, 314 "Save Check sum file\n" }, 315 {"--", "--chroma_format", CHROMA_FORMAT, 316 "Output Chroma format Supported values YUV_420P, YUV_422ILE, RGB_565, YUV_420SP_UV, YUV_420SP_VU\n" }, 317 { "-n", "--num_frames", NUM_FRAMES, 318 "Number of frames to be decoded\n" }, 319 { "--", "--num_cores", NUM_CORES, 320 "Number of cores to be used\n" }, 321 { "--", "--share_display_buf", SHARE_DISPLAY_BUF, 322 "Enable shared display buffer mode\n" }, 323 {"--", "--disable_deblock_level", DISABLE_DEBLOCK_LEVEL, 324 "Disable deblocking level : 0 to 4 - 0 Enable deblocking 4 Disable deblocking completely\n"}, 325 { "--", "--loopback", LOOPBACK, 326 "Enable playback in a loop\n" }, 327 { "--", "--display", DISPLAY, 328 "Enable display (uses SDL)\n" }, 329 { "--", "--fullscreen", FULLSCREEN, 330 "Enable full screen (Only for GDL and SDL)\n" }, 331 { "--", "--fps", FPS, 332 "FPS to be used for display \n" }, 333 {"-i", "--trace", TRACE, 334 "Trace file\n"}, 335 { "--", "--max_wd", MAX_WD, 336 "Maximum width (Default: 2560) \n" }, 337 { "--", "--max_ht", MAX_HT, 338 "Maximum height (Default: 1600)\n" }, 339 340 { "--", "--max_level", MAX_LEVEL, 341 "Maximum Decoder Level (Default: 50)\n" }, 342 343 {"--", "--degrade_type", DEGRADE_TYPE, 344 "Degrade type : 0: No degrade 0th bit set : Disable SAO 1st bit set : Disable deblocking 2nd bit set : Faster inter prediction filters 3rd bit set : Fastest inter prediction filters\n" }, 345 {"--", "--degrade_pics", DEGRADE_PICS, 346 "Degrade pics : 0 : No degrade 1 : Only on non-reference frames 2 : Do not degrade every 4th or key frames 3 : All non-key frames 4 : All frames"}, 347 348 {"--", "--arch", ARCH, 349 "Set Architecture. Supported values ARM_NONEON, ARM_A9Q, ARM_A7, ARM_A5, ARM_NEONINTR,ARMV8_GENERIC, X86_GENERIC, X86_SSSE3, X86_SSE4 \n" }, 350 {"--", "--soc", SOC, 351 "Set SOC. Supported values GENERIC, HISI_37X \n" }, 352 353 }; 354 355 #define PEAK_WINDOW_SIZE 8 356 #define MAX_FRAME_WIDTH 2560 357 #define MAX_FRAME_HEIGHT 1600 358 #define MAX_LEVEL_SUPPORTED 50 359 #define MAX_REF_FRAMES 16 360 #define MAX_REORDER_FRAMES 16 361 #define DEFAULT_SHARE_DISPLAY_BUF 0 362 #define STRIDE 0 363 #define DEFAULT_NUM_CORES 1 364 365 366 #define DUMP_SINGLE_BUF 0 367 #define IV_ISFATALERROR(x) (((x) >> IVD_FATALERROR) & 0x1) 368 369 #define ivd_api_function ih264d_api_function 370 371 #ifdef IOS 372 char filename_trace[PATHLENMAX]; 373 #endif 374 375 #if ANDROID_NDK 376 /*****************************************************************************/ 377 /* */ 378 /* Function Name : raise */ 379 /* */ 380 /* Description : Needed as a workaround when the application is built in */ 381 /* Android NDK. This is an exception to be called for divide*/ 382 /* by zero error */ 383 /* */ 384 /* Inputs : a */ 385 /* Globals : */ 386 /* Processing : None */ 387 /* */ 388 /* Outputs : */ 389 /* Returns : */ 390 /* */ 391 /* Issues : */ 392 /* */ 393 /* Revision History: */ 394 /* */ 395 /* DD MM YYYY Author(s) Changes */ 396 /* 07 09 2012 100189 Initial Version */ 397 /* */ 398 /*****************************************************************************/ 399 int raise(int a) 400 { 401 printf("Divide by zero\n"); 402 return 0; 403 } 404 #endif 405 406 #ifdef _WIN32 407 /*****************************************************************************/ 408 /* Function to print library calls */ 409 /*****************************************************************************/ 410 /*****************************************************************************/ 411 /* */ 412 /* Function Name : memalign */ 413 /* */ 414 /* Description : Returns malloc data. Ideally should return aligned memory*/ 415 /* support alignment will be added later */ 416 /* */ 417 /* Inputs : alignment */ 418 /* i4_size */ 419 /* Globals : */ 420 /* Processing : */ 421 /* */ 422 /* Outputs : */ 423 /* Returns : */ 424 /* */ 425 /* Issues : */ 426 /* */ 427 /* Revision History: */ 428 /* */ 429 /* DD MM YYYY Author(s) Changes */ 430 /* 07 09 2012 100189 Initial Version */ 431 /* */ 432 /*****************************************************************************/ 433 434 void * ih264a_aligned_malloc(WORD32 alignment, WORD32 i4_size) 435 { 436 return (void *)_aligned_malloc(i4_size, alignment); 437 } 438 439 void ih264a_aligned_free(void *pv_buf) 440 { 441 _aligned_free(pv_buf); 442 return; 443 } 444 #endif 445 446 #if IOS 447 void * ih264a_aligned_malloc(WORD32 alignment, WORD32 i4_size) 448 { 449 return malloc(i4_size); 450 } 451 452 void ih264a_aligned_free(void *pv_buf) 453 { 454 free(pv_buf); 455 return; 456 } 457 #endif 458 459 #if (!defined(IOS)) && (!defined(_WIN32)) 460 void * ih264a_aligned_malloc(WORD32 alignment, WORD32 i4_size) 461 { 462 return memalign(alignment, i4_size); 463 } 464 465 void ih264a_aligned_free(void *pv_buf) 466 { 467 free(pv_buf); 468 return; 469 } 470 #endif 471 /*****************************************************************************/ 472 /* */ 473 /* Function Name : set_degrade */ 474 /* */ 475 /* Description : Control call to set degrade level */ 476 /* */ 477 /* */ 478 /* Inputs : codec_obj - Codec Handle */ 479 /* type - degrade level value between 0 to 4 */ 480 /* 0 : No degrade */ 481 /* 1st bit : Disable SAO */ 482 /* 2nd bit : Disable Deblock */ 483 /* 3rd bit : Faster MC for non-ref */ 484 /* 4th bit : Fastest MC for non-ref */ 485 /* pics - Pictures that are are degraded */ 486 /* 0 : No degrade */ 487 /* 1 : Non-ref pictures */ 488 /* 2 : Pictures at given interval are not degraded */ 489 /* 3 : All non-key pictures */ 490 /* 4 : All pictures */ 491 /* Globals : */ 492 /* Processing : Calls degrade control to the codec */ 493 /* */ 494 /* Outputs : */ 495 /* Returns : Control call return i4_status */ 496 /* */ 497 /* Issues : */ 498 /* */ 499 /* Revision History: */ 500 /* */ 501 /* DD MM YYYY Author(s) Changes */ 502 /* 07 09 2012 100189 Initial Version */ 503 /* */ 504 /*****************************************************************************/ 505 506 IV_API_CALL_STATUS_T set_degrade(void *codec_obj, UWORD32 type, WORD32 pics) 507 { 508 ih264d_ctl_degrade_ip_t s_ctl_ip; 509 ih264d_ctl_degrade_op_t s_ctl_op; 510 void *pv_api_ip, *pv_api_op; 511 IV_API_CALL_STATUS_T e_dec_status; 512 513 s_ctl_ip.u4_size = sizeof(ih264d_ctl_degrade_ip_t); 514 s_ctl_ip.i4_degrade_type = type; 515 s_ctl_ip.i4_nondegrade_interval = 4; 516 s_ctl_ip.i4_degrade_pics = pics; 517 518 s_ctl_op.u4_size = sizeof(ih264d_ctl_degrade_op_t); 519 520 pv_api_ip = (void *)&s_ctl_ip; 521 pv_api_op = (void *)&s_ctl_op; 522 523 s_ctl_ip.e_cmd = IVD_CMD_VIDEO_CTL; 524 s_ctl_ip.e_sub_cmd = (IVD_CONTROL_API_COMMAND_TYPE_T) IH264D_CMD_CTL_DEGRADE; 525 526 e_dec_status = ivd_api_function((iv_obj_t *)codec_obj, pv_api_ip, pv_api_op); 527 528 if(IV_SUCCESS != e_dec_status) 529 { 530 printf("Error in setting degrade level \n"); 531 } 532 return (e_dec_status); 533 534 } 535 536 537 538 /*****************************************************************************/ 539 /* */ 540 /* Function Name : enable_skipb_frames */ 541 /* */ 542 /* Description : Control call to enable skipping of b frames */ 543 /* */ 544 /* */ 545 /* Inputs : codec_obj : Codec handle */ 546 /* Globals : */ 547 /* Processing : Calls enable skip B frames control */ 548 /* */ 549 /* Outputs : */ 550 /* Returns : Control call return i4_status */ 551 /* */ 552 /* Issues : */ 553 /* */ 554 /* Revision History: */ 555 /* */ 556 /* DD MM YYYY Author(s) Changes */ 557 /* 07 09 2012 100189 Initial Version */ 558 /* */ 559 /*****************************************************************************/ 560 561 IV_API_CALL_STATUS_T enable_skipb_frames(void *codec_obj, 562 vid_dec_ctx_t *ps_app_ctx) 563 { 564 ivd_ctl_set_config_ip_t s_ctl_ip; 565 ivd_ctl_set_config_op_t s_ctl_op; 566 IV_API_CALL_STATUS_T e_dec_status; 567 568 s_ctl_ip.u4_disp_wd = ps_app_ctx->u4_strd; 569 s_ctl_ip.e_frm_skip_mode = IVD_SKIP_B; 570 571 s_ctl_ip.e_frm_out_mode = IVD_DISPLAY_FRAME_OUT; 572 s_ctl_ip.e_vid_dec_mode = IVD_DECODE_FRAME; 573 s_ctl_ip.e_cmd = IVD_CMD_VIDEO_CTL; 574 s_ctl_ip.e_sub_cmd = IVD_CMD_CTL_SETPARAMS; 575 s_ctl_ip.u4_size = sizeof(ivd_ctl_set_config_ip_t); 576 s_ctl_op.u4_size = sizeof(ivd_ctl_set_config_op_t); 577 578 e_dec_status = ivd_api_function((iv_obj_t *)codec_obj, (void *)&s_ctl_ip, 579 (void *)&s_ctl_op); 580 581 if(IV_SUCCESS != e_dec_status) 582 { 583 printf("Error in Enable SkipB frames \n"); 584 } 585 586 return e_dec_status; 587 } 588 /*****************************************************************************/ 589 /* */ 590 /* Function Name : disable_skipb_frames */ 591 /* */ 592 /* Description : Control call to disable skipping of b frames */ 593 /* */ 594 /* */ 595 /* Inputs : codec_obj : Codec handle */ 596 /* Globals : */ 597 /* Processing : Calls disable B frame skip control */ 598 /* */ 599 /* Outputs : */ 600 /* Returns : Control call return i4_status */ 601 /* */ 602 /* Issues : */ 603 /* */ 604 /* Revision History: */ 605 /* */ 606 /* DD MM YYYY Author(s) Changes */ 607 /* 07 09 2012 100189 Initial Version */ 608 /* */ 609 /*****************************************************************************/ 610 611 IV_API_CALL_STATUS_T disable_skipb_frames(void *codec_obj, 612 vid_dec_ctx_t *ps_app_ctx) 613 { 614 ivd_ctl_set_config_ip_t s_ctl_ip; 615 ivd_ctl_set_config_op_t s_ctl_op; 616 IV_API_CALL_STATUS_T e_dec_status; 617 618 s_ctl_ip.u4_disp_wd = ps_app_ctx->u4_strd; 619 s_ctl_ip.e_frm_skip_mode = IVD_SKIP_NONE; 620 621 s_ctl_ip.e_frm_out_mode = IVD_DISPLAY_FRAME_OUT; 622 s_ctl_ip.e_vid_dec_mode = IVD_DECODE_FRAME; 623 s_ctl_ip.e_cmd = IVD_CMD_VIDEO_CTL; 624 s_ctl_ip.e_sub_cmd = IVD_CMD_CTL_SETPARAMS; 625 s_ctl_ip.u4_size = sizeof(ivd_ctl_set_config_ip_t); 626 s_ctl_op.u4_size = sizeof(ivd_ctl_set_config_op_t); 627 628 e_dec_status = ivd_api_function((iv_obj_t *)codec_obj, (void *)&s_ctl_ip, 629 (void *)&s_ctl_op); 630 631 if(IV_SUCCESS != e_dec_status) 632 { 633 printf("Error in Disable SkipB frames\n"); 634 } 635 636 return e_dec_status; 637 } 638 639 /*****************************************************************************/ 640 /* */ 641 /* Function Name : enable_skippb_frames */ 642 /* */ 643 /* Description : Control call to enable skipping of P & B frames */ 644 /* */ 645 /* */ 646 /* Inputs : codec_obj : Codec handle */ 647 /* Globals : */ 648 /* Processing : Calls enable skip P and B frames control */ 649 /* */ 650 /* Outputs : */ 651 /* Returns : Control call return i4_status */ 652 /* */ 653 /* Issues : */ 654 /* */ 655 /* Revision History: */ 656 /* */ 657 /* DD MM YYYY Author(s) Changes */ 658 /* 07 09 2012 100189 Initial Version */ 659 /* */ 660 /*****************************************************************************/ 661 662 IV_API_CALL_STATUS_T enable_skippb_frames(void *codec_obj, 663 vid_dec_ctx_t *ps_app_ctx) 664 { 665 ivd_ctl_set_config_ip_t s_ctl_ip; 666 ivd_ctl_set_config_op_t s_ctl_op; 667 IV_API_CALL_STATUS_T e_dec_status; 668 669 s_ctl_ip.u4_disp_wd = ps_app_ctx->u4_strd; 670 s_ctl_ip.e_frm_skip_mode = IVD_SKIP_PB; 671 672 s_ctl_ip.e_frm_out_mode = IVD_DISPLAY_FRAME_OUT; 673 s_ctl_ip.e_vid_dec_mode = IVD_DECODE_FRAME; 674 s_ctl_ip.e_cmd = IVD_CMD_VIDEO_CTL; 675 s_ctl_ip.e_sub_cmd = IVD_CMD_CTL_SETPARAMS; 676 s_ctl_ip.u4_size = sizeof(ivd_ctl_set_config_ip_t); 677 s_ctl_op.u4_size = sizeof(ivd_ctl_set_config_op_t); 678 679 e_dec_status = ivd_api_function((iv_obj_t *)codec_obj, (void *)&s_ctl_ip, 680 (void *)&s_ctl_op); 681 if(IV_SUCCESS != e_dec_status) 682 { 683 printf("Error in Enable SkipPB frames\n"); 684 } 685 686 return e_dec_status; 687 } 688 689 /*****************************************************************************/ 690 /* */ 691 /* Function Name : disable_skippb_frames */ 692 /* */ 693 /* Description : Control call to disable skipping of P and B frames */ 694 /* */ 695 /* */ 696 /* Inputs : codec_obj : Codec handle */ 697 /* Globals : */ 698 /* Processing : Calls disable P and B frame skip control */ 699 /* */ 700 /* Outputs : */ 701 /* Returns : Control call return i4_status */ 702 /* */ 703 /* Issues : */ 704 /* */ 705 /* Revision History: */ 706 /* */ 707 /* DD MM YYYY Author(s) Changes */ 708 /* 07 09 2012 100189 Initial Version */ 709 /* */ 710 /*****************************************************************************/ 711 712 IV_API_CALL_STATUS_T disable_skippb_frames(void *codec_obj, 713 vid_dec_ctx_t *ps_app_ctx) 714 { 715 ivd_ctl_set_config_ip_t s_ctl_ip; 716 ivd_ctl_set_config_op_t s_ctl_op; 717 IV_API_CALL_STATUS_T e_dec_status; 718 719 s_ctl_ip.u4_disp_wd = ps_app_ctx->u4_strd; 720 s_ctl_ip.e_frm_skip_mode = IVD_SKIP_NONE; 721 722 s_ctl_ip.e_frm_out_mode = IVD_DISPLAY_FRAME_OUT; 723 s_ctl_ip.e_vid_dec_mode = IVD_DECODE_FRAME; 724 s_ctl_ip.e_cmd = IVD_CMD_VIDEO_CTL; 725 s_ctl_ip.e_sub_cmd = IVD_CMD_CTL_SETPARAMS; 726 s_ctl_ip.u4_size = sizeof(ivd_ctl_set_config_ip_t); 727 s_ctl_op.u4_size = sizeof(ivd_ctl_set_config_op_t); 728 729 e_dec_status = ivd_api_function((iv_obj_t *)codec_obj, (void *)&s_ctl_ip, 730 (void *)&s_ctl_op); 731 if(IV_SUCCESS != e_dec_status) 732 { 733 printf("Error in Disable SkipPB frames\n"); 734 } 735 736 return e_dec_status; 737 } 738 739 /*****************************************************************************/ 740 /* */ 741 /* Function Name : release_disp_frame */ 742 /* */ 743 /* Description : Calls release display control - Used to signal to the */ 744 /* decoder that this particular buffer has been displayed */ 745 /* and that the codec is now free to write to this buffer */ 746 /* */ 747 /* */ 748 /* Inputs : codec_obj : Codec Handle */ 749 /* buf_id : Buffer Id of the buffer to be released */ 750 /* This id would have been returned earlier by */ 751 /* the codec */ 752 /* Globals : */ 753 /* Processing : Calls Release Display call */ 754 /* */ 755 /* Outputs : */ 756 /* Returns : Status of release display call */ 757 /* */ 758 /* Issues : */ 759 /* */ 760 /* Revision History: */ 761 /* */ 762 /* DD MM YYYY Author(s) Changes */ 763 /* 07 09 2012 100189 Initial Version */ 764 /* */ 765 /*****************************************************************************/ 766 767 IV_API_CALL_STATUS_T release_disp_frame(void *codec_obj, UWORD32 buf_id) 768 { 769 ivd_rel_display_frame_ip_t s_video_rel_disp_ip; 770 ivd_rel_display_frame_op_t s_video_rel_disp_op; 771 IV_API_CALL_STATUS_T e_dec_status; 772 773 s_video_rel_disp_ip.e_cmd = IVD_CMD_REL_DISPLAY_FRAME; 774 s_video_rel_disp_ip.u4_size = sizeof(ivd_rel_display_frame_ip_t); 775 s_video_rel_disp_op.u4_size = sizeof(ivd_rel_display_frame_op_t); 776 s_video_rel_disp_ip.u4_disp_buf_id = buf_id; 777 778 e_dec_status = ivd_api_function((iv_obj_t *)codec_obj, (void *)&s_video_rel_disp_ip, 779 (void *)&s_video_rel_disp_op); 780 if(IV_SUCCESS != e_dec_status) 781 { 782 printf("Error in Release Disp frame\n"); 783 } 784 785 786 return (e_dec_status); 787 } 788 789 /*****************************************************************************/ 790 /* */ 791 /* Function Name : get_version */ 792 /* */ 793 /* Description : Control call to get codec version */ 794 /* */ 795 /* */ 796 /* Inputs : codec_obj : Codec handle */ 797 /* Globals : */ 798 /* Processing : Calls enable skip B frames control */ 799 /* */ 800 /* Outputs : */ 801 /* Returns : Control call return i4_status */ 802 /* */ 803 /* Issues : */ 804 /* */ 805 /* Revision History: */ 806 /* */ 807 /* DD MM YYYY Author(s) Changes */ 808 /* 07 09 2012 100189 Initial Version */ 809 /* */ 810 /*****************************************************************************/ 811 812 IV_API_CALL_STATUS_T get_version(void *codec_obj) 813 { 814 ivd_ctl_getversioninfo_ip_t ps_ctl_ip; 815 ivd_ctl_getversioninfo_op_t ps_ctl_op; 816 UWORD8 au1_buf[512]; 817 IV_API_CALL_STATUS_T i4_status; 818 ps_ctl_ip.e_cmd = IVD_CMD_VIDEO_CTL; 819 ps_ctl_ip.e_sub_cmd = IVD_CMD_CTL_GETVERSION; 820 ps_ctl_ip.u4_size = sizeof(ivd_ctl_getversioninfo_ip_t); 821 ps_ctl_op.u4_size = sizeof(ivd_ctl_getversioninfo_op_t); 822 ps_ctl_ip.pv_version_buffer = au1_buf; 823 ps_ctl_ip.u4_version_buffer_size = sizeof(au1_buf); 824 825 i4_status = ivd_api_function((iv_obj_t *)codec_obj, 826 (void *)&(ps_ctl_ip), 827 (void *)&(ps_ctl_op)); 828 829 if(i4_status != IV_SUCCESS) 830 { 831 printf("Error in Getting Version number e_dec_status = %d u4_error_code = %x\n", 832 i4_status, ps_ctl_op.u4_error_code); 833 } 834 else 835 { 836 printf("Ittiam Decoder Version number: %s\n", 837 (char *)ps_ctl_ip.pv_version_buffer); 838 } 839 return i4_status; 840 } 841 /*****************************************************************************/ 842 /* */ 843 /* Function Name : codec_exit */ 844 /* */ 845 /* Description : handles unrecoverable errors */ 846 /* Inputs : Error message */ 847 /* Globals : None */ 848 /* Processing : Prints error message to console and exits. */ 849 /* Outputs : Error mesage to the console */ 850 /* Returns : None */ 851 /* */ 852 /* Issues : */ 853 /* */ 854 /* Revision History: */ 855 /* */ 856 /* DD MM YYYY Author(s) Changes (Describe the changes made) */ 857 /* 07 06 2006 Sankar Creation */ 858 /* */ 859 /*****************************************************************************/ 860 void codec_exit(CHAR *pc_err_message) 861 { 862 printf("%s\n", pc_err_message); 863 exit(-1); 864 } 865 866 /*****************************************************************************/ 867 /* */ 868 /* Function Name : dump_output */ 869 /* */ 870 /* Description : Used to dump output YUV */ 871 /* Inputs : App context, disp output desc, File pointer */ 872 /* Globals : None */ 873 /* Processing : Dumps to a file */ 874 /* Returns : None */ 875 /* */ 876 /* Issues : */ 877 /* */ 878 /* Revision History: */ 879 /* */ 880 /* DD MM YYYY Author(s) Changes (Describe the changes made) */ 881 /* 07 06 2006 Sankar Creation */ 882 /* */ 883 /*****************************************************************************/ 884 void dump_output(vid_dec_ctx_t *ps_app_ctx, 885 iv_yuv_buf_t *ps_disp_frm_buf, 886 UWORD32 u4_disp_frm_id, 887 FILE *ps_op_file, 888 FILE *ps_op_chksum_file, 889 WORD32 i4_op_frm_ts, 890 UWORD32 file_save, 891 UWORD32 chksum_save) 892 893 { 894 895 UWORD32 i; 896 iv_yuv_buf_t s_dump_disp_frm_buf; 897 UWORD32 u4_disp_id; 898 899 memset(&s_dump_disp_frm_buf, 0, sizeof(iv_yuv_buf_t)); 900 901 if(ps_app_ctx->u4_share_disp_buf) 902 { 903 if(ps_app_ctx->dump_q_wr_idx == MAX_DISP_BUFFERS) 904 ps_app_ctx->dump_q_wr_idx = 0; 905 906 if(ps_app_ctx->dump_q_rd_idx == MAX_DISP_BUFFERS) 907 ps_app_ctx->dump_q_rd_idx = 0; 908 909 ps_app_ctx->s_disp_frm_queue[ps_app_ctx->dump_q_wr_idx] = 910 *ps_disp_frm_buf; 911 ps_app_ctx->s_disp_frm_id_queue[ps_app_ctx->dump_q_wr_idx] = 912 u4_disp_frm_id; 913 ps_app_ctx->dump_q_wr_idx++; 914 915 if((WORD32)i4_op_frm_ts >= (WORD32)(ps_app_ctx->disp_delay - 1)) 916 { 917 s_dump_disp_frm_buf = 918 ps_app_ctx->s_disp_frm_queue[ps_app_ctx->dump_q_rd_idx]; 919 u4_disp_id = 920 ps_app_ctx->s_disp_frm_id_queue[ps_app_ctx->dump_q_rd_idx]; 921 ps_app_ctx->dump_q_rd_idx++; 922 } 923 else 924 { 925 return; 926 } 927 } 928 else 929 { 930 s_dump_disp_frm_buf = *ps_disp_frm_buf; 931 u4_disp_id = u4_disp_frm_id; 932 } 933 934 release_disp_frame(ps_app_ctx->cocodec_obj, u4_disp_id); 935 936 if(0 == file_save && 0 == chksum_save) 937 return; 938 939 if(NULL == s_dump_disp_frm_buf.pv_y_buf) 940 return; 941 942 if(ps_app_ctx->e_output_chroma_format == IV_YUV_420P) 943 { 944 #if DUMP_SINGLE_BUF 945 { 946 UWORD8 *buf = s_dump_disp_frm_buf.pv_y_buf - 80 - (s_dump_disp_frm_buf.u4_y_strd * 80); 947 948 UWORD32 i4_size = s_dump_disp_frm_buf.u4_y_strd * ((s_dump_disp_frm_buf.u4_y_ht + 160) + (s_dump_disp_frm_buf.u4_u_ht + 80)); 949 fwrite(buf, 1, i4_size ,ps_op_file); 950 951 } 952 #else 953 if(0 != file_save) 954 { 955 UWORD8 *buf; 956 957 958 buf = (UWORD8 *)s_dump_disp_frm_buf.pv_y_buf; 959 for(i = 0; i < s_dump_disp_frm_buf.u4_y_ht; i++) 960 { 961 fwrite(buf, 1, s_dump_disp_frm_buf.u4_y_wd, ps_op_file); 962 buf += s_dump_disp_frm_buf.u4_y_strd; 963 } 964 965 buf = (UWORD8 *)s_dump_disp_frm_buf.pv_u_buf; 966 for(i = 0; i < s_dump_disp_frm_buf.u4_u_ht; i++) 967 { 968 fwrite(buf, 1, s_dump_disp_frm_buf.u4_u_wd, ps_op_file); 969 buf += s_dump_disp_frm_buf.u4_u_strd; 970 } 971 buf = (UWORD8 *)s_dump_disp_frm_buf.pv_v_buf; 972 for(i = 0; i < s_dump_disp_frm_buf.u4_v_ht; i++) 973 { 974 fwrite(buf, 1, s_dump_disp_frm_buf.u4_v_wd, ps_op_file); 975 buf += s_dump_disp_frm_buf.u4_v_strd; 976 } 977 978 } 979 980 if(0 != chksum_save) 981 { 982 UWORD8 au1_y_chksum[16]; 983 UWORD8 au1_u_chksum[16]; 984 UWORD8 au1_v_chksum[16]; 985 calc_md5_cksum((UWORD8 *)s_dump_disp_frm_buf.pv_y_buf, 986 s_dump_disp_frm_buf.u4_y_strd, 987 s_dump_disp_frm_buf.u4_y_wd, 988 s_dump_disp_frm_buf.u4_y_ht, 989 au1_y_chksum); 990 calc_md5_cksum((UWORD8 *)s_dump_disp_frm_buf.pv_u_buf, 991 s_dump_disp_frm_buf.u4_u_strd, 992 s_dump_disp_frm_buf.u4_u_wd, 993 s_dump_disp_frm_buf.u4_u_ht, 994 au1_u_chksum); 995 calc_md5_cksum((UWORD8 *)s_dump_disp_frm_buf.pv_v_buf, 996 s_dump_disp_frm_buf.u4_v_strd, 997 s_dump_disp_frm_buf.u4_v_wd, 998 s_dump_disp_frm_buf.u4_v_ht, 999 au1_v_chksum); 1000 1001 fwrite(au1_y_chksum, sizeof(UWORD8), 16, ps_op_chksum_file); 1002 fwrite(au1_u_chksum, sizeof(UWORD8), 16, ps_op_chksum_file); 1003 fwrite(au1_v_chksum, sizeof(UWORD8), 16, ps_op_chksum_file); 1004 } 1005 #endif 1006 } 1007 else if((ps_app_ctx->e_output_chroma_format == IV_YUV_420SP_UV) 1008 || (ps_app_ctx->e_output_chroma_format == IV_YUV_420SP_VU)) 1009 { 1010 #if DUMP_SINGLE_BUF 1011 { 1012 1013 UWORD8 *buf = s_dump_disp_frm_buf.pv_y_buf - 24 - (s_dump_disp_frm_buf.u4_y_strd * 40); 1014 1015 UWORD32 i4_size = s_dump_disp_frm_buf.u4_y_strd * ((s_dump_disp_frm_buf.u4_y_ht + 80) + (s_dump_disp_frm_buf.u4_u_ht + 40)); 1016 fwrite(buf, 1, i4_size ,ps_op_file); 1017 } 1018 #else 1019 { 1020 UWORD8 *buf; 1021 1022 buf = (UWORD8 *)s_dump_disp_frm_buf.pv_y_buf; 1023 for(i = 0; i < s_dump_disp_frm_buf.u4_y_ht; i++) 1024 { 1025 fwrite(buf, 1, s_dump_disp_frm_buf.u4_y_wd, ps_op_file); 1026 buf += s_dump_disp_frm_buf.u4_y_strd; 1027 } 1028 1029 buf = (UWORD8 *)s_dump_disp_frm_buf.pv_u_buf; 1030 for(i = 0; i < s_dump_disp_frm_buf.u4_u_ht; i++) 1031 { 1032 fwrite(buf, 1, s_dump_disp_frm_buf.u4_u_wd, ps_op_file); 1033 buf += s_dump_disp_frm_buf.u4_u_strd; 1034 } 1035 } 1036 #endif 1037 } 1038 else if(ps_app_ctx->e_output_chroma_format == IV_RGBA_8888) 1039 { 1040 UWORD8 *buf; 1041 1042 buf = (UWORD8 *)s_dump_disp_frm_buf.pv_y_buf; 1043 for(i = 0; i < s_dump_disp_frm_buf.u4_y_ht; i++) 1044 { 1045 fwrite(buf, 1, s_dump_disp_frm_buf.u4_y_wd * 4, ps_op_file); 1046 buf += s_dump_disp_frm_buf.u4_y_strd * 4; 1047 } 1048 } 1049 else 1050 { 1051 UWORD8 *buf; 1052 1053 buf = (UWORD8 *)s_dump_disp_frm_buf.pv_y_buf; 1054 for(i = 0; i < s_dump_disp_frm_buf.u4_y_ht; i++) 1055 { 1056 fwrite(buf, 1, s_dump_disp_frm_buf.u4_y_strd * 2, ps_op_file); 1057 buf += s_dump_disp_frm_buf.u4_y_strd * 2; 1058 } 1059 } 1060 1061 fflush(ps_op_file); 1062 fflush(ps_op_chksum_file); 1063 1064 } 1065 1066 1067 /*****************************************************************************/ 1068 /* */ 1069 /* Function Name : print_usage */ 1070 /* */ 1071 /* Description : Prints argument format */ 1072 /* */ 1073 /* */ 1074 /* Inputs : */ 1075 /* Globals : */ 1076 /* Processing : Prints argument format */ 1077 /* */ 1078 /* Outputs : */ 1079 /* Returns : */ 1080 /* */ 1081 /* Issues : */ 1082 /* */ 1083 /* Revision History: */ 1084 /* */ 1085 /* DD MM YYYY Author(s) Changes */ 1086 /* 07 09 2012 100189 Initial Version */ 1087 /* */ 1088 /*****************************************************************************/ 1089 1090 void print_usage(void) 1091 { 1092 WORD32 i = 0; 1093 WORD32 num_entries = sizeof(argument_mapping) / sizeof(argument_t); 1094 printf("\nUsage:\n"); 1095 while(i < num_entries) 1096 { 1097 printf("%-32s\t %s", argument_mapping[i].argument_name, 1098 argument_mapping[i].description); 1099 i++; 1100 } 1101 } 1102 1103 /*****************************************************************************/ 1104 /* */ 1105 /* Function Name : get_argument */ 1106 /* */ 1107 /* Description : Gets argument for a given string */ 1108 /* */ 1109 /* */ 1110 /* Inputs : name */ 1111 /* Globals : */ 1112 /* Processing : Searches the given string in the array and returns */ 1113 /* appropriate argument ID */ 1114 /* */ 1115 /* Outputs : Argument ID */ 1116 /* Returns : Argument ID */ 1117 /* */ 1118 /* Issues : */ 1119 /* */ 1120 /* Revision History: */ 1121 /* */ 1122 /* DD MM YYYY Author(s) Changes */ 1123 /* 07 09 2012 100189 Initial Version */ 1124 /* */ 1125 /*****************************************************************************/ 1126 1127 ARGUMENT_T get_argument(CHAR *name) 1128 { 1129 WORD32 i = 0; 1130 WORD32 num_entries = sizeof(argument_mapping) / sizeof(argument_t); 1131 while(i < num_entries) 1132 { 1133 if((0 == strcmp(argument_mapping[i].argument_name, name)) || 1134 ((0 == strcmp(argument_mapping[i].argument_shortname, name)) && 1135 (0 != strcmp(argument_mapping[i].argument_shortname, "--")))) 1136 { 1137 return argument_mapping[i].argument; 1138 } 1139 i++; 1140 } 1141 return INVALID; 1142 } 1143 1144 /*****************************************************************************/ 1145 /* */ 1146 /* Function Name : get_argument */ 1147 /* */ 1148 /* Description : Gets argument for a given string */ 1149 /* */ 1150 /* */ 1151 /* Inputs : name */ 1152 /* Globals : */ 1153 /* Processing : Searches the given string in the array and returns */ 1154 /* appropriate argument ID */ 1155 /* */ 1156 /* Outputs : Argument ID */ 1157 /* Returns : Argument ID */ 1158 /* */ 1159 /* Issues : */ 1160 /* */ 1161 /* Revision History: */ 1162 /* */ 1163 /* DD MM YYYY Author(s) Changes */ 1164 /* 07 09 2012 100189 Initial Version */ 1165 /* */ 1166 /*****************************************************************************/ 1167 1168 void parse_argument(vid_dec_ctx_t *ps_app_ctx, CHAR *argument, CHAR *value) 1169 { 1170 ARGUMENT_T arg; 1171 1172 arg = get_argument(argument); 1173 switch(arg) 1174 { 1175 case HELP: 1176 print_usage(); 1177 exit(-1); 1178 case VERSION: 1179 break; 1180 case INPUT_FILE: 1181 sscanf(value, "%s", ps_app_ctx->ac_ip_fname); 1182 //input_passed = 1; 1183 break; 1184 1185 case OUTPUT: 1186 sscanf(value, "%s", ps_app_ctx->ac_op_fname); 1187 break; 1188 1189 case CHKSUM: 1190 sscanf(value, "%s", ps_app_ctx->ac_op_chksum_fname); 1191 break; 1192 1193 case SAVE_OUTPUT: 1194 sscanf(value, "%d", &ps_app_ctx->u4_file_save_flag); 1195 break; 1196 1197 case SAVE_CHKSUM: 1198 sscanf(value, "%d", &ps_app_ctx->u4_chksum_save_flag); 1199 break; 1200 1201 case CHROMA_FORMAT: 1202 if((strcmp(value, "YUV_420P")) == 0) 1203 ps_app_ctx->e_output_chroma_format = IV_YUV_420P; 1204 else if((strcmp(value, "YUV_422ILE")) == 0) 1205 ps_app_ctx->e_output_chroma_format = IV_YUV_422ILE; 1206 else if((strcmp(value, "RGB_565")) == 0) 1207 ps_app_ctx->e_output_chroma_format = IV_RGB_565; 1208 else if((strcmp(value, "RGBA_8888")) == 0) 1209 ps_app_ctx->e_output_chroma_format = IV_RGBA_8888; 1210 else if((strcmp(value, "YUV_420SP_UV")) == 0) 1211 ps_app_ctx->e_output_chroma_format = IV_YUV_420SP_UV; 1212 else if((strcmp(value, "YUV_420SP_VU")) == 0) 1213 ps_app_ctx->e_output_chroma_format = IV_YUV_420SP_VU; 1214 else 1215 { 1216 printf("\nInvalid colour format setting it to IV_YUV_420P\n"); 1217 ps_app_ctx->e_output_chroma_format = IV_YUV_420P; 1218 } 1219 1220 break; 1221 case NUM_FRAMES: 1222 sscanf(value, "%d", &ps_app_ctx->u4_max_frm_ts); 1223 break; 1224 1225 case NUM_CORES: 1226 sscanf(value, "%d", &ps_app_ctx->u4_num_cores); 1227 break; 1228 case DEGRADE_PICS: 1229 sscanf(value, "%d", &ps_app_ctx->i4_degrade_pics); 1230 break; 1231 case DEGRADE_TYPE: 1232 sscanf(value, "%d", &ps_app_ctx->i4_degrade_type); 1233 break; 1234 case SHARE_DISPLAY_BUF: 1235 sscanf(value, "%d", &ps_app_ctx->u4_share_disp_buf); 1236 break; 1237 case LOOPBACK: 1238 sscanf(value, "%d", &ps_app_ctx->loopback); 1239 break; 1240 case DISPLAY: 1241 #if defined(SDL_DISPLAY) || defined(FBDEV_DISPLAY) || defined(INTEL_CE5300) || defined(IOS_DISPLAY) 1242 sscanf(value, "%d", &ps_app_ctx->display); 1243 #else 1244 ps_app_ctx->display = 0; 1245 #endif 1246 break; 1247 case FULLSCREEN: 1248 sscanf(value, "%d", &ps_app_ctx->full_screen); 1249 break; 1250 case FPS: 1251 sscanf(value, "%d", &ps_app_ctx->fps); 1252 if(ps_app_ctx->fps <= 0) 1253 ps_app_ctx->fps = DEFAULT_FPS; 1254 break; 1255 case MAX_WD: 1256 sscanf(value, "%d", &ps_app_ctx->max_wd); 1257 break; 1258 case MAX_HT: 1259 sscanf(value, "%d", &ps_app_ctx->max_ht); 1260 break; 1261 case MAX_LEVEL: 1262 sscanf(value, "%d", &ps_app_ctx->max_level); 1263 break; 1264 case ARCH: 1265 if((strcmp(value, "ARM_NONEON")) == 0) 1266 ps_app_ctx->e_arch = ARCH_ARM_NONEON; 1267 else if((strcmp(value, "ARM_A9Q")) == 0) 1268 ps_app_ctx->e_arch = ARCH_ARM_A9Q; 1269 else if((strcmp(value, "ARM_A7")) == 0) 1270 ps_app_ctx->e_arch = ARCH_ARM_A7; 1271 else if((strcmp(value, "ARM_A5")) == 0) 1272 ps_app_ctx->e_arch = ARCH_ARM_A5; 1273 else if((strcmp(value, "ARM_NEONINTR")) == 0) 1274 ps_app_ctx->e_arch = ARCH_ARM_NEONINTR; 1275 else if((strcmp(value, "X86_GENERIC")) == 0) 1276 ps_app_ctx->e_arch = ARCH_X86_GENERIC; 1277 else if((strcmp(value, "X86_SSSE3")) == 0) 1278 ps_app_ctx->e_arch = ARCH_X86_SSSE3; 1279 else if((strcmp(value, "X86_SSE42")) == 0) 1280 ps_app_ctx->e_arch = ARCH_X86_SSE42; 1281 else if((strcmp(value, "X86_AVX2")) == 0) 1282 ps_app_ctx->e_arch = ARCH_X86_AVX2; 1283 else if((strcmp(value, "MIPS_GENERIC")) == 0) 1284 ps_app_ctx->e_arch = ARCH_MIPS_GENERIC; 1285 else if((strcmp(value, "MIPS_32")) == 0) 1286 ps_app_ctx->e_arch = ARCH_MIPS_32; 1287 else if((strcmp(value, "ARMV8_GENERIC")) == 0) 1288 ps_app_ctx->e_arch = ARCH_ARMV8_GENERIC; 1289 else 1290 { 1291 printf("\nInvalid Arch. Setting it to ARM_A9Q\n"); 1292 ps_app_ctx->e_arch = ARCH_ARM_A9Q; 1293 } 1294 1295 break; 1296 case SOC: 1297 if((strcmp(value, "GENERIC")) == 0) 1298 ps_app_ctx->e_soc = SOC_GENERIC; 1299 else if((strcmp(value, "HISI_37X")) == 0) 1300 ps_app_ctx->e_soc = SOC_HISI_37X; 1301 else 1302 { 1303 ps_app_ctx->e_soc = atoi(value); 1304 /* 1305 printf("\nInvalid SOC. Setting it to GENERIC\n"); 1306 ps_app_ctx->e_soc = SOC_GENERIC; 1307 */ 1308 } 1309 break; 1310 case PICLEN: 1311 sscanf(value, "%d", &ps_app_ctx->u4_piclen_flag); 1312 break; 1313 1314 case PICLEN_FILE: 1315 sscanf(value, "%s", ps_app_ctx->ac_piclen_fname); 1316 break; 1317 case DISABLE_DEBLOCK_LEVEL: 1318 sscanf(value, "%d", &ps_app_ctx->u4_disable_dblk_level); 1319 break; 1320 1321 case INVALID: 1322 default: 1323 printf("Ignoring argument : %s\n", argument); 1324 break; 1325 } 1326 } 1327 1328 /*****************************************************************************/ 1329 /* */ 1330 /* Function Name : read_cfg_file */ 1331 /* */ 1332 /* Description : Reads arguments from a configuration file */ 1333 /* */ 1334 /* */ 1335 /* Inputs : ps_app_ctx : Application context */ 1336 /* fp_cfg_file : Configuration file handle */ 1337 /* Globals : */ 1338 /* Processing : Parses the arguments and fills in the application context*/ 1339 /* */ 1340 /* Outputs : Arguments parsed */ 1341 /* Returns : None */ 1342 /* */ 1343 /* Issues : */ 1344 /* */ 1345 /* Revision History: */ 1346 /* */ 1347 /* DD MM YYYY Author(s) Changes */ 1348 /* 07 09 2012 100189 Initial Version */ 1349 /* */ 1350 /*****************************************************************************/ 1351 1352 void read_cfg_file(vid_dec_ctx_t *ps_app_ctx, FILE *fp_cfg_file) 1353 { 1354 1355 CHAR line[STRLENGTH]; 1356 CHAR description[STRLENGTH]; 1357 CHAR value[STRLENGTH]; 1358 CHAR argument[STRLENGTH]; 1359 void *ret; 1360 while(0 == feof(fp_cfg_file)) 1361 { 1362 line[0] = '\0'; 1363 ret = fgets(line, STRLENGTH, fp_cfg_file); 1364 if(NULL == ret) 1365 break; 1366 argument[0] = '\0'; 1367 /* Reading Input File Name */ 1368 sscanf(line, "%s %s %s", argument, value, description); 1369 if(argument[0] == '\0') 1370 continue; 1371 1372 parse_argument(ps_app_ctx, argument, value); 1373 } 1374 1375 1376 } 1377 1378 /*! 1379 ************************************************************************** 1380 * \if Function name : dispq_producer_dequeue \endif 1381 * 1382 * \brief 1383 * This function gets a free buffer index where display data can be written 1384 * This is a blocking call and can be exited by setting quit to true in 1385 * the application context 1386 * 1387 * \param[in] ps_app_ctx : Pointer to application context 1388 * 1389 * \return 1390 * returns Next free buffer index for producer 1391 * 1392 * \author 1393 * Ittiam 1394 * 1395 ************************************************************************** 1396 */ 1397 WORD32 dispq_producer_dequeue(vid_dec_ctx_t *ps_app_ctx) 1398 { 1399 WORD32 idx; 1400 1401 /* If there is no free buffer wait */ 1402 1403 while(((ps_app_ctx->disp_q_wr_idx + 1) % NUM_DISPLAY_BUFFERS) == ps_app_ctx->disp_q_rd_idx) 1404 { 1405 1406 ithread_msleep(1); 1407 1408 if(ps_app_ctx->quit) 1409 return(-1); 1410 } 1411 1412 idx = ps_app_ctx->disp_q_wr_idx; 1413 return (idx); 1414 } 1415 1416 /*! 1417 ************************************************************************** 1418 * \if Function name : dispq_producer_queue \endif 1419 * 1420 * \brief 1421 * This function adds buffer which can be displayed 1422 * 1423 * \param[in] ps_app_ctx : Pointer to application context 1424 * 1425 * \return 1426 * returns Next free buffer index for producer 1427 * 1428 * \author 1429 * Ittiam 1430 * 1431 ************************************************************************** 1432 */ 1433 WORD32 dispq_producer_queue(vid_dec_ctx_t *ps_app_ctx) 1434 { 1435 ps_app_ctx->disp_q_wr_idx++; 1436 if(ps_app_ctx->disp_q_wr_idx == NUM_DISPLAY_BUFFERS) 1437 ps_app_ctx->disp_q_wr_idx = 0; 1438 1439 return (0); 1440 } 1441 /*! 1442 ************************************************************************** 1443 * \if Function name : dispq_consumer_dequeue \endif 1444 * 1445 * \brief 1446 * This function gets a free buffer index where display data can be written 1447 * This is a blocking call and can be exited by setting quit to true in 1448 * the application context 1449 * 1450 * \param[in] ps_app_ctx : Pointer to application context 1451 * 1452 * \return 1453 * returns Next free buffer index for producer 1454 * 1455 * \author 1456 * Ittiam 1457 * 1458 ************************************************************************** 1459 */ 1460 WORD32 dispq_consumer_dequeue(vid_dec_ctx_t *ps_app_ctx) 1461 { 1462 WORD32 idx; 1463 1464 /* If there is no free buffer wait */ 1465 1466 while(ps_app_ctx->disp_q_wr_idx == ps_app_ctx->disp_q_rd_idx) 1467 { 1468 1469 ithread_msleep(1); 1470 1471 if(ps_app_ctx->quit) 1472 return(-1); 1473 } 1474 1475 idx = ps_app_ctx->disp_q_rd_idx; 1476 return (idx); 1477 } 1478 1479 /*! 1480 ************************************************************************** 1481 * \if Function name : dispq_producer_queue \endif 1482 * 1483 * \brief 1484 * This function adds buffer which can be displayed 1485 * 1486 * \param[in] ps_app_ctx : Pointer to application context 1487 * 1488 * \return 1489 * returns Next free buffer index for producer 1490 * 1491 * \author 1492 * Ittiam 1493 * 1494 ************************************************************************** 1495 */ 1496 WORD32 dispq_consumer_queue(vid_dec_ctx_t *ps_app_ctx) 1497 { 1498 ps_app_ctx->disp_q_rd_idx++; 1499 if(ps_app_ctx->disp_q_rd_idx == NUM_DISPLAY_BUFFERS) 1500 ps_app_ctx->disp_q_rd_idx = 0; 1501 1502 return (0); 1503 } 1504 1505 /*****************************************************************************/ 1506 /* */ 1507 /* Function Name : display_thread */ 1508 /* */ 1509 /* Description : Thread to display the frame */ 1510 /* */ 1511 /* */ 1512 /* Inputs : pv_ctx : Application context */ 1513 /* */ 1514 /* Globals : */ 1515 /* Processing : Wait for a buffer to get produced by decoder and display */ 1516 /* that frame */ 1517 /* */ 1518 /* Outputs : */ 1519 /* Returns : None */ 1520 /* */ 1521 /* Issues : Pause followed by quit is making some deadlock condn */ 1522 /* If decoder was lagging initially and then fasten up, */ 1523 /* display will also go at faster rate till it reaches */ 1524 /* equilibrium wrt the initial time */ 1525 /* */ 1526 /* Revision History: */ 1527 /* */ 1528 /* DD MM YYYY Author(s) Changes */ 1529 /* 07 05 2013 100578 Initial Version */ 1530 /* */ 1531 /*****************************************************************************/ 1532 1533 WORD32 display_thread(void *pv_ctx) 1534 { 1535 vid_dec_ctx_t *ps_app_ctx = (vid_dec_ctx_t *) pv_ctx; 1536 1537 1538 UWORD32 frm_duration; /* in us */ 1539 UWORD32 current_time; 1540 UWORD32 expected_time; 1541 TIMER s_end_timer; 1542 TIMER s_first_frame_time; 1543 UWORD32 first_frame_displayed; 1544 1545 #ifdef WINDOWS_TIMER 1546 TIMER frequency; 1547 #endif 1548 1549 #ifdef WINDOWS_TIMER 1550 QueryPerformanceFrequency ( &frequency); 1551 #endif 1552 first_frame_displayed = 0; 1553 expected_time = 0; 1554 frm_duration = 1000000/ps_app_ctx->fps; 1555 1556 /* Init display and allocate display buffers */ 1557 ps_app_ctx->pv_disp_ctx = (void *)ps_app_ctx->disp_init(ps_app_ctx->u4_pic_wd, 1558 ps_app_ctx->u4_pic_ht, 1559 ps_app_ctx->i4_screen_wd, 1560 ps_app_ctx->i4_screen_ht, 1561 ps_app_ctx->max_wd, 1562 ps_app_ctx->max_ht, 1563 ps_app_ctx->full_screen, 1564 &ps_app_ctx->quit, 1565 &ps_app_ctx->paused); 1566 ps_app_ctx->alloc_disp_buffers(ps_app_ctx->pv_disp_ctx); 1567 1568 ps_app_ctx->display_init_done = 1; 1569 1570 while(1) 1571 { 1572 WORD32 rd_idx; 1573 1574 rd_idx = dispq_consumer_dequeue(ps_app_ctx); 1575 if (ps_app_ctx->quit) 1576 break; 1577 1578 ps_app_ctx->display_buffer(ps_app_ctx->pv_disp_ctx, rd_idx); 1579 1580 if(0 == first_frame_displayed) 1581 { 1582 GETTIME(&s_first_frame_time); 1583 first_frame_displayed = 1; 1584 } 1585 1586 /*********************************************************************/ 1587 /* Sleep based on the expected time of arrival of current buffer and */ 1588 /* the Current frame */ 1589 /*********************************************************************/ 1590 1591 GETTIME(&s_end_timer); 1592 ELAPSEDTIME(s_first_frame_time,s_end_timer,current_time,frequency); 1593 1594 /* time in micro second */ 1595 expected_time += frm_duration; 1596 1597 //printf("current_time %d expected_time %d diff %d \n", current_time, expected_time, (expected_time - current_time)); 1598 /* sleep for the diff. in time */ 1599 if(current_time < expected_time) 1600 ps_app_ctx->disp_usleep((expected_time - current_time)); 1601 else 1602 expected_time += (current_time - expected_time); 1603 1604 dispq_consumer_queue(ps_app_ctx); 1605 1606 } 1607 1608 1609 while(0 == ps_app_ctx->display_deinit_flag) 1610 { 1611 ps_app_ctx->disp_usleep(1000); 1612 } 1613 ps_app_ctx->disp_deinit(ps_app_ctx->pv_disp_ctx); 1614 1615 return 0; 1616 } 1617 1618 void output_write_stall(CHAR *fname, UWORD32 cur_frm_idx) 1619 { 1620 const UWORD8 threshold = 64; 1621 CHAR past_fname[1000]; 1622 FILE *fp_fast_file = NULL; 1623 1624 if (cur_frm_idx >= threshold) 1625 { 1626 sprintf(past_fname, fname, cur_frm_idx - threshold); 1627 do 1628 { 1629 fp_fast_file = fopen(past_fname,"rb"); 1630 if (fp_fast_file != NULL) 1631 { 1632 fclose(fp_fast_file); 1633 /* Wait until the resource is released by a third party app*/ 1634 ithread_msleep(5); 1635 } 1636 else 1637 break; 1638 } while(1); 1639 } 1640 } 1641 1642 void flush_output(iv_obj_t *codec_obj, 1643 vid_dec_ctx_t *ps_app_ctx, 1644 ivd_out_bufdesc_t *ps_out_buf, 1645 UWORD8 *pu1_bs_buf, 1646 UWORD32 *pu4_op_frm_ts, 1647 FILE *ps_op_file, 1648 FILE *ps_op_chksum_file, 1649 UWORD32 u4_ip_frm_ts, 1650 UWORD32 u4_bytes_remaining) 1651 { 1652 WORD32 ret; 1653 1654 do 1655 { 1656 1657 ivd_ctl_flush_ip_t s_ctl_ip; 1658 ivd_ctl_flush_op_t s_ctl_op; 1659 1660 if(*pu4_op_frm_ts >= (ps_app_ctx->u4_max_frm_ts + ps_app_ctx->disp_delay)) 1661 break; 1662 1663 s_ctl_ip.e_cmd = IVD_CMD_VIDEO_CTL; 1664 s_ctl_ip.e_sub_cmd = IVD_CMD_CTL_FLUSH; 1665 s_ctl_ip.u4_size = sizeof(ivd_ctl_flush_ip_t); 1666 s_ctl_op.u4_size = sizeof(ivd_ctl_flush_op_t); 1667 ret = ivd_api_function((iv_obj_t *)codec_obj, (void *)&s_ctl_ip, 1668 (void *)&s_ctl_op); 1669 1670 if(ret != IV_SUCCESS) 1671 { 1672 printf("Error in Setting the decoder in flush mode\n"); 1673 } 1674 1675 if(IV_SUCCESS == ret) 1676 { 1677 ivd_video_decode_ip_t s_video_decode_ip; 1678 ivd_video_decode_op_t s_video_decode_op; 1679 1680 s_video_decode_ip.e_cmd = IVD_CMD_VIDEO_DECODE; 1681 s_video_decode_ip.u4_ts = u4_ip_frm_ts; 1682 s_video_decode_ip.pv_stream_buffer = pu1_bs_buf; 1683 s_video_decode_ip.u4_num_Bytes = u4_bytes_remaining; 1684 s_video_decode_ip.u4_size = sizeof(ivd_video_decode_ip_t); 1685 s_video_decode_ip.s_out_buffer.u4_min_out_buf_size[0] = 1686 ps_out_buf->u4_min_out_buf_size[0]; 1687 s_video_decode_ip.s_out_buffer.u4_min_out_buf_size[1] = 1688 ps_out_buf->u4_min_out_buf_size[1]; 1689 s_video_decode_ip.s_out_buffer.u4_min_out_buf_size[2] = 1690 ps_out_buf->u4_min_out_buf_size[2]; 1691 1692 s_video_decode_ip.s_out_buffer.pu1_bufs[0] = 1693 ps_out_buf->pu1_bufs[0]; 1694 s_video_decode_ip.s_out_buffer.pu1_bufs[1] = 1695 ps_out_buf->pu1_bufs[1]; 1696 s_video_decode_ip.s_out_buffer.pu1_bufs[2] = 1697 ps_out_buf->pu1_bufs[2]; 1698 s_video_decode_ip.s_out_buffer.u4_num_bufs = 1699 ps_out_buf->u4_num_bufs; 1700 1701 s_video_decode_op.u4_size = sizeof(ivd_video_decode_op_t); 1702 1703 /*****************************************************************************/ 1704 /* API Call: Video Decode */ 1705 /*****************************************************************************/ 1706 ret = ivd_api_function((iv_obj_t *)codec_obj, (void *)&s_video_decode_ip, 1707 (void *)&s_video_decode_op); 1708 1709 if(1 == s_video_decode_op.u4_output_present) 1710 { 1711 CHAR cur_fname[1000]; 1712 CHAR *extn = NULL; 1713 /* The objective is to dump the decoded frames into separate files instead of 1714 * dumping all the frames in one common file. Also, the number of dumped frames 1715 * at any given instance of time cannot exceed 'frame_memory' 1716 */ 1717 if(ps_app_ctx->u4_file_save_flag) 1718 { 1719 /* Locate the position of extension yuv */ 1720 extn = strstr(ps_app_ctx->ac_op_fname,"%d"); 1721 if (extn != NULL) 1722 { 1723 output_write_stall(ps_app_ctx->ac_op_fname,*pu4_op_frm_ts); 1724 /* Generate output file names */ 1725 sprintf(cur_fname,ps_app_ctx->ac_op_fname,*pu4_op_frm_ts); 1726 /* Open Output file */ 1727 ps_op_file = fopen(cur_fname,"wb"); 1728 if (NULL == ps_op_file) 1729 { 1730 CHAR ac_error_str[STRLENGTH]; 1731 sprintf(ac_error_str, "Could not open output file %s", 1732 cur_fname); 1733 1734 codec_exit(ac_error_str); 1735 } 1736 } 1737 } 1738 1739 dump_output(ps_app_ctx, &(s_video_decode_op.s_disp_frm_buf), 1740 s_video_decode_op.u4_disp_buf_id, ps_op_file, 1741 ps_op_chksum_file, 1742 *pu4_op_frm_ts, ps_app_ctx->u4_file_save_flag, 1743 ps_app_ctx->u4_chksum_save_flag); 1744 if (extn != NULL) 1745 fclose(ps_op_file); 1746 (*pu4_op_frm_ts)++; 1747 } 1748 } 1749 } 1750 while(IV_SUCCESS == ret); 1751 1752 } 1753 1754 #ifdef X86_MINGW 1755 void sigsegv_handler() 1756 { 1757 printf("Segmentation fault, Exiting.. \n"); 1758 exit(-1); 1759 } 1760 #endif 1761 1762 UWORD32 default_get_stride(void) 1763 { 1764 return 0; 1765 } 1766 1767 1768 IV_COLOR_FORMAT_T default_get_color_fmt(void) 1769 { 1770 return IV_YUV_420P; 1771 } 1772 /*****************************************************************************/ 1773 /* */ 1774 /* Function Name : main */ 1775 /* */ 1776 /* Description : Application to demonstrate codec API */ 1777 /* */ 1778 /* */ 1779 /* Inputs : argc - Number of arguments */ 1780 /* argv[] - Arguments */ 1781 /* Globals : */ 1782 /* Processing : Shows how to use create, process, control and delete */ 1783 /* */ 1784 /* Outputs : Codec output in a file */ 1785 /* Returns : */ 1786 /* */ 1787 /* Issues : Assumes both PROFILE_ENABLE to be */ 1788 /* defined for multithread decode-display working */ 1789 /* */ 1790 /* Revision History: */ 1791 /* */ 1792 /* DD MM YYYY Author(s) Changes */ 1793 /* 07 09 2012 100189 Initial Version */ 1794 /* 09 05 2013 100578 Multithread decode-display */ 1795 /*****************************************************************************/ 1796 #ifdef IOS 1797 int h264dec_main(char * homedir,char *documentdir, int screen_wd, int screen_ht) 1798 #else 1799 int main(WORD32 argc, CHAR *argv[]) 1800 #endif 1801 { 1802 CHAR ac_cfg_fname[STRLENGTH]; 1803 FILE *fp_cfg_file = NULL; 1804 FILE *ps_piclen_file = NULL; 1805 FILE *ps_ip_file = NULL; 1806 FILE *ps_op_file = NULL; 1807 FILE *ps_op_chksum_file = NULL; 1808 WORD32 ret; 1809 CHAR ac_error_str[STRLENGTH]; 1810 vid_dec_ctx_t s_app_ctx; 1811 UWORD8 *pu1_bs_buf; 1812 1813 ivd_out_bufdesc_t *ps_out_buf; 1814 UWORD32 u4_num_bytes_dec = 0; 1815 UWORD32 file_pos = 0; 1816 IV_API_CALL_STATUS_T e_dec_status; 1817 UWORD32 u4_ip_frm_ts = 0, u4_op_frm_ts = 0; 1818 1819 WORD32 u4_bytes_remaining = 0; 1820 void *pv_mem_rec_location; 1821 UWORD32 u4_num_mem_recs; 1822 UWORD32 i; 1823 UWORD32 u4_ip_buf_len; 1824 UWORD32 frm_cnt = 0; 1825 WORD32 total_bytes_comsumed; 1826 UWORD32 max_op_frm_ts; 1827 UWORD32 u4_num_disp_bufs_with_dec; 1828 1829 #ifdef PROFILE_ENABLE 1830 UWORD32 u4_tot_cycles = 0; 1831 UWORD32 u4_tot_fmt_cycles = 0; 1832 UWORD32 peak_window[PEAK_WINDOW_SIZE]; 1833 UWORD32 peak_window_idx = 0; 1834 UWORD32 peak_avg_max = 0; 1835 #ifdef INTEL_CE5300 1836 UWORD32 time_consumed = 0; 1837 UWORD32 bytes_consumed = 0; 1838 #endif 1839 #endif 1840 1841 #ifdef WINDOWS_TIMER 1842 TIMER frequency; 1843 #endif 1844 WORD32 width = 0, height = 0; 1845 iv_obj_t *codec_obj; 1846 #if defined(GPU_BUILD) && !defined(X86) 1847 // int ioctl_init(); 1848 // ioctl_init(); 1849 #endif 1850 1851 #ifdef X86_MINGW 1852 //For getting printfs without any delay 1853 setvbuf(stdout, NULL, _IONBF, 0); 1854 setvbuf(stderr, NULL, _IONBF, 0); 1855 #endif 1856 #ifdef IOS 1857 sprintf(filename_trace, "%s/iostrace.txt", homedir ); 1858 printf("\ntrace file name = %s",filename_trace); 1859 #endif 1860 1861 #ifdef X86_MINGW 1862 { 1863 signal(SIGSEGV, sigsegv_handler); 1864 } 1865 #endif 1866 1867 1868 #ifndef IOS 1869 /* Usage */ 1870 if(argc < 2) 1871 { 1872 printf("Using test.cfg as configuration file \n"); 1873 strcpy(ac_cfg_fname, "test.cfg"); 1874 } 1875 else if(argc == 2) 1876 { 1877 strcpy(ac_cfg_fname, argv[1]); 1878 } 1879 1880 #else 1881 strcpy(ac_cfg_fname, "test.cfg"); 1882 1883 #endif 1884 1885 1886 /***********************************************************************/ 1887 /* Initialize Application parameters */ 1888 /***********************************************************************/ 1889 1890 strcpy(s_app_ctx.ac_ip_fname, "\0"); 1891 s_app_ctx.dump_q_wr_idx = 0; 1892 s_app_ctx.dump_q_rd_idx = 0; 1893 s_app_ctx.display_thread_created = 0; 1894 s_app_ctx.disp_q_wr_idx = 0; 1895 s_app_ctx.disp_q_rd_idx = 0; 1896 s_app_ctx.disp_delay = 0; 1897 s_app_ctx.loopback = 0; 1898 s_app_ctx.display = 0; 1899 s_app_ctx.full_screen = 0; 1900 s_app_ctx.u4_piclen_flag = 0; 1901 s_app_ctx.fps = DEFAULT_FPS; 1902 file_pos = 0; 1903 total_bytes_comsumed = 0; 1904 u4_ip_frm_ts = 0; 1905 u4_op_frm_ts = 0; 1906 #ifdef PROFILE_ENABLE 1907 memset(peak_window, 0, sizeof(WORD32) * PEAK_WINDOW_SIZE); 1908 #endif 1909 s_app_ctx.u4_share_disp_buf = DEFAULT_SHARE_DISPLAY_BUF; 1910 s_app_ctx.u4_num_cores = DEFAULT_NUM_CORES; 1911 s_app_ctx.i4_degrade_type = 0; 1912 s_app_ctx.i4_degrade_pics = 0; 1913 s_app_ctx.max_wd = 0; 1914 s_app_ctx.max_ht = 0; 1915 s_app_ctx.max_level = 0; 1916 s_app_ctx.e_arch = ARCH_ARM_A9Q; 1917 s_app_ctx.e_soc = SOC_GENERIC; 1918 1919 s_app_ctx.u4_strd = STRIDE; 1920 1921 s_app_ctx.display_thread_handle = malloc(ithread_get_handle_size()); 1922 s_app_ctx.quit = 0; 1923 s_app_ctx.paused = 0; 1924 //s_app_ctx.u4_output_present = 0; 1925 1926 s_app_ctx.get_stride = &default_get_stride; 1927 1928 s_app_ctx.get_color_fmt = &default_get_color_fmt; 1929 1930 /* Set function pointers for display */ 1931 #ifdef SDL_DISPLAY 1932 s_app_ctx.disp_init = &sdl_disp_init; 1933 s_app_ctx.alloc_disp_buffers = &sdl_alloc_disp_buffers; 1934 s_app_ctx.display_buffer = &sdl_display; 1935 s_app_ctx.set_disp_buffers = &sdl_set_disp_buffers; 1936 s_app_ctx.disp_deinit = &sdl_disp_deinit; 1937 s_app_ctx.disp_usleep = &sdl_disp_usleep; 1938 s_app_ctx.get_color_fmt = &sdl_get_color_fmt; 1939 s_app_ctx.get_stride = &sdl_get_stride; 1940 #endif 1941 1942 #ifdef FBDEV_DISPLAY 1943 s_app_ctx.disp_init = &fbd_disp_init; 1944 s_app_ctx.alloc_disp_buffers = &fbd_alloc_disp_buffers; 1945 s_app_ctx.display_buffer = &fbd_display; 1946 s_app_ctx.set_disp_buffers = &fbd_set_disp_buffers; 1947 s_app_ctx.disp_deinit = &fbd_disp_deinit; 1948 s_app_ctx.disp_usleep = &fbd_disp_usleep; 1949 s_app_ctx.get_color_fmt = &fbd_get_color_fmt; 1950 s_app_ctx.get_stride = &fbd_get_stride; 1951 #endif 1952 1953 #ifdef INTEL_CE5300 1954 s_app_ctx.disp_init = &gdl_disp_init; 1955 s_app_ctx.alloc_disp_buffers = &gdl_alloc_disp_buffers; 1956 s_app_ctx.display_buffer = &gdl_display; 1957 s_app_ctx.set_disp_buffers = &gdl_set_disp_buffers; 1958 s_app_ctx.disp_deinit = &gdl_disp_deinit; 1959 s_app_ctx.disp_usleep = &gdl_disp_usleep; 1960 s_app_ctx.get_color_fmt = &gdl_get_color_fmt; 1961 s_app_ctx.get_stride = &gdl_get_stride; 1962 #endif 1963 1964 #ifdef IOS_DISPLAY 1965 s_app_ctx.disp_init = &ios_disp_init; 1966 s_app_ctx.alloc_disp_buffers = &ios_alloc_disp_buffers; 1967 s_app_ctx.display_buffer = &ios_display; 1968 s_app_ctx.set_disp_buffers = &ios_set_disp_buffers; 1969 s_app_ctx.disp_deinit = &ios_disp_deinit; 1970 s_app_ctx.disp_usleep = &ios_disp_usleep; 1971 s_app_ctx.get_color_fmt = &ios_get_color_fmt; 1972 s_app_ctx.get_stride = &ios_get_stride; 1973 #endif 1974 1975 s_app_ctx.display_deinit_flag = 0; 1976 s_app_ctx.e_output_chroma_format = IV_YUV_420SP_UV; 1977 /*************************************************************************/ 1978 /* Parse arguments */ 1979 /*************************************************************************/ 1980 1981 #ifndef IOS 1982 /* Read command line arguments */ 1983 if(argc > 2) 1984 { 1985 for(i = 1; i < (UWORD32)argc; i += 2) 1986 { 1987 if(CONFIG == get_argument(argv[i])) 1988 { 1989 strcpy(ac_cfg_fname, argv[i + 1]); 1990 if((fp_cfg_file = fopen(ac_cfg_fname, "r")) == NULL) 1991 { 1992 sprintf(ac_error_str, "Could not open Configuration file %s", 1993 ac_cfg_fname); 1994 codec_exit(ac_error_str); 1995 } 1996 read_cfg_file(&s_app_ctx, fp_cfg_file); 1997 fclose(fp_cfg_file); 1998 } 1999 else 2000 { 2001 parse_argument(&s_app_ctx, argv[i], argv[i + 1]); 2002 } 2003 } 2004 } 2005 else 2006 { 2007 if((fp_cfg_file = fopen(ac_cfg_fname, "r")) == NULL) 2008 { 2009 sprintf(ac_error_str, "Could not open Configuration file %s", 2010 ac_cfg_fname); 2011 codec_exit(ac_error_str); 2012 } 2013 read_cfg_file(&s_app_ctx, fp_cfg_file); 2014 fclose(fp_cfg_file); 2015 } 2016 #else 2017 sprintf(filename_with_path, "%s/%s", homedir, ac_cfg_fname); 2018 if((fp_cfg_file = fopen(filename_with_path, "r")) == NULL) 2019 { 2020 sprintf(ac_error_str, "Could not open Configuration file %s", 2021 ac_cfg_fname); 2022 codec_exit(ac_error_str); 2023 2024 } 2025 read_cfg_file(&s_app_ctx, fp_cfg_file); 2026 fclose(fp_cfg_file); 2027 2028 #endif 2029 #ifdef PRINT_PICSIZE 2030 /* If the binary is used for only getting number of bytes in each picture, then disable the following features */ 2031 s_app_ctx.u4_piclen_flag = 0; 2032 s_app_ctx.u4_file_save_flag = 0; 2033 s_app_ctx.u4_chksum_save_flag = 0; 2034 s_app_ctx.i4_degrade_pics = 0; 2035 s_app_ctx.i4_degrade_type = 0; 2036 s_app_ctx.loopback = 0; 2037 s_app_ctx.u4_share_disp_buf = 0; 2038 s_app_ctx.display = 0; 2039 #endif 2040 2041 /* If display is enabled, then turn off shared mode and get color format that is supported by display */ 2042 if(1 == s_app_ctx.display) 2043 { 2044 s_app_ctx.u4_share_disp_buf = 0; 2045 s_app_ctx.e_output_chroma_format = s_app_ctx.get_color_fmt(); 2046 } 2047 if(strcmp(s_app_ctx.ac_ip_fname, "\0") == 0) 2048 { 2049 printf("\nNo input file given for decoding\n"); 2050 exit(-1); 2051 } 2052 2053 2054 2055 /***********************************************************************/ 2056 /* create the file object for input file */ 2057 /***********************************************************************/ 2058 #ifdef IOS 2059 sprintf(filename_with_path, "%s/%s", homedir, s_app_ctx.ac_ip_fname); 2060 ps_ip_file = fopen(filename_with_path, "rb"); 2061 #else 2062 ps_ip_file = fopen(s_app_ctx.ac_ip_fname, "rb"); 2063 #endif 2064 if(NULL == ps_ip_file) 2065 { 2066 sprintf(ac_error_str, "Could not open input file %s", 2067 s_app_ctx.ac_ip_fname); 2068 codec_exit(ac_error_str); 2069 } 2070 /***********************************************************************/ 2071 /* create the file object for input file */ 2072 /***********************************************************************/ 2073 if(1 == s_app_ctx.u4_piclen_flag) 2074 { 2075 #ifdef IOS 2076 sprintf(filename_with_path, "%s/%s", homedir, s_app_ctx.ac_piclen_fname); 2077 ps_piclen_file = fopen(filename_with_path, "rb"); 2078 #else 2079 ps_piclen_file = fopen(s_app_ctx.ac_piclen_fname, "rb"); 2080 #endif 2081 if(NULL == ps_piclen_file) 2082 { 2083 sprintf(ac_error_str, "Could not open piclen file %s", 2084 s_app_ctx.ac_piclen_fname); 2085 codec_exit(ac_error_str); 2086 } 2087 } 2088 2089 /***********************************************************************/ 2090 /* create the file object for output file */ 2091 /***********************************************************************/ 2092 2093 /* If the filename does not contain %d, then output will be dumped to 2094 a single file and it is opened here */ 2095 if((1 == s_app_ctx.u4_file_save_flag) && (strstr(s_app_ctx.ac_op_fname,"%d") == NULL)) 2096 { 2097 #ifdef IOS 2098 sprintf(filename_with_path, "%s/%s", documentdir, s_app_ctx.ac_op_fname); 2099 ps_op_file = fopen(filename_with_path,"wb"); 2100 #else 2101 ps_op_file = fopen(s_app_ctx.ac_op_fname, "wb"); 2102 #endif 2103 2104 if(NULL == ps_op_file) 2105 { 2106 sprintf(ac_error_str, "Could not open output file %s", 2107 s_app_ctx.ac_op_fname); 2108 codec_exit(ac_error_str); 2109 } 2110 } 2111 2112 /***********************************************************************/ 2113 /* create the file object for check sum file */ 2114 /***********************************************************************/ 2115 if(1 == s_app_ctx.u4_chksum_save_flag) 2116 { 2117 #if IOS 2118 sprintf(filename_with_path, "%s/%s", documentdir, s_app_ctx.ac_op_chksum_fname); 2119 ps_op_chksum_file = fopen(filename_with_path,"wb"); 2120 #else 2121 ps_op_chksum_file = fopen(s_app_ctx.ac_op_chksum_fname, "wb"); 2122 #endif 2123 if(NULL == ps_op_chksum_file) 2124 { 2125 sprintf(ac_error_str, "Could not open check sum file %s", 2126 s_app_ctx.ac_op_chksum_fname); 2127 codec_exit(ac_error_str); 2128 } 2129 } 2130 /***********************************************************************/ 2131 /* Create decoder instance */ 2132 /***********************************************************************/ 2133 { 2134 2135 ps_out_buf = (ivd_out_bufdesc_t *)malloc(sizeof(ivd_out_bufdesc_t)); 2136 2137 { 2138 iv_num_mem_rec_ip_t s_no_of_mem_rec_query_ip; 2139 iv_num_mem_rec_op_t s_no_of_mem_rec_query_op; 2140 2141 s_no_of_mem_rec_query_ip.u4_size = sizeof(s_no_of_mem_rec_query_ip); 2142 s_no_of_mem_rec_query_op.u4_size = sizeof(s_no_of_mem_rec_query_op); 2143 s_no_of_mem_rec_query_ip.e_cmd = IV_CMD_GET_NUM_MEM_REC; 2144 2145 /*****************************************************************************/ 2146 /* API Call: Get Number of Mem Records */ 2147 /*****************************************************************************/ 2148 e_dec_status = ivd_api_function( 2149 NULL, (void*)&s_no_of_mem_rec_query_ip, 2150 (void*)&s_no_of_mem_rec_query_op); 2151 if(IV_SUCCESS != e_dec_status) 2152 { 2153 sprintf(ac_error_str, "Error in get mem records"); 2154 codec_exit(ac_error_str); 2155 } 2156 2157 u4_num_mem_recs = s_no_of_mem_rec_query_op.u4_num_mem_rec; 2158 } 2159 2160 pv_mem_rec_location = malloc(u4_num_mem_recs * sizeof(iv_mem_rec_t)); 2161 if(pv_mem_rec_location == NULL) 2162 { 2163 sprintf(ac_error_str, "Allocation failure for mem_rec_location"); 2164 codec_exit(ac_error_str); 2165 2166 } 2167 2168 { 2169 ih264d_fill_mem_rec_ip_t s_fill_mem_rec_ip; 2170 ih264d_fill_mem_rec_op_t s_fill_mem_rec_op; 2171 iv_mem_rec_t *ps_mem_rec; 2172 UWORD32 total_size; 2173 2174 s_fill_mem_rec_ip.s_ivd_fill_mem_rec_ip_t.e_cmd = 2175 IV_CMD_FILL_NUM_MEM_REC; 2176 s_fill_mem_rec_ip.s_ivd_fill_mem_rec_ip_t.pv_mem_rec_location = 2177 (iv_mem_rec_t *)pv_mem_rec_location; 2178 s_fill_mem_rec_ip.s_ivd_fill_mem_rec_ip_t.u4_max_frm_wd = 2179 (s_app_ctx.max_wd == 0) ? MAX_FRAME_WIDTH : s_app_ctx.max_wd; 2180 s_fill_mem_rec_ip.s_ivd_fill_mem_rec_ip_t.u4_max_frm_ht = 2181 (s_app_ctx.max_ht == 0) ? MAX_FRAME_HEIGHT : s_app_ctx.max_ht; 2182 s_fill_mem_rec_ip.i4_level = (s_app_ctx.max_level == 0) ? MAX_LEVEL_SUPPORTED : s_app_ctx.max_level; 2183 s_fill_mem_rec_ip.u4_num_ref_frames = MAX_REF_FRAMES; 2184 s_fill_mem_rec_ip.u4_num_reorder_frames = MAX_REORDER_FRAMES; 2185 s_fill_mem_rec_ip.u4_share_disp_buf = s_app_ctx.u4_share_disp_buf; 2186 s_fill_mem_rec_ip.e_output_format = 2187 (IV_COLOR_FORMAT_T)s_app_ctx.e_output_chroma_format; 2188 s_fill_mem_rec_ip.u4_num_extra_disp_buf = EXTRA_DISP_BUFFERS; 2189 2190 s_fill_mem_rec_ip.s_ivd_fill_mem_rec_ip_t.u4_size = 2191 sizeof(ih264d_fill_mem_rec_ip_t); 2192 s_fill_mem_rec_op.s_ivd_fill_mem_rec_op_t.u4_size = 2193 sizeof(ih264d_fill_mem_rec_op_t); 2194 2195 ps_mem_rec = (iv_mem_rec_t *)pv_mem_rec_location; 2196 for(i = 0; i < u4_num_mem_recs; i++) 2197 ps_mem_rec[i].u4_size = sizeof(iv_mem_rec_t); 2198 2199 /*****************************************************************************/ 2200 /* API Call: Fill Mem Records */ 2201 /*****************************************************************************/ 2202 2203 e_dec_status = ivd_api_function(NULL, 2204 (void *)&s_fill_mem_rec_ip, 2205 (void *)&s_fill_mem_rec_op); 2206 2207 u4_num_mem_recs = 2208 s_fill_mem_rec_op.s_ivd_fill_mem_rec_op_t.u4_num_mem_rec_filled; 2209 2210 if(IV_SUCCESS != e_dec_status) 2211 { 2212 sprintf(ac_error_str, "Error in fill mem records: %x",s_fill_mem_rec_op.s_ivd_fill_mem_rec_op_t.u4_error_code); 2213 codec_exit(ac_error_str); 2214 } 2215 2216 ps_mem_rec = (iv_mem_rec_t *)pv_mem_rec_location; 2217 total_size = 0; 2218 for(i = 0; i < u4_num_mem_recs; i++) 2219 { 2220 ps_mem_rec->pv_base = ih264a_aligned_malloc(ps_mem_rec->u4_mem_alignment, 2221 ps_mem_rec->u4_mem_size); 2222 if(ps_mem_rec->pv_base == NULL) 2223 { 2224 sprintf(ac_error_str, 2225 "\nAllocation failure for mem record id %d i4_size %d\n", 2226 i, ps_mem_rec->u4_mem_size); 2227 codec_exit(ac_error_str); 2228 2229 } 2230 total_size += ps_mem_rec->u4_mem_size; 2231 ps_mem_rec++; 2232 } 2233 printf("\nTotal memory for codec %d\n", total_size); 2234 } 2235 /*****************************************************************************/ 2236 /* API Call: Initialize the Decoder */ 2237 /*****************************************************************************/ 2238 { 2239 ih264d_init_ip_t s_init_ip; 2240 ih264d_init_op_t s_init_op; 2241 void *fxns = &ivd_api_function; 2242 iv_mem_rec_t *mem_tab; 2243 2244 mem_tab = (iv_mem_rec_t*)pv_mem_rec_location; 2245 s_init_ip.s_ivd_init_ip_t.e_cmd = (IVD_API_COMMAND_TYPE_T)IV_CMD_INIT; 2246 s_init_ip.s_ivd_init_ip_t.pv_mem_rec_location = mem_tab; 2247 s_init_ip.s_ivd_init_ip_t.u4_frm_max_wd = (s_app_ctx.max_wd == 0) ? MAX_FRAME_WIDTH : s_app_ctx.max_wd; 2248 s_init_ip.s_ivd_init_ip_t.u4_frm_max_ht = (s_app_ctx.max_ht == 0) ? MAX_FRAME_HEIGHT : s_app_ctx.max_ht; 2249 s_init_ip.i4_level = (s_app_ctx.max_level == 0) ? MAX_LEVEL_SUPPORTED : s_app_ctx.max_level; 2250 s_init_ip.u4_num_ref_frames = MAX_REF_FRAMES; 2251 s_init_ip.u4_num_reorder_frames = MAX_REORDER_FRAMES; 2252 s_init_ip.u4_share_disp_buf = s_app_ctx.u4_share_disp_buf; 2253 s_init_ip.u4_num_extra_disp_buf = EXTRA_DISP_BUFFERS; 2254 s_init_ip.s_ivd_init_ip_t.u4_num_mem_rec = u4_num_mem_recs; 2255 s_init_ip.s_ivd_init_ip_t.e_output_format = 2256 (IV_COLOR_FORMAT_T)s_app_ctx.e_output_chroma_format; 2257 s_init_ip.s_ivd_init_ip_t.u4_size = sizeof(ih264d_init_ip_t); 2258 s_init_op.s_ivd_init_op_t.u4_size = sizeof(ih264d_init_op_t); 2259 2260 codec_obj = (iv_obj_t*)mem_tab[0].pv_base; 2261 codec_obj->pv_fxns = fxns; 2262 codec_obj->u4_size = sizeof(iv_obj_t); 2263 2264 s_app_ctx.cocodec_obj = codec_obj; 2265 2266 ret = ivd_api_function((iv_obj_t*)codec_obj, (void *)&s_init_ip, 2267 (void *)&s_init_op); 2268 if(ret != IV_SUCCESS) 2269 { 2270 sprintf(ac_error_str, "Error in Init %8x\n", 2271 s_init_op.s_ivd_init_op_t.u4_error_code); 2272 codec_exit(ac_error_str); 2273 } 2274 2275 2276 /*****************************************************************************/ 2277 /* set stride */ 2278 /*****************************************************************************/ 2279 { 2280 ivd_ctl_set_config_ip_t s_ctl_ip; 2281 ivd_ctl_set_config_op_t s_ctl_op; 2282 2283 2284 s_ctl_ip.u4_disp_wd = STRIDE; 2285 if(1 == s_app_ctx.display) 2286 s_ctl_ip.u4_disp_wd = s_app_ctx.get_stride(); 2287 2288 s_ctl_ip.e_frm_skip_mode = IVD_SKIP_NONE; 2289 s_ctl_ip.e_frm_out_mode = IVD_DECODE_FRAME_OUT; 2290 s_ctl_ip.e_vid_dec_mode = IVD_DECODE_HEADER; 2291 s_ctl_ip.e_cmd = IVD_CMD_VIDEO_CTL; 2292 s_ctl_ip.e_sub_cmd = IVD_CMD_CTL_SETPARAMS; 2293 s_ctl_ip.u4_size = sizeof(ivd_ctl_set_config_ip_t); 2294 s_ctl_op.u4_size = sizeof(ivd_ctl_set_config_op_t); 2295 2296 ret = ivd_api_function((iv_obj_t*)codec_obj, (void *)&s_ctl_ip, 2297 (void *)&s_ctl_op); 2298 if(ret != IV_SUCCESS) 2299 { 2300 sprintf(ac_error_str, 2301 "\nError in setting the stride"); 2302 codec_exit(ac_error_str); 2303 } 2304 } 2305 2306 2307 /*****************************************************************************/ 2308 /* Input and output buffer allocation */ 2309 /*****************************************************************************/ 2310 { 2311 2312 ivd_ctl_getbufinfo_ip_t s_ctl_ip; 2313 ivd_ctl_getbufinfo_op_t s_ctl_op; 2314 WORD32 outlen = 0; 2315 2316 s_ctl_ip.e_cmd = IVD_CMD_VIDEO_CTL; 2317 s_ctl_ip.e_sub_cmd = IVD_CMD_CTL_GETBUFINFO; 2318 s_ctl_ip.u4_size = sizeof(ivd_ctl_getbufinfo_ip_t); 2319 s_ctl_op.u4_size = sizeof(ivd_ctl_getbufinfo_op_t); 2320 ret = ivd_api_function((iv_obj_t*)codec_obj, (void *)&s_ctl_ip, 2321 (void *)&s_ctl_op); 2322 if(ret != IV_SUCCESS) 2323 { 2324 sprintf(ac_error_str, "Error in Get Buf Info %x", s_ctl_op.u4_error_code); 2325 codec_exit(ac_error_str); 2326 } 2327 2328 /* Allocate input buffer */ 2329 u4_ip_buf_len = s_ctl_op.u4_min_in_buf_size[0]; 2330 pu1_bs_buf = (UWORD8 *)malloc(u4_ip_buf_len); 2331 2332 if(pu1_bs_buf == NULL) 2333 { 2334 sprintf(ac_error_str, 2335 "\nAllocation failure for input buffer of i4_size %d", 2336 u4_ip_buf_len); 2337 codec_exit(ac_error_str); 2338 } 2339 s_app_ctx.num_disp_buf = s_ctl_op.u4_num_disp_bufs; 2340 /* Allocate output buffer only if display buffers are not shared */ 2341 /* Or if shared and output is 420P */ 2342 if((0 == s_app_ctx.u4_share_disp_buf) || (IV_YUV_420P == s_app_ctx.e_output_chroma_format)) 2343 { 2344 ps_out_buf->u4_min_out_buf_size[0] = 2345 s_ctl_op.u4_min_out_buf_size[0]; 2346 ps_out_buf->u4_min_out_buf_size[1] = 2347 s_ctl_op.u4_min_out_buf_size[1]; 2348 ps_out_buf->u4_min_out_buf_size[2] = 2349 s_ctl_op.u4_min_out_buf_size[2]; 2350 2351 outlen = s_ctl_op.u4_min_out_buf_size[0]; 2352 if(s_ctl_op.u4_min_num_out_bufs > 1) 2353 outlen += s_ctl_op.u4_min_out_buf_size[1]; 2354 2355 if(s_ctl_op.u4_min_num_out_bufs > 2) 2356 outlen += s_ctl_op.u4_min_out_buf_size[2]; 2357 2358 ps_out_buf->pu1_bufs[0] = (UWORD8 *)malloc(outlen); 2359 if(ps_out_buf->pu1_bufs[0] == NULL) 2360 { 2361 sprintf(ac_error_str, 2362 "\nAllocation failure for output buffer of i4_size %d", 2363 outlen); 2364 codec_exit(ac_error_str); 2365 } 2366 2367 if(s_ctl_op.u4_min_num_out_bufs > 1) 2368 ps_out_buf->pu1_bufs[1] = ps_out_buf->pu1_bufs[0] 2369 + (s_ctl_op.u4_min_out_buf_size[0]); 2370 2371 if(s_ctl_op.u4_min_num_out_bufs > 2) 2372 ps_out_buf->pu1_bufs[2] = ps_out_buf->pu1_bufs[1] 2373 + (s_ctl_op.u4_min_out_buf_size[1]); 2374 2375 ps_out_buf->u4_num_bufs = s_ctl_op.u4_min_num_out_bufs; 2376 } 2377 2378 #ifdef APP_EXTRA_BUFS 2379 s_app_ctx.disp_delay = EXTRA_DISP_BUFFERS; 2380 s_ctl_op.u4_num_disp_bufs += EXTRA_DISP_BUFFERS; 2381 #endif 2382 2383 /*****************************************************************************/ 2384 /* API Call: Allocate display buffers for display buffer shared case */ 2385 /*****************************************************************************/ 2386 2387 for(i = 0; i < s_ctl_op.u4_num_disp_bufs; i++) 2388 { 2389 2390 s_app_ctx.s_disp_buffers[i].u4_min_out_buf_size[0] = 2391 s_ctl_op.u4_min_out_buf_size[0]; 2392 s_app_ctx.s_disp_buffers[i].u4_min_out_buf_size[1] = 2393 s_ctl_op.u4_min_out_buf_size[1]; 2394 s_app_ctx.s_disp_buffers[i].u4_min_out_buf_size[2] = 2395 s_ctl_op.u4_min_out_buf_size[2]; 2396 2397 outlen = s_ctl_op.u4_min_out_buf_size[0]; 2398 if(s_ctl_op.u4_min_num_out_bufs > 1) 2399 outlen += s_ctl_op.u4_min_out_buf_size[1]; 2400 2401 if(s_ctl_op.u4_min_num_out_bufs > 2) 2402 outlen += s_ctl_op.u4_min_out_buf_size[2]; 2403 2404 s_app_ctx.s_disp_buffers[i].pu1_bufs[0] = (UWORD8 *)malloc(outlen); 2405 2406 if(s_app_ctx.s_disp_buffers[i].pu1_bufs[0] == NULL) 2407 { 2408 sprintf(ac_error_str, 2409 "\nAllocation failure for output buffer of i4_size %d", 2410 outlen); 2411 codec_exit(ac_error_str); 2412 } 2413 2414 if(s_ctl_op.u4_min_num_out_bufs > 1) 2415 s_app_ctx.s_disp_buffers[i].pu1_bufs[1] = 2416 s_app_ctx.s_disp_buffers[i].pu1_bufs[0] 2417 + (s_ctl_op.u4_min_out_buf_size[0]); 2418 2419 if(s_ctl_op.u4_min_num_out_bufs > 2) 2420 s_app_ctx.s_disp_buffers[i].pu1_bufs[2] = 2421 s_app_ctx.s_disp_buffers[i].pu1_bufs[1] 2422 + (s_ctl_op.u4_min_out_buf_size[1]); 2423 2424 s_app_ctx.s_disp_buffers[i].u4_num_bufs = 2425 s_ctl_op.u4_min_num_out_bufs; 2426 } 2427 s_app_ctx.num_disp_buf = s_ctl_op.u4_num_disp_bufs; 2428 } 2429 } 2430 2431 } 2432 2433 2434 /*************************************************************************/ 2435 /* set num of cores */ 2436 /*************************************************************************/ 2437 { 2438 2439 ih264d_ctl_set_num_cores_ip_t s_ctl_set_cores_ip; 2440 ih264d_ctl_set_num_cores_op_t s_ctl_set_cores_op; 2441 2442 s_ctl_set_cores_ip.e_cmd = IVD_CMD_VIDEO_CTL; 2443 s_ctl_set_cores_ip.e_sub_cmd =(IVD_CONTROL_API_COMMAND_TYPE_T) IH264D_CMD_CTL_SET_NUM_CORES; 2444 s_ctl_set_cores_ip.u4_num_cores = s_app_ctx.u4_num_cores; 2445 s_ctl_set_cores_ip.u4_size = sizeof(ih264d_ctl_set_num_cores_ip_t); 2446 s_ctl_set_cores_op.u4_size = sizeof(ih264d_ctl_set_num_cores_op_t); 2447 2448 ret = ivd_api_function((iv_obj_t*)codec_obj, (void *)&s_ctl_set_cores_ip, 2449 (void *)&s_ctl_set_cores_op); 2450 if(ret != IV_SUCCESS) 2451 { 2452 sprintf(ac_error_str, "\nError in setting number of cores"); 2453 codec_exit(ac_error_str); 2454 } 2455 2456 } 2457 2458 /*************************************************************************/ 2459 /* set processsor */ 2460 /*************************************************************************/ 2461 { 2462 2463 ih264d_ctl_set_processor_ip_t s_ctl_set_num_processor_ip; 2464 ih264d_ctl_set_processor_op_t s_ctl_set_num_processor_op; 2465 2466 s_ctl_set_num_processor_ip.e_cmd = IVD_CMD_VIDEO_CTL; 2467 s_ctl_set_num_processor_ip.e_sub_cmd =(IVD_CONTROL_API_COMMAND_TYPE_T) IH264D_CMD_CTL_SET_PROCESSOR; 2468 s_ctl_set_num_processor_ip.u4_arch = s_app_ctx.e_arch; 2469 s_ctl_set_num_processor_ip.u4_soc = s_app_ctx.e_soc; 2470 s_ctl_set_num_processor_ip.u4_size = sizeof(ih264d_ctl_set_processor_ip_t); 2471 s_ctl_set_num_processor_op.u4_size = sizeof(ih264d_ctl_set_processor_op_t); 2472 2473 ret = ivd_api_function((iv_obj_t*)codec_obj, (void *)&s_ctl_set_num_processor_ip, 2474 (void *)&s_ctl_set_num_processor_op); 2475 if(ret != IV_SUCCESS) 2476 { 2477 sprintf(ac_error_str, "\nError in setting Processor type"); 2478 codec_exit(ac_error_str); 2479 } 2480 2481 } 2482 2483 2484 /*****************************************************************************/ 2485 /* Decode header to get width and height and buffer sizes */ 2486 /*****************************************************************************/ 2487 { 2488 2489 ivd_ctl_set_config_ip_t s_ctl_ip; 2490 ivd_ctl_set_config_op_t s_ctl_op; 2491 2492 ivd_video_decode_ip_t s_video_decode_ip; 2493 ivd_video_decode_op_t s_video_decode_op; 2494 2495 s_ctl_ip.u4_disp_wd = STRIDE; 2496 if(1 == s_app_ctx.display) 2497 s_ctl_ip.u4_disp_wd = s_app_ctx.get_stride(); 2498 2499 s_ctl_ip.e_frm_skip_mode = IVD_SKIP_NONE; 2500 s_ctl_ip.e_frm_out_mode = IVD_DISPLAY_FRAME_OUT; 2501 s_ctl_ip.e_vid_dec_mode = IVD_DECODE_HEADER; 2502 s_ctl_ip.e_cmd = IVD_CMD_VIDEO_CTL; 2503 s_ctl_ip.e_sub_cmd = IVD_CMD_CTL_SETPARAMS; 2504 s_ctl_ip.u4_size = sizeof(ivd_ctl_set_config_ip_t); 2505 s_ctl_op.u4_size = sizeof(ivd_ctl_set_config_op_t); 2506 2507 ret = ivd_api_function((iv_obj_t*)codec_obj, (void *)&s_ctl_ip, 2508 (void *)&s_ctl_op); 2509 if(ret != IV_SUCCESS) 2510 { 2511 sprintf(ac_error_str, 2512 "\nError in setting the codec in header decode mode"); 2513 codec_exit(ac_error_str); 2514 } 2515 2516 do 2517 { 2518 WORD32 numbytes; 2519 if(0 == s_app_ctx.u4_piclen_flag) 2520 { 2521 fseek(ps_ip_file, file_pos, SEEK_SET); 2522 numbytes = u4_ip_buf_len; 2523 } 2524 else 2525 { 2526 WORD32 entries; 2527 entries = fscanf(ps_piclen_file, "%d\n", &numbytes); 2528 if(1 != entries) 2529 numbytes = u4_ip_buf_len; 2530 } 2531 2532 u4_bytes_remaining = fread(pu1_bs_buf, sizeof(UWORD8), numbytes, 2533 ps_ip_file); 2534 2535 if(0 == u4_bytes_remaining) 2536 { 2537 sprintf(ac_error_str, "\nUnable to read from input file"); 2538 codec_exit(ac_error_str); 2539 } 2540 2541 s_video_decode_ip.e_cmd = IVD_CMD_VIDEO_DECODE; 2542 s_video_decode_ip.u4_ts = u4_ip_frm_ts; 2543 s_video_decode_ip.pv_stream_buffer = pu1_bs_buf; 2544 s_video_decode_ip.u4_num_Bytes = u4_bytes_remaining; 2545 s_video_decode_ip.u4_size = sizeof(ivd_video_decode_ip_t); 2546 s_video_decode_op.u4_size = sizeof(ivd_video_decode_op_t); 2547 2548 /*****************************************************************************/ 2549 /* API Call: Header Decode */ 2550 /*****************************************************************************/ 2551 ret = ivd_api_function((iv_obj_t *)codec_obj, (void *)&s_video_decode_ip, 2552 (void *)&s_video_decode_op); 2553 2554 if(ret != IV_SUCCESS) 2555 { 2556 printf("Error in header decode 0x%x\n", s_video_decode_op.u4_error_code); 2557 // codec_exit(ac_error_str); 2558 } 2559 2560 u4_num_bytes_dec = s_video_decode_op.u4_num_bytes_consumed; 2561 #ifndef PROFILE_ENABLE 2562 printf("%d\n",s_video_decode_op.u4_num_bytes_consumed); 2563 #endif 2564 file_pos += u4_num_bytes_dec; 2565 total_bytes_comsumed += u4_num_bytes_dec; 2566 }while(ret != IV_SUCCESS); 2567 2568 /* copy pic_wd and pic_ht to initialize buffers */ 2569 s_app_ctx.u4_pic_wd = s_video_decode_op.u4_pic_wd; 2570 s_app_ctx.u4_pic_ht = s_video_decode_op.u4_pic_ht; 2571 2572 #if IOS_DISPLAY 2573 s_app_ctx.i4_screen_wd = screen_wd; 2574 s_app_ctx.i4_screen_ht = screen_ht; 2575 #endif 2576 2577 /* Create display thread and wait for the display buffers to be initialized */ 2578 if(1 == s_app_ctx.display) 2579 { 2580 if(0 == s_app_ctx.display_thread_created) 2581 { 2582 s_app_ctx.display_init_done = 0; 2583 ithread_create(s_app_ctx.display_thread_handle, NULL, 2584 (void *) &display_thread, (void *) &s_app_ctx); 2585 s_app_ctx.display_thread_created = 1; 2586 2587 while(1) 2588 { 2589 if(s_app_ctx.display_init_done) 2590 break; 2591 2592 ithread_msleep(1); 2593 } 2594 } 2595 2596 s_app_ctx.u4_strd = s_app_ctx.get_stride(); 2597 } 2598 } 2599 2600 /*************************************************************************/ 2601 /* Get actual number of output buffers requried, which is dependent */ 2602 /* on ps_bitstrm properties such as width, height and level etc */ 2603 /* This is needed mainly for shared display mode */ 2604 /*************************************************************************/ 2605 //if(1 == s_app_ctx.u4_share_disp_buf) 2606 { 2607 /*****************************************************************************/ 2608 /* API Call: Send the allocated display buffers to codec */ 2609 /*****************************************************************************/ 2610 { 2611 ivd_set_display_frame_ip_t s_set_display_frame_ip; 2612 ivd_set_display_frame_op_t s_set_display_frame_op; 2613 2614 s_set_display_frame_ip.e_cmd = IVD_CMD_SET_DISPLAY_FRAME; 2615 s_set_display_frame_ip.u4_size = sizeof(ivd_set_display_frame_ip_t); 2616 s_set_display_frame_op.u4_size = sizeof(ivd_set_display_frame_op_t); 2617 2618 s_set_display_frame_ip.num_disp_bufs = s_app_ctx.num_disp_buf; 2619 2620 memcpy(&(s_set_display_frame_ip.s_disp_buffer), 2621 &(s_app_ctx.s_disp_buffers), 2622 s_app_ctx.num_disp_buf * sizeof(ivd_out_bufdesc_t)); 2623 2624 ret = ivd_api_function((iv_obj_t *)codec_obj, 2625 (void *)&s_set_display_frame_ip, 2626 (void *)&s_set_display_frame_op); 2627 2628 if(IV_SUCCESS != ret) 2629 { 2630 sprintf(ac_error_str, "Error in Set display frame"); 2631 codec_exit(ac_error_str); 2632 } 2633 2634 } 2635 2636 } 2637 2638 /*************************************************************************/ 2639 /* Get frame dimensions for display buffers such as x_offset,y_offset */ 2640 /* etc. This information might be needed to set display buffer */ 2641 /* offsets in case of shared display buffer mode */ 2642 /*************************************************************************/ 2643 { 2644 2645 ih264d_ctl_get_frame_dimensions_ip_t s_ctl_get_frame_dimensions_ip; 2646 ih264d_ctl_get_frame_dimensions_op_t s_ctl_get_frame_dimensions_op; 2647 2648 s_ctl_get_frame_dimensions_ip.e_cmd = IVD_CMD_VIDEO_CTL; 2649 s_ctl_get_frame_dimensions_ip.e_sub_cmd = 2650 (IVD_CONTROL_API_COMMAND_TYPE_T)IH264D_CMD_CTL_GET_BUFFER_DIMENSIONS; 2651 s_ctl_get_frame_dimensions_ip.u4_size = 2652 sizeof(ih264d_ctl_get_frame_dimensions_ip_t); 2653 s_ctl_get_frame_dimensions_op.u4_size = 2654 sizeof(ih264d_ctl_get_frame_dimensions_op_t); 2655 2656 ret = ivd_api_function((iv_obj_t *)codec_obj, (void *)&s_ctl_get_frame_dimensions_ip, 2657 (void *)&s_ctl_get_frame_dimensions_op); 2658 if(IV_SUCCESS != ret) 2659 { 2660 sprintf(ac_error_str, "Error in Get buffer Dimensions"); 2661 codec_exit(ac_error_str); 2662 } 2663 2664 /* 2665 printf("Frame offsets due to padding\n"); 2666 printf("s_ctl_get_frame_dimensions_op.x_offset[0] %d s_ctl_get_frame_dimensions_op.y_offset[0] %d\n", 2667 s_ctl_get_frame_dimensions_op.u4_x_offset[0], 2668 s_ctl_get_frame_dimensions_op.u4_y_offset[0]); 2669 */ 2670 } 2671 2672 2673 2674 /*************************************************************************/ 2675 /* Set the decoder in frame decode mode. It was set in header decode */ 2676 /* mode earlier */ 2677 /*************************************************************************/ 2678 { 2679 2680 ivd_ctl_set_config_ip_t s_ctl_ip; 2681 ivd_ctl_set_config_op_t s_ctl_op; 2682 2683 s_ctl_ip.u4_disp_wd = STRIDE; 2684 if(1 == s_app_ctx.display) 2685 s_ctl_ip.u4_disp_wd = s_app_ctx.get_stride(); 2686 s_ctl_ip.e_frm_skip_mode = IVD_SKIP_NONE; 2687 2688 s_ctl_ip.e_frm_out_mode = IVD_DISPLAY_FRAME_OUT; 2689 s_ctl_ip.e_vid_dec_mode = IVD_DECODE_FRAME; 2690 s_ctl_ip.e_cmd = IVD_CMD_VIDEO_CTL; 2691 s_ctl_ip.e_sub_cmd = IVD_CMD_CTL_SETPARAMS; 2692 s_ctl_ip.u4_size = sizeof(ivd_ctl_set_config_ip_t); 2693 2694 s_ctl_op.u4_size = sizeof(ivd_ctl_set_config_op_t); 2695 2696 ret = ivd_api_function((iv_obj_t *)codec_obj, (void *)&s_ctl_ip, (void *)&s_ctl_op); 2697 2698 if(IV_SUCCESS != ret) 2699 { 2700 sprintf(ac_error_str, "Error in Set Parameters"); 2701 //codec_exit(ac_error_str); 2702 } 2703 2704 } 2705 /*************************************************************************/ 2706 /* If required disable deblocking and sao at given level */ 2707 /*************************************************************************/ 2708 2709 set_degrade(codec_obj, s_app_ctx.i4_degrade_type, s_app_ctx.i4_degrade_pics); 2710 #ifdef WINDOWS_TIMER 2711 QueryPerformanceFrequency ( &frequency); 2712 #endif 2713 #ifndef PRINT_PICSIZE 2714 get_version(codec_obj); 2715 #endif 2716 2717 2718 max_op_frm_ts = s_app_ctx.u4_max_frm_ts + s_app_ctx.disp_delay; 2719 2720 if(max_op_frm_ts < s_app_ctx.disp_delay) 2721 max_op_frm_ts = 0xffffffff;/* clip as overflow has occured*/ 2722 2723 max_op_frm_ts = (s_app_ctx.u4_max_frm_ts > 0)? (max_op_frm_ts): 0xffffffff; 2724 2725 u4_num_disp_bufs_with_dec = 0; 2726 2727 while(u4_op_frm_ts < max_op_frm_ts) 2728 { 2729 2730 #ifdef TEST_FLUSH 2731 if(u4_ip_frm_ts == FLUSH_FRM_CNT) 2732 { 2733 ivd_ctl_flush_ip_t s_ctl_ip; 2734 ivd_ctl_flush_op_t s_ctl_op; 2735 2736 s_ctl_ip.e_cmd = IVD_CMD_VIDEO_CTL; 2737 s_ctl_ip.e_sub_cmd = IVD_CMD_CTL_FLUSH; 2738 s_ctl_ip.u4_size = sizeof(ivd_ctl_flush_ip_t); 2739 s_ctl_op.u4_size = sizeof(ivd_ctl_flush_op_t); 2740 ret = ivd_api_function((iv_obj_t *)codec_obj, (void *)&s_ctl_ip, 2741 (void *)&s_ctl_op); 2742 2743 if(ret != IV_SUCCESS) 2744 { 2745 printf("Error in Setting the decoder in flush mode\n"); 2746 } 2747 // file_pos = 0; 2748 2749 // fseek(ps_ip_file, file_pos, SEEK_SET); 2750 2751 } 2752 #endif 2753 if(u4_num_disp_bufs_with_dec < s_app_ctx.num_disp_buf) 2754 { 2755 release_disp_frame(codec_obj, u4_num_disp_bufs_with_dec); 2756 u4_num_disp_bufs_with_dec ++; 2757 } 2758 2759 2760 /*************************************************************************/ 2761 /* set num of cores */ 2762 /*************************************************************************/ 2763 #ifdef DYNAMIC_NUMCORES 2764 { 2765 2766 ih264d_ctl_set_num_cores_ip_t s_ctl_set_cores_ip; 2767 ih264d_ctl_set_num_cores_op_t s_ctl_set_cores_op; 2768 2769 s_ctl_set_cores_ip.e_cmd = IVD_CMD_VIDEO_CTL; 2770 s_ctl_set_cores_ip.e_sub_cmd = IH264D_CMD_CTL_SET_NUM_CORES; 2771 s_ctl_set_cores_ip.u4_num_cores = 1 + 3 * (u4_ip_frm_ts % 2); 2772 s_ctl_set_cores_ip.u4_size = sizeof(ih264d_ctl_set_num_cores_ip_t); 2773 s_ctl_set_cores_op.u4_size = sizeof(ih264d_ctl_set_num_cores_op_t); 2774 2775 ret = ivd_api_function((iv_obj_t *)codec_obj, (void *)&s_ctl_set_cores_ip, 2776 (void *)&s_ctl_set_cores_op); 2777 if(ret != IV_SUCCESS) 2778 { 2779 sprintf(ac_error_str, "\nError in setting number of cores"); 2780 codec_exit(ac_error_str); 2781 } 2782 2783 } 2784 #endif 2785 /***********************************************************************/ 2786 /* Seek the file to start of current frame, this is equavelent of */ 2787 /* having a parcer which tells the start of current frame */ 2788 /***********************************************************************/ 2789 { 2790 WORD32 numbytes; 2791 2792 if(0 == s_app_ctx.u4_piclen_flag) 2793 { 2794 fseek(ps_ip_file, file_pos, SEEK_SET); 2795 numbytes = u4_ip_buf_len; 2796 } 2797 else 2798 { 2799 WORD32 entries; 2800 entries = fscanf(ps_piclen_file, "%d\n", &numbytes); 2801 if(1 != entries) 2802 numbytes = u4_ip_buf_len; 2803 } 2804 2805 u4_bytes_remaining = fread(pu1_bs_buf, sizeof(UWORD8), 2806 numbytes, ps_ip_file); 2807 2808 if(u4_bytes_remaining == 0) 2809 { 2810 if(1 == s_app_ctx.loopback) 2811 { 2812 file_pos = 0; 2813 if(0 == s_app_ctx.u4_piclen_flag) 2814 { 2815 fseek(ps_ip_file, file_pos, SEEK_SET); 2816 numbytes = u4_ip_buf_len; 2817 } 2818 else 2819 { 2820 WORD32 entries; 2821 entries = fscanf(ps_piclen_file, "%d\n", &numbytes); 2822 if(1 != entries) 2823 numbytes = u4_ip_buf_len; 2824 } 2825 2826 2827 u4_bytes_remaining = fread(pu1_bs_buf, sizeof(UWORD8), 2828 numbytes, ps_ip_file); 2829 } 2830 else 2831 break; 2832 } 2833 } 2834 2835 /*********************************************************************/ 2836 /* Following calls can be enabled at diffent times */ 2837 /*********************************************************************/ 2838 #if ENABLE_DEGRADE 2839 if(u4_op_frm_ts >= 10000) 2840 disable_deblocking(codec_obj, 4); 2841 2842 if(u4_op_frm_ts == 30000) 2843 enable_deblocking(codec_obj); 2844 2845 if(u4_op_frm_ts == 10000) 2846 enable_skippb_frames(codec_obj); 2847 2848 if(u4_op_frm_ts == 60000) 2849 disable_skippb_frames(codec_obj); 2850 2851 if(u4_op_frm_ts == 30000) 2852 enable_skipb_frames(codec_obj); 2853 2854 if(u4_op_frm_ts == 60000) 2855 disable_skipb_frames(codec_obj); 2856 #endif 2857 2858 2859 { 2860 ivd_video_decode_ip_t s_video_decode_ip; 2861 ivd_video_decode_op_t s_video_decode_op; 2862 #ifdef PROFILE_ENABLE 2863 UWORD32 s_elapsed_time; 2864 TIMER s_start_timer; 2865 TIMER s_end_timer; 2866 #endif 2867 2868 2869 s_video_decode_ip.e_cmd = IVD_CMD_VIDEO_DECODE; 2870 s_video_decode_ip.u4_ts = u4_ip_frm_ts; 2871 s_video_decode_ip.pv_stream_buffer = pu1_bs_buf; 2872 s_video_decode_ip.u4_num_Bytes = u4_bytes_remaining; 2873 s_video_decode_ip.u4_size = sizeof(ivd_video_decode_ip_t); 2874 s_video_decode_ip.s_out_buffer.u4_min_out_buf_size[0] = 2875 ps_out_buf->u4_min_out_buf_size[0]; 2876 s_video_decode_ip.s_out_buffer.u4_min_out_buf_size[1] = 2877 ps_out_buf->u4_min_out_buf_size[1]; 2878 s_video_decode_ip.s_out_buffer.u4_min_out_buf_size[2] = 2879 ps_out_buf->u4_min_out_buf_size[2]; 2880 2881 s_video_decode_ip.s_out_buffer.pu1_bufs[0] = 2882 ps_out_buf->pu1_bufs[0]; 2883 s_video_decode_ip.s_out_buffer.pu1_bufs[1] = 2884 ps_out_buf->pu1_bufs[1]; 2885 s_video_decode_ip.s_out_buffer.pu1_bufs[2] = 2886 ps_out_buf->pu1_bufs[2]; 2887 s_video_decode_ip.s_out_buffer.u4_num_bufs = 2888 ps_out_buf->u4_num_bufs; 2889 s_video_decode_op.u4_size = sizeof(ivd_video_decode_op_t); 2890 2891 /* Get display buffer pointers */ 2892 if(1 == s_app_ctx.display) 2893 { 2894 WORD32 wr_idx; 2895 2896 wr_idx = dispq_producer_dequeue(&s_app_ctx); 2897 2898 if(s_app_ctx.quit) 2899 break; 2900 2901 s_app_ctx.set_disp_buffers(s_app_ctx.pv_disp_ctx, wr_idx, 2902 &s_video_decode_ip.s_out_buffer.pu1_bufs[0], 2903 &s_video_decode_ip.s_out_buffer.pu1_bufs[1], 2904 &s_video_decode_ip.s_out_buffer.pu1_bufs[2]); 2905 } 2906 2907 /*****************************************************************************/ 2908 /* API Call: Video Decode */ 2909 /*****************************************************************************/ 2910 2911 GETTIME(&s_start_timer); 2912 2913 ret = ivd_api_function((iv_obj_t *)codec_obj, (void *)&s_video_decode_ip, 2914 (void *)&s_video_decode_op); 2915 2916 2917 GETTIME(&s_end_timer); 2918 ELAPSEDTIME(s_start_timer,s_end_timer,s_elapsed_time,frequency); 2919 #ifdef PROFILE_ENABLE 2920 { 2921 UWORD32 peak_avg, id; 2922 u4_tot_cycles += s_elapsed_time; 2923 peak_window[peak_window_idx++] = s_elapsed_time; 2924 if(peak_window_idx == PEAK_WINDOW_SIZE) 2925 peak_window_idx = 0; 2926 peak_avg = 0; 2927 for(id = 0; id < PEAK_WINDOW_SIZE; id++) 2928 { 2929 peak_avg += peak_window[id]; 2930 } 2931 peak_avg /= PEAK_WINDOW_SIZE; 2932 if(peak_avg > peak_avg_max) 2933 peak_avg_max = peak_avg; 2934 frm_cnt++; 2935 2936 printf("FrameNum: %4d TimeTaken(microsec): %6d AvgTime: %6d PeakAvgTimeMax: %6d Output: %2d NumBytes: %6d \n", 2937 frm_cnt, s_elapsed_time, u4_tot_cycles / frm_cnt, peak_avg_max, s_video_decode_op.u4_output_present, s_video_decode_op.u4_num_bytes_consumed); 2938 2939 } 2940 #ifdef INTEL_CE5300 2941 time_consumed += s_elapsed_time; 2942 bytes_consumed += s_video_decode_op.u4_num_bytes_consumed; 2943 if (!(frm_cnt % (s_app_ctx.fps))) 2944 { 2945 time_consumed = time_consumed/s_app_ctx.fps; 2946 printf("Average decode time(micro sec) for the last second = %6d\n",time_consumed); 2947 printf("Average bitrate(kb) for the last second = %6d\n",(bytes_consumed * 8) / 1024); 2948 time_consumed = 0; 2949 bytes_consumed = 0; 2950 2951 } 2952 #endif 2953 #else 2954 printf("%d\n",s_video_decode_op.u4_num_bytes_consumed); 2955 #endif 2956 2957 if(ret != IV_SUCCESS) 2958 { 2959 printf("Error in video Frame decode : ret %x Error %x\n", ret, 2960 s_video_decode_op.u4_error_code); 2961 } 2962 2963 if((IV_SUCCESS != ret) && 2964 ((s_video_decode_op.u4_error_code & 0xFF) == IVD_RES_CHANGED)) 2965 { 2966 ivd_ctl_reset_ip_t s_ctl_ip; 2967 ivd_ctl_reset_op_t s_ctl_op; 2968 2969 flush_output(codec_obj, &s_app_ctx, ps_out_buf, 2970 pu1_bs_buf, &u4_op_frm_ts, 2971 ps_op_file, ps_op_chksum_file, 2972 u4_ip_frm_ts, u4_bytes_remaining); 2973 2974 s_ctl_ip.e_cmd = IVD_CMD_VIDEO_CTL; 2975 s_ctl_ip.e_sub_cmd = IVD_CMD_CTL_RESET; 2976 s_ctl_ip.u4_size = sizeof(ivd_ctl_reset_ip_t); 2977 s_ctl_op.u4_size = sizeof(ivd_ctl_reset_op_t); 2978 2979 ret = ivd_api_function((iv_obj_t *)codec_obj, (void *)&s_ctl_ip, 2980 (void *)&s_ctl_op); 2981 if(IV_SUCCESS != ret) 2982 { 2983 sprintf(ac_error_str, "Error in Reset"); 2984 codec_exit(ac_error_str); 2985 } 2986 2987 /*when reset all buffers are released by lib*/ 2988 u4_num_disp_bufs_with_dec = 0; 2989 /*************************************************************************/ 2990 /* set num of cores */ 2991 /*************************************************************************/ 2992 { 2993 2994 ih264d_ctl_set_num_cores_ip_t s_ctl_set_cores_ip; 2995 ih264d_ctl_set_num_cores_op_t s_ctl_set_cores_op; 2996 2997 s_ctl_set_cores_ip.e_cmd = IVD_CMD_VIDEO_CTL; 2998 s_ctl_set_cores_ip.e_sub_cmd =(IVD_CONTROL_API_COMMAND_TYPE_T) IH264D_CMD_CTL_SET_NUM_CORES; 2999 s_ctl_set_cores_ip.u4_num_cores = s_app_ctx.u4_num_cores; 3000 s_ctl_set_cores_ip.u4_size = sizeof(ih264d_ctl_set_num_cores_ip_t); 3001 s_ctl_set_cores_op.u4_size = sizeof(ih264d_ctl_set_num_cores_op_t); 3002 3003 ret = ivd_api_function((iv_obj_t*)codec_obj, (void *)&s_ctl_set_cores_ip, 3004 (void *)&s_ctl_set_cores_op); 3005 if(ret != IV_SUCCESS) 3006 { 3007 sprintf(ac_error_str, "\nError in setting number of cores"); 3008 codec_exit(ac_error_str); 3009 } 3010 3011 } 3012 /*************************************************************************/ 3013 /* set processsor */ 3014 /*************************************************************************/ 3015 3016 { 3017 3018 ih264d_ctl_set_processor_ip_t s_ctl_set_num_processor_ip; 3019 ih264d_ctl_set_processor_op_t s_ctl_set_num_processor_op; 3020 3021 s_ctl_set_num_processor_ip.e_cmd = IVD_CMD_VIDEO_CTL; 3022 s_ctl_set_num_processor_ip.e_sub_cmd =(IVD_CONTROL_API_COMMAND_TYPE_T) IH264D_CMD_CTL_SET_PROCESSOR; 3023 s_ctl_set_num_processor_ip.u4_arch = s_app_ctx.e_arch; 3024 s_ctl_set_num_processor_ip.u4_soc = s_app_ctx.e_soc; 3025 s_ctl_set_num_processor_ip.u4_size = sizeof(ih264d_ctl_set_processor_ip_t); 3026 s_ctl_set_num_processor_op.u4_size = sizeof(ih264d_ctl_set_processor_op_t); 3027 3028 ret = ivd_api_function((iv_obj_t*)codec_obj, (void *)&s_ctl_set_num_processor_ip, 3029 (void *)&s_ctl_set_num_processor_op); 3030 if(ret != IV_SUCCESS) 3031 { 3032 sprintf(ac_error_str, "\nError in setting Processor type"); 3033 codec_exit(ac_error_str); 3034 } 3035 3036 } 3037 3038 } 3039 3040 3041 if((1 == s_app_ctx.display) && 3042 (1 == s_video_decode_op.u4_output_present)) 3043 { 3044 dispq_producer_queue(&s_app_ctx); 3045 } 3046 3047 if(IV_B_FRAME == s_video_decode_op.e_pic_type) 3048 s_app_ctx.b_pic_present |= 1; 3049 3050 u4_num_bytes_dec = s_video_decode_op.u4_num_bytes_consumed; 3051 3052 file_pos += u4_num_bytes_dec; 3053 total_bytes_comsumed += u4_num_bytes_dec; 3054 u4_ip_frm_ts++; 3055 3056 3057 if(1 == s_video_decode_op.u4_output_present) 3058 { 3059 3060 CHAR cur_fname[1000]; 3061 CHAR *extn = NULL; 3062 /* The objective is to dump the decoded frames into separate files instead of 3063 * dumping all the frames in one common file. Also, the number of dumped frames 3064 * at any given instance of time cannot exceed 'frame_memory' 3065 */ 3066 if(s_app_ctx.u4_file_save_flag) 3067 { 3068 /* Locate the position of extension yuv */ 3069 extn = strstr(s_app_ctx.ac_op_fname,"%d"); 3070 if (extn != NULL) 3071 { 3072 output_write_stall(s_app_ctx.ac_op_fname,u4_op_frm_ts); 3073 /* Generate output file names */ 3074 sprintf(cur_fname,s_app_ctx.ac_op_fname,u4_op_frm_ts); 3075 /* Open Output file */ 3076 ps_op_file = fopen(cur_fname,"wb"); 3077 if (NULL == ps_op_file) 3078 { 3079 sprintf(ac_error_str, "Could not open output file %s", 3080 cur_fname); 3081 3082 codec_exit(ac_error_str); 3083 } 3084 } 3085 } 3086 3087 width = s_video_decode_op.s_disp_frm_buf.u4_y_wd; 3088 height = s_video_decode_op.s_disp_frm_buf.u4_y_ht; 3089 dump_output(&s_app_ctx, &(s_video_decode_op.s_disp_frm_buf), 3090 s_video_decode_op.u4_disp_buf_id, ps_op_file, 3091 ps_op_chksum_file, 3092 u4_op_frm_ts, s_app_ctx.u4_file_save_flag, 3093 s_app_ctx.u4_chksum_save_flag); 3094 3095 u4_op_frm_ts++; 3096 if (extn != NULL) 3097 fclose(ps_op_file); 3098 3099 } 3100 else 3101 { 3102 if((s_video_decode_op.u4_error_code >> IVD_FATALERROR) & 1) 3103 { 3104 printf("Fatal error\n"); 3105 break; 3106 } 3107 } 3108 3109 } 3110 } 3111 3112 /***********************************************************************/ 3113 /* To get the last decoded frames, call process with NULL input */ 3114 /***********************************************************************/ 3115 flush_output(codec_obj, &s_app_ctx, ps_out_buf, 3116 pu1_bs_buf, &u4_op_frm_ts, 3117 ps_op_file, ps_op_chksum_file, 3118 u4_ip_frm_ts, u4_bytes_remaining); 3119 3120 /* set disp_end u4_flag */ 3121 s_app_ctx.quit = 1; 3122 3123 3124 #ifdef PROFILE_ENABLE 3125 printf("Summary\n"); 3126 printf("Input filename : %s\n", s_app_ctx.ac_ip_fname); 3127 printf("Output Width : %-4d\n", width); 3128 printf("Output Height : %-4d\n", height); 3129 3130 if(frm_cnt) 3131 { 3132 double avg = u4_tot_cycles / frm_cnt; 3133 double bytes_avg = total_bytes_comsumed / frm_cnt; 3134 double bitrate = (bytes_avg * 8 * s_app_ctx.fps)/1000000; 3135 printf("Bitrate @ %2d fps(mbps) : %-6.2f\n", s_app_ctx.fps, bitrate); 3136 printf("Average decode time(micro sec) : %-6d\n", (WORD32)avg); 3137 printf("Avg Peak decode time(%2d frames) : %-6d\n", PEAK_WINDOW_SIZE, (WORD32)peak_avg_max); 3138 avg = (u4_tot_cycles + u4_tot_fmt_cycles)* 1.0 / frm_cnt; 3139 3140 if(0 == s_app_ctx.u4_share_disp_buf) 3141 printf("FPS achieved (with format conv) : %-3.2f\n", 1000000/avg); 3142 else 3143 printf("FPS achieved : %-3.2f\n", 1000000/avg); 3144 } 3145 #endif 3146 /***********************************************************************/ 3147 /* Clear the decoder, close all the files, free all the memory */ 3148 /***********************************************************************/ 3149 if(1 == s_app_ctx.display) 3150 { 3151 s_app_ctx.display_deinit_flag = 1; 3152 /* wait for display to finish */ 3153 if(s_app_ctx.display_thread_created) 3154 { 3155 ithread_join(s_app_ctx.display_thread_handle, NULL); 3156 } 3157 free(s_app_ctx.display_thread_handle); 3158 } 3159 3160 { 3161 iv_retrieve_mem_rec_ip_t s_retrieve_dec_ip; 3162 iv_retrieve_mem_rec_op_t s_retrieve_dec_op; 3163 s_retrieve_dec_ip.pv_mem_rec_location = (iv_mem_rec_t *)pv_mem_rec_location; 3164 3165 s_retrieve_dec_ip.e_cmd = IV_CMD_RETRIEVE_MEMREC; 3166 s_retrieve_dec_ip.u4_size = sizeof(iv_retrieve_mem_rec_ip_t); 3167 s_retrieve_dec_op.u4_size = sizeof(iv_retrieve_mem_rec_op_t); 3168 3169 ret = ivd_api_function((iv_obj_t *)codec_obj, (void *)&s_retrieve_dec_ip, 3170 (void *)&s_retrieve_dec_op); 3171 3172 if(IV_SUCCESS != ret) 3173 { 3174 sprintf(ac_error_str, "Error in Retrieve Memrec"); 3175 codec_exit(ac_error_str); 3176 } 3177 3178 { 3179 iv_mem_rec_t *ps_mem_rec; 3180 UWORD16 u2_i; 3181 3182 u4_num_mem_recs = s_retrieve_dec_op.u4_num_mem_rec_filled; 3183 3184 ps_mem_rec = s_retrieve_dec_ip.pv_mem_rec_location; 3185 3186 for(u2_i = 0; u2_i < u4_num_mem_recs; u2_i++) 3187 { 3188 ih264a_aligned_free(ps_mem_rec->pv_base); 3189 ps_mem_rec++; 3190 } 3191 free(s_retrieve_dec_ip.pv_mem_rec_location); 3192 } 3193 3194 } 3195 /***********************************************************************/ 3196 /* Close all the files and free all the memory */ 3197 /***********************************************************************/ 3198 { 3199 fclose(ps_ip_file); 3200 3201 if((1 == s_app_ctx.u4_file_save_flag) && (strstr(s_app_ctx.ac_op_fname,"%d") == NULL)) 3202 { 3203 fclose(ps_op_file); 3204 } 3205 if(1 == s_app_ctx.u4_chksum_save_flag) 3206 { 3207 fclose(ps_op_chksum_file); 3208 } 3209 3210 } 3211 3212 if(0 == s_app_ctx.u4_share_disp_buf) 3213 { 3214 free(ps_out_buf->pu1_bufs[0]); 3215 } 3216 3217 for(i = 0; i < s_app_ctx.num_disp_buf; i++) 3218 { 3219 free(s_app_ctx.s_disp_buffers[i].pu1_bufs[0]); 3220 } 3221 3222 free(ps_out_buf); 3223 free(pu1_bs_buf); 3224 3225 return (0); 3226 } 3227