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