Snap for 5907899 from 009fcbab7c6997eeb1d187cc093223948671b79b to r-keystone-qcom-release

Change-Id: I5b9e0379453e2f60f5c423ad518a551146fae74e
diff --git a/CMakeLists.txt b/CMakeLists.txt
new file mode 100644
index 0000000..2505d58
--- /dev/null
+++ b/CMakeLists.txt
@@ -0,0 +1,217 @@
+cmake_minimum_required(VERSION 3.5)
+
+set(AVC_ROOT "${CMAKE_CURRENT_SOURCE_DIR}")
+set(AVC_CONFIG_DIR "${CMAKE_CURRENT_BINARY_DIR}")
+
+if("${AVC_ROOT}" STREQUAL "${AVC_CONFIG_DIR}")
+ message(FATAL_ERROR
+ "Building from within the libavc source tree is not supported.\n"
+ "Hint: Run these commands\n" "$ rm -rf CMakeCache.txt CMakeFiles\n"
+ "$ mkdir -p ./build\n" "$ cd ./build\n"
+ "And re-run CMake from the build directory.")
+endif()
+
+set(THREADS_PREFER_PTHREAD_FLAG ON)
+find_package(Threads REQUIRED)
+set(CMAKE_STATIC_LIBRARY_PREFIX "")
+
+if (SANITIZE)
+ string(TOLOWER ${SANITIZE} SANITIZE)
+
+ SET(CMAKE_SANITIZER_C_FLAGS "-fno-omit-frame-pointer -fsanitize=${SANITIZE}")
+ SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${CMAKE_SANITIZER_C_FLAGS}")
+endif()
+
+list(APPEND LIBAVCDEC_SRCS
+"${AVC_ROOT}/common/ih264_buf_mgr.c"
+"${AVC_ROOT}/common/ih264_disp_mgr.c"
+"${AVC_ROOT}/common/ih264_inter_pred_filters.c"
+"${AVC_ROOT}/common/ih264_luma_intra_pred_filters.c"
+"${AVC_ROOT}/common/ih264_chroma_intra_pred_filters.c"
+"${AVC_ROOT}/common/ih264_padding.c"
+"${AVC_ROOT}/common/ih264_mem_fns.c"
+"${AVC_ROOT}/common/ih264_deblk_edge_filters.c"
+"${AVC_ROOT}/common/ih264_iquant_itrans_recon.c"
+"${AVC_ROOT}/common/ih264_ihadamard_scaling.c"
+"${AVC_ROOT}/common/ih264_weighted_pred.c"
+"${AVC_ROOT}/common/ithread.c"
+"${AVC_ROOT}/decoder/ih264d_cabac.c"
+"${AVC_ROOT}/decoder/ih264d_parse_mb_header.c"
+"${AVC_ROOT}/decoder/ih264d_parse_cabac.c"
+"${AVC_ROOT}/decoder/ih264d_process_intra_mb.c"
+"${AVC_ROOT}/decoder/ih264d_inter_pred.c"
+"${AVC_ROOT}/decoder/ih264d_parse_bslice.c"
+"${AVC_ROOT}/decoder/ih264d_parse_pslice.c"
+"${AVC_ROOT}/decoder/ih264d_parse_islice.c"
+"${AVC_ROOT}/decoder/ih264d_cabac_init_tables.c"
+"${AVC_ROOT}/decoder/ih264d_bitstrm.c"
+"${AVC_ROOT}/decoder/ih264d_compute_bs.c"
+"${AVC_ROOT}/decoder/ih264d_deblocking.c"
+"${AVC_ROOT}/decoder/ih264d_parse_headers.c"
+"${AVC_ROOT}/decoder/ih264d_mb_utils.c"
+"${AVC_ROOT}/decoder/ih264d_mvpred.c"
+"${AVC_ROOT}/decoder/ih264d_utils.c"
+"${AVC_ROOT}/decoder/ih264d_process_bslice.c"
+"${AVC_ROOT}/decoder/ih264d_process_pslice.c"
+"${AVC_ROOT}/decoder/ih264d_parse_slice.c"
+"${AVC_ROOT}/decoder/ih264d_quant_scaling.c"
+"${AVC_ROOT}/decoder/ih264d_parse_cavlc.c"
+"${AVC_ROOT}/decoder/ih264d_dpb_mgr.c"
+"${AVC_ROOT}/decoder/ih264d_nal.c"
+"${AVC_ROOT}/decoder/ih264d_sei.c"
+"${AVC_ROOT}/decoder/ih264d_tables.c"
+"${AVC_ROOT}/decoder/ih264d_vui.c"
+"${AVC_ROOT}/decoder/ih264d_format_conv.c"
+"${AVC_ROOT}/decoder/ih264d_thread_parse_decode.c"
+"${AVC_ROOT}/decoder/ih264d_api.c"
+"${AVC_ROOT}/decoder/ih264d_thread_compute_bs.c"
+"${AVC_ROOT}/decoder/ih264d_function_selector_generic.c"
+)
+
+list(APPEND LIBAVCDEC_X86_SRCS
+"${AVC_ROOT}/decoder/x86/ih264d_function_selector.c"
+"${AVC_ROOT}/decoder/x86/ih264d_function_selector_sse42.c"
+"${AVC_ROOT}/decoder/x86/ih264d_function_selector_ssse3.c"
+"${AVC_ROOT}/common/x86/ih264_inter_pred_filters_ssse3.c"
+"${AVC_ROOT}/common/x86/ih264_deblk_luma_ssse3.c"
+"${AVC_ROOT}/common/x86/ih264_deblk_chroma_ssse3.c"
+"${AVC_ROOT}/common/x86/ih264_padding_ssse3.c"
+"${AVC_ROOT}/common/x86/ih264_mem_fns_ssse3.c"
+"${AVC_ROOT}/common/x86/ih264_iquant_itrans_recon_dc_ssse3.c"
+"${AVC_ROOT}/common/x86/ih264_iquant_itrans_recon_ssse3.c"
+"${AVC_ROOT}/common/x86/ih264_luma_intra_pred_filters_ssse3.c"
+"${AVC_ROOT}/common/x86/ih264_chroma_intra_pred_filters_ssse3.c"
+"${AVC_ROOT}/common/x86/ih264_iquant_itrans_recon_sse42.c"
+"${AVC_ROOT}/common/x86/ih264_weighted_pred_sse42.c"
+"${AVC_ROOT}/common/x86/ih264_ihadamard_scaling_sse42.c"
+)
+
+SET(LIBAVCDEC_INCLUDES
+${AVC_ROOT}/common
+${AVC_ROOT}/decoder
+)
+
+SET(LIBAVCDEC_X86_C_FLAGS "-DX86 -DDISABLE_AVX2 -msse4.2 -mno-avx -DDEFAULT_ARCH=D_ARCH_X86_SSE42" )
+SET(LIBAVCDEC_X86_INCLUDES ${AVC_ROOT}/common/x86 ${AVC_ROOT}/decoder/x86)
+SET(LIBAVCDEC_C_FLAGS "${LIBAVCDEC_X86_C_FLAGS}")
+
+include_directories(${LIBAVCDEC_INCLUDES} ${LIBAVCDEC_X86_INCLUDES})
+add_library(libavcdec ${LIBAVCDEC_SRCS} ${LIBAVCDEC_X86_SRCS})
+set_target_properties(libavcdec PROPERTIES COMPILE_FLAGS "${LIBAVCDEC_C_FLAGS}")
+
+
+list(APPEND AVCDEC_SRCS
+"${AVC_ROOT}/test/decoder/main.c"
+)
+
+add_executable(avcdec ${AVCDEC_SRCS})
+set_target_properties(avcdec PROPERTIES COMPILE_FLAGS "-DMD5_DISABLE -DPROFILE_ENABLE")
+target_link_libraries(avcdec libavcdec Threads::Threads)
+
+list(APPEND LIBAVCENC_SRCS
+"${AVC_ROOT}/common/ih264_resi_trans_quant.c"
+"${AVC_ROOT}/common/ih264_iquant_itrans_recon.c"
+"${AVC_ROOT}/common/ih264_ihadamard_scaling.c"
+"${AVC_ROOT}/common/ih264_inter_pred_filters.c"
+"${AVC_ROOT}/common/ih264_luma_intra_pred_filters.c"
+"${AVC_ROOT}/common/ih264_chroma_intra_pred_filters.c"
+"${AVC_ROOT}/common/ih264_padding.c"
+"${AVC_ROOT}/common/ih264_mem_fns.c"
+"${AVC_ROOT}/common/ih264_deblk_edge_filters.c"
+"${AVC_ROOT}/common/ih264_deblk_tables.c"
+"${AVC_ROOT}/common/ih264_cavlc_tables.c"
+"${AVC_ROOT}/common/ih264_cabac_tables.c"
+"${AVC_ROOT}/common/ih264_common_tables.c"
+"${AVC_ROOT}/common/ih264_trans_data.c"
+"${AVC_ROOT}/common/ih264_buf_mgr.c"
+"${AVC_ROOT}/common/ih264_dpb_mgr.c"
+"${AVC_ROOT}/common/ih264_list.c"
+"${AVC_ROOT}/common/ithread.c"
+"${AVC_ROOT}/encoder/ih264e_globals.c"
+"${AVC_ROOT}/encoder/ih264e_intra_modes_eval.c"
+"${AVC_ROOT}/encoder/ih264e_half_pel.c"
+"${AVC_ROOT}/encoder/ih264e_mc.c"
+"${AVC_ROOT}/encoder/ih264e_me.c"
+"${AVC_ROOT}/encoder/ih264e_rc_mem_interface.c"
+"${AVC_ROOT}/encoder/ih264e_time_stamp.c"
+"${AVC_ROOT}/encoder/ih264e_modify_frm_rate.c"
+"${AVC_ROOT}/encoder/ih264e_rate_control.c"
+"${AVC_ROOT}/encoder/ih264e_core_coding.c"
+"${AVC_ROOT}/encoder/ih264e_deblk.c"
+"${AVC_ROOT}/encoder/ih264e_api.c"
+"${AVC_ROOT}/encoder/ih264e_process.c"
+"${AVC_ROOT}/encoder/ih264e_encode.c"
+"${AVC_ROOT}/encoder/ih264e_utils.c"
+"${AVC_ROOT}/encoder/ih264e_version.c"
+"${AVC_ROOT}/encoder/ih264e_bitstream.c"
+"${AVC_ROOT}/encoder/ih264e_cavlc.c"
+"${AVC_ROOT}/encoder/ih264e_cabac_init.c"
+"${AVC_ROOT}/encoder/ih264e_cabac.c"
+"${AVC_ROOT}/encoder/ih264e_cabac_encode.c"
+"${AVC_ROOT}/encoder/ih264e_encode_header.c"
+"${AVC_ROOT}/encoder/ih264e_function_selector_generic.c"
+"${AVC_ROOT}/encoder/ih264e_fmt_conv.c"
+"${AVC_ROOT}/encoder/irc_rate_control_api.c"
+"${AVC_ROOT}/encoder/irc_bit_allocation.c"
+"${AVC_ROOT}/encoder/irc_cbr_buffer_control.c"
+"${AVC_ROOT}/encoder/irc_est_sad.c"
+"${AVC_ROOT}/encoder/irc_fixed_point_error_bits.c"
+"${AVC_ROOT}/encoder/irc_frame_info_collector.c"
+"${AVC_ROOT}/encoder/irc_mb_model_based.c"
+"${AVC_ROOT}/encoder/irc_picture_type.c"
+"${AVC_ROOT}/encoder/irc_rd_model.c"
+"${AVC_ROOT}/encoder/irc_vbr_storage_vbv.c"
+"${AVC_ROOT}/encoder/irc_vbr_str_prms.c"
+"${AVC_ROOT}/encoder/ime.c"
+"${AVC_ROOT}/encoder/ime_distortion_metrics.c"
+)
+
+list(APPEND LIBAVCENC_X86_SRCS
+"${AVC_ROOT}/encoder/x86/ih264e_function_selector.c"
+"${AVC_ROOT}/encoder/x86/ih264e_function_selector_sse42.c"
+"${AVC_ROOT}/encoder/x86/ih264e_function_selector_ssse3.c"
+"${AVC_ROOT}/common/x86/ih264_iquant_itrans_recon_ssse3.c"
+"${AVC_ROOT}/common/x86/ih264_iquant_itrans_recon_dc_ssse3.c"
+"${AVC_ROOT}/common/x86/ih264_ihadamard_scaling_ssse3.c"
+"${AVC_ROOT}/common/x86/ih264_inter_pred_filters_ssse3.c"
+"${AVC_ROOT}/common/x86/ih264_mem_fns_ssse3.c"
+"${AVC_ROOT}/common/x86/ih264_padding_ssse3.c"
+"${AVC_ROOT}/common/x86/ih264_luma_intra_pred_filters_ssse3.c"
+"${AVC_ROOT}/common/x86/ih264_chroma_intra_pred_filters_ssse3.c"
+"${AVC_ROOT}/common/x86/ih264_deblk_chroma_ssse3.c"
+"${AVC_ROOT}/common/x86/ih264_deblk_luma_ssse3.c"
+"${AVC_ROOT}/common/x86/ih264_iquant_itrans_recon_sse42.c"
+"${AVC_ROOT}/common/x86/ih264_ihadamard_scaling_sse42.c"
+"${AVC_ROOT}/common/x86/ih264_resi_trans_quant_sse42.c"
+"${AVC_ROOT}/common/x86/ih264_weighted_pred_sse42.c"
+"${AVC_ROOT}/encoder/x86/ih264e_half_pel_ssse3.c"
+"${AVC_ROOT}/encoder/x86/ih264e_intra_modes_eval_ssse3.c"
+"${AVC_ROOT}/encoder/x86/ime_distortion_metrics_sse42.c"
+)
+
+SET(LIBAVCENC_INCLUDES
+${AVC_ROOT}/common
+${AVC_ROOT}/encoder
+)
+
+SET(LIBAVCENC_X86_C_FLAGS "-msse4.2 -mno-avx -UHP_PL -DN_MB_ENABLE" )
+SET(LIBAVCENC_C_FLAGS "${LIBAVCENC_X86_C_FLAGS}")
+SET(LIBAVCENC_X86_INCLUDES ${AVC_ROOT}/common/x86 ${AVC_ROOT}/encoder/x86)
+
+
+include_directories(${LIBAVCENC_INCLUDES} ${LIBAVCENC_X86_INCLUDES})
+add_library(libavcenc ${LIBAVCENC_SRCS} ${LIBAVCENC_X86_SRCS})
+set_target_properties(libavcenc PROPERTIES COMPILE_FLAGS "${LIBAVCENC_C_FLAGS}")
+
+list(APPEND AVCENC_SRCS
+"${AVC_ROOT}/test/encoder/main.c"
+"${AVC_ROOT}/test/encoder/psnr.c"
+"${AVC_ROOT}/test/encoder/input.c"
+"${AVC_ROOT}/test/encoder/output.c"
+"${AVC_ROOT}/test/encoder/recon.c"
+)
+
+add_executable(avcenc ${AVCENC_SRCS})
+set_target_properties(avcenc PROPERTIES COMPILE_FLAGS "-DARM -DMD5_DISABLE -DPROFILE_ENABLE")
+target_link_libraries(avcenc libavcenc Threads::Threads m)
+
diff --git a/decoder/ih264d_parse_slice.c b/decoder/ih264d_parse_slice.c
index 8d50f9a..1f80912 100644
--- a/decoder/ih264d_parse_slice.c
+++ b/decoder/ih264d_parse_slice.c
@@ -835,12 +835,7 @@
             if(ret != OK)
                 return ret;
 
-            {
-                ivd_video_decode_op_t * ps_dec_output =
-                                (ivd_video_decode_op_t *)ps_dec->pv_dec_out;
 
-                ps_dec_output->u4_frame_decoded_flag = 1;
-            }
             if(ps_dec->au1_pic_buf_ref_flag[ps_dec->u1_pic_buf_id] == 0)
             {
                 ih264_buf_mgr_release((buf_mgr_t *)ps_dec->pv_mv_buf_mgr,
@@ -861,6 +856,11 @@
                         || ((TOP_FIELD_ONLY | BOT_FIELD_ONLY)
                                         == ps_dec->u1_top_bottom_decoded))
         {
+            ivd_video_decode_op_t * ps_dec_output =
+                            (ivd_video_decode_op_t *)ps_dec->pv_dec_out;
+            /* u4_frame_decoded_flag is set to 1 only after both fields
+             * are decoded or it is not a field */
+            ps_dec_output->u4_frame_decoded_flag = 1;
             if(IVD_DECODE_FRAME_OUT == ps_dec->e_frm_out_mode)
             {
                 ret = ih264d_assign_display_seq(ps_dec);
diff --git a/encoder/ih264e_process.c b/encoder/ih264e_process.c
index 644a5a2..7acd239 100644
--- a/encoder/ih264e_process.c
+++ b/encoder/ih264e_process.c
@@ -528,8 +528,6 @@
                     }
                 }
             }
-            /* Dont execute any further instructions until store synchronization took place */
-            DATA_SYNC();
         }
 
         /* Ending bitstream offset for header in bits */
@@ -617,6 +615,9 @@
         DEBUG("entropy status %x", ps_entropy->i4_error_code);
     }
 
+    /* Dont execute any further instructions until store synchronization took place */
+    DATA_SYNC();
+
     /* allow threads to dequeue entropy jobs */
     ps_codec->au4_entropy_thread_active[ctxt_sel] = 0;
 
diff --git a/fuzzer/Android.bp b/fuzzer/Android.bp
new file mode 100644
index 0000000..e174a69
--- /dev/null
+++ b/fuzzer/Android.bp
@@ -0,0 +1,8 @@
+cc_fuzz {
+    name: "avc_dec_fuzzer",
+    srcs: [
+        "avc_dec_fuzzer.cpp",
+    ],
+    static_libs: ["libavcdec"],
+    shared_libs: ["liblog"],
+}
diff --git a/fuzzer/README.md b/fuzzer/README.md
new file mode 100644
index 0000000..a42e8b5
--- /dev/null
+++ b/fuzzer/README.md
@@ -0,0 +1,69 @@
+# Fuzzer for libavc decoder
+
+This describes steps to build avc_dec_fuzzer binary.
+
+## Linux x86/x64
+
+###  Requirements
+- cmake (3.5 or above)
+- make
+- clang (6.0 or above)
+  needs to support -fsanitize=fuzzer, -fsanitize=fuzzer-no-link
+
+### Steps to build
+Clone libavc repository
+```
+$ git clone https://android.googlesource.com/platform/external/libavc
+```
+Create a directory inside libavc and change directory
+```
+ $ cd libavc
+ $ mkdir build
+ $ cd build
+```
+Build libavc using cmake
+```
+ $ CC=clang CXX=clang++ cmake ../ \
+   -DSANITIZE=fuzzer-no-link,address,signed-integer-overflow
+ $ make
+ ```
+Build the fuzzer
+```
+ $ clang++ -std=c++11 -fsanitize=fuzzer,address -I.  -I../  -I../common \
+   -I../decoder -Wl,--start-group ../fuzzer/avc_dec_fuzzer.cpp \
+   -o ./avc_dec_fuzzer ./libavcdec.a -Wl,--end-group
+```
+
+### Steps to run
+Create a directory CORPUS_DIR and copy some elementary h264 files to that folder
+To run the fuzzer
+```
+$ ./avc_dec_fuzzer CORPUS_DIR
+```
+
+## Android
+
+### Steps to build
+Build the fuzzer
+```
+  $ SANITIZE_TARGET=address SANITIZE_HOST=address mmma -j$(nproc) \
+    external/libavc/fuzzer
+```
+
+### Steps to run
+Create a directory CORPUS_DIR and copy some elementary h264 files to that folder
+Push this directory to device.
+
+To run on device
+```
+  $ adb sync data
+  $ adb shell /data/fuzz/avc_dec_fuzzer CORPUS_DIR
+```
+To run on host
+```
+  $ $ANDROID_HOST_OUT/fuzz/avc_dec_fuzzer CORPUS_DIR
+```
+
+## References:
+ * http://llvm.org/docs/LibFuzzer.html
+ * https://github.com/google/oss-fuzz
diff --git a/fuzzer/avc_dec_fuzzer.cpp b/fuzzer/avc_dec_fuzzer.cpp
new file mode 100644
index 0000000..3b00175
--- /dev/null
+++ b/fuzzer/avc_dec_fuzzer.cpp
@@ -0,0 +1,340 @@
+/******************************************************************************
+ *
+ * Copyright (C) 2019 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
+ */
+
+#include <malloc.h>
+#include <stddef.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <algorithm>
+#include <memory>
+
+#include "ih264_typedefs.h"
+#include "ih264d.h"
+#include "iv.h"
+#include "ivd.h"
+
+#define NELEMENTS(x) (sizeof(x) / sizeof(x[0]))
+#define ivd_api_function ih264d_api_function
+const IV_COLOR_FORMAT_T supportedColorFormats[] = {
+    IV_YUV_420P,   IV_YUV_420SP_UV, IV_YUV_420SP_VU,
+    IV_YUV_422ILE, IV_RGB_565,      IV_RGBA_8888};
+
+enum {
+  OFFSET_COLOR_FORMAT = 6,
+  OFFSET_NUM_CORES,
+  /* Should be the last entry */
+  OFFSET_MAX,
+};
+
+const static int kSupportedColorFormats = NELEMENTS(supportedColorFormats);
+const static int kMaxCores = 4;
+void *iv_aligned_malloc(void *ctxt, WORD32 alignment, WORD32 size) {
+  (void)ctxt;
+  return memalign(alignment, size);
+}
+
+void iv_aligned_free(void *ctxt, void *buf) {
+  (void)ctxt;
+  free(buf);
+}
+
+class Codec {
+ public:
+  Codec(IV_COLOR_FORMAT_T colorFormat, size_t numCores);
+  ~Codec();
+
+  void createCodec();
+  void deleteCodec();
+  void resetCodec();
+  void setCores();
+  void allocFrame();
+  void freeFrame();
+  void decodeHeader(const uint8_t *data, size_t size);
+  IV_API_CALL_STATUS_T decodeFrame(const uint8_t *data, size_t size,
+                                   size_t *bytesConsumed);
+  void setParams(IVD_VIDEO_DECODE_MODE_T mode);
+
+ private:
+  IV_COLOR_FORMAT_T mColorFormat;
+  size_t mNumCores;
+  iv_obj_t *mCodec;
+  ivd_out_bufdesc_t mOutBufHandle;
+  uint32_t mWidth;
+  uint32_t mHeight;
+};
+
+Codec::Codec(IV_COLOR_FORMAT_T colorFormat, size_t numCores) {
+  mColorFormat = colorFormat;
+  mNumCores = numCores;
+  mCodec = nullptr;
+  mWidth = 0;
+  mHeight = 0;
+
+  memset(&mOutBufHandle, 0, sizeof(mOutBufHandle));
+}
+Codec::~Codec() {}
+void Codec::createCodec() {
+  IV_API_CALL_STATUS_T ret;
+  ih264d_create_ip_t create_ip;
+  ih264d_create_op_t create_op;
+  void *fxns = (void *)&ivd_api_function;
+
+  create_ip.s_ivd_create_ip_t.e_cmd = IVD_CMD_CREATE;
+  create_ip.s_ivd_create_ip_t.u4_share_disp_buf = 0;
+  create_ip.s_ivd_create_ip_t.e_output_format = mColorFormat;
+  create_ip.s_ivd_create_ip_t.pf_aligned_alloc = iv_aligned_malloc;
+  create_ip.s_ivd_create_ip_t.pf_aligned_free = iv_aligned_free;
+  create_ip.s_ivd_create_ip_t.pv_mem_ctxt = NULL;
+  create_ip.s_ivd_create_ip_t.u4_size = sizeof(ih264d_create_ip_t);
+  create_op.s_ivd_create_op_t.u4_size = sizeof(ih264d_create_op_t);
+
+  ret = ivd_api_function(NULL, (void *)&create_ip, (void *)&create_op);
+  if (ret != IV_SUCCESS) {
+    return;
+  }
+  mCodec = (iv_obj_t *)create_op.s_ivd_create_op_t.pv_handle;
+  mCodec->pv_fxns = fxns;
+  mCodec->u4_size = sizeof(iv_obj_t);
+}
+
+void Codec::deleteCodec() {
+  ivd_delete_ip_t delete_ip;
+  ivd_delete_op_t delete_op;
+
+  delete_ip.e_cmd = IVD_CMD_DELETE;
+  delete_ip.u4_size = sizeof(ivd_delete_ip_t);
+  delete_op.u4_size = sizeof(ivd_delete_op_t);
+
+  ivd_api_function(mCodec, (void *)&delete_ip, (void *)&delete_op);
+}
+void Codec::resetCodec() {
+  ivd_ctl_reset_ip_t s_ctl_ip;
+  ivd_ctl_reset_op_t s_ctl_op;
+
+  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);
+
+  ivd_api_function(mCodec, (void *)&s_ctl_ip, (void *)&s_ctl_op);
+}
+
+void Codec::setCores() {
+  ih264d_ctl_set_num_cores_ip_t s_ctl_ip;
+  ih264d_ctl_set_num_cores_op_t s_ctl_op;
+
+  s_ctl_ip.e_cmd = IVD_CMD_VIDEO_CTL;
+  s_ctl_ip.e_sub_cmd =
+      (IVD_CONTROL_API_COMMAND_TYPE_T)IH264D_CMD_CTL_SET_NUM_CORES;
+  s_ctl_ip.u4_num_cores = mNumCores;
+  s_ctl_ip.u4_size = sizeof(ih264d_ctl_set_num_cores_ip_t);
+  s_ctl_op.u4_size = sizeof(ih264d_ctl_set_num_cores_op_t);
+
+  ivd_api_function(mCodec, (void *)&s_ctl_ip, (void *)&s_ctl_op);
+}
+
+void Codec::setParams(IVD_VIDEO_DECODE_MODE_T mode) {
+  ivd_ctl_set_config_ip_t s_ctl_ip;
+  ivd_ctl_set_config_op_t s_ctl_op;
+
+  s_ctl_ip.u4_disp_wd = 0;
+  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 = mode;
+  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);
+
+  ivd_api_function(mCodec, (void *)&s_ctl_ip, (void *)&s_ctl_op);
+}
+
+void Codec::freeFrame() {
+  for (int i = 0; i < mOutBufHandle.u4_num_bufs; i++) {
+    if (mOutBufHandle.pu1_bufs[i]) {
+      free(mOutBufHandle.pu1_bufs[i]);
+      mOutBufHandle.pu1_bufs[i] = nullptr;
+    }
+  }
+}
+void Codec::allocFrame() {
+  size_t sizes[4] = {0};
+  size_t num_bufs = 0;
+
+  freeFrame();
+
+  memset(&mOutBufHandle, 0, sizeof(mOutBufHandle));
+
+  switch (mColorFormat) {
+    case IV_YUV_420SP_UV:
+      [[fallthrough]];
+    case IV_YUV_420SP_VU:
+      sizes[0] = mWidth * mHeight;
+      sizes[1] = mWidth * mHeight >> 1;
+      num_bufs = 2;
+      break;
+    case IV_YUV_422ILE:
+      sizes[0] = mWidth * mHeight * 2;
+      num_bufs = 1;
+      break;
+    case IV_RGB_565:
+      sizes[0] = mWidth * mHeight * 2;
+      num_bufs = 1;
+      break;
+    case IV_RGBA_8888:
+      sizes[0] = mWidth * mHeight * 4;
+      num_bufs = 1;
+      break;
+    case IV_YUV_420P:
+      [[fallthrough]];
+    default:
+      sizes[0] = mWidth * mHeight;
+      sizes[1] = mWidth * mHeight >> 2;
+      sizes[2] = mWidth * mHeight >> 2;
+      num_bufs = 3;
+      break;
+  }
+  mOutBufHandle.u4_num_bufs = num_bufs;
+  for (int i = 0; i < num_bufs; i++) {
+    mOutBufHandle.u4_min_out_buf_size[i] = sizes[i];
+    mOutBufHandle.pu1_bufs[i] = (UWORD8 *)memalign(16, sizes[i]);
+  }
+}
+void Codec::decodeHeader(const uint8_t *data, size_t size) {
+  setParams(IVD_DECODE_HEADER);
+
+  while (size > 0) {
+    IV_API_CALL_STATUS_T ret;
+    ivd_video_decode_ip_t dec_ip;
+    ivd_video_decode_op_t dec_op;
+    size_t bytes_consumed;
+
+    memset(&dec_ip, 0, sizeof(dec_ip));
+    memset(&dec_op, 0, sizeof(dec_op));
+
+    dec_ip.e_cmd = IVD_CMD_VIDEO_DECODE;
+    dec_ip.u4_ts = 0;
+    dec_ip.pv_stream_buffer = (void *)data;
+    dec_ip.u4_num_Bytes = size;
+    dec_ip.u4_size = sizeof(ivd_video_decode_ip_t);
+    dec_op.u4_size = sizeof(ivd_video_decode_op_t);
+
+    ret = ivd_api_function(mCodec, (void *)&dec_ip, (void *)&dec_op);
+
+    bytes_consumed = dec_op.u4_num_bytes_consumed;
+    /* If no bytes are consumed, then consume 4 bytes to ensure fuzzer proceeds
+     * to feed next data */
+    if (!bytes_consumed) bytes_consumed = 4;
+
+    bytes_consumed = std::min(size, bytes_consumed);
+
+    data += bytes_consumed;
+    size -= bytes_consumed;
+
+    mWidth = std::min(dec_op.u4_pic_wd, (UWORD32)10240);
+    mHeight = std::min(dec_op.u4_pic_ht, (UWORD32)10240);
+
+    /* Break after successful header decode */
+    if (mWidth && mHeight) {
+      break;
+    }
+  }
+  /* if width / height are invalid, set them to defaults */
+  if (!mWidth) mWidth = 1920;
+  if (!mHeight) mHeight = 1088;
+}
+
+IV_API_CALL_STATUS_T Codec::decodeFrame(const uint8_t *data, size_t size,
+                                        size_t *bytesConsumed) {
+  IV_API_CALL_STATUS_T ret;
+  ivd_video_decode_ip_t dec_ip;
+  ivd_video_decode_op_t dec_op;
+
+  memset(&dec_ip, 0, sizeof(dec_ip));
+  memset(&dec_op, 0, sizeof(dec_op));
+
+  dec_ip.e_cmd = IVD_CMD_VIDEO_DECODE;
+  dec_ip.u4_ts = 0;
+  dec_ip.pv_stream_buffer = (void *)data;
+  dec_ip.u4_num_Bytes = size;
+  dec_ip.u4_size = sizeof(ivd_video_decode_ip_t);
+  dec_ip.s_out_buffer = mOutBufHandle;
+
+  dec_op.u4_size = sizeof(ivd_video_decode_op_t);
+
+  ret = ivd_api_function(mCodec, (void *)&dec_ip, (void *)&dec_op);
+
+  /* In case of change in resolution, reset codec and feed the same data again
+   */
+  if (IVD_RES_CHANGED == (dec_op.u4_error_code & 0xFF)) {
+    resetCodec();
+    ret = ivd_api_function(mCodec, (void *)&dec_ip, (void *)&dec_op);
+  }
+  *bytesConsumed = dec_op.u4_num_bytes_consumed;
+
+  /* If no bytes are consumed, then consume 4 bytes to ensure fuzzer proceeds
+   * to feed next data */
+  if (!*bytesConsumed) *bytesConsumed = 4;
+
+  if (mWidth != dec_op.u4_pic_wd || mHeight != dec_op.u4_pic_ht) {
+    mWidth = std::min(dec_op.u4_pic_wd, (UWORD32)10240);
+    mHeight = std::min(dec_op.u4_pic_ht, (UWORD32)10240);
+    allocFrame();
+  }
+
+  return ret;
+}
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
+  if (size < 1) {
+    return 0;
+  }
+  size_t colorFormatOfst = std::min((size_t)OFFSET_COLOR_FORMAT, size - 1);
+  size_t numCoresOfst = std::min((size_t)OFFSET_NUM_CORES, size - 1);
+  size_t colorFormatIdx = data[colorFormatOfst] % kSupportedColorFormats;
+  IV_COLOR_FORMAT_T colorFormat =
+      (IV_COLOR_FORMAT_T)(supportedColorFormats[colorFormatIdx]);
+  uint32_t numCores = (data[numCoresOfst] % kMaxCores) + 1;
+
+  Codec *codec = new Codec(colorFormat, numCores);
+  codec->createCodec();
+  codec->setCores();
+  codec->decodeHeader(data, size);
+  codec->setParams(IVD_DECODE_FRAME);
+  codec->allocFrame();
+
+  while (size > 0) {
+    IV_API_CALL_STATUS_T ret;
+    size_t bytesConsumed;
+    ret = codec->decodeFrame(data, size, &bytesConsumed);
+
+    bytesConsumed = std::min(size, bytesConsumed);
+    data += bytesConsumed;
+    size -= bytesConsumed;
+  }
+
+  codec->freeFrame();
+  codec->deleteCodec();
+  delete codec;
+  return 0;
+}
diff --git a/fuzzer/avc_dec_fuzzer.dict b/fuzzer/avc_dec_fuzzer.dict
new file mode 100644
index 0000000..f436f20
--- /dev/null
+++ b/fuzzer/avc_dec_fuzzer.dict
@@ -0,0 +1,2 @@
+# Start code (bytes 0-3)
+kw1="\x00\x00\x00\x01"
diff --git a/test/encoder/main.c b/test/encoder/main.c
index bc25e8d..15261df 100644
--- a/test/encoder/main.c
+++ b/test/encoder/main.c
@@ -846,12 +846,14 @@
 
     while(0 == (feof(fp_cfg)))
     {
+        int ret;
         line[0] = '\0';
-        fgets(line, STRLENGTH, fp_cfg);
+        if(NULL == fgets(line, sizeof(line), fp_cfg))
+            break;
         argument[0] = '\0';
         /* Reading Input File Name */
-        sscanf(line, "%s %s %s", argument, value, description);
-        if(argument[0] == '\0')
+        ret = sscanf(line, "%s %s %s", argument, value, description);
+        if(ret < 2)
             continue;
 
         parse_argument(ps_app_ctxt, argument, value);