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