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