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