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