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 1785 #ifdef X86_MINGW 1786 //For getting printfs without any delay 1787 setvbuf(stdout, NULL, _IONBF, 0); 1788 setvbuf(stderr, NULL, _IONBF, 0); 1789 #endif 1790 #ifdef IOS 1791 sprintf(filename_trace, "%s/iostrace.txt", homedir); 1792 printf("\ntrace file name = %s", filename_trace); 1793 #endif 1794 1795 #ifdef X86_MINGW 1796 { 1797 signal(SIGSEGV, sigsegv_handler); 1798 } 1799 #endif 1800 1801 1802 #ifndef IOS 1803 /* Usage */ 1804 if(argc < 2) 1805 { 1806 printf("Using test.cfg as configuration file \n"); 1807 strcpy(ac_cfg_fname, "test.cfg"); 1808 } 1809 else if(argc == 2) 1810 { 1811 strcpy(ac_cfg_fname, argv[1]); 1812 } 1813 1814 #else 1815 strcpy(ac_cfg_fname, "test.cfg"); 1816 1817 #endif 1818 1819 1820 /***********************************************************************/ 1821 /* Initialize Application parameters */ 1822 /***********************************************************************/ 1823 1824 strcpy(s_app_ctx.ac_ip_fname, "\0"); 1825 s_app_ctx.dump_q_wr_idx = 0; 1826 s_app_ctx.dump_q_rd_idx = 0; 1827 s_app_ctx.display_thread_created = 0; 1828 s_app_ctx.disp_q_wr_idx = 0; 1829 s_app_ctx.disp_q_rd_idx = 0; 1830 s_app_ctx.disp_delay = 0; 1831 s_app_ctx.loopback = 0; 1832 s_app_ctx.display = 0; 1833 s_app_ctx.full_screen = 0; 1834 s_app_ctx.u4_piclen_flag = 0; 1835 s_app_ctx.fps = DEFAULT_FPS; 1836 file_pos = 0; 1837 total_bytes_comsumed = 0; 1838 u4_ip_frm_ts = 0; 1839 u4_op_frm_ts = 0; 1840 #ifdef PROFILE_ENABLE 1841 memset(peak_window, 0, sizeof(WORD32) * PEAK_WINDOW_SIZE); 1842 #endif 1843 s_app_ctx.share_disp_buf = DEFAULT_SHARE_DISPLAY_BUF; 1844 s_app_ctx.u4_num_cores = DEFAULT_NUM_CORES; 1845 s_app_ctx.i4_degrade_type = 0; 1846 s_app_ctx.i4_degrade_pics = 0; 1847 s_app_ctx.max_wd = 0; 1848 s_app_ctx.max_ht = 0; 1849 s_app_ctx.max_level = 0; 1850 s_app_ctx.e_arch = ARCH_ARM_A9Q; 1851 s_app_ctx.e_soc = SOC_GENERIC; 1852 1853 s_app_ctx.u4_strd = STRIDE; 1854 1855 s_app_ctx.display_thread_handle = malloc(ithread_get_handle_size()); 1856 s_app_ctx.quit = 0; 1857 s_app_ctx.paused = 0; 1858 //s_app_ctx.u4_output_present = 0; 1859 1860 s_app_ctx.get_stride = &default_get_stride; 1861 1862 s_app_ctx.get_color_fmt = &default_get_color_fmt; 1863 1864 /* Set function pointers for display */ 1865 #ifdef SDL_DISPLAY 1866 s_app_ctx.disp_init = &sdl_disp_init; 1867 s_app_ctx.alloc_disp_buffers = &sdl_alloc_disp_buffers; 1868 s_app_ctx.display_buffer = &sdl_display; 1869 s_app_ctx.set_disp_buffers = &sdl_set_disp_buffers; 1870 s_app_ctx.disp_deinit = &sdl_disp_deinit; 1871 s_app_ctx.disp_usleep = &sdl_disp_usleep; 1872 s_app_ctx.get_color_fmt = &sdl_get_color_fmt; 1873 s_app_ctx.get_stride = &sdl_get_stride; 1874 #endif 1875 1876 #ifdef FBDEV_DISPLAY 1877 s_app_ctx.disp_init = &fbd_disp_init; 1878 s_app_ctx.alloc_disp_buffers = &fbd_alloc_disp_buffers; 1879 s_app_ctx.display_buffer = &fbd_display; 1880 s_app_ctx.set_disp_buffers = &fbd_set_disp_buffers; 1881 s_app_ctx.disp_deinit = &fbd_disp_deinit; 1882 s_app_ctx.disp_usleep = &fbd_disp_usleep; 1883 s_app_ctx.get_color_fmt = &fbd_get_color_fmt; 1884 s_app_ctx.get_stride = &fbd_get_stride; 1885 #endif 1886 1887 #ifdef INTEL_CE5300 1888 s_app_ctx.disp_init = &gdl_disp_init; 1889 s_app_ctx.alloc_disp_buffers = &gdl_alloc_disp_buffers; 1890 s_app_ctx.display_buffer = &gdl_display; 1891 s_app_ctx.set_disp_buffers = &gdl_set_disp_buffers; 1892 s_app_ctx.disp_deinit = &gdl_disp_deinit; 1893 s_app_ctx.disp_usleep = &gdl_disp_usleep; 1894 s_app_ctx.get_color_fmt = &gdl_get_color_fmt; 1895 s_app_ctx.get_stride = &gdl_get_stride; 1896 #endif 1897 1898 #ifdef IOS_DISPLAY 1899 s_app_ctx.disp_init = &ios_disp_init; 1900 s_app_ctx.alloc_disp_buffers = &ios_alloc_disp_buffers; 1901 s_app_ctx.display_buffer = &ios_display; 1902 s_app_ctx.set_disp_buffers = &ios_set_disp_buffers; 1903 s_app_ctx.disp_deinit = &ios_disp_deinit; 1904 s_app_ctx.disp_usleep = &ios_disp_usleep; 1905 s_app_ctx.get_color_fmt = &ios_get_color_fmt; 1906 s_app_ctx.get_stride = &ios_get_stride; 1907 #endif 1908 1909 s_app_ctx.display_deinit_flag = 0; 1910 s_app_ctx.e_output_chroma_format = IV_YUV_420SP_UV; 1911 /*************************************************************************/ 1912 /* Parse arguments */ 1913 /*************************************************************************/ 1914 1915 #ifndef IOS 1916 /* Read command line arguments */ 1917 if(argc > 2) 1918 { 1919 for(i = 1; i < (UWORD32)argc; i += 2) 1920 { 1921 if(CONFIG == get_argument(argv[i])) 1922 { 1923 strcpy(ac_cfg_fname, argv[i + 1]); 1924 if((fp_cfg_file = fopen(ac_cfg_fname, "r")) == NULL) 1925 { 1926 sprintf(ac_error_str, "Could not open Configuration file %s", 1927 ac_cfg_fname); 1928 codec_exit(ac_error_str); 1929 } 1930 read_cfg_file(&s_app_ctx, fp_cfg_file); 1931 fclose(fp_cfg_file); 1932 } 1933 else 1934 { 1935 parse_argument(&s_app_ctx, argv[i], argv[i + 1]); 1936 } 1937 } 1938 } 1939 else 1940 { 1941 if((fp_cfg_file = fopen(ac_cfg_fname, "r")) == NULL) 1942 { 1943 sprintf(ac_error_str, "Could not open Configuration file %s", 1944 ac_cfg_fname); 1945 codec_exit(ac_error_str); 1946 } 1947 read_cfg_file(&s_app_ctx, fp_cfg_file); 1948 fclose(fp_cfg_file); 1949 } 1950 #else 1951 sprintf(filename_with_path, "%s/%s", homedir, ac_cfg_fname); 1952 if((fp_cfg_file = fopen(filename_with_path, "r")) == NULL) 1953 { 1954 sprintf(ac_error_str, "Could not open Configuration file %s", 1955 ac_cfg_fname); 1956 codec_exit(ac_error_str); 1957 1958 } 1959 read_cfg_file(&s_app_ctx, fp_cfg_file); 1960 fclose(fp_cfg_file); 1961 1962 #endif 1963 #ifdef PRINT_PICSIZE 1964 /* If the binary is used for only getting number of bytes in each picture, then disable the following features */ 1965 s_app_ctx.u4_piclen_flag = 0; 1966 s_app_ctx.u4_file_save_flag = 0; 1967 s_app_ctx.u4_chksum_save_flag = 0; 1968 s_app_ctx.i4_degrade_pics = 0; 1969 s_app_ctx.i4_degrade_type = 0; 1970 s_app_ctx.loopback = 0; 1971 s_app_ctx.share_disp_buf = 0; 1972 s_app_ctx.display = 0; 1973 #endif 1974 1975 /* If display is enabled, then turn off shared mode and get color format that is supported by display */ 1976 if(1 == s_app_ctx.display) 1977 { 1978 s_app_ctx.share_disp_buf = 0; 1979 s_app_ctx.e_output_chroma_format = s_app_ctx.get_color_fmt(); 1980 } 1981 if(strcmp(s_app_ctx.ac_ip_fname, "\0") == 0) 1982 { 1983 printf("\nNo input file given for decoding\n"); 1984 exit(-1); 1985 } 1986 1987 1988 /***********************************************************************/ 1989 /* create the file object for input file */ 1990 /***********************************************************************/ 1991 #ifdef IOS 1992 sprintf(filename_with_path, "%s/%s", homedir, s_app_ctx.ac_ip_fname); 1993 ps_ip_file = fopen(filename_with_path, "rb"); 1994 #else 1995 ps_ip_file = fopen(s_app_ctx.ac_ip_fname, "rb"); 1996 #endif 1997 if(NULL == ps_ip_file) 1998 { 1999 sprintf(ac_error_str, "Could not open input file %s", 2000 s_app_ctx.ac_ip_fname); 2001 codec_exit(ac_error_str); 2002 } 2003 /***********************************************************************/ 2004 /* create the file object for input file */ 2005 /***********************************************************************/ 2006 if(1 == s_app_ctx.u4_piclen_flag) 2007 { 2008 #ifdef IOS 2009 sprintf(filename_with_path, "%s/%s", homedir, s_app_ctx.ac_piclen_fname); 2010 ps_piclen_file = fopen(filename_with_path, "rb"); 2011 #else 2012 ps_piclen_file = fopen(s_app_ctx.ac_piclen_fname, "rb"); 2013 #endif 2014 if(NULL == ps_piclen_file) 2015 { 2016 sprintf(ac_error_str, "Could not open piclen file %s", 2017 s_app_ctx.ac_piclen_fname); 2018 codec_exit(ac_error_str); 2019 } 2020 } 2021 2022 /***********************************************************************/ 2023 /* create the file object for output file */ 2024 /***********************************************************************/ 2025 if(1 == s_app_ctx.u4_file_save_flag) 2026 { 2027 #ifdef IOS 2028 sprintf(filename_with_path, "%s/%s", documentdir, s_app_ctx.ac_op_fname); 2029 ps_op_file = fopen(filename_with_path, "wb"); 2030 #else 2031 ps_op_file = fopen(s_app_ctx.ac_op_fname, "wb"); 2032 #endif 2033 2034 if(NULL == ps_op_file) 2035 { 2036 sprintf(ac_error_str, "Could not open output file %s", 2037 s_app_ctx.ac_op_fname); 2038 codec_exit(ac_error_str); 2039 } 2040 } 2041 2042 /***********************************************************************/ 2043 /* create the file object for check sum file */ 2044 /***********************************************************************/ 2045 if(1 == s_app_ctx.u4_chksum_save_flag) 2046 { 2047 #if IOS 2048 sprintf(filename_with_path, "%s/%s", documentdir, s_app_ctx.ac_op_chksum_fname); 2049 ps_op_chksum_file = fopen(filename_with_path, "wb"); 2050 #else 2051 ps_op_chksum_file = fopen(s_app_ctx.ac_op_chksum_fname, "wb"); 2052 #endif 2053 if(NULL == ps_op_chksum_file) 2054 { 2055 sprintf(ac_error_str, "Could not open check sum file %s", 2056 s_app_ctx.ac_op_chksum_fname); 2057 codec_exit(ac_error_str); 2058 } 2059 } 2060 /***********************************************************************/ 2061 /* Create decoder instance */ 2062 /***********************************************************************/ 2063 { 2064 2065 ps_out_buf = (ivd_out_bufdesc_t *)malloc(sizeof(ivd_out_bufdesc_t)); 2066 2067 { 2068 iv_num_mem_rec_ip_t s_no_of_mem_rec_query_ip; 2069 iv_num_mem_rec_op_t s_no_of_mem_rec_query_op; 2070 2071 s_no_of_mem_rec_query_ip.u4_size = sizeof(s_no_of_mem_rec_query_ip); 2072 s_no_of_mem_rec_query_op.u4_size = sizeof(s_no_of_mem_rec_query_op); 2073 s_no_of_mem_rec_query_ip.e_cmd = IV_CMD_GET_NUM_MEM_REC; 2074 2075 /*****************************************************************************/ 2076 /* API Call: Get Number of Mem Records */ 2077 /*****************************************************************************/ 2078 e_dec_status = ivd_cxa_api_function( 2079 NULL, (void *)&s_no_of_mem_rec_query_ip, 2080 (void *)&s_no_of_mem_rec_query_op); 2081 if(IV_SUCCESS != e_dec_status) 2082 { 2083 sprintf(ac_error_str, "Error in get mem records"); 2084 codec_exit(ac_error_str); 2085 } 2086 2087 u4_num_mem_recs = s_no_of_mem_rec_query_op.u4_num_mem_rec; 2088 } 2089 2090 pv_mem_rec_location = malloc(u4_num_mem_recs * sizeof(iv_mem_rec_t)); 2091 if(pv_mem_rec_location == NULL) 2092 { 2093 sprintf(ac_error_str, "Allocation failure for mem_rec_location"); 2094 codec_exit(ac_error_str); 2095 2096 } 2097 2098 { 2099 ihevcd_cxa_fill_mem_rec_ip_t s_fill_mem_rec_ip; 2100 ihevcd_cxa_fill_mem_rec_op_t s_fill_mem_rec_op; 2101 iv_mem_rec_t *ps_mem_rec; 2102 UWORD32 total_size; 2103 2104 s_fill_mem_rec_ip.s_ivd_fill_mem_rec_ip_t.e_cmd = 2105 IV_CMD_FILL_NUM_MEM_REC; 2106 s_fill_mem_rec_ip.s_ivd_fill_mem_rec_ip_t.pv_mem_rec_location = 2107 (iv_mem_rec_t *)pv_mem_rec_location; 2108 s_fill_mem_rec_ip.s_ivd_fill_mem_rec_ip_t.u4_max_frm_wd = 2109 (s_app_ctx.max_wd == 0) ? MAX_FRAME_WIDTH : s_app_ctx.max_wd; 2110 s_fill_mem_rec_ip.s_ivd_fill_mem_rec_ip_t.u4_max_frm_ht = 2111 (s_app_ctx.max_ht == 0) ? MAX_FRAME_HEIGHT : s_app_ctx.max_ht; 2112 s_fill_mem_rec_ip.i4_level = (s_app_ctx.max_level == 0) ? MAX_LEVEL_SUPPORTED : s_app_ctx.max_level; 2113 s_fill_mem_rec_ip.u4_num_ref_frames = MAX_REF_FRAMES; 2114 s_fill_mem_rec_ip.u4_num_reorder_frames = MAX_REORDER_FRAMES; 2115 s_fill_mem_rec_ip.u4_share_disp_buf = s_app_ctx.share_disp_buf; 2116 s_fill_mem_rec_ip.e_output_format = 2117 (IV_COLOR_FORMAT_T)s_app_ctx.e_output_chroma_format; 2118 s_fill_mem_rec_ip.u4_num_extra_disp_buf = EXTRA_DISP_BUFFERS; 2119 2120 s_fill_mem_rec_ip.s_ivd_fill_mem_rec_ip_t.u4_size = 2121 sizeof(ihevcd_cxa_fill_mem_rec_ip_t); 2122 s_fill_mem_rec_op.s_ivd_fill_mem_rec_op_t.u4_size = 2123 sizeof(ihevcd_cxa_fill_mem_rec_op_t); 2124 2125 ps_mem_rec = (iv_mem_rec_t *)pv_mem_rec_location; 2126 for(i = 0; i < u4_num_mem_recs; i++) 2127 ps_mem_rec[i].u4_size = sizeof(iv_mem_rec_t); 2128 2129 /*****************************************************************************/ 2130 /* API Call: Fill Mem Records */ 2131 /*****************************************************************************/ 2132 2133 e_dec_status = ivd_cxa_api_function(NULL, 2134 (void *)&s_fill_mem_rec_ip, 2135 (void *)&s_fill_mem_rec_op); 2136 2137 u4_num_mem_recs = 2138 s_fill_mem_rec_op.s_ivd_fill_mem_rec_op_t.u4_num_mem_rec_filled; 2139 2140 if(IV_SUCCESS != e_dec_status) 2141 { 2142 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); 2143 codec_exit(ac_error_str); 2144 } 2145 2146 ps_mem_rec = (iv_mem_rec_t *)pv_mem_rec_location; 2147 total_size = 0; 2148 for(i = 0; i < u4_num_mem_recs; i++) 2149 { 2150 ps_mem_rec->pv_base = ihevca_aligned_malloc(ps_mem_rec->u4_mem_alignment, 2151 ps_mem_rec->u4_mem_size); 2152 if(ps_mem_rec->pv_base == NULL) 2153 { 2154 sprintf(ac_error_str, 2155 "\nAllocation failure for mem record id %d size %d\n", 2156 i, ps_mem_rec->u4_mem_size); 2157 codec_exit(ac_error_str); 2158 2159 } 2160 total_size += ps_mem_rec->u4_mem_size; 2161 2162 ps_mem_rec++; 2163 } 2164 //printf("\nTotal memory for codec %d\n", total_size); 2165 } 2166 /*****************************************************************************/ 2167 /* API Call: Initialize the Decoder */ 2168 /*****************************************************************************/ 2169 { 2170 ihevcd_cxa_init_ip_t s_init_ip; 2171 ihevcd_cxa_init_op_t s_init_op; 2172 void *fxns = &ivd_cxa_api_function; 2173 iv_mem_rec_t *mem_tab; 2174 2175 mem_tab = (iv_mem_rec_t *)pv_mem_rec_location; 2176 s_init_ip.s_ivd_init_ip_t.e_cmd = (IVD_API_COMMAND_TYPE_T)IV_CMD_INIT; 2177 s_init_ip.s_ivd_init_ip_t.pv_mem_rec_location = mem_tab; 2178 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; 2179 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; 2180 s_init_ip.i4_level = (s_app_ctx.max_level == 0) ? MAX_LEVEL_SUPPORTED : s_app_ctx.max_level; 2181 s_init_ip.u4_num_ref_frames = MAX_REF_FRAMES; 2182 s_init_ip.u4_num_reorder_frames = MAX_REORDER_FRAMES; 2183 s_init_ip.u4_share_disp_buf = s_app_ctx.share_disp_buf; 2184 s_init_ip.u4_num_extra_disp_buf = EXTRA_DISP_BUFFERS; 2185 s_init_ip.s_ivd_init_ip_t.u4_num_mem_rec = u4_num_mem_recs; 2186 s_init_ip.s_ivd_init_ip_t.e_output_format = 2187 (IV_COLOR_FORMAT_T)s_app_ctx.e_output_chroma_format; 2188 s_init_ip.s_ivd_init_ip_t.u4_size = sizeof(ihevcd_cxa_init_ip_t); 2189 s_init_op.s_ivd_init_op_t.u4_size = sizeof(ihevcd_cxa_init_op_t); 2190 2191 codec_obj = (iv_obj_t *)mem_tab[0].pv_base; 2192 codec_obj->pv_fxns = fxns; 2193 codec_obj->u4_size = sizeof(iv_obj_t); 2194 2195 s_app_ctx.cocodec_obj = codec_obj; 2196 2197 ret = ivd_cxa_api_function((iv_obj_t *)codec_obj, (void *)&s_init_ip, 2198 (void *)&s_init_op); 2199 if(ret != IV_SUCCESS) 2200 { 2201 sprintf(ac_error_str, "Error in Init %8x\n", 2202 s_init_op.s_ivd_init_op_t.u4_error_code); 2203 codec_exit(ac_error_str); 2204 } 2205 2206 /*****************************************************************************/ 2207 /* Input and output buffer allocation */ 2208 /*****************************************************************************/ 2209 { 2210 2211 ivd_ctl_getbufinfo_ip_t s_ctl_ip; 2212 ivd_ctl_getbufinfo_op_t s_ctl_op; 2213 2214 s_ctl_ip.e_cmd = IVD_CMD_VIDEO_CTL; 2215 s_ctl_ip.e_sub_cmd = IVD_CMD_CTL_GETBUFINFO; 2216 s_ctl_ip.u4_size = sizeof(ivd_ctl_getbufinfo_ip_t); 2217 s_ctl_op.u4_size = sizeof(ivd_ctl_getbufinfo_op_t); 2218 ret = ivd_cxa_api_function((iv_obj_t *)codec_obj, (void *)&s_ctl_ip, 2219 (void *)&s_ctl_op); 2220 if(ret != IV_SUCCESS) 2221 { 2222 sprintf(ac_error_str, "Error in Get Buf Info %x", s_ctl_op.u4_error_code); 2223 codec_exit(ac_error_str); 2224 } 2225 2226 /* Allocate input buffer */ 2227 u4_ip_buf_len = s_ctl_op.u4_min_in_buf_size[0]; 2228 pu1_bs_buf = (UWORD8 *)malloc(u4_ip_buf_len); 2229 2230 if(pu1_bs_buf == NULL) 2231 { 2232 sprintf(ac_error_str, 2233 "\nAllocation failure for input buffer of size %d", 2234 u4_ip_buf_len); 2235 codec_exit(ac_error_str); 2236 } 2237 s_app_ctx.num_disp_buf = s_ctl_op.u4_num_disp_bufs; 2238 /* Allocate output buffer only if display buffers are not shared */ 2239 /* Or if shared and output is 420P */ 2240 if((0 == s_app_ctx.share_disp_buf) || (IV_YUV_420P == s_app_ctx.e_output_chroma_format)) 2241 { 2242 UWORD32 outlen; 2243 ps_out_buf->u4_min_out_buf_size[0] = 2244 s_ctl_op.u4_min_out_buf_size[0]; 2245 ps_out_buf->u4_min_out_buf_size[1] = 2246 s_ctl_op.u4_min_out_buf_size[1]; 2247 ps_out_buf->u4_min_out_buf_size[2] = 2248 s_ctl_op.u4_min_out_buf_size[2]; 2249 2250 outlen = s_ctl_op.u4_min_out_buf_size[0]; 2251 if(s_ctl_op.u4_min_num_out_bufs > 1) 2252 outlen += s_ctl_op.u4_min_out_buf_size[1]; 2253 2254 if(s_ctl_op.u4_min_num_out_bufs > 2) 2255 outlen += s_ctl_op.u4_min_out_buf_size[2]; 2256 2257 ps_out_buf->pu1_bufs[0] = (UWORD8 *)malloc(outlen); 2258 if(ps_out_buf->pu1_bufs[0] == NULL) 2259 { 2260 sprintf(ac_error_str, 2261 "\nAllocation failure for output buffer of size %d", 2262 outlen); 2263 codec_exit(ac_error_str); 2264 } 2265 2266 if(s_ctl_op.u4_min_num_out_bufs > 1) 2267 ps_out_buf->pu1_bufs[1] = ps_out_buf->pu1_bufs[0] 2268 + (s_ctl_op.u4_min_out_buf_size[0]); 2269 2270 if(s_ctl_op.u4_min_num_out_bufs > 2) 2271 ps_out_buf->pu1_bufs[2] = ps_out_buf->pu1_bufs[1] 2272 + (s_ctl_op.u4_min_out_buf_size[1]); 2273 2274 ps_out_buf->u4_num_bufs = s_ctl_op.u4_min_num_out_bufs; 2275 } 2276 2277 } 2278 } 2279 2280 } 2281 2282 2283 /*************************************************************************/ 2284 /* set num of cores */ 2285 /*************************************************************************/ 2286 { 2287 2288 ihevcd_cxa_ctl_set_num_cores_ip_t s_ctl_set_cores_ip; 2289 ihevcd_cxa_ctl_set_num_cores_op_t s_ctl_set_cores_op; 2290 2291 s_ctl_set_cores_ip.e_cmd = IVD_CMD_VIDEO_CTL; 2292 s_ctl_set_cores_ip.e_sub_cmd = (IVD_CONTROL_API_COMMAND_TYPE_T)IHEVCD_CXA_CMD_CTL_SET_NUM_CORES; 2293 s_ctl_set_cores_ip.u4_num_cores = s_app_ctx.u4_num_cores; 2294 s_ctl_set_cores_ip.u4_size = sizeof(ihevcd_cxa_ctl_set_num_cores_ip_t); 2295 s_ctl_set_cores_op.u4_size = sizeof(ihevcd_cxa_ctl_set_num_cores_op_t); 2296 2297 ret = ivd_cxa_api_function((iv_obj_t *)codec_obj, (void *)&s_ctl_set_cores_ip, 2298 (void *)&s_ctl_set_cores_op); 2299 if(ret != IV_SUCCESS) 2300 { 2301 sprintf(ac_error_str, "\nError in setting number of cores"); 2302 codec_exit(ac_error_str); 2303 } 2304 2305 } 2306 /*************************************************************************/ 2307 /* set processsor */ 2308 /*************************************************************************/ 2309 { 2310 2311 ihevcd_cxa_ctl_set_processor_ip_t s_ctl_set_num_processor_ip; 2312 ihevcd_cxa_ctl_set_processor_op_t s_ctl_set_num_processor_op; 2313 2314 s_ctl_set_num_processor_ip.e_cmd = IVD_CMD_VIDEO_CTL; 2315 s_ctl_set_num_processor_ip.e_sub_cmd = (IVD_CONTROL_API_COMMAND_TYPE_T)IHEVCD_CXA_CMD_CTL_SET_PROCESSOR; 2316 s_ctl_set_num_processor_ip.u4_arch = s_app_ctx.e_arch; 2317 s_ctl_set_num_processor_ip.u4_soc = s_app_ctx.e_soc; 2318 s_ctl_set_num_processor_ip.u4_size = sizeof(ihevcd_cxa_ctl_set_processor_ip_t); 2319 s_ctl_set_num_processor_op.u4_size = sizeof(ihevcd_cxa_ctl_set_processor_op_t); 2320 2321 ret = ivd_cxa_api_function((iv_obj_t *)codec_obj, (void *)&s_ctl_set_num_processor_ip, 2322 (void *)&s_ctl_set_num_processor_op); 2323 if(ret != IV_SUCCESS) 2324 { 2325 sprintf(ac_error_str, "\nError in setting Processor type"); 2326 codec_exit(ac_error_str); 2327 } 2328 2329 } 2330 2331 2332 /*****************************************************************************/ 2333 /* Decode header to get width and height and buffer sizes */ 2334 /*****************************************************************************/ 2335 { 2336 2337 ivd_ctl_set_config_ip_t s_ctl_ip; 2338 ivd_ctl_set_config_op_t s_ctl_op; 2339 2340 ivd_video_decode_ip_t s_video_decode_ip; 2341 ivd_video_decode_op_t s_video_decode_op; 2342 2343 s_ctl_ip.u4_disp_wd = STRIDE; 2344 if(1 == s_app_ctx.display) 2345 s_ctl_ip.u4_disp_wd = s_app_ctx.get_stride(); 2346 2347 s_ctl_ip.e_frm_skip_mode = IVD_SKIP_NONE; 2348 s_ctl_ip.e_frm_out_mode = IVD_DISPLAY_FRAME_OUT; 2349 s_ctl_ip.e_vid_dec_mode = IVD_DECODE_HEADER; 2350 s_ctl_ip.e_cmd = IVD_CMD_VIDEO_CTL; 2351 s_ctl_ip.e_sub_cmd = IVD_CMD_CTL_SETPARAMS; 2352 s_ctl_ip.u4_size = sizeof(ivd_ctl_set_config_ip_t); 2353 s_ctl_op.u4_size = sizeof(ivd_ctl_set_config_op_t); 2354 2355 ret = ivd_cxa_api_function((iv_obj_t *)codec_obj, (void *)&s_ctl_ip, 2356 (void *)&s_ctl_op); 2357 if(ret != IV_SUCCESS) 2358 { 2359 sprintf(ac_error_str, 2360 "\nError in setting the codec in header decode mode"); 2361 codec_exit(ac_error_str); 2362 } 2363 2364 do 2365 { 2366 WORD32 numbytes; 2367 if(0 == s_app_ctx.u4_piclen_flag) 2368 { 2369 fseek(ps_ip_file, file_pos, SEEK_SET); 2370 numbytes = u4_ip_buf_len; 2371 } 2372 else 2373 { 2374 WORD32 entries; 2375 entries = fscanf(ps_piclen_file, "%d\n", &numbytes); 2376 if(1 != entries) 2377 numbytes = u4_ip_buf_len; 2378 } 2379 2380 u4_bytes_remaining = fread(pu1_bs_buf, sizeof(UWORD8), numbytes, 2381 ps_ip_file); 2382 2383 if(0 == u4_bytes_remaining) 2384 { 2385 sprintf(ac_error_str, "\nUnable to read from input file"); 2386 codec_exit(ac_error_str); 2387 } 2388 2389 s_video_decode_ip.e_cmd = IVD_CMD_VIDEO_DECODE; 2390 s_video_decode_ip.u4_ts = u4_ip_frm_ts; 2391 s_video_decode_ip.pv_stream_buffer = pu1_bs_buf; 2392 s_video_decode_ip.u4_num_Bytes = u4_bytes_remaining; 2393 s_video_decode_ip.u4_size = sizeof(ivd_video_decode_ip_t); 2394 s_video_decode_op.u4_size = sizeof(ivd_video_decode_op_t); 2395 2396 /*****************************************************************************/ 2397 /* API Call: Header Decode */ 2398 /*****************************************************************************/ 2399 ret = ivd_cxa_api_function((iv_obj_t *)codec_obj, (void *)&s_video_decode_ip, 2400 (void *)&s_video_decode_op); 2401 2402 if(ret != IV_SUCCESS) 2403 { 2404 sprintf(ac_error_str, "\nError in header decode %x", 2405 s_video_decode_op.u4_error_code); 2406 // codec_exit(ac_error_str); 2407 } 2408 2409 u4_num_bytes_dec = s_video_decode_op.u4_num_bytes_consumed; 2410 #ifndef PROFILE_ENABLE 2411 printf("%d\n", s_video_decode_op.u4_num_bytes_consumed); 2412 #endif 2413 file_pos += u4_num_bytes_dec; 2414 total_bytes_comsumed += u4_num_bytes_dec; 2415 }while(ret != IV_SUCCESS); 2416 2417 /* copy pic_wd and pic_ht to initialize buffers */ 2418 s_app_ctx.u4_pic_wd = s_video_decode_op.u4_pic_wd; 2419 s_app_ctx.u4_pic_ht = s_video_decode_op.u4_pic_ht; 2420 2421 #if IOS_DISPLAY 2422 s_app_ctx.i4_screen_wd = screen_wd; 2423 s_app_ctx.i4_screen_ht = screen_ht; 2424 #endif 2425 2426 /* Create display thread and wait for the display buffers to be initialized */ 2427 if(1 == s_app_ctx.display) 2428 { 2429 if(0 == s_app_ctx.display_thread_created) 2430 { 2431 s_app_ctx.display_init_done = 0; 2432 ithread_create(s_app_ctx.display_thread_handle, NULL, 2433 (void *)&display_thread, (void *)&s_app_ctx); 2434 s_app_ctx.display_thread_created = 1; 2435 2436 while(1) 2437 { 2438 if(s_app_ctx.display_init_done) 2439 break; 2440 2441 ithread_msleep(1); 2442 } 2443 } 2444 2445 s_app_ctx.u4_strd = s_app_ctx.get_stride(); 2446 } 2447 } 2448 2449 /*************************************************************************/ 2450 /* Get actual number of output buffers requried, which is dependent */ 2451 /* on stream properties such as width, height and level etc */ 2452 /* This is needed mainly for shared display mode */ 2453 /*************************************************************************/ 2454 //if(1 == s_app_ctx.share_disp_buf) 2455 { 2456 ivd_ctl_getbufinfo_ip_t s_ctl_ip; 2457 ivd_ctl_getbufinfo_op_t s_ctl_op; 2458 WORD32 outlen = 0; 2459 2460 s_ctl_ip.e_cmd = IVD_CMD_VIDEO_CTL; 2461 s_ctl_ip.e_sub_cmd = IVD_CMD_CTL_GETBUFINFO; 2462 s_ctl_ip.u4_size = sizeof(ivd_ctl_getbufinfo_ip_t); 2463 s_ctl_op.u4_size = sizeof(ivd_ctl_getbufinfo_op_t); 2464 ret = ivd_cxa_api_function((iv_obj_t *)codec_obj, (void *)&s_ctl_ip, 2465 (void *)&s_ctl_op); 2466 if(ret != IV_SUCCESS) 2467 { 2468 sprintf(ac_error_str, "Error in Get Buf Info %x", s_ctl_op.u4_error_code); 2469 codec_exit(ac_error_str); 2470 } 2471 2472 #ifdef APP_EXTRA_BUFS 2473 s_app_ctx.disp_delay = EXTRA_DISP_BUFFERS; 2474 s_ctl_op.u4_num_disp_bufs += EXTRA_DISP_BUFFERS; 2475 #endif 2476 2477 /*****************************************************************************/ 2478 /* API Call: Allocate display buffers for display buffer shared case */ 2479 /*****************************************************************************/ 2480 2481 for(i = 0; i < s_ctl_op.u4_num_disp_bufs; i++) 2482 { 2483 2484 s_app_ctx.s_disp_buffers[i].u4_min_out_buf_size[0] = 2485 s_ctl_op.u4_min_out_buf_size[0]; 2486 s_app_ctx.s_disp_buffers[i].u4_min_out_buf_size[1] = 2487 s_ctl_op.u4_min_out_buf_size[1]; 2488 s_app_ctx.s_disp_buffers[i].u4_min_out_buf_size[2] = 2489 s_ctl_op.u4_min_out_buf_size[2]; 2490 2491 outlen = s_ctl_op.u4_min_out_buf_size[0]; 2492 if(s_ctl_op.u4_min_num_out_bufs > 1) 2493 outlen += s_ctl_op.u4_min_out_buf_size[1]; 2494 2495 if(s_ctl_op.u4_min_num_out_bufs > 2) 2496 outlen += s_ctl_op.u4_min_out_buf_size[2]; 2497 2498 s_app_ctx.s_disp_buffers[i].pu1_bufs[0] = (UWORD8 *)malloc(outlen); 2499 2500 if(s_app_ctx.s_disp_buffers[i].pu1_bufs[0] == NULL) 2501 { 2502 sprintf(ac_error_str, 2503 "\nAllocation failure for output buffer of size %d", 2504 outlen); 2505 codec_exit(ac_error_str); 2506 } 2507 2508 if(s_ctl_op.u4_min_num_out_bufs > 1) 2509 s_app_ctx.s_disp_buffers[i].pu1_bufs[1] = 2510 s_app_ctx.s_disp_buffers[i].pu1_bufs[0] 2511 + (s_ctl_op.u4_min_out_buf_size[0]); 2512 2513 if(s_ctl_op.u4_min_num_out_bufs > 2) 2514 s_app_ctx.s_disp_buffers[i].pu1_bufs[2] = 2515 s_app_ctx.s_disp_buffers[i].pu1_bufs[1] 2516 + (s_ctl_op.u4_min_out_buf_size[1]); 2517 2518 s_app_ctx.s_disp_buffers[i].u4_num_bufs = 2519 s_ctl_op.u4_min_num_out_bufs; 2520 } 2521 s_app_ctx.num_disp_buf = s_ctl_op.u4_num_disp_bufs; 2522 2523 /*****************************************************************************/ 2524 /* API Call: Send the allocated display buffers to codec */ 2525 /*****************************************************************************/ 2526 { 2527 ivd_set_display_frame_ip_t s_set_display_frame_ip; 2528 ivd_set_display_frame_op_t s_set_display_frame_op; 2529 2530 s_set_display_frame_ip.e_cmd = IVD_CMD_SET_DISPLAY_FRAME; 2531 s_set_display_frame_ip.u4_size = sizeof(ivd_set_display_frame_ip_t); 2532 s_set_display_frame_op.u4_size = sizeof(ivd_set_display_frame_op_t); 2533 2534 s_set_display_frame_ip.num_disp_bufs = s_app_ctx.num_disp_buf; 2535 2536 memcpy(&(s_set_display_frame_ip.s_disp_buffer), 2537 &(s_app_ctx.s_disp_buffers), 2538 s_ctl_op.u4_num_disp_bufs * sizeof(ivd_out_bufdesc_t)); 2539 2540 ret = ivd_cxa_api_function((iv_obj_t *)codec_obj, 2541 (void *)&s_set_display_frame_ip, 2542 (void *)&s_set_display_frame_op); 2543 2544 if(IV_SUCCESS != ret) 2545 { 2546 sprintf(ac_error_str, "Error in Set display frame"); 2547 codec_exit(ac_error_str); 2548 } 2549 2550 } 2551 2552 } 2553 2554 /*************************************************************************/ 2555 /* Get frame dimensions for display buffers such as x_offset,y_offset */ 2556 /* etc. This information might be needed to set display buffer */ 2557 /* offsets in case of shared display buffer mode */ 2558 /*************************************************************************/ 2559 { 2560 2561 ihevcd_cxa_ctl_get_frame_dimensions_ip_t s_ctl_get_frame_dimensions_ip; 2562 ihevcd_cxa_ctl_get_frame_dimensions_op_t s_ctl_get_frame_dimensions_op; 2563 2564 s_ctl_get_frame_dimensions_ip.e_cmd = IVD_CMD_VIDEO_CTL; 2565 s_ctl_get_frame_dimensions_ip.e_sub_cmd = 2566 (IVD_CONTROL_API_COMMAND_TYPE_T)IHEVCD_CXA_CMD_CTL_GET_BUFFER_DIMENSIONS; 2567 s_ctl_get_frame_dimensions_ip.u4_size = 2568 sizeof(ihevcd_cxa_ctl_get_frame_dimensions_ip_t); 2569 s_ctl_get_frame_dimensions_op.u4_size = 2570 sizeof(ihevcd_cxa_ctl_get_frame_dimensions_op_t); 2571 2572 ret = ivd_cxa_api_function((iv_obj_t *)codec_obj, (void *)&s_ctl_get_frame_dimensions_ip, 2573 (void *)&s_ctl_get_frame_dimensions_op); 2574 if(IV_SUCCESS != ret) 2575 { 2576 sprintf(ac_error_str, "Error in Get buffer Dimensions"); 2577 codec_exit(ac_error_str); 2578 } 2579 2580 /* 2581 printf("Frame offsets due to padding\n"); 2582 printf("s_ctl_get_frame_dimensions_op.x_offset[0] %d s_ctl_get_frame_dimensions_op.y_offset[0] %d\n", 2583 s_ctl_get_frame_dimensions_op.u4_x_offset[0], 2584 s_ctl_get_frame_dimensions_op.u4_y_offset[0]); 2585 */ 2586 } 2587 2588 2589 /*************************************************************************/ 2590 /* Get VUI parameters */ 2591 /*************************************************************************/ 2592 { 2593 2594 ihevcd_cxa_ctl_get_vui_params_ip_t s_ctl_get_vui_params_ip; 2595 ihevcd_cxa_ctl_get_vui_params_op_t s_ctl_get_vui_params_op; 2596 2597 s_ctl_get_vui_params_ip.e_cmd = IVD_CMD_VIDEO_CTL; 2598 s_ctl_get_vui_params_ip.e_sub_cmd = 2599 (IVD_CONTROL_API_COMMAND_TYPE_T)IHEVCD_CXA_CMD_CTL_GET_VUI_PARAMS; 2600 s_ctl_get_vui_params_ip.u4_size = 2601 sizeof(ihevcd_cxa_ctl_get_vui_params_ip_t); 2602 s_ctl_get_vui_params_op.u4_size = 2603 sizeof(ihevcd_cxa_ctl_get_vui_params_op_t); 2604 2605 ret = ivd_cxa_api_function((iv_obj_t *)codec_obj, (void *)&s_ctl_get_vui_params_ip, 2606 (void *)&s_ctl_get_vui_params_op); 2607 if(IV_SUCCESS != ret) 2608 { 2609 sprintf(ac_error_str, "Error in Get VUI params"); 2610 //codec_exit(ac_error_str); 2611 } 2612 2613 } 2614 2615 2616 /*************************************************************************/ 2617 /* Set the decoder in frame decode mode. It was set in header decode */ 2618 /* mode earlier */ 2619 /*************************************************************************/ 2620 { 2621 2622 ivd_ctl_set_config_ip_t s_ctl_ip; 2623 ivd_ctl_set_config_op_t s_ctl_op; 2624 2625 s_ctl_ip.u4_disp_wd = STRIDE; 2626 if(1 == s_app_ctx.display) 2627 s_ctl_ip.u4_disp_wd = s_app_ctx.get_stride(); 2628 s_ctl_ip.e_frm_skip_mode = IVD_SKIP_NONE; 2629 2630 s_ctl_ip.e_frm_out_mode = IVD_DISPLAY_FRAME_OUT; 2631 s_ctl_ip.e_vid_dec_mode = IVD_DECODE_FRAME; 2632 s_ctl_ip.e_cmd = IVD_CMD_VIDEO_CTL; 2633 s_ctl_ip.e_sub_cmd = IVD_CMD_CTL_SETPARAMS; 2634 s_ctl_ip.u4_size = sizeof(ivd_ctl_set_config_ip_t); 2635 2636 s_ctl_op.u4_size = sizeof(ivd_ctl_set_config_op_t); 2637 2638 ret = ivd_cxa_api_function((iv_obj_t *)codec_obj, (void *)&s_ctl_ip, (void *)&s_ctl_op); 2639 2640 if(IV_SUCCESS != ret) 2641 { 2642 sprintf(ac_error_str, "Error in Set Parameters"); 2643 //codec_exit(ac_error_str); 2644 } 2645 2646 } 2647 /*************************************************************************/ 2648 /* If required disable deblocking and sao at given level */ 2649 /*************************************************************************/ 2650 set_degrade(codec_obj, s_app_ctx.i4_degrade_type, s_app_ctx.i4_degrade_pics); 2651 #ifdef X86_MSVC 2652 QueryPerformanceFrequency(&frequency); 2653 #endif 2654 #ifndef PRINT_PICSIZE 2655 get_version(codec_obj); 2656 #endif 2657 while(u4_op_frm_ts < (s_app_ctx.u4_max_frm_ts + s_app_ctx.disp_delay)) 2658 { 2659 2660 #ifdef TEST_FLUSH 2661 if(u4_ip_frm_ts == FLUSH_FRM_CNT) 2662 { 2663 ivd_ctl_flush_ip_t s_ctl_ip; 2664 ivd_ctl_flush_op_t s_ctl_op; 2665 2666 s_ctl_ip.e_cmd = IVD_CMD_VIDEO_CTL; 2667 s_ctl_ip.e_sub_cmd = IVD_CMD_CTL_FLUSH; 2668 s_ctl_ip.u4_size = sizeof(ivd_ctl_flush_ip_t); 2669 s_ctl_op.u4_size = sizeof(ivd_ctl_flush_op_t); 2670 ret = ivd_cxa_api_function((iv_obj_t *)codec_obj, (void *)&s_ctl_ip, 2671 (void *)&s_ctl_op); 2672 2673 if(ret != IV_SUCCESS) 2674 { 2675 printf("Error in Setting the decoder in flush mode\n"); 2676 } 2677 file_pos = 0; 2678 2679 fseek(ps_ip_file, file_pos, SEEK_SET); 2680 2681 } 2682 #endif 2683 if(u4_ip_frm_ts < s_app_ctx.num_disp_buf) 2684 { 2685 release_disp_frame(codec_obj, u4_ip_frm_ts); 2686 } 2687 2688 2689 /*************************************************************************/ 2690 /* set num of cores */ 2691 /*************************************************************************/ 2692 #ifdef DYNAMIC_NUMCORES 2693 { 2694 2695 ihevcd_cxa_ctl_set_num_cores_ip_t s_ctl_set_cores_ip; 2696 ihevcd_cxa_ctl_set_num_cores_op_t s_ctl_set_cores_op; 2697 2698 s_ctl_set_cores_ip.e_cmd = IVD_CMD_VIDEO_CTL; 2699 s_ctl_set_cores_ip.e_sub_cmd = IHEVCD_CXA_CMD_CTL_SET_NUM_CORES; 2700 s_ctl_set_cores_ip.u4_num_cores = 1 + 3 * (u4_ip_frm_ts % 2); 2701 s_ctl_set_cores_ip.u4_size = sizeof(ihevcd_cxa_ctl_set_num_cores_ip_t); 2702 s_ctl_set_cores_op.u4_size = sizeof(ihevcd_cxa_ctl_set_num_cores_op_t); 2703 2704 ret = ivd_cxa_api_function((iv_obj_t *)codec_obj, (void *)&s_ctl_set_cores_ip, 2705 (void *)&s_ctl_set_cores_op); 2706 if(ret != IV_SUCCESS) 2707 { 2708 sprintf(ac_error_str, "\nError in setting number of cores"); 2709 codec_exit(ac_error_str); 2710 } 2711 2712 } 2713 #endif 2714 /***********************************************************************/ 2715 /* Seek the file to start of current frame, this is equavelent of */ 2716 /* having a parcer which tells the start of current frame */ 2717 /***********************************************************************/ 2718 { 2719 WORD32 numbytes; 2720 2721 if(0 == s_app_ctx.u4_piclen_flag) 2722 { 2723 fseek(ps_ip_file, file_pos, SEEK_SET); 2724 numbytes = u4_ip_buf_len; 2725 } 2726 else 2727 { 2728 WORD32 entries; 2729 entries = fscanf(ps_piclen_file, "%d\n", &numbytes); 2730 if(1 != entries) 2731 numbytes = u4_ip_buf_len; 2732 } 2733 2734 u4_bytes_remaining = fread(pu1_bs_buf, sizeof(UWORD8), 2735 numbytes, ps_ip_file); 2736 2737 if(u4_bytes_remaining == 0) 2738 { 2739 if(1 == s_app_ctx.loopback) 2740 { 2741 file_pos = 0; 2742 if(0 == s_app_ctx.u4_piclen_flag) 2743 { 2744 fseek(ps_ip_file, file_pos, SEEK_SET); 2745 numbytes = u4_ip_buf_len; 2746 } 2747 else 2748 { 2749 WORD32 entries; 2750 entries = fscanf(ps_piclen_file, "%d\n", &numbytes); 2751 if(1 != entries) 2752 numbytes = u4_ip_buf_len; 2753 } 2754 2755 2756 u4_bytes_remaining = fread(pu1_bs_buf, sizeof(UWORD8), 2757 numbytes, ps_ip_file); 2758 } 2759 else 2760 break; 2761 } 2762 } 2763 2764 /*********************************************************************/ 2765 /* Following calls can be enabled at diffent times */ 2766 /*********************************************************************/ 2767 #if ENABLE_DEGRADE 2768 if(u4_op_frm_ts >= 10000) 2769 disable_deblocking(codec_obj, 4); 2770 2771 if(u4_op_frm_ts == 30000) 2772 enable_deblocking(codec_obj); 2773 2774 if(u4_op_frm_ts == 10000) 2775 enable_skippb_frames(codec_obj); 2776 2777 if(u4_op_frm_ts == 60000) 2778 disable_skippb_frames(codec_obj); 2779 2780 if(u4_op_frm_ts == 30000) 2781 enable_skipb_frames(codec_obj); 2782 2783 if(u4_op_frm_ts == 60000) 2784 disable_skipb_frames(codec_obj); 2785 #endif 2786 2787 2788 { 2789 ivd_video_decode_ip_t s_video_decode_ip; 2790 ivd_video_decode_op_t s_video_decode_op; 2791 #ifdef PROFILE_ENABLE 2792 UWORD32 s_elapsed_time; 2793 TIMER s_start_timer; 2794 TIMER s_end_timer; 2795 #endif 2796 2797 2798 s_video_decode_ip.e_cmd = IVD_CMD_VIDEO_DECODE; 2799 s_video_decode_ip.u4_ts = u4_ip_frm_ts; 2800 s_video_decode_ip.pv_stream_buffer = pu1_bs_buf; 2801 s_video_decode_ip.u4_num_Bytes = u4_bytes_remaining; 2802 s_video_decode_ip.u4_size = sizeof(ivd_video_decode_ip_t); 2803 s_video_decode_ip.s_out_buffer.u4_min_out_buf_size[0] = 2804 ps_out_buf->u4_min_out_buf_size[0]; 2805 s_video_decode_ip.s_out_buffer.u4_min_out_buf_size[1] = 2806 ps_out_buf->u4_min_out_buf_size[1]; 2807 s_video_decode_ip.s_out_buffer.u4_min_out_buf_size[2] = 2808 ps_out_buf->u4_min_out_buf_size[2]; 2809 2810 s_video_decode_ip.s_out_buffer.pu1_bufs[0] = 2811 ps_out_buf->pu1_bufs[0]; 2812 s_video_decode_ip.s_out_buffer.pu1_bufs[1] = 2813 ps_out_buf->pu1_bufs[1]; 2814 s_video_decode_ip.s_out_buffer.pu1_bufs[2] = 2815 ps_out_buf->pu1_bufs[2]; 2816 s_video_decode_ip.s_out_buffer.u4_num_bufs = 2817 ps_out_buf->u4_num_bufs; 2818 s_video_decode_op.u4_size = sizeof(ivd_video_decode_op_t); 2819 2820 /* Get display buffer pointers */ 2821 if(1 == s_app_ctx.display) 2822 { 2823 WORD32 wr_idx; 2824 2825 wr_idx = dispq_producer_dequeue(&s_app_ctx); 2826 2827 if(s_app_ctx.quit) 2828 break; 2829 2830 s_app_ctx.set_disp_buffers(s_app_ctx.pv_disp_ctx, wr_idx, 2831 &s_video_decode_ip.s_out_buffer.pu1_bufs[0], 2832 &s_video_decode_ip.s_out_buffer.pu1_bufs[1], 2833 &s_video_decode_ip.s_out_buffer.pu1_bufs[2]); 2834 } 2835 2836 /*****************************************************************************/ 2837 /* API Call: Video Decode */ 2838 /*****************************************************************************/ 2839 2840 GETTIME(&s_start_timer); 2841 2842 ret = ivd_cxa_api_function((iv_obj_t *)codec_obj, (void *)&s_video_decode_ip, 2843 (void *)&s_video_decode_op); 2844 2845 2846 GETTIME(&s_end_timer); 2847 ELAPSEDTIME(s_start_timer, s_end_timer, s_elapsed_time, frequency); 2848 #ifdef PROFILE_ENABLE 2849 { 2850 UWORD32 peak_avg, id; 2851 u4_tot_cycles += s_elapsed_time; 2852 peak_window[peak_window_idx++] = s_elapsed_time; 2853 if(peak_window_idx == PEAK_WINDOW_SIZE) 2854 peak_window_idx = 0; 2855 peak_avg = 0; 2856 for(id = 0; id < PEAK_WINDOW_SIZE; id++) 2857 { 2858 peak_avg += peak_window[id]; 2859 } 2860 peak_avg /= PEAK_WINDOW_SIZE; 2861 if(peak_avg > peak_avg_max) 2862 peak_avg_max = peak_avg; 2863 frm_cnt++; 2864 2865 printf("FrameNum: %4d TimeTaken(microsec): %6d AvgTime: %6d PeakAvgTimeMax: %6d Output: %2d NumBytes: %6d \n", 2866 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); 2867 2868 } 2869 #ifdef INTEL_CE5300 2870 time_consumed += s_elapsed_time; 2871 bytes_consumed += s_video_decode_op.u4_num_bytes_consumed; 2872 if(!(frm_cnt % (s_app_ctx.fps))) 2873 { 2874 time_consumed = time_consumed / s_app_ctx.fps; 2875 printf("Average decode time(micro sec) for the last second = %6d\n", time_consumed); 2876 printf("Average bitrate(kb) for the last second = %6d\n", (bytes_consumed * 8) / 1024); 2877 time_consumed = 0; 2878 bytes_consumed = 0; 2879 2880 } 2881 #endif 2882 #else 2883 printf("%d\n", s_video_decode_op.u4_num_bytes_consumed); 2884 #endif 2885 2886 if(ret != IV_SUCCESS) 2887 { 2888 printf("Error in video Frame decode : ret %x Error %x\n", ret, 2889 s_video_decode_op.u4_error_code); 2890 } 2891 2892 if((IV_SUCCESS != ret) && 2893 ((s_video_decode_op.u4_error_code & 0xFF) == IVD_RES_CHANGED)) 2894 { 2895 ivd_ctl_reset_ip_t s_ctl_ip; 2896 ivd_ctl_reset_op_t s_ctl_op; 2897 2898 flush_output(codec_obj, &s_app_ctx, ps_out_buf, 2899 pu1_bs_buf, &u4_op_frm_ts, 2900 ps_op_file, ps_op_chksum_file, 2901 u4_ip_frm_ts, u4_bytes_remaining); 2902 2903 s_ctl_ip.e_cmd = IVD_CMD_VIDEO_CTL; 2904 s_ctl_ip.e_sub_cmd = IVD_CMD_CTL_RESET; 2905 s_ctl_ip.u4_size = sizeof(ivd_ctl_reset_ip_t); 2906 s_ctl_op.u4_size = sizeof(ivd_ctl_reset_op_t); 2907 2908 ret = ivd_cxa_api_function((iv_obj_t *)codec_obj, (void *)&s_ctl_ip, 2909 (void *)&s_ctl_op); 2910 if(IV_SUCCESS != ret) 2911 { 2912 sprintf(ac_error_str, "Error in Reset"); 2913 codec_exit(ac_error_str); 2914 } 2915 /*************************************************************************/ 2916 /* set num of cores */ 2917 /*************************************************************************/ 2918 { 2919 2920 ihevcd_cxa_ctl_set_num_cores_ip_t s_ctl_set_cores_ip; 2921 ihevcd_cxa_ctl_set_num_cores_op_t s_ctl_set_cores_op; 2922 2923 s_ctl_set_cores_ip.e_cmd = IVD_CMD_VIDEO_CTL; 2924 s_ctl_set_cores_ip.e_sub_cmd = (IVD_CONTROL_API_COMMAND_TYPE_T)IHEVCD_CXA_CMD_CTL_SET_NUM_CORES; 2925 s_ctl_set_cores_ip.u4_num_cores = s_app_ctx.u4_num_cores; 2926 s_ctl_set_cores_ip.u4_size = sizeof(ihevcd_cxa_ctl_set_num_cores_ip_t); 2927 s_ctl_set_cores_op.u4_size = sizeof(ihevcd_cxa_ctl_set_num_cores_op_t); 2928 2929 ret = ivd_cxa_api_function((iv_obj_t *)codec_obj, (void *)&s_ctl_set_cores_ip, 2930 (void *)&s_ctl_set_cores_op); 2931 if(ret != IV_SUCCESS) 2932 { 2933 sprintf(ac_error_str, "\nError in setting number of cores"); 2934 codec_exit(ac_error_str); 2935 } 2936 2937 } 2938 /*************************************************************************/ 2939 /* set processsor */ 2940 /*************************************************************************/ 2941 { 2942 2943 ihevcd_cxa_ctl_set_processor_ip_t s_ctl_set_num_processor_ip; 2944 ihevcd_cxa_ctl_set_processor_op_t s_ctl_set_num_processor_op; 2945 2946 s_ctl_set_num_processor_ip.e_cmd = IVD_CMD_VIDEO_CTL; 2947 s_ctl_set_num_processor_ip.e_sub_cmd = (IVD_CONTROL_API_COMMAND_TYPE_T)IHEVCD_CXA_CMD_CTL_SET_PROCESSOR; 2948 s_ctl_set_num_processor_ip.u4_arch = s_app_ctx.e_arch; 2949 s_ctl_set_num_processor_ip.u4_soc = s_app_ctx.e_soc; 2950 s_ctl_set_num_processor_ip.u4_size = sizeof(ihevcd_cxa_ctl_set_processor_ip_t); 2951 s_ctl_set_num_processor_op.u4_size = sizeof(ihevcd_cxa_ctl_set_processor_op_t); 2952 2953 ret = ivd_cxa_api_function((iv_obj_t *)codec_obj, (void *)&s_ctl_set_num_processor_ip, 2954 (void *)&s_ctl_set_num_processor_op); 2955 if(ret != IV_SUCCESS) 2956 { 2957 sprintf(ac_error_str, "\nError in setting Processor type"); 2958 codec_exit(ac_error_str); 2959 } 2960 2961 } 2962 } 2963 2964 2965 if((1 == s_app_ctx.display) && 2966 (1 == s_video_decode_op.u4_output_present)) 2967 { 2968 dispq_producer_queue(&s_app_ctx); 2969 } 2970 2971 if(IV_B_FRAME == s_video_decode_op.e_pic_type) 2972 s_app_ctx.b_pic_present |= 1; 2973 2974 u4_num_bytes_dec = s_video_decode_op.u4_num_bytes_consumed; 2975 2976 file_pos += u4_num_bytes_dec; 2977 total_bytes_comsumed += u4_num_bytes_dec; 2978 u4_ip_frm_ts++; 2979 2980 2981 if(1 == s_video_decode_op.u4_output_present) 2982 { 2983 width = s_video_decode_op.s_disp_frm_buf.u4_y_wd; 2984 height = s_video_decode_op.s_disp_frm_buf.u4_y_ht; 2985 dump_output(&s_app_ctx, &(s_video_decode_op.s_disp_frm_buf), 2986 s_video_decode_op.u4_disp_buf_id, ps_op_file, 2987 ps_op_chksum_file, 2988 u4_op_frm_ts, s_app_ctx.u4_file_save_flag, 2989 s_app_ctx.u4_chksum_save_flag); 2990 2991 u4_op_frm_ts++; 2992 } 2993 else 2994 { 2995 if((s_video_decode_op.u4_error_code >> IVD_FATALERROR) & 1) 2996 { 2997 printf("Fatal error\n"); 2998 break; 2999 } 3000 } 3001 3002 } 3003 } 3004 3005 /***********************************************************************/ 3006 /* To get the last decoded frames, call process with NULL input */ 3007 /***********************************************************************/ 3008 flush_output(codec_obj, &s_app_ctx, ps_out_buf, 3009 pu1_bs_buf, &u4_op_frm_ts, 3010 ps_op_file, ps_op_chksum_file, 3011 u4_ip_frm_ts, u4_bytes_remaining); 3012 3013 /* set disp_end flag */ 3014 s_app_ctx.quit = 1; 3015 3016 3017 #ifdef PROFILE_ENABLE 3018 printf("Summary\n"); 3019 printf("Input filename : %s\n", s_app_ctx.ac_ip_fname); 3020 printf("Output Width : %-4d\n", width); 3021 printf("Output Height : %-4d\n", height); 3022 3023 if(frm_cnt) 3024 { 3025 double avg = u4_tot_cycles / frm_cnt; 3026 double bytes_avg = total_bytes_comsumed / frm_cnt; 3027 double bitrate = (bytes_avg * 8 * s_app_ctx.fps) / 1000000; 3028 printf("Bitrate @ %2d fps(mbps) : %-6.2f\n", s_app_ctx.fps, bitrate); 3029 printf("Average decode time(micro sec) : %-6d\n", (WORD32)avg); 3030 printf("Avg Peak decode time(%2d frames) : %-6d\n", PEAK_WINDOW_SIZE, (WORD32)peak_avg_max); 3031 avg = (u4_tot_cycles + u4_tot_fmt_cycles) * 1.0 / frm_cnt; 3032 3033 if(0 == s_app_ctx.share_disp_buf) 3034 printf("FPS achieved (with format conv) : %-3.2f\n", 1000000 / avg); 3035 else 3036 printf("FPS achieved : %-3.2f\n", 1000000 / avg); 3037 } 3038 #endif 3039 /***********************************************************************/ 3040 /* Clear the decoder, close all the files, free all the memory */ 3041 /***********************************************************************/ 3042 if(1 == s_app_ctx.display) 3043 { 3044 s_app_ctx.display_deinit_flag = 1; 3045 /* wait for display to finish */ 3046 if(s_app_ctx.display_thread_created) 3047 { 3048 ithread_join(s_app_ctx.display_thread_handle, NULL); 3049 } 3050 free(s_app_ctx.display_thread_handle); 3051 } 3052 3053 { 3054 iv_retrieve_mem_rec_ip_t s_retrieve_dec_ip; 3055 iv_retrieve_mem_rec_op_t s_retrieve_dec_op; 3056 s_retrieve_dec_ip.pv_mem_rec_location = (iv_mem_rec_t *)pv_mem_rec_location; 3057 3058 s_retrieve_dec_ip.e_cmd = IV_CMD_RETRIEVE_MEMREC; 3059 s_retrieve_dec_ip.u4_size = sizeof(iv_retrieve_mem_rec_ip_t); 3060 s_retrieve_dec_op.u4_size = sizeof(iv_retrieve_mem_rec_op_t); 3061 3062 ret = ivd_cxa_api_function((iv_obj_t *)codec_obj, (void *)&s_retrieve_dec_ip, 3063 (void *)&s_retrieve_dec_op); 3064 3065 if(IV_SUCCESS != ret) 3066 { 3067 sprintf(ac_error_str, "Error in Retrieve Memrec"); 3068 codec_exit(ac_error_str); 3069 } 3070 3071 { 3072 iv_mem_rec_t *ps_mem_rec; 3073 UWORD16 u2_i; 3074 3075 u4_num_mem_recs = s_retrieve_dec_op.u4_num_mem_rec_filled; 3076 3077 ps_mem_rec = s_retrieve_dec_ip.pv_mem_rec_location; 3078 3079 for(u2_i = 0; u2_i < u4_num_mem_recs; u2_i++) 3080 { 3081 ihevca_aligned_free(ps_mem_rec->pv_base); 3082 ps_mem_rec++; 3083 } 3084 free(s_retrieve_dec_ip.pv_mem_rec_location); 3085 } 3086 3087 } 3088 /***********************************************************************/ 3089 /* Close all the files and free all the memory */ 3090 /***********************************************************************/ 3091 { 3092 fclose(ps_ip_file); 3093 3094 if(1 == s_app_ctx.u4_file_save_flag) 3095 { 3096 fclose(ps_op_file); 3097 } 3098 if(1 == s_app_ctx.u4_chksum_save_flag) 3099 { 3100 fclose(ps_op_chksum_file); 3101 } 3102 3103 } 3104 3105 if(0 == s_app_ctx.share_disp_buf) 3106 { 3107 free(ps_out_buf->pu1_bufs[0]); 3108 } 3109 3110 for(i = 0; i < s_app_ctx.num_disp_buf; i++) 3111 { 3112 free(s_app_ctx.s_disp_buffers[i].pu1_bufs[0]); 3113 } 3114 3115 free(ps_out_buf); 3116 free(pu1_bs_buf); 3117 3118 return (0); 3119 } 3120