• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
83 char filename_with_path[PATHLENMAX];
84 #endif
85 
86 #ifdef PROFILE_ENABLE
87 #ifdef X86_MSVC
88 typedef  LARGE_INTEGER TIMER;
89 #else
90 //#ifdef X86_MINGW
91 typedef struct timeval TIMER;
92 //#endif
93 #endif
94 #else
95 typedef 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
129 void 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
134 void* sdl_disp_init(UWORD32, UWORD32, WORD32, WORD32, WORD32, WORD32, WORD32, WORD32 *, WORD32 *);
135 void sdl_alloc_disp_buffers(void *);
136 void sdl_display(void *, WORD32);
137 void sdl_set_disp_buffers(void *, WORD32, UWORD8 **, UWORD8 **, UWORD8 **);
138 void sdl_disp_deinit(void *);
139 void sdl_disp_usleep(UWORD32);
140 IV_COLOR_FORMAT_T sdl_get_color_fmt(void);
141 UWORD32 sdl_get_stride(void);
142 #endif
143 
144 #ifdef INTEL_CE5300
145 void* gdl_disp_init(UWORD32, UWORD32, WORD32, WORD32, WORD32, WORD32, WORD32, WORD32 *, WORD32 *);
146 void gdl_alloc_disp_buffers(void *);
147 void gdl_display(void *, WORD32);
148 void gdl_set_disp_buffers(void *, WORD32, UWORD8 **, UWORD8 **, UWORD8 **);
149 void gdl_disp_deinit(void *);
150 void gdl_disp_usleep(UWORD32);
151 IV_COLOR_FORMAT_T gdl_get_color_fmt(void);
152 UWORD32 gdl_get_stride(void);
153 #endif
154 
155 #ifdef FBDEV_DISPLAY
156 void* fbd_disp_init(UWORD32, UWORD32, WORD32, WORD32, WORD32, WORD32, WORD32, WORD32 *, WORD32 *);
157 void fbd_alloc_disp_buffers(void *);
158 void fbd_display(void *, WORD32);
159 void fbd_set_disp_buffers(void *, WORD32, UWORD8 **, UWORD8 **, UWORD8 **);
160 void fbd_disp_deinit(void *);
161 void fbd_disp_usleep(UWORD32);
162 IV_COLOR_FORMAT_T fbd_get_color_fmt(void);
163 UWORD32 fbd_get_stride(void);
164 #endif
165 
166 #ifdef IOS_DISPLAY
167 void* ios_disp_init(UWORD32, UWORD32, WORD32, WORD32, WORD32, WORD32, WORD32, WORD32 *, WORD32 *);
168 void ios_alloc_disp_buffers(void *);
169 void ios_display(void *, WORD32);
170 void ios_set_disp_buffers(void *, WORD32, UWORD8 **, UWORD8 **, UWORD8 **);
171 void ios_disp_deinit(void *);
172 void ios_disp_usleep(UWORD32);
173 IV_COLOR_FORMAT_T ios_get_color_fmt(void);
174 UWORD32 ios_get_stride(void);
175 #endif
176 
177 typedef 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 
249 typedef 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 
279 typedef struct
280 {
281     CHAR argument_shortname[4];
282     CHAR argument_name[128];
283     ARGUMENT_T argument;
284     CHAR description[512];
285 }argument_t;
286 
287 static 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
349 char 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 /*****************************************************************************/
raise(int a)376 int 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 
ihevca_aligned_malloc(void * pv_ctxt,WORD32 alignment,WORD32 i4_size)411 void *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 
ihevca_aligned_free(void * pv_ctxt,void * pv_buf)417 void 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
ihevca_aligned_malloc(void * pv_ctxt,WORD32 alignment,WORD32 i4_size)426 void *ihevca_aligned_malloc(void *pv_ctxt, WORD32 alignment, WORD32 i4_size)
427 {
428     (void)pv_ctxt;
429     return malloc(i4_size);
430 }
431 
ihevca_aligned_free(void * pv_ctxt,void * pv_buf)432 void 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))
ihevca_aligned_malloc(void * pv_ctxt,WORD32 alignment,WORD32 i4_size)441 void *ihevca_aligned_malloc(void *pv_ctxt, WORD32 alignment, WORD32 i4_size)
442 {
443    (void)pv_ctxt;
444     return memalign(alignment, i4_size);
445 }
446 
ihevca_aligned_free(void * pv_ctxt,void * pv_buf)447 void 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 
set_degrade(void * codec_obj,UWORD32 type,WORD32 pics)489 IV_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 
enable_skipb_frames(void * codec_obj,vid_dec_ctx_t * ps_app_ctx)542 IV_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 
disable_skipb_frames(void * codec_obj,vid_dec_ctx_t * ps_app_ctx)592 IV_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 
enable_skippb_frames(void * codec_obj,vid_dec_ctx_t * ps_app_ctx)643 IV_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 
disable_skippb_frames(void * codec_obj,vid_dec_ctx_t * ps_app_ctx)693 IV_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 
release_disp_frame(void * codec_obj,UWORD32 buf_id)748 IV_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 
get_version(void * codec_obj)793 IV_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 /*****************************************************************************/
codec_exit(CHAR * pc_err_message)841 void 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 /*****************************************************************************/
dump_output(vid_dec_ctx_t * ps_app_ctx,iv_yuv_buf_t * ps_disp_frm_buf,UWORD32 u4_disp_frm_id,FILE * ps_op_file,FILE * ps_op_chksum_file,WORD32 i4_op_frm_ts,UWORD32 file_save,UWORD32 chksum_save)865 void 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 
print_usage(void)1072 void 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 
get_argument(CHAR * name)1109 ARGUMENT_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 
parse_argument(vid_dec_ctx_t * ps_app_ctx,CHAR * argument,CHAR * value)1150 void 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 
read_cfg_file(vid_dec_ctx_t * ps_app_ctx,FILE * fp_cfg_file)1322 void 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 */
dispq_producer_dequeue(vid_dec_ctx_t * ps_app_ctx)1367 WORD32 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 */
dispq_producer_queue(vid_dec_ctx_t * ps_app_ctx)1403 WORD32 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 */
dispq_consumer_dequeue(vid_dec_ctx_t * ps_app_ctx)1430 WORD32 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 */
dispq_consumer_queue(vid_dec_ctx_t * ps_app_ctx)1466 WORD32 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 
display_thread(void * pv_ctx)1503 WORD32 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 
flush_output(iv_obj_t * codec_obj,vid_dec_ctx_t * ps_app_ctx,ivd_out_bufdesc_t * ps_out_buf,UWORD8 * pu1_bs_buf,UWORD32 * pu4_op_frm_ts,FILE * ps_op_file,FILE * ps_op_chksum_file,UWORD32 u4_ip_frm_ts,UWORD32 u4_bytes_remaining)1591 void 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
sigsegv_handler()1674 void sigsegv_handler()
1675 {
1676     printf("Segmentation fault, Exiting.. \n");
1677     exit(-1);
1678 }
1679 #endif
1680 
default_get_stride(void)1681 UWORD32 default_get_stride(void)
1682 {
1683     return 0;
1684 }
1685 
1686 
default_get_color_fmt(void)1687 IV_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
hevcdec_main(char * homedir,char * documentdir,int screen_wd,int screen_ht)1716 int hevcdec_main(char *homedir, char *documentdir, int screen_wd, int screen_ht)
1717 #else
1718 int 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