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