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