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