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