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