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 
   1785 #ifdef X86_MINGW
   1786     //For getting printfs without any delay
   1787     setvbuf(stdout, NULL, _IONBF, 0);
   1788     setvbuf(stderr, NULL, _IONBF, 0);
   1789 #endif
   1790 #ifdef IOS
   1791     sprintf(filename_trace, "%s/iostrace.txt", homedir);
   1792     printf("\ntrace file name = %s", filename_trace);
   1793 #endif
   1794 
   1795 #ifdef X86_MINGW
   1796     {
   1797         signal(SIGSEGV, sigsegv_handler);
   1798     }
   1799 #endif
   1800 
   1801 
   1802 #ifndef IOS
   1803     /* Usage */
   1804     if(argc < 2)
   1805     {
   1806         printf("Using test.cfg as configuration file \n");
   1807         strcpy(ac_cfg_fname, "test.cfg");
   1808     }
   1809     else if(argc == 2)
   1810     {
   1811         strcpy(ac_cfg_fname, argv[1]);
   1812     }
   1813 
   1814 #else
   1815     strcpy(ac_cfg_fname, "test.cfg");
   1816 
   1817 #endif
   1818 
   1819 
   1820     /***********************************************************************/
   1821     /*                  Initialize Application parameters                  */
   1822     /***********************************************************************/
   1823 
   1824     strcpy(s_app_ctx.ac_ip_fname, "\0");
   1825     s_app_ctx.dump_q_wr_idx = 0;
   1826     s_app_ctx.dump_q_rd_idx = 0;
   1827     s_app_ctx.display_thread_created = 0;
   1828     s_app_ctx.disp_q_wr_idx = 0;
   1829     s_app_ctx.disp_q_rd_idx = 0;
   1830     s_app_ctx.disp_delay = 0;
   1831     s_app_ctx.loopback = 0;
   1832     s_app_ctx.display = 0;
   1833     s_app_ctx.full_screen = 0;
   1834     s_app_ctx.u4_piclen_flag = 0;
   1835     s_app_ctx.fps = DEFAULT_FPS;
   1836     file_pos = 0;
   1837     total_bytes_comsumed = 0;
   1838     u4_ip_frm_ts = 0;
   1839     u4_op_frm_ts = 0;
   1840 #ifdef PROFILE_ENABLE
   1841     memset(peak_window, 0, sizeof(WORD32) * PEAK_WINDOW_SIZE);
   1842 #endif
   1843     s_app_ctx.share_disp_buf = DEFAULT_SHARE_DISPLAY_BUF;
   1844     s_app_ctx.u4_num_cores = DEFAULT_NUM_CORES;
   1845     s_app_ctx.i4_degrade_type = 0;
   1846     s_app_ctx.i4_degrade_pics = 0;
   1847     s_app_ctx.max_wd = 0;
   1848     s_app_ctx.max_ht = 0;
   1849     s_app_ctx.max_level = 0;
   1850     s_app_ctx.e_arch = ARCH_ARM_A9Q;
   1851     s_app_ctx.e_soc = SOC_GENERIC;
   1852 
   1853     s_app_ctx.u4_strd = STRIDE;
   1854 
   1855     s_app_ctx.display_thread_handle           = malloc(ithread_get_handle_size());
   1856     s_app_ctx.quit          = 0;
   1857     s_app_ctx.paused        = 0;
   1858     //s_app_ctx.u4_output_present = 0;
   1859 
   1860     s_app_ctx.get_stride = &default_get_stride;
   1861 
   1862     s_app_ctx.get_color_fmt = &default_get_color_fmt;
   1863 
   1864     /* Set function pointers for display */
   1865 #ifdef SDL_DISPLAY
   1866     s_app_ctx.disp_init = &sdl_disp_init;
   1867     s_app_ctx.alloc_disp_buffers = &sdl_alloc_disp_buffers;
   1868     s_app_ctx.display_buffer = &sdl_display;
   1869     s_app_ctx.set_disp_buffers = &sdl_set_disp_buffers;
   1870     s_app_ctx.disp_deinit = &sdl_disp_deinit;
   1871     s_app_ctx.disp_usleep = &sdl_disp_usleep;
   1872     s_app_ctx.get_color_fmt = &sdl_get_color_fmt;
   1873     s_app_ctx.get_stride = &sdl_get_stride;
   1874 #endif
   1875 
   1876 #ifdef FBDEV_DISPLAY
   1877     s_app_ctx.disp_init = &fbd_disp_init;
   1878     s_app_ctx.alloc_disp_buffers = &fbd_alloc_disp_buffers;
   1879     s_app_ctx.display_buffer = &fbd_display;
   1880     s_app_ctx.set_disp_buffers = &fbd_set_disp_buffers;
   1881     s_app_ctx.disp_deinit = &fbd_disp_deinit;
   1882     s_app_ctx.disp_usleep = &fbd_disp_usleep;
   1883     s_app_ctx.get_color_fmt = &fbd_get_color_fmt;
   1884     s_app_ctx.get_stride = &fbd_get_stride;
   1885 #endif
   1886 
   1887 #ifdef INTEL_CE5300
   1888     s_app_ctx.disp_init = &gdl_disp_init;
   1889     s_app_ctx.alloc_disp_buffers = &gdl_alloc_disp_buffers;
   1890     s_app_ctx.display_buffer = &gdl_display;
   1891     s_app_ctx.set_disp_buffers = &gdl_set_disp_buffers;
   1892     s_app_ctx.disp_deinit = &gdl_disp_deinit;
   1893     s_app_ctx.disp_usleep = &gdl_disp_usleep;
   1894     s_app_ctx.get_color_fmt = &gdl_get_color_fmt;
   1895     s_app_ctx.get_stride = &gdl_get_stride;
   1896 #endif
   1897 
   1898 #ifdef IOS_DISPLAY
   1899     s_app_ctx.disp_init = &ios_disp_init;
   1900     s_app_ctx.alloc_disp_buffers = &ios_alloc_disp_buffers;
   1901     s_app_ctx.display_buffer = &ios_display;
   1902     s_app_ctx.set_disp_buffers = &ios_set_disp_buffers;
   1903     s_app_ctx.disp_deinit = &ios_disp_deinit;
   1904     s_app_ctx.disp_usleep = &ios_disp_usleep;
   1905     s_app_ctx.get_color_fmt = &ios_get_color_fmt;
   1906     s_app_ctx.get_stride = &ios_get_stride;
   1907 #endif
   1908 
   1909     s_app_ctx.display_deinit_flag = 0;
   1910     s_app_ctx.e_output_chroma_format = IV_YUV_420SP_UV;
   1911     /*************************************************************************/
   1912     /* Parse arguments                                                       */
   1913     /*************************************************************************/
   1914 
   1915 #ifndef IOS
   1916     /* Read command line arguments */
   1917     if(argc > 2)
   1918     {
   1919         for(i = 1; i < (UWORD32)argc; i += 2)
   1920         {
   1921             if(CONFIG == get_argument(argv[i]))
   1922             {
   1923                 strcpy(ac_cfg_fname, argv[i + 1]);
   1924                 if((fp_cfg_file = fopen(ac_cfg_fname, "r")) == NULL)
   1925                 {
   1926                     sprintf(ac_error_str, "Could not open Configuration file %s",
   1927                             ac_cfg_fname);
   1928                     codec_exit(ac_error_str);
   1929                 }
   1930                 read_cfg_file(&s_app_ctx, fp_cfg_file);
   1931                 fclose(fp_cfg_file);
   1932             }
   1933             else
   1934             {
   1935                 parse_argument(&s_app_ctx, argv[i], argv[i + 1]);
   1936             }
   1937         }
   1938     }
   1939     else
   1940     {
   1941         if((fp_cfg_file = fopen(ac_cfg_fname, "r")) == NULL)
   1942         {
   1943             sprintf(ac_error_str, "Could not open Configuration file %s",
   1944                     ac_cfg_fname);
   1945             codec_exit(ac_error_str);
   1946         }
   1947         read_cfg_file(&s_app_ctx, fp_cfg_file);
   1948         fclose(fp_cfg_file);
   1949     }
   1950 #else
   1951     sprintf(filename_with_path, "%s/%s", homedir, ac_cfg_fname);
   1952     if((fp_cfg_file = fopen(filename_with_path, "r")) == NULL)
   1953     {
   1954         sprintf(ac_error_str, "Could not open Configuration file %s",
   1955                 ac_cfg_fname);
   1956         codec_exit(ac_error_str);
   1957 
   1958     }
   1959     read_cfg_file(&s_app_ctx, fp_cfg_file);
   1960     fclose(fp_cfg_file);
   1961 
   1962 #endif
   1963 #ifdef PRINT_PICSIZE
   1964     /* If the binary is used for only getting number of bytes in each picture, then disable the following features */
   1965     s_app_ctx.u4_piclen_flag = 0;
   1966     s_app_ctx.u4_file_save_flag = 0;
   1967     s_app_ctx.u4_chksum_save_flag = 0;
   1968     s_app_ctx.i4_degrade_pics = 0;
   1969     s_app_ctx.i4_degrade_type = 0;
   1970     s_app_ctx.loopback = 0;
   1971     s_app_ctx.share_disp_buf = 0;
   1972     s_app_ctx.display = 0;
   1973 #endif
   1974 
   1975     /* If display is enabled, then turn off shared mode and get color format that is supported by display */
   1976     if(1 == s_app_ctx.display)
   1977     {
   1978         s_app_ctx.share_disp_buf = 0;
   1979         s_app_ctx.e_output_chroma_format = s_app_ctx.get_color_fmt();
   1980     }
   1981     if(strcmp(s_app_ctx.ac_ip_fname, "\0") == 0)
   1982     {
   1983         printf("\nNo input file given for decoding\n");
   1984         exit(-1);
   1985     }
   1986 
   1987 
   1988     /***********************************************************************/
   1989     /*          create the file object for input file                      */
   1990     /***********************************************************************/
   1991 #ifdef IOS
   1992     sprintf(filename_with_path, "%s/%s", homedir, s_app_ctx.ac_ip_fname);
   1993     ps_ip_file = fopen(filename_with_path, "rb");
   1994 #else
   1995     ps_ip_file = fopen(s_app_ctx.ac_ip_fname, "rb");
   1996 #endif
   1997     if(NULL == ps_ip_file)
   1998     {
   1999         sprintf(ac_error_str, "Could not open input file %s",
   2000                 s_app_ctx.ac_ip_fname);
   2001         codec_exit(ac_error_str);
   2002     }
   2003     /***********************************************************************/
   2004     /*          create the file object for input file                      */
   2005     /***********************************************************************/
   2006     if(1 == s_app_ctx.u4_piclen_flag)
   2007     {
   2008 #ifdef IOS
   2009         sprintf(filename_with_path, "%s/%s", homedir, s_app_ctx.ac_piclen_fname);
   2010         ps_piclen_file = fopen(filename_with_path, "rb");
   2011 #else
   2012         ps_piclen_file = fopen(s_app_ctx.ac_piclen_fname, "rb");
   2013 #endif
   2014         if(NULL == ps_piclen_file)
   2015         {
   2016             sprintf(ac_error_str, "Could not open piclen file %s",
   2017                     s_app_ctx.ac_piclen_fname);
   2018             codec_exit(ac_error_str);
   2019         }
   2020     }
   2021 
   2022     /***********************************************************************/
   2023     /*          create the file object for output file                     */
   2024     /***********************************************************************/
   2025     if(1 == s_app_ctx.u4_file_save_flag)
   2026     {
   2027 #ifdef IOS
   2028         sprintf(filename_with_path, "%s/%s", documentdir, s_app_ctx.ac_op_fname);
   2029         ps_op_file = fopen(filename_with_path, "wb");
   2030 #else
   2031         ps_op_file = fopen(s_app_ctx.ac_op_fname, "wb");
   2032 #endif
   2033 
   2034         if(NULL == ps_op_file)
   2035         {
   2036             sprintf(ac_error_str, "Could not open output file %s",
   2037                     s_app_ctx.ac_op_fname);
   2038             codec_exit(ac_error_str);
   2039         }
   2040     }
   2041 
   2042     /***********************************************************************/
   2043     /*          create the file object for check sum file                  */
   2044     /***********************************************************************/
   2045     if(1 == s_app_ctx.u4_chksum_save_flag)
   2046     {
   2047 #if IOS
   2048         sprintf(filename_with_path, "%s/%s", documentdir, s_app_ctx.ac_op_chksum_fname);
   2049         ps_op_chksum_file = fopen(filename_with_path, "wb");
   2050 #else
   2051         ps_op_chksum_file = fopen(s_app_ctx.ac_op_chksum_fname, "wb");
   2052 #endif
   2053         if(NULL == ps_op_chksum_file)
   2054         {
   2055             sprintf(ac_error_str, "Could not open check sum file %s",
   2056                     s_app_ctx.ac_op_chksum_fname);
   2057             codec_exit(ac_error_str);
   2058         }
   2059     }
   2060     /***********************************************************************/
   2061     /*                      Create decoder instance                        */
   2062     /***********************************************************************/
   2063     {
   2064 
   2065         ps_out_buf = (ivd_out_bufdesc_t *)malloc(sizeof(ivd_out_bufdesc_t));
   2066 
   2067         {
   2068             iv_num_mem_rec_ip_t s_no_of_mem_rec_query_ip;
   2069             iv_num_mem_rec_op_t s_no_of_mem_rec_query_op;
   2070 
   2071             s_no_of_mem_rec_query_ip.u4_size = sizeof(s_no_of_mem_rec_query_ip);
   2072             s_no_of_mem_rec_query_op.u4_size = sizeof(s_no_of_mem_rec_query_op);
   2073             s_no_of_mem_rec_query_ip.e_cmd = IV_CMD_GET_NUM_MEM_REC;
   2074 
   2075             /*****************************************************************************/
   2076             /*   API Call: Get Number of Mem Records                                     */
   2077             /*****************************************************************************/
   2078             e_dec_status = ivd_cxa_api_function(
   2079                             NULL, (void *)&s_no_of_mem_rec_query_ip,
   2080                             (void *)&s_no_of_mem_rec_query_op);
   2081             if(IV_SUCCESS != e_dec_status)
   2082             {
   2083                 sprintf(ac_error_str, "Error in get mem records");
   2084                 codec_exit(ac_error_str);
   2085             }
   2086 
   2087             u4_num_mem_recs = s_no_of_mem_rec_query_op.u4_num_mem_rec;
   2088         }
   2089 
   2090         pv_mem_rec_location = malloc(u4_num_mem_recs * sizeof(iv_mem_rec_t));
   2091         if(pv_mem_rec_location == NULL)
   2092         {
   2093             sprintf(ac_error_str, "Allocation failure for mem_rec_location");
   2094             codec_exit(ac_error_str);
   2095 
   2096         }
   2097 
   2098         {
   2099             ihevcd_cxa_fill_mem_rec_ip_t s_fill_mem_rec_ip;
   2100             ihevcd_cxa_fill_mem_rec_op_t s_fill_mem_rec_op;
   2101             iv_mem_rec_t *ps_mem_rec;
   2102             UWORD32 total_size;
   2103 
   2104             s_fill_mem_rec_ip.s_ivd_fill_mem_rec_ip_t.e_cmd =
   2105                             IV_CMD_FILL_NUM_MEM_REC;
   2106             s_fill_mem_rec_ip.s_ivd_fill_mem_rec_ip_t.pv_mem_rec_location =
   2107                             (iv_mem_rec_t *)pv_mem_rec_location;
   2108             s_fill_mem_rec_ip.s_ivd_fill_mem_rec_ip_t.u4_max_frm_wd =
   2109                             (s_app_ctx.max_wd == 0) ? MAX_FRAME_WIDTH : s_app_ctx.max_wd;
   2110             s_fill_mem_rec_ip.s_ivd_fill_mem_rec_ip_t.u4_max_frm_ht =
   2111                             (s_app_ctx.max_ht == 0) ? MAX_FRAME_HEIGHT : s_app_ctx.max_ht;
   2112             s_fill_mem_rec_ip.i4_level = (s_app_ctx.max_level == 0) ? MAX_LEVEL_SUPPORTED : s_app_ctx.max_level;
   2113             s_fill_mem_rec_ip.u4_num_ref_frames = MAX_REF_FRAMES;
   2114             s_fill_mem_rec_ip.u4_num_reorder_frames = MAX_REORDER_FRAMES;
   2115             s_fill_mem_rec_ip.u4_share_disp_buf = s_app_ctx.share_disp_buf;
   2116             s_fill_mem_rec_ip.e_output_format =
   2117                             (IV_COLOR_FORMAT_T)s_app_ctx.e_output_chroma_format;
   2118             s_fill_mem_rec_ip.u4_num_extra_disp_buf = EXTRA_DISP_BUFFERS;
   2119 
   2120             s_fill_mem_rec_ip.s_ivd_fill_mem_rec_ip_t.u4_size =
   2121                             sizeof(ihevcd_cxa_fill_mem_rec_ip_t);
   2122             s_fill_mem_rec_op.s_ivd_fill_mem_rec_op_t.u4_size =
   2123                             sizeof(ihevcd_cxa_fill_mem_rec_op_t);
   2124 
   2125             ps_mem_rec = (iv_mem_rec_t *)pv_mem_rec_location;
   2126             for(i = 0; i < u4_num_mem_recs; i++)
   2127                 ps_mem_rec[i].u4_size = sizeof(iv_mem_rec_t);
   2128 
   2129             /*****************************************************************************/
   2130             /*   API Call: Fill Mem Records                                     */
   2131             /*****************************************************************************/
   2132 
   2133             e_dec_status = ivd_cxa_api_function(NULL,
   2134                                                 (void *)&s_fill_mem_rec_ip,
   2135                                                 (void *)&s_fill_mem_rec_op);
   2136 
   2137             u4_num_mem_recs =
   2138                             s_fill_mem_rec_op.s_ivd_fill_mem_rec_op_t.u4_num_mem_rec_filled;
   2139 
   2140             if(IV_SUCCESS != e_dec_status)
   2141             {
   2142                 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);
   2143                 codec_exit(ac_error_str);
   2144             }
   2145 
   2146             ps_mem_rec = (iv_mem_rec_t *)pv_mem_rec_location;
   2147             total_size = 0;
   2148             for(i = 0; i < u4_num_mem_recs; i++)
   2149             {
   2150                 ps_mem_rec->pv_base = ihevca_aligned_malloc(ps_mem_rec->u4_mem_alignment,
   2151                                                             ps_mem_rec->u4_mem_size);
   2152                 if(ps_mem_rec->pv_base == NULL)
   2153                 {
   2154                     sprintf(ac_error_str,
   2155                             "\nAllocation failure for mem record id %d size %d\n",
   2156                             i, ps_mem_rec->u4_mem_size);
   2157                     codec_exit(ac_error_str);
   2158 
   2159                 }
   2160                 total_size += ps_mem_rec->u4_mem_size;
   2161 
   2162                 ps_mem_rec++;
   2163             }
   2164             //printf("\nTotal memory for codec %d\n", total_size);
   2165         }
   2166         /*****************************************************************************/
   2167         /*   API Call: Initialize the Decoder                                        */
   2168         /*****************************************************************************/
   2169         {
   2170             ihevcd_cxa_init_ip_t s_init_ip;
   2171             ihevcd_cxa_init_op_t s_init_op;
   2172             void *fxns = &ivd_cxa_api_function;
   2173             iv_mem_rec_t *mem_tab;
   2174 
   2175             mem_tab = (iv_mem_rec_t *)pv_mem_rec_location;
   2176             s_init_ip.s_ivd_init_ip_t.e_cmd = (IVD_API_COMMAND_TYPE_T)IV_CMD_INIT;
   2177             s_init_ip.s_ivd_init_ip_t.pv_mem_rec_location = mem_tab;
   2178             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;
   2179             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;
   2180             s_init_ip.i4_level = (s_app_ctx.max_level == 0) ? MAX_LEVEL_SUPPORTED : s_app_ctx.max_level;
   2181             s_init_ip.u4_num_ref_frames = MAX_REF_FRAMES;
   2182             s_init_ip.u4_num_reorder_frames = MAX_REORDER_FRAMES;
   2183             s_init_ip.u4_share_disp_buf = s_app_ctx.share_disp_buf;
   2184             s_init_ip.u4_num_extra_disp_buf = EXTRA_DISP_BUFFERS;
   2185             s_init_ip.s_ivd_init_ip_t.u4_num_mem_rec = u4_num_mem_recs;
   2186             s_init_ip.s_ivd_init_ip_t.e_output_format =
   2187                             (IV_COLOR_FORMAT_T)s_app_ctx.e_output_chroma_format;
   2188             s_init_ip.s_ivd_init_ip_t.u4_size = sizeof(ihevcd_cxa_init_ip_t);
   2189             s_init_op.s_ivd_init_op_t.u4_size = sizeof(ihevcd_cxa_init_op_t);
   2190 
   2191             codec_obj = (iv_obj_t *)mem_tab[0].pv_base;
   2192             codec_obj->pv_fxns = fxns;
   2193             codec_obj->u4_size = sizeof(iv_obj_t);
   2194 
   2195             s_app_ctx.cocodec_obj = codec_obj;
   2196 
   2197             ret = ivd_cxa_api_function((iv_obj_t *)codec_obj, (void *)&s_init_ip,
   2198                                        (void *)&s_init_op);
   2199             if(ret != IV_SUCCESS)
   2200             {
   2201                 sprintf(ac_error_str, "Error in Init %8x\n",
   2202                         s_init_op.s_ivd_init_op_t.u4_error_code);
   2203                 codec_exit(ac_error_str);
   2204             }
   2205 
   2206             /*****************************************************************************/
   2207             /*  Input and output buffer allocation                                       */
   2208             /*****************************************************************************/
   2209             {
   2210 
   2211                 ivd_ctl_getbufinfo_ip_t s_ctl_ip;
   2212                 ivd_ctl_getbufinfo_op_t s_ctl_op;
   2213 
   2214                 s_ctl_ip.e_cmd = IVD_CMD_VIDEO_CTL;
   2215                 s_ctl_ip.e_sub_cmd = IVD_CMD_CTL_GETBUFINFO;
   2216                 s_ctl_ip.u4_size = sizeof(ivd_ctl_getbufinfo_ip_t);
   2217                 s_ctl_op.u4_size = sizeof(ivd_ctl_getbufinfo_op_t);
   2218                 ret = ivd_cxa_api_function((iv_obj_t *)codec_obj, (void *)&s_ctl_ip,
   2219                                            (void *)&s_ctl_op);
   2220                 if(ret != IV_SUCCESS)
   2221                 {
   2222                     sprintf(ac_error_str, "Error in Get Buf Info %x", s_ctl_op.u4_error_code);
   2223                     codec_exit(ac_error_str);
   2224                 }
   2225 
   2226                 /* Allocate input buffer */
   2227                 u4_ip_buf_len = s_ctl_op.u4_min_in_buf_size[0];
   2228                 pu1_bs_buf = (UWORD8 *)malloc(u4_ip_buf_len);
   2229 
   2230                 if(pu1_bs_buf == NULL)
   2231                 {
   2232                     sprintf(ac_error_str,
   2233                             "\nAllocation failure for input buffer of size %d",
   2234                             u4_ip_buf_len);
   2235                     codec_exit(ac_error_str);
   2236                 }
   2237                 s_app_ctx.num_disp_buf = s_ctl_op.u4_num_disp_bufs;
   2238                 /* Allocate output buffer only if display buffers are not shared */
   2239                 /* Or if shared and output is 420P */
   2240                 if((0 == s_app_ctx.share_disp_buf) || (IV_YUV_420P == s_app_ctx.e_output_chroma_format))
   2241                 {
   2242                     UWORD32 outlen;
   2243                     ps_out_buf->u4_min_out_buf_size[0] =
   2244                                     s_ctl_op.u4_min_out_buf_size[0];
   2245                     ps_out_buf->u4_min_out_buf_size[1] =
   2246                                     s_ctl_op.u4_min_out_buf_size[1];
   2247                     ps_out_buf->u4_min_out_buf_size[2] =
   2248                                     s_ctl_op.u4_min_out_buf_size[2];
   2249 
   2250                     outlen = s_ctl_op.u4_min_out_buf_size[0];
   2251                     if(s_ctl_op.u4_min_num_out_bufs > 1)
   2252                         outlen += s_ctl_op.u4_min_out_buf_size[1];
   2253 
   2254                     if(s_ctl_op.u4_min_num_out_bufs > 2)
   2255                         outlen += s_ctl_op.u4_min_out_buf_size[2];
   2256 
   2257                     ps_out_buf->pu1_bufs[0] = (UWORD8 *)malloc(outlen);
   2258                     if(ps_out_buf->pu1_bufs[0] == NULL)
   2259                     {
   2260                         sprintf(ac_error_str,
   2261                                 "\nAllocation failure for output buffer of size %d",
   2262                                 outlen);
   2263                         codec_exit(ac_error_str);
   2264                     }
   2265 
   2266                     if(s_ctl_op.u4_min_num_out_bufs > 1)
   2267                         ps_out_buf->pu1_bufs[1] = ps_out_buf->pu1_bufs[0]
   2268                                         + (s_ctl_op.u4_min_out_buf_size[0]);
   2269 
   2270                     if(s_ctl_op.u4_min_num_out_bufs > 2)
   2271                         ps_out_buf->pu1_bufs[2] = ps_out_buf->pu1_bufs[1]
   2272                                         + (s_ctl_op.u4_min_out_buf_size[1]);
   2273 
   2274                     ps_out_buf->u4_num_bufs = s_ctl_op.u4_min_num_out_bufs;
   2275                 }
   2276 
   2277             }
   2278         }
   2279 
   2280     }
   2281 
   2282 
   2283     /*************************************************************************/
   2284     /* set num of cores                                                      */
   2285     /*************************************************************************/
   2286     {
   2287 
   2288         ihevcd_cxa_ctl_set_num_cores_ip_t s_ctl_set_cores_ip;
   2289         ihevcd_cxa_ctl_set_num_cores_op_t s_ctl_set_cores_op;
   2290 
   2291         s_ctl_set_cores_ip.e_cmd = IVD_CMD_VIDEO_CTL;
   2292         s_ctl_set_cores_ip.e_sub_cmd = (IVD_CONTROL_API_COMMAND_TYPE_T)IHEVCD_CXA_CMD_CTL_SET_NUM_CORES;
   2293         s_ctl_set_cores_ip.u4_num_cores = s_app_ctx.u4_num_cores;
   2294         s_ctl_set_cores_ip.u4_size = sizeof(ihevcd_cxa_ctl_set_num_cores_ip_t);
   2295         s_ctl_set_cores_op.u4_size = sizeof(ihevcd_cxa_ctl_set_num_cores_op_t);
   2296 
   2297         ret = ivd_cxa_api_function((iv_obj_t *)codec_obj, (void *)&s_ctl_set_cores_ip,
   2298                                    (void *)&s_ctl_set_cores_op);
   2299         if(ret != IV_SUCCESS)
   2300         {
   2301             sprintf(ac_error_str, "\nError in setting number of cores");
   2302             codec_exit(ac_error_str);
   2303         }
   2304 
   2305     }
   2306     /*************************************************************************/
   2307     /* set processsor                                                        */
   2308     /*************************************************************************/
   2309     {
   2310 
   2311         ihevcd_cxa_ctl_set_processor_ip_t s_ctl_set_num_processor_ip;
   2312         ihevcd_cxa_ctl_set_processor_op_t s_ctl_set_num_processor_op;
   2313 
   2314         s_ctl_set_num_processor_ip.e_cmd = IVD_CMD_VIDEO_CTL;
   2315         s_ctl_set_num_processor_ip.e_sub_cmd = (IVD_CONTROL_API_COMMAND_TYPE_T)IHEVCD_CXA_CMD_CTL_SET_PROCESSOR;
   2316         s_ctl_set_num_processor_ip.u4_arch = s_app_ctx.e_arch;
   2317         s_ctl_set_num_processor_ip.u4_soc = s_app_ctx.e_soc;
   2318         s_ctl_set_num_processor_ip.u4_size = sizeof(ihevcd_cxa_ctl_set_processor_ip_t);
   2319         s_ctl_set_num_processor_op.u4_size = sizeof(ihevcd_cxa_ctl_set_processor_op_t);
   2320 
   2321         ret = ivd_cxa_api_function((iv_obj_t *)codec_obj, (void *)&s_ctl_set_num_processor_ip,
   2322                                    (void *)&s_ctl_set_num_processor_op);
   2323         if(ret != IV_SUCCESS)
   2324         {
   2325             sprintf(ac_error_str, "\nError in setting Processor type");
   2326             codec_exit(ac_error_str);
   2327         }
   2328 
   2329     }
   2330 
   2331 
   2332     /*****************************************************************************/
   2333     /*   Decode header to get width and height and buffer sizes                  */
   2334     /*****************************************************************************/
   2335     {
   2336 
   2337         ivd_ctl_set_config_ip_t s_ctl_ip;
   2338         ivd_ctl_set_config_op_t s_ctl_op;
   2339 
   2340         ivd_video_decode_ip_t s_video_decode_ip;
   2341         ivd_video_decode_op_t s_video_decode_op;
   2342 
   2343         s_ctl_ip.u4_disp_wd = STRIDE;
   2344         if(1 == s_app_ctx.display)
   2345             s_ctl_ip.u4_disp_wd = s_app_ctx.get_stride();
   2346 
   2347         s_ctl_ip.e_frm_skip_mode = IVD_SKIP_NONE;
   2348         s_ctl_ip.e_frm_out_mode = IVD_DISPLAY_FRAME_OUT;
   2349         s_ctl_ip.e_vid_dec_mode = IVD_DECODE_HEADER;
   2350         s_ctl_ip.e_cmd = IVD_CMD_VIDEO_CTL;
   2351         s_ctl_ip.e_sub_cmd = IVD_CMD_CTL_SETPARAMS;
   2352         s_ctl_ip.u4_size = sizeof(ivd_ctl_set_config_ip_t);
   2353         s_ctl_op.u4_size = sizeof(ivd_ctl_set_config_op_t);
   2354 
   2355         ret = ivd_cxa_api_function((iv_obj_t *)codec_obj, (void *)&s_ctl_ip,
   2356                                    (void *)&s_ctl_op);
   2357         if(ret != IV_SUCCESS)
   2358         {
   2359             sprintf(ac_error_str,
   2360                     "\nError in setting the codec in header decode mode");
   2361             codec_exit(ac_error_str);
   2362         }
   2363 
   2364         do
   2365         {
   2366             WORD32 numbytes;
   2367             if(0 == s_app_ctx.u4_piclen_flag)
   2368             {
   2369                 fseek(ps_ip_file, file_pos, SEEK_SET);
   2370                 numbytes = u4_ip_buf_len;
   2371             }
   2372             else
   2373             {
   2374                 WORD32 entries;
   2375                 entries = fscanf(ps_piclen_file, "%d\n", &numbytes);
   2376                 if(1 != entries)
   2377                     numbytes = u4_ip_buf_len;
   2378             }
   2379 
   2380             u4_bytes_remaining = fread(pu1_bs_buf, sizeof(UWORD8), numbytes,
   2381                                        ps_ip_file);
   2382 
   2383             if(0 == u4_bytes_remaining)
   2384             {
   2385                 sprintf(ac_error_str, "\nUnable to read from input file");
   2386                 codec_exit(ac_error_str);
   2387             }
   2388 
   2389             s_video_decode_ip.e_cmd = IVD_CMD_VIDEO_DECODE;
   2390             s_video_decode_ip.u4_ts = u4_ip_frm_ts;
   2391             s_video_decode_ip.pv_stream_buffer = pu1_bs_buf;
   2392             s_video_decode_ip.u4_num_Bytes = u4_bytes_remaining;
   2393             s_video_decode_ip.u4_size = sizeof(ivd_video_decode_ip_t);
   2394             s_video_decode_op.u4_size = sizeof(ivd_video_decode_op_t);
   2395 
   2396             /*****************************************************************************/
   2397             /*   API Call: Header Decode                                                  */
   2398             /*****************************************************************************/
   2399             ret = ivd_cxa_api_function((iv_obj_t *)codec_obj, (void *)&s_video_decode_ip,
   2400                                        (void *)&s_video_decode_op);
   2401 
   2402             if(ret != IV_SUCCESS)
   2403             {
   2404                 sprintf(ac_error_str, "\nError in header decode %x",
   2405                         s_video_decode_op.u4_error_code);
   2406                 // codec_exit(ac_error_str);
   2407             }
   2408 
   2409             u4_num_bytes_dec = s_video_decode_op.u4_num_bytes_consumed;
   2410 #ifndef PROFILE_ENABLE
   2411             printf("%d\n", s_video_decode_op.u4_num_bytes_consumed);
   2412 #endif
   2413             file_pos += u4_num_bytes_dec;
   2414             total_bytes_comsumed += u4_num_bytes_dec;
   2415         }while(ret != IV_SUCCESS);
   2416 
   2417         /* copy pic_wd and pic_ht to initialize buffers */
   2418         s_app_ctx.u4_pic_wd = s_video_decode_op.u4_pic_wd;
   2419         s_app_ctx.u4_pic_ht = s_video_decode_op.u4_pic_ht;
   2420 
   2421 #if IOS_DISPLAY
   2422         s_app_ctx.i4_screen_wd = screen_wd;
   2423         s_app_ctx.i4_screen_ht = screen_ht;
   2424 #endif
   2425 
   2426         /* Create display thread and wait for the display buffers to be initialized */
   2427         if(1 == s_app_ctx.display)
   2428         {
   2429             if(0 == s_app_ctx.display_thread_created)
   2430             {
   2431                 s_app_ctx.display_init_done = 0;
   2432                 ithread_create(s_app_ctx.display_thread_handle, NULL,
   2433                                (void *)&display_thread, (void *)&s_app_ctx);
   2434                 s_app_ctx.display_thread_created = 1;
   2435 
   2436                 while(1)
   2437                 {
   2438                     if(s_app_ctx.display_init_done)
   2439                         break;
   2440 
   2441                     ithread_msleep(1);
   2442                 }
   2443             }
   2444 
   2445             s_app_ctx.u4_strd = s_app_ctx.get_stride();
   2446         }
   2447     }
   2448 
   2449     /*************************************************************************/
   2450     /* Get actual number of output buffers requried, which is dependent      */
   2451     /* on stream properties such as width, height and level etc              */
   2452     /* This is needed mainly for shared display mode                         */
   2453     /*************************************************************************/
   2454     //if(1 == s_app_ctx.share_disp_buf)
   2455     {
   2456         ivd_ctl_getbufinfo_ip_t s_ctl_ip;
   2457         ivd_ctl_getbufinfo_op_t s_ctl_op;
   2458         WORD32 outlen = 0;
   2459 
   2460         s_ctl_ip.e_cmd = IVD_CMD_VIDEO_CTL;
   2461         s_ctl_ip.e_sub_cmd = IVD_CMD_CTL_GETBUFINFO;
   2462         s_ctl_ip.u4_size = sizeof(ivd_ctl_getbufinfo_ip_t);
   2463         s_ctl_op.u4_size = sizeof(ivd_ctl_getbufinfo_op_t);
   2464         ret = ivd_cxa_api_function((iv_obj_t *)codec_obj, (void *)&s_ctl_ip,
   2465                                    (void *)&s_ctl_op);
   2466         if(ret != IV_SUCCESS)
   2467         {
   2468             sprintf(ac_error_str, "Error in Get Buf Info %x", s_ctl_op.u4_error_code);
   2469             codec_exit(ac_error_str);
   2470         }
   2471 
   2472 #ifdef APP_EXTRA_BUFS
   2473         s_app_ctx.disp_delay = EXTRA_DISP_BUFFERS;
   2474         s_ctl_op.u4_num_disp_bufs += EXTRA_DISP_BUFFERS;
   2475 #endif
   2476 
   2477         /*****************************************************************************/
   2478         /*   API Call: Allocate display buffers for display buffer shared case       */
   2479         /*****************************************************************************/
   2480 
   2481         for(i = 0; i < s_ctl_op.u4_num_disp_bufs; i++)
   2482         {
   2483 
   2484             s_app_ctx.s_disp_buffers[i].u4_min_out_buf_size[0] =
   2485                             s_ctl_op.u4_min_out_buf_size[0];
   2486             s_app_ctx.s_disp_buffers[i].u4_min_out_buf_size[1] =
   2487                             s_ctl_op.u4_min_out_buf_size[1];
   2488             s_app_ctx.s_disp_buffers[i].u4_min_out_buf_size[2] =
   2489                             s_ctl_op.u4_min_out_buf_size[2];
   2490 
   2491             outlen = s_ctl_op.u4_min_out_buf_size[0];
   2492             if(s_ctl_op.u4_min_num_out_bufs > 1)
   2493                 outlen += s_ctl_op.u4_min_out_buf_size[1];
   2494 
   2495             if(s_ctl_op.u4_min_num_out_bufs > 2)
   2496                 outlen += s_ctl_op.u4_min_out_buf_size[2];
   2497 
   2498             s_app_ctx.s_disp_buffers[i].pu1_bufs[0] = (UWORD8 *)malloc(outlen);
   2499 
   2500             if(s_app_ctx.s_disp_buffers[i].pu1_bufs[0] == NULL)
   2501             {
   2502                 sprintf(ac_error_str,
   2503                         "\nAllocation failure for output buffer of size %d",
   2504                         outlen);
   2505                 codec_exit(ac_error_str);
   2506             }
   2507 
   2508             if(s_ctl_op.u4_min_num_out_bufs > 1)
   2509                 s_app_ctx.s_disp_buffers[i].pu1_bufs[1] =
   2510                                 s_app_ctx.s_disp_buffers[i].pu1_bufs[0]
   2511                                                 + (s_ctl_op.u4_min_out_buf_size[0]);
   2512 
   2513             if(s_ctl_op.u4_min_num_out_bufs > 2)
   2514                 s_app_ctx.s_disp_buffers[i].pu1_bufs[2] =
   2515                                 s_app_ctx.s_disp_buffers[i].pu1_bufs[1]
   2516                                                 + (s_ctl_op.u4_min_out_buf_size[1]);
   2517 
   2518             s_app_ctx.s_disp_buffers[i].u4_num_bufs =
   2519                             s_ctl_op.u4_min_num_out_bufs;
   2520         }
   2521         s_app_ctx.num_disp_buf = s_ctl_op.u4_num_disp_bufs;
   2522 
   2523         /*****************************************************************************/
   2524         /*   API Call: Send the allocated display buffers to codec                   */
   2525         /*****************************************************************************/
   2526         {
   2527             ivd_set_display_frame_ip_t s_set_display_frame_ip;
   2528             ivd_set_display_frame_op_t s_set_display_frame_op;
   2529 
   2530             s_set_display_frame_ip.e_cmd = IVD_CMD_SET_DISPLAY_FRAME;
   2531             s_set_display_frame_ip.u4_size = sizeof(ivd_set_display_frame_ip_t);
   2532             s_set_display_frame_op.u4_size = sizeof(ivd_set_display_frame_op_t);
   2533 
   2534             s_set_display_frame_ip.num_disp_bufs = s_app_ctx.num_disp_buf;
   2535 
   2536             memcpy(&(s_set_display_frame_ip.s_disp_buffer),
   2537                    &(s_app_ctx.s_disp_buffers),
   2538                    s_ctl_op.u4_num_disp_bufs * sizeof(ivd_out_bufdesc_t));
   2539 
   2540             ret = ivd_cxa_api_function((iv_obj_t *)codec_obj,
   2541                                        (void *)&s_set_display_frame_ip,
   2542                                        (void *)&s_set_display_frame_op);
   2543 
   2544             if(IV_SUCCESS != ret)
   2545             {
   2546                 sprintf(ac_error_str, "Error in Set display frame");
   2547                 codec_exit(ac_error_str);
   2548             }
   2549 
   2550         }
   2551 
   2552     }
   2553 
   2554     /*************************************************************************/
   2555     /* Get frame dimensions for display buffers such as x_offset,y_offset    */
   2556     /* etc. This information might be needed to set display buffer           */
   2557     /* offsets in case of shared display buffer mode                         */
   2558     /*************************************************************************/
   2559     {
   2560 
   2561         ihevcd_cxa_ctl_get_frame_dimensions_ip_t s_ctl_get_frame_dimensions_ip;
   2562         ihevcd_cxa_ctl_get_frame_dimensions_op_t s_ctl_get_frame_dimensions_op;
   2563 
   2564         s_ctl_get_frame_dimensions_ip.e_cmd = IVD_CMD_VIDEO_CTL;
   2565         s_ctl_get_frame_dimensions_ip.e_sub_cmd =
   2566                         (IVD_CONTROL_API_COMMAND_TYPE_T)IHEVCD_CXA_CMD_CTL_GET_BUFFER_DIMENSIONS;
   2567         s_ctl_get_frame_dimensions_ip.u4_size =
   2568                         sizeof(ihevcd_cxa_ctl_get_frame_dimensions_ip_t);
   2569         s_ctl_get_frame_dimensions_op.u4_size =
   2570                         sizeof(ihevcd_cxa_ctl_get_frame_dimensions_op_t);
   2571 
   2572         ret = ivd_cxa_api_function((iv_obj_t *)codec_obj, (void *)&s_ctl_get_frame_dimensions_ip,
   2573                                    (void *)&s_ctl_get_frame_dimensions_op);
   2574         if(IV_SUCCESS != ret)
   2575         {
   2576             sprintf(ac_error_str, "Error in Get buffer Dimensions");
   2577             codec_exit(ac_error_str);
   2578         }
   2579 
   2580 /*
   2581         printf("Frame offsets due to padding\n");
   2582         printf("s_ctl_get_frame_dimensions_op.x_offset[0] %d s_ctl_get_frame_dimensions_op.y_offset[0] %d\n",
   2583                s_ctl_get_frame_dimensions_op.u4_x_offset[0],
   2584                s_ctl_get_frame_dimensions_op.u4_y_offset[0]);
   2585 */
   2586     }
   2587 
   2588 
   2589     /*************************************************************************/
   2590     /* Get VUI parameters                                                    */
   2591     /*************************************************************************/
   2592     {
   2593 
   2594         ihevcd_cxa_ctl_get_vui_params_ip_t s_ctl_get_vui_params_ip;
   2595         ihevcd_cxa_ctl_get_vui_params_op_t s_ctl_get_vui_params_op;
   2596 
   2597         s_ctl_get_vui_params_ip.e_cmd = IVD_CMD_VIDEO_CTL;
   2598         s_ctl_get_vui_params_ip.e_sub_cmd =
   2599                         (IVD_CONTROL_API_COMMAND_TYPE_T)IHEVCD_CXA_CMD_CTL_GET_VUI_PARAMS;
   2600         s_ctl_get_vui_params_ip.u4_size =
   2601                         sizeof(ihevcd_cxa_ctl_get_vui_params_ip_t);
   2602         s_ctl_get_vui_params_op.u4_size =
   2603                         sizeof(ihevcd_cxa_ctl_get_vui_params_op_t);
   2604 
   2605         ret = ivd_cxa_api_function((iv_obj_t *)codec_obj, (void *)&s_ctl_get_vui_params_ip,
   2606                                    (void *)&s_ctl_get_vui_params_op);
   2607         if(IV_SUCCESS != ret)
   2608         {
   2609             sprintf(ac_error_str, "Error in Get VUI params");
   2610             //codec_exit(ac_error_str);
   2611         }
   2612 
   2613     }
   2614 
   2615 
   2616     /*************************************************************************/
   2617     /* Set the decoder in frame decode mode. It was set in header decode     */
   2618     /* mode earlier                                                          */
   2619     /*************************************************************************/
   2620     {
   2621 
   2622         ivd_ctl_set_config_ip_t s_ctl_ip;
   2623         ivd_ctl_set_config_op_t s_ctl_op;
   2624 
   2625         s_ctl_ip.u4_disp_wd = STRIDE;
   2626         if(1 == s_app_ctx.display)
   2627             s_ctl_ip.u4_disp_wd = s_app_ctx.get_stride();
   2628         s_ctl_ip.e_frm_skip_mode = IVD_SKIP_NONE;
   2629 
   2630         s_ctl_ip.e_frm_out_mode = IVD_DISPLAY_FRAME_OUT;
   2631         s_ctl_ip.e_vid_dec_mode = IVD_DECODE_FRAME;
   2632         s_ctl_ip.e_cmd = IVD_CMD_VIDEO_CTL;
   2633         s_ctl_ip.e_sub_cmd = IVD_CMD_CTL_SETPARAMS;
   2634         s_ctl_ip.u4_size = sizeof(ivd_ctl_set_config_ip_t);
   2635 
   2636         s_ctl_op.u4_size = sizeof(ivd_ctl_set_config_op_t);
   2637 
   2638         ret = ivd_cxa_api_function((iv_obj_t *)codec_obj, (void *)&s_ctl_ip, (void *)&s_ctl_op);
   2639 
   2640         if(IV_SUCCESS != ret)
   2641         {
   2642             sprintf(ac_error_str, "Error in Set Parameters");
   2643             //codec_exit(ac_error_str);
   2644         }
   2645 
   2646     }
   2647     /*************************************************************************/
   2648     /* If required disable deblocking and sao at given level                 */
   2649     /*************************************************************************/
   2650     set_degrade(codec_obj, s_app_ctx.i4_degrade_type, s_app_ctx.i4_degrade_pics);
   2651 #ifdef X86_MSVC
   2652     QueryPerformanceFrequency(&frequency);
   2653 #endif
   2654 #ifndef PRINT_PICSIZE
   2655     get_version(codec_obj);
   2656 #endif
   2657     while(u4_op_frm_ts < (s_app_ctx.u4_max_frm_ts + s_app_ctx.disp_delay))
   2658     {
   2659 
   2660 #ifdef TEST_FLUSH
   2661         if(u4_ip_frm_ts == FLUSH_FRM_CNT)
   2662         {
   2663             ivd_ctl_flush_ip_t s_ctl_ip;
   2664             ivd_ctl_flush_op_t s_ctl_op;
   2665 
   2666             s_ctl_ip.e_cmd = IVD_CMD_VIDEO_CTL;
   2667             s_ctl_ip.e_sub_cmd = IVD_CMD_CTL_FLUSH;
   2668             s_ctl_ip.u4_size = sizeof(ivd_ctl_flush_ip_t);
   2669             s_ctl_op.u4_size = sizeof(ivd_ctl_flush_op_t);
   2670             ret = ivd_cxa_api_function((iv_obj_t *)codec_obj, (void *)&s_ctl_ip,
   2671                                        (void *)&s_ctl_op);
   2672 
   2673             if(ret != IV_SUCCESS)
   2674             {
   2675                 printf("Error in Setting the decoder in flush mode\n");
   2676             }
   2677             file_pos = 0;
   2678 
   2679             fseek(ps_ip_file, file_pos, SEEK_SET);
   2680 
   2681         }
   2682 #endif
   2683         if(u4_ip_frm_ts < s_app_ctx.num_disp_buf)
   2684         {
   2685             release_disp_frame(codec_obj, u4_ip_frm_ts);
   2686         }
   2687 
   2688 
   2689         /*************************************************************************/
   2690         /* set num of cores                                                      */
   2691         /*************************************************************************/
   2692 #ifdef DYNAMIC_NUMCORES
   2693         {
   2694 
   2695             ihevcd_cxa_ctl_set_num_cores_ip_t s_ctl_set_cores_ip;
   2696             ihevcd_cxa_ctl_set_num_cores_op_t s_ctl_set_cores_op;
   2697 
   2698             s_ctl_set_cores_ip.e_cmd = IVD_CMD_VIDEO_CTL;
   2699             s_ctl_set_cores_ip.e_sub_cmd = IHEVCD_CXA_CMD_CTL_SET_NUM_CORES;
   2700             s_ctl_set_cores_ip.u4_num_cores =  1 + 3 * (u4_ip_frm_ts % 2);
   2701             s_ctl_set_cores_ip.u4_size = sizeof(ihevcd_cxa_ctl_set_num_cores_ip_t);
   2702             s_ctl_set_cores_op.u4_size = sizeof(ihevcd_cxa_ctl_set_num_cores_op_t);
   2703 
   2704             ret = ivd_cxa_api_function((iv_obj_t *)codec_obj, (void *)&s_ctl_set_cores_ip,
   2705                                        (void *)&s_ctl_set_cores_op);
   2706             if(ret != IV_SUCCESS)
   2707             {
   2708                 sprintf(ac_error_str, "\nError in setting number of cores");
   2709                 codec_exit(ac_error_str);
   2710             }
   2711 
   2712         }
   2713 #endif
   2714         /***********************************************************************/
   2715         /*   Seek the file to start of current frame, this is equavelent of    */
   2716         /*   having a parcer which tells the start of current frame            */
   2717         /***********************************************************************/
   2718         {
   2719             WORD32 numbytes;
   2720 
   2721             if(0 == s_app_ctx.u4_piclen_flag)
   2722             {
   2723                 fseek(ps_ip_file, file_pos, SEEK_SET);
   2724                 numbytes = u4_ip_buf_len;
   2725             }
   2726             else
   2727             {
   2728                 WORD32 entries;
   2729                 entries = fscanf(ps_piclen_file, "%d\n", &numbytes);
   2730                 if(1 != entries)
   2731                     numbytes = u4_ip_buf_len;
   2732             }
   2733 
   2734             u4_bytes_remaining = fread(pu1_bs_buf, sizeof(UWORD8),
   2735                                        numbytes, ps_ip_file);
   2736 
   2737             if(u4_bytes_remaining == 0)
   2738             {
   2739                 if(1 == s_app_ctx.loopback)
   2740                 {
   2741                     file_pos = 0;
   2742                     if(0 == s_app_ctx.u4_piclen_flag)
   2743                     {
   2744                         fseek(ps_ip_file, file_pos, SEEK_SET);
   2745                         numbytes = u4_ip_buf_len;
   2746                     }
   2747                     else
   2748                     {
   2749                         WORD32 entries;
   2750                         entries = fscanf(ps_piclen_file, "%d\n", &numbytes);
   2751                         if(1 != entries)
   2752                             numbytes = u4_ip_buf_len;
   2753                     }
   2754 
   2755 
   2756                     u4_bytes_remaining = fread(pu1_bs_buf, sizeof(UWORD8),
   2757                                                numbytes, ps_ip_file);
   2758                 }
   2759                 else
   2760                     break;
   2761             }
   2762         }
   2763 
   2764         /*********************************************************************/
   2765         /* Following calls can be enabled at diffent times                   */
   2766         /*********************************************************************/
   2767 #if ENABLE_DEGRADE
   2768         if(u4_op_frm_ts >= 10000)
   2769             disable_deblocking(codec_obj, 4);
   2770 
   2771         if(u4_op_frm_ts == 30000)
   2772             enable_deblocking(codec_obj);
   2773 
   2774         if(u4_op_frm_ts == 10000)
   2775             enable_skippb_frames(codec_obj);
   2776 
   2777         if(u4_op_frm_ts == 60000)
   2778             disable_skippb_frames(codec_obj);
   2779 
   2780         if(u4_op_frm_ts == 30000)
   2781             enable_skipb_frames(codec_obj);
   2782 
   2783         if(u4_op_frm_ts == 60000)
   2784             disable_skipb_frames(codec_obj);
   2785 #endif
   2786 
   2787 
   2788         {
   2789             ivd_video_decode_ip_t s_video_decode_ip;
   2790             ivd_video_decode_op_t s_video_decode_op;
   2791 #ifdef PROFILE_ENABLE
   2792             UWORD32 s_elapsed_time;
   2793             TIMER s_start_timer;
   2794             TIMER s_end_timer;
   2795 #endif
   2796 
   2797 
   2798             s_video_decode_ip.e_cmd = IVD_CMD_VIDEO_DECODE;
   2799             s_video_decode_ip.u4_ts = u4_ip_frm_ts;
   2800             s_video_decode_ip.pv_stream_buffer = pu1_bs_buf;
   2801             s_video_decode_ip.u4_num_Bytes = u4_bytes_remaining;
   2802             s_video_decode_ip.u4_size = sizeof(ivd_video_decode_ip_t);
   2803             s_video_decode_ip.s_out_buffer.u4_min_out_buf_size[0] =
   2804                             ps_out_buf->u4_min_out_buf_size[0];
   2805             s_video_decode_ip.s_out_buffer.u4_min_out_buf_size[1] =
   2806                             ps_out_buf->u4_min_out_buf_size[1];
   2807             s_video_decode_ip.s_out_buffer.u4_min_out_buf_size[2] =
   2808                             ps_out_buf->u4_min_out_buf_size[2];
   2809 
   2810             s_video_decode_ip.s_out_buffer.pu1_bufs[0] =
   2811                             ps_out_buf->pu1_bufs[0];
   2812             s_video_decode_ip.s_out_buffer.pu1_bufs[1] =
   2813                             ps_out_buf->pu1_bufs[1];
   2814             s_video_decode_ip.s_out_buffer.pu1_bufs[2] =
   2815                             ps_out_buf->pu1_bufs[2];
   2816             s_video_decode_ip.s_out_buffer.u4_num_bufs =
   2817                             ps_out_buf->u4_num_bufs;
   2818             s_video_decode_op.u4_size = sizeof(ivd_video_decode_op_t);
   2819 
   2820             /* Get display buffer pointers */
   2821             if(1 == s_app_ctx.display)
   2822             {
   2823                 WORD32 wr_idx;
   2824 
   2825                 wr_idx = dispq_producer_dequeue(&s_app_ctx);
   2826 
   2827                 if(s_app_ctx.quit)
   2828                     break;
   2829 
   2830                 s_app_ctx.set_disp_buffers(s_app_ctx.pv_disp_ctx, wr_idx,
   2831                                            &s_video_decode_ip.s_out_buffer.pu1_bufs[0],
   2832                                            &s_video_decode_ip.s_out_buffer.pu1_bufs[1],
   2833                                            &s_video_decode_ip.s_out_buffer.pu1_bufs[2]);
   2834             }
   2835 
   2836             /*****************************************************************************/
   2837             /*   API Call: Video Decode                                                  */
   2838             /*****************************************************************************/
   2839 
   2840             GETTIME(&s_start_timer);
   2841 
   2842             ret = ivd_cxa_api_function((iv_obj_t *)codec_obj, (void *)&s_video_decode_ip,
   2843                                        (void *)&s_video_decode_op);
   2844 
   2845 
   2846             GETTIME(&s_end_timer);
   2847             ELAPSEDTIME(s_start_timer, s_end_timer, s_elapsed_time, frequency);
   2848 #ifdef PROFILE_ENABLE
   2849             {
   2850                 UWORD32 peak_avg, id;
   2851                 u4_tot_cycles += s_elapsed_time;
   2852                 peak_window[peak_window_idx++] = s_elapsed_time;
   2853                 if(peak_window_idx == PEAK_WINDOW_SIZE)
   2854                     peak_window_idx = 0;
   2855                 peak_avg = 0;
   2856                 for(id = 0; id < PEAK_WINDOW_SIZE; id++)
   2857                 {
   2858                     peak_avg += peak_window[id];
   2859                 }
   2860                 peak_avg /= PEAK_WINDOW_SIZE;
   2861                 if(peak_avg > peak_avg_max)
   2862                     peak_avg_max = peak_avg;
   2863                 frm_cnt++;
   2864 
   2865                 printf("FrameNum: %4d TimeTaken(microsec): %6d AvgTime: %6d PeakAvgTimeMax: %6d Output: %2d NumBytes: %6d \n",
   2866                        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);
   2867 
   2868             }
   2869 #ifdef INTEL_CE5300
   2870             time_consumed += s_elapsed_time;
   2871             bytes_consumed += s_video_decode_op.u4_num_bytes_consumed;
   2872             if(!(frm_cnt % (s_app_ctx.fps)))
   2873             {
   2874                 time_consumed = time_consumed / s_app_ctx.fps;
   2875                 printf("Average decode time(micro sec) for the last second = %6d\n", time_consumed);
   2876                 printf("Average bitrate(kb) for the last second = %6d\n", (bytes_consumed * 8) / 1024);
   2877                 time_consumed = 0;
   2878                 bytes_consumed = 0;
   2879 
   2880             }
   2881 #endif
   2882 #else
   2883             printf("%d\n", s_video_decode_op.u4_num_bytes_consumed);
   2884 #endif
   2885 
   2886             if(ret != IV_SUCCESS)
   2887             {
   2888                 printf("Error in video Frame decode : ret %x Error %x\n", ret,
   2889                        s_video_decode_op.u4_error_code);
   2890             }
   2891 
   2892             if((IV_SUCCESS != ret) &&
   2893                             ((s_video_decode_op.u4_error_code & 0xFF) == IVD_RES_CHANGED))
   2894             {
   2895                 ivd_ctl_reset_ip_t s_ctl_ip;
   2896                 ivd_ctl_reset_op_t s_ctl_op;
   2897 
   2898                 flush_output(codec_obj, &s_app_ctx, ps_out_buf,
   2899                              pu1_bs_buf, &u4_op_frm_ts,
   2900                              ps_op_file, ps_op_chksum_file,
   2901                              u4_ip_frm_ts, u4_bytes_remaining);
   2902 
   2903                 s_ctl_ip.e_cmd = IVD_CMD_VIDEO_CTL;
   2904                 s_ctl_ip.e_sub_cmd = IVD_CMD_CTL_RESET;
   2905                 s_ctl_ip.u4_size = sizeof(ivd_ctl_reset_ip_t);
   2906                 s_ctl_op.u4_size = sizeof(ivd_ctl_reset_op_t);
   2907 
   2908                 ret = ivd_cxa_api_function((iv_obj_t *)codec_obj, (void *)&s_ctl_ip,
   2909                                            (void *)&s_ctl_op);
   2910                 if(IV_SUCCESS != ret)
   2911                 {
   2912                     sprintf(ac_error_str, "Error in Reset");
   2913                     codec_exit(ac_error_str);
   2914                 }
   2915                 /*************************************************************************/
   2916                 /* set num of cores                                                      */
   2917                 /*************************************************************************/
   2918                 {
   2919 
   2920                     ihevcd_cxa_ctl_set_num_cores_ip_t s_ctl_set_cores_ip;
   2921                     ihevcd_cxa_ctl_set_num_cores_op_t s_ctl_set_cores_op;
   2922 
   2923                     s_ctl_set_cores_ip.e_cmd = IVD_CMD_VIDEO_CTL;
   2924                     s_ctl_set_cores_ip.e_sub_cmd = (IVD_CONTROL_API_COMMAND_TYPE_T)IHEVCD_CXA_CMD_CTL_SET_NUM_CORES;
   2925                     s_ctl_set_cores_ip.u4_num_cores = s_app_ctx.u4_num_cores;
   2926                     s_ctl_set_cores_ip.u4_size = sizeof(ihevcd_cxa_ctl_set_num_cores_ip_t);
   2927                     s_ctl_set_cores_op.u4_size = sizeof(ihevcd_cxa_ctl_set_num_cores_op_t);
   2928 
   2929                     ret = ivd_cxa_api_function((iv_obj_t *)codec_obj, (void *)&s_ctl_set_cores_ip,
   2930                                                (void *)&s_ctl_set_cores_op);
   2931                     if(ret != IV_SUCCESS)
   2932                     {
   2933                         sprintf(ac_error_str, "\nError in setting number of cores");
   2934                         codec_exit(ac_error_str);
   2935                     }
   2936 
   2937                 }
   2938                 /*************************************************************************/
   2939                 /* set processsor                                                        */
   2940                 /*************************************************************************/
   2941                 {
   2942 
   2943                     ihevcd_cxa_ctl_set_processor_ip_t s_ctl_set_num_processor_ip;
   2944                     ihevcd_cxa_ctl_set_processor_op_t s_ctl_set_num_processor_op;
   2945 
   2946                     s_ctl_set_num_processor_ip.e_cmd = IVD_CMD_VIDEO_CTL;
   2947                     s_ctl_set_num_processor_ip.e_sub_cmd = (IVD_CONTROL_API_COMMAND_TYPE_T)IHEVCD_CXA_CMD_CTL_SET_PROCESSOR;
   2948                     s_ctl_set_num_processor_ip.u4_arch = s_app_ctx.e_arch;
   2949                     s_ctl_set_num_processor_ip.u4_soc = s_app_ctx.e_soc;
   2950                     s_ctl_set_num_processor_ip.u4_size = sizeof(ihevcd_cxa_ctl_set_processor_ip_t);
   2951                     s_ctl_set_num_processor_op.u4_size = sizeof(ihevcd_cxa_ctl_set_processor_op_t);
   2952 
   2953                     ret = ivd_cxa_api_function((iv_obj_t *)codec_obj, (void *)&s_ctl_set_num_processor_ip,
   2954                                                (void *)&s_ctl_set_num_processor_op);
   2955                     if(ret != IV_SUCCESS)
   2956                     {
   2957                         sprintf(ac_error_str, "\nError in setting Processor type");
   2958                         codec_exit(ac_error_str);
   2959                     }
   2960 
   2961                 }
   2962             }
   2963 
   2964 
   2965             if((1 == s_app_ctx.display) &&
   2966                             (1 == s_video_decode_op.u4_output_present))
   2967             {
   2968                 dispq_producer_queue(&s_app_ctx);
   2969             }
   2970 
   2971             if(IV_B_FRAME == s_video_decode_op.e_pic_type)
   2972                 s_app_ctx.b_pic_present |= 1;
   2973 
   2974             u4_num_bytes_dec = s_video_decode_op.u4_num_bytes_consumed;
   2975 
   2976             file_pos += u4_num_bytes_dec;
   2977             total_bytes_comsumed += u4_num_bytes_dec;
   2978             u4_ip_frm_ts++;
   2979 
   2980 
   2981             if(1 == s_video_decode_op.u4_output_present)
   2982             {
   2983                 width = s_video_decode_op.s_disp_frm_buf.u4_y_wd;
   2984                 height = s_video_decode_op.s_disp_frm_buf.u4_y_ht;
   2985                 dump_output(&s_app_ctx, &(s_video_decode_op.s_disp_frm_buf),
   2986                             s_video_decode_op.u4_disp_buf_id, ps_op_file,
   2987                             ps_op_chksum_file,
   2988                             u4_op_frm_ts, s_app_ctx.u4_file_save_flag,
   2989                             s_app_ctx.u4_chksum_save_flag);
   2990 
   2991                 u4_op_frm_ts++;
   2992             }
   2993             else
   2994             {
   2995                 if((s_video_decode_op.u4_error_code >> IVD_FATALERROR) & 1)
   2996                 {
   2997                     printf("Fatal error\n");
   2998                     break;
   2999                 }
   3000             }
   3001 
   3002         }
   3003     }
   3004 
   3005     /***********************************************************************/
   3006     /*      To get the last decoded frames, call process with NULL input    */
   3007     /***********************************************************************/
   3008     flush_output(codec_obj, &s_app_ctx, ps_out_buf,
   3009                  pu1_bs_buf, &u4_op_frm_ts,
   3010                  ps_op_file, ps_op_chksum_file,
   3011                  u4_ip_frm_ts, u4_bytes_remaining);
   3012 
   3013     /* set disp_end flag */
   3014     s_app_ctx.quit = 1;
   3015 
   3016 
   3017 #ifdef PROFILE_ENABLE
   3018     printf("Summary\n");
   3019     printf("Input filename                  : %s\n", s_app_ctx.ac_ip_fname);
   3020     printf("Output Width                    : %-4d\n", width);
   3021     printf("Output Height                   : %-4d\n", height);
   3022 
   3023     if(frm_cnt)
   3024     {
   3025         double avg = u4_tot_cycles / frm_cnt;
   3026         double bytes_avg = total_bytes_comsumed / frm_cnt;
   3027         double bitrate = (bytes_avg * 8 * s_app_ctx.fps) / 1000000;
   3028         printf("Bitrate @ %2d fps(mbps)          : %-6.2f\n", s_app_ctx.fps, bitrate);
   3029         printf("Average decode time(micro sec)  : %-6d\n", (WORD32)avg);
   3030         printf("Avg Peak decode time(%2d frames) : %-6d\n", PEAK_WINDOW_SIZE, (WORD32)peak_avg_max);
   3031         avg = (u4_tot_cycles + u4_tot_fmt_cycles) * 1.0 / frm_cnt;
   3032 
   3033         if(0 == s_app_ctx.share_disp_buf)
   3034             printf("FPS achieved (with format conv) : %-3.2f\n", 1000000 / avg);
   3035         else
   3036             printf("FPS achieved                    : %-3.2f\n", 1000000 / avg);
   3037     }
   3038 #endif
   3039     /***********************************************************************/
   3040     /*   Clear the decoder, close all the files, free all the memory       */
   3041     /***********************************************************************/
   3042     if(1 == s_app_ctx.display)
   3043     {
   3044         s_app_ctx.display_deinit_flag = 1;
   3045         /* wait for display to finish */
   3046         if(s_app_ctx.display_thread_created)
   3047         {
   3048             ithread_join(s_app_ctx.display_thread_handle, NULL);
   3049         }
   3050         free(s_app_ctx.display_thread_handle);
   3051     }
   3052 
   3053     {
   3054         iv_retrieve_mem_rec_ip_t s_retrieve_dec_ip;
   3055         iv_retrieve_mem_rec_op_t s_retrieve_dec_op;
   3056         s_retrieve_dec_ip.pv_mem_rec_location = (iv_mem_rec_t *)pv_mem_rec_location;
   3057 
   3058         s_retrieve_dec_ip.e_cmd = IV_CMD_RETRIEVE_MEMREC;
   3059         s_retrieve_dec_ip.u4_size = sizeof(iv_retrieve_mem_rec_ip_t);
   3060         s_retrieve_dec_op.u4_size = sizeof(iv_retrieve_mem_rec_op_t);
   3061 
   3062         ret = ivd_cxa_api_function((iv_obj_t *)codec_obj, (void *)&s_retrieve_dec_ip,
   3063                                    (void *)&s_retrieve_dec_op);
   3064 
   3065         if(IV_SUCCESS != ret)
   3066         {
   3067             sprintf(ac_error_str, "Error in Retrieve Memrec");
   3068             codec_exit(ac_error_str);
   3069         }
   3070 
   3071         {
   3072             iv_mem_rec_t *ps_mem_rec;
   3073             UWORD16 u2_i;
   3074 
   3075             u4_num_mem_recs = s_retrieve_dec_op.u4_num_mem_rec_filled;
   3076 
   3077             ps_mem_rec = s_retrieve_dec_ip.pv_mem_rec_location;
   3078 
   3079             for(u2_i = 0; u2_i < u4_num_mem_recs; u2_i++)
   3080             {
   3081                 ihevca_aligned_free(ps_mem_rec->pv_base);
   3082                 ps_mem_rec++;
   3083             }
   3084             free(s_retrieve_dec_ip.pv_mem_rec_location);
   3085         }
   3086 
   3087     }
   3088     /***********************************************************************/
   3089     /*              Close all the files and free all the memory            */
   3090     /***********************************************************************/
   3091     {
   3092         fclose(ps_ip_file);
   3093 
   3094         if(1 == s_app_ctx.u4_file_save_flag)
   3095         {
   3096             fclose(ps_op_file);
   3097         }
   3098         if(1 == s_app_ctx.u4_chksum_save_flag)
   3099         {
   3100             fclose(ps_op_chksum_file);
   3101         }
   3102 
   3103     }
   3104 
   3105     if(0 == s_app_ctx.share_disp_buf)
   3106     {
   3107         free(ps_out_buf->pu1_bufs[0]);
   3108     }
   3109 
   3110     for(i = 0; i < s_app_ctx.num_disp_buf; i++)
   3111     {
   3112         free(s_app_ctx.s_disp_buffers[i].pu1_bufs[0]);
   3113     }
   3114 
   3115     free(ps_out_buf);
   3116     free(pu1_bs_buf);
   3117 
   3118     return (0);
   3119 }
   3120