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