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