aboutsummaryrefslogtreecommitdiff
path: root/examples/svcdec/main.c
diff options
context:
space:
mode:
Diffstat (limited to 'examples/svcdec/main.c')
-rw-r--r--examples/svcdec/main.c3441
1 files changed, 3441 insertions, 0 deletions
diff --git a/examples/svcdec/main.c b/examples/svcdec/main.c
new file mode 100644
index 0000000..412062c
--- /dev/null
+++ b/examples/svcdec/main.c
@@ -0,0 +1,3441 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *****************************************************************************
+ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
+ */
+/**
+ *******************************************************************************
+ * @file
+ * main.c
+ *
+ * @brief
+ * Contains an application that demonstrates use of H264 decoder API
+ *
+ * @author
+ * Kishore
+ *
+ * @remarks
+ * None
+ *
+ *******************************************************************************
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+#ifdef X86_MINGW
+#include <signal.h>
+#endif
+
+#ifdef IOS_DISPLAY
+#include "cast_types.h"
+#else
+#include "ih264_typedefs.h"
+#endif
+
+#include "iv.h"
+#include "ivd.h"
+#include "ithread.h"
+
+#include "ih264d.h"
+#include "isvcd.h"
+#ifdef WINDOWS_TIMER
+#include <windows.h>
+#else
+#include <sys/time.h>
+#endif
+
+// #define ADAPTIVE_TEST
+#define ADAPTIVE_MAX_WD 4096
+#define ADAPTIVE_MAX_HT 2160
+
+#define ALIGN8(x) ((((x) + 7) >> 3) << 3)
+#define NUM_DISPLAY_BUFFERS 4
+#define DEFAULT_FPS 30
+
+#define ENABLE_DEGRADE 0
+#define MAX_DISP_BUFFERS 64
+#define EXTRA_DISP_BUFFERS 8
+#define STRLENGTH 1000
+#define STR2(x) #x
+#define STR(X) STR2(X)
+
+// #define TEST_FLUSH
+#define FLUSH_FRM_CNT 100
+// #define APP_EXTRA_BUFS 1
+
+#undef PROFILE_ENABLE
+
+#ifdef IOS
+#define PATHLENMAX 500
+char filename_with_path[PATHLENMAX];
+#endif
+
+#ifdef PROFILE_ENABLE
+#ifdef WINDOWS_TIMER
+typedef LARGE_INTEGER TIMER;
+#else
+// #ifdef GCC_TIMER
+typedef struct timeval TIMER;
+// #endif
+#endif
+#else
+typedef WORD32 TIMER;
+#endif
+
+#ifdef PROFILE_ENABLE
+#ifdef WINDOWS_TIMER
+#define GETTIME(timer) QueryPerformanceCounter(timer);
+#else
+// #ifdef GCC_TIMER
+#define GETTIME(timer) gettimeofday(timer, NULL);
+// #endif
+#endif
+
+#ifdef WINDOWS_TIMER
+#define ELAPSEDTIME(s_start_timer, s_end_timer, s_elapsed_time, frequency) \
+ { \
+ TIMER s_temp_time; \
+ s_temp_time.LowPart = s_end_timer.LowPart - s_start_timer.LowPart; \
+ s_elapsed_time = \
+ (UWORD32) (((DOUBLE) s_temp_time.LowPart / (DOUBLE) frequency.LowPart) * 1000000); \
+ }
+#else
+// #ifdef GCC_TIMER
+#define ELAPSEDTIME(s_start_timer, s_end_timer, s_elapsed_time, frequency) \
+ s_elapsed_time = ((s_end_timer.tv_sec - s_start_timer.tv_sec) * 1000000) + \
+ (s_end_timer.tv_usec - s_start_timer.tv_usec);
+// #endif
+#endif
+
+#else
+#define GETTIME(timer)
+#define ELAPSEDTIME(s_start_timer, s_end_timer, s_elapsed_time, frequency)
+#endif
+
+/* Function declarations */
+#ifndef MD5_DISABLE
+void calc_md5_cksum(UWORD8 *pu1_inbuf, UWORD32 u4_stride, UWORD32 u4_width, UWORD32 u4_height,
+ UWORD8 *pu1_cksum_p);
+#else
+#define calc_md5_cksum(a, b, c, d, e)
+#endif
+#ifdef SDL_DISPLAY
+void *sdl_disp_init(UWORD32, UWORD32, WORD32, WORD32, WORD32, WORD32, WORD32, WORD32 *, WORD32 *);
+void sdl_alloc_disp_buffers(void *);
+void sdl_display(void *, WORD32);
+void sdl_set_disp_buffers(void *, WORD32, UWORD8 **, UWORD8 **, UWORD8 **);
+void sdl_disp_deinit(void *);
+void sdl_disp_usleep(UWORD32);
+IV_COLOR_FORMAT_T sdl_get_color_fmt(void);
+UWORD32 sdl_get_stride(void);
+#endif
+
+#ifdef INTEL_CE5300
+void *gdl_disp_init(UWORD32, UWORD32, WORD32, WORD32, WORD32, WORD32, WORD32, WORD32 *, WORD32 *);
+void gdl_alloc_disp_buffers(void *);
+void gdl_display(void *, WORD32);
+void gdl_set_disp_buffers(void *, WORD32, UWORD8 **, UWORD8 **, UWORD8 **);
+void gdl_disp_deinit(void *);
+void gdl_disp_usleep(UWORD32);
+IV_COLOR_FORMAT_T gdl_get_color_fmt(void);
+UWORD32 gdl_get_stride(void);
+#endif
+
+#ifdef FBDEV_DISPLAY
+void *fbd_disp_init(UWORD32, UWORD32, WORD32, WORD32, WORD32, WORD32, WORD32, WORD32 *, WORD32 *);
+void fbd_alloc_disp_buffers(void *);
+void fbd_display(void *, WORD32);
+void fbd_set_disp_buffers(void *, WORD32, UWORD8 **, UWORD8 **, UWORD8 **);
+void fbd_disp_deinit(void *);
+void fbd_disp_usleep(UWORD32);
+IV_COLOR_FORMAT_T fbd_get_color_fmt(void);
+UWORD32 fbd_get_stride(void);
+#endif
+
+#ifdef IOS_DISPLAY
+void *ios_disp_init(UWORD32, UWORD32, WORD32, WORD32, WORD32, WORD32, WORD32, WORD32 *, WORD32 *);
+void ios_alloc_disp_buffers(void *);
+void ios_display(void *, WORD32);
+void ios_set_disp_buffers(void *, WORD32, UWORD8 **, UWORD8 **, UWORD8 **);
+void ios_disp_deinit(void *);
+void ios_disp_usleep(UWORD32);
+IV_COLOR_FORMAT_T ios_get_color_fmt(void);
+UWORD32 ios_get_stride(void);
+#endif
+
+typedef struct
+{
+ UWORD32 u4_piclen_flag;
+ UWORD32 u4_file_save_flag;
+ UWORD32 u4_frame_info_enable;
+ UWORD32 u4_chksum_save_flag;
+ UWORD32 u4_max_frm_ts;
+ IV_COLOR_FORMAT_T e_output_chroma_format;
+ IVD_ARCH_T e_arch;
+ IVD_SOC_T e_soc;
+ UWORD32 dump_q_rd_idx;
+ UWORD32 dump_q_wr_idx;
+ WORD32 disp_q_wr_idx;
+ WORD32 disp_q_rd_idx;
+
+ void *cocodec_obj;
+ UWORD32 u4_share_disp_buf;
+ UWORD32 num_disp_buf;
+ UWORD32 b_pic_present;
+ UWORD32 u4_disable_dblk_level;
+ WORD32 i4_target_layer_id;
+ WORD32 i4_degrade_type;
+ WORD32 i4_degrade_pics;
+ UWORD32 u4_num_cores;
+ UWORD32 disp_delay;
+ WORD32 trace_enable;
+ CHAR ac_trace_fname[STRLENGTH];
+ CHAR ac_piclen_fname[STRLENGTH];
+ CHAR ac_ip_fname[STRLENGTH];
+ CHAR ac_op_fname[STRLENGTH];
+ CHAR ac_qp_map_fname[STRLENGTH];
+ CHAR ac_blk_type_map_fname[STRLENGTH];
+ CHAR ac_op_chksum_fname[STRLENGTH];
+ ivd_out_bufdesc_t s_disp_buffers[MAX_DISP_BUFFERS];
+ iv_yuv_buf_t s_disp_frm_queue[MAX_DISP_BUFFERS];
+ UWORD32 s_disp_frm_id_queue[MAX_DISP_BUFFERS];
+ UWORD32 loopback;
+ UWORD32 display;
+ UWORD32 full_screen;
+ UWORD32 fps;
+
+ UWORD32 u4_strd;
+
+ /* For signalling to display thread */
+ UWORD32 u4_pic_wd;
+ UWORD32 u4_pic_ht;
+
+ /* For IOS diplay */
+ WORD32 i4_screen_wd;
+ WORD32 i4_screen_ht;
+
+ WORD32 quit;
+ WORD32 paused;
+
+ void *pv_disp_ctx;
+ void *display_thread_handle;
+ WORD32 display_thread_created;
+ volatile WORD32 display_init_done;
+ volatile WORD32 display_deinit_flag;
+
+ void *(*disp_init)(UWORD32, UWORD32, WORD32, WORD32, WORD32, WORD32, WORD32, WORD32 *,
+ WORD32 *);
+ void (*alloc_disp_buffers)(void *);
+ void (*display_buffer)(void *, WORD32);
+ void (*set_disp_buffers)(void *, WORD32, UWORD8 **, UWORD8 **, UWORD8 **);
+ void (*disp_deinit)(void *);
+ void (*disp_usleep)(UWORD32);
+ IV_COLOR_FORMAT_T (*get_color_fmt)(void);
+ UWORD32 (*get_stride)(void);
+} vid_dec_ctx_t;
+
+/**
+ * function pointer to malloc
+ */
+void *(*pf_mem_alloc)(UWORD32 u4_size);
+
+/**
+ * function pointer to free
+ */
+void (*pf_mem_free)(void *pv_mem);
+
+typedef enum
+{
+ INVALID,
+ HELP,
+ VERSION,
+ INPUT_FILE,
+ OUTPUT,
+ QP_MAP_FILE,
+ BLK_TYPE_MAP_FILE,
+ CHKSUM,
+ SAVE_OUTPUT,
+ SAVE_FRAME_INFO,
+ SAVE_CHKSUM,
+ CHROMA_FORMAT,
+ NUM_FRAMES,
+ NUM_CORES,
+ DISABLE_DEBLOCK_LEVEL,
+ SHARE_DISPLAY_BUF,
+ LOOPBACK,
+ DISPLAY,
+ FULLSCREEN,
+ FPS,
+ TRACE,
+ CONFIG,
+
+ DEGRADE_TYPE,
+ DEGRADE_PICS,
+ ARCH,
+ SOC,
+ PICLEN,
+ PICLEN_FILE,
+ TARGET_LAYER_ID,
+} ARGUMENT_T;
+
+typedef struct
+{
+ CHAR argument_shortname[4];
+ CHAR argument_name[128];
+ ARGUMENT_T argument;
+ CHAR description[512];
+} argument_t;
+
+static const argument_t argument_mapping[] = {
+ {"-h", "--help", HELP, "Print this help\n"},
+ {"-c", "--config", CONFIG, "config file (Default: test.cfg)\n"},
+
+ {"-v", "--version", VERSION, "Version information\n"},
+ {"-i", "--input", INPUT_FILE, "Input file\n"},
+ {"-o", "--output", OUTPUT, "Output file\n"},
+ {"--", "--qp_map_file", QP_MAP_FILE, "QP map file\n"},
+ {"--", "--blk_type_map_file", BLK_TYPE_MAP_FILE, "Block type map file\n"},
+ {"--", "--piclen", PICLEN,
+ "Flag to signal if the decoder has to use a file containing number of "
+ "bytes in each picture to be fed in each call\n"},
+ {"--", "--piclen_file", PICLEN_FILE,
+ "File containing number of bytes in each picture - each line containing "
+ "one i4_size\n"},
+ {"--", "--chksum", CHKSUM, "Output MD5 Checksum file\n"},
+ {"-s", "--save_output", SAVE_OUTPUT, "Save Output file\n"},
+ {"--", "--save_frame_info", SAVE_FRAME_INFO, "Save frame_info file\n"},
+ {"--", "--save_chksum", SAVE_CHKSUM, "Save Check sum file\n"},
+ {"--", "--chroma_format", CHROMA_FORMAT,
+ "Output Chroma format Supported values YUV_420P, YUV_422ILE, RGB_565, "
+ "YUV_420SP_UV, YUV_420SP_VU\n"},
+ {"-n", "--num_frames", NUM_FRAMES, "Number of frames to be decoded\n"},
+ {"--", "--num_cores", NUM_CORES, "Number of cores to be used\n"},
+ {"--", "--share_display_buf", SHARE_DISPLAY_BUF, "Enable shared display buffer mode\n"},
+ {"--", "--disable_deblock_level", DISABLE_DEBLOCK_LEVEL,
+ "Disable deblocking level : 0 to 4 - 0 Enable deblocking 4 Disable "
+ "deblocking completely\n"},
+ {"--", "--loopback", LOOPBACK, "Enable playback in a loop\n"},
+ {"--", "--display", DISPLAY, "Enable display (uses SDL)\n"},
+ {"--", "--fullscreen", FULLSCREEN, "Enable full screen (Only for GDL and SDL)\n"},
+ {"--", "--fps", FPS, "FPS to be used for display \n"},
+ {"-i", "--trace", TRACE, "Trace file\n"},
+
+ {"--", "--degrade_type", DEGRADE_TYPE,
+ "Degrade type : 0: No degrade 0th bit set : Disable SAO 1st bit set : "
+ "Disable deblocking 2nd bit set : Faster inter prediction filters 3rd bit "
+ "set : Fastest inter prediction filters\n"},
+ {"--", "--degrade_pics", DEGRADE_PICS,
+ "Degrade pics : 0 : No degrade 1 : Only on non-reference frames 2 : Do "
+ "not degrade every 4th or key frames 3 : All non-key frames 4 : All "
+ "frames"},
+
+ {"--", "--arch", ARCH,
+ "Set Architecture. Supported values ARM_NONEON, ARM_A9Q, ARM_A7, ARM_A5, "
+ "ARM_NEONINTR,ARMV8_GENERIC, X86_GENERIC, X86_SSSE3, X86_SSE4 \n"},
+ {"--", "--soc", SOC, "Set SOC. Supported values GENERIC, HISI_37X \n"},
+ {"-t", "--target_layer_id", TARGET_LAYER_ID, "Version information\n"},
+
+};
+
+#define PEAK_WINDOW_SIZE 8
+#define DEFAULT_SHARE_DISPLAY_BUF 0
+#define STRIDE 0
+#define DEFAULT_NUM_CORES 1
+
+#define DUMP_SINGLE_BUF 0
+#define IV_ISFATALERROR(x) (((x) >> IVD_FATALERROR) & 0x1)
+
+#define ivd_api_function isvcd_api_function
+
+#ifdef IOS
+char filename_trace[PATHLENMAX];
+#endif
+
+#if ANDROID_NDK
+/*****************************************************************************/
+/* */
+/* Function Name : raise */
+/* */
+/* Description : Needed as a workaround when the application is built in */
+/* Android NDK. This is an exception to be called for divide*/
+/* by zero error */
+/* */
+/* Inputs : a */
+/* Globals : */
+/* Processing : None */
+/* */
+/* Outputs : */
+/* Returns : */
+/* */
+/* Issues : */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes */
+/* 07 09 2012 100189 Initial Version */
+/* */
+/*****************************************************************************/
+int raise(int a)
+{
+ printf("Divide by zero\n");
+ return 0;
+}
+#endif
+
+#ifdef _WIN32
+/*****************************************************************************/
+/* Function to print library calls */
+/*****************************************************************************/
+/*****************************************************************************/
+/* */
+/* Function Name : memalign */
+/* */
+/* Description : Returns malloc data. Ideally should return aligned memory*/
+/* support alignment will be added later */
+/* */
+/* Inputs : alignment i4_size */
+/* Globals : */
+/* Processing : */
+/* */
+/* Outputs : */
+/* Returns : */
+/* */
+/* Issues : */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes */
+/* 06 09 2021 Kishore Initial Version */
+/* */
+/*****************************************************************************/
+
+void *ih264a_aligned_malloc(void *pv_ctxt, WORD32 alignment, WORD32 i4_size)
+{
+ (void) pv_ctxt;
+ return (void *) _aligned_malloc(i4_size, alignment);
+}
+
+void ih264a_aligned_free(void *pv_ctxt, void *pv_buf)
+{
+ (void) pv_ctxt;
+ _aligned_free(pv_buf);
+ return;
+}
+#endif
+
+#if IOS
+void *ih264a_aligned_malloc(void *pv_ctxt, WORD32 alignment, WORD32 i4_size)
+{
+ (void) pv_ctxt;
+ return malloc(i4_size);
+}
+
+void ih264a_aligned_free(void *pv_ctxt, void *pv_buf)
+{
+ (void) pv_ctxt;
+ free(pv_buf);
+}
+#endif
+
+#if(!defined(IOS)) && (!defined(_WIN32))
+void *ih264a_aligned_malloc(void *pv_ctxt, WORD32 alignment, WORD32 i4_size)
+{
+ void *buf = NULL;
+ (void) pv_ctxt;
+ if(0 != posix_memalign(&buf, alignment, i4_size))
+ {
+ return NULL;
+ }
+ return buf;
+}
+
+void ih264a_aligned_free(void *pv_ctxt, void *pv_buf)
+{
+ (void) pv_ctxt;
+ free(pv_buf);
+}
+#endif
+
+void *ih264a_memory_alloc(UWORD32 u4_size) { return (malloc(u4_size)); }
+
+void ih264a_memory_free(void *pv_mem) { free(pv_mem); }
+/*****************************************************************************/
+/* */
+/* Function Name : set_degrade */
+/* */
+/* Description : Control call to set degrade level */
+/* */
+/* */
+/* Inputs : codec_obj - Codec Handle */
+/* type - degrade level value between 0 to 4 */
+/* 0 : No degrade */
+/* 1st bit : Disable SAO */
+/* 2nd bit : Disable Deblock */
+/* 3rd bit : Faster MC for non-ref */
+/* 4th bit : Fastest MC for non-ref */
+/* pics - Pictures that are are degraded */
+/* 0 : No degrade */
+/* 1 : Non-ref pictures */
+/* 2 : Pictures at given interval are not degraded */
+/* 3 : All non-key pictures */
+/* 4 : All pictures */
+/* Globals : */
+/* Processing : Calls degrade control to the codec */
+/* */
+/* Outputs : */
+/* Returns : Control call return i4_status */
+/* */
+/* Issues : */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes */
+/* 06 09 2021 Kishore Initial Version */
+/* */
+/*****************************************************************************/
+
+IV_API_CALL_STATUS_T set_degrade(void *codec_obj, UWORD32 type, WORD32 pics)
+{
+ isvcd_ctl_degrade_ip_t s_ctl_ip;
+ isvcd_ctl_degrade_op_t s_ctl_op;
+ void *pv_api_ip, *pv_api_op;
+ IV_API_CALL_STATUS_T e_dec_status;
+
+ s_ctl_ip.u4_size = sizeof(isvcd_ctl_degrade_ip_t);
+ s_ctl_ip.i4_degrade_type = type;
+ s_ctl_ip.i4_nondegrade_interval = 4;
+ s_ctl_ip.i4_degrade_pics = pics;
+
+ s_ctl_op.u4_size = sizeof(isvcd_ctl_degrade_op_t);
+
+ pv_api_ip = (void *) &s_ctl_ip;
+ pv_api_op = (void *) &s_ctl_op;
+
+ s_ctl_ip.e_cmd = IVD_CMD_VIDEO_CTL;
+ s_ctl_ip.e_sub_cmd = (IVD_CONTROL_API_COMMAND_TYPE_T) IH264D_CMD_CTL_DEGRADE;
+
+ e_dec_status = ivd_api_function((iv_obj_t *) codec_obj, pv_api_ip, pv_api_op);
+
+ if(IV_SUCCESS != e_dec_status)
+ {
+ printf("Error in setting degrade level \n");
+ }
+ return (e_dec_status);
+}
+
+/*****************************************************************************/
+/* */
+/* Function Name : enable_skipb_frames */
+/* */
+/* Description : Control call to enable skipping of b frames */
+/* */
+/* */
+/* Inputs : codec_obj : Codec handle */
+/* Globals : */
+/* Processing : Calls enable skip B frames control */
+/* */
+/* Outputs : */
+/* Returns : Control call return i4_status */
+/* */
+/* Issues : */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes */
+/* 06 09 2021 Kishore Initial Version */
+/* */
+/*****************************************************************************/
+
+IV_API_CALL_STATUS_T enable_skipb_frames(void *codec_obj, vid_dec_ctx_t *ps_app_ctx)
+{
+ isvcd_ctl_set_config_ip_t s_h264d_ctl_ip;
+ isvcd_ctl_set_config_op_t s_h264d_ctl_op;
+ ivd_ctl_set_config_ip_t *ps_ctl_ip = &s_h264d_ctl_ip.s_ivd_ctl_set_config_ip_t;
+ ivd_ctl_set_config_op_t *ps_ctl_op = &s_h264d_ctl_op.s_ivd_ctl_set_config_op_t;
+ IV_API_CALL_STATUS_T e_dec_status;
+
+ ps_ctl_ip->u4_disp_wd = ps_app_ctx->u4_strd;
+ ps_ctl_ip->e_frm_skip_mode = IVD_SKIP_B;
+
+ ps_ctl_ip->e_frm_out_mode = IVD_DISPLAY_FRAME_OUT;
+ ps_ctl_ip->e_vid_dec_mode = IVD_DECODE_FRAME;
+ ps_ctl_ip->e_cmd = IVD_CMD_VIDEO_CTL;
+ ps_ctl_ip->e_sub_cmd = IVD_CMD_CTL_SETPARAMS;
+ ps_ctl_ip->u4_size = sizeof(isvcd_ctl_set_config_ip_t);
+ ps_ctl_op->u4_size = sizeof(isvcd_ctl_set_config_op_t);
+
+ e_dec_status = ivd_api_function((iv_obj_t *) codec_obj, (void *) &s_h264d_ctl_ip,
+ (void *) &s_h264d_ctl_op);
+
+ if(IV_SUCCESS != e_dec_status)
+ {
+ printf("Error in Enable SkipB frames \n");
+ }
+
+ return e_dec_status;
+}
+/*****************************************************************************/
+/* */
+/* Function Name : disable_skipb_frames */
+/* */
+/* Description : Control call to disable skipping of b frames */
+/* */
+/* */
+/* Inputs : codec_obj : Codec handle */
+/* Globals : */
+/* Processing : Calls disable B frame skip control */
+/* */
+/* Outputs : */
+/* Returns : Control call return i4_status */
+/* */
+/* Issues : */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes */
+/* 06 09 2021 Kishore Initial Version */
+/* */
+/*****************************************************************************/
+
+IV_API_CALL_STATUS_T disable_skipb_frames(void *codec_obj, vid_dec_ctx_t *ps_app_ctx)
+{
+ isvcd_ctl_set_config_ip_t s_h264d_ctl_ip;
+ isvcd_ctl_set_config_op_t s_h264d_ctl_op;
+ ivd_ctl_set_config_ip_t *ps_ctl_ip = &s_h264d_ctl_ip.s_ivd_ctl_set_config_ip_t;
+ ivd_ctl_set_config_op_t *ps_ctl_op = &s_h264d_ctl_op.s_ivd_ctl_set_config_op_t;
+ IV_API_CALL_STATUS_T e_dec_status;
+
+ ps_ctl_ip->u4_disp_wd = ps_app_ctx->u4_strd;
+ ps_ctl_ip->e_frm_skip_mode = IVD_SKIP_NONE;
+
+ ps_ctl_ip->e_frm_out_mode = IVD_DISPLAY_FRAME_OUT;
+ ps_ctl_ip->e_vid_dec_mode = IVD_DECODE_FRAME;
+ ps_ctl_ip->e_cmd = IVD_CMD_VIDEO_CTL;
+ ps_ctl_ip->e_sub_cmd = IVD_CMD_CTL_SETPARAMS;
+ ps_ctl_ip->u4_size = sizeof(isvcd_ctl_set_config_ip_t);
+ ps_ctl_op->u4_size = sizeof(isvcd_ctl_set_config_op_t);
+
+ e_dec_status = ivd_api_function((iv_obj_t *) codec_obj, (void *) &s_h264d_ctl_ip,
+ (void *) &s_h264d_ctl_op);
+
+ if(IV_SUCCESS != e_dec_status)
+ {
+ printf("Error in Disable SkipB frames\n");
+ }
+
+ return e_dec_status;
+}
+
+/*****************************************************************************/
+/* */
+/* Function Name : enable_skippb_frames */
+/* */
+/* Description : Control call to enable skipping of P & B frames */
+/* */
+/* */
+/* Inputs : codec_obj : Codec handle */
+/* Globals : */
+/* Processing : Calls enable skip P and B frames control */
+/* */
+/* Outputs : */
+/* Returns : Control call return i4_status */
+/* */
+/* Issues : */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes */
+/* 06 09 2021 Kishore Initial Version */
+/* */
+/*****************************************************************************/
+
+IV_API_CALL_STATUS_T enable_skippb_frames(void *codec_obj, vid_dec_ctx_t *ps_app_ctx)
+{
+ isvcd_ctl_set_config_ip_t s_h264d_ctl_ip;
+ isvcd_ctl_set_config_op_t s_h264d_ctl_op;
+ ivd_ctl_set_config_ip_t *ps_ctl_ip = &s_h264d_ctl_ip.s_ivd_ctl_set_config_ip_t;
+ ivd_ctl_set_config_op_t *ps_ctl_op = &s_h264d_ctl_op.s_ivd_ctl_set_config_op_t;
+ IV_API_CALL_STATUS_T e_dec_status;
+
+ ps_ctl_ip->u4_disp_wd = ps_app_ctx->u4_strd;
+ ps_ctl_ip->e_frm_skip_mode = IVD_SKIP_PB;
+
+ ps_ctl_ip->e_frm_out_mode = IVD_DISPLAY_FRAME_OUT;
+ ps_ctl_ip->e_vid_dec_mode = IVD_DECODE_FRAME;
+ ps_ctl_ip->e_cmd = IVD_CMD_VIDEO_CTL;
+ ps_ctl_ip->e_sub_cmd = IVD_CMD_CTL_SETPARAMS;
+ ps_ctl_ip->u4_size = sizeof(isvcd_ctl_set_config_ip_t);
+ ps_ctl_op->u4_size = sizeof(isvcd_ctl_set_config_op_t);
+
+ e_dec_status = ivd_api_function((iv_obj_t *) codec_obj, (void *) &s_h264d_ctl_ip,
+ (void *) &s_h264d_ctl_op);
+ if(IV_SUCCESS != e_dec_status)
+ {
+ printf("Error in Enable SkipPB frames\n");
+ }
+
+ return e_dec_status;
+}
+
+/*****************************************************************************/
+/* */
+/* Function Name : disable_skippb_frames */
+/* */
+/* Description : Control call to disable skipping of P and B frames */
+/* */
+/* */
+/* Inputs : codec_obj : Codec handle */
+/* Globals : */
+/* Processing : Calls disable P and B frame skip control */
+/* */
+/* Outputs : */
+/* Returns : Control call return i4_status */
+/* */
+/* Issues : */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes */
+/* 06 09 2021 Kishore Initial Version */
+/* */
+/*****************************************************************************/
+
+IV_API_CALL_STATUS_T disable_skippb_frames(void *codec_obj, vid_dec_ctx_t *ps_app_ctx)
+{
+ isvcd_ctl_set_config_ip_t s_h264d_ctl_ip;
+ isvcd_ctl_set_config_op_t s_h264d_ctl_op;
+ ivd_ctl_set_config_ip_t *ps_ctl_ip = &s_h264d_ctl_ip.s_ivd_ctl_set_config_ip_t;
+ ivd_ctl_set_config_op_t *ps_ctl_op = &s_h264d_ctl_op.s_ivd_ctl_set_config_op_t;
+ IV_API_CALL_STATUS_T e_dec_status;
+
+ ps_ctl_ip->u4_disp_wd = ps_app_ctx->u4_strd;
+ ps_ctl_ip->e_frm_skip_mode = IVD_SKIP_NONE;
+
+ ps_ctl_ip->e_frm_out_mode = IVD_DISPLAY_FRAME_OUT;
+ ps_ctl_ip->e_vid_dec_mode = IVD_DECODE_FRAME;
+ ps_ctl_ip->e_cmd = IVD_CMD_VIDEO_CTL;
+ ps_ctl_ip->e_sub_cmd = IVD_CMD_CTL_SETPARAMS;
+ ps_ctl_ip->u4_size = sizeof(isvcd_ctl_set_config_ip_t);
+ ps_ctl_op->u4_size = sizeof(isvcd_ctl_set_config_op_t);
+
+ e_dec_status = ivd_api_function((iv_obj_t *) codec_obj, (void *) &s_h264d_ctl_ip,
+ (void *) &s_h264d_ctl_op);
+ if(IV_SUCCESS != e_dec_status)
+ {
+ printf("Error in Disable SkipPB frames\n");
+ }
+
+ return e_dec_status;
+}
+
+/*****************************************************************************/
+/* */
+/* Function Name : release_disp_frame */
+/* */
+/* Description : Calls release display control - Used to signal to the */
+/* decoder that this particular buffer has been displayed */
+/* and that the codec is now free to write to this buffer */
+/* */
+/* */
+/* Inputs : codec_obj : Codec Handle */
+/* buf_id : Buffer Id of the buffer to be released */
+/* This id would have been returned earlier by */
+/* the codec */
+/* Globals : */
+/* Processing : Calls Release Display call */
+/* */
+/* Outputs : */
+/* Returns : Status of release display call */
+/* */
+/* Issues : */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes */
+/* 06 09 2021 Kishore Initial Version */
+/* */
+/*****************************************************************************/
+
+IV_API_CALL_STATUS_T release_disp_frame(void *codec_obj, UWORD32 buf_id)
+{
+ ivd_rel_display_frame_ip_t s_video_rel_disp_ip;
+ ivd_rel_display_frame_op_t s_video_rel_disp_op;
+ IV_API_CALL_STATUS_T e_dec_status;
+
+ s_video_rel_disp_ip.e_cmd = IVD_CMD_REL_DISPLAY_FRAME;
+ s_video_rel_disp_ip.u4_size = sizeof(ivd_rel_display_frame_ip_t);
+ s_video_rel_disp_op.u4_size = sizeof(ivd_rel_display_frame_op_t);
+ s_video_rel_disp_ip.u4_disp_buf_id = buf_id;
+
+ e_dec_status = ivd_api_function((iv_obj_t *) codec_obj, (void *) &s_video_rel_disp_ip,
+ (void *) &s_video_rel_disp_op);
+ if(IV_SUCCESS != e_dec_status)
+ {
+ printf("Error in Release Disp frame\n");
+ }
+
+ return (e_dec_status);
+}
+
+/*****************************************************************************/
+/* */
+/* Function Name : get_version */
+/* */
+/* Description : Control call to get codec version */
+/* */
+/* */
+/* Inputs : codec_obj : Codec handle */
+/* Globals : */
+/* Processing : Calls enable skip B frames control */
+/* */
+/* Outputs : */
+/* Returns : Control call return i4_status */
+/* */
+/* Issues : */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes */
+/* 06 09 2021 Kishore Initial Version */
+/* */
+/*****************************************************************************/
+
+IV_API_CALL_STATUS_T get_version(void *codec_obj)
+{
+ ivd_ctl_getversioninfo_ip_t ps_ctl_ip;
+ ivd_ctl_getversioninfo_op_t ps_ctl_op;
+ UWORD8 au1_buf[512];
+ IV_API_CALL_STATUS_T i4_status;
+ ps_ctl_ip.e_cmd = IVD_CMD_VIDEO_CTL;
+ ps_ctl_ip.e_sub_cmd = IVD_CMD_CTL_GETVERSION;
+ ps_ctl_ip.u4_size = sizeof(ivd_ctl_getversioninfo_ip_t);
+ ps_ctl_op.u4_size = sizeof(ivd_ctl_getversioninfo_op_t);
+ ps_ctl_ip.pv_version_buffer = au1_buf;
+ ps_ctl_ip.u4_version_buffer_size = sizeof(au1_buf);
+
+ i4_status =
+ ivd_api_function((iv_obj_t *) codec_obj, (void *) &(ps_ctl_ip), (void *) &(ps_ctl_op));
+
+ if(i4_status != IV_SUCCESS)
+ {
+ printf(
+ "Error in Getting Version number e_dec_status = %d u4_error_code = "
+ "%x\n",
+ i4_status, ps_ctl_op.u4_error_code);
+ }
+ else
+ {
+ printf("Ittiam Decoder Version number: %s\n", (char *) ps_ctl_ip.pv_version_buffer);
+ }
+ return i4_status;
+}
+/*****************************************************************************/
+/* */
+/* Function Name : codec_exit */
+/* */
+/* Description : handles unrecoverable errors */
+/* Inputs : Error message */
+/* Globals : None */
+/* Processing : Prints error message to console and exits. */
+/* Outputs : Error mesage to the console */
+/* Returns : None */
+/* */
+/* Issues : */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 06 09 2021 Kishore Creation */
+/* */
+/*****************************************************************************/
+void codec_exit(CHAR *pc_err_message)
+{
+ printf("%s\n", pc_err_message);
+ exit(-1);
+}
+
+/*****************************************************************************/
+/* */
+/* Function Name : dump_output */
+/* */
+/* Description : Used to dump output YUV */
+/* Inputs : App context, disp output desc, File pointer */
+/* Globals : None */
+/* Processing : Dumps to a file */
+/* Returns : None */
+/* */
+/* Issues : */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes (Describe the changes made) */
+/* 06 09 2021 Kishore Creation */
+/* */
+/*****************************************************************************/
+void 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)
+
+{
+ UWORD32 i;
+ iv_yuv_buf_t s_dump_disp_frm_buf;
+ UWORD32 u4_disp_id;
+
+ memset(&s_dump_disp_frm_buf, 0, sizeof(iv_yuv_buf_t));
+
+ if(ps_app_ctx->u4_share_disp_buf)
+ {
+ if(ps_app_ctx->dump_q_wr_idx == MAX_DISP_BUFFERS) ps_app_ctx->dump_q_wr_idx = 0;
+
+ if(ps_app_ctx->dump_q_rd_idx == MAX_DISP_BUFFERS) ps_app_ctx->dump_q_rd_idx = 0;
+
+ ps_app_ctx->s_disp_frm_queue[ps_app_ctx->dump_q_wr_idx] = *ps_disp_frm_buf;
+ ps_app_ctx->s_disp_frm_id_queue[ps_app_ctx->dump_q_wr_idx] = u4_disp_frm_id;
+ ps_app_ctx->dump_q_wr_idx++;
+
+ if((WORD32) i4_op_frm_ts >= (WORD32) (ps_app_ctx->disp_delay - 1))
+ {
+ s_dump_disp_frm_buf = ps_app_ctx->s_disp_frm_queue[ps_app_ctx->dump_q_rd_idx];
+ u4_disp_id = ps_app_ctx->s_disp_frm_id_queue[ps_app_ctx->dump_q_rd_idx];
+ ps_app_ctx->dump_q_rd_idx++;
+ }
+ else
+ {
+ return;
+ }
+ }
+ else
+ {
+ s_dump_disp_frm_buf = *ps_disp_frm_buf;
+ u4_disp_id = u4_disp_frm_id;
+ }
+
+ release_disp_frame(ps_app_ctx->cocodec_obj, u4_disp_id);
+
+ if(0 == file_save && 0 == chksum_save && 0 == mbinfo_save) return;
+
+ if(0 != mbinfo_save)
+ {
+ UWORD8 *buf;
+ if(ps_h264d_decode_op->pu1_8x8_blk_qp_map && ps_qp_file)
+ {
+ buf = ps_h264d_decode_op->pu1_8x8_blk_qp_map;
+ fwrite(buf, 1, ps_h264d_decode_op->u4_8x8_blk_qp_map_size, ps_qp_file);
+ fflush(ps_qp_file);
+ }
+ if(ps_h264d_decode_op->pu1_8x8_blk_type_map && ps_mb_type_file)
+ {
+ buf = ps_h264d_decode_op->pu1_8x8_blk_type_map;
+ fwrite(buf, 1, ps_h264d_decode_op->u4_8x8_blk_type_map_size, ps_mb_type_file);
+ fflush(ps_mb_type_file);
+ }
+ }
+ if(NULL == s_dump_disp_frm_buf.pv_y_buf) return;
+
+ if(ps_app_ctx->e_output_chroma_format == IV_YUV_420P)
+ {
+#if DUMP_SINGLE_BUF
+ {
+ UWORD8 *buf = s_dump_disp_frm_buf.pv_y_buf - 80 - (s_dump_disp_frm_buf.u4_y_strd * 80);
+
+ UWORD32 i4_size = s_dump_disp_frm_buf.u4_y_strd * ((s_dump_disp_frm_buf.u4_y_ht + 160) +
+ (s_dump_disp_frm_buf.u4_u_ht + 80));
+ fwrite(buf, 1, i4_size, ps_op_file);
+ }
+#else
+ if(0 != file_save && ps_op_file)
+ {
+ UWORD8 *buf;
+
+ buf = (UWORD8 *) s_dump_disp_frm_buf.pv_y_buf;
+ for(i = 0; i < s_dump_disp_frm_buf.u4_y_ht; i++)
+ {
+ fwrite(buf, 1, s_dump_disp_frm_buf.u4_y_wd, ps_op_file);
+ buf += s_dump_disp_frm_buf.u4_y_strd;
+ }
+
+ buf = (UWORD8 *) s_dump_disp_frm_buf.pv_u_buf;
+ for(i = 0; i < s_dump_disp_frm_buf.u4_u_ht; i++)
+ {
+ fwrite(buf, 1, s_dump_disp_frm_buf.u4_u_wd, ps_op_file);
+ buf += s_dump_disp_frm_buf.u4_u_strd;
+ }
+ buf = (UWORD8 *) s_dump_disp_frm_buf.pv_v_buf;
+ for(i = 0; i < s_dump_disp_frm_buf.u4_v_ht; i++)
+ {
+ fwrite(buf, 1, s_dump_disp_frm_buf.u4_v_wd, ps_op_file);
+ buf += s_dump_disp_frm_buf.u4_v_strd;
+ }
+ }
+
+ if(0 != chksum_save && ps_op_chksum_file)
+ {
+ UWORD8 au1_y_chksum[16];
+ UWORD8 au1_u_chksum[16];
+ UWORD8 au1_v_chksum[16];
+ calc_md5_cksum((UWORD8 *) s_dump_disp_frm_buf.pv_y_buf, s_dump_disp_frm_buf.u4_y_strd,
+ s_dump_disp_frm_buf.u4_y_wd, s_dump_disp_frm_buf.u4_y_ht, au1_y_chksum);
+ calc_md5_cksum((UWORD8 *) s_dump_disp_frm_buf.pv_u_buf, s_dump_disp_frm_buf.u4_u_strd,
+ s_dump_disp_frm_buf.u4_u_wd, s_dump_disp_frm_buf.u4_u_ht, au1_u_chksum);
+ calc_md5_cksum((UWORD8 *) s_dump_disp_frm_buf.pv_v_buf, s_dump_disp_frm_buf.u4_v_strd,
+ s_dump_disp_frm_buf.u4_v_wd, s_dump_disp_frm_buf.u4_v_ht, au1_v_chksum);
+
+ fwrite(au1_y_chksum, sizeof(UWORD8), 16, ps_op_chksum_file);
+ fwrite(au1_u_chksum, sizeof(UWORD8), 16, ps_op_chksum_file);
+ fwrite(au1_v_chksum, sizeof(UWORD8), 16, ps_op_chksum_file);
+ }
+#endif
+ }
+ else if((ps_app_ctx->e_output_chroma_format == IV_YUV_420SP_UV) ||
+ (ps_app_ctx->e_output_chroma_format == IV_YUV_420SP_VU))
+ {
+#if DUMP_SINGLE_BUF
+ {
+ UWORD8 *buf = s_dump_disp_frm_buf.pv_y_buf - 24 - (s_dump_disp_frm_buf.u4_y_strd * 40);
+
+ UWORD32 i4_size = s_dump_disp_frm_buf.u4_y_strd * ((s_dump_disp_frm_buf.u4_y_ht + 80) +
+ (s_dump_disp_frm_buf.u4_u_ht + 40));
+ fwrite(buf, 1, i4_size, ps_op_file);
+ }
+#else
+ {
+ UWORD8 *buf;
+
+ buf = (UWORD8 *) s_dump_disp_frm_buf.pv_y_buf;
+ for(i = 0; i < s_dump_disp_frm_buf.u4_y_ht; i++)
+ {
+ fwrite(buf, 1, s_dump_disp_frm_buf.u4_y_wd, ps_op_file);
+ buf += s_dump_disp_frm_buf.u4_y_strd;
+ }
+
+ buf = (UWORD8 *) s_dump_disp_frm_buf.pv_u_buf;
+ for(i = 0; i < s_dump_disp_frm_buf.u4_u_ht; i++)
+ {
+ fwrite(buf, 1, s_dump_disp_frm_buf.u4_u_wd, ps_op_file);
+ buf += s_dump_disp_frm_buf.u4_u_strd;
+ }
+ }
+#endif
+ }
+ else if(ps_app_ctx->e_output_chroma_format == IV_RGBA_8888)
+ {
+ UWORD8 *buf;
+
+ buf = (UWORD8 *) s_dump_disp_frm_buf.pv_y_buf;
+ for(i = 0; i < s_dump_disp_frm_buf.u4_y_ht; i++)
+ {
+ fwrite(buf, 1, s_dump_disp_frm_buf.u4_y_wd * 4, ps_op_file);
+ buf += s_dump_disp_frm_buf.u4_y_strd * 4;
+ }
+ }
+ else
+ {
+ UWORD8 *buf;
+
+ buf = (UWORD8 *) s_dump_disp_frm_buf.pv_y_buf;
+ for(i = 0; i < s_dump_disp_frm_buf.u4_y_ht; i++)
+ {
+ fwrite(buf, 1, s_dump_disp_frm_buf.u4_y_strd * 2, ps_op_file);
+ buf += s_dump_disp_frm_buf.u4_y_strd * 2;
+ }
+ }
+
+ fflush(ps_op_file);
+ fflush(ps_op_chksum_file);
+}
+
+/*****************************************************************************/
+/* */
+/* Function Name : print_usage */
+/* */
+/* Description : Prints argument format */
+/* */
+/* */
+/* Inputs : */
+/* Globals : */
+/* Processing : Prints argument format */
+/* */
+/* Outputs : */
+/* Returns : */
+/* */
+/* Issues : */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes */
+/* 06 09 2021 Kishore Initial Version */
+/* */
+/*****************************************************************************/
+
+void print_usage(void)
+{
+ WORD32 i = 0;
+ WORD32 num_entries = sizeof(argument_mapping) / sizeof(argument_t);
+ printf("\nUsage:\n");
+ while(i < num_entries)
+ {
+ printf("%-32s\t %s", argument_mapping[i].argument_name, argument_mapping[i].description);
+ i++;
+ }
+}
+
+/*****************************************************************************/
+/* */
+/* Function Name : get_argument */
+/* */
+/* Description : Gets argument for a given string */
+/* */
+/* */
+/* Inputs : name */
+/* Globals : */
+/* Processing : Searches the given string in the array and returns */
+/* appropriate argument ID */
+/* */
+/* Outputs : Argument ID */
+/* Returns : Argument ID */
+/* */
+/* Issues : */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes */
+/* 06 09 2021 Kishore Initial Version */
+/* */
+/*****************************************************************************/
+
+ARGUMENT_T get_argument(CHAR *name)
+{
+ WORD32 i = 0;
+ WORD32 num_entries = sizeof(argument_mapping) / sizeof(argument_t);
+ while(i < num_entries)
+ {
+ if((0 == strcmp(argument_mapping[i].argument_name, name)) ||
+ ((0 == strcmp(argument_mapping[i].argument_shortname, name)) &&
+ (0 != strcmp(argument_mapping[i].argument_shortname, "--"))))
+ {
+ return argument_mapping[i].argument;
+ }
+ i++;
+ }
+ return INVALID;
+}
+
+/*****************************************************************************/
+/* */
+/* Function Name : get_argument */
+/* */
+/* Description : Gets argument for a given string */
+/* */
+/* */
+/* Inputs : name */
+/* Globals : */
+/* Processing : Searches the given string in the array and returns */
+/* appropriate argument ID */
+/* */
+/* Outputs : Argument ID */
+/* Returns : Argument ID */
+/* */
+/* Issues : */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes */
+/* 06 09 2021 Kishore Initial Version */
+/* */
+/*****************************************************************************/
+
+void parse_argument(vid_dec_ctx_t *ps_app_ctx, CHAR *argument, CHAR *value)
+{
+ ARGUMENT_T arg;
+
+ arg = get_argument(argument);
+ switch(arg)
+ {
+ case HELP:
+ print_usage();
+ exit(-1);
+ case VERSION:
+ break;
+ case INPUT_FILE:
+ sscanf(value, "%" STR(STRLENGTH) "s", ps_app_ctx->ac_ip_fname);
+ // input_passed = 1;
+ break;
+
+ case OUTPUT:
+ sscanf(value, "%" STR(STRLENGTH) "s", ps_app_ctx->ac_op_fname);
+ break;
+
+ case QP_MAP_FILE:
+ sscanf(value, "%" STR(STRLENGTH) "s", ps_app_ctx->ac_qp_map_fname);
+ break;
+
+ case BLK_TYPE_MAP_FILE:
+ sscanf(value, "%" STR(STRLENGTH) "s", ps_app_ctx->ac_blk_type_map_fname);
+ break;
+
+ case CHKSUM:
+ sscanf(value, "%" STR(STRLENGTH) "s", ps_app_ctx->ac_op_chksum_fname);
+ break;
+
+ case SAVE_OUTPUT:
+ sscanf(value, "%d", &ps_app_ctx->u4_file_save_flag);
+ break;
+
+ case SAVE_FRAME_INFO:
+ sscanf(value, "%d", &ps_app_ctx->u4_frame_info_enable);
+ break;
+
+ case SAVE_CHKSUM:
+ sscanf(value, "%d", &ps_app_ctx->u4_chksum_save_flag);
+ break;
+
+ case CHROMA_FORMAT:
+ if((strcmp(value, "YUV_420P")) == 0)
+ ps_app_ctx->e_output_chroma_format = IV_YUV_420P;
+ else if((strcmp(value, "YUV_422ILE")) == 0)
+ ps_app_ctx->e_output_chroma_format = IV_YUV_422ILE;
+ else if((strcmp(value, "RGB_565")) == 0)
+ ps_app_ctx->e_output_chroma_format = IV_RGB_565;
+ else if((strcmp(value, "RGBA_8888")) == 0)
+ ps_app_ctx->e_output_chroma_format = IV_RGBA_8888;
+ else if((strcmp(value, "YUV_420SP_UV")) == 0)
+ ps_app_ctx->e_output_chroma_format = IV_YUV_420SP_UV;
+ else if((strcmp(value, "YUV_420SP_VU")) == 0)
+ ps_app_ctx->e_output_chroma_format = IV_YUV_420SP_VU;
+ else
+ {
+ printf("\nInvalid colour format setting it to IV_YUV_420P\n");
+ ps_app_ctx->e_output_chroma_format = IV_YUV_420P;
+ }
+
+ break;
+ case NUM_FRAMES:
+ sscanf(value, "%d", &ps_app_ctx->u4_max_frm_ts);
+ break;
+
+ case NUM_CORES:
+ sscanf(value, "%d", &ps_app_ctx->u4_num_cores);
+ break;
+ case DEGRADE_PICS:
+ sscanf(value, "%d", &ps_app_ctx->i4_degrade_pics);
+ break;
+ case DEGRADE_TYPE:
+ sscanf(value, "%d", &ps_app_ctx->i4_degrade_type);
+ break;
+ case SHARE_DISPLAY_BUF:
+ sscanf(value, "%d", &ps_app_ctx->u4_share_disp_buf);
+ break;
+ case LOOPBACK:
+ sscanf(value, "%d", &ps_app_ctx->loopback);
+ break;
+ case DISPLAY:
+#if defined(SDL_DISPLAY) || defined(FBDEV_DISPLAY) || defined(INTEL_CE5300) || defined(IOS_DISPLAY)
+ sscanf(value, "%d", &ps_app_ctx->display);
+#else
+ ps_app_ctx->display = 0;
+#endif
+ break;
+ case FULLSCREEN:
+ sscanf(value, "%d", &ps_app_ctx->full_screen);
+ break;
+ case FPS:
+ sscanf(value, "%d", &ps_app_ctx->fps);
+ if(ps_app_ctx->fps <= 0) ps_app_ctx->fps = DEFAULT_FPS;
+ break;
+ case ARCH:
+ if((strcmp(value, "ARM_NONEON")) == 0)
+ ps_app_ctx->e_arch = ARCH_ARM_NONEON;
+ else if((strcmp(value, "ARM_A9Q")) == 0)
+ ps_app_ctx->e_arch = ARCH_ARM_A9Q;
+ else if((strcmp(value, "ARM_A7")) == 0)
+ ps_app_ctx->e_arch = ARCH_ARM_A7;
+ else if((strcmp(value, "ARM_A5")) == 0)
+ ps_app_ctx->e_arch = ARCH_ARM_A5;
+ else if((strcmp(value, "ARM_NEONINTR")) == 0)
+ ps_app_ctx->e_arch = ARCH_ARM_NEONINTR;
+ else if((strcmp(value, "X86_GENERIC")) == 0)
+ ps_app_ctx->e_arch = ARCH_X86_GENERIC;
+ else if((strcmp(value, "X86_SSSE3")) == 0)
+ ps_app_ctx->e_arch = ARCH_X86_SSSE3;
+ else if((strcmp(value, "X86_SSE42")) == 0)
+ ps_app_ctx->e_arch = ARCH_X86_SSE42;
+ else if((strcmp(value, "X86_AVX2")) == 0)
+ ps_app_ctx->e_arch = ARCH_X86_AVX2;
+ else if((strcmp(value, "MIPS_GENERIC")) == 0)
+ ps_app_ctx->e_arch = ARCH_MIPS_GENERIC;
+ else if((strcmp(value, "MIPS_32")) == 0)
+ ps_app_ctx->e_arch = ARCH_MIPS_32;
+ else if((strcmp(value, "ARMV8_GENERIC")) == 0)
+ ps_app_ctx->e_arch = ARCH_ARMV8_GENERIC;
+ else
+ {
+ printf("\nInvalid Arch. Setting it to ARM_A9Q\n");
+ ps_app_ctx->e_arch = ARCH_ARM_A9Q;
+ }
+
+ break;
+ case SOC:
+ if((strcmp(value, "GENERIC")) == 0)
+ ps_app_ctx->e_soc = SOC_GENERIC;
+ else if((strcmp(value, "HISI_37X")) == 0)
+ ps_app_ctx->e_soc = SOC_HISI_37X;
+ else
+ {
+ ps_app_ctx->e_soc = atoi(value);
+ /*
+ printf("\nInvalid SOC. Setting it to GENERIC\n");
+ ps_app_ctx->e_soc = SOC_GENERIC;
+ */
+ }
+ break;
+ case PICLEN:
+ sscanf(value, "%d", &ps_app_ctx->u4_piclen_flag);
+ break;
+
+ case PICLEN_FILE:
+ sscanf(value, "%" STR(STRLENGTH) "s", ps_app_ctx->ac_piclen_fname);
+ break;
+ case DISABLE_DEBLOCK_LEVEL:
+ sscanf(value, "%d", &ps_app_ctx->u4_disable_dblk_level);
+ break;
+
+ case TARGET_LAYER_ID:
+ sscanf(value, "%d", &ps_app_ctx->i4_target_layer_id);
+ break;
+
+ case INVALID:
+ default:
+ printf("Ignoring argument : %s\n", argument);
+ break;
+ }
+}
+
+/*****************************************************************************/
+/* */
+/* Function Name : read_cfg_file */
+/* */
+/* Description : Reads arguments from a configuration file */
+/* */
+/* */
+/* Inputs : ps_app_ctx : Application context */
+/* fp_cfg_file : Configuration file handle */
+/* Globals : */
+/* Processing : Parses the arguments and fills in the application context*/
+/* */
+/* Outputs : Arguments parsed */
+/* Returns : None */
+/* */
+/* Issues : */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes */
+/* 06 09 2021 Kishore Initial Version */
+/* */
+/*****************************************************************************/
+
+void read_cfg_file(vid_dec_ctx_t *ps_app_ctx, FILE *fp_cfg_file)
+{
+ CHAR line[STRLENGTH];
+ CHAR description[STRLENGTH];
+ CHAR value[STRLENGTH];
+ CHAR argument[STRLENGTH];
+ void *ret;
+ while(0 == feof(fp_cfg_file))
+ {
+ line[0] = '\0';
+ ret = fgets(line, STRLENGTH, fp_cfg_file);
+ if(NULL == ret) break;
+ argument[0] = '\0';
+ /* Reading Input File Name */
+ sscanf(line, "%s %s %s", argument, value, description);
+ if(argument[0] == '\0') continue;
+
+ parse_argument(ps_app_ctx, argument, value);
+ }
+}
+
+/*!
+**************************************************************************
+* \if Function name : dispq_producer_dequeue \endif
+*
+* \brief
+* This function gets a free buffer index where display data can be written
+* This is a blocking call and can be exited by setting quit to true in
+* the application context
+*
+* \param[in] ps_app_ctx : Pointer to application context
+*
+* \return
+* returns Next free buffer index for producer
+*
+* \author
+* Ittiam
+*
+**************************************************************************
+*/
+WORD32 dispq_producer_dequeue(vid_dec_ctx_t *ps_app_ctx)
+{
+ WORD32 idx;
+
+ /* If there is no free buffer wait */
+
+ while(((ps_app_ctx->disp_q_wr_idx + 1) % NUM_DISPLAY_BUFFERS) == ps_app_ctx->disp_q_rd_idx)
+ {
+ ithread_sleep(1000);
+
+ if(ps_app_ctx->quit) return (-1);
+ }
+
+ idx = ps_app_ctx->disp_q_wr_idx;
+ return (idx);
+}
+
+/*!
+**************************************************************************
+* \if Function name : dispq_producer_queue \endif
+*
+* \brief
+* This function adds buffer which can be displayed
+*
+* \param[in] ps_app_ctx : Pointer to application context
+*
+* \return
+* returns Next free buffer index for producer
+*
+* \author
+* Ittiam
+*
+**************************************************************************
+*/
+WORD32 dispq_producer_queue(vid_dec_ctx_t *ps_app_ctx)
+{
+ ps_app_ctx->disp_q_wr_idx++;
+ if(ps_app_ctx->disp_q_wr_idx == NUM_DISPLAY_BUFFERS) ps_app_ctx->disp_q_wr_idx = 0;
+
+ return (0);
+}
+/*!
+**************************************************************************
+* \if Function name : dispq_consumer_dequeue \endif
+*
+* \brief
+* This function gets a free buffer index where display data can be written
+* This is a blocking call and can be exited by setting quit to true in
+* the application context
+*
+* \param[in] ps_app_ctx : Pointer to application context
+*
+* \return
+* returns Next free buffer index for producer
+*
+* \author
+* Ittiam
+*
+**************************************************************************
+*/
+WORD32 dispq_consumer_dequeue(vid_dec_ctx_t *ps_app_ctx)
+{
+ WORD32 idx;
+
+ /* If there is no free buffer wait */
+
+ while(ps_app_ctx->disp_q_wr_idx == ps_app_ctx->disp_q_rd_idx)
+ {
+ ithread_sleep(1000);
+
+ if(ps_app_ctx->quit) return (-1);
+ }
+
+ idx = ps_app_ctx->disp_q_rd_idx;
+ return (idx);
+}
+
+/*!
+**************************************************************************
+* \if Function name : dispq_producer_queue \endif
+*
+* \brief
+* This function adds buffer which can be displayed
+*
+* \param[in] ps_app_ctx : Pointer to application context
+*
+* \return
+* returns Next free buffer index for producer
+*
+* \author
+* Ittiam
+*
+**************************************************************************
+*/
+WORD32 dispq_consumer_queue(vid_dec_ctx_t *ps_app_ctx)
+{
+ ps_app_ctx->disp_q_rd_idx++;
+ if(ps_app_ctx->disp_q_rd_idx == NUM_DISPLAY_BUFFERS) ps_app_ctx->disp_q_rd_idx = 0;
+
+ return (0);
+}
+
+/*****************************************************************************/
+/* */
+/* Function Name : display_thread */
+/* */
+/* Description : Thread to display the frame */
+/* */
+/* */
+/* Inputs : pv_ctx : Application context */
+/* */
+/* Globals : */
+/* Processing : Wait for a buffer to get produced by decoder and display */
+/* that frame */
+/* */
+/* Outputs : */
+/* Returns : None */
+/* */
+/* Issues : Pause followed by quit is making some deadlock condn */
+/* If decoder was lagging initially and then fasten up, */
+/* display will also go at faster rate till it reaches */
+/* equilibrium wrt the initial time */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes */
+/* 06 09 2021 Kishore Initial Version */
+/* */
+/*****************************************************************************/
+
+WORD32 display_thread(void *pv_ctx)
+{
+ vid_dec_ctx_t *ps_app_ctx = (vid_dec_ctx_t *) pv_ctx;
+
+ UWORD32 frm_duration; /* in us */
+ UWORD32 current_time = 0;
+ UWORD32 expected_time;
+ UWORD32 first_frame_displayed;
+
+#ifdef WINDOWS_TIMER
+ LARGE_INTEGER frequency;
+#endif
+
+#ifdef WINDOWS_TIMER
+ QueryPerformanceFrequency(&frequency);
+#endif
+
+#ifdef PROFILE_ENABLE
+ UWORD32 s_elapsed_time;
+ TIMER s_start_timer;
+ TIMER s_end_timer;
+ TIMER s_first_frame_time;
+#endif
+
+ first_frame_displayed = 0;
+ expected_time = 0;
+ frm_duration = 1000000 / ps_app_ctx->fps;
+
+ /* Init display and allocate display buffers */
+ ps_app_ctx->pv_disp_ctx = (void *) ps_app_ctx->disp_init(
+ ps_app_ctx->u4_pic_wd, ps_app_ctx->u4_pic_ht, ps_app_ctx->i4_screen_wd,
+ ps_app_ctx->i4_screen_ht, ps_app_ctx->u4_pic_wd, ps_app_ctx->u4_pic_ht,
+ ps_app_ctx->full_screen, &ps_app_ctx->quit, &ps_app_ctx->paused);
+ ps_app_ctx->alloc_disp_buffers(ps_app_ctx->pv_disp_ctx);
+
+ ps_app_ctx->display_init_done = 1;
+
+ while(1)
+ {
+ WORD32 rd_idx;
+
+ rd_idx = dispq_consumer_dequeue(ps_app_ctx);
+ if(ps_app_ctx->quit) break;
+
+ ps_app_ctx->display_buffer(ps_app_ctx->pv_disp_ctx, rd_idx);
+
+ if(0 == first_frame_displayed)
+ {
+ GETTIME(&s_first_frame_time);
+ first_frame_displayed = 1;
+ }
+
+ /*********************************************************************/
+ /* Sleep based on the expected time of arrival of current buffer and */
+ /* the Current frame */
+ /*********************************************************************/
+
+ GETTIME(&s_end_timer);
+ ELAPSEDTIME(s_first_frame_time, s_end_timer, current_time, frequency);
+
+ /* time in micro second */
+ expected_time += frm_duration;
+
+ // printf("current_time %d expected_time %d diff %d \n", current_time,
+ // expected_time, (expected_time - current_time));
+ /* sleep for the diff. in time */
+ if(current_time < expected_time)
+ ps_app_ctx->disp_usleep((expected_time - current_time));
+ else
+ expected_time += (current_time - expected_time);
+
+ dispq_consumer_queue(ps_app_ctx);
+ }
+
+ while(0 == ps_app_ctx->display_deinit_flag)
+ {
+ ps_app_ctx->disp_usleep(1000);
+ }
+ ps_app_ctx->disp_deinit(ps_app_ctx->pv_disp_ctx);
+
+ return 0;
+}
+
+void output_write_stall(CHAR *fname, UWORD32 cur_frm_idx)
+{
+ const UWORD8 threshold = 64;
+ CHAR past_fname[1000];
+ FILE *fp_fast_file = NULL;
+
+ if(cur_frm_idx >= threshold)
+ {
+ sprintf(past_fname, fname, cur_frm_idx - threshold);
+ do
+ {
+ fp_fast_file = fopen(past_fname, "rb");
+ if(fp_fast_file != NULL)
+ {
+ fclose(fp_fast_file);
+ /* Wait until the resource is released by a third party app*/
+ ithread_sleep(5000);
+ }
+ else
+ break;
+ } while(1);
+ }
+}
+
+void 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)
+{
+ WORD32 ret;
+
+ do
+ {
+ ivd_ctl_flush_ip_t s_ctl_ip;
+ ivd_ctl_flush_op_t s_ctl_op;
+
+ if(*pu4_op_frm_ts >= (ps_app_ctx->u4_max_frm_ts + ps_app_ctx->disp_delay)) break;
+
+ s_ctl_ip.e_cmd = IVD_CMD_VIDEO_CTL;
+ s_ctl_ip.e_sub_cmd = IVD_CMD_CTL_FLUSH;
+ s_ctl_ip.u4_size = sizeof(ivd_ctl_flush_ip_t);
+ s_ctl_op.u4_size = sizeof(ivd_ctl_flush_op_t);
+ ret = ivd_api_function((iv_obj_t *) codec_obj, (void *) &s_ctl_ip, (void *) &s_ctl_op);
+
+ if(ret != IV_SUCCESS)
+ {
+ printf("Error in Setting the decoder in flush mode\n");
+ }
+
+ if(IV_SUCCESS == ret)
+ {
+ isvcd_video_decode_ip_t s_h264d_decode_ip;
+ isvcd_video_decode_op_t s_h264d_decode_op;
+ ivd_video_decode_ip_t *ps_video_decode_ip = &s_h264d_decode_ip.s_ivd_video_decode_ip_t;
+ ivd_video_decode_op_t *ps_video_decode_op = &s_h264d_decode_op.s_ivd_video_decode_op_t;
+
+ ps_video_decode_ip->e_cmd = IVD_CMD_VIDEO_DECODE;
+ ps_video_decode_ip->u4_ts = u4_ip_frm_ts;
+ ps_video_decode_ip->pv_stream_buffer = pu1_bs_buf;
+ ps_video_decode_ip->u4_num_Bytes = u4_bytes_remaining;
+ ps_video_decode_ip->u4_size = sizeof(isvcd_video_decode_ip_t);
+ ps_video_decode_ip->s_out_buffer.u4_min_out_buf_size[0] =
+ ps_out_buf->u4_min_out_buf_size[0];
+ ps_video_decode_ip->s_out_buffer.u4_min_out_buf_size[1] =
+ ps_out_buf->u4_min_out_buf_size[1];
+ ps_video_decode_ip->s_out_buffer.u4_min_out_buf_size[2] =
+ ps_out_buf->u4_min_out_buf_size[2];
+
+ ps_video_decode_ip->s_out_buffer.pu1_bufs[0] = ps_out_buf->pu1_bufs[0];
+ ps_video_decode_ip->s_out_buffer.pu1_bufs[1] = ps_out_buf->pu1_bufs[1];
+ ps_video_decode_ip->s_out_buffer.pu1_bufs[2] = ps_out_buf->pu1_bufs[2];
+ ps_video_decode_ip->s_out_buffer.u4_num_bufs = ps_out_buf->u4_num_bufs;
+
+ ps_video_decode_op->u4_size = sizeof(isvcd_video_decode_op_t);
+ s_h264d_decode_ip.pu1_8x8_blk_qp_map = pu1_qp_map_buf;
+ s_h264d_decode_ip.pu1_8x8_blk_type_map = pu1_blk_type_map_buf;
+ s_h264d_decode_ip.u4_8x8_blk_qp_map_size = (ADAPTIVE_MAX_HT * ADAPTIVE_MAX_WD) >> 6;
+ s_h264d_decode_ip.u4_8x8_blk_type_map_size = (ADAPTIVE_MAX_HT * ADAPTIVE_MAX_WD) >> 6;
+
+ /*****************************************************************************/
+ /* API Call: Video Decode */
+ /*****************************************************************************/
+ ret = ivd_api_function((iv_obj_t *) codec_obj, (void *) &s_h264d_decode_ip,
+ (void *) &s_h264d_decode_op);
+
+ if(1 == ps_video_decode_op->u4_output_present)
+ {
+ CHAR cur_fname[1000];
+ CHAR *extn = NULL;
+ /* The objective is to dump the decoded frames into separate files
+ * instead of dumping all the frames in one common file. Also, the
+ * number of dumped frames at any given instance of time cannot exceed
+ * 'frame_memory'
+ */
+
+ /*************************************************************************/
+ /* Get SEI MDCV parameters */
+ /*************************************************************************/
+ if(1 == ps_video_decode_op->s_sei_decode_op.u1_sei_mdcv_params_present_flag)
+ {
+ isvcd_ctl_get_sei_mdcv_params_ip_t s_ctl_get_sei_mdcv_params_ip;
+ isvcd_ctl_get_sei_mdcv_params_op_t s_ctl_get_sei_mdcv_params_op;
+
+ memset(&s_ctl_get_sei_mdcv_params_ip, 0,
+ sizeof(isvcd_ctl_get_sei_mdcv_params_ip_t));
+ memset(&s_ctl_get_sei_mdcv_params_op, 0,
+ sizeof(isvcd_ctl_get_sei_mdcv_params_op_t));
+
+ s_ctl_get_sei_mdcv_params_ip.e_cmd = IVD_CMD_VIDEO_CTL;
+ s_ctl_get_sei_mdcv_params_ip.e_sub_cmd =
+ (IVD_CONTROL_API_COMMAND_TYPE_T) IH264D_CMD_CTL_GET_SEI_MDCV_PARAMS;
+ s_ctl_get_sei_mdcv_params_ip.u4_size =
+ sizeof(isvcd_ctl_get_sei_mdcv_params_ip_t);
+ s_ctl_get_sei_mdcv_params_op.u4_size =
+ sizeof(isvcd_ctl_get_sei_mdcv_params_op_t);
+
+ ret = ivd_api_function((iv_obj_t *) codec_obj,
+ (void *) &s_ctl_get_sei_mdcv_params_ip,
+ (void *) &s_ctl_get_sei_mdcv_params_op);
+
+ if(IV_SUCCESS != ret)
+ {
+ printf("MDCV SEI params not present : Error %x\n",
+ s_ctl_get_sei_mdcv_params_op.u4_error_code);
+ }
+ }
+ /*************************************************************************/
+ /* Get SEI CLL parameters */
+ /*************************************************************************/
+ if(1 == ps_video_decode_op->s_sei_decode_op.u1_sei_cll_params_present_flag)
+ {
+ isvcd_ctl_get_sei_cll_params_ip_t s_ctl_get_sei_cll_params_ip;
+ isvcd_ctl_get_sei_cll_params_op_t s_ctl_get_sei_cll_params_op;
+
+ memset(&s_ctl_get_sei_cll_params_ip, 0,
+ sizeof(isvcd_ctl_get_sei_cll_params_ip_t));
+ memset(&s_ctl_get_sei_cll_params_op, 0,
+ sizeof(isvcd_ctl_get_sei_cll_params_op_t));
+
+ s_ctl_get_sei_cll_params_ip.e_cmd = IVD_CMD_VIDEO_CTL;
+ s_ctl_get_sei_cll_params_ip.e_sub_cmd =
+ (IVD_CONTROL_API_COMMAND_TYPE_T) IH264D_CMD_CTL_GET_SEI_CLL_PARAMS;
+ s_ctl_get_sei_cll_params_ip.u4_size = sizeof(isvcd_ctl_get_sei_cll_params_ip_t);
+ s_ctl_get_sei_cll_params_op.u4_size = sizeof(isvcd_ctl_get_sei_cll_params_op_t);
+
+ ret = ivd_api_function((iv_obj_t *) codec_obj,
+ (void *) &s_ctl_get_sei_cll_params_ip,
+ (void *) &s_ctl_get_sei_cll_params_op);
+
+ if(IV_SUCCESS != ret)
+ {
+ printf("CLL SEI params not present : Error %x\n",
+ s_ctl_get_sei_cll_params_op.u4_error_code);
+ }
+ }
+ /*************************************************************************/
+ /* Get SEI AVE parameters */
+ /*************************************************************************/
+ if(1 == ps_video_decode_op->s_sei_decode_op.u1_sei_ave_params_present_flag)
+ {
+ isvcd_ctl_get_sei_ave_params_ip_t s_ctl_get_sei_ave_params_ip;
+ isvcd_ctl_get_sei_ave_params_op_t s_ctl_get_sei_ave_params_op;
+
+ memset(&s_ctl_get_sei_ave_params_ip, 0,
+ sizeof(isvcd_ctl_get_sei_ave_params_ip_t));
+ memset(&s_ctl_get_sei_ave_params_op, 0,
+ sizeof(isvcd_ctl_get_sei_ave_params_op_t));
+
+ s_ctl_get_sei_ave_params_ip.e_cmd = IVD_CMD_VIDEO_CTL;
+ s_ctl_get_sei_ave_params_ip.e_sub_cmd =
+ (IVD_CONTROL_API_COMMAND_TYPE_T) IH264D_CMD_CTL_GET_SEI_AVE_PARAMS;
+ s_ctl_get_sei_ave_params_ip.u4_size = sizeof(isvcd_ctl_get_sei_ave_params_ip_t);
+ s_ctl_get_sei_ave_params_op.u4_size = sizeof(isvcd_ctl_get_sei_ave_params_op_t);
+
+ ret = ivd_api_function((iv_obj_t *) codec_obj,
+ (void *) &s_ctl_get_sei_ave_params_ip,
+ (void *) &s_ctl_get_sei_ave_params_op);
+
+ if(IV_SUCCESS != ret)
+ {
+ printf("AVE SEI params not present : Error %x\n",
+ s_ctl_get_sei_ave_params_op.u4_error_code);
+ }
+ }
+ /*************************************************************************/
+ /* Get SEI CCV parameters */
+ /*************************************************************************/
+ if(1 == ps_video_decode_op->s_sei_decode_op.u1_sei_ccv_params_present_flag)
+ {
+ isvcd_ctl_get_sei_ccv_params_ip_t s_ctl_get_sei_ccv_params_ip;
+ isvcd_ctl_get_sei_ccv_params_op_t s_ctl_get_sei_ccv_params_op;
+
+ memset(&s_ctl_get_sei_ccv_params_ip, 0,
+ sizeof(isvcd_ctl_get_sei_ccv_params_ip_t));
+ memset(&s_ctl_get_sei_ccv_params_op, 0,
+ sizeof(isvcd_ctl_get_sei_ccv_params_op_t));
+
+ s_ctl_get_sei_ccv_params_ip.e_cmd = IVD_CMD_VIDEO_CTL;
+ s_ctl_get_sei_ccv_params_ip.e_sub_cmd =
+ (IVD_CONTROL_API_COMMAND_TYPE_T) IH264D_CMD_CTL_GET_SEI_CCV_PARAMS;
+ s_ctl_get_sei_ccv_params_ip.u4_size = sizeof(isvcd_ctl_get_sei_ccv_params_ip_t);
+ s_ctl_get_sei_ccv_params_op.u4_size = sizeof(isvcd_ctl_get_sei_ccv_params_op_t);
+
+ ret = ivd_api_function((iv_obj_t *) codec_obj,
+ (void *) &s_ctl_get_sei_ccv_params_ip,
+ (void *) &s_ctl_get_sei_ccv_params_op);
+
+ if(IV_SUCCESS != ret)
+ {
+ printf("CCV SEI params not present : Error %x\n",
+ s_ctl_get_sei_ccv_params_op.u4_error_code);
+ }
+ }
+
+ if(ps_app_ctx->u4_file_save_flag)
+ {
+ /* Locate the position of extension yuv */
+ extn = strstr(ps_app_ctx->ac_op_fname, "%d");
+ if(extn != NULL)
+ {
+ output_write_stall(ps_app_ctx->ac_op_fname, *pu4_op_frm_ts);
+ /* Generate output file names */
+ sprintf(cur_fname, ps_app_ctx->ac_op_fname, *pu4_op_frm_ts);
+ /* Open Output file */
+ ps_op_file = fopen(cur_fname, "wb");
+ if(NULL == ps_op_file)
+ {
+ CHAR ac_error_str[STRLENGTH];
+ snprintf(ac_error_str, sizeof(ac_error_str),
+ "Could not open output file %s", cur_fname);
+
+ codec_exit(ac_error_str);
+ }
+ }
+ }
+
+ dump_output(ps_app_ctx, &(ps_video_decode_op->s_disp_frm_buf), &s_h264d_decode_op,
+ ps_video_decode_op->u4_disp_buf_id, ps_op_file, ps_qp_file,
+ ps_mb_type_file, ps_op_chksum_file, *pu4_op_frm_ts,
+ ps_app_ctx->u4_file_save_flag, ps_app_ctx->u4_chksum_save_flag,
+ ps_app_ctx->u4_frame_info_enable);
+ if(extn != NULL) fclose(ps_op_file);
+ (*pu4_op_frm_ts)++;
+ }
+ }
+ } while(IV_SUCCESS == ret);
+}
+
+#ifdef X86_MINGW
+void sigsegv_handler()
+{
+ printf("Segmentation fault, Exiting.. \n");
+ exit(-1);
+}
+#endif
+
+UWORD32 default_get_stride(void) { return 0; }
+
+IV_COLOR_FORMAT_T default_get_color_fmt(void) { return IV_YUV_420P; }
+/*****************************************************************************/
+/* */
+/* Function Name : main */
+/* */
+/* Description : Application to demonstrate codec API */
+/* */
+/* */
+/* Inputs : argc - Number of arguments */
+/* argv[] - Arguments */
+/* Globals : */
+/* Processing : Shows how to use create, process, control and delete */
+/* */
+/* Outputs : Codec output in a file */
+/* Returns : */
+/* */
+/* Issues : Assumes both PROFILE_ENABLE to be */
+/* defined for multithread decode-display working */
+/* */
+/* Revision History: */
+/* */
+/* DD MM YYYY Author(s) Changes */
+/* 06 09 2021 Kishore Initial Version */
+/*****************************************************************************/
+#ifdef IOS
+int h264dec_main(char *homedir, char *documentdir, int screen_wd, int screen_ht)
+#else
+int main(WORD32 argc, CHAR *argv[])
+#endif
+{
+ CHAR ac_cfg_fname[STRLENGTH];
+ FILE *fp_cfg_file = NULL;
+ FILE *ps_piclen_file = NULL;
+ FILE *ps_ip_file = NULL;
+ FILE *ps_op_file = NULL;
+ FILE *ps_qp_file = NULL;
+ FILE *ps_mb_type_file = NULL;
+ FILE *ps_op_chksum_file = NULL;
+ WORD32 ret;
+ CHAR ac_error_str[STRLENGTH];
+ vid_dec_ctx_t s_app_ctx;
+ UWORD8 *pu1_bs_buf = NULL;
+ UWORD8 *pu1_qp_map_buf = NULL;
+ UWORD8 *pu1_blk_type_map_buf = NULL;
+
+ ivd_out_bufdesc_t *ps_out_buf;
+ UWORD32 u4_num_bytes_dec = 0;
+ UWORD32 file_pos = 0;
+
+ UWORD32 u4_ip_frm_ts = 0, u4_op_frm_ts = 0;
+
+ WORD32 u4_bytes_remaining = 0;
+ UWORD32 i;
+ UWORD32 u4_ip_buf_len;
+ WORD32 total_bytes_comsumed;
+ UWORD32 max_op_frm_ts;
+ UWORD32 u4_num_disp_bufs_with_dec;
+
+#ifdef PROFILE_ENABLE
+ UWORD32 u4_tot_cycles = 0;
+ UWORD32 frm_cnt = 0;
+ UWORD32 u4_tot_fmt_cycles = 0;
+ UWORD32 peak_window[PEAK_WINDOW_SIZE];
+ UWORD32 peak_window_idx = 0;
+ UWORD32 peak_avg_max = 0;
+#ifdef INTEL_CE5300
+ UWORD32 time_consumed = 0;
+ UWORD32 bytes_consumed = 0;
+#endif
+#endif
+
+#ifdef WINDOWS_TIMER
+ LARGE_INTEGER frequency;
+#endif
+#ifdef PROFILE_ENABLE
+ WORD32 width = 0, height = 0;
+#endif
+ iv_obj_t *codec_obj;
+#if defined(GPU_BUILD) && !defined(X86)
+// int ioctl_init();
+// ioctl_init();
+#endif
+
+#ifdef X86_MINGW
+ // For getting printfs without any delay
+ setvbuf(stdout, NULL, _IONBF, 0);
+ setvbuf(stderr, NULL, _IONBF, 0);
+#endif
+#ifdef IOS
+ sprintf(filename_trace, "%s/iostrace.txt", homedir);
+ printf("\ntrace file name = %s", filename_trace);
+#endif
+
+#ifdef X86_MINGW
+ {
+ signal(SIGSEGV, sigsegv_handler);
+ }
+#endif
+
+#ifndef IOS
+ /* Usage */
+ if(argc < 2)
+ {
+ printf("Using test.cfg as configuration file \n");
+ strcpy(ac_cfg_fname, "test.cfg");
+ }
+ else if(argc == 2)
+ {
+ strcpy(ac_cfg_fname, argv[1]);
+ }
+
+#else
+ strcpy(ac_cfg_fname, "test.cfg");
+
+#endif
+
+ /***********************************************************************/
+ /* Initialize Application parameters */
+ /***********************************************************************/
+
+ strcpy(s_app_ctx.ac_ip_fname, "\0");
+ s_app_ctx.dump_q_wr_idx = 0;
+ s_app_ctx.dump_q_rd_idx = 0;
+ s_app_ctx.display_thread_created = 0;
+ s_app_ctx.disp_q_wr_idx = 0;
+ s_app_ctx.disp_q_rd_idx = 0;
+ s_app_ctx.disp_delay = 0;
+ s_app_ctx.loopback = 0;
+ s_app_ctx.display = 0;
+ s_app_ctx.full_screen = 0;
+ s_app_ctx.u4_piclen_flag = 0;
+ s_app_ctx.fps = DEFAULT_FPS;
+ file_pos = 0;
+ total_bytes_comsumed = 0;
+ u4_ip_frm_ts = 0;
+ u4_op_frm_ts = 0;
+#ifdef PROFILE_ENABLE
+ memset(peak_window, 0, sizeof(WORD32) * PEAK_WINDOW_SIZE);
+#endif
+ s_app_ctx.u4_share_disp_buf = DEFAULT_SHARE_DISPLAY_BUF;
+ s_app_ctx.u4_num_cores = DEFAULT_NUM_CORES;
+ s_app_ctx.i4_degrade_type = 0;
+ s_app_ctx.i4_degrade_pics = 0;
+ s_app_ctx.e_arch = ARCH_ARM_A9Q;
+ s_app_ctx.e_soc = SOC_GENERIC;
+ s_app_ctx.i4_target_layer_id = 0;
+
+ s_app_ctx.u4_strd = STRIDE;
+
+ s_app_ctx.display_thread_handle = malloc(ithread_get_handle_size());
+ s_app_ctx.quit = 0;
+ s_app_ctx.paused = 0;
+ // s_app_ctx.u4_output_present = 0;
+ s_app_ctx.u4_chksum_save_flag = 0;
+ s_app_ctx.u4_frame_info_enable = 0;
+
+ s_app_ctx.get_stride = &default_get_stride;
+
+ s_app_ctx.get_color_fmt = &default_get_color_fmt;
+
+ /* Set function pointers for display */
+#ifdef SDL_DISPLAY
+ s_app_ctx.disp_init = &sdl_disp_init;
+ s_app_ctx.alloc_disp_buffers = &sdl_alloc_disp_buffers;
+ s_app_ctx.display_buffer = &sdl_display;
+ s_app_ctx.set_disp_buffers = &sdl_set_disp_buffers;
+ s_app_ctx.disp_deinit = &sdl_disp_deinit;
+ s_app_ctx.disp_usleep = &sdl_disp_usleep;
+ s_app_ctx.get_color_fmt = &sdl_get_color_fmt;
+ s_app_ctx.get_stride = &sdl_get_stride;
+#endif
+
+#ifdef FBDEV_DISPLAY
+ s_app_ctx.disp_init = &fbd_disp_init;
+ s_app_ctx.alloc_disp_buffers = &fbd_alloc_disp_buffers;
+ s_app_ctx.display_buffer = &fbd_display;
+ s_app_ctx.set_disp_buffers = &fbd_set_disp_buffers;
+ s_app_ctx.disp_deinit = &fbd_disp_deinit;
+ s_app_ctx.disp_usleep = &fbd_disp_usleep;
+ s_app_ctx.get_color_fmt = &fbd_get_color_fmt;
+ s_app_ctx.get_stride = &fbd_get_stride;
+#endif
+
+#ifdef INTEL_CE5300
+ s_app_ctx.disp_init = &gdl_disp_init;
+ s_app_ctx.alloc_disp_buffers = &gdl_alloc_disp_buffers;
+ s_app_ctx.display_buffer = &gdl_display;
+ s_app_ctx.set_disp_buffers = &gdl_set_disp_buffers;
+ s_app_ctx.disp_deinit = &gdl_disp_deinit;
+ s_app_ctx.disp_usleep = &gdl_disp_usleep;
+ s_app_ctx.get_color_fmt = &gdl_get_color_fmt;
+ s_app_ctx.get_stride = &gdl_get_stride;
+#endif
+
+#ifdef IOS_DISPLAY
+ s_app_ctx.disp_init = &ios_disp_init;
+ s_app_ctx.alloc_disp_buffers = &ios_alloc_disp_buffers;
+ s_app_ctx.display_buffer = &ios_display;
+ s_app_ctx.set_disp_buffers = &ios_set_disp_buffers;
+ s_app_ctx.disp_deinit = &ios_disp_deinit;
+ s_app_ctx.disp_usleep = &ios_disp_usleep;
+ s_app_ctx.get_color_fmt = &ios_get_color_fmt;
+ s_app_ctx.get_stride = &ios_get_stride;
+#endif
+
+ s_app_ctx.display_deinit_flag = 0;
+ s_app_ctx.e_output_chroma_format = IV_YUV_420SP_UV;
+ /*************************************************************************/
+ /* Parse arguments */
+ /*************************************************************************/
+
+#ifndef IOS
+ /* Read command line arguments */
+ if(argc > 2)
+ {
+ for(i = 1; i < (UWORD32) argc; i += 2)
+ {
+ if(CONFIG == get_argument(argv[i]))
+ {
+ strcpy(ac_cfg_fname, argv[i + 1]);
+ if((fp_cfg_file = fopen(ac_cfg_fname, "r")) == NULL)
+ {
+ snprintf(ac_error_str, sizeof(ac_error_str),
+ "Could not open Configuration file %s", ac_cfg_fname);
+ codec_exit(ac_error_str);
+ }
+ read_cfg_file(&s_app_ctx, fp_cfg_file);
+ fclose(fp_cfg_file);
+ }
+ else
+ {
+ parse_argument(&s_app_ctx, argv[i], argv[i + 1]);
+ }
+ }
+ }
+ else
+ {
+ if((fp_cfg_file = fopen(ac_cfg_fname, "r")) == NULL)
+ {
+ snprintf(ac_error_str, sizeof(ac_error_str), "Could not open Configuration file %s",
+ ac_cfg_fname);
+ codec_exit(ac_error_str);
+ }
+ read_cfg_file(&s_app_ctx, fp_cfg_file);
+ fclose(fp_cfg_file);
+ }
+#else
+ snprintf(filename_with_path, sizeof(filename_with_path), "%s/%s", homedir, ac_cfg_fname);
+ if((fp_cfg_file = fopen(filename_with_path, "r")) == NULL)
+ {
+ snprintf(ac_error_str, sizeof(ac_error_str), "Could not open Configuration file %s",
+ ac_cfg_fname);
+ codec_exit(ac_error_str);
+ }
+ read_cfg_file(&s_app_ctx, fp_cfg_file);
+ fclose(fp_cfg_file);
+
+#endif
+#ifdef PRINT_PICSIZE
+ /* If the binary is used for only getting number of bytes in each picture,
+ * then disable the following features */
+ s_app_ctx.u4_piclen_flag = 0;
+ s_app_ctx.u4_file_save_flag = 0;
+ s_app_ctx.u4_chksum_save_flag = 0;
+ s_app_ctx.i4_degrade_pics = 0;
+ s_app_ctx.i4_degrade_type = 0;
+ s_app_ctx.loopback = 0;
+ s_app_ctx.u4_share_disp_buf = 0;
+ s_app_ctx.display = 0;
+#endif
+
+ /* If display is enabled, then turn off shared mode and get color format that
+ * is supported by display */
+ if(1 == s_app_ctx.display)
+ {
+ s_app_ctx.u4_share_disp_buf = 0;
+ s_app_ctx.e_output_chroma_format = s_app_ctx.get_color_fmt();
+ }
+ if(strcmp(s_app_ctx.ac_ip_fname, "\0") == 0)
+ {
+ printf("\nNo input file given for decoding\n");
+ exit(-1);
+ }
+
+ if(1 == s_app_ctx.u4_frame_info_enable)
+ {
+ pu1_qp_map_buf = calloc((ADAPTIVE_MAX_HT * ADAPTIVE_MAX_WD) >> 6, 1);
+ pu1_blk_type_map_buf = calloc((ADAPTIVE_MAX_HT * ADAPTIVE_MAX_WD) >> 6, 1);
+ }
+
+ /***********************************************************************/
+ /* create the file object for input file */
+ /***********************************************************************/
+#ifdef IOS
+ snprintf(filename_with_path, sizeof(filename_with_path), "%s/%s", homedir,
+ s_app_ctx.ac_ip_fname);
+ ps_ip_file = fopen(filename_with_path, "rb");
+#else
+ ps_ip_file = fopen(s_app_ctx.ac_ip_fname, "rb");
+#endif
+ if(NULL == ps_ip_file)
+ {
+ snprintf(ac_error_str, sizeof(ac_error_str), "Could not open input file %s",
+ s_app_ctx.ac_ip_fname);
+ codec_exit(ac_error_str);
+ }
+ /***********************************************************************/
+ /* create the file object for input file */
+ /***********************************************************************/
+ if(1 == s_app_ctx.u4_piclen_flag)
+ {
+#ifdef IOS
+ snprintf(filename_with_path, sizeof(filename_with_path), "%s/%s",
+ s_app_ctx.ac_piclen_fname);
+ ps_piclen_file = fopen(filename_with_path, "rb");
+#else
+ ps_piclen_file = fopen(s_app_ctx.ac_piclen_fname, "rb");
+#endif
+ if(NULL == ps_piclen_file)
+ {
+ snprintf(ac_error_str, sizeof(ac_error_str), "Could not open piclen file %s",
+ s_app_ctx.ac_piclen_fname);
+ codec_exit(ac_error_str);
+ }
+ }
+
+ /***********************************************************************/
+ /* create the file object for output file */
+ /***********************************************************************/
+
+ /* If the filename does not contain %d, then output will be dumped to
+ a single file and it is opened here */
+ if((1 == s_app_ctx.u4_file_save_flag) && (strstr(s_app_ctx.ac_op_fname, "%d") == NULL))
+ {
+#ifdef IOS
+ snprintf(filename_with_path, sizeof(filename_with_path), "%s/%s", documentdir,
+ s_app_ctx.ac_op_fname);
+ ps_op_file = fopen(filename_with_path, "wb");
+#else
+ ps_op_file = fopen(s_app_ctx.ac_op_fname, "wb");
+#endif
+
+ if(NULL == ps_op_file)
+ {
+ snprintf(ac_error_str, sizeof(ac_error_str), "Could not open output file %s",
+ s_app_ctx.ac_op_fname);
+ codec_exit(ac_error_str);
+ }
+ }
+
+ /***********************************************************************/
+ /* create the file object for mbinfo file */
+ /***********************************************************************/
+
+ if(1 == s_app_ctx.u4_frame_info_enable)
+ {
+#ifdef IOS
+ snprintf(filename_with_path, sizeof(filename_with_path), "%s/%s", documentdir,
+ s_app_ctx.ac_qp_map_fname);
+ ps_qp_file = fopen(filename_with_path, "wb");
+
+ snprintf(filename_with_path, sizeof(filename_with_path), "%s/%s", documentdir,
+ s_app_ctx.ac_blk_type_map_fname);
+ ps_mb_type_file = fopen(filename_with_path, "wb");
+#else
+ ps_qp_file = fopen(s_app_ctx.ac_qp_map_fname, "wb");
+ ps_mb_type_file = fopen(s_app_ctx.ac_blk_type_map_fname, "wb");
+
+#endif
+
+ if(NULL == ps_qp_file)
+ {
+ snprintf(ac_error_str, sizeof(ac_error_str), "Could not open block_qp map file %s",
+ s_app_ctx.ac_qp_map_fname);
+ }
+ if(NULL == ps_mb_type_file)
+ {
+ snprintf(ac_error_str, sizeof(ac_error_str), "Could not open block_type map file %s",
+ s_app_ctx.ac_blk_type_map_fname);
+ }
+ }
+
+ /***********************************************************************/
+ /* create the file object for check sum file */
+ /***********************************************************************/
+ if(1 == s_app_ctx.u4_chksum_save_flag)
+ {
+#if IOS
+ snprintf(filename_with_path, sizeof(filename_with_path), "%s/%s", documentdir,
+ s_app_ctx.ac_op_chksum_fname);
+ ps_op_chksum_file = fopen(filename_with_path, "wb");
+#else
+ ps_op_chksum_file = fopen(s_app_ctx.ac_op_chksum_fname, "wb");
+#endif
+ if(NULL == ps_op_chksum_file)
+ {
+ snprintf(ac_error_str, sizeof(ac_error_str), "Could not open check sum file %s",
+ s_app_ctx.ac_op_chksum_fname);
+ codec_exit(ac_error_str);
+ }
+ }
+ /***********************************************************************/
+ /* Create decoder instance */
+ /***********************************************************************/
+ {
+ ps_out_buf = (ivd_out_bufdesc_t *) malloc(sizeof(ivd_out_bufdesc_t));
+
+ /*****************************************************************************/
+ /* API Call: Initialize the Decoder */
+ /*****************************************************************************/
+ {
+ isvcd_create_ip_t s_create_ip = {};
+ isvcd_create_op_t s_create_op = {};
+ void *fxns = &ivd_api_function;
+
+ s_create_ip.s_ivd_create_ip_t.e_cmd = IVD_CMD_CREATE;
+ s_create_ip.s_ivd_create_ip_t.u4_share_disp_buf = s_app_ctx.u4_share_disp_buf;
+ s_create_ip.s_ivd_create_ip_t.e_output_format =
+ (IV_COLOR_FORMAT_T) s_app_ctx.e_output_chroma_format;
+ s_create_ip.s_ivd_create_ip_t.pf_aligned_alloc = ih264a_aligned_malloc;
+ s_create_ip.s_ivd_create_ip_t.pf_aligned_free = ih264a_aligned_free;
+ s_create_ip.s_ivd_create_ip_t.pv_mem_ctxt = NULL;
+ s_create_ip.s_ivd_create_ip_t.u4_size = sizeof(isvcd_create_ip_t);
+ s_create_op.s_ivd_create_op_t.u4_size = sizeof(isvcd_create_op_t);
+ s_create_ip.u4_enable_frame_info = s_app_ctx.u4_frame_info_enable;
+
+ ret = ivd_api_function(NULL, (void *) &s_create_ip, (void *) &s_create_op);
+ if(ret != IV_SUCCESS)
+ {
+ sprintf(ac_error_str, "Error in Create %8x\n",
+ s_create_op.s_ivd_create_op_t.u4_error_code);
+ codec_exit(ac_error_str);
+ }
+ codec_obj = (iv_obj_t *) s_create_op.s_ivd_create_op_t.pv_handle;
+ codec_obj->pv_fxns = fxns;
+ codec_obj->u4_size = sizeof(iv_obj_t);
+ s_app_ctx.cocodec_obj = codec_obj;
+
+ /*****************************************************************************/
+ /* set stride */
+ /*****************************************************************************/
+ {
+ isvcd_ctl_set_config_ip_t s_h264d_ctl_ip = {};
+ isvcd_ctl_set_config_op_t s_h264d_ctl_op = {};
+ ivd_ctl_set_config_ip_t *ps_ctl_ip = &s_h264d_ctl_ip.s_ivd_ctl_set_config_ip_t;
+ ivd_ctl_set_config_op_t *ps_ctl_op = &s_h264d_ctl_op.s_ivd_ctl_set_config_op_t;
+
+ ps_ctl_ip->u4_disp_wd = STRIDE;
+ if(1 == s_app_ctx.display) ps_ctl_ip->u4_disp_wd = s_app_ctx.get_stride();
+
+ ps_ctl_ip->e_frm_skip_mode = IVD_SKIP_NONE;
+ ps_ctl_ip->e_frm_out_mode = IVD_DISPLAY_FRAME_OUT;
+ ps_ctl_ip->e_vid_dec_mode = IVD_DECODE_HEADER;
+ ps_ctl_ip->e_cmd = IVD_CMD_VIDEO_CTL;
+ ps_ctl_ip->e_sub_cmd = IVD_CMD_CTL_SETPARAMS;
+ ps_ctl_ip->u4_size = sizeof(isvcd_ctl_set_config_ip_t);
+ ps_ctl_op->u4_size = sizeof(isvcd_ctl_set_config_op_t);
+
+ ret = ivd_api_function((iv_obj_t *) codec_obj, (void *) &s_h264d_ctl_ip,
+ (void *) &s_h264d_ctl_op);
+ if(ret != IV_SUCCESS)
+ {
+ sprintf(ac_error_str, "\nError in setting the stride");
+ codec_exit(ac_error_str);
+ }
+ }
+ }
+ }
+
+ /*************************************************************************/
+ /* set num of cores */
+ /*************************************************************************/
+ {
+ isvcd_ctl_set_num_cores_ip_t s_ctl_set_cores_ip;
+ isvcd_ctl_set_num_cores_op_t s_ctl_set_cores_op;
+
+ s_ctl_set_cores_ip.e_cmd = IVD_CMD_VIDEO_CTL;
+ s_ctl_set_cores_ip.e_sub_cmd =
+ (IVD_CONTROL_API_COMMAND_TYPE_T) IH264D_CMD_CTL_SET_NUM_CORES;
+ s_ctl_set_cores_ip.u4_num_cores = s_app_ctx.u4_num_cores;
+ s_ctl_set_cores_ip.u4_size = sizeof(isvcd_ctl_set_num_cores_ip_t);
+ s_ctl_set_cores_op.u4_size = sizeof(isvcd_ctl_set_num_cores_op_t);
+
+ ret = ivd_api_function((iv_obj_t *) codec_obj, (void *) &s_ctl_set_cores_ip,
+ (void *) &s_ctl_set_cores_op);
+ if(ret != IV_SUCCESS)
+ {
+ sprintf(ac_error_str, "\nError in setting number of cores");
+ codec_exit(ac_error_str);
+ }
+ }
+
+ /*************************************************************************/
+ /* set target layer */
+ /*************************************************************************/
+ {
+ isvcd_set_target_layer_ip_t s_ctl_set_target_layer_ip;
+ isvcd_set_target_layer_op_t s_ctl_set_target_layer_op;
+
+ s_ctl_set_target_layer_ip.e_cmd = IVD_CMD_VIDEO_CTL;
+ s_ctl_set_target_layer_ip.e_sub_cmd =
+ (IVD_CONTROL_API_COMMAND_TYPE_T) ISVCD_CMD_CTL_SET_TGT_LAYER;
+ s_ctl_set_target_layer_ip.u1_tgt_priority_id = 63;
+ s_ctl_set_target_layer_ip.u1_tgt_temp_id = 7;
+ s_ctl_set_target_layer_ip.u1_tgt_quality_id = 0;
+ s_ctl_set_target_layer_ip.u1_tgt_dep_id = s_app_ctx.i4_target_layer_id;
+ s_ctl_set_target_layer_ip.u4_size = sizeof(isvcd_set_target_layer_ip_t);
+ s_ctl_set_target_layer_op.u4_size = sizeof(isvcd_set_target_layer_op_t);
+
+ ret = ivd_api_function((iv_obj_t *) codec_obj, (void *) &s_ctl_set_target_layer_ip,
+ (void *) &s_ctl_set_target_layer_op);
+
+ if(ret != IV_SUCCESS)
+ {
+ sprintf(ac_error_str, "\nError in setting target layer id");
+ codec_exit(ac_error_str);
+ }
+ }
+
+ /*************************************************************************/
+ /* set processsor */
+ /*************************************************************************/
+ {
+ isvcd_ctl_set_processor_ip_t s_ctl_set_num_processor_ip;
+ isvcd_ctl_set_processor_op_t s_ctl_set_num_processor_op;
+
+ s_ctl_set_num_processor_ip.e_cmd = IVD_CMD_VIDEO_CTL;
+ s_ctl_set_num_processor_ip.e_sub_cmd =
+ (IVD_CONTROL_API_COMMAND_TYPE_T) IH264D_CMD_CTL_SET_PROCESSOR;
+ s_ctl_set_num_processor_ip.u4_arch = s_app_ctx.e_arch;
+ s_ctl_set_num_processor_ip.u4_soc = s_app_ctx.e_soc;
+ s_ctl_set_num_processor_ip.u4_size = sizeof(isvcd_ctl_set_processor_ip_t);
+ s_ctl_set_num_processor_op.u4_size = sizeof(isvcd_ctl_set_processor_op_t);
+
+ ret = ivd_api_function((iv_obj_t *) codec_obj, (void *) &s_ctl_set_num_processor_ip,
+ (void *) &s_ctl_set_num_processor_op);
+ if(ret != IV_SUCCESS)
+ {
+ sprintf(ac_error_str, "\nError in setting Processor type");
+ codec_exit(ac_error_str);
+ }
+ }
+
+ flush_output(codec_obj, &s_app_ctx, ps_out_buf, pu1_bs_buf, &u4_op_frm_ts, ps_op_file,
+ ps_qp_file, ps_mb_type_file, pu1_qp_map_buf, pu1_blk_type_map_buf,
+ ps_op_chksum_file, u4_ip_frm_ts, u4_bytes_remaining);
+
+ /*****************************************************************************/
+ /* Decode header to get width and height and buffer sizes */
+ /*****************************************************************************/
+ {
+ isvcd_video_decode_ip_t s_h264d_decode_ip = {};
+ isvcd_video_decode_op_t s_h264d_decode_op = {};
+ ivd_video_decode_ip_t *ps_video_decode_ip = &s_h264d_decode_ip.s_ivd_video_decode_ip_t;
+ ivd_video_decode_op_t *ps_video_decode_op = &s_h264d_decode_op.s_ivd_video_decode_op_t;
+
+ {
+ isvcd_ctl_set_config_ip_t s_h264d_ctl_ip = {};
+ isvcd_ctl_set_config_op_t s_h264d_ctl_op = {};
+ ivd_ctl_set_config_ip_t *ps_ctl_ip = &s_h264d_ctl_ip.s_ivd_ctl_set_config_ip_t;
+ ivd_ctl_set_config_op_t *ps_ctl_op = &s_h264d_ctl_op.s_ivd_ctl_set_config_op_t;
+
+ ps_ctl_ip->u4_disp_wd = STRIDE;
+ if(1 == s_app_ctx.display) ps_ctl_ip->u4_disp_wd = s_app_ctx.get_stride();
+
+ ps_ctl_ip->e_frm_skip_mode = IVD_SKIP_NONE;
+ ps_ctl_ip->e_frm_out_mode = IVD_DISPLAY_FRAME_OUT;
+ ps_ctl_ip->e_vid_dec_mode = IVD_DECODE_HEADER;
+ ps_ctl_ip->e_cmd = IVD_CMD_VIDEO_CTL;
+ ps_ctl_ip->e_sub_cmd = IVD_CMD_CTL_SETPARAMS;
+ ps_ctl_ip->u4_size = sizeof(isvcd_ctl_set_config_ip_t);
+ ps_ctl_op->u4_size = sizeof(isvcd_ctl_set_config_op_t);
+
+ ret = ivd_api_function((iv_obj_t *) codec_obj, (void *) &s_h264d_ctl_ip,
+ (void *) &s_h264d_ctl_op);
+ if(ret != IV_SUCCESS)
+ {
+ sprintf(ac_error_str, "\nError in setting the codec in header decode mode");
+ codec_exit(ac_error_str);
+ }
+ }
+
+ /* Allocate input buffer for header */
+ u4_ip_buf_len = 256 * 1024;
+ pu1_bs_buf = (UWORD8 *) malloc(u4_ip_buf_len);
+
+ if(pu1_bs_buf == NULL)
+ {
+ sprintf(ac_error_str, "\nAllocation failure for input buffer of i4_size %d",
+ u4_ip_buf_len);
+ codec_exit(ac_error_str);
+ }
+
+ do
+ {
+ WORD32 numbytes;
+
+ if(0 == s_app_ctx.u4_piclen_flag)
+ {
+ fseek(ps_ip_file, file_pos, SEEK_SET);
+ numbytes = u4_ip_buf_len;
+ }
+ else
+ {
+ WORD32 entries;
+ entries = fscanf(ps_piclen_file, "%d\n", &numbytes);
+ if(1 != entries) numbytes = u4_ip_buf_len;
+ }
+
+ u4_bytes_remaining = (WORD32) fread(pu1_bs_buf, sizeof(UWORD8), numbytes, ps_ip_file);
+
+ if((1 == s_app_ctx.u4_piclen_flag) && (u4_bytes_remaining > 0))
+ {
+ *(pu1_bs_buf + numbytes) = 0x00;
+ numbytes++;
+ *(pu1_bs_buf + numbytes) = 0x00;
+ numbytes++;
+ *(pu1_bs_buf + numbytes) = 0x00;
+ numbytes++;
+ *(pu1_bs_buf + numbytes) = 0x01;
+ numbytes++;
+ *(pu1_bs_buf + numbytes) = 0x09;
+ numbytes++;
+ *(pu1_bs_buf + numbytes) = 0x10;
+ numbytes++;
+
+ u4_bytes_remaining += 6;
+ }
+
+ if(0 == u4_bytes_remaining)
+ {
+ sprintf(ac_error_str, "\nUnable to read from input file");
+ codec_exit(ac_error_str);
+ }
+
+ ps_video_decode_ip->e_cmd = IVD_CMD_VIDEO_DECODE;
+ ps_video_decode_ip->u4_ts = u4_ip_frm_ts;
+ ps_video_decode_ip->pv_stream_buffer = pu1_bs_buf;
+ ps_video_decode_ip->u4_num_Bytes = u4_bytes_remaining;
+ ps_video_decode_ip->u4_size = sizeof(isvcd_video_decode_ip_t);
+ ps_video_decode_op->u4_size = sizeof(isvcd_video_decode_op_t);
+ s_h264d_decode_ip.pu1_8x8_blk_qp_map = pu1_qp_map_buf;
+ s_h264d_decode_ip.pu1_8x8_blk_type_map = pu1_blk_type_map_buf;
+ s_h264d_decode_ip.u4_8x8_blk_qp_map_size = (ADAPTIVE_MAX_HT * ADAPTIVE_MAX_WD) >> 6;
+ s_h264d_decode_ip.u4_8x8_blk_type_map_size = (ADAPTIVE_MAX_HT * ADAPTIVE_MAX_WD) >> 6;
+
+ /*****************************************************************************/
+ /* API Call: Header Decode */
+ /*****************************************************************************/
+ ret = ivd_api_function((iv_obj_t *) codec_obj, (void *) &s_h264d_decode_ip,
+ (void *) &s_h264d_decode_op);
+
+ if(ret != IV_SUCCESS)
+ {
+ printf("Error in header decode 0x%x\n", ps_video_decode_op->u4_error_code);
+ // codec_exit(ac_error_str);
+ }
+
+ u4_num_bytes_dec = ps_video_decode_op->u4_num_bytes_consumed;
+#ifndef PROFILE_ENABLE
+ printf("%d\n", ps_video_decode_op->u4_num_bytes_consumed);
+#endif
+ file_pos += u4_num_bytes_dec;
+ total_bytes_comsumed += u4_num_bytes_dec;
+ } while(ret != IV_SUCCESS);
+
+ /* copy pic_wd and pic_ht to initialize buffers */
+ s_app_ctx.u4_pic_wd = ps_video_decode_op->u4_pic_wd;
+ s_app_ctx.u4_pic_ht = ps_video_decode_op->u4_pic_ht;
+
+ free(pu1_bs_buf);
+
+#if IOS_DISPLAY
+ s_app_ctx.i4_screen_wd = screen_wd;
+ s_app_ctx.i4_screen_ht = screen_ht;
+#endif
+ {
+ ivd_ctl_getbufinfo_ip_t s_ctl_ip;
+ ivd_ctl_getbufinfo_op_t s_ctl_op;
+ WORD32 outlen = 0;
+
+ s_ctl_ip.e_cmd = IVD_CMD_VIDEO_CTL;
+ s_ctl_ip.e_sub_cmd = IVD_CMD_CTL_GETBUFINFO;
+ s_ctl_ip.u4_size = sizeof(ivd_ctl_getbufinfo_ip_t);
+ s_ctl_op.u4_size = sizeof(ivd_ctl_getbufinfo_op_t);
+ ret = ivd_api_function((iv_obj_t *) codec_obj, (void *) &s_ctl_ip, (void *) &s_ctl_op);
+ if(ret != IV_SUCCESS)
+ {
+ sprintf(ac_error_str, "Error in Get Buf Info %x", s_ctl_op.u4_error_code);
+ codec_exit(ac_error_str);
+ }
+
+ /* Allocate bitstream buffer */
+ u4_ip_buf_len = s_ctl_op.u4_min_in_buf_size[0];
+#ifdef ADAPTIVE_TEST
+ u4_ip_buf_len = ADAPTIVE_MAX_WD * ADAPTIVE_MAX_HT * 3 >> 1;
+#endif
+ pu1_bs_buf = (UWORD8 *) malloc(u4_ip_buf_len);
+
+ if(pu1_bs_buf == NULL)
+ {
+ sprintf(ac_error_str, "\nAllocation failure for input buffer of i4_size %d",
+ u4_ip_buf_len);
+ codec_exit(ac_error_str);
+ }
+
+ s_app_ctx.num_disp_buf = s_ctl_op.u4_num_disp_bufs;
+ /* Allocate output buffer only if display buffers are not shared */
+ /* Or if shared and output is 420P */
+ if((0 == s_app_ctx.u4_share_disp_buf) ||
+ (IV_YUV_420P == s_app_ctx.e_output_chroma_format))
+ {
+#ifdef ADAPTIVE_TEST
+ switch(s_app_ctx.e_output_chroma_format)
+ {
+ case IV_YUV_420P:
+ {
+ s_ctl_op.u4_min_out_buf_size[0] = ADAPTIVE_MAX_WD * ADAPTIVE_MAX_HT;
+ s_ctl_op.u4_min_out_buf_size[1] = ADAPTIVE_MAX_WD * ADAPTIVE_MAX_HT >> 2;
+ s_ctl_op.u4_min_out_buf_size[2] = ADAPTIVE_MAX_WD * ADAPTIVE_MAX_HT >> 2;
+ break;
+ }
+ case IV_YUV_420SP_UV:
+ case IV_YUV_420SP_VU:
+ {
+ s_ctl_op.u4_min_out_buf_size[0] = ADAPTIVE_MAX_WD * ADAPTIVE_MAX_HT;
+ s_ctl_op.u4_min_out_buf_size[1] = ADAPTIVE_MAX_WD * ADAPTIVE_MAX_HT >> 1;
+ s_ctl_op.u4_min_out_buf_size[2] = 0;
+ break;
+ }
+ case IV_YUV_422ILE:
+ {
+ s_ctl_op.u4_min_out_buf_size[0] = ADAPTIVE_MAX_WD * ADAPTIVE_MAX_HT * 2;
+ s_ctl_op.u4_min_out_buf_size[1] = 0;
+ s_ctl_op.u4_min_out_buf_size[2] = 0;
+ break;
+ }
+ case IV_RGBA_8888:
+ {
+ s_ctl_op.u4_min_out_buf_size[0] = ADAPTIVE_MAX_WD * ADAPTIVE_MAX_HT * 4;
+ s_ctl_op.u4_min_out_buf_size[1] = 0;
+ s_ctl_op.u4_min_out_buf_size[2] = 0;
+ break;
+ }
+ case IV_RGB_565:
+ {
+ s_ctl_op.u4_min_out_buf_size[0] = ADAPTIVE_MAX_WD * ADAPTIVE_MAX_HT * 2;
+ s_ctl_op.u4_min_out_buf_size[1] = 0;
+ s_ctl_op.u4_min_out_buf_size[2] = 0;
+ break;
+ }
+ default:
+ break;
+ }
+#endif
+ ps_out_buf->u4_min_out_buf_size[0] = s_ctl_op.u4_min_out_buf_size[0];
+ ps_out_buf->u4_min_out_buf_size[1] = s_ctl_op.u4_min_out_buf_size[1];
+ ps_out_buf->u4_min_out_buf_size[2] = s_ctl_op.u4_min_out_buf_size[2];
+
+ outlen = s_ctl_op.u4_min_out_buf_size[0];
+ if(s_ctl_op.u4_min_num_out_bufs > 1) outlen += s_ctl_op.u4_min_out_buf_size[1];
+
+ if(s_ctl_op.u4_min_num_out_bufs > 2) outlen += s_ctl_op.u4_min_out_buf_size[2];
+
+ ps_out_buf->pu1_bufs[0] = (UWORD8 *) malloc(outlen);
+ if(ps_out_buf->pu1_bufs[0] == NULL)
+ {
+ sprintf(ac_error_str, "\nAllocation failure for output buffer of i4_size %d",
+ outlen);
+ codec_exit(ac_error_str);
+ }
+
+ if(s_ctl_op.u4_min_num_out_bufs > 1)
+ ps_out_buf->pu1_bufs[1] =
+ ps_out_buf->pu1_bufs[0] + (s_ctl_op.u4_min_out_buf_size[0]);
+
+ if(s_ctl_op.u4_min_num_out_bufs > 2)
+ ps_out_buf->pu1_bufs[2] =
+ ps_out_buf->pu1_bufs[1] + (s_ctl_op.u4_min_out_buf_size[1]);
+
+ ps_out_buf->u4_num_bufs = s_ctl_op.u4_min_num_out_bufs;
+ }
+
+#ifdef APP_EXTRA_BUFS
+ s_app_ctx.disp_delay = EXTRA_DISP_BUFFERS;
+ s_ctl_op.u4_num_disp_bufs += EXTRA_DISP_BUFFERS;
+#endif
+
+ /*****************************************************************************/
+ /* API Call: Allocate display buffers for display buffer shared case */
+ /*****************************************************************************/
+
+ for(i = 0; i < s_ctl_op.u4_num_disp_bufs; i++)
+ {
+ s_app_ctx.s_disp_buffers[i].u4_min_out_buf_size[0] =
+ s_ctl_op.u4_min_out_buf_size[0];
+ s_app_ctx.s_disp_buffers[i].u4_min_out_buf_size[1] =
+ s_ctl_op.u4_min_out_buf_size[1];
+ s_app_ctx.s_disp_buffers[i].u4_min_out_buf_size[2] =
+ s_ctl_op.u4_min_out_buf_size[2];
+
+ outlen = s_ctl_op.u4_min_out_buf_size[0];
+ if(s_ctl_op.u4_min_num_out_bufs > 1) outlen += s_ctl_op.u4_min_out_buf_size[1];
+
+ if(s_ctl_op.u4_min_num_out_bufs > 2) outlen += s_ctl_op.u4_min_out_buf_size[2];
+
+ s_app_ctx.s_disp_buffers[i].pu1_bufs[0] = (UWORD8 *) malloc(outlen);
+
+ if(s_app_ctx.s_disp_buffers[i].pu1_bufs[0] == NULL)
+ {
+ sprintf(ac_error_str, "\nAllocation failure for output buffer of i4_size %d",
+ outlen);
+ codec_exit(ac_error_str);
+ }
+
+ if(s_ctl_op.u4_min_num_out_bufs > 1)
+ s_app_ctx.s_disp_buffers[i].pu1_bufs[1] =
+ s_app_ctx.s_disp_buffers[i].pu1_bufs[0] + (s_ctl_op.u4_min_out_buf_size[0]);
+
+ if(s_ctl_op.u4_min_num_out_bufs > 2)
+ s_app_ctx.s_disp_buffers[i].pu1_bufs[2] =
+ s_app_ctx.s_disp_buffers[i].pu1_bufs[1] + (s_ctl_op.u4_min_out_buf_size[1]);
+
+ s_app_ctx.s_disp_buffers[i].u4_num_bufs = s_ctl_op.u4_min_num_out_bufs;
+ }
+ s_app_ctx.num_disp_buf = s_ctl_op.u4_num_disp_bufs;
+ }
+
+ /* Create display thread and wait for the display buffers to be initialized*/
+ if(1 == s_app_ctx.display)
+ {
+ if(0 == s_app_ctx.display_thread_created)
+ {
+ s_app_ctx.display_init_done = 0;
+ ithread_create(s_app_ctx.display_thread_handle, NULL, (void *) &display_thread,
+ (void *) &s_app_ctx);
+ s_app_ctx.display_thread_created = 1;
+
+ while(1)
+ {
+ if(s_app_ctx.display_init_done) break;
+
+ ithread_msleep(1);
+ }
+ }
+
+ s_app_ctx.u4_strd = s_app_ctx.get_stride();
+ }
+ }
+
+ /*************************************************************************/
+ /* Get actual number of output buffers requried, which is dependent */
+ /* on ps_bitstrm properties such as width, height and level etc */
+ /* This is needed mainly for shared display mode */
+ /*************************************************************************/
+
+ /*****************************************************************************/
+ /* API Call: Send the allocated display buffers to codec */
+ /*****************************************************************************/
+ {
+ ivd_set_display_frame_ip_t s_set_display_frame_ip;
+ ivd_set_display_frame_op_t s_set_display_frame_op;
+
+ s_set_display_frame_ip.e_cmd = IVD_CMD_SET_DISPLAY_FRAME;
+ s_set_display_frame_ip.u4_size = sizeof(ivd_set_display_frame_ip_t);
+ s_set_display_frame_op.u4_size = sizeof(ivd_set_display_frame_op_t);
+
+ s_set_display_frame_ip.num_disp_bufs = s_app_ctx.num_disp_buf;
+
+ memcpy(&(s_set_display_frame_ip.s_disp_buffer), &(s_app_ctx.s_disp_buffers),
+ s_app_ctx.num_disp_buf * sizeof(ivd_out_bufdesc_t));
+
+ ret = ivd_api_function((iv_obj_t *) codec_obj, (void *) &s_set_display_frame_ip,
+ (void *) &s_set_display_frame_op);
+
+ if(IV_SUCCESS != ret)
+ {
+ sprintf(ac_error_str, "Error in Set display frame");
+ codec_exit(ac_error_str);
+ }
+ }
+
+ /*************************************************************************/
+ /* Get frame dimensions for display buffers such as x_offset,y_offset */
+ /* etc. This information might be needed to set display buffer */
+ /* offsets in case of shared display buffer mode */
+ /*************************************************************************/
+ {
+ isvcd_ctl_get_frame_dimensions_ip_t s_ctl_get_frame_dimensions_ip;
+ isvcd_ctl_get_frame_dimensions_op_t s_ctl_get_frame_dimensions_op;
+
+ s_ctl_get_frame_dimensions_ip.e_cmd = IVD_CMD_VIDEO_CTL;
+ s_ctl_get_frame_dimensions_ip.e_sub_cmd =
+ (IVD_CONTROL_API_COMMAND_TYPE_T) IH264D_CMD_CTL_GET_BUFFER_DIMENSIONS;
+ s_ctl_get_frame_dimensions_ip.u4_size = sizeof(isvcd_ctl_get_frame_dimensions_ip_t);
+ s_ctl_get_frame_dimensions_op.u4_size = sizeof(isvcd_ctl_get_frame_dimensions_op_t);
+
+ ret = ivd_api_function((iv_obj_t *) codec_obj, (void *) &s_ctl_get_frame_dimensions_ip,
+ (void *) &s_ctl_get_frame_dimensions_op);
+ if(IV_SUCCESS != ret)
+ {
+ sprintf(ac_error_str, "Error in Get buffer Dimensions");
+ codec_exit(ac_error_str);
+ }
+ }
+
+ /*************************************************************************/
+ /* Get VUI parameters */
+ /*************************************************************************/
+ {
+ isvcd_ctl_get_vui_params_ip_t s_ctl_get_vui_params_ip;
+ isvcd_ctl_get_vui_params_op_t s_ctl_get_vui_params_op;
+
+ s_ctl_get_vui_params_ip.e_cmd = IVD_CMD_VIDEO_CTL;
+ s_ctl_get_vui_params_ip.e_sub_cmd =
+ (IVD_CONTROL_API_COMMAND_TYPE_T) IH264D_CMD_CTL_GET_VUI_PARAMS;
+ s_ctl_get_vui_params_ip.u4_size = sizeof(isvcd_ctl_get_vui_params_ip_t);
+ s_ctl_get_vui_params_op.u4_size = sizeof(isvcd_ctl_get_vui_params_op_t);
+
+ ret = ivd_api_function((iv_obj_t *) codec_obj, (void *) &s_ctl_get_vui_params_ip,
+ (void *) &s_ctl_get_vui_params_op);
+ if(IV_SUCCESS != ret)
+ {
+ sprintf(ac_error_str, "Error in Get VUI params");
+ // codec_exit(ac_error_str);
+ }
+ }
+
+ /*************************************************************************/
+ /* Set the decoder in frame decode mode. It was set in header decode */
+ /* mode earlier */
+ /*************************************************************************/
+ {
+ isvcd_ctl_set_config_ip_t s_h264d_ctl_ip = {};
+ isvcd_ctl_set_config_op_t s_h264d_ctl_op = {};
+ ivd_ctl_set_config_ip_t *ps_ctl_ip = &s_h264d_ctl_ip.s_ivd_ctl_set_config_ip_t;
+ ivd_ctl_set_config_op_t *ps_ctl_op = &s_h264d_ctl_op.s_ivd_ctl_set_config_op_t;
+
+ ps_ctl_ip->u4_disp_wd = STRIDE;
+ if(1 == s_app_ctx.display) ps_ctl_ip->u4_disp_wd = s_app_ctx.get_stride();
+ ps_ctl_ip->e_frm_skip_mode = IVD_SKIP_NONE;
+
+ ps_ctl_ip->e_frm_out_mode = IVD_DISPLAY_FRAME_OUT;
+ ps_ctl_ip->e_vid_dec_mode = IVD_DECODE_FRAME;
+ ps_ctl_ip->e_cmd = IVD_CMD_VIDEO_CTL;
+ ps_ctl_ip->e_sub_cmd = IVD_CMD_CTL_SETPARAMS;
+ ps_ctl_ip->u4_size = sizeof(isvcd_ctl_set_config_ip_t);
+
+ ps_ctl_op->u4_size = sizeof(isvcd_ctl_set_config_op_t);
+
+ ret = ivd_api_function((iv_obj_t *) codec_obj, (void *) &s_h264d_ctl_ip,
+ (void *) &s_h264d_ctl_op);
+
+ if(IV_SUCCESS != ret)
+ {
+ sprintf(ac_error_str, "Error in Set Parameters");
+ // codec_exit(ac_error_str);
+ }
+ }
+ /*************************************************************************/
+ /* If required disable deblocking and sao at given level */
+ /*************************************************************************/
+
+ set_degrade(codec_obj, s_app_ctx.i4_degrade_type, s_app_ctx.i4_degrade_pics);
+#ifdef WINDOWS_TIMER
+ QueryPerformanceFrequency(&frequency);
+#endif
+#ifndef PRINT_PICSIZE
+ get_version(codec_obj);
+#endif
+
+ max_op_frm_ts = s_app_ctx.u4_max_frm_ts + s_app_ctx.disp_delay;
+
+ if(max_op_frm_ts < s_app_ctx.disp_delay)
+ max_op_frm_ts = 0xffffffff; /* clip as overflow has occured*/
+
+ max_op_frm_ts = (s_app_ctx.u4_max_frm_ts > 0) ? (max_op_frm_ts) : 0xffffffff;
+
+ u4_num_disp_bufs_with_dec = 0;
+
+ while(u4_op_frm_ts < max_op_frm_ts)
+ {
+#ifdef TEST_FLUSH
+ if(u4_ip_frm_ts == FLUSH_FRM_CNT)
+ {
+ ivd_ctl_flush_ip_t s_ctl_ip;
+ ivd_ctl_flush_op_t s_ctl_op;
+
+ s_ctl_ip.e_cmd = IVD_CMD_VIDEO_CTL;
+ s_ctl_ip.e_sub_cmd = IVD_CMD_CTL_FLUSH;
+ s_ctl_ip.u4_size = sizeof(ivd_ctl_flush_ip_t);
+ s_ctl_op.u4_size = sizeof(ivd_ctl_flush_op_t);
+ ret = ivd_api_function((iv_obj_t *) codec_obj, (void *) &s_ctl_ip, (void *) &s_ctl_op);
+
+ if(ret != IV_SUCCESS)
+ {
+ printf("Error in Setting the decoder in flush mode\n");
+ }
+ // file_pos = 0;
+
+ // fseek(ps_ip_file, file_pos, SEEK_SET);
+ }
+#endif
+ if(u4_num_disp_bufs_with_dec < s_app_ctx.num_disp_buf)
+ {
+ release_disp_frame(codec_obj, u4_num_disp_bufs_with_dec);
+ u4_num_disp_bufs_with_dec++;
+ }
+
+ /*************************************************************************/
+ /* set num of cores */
+ /*************************************************************************/
+#ifdef DYNAMIC_NUMCORES
+ {
+ isvcd_ctl_set_num_cores_ip_t s_ctl_set_cores_ip;
+ isvcd_ctl_set_num_cores_op_t s_ctl_set_cores_op;
+
+ s_ctl_set_cores_ip.e_cmd = IVD_CMD_VIDEO_CTL;
+ s_ctl_set_cores_ip.e_sub_cmd = IH264D_CMD_CTL_SET_NUM_CORES;
+ s_ctl_set_cores_ip.u4_num_cores = 1 + 3 * (u4_ip_frm_ts % 2);
+ s_ctl_set_cores_ip.u4_size = sizeof(isvcd_ctl_set_num_cores_ip_t);
+ s_ctl_set_cores_op.u4_size = sizeof(isvcd_ctl_set_num_cores_op_t);
+
+ ret = ivd_api_function((iv_obj_t *) codec_obj, (void *) &s_ctl_set_cores_ip,
+ (void *) &s_ctl_set_cores_op);
+ if(ret != IV_SUCCESS)
+ {
+ sprintf(ac_error_str, "\nError in setting number of cores");
+ codec_exit(ac_error_str);
+ }
+ }
+#endif
+ /***********************************************************************/
+ /* Seek the file to start of current frame, this is equavelent of */
+ /* having a parcer which tells the start of current frame */
+ /***********************************************************************/
+ {
+ WORD32 numbytes;
+
+ if(0 == s_app_ctx.u4_piclen_flag)
+ {
+ fseek(ps_ip_file, file_pos, SEEK_SET);
+ numbytes = u4_ip_buf_len;
+ }
+ else
+ {
+ WORD32 entries;
+ entries = fscanf(ps_piclen_file, "%d\n", &numbytes);
+ if(1 != entries) numbytes = u4_ip_buf_len;
+ }
+
+ u4_bytes_remaining = (WORD32) fread(pu1_bs_buf, sizeof(UWORD8), numbytes, ps_ip_file);
+
+ // AUD_PIC_BOUNDARY
+ if((1 == s_app_ctx.u4_piclen_flag) && (u4_bytes_remaining > 0))
+ {
+ *(pu1_bs_buf + numbytes) = 0x00;
+ numbytes++;
+ *(pu1_bs_buf + numbytes) = 0x00;
+ numbytes++;
+ *(pu1_bs_buf + numbytes) = 0x00;
+ numbytes++;
+ *(pu1_bs_buf + numbytes) = 0x01;
+ numbytes++;
+ *(pu1_bs_buf + numbytes) = 0x09;
+ numbytes++;
+ *(pu1_bs_buf + numbytes) = 0x10;
+ numbytes++;
+
+ u4_bytes_remaining += 6;
+ }
+
+ if(u4_bytes_remaining == 0)
+ {
+ if(1 == s_app_ctx.loopback)
+ {
+ file_pos = 0;
+ if(0 == s_app_ctx.u4_piclen_flag)
+ {
+ fseek(ps_ip_file, file_pos, SEEK_SET);
+ numbytes = u4_ip_buf_len;
+ }
+ else
+ {
+ WORD32 entries;
+ entries = fscanf(ps_piclen_file, "%d\n", &numbytes);
+ if(1 != entries) numbytes = u4_ip_buf_len;
+ }
+
+ u4_bytes_remaining =
+ (WORD32) fread(pu1_bs_buf, sizeof(UWORD8), numbytes, ps_ip_file);
+ }
+ else
+ break;
+ }
+ }
+
+ /*********************************************************************/
+ /* Following calls can be enabled at diffent times */
+ /*********************************************************************/
+#if ENABLE_DEGRADE
+ if(u4_op_frm_ts >= 10000) disable_deblocking(codec_obj, 4);
+
+ if(u4_op_frm_ts == 30000) enable_deblocking(codec_obj);
+
+ if(u4_op_frm_ts == 10000) enable_skippb_frames(codec_obj);
+
+ if(u4_op_frm_ts == 60000) disable_skippb_frames(codec_obj);
+
+ if(u4_op_frm_ts == 30000) enable_skipb_frames(codec_obj);
+
+ if(u4_op_frm_ts == 60000) disable_skipb_frames(codec_obj);
+#endif
+
+ {
+ isvcd_video_decode_ip_t s_h264d_decode_ip = {};
+ isvcd_video_decode_op_t s_h264d_decode_op = {};
+ ivd_video_decode_ip_t *ps_video_decode_ip = &s_h264d_decode_ip.s_ivd_video_decode_ip_t;
+ ivd_video_decode_op_t *ps_video_decode_op = &s_h264d_decode_op.s_ivd_video_decode_op_t;
+#ifdef PROFILE_ENABLE
+ UWORD32 s_elapsed_time;
+ TIMER s_start_timer;
+ TIMER s_end_timer;
+#endif
+
+ ps_video_decode_ip->e_cmd = IVD_CMD_VIDEO_DECODE;
+ ps_video_decode_ip->u4_ts = u4_ip_frm_ts;
+ ps_video_decode_ip->pv_stream_buffer = pu1_bs_buf;
+ ps_video_decode_ip->u4_num_Bytes = u4_bytes_remaining;
+ ps_video_decode_ip->u4_size = sizeof(isvcd_video_decode_ip_t);
+ ps_video_decode_ip->s_out_buffer.u4_min_out_buf_size[0] =
+ ps_out_buf->u4_min_out_buf_size[0];
+ ps_video_decode_ip->s_out_buffer.u4_min_out_buf_size[1] =
+ ps_out_buf->u4_min_out_buf_size[1];
+ ps_video_decode_ip->s_out_buffer.u4_min_out_buf_size[2] =
+ ps_out_buf->u4_min_out_buf_size[2];
+
+ ps_video_decode_ip->s_out_buffer.pu1_bufs[0] = ps_out_buf->pu1_bufs[0];
+ ps_video_decode_ip->s_out_buffer.pu1_bufs[1] = ps_out_buf->pu1_bufs[1];
+ ps_video_decode_ip->s_out_buffer.pu1_bufs[2] = ps_out_buf->pu1_bufs[2];
+ ps_video_decode_ip->s_out_buffer.u4_num_bufs = ps_out_buf->u4_num_bufs;
+ ps_video_decode_op->u4_size = sizeof(isvcd_video_decode_op_t);
+ s_h264d_decode_ip.pu1_8x8_blk_qp_map = pu1_qp_map_buf;
+ s_h264d_decode_ip.pu1_8x8_blk_type_map = pu1_blk_type_map_buf;
+ s_h264d_decode_ip.u4_8x8_blk_qp_map_size = (ADAPTIVE_MAX_HT * ADAPTIVE_MAX_WD) >> 6;
+ s_h264d_decode_ip.u4_8x8_blk_type_map_size = (ADAPTIVE_MAX_HT * ADAPTIVE_MAX_WD) >> 6;
+
+ /* Get display buffer pointers */
+ if(1 == s_app_ctx.display)
+ {
+ WORD32 wr_idx;
+
+ wr_idx = dispq_producer_dequeue(&s_app_ctx);
+
+ if(s_app_ctx.quit) break;
+
+ s_app_ctx.set_disp_buffers(s_app_ctx.pv_disp_ctx, wr_idx,
+ &ps_video_decode_ip->s_out_buffer.pu1_bufs[0],
+ &ps_video_decode_ip->s_out_buffer.pu1_bufs[1],
+ &ps_video_decode_ip->s_out_buffer.pu1_bufs[2]);
+ }
+
+ /*****************************************************************************/
+ /* API Call: Video Decode */
+ /*****************************************************************************/
+
+ GETTIME(&s_start_timer);
+
+ ret = ivd_api_function((iv_obj_t *) codec_obj, (void *) &s_h264d_decode_ip,
+ (void *) &s_h264d_decode_op);
+
+ GETTIME(&s_end_timer);
+ ELAPSEDTIME(s_start_timer, s_end_timer, s_elapsed_time, frequency);
+#ifdef PROFILE_ENABLE
+ {
+ UWORD32 peak_avg, id;
+ u4_tot_cycles += s_elapsed_time;
+ peak_window[peak_window_idx++] = s_elapsed_time;
+ if(peak_window_idx == PEAK_WINDOW_SIZE) peak_window_idx = 0;
+ peak_avg = 0;
+ for(id = 0; id < PEAK_WINDOW_SIZE; id++)
+ {
+ peak_avg += peak_window[id];
+ }
+ peak_avg /= PEAK_WINDOW_SIZE;
+ if(peak_avg > peak_avg_max) peak_avg_max = peak_avg;
+ frm_cnt++;
+
+ printf(
+ "FrameNum: %4d TimeTaken(microsec): %6d AvgTime: %6d "
+ "PeakAvgTimeMax: %6d Output: %2d NumBytes: %6d \n",
+ frm_cnt, s_elapsed_time, u4_tot_cycles / frm_cnt, peak_avg_max,
+ ps_video_decode_op->u4_output_present,
+ ps_video_decode_op->u4_num_bytes_consumed);
+ }
+#else
+ printf("%d\n", ps_video_decode_op->u4_num_bytes_consumed);
+#endif
+
+ if(ret != IV_SUCCESS)
+ {
+ printf("Error in video Frame decode : ret %x Error %x\n", ret,
+ ps_video_decode_op->u4_error_code);
+ }
+
+ if((IV_SUCCESS != ret) &&
+ ((ps_video_decode_op->u4_error_code & 0xFF) == IVD_RES_CHANGED))
+ {
+ ivd_ctl_reset_ip_t s_ctl_ip;
+ ivd_ctl_reset_op_t s_ctl_op;
+
+ flush_output(codec_obj, &s_app_ctx, ps_out_buf, pu1_bs_buf, &u4_op_frm_ts,
+ ps_op_file, ps_qp_file, ps_mb_type_file, pu1_qp_map_buf,
+ pu1_blk_type_map_buf, ps_op_chksum_file, u4_ip_frm_ts,
+ u4_bytes_remaining);
+
+ s_ctl_ip.e_cmd = IVD_CMD_VIDEO_CTL;
+ s_ctl_ip.e_sub_cmd = IVD_CMD_CTL_RESET;
+ s_ctl_ip.u4_size = sizeof(ivd_ctl_reset_ip_t);
+ s_ctl_op.u4_size = sizeof(ivd_ctl_reset_op_t);
+
+ ret = ivd_api_function((iv_obj_t *) codec_obj, (void *) &s_ctl_ip,
+ (void *) &s_ctl_op);
+ if(IV_SUCCESS != ret)
+ {
+ sprintf(ac_error_str, "Error in Reset");
+ codec_exit(ac_error_str);
+ }
+
+ /*when reset all buffers are released by lib*/
+ u4_num_disp_bufs_with_dec = 0;
+ /*************************************************************************/
+ /* set num of cores */
+ /*************************************************************************/
+ {
+ isvcd_ctl_set_num_cores_ip_t s_ctl_set_cores_ip;
+ isvcd_ctl_set_num_cores_op_t s_ctl_set_cores_op;
+
+ s_ctl_set_cores_ip.e_cmd = IVD_CMD_VIDEO_CTL;
+ s_ctl_set_cores_ip.e_sub_cmd =
+ (IVD_CONTROL_API_COMMAND_TYPE_T) IH264D_CMD_CTL_SET_NUM_CORES;
+ s_ctl_set_cores_ip.u4_num_cores = s_app_ctx.u4_num_cores;
+ s_ctl_set_cores_ip.u4_size = sizeof(isvcd_ctl_set_num_cores_ip_t);
+ s_ctl_set_cores_op.u4_size = sizeof(isvcd_ctl_set_num_cores_op_t);
+
+ ret = ivd_api_function((iv_obj_t *) codec_obj, (void *) &s_ctl_set_cores_ip,
+ (void *) &s_ctl_set_cores_op);
+ if(ret != IV_SUCCESS)
+ {
+ sprintf(ac_error_str, "\nError in setting number of cores");
+ codec_exit(ac_error_str);
+ }
+ }
+ /*************************************************************************/
+ /* set processsor */
+ /*************************************************************************/
+
+ {
+ isvcd_ctl_set_processor_ip_t s_ctl_set_num_processor_ip;
+ isvcd_ctl_set_processor_op_t s_ctl_set_num_processor_op;
+
+ s_ctl_set_num_processor_ip.e_cmd = IVD_CMD_VIDEO_CTL;
+ s_ctl_set_num_processor_ip.e_sub_cmd =
+ (IVD_CONTROL_API_COMMAND_TYPE_T) IH264D_CMD_CTL_SET_PROCESSOR;
+ s_ctl_set_num_processor_ip.u4_arch = s_app_ctx.e_arch;
+ s_ctl_set_num_processor_ip.u4_soc = s_app_ctx.e_soc;
+ s_ctl_set_num_processor_ip.u4_size = sizeof(isvcd_ctl_set_processor_ip_t);
+ s_ctl_set_num_processor_op.u4_size = sizeof(isvcd_ctl_set_processor_op_t);
+
+ ret = ivd_api_function((iv_obj_t *) codec_obj,
+ (void *) &s_ctl_set_num_processor_ip,
+ (void *) &s_ctl_set_num_processor_op);
+ if(ret != IV_SUCCESS)
+ {
+ sprintf(ac_error_str, "\nError in setting Processor type");
+ codec_exit(ac_error_str);
+ }
+ }
+ }
+
+ /*************************************************************************/
+ /* Get SEI MDCV parameters */
+ /*************************************************************************/
+ if(1 == ps_video_decode_op->s_sei_decode_op.u1_sei_mdcv_params_present_flag)
+ {
+ isvcd_ctl_get_sei_mdcv_params_ip_t s_ctl_get_sei_mdcv_params_ip;
+ isvcd_ctl_get_sei_mdcv_params_op_t s_ctl_get_sei_mdcv_params_op;
+
+ memset(&s_ctl_get_sei_mdcv_params_ip, 0,
+ sizeof(isvcd_ctl_get_sei_mdcv_params_ip_t));
+ memset(&s_ctl_get_sei_mdcv_params_op, 0,
+ sizeof(isvcd_ctl_get_sei_mdcv_params_op_t));
+
+ s_ctl_get_sei_mdcv_params_ip.e_cmd = IVD_CMD_VIDEO_CTL;
+ s_ctl_get_sei_mdcv_params_ip.e_sub_cmd =
+ (IVD_CONTROL_API_COMMAND_TYPE_T) IH264D_CMD_CTL_GET_SEI_MDCV_PARAMS;
+ s_ctl_get_sei_mdcv_params_ip.u4_size = sizeof(isvcd_ctl_get_sei_mdcv_params_ip_t);
+ s_ctl_get_sei_mdcv_params_op.u4_size = sizeof(isvcd_ctl_get_sei_mdcv_params_op_t);
+
+ ret =
+ ivd_api_function((iv_obj_t *) codec_obj, (void *) &s_ctl_get_sei_mdcv_params_ip,
+ (void *) &s_ctl_get_sei_mdcv_params_op);
+
+ if(IV_SUCCESS != ret)
+ {
+ printf("MDCV SEI params not present : Error %x\n",
+ s_ctl_get_sei_mdcv_params_op.u4_error_code);
+ }
+ }
+ /*************************************************************************/
+ /* Get SEI CLL parameters */
+ /*************************************************************************/
+ if(1 == ps_video_decode_op->s_sei_decode_op.u1_sei_cll_params_present_flag)
+ {
+ isvcd_ctl_get_sei_cll_params_ip_t s_ctl_get_sei_cll_params_ip;
+ isvcd_ctl_get_sei_cll_params_op_t s_ctl_get_sei_cll_params_op;
+
+ memset(&s_ctl_get_sei_cll_params_ip, 0, sizeof(isvcd_ctl_get_sei_cll_params_ip_t));
+ memset(&s_ctl_get_sei_cll_params_op, 0, sizeof(isvcd_ctl_get_sei_cll_params_op_t));
+
+ s_ctl_get_sei_cll_params_ip.e_cmd = IVD_CMD_VIDEO_CTL;
+ s_ctl_get_sei_cll_params_ip.e_sub_cmd =
+ (IVD_CONTROL_API_COMMAND_TYPE_T) IH264D_CMD_CTL_GET_SEI_CLL_PARAMS;
+ s_ctl_get_sei_cll_params_ip.u4_size = sizeof(isvcd_ctl_get_sei_cll_params_ip_t);
+ s_ctl_get_sei_cll_params_op.u4_size = sizeof(isvcd_ctl_get_sei_cll_params_op_t);
+
+ ret =
+ ivd_api_function((iv_obj_t *) codec_obj, (void *) &s_ctl_get_sei_cll_params_ip,
+ (void *) &s_ctl_get_sei_cll_params_op);
+
+ if(IV_SUCCESS != ret)
+ {
+ printf("CLL SEI params not present : Error %x\n",
+ s_ctl_get_sei_cll_params_op.u4_error_code);
+ }
+ }
+ /*************************************************************************/
+ /* Get SEI AVE parameters */
+ /*************************************************************************/
+ if(1 == ps_video_decode_op->s_sei_decode_op.u1_sei_ave_params_present_flag)
+ {
+ isvcd_ctl_get_sei_ave_params_ip_t s_ctl_get_sei_ave_params_ip;
+ isvcd_ctl_get_sei_ave_params_op_t s_ctl_get_sei_ave_params_op;
+
+ memset(&s_ctl_get_sei_ave_params_ip, 0, sizeof(isvcd_ctl_get_sei_ave_params_ip_t));
+ memset(&s_ctl_get_sei_ave_params_op, 0, sizeof(isvcd_ctl_get_sei_ave_params_op_t));
+
+ s_ctl_get_sei_ave_params_ip.e_cmd = IVD_CMD_VIDEO_CTL;
+ s_ctl_get_sei_ave_params_ip.e_sub_cmd =
+ (IVD_CONTROL_API_COMMAND_TYPE_T) IH264D_CMD_CTL_GET_SEI_AVE_PARAMS;
+ s_ctl_get_sei_ave_params_ip.u4_size = sizeof(isvcd_ctl_get_sei_ave_params_ip_t);
+ s_ctl_get_sei_ave_params_op.u4_size = sizeof(isvcd_ctl_get_sei_ave_params_op_t);
+
+ ret =
+ ivd_api_function((iv_obj_t *) codec_obj, (void *) &s_ctl_get_sei_ave_params_ip,
+ (void *) &s_ctl_get_sei_ave_params_op);
+
+ if(IV_SUCCESS != ret)
+ {
+ printf("AVE SEI params not present : Error %x\n",
+ s_ctl_get_sei_ave_params_op.u4_error_code);
+ }
+ }
+ /*************************************************************************/
+ /* Get SEI CCV parameters */
+ /*************************************************************************/
+ if(1 == ps_video_decode_op->s_sei_decode_op.u1_sei_ccv_params_present_flag)
+ {
+ isvcd_ctl_get_sei_ccv_params_ip_t s_ctl_get_sei_ccv_params_ip;
+ isvcd_ctl_get_sei_ccv_params_op_t s_ctl_get_sei_ccv_params_op;
+
+ memset(&s_ctl_get_sei_ccv_params_ip, 0, sizeof(isvcd_ctl_get_sei_ccv_params_ip_t));
+ memset(&s_ctl_get_sei_ccv_params_op, 0, sizeof(isvcd_ctl_get_sei_ccv_params_op_t));
+
+ s_ctl_get_sei_ccv_params_ip.e_cmd = IVD_CMD_VIDEO_CTL;
+ s_ctl_get_sei_ccv_params_ip.e_sub_cmd =
+ (IVD_CONTROL_API_COMMAND_TYPE_T) IH264D_CMD_CTL_GET_SEI_CCV_PARAMS;
+ s_ctl_get_sei_ccv_params_ip.u4_size = sizeof(isvcd_ctl_get_sei_ccv_params_ip_t);
+ s_ctl_get_sei_ccv_params_op.u4_size = sizeof(isvcd_ctl_get_sei_ccv_params_op_t);
+
+ ret =
+ ivd_api_function((iv_obj_t *) codec_obj, (void *) &s_ctl_get_sei_ccv_params_ip,
+ (void *) &s_ctl_get_sei_ccv_params_op);
+
+ if(IV_SUCCESS != ret)
+ {
+ printf("CCV SEI params not present : Error %x\n",
+ s_ctl_get_sei_ccv_params_op.u4_error_code);
+ }
+ }
+
+ if((1 == s_app_ctx.display) && (1 == ps_video_decode_op->u4_output_present))
+ {
+ dispq_producer_queue(&s_app_ctx);
+ }
+
+ if(IV_B_FRAME == ps_video_decode_op->e_pic_type) s_app_ctx.b_pic_present |= 1;
+
+ u4_num_bytes_dec = ps_video_decode_op->u4_num_bytes_consumed;
+
+ file_pos += u4_num_bytes_dec;
+ total_bytes_comsumed += u4_num_bytes_dec;
+ u4_ip_frm_ts++;
+
+ if(1 == ps_video_decode_op->u4_output_present)
+ {
+ CHAR cur_fname[1000];
+ CHAR *extn = NULL;
+ /* The objective is to dump the decoded frames into separate files instead
+ * of dumping all the frames in one common file. Also, the number of
+ * dumped frames at any given instance of time cannot exceed
+ * 'frame_memory'
+ */
+ if(s_app_ctx.u4_file_save_flag)
+ {
+ /* Locate the position of extension yuv */
+ extn = strstr(s_app_ctx.ac_op_fname, "%d");
+ if(extn != NULL)
+ {
+ output_write_stall(s_app_ctx.ac_op_fname, u4_op_frm_ts);
+ /* Generate output file names */
+ sprintf(cur_fname, s_app_ctx.ac_op_fname, u4_op_frm_ts);
+ /* Open Output file */
+ ps_op_file = fopen(cur_fname, "wb");
+ if(NULL == ps_op_file)
+ {
+ snprintf(ac_error_str, sizeof(ac_error_str),
+ "Could not open output file %s", cur_fname);
+
+ codec_exit(ac_error_str);
+ }
+ }
+ }
+
+#ifdef PROFILE_ENABLE
+ width = ps_video_decode_op->s_disp_frm_buf.u4_y_wd;
+ height = ps_video_decode_op->s_disp_frm_buf.u4_y_ht;
+#endif
+ dump_output(&s_app_ctx, &(ps_video_decode_op->s_disp_frm_buf), &s_h264d_decode_op,
+ ps_video_decode_op->u4_disp_buf_id, ps_op_file, ps_qp_file,
+ ps_mb_type_file, ps_op_chksum_file, u4_op_frm_ts,
+ s_app_ctx.u4_file_save_flag, s_app_ctx.u4_chksum_save_flag,
+ s_app_ctx.u4_frame_info_enable);
+
+ u4_op_frm_ts++;
+ if(extn != NULL) fclose(ps_op_file);
+ }
+ else
+ {
+ if((ps_video_decode_op->u4_error_code >> IVD_FATALERROR) & 1)
+ {
+ printf("Fatal error\n");
+ break;
+ }
+ }
+ }
+ }
+
+ /***********************************************************************/
+ /* To get the last decoded frames, call process with NULL input */
+ /***********************************************************************/
+ flush_output(codec_obj, &s_app_ctx, ps_out_buf, pu1_bs_buf, &u4_op_frm_ts, ps_op_file,
+ ps_qp_file, ps_mb_type_file, pu1_qp_map_buf, pu1_blk_type_map_buf,
+ ps_op_chksum_file, u4_ip_frm_ts, u4_bytes_remaining);
+
+ /* set disp_end u4_flag */
+ s_app_ctx.quit = 1;
+
+#ifdef PROFILE_ENABLE
+ printf("Summary\n");
+ printf("Input filename : %s\n", s_app_ctx.ac_ip_fname);
+ printf("Output Width : %-4d\n", width);
+ printf("Output Height : %-4d\n", height);
+
+ if(frm_cnt)
+ {
+ double avg = u4_tot_cycles / frm_cnt;
+ double bytes_avg = total_bytes_comsumed / frm_cnt;
+ double bitrate = (bytes_avg * 8 * s_app_ctx.fps) / 1000000;
+ printf("Bitrate @ %2d fps(mbps) : %-6.2f\n", s_app_ctx.fps, bitrate);
+ printf("Average decode time(micro sec) : %-6d\n", (WORD32) avg);
+ printf("Avg Peak decode time(%2d frames) : %-6d\n", PEAK_WINDOW_SIZE,
+ (WORD32) peak_avg_max);
+ avg = (u4_tot_cycles + u4_tot_fmt_cycles) * 1.0 / frm_cnt;
+
+ if(0 == s_app_ctx.u4_share_disp_buf)
+ printf("FPS achieved (with format conv) : %-3.2f\n", 1000000 / avg);
+ else
+ printf("FPS achieved : %-3.2f\n", 1000000 / avg);
+ }
+#endif
+ /***********************************************************************/
+ /* Clear the decoder, close all the files, free all the memory */
+ /***********************************************************************/
+ if(1 == s_app_ctx.display)
+ {
+ s_app_ctx.display_deinit_flag = 1;
+ /* wait for display to finish */
+ if(s_app_ctx.display_thread_created)
+ {
+ ithread_join(s_app_ctx.display_thread_handle, NULL);
+ }
+ free(s_app_ctx.display_thread_handle);
+ }
+
+ {
+ ivd_delete_ip_t s_delete_dec_ip;
+ ivd_delete_op_t s_delete_dec_op;
+
+ s_delete_dec_ip.e_cmd = IVD_CMD_DELETE;
+ s_delete_dec_ip.u4_size = sizeof(ivd_delete_ip_t);
+ s_delete_dec_op.u4_size = sizeof(ivd_delete_op_t);
+
+ ret = ivd_api_function((iv_obj_t *) codec_obj, (void *) &s_delete_dec_ip,
+ (void *) &s_delete_dec_op);
+
+ if(IV_SUCCESS != ret)
+ {
+ sprintf(ac_error_str, "Error in Codec delete");
+ codec_exit(ac_error_str);
+ }
+ }
+ /***********************************************************************/
+ /* Close all the files and free all the memory */
+ /***********************************************************************/
+ {
+ fclose(ps_ip_file);
+
+ if((1 == s_app_ctx.u4_file_save_flag) && (strstr(s_app_ctx.ac_op_fname, "%d") == NULL))
+ {
+ fclose(ps_op_file);
+ }
+ if(1 == s_app_ctx.u4_chksum_save_flag)
+ {
+ fclose(ps_op_chksum_file);
+ }
+ if(1 == s_app_ctx.u4_frame_info_enable)
+ {
+ if(NULL != ps_qp_file)
+ {
+ fclose(ps_qp_file);
+ }
+ if(NULL != ps_mb_type_file)
+ {
+ fclose(ps_mb_type_file);
+ }
+ }
+ }
+
+ if(0 == s_app_ctx.u4_share_disp_buf)
+ {
+ free(ps_out_buf->pu1_bufs[0]);
+ }
+
+ for(i = 0; i < s_app_ctx.num_disp_buf; i++)
+ {
+ free(s_app_ctx.s_disp_buffers[i].pu1_bufs[0]);
+ }
+
+ free(ps_out_buf);
+ free(pu1_bs_buf);
+ if(1 == s_app_ctx.u4_frame_info_enable)
+ {
+ if(pu1_qp_map_buf)
+ {
+ free(pu1_qp_map_buf);
+ }
+ if(pu1_blk_type_map_buf)
+ {
+ free(pu1_blk_type_map_buf);
+ }
+ }
+
+ if(s_app_ctx.display_thread_handle) free(s_app_ctx.display_thread_handle);
+
+ return (0);
+}