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