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