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