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