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