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