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