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