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