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