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