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