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