[RESTRICT AUTOMERGE] CTS test for Android Security b/120644655

Bug: 120644655
Bug: 128930802
Test: Ran the new testcase on android-8.1.0_r1 with/without patch

Change-Id: I350a4fee25ae5877bbeafc99a0e613f615b27755
diff --git a/hostsidetests/securitybulletin/res/cve_2019_2028.m2v b/hostsidetests/securitybulletin/res/cve_2019_2028.m2v
new file mode 100644
index 0000000..ca6a50e
--- /dev/null
+++ b/hostsidetests/securitybulletin/res/cve_2019_2028.m2v
Binary files differ
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2019-2028/Android.mk b/hostsidetests/securitybulletin/securityPatch/CVE-2019-2028/Android.mk
new file mode 100644
index 0000000..5a418c5
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2019-2028/Android.mk
@@ -0,0 +1,41 @@
+# Copyright (C) 2020 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.
+
+LOCAL_PATH := $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := CVE-2019-2028
+LOCAL_SRC_FILES := poc.c
+ifeq ($(ARCH_ARM_HAVE_NEON),true)
+LOCAL_SRC_FILES_arm += poc_arm_neon_utils.c
+LOCAL_SRC_FILES_arm += arm_neon_utils.s
+endif
+LOCAL_MULTILIB := 32
+LOCAL_MODULE_STEM_32 := $(LOCAL_MODULE)32
+LOCAL_C_INCLUDES_32 := external/libmpeg2/common
+LOCAL_C_INCLUDES_32 += external/libmpeg2/decoder
+LOCAL_SHARED_LIBRARIES_32 := liblog
+LOCAL_SHARED_LIBRARIES_32 += libstagefright_soft_mpeg2dec
+
+# Tag this module as a cts test artifact
+LOCAL_COMPATIBILITY_SUITE := cts sts vts
+LOCAL_CTS_TEST_PACKAGE := android.security.cts
+
+LOCAL_ARM_MODE := arm
+LOCAL_CFLAGS += -Wall -Werror -Wno-uninitialized -Wno-unused-variable
+LOCAL_CFLAGS += -fPIC -DMD5_DISABLE
+ifeq ($(ARCH_ARM_HAVE_NEON),true)
+LOCAL_CFLAGS_arm += -DCHECK_ARM_REGISTERS
+endif
+include $(BUILD_CTS_EXECUTABLE)
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2019-2028/arm_neon_utils.s b/hostsidetests/securitybulletin/securityPatch/CVE-2019-2028/arm_neon_utils.s
new file mode 100644
index 0000000..c85ee09
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2019-2028/arm_neon_utils.s
@@ -0,0 +1,32 @@
+.text
+.align 4
+
+.globl write_to_callee_saved_registers
+.type write_to_callee_saved_registers, %function
+write_to_callee_saved_registers:
+
+    push        {lr}
+    vld1.64      d8,[r0]!
+    vld1.64      d9,[r0]!
+    vld1.64      d10,[r0]!
+    vld1.64      d11,[r0]!
+    vld1.64      d12,[r0]!
+    vld1.64      d13,[r0]!
+    vld1.64      d14,[r0]!
+    vld1.64      d15,[r0]!
+    pop         {pc}
+
+.globl read_from_callee_saved_registers
+.type read_from_callee_saved_registers, %function
+read_from_callee_saved_registers:
+
+    push        {lr}
+    vst1.64      d8,[r0]!
+    vst1.64      d9,[r0]!
+    vst1.64      d10,[r0]!
+    vst1.64      d11,[r0]!
+    vst1.64      d12,[r0]!
+    vst1.64      d13,[r0]!
+    vst1.64      d14,[r0]!
+    vst1.64      d15,[r0]!
+    pop         {pc}
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2019-2028/poc.c b/hostsidetests/securitybulletin/securityPatch/CVE-2019-2028/poc.c
new file mode 100644
index 0000000..4bab9ae
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2019-2028/poc.c
@@ -0,0 +1,2993 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2015 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 Name         : main.c                                               */
+/*                                                                           */
+/*  Description       : Contains an application that demonstrates use of HEVC*/
+/*                      decoder API                                          */
+/*                                                                           */
+/*  List of Functions :                                                      */
+/*                                                                           */
+/*  Issues / Problems : None                                                 */
+/*                                                                           */
+/*  Revision History  :                                                      */
+/*                                                                           */
+/*         DD MM YYYY   Author(s)       Changes                              */
+/*         07 09 2012   Harish          Initial Version                      */
+/*****************************************************************************/
+/*****************************************************************************/
+/* File Includes                                                             */
+/*****************************************************************************/
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+#ifdef X86_MINGW
+#include <signal.h>
+#endif
+
+#ifndef IOS
+#include <malloc.h>
+#endif
+#ifdef IOS_DISPLAY
+#include "cast_types.h"
+#else
+#include "iv_datatypedef.h"
+#endif
+
+#include "iv.h"
+#include "ivd.h"
+#include "impeg2d.h"
+#include "ithread.h"
+
+#ifdef WINDOWS_TIMER
+#include <windows.h>
+#else
+#include <sys/time.h>
+#endif
+
+#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  0
+#define STRLENGTH 1000
+
+//#define TEST_FLUSH
+#define FLUSH_FRM_CNT 100
+
+#ifdef IOS
+#define PATHLENMAX 500
+char filename_with_path[PATHLENMAX];
+#endif
+
+#ifdef PROFILE_ENABLE
+#ifdef WINDOWS_TIMER
+typedef LARGE_INTEGER TIMER;
+#else
+typedef struct timeval TIMER;
+#endif
+#else
+typedef WORD32 TIMER;
+#endif
+
+#ifdef PROFILE_ENABLE
+#ifdef WINDOWS_TIMER
+#define GETTIME(timer) QueryPerformanceCounter(timer);
+#else
+#define GETTIME(timer) gettimeofday(timer,NULL);
+#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
+#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
+
+#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_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 share_disp_buf;
+    UWORD32 deinterlace;
+    UWORD32 num_disp_buf;
+    UWORD32 b_pic_present;
+    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_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 max_wd;
+    UWORD32 max_ht;
+    UWORD32 max_level;
+
+    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;
+
+    //UWORD32 u4_output_present;
+    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;
+
+typedef enum {
+    INVALID,
+    HELP,
+    VERSION,
+    INPUT_FILE,
+    OUTPUT,
+    CHKSUM,
+    SAVE_OUTPUT,
+    SAVE_CHKSUM,
+    CHROMA_FORMAT,
+    NUM_FRAMES,
+    NUM_CORES,
+
+    SHARE_DISPLAY_BUF,
+    DEINTERLACE,
+    LOOPBACK,
+    DISPLAY,
+    FULLSCREEN,
+    FPS,
+    TRACE,
+    MAX_WD,
+    MAX_HT,
+    MAX_LEVEL,
+    CONFIG,
+
+    DEGRADE_TYPE,
+    DEGRADE_PICS,
+    ARCH,
+    SOC,
+    PICLEN,
+    PICLEN_FILE,
+} 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" },
+                { "--", "--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 size\n" },
+                { "--", "--chksum", CHKSUM, "Output MD5 Checksum file\n" },
+                { "-s", "--save_output", SAVE_OUTPUT, "Save Output 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" }, { "--",
+                        "--deinterlace", DEINTERLACE,
+                        "Enable deinterlacing for interlaced pics\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" }, { "--", "--max_wd",
+                        MAX_WD, "Maximum width (Default: 2560) \n" },
+                { "--", "--max_ht", MAX_HT, "Maximum height (Default: 1600)\n" },
+                { "--", "--arch", ARCH,
+                        "Set Architecture. Supported values  ARM_NONEON, ARM_A9Q, ARM_A7, ARM_A5, ARM_NEONINTR, X86_GENERIC, X86_SSSE3, X86_SSE4 \n" },
+                { "--", "--soc", SOC,
+                        "Set SOC. Supported values  GENERIC, HISI_37X \n" },
+
+#if 0
+        {   "--", "--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"},
+
+        {   "--", "--max_level", MAX_LEVEL,
+            "Maximum Decoder Level (Default: 50)\n"},
+#endif
+    };
+
+#define PEAK_WINDOW_SIZE            8
+#define MAX_FRAME_WIDTH             2560
+#define MAX_FRAME_HEIGHT            1600
+#define MAX_LEVEL_SUPPORTED         50
+#define MAX_REF_FRAMES              16
+#define MAX_REORDER_FRAMES          16
+#define DEFAULT_SHARE_DISPLAY_BUF   0
+#define DEFAULT_DEINTERLACE         0
+#define STRIDE                      0
+#define DEFAULT_NUM_CORES           1
+
+#define DUMP_SINGLE_BUF 0
+#define IV_ISFATALERROR(x)         (((x) >> IVD_FATALERROR) & 0x1)
+
+#ifdef CHECK_ARM_REGISTERS
+IV_API_CALL_STATUS_T ivd_api_function (iv_obj_t *ps_dechdl, void *pv_api_ip, \
+                                           void *pv_api_op);
+#else
+#define ivd_api_function        impeg2d_api_function
+#endif
+
+#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                                                */
+/*                  size                                                     */
+/*  Globals       :                                                          */
+/*  Processing    :                                                          */
+/*                                                                           */
+/*  Outputs       :                                                          */
+/*  Returns       :                                                          */
+/*                                                                           */
+/*  Issues        :                                                          */
+/*                                                                           */
+/*  Revision History:                                                        */
+/*                                                                           */
+/*         DD MM YYYY   Author(s)       Changes                              */
+/*         07 09 2012   100189          Initial Version                      */
+/*                                                                           */
+/*****************************************************************************/
+
+void* app_aligned_malloc(WORD32 alignment, WORD32 size)
+{
+    return (void *)_aligned_malloc(size, alignment);
+}
+
+void app_aligned_free(void *pv_buf)
+{
+    _aligned_free(pv_buf);
+    return;
+}
+#endif
+
+#if IOS
+void* app_aligned_malloc(WORD32 alignment, WORD32 size)
+{
+    return malloc(size);
+}
+
+void app_aligned_free(void *pv_buf)
+{
+    free(pv_buf);
+    return;
+}
+#endif
+
+#if (!defined(IOS)) && (!defined(_WIN32))
+void* app_aligned_malloc(WORD32 alignment, WORD32 size) {
+    return memalign(alignment, size);
+}
+
+void app_aligned_free(void *pv_buf) {
+    free(pv_buf);
+    return;
+}
+#endif
+
+/*****************************************************************************/
+/*                                                                           */
+/*  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 status                               */
+/*                                                                           */
+/*  Issues        :                                                          */
+/*                                                                           */
+/*  Revision History:                                                        */
+/*                                                                           */
+/*         DD MM YYYY   Author(s)       Changes                              */
+/*         07 09 2012   100189          Initial Version                      */
+/*                                                                           */
+/*****************************************************************************/
+
+IV_API_CALL_STATUS_T set_degrade(void *codec_obj, UWORD32 type, WORD32 pics) {
+    IV_API_CALL_STATUS_T e_dec_status = IV_SUCCESS;
+#if 0
+    impeg2d_ctl_degrade_ip_t s_ctl_ip;
+    impeg2d_ctl_degrade_op_t s_ctl_op;
+    void *pv_api_ip, *pv_api_op;
+
+    s_ctl_ip.u4_size = sizeof(impeg2d_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(impeg2d_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)IMPEG2D_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");
+    }
+#endif
+    ((void) (codec_obj));
+    ((void) (type));
+    ((void) (pics));
+    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 status                               */
+/*                                                                           */
+/*  Issues        :                                                          */
+/*                                                                           */
+/*  Revision History:                                                        */
+/*                                                                           */
+/*         DD MM YYYY   Author(s)       Changes                              */
+/*         07 09 2012   100189          Initial Version                      */
+/*                                                                           */
+/*****************************************************************************/
+
+IV_API_CALL_STATUS_T enable_skipb_frames(void *codec_obj,
+                                         vid_dec_ctx_t *ps_app_ctx) {
+    ivd_ctl_set_config_ip_t s_ctl_ip;
+    ivd_ctl_set_config_op_t s_ctl_op;
+    IV_API_CALL_STATUS_T e_dec_status;
+
+    s_ctl_ip.u4_disp_wd = ps_app_ctx->u4_strd;
+    s_ctl_ip.e_frm_skip_mode = IVD_SKIP_B;
+
+    s_ctl_ip.e_frm_out_mode = IVD_DISPLAY_FRAME_OUT;
+    s_ctl_ip.e_vid_dec_mode = IVD_DECODE_FRAME;
+    s_ctl_ip.e_cmd = IVD_CMD_VIDEO_CTL;
+    s_ctl_ip.e_sub_cmd = IVD_CMD_CTL_SETPARAMS;
+    s_ctl_ip.u4_size = sizeof(ivd_ctl_set_config_ip_t);
+    s_ctl_op.u4_size = sizeof(ivd_ctl_set_config_op_t);
+
+    e_dec_status = ivd_api_function((iv_obj_t *) codec_obj, (void *) &s_ctl_ip,
+                                    (void *) &s_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 status                               */
+/*                                                                           */
+/*  Issues        :                                                          */
+/*                                                                           */
+/*  Revision History:                                                        */
+/*                                                                           */
+/*         DD MM YYYY   Author(s)       Changes                              */
+/*         07 09 2012   100189          Initial Version                      */
+/*                                                                           */
+/*****************************************************************************/
+
+IV_API_CALL_STATUS_T disable_skipb_frames(void *codec_obj,
+                                          vid_dec_ctx_t *ps_app_ctx) {
+    ivd_ctl_set_config_ip_t s_ctl_ip;
+    ivd_ctl_set_config_op_t s_ctl_op;
+    IV_API_CALL_STATUS_T e_dec_status;
+
+    s_ctl_ip.u4_disp_wd = ps_app_ctx->u4_strd;
+    s_ctl_ip.e_frm_skip_mode = IVD_SKIP_NONE;
+
+    s_ctl_ip.e_frm_out_mode = IVD_DISPLAY_FRAME_OUT;
+    s_ctl_ip.e_vid_dec_mode = IVD_DECODE_FRAME;
+    s_ctl_ip.e_cmd = IVD_CMD_VIDEO_CTL;
+    s_ctl_ip.e_sub_cmd = IVD_CMD_CTL_SETPARAMS;
+    s_ctl_ip.u4_size = sizeof(ivd_ctl_set_config_ip_t);
+    s_ctl_op.u4_size = sizeof(ivd_ctl_set_config_op_t);
+
+    e_dec_status = ivd_api_function((iv_obj_t *) codec_obj, (void *) &s_ctl_ip,
+                                    (void *) &s_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 status                               */
+/*                                                                           */
+/*  Issues        :                                                          */
+/*                                                                           */
+/*  Revision History:                                                        */
+/*                                                                           */
+/*         DD MM YYYY   Author(s)       Changes                              */
+/*         07 09 2012   100189          Initial Version                      */
+/*                                                                           */
+/*****************************************************************************/
+
+IV_API_CALL_STATUS_T enable_skippb_frames(void *codec_obj,
+                                          vid_dec_ctx_t *ps_app_ctx) {
+    ivd_ctl_set_config_ip_t s_ctl_ip;
+    ivd_ctl_set_config_op_t s_ctl_op;
+    IV_API_CALL_STATUS_T e_dec_status;
+
+    s_ctl_ip.u4_disp_wd = ps_app_ctx->u4_strd;
+    s_ctl_ip.e_frm_skip_mode = IVD_SKIP_PB;
+
+    s_ctl_ip.e_frm_out_mode = IVD_DISPLAY_FRAME_OUT;
+    s_ctl_ip.e_vid_dec_mode = IVD_DECODE_FRAME;
+    s_ctl_ip.e_cmd = IVD_CMD_VIDEO_CTL;
+    s_ctl_ip.e_sub_cmd = IVD_CMD_CTL_SETPARAMS;
+    s_ctl_ip.u4_size = sizeof(ivd_ctl_set_config_ip_t);
+    s_ctl_op.u4_size = sizeof(ivd_ctl_set_config_op_t);
+
+    e_dec_status = ivd_api_function((iv_obj_t *) codec_obj, (void *) &s_ctl_ip,
+                                    (void *) &s_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 status                               */
+/*                                                                           */
+/*  Issues        :                                                          */
+/*                                                                           */
+/*  Revision History:                                                        */
+/*                                                                           */
+/*         DD MM YYYY   Author(s)       Changes                              */
+/*         07 09 2012   100189          Initial Version                      */
+/*                                                                           */
+/*****************************************************************************/
+
+IV_API_CALL_STATUS_T disable_skippb_frames(void *codec_obj,
+                                           vid_dec_ctx_t *ps_app_ctx) {
+    ivd_ctl_set_config_ip_t s_ctl_ip;
+    ivd_ctl_set_config_op_t s_ctl_op;
+    IV_API_CALL_STATUS_T e_dec_status;
+
+    s_ctl_ip.u4_disp_wd = ps_app_ctx->u4_strd;
+    s_ctl_ip.e_frm_skip_mode = IVD_SKIP_NONE;
+
+    s_ctl_ip.e_frm_out_mode = IVD_DISPLAY_FRAME_OUT;
+    s_ctl_ip.e_vid_dec_mode = IVD_DECODE_FRAME;
+    s_ctl_ip.e_cmd = IVD_CMD_VIDEO_CTL;
+    s_ctl_ip.e_sub_cmd = IVD_CMD_CTL_SETPARAMS;
+    s_ctl_ip.u4_size = sizeof(ivd_ctl_set_config_ip_t);
+    s_ctl_op.u4_size = sizeof(ivd_ctl_set_config_op_t);
+
+    e_dec_status = ivd_api_function((iv_obj_t *) codec_obj, (void *) &s_ctl_ip,
+                                    (void *) &s_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                              */
+/*         07 09 2012   100189          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 status                               */
+/*                                                                           */
+/*  Issues        :                                                          */
+/*                                                                           */
+/*  Revision History:                                                        */
+/*                                                                           */
+/*         DD MM YYYY   Author(s)       Changes                              */
+/*         07 09 2012   100189          Initial Version                      */
+/*                                                                           */
+/*****************************************************************************/
+
+IV_API_CALL_STATUS_T get_version(void *codec_obj) {
+    ivd_ctl_getversioninfo_ip_t s_ctl_dec_ip;
+    ivd_ctl_getversioninfo_op_t s_ctl_dec_op;
+    UWORD8 au1_buf[512];
+    IV_API_CALL_STATUS_T status;
+    s_ctl_dec_ip.e_cmd = IVD_CMD_VIDEO_CTL;
+    s_ctl_dec_ip.e_sub_cmd = IVD_CMD_CTL_GETVERSION;
+    s_ctl_dec_ip.u4_size = sizeof(ivd_ctl_getversioninfo_ip_t);
+    s_ctl_dec_op.u4_size = sizeof(ivd_ctl_getversioninfo_op_t);
+    s_ctl_dec_ip.pv_version_buffer = au1_buf;
+    s_ctl_dec_ip.u4_version_buffer_size = sizeof(au1_buf);
+
+    status = ivd_api_function((iv_obj_t *) codec_obj, (void *) &(s_ctl_dec_ip),
+                              (void *) &(s_ctl_dec_op));
+
+    if (status != IV_SUCCESS) {
+        printf("Error in Getting Version number e_dec_status = %d u4_error_code = %x\n",
+               status, s_ctl_dec_op.u4_error_code);
+    } else {
+        printf("Ittiam Decoder Version number: %s\n",
+               (char *) s_ctl_dec_ip.pv_version_buffer);
+    }
+    return status;
+}
+/*****************************************************************************/
+/*                                                                           */
+/*  Function Name : codec_exit                                               */
+/*                                                                           */
+/*  Description   : handles unrecoverable errors                             */
+/*  Inputs        : Error message                                            */
+/*  Globals       : None                                                     */
+/*  Processing    : Prints error message to console and exits.               */
+/*  Outputs       : Error message to the console                              */
+/*  Returns       : None                                                     */
+/*                                                                           */
+/*  Issues        :                                                          */
+/*                                                                           */
+/*  Revision History:                                                        */
+/*                                                                           */
+/*         DD MM YYYY   Author(s)       Changes (Describe the changes made)  */
+/*         07 06 2006   Sankar          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)  */
+/*         07 06 2006   Sankar          Creation                             */
+/*                                                                           */
+/*****************************************************************************/
+void dump_output(vid_dec_ctx_t *ps_app_ctx, iv_yuv_buf_t *ps_disp_frm_buf,
+                 UWORD32 u4_disp_frm_id, FILE *ps_op_file,
+                 FILE *ps_op_chksum_file, WORD32 i4_op_frm_ts,
+                 UWORD32 file_save, UWORD32 chksum_save)
+
+                 {
+
+    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->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;
+    }
+    if (1 == ps_app_ctx->share_disp_buf)
+        release_disp_frame(ps_app_ctx->cocodec_obj, u4_disp_id);
+
+    if (0 == file_save && 0 == chksum_save)
+        return;
+
+    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 - 24 - (s_dump_disp_frm_buf.u4_y_strd * 40);
+
+            UWORD32 size = s_dump_disp_frm_buf.u4_y_strd * ((s_dump_disp_frm_buf.u4_y_ht + 80) + (s_dump_disp_frm_buf.u4_u_ht + 40));
+            fwrite(buf, 1, size, ps_op_file);
+
+        }
+#else
+        if (0 != file_save) {
+            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) {
+            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 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, 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                              */
+/*         07 09 2012   100189          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                              */
+/*         07 09 2012   100189          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                              */
+/*         07 09 2012   100189          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, "%s", ps_app_ctx->ac_ip_fname);
+            //input_passed = 1;
+            break;
+
+        case OUTPUT:
+            sscanf(value, "%s", ps_app_ctx->ac_op_fname);
+            break;
+
+        case CHKSUM:
+            sscanf(value, "%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_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);
+            ps_app_ctx->i4_degrade_pics = 0;
+            printf("degrade_pics is not supported. Setting it to zero");
+            break;
+        case DEGRADE_TYPE:
+            sscanf(value, "%d", &ps_app_ctx->i4_degrade_type);
+            break;
+        case SHARE_DISPLAY_BUF:
+            sscanf(value, "%d", &ps_app_ctx->share_disp_buf);
+            break;
+        case DEINTERLACE:
+            sscanf(value, "%d", &ps_app_ctx->deinterlace);
+            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 MAX_WD:
+            sscanf(value, "%d", &ps_app_ctx->max_wd);
+            break;
+        case MAX_HT:
+            sscanf(value, "%d", &ps_app_ctx->max_ht);
+            break;
+        case MAX_LEVEL:
+            sscanf(value, "%d", &ps_app_ctx->max_level);
+            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_V8")) == 0)
+                ps_app_ctx->e_arch = ARCH_ARMV8_GENERIC;
+            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 {
+                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, "%s", ps_app_ctx->ac_piclen_fname);
+            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                              */
+/*         07 09 2012   100189          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_msleep(1);
+
+        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_msleep(1);
+
+        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                              */
+/*         07 05 2013   100578          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;
+    UWORD32 expected_time;
+    TIMER s_end_timer;
+    TIMER s_first_frame_time;
+    UWORD32 first_frame_displayed;
+
+#ifdef WINDOWS_TIMER
+    TIMER frequency;
+#endif
+
+#ifdef WINDOWS_TIMER
+    QueryPerformanceFrequency(&frequency);
+#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->max_wd, ps_app_ctx->max_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);
+
+    /* destroy the display thread */
+    ithread_exit(ps_app_ctx->display_thread_handle);
+
+    return 0;
+}
+
+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_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) {
+            ivd_video_decode_ip_t s_video_decode_ip;
+            ivd_video_decode_op_t s_video_decode_op;
+
+            s_video_decode_ip.e_cmd = IVD_CMD_VIDEO_DECODE;
+            s_video_decode_ip.u4_ts = u4_ip_frm_ts;
+            s_video_decode_ip.pv_stream_buffer = pu1_bs_buf;
+            s_video_decode_ip.u4_num_Bytes = u4_bytes_remaining;
+            s_video_decode_ip.u4_size = sizeof(ivd_video_decode_ip_t);
+            s_video_decode_ip.s_out_buffer.u4_min_out_buf_size[0] = ps_out_buf
+                    ->u4_min_out_buf_size[0];
+            s_video_decode_ip.s_out_buffer.u4_min_out_buf_size[1] = ps_out_buf
+                    ->u4_min_out_buf_size[1];
+            s_video_decode_ip.s_out_buffer.u4_min_out_buf_size[2] = ps_out_buf
+                    ->u4_min_out_buf_size[2];
+
+            s_video_decode_ip.s_out_buffer.pu1_bufs[0] =
+                    ps_out_buf->pu1_bufs[0];
+            s_video_decode_ip.s_out_buffer.pu1_bufs[1] =
+                    ps_out_buf->pu1_bufs[1];
+            s_video_decode_ip.s_out_buffer.pu1_bufs[2] =
+                    ps_out_buf->pu1_bufs[2];
+            s_video_decode_ip.s_out_buffer.u4_num_bufs =
+                    ps_out_buf->u4_num_bufs;
+
+            s_video_decode_op.u4_size = sizeof(ivd_video_decode_op_t);
+
+            /*****************************************************************************/
+            /*   API Call: Video Decode                                                  */
+            /*****************************************************************************/
+            ret = ivd_api_function((iv_obj_t *) codec_obj,
+                                   (void *) &s_video_decode_ip,
+                                   (void *) &s_video_decode_op);
+
+            if (1 == s_video_decode_op.u4_output_present) {
+                dump_output(ps_app_ctx, &(s_video_decode_op.s_disp_frm_buf),
+                            s_video_decode_op.u4_disp_buf_id, ps_op_file,
+                            ps_op_chksum_file, *pu4_op_frm_ts,
+                            ps_app_ctx->u4_file_save_flag,
+                            ps_app_ctx->u4_chksum_save_flag);
+
+                (*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                              */
+/*         07 09 2012   100189          Initial Version                      */
+/*         09 05 2013   100578          Multithread decode-display           */
+/*****************************************************************************/
+#ifdef IOS
+int vdec_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_op_chksum_file = NULL;
+    WORD32 ret;
+    CHAR ac_error_str[STRLENGTH];
+    vid_dec_ctx_t s_app_ctx;
+    UWORD8 *pu1_bs_buf;
+
+    ivd_out_bufdesc_t *ps_out_buf;
+    UWORD32 u4_num_bytes_dec = 0;
+    UWORD32 file_pos = 0;
+    IV_API_CALL_STATUS_T e_dec_status;
+    UWORD32 u4_ip_frm_ts = 0, u4_op_frm_ts = 0;
+
+    WORD32 u4_bytes_remaining = 0;
+    void *pv_mem_rec_location;
+    UWORD32 u4_num_mem_recs;
+    UWORD32 i;
+    UWORD32 u4_ip_buf_len;
+    UWORD32 frm_cnt = 0;
+    WORD32 total_bytes_comsumed;
+
+#ifdef PROFILE_ENABLE
+    UWORD32 u4_tot_cycles = 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
+    TIMER frequency;
+#endif
+    WORD32 width = 0, height = 0;
+    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.deinterlace = DEFAULT_DEINTERLACE;
+    s_app_ctx.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.max_wd = 0;
+    s_app_ctx.max_ht = 0;
+    s_app_ctx.max_level = 0;
+    s_app_ctx.e_arch = ARCH_ARM_A9Q;
+    s_app_ctx.e_soc = SOC_GENERIC;
+
+    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.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) {
+                    sprintf(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) {
+            sprintf(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
+    sprintf(filename_with_path, "%s/%s", homedir, ac_cfg_fname);
+    if((fp_cfg_file = fopen(filename_with_path, "r")) == NULL)
+    {
+        sprintf(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.deinterlace = 0;
+    s_app_ctx.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.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);
+    }
+
+    /***********************************************************************/
+    /*          create the file object for input file                      */
+    /***********************************************************************/
+#ifdef IOS
+    sprintf(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) {
+        sprintf(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
+        sprintf(filename_with_path, "%s/%s", homedir, 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) {
+            sprintf(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 (1 == s_app_ctx.u4_file_save_flag) {
+#ifdef IOS
+        sprintf(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) {
+            sprintf(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 check sum file                  */
+    /***********************************************************************/
+    if (1 == s_app_ctx.u4_chksum_save_flag) {
+#if IOS
+        sprintf(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) {
+            sprintf(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));
+
+        {
+            iv_num_mem_rec_ip_t s_no_of_mem_rec_query_ip;
+            iv_num_mem_rec_op_t s_no_of_mem_rec_query_op;
+
+            s_no_of_mem_rec_query_ip.u4_size = sizeof(s_no_of_mem_rec_query_ip);
+            s_no_of_mem_rec_query_op.u4_size = sizeof(s_no_of_mem_rec_query_op);
+            s_no_of_mem_rec_query_ip.e_cmd = IV_CMD_GET_NUM_MEM_REC;
+
+            /*****************************************************************************/
+            /*   API Call: Get Number of Mem Records                                     */
+            /*****************************************************************************/
+            e_dec_status = ivd_api_function(NULL,
+                                            (void *) &s_no_of_mem_rec_query_ip,
+                                            (void *) &s_no_of_mem_rec_query_op);
+            if (IV_SUCCESS != e_dec_status) {
+                sprintf(ac_error_str, "Error in get mem records");
+                codec_exit(ac_error_str);
+            }
+
+            u4_num_mem_recs = s_no_of_mem_rec_query_op.u4_num_mem_rec;
+        }
+
+        pv_mem_rec_location = malloc(u4_num_mem_recs * sizeof(iv_mem_rec_t));
+        if (pv_mem_rec_location == NULL) {
+            sprintf(ac_error_str, "Allocation failure for mem_rec_location");
+            codec_exit(ac_error_str);
+
+        }
+
+        {
+            impeg2d_fill_mem_rec_ip_t s_fill_mem_rec_ip;
+            impeg2d_fill_mem_rec_op_t s_fill_mem_rec_op;
+            iv_mem_rec_t *ps_mem_rec;
+            UWORD32 total_size;
+
+            s_fill_mem_rec_ip.s_ivd_fill_mem_rec_ip_t.e_cmd =
+                    IV_CMD_FILL_NUM_MEM_REC;
+            s_fill_mem_rec_ip.s_ivd_fill_mem_rec_ip_t.pv_mem_rec_location =
+                    (iv_mem_rec_t *) pv_mem_rec_location;
+            s_fill_mem_rec_ip.s_ivd_fill_mem_rec_ip_t.u4_max_frm_wd =
+                    (s_app_ctx.max_wd == 0) ?
+                    MAX_FRAME_WIDTH :
+                                              s_app_ctx.max_wd;
+            s_fill_mem_rec_ip.s_ivd_fill_mem_rec_ip_t.u4_max_frm_ht =
+                    (s_app_ctx.max_ht == 0) ?
+                    MAX_FRAME_HEIGHT :
+                                              s_app_ctx.max_ht;
+            s_fill_mem_rec_ip.u4_share_disp_buf = s_app_ctx.share_disp_buf;
+            s_fill_mem_rec_ip.u4_deinterlace = s_app_ctx.deinterlace;
+            s_fill_mem_rec_ip.e_output_format = (IV_COLOR_FORMAT_T) s_app_ctx
+                    .e_output_chroma_format;
+
+            s_fill_mem_rec_ip.s_ivd_fill_mem_rec_ip_t.u4_size =
+                    sizeof(impeg2d_fill_mem_rec_ip_t);
+            s_fill_mem_rec_op.s_ivd_fill_mem_rec_op_t.u4_size =
+                    sizeof(impeg2d_fill_mem_rec_op_t);
+
+            ps_mem_rec = (iv_mem_rec_t *) pv_mem_rec_location;
+            for (i = 0; i < u4_num_mem_recs; i++)
+                ps_mem_rec[i].u4_size = sizeof(iv_mem_rec_t);
+
+            /*****************************************************************************/
+            /*   API Call: Fill Mem Records                                     */
+            /*****************************************************************************/
+
+            e_dec_status = ivd_api_function(NULL, (void *) &s_fill_mem_rec_ip,
+                                            (void *) &s_fill_mem_rec_op);
+
+            u4_num_mem_recs = s_fill_mem_rec_op.s_ivd_fill_mem_rec_op_t
+                    .u4_num_mem_rec_filled;
+
+            if (IV_SUCCESS != e_dec_status) {
+                sprintf(ac_error_str,
+                        "Error in fill mem records: %x",
+                        s_fill_mem_rec_op.s_ivd_fill_mem_rec_op_t.u4_error_code);
+                codec_exit(ac_error_str);
+            }
+
+            ps_mem_rec = (iv_mem_rec_t *) pv_mem_rec_location;
+            total_size = 0;
+            for (i = 0; i < u4_num_mem_recs; i++) {
+                ps_mem_rec->pv_base = app_aligned_malloc(
+                        ps_mem_rec->u4_mem_alignment, ps_mem_rec->u4_mem_size);
+                if (ps_mem_rec->pv_base == NULL) {
+                    sprintf(ac_error_str,
+                            "\nAllocation failure for mem record id %d size %d\n",
+                            i, ps_mem_rec->u4_mem_size);
+                    codec_exit(ac_error_str);
+
+                }
+                total_size += ps_mem_rec->u4_mem_size;
+
+                ps_mem_rec++;
+            }
+            //printf("\nTotal memory for codec %d\n", total_size);
+        }
+        /*****************************************************************************/
+        /*   API Call: Initialize the Decoder                                        */
+        /*****************************************************************************/
+        {
+            impeg2d_init_ip_t s_init_ip;
+            impeg2d_init_op_t s_init_op;
+            void *fxns = &ivd_api_function;
+            iv_mem_rec_t *mem_tab;
+
+            mem_tab = (iv_mem_rec_t *) pv_mem_rec_location;
+            s_init_ip.s_ivd_init_ip_t.e_cmd =
+                    (IVD_API_COMMAND_TYPE_T) IV_CMD_INIT;
+            s_init_ip.s_ivd_init_ip_t.pv_mem_rec_location = mem_tab;
+            s_init_ip.s_ivd_init_ip_t.u4_frm_max_wd =
+                    (s_app_ctx.max_wd == 0) ?
+                    MAX_FRAME_WIDTH :
+                                              s_app_ctx.max_wd;
+            s_init_ip.s_ivd_init_ip_t.u4_frm_max_ht =
+                    (s_app_ctx.max_ht == 0) ?
+                    MAX_FRAME_HEIGHT :
+                                              s_app_ctx.max_ht;
+
+            s_init_ip.u4_share_disp_buf = s_app_ctx.share_disp_buf;
+            s_init_ip.u4_deinterlace = s_app_ctx.deinterlace;
+            s_init_ip.s_ivd_init_ip_t.u4_num_mem_rec = u4_num_mem_recs;
+            s_init_ip.s_ivd_init_ip_t.e_output_format =
+                    (IV_COLOR_FORMAT_T) s_app_ctx.e_output_chroma_format;
+            s_init_ip.s_ivd_init_ip_t.u4_size = sizeof(impeg2d_init_ip_t);
+            s_init_op.s_ivd_init_op_t.u4_size = sizeof(impeg2d_init_op_t);
+
+            codec_obj = (iv_obj_t *) mem_tab[0].pv_base;
+            codec_obj->pv_fxns = fxns;
+            codec_obj->u4_size = sizeof(iv_obj_t);
+
+            s_app_ctx.cocodec_obj = codec_obj;
+
+            ret = ivd_api_function((iv_obj_t *) codec_obj, (void *) &s_init_ip,
+                                   (void *) &s_init_op);
+            if (ret != IV_SUCCESS) {
+                sprintf(ac_error_str, "Error in Init %8x\n",
+                        s_init_op.s_ivd_init_op_t.u4_error_code);
+                codec_exit(ac_error_str);
+            }
+
+            /*****************************************************************************/
+            /*  Input and output buffer allocation                                       */
+            /*****************************************************************************/
+            {
+
+                ivd_ctl_getbufinfo_ip_t s_ctl_ip;
+                ivd_ctl_getbufinfo_op_t s_ctl_op;
+
+                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 input buffer */
+                u4_ip_buf_len = s_ctl_op.u4_min_in_buf_size[0];
+                pu1_bs_buf = (UWORD8 *) malloc(u4_ip_buf_len);
+
+                if (pu1_bs_buf == NULL) {
+                    sprintf(ac_error_str,
+                            "\nAllocation failure for input buffer of 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.share_disp_buf)
+                        || (IV_YUV_420P == s_app_ctx.e_output_chroma_format)) {
+                    UWORD32 outlen;
+                    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 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;
+                }
+
+            }
+        }
+
+    }
+
+    /*************************************************************************/
+    /* set num of cores                                                      */
+    /*************************************************************************/
+    {
+
+        impeg2d_ctl_set_num_cores_ip_t s_ctl_set_cores_ip;
+        impeg2d_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) IMPEG2D_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(impeg2d_ctl_set_num_cores_ip_t);
+        s_ctl_set_cores_op.u4_size = sizeof(impeg2d_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                                                        */
+    /*************************************************************************/
+
+    {
+
+        impeg2d_ctl_set_processor_ip_t s_ctl_set_num_processor_ip;
+        impeg2d_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) IMPEG2D_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(impeg2d_ctl_set_processor_ip_t);
+        s_ctl_set_num_processor_op.u4_size =
+                sizeof(impeg2d_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);
+        }
+
+    }
+
+    /*****************************************************************************/
+    /*   Decode header to get width and height and buffer sizes                  */
+    /*****************************************************************************/
+    {
+
+        ivd_ctl_set_config_ip_t s_ctl_ip;
+        ivd_ctl_set_config_op_t s_ctl_op;
+
+        ivd_video_decode_ip_t s_video_decode_ip;
+        ivd_video_decode_op_t s_video_decode_op;
+
+        s_ctl_ip.u4_disp_wd = STRIDE;
+        if (1 == s_app_ctx.display)
+            s_ctl_ip.u4_disp_wd = s_app_ctx.get_stride();
+
+        s_ctl_ip.e_frm_skip_mode = IVD_SKIP_NONE;
+        s_ctl_ip.e_frm_out_mode = IVD_DISPLAY_FRAME_OUT;
+        s_ctl_ip.e_vid_dec_mode = IVD_DECODE_HEADER;
+        s_ctl_ip.e_cmd = IVD_CMD_VIDEO_CTL;
+        s_ctl_ip.e_sub_cmd = IVD_CMD_CTL_SETPARAMS;
+        s_ctl_ip.u4_size = sizeof(ivd_ctl_set_config_ip_t);
+        s_ctl_op.u4_size = sizeof(ivd_ctl_set_config_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,
+                    "\nError in setting the codec in header decode mode");
+            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 = fread(pu1_bs_buf, sizeof(UWORD8), numbytes,
+                                       ps_ip_file);
+
+            if (0 == u4_bytes_remaining) {
+                sprintf(ac_error_str, "\nUnable to read from input file");
+                codec_exit(ac_error_str);
+            }
+
+            s_video_decode_ip.e_cmd = IVD_CMD_VIDEO_DECODE;
+            s_video_decode_ip.u4_ts = u4_ip_frm_ts;
+            s_video_decode_ip.pv_stream_buffer = pu1_bs_buf;
+            s_video_decode_ip.u4_num_Bytes = u4_bytes_remaining;
+            s_video_decode_ip.u4_size = sizeof(ivd_video_decode_ip_t);
+            s_video_decode_op.u4_size = sizeof(ivd_video_decode_op_t);
+
+            /*****************************************************************************/
+            /*   API Call: Header Decode                                                  */
+            /*****************************************************************************/
+            ret = ivd_api_function((iv_obj_t *) codec_obj,
+                                   (void *) &s_video_decode_ip,
+                                   (void *) &s_video_decode_op);
+
+            if (ret != IV_SUCCESS) {
+                sprintf(ac_error_str, "\nError in header decode %x",
+                        s_video_decode_op.u4_error_code);
+                // codec_exit(ac_error_str);
+            }
+
+            u4_num_bytes_dec = s_video_decode_op.u4_num_bytes_consumed;
+#ifndef PROFILE_ENABLE
+            printf("%d\n", s_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 = s_video_decode_op.u4_pic_wd;
+        s_app_ctx.u4_pic_ht = s_video_decode_op.u4_pic_ht;
+
+#if IOS_DISPLAY
+        s_app_ctx.i4_screen_wd = screen_wd;
+        s_app_ctx.i4_screen_ht = screen_ht;
+#endif
+
+        /* 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 required, which is dependent      */
+    /* on stream properties such as width, height and level etc              */
+    /* This is needed mainly for shared display mode                         */
+    /*************************************************************************/
+    //if(1 == s_app_ctx.share_disp_buf)
+    {
+        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);
+        }
+
+#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 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;
+
+        /*****************************************************************************/
+        /*   API Call: Send the allocated display buffers to codec                   */
+        /*****************************************************************************/
+        if (1 == s_app_ctx.share_disp_buf) {
+            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_ctl_op.u4_num_disp_bufs * 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                         */
+    /*************************************************************************/
+    {
+
+        impeg2d_ctl_get_frame_dimensions_ip_t s_ctl_get_frame_dimensions_ip;
+        impeg2d_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) IMPEG2D_CMD_CTL_GET_BUFFER_DIMENSIONS;
+        s_ctl_get_frame_dimensions_ip.u4_size =
+                sizeof(impeg2d_ctl_get_frame_dimensions_ip_t);
+        s_ctl_get_frame_dimensions_op.u4_size =
+                sizeof(impeg2d_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);
+        }
+
+        /*
+         printf("Frame offsets due to padding\n");
+         printf("s_ctl_get_frame_dimensions_op.x_offset[0] %d s_ctl_get_frame_dimensions_op.y_offset[0] %d\n",
+         s_ctl_get_frame_dimensions_op.u4_x_offset[0],
+         s_ctl_get_frame_dimensions_op.u4_y_offset[0]);
+         */
+    }
+
+    /*************************************************************************/
+    /* Get VUI parameters                                                    */
+    /*************************************************************************/
+#if 0
+    {
+
+        impeg2d_ctl_get_vui_params_ip_t s_ctl_get_vui_params_ip;
+        impeg2d_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)IMPEG2D_CMD_CTL_GET_VUI_PARAMS;
+        s_ctl_get_vui_params_ip.u4_size =
+        sizeof(impeg2d_ctl_get_vui_params_ip_t);
+        s_ctl_get_vui_params_op.u4_size =
+        sizeof(impeg2d_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);
+        }
+
+    }
+#endif
+
+    /*************************************************************************/
+    /* Set the decoder in frame decode mode. It was set in header decode     */
+    /* mode earlier                                                          */
+    /*************************************************************************/
+    {
+
+        ivd_ctl_set_config_ip_t s_ctl_ip;
+        ivd_ctl_set_config_op_t s_ctl_op;
+
+        s_ctl_ip.u4_disp_wd = STRIDE;
+        if (1 == s_app_ctx.display)
+            s_ctl_ip.u4_disp_wd = s_app_ctx.get_stride();
+        s_ctl_ip.e_frm_skip_mode = IVD_SKIP_NONE;
+
+        s_ctl_ip.e_frm_out_mode = IVD_DISPLAY_FRAME_OUT;
+        s_ctl_ip.e_vid_dec_mode = IVD_DECODE_FRAME;
+        s_ctl_ip.e_cmd = IVD_CMD_VIDEO_CTL;
+        s_ctl_ip.e_sub_cmd = IVD_CMD_CTL_SETPARAMS;
+        s_ctl_ip.u4_size = sizeof(ivd_ctl_set_config_ip_t);
+
+        s_ctl_op.u4_size = sizeof(ivd_ctl_set_config_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 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
+    while (u4_op_frm_ts < (s_app_ctx.u4_max_frm_ts + s_app_ctx.disp_delay)) {
+
+#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_ip_frm_ts < s_app_ctx.num_disp_buf
+                && (1 == s_app_ctx.share_disp_buf)) {
+            release_disp_frame(codec_obj, u4_ip_frm_ts);
+        }
+
+        /*************************************************************************/
+        /* set num of cores                                                      */
+        /*************************************************************************/
+#ifdef DYNAMIC_NUMCORES
+        {
+
+            impeg2d_ctl_set_num_cores_ip_t s_ctl_set_cores_ip;
+            impeg2d_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 = IMPEG2D_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(impeg2d_ctl_set_num_cores_ip_t);
+            s_ctl_set_cores_op.u4_size = sizeof(impeg2d_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 = fread(pu1_bs_buf, sizeof(UWORD8), numbytes,
+                                       ps_ip_file);
+
+            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 = 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
+
+        {
+            ivd_video_decode_ip_t s_video_decode_ip;
+            ivd_video_decode_op_t s_video_decode_op;
+#ifdef PROFILE_ENABLE
+            UWORD32 s_elapsed_time;
+            TIMER s_start_timer;
+            TIMER s_end_timer;
+#endif
+
+            s_video_decode_ip.e_cmd = IVD_CMD_VIDEO_DECODE;
+            s_video_decode_ip.u4_ts = u4_ip_frm_ts;
+            s_video_decode_ip.pv_stream_buffer = pu1_bs_buf;
+            s_video_decode_ip.u4_num_Bytes = u4_bytes_remaining;
+            s_video_decode_ip.u4_size = sizeof(ivd_video_decode_ip_t);
+            s_video_decode_ip.s_out_buffer.u4_min_out_buf_size[0] = ps_out_buf
+                    ->u4_min_out_buf_size[0];
+            s_video_decode_ip.s_out_buffer.u4_min_out_buf_size[1] = ps_out_buf
+                    ->u4_min_out_buf_size[1];
+            s_video_decode_ip.s_out_buffer.u4_min_out_buf_size[2] = ps_out_buf
+                    ->u4_min_out_buf_size[2];
+
+            s_video_decode_ip.s_out_buffer.pu1_bufs[0] =
+                    ps_out_buf->pu1_bufs[0];
+            s_video_decode_ip.s_out_buffer.pu1_bufs[1] =
+                    ps_out_buf->pu1_bufs[1];
+            s_video_decode_ip.s_out_buffer.pu1_bufs[2] =
+                    ps_out_buf->pu1_bufs[2];
+            s_video_decode_ip.s_out_buffer.u4_num_bufs =
+                    ps_out_buf->u4_num_bufs;
+            s_video_decode_op.u4_size = sizeof(ivd_video_decode_op_t);
+
+            /* 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,
+                        &s_video_decode_ip.s_out_buffer.pu1_bufs[0],
+                        &s_video_decode_ip.s_out_buffer.pu1_bufs[1],
+                        &s_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_video_decode_ip,
+                                   (void *) &s_video_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, s_video_decode_op.u4_output_present, s_video_decode_op.u4_num_bytes_consumed);
+
+            }
+#ifdef INTEL_CE5300
+            time_consumed += s_elapsed_time;
+            bytes_consumed += s_video_decode_op.u4_num_bytes_consumed;
+            if(!(frm_cnt % (s_app_ctx.fps)))
+            {
+                time_consumed = time_consumed / s_app_ctx.fps;
+                printf("Average decode time(micro sec) for the last second = %6d\n", time_consumed);
+                printf("Average bitrate(kb) for the last second = %6d\n", (bytes_consumed * 8) / 1024);
+                time_consumed = 0;
+                bytes_consumed = 0;
+
+            }
+#endif
+#else
+            printf("%d\n", s_video_decode_op.u4_num_bytes_consumed);
+#endif
+
+            if (IV_SUCCESS != ret) {
+                printf("Error in video Frame decode : ret %x Error %x\n", ret,
+                       s_video_decode_op.u4_error_code);
+                if ((s_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_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);
+                    }
+                    /*************************************************************************/
+                    /* set num of cores                                                      */
+                    /*************************************************************************/
+                    {
+
+                        impeg2d_ctl_set_num_cores_ip_t s_ctl_set_cores_ip;
+                        impeg2d_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) IMPEG2D_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(impeg2d_ctl_set_num_cores_ip_t);
+                        s_ctl_set_cores_op.u4_size =
+                                sizeof(impeg2d_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                                                        */
+                    /*************************************************************************/
+
+                    {
+
+                        impeg2d_ctl_set_processor_ip_t s_ctl_set_num_processor_ip;
+                        impeg2d_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) IMPEG2D_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(impeg2d_ctl_set_processor_ip_t);
+                        s_ctl_set_num_processor_op.u4_size =
+                                sizeof(impeg2d_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);
+                        }
+
+                    }
+
+                } else if (IMPEG2D_UNSUPPORTED_DIMENSIONS
+                        == (IMPEG2D_ERROR_CODES_T) s_video_decode_op
+                                .u4_error_code) {
+                    flush_output(codec_obj, &s_app_ctx, ps_out_buf, pu1_bs_buf,
+                                 &u4_op_frm_ts, ps_op_file, ps_op_chksum_file,
+                                 u4_ip_frm_ts, u4_bytes_remaining);
+
+                    printf("Reinit codec with width %d and height %d\n",
+                           s_video_decode_op.u4_pic_wd,
+                           s_video_decode_op.u4_pic_ht);
+
+                    break;
+                } else if (IVD_DISP_FRM_ZERO_OP_BUF_SIZE
+                        == (IMPEG2D_ERROR_CODES_T) s_video_decode_op
+                                .u4_error_code) {
+                    printf("Output buffer is not large enough!\n");
+                    break;
+                }
+            }
+
+            if ((1 == s_app_ctx.display)
+                    && (1 == s_video_decode_op.u4_output_present)) {
+                dispq_producer_queue(&s_app_ctx);
+            }
+
+            if (IV_B_FRAME == s_video_decode_op.e_pic_type)
+                s_app_ctx.b_pic_present |= 1;
+
+            u4_num_bytes_dec = s_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 == s_video_decode_op.u4_output_present) {
+                width = s_video_decode_op.s_disp_frm_buf.u4_y_wd;
+                height = s_video_decode_op.s_disp_frm_buf.u4_y_ht;
+                dump_output(&s_app_ctx, &(s_video_decode_op.s_disp_frm_buf),
+                            s_video_decode_op.u4_disp_buf_id, ps_op_file,
+                            ps_op_chksum_file, u4_op_frm_ts,
+                            s_app_ctx.u4_file_save_flag,
+                            s_app_ctx.u4_chksum_save_flag);
+
+                u4_op_frm_ts++;
+            } else {
+                if ((s_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_op_chksum_file, u4_ip_frm_ts,
+                 u4_bytes_remaining);
+
+    /* set disp_end 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.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);
+    }
+
+    {
+        iv_retrieve_mem_rec_ip_t s_retrieve_dec_ip;
+        iv_retrieve_mem_rec_op_t s_retrieve_dec_op;
+        s_retrieve_dec_ip.pv_mem_rec_location =
+                (iv_mem_rec_t *) pv_mem_rec_location;
+
+        s_retrieve_dec_ip.e_cmd = IV_CMD_RETRIEVE_MEMREC;
+        s_retrieve_dec_ip.u4_size = sizeof(iv_retrieve_mem_rec_ip_t);
+        s_retrieve_dec_op.u4_size = sizeof(iv_retrieve_mem_rec_op_t);
+
+        ret = ivd_api_function((iv_obj_t *) codec_obj,
+                               (void *) &s_retrieve_dec_ip,
+                               (void *) &s_retrieve_dec_op);
+
+        if (IV_SUCCESS != ret) {
+            sprintf(ac_error_str, "Error in Retrieve Memrec");
+            codec_exit(ac_error_str);
+        }
+
+        {
+            iv_mem_rec_t *ps_mem_rec;
+            UWORD16 u2_i;
+
+            u4_num_mem_recs = s_retrieve_dec_op.u4_num_mem_rec_filled;
+
+            ps_mem_rec = s_retrieve_dec_ip.pv_mem_rec_location;
+
+            for (u2_i = 0; u2_i < u4_num_mem_recs; u2_i++) {
+                app_aligned_free(ps_mem_rec->pv_base);
+                ps_mem_rec++;
+            }
+            free(s_retrieve_dec_ip.pv_mem_rec_location);
+        }
+
+    }
+    /***********************************************************************/
+    /*              Close all the files and free all the memory            */
+    /***********************************************************************/
+    {
+        fclose(ps_ip_file);
+
+        if (1 == s_app_ctx.u4_file_save_flag) {
+            fclose(ps_op_file);
+        }
+        if (1 == s_app_ctx.u4_chksum_save_flag) {
+            fclose(ps_op_chksum_file);
+        }
+
+    }
+
+    if (0 == s_app_ctx.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);
+
+    return (0);
+}
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2019-2028/poc_arm_neon_utils.c b/hostsidetests/securitybulletin/securityPatch/CVE-2019-2028/poc_arm_neon_utils.c
new file mode 100644
index 0000000..eba52f3
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2019-2028/poc_arm_neon_utils.c
@@ -0,0 +1,51 @@
+/**
+ * Copyright (C) 2020 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.
+ */
+#define _GNU_SOURCE
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <sys/time.h>
+#include <stdlib.h>
+#include <string.h>
+#include "iv_datatypedef.h"
+
+#include "impeg2d.h"
+#include "../includes/common.h"
+
+#define COLORING_BYTE 0xBE
+void write_to_callee_saved_registers(char write_array[8][8]);
+void read_from_callee_saved_registers(char read_array[8][8]);
+void check_read_values(char read_array[8][8], char write_arrayp[8][8]);
+char write_array[8][8] __attribute__ ((aligned (16)));
+char read_array[8][8] __attribute__ ((aligned (16)));
+
+void check_read_values(char read_array[8][8], char write_array[8][8]) {
+    if (0 != (memcmp(write_array, read_array, 64))) {
+        exit(EXIT_VULNERABLE);
+    }
+}
+IV_API_CALL_STATUS_T ivd_api_function(iv_obj_t *ps_handle, void *pv_api_ip,
+                                          void *pv_api_op) {
+    memset(write_array, COLORING_BYTE, (8 * 8));
+    memset(read_array, 0, (8 * 8));
+    write_to_callee_saved_registers(write_array);
+
+    IV_API_CALL_STATUS_T status = 0;
+    status = impeg2d_api_function(ps_handle, pv_api_ip, pv_api_op);
+
+    read_from_callee_saved_registers(read_array);
+    check_read_values(read_array, write_array);
+    return status;
+}
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/TestMediaCodec.java b/hostsidetests/securitybulletin/src/android/security/cts/TestMediaCodec.java
index 2073310..01ad909 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/TestMediaCodec.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/TestMediaCodec.java
@@ -379,6 +379,18 @@
      ******************************************************************************/
 
     /**
+     * b/120644655
+     * Vulnerability Behaviour: EXIT_VULNERABLE (113)
+     **/
+    @SecurityTest(minPatchLevel = "2019-04")
+    public void testPocCVE_2019_2028() throws Exception {
+        String inputFiles[] = {"cve_2019_2028.m2v"};
+        AdbUtils.runPocAssertNoCrashesNotVulnerable("CVE-2019-2028",
+                "-i " + AdbUtils.TMP_PATH + inputFiles[0] + " --num_frames -1", inputFiles,
+                AdbUtils.TMP_PATH, getDevice());
+    }
+
+    /**
      * b/74078669
      * Vulnerability Behaviour: SIGSEGV in self
      */