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