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#if defined(GPU_BUILD) && !defined(X86)
1785//    int ioctl_init();
1786//    ioctl_init();
1787#endif
1788
1789#ifdef X86_MINGW
1790    //For getting printfs without any delay
1791    setvbuf(stdout, NULL, _IONBF, 0);
1792    setvbuf(stderr, NULL, _IONBF, 0);
1793#endif
1794#ifdef IOS
1795    sprintf(filename_trace, "%s/iostrace.txt", homedir);
1796    printf("\ntrace file name = %s", filename_trace);
1797#endif
1798
1799#ifdef X86_MINGW
1800    {
1801        signal(SIGSEGV, sigsegv_handler);
1802    }
1803#endif
1804
1805
1806#ifndef IOS
1807    /* Usage */
1808    if(argc < 2)
1809    {
1810        printf("Using test.cfg as configuration file \n");
1811        strcpy(ac_cfg_fname, "test.cfg");
1812    }
1813    else if(argc == 2)
1814    {
1815        strcpy(ac_cfg_fname, argv[1]);
1816    }
1817
1818#else
1819    strcpy(ac_cfg_fname, "test.cfg");
1820
1821#endif
1822
1823
1824    /***********************************************************************/
1825    /*                  Initialize Application parameters                  */
1826    /***********************************************************************/
1827
1828    strcpy(s_app_ctx.ac_ip_fname, "\0");
1829    s_app_ctx.dump_q_wr_idx = 0;
1830    s_app_ctx.dump_q_rd_idx = 0;
1831    s_app_ctx.display_thread_created = 0;
1832    s_app_ctx.disp_q_wr_idx = 0;
1833    s_app_ctx.disp_q_rd_idx = 0;
1834    s_app_ctx.disp_delay = 0;
1835    s_app_ctx.loopback = 0;
1836    s_app_ctx.display = 0;
1837    s_app_ctx.full_screen = 0;
1838    s_app_ctx.u4_piclen_flag = 0;
1839    s_app_ctx.fps = DEFAULT_FPS;
1840    file_pos = 0;
1841    total_bytes_comsumed = 0;
1842    u4_ip_frm_ts = 0;
1843    u4_op_frm_ts = 0;
1844#ifdef PROFILE_ENABLE
1845    memset(peak_window, 0, sizeof(WORD32) * PEAK_WINDOW_SIZE);
1846#endif
1847    s_app_ctx.share_disp_buf = DEFAULT_SHARE_DISPLAY_BUF;
1848    s_app_ctx.u4_num_cores = DEFAULT_NUM_CORES;
1849    s_app_ctx.i4_degrade_type = 0;
1850    s_app_ctx.i4_degrade_pics = 0;
1851    s_app_ctx.max_wd = 0;
1852    s_app_ctx.max_ht = 0;
1853    s_app_ctx.max_level = 0;
1854    s_app_ctx.e_arch = ARCH_ARM_A9Q;
1855    s_app_ctx.e_soc = SOC_GENERIC;
1856
1857    s_app_ctx.u4_strd = STRIDE;
1858
1859    s_app_ctx.display_thread_handle           = malloc(ithread_get_handle_size());
1860    s_app_ctx.quit          = 0;
1861    s_app_ctx.paused        = 0;
1862    //s_app_ctx.u4_output_present = 0;
1863
1864    s_app_ctx.get_stride = &default_get_stride;
1865
1866    s_app_ctx.get_color_fmt = &default_get_color_fmt;
1867
1868    /* Set function pointers for display */
1869#ifdef SDL_DISPLAY
1870    s_app_ctx.disp_init = &sdl_disp_init;
1871    s_app_ctx.alloc_disp_buffers = &sdl_alloc_disp_buffers;
1872    s_app_ctx.display_buffer = &sdl_display;
1873    s_app_ctx.set_disp_buffers = &sdl_set_disp_buffers;
1874    s_app_ctx.disp_deinit = &sdl_disp_deinit;
1875    s_app_ctx.disp_usleep = &sdl_disp_usleep;
1876    s_app_ctx.get_color_fmt = &sdl_get_color_fmt;
1877    s_app_ctx.get_stride = &sdl_get_stride;
1878#endif
1879
1880#ifdef FBDEV_DISPLAY
1881    s_app_ctx.disp_init = &fbd_disp_init;
1882    s_app_ctx.alloc_disp_buffers = &fbd_alloc_disp_buffers;
1883    s_app_ctx.display_buffer = &fbd_display;
1884    s_app_ctx.set_disp_buffers = &fbd_set_disp_buffers;
1885    s_app_ctx.disp_deinit = &fbd_disp_deinit;
1886    s_app_ctx.disp_usleep = &fbd_disp_usleep;
1887    s_app_ctx.get_color_fmt = &fbd_get_color_fmt;
1888    s_app_ctx.get_stride = &fbd_get_stride;
1889#endif
1890
1891#ifdef INTEL_CE5300
1892    s_app_ctx.disp_init = &gdl_disp_init;
1893    s_app_ctx.alloc_disp_buffers = &gdl_alloc_disp_buffers;
1894    s_app_ctx.display_buffer = &gdl_display;
1895    s_app_ctx.set_disp_buffers = &gdl_set_disp_buffers;
1896    s_app_ctx.disp_deinit = &gdl_disp_deinit;
1897    s_app_ctx.disp_usleep = &gdl_disp_usleep;
1898    s_app_ctx.get_color_fmt = &gdl_get_color_fmt;
1899    s_app_ctx.get_stride = &gdl_get_stride;
1900#endif
1901
1902#ifdef IOS_DISPLAY
1903    s_app_ctx.disp_init = &ios_disp_init;
1904    s_app_ctx.alloc_disp_buffers = &ios_alloc_disp_buffers;
1905    s_app_ctx.display_buffer = &ios_display;
1906    s_app_ctx.set_disp_buffers = &ios_set_disp_buffers;
1907    s_app_ctx.disp_deinit = &ios_disp_deinit;
1908    s_app_ctx.disp_usleep = &ios_disp_usleep;
1909    s_app_ctx.get_color_fmt = &ios_get_color_fmt;
1910    s_app_ctx.get_stride = &ios_get_stride;
1911#endif
1912
1913    s_app_ctx.display_deinit_flag = 0;
1914    s_app_ctx.e_output_chroma_format = IV_YUV_420SP_UV;
1915    /*************************************************************************/
1916    /* Parse arguments                                                       */
1917    /*************************************************************************/
1918
1919#ifndef IOS
1920    /* Read command line arguments */
1921    if(argc > 2)
1922    {
1923        for(i = 1; i < (UWORD32)argc; i += 2)
1924        {
1925            if(CONFIG == get_argument(argv[i]))
1926            {
1927                strcpy(ac_cfg_fname, argv[i + 1]);
1928                if((fp_cfg_file = fopen(ac_cfg_fname, "r")) == NULL)
1929                {
1930                    sprintf(ac_error_str, "Could not open Configuration file %s",
1931                            ac_cfg_fname);
1932                    codec_exit(ac_error_str);
1933                }
1934                read_cfg_file(&s_app_ctx, fp_cfg_file);
1935                fclose(fp_cfg_file);
1936            }
1937            else
1938            {
1939                parse_argument(&s_app_ctx, argv[i], argv[i + 1]);
1940            }
1941        }
1942    }
1943    else
1944    {
1945        if((fp_cfg_file = fopen(ac_cfg_fname, "r")) == NULL)
1946        {
1947            sprintf(ac_error_str, "Could not open Configuration file %s",
1948                    ac_cfg_fname);
1949            codec_exit(ac_error_str);
1950        }
1951        read_cfg_file(&s_app_ctx, fp_cfg_file);
1952        fclose(fp_cfg_file);
1953    }
1954#else
1955    sprintf(filename_with_path, "%s/%s", homedir, ac_cfg_fname);
1956    if((fp_cfg_file = fopen(filename_with_path, "r")) == NULL)
1957    {
1958        sprintf(ac_error_str, "Could not open Configuration file %s",
1959                ac_cfg_fname);
1960        codec_exit(ac_error_str);
1961
1962    }
1963    read_cfg_file(&s_app_ctx, fp_cfg_file);
1964    fclose(fp_cfg_file);
1965
1966#endif
1967#ifdef PRINT_PICSIZE
1968    /* If the binary is used for only getting number of bytes in each picture, then disable the following features */
1969    s_app_ctx.u4_piclen_flag = 0;
1970    s_app_ctx.u4_file_save_flag = 0;
1971    s_app_ctx.u4_chksum_save_flag = 0;
1972    s_app_ctx.i4_degrade_pics = 0;
1973    s_app_ctx.i4_degrade_type = 0;
1974    s_app_ctx.loopback = 0;
1975    s_app_ctx.share_disp_buf = 0;
1976    s_app_ctx.display = 0;
1977#endif
1978
1979    /* If display is enabled, then turn off shared mode and get color format that is supported by display */
1980    if(1 == s_app_ctx.display)
1981    {
1982        s_app_ctx.share_disp_buf = 0;
1983        s_app_ctx.e_output_chroma_format = s_app_ctx.get_color_fmt();
1984    }
1985    if(strcmp(s_app_ctx.ac_ip_fname, "\0") == 0)
1986    {
1987        printf("\nNo input file given for decoding\n");
1988        exit(-1);
1989    }
1990
1991
1992    /***********************************************************************/
1993    /*          create the file object for input file                      */
1994    /***********************************************************************/
1995#ifdef IOS
1996    sprintf(filename_with_path, "%s/%s", homedir, s_app_ctx.ac_ip_fname);
1997    ps_ip_file = fopen(filename_with_path, "rb");
1998#else
1999    ps_ip_file = fopen(s_app_ctx.ac_ip_fname, "rb");
2000#endif
2001    if(NULL == ps_ip_file)
2002    {
2003        sprintf(ac_error_str, "Could not open input file %s",
2004                s_app_ctx.ac_ip_fname);
2005        codec_exit(ac_error_str);
2006    }
2007    /***********************************************************************/
2008    /*          create the file object for input file                      */
2009    /***********************************************************************/
2010    if(1 == s_app_ctx.u4_piclen_flag)
2011    {
2012#ifdef IOS
2013        sprintf(filename_with_path, "%s/%s", homedir, s_app_ctx.ac_piclen_fname);
2014        ps_piclen_file = fopen(filename_with_path, "rb");
2015#else
2016        ps_piclen_file = fopen(s_app_ctx.ac_piclen_fname, "rb");
2017#endif
2018        if(NULL == ps_piclen_file)
2019        {
2020            sprintf(ac_error_str, "Could not open piclen file %s",
2021                    s_app_ctx.ac_piclen_fname);
2022            codec_exit(ac_error_str);
2023        }
2024    }
2025
2026    /***********************************************************************/
2027    /*          create the file object for output file                     */
2028    /***********************************************************************/
2029    if(1 == s_app_ctx.u4_file_save_flag)
2030    {
2031#ifdef IOS
2032        sprintf(filename_with_path, "%s/%s", documentdir, s_app_ctx.ac_op_fname);
2033        ps_op_file = fopen(filename_with_path, "wb");
2034#else
2035        ps_op_file = fopen(s_app_ctx.ac_op_fname, "wb");
2036#endif
2037
2038        if(NULL == ps_op_file)
2039        {
2040            sprintf(ac_error_str, "Could not open output file %s",
2041                    s_app_ctx.ac_op_fname);
2042            codec_exit(ac_error_str);
2043        }
2044    }
2045
2046    /***********************************************************************/
2047    /*          create the file object for check sum file                  */
2048    /***********************************************************************/
2049    if(1 == s_app_ctx.u4_chksum_save_flag)
2050    {
2051#if IOS
2052        sprintf(filename_with_path, "%s/%s", documentdir, s_app_ctx.ac_op_chksum_fname);
2053        ps_op_chksum_file = fopen(filename_with_path, "wb");
2054#else
2055        ps_op_chksum_file = fopen(s_app_ctx.ac_op_chksum_fname, "wb");
2056#endif
2057        if(NULL == ps_op_chksum_file)
2058        {
2059            sprintf(ac_error_str, "Could not open check sum file %s",
2060                    s_app_ctx.ac_op_chksum_fname);
2061            codec_exit(ac_error_str);
2062        }
2063    }
2064    /***********************************************************************/
2065    /*                      Create decoder instance                        */
2066    /***********************************************************************/
2067    {
2068
2069        ps_out_buf = (ivd_out_bufdesc_t *)malloc(sizeof(ivd_out_bufdesc_t));
2070
2071        {
2072            iv_num_mem_rec_ip_t s_no_of_mem_rec_query_ip;
2073            iv_num_mem_rec_op_t s_no_of_mem_rec_query_op;
2074
2075            s_no_of_mem_rec_query_ip.u4_size = sizeof(s_no_of_mem_rec_query_ip);
2076            s_no_of_mem_rec_query_op.u4_size = sizeof(s_no_of_mem_rec_query_op);
2077            s_no_of_mem_rec_query_ip.e_cmd = IV_CMD_GET_NUM_MEM_REC;
2078
2079            /*****************************************************************************/
2080            /*   API Call: Get Number of Mem Records                                     */
2081            /*****************************************************************************/
2082            e_dec_status = ivd_cxa_api_function(
2083                            NULL, (void *)&s_no_of_mem_rec_query_ip,
2084                            (void *)&s_no_of_mem_rec_query_op);
2085            if(IV_SUCCESS != e_dec_status)
2086            {
2087                sprintf(ac_error_str, "Error in get mem records");
2088                codec_exit(ac_error_str);
2089            }
2090
2091            u4_num_mem_recs = s_no_of_mem_rec_query_op.u4_num_mem_rec;
2092        }
2093
2094        pv_mem_rec_location = malloc(u4_num_mem_recs * sizeof(iv_mem_rec_t));
2095        if(pv_mem_rec_location == NULL)
2096        {
2097            sprintf(ac_error_str, "Allocation failure for mem_rec_location");
2098            codec_exit(ac_error_str);
2099
2100        }
2101
2102        {
2103            ihevcd_cxa_fill_mem_rec_ip_t s_fill_mem_rec_ip;
2104            ihevcd_cxa_fill_mem_rec_op_t s_fill_mem_rec_op;
2105            iv_mem_rec_t *ps_mem_rec;
2106            UWORD32 total_size;
2107
2108            s_fill_mem_rec_ip.s_ivd_fill_mem_rec_ip_t.e_cmd =
2109                            IV_CMD_FILL_NUM_MEM_REC;
2110            s_fill_mem_rec_ip.s_ivd_fill_mem_rec_ip_t.pv_mem_rec_location =
2111                            (iv_mem_rec_t *)pv_mem_rec_location;
2112            s_fill_mem_rec_ip.s_ivd_fill_mem_rec_ip_t.u4_max_frm_wd =
2113                            (s_app_ctx.max_wd == 0) ? MAX_FRAME_WIDTH : s_app_ctx.max_wd;
2114            s_fill_mem_rec_ip.s_ivd_fill_mem_rec_ip_t.u4_max_frm_ht =
2115                            (s_app_ctx.max_ht == 0) ? MAX_FRAME_HEIGHT : s_app_ctx.max_ht;
2116            s_fill_mem_rec_ip.i4_level = (s_app_ctx.max_level == 0) ? MAX_LEVEL_SUPPORTED : s_app_ctx.max_level;
2117            s_fill_mem_rec_ip.u4_num_ref_frames = MAX_REF_FRAMES;
2118            s_fill_mem_rec_ip.u4_num_reorder_frames = MAX_REORDER_FRAMES;
2119            s_fill_mem_rec_ip.u4_share_disp_buf = s_app_ctx.share_disp_buf;
2120            s_fill_mem_rec_ip.e_output_format =
2121                            (IV_COLOR_FORMAT_T)s_app_ctx.e_output_chroma_format;
2122            s_fill_mem_rec_ip.u4_num_extra_disp_buf = EXTRA_DISP_BUFFERS;
2123
2124            s_fill_mem_rec_ip.s_ivd_fill_mem_rec_ip_t.u4_size =
2125                            sizeof(ihevcd_cxa_fill_mem_rec_ip_t);
2126            s_fill_mem_rec_op.s_ivd_fill_mem_rec_op_t.u4_size =
2127                            sizeof(ihevcd_cxa_fill_mem_rec_op_t);
2128
2129            ps_mem_rec = (iv_mem_rec_t *)pv_mem_rec_location;
2130            for(i = 0; i < u4_num_mem_recs; i++)
2131                ps_mem_rec[i].u4_size = sizeof(iv_mem_rec_t);
2132
2133            /*****************************************************************************/
2134            /*   API Call: Fill Mem Records                                     */
2135            /*****************************************************************************/
2136
2137            e_dec_status = ivd_cxa_api_function(NULL,
2138                                                (void *)&s_fill_mem_rec_ip,
2139                                                (void *)&s_fill_mem_rec_op);
2140
2141            u4_num_mem_recs =
2142                            s_fill_mem_rec_op.s_ivd_fill_mem_rec_op_t.u4_num_mem_rec_filled;
2143
2144            if(IV_SUCCESS != e_dec_status)
2145            {
2146                sprintf(ac_error_str, "Error in fill mem records: %x", s_fill_mem_rec_op.s_ivd_fill_mem_rec_op_t.u4_error_code);
2147                codec_exit(ac_error_str);
2148            }
2149
2150            ps_mem_rec = (iv_mem_rec_t *)pv_mem_rec_location;
2151            total_size = 0;
2152            for(i = 0; i < u4_num_mem_recs; i++)
2153            {
2154                ps_mem_rec->pv_base = ihevca_aligned_malloc(ps_mem_rec->u4_mem_alignment,
2155                                                            ps_mem_rec->u4_mem_size);
2156                if(ps_mem_rec->pv_base == NULL)
2157                {
2158                    sprintf(ac_error_str,
2159                            "\nAllocation failure for mem record id %d size %d\n",
2160                            i, ps_mem_rec->u4_mem_size);
2161                    codec_exit(ac_error_str);
2162
2163                }
2164                total_size += ps_mem_rec->u4_mem_size;
2165
2166                ps_mem_rec++;
2167            }
2168            //printf("\nTotal memory for codec %d\n", total_size);
2169        }
2170        /*****************************************************************************/
2171        /*   API Call: Initialize the Decoder                                        */
2172        /*****************************************************************************/
2173        {
2174            ihevcd_cxa_init_ip_t s_init_ip;
2175            ihevcd_cxa_init_op_t s_init_op;
2176            void *fxns = &ivd_cxa_api_function;
2177            iv_mem_rec_t *mem_tab;
2178
2179            mem_tab = (iv_mem_rec_t *)pv_mem_rec_location;
2180            s_init_ip.s_ivd_init_ip_t.e_cmd = (IVD_API_COMMAND_TYPE_T)IV_CMD_INIT;
2181            s_init_ip.s_ivd_init_ip_t.pv_mem_rec_location = mem_tab;
2182            s_init_ip.s_ivd_init_ip_t.u4_frm_max_wd = (s_app_ctx.max_wd == 0) ? MAX_FRAME_WIDTH : s_app_ctx.max_wd;
2183            s_init_ip.s_ivd_init_ip_t.u4_frm_max_ht = (s_app_ctx.max_ht == 0) ? MAX_FRAME_HEIGHT : s_app_ctx.max_ht;
2184            s_init_ip.i4_level = (s_app_ctx.max_level == 0) ? MAX_LEVEL_SUPPORTED : s_app_ctx.max_level;
2185            s_init_ip.u4_num_ref_frames = MAX_REF_FRAMES;
2186            s_init_ip.u4_num_reorder_frames = MAX_REORDER_FRAMES;
2187            s_init_ip.u4_share_disp_buf = s_app_ctx.share_disp_buf;
2188            s_init_ip.u4_num_extra_disp_buf = EXTRA_DISP_BUFFERS;
2189            s_init_ip.s_ivd_init_ip_t.u4_num_mem_rec = u4_num_mem_recs;
2190            s_init_ip.s_ivd_init_ip_t.e_output_format =
2191                            (IV_COLOR_FORMAT_T)s_app_ctx.e_output_chroma_format;
2192            s_init_ip.s_ivd_init_ip_t.u4_size = sizeof(ihevcd_cxa_init_ip_t);
2193            s_init_op.s_ivd_init_op_t.u4_size = sizeof(ihevcd_cxa_init_op_t);
2194
2195            codec_obj = (iv_obj_t *)mem_tab[0].pv_base;
2196            codec_obj->pv_fxns = fxns;
2197            codec_obj->u4_size = sizeof(iv_obj_t);
2198
2199            s_app_ctx.cocodec_obj = codec_obj;
2200
2201            ret = ivd_cxa_api_function((iv_obj_t *)codec_obj, (void *)&s_init_ip,
2202                                       (void *)&s_init_op);
2203            if(ret != IV_SUCCESS)
2204            {
2205                sprintf(ac_error_str, "Error in Init %8x\n",
2206                        s_init_op.s_ivd_init_op_t.u4_error_code);
2207                codec_exit(ac_error_str);
2208            }
2209
2210            /*****************************************************************************/
2211            /*  Input and output buffer allocation                                       */
2212            /*****************************************************************************/
2213            {
2214
2215                ivd_ctl_getbufinfo_ip_t s_ctl_ip;
2216                ivd_ctl_getbufinfo_op_t s_ctl_op;
2217
2218                s_ctl_ip.e_cmd = IVD_CMD_VIDEO_CTL;
2219                s_ctl_ip.e_sub_cmd = IVD_CMD_CTL_GETBUFINFO;
2220                s_ctl_ip.u4_size = sizeof(ivd_ctl_getbufinfo_ip_t);
2221                s_ctl_op.u4_size = sizeof(ivd_ctl_getbufinfo_op_t);
2222                ret = ivd_cxa_api_function((iv_obj_t *)codec_obj, (void *)&s_ctl_ip,
2223                                           (void *)&s_ctl_op);
2224                if(ret != IV_SUCCESS)
2225                {
2226                    sprintf(ac_error_str, "Error in Get Buf Info %x", s_ctl_op.u4_error_code);
2227                    codec_exit(ac_error_str);
2228                }
2229
2230                /* Allocate input buffer */
2231                u4_ip_buf_len = s_ctl_op.u4_min_in_buf_size[0];
2232                pu1_bs_buf = (UWORD8 *)malloc(u4_ip_buf_len);
2233
2234                if(pu1_bs_buf == NULL)
2235                {
2236                    sprintf(ac_error_str,
2237                            "\nAllocation failure for input buffer of size %d",
2238                            u4_ip_buf_len);
2239                    codec_exit(ac_error_str);
2240                }
2241                s_app_ctx.num_disp_buf = s_ctl_op.u4_num_disp_bufs;
2242                /* Allocate output buffer only if display buffers are not shared */
2243                /* Or if shared and output is 420P */
2244                if((0 == s_app_ctx.share_disp_buf) || (IV_YUV_420P == s_app_ctx.e_output_chroma_format))
2245                {
2246                    UWORD32 outlen;
2247                    ps_out_buf->u4_min_out_buf_size[0] =
2248                                    s_ctl_op.u4_min_out_buf_size[0];
2249                    ps_out_buf->u4_min_out_buf_size[1] =
2250                                    s_ctl_op.u4_min_out_buf_size[1];
2251                    ps_out_buf->u4_min_out_buf_size[2] =
2252                                    s_ctl_op.u4_min_out_buf_size[2];
2253
2254                    outlen = s_ctl_op.u4_min_out_buf_size[0];
2255                    if(s_ctl_op.u4_min_num_out_bufs > 1)
2256                        outlen += s_ctl_op.u4_min_out_buf_size[1];
2257
2258                    if(s_ctl_op.u4_min_num_out_bufs > 2)
2259                        outlen += s_ctl_op.u4_min_out_buf_size[2];
2260
2261                    ps_out_buf->pu1_bufs[0] = (UWORD8 *)malloc(outlen);
2262                    if(ps_out_buf->pu1_bufs[0] == NULL)
2263                    {
2264                        sprintf(ac_error_str,
2265                                "\nAllocation failure for output buffer of size %d",
2266                                outlen);
2267                        codec_exit(ac_error_str);
2268                    }
2269
2270                    if(s_ctl_op.u4_min_num_out_bufs > 1)
2271                        ps_out_buf->pu1_bufs[1] = ps_out_buf->pu1_bufs[0]
2272                                        + (s_ctl_op.u4_min_out_buf_size[0]);
2273
2274                    if(s_ctl_op.u4_min_num_out_bufs > 2)
2275                        ps_out_buf->pu1_bufs[2] = ps_out_buf->pu1_bufs[1]
2276                                        + (s_ctl_op.u4_min_out_buf_size[1]);
2277
2278                    ps_out_buf->u4_num_bufs = s_ctl_op.u4_min_num_out_bufs;
2279                }
2280
2281            }
2282        }
2283
2284    }
2285
2286
2287    /*************************************************************************/
2288    /* set num of cores                                                      */
2289    /*************************************************************************/
2290    {
2291
2292        ihevcd_cxa_ctl_set_num_cores_ip_t s_ctl_set_cores_ip;
2293        ihevcd_cxa_ctl_set_num_cores_op_t s_ctl_set_cores_op;
2294
2295        s_ctl_set_cores_ip.e_cmd = IVD_CMD_VIDEO_CTL;
2296        s_ctl_set_cores_ip.e_sub_cmd = (IVD_CONTROL_API_COMMAND_TYPE_T)IHEVCD_CXA_CMD_CTL_SET_NUM_CORES;
2297        s_ctl_set_cores_ip.u4_num_cores = s_app_ctx.u4_num_cores;
2298        s_ctl_set_cores_ip.u4_size = sizeof(ihevcd_cxa_ctl_set_num_cores_ip_t);
2299        s_ctl_set_cores_op.u4_size = sizeof(ihevcd_cxa_ctl_set_num_cores_op_t);
2300
2301        ret = ivd_cxa_api_function((iv_obj_t *)codec_obj, (void *)&s_ctl_set_cores_ip,
2302                                   (void *)&s_ctl_set_cores_op);
2303        if(ret != IV_SUCCESS)
2304        {
2305            sprintf(ac_error_str, "\nError in setting number of cores");
2306            codec_exit(ac_error_str);
2307        }
2308
2309    }
2310    /*************************************************************************/
2311    /* set processsor                                                        */
2312    /*************************************************************************/
2313    {
2314
2315        ihevcd_cxa_ctl_set_processor_ip_t s_ctl_set_num_processor_ip;
2316        ihevcd_cxa_ctl_set_processor_op_t s_ctl_set_num_processor_op;
2317
2318        s_ctl_set_num_processor_ip.e_cmd = IVD_CMD_VIDEO_CTL;
2319        s_ctl_set_num_processor_ip.e_sub_cmd = (IVD_CONTROL_API_COMMAND_TYPE_T)IHEVCD_CXA_CMD_CTL_SET_PROCESSOR;
2320        s_ctl_set_num_processor_ip.u4_arch = s_app_ctx.e_arch;
2321        s_ctl_set_num_processor_ip.u4_soc = s_app_ctx.e_soc;
2322        s_ctl_set_num_processor_ip.u4_size = sizeof(ihevcd_cxa_ctl_set_processor_ip_t);
2323        s_ctl_set_num_processor_op.u4_size = sizeof(ihevcd_cxa_ctl_set_processor_op_t);
2324
2325        ret = ivd_cxa_api_function((iv_obj_t *)codec_obj, (void *)&s_ctl_set_num_processor_ip,
2326                                   (void *)&s_ctl_set_num_processor_op);
2327        if(ret != IV_SUCCESS)
2328        {
2329            sprintf(ac_error_str, "\nError in setting Processor type");
2330            codec_exit(ac_error_str);
2331        }
2332
2333    }
2334
2335
2336    /*****************************************************************************/
2337    /*   Decode header to get width and height and buffer sizes                  */
2338    /*****************************************************************************/
2339    {
2340
2341        ivd_ctl_set_config_ip_t s_ctl_ip;
2342        ivd_ctl_set_config_op_t s_ctl_op;
2343
2344        ivd_video_decode_ip_t s_video_decode_ip;
2345        ivd_video_decode_op_t s_video_decode_op;
2346
2347        s_ctl_ip.u4_disp_wd = STRIDE;
2348        if(1 == s_app_ctx.display)
2349            s_ctl_ip.u4_disp_wd = s_app_ctx.get_stride();
2350
2351        s_ctl_ip.e_frm_skip_mode = IVD_SKIP_NONE;
2352        s_ctl_ip.e_frm_out_mode = IVD_DISPLAY_FRAME_OUT;
2353        s_ctl_ip.e_vid_dec_mode = IVD_DECODE_HEADER;
2354        s_ctl_ip.e_cmd = IVD_CMD_VIDEO_CTL;
2355        s_ctl_ip.e_sub_cmd = IVD_CMD_CTL_SETPARAMS;
2356        s_ctl_ip.u4_size = sizeof(ivd_ctl_set_config_ip_t);
2357        s_ctl_op.u4_size = sizeof(ivd_ctl_set_config_op_t);
2358
2359        ret = ivd_cxa_api_function((iv_obj_t *)codec_obj, (void *)&s_ctl_ip,
2360                                   (void *)&s_ctl_op);
2361        if(ret != IV_SUCCESS)
2362        {
2363            sprintf(ac_error_str,
2364                    "\nError in setting the codec in header decode mode");
2365            codec_exit(ac_error_str);
2366        }
2367
2368        do
2369        {
2370            WORD32 numbytes;
2371            if(0 == s_app_ctx.u4_piclen_flag)
2372            {
2373                fseek(ps_ip_file, file_pos, SEEK_SET);
2374                numbytes = u4_ip_buf_len;
2375            }
2376            else
2377            {
2378                WORD32 entries;
2379                entries = fscanf(ps_piclen_file, "%d\n", &numbytes);
2380                if(1 != entries)
2381                    numbytes = u4_ip_buf_len;
2382            }
2383
2384            u4_bytes_remaining = fread(pu1_bs_buf, sizeof(UWORD8), numbytes,
2385                                       ps_ip_file);
2386
2387            if(0 == u4_bytes_remaining)
2388            {
2389                sprintf(ac_error_str, "\nUnable to read from input file");
2390                codec_exit(ac_error_str);
2391            }
2392
2393            s_video_decode_ip.e_cmd = IVD_CMD_VIDEO_DECODE;
2394            s_video_decode_ip.u4_ts = u4_ip_frm_ts;
2395            s_video_decode_ip.pv_stream_buffer = pu1_bs_buf;
2396            s_video_decode_ip.u4_num_Bytes = u4_bytes_remaining;
2397            s_video_decode_ip.u4_size = sizeof(ivd_video_decode_ip_t);
2398            s_video_decode_op.u4_size = sizeof(ivd_video_decode_op_t);
2399
2400            /*****************************************************************************/
2401            /*   API Call: Header Decode                                                  */
2402            /*****************************************************************************/
2403            ret = ivd_cxa_api_function((iv_obj_t *)codec_obj, (void *)&s_video_decode_ip,
2404                                       (void *)&s_video_decode_op);
2405
2406            if(ret != IV_SUCCESS)
2407            {
2408                sprintf(ac_error_str, "\nError in header decode %x",
2409                        s_video_decode_op.u4_error_code);
2410                // codec_exit(ac_error_str);
2411            }
2412
2413            u4_num_bytes_dec = s_video_decode_op.u4_num_bytes_consumed;
2414#ifndef PROFILE_ENABLE
2415            printf("%d\n", s_video_decode_op.u4_num_bytes_consumed);
2416#endif
2417            file_pos += u4_num_bytes_dec;
2418            total_bytes_comsumed += u4_num_bytes_dec;
2419        }while(ret != IV_SUCCESS);
2420
2421        /* copy pic_wd and pic_ht to initialize buffers */
2422        s_app_ctx.u4_pic_wd = s_video_decode_op.u4_pic_wd;
2423        s_app_ctx.u4_pic_ht = s_video_decode_op.u4_pic_ht;
2424
2425#if IOS_DISPLAY
2426        s_app_ctx.i4_screen_wd = screen_wd;
2427        s_app_ctx.i4_screen_ht = screen_ht;
2428#endif
2429
2430        /* Create display thread and wait for the display buffers to be initialized */
2431        if(1 == s_app_ctx.display)
2432        {
2433            if(0 == s_app_ctx.display_thread_created)
2434            {
2435                s_app_ctx.display_init_done = 0;
2436                ithread_create(s_app_ctx.display_thread_handle, NULL,
2437                               (void *)&display_thread, (void *)&s_app_ctx);
2438                s_app_ctx.display_thread_created = 1;
2439
2440                while(1)
2441                {
2442                    if(s_app_ctx.display_init_done)
2443                        break;
2444
2445                    ithread_msleep(1);
2446                }
2447            }
2448
2449            s_app_ctx.u4_strd = s_app_ctx.get_stride();
2450        }
2451    }
2452
2453    /*************************************************************************/
2454    /* Get actual number of output buffers requried, which is dependent      */
2455    /* on stream properties such as width, height and level etc              */
2456    /* This is needed mainly for shared display mode                         */
2457    /*************************************************************************/
2458    //if(1 == s_app_ctx.share_disp_buf)
2459    {
2460        ivd_ctl_getbufinfo_ip_t s_ctl_ip;
2461        ivd_ctl_getbufinfo_op_t s_ctl_op;
2462        WORD32 outlen = 0;
2463
2464        s_ctl_ip.e_cmd = IVD_CMD_VIDEO_CTL;
2465        s_ctl_ip.e_sub_cmd = IVD_CMD_CTL_GETBUFINFO;
2466        s_ctl_ip.u4_size = sizeof(ivd_ctl_getbufinfo_ip_t);
2467        s_ctl_op.u4_size = sizeof(ivd_ctl_getbufinfo_op_t);
2468        ret = ivd_cxa_api_function((iv_obj_t *)codec_obj, (void *)&s_ctl_ip,
2469                                   (void *)&s_ctl_op);
2470        if(ret != IV_SUCCESS)
2471        {
2472            sprintf(ac_error_str, "Error in Get Buf Info %x", s_ctl_op.u4_error_code);
2473            codec_exit(ac_error_str);
2474        }
2475
2476#ifdef APP_EXTRA_BUFS
2477        s_app_ctx.disp_delay = EXTRA_DISP_BUFFERS;
2478        s_ctl_op.u4_num_disp_bufs += EXTRA_DISP_BUFFERS;
2479#endif
2480
2481        /*****************************************************************************/
2482        /*   API Call: Allocate display buffers for display buffer shared case       */
2483        /*****************************************************************************/
2484
2485        for(i = 0; i < s_ctl_op.u4_num_disp_bufs; i++)
2486        {
2487
2488            s_app_ctx.s_disp_buffers[i].u4_min_out_buf_size[0] =
2489                            s_ctl_op.u4_min_out_buf_size[0];
2490            s_app_ctx.s_disp_buffers[i].u4_min_out_buf_size[1] =
2491                            s_ctl_op.u4_min_out_buf_size[1];
2492            s_app_ctx.s_disp_buffers[i].u4_min_out_buf_size[2] =
2493                            s_ctl_op.u4_min_out_buf_size[2];
2494
2495            outlen = s_ctl_op.u4_min_out_buf_size[0];
2496            if(s_ctl_op.u4_min_num_out_bufs > 1)
2497                outlen += s_ctl_op.u4_min_out_buf_size[1];
2498
2499            if(s_ctl_op.u4_min_num_out_bufs > 2)
2500                outlen += s_ctl_op.u4_min_out_buf_size[2];
2501
2502            s_app_ctx.s_disp_buffers[i].pu1_bufs[0] = (UWORD8 *)malloc(outlen);
2503
2504            if(s_app_ctx.s_disp_buffers[i].pu1_bufs[0] == NULL)
2505            {
2506                sprintf(ac_error_str,
2507                        "\nAllocation failure for output buffer of size %d",
2508                        outlen);
2509                codec_exit(ac_error_str);
2510            }
2511
2512            if(s_ctl_op.u4_min_num_out_bufs > 1)
2513                s_app_ctx.s_disp_buffers[i].pu1_bufs[1] =
2514                                s_app_ctx.s_disp_buffers[i].pu1_bufs[0]
2515                                                + (s_ctl_op.u4_min_out_buf_size[0]);
2516
2517            if(s_ctl_op.u4_min_num_out_bufs > 2)
2518                s_app_ctx.s_disp_buffers[i].pu1_bufs[2] =
2519                                s_app_ctx.s_disp_buffers[i].pu1_bufs[1]
2520                                                + (s_ctl_op.u4_min_out_buf_size[1]);
2521
2522            s_app_ctx.s_disp_buffers[i].u4_num_bufs =
2523                            s_ctl_op.u4_min_num_out_bufs;
2524        }
2525        s_app_ctx.num_disp_buf = s_ctl_op.u4_num_disp_bufs;
2526
2527        /*****************************************************************************/
2528        /*   API Call: Send the allocated display buffers to codec                   */
2529        /*****************************************************************************/
2530        {
2531            ivd_set_display_frame_ip_t s_set_display_frame_ip;
2532            ivd_set_display_frame_op_t s_set_display_frame_op;
2533
2534            s_set_display_frame_ip.e_cmd = IVD_CMD_SET_DISPLAY_FRAME;
2535            s_set_display_frame_ip.u4_size = sizeof(ivd_set_display_frame_ip_t);
2536            s_set_display_frame_op.u4_size = sizeof(ivd_set_display_frame_op_t);
2537
2538            s_set_display_frame_ip.num_disp_bufs = s_app_ctx.num_disp_buf;
2539
2540            memcpy(&(s_set_display_frame_ip.s_disp_buffer),
2541                   &(s_app_ctx.s_disp_buffers),
2542                   s_ctl_op.u4_num_disp_bufs * sizeof(ivd_out_bufdesc_t));
2543
2544            ret = ivd_cxa_api_function((iv_obj_t *)codec_obj,
2545                                       (void *)&s_set_display_frame_ip,
2546                                       (void *)&s_set_display_frame_op);
2547
2548            if(IV_SUCCESS != ret)
2549            {
2550                sprintf(ac_error_str, "Error in Set display frame");
2551                codec_exit(ac_error_str);
2552            }
2553
2554        }
2555
2556    }
2557
2558    /*************************************************************************/
2559    /* Get frame dimensions for display buffers such as x_offset,y_offset    */
2560    /* etc. This information might be needed to set display buffer           */
2561    /* offsets in case of shared display buffer mode                         */
2562    /*************************************************************************/
2563    {
2564
2565        ihevcd_cxa_ctl_get_frame_dimensions_ip_t s_ctl_get_frame_dimensions_ip;
2566        ihevcd_cxa_ctl_get_frame_dimensions_op_t s_ctl_get_frame_dimensions_op;
2567
2568        s_ctl_get_frame_dimensions_ip.e_cmd = IVD_CMD_VIDEO_CTL;
2569        s_ctl_get_frame_dimensions_ip.e_sub_cmd =
2570                        (IVD_CONTROL_API_COMMAND_TYPE_T)IHEVCD_CXA_CMD_CTL_GET_BUFFER_DIMENSIONS;
2571        s_ctl_get_frame_dimensions_ip.u4_size =
2572                        sizeof(ihevcd_cxa_ctl_get_frame_dimensions_ip_t);
2573        s_ctl_get_frame_dimensions_op.u4_size =
2574                        sizeof(ihevcd_cxa_ctl_get_frame_dimensions_op_t);
2575
2576        ret = ivd_cxa_api_function((iv_obj_t *)codec_obj, (void *)&s_ctl_get_frame_dimensions_ip,
2577                                   (void *)&s_ctl_get_frame_dimensions_op);
2578        if(IV_SUCCESS != ret)
2579        {
2580            sprintf(ac_error_str, "Error in Get buffer Dimensions");
2581            codec_exit(ac_error_str);
2582        }
2583
2584/*
2585        printf("Frame offsets due to padding\n");
2586        printf("s_ctl_get_frame_dimensions_op.x_offset[0] %d s_ctl_get_frame_dimensions_op.y_offset[0] %d\n",
2587               s_ctl_get_frame_dimensions_op.u4_x_offset[0],
2588               s_ctl_get_frame_dimensions_op.u4_y_offset[0]);
2589*/
2590    }
2591
2592
2593    /*************************************************************************/
2594    /* Get VUI parameters                                                    */
2595    /*************************************************************************/
2596    {
2597
2598        ihevcd_cxa_ctl_get_vui_params_ip_t s_ctl_get_vui_params_ip;
2599        ihevcd_cxa_ctl_get_vui_params_op_t s_ctl_get_vui_params_op;
2600
2601        s_ctl_get_vui_params_ip.e_cmd = IVD_CMD_VIDEO_CTL;
2602        s_ctl_get_vui_params_ip.e_sub_cmd =
2603                        (IVD_CONTROL_API_COMMAND_TYPE_T)IHEVCD_CXA_CMD_CTL_GET_VUI_PARAMS;
2604        s_ctl_get_vui_params_ip.u4_size =
2605                        sizeof(ihevcd_cxa_ctl_get_vui_params_ip_t);
2606        s_ctl_get_vui_params_op.u4_size =
2607                        sizeof(ihevcd_cxa_ctl_get_vui_params_op_t);
2608
2609        ret = ivd_cxa_api_function((iv_obj_t *)codec_obj, (void *)&s_ctl_get_vui_params_ip,
2610                                   (void *)&s_ctl_get_vui_params_op);
2611        if(IV_SUCCESS != ret)
2612        {
2613            sprintf(ac_error_str, "Error in Get VUI params");
2614            //codec_exit(ac_error_str);
2615        }
2616
2617    }
2618
2619
2620    /*************************************************************************/
2621    /* Set the decoder in frame decode mode. It was set in header decode     */
2622    /* mode earlier                                                          */
2623    /*************************************************************************/
2624    {
2625
2626        ivd_ctl_set_config_ip_t s_ctl_ip;
2627        ivd_ctl_set_config_op_t s_ctl_op;
2628
2629        s_ctl_ip.u4_disp_wd = STRIDE;
2630        if(1 == s_app_ctx.display)
2631            s_ctl_ip.u4_disp_wd = s_app_ctx.get_stride();
2632        s_ctl_ip.e_frm_skip_mode = IVD_SKIP_NONE;
2633
2634        s_ctl_ip.e_frm_out_mode = IVD_DISPLAY_FRAME_OUT;
2635        s_ctl_ip.e_vid_dec_mode = IVD_DECODE_FRAME;
2636        s_ctl_ip.e_cmd = IVD_CMD_VIDEO_CTL;
2637        s_ctl_ip.e_sub_cmd = IVD_CMD_CTL_SETPARAMS;
2638        s_ctl_ip.u4_size = sizeof(ivd_ctl_set_config_ip_t);
2639
2640        s_ctl_op.u4_size = sizeof(ivd_ctl_set_config_op_t);
2641
2642        ret = ivd_cxa_api_function((iv_obj_t *)codec_obj, (void *)&s_ctl_ip, (void *)&s_ctl_op);
2643
2644        if(IV_SUCCESS != ret)
2645        {
2646            sprintf(ac_error_str, "Error in Set Parameters");
2647            //codec_exit(ac_error_str);
2648        }
2649
2650    }
2651    /*************************************************************************/
2652    /* If required disable deblocking and sao at given level                 */
2653    /*************************************************************************/
2654    set_degrade(codec_obj, s_app_ctx.i4_degrade_type, s_app_ctx.i4_degrade_pics);
2655#ifdef X86_MSVC
2656    QueryPerformanceFrequency(&frequency);
2657#endif
2658#ifndef PRINT_PICSIZE
2659    get_version(codec_obj);
2660#endif
2661    while(u4_op_frm_ts < (s_app_ctx.u4_max_frm_ts + s_app_ctx.disp_delay))
2662    {
2663
2664#ifdef TEST_FLUSH
2665        if(u4_ip_frm_ts == FLUSH_FRM_CNT)
2666        {
2667            ivd_ctl_flush_ip_t s_ctl_ip;
2668            ivd_ctl_flush_op_t s_ctl_op;
2669
2670            s_ctl_ip.e_cmd = IVD_CMD_VIDEO_CTL;
2671            s_ctl_ip.e_sub_cmd = IVD_CMD_CTL_FLUSH;
2672            s_ctl_ip.u4_size = sizeof(ivd_ctl_flush_ip_t);
2673            s_ctl_op.u4_size = sizeof(ivd_ctl_flush_op_t);
2674            ret = ivd_cxa_api_function((iv_obj_t *)codec_obj, (void *)&s_ctl_ip,
2675                                       (void *)&s_ctl_op);
2676
2677            if(ret != IV_SUCCESS)
2678            {
2679                printf("Error in Setting the decoder in flush mode\n");
2680            }
2681            file_pos = 0;
2682
2683            fseek(ps_ip_file, file_pos, SEEK_SET);
2684
2685        }
2686#endif
2687        if(u4_ip_frm_ts < s_app_ctx.num_disp_buf)
2688        {
2689            release_disp_frame(codec_obj, u4_ip_frm_ts);
2690        }
2691
2692
2693        /*************************************************************************/
2694        /* set num of cores                                                      */
2695        /*************************************************************************/
2696#ifdef DYNAMIC_NUMCORES
2697        {
2698
2699            ihevcd_cxa_ctl_set_num_cores_ip_t s_ctl_set_cores_ip;
2700            ihevcd_cxa_ctl_set_num_cores_op_t s_ctl_set_cores_op;
2701
2702            s_ctl_set_cores_ip.e_cmd = IVD_CMD_VIDEO_CTL;
2703            s_ctl_set_cores_ip.e_sub_cmd = IHEVCD_CXA_CMD_CTL_SET_NUM_CORES;
2704            s_ctl_set_cores_ip.u4_num_cores =  1 + 3 * (u4_ip_frm_ts % 2);
2705            s_ctl_set_cores_ip.u4_size = sizeof(ihevcd_cxa_ctl_set_num_cores_ip_t);
2706            s_ctl_set_cores_op.u4_size = sizeof(ihevcd_cxa_ctl_set_num_cores_op_t);
2707
2708            ret = ivd_cxa_api_function((iv_obj_t *)codec_obj, (void *)&s_ctl_set_cores_ip,
2709                                       (void *)&s_ctl_set_cores_op);
2710            if(ret != IV_SUCCESS)
2711            {
2712                sprintf(ac_error_str, "\nError in setting number of cores");
2713                codec_exit(ac_error_str);
2714            }
2715
2716        }
2717#endif
2718        /***********************************************************************/
2719        /*   Seek the file to start of current frame, this is equavelent of    */
2720        /*   having a parcer which tells the start of current frame            */
2721        /***********************************************************************/
2722        {
2723            WORD32 numbytes;
2724
2725            if(0 == s_app_ctx.u4_piclen_flag)
2726            {
2727                fseek(ps_ip_file, file_pos, SEEK_SET);
2728                numbytes = u4_ip_buf_len;
2729            }
2730            else
2731            {
2732                WORD32 entries;
2733                entries = fscanf(ps_piclen_file, "%d\n", &numbytes);
2734                if(1 != entries)
2735                    numbytes = u4_ip_buf_len;
2736            }
2737
2738            u4_bytes_remaining = fread(pu1_bs_buf, sizeof(UWORD8),
2739                                       numbytes, ps_ip_file);
2740
2741            if(u4_bytes_remaining == 0)
2742            {
2743                if(1 == s_app_ctx.loopback)
2744                {
2745                    file_pos = 0;
2746                    if(0 == s_app_ctx.u4_piclen_flag)
2747                    {
2748                        fseek(ps_ip_file, file_pos, SEEK_SET);
2749                        numbytes = u4_ip_buf_len;
2750                    }
2751                    else
2752                    {
2753                        WORD32 entries;
2754                        entries = fscanf(ps_piclen_file, "%d\n", &numbytes);
2755                        if(1 != entries)
2756                            numbytes = u4_ip_buf_len;
2757                    }
2758
2759
2760                    u4_bytes_remaining = fread(pu1_bs_buf, sizeof(UWORD8),
2761                                               numbytes, ps_ip_file);
2762                }
2763                else
2764                    break;
2765            }
2766        }
2767
2768        /*********************************************************************/
2769        /* Following calls can be enabled at diffent times                   */
2770        /*********************************************************************/
2771#if ENABLE_DEGRADE
2772        if(u4_op_frm_ts >= 10000)
2773            disable_deblocking(codec_obj, 4);
2774
2775        if(u4_op_frm_ts == 30000)
2776            enable_deblocking(codec_obj);
2777
2778        if(u4_op_frm_ts == 10000)
2779            enable_skippb_frames(codec_obj);
2780
2781        if(u4_op_frm_ts == 60000)
2782            disable_skippb_frames(codec_obj);
2783
2784        if(u4_op_frm_ts == 30000)
2785            enable_skipb_frames(codec_obj);
2786
2787        if(u4_op_frm_ts == 60000)
2788            disable_skipb_frames(codec_obj);
2789#endif
2790
2791
2792        {
2793            ivd_video_decode_ip_t s_video_decode_ip;
2794            ivd_video_decode_op_t s_video_decode_op;
2795#ifdef PROFILE_ENABLE
2796            UWORD32 s_elapsed_time;
2797            TIMER s_start_timer;
2798            TIMER s_end_timer;
2799#endif
2800
2801
2802            s_video_decode_ip.e_cmd = IVD_CMD_VIDEO_DECODE;
2803            s_video_decode_ip.u4_ts = u4_ip_frm_ts;
2804            s_video_decode_ip.pv_stream_buffer = pu1_bs_buf;
2805            s_video_decode_ip.u4_num_Bytes = u4_bytes_remaining;
2806            s_video_decode_ip.u4_size = sizeof(ivd_video_decode_ip_t);
2807            s_video_decode_ip.s_out_buffer.u4_min_out_buf_size[0] =
2808                            ps_out_buf->u4_min_out_buf_size[0];
2809            s_video_decode_ip.s_out_buffer.u4_min_out_buf_size[1] =
2810                            ps_out_buf->u4_min_out_buf_size[1];
2811            s_video_decode_ip.s_out_buffer.u4_min_out_buf_size[2] =
2812                            ps_out_buf->u4_min_out_buf_size[2];
2813
2814            s_video_decode_ip.s_out_buffer.pu1_bufs[0] =
2815                            ps_out_buf->pu1_bufs[0];
2816            s_video_decode_ip.s_out_buffer.pu1_bufs[1] =
2817                            ps_out_buf->pu1_bufs[1];
2818            s_video_decode_ip.s_out_buffer.pu1_bufs[2] =
2819                            ps_out_buf->pu1_bufs[2];
2820            s_video_decode_ip.s_out_buffer.u4_num_bufs =
2821                            ps_out_buf->u4_num_bufs;
2822            s_video_decode_op.u4_size = sizeof(ivd_video_decode_op_t);
2823
2824            /* Get display buffer pointers */
2825            if(1 == s_app_ctx.display)
2826            {
2827                WORD32 wr_idx;
2828
2829                wr_idx = dispq_producer_dequeue(&s_app_ctx);
2830
2831                if(s_app_ctx.quit)
2832                    break;
2833
2834                s_app_ctx.set_disp_buffers(s_app_ctx.pv_disp_ctx, wr_idx,
2835                                           &s_video_decode_ip.s_out_buffer.pu1_bufs[0],
2836                                           &s_video_decode_ip.s_out_buffer.pu1_bufs[1],
2837                                           &s_video_decode_ip.s_out_buffer.pu1_bufs[2]);
2838            }
2839
2840            /*****************************************************************************/
2841            /*   API Call: Video Decode                                                  */
2842            /*****************************************************************************/
2843
2844            GETTIME(&s_start_timer);
2845
2846            ret = ivd_cxa_api_function((iv_obj_t *)codec_obj, (void *)&s_video_decode_ip,
2847                                       (void *)&s_video_decode_op);
2848
2849
2850            GETTIME(&s_end_timer);
2851            ELAPSEDTIME(s_start_timer, s_end_timer, s_elapsed_time, frequency);
2852#ifdef PROFILE_ENABLE
2853            {
2854                UWORD32 peak_avg, id;
2855                u4_tot_cycles += s_elapsed_time;
2856                peak_window[peak_window_idx++] = s_elapsed_time;
2857                if(peak_window_idx == PEAK_WINDOW_SIZE)
2858                    peak_window_idx = 0;
2859                peak_avg = 0;
2860                for(id = 0; id < PEAK_WINDOW_SIZE; id++)
2861                {
2862                    peak_avg += peak_window[id];
2863                }
2864                peak_avg /= PEAK_WINDOW_SIZE;
2865                if(peak_avg > peak_avg_max)
2866                    peak_avg_max = peak_avg;
2867                frm_cnt++;
2868
2869                printf("FrameNum: %4d TimeTaken(microsec): %6d AvgTime: %6d PeakAvgTimeMax: %6d Output: %2d NumBytes: %6d \n",
2870                       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);
2871
2872            }
2873#ifdef INTEL_CE5300
2874            time_consumed += s_elapsed_time;
2875            bytes_consumed += s_video_decode_op.u4_num_bytes_consumed;
2876            if(!(frm_cnt % (s_app_ctx.fps)))
2877            {
2878                time_consumed = time_consumed / s_app_ctx.fps;
2879                printf("Average decode time(micro sec) for the last second = %6d\n", time_consumed);
2880                printf("Average bitrate(kb) for the last second = %6d\n", (bytes_consumed * 8) / 1024);
2881                time_consumed = 0;
2882                bytes_consumed = 0;
2883
2884            }
2885#endif
2886#else
2887            printf("%d\n", s_video_decode_op.u4_num_bytes_consumed);
2888#endif
2889
2890            if(ret != IV_SUCCESS)
2891            {
2892                printf("Error in video Frame decode : ret %x Error %x\n", ret,
2893                       s_video_decode_op.u4_error_code);
2894            }
2895
2896            if((IV_SUCCESS != ret) &&
2897                            ((s_video_decode_op.u4_error_code & 0xFF) == IVD_RES_CHANGED))
2898            {
2899                ivd_ctl_reset_ip_t s_ctl_ip;
2900                ivd_ctl_reset_op_t s_ctl_op;
2901
2902                flush_output(codec_obj, &s_app_ctx, ps_out_buf,
2903                             pu1_bs_buf, &u4_op_frm_ts,
2904                             ps_op_file, ps_op_chksum_file,
2905                             u4_ip_frm_ts, u4_bytes_remaining);
2906
2907                s_ctl_ip.e_cmd = IVD_CMD_VIDEO_CTL;
2908                s_ctl_ip.e_sub_cmd = IVD_CMD_CTL_RESET;
2909                s_ctl_ip.u4_size = sizeof(ivd_ctl_reset_ip_t);
2910                s_ctl_op.u4_size = sizeof(ivd_ctl_reset_op_t);
2911
2912                ret = ivd_cxa_api_function((iv_obj_t *)codec_obj, (void *)&s_ctl_ip,
2913                                           (void *)&s_ctl_op);
2914                if(IV_SUCCESS != ret)
2915                {
2916                    sprintf(ac_error_str, "Error in Reset");
2917                    codec_exit(ac_error_str);
2918                }
2919                /*************************************************************************/
2920                /* set num of cores                                                      */
2921                /*************************************************************************/
2922                {
2923
2924                    ihevcd_cxa_ctl_set_num_cores_ip_t s_ctl_set_cores_ip;
2925                    ihevcd_cxa_ctl_set_num_cores_op_t s_ctl_set_cores_op;
2926
2927                    s_ctl_set_cores_ip.e_cmd = IVD_CMD_VIDEO_CTL;
2928                    s_ctl_set_cores_ip.e_sub_cmd = (IVD_CONTROL_API_COMMAND_TYPE_T)IHEVCD_CXA_CMD_CTL_SET_NUM_CORES;
2929                    s_ctl_set_cores_ip.u4_num_cores = s_app_ctx.u4_num_cores;
2930                    s_ctl_set_cores_ip.u4_size = sizeof(ihevcd_cxa_ctl_set_num_cores_ip_t);
2931                    s_ctl_set_cores_op.u4_size = sizeof(ihevcd_cxa_ctl_set_num_cores_op_t);
2932
2933                    ret = ivd_cxa_api_function((iv_obj_t *)codec_obj, (void *)&s_ctl_set_cores_ip,
2934                                               (void *)&s_ctl_set_cores_op);
2935                    if(ret != IV_SUCCESS)
2936                    {
2937                        sprintf(ac_error_str, "\nError in setting number of cores");
2938                        codec_exit(ac_error_str);
2939                    }
2940
2941                }
2942                /*************************************************************************/
2943                /* set processsor                                                        */
2944                /*************************************************************************/
2945                {
2946
2947                    ihevcd_cxa_ctl_set_processor_ip_t s_ctl_set_num_processor_ip;
2948                    ihevcd_cxa_ctl_set_processor_op_t s_ctl_set_num_processor_op;
2949
2950                    s_ctl_set_num_processor_ip.e_cmd = IVD_CMD_VIDEO_CTL;
2951                    s_ctl_set_num_processor_ip.e_sub_cmd = (IVD_CONTROL_API_COMMAND_TYPE_T)IHEVCD_CXA_CMD_CTL_SET_PROCESSOR;
2952                    s_ctl_set_num_processor_ip.u4_arch = s_app_ctx.e_arch;
2953                    s_ctl_set_num_processor_ip.u4_soc = s_app_ctx.e_soc;
2954                    s_ctl_set_num_processor_ip.u4_size = sizeof(ihevcd_cxa_ctl_set_processor_ip_t);
2955                    s_ctl_set_num_processor_op.u4_size = sizeof(ihevcd_cxa_ctl_set_processor_op_t);
2956
2957                    ret = ivd_cxa_api_function((iv_obj_t *)codec_obj, (void *)&s_ctl_set_num_processor_ip,
2958                                               (void *)&s_ctl_set_num_processor_op);
2959                    if(ret != IV_SUCCESS)
2960                    {
2961                        sprintf(ac_error_str, "\nError in setting Processor type");
2962                        codec_exit(ac_error_str);
2963                    }
2964
2965                }
2966            }
2967
2968
2969            if((1 == s_app_ctx.display) &&
2970                            (1 == s_video_decode_op.u4_output_present))
2971            {
2972                dispq_producer_queue(&s_app_ctx);
2973            }
2974
2975            if(IV_B_FRAME == s_video_decode_op.e_pic_type)
2976                s_app_ctx.b_pic_present |= 1;
2977
2978            u4_num_bytes_dec = s_video_decode_op.u4_num_bytes_consumed;
2979
2980            file_pos += u4_num_bytes_dec;
2981            total_bytes_comsumed += u4_num_bytes_dec;
2982            u4_ip_frm_ts++;
2983
2984
2985            if(1 == s_video_decode_op.u4_output_present)
2986            {
2987                width = s_video_decode_op.s_disp_frm_buf.u4_y_wd;
2988                height = s_video_decode_op.s_disp_frm_buf.u4_y_ht;
2989                dump_output(&s_app_ctx, &(s_video_decode_op.s_disp_frm_buf),
2990                            s_video_decode_op.u4_disp_buf_id, ps_op_file,
2991                            ps_op_chksum_file,
2992                            u4_op_frm_ts, s_app_ctx.u4_file_save_flag,
2993                            s_app_ctx.u4_chksum_save_flag);
2994
2995                u4_op_frm_ts++;
2996            }
2997            else
2998            {
2999                if((s_video_decode_op.u4_error_code >> IVD_FATALERROR) & 1)
3000                {
3001                    printf("Fatal error\n");
3002                    break;
3003                }
3004            }
3005
3006        }
3007    }
3008
3009    /***********************************************************************/
3010    /*      To get the last decoded frames, call process with NULL input    */
3011    /***********************************************************************/
3012    flush_output(codec_obj, &s_app_ctx, ps_out_buf,
3013                 pu1_bs_buf, &u4_op_frm_ts,
3014                 ps_op_file, ps_op_chksum_file,
3015                 u4_ip_frm_ts, u4_bytes_remaining);
3016
3017    /* set disp_end flag */
3018    s_app_ctx.quit = 1;
3019
3020
3021#ifdef PROFILE_ENABLE
3022    printf("Summary\n");
3023    printf("Input filename                  : %s\n", s_app_ctx.ac_ip_fname);
3024    printf("Output Width                    : %-4d\n", width);
3025    printf("Output Height                   : %-4d\n", height);
3026
3027    if(frm_cnt)
3028    {
3029        double avg = u4_tot_cycles / frm_cnt;
3030        double bytes_avg = total_bytes_comsumed / frm_cnt;
3031        double bitrate = (bytes_avg * 8 * s_app_ctx.fps) / 1000000;
3032        printf("Bitrate @ %2d fps(mbps)          : %-6.2f\n", s_app_ctx.fps, bitrate);
3033        printf("Average decode time(micro sec)  : %-6d\n", (WORD32)avg);
3034        printf("Avg Peak decode time(%2d frames) : %-6d\n", PEAK_WINDOW_SIZE, (WORD32)peak_avg_max);
3035        avg = (u4_tot_cycles + u4_tot_fmt_cycles) * 1.0 / frm_cnt;
3036
3037        if(0 == s_app_ctx.share_disp_buf)
3038            printf("FPS achieved (with format conv) : %-3.2f\n", 1000000 / avg);
3039        else
3040            printf("FPS achieved                    : %-3.2f\n", 1000000 / avg);
3041    }
3042#endif
3043    /***********************************************************************/
3044    /*   Clear the decoder, close all the files, free all the memory       */
3045    /***********************************************************************/
3046    if(1 == s_app_ctx.display)
3047    {
3048        s_app_ctx.display_deinit_flag = 1;
3049        /* wait for display to finish */
3050        if(s_app_ctx.display_thread_created)
3051        {
3052            ithread_join(s_app_ctx.display_thread_handle, NULL);
3053        }
3054        free(s_app_ctx.display_thread_handle);
3055    }
3056
3057    {
3058        iv_retrieve_mem_rec_ip_t s_retrieve_dec_ip;
3059        iv_retrieve_mem_rec_op_t s_retrieve_dec_op;
3060        s_retrieve_dec_ip.pv_mem_rec_location = (iv_mem_rec_t *)pv_mem_rec_location;
3061
3062        s_retrieve_dec_ip.e_cmd = IV_CMD_RETRIEVE_MEMREC;
3063        s_retrieve_dec_ip.u4_size = sizeof(iv_retrieve_mem_rec_ip_t);
3064        s_retrieve_dec_op.u4_size = sizeof(iv_retrieve_mem_rec_op_t);
3065
3066        ret = ivd_cxa_api_function((iv_obj_t *)codec_obj, (void *)&s_retrieve_dec_ip,
3067                                   (void *)&s_retrieve_dec_op);
3068
3069        if(IV_SUCCESS != ret)
3070        {
3071            sprintf(ac_error_str, "Error in Retrieve Memrec");
3072            codec_exit(ac_error_str);
3073        }
3074
3075        {
3076            iv_mem_rec_t *ps_mem_rec;
3077            UWORD16 u2_i;
3078
3079            u4_num_mem_recs = s_retrieve_dec_op.u4_num_mem_rec_filled;
3080
3081            ps_mem_rec = s_retrieve_dec_ip.pv_mem_rec_location;
3082
3083            for(u2_i = 0; u2_i < u4_num_mem_recs; u2_i++)
3084            {
3085                ihevca_aligned_free(ps_mem_rec->pv_base);
3086                ps_mem_rec++;
3087            }
3088            free(s_retrieve_dec_ip.pv_mem_rec_location);
3089        }
3090
3091    }
3092    /***********************************************************************/
3093    /*              Close all the files and free all the memory            */
3094    /***********************************************************************/
3095    {
3096        fclose(ps_ip_file);
3097
3098        if(1 == s_app_ctx.u4_file_save_flag)
3099        {
3100            fclose(ps_op_file);
3101        }
3102        if(1 == s_app_ctx.u4_chksum_save_flag)
3103        {
3104            fclose(ps_op_chksum_file);
3105        }
3106
3107    }
3108
3109    if(0 == s_app_ctx.share_disp_buf)
3110    {
3111        free(ps_out_buf->pu1_bufs[0]);
3112    }
3113
3114    for(i = 0; i < s_app_ctx.num_disp_buf; i++)
3115    {
3116        free(s_app_ctx.s_disp_buffers[i].pu1_bufs[0]);
3117    }
3118
3119    free(ps_out_buf);
3120    free(pu1_bs_buf);
3121
3122    return (0);
3123}
3124