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