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