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