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