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