mm-video: merge up to CAF tip

merge up to "a78eeb68e340c
mm-video-v4l2: venc: update color format in port-def"

include
mm-video-v4l2: compilation fixes for C++11 compiler

Change-Id: I14daa9a47bb4da476395adec7af6427c5578f111
diff --git a/Android.mk b/Android.mk
index 17f2b6b..64f9fac 100644
--- a/Android.mk
+++ b/Android.mk
@@ -1,5 +1,5 @@
 QCOM_MEDIA_ROOT := $(call my-dir)
-ifneq ($(filter msm8610 msm8226 msm8974 msm8960 msm8660 msm7627a msm7630_surf msm8084 mpq8092,$(TARGET_BOARD_PLATFORM)),)
+ifneq ($(filter msm8610 msm8226 msm8974 msm8960 msm8660 msm7627a msm7630_surf msm8084 msm8992 msm8994,$(TARGET_BOARD_PLATFORM)),)
 include $(QCOM_MEDIA_ROOT)/mm-core/Android.mk
 include $(QCOM_MEDIA_ROOT)/libstagefrighthw/Android.mk
 endif
@@ -8,10 +8,10 @@
 include $(QCOM_MEDIA_ROOT)/mm-video-legacy/Android.mk
 endif
 
-ifneq ($(filter msm8610 msm8226 msm8974 msm8084 mpq8092,$(TARGET_BOARD_PLATFORM)),)
+ifneq ($(filter msm8610 msm8226 msm8974 msm8084 msm8992 msm8994,$(TARGET_BOARD_PLATFORM)),)
 include $(QCOM_MEDIA_ROOT)/mm-video-v4l2/Android.mk
 endif
 
-ifneq ($(filter msm8610 msm8226 msm8974 msm8960 msm8084 mpq8092,$(TARGET_BOARD_PLATFORM)),)
+ifneq ($(filter msm8610 msm8226 msm8974 msm8960 msm8084 msm8992 msm8994,$(TARGET_BOARD_PLATFORM)),)
 include $(QCOM_MEDIA_ROOT)/libc2dcolorconvert/Android.mk
 endif
diff --git a/libc2dcolorconvert/Android.mk b/libc2dcolorconvert/Android.mk
index 7aa530d..4edb0a5 100644
--- a/libc2dcolorconvert/Android.mk
+++ b/libc2dcolorconvert/Android.mk
@@ -6,8 +6,6 @@
         C2DColorConverter.cpp
 
 LOCAL_C_INCLUDES := \
-    $(TOP)/frameworks/av/include/media/stagefright \
-    $(TOP)/frameworks/native/include/media/openmax \
     $(TARGET_OUT_HEADERS)/qcom/display
 
 LOCAL_SHARED_LIBRARIES := liblog libdl
diff --git a/libc2dcolorconvert/C2DColorConverter.cpp b/libc2dcolorconvert/C2DColorConverter.cpp
index 36e456d..bf61269 100644
--- a/libc2dcolorconvert/C2DColorConverter.cpp
+++ b/libc2dcolorconvert/C2DColorConverter.cpp
@@ -35,6 +35,8 @@
 #include <sys/ioctl.h>
 #include <utils/Log.h>
 #include <dlfcn.h>
+#include <string.h>
+#include <errno.h>
 
 #undef LOG_TAG
 #define LOG_TAG "C2DColorConvert"
diff --git a/libc2dcolorconvert/C2DColorConverter.h b/libc2dcolorconvert/C2DColorConverter.h
index 0c84fad..f13f919 100644
--- a/libc2dcolorconvert/C2DColorConverter.h
+++ b/libc2dcolorconvert/C2DColorConverter.h
@@ -31,7 +31,6 @@
 #define C2D_ColorConverter_H_
 
 #include <c2d2.h>
-#include <ColorConverter.h>
 #include <sys/types.h>
 
 typedef C2D_STATUS (*LINK_c2dCreateSurface)( uint32 *surface_id,
diff --git a/libstagefrighthw/QComOMXPlugin.cpp b/libstagefrighthw/QComOMXPlugin.cpp
index 9446dcf..5d23243 100644
--- a/libstagefrighthw/QComOMXPlugin.cpp
+++ b/libstagefrighthw/QComOMXPlugin.cpp
@@ -1,5 +1,6 @@
 /*
  * Copyright (C) 2009 The Android Open Source Project
+ * Copyright (c) 2014, The Linux Foundation. All rights reserved.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -48,6 +49,11 @@
             (GetRolesOfComponentFunc)dlsym(
                     mLibHandle, "OMX_GetRolesOfComponent");
 
+        if (!mInit || !mDeinit || !mComponentNameEnum || !mGetHandle ||
+            !mFreeHandle || !mGetRolesOfComponentHandle) {
+            dlclose(mLibHandle);
+            mLibHandle = NULL;
+        } else
         (*mInit)();
     }
 }
diff --git a/mm-core/Android.mk b/mm-core/Android.mk
old mode 100755
new mode 100644
index df15666..bdee813
--- a/mm-core/Android.mk
+++ b/mm-core/Android.mk
@@ -34,8 +34,12 @@
 MM_CORE_TARGET = 8084
 else ifeq ($(TARGET_BOARD_PLATFORM),mpq8092)
 MM_CORE_TARGET = 8092
-else ifeq ($(TARGET_BOARD_PLATFORM),plutonium)
-MM_CORE_TARGET = plutonium
+else ifeq ($(TARGET_BOARD_PLATFORM),msm8992)
+MM_CORE_TARGET = msm8992
+else ifeq ($(TARGET_BOARD_PLATFORM),msm8994)
+MM_CORE_TARGET = msm8994
+else ifeq ($(TARGET_BOARD_PLATFORM),thulium)
+MM_CORE_TARGET = thulium
 else
 MM_CORE_TARGET = default
 endif
@@ -86,7 +90,7 @@
 
 LOCAL_SRC_FILES         := src/common/omx_core_cmp.cpp
 LOCAL_SRC_FILES         += src/common/qc_omx_core.c
-ifneq (,$(filter msm8916 plutonium,$(TARGET_BOARD_PLATFORM)))
+ifneq (,$(filter msm8916 msm8994 msm8909 thulium msm8992,$(TARGET_BOARD_PLATFORM)))
 LOCAL_SRC_FILES         += src/$(MM_CORE_TARGET)/registry_table_android.c
 else
 LOCAL_SRC_FILES         += src/$(MM_CORE_TARGET)/qc_registry_table_android.c
@@ -109,7 +113,7 @@
 
 LOCAL_SRC_FILES         := src/common/omx_core_cmp.cpp
 LOCAL_SRC_FILES         += src/common/qc_omx_core.c
-ifneq (,$(filter msm8916 plutonium,$(TARGET_BOARD_PLATFORM)))
+ifneq (,$(filter msm8916 msm8994 msm8909 thulium msm8992,$(TARGET_BOARD_PLATFORM)))
 LOCAL_SRC_FILES         += src/$(MM_CORE_TARGET)/registry_table.c
 else
 LOCAL_SRC_FILES         += src/$(MM_CORE_TARGET)/qc_registry_table.c
diff --git a/mm-core/inc/OMX_QCOMExtns.h b/mm-core/inc/OMX_QCOMExtns.h
old mode 100755
new mode 100644
index 1c85a80..f0e1593
--- a/mm-core/inc/OMX_QCOMExtns.h
+++ b/mm-core/inc/OMX_QCOMExtns.h
@@ -1,5 +1,5 @@
 /*--------------------------------------------------------------------------
-Copyright (c) 2009-2014, The Linux Foundation. All rights reserved.
+Copyright (c) 2009-2015, The Linux Foundation. All rights reserved.
 
 Redistribution and use in source and binary forms, with or without
 modification, are permitted provided that the following conditions are met:
@@ -229,7 +229,7 @@
     OMX_QCOM_PLATFORM_PRIVATE_ENTRY_TYPE type;
 
     /** Pointer to platform specific entry */
-    void* entry;
+    OMX_PTR entry;
 }OMX_QCOM_PLATFORM_PRIVATE_ENTRY;
 
 typedef struct OMX_QCOM_PLATFORM_PRIVATE_LIST
@@ -461,18 +461,79 @@
 
     OMX_QcomIndexParamPeakBitrate = 0x7F00003A,
 
-    /*"OMX.QCOM.index.config.video.LTRMark"*/
-    OMX_QcomIndexConfigVideoLTRMark = QOMX_IndexConfigVideoLTRMark,
-
     /* Enable InitialQP index */
     QOMX_IndexParamVideoInitialQp = 0x7F00003B,
 
     OMX_QcomIndexParamSetMVSearchrange = 0x7F00003C,
 
-    OMX_QcomIndexFlexibleYUVDescription = 0x7F00003D,
+    OMX_QcomIndexConfigPerfLevel = 0x7F00003D,
+
+    /*"OMX.QCOM.index.param.video.LTRCount"*/
+    OMX_QcomIndexParamVideoLTRCount = QOMX_IndexParamVideoLTRCount,
+
+    /*"OMX.QCOM.index.config.video.LTRUse"*/
+    OMX_QcomIndexConfigVideoLTRUse = QOMX_IndexConfigVideoLTRUse,
+
+    /*"OMX.QCOM.index.config.video.LTRMark"*/
+    OMX_QcomIndexConfigVideoLTRMark = QOMX_IndexConfigVideoLTRMark,
+
+    /*"OMX.QCOM.index.param.video.CustomBufferSize"*/
+    OMX_QcomIndexParamVideoCustomBufferSize = 0x7F00003E,
+
+    /*"OMX.QCOM.index.param.video.Mpeg2SeqDispExtraData"*/
+    OMX_QcomIndexParamMpeg2SeqDispExtraData = 0x7F000040,
+
+    /* Max Hierarchical P layers */
+    OMX_QcomIndexMaxHierarchicallayers = 0x7F000041,
+
+    /* Set Encoder Performance Index */
+    OMX_QcomIndexConfigVideoVencPerfMode = 0x7F000042,
+
+    /* Set Hybrid Hier-p layers */
+    OMX_QcomIndexParamVideoHybridHierpMode = 0x7F000043,
+
+    OMX_QcomIndexFlexibleYUVDescription = 0x7F000044,
 };
 
 /**
+* This is custom extension to configure Hybrid Hier-p settings.
+* This mode is different from enabling Hier-p mode. This
+* property enables Hier-p encoding with LTR referencing in each
+* sub-GOP.
+*
+* STRUCT MEMBERS
+*
+* nSize         : Size of Structure in bytes
+* nVersion      : OpenMAX IL specification version information
+* nHpLayers     : Set the number of Hier-p layers for the session
+*                  - This should be <= 6. (1 Base layer +
+*                    5 Enhancement layers)
+*/
+
+typedef struct QOMX_EXTNINDEX_VIDEO_HYBRID_HP_MODE {
+   OMX_U32 nSize;
+   OMX_VERSIONTYPE nVersion;
+   OMX_U32 nHpLayers;
+} QOMX_EXTNINDEX_VIDEO_HYBRID_HP_MODE;
+
+/**
+ * Encoder Performance Mode.  This structure is used to set
+ * performance mode or power save mode when encoding. The search
+ * range is modified to save power or improve quality.
+ *
+ * STRUCT MEMBERS:
+ * OMX_U32 nPerfMode  : Performance mode:
+ *                                      1: MAX_QUALITY
+ *                                      2: POWER_SAVE
+ */
+
+typedef struct QOMX_EXTNINDEX_VIDEO_PERFMODE {
+    OMX_U32 nSize;
+    OMX_VERSIONTYPE nVersion;
+    OMX_U32 nPerfMode;
+} QOMX_EXTNINDEX_VIDEO_PERFMODE;
+
+/**
  * Initial QP parameter.  This structure is used to enable
  * vendor specific extension to let client enable setting
  * initial QP values to I P B Frames
@@ -610,6 +671,12 @@
     OMX_U32 nCount;
 } QOMX_VIDEO_PARAM_LTRCOUNT_TYPE;
 
+
+/**
+ * This should be used with OMX_QcomIndexParamVideoLTRCount extension.
+ */
+typedef QOMX_VIDEO_PARAM_LTRCOUNT_TYPE OMX_QCOM_VIDEO_PARAM_LTRCOUNT_TYPE;
+
 /**
  * LTR period index parameter.  This structure is used
  * to enable vendor specific extension on output port
@@ -635,14 +702,22 @@
  *  nSize              : Size of Structure in bytes
  *  nVersion           : OpenMAX IL specification version information
  *  nPortIndex         : Index of the port to which this structure applies
+ *  nID                : Specifies the identifier of the LTR frame to be marked
+ *                       as reference frame for encoding subsequent frames.
  */
 typedef struct QOMX_VIDEO_CONFIG_LTRMARK_TYPE {
     OMX_U32 nSize;
     OMX_VERSIONTYPE nVersion;
     OMX_U32 nPortIndex;
+    OMX_U32 nID;
 } QOMX_VIDEO_CONFIG_LTRMARK_TYPE;
 
 /**
+ * This should be used with OMX_QcomIndexConfigVideoLTRMark extension.
+ */
+typedef QOMX_VIDEO_CONFIG_LTRMARK_TYPE OMX_QCOM_VIDEO_CONFIG_LTRMARK_TYPE;
+
+/**
  * Specifies an LTR frame to encode subsequent frames.
  * STRUCT MEMBERS:
  *  nSize              : Size of Structure in bytes
@@ -666,6 +741,11 @@
 } QOMX_VIDEO_CONFIG_LTRUSE_TYPE;
 
 /**
+ * This should be used with OMX_QcomIndexConfigVideoLTRUse extension.
+ */
+typedef QOMX_VIDEO_CONFIG_LTRUSE_TYPE OMX_QCOM_VIDEO_CONFIG_LTRUSE_TYPE;
+
+/**
  * Enumeration used to define the video encoder modes
  *
  * ENUMS:
@@ -832,6 +912,17 @@
 
 /**
  * This structure describes the parameters corresponding
+ * to OMX_QcomIndexConfigPerfLevel extension. It will set
+ * the performance mode specified as QOMX_VIDEO_PERF_LEVEL.
+ */
+typedef struct OMX_QCOM_VIDEO_CONFIG_PERF_LEVEL {
+    OMX_U32 nSize;                      /** Size of the structure in bytes */
+    OMX_VERSIONTYPE nVersion;           /** OMX specification version information */
+    QOMX_VIDEO_PERF_LEVEL ePerfLevel;   /** Performance level */
+} OMX_QCOM_VIDEO_CONFIG_PERF_LEVEL;
+
+/**
+ * This structure describes the parameters corresponding
  * to OMX_QcomIndexParamH264VUITimingInfo extension. It
  * will enable/disable the VUI timing info.
  */
@@ -1026,6 +1117,11 @@
    OMX_U8  data[0];
 } OMX_QCOM_EXTRADATA_MBINFO;
 
+typedef struct OMX_QCOM_EXTRADATA_MPEG2SEQDISPLAY {
+    OMX_U32 disp_width;
+    OMX_U32 disp_height;
+} OMX_QCOM_EXTRADATA_MPEG2SEQDISPLAY;
+
 typedef enum OMX_QCOM_EXTRADATATYPE
 {
    OMX_ExtraDataFrameInfo = 0x7F000001,
@@ -1043,6 +1139,7 @@
     OMX_ExtraDataQP =                      0x7F00000d,
     OMX_ExtraDataInputBitsInfo =           0x7F00000e,
     OMX_ExtraDataVideoEncoderMBInfo =      0x7F00000f,
+    OMX_ExtraDataMpeg2SeqDisplay =         0x7F000010,
 } OMX_QCOM_EXTRADATATYPE;
 
 typedef struct  OMX_STREAMINTERLACEFORMATTYPE {
@@ -1292,6 +1389,12 @@
         OMX_BOOL bEnable;
 } QOMX_INDEXDOWNSCALAR;
 
+typedef struct QOMX_VIDEO_CUSTOM_BUFFERSIZE {
+        OMX_U32 nSize;
+        OMX_VERSIONTYPE nVersion;
+        OMX_U32 nPortIndex;
+        OMX_U32 nBufferSize;
+} QOMX_VIDEO_CUSTOM_BUFFERSIZE;
 
 #define OMX_QCOM_INDEX_PARAM_VIDEO_SYNCFRAMEDECODINGMODE "OMX.QCOM.index.param.video.SyncFrameDecodingMode"
 #define OMX_QCOM_INDEX_PARAM_INDEXEXTRADATA "OMX.QCOM.index.param.IndexExtraData"
@@ -1301,6 +1404,7 @@
 #define OMX_QCOM_INDEX_PARAM_VIDEO_INPUTBITSINFO_EXTRADATA "OMX.QCOM.index.param.video.InputBitsInfoExtradata"
 #define OMX_QCOM_INDEX_PARAM_VIDEO_EXTNUSER_EXTRADATA "OMX.QCOM.index.param.video.ExtnUserExtraData"
 #define OMX_QCOM_INDEX_CONFIG_VIDEO_FRAMEPACKING_INFO "OMX.QCOM.index.config.video.FramePackingInfo"
+#define OMX_QCOM_INDEX_PARAM_VIDEO_MPEG2SEQDISP_EXTRADATA "OMX.QCOM.index.param.video.Mpeg2SeqDispExtraData"
 
 typedef enum {
     QOMX_VIDEO_FRAME_PACKING_CHECKERBOARD = 0,
diff --git a/mm-core/inc/OMX_Types.h b/mm-core/inc/OMX_Types.h
index 264532d..9871def 100644
--- a/mm-core/inc/OMX_Types.h
+++ b/mm-core/inc/OMX_Types.h
@@ -31,6 +31,8 @@
 #ifndef OMX_Types_h
 #define OMX_Types_h
 
+#include <stdint.h>
+
 #ifdef __cplusplus
 extern "C" {
 #endif /* __cplusplus */
@@ -142,10 +144,10 @@
 typedef signed short OMX_S16;
 
 /** OMX_U32 is a 32 bit unsigned quantity that is 32 bit word aligned */
-typedef unsigned long OMX_U32;
+typedef uint32_t OMX_U32;
 
 /** OMX_S32 is a 32 bit signed quantity that is 32 bit word aligned */
-typedef signed long OMX_S32;
+typedef int32_t OMX_S32;
 
 
 /* Users with compilers that cannot accept the "long long" designation should
@@ -192,6 +194,14 @@
     OMX_BOOL_MAX = 0x7FFFFFFF
 } OMX_BOOL;
 
+#ifdef OMX_ANDROID_COMPILE_AS_32BIT_ON_64BIT_PLATFORMS
+
+typedef OMX_U32 OMX_PTR;
+typedef OMX_PTR OMX_STRING;
+typedef OMX_PTR OMX_BYTE;
+
+#else
+
 /** The OMX_PTR type is intended to be used to pass pointers between the OMX
     applications and the OMX Core and components.  This is a 32 bit pointer and
     is aligned on a 32 bit boundary.
@@ -216,6 +226,10 @@
     at runtime.  This identifier should be generated by a component in a way
     that guarantees that every instance of the identifier running on the system
     is unique. */
+
+
+#endif
+
 typedef unsigned char OMX_UUIDTYPE[128];
 
 /** The OMX_DIRTYPE enumeration is used to indicate if a port is an input or
diff --git a/mm-core/inc/QCMediaDefs.h b/mm-core/inc/QCMediaDefs.h
old mode 100755
new mode 100644
index cc2ea95..050f2ec
--- a/mm-core/inc/QCMediaDefs.h
+++ b/mm-core/inc/QCMediaDefs.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012 - 2013, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012 - 2014, The Linux Foundation. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions are
@@ -51,7 +51,6 @@
 extern const char *MEDIA_MIMETYPE_AUDIO_EAC3;
 extern const char *MEDIA_MIMETYPE_AUDIO_AMR_WB_PLUS;
 extern const char *MEDIA_MIMETYPE_CONTAINER_QCMPEG2TS;
-extern const char *MEDIA_MIMETYPE_VIDEO_HEVC;
 extern const char *MEDIA_MIMETYPE_CONTAINER_QCMPEG;
 extern const char *MEDIA_MIMETYPE_CONTAINER_QCAMR_NB;
 extern const char *MEDIA_MIMETYPE_CONTAINER_QCAMR_WB;
@@ -63,6 +62,7 @@
 extern const char *MEDIA_MIMETYPE_CONTAINER_QCOGG;
 extern const char *MEDIA_MIMETYPE_CONTAINER_QTIFLAC;
 extern const char *MEDIA_MIMETYPE_VIDEO_VPX; //backward compatibility
+extern const char *MEDIA_MIMETYPE_AUDIO_EAC3_JOC;
 }  // namespace android
 
 #endif  //QC_MEDIA_DEFS_H_
diff --git a/mm-core/inc/QCMetaData.h b/mm-core/inc/QCMetaData.h
old mode 100755
new mode 100644
index 473cca6..c4805e0
--- a/mm-core/inc/QCMetaData.h
+++ b/mm-core/inc/QCMetaData.h
@@ -64,6 +64,14 @@
     kKeySmoothStreaming      = 'ESmS',  //bool (int32_t)
     kKeyHFR                  = 'hfr ',  // int32_t
     kKeyHSR                  = 'hsr ',  // int32_t
+
+    kKeySampleBits        = 'sbit', // int32_t (audio sample bit-width)
+    kKeyPcmFormat         = 'pfmt', //int32_t (pcm format)
+    kKeyMinBlkSize        = 'mibs', //int32_t
+    kKeyMaxBlkSize        = 'mabs', //int32_t
+    kKeyMinFrmSize        = 'mifs', //int32_t
+    kKeyMaxFrmSize        = 'mafs', //int32_t
+    kKeyMd5Sum            = 'md5s', //cstring
 };
 
 enum {
diff --git a/mm-core/src/msm8992/registry_table.c b/mm-core/src/msm8992/registry_table.c
new file mode 100644
index 0000000..b4d4866
--- /dev/null
+++ b/mm-core/src/msm8992/registry_table.c
@@ -0,0 +1,511 @@
+/*--------------------------------------------------------------------------
+Copyright (c) 2014, The Linux Foundation. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+    * Redistributions of source code must retain the above copyright
+      notice, this list of conditions and the following disclaimer.
+    * Redistributions in binary form must reproduce the above
+      copyright notice, this list of conditions and the following
+      disclaimer in the documentation and/or other materials provided
+      with the distribution.
+    * Neither the name of The Linux Foundation nor the names of its
+      contributors may be used to endorse or promote products derived
+      from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+--------------------------------------------------------------------------*/
+/*============================================================================
+                            O p e n M A X   w r a p p e r s
+                             O p e n  M A X   C o r e
+
+ This module contains the registry table for the QCOM's OpenMAX core.
+
+*//*========================================================================*/
+
+#include "qc_omx_core.h"
+
+omx_core_cb_type core[] =
+{
+  {
+    "OMX.qcom.video.decoder.avc",
+    NULL,   // Create instance function
+    // Unique instance handle
+    {
+      NULL,
+      NULL,
+      NULL,
+      NULL
+    },
+    NULL,   // Shared object library handle
+    "libOmxVdec.so",
+    {
+      "video_decoder.avc"
+    }
+  },
+  {
+    "OMX.qcom.video.decoder.mpeg4",
+    NULL,   // Create instance function
+    // Unique instance handle
+    {
+      NULL,
+      NULL,
+      NULL,
+      NULL
+    },
+    NULL,   // Shared object library handle
+    "libOmxVdec.so",
+    {
+      "video_decoder.mpeg4"
+    }
+  },
+  {
+    "OMX.qcom.video.decoder.vc1",
+    NULL,   // Create instance function
+    // Unique instance handle
+    {
+      NULL,
+      NULL,
+      NULL,
+      NULL
+    },
+    NULL,   // Shared object library handle
+    "libOmxVdec.so",
+    {
+      "video_decoder.vc1"
+    }
+  },
+  {
+    "OMX.qcom.video.decoder.wmv",
+    NULL,   // Create instance function
+    // Unique instance handle
+    {
+      NULL,
+      NULL,
+      NULL,
+      NULL
+    },
+    NULL,   // Shared object library handle
+    "libOmxVdec.so",
+    {
+      "video_decoder.vc1"
+    }
+  },
+  {
+    "OMX.qcom.file.muxer",
+    NULL,   // Create instance function
+    // Unique instance handle
+    {
+      NULL,
+      NULL,
+      NULL,
+      NULL
+    },
+    NULL,   // Shared object library handle
+
+    "libOmxMux.so",
+    {
+      "container_muxer.mp2"
+    }
+  },
+  {
+    "OMX.qcom.video.decoder.divx4",
+    NULL,   // Create instance function
+    // Unique instance handle
+    {
+      NULL,
+      NULL,
+      NULL,
+      NULL
+    },
+    NULL,   // Shared object library handle
+    "libOmxVdec.so",
+    {
+      "video_decoder.divx"
+    }
+  },
+  {
+    "OMX.qcom.video.decoder.divx",
+    NULL,   // Create instance function
+    // Unique instance handle
+    {
+      NULL,
+      NULL,
+      NULL,
+      NULL
+    },
+    NULL,   // Shared object library handle
+    "libOmxVdec.so",
+    {
+      "video_decoder.divx"
+    }
+  },
+  {
+    "OMX.qcom.video.decoder.divx311",
+    NULL,   // Create instance function
+    // Unique instance handle
+    {
+      NULL,
+      NULL,
+      NULL,
+      NULL
+    },
+    NULL,   // Shared object library handle
+    "libOmxVdec.so",
+    {
+      "video_decoder.divx"
+    }
+  },
+  {
+    "OMX.qcom.video.decoder.h263",
+    NULL,   // Create instance function
+    // Unique instance handle
+    {
+      NULL,
+      NULL,
+      NULL,
+      NULL
+    },
+    NULL,   // Shared object library handle
+    "libOmxVdec.so",
+    {
+      "video_decoder.h263"
+    }
+  },
+  {
+    "OMX.qcom.video.decoder.hevc",
+    NULL,   // Create instance function
+    // Unique instance handle
+    {
+      NULL,
+      NULL,
+      NULL,
+      NULL
+    },
+    NULL,   // Shared object library handle
+    "libOmxVdec.so",
+    {
+      "video_decoder.hevc"
+    }
+  },
+  {
+    "OMX.qcom.video.decoder.hevc.secure",
+    NULL, // Create instance function
+    // Unique instance handle
+    {
+      NULL,
+      NULL,
+      NULL,
+      NULL
+    },
+    NULL,   // Shared object library handle
+    "libOmxVdec.so",
+    {
+      "video_decoder.hevc"
+    }
+   },
+   {
+    "OMX.qcom.video.decoder.vp8",
+    NULL,   // Create instance function
+    // Unique instance handle
+    {
+      NULL,
+      NULL,
+      NULL,
+      NULL
+    },
+    NULL,   // Shared object library handle
+    "libOmxVdec.so",
+    {
+      "video_decoder.vp8"
+    }
+  },
+   {
+    "OMX.qcom.video.encoder.mpeg4",
+    NULL,   // Create instance function
+    // Unique instance handle
+    {
+      NULL,
+      NULL,
+      NULL,
+      NULL
+    },
+    NULL,   // Shared object library handle
+    "libOmxVenc.so",
+    {
+      "video_encoder.mpeg4"
+    }
+  },
+   {
+    "OMX.qcom.video.encoder.h263",
+    NULL,   // Create instance function
+    // Unique instance handle
+    {
+      NULL,
+      NULL,
+      NULL,
+      NULL
+    },
+    NULL,   // Shared object library handle
+    "libOmxVenc.so",
+    {
+      "video_encoder.h263",
+    }
+  },
+   {
+    "OMX.qcom.video.encoder.avc",
+    NULL, // Create instance function
+    // Unique instance handle
+    {
+      NULL,
+      NULL,
+      NULL,
+      NULL
+    },
+    NULL,   // Shared object library handle
+    "libOmxVenc.so",
+    {
+      "video_encoder.avc"
+    }
+  },
+   {
+    "OMX.qcom.video.encoder.vp8",
+    NULL,   // Create instance function
+    // Unique instance handle
+    {
+      NULL,
+      NULL,
+      NULL,
+      NULL
+    },
+    NULL,   // Shared object library handle
+    "libOmxVenc.so",
+    {
+      "video_encoder.vp8",
+    }
+  },
+  {
+    "OMX.qti.video.encoder.hevc",
+    NULL,   // Create instance function
+    // Unique instance handle
+    {
+      NULL,
+      NULL,
+      NULL,
+      NULL
+    },
+    NULL,   // Shared object library handle
+    "libOmxSwVencHevc.so",
+    {
+      "video_encoder.hevc"
+    }
+  },
+  {
+    "OMX.qcom.audio.decoder.Qcelp13",
+    NULL, // Create instance function
+    // Unique instance handle
+    {
+      NULL,
+      NULL,
+      NULL,
+      NULL
+    },
+    NULL,   // Shared object library handle
+    "libOmxQcelp13Dec.so",
+    {
+      "audio_decoder.Qcelp13"
+    }
+  },
+  {
+    "OMX.qcom.audio.decoder.evrc",
+    NULL, // Create instance function
+    // Unique instance handle
+    {
+      NULL,
+      NULL,
+      NULL,
+      NULL
+    },
+    NULL,   // Shared object library handle
+    "libOmxEvrcDec.so",
+    {
+      "audio_decoder.evrc"
+    }
+  },
+  {
+    "OMX.qcom.audio.decoder.wma",
+    NULL, // Create instance function
+    // Unique instance handle
+    {
+     NULL,
+     NULL,
+     NULL,
+     NULL
+    },
+    NULL,   // Shared object library handle
+    "libOmxWmaDec.so",
+    {
+     "audio_decoder.wma"
+    }
+  },
+  {
+    "OMX.qcom.audio.decoder.wma10Pro",
+    NULL,   // Create instance function
+    // Unique instance handle
+    {
+     NULL,
+     NULL,
+     NULL,
+     NULL
+    },
+    NULL,   // Shared object library handle
+    "libOmxWmaDec.so",
+    {
+     "audio_decoder.wma"
+    }
+  },
+  {
+    "OMX.qcom.audio.decoder.aac",
+    NULL,   // Create instance function
+    // Unique instance handle
+    {
+      NULL,
+      NULL,
+      NULL,
+      NULL
+    },
+    NULL,   // Shared object library handle
+    "libOmxAacDec.so",
+    {
+      "audio_decoder.aac"
+    }
+  },
+  {
+    "OMX.qcom.audio.encoder.aac",
+    NULL, // Create instance function
+    // Unique instance handle
+    {
+      NULL,
+      NULL,
+      NULL,
+      NULL
+    },
+    NULL,  // Shared object library handle
+    "libOmxAacEnc.so",
+    {
+      "audio_encoder.aac"
+    }
+  },
+  {
+    "OMX.qcom.audio.encoder.qcelp13",
+    NULL,   // Create instance function
+    // Unique instance handle
+    {
+      NULL,
+      NULL,
+      NULL,
+      NULL
+    },
+    NULL,   // Shared object library handle
+    "libOmxQcelp13Enc.so",
+    {
+      "audio_encoder.qcelp13"
+    }
+  },
+  {
+    "OMX.qcom.audio.encoder.evrc",
+    NULL,   // Create instance function
+    // Unique instance handle
+    {
+      NULL,
+      NULL,
+      NULL,
+      NULL
+    },
+    NULL,   // Shared object library handle
+    "libOmxEvrcEnc.so",
+    {
+      "audio_encoder.evrc"
+    }
+  },
+  {
+    "OMX.qcom.audio.encoder.amrnb",
+    NULL,   // Create instance function
+    // Unique instance handle
+    {
+      NULL,
+      NULL,
+      NULL,
+      NULL
+    },
+    NULL,   // Shared object library handle
+    "libOmxAmrEnc.so",
+    {
+      "audio_encoder.amrnb"
+    }
+  },
+ {
+    "OMX.qcom.audio.decoder.aac",
+    NULL,   // Create instance function
+    // Unique instance handle
+    {
+      NULL,
+      NULL,
+      NULL,
+      NULL
+    },
+    NULL,   // Shared object library handle
+    "libOmxAacDec.so",
+    {
+      "audio_decoder.aac"
+    }
+  },
+  {
+    "OMX.qcom.audio.decoder.multiaac",
+    NULL,   // Create instance function
+    // Unique instance handle
+    {
+      NULL,
+      NULL,
+      NULL,
+      NULL
+    },
+    NULL,   // Shared object library handle
+    "libOmxAacDec.so",
+    {
+      "audio_decoder.aac"
+    }
+  },
+  {
+    "OMX.qcom.video.postprocessing",
+    NULL, // Create instance function
+    // Unique instance handle
+    {
+      NULL,
+      NULL,
+      NULL,
+      NULL
+    },
+    NULL,   // Shared object library handle
+    "libOmxVdpp.so",
+    {
+      "videopostprocessing"
+    }
+  }
+};
+
+const unsigned int SIZE_OF_CORE = sizeof(core) / sizeof(omx_core_cb_type);
+
+
diff --git a/mm-core/src/msm8992/registry_table_android.c b/mm-core/src/msm8992/registry_table_android.c
new file mode 100644
index 0000000..200374e
--- /dev/null
+++ b/mm-core/src/msm8992/registry_table_android.c
@@ -0,0 +1,654 @@
+/*--------------------------------------------------------------------------
+Copyright (c) 2014, The Linux Foundation. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+    * Redistributions of source code must retain the above copyright
+      notice, this list of conditions and the following disclaimer.
+    * Redistributions in binary form must reproduce the above
+      copyright notice, this list of conditions and the following
+      disclaimer in the documentation and/or other materials provided
+      with the distribution.
+    * Neither the name of The Linux Foundation nor the names of its
+      contributors may be used to endorse or promote products derived
+      from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+--------------------------------------------------------------------------*/
+/*============================================================================
+                            O p e n M A X   w r a p p e r s
+                             O p e n  M A X   C o r e
+
+  This module contains the registry table for the QCOM's OpenMAX core.
+
+*//*========================================================================*/
+
+
+#include "qc_omx_core.h"
+
+omx_core_cb_type core[] =
+{
+  {
+    "OMX.qcom.video.decoder.avc",
+    NULL, // Create instance function
+    // Unique instance handle
+    {
+      NULL,
+      NULL,
+      NULL,
+      NULL
+    },
+    NULL,   // Shared object library handle
+    "libOmxVdec.so",
+    {
+      "video_decoder.avc"
+    }
+  },
+  {
+    "OMX.qcom.video.decoder.avc.secure",
+    NULL, // Create instance function
+    // Unique instance handle
+    {
+      NULL,
+      NULL,
+      NULL,
+      NULL
+    },
+    NULL,   // Shared object library handle
+    "libOmxVdec.so",
+    {
+      "video_decoder.avc"
+    }
+  },
+  {
+    "OMX.qcom.video.decoder.divx4",
+    NULL,   // Create instance function
+    // Unique instance handle
+    {
+      NULL,
+      NULL,
+      NULL,
+      NULL
+    },
+    NULL,   // Shared object library handle
+    "libOmxVdec.so",
+    {
+      "video_decoder.divx"
+    }
+  },
+  {
+    "OMX.qcom.video.decoder.divx",
+    NULL,   // Create instance function
+    // Unique instance handle
+    {
+      NULL,
+      NULL,
+      NULL,
+      NULL
+    },
+    NULL,   // Shared object library handle
+    "libOmxVdec.so",
+    {
+      "video_decoder.divx"
+    }
+  },
+  {
+    "OMX.qcom.video.decoder.divx311",
+    NULL,   // Create instance function
+    // Unique instance handle
+    {
+      NULL,
+      NULL,
+      NULL,
+      NULL
+    },
+    NULL,   // Shared object library handle
+    "libOmxVdec.so",
+    {
+      "video_decoder.divx"
+    }
+  },
+  {
+    "OMX.qcom.video.decoder.mpeg4",
+    NULL, // Create instance function
+    // Unique instance handle
+    {
+      NULL,
+      NULL,
+      NULL,
+      NULL
+    },
+    NULL,   // Shared object library handle
+    "libOmxVdec.so",
+    {
+      "video_decoder.mpeg4"
+    }
+  },
+  {
+    "OMX.qcom.video.decoder.mpeg2",
+    NULL, // Create instance function
+    // Unique instance handle
+    {
+      NULL,
+      NULL,
+      NULL,
+      NULL
+    },
+    NULL,   // Shared object library handle
+    "libOmxVdec.so",
+    {
+      "video_decoder.mpeg2"
+    }
+  },
+  {
+    "OMX.qcom.video.decoder.mpeg2.secure",
+    NULL, // Create instance function
+    // Unique instance handle
+    {
+      NULL,
+      NULL,
+      NULL,
+      NULL
+    },
+    NULL,   // Shared object library handle
+    "libOmxVdec.so",
+    {
+      "video_decoder.mpeg2"
+    }
+  },
+  {
+    "OMX.qcom.video.decoder.vc1",
+    NULL, // Create instance function
+    // Unique instance handle
+    {
+      NULL,
+      NULL,
+      NULL,
+      NULL
+    },
+    NULL,   // Shared object library handle
+    "libOmxVdec.so",
+    {
+      "video_decoder.vc1"
+    }
+  },
+  {
+    "OMX.qcom.video.decoder.vc1.secure",
+    NULL, // Create instance function
+    // Unique instance handle
+    {
+      NULL,
+      NULL,
+      NULL,
+      NULL
+    },
+    NULL,   // Shared object library handle
+    "libOmxVdec.so",
+    {
+      "video_decoder.vc1"
+    }
+  },
+  {
+    "OMX.qcom.video.decoder.wmv",
+    NULL, // Create instance function
+    // Unique instance handle
+    {
+      NULL,
+      NULL,
+      NULL,
+      NULL
+    },
+    NULL,   // Shared object library handle
+    "libOmxVdec.so",
+    {
+      "video_decoder.vc1"
+    }
+  },
+  {
+    "OMX.qcom.video.decoder.wmv.secure",
+    NULL, // Create instance function
+    // Unique instance handle
+    {
+      NULL,
+      NULL,
+      NULL,
+      NULL
+    },
+    NULL,   // Shared object library handle
+    "libOmxVdec.so",
+    {
+      "video_decoder.vc1"
+    }
+  },
+  {
+    "OMX.qcom.video.decoder.h263",
+    NULL, // Create instance function
+    // Unique instance handle
+    {
+      NULL,
+      NULL,
+      NULL,
+      NULL
+    },
+    NULL,   // Shared object library handle
+    "libOmxVdec.so",
+    {
+      "video_decoder.h263"
+    }
+  },
+{
+    "OMX.qcom.video.decoder.hevc",
+    NULL,   // Create instance function
+    // Unique instance handle
+    {
+      NULL,
+      NULL,
+      NULL,
+      NULL
+    },
+    NULL,   // Shared object library handle
+    "libOmxVdec.so",
+    {
+      "video_decoder.hevc"
+    }
+  },
+  {
+    "OMX.qcom.video.decoder.hevc.secure",
+    NULL, // Create instance function
+    // Unique instance handle
+    {
+      NULL,
+      NULL,
+      NULL,
+      NULL
+    },
+    NULL,   // Shared object library handle
+    "libOmxVdec.so",
+    {
+      "video_decoder.hevc"
+    }
+   },
+   {
+    "OMX.qcom.video.decoder.vp8",
+    NULL, // Create instance function
+    // Unique instance handle
+    {
+      NULL,
+      NULL,
+      NULL,
+      NULL
+    },
+    NULL,   // Shared object library handle
+    "libOmxVdec.so",
+    {
+      "video_decoder.vp8"
+    }
+  },
+   {
+    "OMX.qcom.video.encoder.mpeg4",
+    NULL, // Create instance function
+    // Unique instance handle
+    {
+      NULL,
+      NULL,
+      NULL,
+      NULL
+    },
+    NULL,   // Shared object library handle
+    "libOmxVenc.so",
+    {
+      "video_encoder.mpeg4"
+    }
+  },
+   {
+    "OMX.qcom.video.encoder.h263",
+    NULL, // Create instance function
+    // Unique instance handle
+    {
+      NULL,
+      NULL,
+      NULL,
+      NULL
+    },
+    NULL,   // Shared object library handle
+    "libOmxVenc.so",
+    {
+      "video_encoder.h263"
+    }
+  },
+  {
+    "OMX.qcom.video.encoder.avc",
+    NULL, // Create instance function
+    // Unique instance handle
+    {
+      NULL,
+      NULL,
+      NULL,
+      NULL
+    },
+    NULL,   // Shared object library handle
+    "libOmxVenc.so",
+    {
+      "video_encoder.avc"
+    }
+  },
+  {
+    "OMX.qcom.video.encoder.avc.secure",
+    NULL, // Create instance function
+    // Unique instance handle
+    {
+      NULL,
+      NULL,
+      NULL,
+      NULL
+    },
+    NULL,   // Shared object library handle
+    "libOmxVenc.so",
+    {
+      "video_encoder.avc"
+    }
+  },
+  {
+    "OMX.qcom.video.encoder.vp8",
+    NULL, // Create instance function
+    // Unique instance handle
+    {
+      NULL,
+      NULL,
+      NULL,
+      NULL
+    },
+    NULL,   // Shared object library handle
+    "libOmxVenc.so",
+    {
+      "video_encoder.vp8"
+    }
+  },
+  {
+    "OMX.qti.video.encoder.hevc",
+    NULL,   // Create instance function
+    // Unique instance handle
+    {
+      NULL,
+      NULL,
+      NULL,
+      NULL
+    },
+    NULL,   // Shared object library handle
+    "libOmxSwVencHevc.so",
+    {
+      "video_encoder.hevc"
+    }
+  },
+  {
+    "OMX.qcom.audio.decoder.Qcelp13",
+    NULL, // Create instance function
+    // Unique instance handle
+    {
+      NULL,
+      NULL,
+      NULL,
+      NULL
+    },
+    NULL,   // Shared object library handle
+    "libOmxQcelp13Dec.so",
+    {
+      "audio_decoder.Qcelp13"
+    }
+  },
+  {
+    "OMX.qcom.audio.decoder.evrc",
+    NULL, // Create instance function
+    // Unique instance handle
+    {
+      NULL,
+      NULL,
+      NULL,
+      NULL
+    },
+    NULL,   // Shared object library handle
+    "libOmxEvrcDec.so",
+    {
+      "audio_decoder.evrc"
+    }
+  },
+  {
+    "OMX.qcom.audio.decoder.wma",
+    NULL, // Create instance function
+    // Unique instance handle
+    {
+     NULL,
+     NULL,
+     NULL,
+     NULL
+    },
+    NULL,   // Shared object library handle
+    "libOmxWmaDec.so",
+    {
+     "audio_decoder.wma"
+    }
+  },
+  {
+    "OMX.qcom.audio.decoder.wma10Pro",
+    NULL,   // Create instance function
+    // Unique instance handle
+    {
+     NULL,
+     NULL,
+     NULL,
+     NULL
+    },
+    NULL,   // Shared object library handle
+    "libOmxWmaDec.so",
+    {
+     "audio_decoder.wma"
+    }
+  },
+  {
+    "OMX.qcom.audio.decoder.wmaLossLess",
+    NULL,   // Create instance function
+    // Unique instance handle
+    {
+     NULL,
+     NULL,
+     NULL,
+     NULL
+    },
+    NULL,   // Shared object library handle
+    "libOmxWmaDec.so",
+    {
+     "audio_decoder.wma"
+    }
+  },
+  {
+    "OMX.qcom.audio.decoder.amrwbplus",
+    NULL,   // Create instance function
+    // Unique instance handle
+    {
+     NULL,
+     NULL,
+     NULL,
+     NULL
+    },
+    NULL,   // Shared object library handle
+    "libOmxAmrwbplusDec.so",
+    {
+     "audio_decoder.awbplus"
+    }
+  },
+  {
+    "OMX.qcom.audio.decoder.aac",
+    NULL,   // Create instance function
+    // Unique instance handle
+    {
+      NULL,
+      NULL,
+      NULL,
+      NULL
+    },
+    NULL,   // Shared object library handle
+    "libOmxAacDec.so",
+    {
+      "audio_decoder.aac"
+    }
+  },
+  {
+    "OMX.qcom.audio.encoder.aac",
+    NULL, // Create instance function
+    // Unique instance handle
+    {
+      NULL,
+      NULL,
+      NULL,
+      NULL
+    },
+    NULL,  // Shared object library handle
+    "libOmxAacEnc.so",
+    {
+      "audio_encoder.aac"
+    }
+  },
+  {
+    "OMX.qcom.audio.encoder.qcelp13",
+    NULL,   // Create instance function
+    // Unique instance handle
+    {
+      NULL,
+      NULL,
+      NULL,
+      NULL
+    },
+    NULL,   // Shared object library handle
+    "libOmxQcelp13Enc.so",
+    {
+      "audio_encoder.qcelp13"
+    }
+  },
+  {
+    "OMX.qcom.audio.encoder.evrc",
+    NULL,   // Create instance function
+    // Unique instance handle
+    {
+      NULL,
+      NULL,
+      NULL,
+      NULL
+    },
+    NULL,   // Shared object library handle
+    "libOmxEvrcEnc.so",
+    {
+      "audio_encoder.evrc"
+    }
+  },
+  {
+    "OMX.qcom.audio.encoder.amrnb",
+    NULL,   // Create instance function
+    // Unique instance handle
+    {
+      NULL,
+      NULL,
+      NULL,
+      NULL
+    },
+    NULL,   // Shared object library handle
+    "libOmxAmrEnc.so",
+    {
+      "audio_encoder.amrnb"
+    }
+  },
+ {
+    "OMX.qcom.audio.decoder.aac",
+    NULL,   // Create instance function
+    // Unique instance handle
+    {
+      NULL,
+      NULL,
+      NULL,
+      NULL
+    },
+    NULL,   // Shared object library handle
+    "libOmxAacDec.so",
+    {
+      "audio_decoder.aac"
+    }
+  },
+ {
+    "OMX.qcom.audio.decoder.multiaac",
+    NULL,   // Create instance function
+    // Unique instance handle
+    {
+      NULL,
+      NULL,
+      NULL,
+      NULL
+    },
+    NULL,   // Shared object library handle
+    "libOmxAacDec.so",
+    {
+      "audio_decoder.aac"
+    }
+  },
+  {
+    "AIV.play.generic",
+    NULL, // Create instance function
+    // Unique instance handle
+    {
+      NULL,
+      NULL,
+      NULL,
+      NULL
+    },
+    NULL,  // Shared object library handle
+    "libAivPlay.so",
+    {
+      "AIV.play.role.generic"
+    }
+  },
+  {
+    "OMX.qcom.file.muxer",
+    NULL, // Create instance function
+    // Unique instance handle
+    {
+      NULL,
+      NULL,
+      NULL,
+      NULL
+    },
+    NULL,   // Shared object library handle
+    "libOmxMux.so",
+    {
+      "container_muxer.mp2"
+    }
+  },
+  {
+    "OMX.qcom.video.postprocessing",
+    NULL, // Create instance function
+    // Unique instance handle
+    {
+      NULL,
+      NULL,
+      NULL,
+      NULL
+    },
+    NULL,   // Shared object library handle
+    "libOmxVdpp.so",
+    {
+      "videopostprocessing"
+    }
+  }
+};
+
+const unsigned int SIZE_OF_CORE = sizeof(core) / sizeof(omx_core_cb_type);
+
+
diff --git a/mm-core/src/msm8994/registry_table.c b/mm-core/src/msm8994/registry_table.c
new file mode 100644
index 0000000..d6820a8
--- /dev/null
+++ b/mm-core/src/msm8994/registry_table.c
@@ -0,0 +1,495 @@
+/*--------------------------------------------------------------------------
+Copyright (c) 2014, The Linux Foundation. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+    * Redistributions of source code must retain the above copyright
+      notice, this list of conditions and the following disclaimer.
+    * Redistributions in binary form must reproduce the above
+      copyright notice, this list of conditions and the following
+      disclaimer in the documentation and/or other materials provided
+      with the distribution.
+    * Neither the name of The Linux Foundation nor the names of its
+      contributors may be used to endorse or promote products derived
+      from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+--------------------------------------------------------------------------*/
+/*============================================================================
+                            O p e n M A X   w r a p p e r s
+                             O p e n  M A X   C o r e
+
+ This module contains the registry table for the QCOM's OpenMAX core.
+
+*//*========================================================================*/
+
+#include "qc_omx_core.h"
+
+omx_core_cb_type core[] =
+{
+  {
+    "OMX.qcom.video.decoder.avc",
+    NULL,   // Create instance function
+    // Unique instance handle
+    {
+      NULL,
+      NULL,
+      NULL,
+      NULL
+    },
+    NULL,   // Shared object library handle
+    "libOmxVdec.so",
+    {
+      "video_decoder.avc"
+    }
+  },
+  {
+    "OMX.qcom.video.decoder.mpeg4",
+    NULL,   // Create instance function
+    // Unique instance handle
+    {
+      NULL,
+      NULL,
+      NULL,
+      NULL
+    },
+    NULL,   // Shared object library handle
+    "libOmxVdec.so",
+    {
+      "video_decoder.mpeg4"
+    }
+  },
+  {
+    "OMX.qcom.video.decoder.vc1",
+    NULL,   // Create instance function
+    // Unique instance handle
+    {
+      NULL,
+      NULL,
+      NULL,
+      NULL
+    },
+    NULL,   // Shared object library handle
+    "libOmxVdec.so",
+    {
+      "video_decoder.vc1"
+    }
+  },
+  {
+    "OMX.qcom.video.decoder.wmv",
+    NULL,   // Create instance function
+    // Unique instance handle
+    {
+      NULL,
+      NULL,
+      NULL,
+      NULL
+    },
+    NULL,   // Shared object library handle
+    "libOmxVdec.so",
+    {
+      "video_decoder.vc1"
+    }
+  },
+  {
+    "OMX.qcom.file.muxer",
+    NULL,   // Create instance function
+    // Unique instance handle
+    {
+      NULL,
+      NULL,
+      NULL,
+      NULL
+    },
+    NULL,   // Shared object library handle
+
+    "libOmxMux.so",
+    {
+      "container_muxer.mp2"
+    }
+  },
+  {
+    "OMX.qcom.video.decoder.divx4",
+    NULL,   // Create instance function
+    // Unique instance handle
+    {
+      NULL,
+      NULL,
+      NULL,
+      NULL
+    },
+    NULL,   // Shared object library handle
+    "libOmxVdec.so",
+    {
+      "video_decoder.divx"
+    }
+  },
+  {
+    "OMX.qcom.video.decoder.divx",
+    NULL,   // Create instance function
+    // Unique instance handle
+    {
+      NULL,
+      NULL,
+      NULL,
+      NULL
+    },
+    NULL,   // Shared object library handle
+    "libOmxVdec.so",
+    {
+      "video_decoder.divx"
+    }
+  },
+  {
+    "OMX.qcom.video.decoder.divx311",
+    NULL,   // Create instance function
+    // Unique instance handle
+    {
+      NULL,
+      NULL,
+      NULL,
+      NULL
+    },
+    NULL,   // Shared object library handle
+    "libOmxVdec.so",
+    {
+      "video_decoder.divx"
+    }
+  },
+  {
+    "OMX.qcom.video.decoder.h263",
+    NULL,   // Create instance function
+    // Unique instance handle
+    {
+      NULL,
+      NULL,
+      NULL,
+      NULL
+    },
+    NULL,   // Shared object library handle
+    "libOmxVdec.so",
+    {
+      "video_decoder.h263"
+    }
+  },
+  {
+    "OMX.qcom.video.decoder.hevc",
+    NULL,   // Create instance function
+    // Unique instance handle
+    {
+      NULL,
+      NULL,
+      NULL,
+      NULL
+    },
+    NULL,   // Shared object library handle
+    "libOmxVdec.so",
+    {
+      "video_decoder.hevc"
+    }
+  },
+   {
+    "OMX.qcom.video.decoder.vp8",
+    NULL,   // Create instance function
+    // Unique instance handle
+    {
+      NULL,
+      NULL,
+      NULL,
+      NULL
+    },
+    NULL,   // Shared object library handle
+    "libOmxVdec.so",
+    {
+      "video_decoder.vp8"
+    }
+  },
+   {
+    "OMX.qcom.video.encoder.mpeg4",
+    NULL,   // Create instance function
+    // Unique instance handle
+    {
+      NULL,
+      NULL,
+      NULL,
+      NULL
+    },
+    NULL,   // Shared object library handle
+    "libOmxVenc.so",
+    {
+      "video_encoder.mpeg4"
+    }
+  },
+   {
+    "OMX.qcom.video.encoder.h263",
+    NULL,   // Create instance function
+    // Unique instance handle
+    {
+      NULL,
+      NULL,
+      NULL,
+      NULL
+    },
+    NULL,   // Shared object library handle
+    "libOmxVenc.so",
+    {
+      "video_encoder.h263",
+    }
+  },
+   {
+    "OMX.qcom.video.encoder.avc",
+    NULL, // Create instance function
+    // Unique instance handle
+    {
+      NULL,
+      NULL,
+      NULL,
+      NULL
+    },
+    NULL,   // Shared object library handle
+    "libOmxVenc.so",
+    {
+      "video_encoder.avc"
+    }
+  },
+   {
+    "OMX.qcom.video.encoder.vp8",
+    NULL,   // Create instance function
+    // Unique instance handle
+    {
+      NULL,
+      NULL,
+      NULL,
+      NULL
+    },
+    NULL,   // Shared object library handle
+    "libOmxVenc.so",
+    {
+      "video_encoder.vp8",
+    }
+  },
+  {
+    "OMX.qcom.video.encoder.hevc",
+    NULL,   // Create instance function
+    // Unique instance handle
+    {
+      NULL,
+      NULL,
+      NULL,
+      NULL
+    },
+    NULL,   // Shared object library handle
+    "libOmxVenc.so",
+    {
+      "video_encoder.hevc"
+    }
+  },
+  {
+    "OMX.qcom.audio.decoder.Qcelp13",
+    NULL, // Create instance function
+    // Unique instance handle
+    {
+      NULL,
+      NULL,
+      NULL,
+      NULL
+    },
+    NULL,   // Shared object library handle
+    "libOmxQcelp13Dec.so",
+    {
+      "audio_decoder.Qcelp13"
+    }
+  },
+  {
+    "OMX.qcom.audio.decoder.evrc",
+    NULL, // Create instance function
+    // Unique instance handle
+    {
+      NULL,
+      NULL,
+      NULL,
+      NULL
+    },
+    NULL,   // Shared object library handle
+    "libOmxEvrcDec.so",
+    {
+      "audio_decoder.evrc"
+    }
+  },
+  {
+    "OMX.qcom.audio.decoder.wma",
+    NULL, // Create instance function
+    // Unique instance handle
+    {
+     NULL,
+     NULL,
+     NULL,
+     NULL
+    },
+    NULL,   // Shared object library handle
+    "libOmxWmaDec.so",
+    {
+     "audio_decoder.wma"
+    }
+  },
+  {
+    "OMX.qcom.audio.decoder.wma10Pro",
+    NULL,   // Create instance function
+    // Unique instance handle
+    {
+     NULL,
+     NULL,
+     NULL,
+     NULL
+    },
+    NULL,   // Shared object library handle
+    "libOmxWmaDec.so",
+    {
+     "audio_decoder.wma"
+    }
+  },
+  {
+    "OMX.qcom.audio.decoder.aac",
+    NULL,   // Create instance function
+    // Unique instance handle
+    {
+      NULL,
+      NULL,
+      NULL,
+      NULL
+    },
+    NULL,   // Shared object library handle
+    "libOmxAacDec.so",
+    {
+      "audio_decoder.aac"
+    }
+  },
+  {
+    "OMX.qcom.audio.encoder.aac",
+    NULL, // Create instance function
+    // Unique instance handle
+    {
+      NULL,
+      NULL,
+      NULL,
+      NULL
+    },
+    NULL,  // Shared object library handle
+    "libOmxAacEnc.so",
+    {
+      "audio_encoder.aac"
+    }
+  },
+  {
+    "OMX.qcom.audio.encoder.qcelp13",
+    NULL,   // Create instance function
+    // Unique instance handle
+    {
+      NULL,
+      NULL,
+      NULL,
+      NULL
+    },
+    NULL,   // Shared object library handle
+    "libOmxQcelp13Enc.so",
+    {
+      "audio_encoder.qcelp13"
+    }
+  },
+  {
+    "OMX.qcom.audio.encoder.evrc",
+    NULL,   // Create instance function
+    // Unique instance handle
+    {
+      NULL,
+      NULL,
+      NULL,
+      NULL
+    },
+    NULL,   // Shared object library handle
+    "libOmxEvrcEnc.so",
+    {
+      "audio_encoder.evrc"
+    }
+  },
+  {
+    "OMX.qcom.audio.encoder.amrnb",
+    NULL,   // Create instance function
+    // Unique instance handle
+    {
+      NULL,
+      NULL,
+      NULL,
+      NULL
+    },
+    NULL,   // Shared object library handle
+    "libOmxAmrEnc.so",
+    {
+      "audio_encoder.amrnb"
+    }
+  },
+ {
+    "OMX.qcom.audio.decoder.aac",
+    NULL,   // Create instance function
+    // Unique instance handle
+    {
+      NULL,
+      NULL,
+      NULL,
+      NULL
+    },
+    NULL,   // Shared object library handle
+    "libOmxAacDec.so",
+    {
+      "audio_decoder.aac"
+    }
+  },
+  {
+    "OMX.qcom.audio.decoder.multiaac",
+    NULL,   // Create instance function
+    // Unique instance handle
+    {
+      NULL,
+      NULL,
+      NULL,
+      NULL
+    },
+    NULL,   // Shared object library handle
+    "libOmxAacDec.so",
+    {
+      "audio_decoder.aac"
+    }
+  },
+  {
+    "OMX.qcom.video.postprocessing",
+    NULL, // Create instance function
+    // Unique instance handle
+    {
+      NULL,
+      NULL,
+      NULL,
+      NULL
+    },
+    NULL,   // Shared object library handle
+    "libOmxVdpp.so",
+    {
+      "videopostprocessing"
+    }
+  }
+};
+
+const unsigned int SIZE_OF_CORE = sizeof(core) / sizeof(omx_core_cb_type);
+
+
diff --git a/mm-core/src/msm8994/registry_table_android.c b/mm-core/src/msm8994/registry_table_android.c
new file mode 100644
index 0000000..449e4c9
--- /dev/null
+++ b/mm-core/src/msm8994/registry_table_android.c
@@ -0,0 +1,670 @@
+/*--------------------------------------------------------------------------
+Copyright (c) 2014, The Linux Foundation. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+    * Redistributions of source code must retain the above copyright
+      notice, this list of conditions and the following disclaimer.
+    * Redistributions in binary form must reproduce the above
+      copyright notice, this list of conditions and the following
+      disclaimer in the documentation and/or other materials provided
+      with the distribution.
+    * Neither the name of The Linux Foundation nor the names of its
+      contributors may be used to endorse or promote products derived
+      from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+--------------------------------------------------------------------------*/
+/*============================================================================
+                            O p e n M A X   w r a p p e r s
+                             O p e n  M A X   C o r e
+
+  This module contains the registry table for the QCOM's OpenMAX core.
+
+*//*========================================================================*/
+
+
+#include "qc_omx_core.h"
+
+omx_core_cb_type core[] =
+{
+  {
+    "OMX.qcom.video.decoder.avc",
+    NULL, // Create instance function
+    // Unique instance handle
+    {
+      NULL,
+      NULL,
+      NULL,
+      NULL
+    },
+    NULL,   // Shared object library handle
+    "libOmxVdec.so",
+    {
+      "video_decoder.avc"
+    }
+  },
+  {
+    "OMX.qcom.video.decoder.avc.secure",
+    NULL, // Create instance function
+    // Unique instance handle
+    {
+      NULL,
+      NULL,
+      NULL,
+      NULL
+    },
+    NULL,   // Shared object library handle
+    "libOmxVdec.so",
+    {
+      "video_decoder.avc"
+    }
+  },
+  {
+    "OMX.qcom.video.decoder.divx4",
+    NULL,   // Create instance function
+    // Unique instance handle
+    {
+      NULL,
+      NULL,
+      NULL,
+      NULL
+    },
+    NULL,   // Shared object library handle
+    "libOmxVdec.so",
+    {
+      "video_decoder.divx"
+    }
+  },
+  {
+    "OMX.qcom.video.decoder.divx",
+    NULL,   // Create instance function
+    // Unique instance handle
+    {
+      NULL,
+      NULL,
+      NULL,
+      NULL
+    },
+    NULL,   // Shared object library handle
+    "libOmxVdec.so",
+    {
+      "video_decoder.divx"
+    }
+  },
+  {
+    "OMX.qcom.video.decoder.divx311",
+    NULL,   // Create instance function
+    // Unique instance handle
+    {
+      NULL,
+      NULL,
+      NULL,
+      NULL
+    },
+    NULL,   // Shared object library handle
+    "libOmxVdec.so",
+    {
+      "video_decoder.divx"
+    }
+  },
+  {
+    "OMX.qcom.video.decoder.mpeg4",
+    NULL, // Create instance function
+    // Unique instance handle
+    {
+      NULL,
+      NULL,
+      NULL,
+      NULL
+    },
+    NULL,   // Shared object library handle
+    "libOmxVdec.so",
+    {
+      "video_decoder.mpeg4"
+    }
+  },
+  {
+    "OMX.qcom.video.decoder.mpeg2",
+    NULL, // Create instance function
+    // Unique instance handle
+    {
+      NULL,
+      NULL,
+      NULL,
+      NULL
+    },
+    NULL,   // Shared object library handle
+    "libOmxVdec.so",
+    {
+      "video_decoder.mpeg2"
+    }
+  },
+  {
+    "OMX.qcom.video.decoder.mpeg2.secure",
+    NULL, // Create instance function
+    // Unique instance handle
+    {
+      NULL,
+      NULL,
+      NULL,
+      NULL
+    },
+    NULL,   // Shared object library handle
+    "libOmxVdec.so",
+    {
+      "video_decoder.mpeg2"
+    }
+  },
+  {
+    "OMX.qcom.video.decoder.vc1",
+    NULL, // Create instance function
+    // Unique instance handle
+    {
+      NULL,
+      NULL,
+      NULL,
+      NULL
+    },
+    NULL,   // Shared object library handle
+    "libOmxVdec.so",
+    {
+      "video_decoder.vc1"
+    }
+  },
+  {
+    "OMX.qcom.video.decoder.vc1.secure",
+    NULL, // Create instance function
+    // Unique instance handle
+    {
+      NULL,
+      NULL,
+      NULL,
+      NULL
+    },
+    NULL,   // Shared object library handle
+    "libOmxVdec.so",
+    {
+      "video_decoder.vc1"
+    }
+  },
+  {
+    "OMX.qcom.video.decoder.wmv",
+    NULL, // Create instance function
+    // Unique instance handle
+    {
+      NULL,
+      NULL,
+      NULL,
+      NULL
+    },
+    NULL,   // Shared object library handle
+    "libOmxVdec.so",
+    {
+      "video_decoder.vc1"
+    }
+  },
+  {
+    "OMX.qcom.video.decoder.wmv.secure",
+    NULL, // Create instance function
+    // Unique instance handle
+    {
+      NULL,
+      NULL,
+      NULL,
+      NULL
+    },
+    NULL,   // Shared object library handle
+    "libOmxVdec.so",
+    {
+      "video_decoder.vc1"
+    }
+  },
+  {
+    "OMX.qcom.video.decoder.h263",
+    NULL, // Create instance function
+    // Unique instance handle
+    {
+      NULL,
+      NULL,
+      NULL,
+      NULL
+    },
+    NULL,   // Shared object library handle
+    "libOmxVdec.so",
+    {
+      "video_decoder.h263"
+    }
+  },
+  {
+    "OMX.qcom.video.decoder.hevc",
+    NULL,   // Create instance function
+    // Unique instance handle
+    {
+      NULL,
+      NULL,
+      NULL,
+      NULL
+    },
+    NULL,   // Shared object library handle
+    "libOmxVdec.so",
+    {
+      "video_decoder.hevc"
+    }
+  },
+  {
+    "OMX.qcom.video.decoder.hevc.secure",
+    NULL,   // Create instance function
+    // Unique instance handle
+    {
+      NULL,
+      NULL,
+      NULL,
+      NULL
+    },
+    NULL,   // Shared object library handle
+    "libOmxVdec.so",
+    {
+      "video_decoder.hevc"
+    }
+  },
+  {
+    "OMX.qcom.video.decoder.vp8",
+    NULL, // Create instance function
+    // Unique instance handle
+    {
+      NULL,
+      NULL,
+      NULL,
+      NULL
+    },
+    NULL,   // Shared object library handle
+    "libOmxVdec.so",
+    {
+      "video_decoder.vp8"
+    }
+  },
+  {
+    "OMX.qcom.video.encoder.mpeg4",
+    NULL, // Create instance function
+    // Unique instance handle
+    {
+      NULL,
+      NULL,
+      NULL,
+      NULL
+    },
+    NULL,   // Shared object library handle
+    "libOmxVenc.so",
+    {
+      "video_encoder.mpeg4"
+    }
+  },
+  {
+    "OMX.qcom.video.encoder.h263",
+    NULL, // Create instance function
+    // Unique instance handle
+    {
+      NULL,
+      NULL,
+      NULL,
+      NULL
+    },
+    NULL,   // Shared object library handle
+    "libOmxVenc.so",
+    {
+      "video_encoder.h263"
+    }
+  },
+  {
+    "OMX.qcom.video.encoder.avc",
+    NULL, // Create instance function
+    // Unique instance handle
+    {
+      NULL,
+      NULL,
+      NULL,
+      NULL
+    },
+    NULL,   // Shared object library handle
+    "libOmxVenc.so",
+    {
+      "video_encoder.avc"
+    }
+  },
+  {
+    "OMX.qcom.video.encoder.avc.secure",
+    NULL, // Create instance function
+    // Unique instance handle
+    {
+      NULL,
+      NULL,
+      NULL,
+      NULL
+    },
+    NULL,   // Shared object library handle
+    "libOmxVenc.so",
+    {
+      "video_encoder.avc"
+    }
+  },
+  {
+    "OMX.qcom.video.encoder.vp8",
+    NULL, // Create instance function
+    // Unique instance handle
+    {
+      NULL,
+      NULL,
+      NULL,
+      NULL
+    },
+    NULL,   // Shared object library handle
+    "libOmxVenc.so",
+    {
+      "video_encoder.vp8"
+    }
+  },
+  {
+    "OMX.qcom.video.encoder.hevc",
+    NULL,   // Create instance function
+    // Unique instance handle
+    {
+      NULL,
+      NULL,
+      NULL,
+      NULL
+    },
+    NULL,   // Shared object library handle
+    "libOmxVenc.so",
+    {
+      "video_encoder.hevc"
+    }
+  },
+  {
+    "OMX.qcom.video.encoder.hevc.secure",
+    NULL,   // Create instance function
+    // Unique instance handle
+    {
+      NULL,
+      NULL,
+      NULL,
+      NULL
+    },
+    NULL,   // Shared object library handle
+    "libOmxVenc.so",
+    {
+      "video_encoder.hevc"
+    }
+  },
+  {
+    "OMX.qcom.audio.decoder.Qcelp13",
+    NULL, // Create instance function
+    // Unique instance handle
+    {
+      NULL,
+      NULL,
+      NULL,
+      NULL
+    },
+    NULL,   // Shared object library handle
+    "libOmxQcelp13Dec.so",
+    {
+      "audio_decoder.Qcelp13"
+    }
+  },
+  {
+    "OMX.qcom.audio.decoder.evrc",
+    NULL, // Create instance function
+    // Unique instance handle
+    {
+      NULL,
+      NULL,
+      NULL,
+      NULL
+    },
+    NULL,   // Shared object library handle
+    "libOmxEvrcDec.so",
+    {
+      "audio_decoder.evrc"
+    }
+  },
+  {
+    "OMX.qcom.audio.decoder.wma",
+    NULL, // Create instance function
+    // Unique instance handle
+    {
+     NULL,
+     NULL,
+     NULL,
+     NULL
+    },
+    NULL,   // Shared object library handle
+    "libOmxWmaDec.so",
+    {
+     "audio_decoder.wma"
+    }
+  },
+  {
+    "OMX.qcom.audio.decoder.wma10Pro",
+    NULL,   // Create instance function
+    // Unique instance handle
+    {
+     NULL,
+     NULL,
+     NULL,
+     NULL
+    },
+    NULL,   // Shared object library handle
+    "libOmxWmaDec.so",
+    {
+     "audio_decoder.wma"
+    }
+  },
+  {
+    "OMX.qcom.audio.decoder.wmaLossLess",
+    NULL,   // Create instance function
+    // Unique instance handle
+    {
+     NULL,
+     NULL,
+     NULL,
+     NULL
+    },
+    NULL,   // Shared object library handle
+    "libOmxWmaDec.so",
+    {
+     "audio_decoder.wma"
+    }
+  },
+  {
+    "OMX.qcom.audio.decoder.amrwbplus",
+    NULL,   // Create instance function
+    // Unique instance handle
+    {
+     NULL,
+     NULL,
+     NULL,
+     NULL
+    },
+    NULL,   // Shared object library handle
+    "libOmxAmrwbplusDec.so",
+    {
+     "audio_decoder.awbplus"
+    }
+  },
+  {
+    "OMX.qcom.audio.decoder.aac",
+    NULL,   // Create instance function
+    // Unique instance handle
+    {
+      NULL,
+      NULL,
+      NULL,
+      NULL
+    },
+    NULL,   // Shared object library handle
+    "libOmxAacDec.so",
+    {
+      "audio_decoder.aac"
+    }
+  },
+  {
+    "OMX.qcom.audio.encoder.aac",
+    NULL, // Create instance function
+    // Unique instance handle
+    {
+      NULL,
+      NULL,
+      NULL,
+      NULL
+    },
+    NULL,  // Shared object library handle
+    "libOmxAacEnc.so",
+    {
+      "audio_encoder.aac"
+    }
+  },
+  {
+    "OMX.qcom.audio.encoder.qcelp13",
+    NULL,   // Create instance function
+    // Unique instance handle
+    {
+      NULL,
+      NULL,
+      NULL,
+      NULL
+    },
+    NULL,   // Shared object library handle
+    "libOmxQcelp13Enc.so",
+    {
+      "audio_encoder.qcelp13"
+    }
+  },
+  {
+    "OMX.qcom.audio.encoder.evrc",
+    NULL,   // Create instance function
+    // Unique instance handle
+    {
+      NULL,
+      NULL,
+      NULL,
+      NULL
+    },
+    NULL,   // Shared object library handle
+    "libOmxEvrcEnc.so",
+    {
+      "audio_encoder.evrc"
+    }
+  },
+  {
+    "OMX.qcom.audio.encoder.amrnb",
+    NULL,   // Create instance function
+    // Unique instance handle
+    {
+      NULL,
+      NULL,
+      NULL,
+      NULL
+    },
+    NULL,   // Shared object library handle
+    "libOmxAmrEnc.so",
+    {
+      "audio_encoder.amrnb"
+    }
+  },
+ {
+    "OMX.qcom.audio.decoder.aac",
+    NULL,   // Create instance function
+    // Unique instance handle
+    {
+      NULL,
+      NULL,
+      NULL,
+      NULL
+    },
+    NULL,   // Shared object library handle
+    "libOmxAacDec.so",
+    {
+      "audio_decoder.aac"
+    }
+  },
+ {
+    "OMX.qcom.audio.decoder.multiaac",
+    NULL,   // Create instance function
+    // Unique instance handle
+    {
+      NULL,
+      NULL,
+      NULL,
+      NULL
+    },
+    NULL,   // Shared object library handle
+    "libOmxAacDec.so",
+    {
+      "audio_decoder.aac"
+    }
+  },
+  {
+    "AIV.play.generic",
+    NULL, // Create instance function
+    // Unique instance handle
+    {
+      NULL,
+      NULL,
+      NULL,
+      NULL
+    },
+    NULL,  // Shared object library handle
+    "libAivPlay.so",
+    {
+      "AIV.play.role.generic"
+    }
+  },
+  {
+    "OMX.qcom.file.muxer",
+    NULL, // Create instance function
+    // Unique instance handle
+    {
+      NULL,
+      NULL,
+      NULL,
+      NULL
+    },
+    NULL,   // Shared object library handle
+    "libOmxMux.so",
+    {
+      "container_muxer.mp2"
+    }
+  },
+  {
+    "OMX.qcom.video.postprocessing",
+    NULL, // Create instance function
+    // Unique instance handle
+    {
+      NULL,
+      NULL,
+      NULL,
+      NULL
+    },
+    NULL,   // Shared object library handle
+    "libOmxVdpp.so",
+    {
+      "videopostprocessing"
+    }
+  }
+};
+
+const unsigned int SIZE_OF_CORE = sizeof(core) / sizeof(omx_core_cb_type);
+
+
diff --git a/mm-video-legacy/vidc/venc/inc/video_encoder_device.h b/mm-video-legacy/vidc/venc/inc/video_encoder_device.h
index fcca3ea..bacb3fc 100644
--- a/mm-video-legacy/vidc/venc/inc/video_encoder_device.h
+++ b/mm-video-legacy/vidc/venc/inc/video_encoder_device.h
@@ -65,10 +65,10 @@
   bool venc_empty_buf(void *, void *,unsigned,unsigned);
   bool venc_fill_buf(void *, void *,unsigned,unsigned);
 
-  bool venc_get_buf_req(unsigned long *,unsigned long *,
-                        unsigned long *,unsigned long);
-  bool venc_set_buf_req(unsigned long *,unsigned long *,
-                        unsigned long *,unsigned long);
+  bool venc_get_buf_req(OMX_U32 *,OMX_U32 *,
+                        OMX_U32 *,OMX_U32);
+  bool venc_set_buf_req(OMX_U32 *,OMX_U32 *,
+                        OMX_U32 *,OMX_U32);
   bool venc_set_param(void *,OMX_INDEXTYPE);
   bool venc_set_config(void *configData, OMX_INDEXTYPE index);
   bool venc_get_profile_level(OMX_U32 *eProfile,OMX_U32 *eLevel);
diff --git a/mm-video-legacy/vidc/venc/src/video_encoder_device.cpp b/mm-video-legacy/vidc/venc/src/video_encoder_device.cpp
index aed5b18..4992780 100644
--- a/mm-video-legacy/vidc/venc/src/video_encoder_device.cpp
+++ b/mm-video-legacy/vidc/venc/src/video_encoder_device.cpp
@@ -335,10 +335,10 @@
 #endif
 }
 
-bool venc_dev::venc_set_buf_req(unsigned long *min_buff_count,
-                                unsigned long *actual_buff_count,
-                                unsigned long *buff_size,
-                                unsigned long port)
+bool venc_dev::venc_set_buf_req(OMX_U32 *min_buff_count,
+                                OMX_U32 *actual_buff_count,
+                                OMX_U32 *buff_size,
+                                OMX_U32 port)
 {
   struct venc_ioctl_msg ioctl_msg = {NULL,NULL};
   unsigned long temp_count = 0;
@@ -501,10 +501,10 @@
   return true;
 }
 
-bool venc_dev::venc_get_buf_req(unsigned long *min_buff_count,
-                                unsigned long *actual_buff_count,
-                                unsigned long *buff_size,
-                                unsigned long port)
+bool venc_dev::venc_get_buf_req(OMX_U32 *min_buff_count,
+                                OMX_U32 *actual_buff_count,
+                                OMX_U32 *buff_size,
+                                OMX_U32 port)
 {
   struct venc_ioctl_msg ioctl_msg = {NULL,NULL};
 
diff --git a/mm-video-v4l2/vidc/common/src/extra_data_handler.cpp b/mm-video-v4l2/vidc/common/src/extra_data_handler.cpp
old mode 100755
new mode 100644
index d14a252..bb4cafa
--- a/mm-video-v4l2/vidc/common/src/extra_data_handler.cpp
+++ b/mm-video-v4l2/vidc/common/src/extra_data_handler.cpp
@@ -1,5 +1,5 @@
 /*--------------------------------------------------------------------------
-Copyright (c) 2010-2014, The Linux Foundation. All rights reserved.
+Copyright (c) 2010-2015, The Linux Foundation. All rights reserved.
 
 Redistribution and use in source and binary forms, with or without
 modification, are permitted provided that the following conditions are met:
@@ -28,6 +28,8 @@
 
 #include "extra_data_handler.h"
 
+int debug_level = PRIO_ERROR;
+
 extra_data_handler::extra_data_handler()
 {
     rbsp_buf = (OMX_U8 *) calloc(1,100);
diff --git a/mm-video-v4l2/vidc/vdec.mk b/mm-video-v4l2/vidc/vdec.mk
index 98ac369..5732ef5 100644
--- a/mm-video-v4l2/vidc/vdec.mk
+++ b/mm-video-v4l2/vidc/vdec.mk
@@ -70,7 +70,7 @@
 libOmxVdec-def += -D_MSM8974_
 libOmxVdec-def += -D_ION_HEAP_MASK_COMPATIBILITY_WA
 endif
-ifeq ($(TARGET_BOARD_PLATFORM),mpq8092)
+ifeq ($(TARGET_BOARD_PLATFORM),msm8992)
 libOmxVdec-def += -DMAX_RES_1080P
 libOmxVdec-def += -DMAX_RES_1080P_EBI
 libOmxVdec-def += -DPROCESS_EXTRADATA_IN_OUTPUT_PORT
@@ -118,7 +118,7 @@
 LOCAL_SRC_FILES         += vdec/src/ts_parser.cpp
 LOCAL_SRC_FILES         += vdec/src/mp4_utils.cpp
 LOCAL_SRC_FILES         += vdec/src/hevc_utils.cpp
-ifneq ($(filter msm8974 msm8610 msm8226 msm8084 mpq8092,$(TARGET_BOARD_PLATFORM)),)
+ifneq ($(filter msm8974 msm8610 msm8226 msm8084 msm8992,$(TARGET_BOARD_PLATFORM)),)
 LOCAL_SRC_FILES         += vdec/src/omx_vdec_msm8974.cpp
 else
 LOCAL_SHARED_LIBRARIES  += libhardware
@@ -143,7 +143,7 @@
 include $(CLEAR_VARS)
 LOCAL_PATH:= $(ROOT_DIR)
 
-ifneq ($(filter msm8974 msm8610 msm8084 mpq8092,$(TARGET_BOARD_PLATFORM)),)
+ifneq ($(filter msm8974 msm8610 msm8084 msm8992,$(TARGET_BOARD_PLATFORM)),)
 
 LOCAL_MODULE                    := libOmxVdecHevc
 LOCAL_MODULE_TAGS               := optional
diff --git a/mm-video-v4l2/vidc/vdec/inc/omx_vdec.h b/mm-video-v4l2/vidc/vdec/inc/omx_vdec.h
old mode 100755
new mode 100644
index 59fd836..11d67d3
--- a/mm-video-v4l2/vidc/vdec/inc/omx_vdec.h
+++ b/mm-video-v4l2/vidc/vdec/inc/omx_vdec.h
@@ -92,6 +92,7 @@
 #endif
 #include "OMX_Core.h"
 #include "OMX_QCOMExtns.h"
+#include "OMX_VideoExt.h"
 #include "qc_omx_component.h"
 #include <linux/msm_vidc_dec.h>
 #include <media/msm_vidc.h>
@@ -118,11 +119,11 @@
 class VideoHeap : public MemoryHeapBase
 {
     public:
-        VideoHeap(int devicefd, size_t size, void* base,struct ion_handle *handle,int mapfd);
+        VideoHeap(int devicefd, size_t size, void* base,ion_user_handle_t handle,int mapfd);
         virtual ~VideoHeap() {}
     private:
         int m_ion_device_fd;
-        struct ion_handle *m_ion_handle;
+        ion_user_handle_t m_ion_handle;
 };
 #else
 // local pmem heap object
@@ -153,10 +154,10 @@
         (unsigned)((OMX_BUFFERHEADERTYPE *)bufHdr)->nTimeStamp)
 
 // BitMask Management logic
-#define BITS_PER_BYTE        32
-#define BITMASK_SIZE(mIndex) (((mIndex) + BITS_PER_BYTE - 1)/BITS_PER_BYTE)
-#define BITMASK_OFFSET(mIndex) ((mIndex)/BITS_PER_BYTE)
-#define BITMASK_FLAG(mIndex) (1 << ((mIndex) % BITS_PER_BYTE))
+#define BITS_PER_INDEX        64
+#define BITMASK_SIZE(mIndex) (((mIndex) + BITS_PER_INDEX - 1)/BITS_PER_INDEX)
+#define BITMASK_OFFSET(mIndex) ((mIndex)/BITS_PER_INDEX)
+#define BITMASK_FLAG(mIndex) ((uint64_t)1 << ((mIndex) % BITS_PER_INDEX))
 #define BITMASK_CLEAR(mArray,mIndex) (mArray)[BITMASK_OFFSET(mIndex)] \
     &=  ~(BITMASK_FLAG(mIndex))
 #define BITMASK_SET(mArray,mIndex)  (mArray)[BITMASK_OFFSET(mIndex)] \
@@ -199,6 +200,7 @@
 #define OMX_FRAMEPACK_EXTRADATA 0x00400000
 #define OMX_QP_EXTRADATA        0x00800000
 #define OMX_BITSINFO_EXTRADATA  0x01000000
+#define OMX_MPEG2SEQDISP_EXTRADATA 0x02000000
 #define DRIVER_EXTRADATA_MASK   0x0000FFFF
 
 #define OMX_INTERLACE_EXTRADATA_SIZE ((sizeof(OMX_OTHER_EXTRADATATYPE) +\
@@ -215,8 +217,10 @@
             sizeof(OMX_QCOM_EXTRADATA_QP) + 3)&(~3))
 #define OMX_BITSINFO_EXTRADATA_SIZE ((sizeof(OMX_OTHER_EXTRADATATYPE) +\
             sizeof(OMX_QCOM_EXTRADATA_BITS_INFO) + 3)&(~3))
+#define OMX_MPEG2SEQDISP_EXTRADATA_SIZE ((sizeof(OMX_OTHER_EXTRADATATYPE) +\
+            sizeof(OMX_QCOM_EXTRADATA_MPEG2SEQDISPLAY) + 3)&(~3))
 #define OMX_USERDATA_EXTRADATA_SIZE ((sizeof(OMX_OTHER_EXTRADATATYPE) +\
-            ((8*1024) + 3))&(~3)) /* 8 KB is the size that driver/FW considers as worst case size for userdata */
+            + 3)&(~3))
 
 //  Define next macro with required values to enable default extradata,
 //    VDEC_EXTRADATA_MB_ERROR_MAP
@@ -256,6 +260,7 @@
     enum vdec_output_fromat output_format;
     enum vdec_interlaced_format interlace;
     enum vdec_output_order picture_order;
+    struct vdec_framesize frame_size;
     struct vdec_picsize video_resolution;
     struct vdec_allocatorproperty ip_buf;
     struct vdec_allocatorproperty op_buf;
@@ -474,7 +479,8 @@
             OMX_COMPONENT_PAUSE_PENDING          =0xB,
             OMX_COMPONENT_EXECUTE_PENDING        =0xC,
             OMX_COMPONENT_OUTPUT_FLUSH_IN_DISABLE_PENDING =0xD,
-            OMX_COMPONENT_DISABLE_OUTPUT_DEFERRED=0xE
+            OMX_COMPONENT_DISABLE_OUTPUT_DEFERRED=0xE,
+            OMX_COMPONENT_FLUSH_DEFERRED = 0xF
         };
 
         // Deferred callback identifiers
@@ -511,6 +517,7 @@
             OMX_COMPONENT_GENERATE_INFO_PORT_RECONFIG = 0x15,
             OMX_COMPONENT_GENERATE_INFO_FIELD_DROPPED = 0x16,
             OMX_COMPONENT_GENERATE_UNSUPPORTED_SETTING = 0x17,
+            OMX_COMPONENT_GENERATE_HARDWARE_OVERLOAD = 0x18,
         };
 
         enum vc1_profile_type {
@@ -688,6 +695,8 @@
                 struct msm_vidc_frame_qp_payload *qp_payload);
         void append_bitsinfo_extradata(OMX_OTHER_EXTRADATATYPE *extra,
                 struct msm_vidc_frame_bits_info_payload *bits_payload);
+        void append_mpeg2_seqdisplay_extradata(OMX_OTHER_EXTRADATATYPE *extra,
+                struct msm_vidc_mpeg2_seqdisp_payload* seq_display_payload);
         void insert_demux_addr_offset(OMX_U32 address_offset);
         void extract_demux_addr_offsets(OMX_BUFFERHEADERTYPE *buf_hdr);
         OMX_ERRORTYPE handle_demux_data(OMX_BUFFERHEADERTYPE *buf_hdr);
@@ -730,7 +739,7 @@
 
         inline void omx_report_error () {
             if (m_cb.EventHandler && !m_error_propogated) {
-                ALOGE("\nERROR: Sending OMX_EventError to Client");
+                DEBUG_PRINT_ERROR("ERROR: Sending OMX_ErrorHardware to Client");
                 m_error_propogated = true;
                 m_cb.EventHandler(&m_cmp,m_app_data,
                         OMX_EventError,OMX_ErrorHardware,0,NULL);
@@ -740,12 +749,22 @@
         inline void omx_report_unsupported_setting () {
             if (m_cb.EventHandler && !m_error_propogated) {
                 DEBUG_PRINT_ERROR(
-                        "\nERROR: Sending OMX_ErrorUnsupportedSetting to Client");
+                        "ERROR: Sending OMX_ErrorUnsupportedSetting to Client");
                 m_error_propogated = true;
                 m_cb.EventHandler(&m_cmp,m_app_data,
                         OMX_EventError,OMX_ErrorUnsupportedSetting,0,NULL);
             }
         }
+        inline void omx_report_hw_overload () {
+            if (m_cb.EventHandler && !m_error_propogated) {
+                DEBUG_PRINT_ERROR(
+                        "ERROR: Sending OMX_ErrorInsufficientResources to Client");
+                m_error_propogated = true;
+                m_cb.EventHandler(&m_cmp, m_app_data,
+                        OMX_EventError, OMX_ErrorInsufficientResources, 0, NULL);
+            }
+        }
+
 #ifdef _ANDROID_
         OMX_ERRORTYPE createDivxDrmContext();
 #endif //_ANDROID_
@@ -809,9 +828,9 @@
         int pending_input_buffers;
         int pending_output_buffers;
         // bitmask array size for output side
-        unsigned int m_out_bm_count;
+        uint64_t m_out_bm_count;
         // bitmask array size for input side
-        unsigned int m_inp_bm_count;
+        uint64_t m_inp_bm_count;
         //Input port Populated
         OMX_BOOL m_inp_bPopulated;
         //Output port Populated
@@ -933,10 +952,14 @@
         int capture_capability;
         int output_capability;
         bool streaming[MAX_PORT];
+        OMX_FRAMESIZETYPE framesize;
         OMX_CONFIG_RECTTYPE rectangle;
-        int prev_n_filled_len;
+        OMX_U32 prev_n_filled_len;
         bool is_down_scalar_enabled;
 #endif
+        struct custom_buffersize {
+            OMX_U32 input_buffersize;
+        } m_custom_buffersize;
         bool m_power_hinted;
         bool is_q6_platform;
         OMX_ERRORTYPE power_module_register();
@@ -954,6 +977,7 @@
         OMX_U32 m_smoothstreaming_width;
         OMX_U32 m_smoothstreaming_height;
         OMX_ERRORTYPE enable_smoothstreaming();
+        OMX_ERRORTYPE enable_adaptive_playback(unsigned long width, unsigned long height);
 
         unsigned int m_fill_output_msg;
         bool client_set_fps;
@@ -977,6 +1001,7 @@
                         OMX_BUFFERHEADERTYPE **bufferHdr,OMX_U32 port,OMX_PTR appData,
                         OMX_U32 bytes);
                 OMX_ERRORTYPE free_output_buffer(OMX_BUFFERHEADERTYPE *bufferHdr);
+                bool is_color_conversion_enabled() {return enabled;}
             private:
 #define MAX_COUNT 32
                 omx_vdec *omx;
@@ -1002,6 +1027,14 @@
                     sp<MemoryHeapBase>    video_heap_ptr;
                 };
                 struct vidc_heap m_heap_ptr[MAX_COUNT];
+
+                OMX_ERRORTYPE cache_ops(unsigned int index, unsigned int cmd);
+                inline OMX_ERRORTYPE cache_clean_buffer(unsigned int index) {
+                    return cache_ops(index, ION_IOC_CLEAN_CACHES);
+                }
+                OMX_ERRORTYPE cache_clean_invalidate_buffer(unsigned int index) {
+                    return cache_ops(index, ION_IOC_CLEAN_INV_CACHES);
+                }
         };
 #if  defined (_MSM8960_) || defined (_MSM8974_)
         allocate_color_convert_buf client_buffers;
@@ -1014,6 +1047,8 @@
         void send_codec_config();
 #endif
         OMX_TICKS m_last_rendered_TS;
+        volatile int32_t m_queued_codec_config_count;
+        bool secure_scaling_to_non_secure_opb;
 
         class perf_control {
             // 2 cores will be requested if framerate is beyond 45 fps
@@ -1035,19 +1070,33 @@
         };
         perf_control m_perf_control;
 
-        volatile int32_t m_queued_codec_config_count;
-        static OMX_COLOR_FORMATTYPE getColorFormatAt(OMX_U32 index) {
-            OMX_COLOR_FORMATTYPE formats[] = {
+        static OMX_COLOR_FORMATTYPE getPreferredColorFormatNonSurfaceMode(OMX_U32 index) {
+            //On Android, we default to standard YUV formats for non-surface use-cases
+            //where apps prefer known color formats.
+            OMX_COLOR_FORMATTYPE formatsNonSurfaceMode[] = {
+                [0] = OMX_COLOR_FormatYUV420SemiPlanar,
+                [1] = OMX_COLOR_FormatYUV420Planar,
+                [2] = (OMX_COLOR_FORMATTYPE)QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m,
+                [3] = (OMX_COLOR_FORMATTYPE)QOMX_COLOR_FORMATYUV420PackedSemiPlanar32mMultiView,
+            };
+            return (index < sizeof(formatsNonSurfaceMode) / sizeof(OMX_COLOR_FORMATTYPE)) ?
+                formatsNonSurfaceMode[index] : OMX_COLOR_FormatMax;
+        }
+
+        static OMX_COLOR_FORMATTYPE getPreferredColorFormatDefaultMode(OMX_U32 index) {
+            //for surface mode (normal playback), advertise native/accelerated formats first
+            OMX_COLOR_FORMATTYPE formatsDefault[] = {
                 [0] = (OMX_COLOR_FORMATTYPE)QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m,
                 [1] = OMX_COLOR_FormatYUV420SemiPlanar,
                 [2] = OMX_COLOR_FormatYUV420Planar,
                 [3] = (OMX_COLOR_FORMATTYPE)QOMX_COLOR_FORMATYUV420PackedSemiPlanar32mMultiView,
             };
-            return (index < sizeof(formats) / sizeof(OMX_COLOR_FORMATTYPE)) ?
-                formats[index] : OMX_COLOR_FormatMax;
+            return (index < sizeof(formatsDefault) / sizeof(OMX_COLOR_FORMATTYPE)) ?
+                formatsDefault[index] : OMX_COLOR_FormatMax;
         }
 
-        static OMX_ERRORTYPE describeColorFormat(DescribeColorFormatParams *params);
+        static OMX_ERRORTYPE describeColorFormat(OMX_PTR params);
+
 };
 
 #ifdef _MSM8974_
diff --git a/mm-video-v4l2/vidc/vdec/inc/ts_parser.h b/mm-video-v4l2/vidc/vdec/inc/ts_parser.h
old mode 100755
new mode 100644
index 161b64d..2d5d1a4
--- a/mm-video-v4l2/vidc/vdec/inc/ts_parser.h
+++ b/mm-video-v4l2/vidc/vdec/inc/ts_parser.h
@@ -1,5 +1,5 @@
 /*--------------------------------------------------------------------------
-Copyright (c) 2010-2012, The Linux Foundation. All rights reserved.
+Copyright (c) 2010-2015, The Linux Foundation. All rights reserved.
 
 Redistribution and use in source and binary forms, with or without
 modification, are permitted provided that the following conditions are met:
@@ -47,6 +47,21 @@
 
 class omx_time_stamp_reorder
 {
+    class auto_lock {
+        public:
+            auto_lock(pthread_mutex_t *lock)
+                : mLock(lock) {
+                    if (mLock)
+                        pthread_mutex_lock(mLock);
+                }
+            ~auto_lock() {
+                if (mLock)
+                    pthread_mutex_unlock(mLock);
+            }
+        private:
+            pthread_mutex_t *mLock;
+    };
+
     public:
         omx_time_stamp_reorder();
         ~omx_time_stamp_reorder();
@@ -86,5 +101,6 @@
         }
         bool reorder_ts;
         bool print_debug;
+        pthread_mutex_t m_lock;
 };
 #endif
diff --git a/mm-video-v4l2/vidc/vdec/src/h264_utils.cpp b/mm-video-v4l2/vidc/vdec/src/h264_utils.cpp
old mode 100755
new mode 100644
index e21d716..8eb5168
--- a/mm-video-v4l2/vidc/vdec/src/h264_utils.cpp
+++ b/mm-video-v4l2/vidc/vdec/src/h264_utils.cpp
@@ -1,5 +1,5 @@
 /*--------------------------------------------------------------------------
-Copyright (c) 2010 - 2013, The Linux Foundation. All rights reserved.
+Copyright (c) 2010 - 2015, The Linux Foundation. All rights reserved.
 
 Redistribution and use in source and binary forms, with or without
 modification, are permitted provided that the following conditions are met:
@@ -1292,7 +1292,7 @@
 void h264_stream_parser::parse_nal(OMX_U8* data_ptr, OMX_U32 data_len, OMX_U32 nal_type, bool enable_emu_sc)
 {
     OMX_U32 nal_unit_type = NALU_TYPE_UNSPECIFIED, cons_bytes = 0;
-    ALOGV("parse_nal(): IN nal_type(%lu)", nal_type);
+    ALOGV("parse_nal(): IN nal_type(%u)", nal_type);
     if (!data_len)
         return;
     init_bitstream(data_ptr, data_len);
@@ -1320,7 +1320,7 @@
             parse_vui(true);
             break;
         default:
-            ALOGV("nal_unit_type received : %lu", nal_type);
+            ALOGV("nal_unit_type received : %u", nal_type);
     }
     ALOGV("parse_nal(): OUT");
 }
diff --git a/mm-video-v4l2/vidc/vdec/src/omx_vdec_hevc.cpp b/mm-video-v4l2/vidc/vdec/src/omx_vdec_hevc.cpp
old mode 100755
new mode 100644
index 2811e3b..b82d066
--- a/mm-video-v4l2/vidc/vdec/src/omx_vdec_hevc.cpp
+++ b/mm-video-v4l2/vidc/vdec/src/omx_vdec_hevc.cpp
@@ -136,8 +136,6 @@
 
 #define DEFAULT_EXTRADATA (OMX_INTERLACE_EXTRADATA)
 
-int debug_level = PRIO_ERROR;
-
 void* async_message_thread (void *input)
 {
     OMX_BUFFERHEADERTYPE *buffer;
@@ -462,7 +460,7 @@
 #ifdef _ANDROID_
 #ifdef USE_ION
 VideoHeap::VideoHeap(int devicefd, size_t size, void* base,
-        struct ion_handle *handle, int ionMapfd)
+        ion_user_handle_t handle, int ionMapfd)
 {
     //    ionInit(devicefd, base, size, 0 , MEM_DEVICE,handle,ionMapfd);
 }
@@ -5252,6 +5250,7 @@
 OMX_ERRORTYPE  omx_vdec::fill_this_buffer(OMX_IN OMX_HANDLETYPE  hComp,
         OMX_IN OMX_BUFFERHEADERTYPE* buffer)
 {
+    unsigned nPortIndex = buffer - client_buffers.get_il_buf_hdr();
 
     if (m_state == OMX_StateInvalid) {
         DEBUG_PRINT_ERROR("FTB in Invalid State");
@@ -5264,7 +5263,9 @@
     }
 
     if (buffer == NULL ||
-            ((buffer - client_buffers.get_il_buf_hdr()) >= drv_ctx.op_buf.actualcount)) {
+            (nPortIndex >= drv_ctx.op_buf.actualcount)) {
+        DEBUG_PRINT_ERROR("FTB: ERROR: invalid buffer index,  nPortIndex %u bufCount %u",
+            nPortIndex, drv_ctx.op_buf.actualcount);
         return OMX_ErrorBadParameter;
     }
 
@@ -5305,8 +5306,11 @@
 
     nPortIndex = buffer-((OMX_BUFFERHEADERTYPE *)client_buffers.get_il_buf_hdr());
 
-    if (bufferAdd == NULL || nPortIndex > drv_ctx.op_buf.actualcount)
+    if (bufferAdd == NULL || nPortIndex > drv_ctx.op_buf.actualcount) {
+        DEBUG_PRINT_ERROR("FTBProxy: ERROR: invalid buffer index, nPortIndex %u bufCount %u",
+            nPortIndex, drv_ctx.op_buf.actualcount);
         return OMX_ErrorBadParameter;
+    }
 
     DEBUG_PRINT_LOW("FTBProxy: bufhdr = %p, bufhdr->pBuffer = %p",
             bufferAdd, bufferAdd->pBuffer);
@@ -6941,12 +6945,12 @@
         alloc_data->flags |= ION_SECURE;
 
 #ifdef _HEVC_USE_ADSP_HEAP_
-    alloc_data->ION_HEAP_MASK = ION_HEAP(ION_ADSP_HEAP_ID);
+    alloc_data->heap_id_mask = ION_HEAP(ION_ADSP_HEAP_ID);
 #else
-    alloc_data->ION_HEAP_MASK = ION_HEAP(ION_IOMMU_HEAP_ID);
+    alloc_data->heap_id_mask = ION_HEAP(ION_IOMMU_HEAP_ID);
 #endif
     if (secure_mode) {
-        alloc_data->ION_HEAP_MASK = ION_HEAP(MEM_HEAP_ID);
+        alloc_data->heap_id_mask = ION_HEAP(MEM_HEAP_ID);
     }
     rc = ioctl(fd,ION_IOC_ALLOC,alloc_data);
     if (rc || !alloc_data->handle) {
diff --git a/mm-video-v4l2/vidc/vdec/src/omx_vdec_msm8974.cpp b/mm-video-v4l2/vidc/vdec/src/omx_vdec_msm8974.cpp
old mode 100755
new mode 100644
index 4ba2158..dfb0c0a
--- a/mm-video-v4l2/vidc/vdec/src/omx_vdec_msm8974.cpp
+++ b/mm-video-v4l2/vidc/vdec/src/omx_vdec_msm8974.cpp
@@ -39,6 +39,9 @@
 //                             Include Files
 //////////////////////////////////////////////////////////////////////////////
 
+#define __STDC_FORMAT_MACROS
+#include <inttypes.h>
+
 #include <string.h>
 #include <pthread.h>
 #include <sys/prctl.h>
@@ -83,11 +86,10 @@
 
 #ifdef OUTPUT_EXTRADATA_LOG
 FILE *outputExtradataFile;
-char output_extradata_filename [] = "/data/misc/extradata";
+char output_extradata_filename [] = "/data/misc/media/extradata";
 #endif
 
 #define DEFAULT_FPS 30
-#define MAX_INPUT_ERROR DEFAULT_FPS
 #define MAX_SUPPORTED_FPS 120
 #define DEFAULT_WIDTH_ALIGNMENT 128
 #define DEFAULT_HEIGHT_ALIGNMENT 32
@@ -124,11 +126,11 @@
 #define Log2(number, power)  { OMX_U32 temp = number; power = 0; while( (0 == (temp & 0x1)) &&  power < 16) { temp >>=0x1; power++; } }
 #define Q16ToFraction(q,num,den) { OMX_U32 power; Log2(q,power);  num = q >> power; den = 0x1 << (16 - power); }
 #define EXTRADATA_IDX(__num_planes) (__num_planes  - 1)
+#define ALIGN(x, to_align) ((((unsigned) x) + (to_align - 1)) & ~(to_align - 1))
 
 #define DEFAULT_EXTRADATA (OMX_INTERLACE_EXTRADATA)
-#define DEFAULT_CONCEAL_COLOR "32896" //0x8080, black by default
+#define DEFAULT_CONCEAL_COLOR "32784" //0x8010, black by default
 
-int debug_level = PRIO_ERROR;
 
 static OMX_U32 maxSmoothStreamingWidth = 1920;
 static OMX_U32 maxSmoothStreamingHeight = 1088;
@@ -176,6 +178,8 @@
                     vdec_msg.msgdata.output_frame.framesize.top = plane[0].reserved[3];
                     vdec_msg.msgdata.output_frame.framesize.right = plane[0].reserved[4];
                     vdec_msg.msgdata.output_frame.framesize.bottom = plane[0].reserved[5];
+                    vdec_msg.msgdata.output_frame.picsize.frame_width = plane[0].reserved[6];
+                    vdec_msg.msgdata.output_frame.picsize.frame_height = plane[0].reserved[7];
                 }
                 if (omx->async_message_process(input,&vdec_msg) < 0) {
                     DEBUG_PRINT_HIGH("async_message_thread Exited");
@@ -229,6 +233,24 @@
             } else if (dqevent.type == V4L2_EVENT_MSM_VIDC_CLOSE_DONE) {
                 DEBUG_PRINT_HIGH("VIDC Close Done Recieved and async_message_thread Exited");
                 break;
+            } else if (dqevent.type == V4L2_EVENT_MSM_VIDC_HW_OVERLOAD) {
+                struct vdec_msginfo vdec_msg;
+                vdec_msg.msgcode=VDEC_MSG_EVT_HW_OVERLOAD;
+                vdec_msg.status_code=VDEC_S_SUCCESS;
+                DEBUG_PRINT_ERROR("HW Overload received");
+                if (omx->async_message_process(input,&vdec_msg) < 0) {
+                    DEBUG_PRINT_HIGH("async_message_thread Exited");
+                    break;
+                }
+            } else if (dqevent.type == V4L2_EVENT_MSM_VIDC_HW_UNSUPPORTED) {
+                struct vdec_msginfo vdec_msg;
+                vdec_msg.msgcode=VDEC_MSG_EVT_HW_UNSUPPORTED;
+                vdec_msg.status_code=VDEC_S_SUCCESS;
+                DEBUG_PRINT_ERROR("HW Unsupported received");
+                if (omx->async_message_process(input,&vdec_msg) < 0) {
+                    DEBUG_PRINT_HIGH("async_message_thread Exited");
+                    break;
+                }
             } else if (dqevent.type == V4L2_EVENT_MSM_VIDC_SYS_ERROR) {
                 struct vdec_msginfo vdec_msg;
                 vdec_msg.msgcode=VDEC_MSG_EVT_HW_ERROR;
@@ -470,7 +492,7 @@
 #ifdef _ANDROID_
 #ifdef USE_ION
 VideoHeap::VideoHeap(int devicefd, size_t size, void* base,
-        struct ion_handle *handle, int ionMapfd)
+        ion_user_handle_t handle, int ionMapfd)
 {
     (void) devicefd;
     (void) size;
@@ -505,7 +527,6 @@
     m_app_data(NULL),
     m_inp_mem_ptr(NULL),
     m_out_mem_ptr(NULL),
-    m_inp_err_count(0),
     input_flush_progress (false),
     output_flush_progress (false),
     input_use_buffer (false),
@@ -570,10 +591,11 @@
     m_profile(0),
     client_set_fps(false),
     m_last_rendered_TS(-1),
-    m_queued_codec_config_count(0)
+    m_queued_codec_config_count(0),
+    secure_scaling_to_non_secure_opb(false)
 {
     /* Assumption is that , to begin with , we have all the frames with decoder */
-    DEBUG_PRINT_HIGH("In %d bit OMX vdec Constructor", sizeof(long) * 8);
+    DEBUG_PRINT_HIGH("In %u bit OMX vdec Constructor", (unsigned int)sizeof(long) * 8);
     memset(&m_debug,0,sizeof(m_debug));
 #ifdef _ANDROID_
     char property_value[PROPERTY_VALUE_MAX] = {0};
@@ -645,6 +667,7 @@
     memset (&h264_scratch,0,sizeof (OMX_BUFFERHEADERTYPE));
     memset (m_hwdevice_name,0,sizeof(m_hwdevice_name));
     memset(m_demux_offsets, 0, ( sizeof(OMX_U32) * 8192) );
+    memset(&m_custom_buffersize, 0, sizeof(m_custom_buffersize));
     m_demux_entries = 0;
     msg_thread_id = 0;
     async_thread_id = 0;
@@ -692,7 +715,9 @@
     V4L2_EVENT_MSM_VIDC_RELEASE_BUFFER_REFERENCE,
     V4L2_EVENT_MSM_VIDC_RELEASE_UNQUEUED_BUFFER,
     V4L2_EVENT_MSM_VIDC_CLOSE_DONE,
-    V4L2_EVENT_MSM_VIDC_SYS_ERROR
+    V4L2_EVENT_MSM_VIDC_SYS_ERROR,
+    V4L2_EVENT_MSM_VIDC_HW_OVERLOAD,
+    V4L2_EVENT_MSM_VIDC_HW_UNSUPPORTED
 };
 
 static OMX_ERRORTYPE subscribe_to_events(int fd)
@@ -947,12 +972,17 @@
                         pThis->omx_report_error ();
                     }
                     break;
-                case OMX_COMPONENT_GENERATE_ETB:
-                    if (pThis->empty_this_buffer_proxy((OMX_HANDLETYPE)(intptr_t)p1,\
-                                (OMX_BUFFERHEADERTYPE *)(intptr_t)p2) != OMX_ErrorNone) {
+                case OMX_COMPONENT_GENERATE_ETB: {
+                        OMX_ERRORTYPE iret;
+                        iret = pThis->empty_this_buffer_proxy((OMX_HANDLETYPE)p1, (OMX_BUFFERHEADERTYPE *)p2);
+                        if (iret == OMX_ErrorInsufficientResources) {
+                            DEBUG_PRINT_ERROR("empty_this_buffer_proxy failure due to HW overload");
+                            pThis->omx_report_hw_overload ();
+                        } else if (iret != OMX_ErrorNone) {
                         DEBUG_PRINT_ERROR("empty_this_buffer_proxy failure");
                         pThis->omx_report_error ();
                     }
+                    }
                     break;
 
                 case OMX_COMPONENT_GENERATE_FTB:
@@ -975,23 +1005,16 @@
                         pThis->omx_report_error ();
                     } else {
                         if (p2 == VDEC_S_INPUT_BITSTREAM_ERR && p1) {
-                            pThis->m_inp_err_count++;
                             pThis->time_stamp_dts.remove_time_stamp(
                                     ((OMX_BUFFERHEADERTYPE *)(intptr_t)p1)->nTimeStamp,
                                     (pThis->drv_ctx.interlace != VDEC_InterlaceFrameProgressive)
                                     ?true:false);
-                        } else {
-                            pThis->m_inp_err_count = 0;
                         }
                         if ( pThis->empty_buffer_done(&pThis->m_cmp,
                                     (OMX_BUFFERHEADERTYPE *)(intptr_t)p1) != OMX_ErrorNone) {
                             DEBUG_PRINT_ERROR("empty_buffer_done failure");
                             pThis->omx_report_error ();
                         }
-                        if (pThis->m_inp_err_count >= MAX_INPUT_ERROR) {
-                            DEBUG_PRINT_ERROR("Input bitstream error for consecutive %d frames.", MAX_INPUT_ERROR);
-                            pThis->omx_report_error ();
-                        }
                     }
                     break;
                 case OMX_COMPONENT_GENERATE_INFO_FIELD_DROPPED: {
@@ -1218,10 +1241,87 @@
                                         break;
 
                 case OMX_COMPONENT_GENERATE_PORT_RECONFIG:
-                                        DEBUG_PRINT_HIGH("Rxd OMX_COMPONENT_GENERATE_PORT_RECONFIG");
-
                                         if (p2 == OMX_IndexParamPortDefinition) {
+                                            DEBUG_PRINT_HIGH("Rxd PORT_RECONFIG: OMX_IndexParamPortDefinition");
                                             pThis->in_reconfig = true;
+
+                                        }  else if (p2 == OMX_IndexConfigCommonOutputCrop) {
+                                            DEBUG_PRINT_HIGH("Rxd PORT_RECONFIG: OMX_IndexConfigCommonOutputCrop");
+
+                                            /* Check if resolution is changed in smooth streaming mode */
+                                            if (pThis->m_smoothstreaming_mode &&
+                                                (pThis->framesize.nWidth !=
+                                                    pThis->drv_ctx.video_resolution.frame_width) ||
+                                                (pThis->framesize.nHeight !=
+                                                    pThis->drv_ctx.video_resolution.frame_height)) {
+
+                                                DEBUG_PRINT_HIGH("Resolution changed from: wxh = %dx%d to: wxh = %dx%d",
+                                                        pThis->framesize.nWidth,
+                                                        pThis->framesize.nHeight,
+                                                        pThis->drv_ctx.video_resolution.frame_width,
+                                                        pThis->drv_ctx.video_resolution.frame_height);
+
+                                                /* Update new resolution */
+                                                pThis->framesize.nWidth =
+                                                       pThis->drv_ctx.video_resolution.frame_width;
+                                                pThis->framesize.nHeight =
+                                                       pThis->drv_ctx.video_resolution.frame_height;
+
+                                                /* Update C2D with new resolution */
+                                                if (!pThis->client_buffers.update_buffer_req()) {
+                                                    DEBUG_PRINT_ERROR("Setting C2D buffer requirements failed");
+                                                }
+                                            }
+
+                                            /* Update new crop information */
+                                            pThis->rectangle.nLeft = pThis->drv_ctx.frame_size.left;
+                                            pThis->rectangle.nTop = pThis->drv_ctx.frame_size.top;
+                                            pThis->rectangle.nWidth = pThis->drv_ctx.frame_size.right;
+                                            pThis->rectangle.nHeight = pThis->drv_ctx.frame_size.bottom;
+
+                                            /* Validate the new crop information */
+                                            if (pThis->rectangle.nLeft + pThis->rectangle.nWidth >
+                                                pThis->drv_ctx.video_resolution.frame_width) {
+
+                                                DEBUG_PRINT_HIGH("Crop L[%u] + R[%u] > W[%u]",
+                                                        pThis->rectangle.nLeft, pThis->rectangle.nWidth,
+                                                        pThis->drv_ctx.video_resolution.frame_width);
+                                                pThis->rectangle.nLeft = 0;
+
+                                                if (pThis->rectangle.nWidth >
+                                                    pThis->drv_ctx.video_resolution.frame_width) {
+
+                                                    DEBUG_PRINT_HIGH("Crop R[%u] > W[%u]",
+                                                            pThis->rectangle.nWidth,
+                                                            pThis->drv_ctx.video_resolution.frame_width);
+                                                    pThis->rectangle.nWidth =
+                                                        pThis->drv_ctx.video_resolution.frame_width;
+                                                }
+                                            }
+                                            if (pThis->rectangle.nTop + pThis->rectangle.nHeight >
+                                                pThis->drv_ctx.video_resolution.frame_height) {
+
+                                                DEBUG_PRINT_HIGH("Crop T[%u] + B[%u] > H[%u]",
+                                                    pThis->rectangle.nTop, pThis->rectangle.nHeight,
+                                                    pThis->drv_ctx.video_resolution.frame_height);
+                                                pThis->rectangle.nTop = 0;
+
+                                                if (pThis->rectangle.nHeight >
+                                                    pThis->drv_ctx.video_resolution.frame_height) {
+
+                                                    DEBUG_PRINT_HIGH("Crop B[%u] > H[%u]",
+                                                        pThis->rectangle.nHeight,
+                                                        pThis->drv_ctx.video_resolution.frame_height);
+                                                    pThis->rectangle.nHeight =
+                                                        pThis->drv_ctx.video_resolution.frame_height;
+                                                }
+                                            }
+                                            DEBUG_PRINT_HIGH("Updated Crop Info: L: %u, T: %u, R: %u, B: %u",
+                                                    pThis->rectangle.nLeft, pThis->rectangle.nTop,
+                                                    pThis->rectangle.nWidth, pThis->rectangle.nHeight);
+                                        } else {
+                                            DEBUG_PRINT_ERROR("Rxd Invalid PORT_RECONFIG event (%lu)", p2);
+                                            break;
                                         }
                                         if (pThis->m_cb.EventHandler) {
                                             pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
@@ -1254,6 +1354,11 @@
                                         pThis->omx_report_unsupported_setting();
                                         break;
 
+                case OMX_COMPONENT_GENERATE_HARDWARE_OVERLOAD:
+                                        DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_HARDWARE_OVERLOAD");
+                                        pThis->omx_report_hw_overload();
+                                        break;
+
                 default:
                                         break;
             }
@@ -1281,10 +1386,12 @@
     drv_ctx.video_resolution.frame_width = width;
     drv_ctx.video_resolution.scan_lines = scan_lines;
     drv_ctx.video_resolution.stride = stride;
+    if(!is_down_scalar_enabled) {
     rectangle.nLeft = 0;
     rectangle.nTop = 0;
     rectangle.nWidth = drv_ctx.video_resolution.frame_width;
     rectangle.nHeight = drv_ctx.video_resolution.frame_height;
+    }
     return format_changed;
 }
 
@@ -1338,6 +1445,10 @@
                 sprintf(m_debug.infile_name, "%s/input_dec_%d_%d_%p.264",
                         m_debug.log_loc, drv_ctx.video_resolution.frame_width, drv_ctx.video_resolution.frame_height, this);
         }
+        else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.hevc", OMX_MAX_STRINGNAME_SIZE)) {
+                sprintf(m_debug.infile_name, "%s/input_dec_%d_%d_%p.265",
+                        m_debug.log_loc, drv_ctx.video_resolution.frame_width, drv_ctx.video_resolution.frame_height, this);
+        }
         else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vc1", OMX_MAX_STRINGNAME_SIZE)) {
                 sprintf(m_debug.infile_name, "%s/input_dec_%d_%d_%p.vc1",
                         m_debug.log_loc, drv_ctx.video_resolution.frame_width, drv_ctx.video_resolution.frame_height, this);
@@ -1350,6 +1461,10 @@
                 sprintf(m_debug.infile_name, "%s/input_dec_%d_%d_%p.ivf",
                         m_debug.log_loc, drv_ctx.video_resolution.frame_width, drv_ctx.video_resolution.frame_height, this);
         }
+        else {
+               sprintf(m_debug.infile_name, "%s/input_dec_%d_%d_%p.divx",
+                        m_debug.log_loc, drv_ctx.video_resolution.frame_width, drv_ctx.video_resolution.frame_height, this);
+        }
         m_debug.infile = fopen (m_debug.infile_name, "ab");
         if (!m_debug.infile) {
             DEBUG_PRINT_HIGH("Failed to open input file: %s for logging", m_debug.infile_name);
@@ -1402,7 +1517,7 @@
 }
 
 int omx_vdec::log_output_buffers(OMX_BUFFERHEADERTYPE *buffer) {
-    if (m_debug.out_buffer_log && !m_debug.outfile) {
+    if (m_debug.out_buffer_log && !m_debug.outfile && buffer->nFilledLen) {
         sprintf(m_debug.outfile_name, "%s/output_%d_%d_%p.yuv",
                 m_debug.log_loc, drv_ctx.video_resolution.frame_width, drv_ctx.video_resolution.frame_height, this);
         m_debug.outfile = fopen (m_debug.outfile_name, "ab");
@@ -1473,7 +1588,7 @@
     int fds[2];
     int r,ret=0;
     bool codec_ambiguous = false;
-    OMX_STRING device_name = (OMX_STRING)"/dev/video/venus_dec";
+    OMX_STRING device_name = (OMX_STRING)"/dev/video32";
     char property_value[PROPERTY_VALUE_MAX] = {0};
 
 #ifdef _ANDROID_
@@ -1493,10 +1608,15 @@
      * Clients may configure OMX_QCOM_FramePacking_Arbitrary to enable this mode
      */
     arbitrary_bytes = false;
+    property_get("vidc.dec.debug.arbitrarybytes.mode", property_value, "0");
+    if (atoi(property_value)) {
+        DEBUG_PRINT_HIGH("arbitrary_bytes mode enabled via property command");
+        arbitrary_bytes = true;
+    }
 #endif
 
-    if (!strncmp(role, "OMX.qcom.video.decoder.avc.secure",OMX_MAX_STRINGNAME_SIZE)) {
-        struct v4l2_control control;
+    if (!strncmp(role, "OMX.qcom.video.decoder.avc.secure",
+                OMX_MAX_STRINGNAME_SIZE)) {
         secure_mode = true;
         arbitrary_bytes = false;
         role = (OMX_STRING)"OMX.qcom.video.decoder.avc";
@@ -1505,6 +1625,26 @@
         secure_mode = true;
         arbitrary_bytes = false;
         role = (OMX_STRING)"OMX.qcom.video.decoder.mpeg2";
+    } else if (!strncmp(role, "OMX.qcom.video.decoder.hevc.secure",
+                OMX_MAX_STRINGNAME_SIZE)) {
+        secure_mode = true;
+        arbitrary_bytes = false;
+        role = (OMX_STRING)"OMX.qcom.video.decoder.hevc";
+    } else if (!strncmp(role, "OMX.qcom.video.decoder.vc1.secure",
+                OMX_MAX_STRINGNAME_SIZE)) {
+        secure_mode = true;
+        arbitrary_bytes = false;
+        role = (OMX_STRING)"OMX.qcom.video.decoder.vc1";
+    } else if (!strncmp(role, "OMX.qcom.video.decoder.wmv.secure",
+                OMX_MAX_STRINGNAME_SIZE)) {
+        secure_mode = true;
+        arbitrary_bytes = false;
+        role = (OMX_STRING)"OMX.qcom.video.decoder.wmv";
+    } else if (!strncmp(role, "OMX.qcom.video.decoder.mpeg4.secure",
+                OMX_MAX_STRINGNAME_SIZE)) {
+        secure_mode = true;
+        arbitrary_bytes = false;
+        role = (OMX_STRING)"OMX.qcom.video.decoder.mpeg4";
     }
 
     drv_ctx.video_driver_fd = open(device_name, O_RDWR);
@@ -1643,7 +1783,7 @@
         strlcpy((char *)m_cRole, "video_decoder.hevc",OMX_MAX_STRINGNAME_SIZE);
         drv_ctx.decoder_format = VDEC_CODECTYPE_HEVC;
         output_capability = V4L2_PIX_FMT_HEVC;
-        eCompressionFormat = OMX_VIDEO_CodingHEVC;
+        eCompressionFormat = (OMX_VIDEO_CODINGTYPE)QOMX_VIDEO_CodingHevc;
         codec_type_parse = CODEC_TYPE_HEVC;
         m_frame_parser.init_start_codes(codec_type_parse);
         m_frame_parser.init_nal_length(nal_length);
@@ -1779,6 +1919,7 @@
             m_decoder_capability.max_height = frmsize.stepwise.max_height;
         }
 
+        memset(&fmt, 0x0, sizeof(struct v4l2_format));
         fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
         fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
         fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
@@ -1788,6 +1929,14 @@
             /*TODO: How to handle this case */
             DEBUG_PRINT_ERROR("Failed to set format on capture port");
         }
+        memset(&framesize, 0, sizeof(OMX_FRAMESIZETYPE));
+        framesize.nWidth = drv_ctx.video_resolution.frame_width;
+        framesize.nHeight = drv_ctx.video_resolution.frame_height;
+
+        memset(&rectangle, 0, sizeof(OMX_CONFIG_RECTTYPE));
+        rectangle.nWidth = drv_ctx.video_resolution.frame_width;
+        rectangle.nHeight = drv_ctx.video_resolution.frame_height;
+
         DEBUG_PRINT_HIGH("Set Format was successful");
         if (secure_mode) {
             control.id = V4L2_CID_MPEG_VIDC_VIDEO_SECURE;
@@ -1827,6 +1976,16 @@
         ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control);
         drv_ctx.idr_only_decoding = 0;
 
+        property_get("vidc.debug.turbo", property_value, "0");
+        if (atoi(property_value)) {
+            DEBUG_PRINT_HIGH("Turbo mode debug property enabled");
+            control.id = V4L2_CID_MPEG_VIDC_SET_PERF_LEVEL;
+            control.value = V4L2_CID_MPEG_VIDC_PERF_LEVEL_TURBO;
+            if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
+                DEBUG_PRINT_ERROR("Failed to set turbo mode");
+            }
+        }
+
         m_state = OMX_StateLoaded;
 #ifdef DEFAULT_EXTRADATA
         if (strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8",
@@ -1835,7 +1994,7 @@
                 enable_extradata(DEFAULT_EXTRADATA, true, true);
 #endif
         eRet=get_buffer_req(&drv_ctx.ip_buf);
-        DEBUG_PRINT_HIGH("Input Buffer Size =%d",drv_ctx.ip_buf.buffer_size);
+        DEBUG_PRINT_HIGH("Input Buffer Size =%u",(unsigned int)drv_ctx.ip_buf.buffer_size);
         get_buffer_req(&drv_ctx.op_buf);
         if (drv_ctx.decoder_format == VDEC_CODECTYPE_H264 ||
                 drv_ctx.decoder_format == VDEC_CODECTYPE_HEVC ||
@@ -1977,18 +2136,6 @@
         DEBUG_PRINT_ERROR("send_command(): ERROR OMX_CommandFlush "
                 "to invalid port: %u", (unsigned int)param1);
         return OMX_ErrorBadPortIndex;
-    } else if (cmd == OMX_CommandFlush && (param1 == OMX_CORE_INPUT_PORT_INDEX ||
-                param1 == OMX_ALL)) {
-        while (android_atomic_add(0, &m_queued_codec_config_count) > 0) {
-            struct timespec ts;
-
-            clock_gettime(CLOCK_REALTIME, &ts);
-            ts.tv_sec += 2;
-            if (sem_timedwait(&m_safe_flush, &ts)) {
-                DEBUG_PRINT_ERROR("Failed to wait for EBDs of CODEC CONFIG buffers");
-                break;
-            }
-        }
     }
 
     post_event((unsigned)cmd,(unsigned)param1,OMX_COMPONENT_GENERATE_COMMAND);
@@ -2325,6 +2472,23 @@
 #ifdef _MSM8974_
         send_codec_config();
 #endif
+        if (cmd == OMX_CommandFlush && (param1 == OMX_CORE_INPUT_PORT_INDEX ||
+                    param1 == OMX_ALL)) {
+            if (android_atomic_add(0, &m_queued_codec_config_count) > 0) {
+               struct timespec ts;
+
+               clock_gettime(CLOCK_REALTIME, &ts);
+               ts.tv_sec += 2;
+               DEBUG_PRINT_LOW("waiting for %d EBDs of CODEC CONFIG buffers ",
+                       m_queued_codec_config_count);
+               BITMASK_SET(&m_flags, OMX_COMPONENT_FLUSH_DEFERRED);
+               if (sem_timedwait(&m_safe_flush, &ts)) {
+                   DEBUG_PRINT_ERROR("Failed to wait for EBDs of CODEC CONFIG buffers");
+               }
+               BITMASK_CLEAR (&m_flags,OMX_COMPONENT_FLUSH_DEFERRED);
+            }
+        }
+
         if (OMX_CORE_INPUT_PORT_INDEX == param1 || OMX_ALL == param1) {
             BITMASK_SET(&m_flags, OMX_COMPONENT_INPUT_FLUSH_PENDING);
         }
@@ -2646,11 +2810,26 @@
 {
     bool bRet = false;
 
+    /* Just drop messages typically generated by hardware (w/o client request),
+     * if we've reported an error to client. */
+    if (m_error_propogated) {
+        switch (id) {
+            case OMX_COMPONENT_GENERATE_PORT_RECONFIG:
+            case OMX_COMPONENT_GENERATE_HARDWARE_ERROR:
+                DEBUG_PRINT_ERROR("Dropping message %lx "
+                        "since client expected to be in error state", id);
+                return false;
+            default:
+                /* whatever */
+                break;
+        }
+    }
 
     pthread_mutex_lock(&m_lock);
 
     if (id == m_fill_output_msg ||
-            id == OMX_COMPONENT_GENERATE_FBD) {
+            id == OMX_COMPONENT_GENERATE_FBD ||
+            id == OMX_COMPONENT_GENERATE_PORT_RECONFIG) {
         m_ftb_q.insert_entry(p1,p2,id);
     } else if (id == OMX_COMPONENT_GENERATE_ETB ||
             id == OMX_COMPONENT_GENERATE_EBD ||
@@ -2702,9 +2881,14 @@
                 eRet = OMX_ErrorNoMore;
             }
         } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.hevc", OMX_MAX_STRINGNAME_SIZE)) {
+            if (profileLevelType->nProfileIndex == 0) {
+                profileLevelType->eProfile = OMX_VIDEO_HEVCProfileMain;
+                profileLevelType->eLevel   = OMX_VIDEO_HEVCMainTierLevel51;
+            } else {
                 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %u",
                         (unsigned int)profileLevelType->nProfileIndex);
                 eRet = OMX_ErrorNoMore;
+            }
         } else if ((!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.h263",OMX_MAX_STRINGNAME_SIZE))) {
             if (profileLevelType->nProfileIndex == 0) {
                 profileLevelType->eProfile = OMX_VIDEO_H263ProfileBaseline;
@@ -2822,7 +3006,19 @@
                                     }
                                 } else if (1 == portFmt->nPortIndex) {
                                     portFmt->eCompressionFormat =  OMX_VIDEO_CodingUnused;
-                                    portFmt->eColorFormat = getColorFormatAt(portFmt->nIndex);
+
+                                    // Distinguish non-surface mode from normal playback use-case based on
+                                    // usage hinted via "OMX.google.android.index.useAndroidNativeBuffer2"
+                                    // For non-android, use the default list
+                                    // Also use default format-list if FLEXIBLE YUV is supported,
+                                    // as the client negotiates the standard color-format if it needs to
+                                    bool useNonSurfaceMode = false;
+#if defined(_ANDROID_) && !defined(FLEXYUV_SUPPORTED)
+                                    useNonSurfaceMode = (m_enable_android_native_buffers == OMX_FALSE);
+#endif
+                                    portFmt->eColorFormat = useNonSurfaceMode ?
+                                        getPreferredColorFormatNonSurfaceMode(portFmt->nIndex) :
+                                        getPreferredColorFormatDefaultMode(portFmt->nIndex);
 
                                     if (portFmt->eColorFormat == OMX_COLOR_FormatMax ) {
                                         eRet = OMX_ErrorNoMore;
@@ -2946,7 +3142,7 @@
                                         GetAndroidNativeBufferUsageParams* nativeBuffersUsage = (GetAndroidNativeBufferUsageParams *) paramData;
                                         if (nativeBuffersUsage->nPortIndex == OMX_CORE_OUTPUT_PORT_INDEX) {
 
-                                            if (secure_mode) {
+                                            if (secure_mode && !secure_scaling_to_non_secure_opb) {
                                                 nativeBuffersUsage->nUsage = (GRALLOC_USAGE_PRIVATE_MM_HEAP | GRALLOC_USAGE_PROTECTED |
                                                         GRALLOC_USAGE_PRIVATE_UNCACHED);
                                             } else {
@@ -2961,11 +3157,15 @@
                                     }
                                     break;
 #endif
+
+#ifdef FLEXYUV_SUPPORTED
         case OMX_QcomIndexFlexibleYUVDescription: {
                 DEBUG_PRINT_LOW("get_parameter: describeColorFormat");
-                eRet = describeColorFormat((DescribeColorFormatParams *)paramData);
+                eRet = describeColorFormat(paramData);
                 break;
             }
+#endif
+
         default: {
                  DEBUG_PRINT_ERROR("get_parameter: unknown param %08x", paramIndex);
                  eRet =OMX_ErrorUnsupportedIndex;
@@ -3050,6 +3250,9 @@
     OMX_ERRORTYPE eRet = OMX_ErrorNone;
     int ret=0;
     struct v4l2_format fmt;
+#ifdef _ANDROID_
+    char property_value[PROPERTY_VALUE_MAX] = {0};
+#endif
     if (m_state == OMX_StateInvalid) {
         DEBUG_PRINT_ERROR("Set Param in Invalid State");
         return OMX_ErrorInvalidState;
@@ -3077,6 +3280,7 @@
                                        (int)portDefn->format.video.nFrameWidth);
                                if (OMX_DirOutput == portDefn->eDir) {
                                    DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamPortDefinition OP port");
+                                   bool port_format_changed = false;
                                    m_display_id = portDefn->format.video.pNativeWindow;
                                    unsigned int buffer_size;
                                    /* update output port resolution with client supplied dimensions
@@ -3088,13 +3292,34 @@
                                                (unsigned int)portDefn->format.video.nFrameHeight);
                                        if (portDefn->format.video.nFrameHeight != 0x0 &&
                                                portDefn->format.video.nFrameWidth != 0x0) {
+                                           memset(&fmt, 0x0, sizeof(struct v4l2_format));
+                                           fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
+                                           fmt.fmt.pix_mp.pixelformat = capture_capability;
+                                           ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_G_FMT, &fmt);
+                                           if (ret) {
+                                               DEBUG_PRINT_ERROR("Get Resolution failed");
+                                               eRet = OMX_ErrorHardware;
+                                               break;
+                                           }
+                                           if ((portDefn->format.video.nFrameHeight != (unsigned int)fmt.fmt.pix_mp.height) ||
+                                               (portDefn->format.video.nFrameWidth != (unsigned int)fmt.fmt.pix_mp.width)) {
+                                                   port_format_changed = true;
+                                           }
                                            update_resolution(portDefn->format.video.nFrameWidth,
                                                    portDefn->format.video.nFrameHeight,
                                                    portDefn->format.video.nFrameWidth,
                                                    portDefn->format.video.nFrameHeight);
+
+                                           /* set crop info */
+                                           rectangle.nLeft = 0;
+                                           rectangle.nTop = 0;
+                                           rectangle.nWidth = portDefn->format.video.nFrameWidth;
+                                           rectangle.nHeight = portDefn->format.video.nFrameHeight;
+
                                            eRet = is_video_session_supported();
                                            if (eRet)
                                                break;
+                                           memset(&fmt, 0x0, sizeof(struct v4l2_format));
                                            fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
                                            fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
                                            fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
@@ -3108,11 +3333,56 @@
                                            } else
                                                eRet = get_buffer_req(&drv_ctx.op_buf);
                                        }
+
+                                       if (eRet) {
+                                           break;
+                                       }
+
+                                       if (secure_mode) {
+                                           struct v4l2_control control;
+                                           control.id = V4L2_CID_MPEG_VIDC_VIDEO_SECURE_SCALING_THRESHOLD;
+                                           if (ioctl(drv_ctx.video_driver_fd, VIDIOC_G_CTRL, &control) < 0) {
+                                               DEBUG_PRINT_ERROR("Failed getting secure scaling threshold : %d, id was : %x", errno, control.id);
+                                               eRet = OMX_ErrorHardware;
+                                           } else {
+                                               /* This is a workaround for a bug in fw which uses stride
+                                                * and slice instead of width and height to check against
+                                                * the threshold.
+                                                */
+                                               OMX_U32 stride, slice;
+                                               if (drv_ctx.output_format == VDEC_YUV_FORMAT_NV12) {
+                                                   stride = VENUS_Y_STRIDE(COLOR_FMT_NV12, portDefn->format.video.nFrameWidth);
+                                                   slice = VENUS_Y_SCANLINES(COLOR_FMT_NV12, portDefn->format.video.nFrameHeight);
+                                               } else {
+                                                   stride = portDefn->format.video.nFrameWidth;
+                                                   slice = portDefn->format.video.nFrameHeight;
+                                               }
+
+                                               DEBUG_PRINT_LOW("Stride is %d, slice is %d, sxs is %d\n", stride, slice, stride * slice);
+                                               DEBUG_PRINT_LOW("Threshold value is %d\n", control.value);
+
+                                               if (stride * slice <= (OMX_U32)control.value) {
+                                                   secure_scaling_to_non_secure_opb = true;
+                                                   DEBUG_PRINT_HIGH("Enabling secure scalar out of CPZ");
+                                                   control.id = V4L2_CID_MPEG_VIDC_VIDEO_NON_SECURE_OUTPUT2;
+                                                   control.value = 1;
+                                                   if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control) < 0) {
+                                                       DEBUG_PRINT_ERROR("Enabling non-secure output2 failed");
+                                                       eRet = OMX_ErrorUnsupportedSetting;
+                                                   }
                                    }
+                                           }
+                                       }
+                                   }
+
+                                   if (eRet) {
+                                       break;
+                                   }
+
                                    if (!client_buffers.get_buffer_req(buffer_size)) {
                                        DEBUG_PRINT_ERROR("Error in getting buffer requirements");
                                        eRet = OMX_ErrorBadParameter;
-                                   } else {
+                                   } else if (!port_format_changed) {
                                        if ( portDefn->nBufferCountActual >= drv_ctx.op_buf.mincount &&
                                                portDefn->nBufferSize >=  drv_ctx.op_buf.buffer_size ) {
                                            drv_ctx.op_buf.actualcount = portDefn->nBufferCountActual;
@@ -3125,7 +3395,7 @@
                                                m_port_def = *portDefn;
                                        } else {
                                            DEBUG_PRINT_ERROR("ERROR: OP Requirements(#%d: %u) Requested(#%u: %u)",
-                                                   drv_ctx.op_buf.mincount, drv_ctx.op_buf.buffer_size,
+                                                   drv_ctx.op_buf.mincount, (unsigned int)drv_ctx.op_buf.buffer_size,
                                                    (unsigned int)portDefn->nBufferCountActual, (unsigned int)portDefn->nBufferSize);
                                            eRet = OMX_ErrorBadParameter;
                                        }
@@ -3170,7 +3440,7 @@
                                            eRet = OMX_ErrorHardware;
                                            break;
                                    }
-                                       m_perf_control.request_cores(frm_int);
+                                       //m_perf_control.request_cores(frm_int);
                                    }
 
                                    if (drv_ctx.video_resolution.frame_height !=
@@ -3198,6 +3468,7 @@
                                            eRet = is_video_session_supported();
                                            if (eRet)
                                                break;
+                                           memset(&fmt, 0x0, sizeof(struct v4l2_format));
                                            fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
                                            fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
                                            fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
@@ -3207,10 +3478,19 @@
                                            if (ret) {
                                                DEBUG_PRINT_ERROR("Set Resolution failed");
                                                eRet = OMX_ErrorUnsupportedSetting;
-                                           } else
+                                           } else {
+                                               if (!is_down_scalar_enabled)
                                                eRet = get_buffer_req(&drv_ctx.op_buf);
                                        }
                                    }
+                                   }
+                                   if (m_custom_buffersize.input_buffersize
+                                        && (portDefn->nBufferSize > m_custom_buffersize.input_buffersize)) {
+                                       DEBUG_PRINT_ERROR("ERROR: Custom buffer size set by client: %d, trying to set: %d",
+                                               m_custom_buffersize.input_buffersize, portDefn->nBufferSize);
+                                       eRet = OMX_ErrorBadParameter;
+                                       break;
+                                   }
                                    if (portDefn->nBufferCountActual >= drv_ctx.ip_buf.mincount
                                            || portDefn->nBufferSize != drv_ctx.ip_buf.buffer_size) {
                                        port_format_changed = true;
@@ -3222,7 +3502,7 @@
                                    }
                                    if (false == port_format_changed) {
                                        DEBUG_PRINT_ERROR("ERROR: IP Requirements(#%d: %u) Requested(#%u: %u)",
-                                               drv_ctx.ip_buf.mincount, drv_ctx.ip_buf.buffer_size,
+                                               drv_ctx.ip_buf.mincount, (unsigned int)drv_ctx.ip_buf.buffer_size,
                                                (unsigned int)portDefn->nBufferCountActual, (unsigned int)portDefn->nBufferSize);
                                        eRet = OMX_ErrorBadParameter;
                                    }
@@ -3241,6 +3521,7 @@
                                 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoPortFormat 0x%x, port: %u",
                                         portFmt->eColorFormat, (unsigned int)portFmt->nPortIndex);
 
+                                memset(&fmt, 0x0, sizeof(struct v4l2_format));
                                 if (1 == portFmt->nPortIndex) {
                                     fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
                                     fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
@@ -3297,6 +3578,13 @@
                                 } else if (portFmt->nFramePackingFormat ==
                                         OMX_QCOM_FramePacking_OnlyOneCompleteFrame) {
                                     arbitrary_bytes = false;
+#ifdef _ANDROID_
+                                    property_get("vidc.dec.debug.arbitrarybytes.mode", property_value, "0");
+                                    if (atoi(property_value)) {
+                                        DEBUG_PRINT_HIGH("arbitrary_bytes enabled via property command");
+                                        arbitrary_bytes = true;
+                                    }
+#endif
                                 } else {
                                     DEBUG_PRINT_ERROR("Setparameter: unknown FramePacking format %u",
                                             (unsigned int)portFmt->nFramePackingFormat);
@@ -3525,6 +3813,10 @@
                                 eRet = enable_extradata(OMX_EXTNUSER_EXTRADATA, false,
                                     ((QOMX_ENABLETYPE *)paramData)->bEnable);
                                break;
+        case OMX_QcomIndexParamMpeg2SeqDispExtraData:
+                                eRet = enable_extradata(OMX_MPEG2SEQDISP_EXTRADATA, false,
+                                    ((QOMX_ENABLETYPE *)paramData)->bEnable);
+                                break;
         case OMX_QcomIndexParamVideoDivx: {
                               QOMX_VIDEO_PARAM_DIVXTYPE* divXType = (QOMX_VIDEO_PARAM_DIVXTYPE *) paramData;
                           }
@@ -3607,6 +3899,15 @@
                                            if (enableNativeBuffers) {
                                                m_enable_android_native_buffers = enableNativeBuffers->enable;
                                            }
+#if !defined(FLEXYUV_SUPPORTED)
+                                           if (m_enable_android_native_buffers) {
+                                               // Use the most-preferred-native-color-format as surface-mode is hinted here
+                                               if(!client_buffers.set_color_format(getPreferredColorFormatDefaultMode(0))) {
+                                                   DEBUG_PRINT_ERROR("Failed to set native color format!");
+                                                   eRet = OMX_ErrorUnsupportedSetting;
+                                               }
+                                           }
+#endif
                                        }
                                        break;
         case OMX_GoogleAndroidIndexUseAndroidNativeBuffer: {
@@ -3727,36 +4028,7 @@
                              (unsigned int)maxSmoothStreamingWidth, (unsigned int)maxSmoothStreamingHeight);
                     eRet = OMX_ErrorBadParameter;
                 } else {
-                    eRet = enable_smoothstreaming();
-                    if (eRet != OMX_ErrorNone) {
-                         DEBUG_PRINT_ERROR("Failed to enable Adaptive Playback on driver.");
-                         eRet = OMX_ErrorHardware;
-                     } else  {
-                         DEBUG_PRINT_HIGH("Enabling Adaptive playback for %u x %u",
-                                 (unsigned int)pParams->nMaxFrameWidth,
-                                 (unsigned int)pParams->nMaxFrameHeight);
-                         m_smoothstreaming_mode = true;
-                         m_smoothstreaming_width = pParams->nMaxFrameWidth;
-                         m_smoothstreaming_height = pParams->nMaxFrameHeight;
-                     }
-                     struct v4l2_format fmt;
-                     update_resolution(m_smoothstreaming_width, m_smoothstreaming_height,
-                                                  m_smoothstreaming_width, m_smoothstreaming_height);
-                     eRet = is_video_session_supported();
-                     if (eRet)
-                         break;
-                     fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
-                     fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
-                     fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
-                     fmt.fmt.pix_mp.pixelformat = output_capability;
-                     DEBUG_PRINT_LOW("fmt.fmt.pix_mp.height = %d , fmt.fmt.pix_mp.width = %d",
-                                                     fmt.fmt.pix_mp.height,fmt.fmt.pix_mp.width);
-                     ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
-                     if (ret) {
-                         DEBUG_PRINT_ERROR("Set Resolution failed");
-                         eRet = OMX_ErrorUnsupportedSetting;
-                     } else
-                         eRet = get_buffer_req(&drv_ctx.op_buf);
+                    eRet = enable_adaptive_playback(pParams->nMaxFrameWidth, pParams->nMaxFrameHeight);
                  }
             } else {
                 DEBUG_PRINT_ERROR(
@@ -3767,6 +4039,33 @@
         }
 
 #endif
+        case OMX_QcomIndexParamVideoCustomBufferSize:
+        {
+            DEBUG_PRINT_LOW("set_parameter: OMX_QcomIndexParamVideoCustomBufferSize");
+            QOMX_VIDEO_CUSTOM_BUFFERSIZE* pParam = (QOMX_VIDEO_CUSTOM_BUFFERSIZE*)paramData;
+            if (pParam->nPortIndex == OMX_CORE_INPUT_PORT_INDEX) {
+                struct v4l2_control control;
+                control.id = V4L2_CID_MPEG_VIDC_VIDEO_BUFFER_SIZE_LIMIT;
+                control.value = pParam->nBufferSize;
+                if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
+                    DEBUG_PRINT_ERROR("Failed to set input buffer size");
+                    eRet = OMX_ErrorUnsupportedSetting;
+                } else {
+                    eRet = get_buffer_req(&drv_ctx.ip_buf);
+                    if (eRet == OMX_ErrorNone) {
+                        m_custom_buffersize.input_buffersize = drv_ctx.ip_buf.buffer_size;
+                        DEBUG_PRINT_HIGH("Successfully set custom input buffer size = %d",
+                            m_custom_buffersize.input_buffersize);
+                    } else {
+                        DEBUG_PRINT_ERROR("Failed to get buffer requirement");
+                    }
+                }
+            } else {
+                DEBUG_PRINT_ERROR("ERROR: Custom buffer size in not supported on output port");
+                eRet = OMX_ErrorBadParameter;
+            }
+            break;
+        }
         default: {
                  DEBUG_PRINT_ERROR("Setparameter: unknown param %d", paramIndex);
                  eRet = OMX_ErrorUnsupportedIndex;
@@ -3850,6 +4149,36 @@
         case OMX_IndexConfigCommonOutputCrop: {
                                   OMX_CONFIG_RECTTYPE *rect = (OMX_CONFIG_RECTTYPE *) configData;
                                   memcpy(rect, &rectangle, sizeof(OMX_CONFIG_RECTTYPE));
+                                  DEBUG_PRINT_HIGH("get_config: crop info: L: %u, T: %u, R: %u, B: %u",
+                                        rectangle.nLeft, rectangle.nTop,
+                                        rectangle.nWidth, rectangle.nHeight);
+                                  break;
+                              }
+        case OMX_QcomIndexConfigPerfLevel: {
+                struct v4l2_control control;
+                OMX_QCOM_VIDEO_CONFIG_PERF_LEVEL *perf =
+                        (OMX_QCOM_VIDEO_CONFIG_PERF_LEVEL *)configData;
+
+                control.id = V4L2_CID_MPEG_VIDC_SET_PERF_LEVEL;
+                if (ioctl(drv_ctx.video_driver_fd, VIDIOC_G_CTRL, &control) < 0) {
+                    DEBUG_PRINT_ERROR("Failed getting performance level: %d", errno);
+                    eRet = OMX_ErrorHardware;
+                }
+
+                if (eRet == OMX_ErrorNone) {
+                    switch (control.value) {
+                        case V4L2_CID_MPEG_VIDC_PERF_LEVEL_TURBO:
+                            perf->ePerfLevel = OMX_QCOM_PerfLevelTurbo;
+                            break;
+                        default:
+                            DEBUG_PRINT_HIGH("Unknown perf level %d, reporting Nominal instead", control.value);
+                            /* Fall through */
+                        case V4L2_CID_MPEG_VIDC_PERF_LEVEL_NOMINAL:
+                            perf->ePerfLevel = OMX_QCOM_PerfLevelNominal;
+                            break;
+                    }
+                }
+
                                   break;
                               }
         default: {
@@ -4082,6 +4411,33 @@
         }
 
         return ret;
+    } else if ((int)configIndex == (int)OMX_QcomIndexConfigPerfLevel) {
+        OMX_QCOM_VIDEO_CONFIG_PERF_LEVEL *perf =
+            (OMX_QCOM_VIDEO_CONFIG_PERF_LEVEL *)configData;
+        struct v4l2_control control;
+
+        DEBUG_PRINT_LOW("Set perf level: %d", perf->ePerfLevel);
+
+        control.id = V4L2_CID_MPEG_VIDC_SET_PERF_LEVEL;
+
+        switch (perf->ePerfLevel) {
+            case OMX_QCOM_PerfLevelNominal:
+                control.value = V4L2_CID_MPEG_VIDC_PERF_LEVEL_NOMINAL;
+                break;
+            case OMX_QCOM_PerfLevelTurbo:
+                control.value = V4L2_CID_MPEG_VIDC_PERF_LEVEL_TURBO;
+                break;
+            default:
+                ret = OMX_ErrorUnsupportedSetting;
+                break;
+        }
+
+        if (ret == OMX_ErrorNone) {
+            ret = (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control) < 0) ?
+                OMX_ErrorUnsupportedSetting : OMX_ErrorNone;
+        }
+
+        return ret;
     }
 
     return OMX_ErrorNotImplemented;
@@ -4125,6 +4481,8 @@
         *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamVideoInputBitsInfoExtraData;
     } else if (extn_equals(paramName, OMX_QCOM_INDEX_PARAM_VIDEO_EXTNUSER_EXTRADATA)) {
         *indexType = (OMX_INDEXTYPE)OMX_QcomIndexEnableExtnUserData;
+    } else if (extn_equals(paramName, OMX_QCOM_INDEX_PARAM_VIDEO_MPEG2SEQDISP_EXTRADATA)) {
+        *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamMpeg2SeqDispExtraData;
     }
 #if defined (_ANDROID_HONEYCOMB_) || defined (_ANDROID_ICS_)
     else if (extn_equals(paramName, "OMX.google.android.index.enableAndroidNativeBuffers")) {
@@ -4141,14 +4499,16 @@
     else if (extn_equals(paramName, "OMX.google.android.index.storeMetaDataInBuffers")) {
         *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamVideoMetaBufferMode;
     }
-#if ADAPTIVE_PLAYBACK_SUPPORTED
+#ifdef ADAPTIVE_PLAYBACK_SUPPORTED
     else if (extn_equals(paramName, "OMX.google.android.index.prepareForAdaptivePlayback")) {
         *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamVideoAdaptivePlaybackMode;
     }
 #endif
+#ifdef FLEXYUV_SUPPORTED
     else if (extn_equals(paramName,"OMX.google.android.index.describeColorFormat")) {
         *indexType = (OMX_INDEXTYPE)OMX_QcomIndexFlexibleYUVDescription;
     }
+#endif
     else {
         DEBUG_PRINT_ERROR("Extension: %s not implemented", paramName);
         return OMX_ErrorNotImplemented;
@@ -4318,6 +4678,9 @@
         eRet = OMX_ErrorInsufficientResources;
     }
 
+    if (eRet != OMX_ErrorNone)
+       return eRet;
+
     if (dynamic_buf_mode) {
         *bufferHdr = (m_out_mem_ptr + i );
         (*bufferHdr)->pBuffer = NULL;
@@ -4352,14 +4715,25 @@
                 handle = (private_handle_t *)buff;
                 privateAppData = appData;
             }
-
-            if ((OMX_U32)handle->size < drv_ctx.op_buf.buffer_size) {
-                DEBUG_PRINT_ERROR("Insufficient sized buffer given for playback,"
-                        " expected %u, got %u",
-                        drv_ctx.op_buf.buffer_size, (unsigned int)handle->size);
+            if (!handle) {
+                DEBUG_PRINT_ERROR("handle is invalid");
                 return OMX_ErrorBadParameter;
             }
 
+            if ((OMX_U32)handle->size < drv_ctx.op_buf.buffer_size) {
+                if (secure_mode && secure_scaling_to_non_secure_opb) {
+                    DEBUG_PRINT_HIGH("Buffer size expected %u, got %u, but it's ok since we will never map it",
+                        (unsigned int)drv_ctx.op_buf.buffer_size, (unsigned int)handle->size);
+                } else {
+                DEBUG_PRINT_ERROR("Insufficient sized buffer given for playback,"
+                        " expected %u, got %u",
+                            (unsigned int)drv_ctx.op_buf.buffer_size, (unsigned int)handle->size);
+                return OMX_ErrorBadParameter;
+            }
+            }
+
+            drv_ctx.op_buf.buffer_size = handle->size;
+
             if (!m_use_android_native_buffers) {
                 if (!secure_mode) {
                     buff =  (OMX_U8*)mmap(0, handle->size,
@@ -4454,7 +4828,7 @@
                 OMX_QCOM_PLATFORM_PRIVATE_LIST *pmem_list;
                 OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pmem_info;
                 pmem_list = (OMX_QCOM_PLATFORM_PRIVATE_LIST*) appData;
-                if (!pmem_list->entryList || !pmem_list->entryList->entry ||
+                if (!pmem_list || !pmem_list->entryList || !pmem_list->entryList->entry ||
                         !pmem_list->nEntries ||
                         pmem_list->entryList->type != OMX_QCOM_PLATFORM_PRIVATE_PMEM) {
                     DEBUG_PRINT_ERROR("Pmem info not valid in use buffer");
@@ -4627,12 +5001,10 @@
     OMX_ERRORTYPE error = OMX_ErrorNone;
     struct vdec_setbuffer_cmd setbuffers;
 
-    if (bufferHdr == NULL || bytes == 0) {
-        if (!secure_mode && buffer == NULL) {
+    if (bufferHdr == NULL || bytes == 0 || (!secure_mode && buffer == NULL)) {
             DEBUG_PRINT_ERROR("bad param 0x%p %u 0x%p",bufferHdr, (unsigned int)bytes, buffer);
             return OMX_ErrorBadParameter;
         }
-    }
     if (m_state == OMX_StateInvalid) {
         DEBUG_PRINT_ERROR("Use Buffer in Invalid State");
         return OMX_ErrorInvalidState;
@@ -4703,8 +5075,8 @@
             if (!secure_mode) {
                 DEBUG_PRINT_LOW("unmap the input buffer fd=%d",
                         drv_ctx.ptr_inputbuffer[index].pmem_fd);
-                DEBUG_PRINT_LOW("unmap the input buffer size=%d  address = %p",
-                        drv_ctx.ptr_inputbuffer[index].mmaped_size,
+                DEBUG_PRINT_LOW("unmap the input buffer size=%u  address = %p",
+                        (unsigned int)drv_ctx.ptr_inputbuffer[index].mmaped_size,
                         drv_ctx.ptr_inputbuffer[index].bufferaddr);
                 munmap (drv_ctx.ptr_inputbuffer[index].bufferaddr,
                         drv_ctx.ptr_inputbuffer[index].mmaped_size);
@@ -4762,8 +5134,8 @@
                     if (!secure_mode) {
                         DEBUG_PRINT_LOW("unmap the output buffer fd = %d",
                                 drv_ctx.ptr_outputbuffer[0].pmem_fd);
-                        DEBUG_PRINT_LOW("unmap the ouput buffer size=%d  address = %p",
-                                drv_ctx.ptr_outputbuffer[0].mmaped_size * drv_ctx.op_buf.actualcount,
+                        DEBUG_PRINT_LOW("unmap the ouput buffer size=%u  address = %p",
+                                (unsigned int)drv_ctx.ptr_outputbuffer[0].mmaped_size * drv_ctx.op_buf.actualcount,
                                 drv_ctx.ptr_outputbuffer[0].bufferaddr);
                         munmap (drv_ctx.ptr_outputbuffer[0].bufferaddr,
                                 drv_ctx.ptr_outputbuffer[0].mmaped_size * drv_ctx.op_buf.actualcount);
@@ -4811,8 +5183,8 @@
                   calloc( (sizeof(OMX_BUFFERHEADERTYPE*)),
                           drv_ctx.ip_buf.actualcount);
 
-        if (m_inp_heap_ptr == NULL) {
-            DEBUG_PRINT_ERROR("m_inp_heap_ptr Allocation failed ");
+        if (m_inp_heap_ptr == NULL || m_phdr_pmem_ptr == NULL) {
+            DEBUG_PRINT_ERROR("m_inp_heap_ptr or m_phdr_pmem_ptr Allocation failed ");
             return OMX_ErrorInsufficientResources;
         }
     }
@@ -4893,15 +5265,15 @@
 
 
     if (bytes != drv_ctx.ip_buf.buffer_size) {
-        DEBUG_PRINT_LOW("Requested Size is wrong %u epected is %d",
-                (unsigned int)bytes, drv_ctx.ip_buf.buffer_size);
+        DEBUG_PRINT_LOW("Requested Size is wrong %u epected is %u",
+                (unsigned int)bytes, (unsigned int)drv_ctx.ip_buf.buffer_size);
         return OMX_ErrorBadParameter;
     }
 
     if (!m_inp_mem_ptr) {
-        DEBUG_PRINT_HIGH("Allocate i/p buffer Header: Cnt(%d) Sz(%d)",
+        DEBUG_PRINT_HIGH("Allocate i/p buffer Header: Cnt(%d) Sz(%u)",
                 drv_ctx.ip_buf.actualcount,
-                drv_ctx.ip_buf.buffer_size);
+                (unsigned int)drv_ctx.ip_buf.buffer_size);
 
         m_inp_mem_ptr = (OMX_BUFFERHEADERTYPE*) \
                 calloc( (sizeof(OMX_BUFFERHEADERTYPE)), drv_ctx.ip_buf.actualcount);
@@ -4949,7 +5321,7 @@
         drv_ctx.ip_buf_ion_info[i].ion_device_fd = alloc_map_ion_memory(
                 drv_ctx.ip_buf.buffer_size,drv_ctx.op_buf.alignment,
                 &drv_ctx.ip_buf_ion_info[i].ion_alloc_data,
-                &drv_ctx.ip_buf_ion_info[i].fd_ion_data, secure_mode ? ION_SECURE : 0);
+                &drv_ctx.ip_buf_ion_info[i].fd_ion_data, secure_mode ? ION_SECURE : ION_FLAG_CACHED);
         if (drv_ctx.ip_buf_ion_info[i].ion_device_fd < 0) {
             return OMX_ErrorInsufficientResources;
         }
@@ -5085,9 +5457,9 @@
     struct ion_fd_data fd_ion_data;
 #endif
     if (!m_out_mem_ptr) {
-        DEBUG_PRINT_HIGH("Allocate o/p buffer Header: Cnt(%d) Sz(%d)",
+        DEBUG_PRINT_HIGH("Allocate o/p buffer Header: Cnt(%d) Sz(%u)",
                 drv_ctx.op_buf.actualcount,
-                drv_ctx.op_buf.buffer_size);
+                (unsigned int)drv_ctx.op_buf.buffer_size);
         int nBufHdrSize        = 0;
         int nPlatformEntrySize = 0;
         int nPlatformListSize  = 0;
@@ -5111,17 +5483,23 @@
         nPlatformEntrySize = drv_ctx.op_buf.actualcount *
             sizeof(OMX_QCOM_PLATFORM_PRIVATE_ENTRY);
 
-        DEBUG_PRINT_LOW("TotalBufHdr %d BufHdrSize %d PMEM %d PL %d",nBufHdrSize,
-                sizeof(OMX_BUFFERHEADERTYPE),
+        DEBUG_PRINT_LOW("TotalBufHdr %d BufHdrSize %u PMEM %d PL %d",nBufHdrSize,
+                (unsigned int)sizeof(OMX_BUFFERHEADERTYPE),
                 nPMEMInfoSize,
                 nPlatformListSize);
         DEBUG_PRINT_LOW("PE %d OutputBuffer Count %d",nPlatformEntrySize,
                 drv_ctx.op_buf.actualcount);
 #ifdef USE_ION
+        // Allocate output buffers as cached to improve performance of software-reading
+        // of the YUVs. Output buffers are cache-invalidated in driver.
+        // If color-conversion is involved, Only the C2D output buffers are cached, no
+        // need to cache the decoder's output buffers
+        int cache_flag = client_buffers.is_color_conversion_enabled() ? 0 : ION_FLAG_CACHED;
         ion_device_fd = alloc_map_ion_memory(
                 drv_ctx.op_buf.buffer_size * drv_ctx.op_buf.actualcount,
-                drv_ctx.op_buf.alignment,
-                &ion_alloc_data, &fd_ion_data, secure_mode ? ION_SECURE : 0);
+                secure_scaling_to_non_secure_opb ? SZ_4K : drv_ctx.op_buf.alignment,
+                &ion_alloc_data, &fd_ion_data,
+                (secure_mode && !secure_scaling_to_non_secure_opb) ? ION_SECURE : cache_flag);
         if (ion_device_fd < 0) {
             return OMX_ErrorInsufficientResources;
         }
@@ -5159,8 +5537,8 @@
                      drv_ctx.op_buf.actualcount),
                     PROT_READ|PROT_WRITE,MAP_SHARED,pmem_fd,0);
             if (pmem_baseaddress == MAP_FAILED) {
-                DEBUG_PRINT_ERROR("MMAP failed for Size %d",
-                        drv_ctx.op_buf.buffer_size);
+                DEBUG_PRINT_ERROR("MMAP failed for Size %u",
+                        (unsigned int)drv_ctx.op_buf.buffer_size);
                 close(pmem_fd);
 #ifdef USE_ION
                 free_ion_memory(&drv_ctx.op_buf_ion_info[i]);
@@ -5179,10 +5557,19 @@
         drv_ctx.ptr_respbuffer = (struct vdec_output_frameinfo  *)\
                      calloc (sizeof (struct vdec_output_frameinfo),
                              drv_ctx.op_buf.actualcount);
+        if (!drv_ctx.ptr_outputbuffer || !drv_ctx.ptr_respbuffer) {
+            DEBUG_PRINT_ERROR("Failed to alloc drv_ctx.ptr_outputbuffer or drv_ctx.ptr_respbuffer ");
+            return OMX_ErrorInsufficientResources;
+        }
+
 #ifdef USE_ION
         drv_ctx.op_buf_ion_info = (struct vdec_ion *)\
                       calloc (sizeof(struct vdec_ion),
                               drv_ctx.op_buf.actualcount);
+        if (!drv_ctx.op_buf_ion_info) {
+            DEBUG_PRINT_ERROR("Failed to alloc drv_ctx.op_buf_ion_info");
+            return OMX_ErrorInsufficientResources;
+        }
 #endif
 
         if (m_out_mem_ptr && pPtr && drv_ctx.ptr_outputbuffer
@@ -5248,8 +5635,8 @@
                 m_pmem_info[i].mapped_size = drv_ctx.ptr_outputbuffer[i].mmaped_size;
                 m_pmem_info[i].buffer = drv_ctx.ptr_outputbuffer[i].bufferaddr;
 
-                DEBUG_PRINT_LOW("pmem_fd = %d offset = %d address = %p",
-                        pmem_fd, drv_ctx.ptr_outputbuffer[i].offset,
+                DEBUG_PRINT_LOW("pmem_fd = %d offset = %u address = %p",
+                        pmem_fd, (unsigned int)drv_ctx.ptr_outputbuffer[i].offset,
                         drv_ctx.ptr_outputbuffer[i].bufferaddr);
                 // Move the buffer and buffer header pointers
                 bufHdr++;
@@ -5308,7 +5695,12 @@
 
             *bufferHdr = (m_out_mem_ptr + i );
             if (secure_mode) {
+#ifdef USE_ION
+                drv_ctx.ptr_outputbuffer[i].bufferaddr =
+                    (OMX_U8 *)(intptr_t)drv_ctx.op_buf_ion_info[i].fd_ion_data.fd;
+#else
                 drv_ctx.ptr_outputbuffer[i].bufferaddr = *bufferHdr;
+#endif
             }
             drv_ctx.ptr_outputbuffer[i].mmaped_size = drv_ctx.op_buf.buffer_size;
 
@@ -5684,6 +6076,7 @@
     } else {
         post_event ((unsigned long)hComp,(unsigned long)buffer,OMX_COMPONENT_GENERATE_ETB);
     }
+    time_stamp_dts.insert_timestamp(buffer);
     return OMX_ErrorNone;
 }
 
@@ -5713,7 +6106,6 @@
     struct vdec_bufferpayload *temp_buffer;
     struct vdec_seqheader seq_header;
     bool port_setting_changed = true;
-    bool not_coded_vop = false;
 
     /*Should we generate a Aync error event*/
     if (buffer == NULL || buffer->pInputPortPrivate == NULL) {
@@ -5740,30 +6132,7 @@
         return OMX_ErrorNone;
     }
 
-
-    if (codec_type_parse == CODEC_TYPE_MPEG4 || codec_type_parse == CODEC_TYPE_DIVX) {
-        mp4StreamType psBits;
-        psBits.data = (unsigned char *)(buffer->pBuffer + buffer->nOffset);
-        psBits.numBytes = buffer->nFilledLen;
-        mp4_headerparser.parseHeader(&psBits);
-        not_coded_vop = mp4_headerparser.is_notcodec_vop(
-                (buffer->pBuffer + buffer->nOffset),buffer->nFilledLen);
-        if (not_coded_vop) {
-            DEBUG_PRINT_HIGH("Found Not coded vop len %u frame number %u",
-                    (unsigned int)buffer->nFilledLen,frame_count);
-            if (buffer->nFlags & OMX_BUFFERFLAG_EOS) {
-                DEBUG_PRINT_HIGH("Eos and Not coded Vop set len to zero");
-                not_coded_vop = false;
-                buffer->nFilledLen = 0;
-            }
-        }
-    }
-
-    if (input_flush_progress == true
-
-            || not_coded_vop
-
-       ) {
+    if (input_flush_progress == true) {
         DEBUG_PRINT_LOW("Flush in progress return buffer ");
         post_event ((unsigned long)buffer,VDEC_S_SUCCESS,
                 OMX_COMPONENT_GENERATE_EBD);
@@ -5904,16 +6273,17 @@
     buf.flags |= (buffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG) ? V4L2_QCOM_BUF_FLAG_CODECCONFIG: 0;
     buf.flags |= (buffer->nFlags & OMX_BUFFERFLAG_DECODEONLY) ? V4L2_QCOM_BUF_FLAG_DECODEONLY: 0;
 
+    if (buffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG) {
+        DEBUG_PRINT_LOW("Increment codec_config buffer counter");
+        android_atomic_inc(&m_queued_codec_config_count);
+    }
+
     rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_QBUF, &buf);
     if (rc) {
         DEBUG_PRINT_ERROR("Failed to qbuf Input buffer to driver");
         return OMX_ErrorHardware;
     }
 
-    if (buffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG) {
-        android_atomic_inc(&m_queued_codec_config_count);
-    }
-
     if (codec_config_flag && !(buffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG)) {
         codec_config_flag = false;
     }
@@ -5927,6 +6297,11 @@
         if (!ret) {
             DEBUG_PRINT_HIGH("Streamon on OUTPUT Plane was successful");
             streaming[OUTPUT_PORT] = true;
+        } else if (errno == EBUSY) {
+            DEBUG_PRINT_ERROR("Failed to call stream on OUTPUT due to HW_OVERLOAD");
+            post_event ((unsigned long)buffer, VDEC_S_SUCCESS,
+                    OMX_COMPONENT_GENERATE_EBD);
+            return OMX_ErrorInsufficientResources;
         } else {
             DEBUG_PRINT_ERROR("Failed to call streamon on OUTPUT");
             DEBUG_PRINT_LOW("If Stream on failed no buffer should be queued");
@@ -5935,9 +6310,9 @@
             return OMX_ErrorBadParameter;
         }
     }
-    DEBUG_PRINT_LOW("[ETBP] pBuf(%p) nTS(%lld) Sz(%d)",
-            frameinfo.bufferaddr, frameinfo.timestamp, frameinfo.datalen);
-    time_stamp_dts.insert_timestamp(buffer);
+    DEBUG_PRINT_LOW("[ETBP] pBuf(%p) nTS(%lld) Sz(%u)",
+            frameinfo.bufferaddr, (long long)frameinfo.timestamp,
+            (unsigned int)frameinfo.datalen);
 
     return ret;
 }
@@ -5960,13 +6335,14 @@
 OMX_ERRORTYPE  omx_vdec::fill_this_buffer(OMX_IN OMX_HANDLETYPE  hComp,
         OMX_IN OMX_BUFFERHEADERTYPE* buffer)
 {
+    unsigned nPortIndex = 0;
     if (dynamic_buf_mode) {
         private_handle_t *handle = NULL;
         struct VideoDecoderOutputMetaData *meta;
         unsigned int nPortIndex = 0;
 
         if (!buffer || !buffer->pBuffer) {
-            DEBUG_PRINT_ERROR("%s: invalid params: %p %p", __FUNCTION__, buffer, buffer->pBuffer);
+            DEBUG_PRINT_ERROR("%s: invalid params: %p", __FUNCTION__, buffer);
             return OMX_ErrorBadParameter;
         }
 
@@ -5988,6 +6364,12 @@
         //Store private handle from GraphicBuffer
         native_buffer[nPortIndex].privatehandle = handle;
         native_buffer[nPortIndex].nativehandle = handle;
+
+        //buffer->nAllocLen will be sizeof(struct VideoDecoderOutputMetaData). Overwrite
+        //this with a more sane size so that we don't compensate in rest of code
+        //We'll restore this size later on, so that it's transparent to client
+        buffer->nFilledLen = 0;
+        buffer->nAllocLen = handle->size;
     }
 
 
@@ -6001,8 +6383,11 @@
         return OMX_ErrorIncorrectStateOperation;
     }
 
+    nPortIndex = buffer - client_buffers.get_il_buf_hdr();
     if (buffer == NULL ||
-            ((buffer - client_buffers.get_il_buf_hdr()) >= (int)drv_ctx.op_buf.actualcount)) {
+            (nPortIndex >= drv_ctx.op_buf.actualcount)) {
+        DEBUG_PRINT_ERROR("FTB: ERROR: invalid buffer index, nPortIndex %u bufCount %u",
+            nPortIndex, drv_ctx.op_buf.actualcount);
         return OMX_ErrorBadParameter;
     }
 
@@ -6043,8 +6428,11 @@
 
     nPortIndex = buffer-((OMX_BUFFERHEADERTYPE *)client_buffers.get_il_buf_hdr());
 
-    if (bufferAdd == NULL || nPortIndex > drv_ctx.op_buf.actualcount)
+    if (bufferAdd == NULL || nPortIndex > drv_ctx.op_buf.actualcount) {
+        DEBUG_PRINT_ERROR("FTBProxy: ERROR: invalid buffer index, nPortIndex %u bufCount %u",
+            nPortIndex, drv_ctx.op_buf.actualcount);
         return OMX_ErrorBadParameter;
+    }
 
     DEBUG_PRINT_LOW("FTBProxy: bufhdr = %p, bufhdr->pBuffer = %p",
             bufferAdd, bufferAdd->pBuffer);
@@ -6073,6 +6461,10 @@
 
     pending_output_buffers++;
     buffer = client_buffers.get_dr_buf_hdr(bufferAdd);
+    if (!buffer) {
+       DEBUG_PRINT_ERROR("err: client_buffer ptr invalid");
+       return OMX_ErrorBadParameter;
+    }
     ptr_respbuffer = (struct vdec_output_frameinfo*)buffer->pOutputPortPrivate;
     if (ptr_respbuffer) {
         ptr_outputbuffer =  (struct vdec_bufferpayload*)ptr_respbuffer->client_data;
@@ -6091,7 +6483,7 @@
     struct v4l2_plane plane[VIDEO_MAX_PLANES];
     memset( (void *)&buf, 0, sizeof(buf));
     memset( (void *)plane, 0, (sizeof(struct v4l2_plane)*VIDEO_MAX_PLANES));
-    int extra_idx = 0;
+    unsigned int extra_idx = 0;
 
     buf.index = nPortIndex;
     buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
@@ -6115,7 +6507,7 @@
         plane[extra_idx].reserved[1] = nPortIndex * drv_ctx.extradata_info.buffer_size;
         plane[extra_idx].data_offset = 0;
     } else if (extra_idx >= VIDEO_MAX_PLANES) {
-        DEBUG_PRINT_ERROR("Extradata index higher than expected: %d", extra_idx);
+        DEBUG_PRINT_ERROR("Extradata index higher than expected: %u", extra_idx);
         return OMX_ErrorBadParameter;
     }
     buf.m.planes = plane;
@@ -6721,6 +7113,28 @@
         handle_extradata(buffer);
     }
 
+#ifdef OUTPUT_EXTRADATA_LOG
+    if (outputExtradataFile) {
+        int buf_index = buffer - m_out_mem_ptr;
+        OMX_U8 *pBuffer = (OMX_U8 *)(drv_ctx.ptr_outputbuffer[buf_index].bufferaddr);
+
+        OMX_OTHER_EXTRADATATYPE *p_extra = NULL;
+        p_extra = (OMX_OTHER_EXTRADATATYPE *)
+            ((unsigned long)(pBuffer + buffer->nOffset + buffer->nFilledLen + 3)&(~3));
+
+        while (p_extra && (OMX_U8*)p_extra < (pBuffer + buffer->nAllocLen) ) {
+            DEBUG_PRINT_LOW("WRITING extradata, size=%d,type=%x",
+                                    p_extra->nSize, p_extra->eType);
+            fwrite (p_extra,1,p_extra->nSize,outputExtradataFile);
+
+            if (p_extra->eType == OMX_ExtraDataNone) {
+                break;
+            }
+            p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + p_extra->nSize);
+        }
+    }
+#endif
+
     /* For use buffer we need to copy the data */
     if (!output_flush_progress) {
         /* This is the error check for non-recoverable errros */
@@ -6759,13 +7173,16 @@
                     }
                 }
             }
-        } else {
-            time_stamp_dts.remove_time_stamp(
-                    buffer->nTimeStamp,
-                    is_interlaced && is_duplicate_ts_valid);
+        }
         }
 
-
+    /* Since we're passing around handles, adjust nFilledLen and nAllocLen
+     * to size of the handle.  Do it _after_ handle_extradata() which
+     * requires the respective sizes to be accurate. */
+    if (dynamic_buf_mode) {
+        buffer->nAllocLen = sizeof(struct VideoDecoderOutputMetaData);
+        buffer->nFilledLen = buffer->nFilledLen ?
+            sizeof(struct VideoDecoderOutputMetaData) : 0;
     }
     if (m_cb.FillBufferDone) {
         if (buffer->nFilledLen > 0) {
@@ -6793,25 +7210,6 @@
                     proc_frms = 0;
                 }
             }
-
-#ifdef OUTPUT_EXTRADATA_LOG
-            if (outputExtradataFile) {
-
-                OMX_OTHER_EXTRADATATYPE *p_extra = NULL;
-                p_extra = (OMX_OTHER_EXTRADATATYPE *)
-                    ((unsigned)(buffer->pBuffer + buffer->nOffset +
-                        buffer->nFilledLen + 3)&(~3));
-                while (p_extra &&
-                        (OMX_U8*)p_extra < (buffer->pBuffer + buffer->nAllocLen) ) {
-                    DEBUG_PRINT_LOW("WRITING extradata, size=%d,type=%d",p_extra->nSize, p_extra->eType);
-                    fwrite (p_extra,1,p_extra->nSize,outputExtradataFile);
-                    if (p_extra->eType == OMX_ExtraDataNone) {
-                        break;
-                    }
-                    p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + p_extra->nSize);
-                }
-            }
-#endif
         }
         if (buffer->nFlags & OMX_BUFFERFLAG_EOS) {
             prev_ts = LLONG_MAX;
@@ -6877,12 +7275,14 @@
     }
 
 #ifdef ADAPTIVE_PLAYBACK_SUPPORTED
-    if (m_smoothstreaming_mode) {
+    if (m_smoothstreaming_mode && m_out_mem_ptr) {
         OMX_U32 buf_index = buffer - m_out_mem_ptr;
         BufferDim_t dim;
-        dim.sliceWidth = drv_ctx.video_resolution.frame_width;
-        dim.sliceHeight = drv_ctx.video_resolution.frame_height;
-        private_handle_t *private_handle = native_buffer[buf_index].privatehandle;
+        private_handle_t *private_handle = NULL;
+        dim.sliceWidth = framesize.nWidth;
+        dim.sliceHeight = framesize.nHeight;
+        if (native_buffer[buf_index].privatehandle)
+            private_handle = native_buffer[buf_index].privatehandle;
         if (private_handle) {
             DEBUG_PRINT_LOW("set metadata: update buf-geometry with stride %d slice %d",
                 dim.sliceWidth, dim.sliceHeight);
@@ -6903,21 +7303,9 @@
         return OMX_ErrorBadParameter;
     }
 
-    DEBUG_PRINT_LOW("empty_buffer_done: bufhdr = %p, bufhdr->pBuffer = %p",
-            buffer, buffer->pBuffer);
+    DEBUG_PRINT_LOW("empty_buffer_done: bufhdr = %p, bufhdr->pBuffer = %p, bufhdr->nFlags = %x",
+            buffer, buffer->pBuffer, buffer->nFlags);
     pending_input_buffers--;
-    if (buffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG) {
-        int pending_flush_waiters;
-
-        while (pending_flush_waiters = INT_MAX,
-                sem_getvalue(&m_safe_flush, &pending_flush_waiters),
-                /* 0 == there /are/ waiters depending on POSIX implementation */
-                pending_flush_waiters <= 0 ) {
-            sem_post(&m_safe_flush);
-        }
-
-        android_atomic_and(0, &m_queued_codec_config_count); /* no clearer way to set to 0 */
-    }
 
     if (arbitrary_bytes) {
         if (pdest_frame == NULL && input_flush_progress == false) {
@@ -6967,6 +7355,16 @@
                     OMX_COMPONENT_GENERATE_HARDWARE_ERROR);
             break;
 
+        case VDEC_MSG_EVT_HW_OVERLOAD:
+            omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
+                    OMX_COMPONENT_GENERATE_HARDWARE_OVERLOAD);
+            break;
+
+        case VDEC_MSG_EVT_HW_UNSUPPORTED:
+            omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
+                    OMX_COMPONENT_GENERATE_UNSUPPORTED_SETTING);
+            break;
+
         case VDEC_MSG_RESP_START_DONE:
             omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
                     OMX_COMPONENT_GENERATE_START_DONE);
@@ -7007,14 +7405,27 @@
                     ((omxhdr - omx->m_inp_mem_ptr) > (int)omx->drv_ctx.ip_buf.actualcount) ) {
                 omxhdr = NULL;
                 vdec_msg->status_code = VDEC_S_EFATAL;
+                break;
             }
             if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_INPUT_UNSUPPORTED) {
                 DEBUG_PRINT_HIGH("Unsupported input");
                 omx->omx_report_error ();
             }
             if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_DATA_CORRUPT) {
+                omxhdr->nFlags |= OMX_BUFFERFLAG_DATACORRUPT;
                 vdec_msg->status_code = VDEC_S_INPUT_BITSTREAM_ERR;
             }
+            if (omxhdr->nFlags & OMX_BUFFERFLAG_CODECCONFIG) {
+
+                DEBUG_PRINT_LOW("Decrement codec_config buffer counter");
+                android_atomic_dec(&omx->m_queued_codec_config_count);
+                if ((android_atomic_add(0, &omx->m_queued_codec_config_count) == 0) &&
+                    BITMASK_PRESENT(&omx->m_flags, OMX_COMPONENT_FLUSH_DEFERRED)) {
+                    DEBUG_PRINT_LOW("sem post for CODEC CONFIG buffer");
+                    sem_post(&omx->m_safe_flush);
+                }
+            }
+
             omx->post_event ((unsigned long)omxhdr,vdec_msg->status_code,
                     OMX_COMPONENT_GENERATE_EBD);
             break;
@@ -7026,7 +7437,7 @@
                 omx->post_event ((unsigned long)timestamp, vdec_msg->status_code,
                         OMX_COMPONENT_GENERATE_INFO_FIELD_DROPPED);
                 DEBUG_PRINT_HIGH("Field dropped time stamp is %lld",
-                        vdec_msg->msgdata.output_frame.time_stamp);
+                        (long long)vdec_msg->msgdata.output_frame.time_stamp);
             }
             break;
         case VDEC_MSG_RESP_OUTPUT_FLUSHED:
@@ -7034,17 +7445,21 @@
 
             v4l2_buf_ptr = (v4l2_buffer*)vdec_msg->msgdata.output_frame.client_data;
             omxhdr=omx->m_out_mem_ptr+v4l2_buf_ptr->index;
-            DEBUG_PRINT_LOW("[RespBufDone] Buf(%p) Ts(%lld) Pic_type(%u)",
-                    omxhdr, vdec_msg->msgdata.output_frame.time_stamp,
-                    vdec_msg->msgdata.output_frame.pic_type);
+
+            DEBUG_PRINT_LOW("[RespBufDone] Buf(%p) Ts(%lld) PicType(%u) Flags (0x%x) FillLen(%u) Crop: L(%u) T(%u) R(%u) B(%u)",
+                    omxhdr, (long long)vdec_msg->msgdata.output_frame.time_stamp,
+                    vdec_msg->msgdata.output_frame.pic_type, v4l2_buf_ptr->flags,
+                    (unsigned int)vdec_msg->msgdata.output_frame.len,
+                    vdec_msg->msgdata.output_frame.framesize.left,
+                    vdec_msg->msgdata.output_frame.framesize.top,
+                    vdec_msg->msgdata.output_frame.framesize.right,
+                    vdec_msg->msgdata.output_frame.framesize.bottom);
 
             if (omxhdr && omxhdr->pOutputPortPrivate &&
                     ((omxhdr - omx->m_out_mem_ptr) < (int)omx->drv_ctx.op_buf.actualcount) &&
                     (((struct vdec_output_frameinfo *)omxhdr->pOutputPortPrivate
                       - omx->drv_ctx.ptr_respbuffer) < (int)omx->drv_ctx.op_buf.actualcount)) {
-                if (omx->dynamic_buf_mode && vdec_msg->msgdata.output_frame.len) {
-                    vdec_msg->msgdata.output_frame.len = omxhdr->nAllocLen;
-                }
+
                 if ( vdec_msg->msgdata.output_frame.len <=  omxhdr->nAllocLen) {
                     omxhdr->nFilledLen = vdec_msg->msgdata.output_frame.len;
                     omxhdr->nOffset = vdec_msg->msgdata.output_frame.offset;
@@ -7063,6 +7478,9 @@
                     } else {
                         omxhdr->nFlags &= ~OMX_BUFFERFLAG_SYNCFRAME;
                     }
+                    if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_EOSEQ) {
+                        omxhdr->nFlags |= QOMX_VIDEO_BUFFERFLAG_EOSEQ;
+                    }
                     if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_DECODEONLY) {
                         omxhdr->nFlags |= OMX_BUFFERFLAG_DECODEONLY;
                     }
@@ -7097,75 +7515,51 @@
                     }
                     vdec_msg->msgdata.output_frame.bufferaddr =
                         omx->drv_ctx.ptr_outputbuffer[v4l2_buf_ptr->index].bufferaddr;
-                    int format_notably_changed = 0;
-                    if (omxhdr->nFilledLen &&
-                            (omxhdr->nFilledLen != (unsigned)omx->prev_n_filled_len)) {
-                        if ((vdec_msg->msgdata.output_frame.framesize.bottom != omx->drv_ctx.video_resolution.frame_height) ||
-                                (vdec_msg->msgdata.output_frame.framesize.right != omx->drv_ctx.video_resolution.frame_width)) {
-                            DEBUG_PRINT_HIGH("Height/Width information has changed");
-                            omx->drv_ctx.video_resolution.frame_height = vdec_msg->msgdata.output_frame.framesize.bottom;
-                            omx->drv_ctx.video_resolution.frame_width = vdec_msg->msgdata.output_frame.framesize.right;
-                            format_notably_changed = 1;
-                        }
-                    }
-                    if (omxhdr->nFilledLen && (((unsigned)omx->rectangle.nLeft !=
-                                    vdec_msg->msgdata.output_frame.framesize.left)
-                                || ((unsigned)omx->rectangle.nTop != vdec_msg->msgdata.output_frame.framesize.top)
-                                || (omx->rectangle.nWidth != vdec_msg->msgdata.output_frame.framesize.right)
-                                || (omx->rectangle.nHeight != vdec_msg->msgdata.output_frame.framesize.bottom))) {
-                        if ((vdec_msg->msgdata.output_frame.framesize.bottom != omx->drv_ctx.video_resolution.frame_height) ||
-                                (vdec_msg->msgdata.output_frame.framesize.right != omx->drv_ctx.video_resolution.frame_width)) {
-                            omx->drv_ctx.video_resolution.frame_height = vdec_msg->msgdata.output_frame.framesize.bottom;
-                            omx->drv_ctx.video_resolution.frame_width = vdec_msg->msgdata.output_frame.framesize.right;
-                            DEBUG_PRINT_HIGH("Height/Width information has changed. W: %d --> %d, H: %d --> %d",
-                                    omx->drv_ctx.video_resolution.frame_width, vdec_msg->msgdata.output_frame.framesize.right,
-                                    omx->drv_ctx.video_resolution.frame_height, vdec_msg->msgdata.output_frame.framesize.bottom);
-                        }
-                        DEBUG_PRINT_HIGH("Crop information changed. W: %u --> %d, H: %u -> %d",
-                                (unsigned int)omx->rectangle.nWidth, vdec_msg->msgdata.output_frame.framesize.right,
-                                (unsigned int)omx->rectangle.nHeight, vdec_msg->msgdata.output_frame.framesize.bottom);
-                        if (vdec_msg->msgdata.output_frame.framesize.left + vdec_msg->msgdata.output_frame.framesize.right >=
-                            omx->drv_ctx.video_resolution.frame_width) {
-                            vdec_msg->msgdata.output_frame.framesize.left = 0;
-                            if (vdec_msg->msgdata.output_frame.framesize.right > omx->drv_ctx.video_resolution.frame_width) {
-                                vdec_msg->msgdata.output_frame.framesize.right =  omx->drv_ctx.video_resolution.frame_width;
-                            }
-                        }
-                        if (vdec_msg->msgdata.output_frame.framesize.top + vdec_msg->msgdata.output_frame.framesize.bottom >=
-                            omx->drv_ctx.video_resolution.frame_height) {
-                            vdec_msg->msgdata.output_frame.framesize.top = 0;
-                            if (vdec_msg->msgdata.output_frame.framesize.bottom > omx->drv_ctx.video_resolution.frame_height) {
-                                vdec_msg->msgdata.output_frame.framesize.bottom =  omx->drv_ctx.video_resolution.frame_height;
-                            }
-                        }
-                        DEBUG_PRINT_LOW("omx_vdec: Adjusted Dim L: %d, T: %d, R: %d, B: %d, W: %d, H: %d",
+
+                    /* Post event if resolution OR crop changed */
+                    /* filled length will be changed if resolution changed */
+                    /* Crop parameters can be changed even without resolution change */
+                    if (omxhdr->nFilledLen
+                        && ((omx->prev_n_filled_len != omxhdr->nFilledLen)
+                        || (omx->drv_ctx.frame_size.left != vdec_msg->msgdata.output_frame.framesize.left)
+                        || (omx->drv_ctx.frame_size.top != vdec_msg->msgdata.output_frame.framesize.top)
+                        || (omx->drv_ctx.frame_size.right != vdec_msg->msgdata.output_frame.framesize.right)
+                        || (omx->drv_ctx.frame_size.bottom != vdec_msg->msgdata.output_frame.framesize.bottom)
+                        || (omx->drv_ctx.video_resolution.frame_width != vdec_msg->msgdata.output_frame.picsize.frame_width)
+                        || (omx->drv_ctx.video_resolution.frame_height != vdec_msg->msgdata.output_frame.picsize.frame_height) )) {
+
+                        DEBUG_PRINT_HIGH("Paramters Changed From: Len: %u, WxH: %dx%d, L: %u, T: %u, R: %u, B: %u --> Len: %u, WxH: %dx%d, L: %u, T: %u, R: %u, B: %u",
+                                omx->prev_n_filled_len,
+                                omx->drv_ctx.video_resolution.frame_width,
+                                omx->drv_ctx.video_resolution.frame_height,
+                                omx->drv_ctx.frame_size.left, omx->drv_ctx.frame_size.top,
+                                omx->drv_ctx.frame_size.right, omx->drv_ctx.frame_size.bottom,
+                                omxhdr->nFilledLen, vdec_msg->msgdata.output_frame.picsize.frame_width,
+                                vdec_msg->msgdata.output_frame.picsize.frame_height,
                                         vdec_msg->msgdata.output_frame.framesize.left,
                                         vdec_msg->msgdata.output_frame.framesize.top,
                                         vdec_msg->msgdata.output_frame.framesize.right,
-                                        vdec_msg->msgdata.output_frame.framesize.bottom,
-                                        omx->drv_ctx.video_resolution.frame_width,
-                                        omx->drv_ctx.video_resolution.frame_height);
-                        omx->rectangle.nLeft = vdec_msg->msgdata.output_frame.framesize.left;
-                        omx->rectangle.nTop = vdec_msg->msgdata.output_frame.framesize.top;
-                        omx->rectangle.nWidth = vdec_msg->msgdata.output_frame.framesize.right;
-                        omx->rectangle.nHeight = vdec_msg->msgdata.output_frame.framesize.bottom;
-                        format_notably_changed = 1;
-                    }
-                    DEBUG_PRINT_HIGH("Left: %d, Right: %d, top: %d, Bottom: %d",
-                                      vdec_msg->msgdata.output_frame.framesize.left,vdec_msg->msgdata.output_frame.framesize.right,
-                                      vdec_msg->msgdata.output_frame.framesize.top, vdec_msg->msgdata.output_frame.framesize.bottom);
-                    if (format_notably_changed) {
-                        if (omx->is_video_session_supported()) {
-                            omx->post_event (0, vdec_msg->status_code,
-                                    OMX_COMPONENT_GENERATE_UNSUPPORTED_SETTING);
-                        } else {
-                            if (!omx->client_buffers.update_buffer_req()) {
-                                DEBUG_PRINT_ERROR("Setting c2D buffer requirements failed");
-                            }
-                            omx->post_event (OMX_CORE_OUTPUT_PORT_INDEX, OMX_IndexConfigCommonOutputCrop,
+                                vdec_msg->msgdata.output_frame.framesize.bottom);
+
+                        omx->drv_ctx.video_resolution.frame_width =
+                                vdec_msg->msgdata.output_frame.picsize.frame_width;
+                        omx->drv_ctx.video_resolution.frame_height =
+                                vdec_msg->msgdata.output_frame.picsize.frame_height;
+                        if (omx->drv_ctx.output_format == VDEC_YUV_FORMAT_NV12) {
+                            omx->drv_ctx.video_resolution.stride =
+                                VENUS_Y_STRIDE(COLOR_FMT_NV12, omx->drv_ctx.video_resolution.frame_width);
+                            omx->drv_ctx.video_resolution.scan_lines =
+                                VENUS_Y_SCANLINES(COLOR_FMT_NV12, omx->drv_ctx.video_resolution.frame_height);
+                        }
+                        memcpy(&omx->drv_ctx.frame_size,
+                                &vdec_msg->msgdata.output_frame.framesize,
+                                sizeof(struct vdec_framesize));
+
+                        omx->post_event(OMX_CORE_OUTPUT_PORT_INDEX,
+                                OMX_IndexConfigCommonOutputCrop,
                                     OMX_COMPONENT_GENERATE_PORT_RECONFIG);
                         }
-                    }
+
                     if (omxhdr->nFilledLen)
                         omx->prev_n_filled_len = omxhdr->nFilledLen;
 
@@ -7188,16 +7582,23 @@
                                 ((unsigned long)vdec_msg->msgdata.output_frame.bufferaddr +
                                  (unsigned long)vdec_msg->msgdata.output_frame.offset),
                                 vdec_msg->msgdata.output_frame.len);
-                } else
+                } else {
+                    DEBUG_PRINT_ERROR("Invalid filled length = %u, buffer size = %u, prev_length = %u",
+                            (unsigned int)vdec_msg->msgdata.output_frame.len,
+                            omxhdr->nAllocLen, omx->prev_n_filled_len);
                     omxhdr->nFilledLen = 0;
+                }
+
                 omx->post_event ((unsigned long)omxhdr, vdec_msg->status_code,
                         OMX_COMPONENT_GENERATE_FBD);
-            } else if (vdec_msg->msgdata.output_frame.flags & OMX_BUFFERFLAG_EOS)
+
+            } else if (vdec_msg->msgdata.output_frame.flags & OMX_BUFFERFLAG_EOS) {
                 omx->post_event ((unsigned long)NULL, vdec_msg->status_code,
                         OMX_COMPONENT_GENERATE_EOS_DONE);
-            else
+            } else {
                 omx->post_event ((unsigned int)NULL, vdec_msg->status_code,
                         OMX_COMPONENT_GENERATE_HARDWARE_ERROR);
+            }
             break;
         case VDEC_MSG_EVT_CONFIG_CHANGED:
             DEBUG_PRINT_HIGH("Port settings changed");
@@ -7247,7 +7648,9 @@
         }
     }
 
-
+    if (codec_config_flag && !(buffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG)) {
+        codec_config_flag = false;
+    }
     return OMX_ErrorNone;
 }
 
@@ -7609,6 +8012,7 @@
                                      h264_scratch.pBuffer,h264_scratch.nFilledLen);
                              pdest_frame->nFilledLen += h264_scratch.nFilledLen;
                              h264_scratch.nFilledLen = 0;
+                             if (h264_last_au_ts != LLONG_MAX)
                              pdest_frame->nTimeStamp = h264_last_au_ts;
                         } else {
                             /* Completely new frame, let's just push what
@@ -8111,12 +8515,12 @@
 {
     OMX_ERRORTYPE eRet = OMX_ErrorNone;
     struct v4l2_requestbuffers bufreq;
-    unsigned int buf_size = 0, extra_data_size = 0, client_extra_data_size = 0;
+    unsigned int buf_size = 0, extra_data_size = 0, default_extra_data_size = 0;
     unsigned int final_extra_data_size = 0;
     struct v4l2_format fmt;
     int ret = 0;
-    DEBUG_PRINT_LOW("GetBufReq IN: ActCnt(%d) Size(%d)",
-            buffer_prop->actualcount, buffer_prop->buffer_size);
+    DEBUG_PRINT_LOW("GetBufReq IN: ActCnt(%d) Size(%u)",
+            buffer_prop->actualcount, (unsigned int)buffer_prop->buffer_size);
     bufreq.memory = V4L2_MEMORY_USERPTR;
     bufreq.count = 1;
     if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_INPUT) {
@@ -8143,8 +8547,8 @@
         buffer_prop->mincount = bufreq.count;
         DEBUG_PRINT_HIGH("Count = %d",bufreq.count);
     }
-    DEBUG_PRINT_LOW("GetBufReq IN: ActCnt(%d) Size(%d)",
-            buffer_prop->actualcount, buffer_prop->buffer_size);
+    DEBUG_PRINT_LOW("GetBufReq IN: ActCnt(%d) Size(%u)",
+            buffer_prop->actualcount, (unsigned int)buffer_prop->buffer_size);
 
     fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
     fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
@@ -8179,53 +8583,24 @@
             DEBUG_PRINT_ERROR("Extradata index is more than allowed: %d", extra_idx);
             return OMX_ErrorBadParameter;
         }
-        if (client_extradata & OMX_FRAMEINFO_EXTRADATA) {
-            DEBUG_PRINT_HIGH("Frame info extra data enabled!");
-            client_extra_data_size += OMX_FRAMEINFO_EXTRADATA_SIZE;
-        }
-        if (client_extradata & OMX_INTERLACE_EXTRADATA) {
-            client_extra_data_size += OMX_INTERLACE_EXTRADATA_SIZE;
-        }
-        if (client_extradata & OMX_PORTDEF_EXTRADATA) {
-            client_extra_data_size += OMX_PORTDEF_EXTRADATA_SIZE;
-            DEBUG_PRINT_HIGH("Smooth streaming enabled extra_data_size=%d",
-                    client_extra_data_size);
-        }
-        if ((client_extradata & OMX_FRAMEDIMENSION_EXTRADATA)) {
-            client_extra_data_size += OMX_FRAMEDIMENSION_EXTRADATA_SIZE;
-            DEBUG_PRINT_HIGH("Frame dimension enabled extra_data_size = %d\n",
-                    client_extra_data_size);
-        }
-        if (client_extradata & OMX_FRAMEPACK_EXTRADATA) {
-            client_extra_data_size += OMX_FRAMEPACK_EXTRADATA_SIZE;
-            DEBUG_PRINT_HIGH("framepack extradata enabled");
-        }
-        if (client_extradata & OMX_QP_EXTRADATA) {
-            client_extra_data_size += OMX_QP_EXTRADATA_SIZE;
-            DEBUG_PRINT_HIGH("QP extradata enabled");
-        }
-        if (client_extradata & OMX_BITSINFO_EXTRADATA) {
-            client_extra_data_size += OMX_BITSINFO_EXTRADATA_SIZE;
-            DEBUG_PRINT_HIGH("Input bits info extradata enabled");
-        }
-        if (client_extradata & OMX_EXTNUSER_EXTRADATA) {
-            client_extra_data_size += OMX_USERDATA_EXTRADATA_SIZE;
-            DEBUG_PRINT_HIGH("Userdata extradata enabled");
-        }
 
-        if (client_extra_data_size) {
-            client_extra_data_size += sizeof(OMX_OTHER_EXTRADATATYPE); //Space for terminator
-            buf_size = ((buf_size + 3)&(~3)); //Align extradata start address to 64Bit
-        }
-        final_extra_data_size = (extra_data_size > client_extra_data_size ?
-            extra_data_size : client_extra_data_size);
+        default_extra_data_size = VENUS_EXTRADATA_SIZE(
+                drv_ctx.video_resolution.frame_height,
+                drv_ctx.video_resolution.frame_width);
+        final_extra_data_size = extra_data_size > default_extra_data_size ?
+            extra_data_size : default_extra_data_size;
+
+        final_extra_data_size = (final_extra_data_size + buffer_prop->alignment - 1) &
+            (~(buffer_prop->alignment - 1));
+
         drv_ctx.extradata_info.size = buffer_prop->actualcount * final_extra_data_size;
         drv_ctx.extradata_info.count = buffer_prop->actualcount;
         drv_ctx.extradata_info.buffer_size = final_extra_data_size;
-        buf_size += client_extra_data_size;
+        if (!secure_mode)
+            buf_size += final_extra_data_size;
         buf_size = (buf_size + buffer_prop->alignment - 1)&(~(buffer_prop->alignment - 1));
-        DEBUG_PRINT_LOW("GetBufReq UPDATE: ActCnt(%d) Size(%d) BufSize(%d)",
-                buffer_prop->actualcount, buffer_prop->buffer_size, buf_size);
+        DEBUG_PRINT_LOW("GetBufReq UPDATE: ActCnt(%d) Size(%u) BufSize(%d)",
+                buffer_prop->actualcount, (unsigned int)buffer_prop->buffer_size, buf_size);
         if (extra_data_size)
             DEBUG_PRINT_LOW("GetBufReq UPDATE: extradata: TotalSize(%d) BufferSize(%lu)",
                 drv_ctx.extradata_info.size, drv_ctx.extradata_info.buffer_size);
@@ -8237,8 +8612,8 @@
             eRet = set_buffer_req(buffer_prop);
         }
     }
-    DEBUG_PRINT_LOW("GetBufReq OUT: ActCnt(%d) Size(%d)",
-            buffer_prop->actualcount, buffer_prop->buffer_size);
+    DEBUG_PRINT_LOW("GetBufReq OUT: ActCnt(%d) Size(%u)",
+            buffer_prop->actualcount, (unsigned int)buffer_prop->buffer_size);
     return eRet;
 }
 
@@ -8249,14 +8624,15 @@
     struct v4l2_format fmt;
     struct v4l2_requestbuffers bufreq;
     int ret;
-    DEBUG_PRINT_LOW("SetBufReq IN: ActCnt(%d) Size(%d)",
-            buffer_prop->actualcount, buffer_prop->buffer_size);
+    DEBUG_PRINT_LOW("SetBufReq IN: ActCnt(%d) Size(%u)",
+            buffer_prop->actualcount, (unsigned int)buffer_prop->buffer_size);
     buf_size = (buffer_prop->buffer_size + buffer_prop->alignment - 1)&(~(buffer_prop->alignment - 1));
     if (buf_size != buffer_prop->buffer_size) {
-        DEBUG_PRINT_ERROR("Buffer size alignment error: Requested(%d) Required(%d)",
-                buffer_prop->buffer_size, buf_size);
+        DEBUG_PRINT_ERROR("Buffer size alignment error: Requested(%u) Required(%d)",
+                (unsigned int)buffer_prop->buffer_size, buf_size);
         eRet = OMX_ErrorBadParameter;
     } else {
+        memset(&fmt, 0x0, sizeof(struct v4l2_format));
         fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
         fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
 
@@ -8320,6 +8696,7 @@
 OMX_ERRORTYPE omx_vdec::update_portdef(OMX_PARAM_PORTDEFINITIONTYPE *portDefn)
 {
     OMX_ERRORTYPE eRet = OMX_ErrorNone;
+    struct v4l2_format fmt;
     if (!portDefn) {
         return OMX_ErrorBadParameter;
     }
@@ -8334,6 +8711,7 @@
         DEBUG_PRINT_ERROR("Error: Divide by zero");
         return OMX_ErrorBadParameter;
     }
+    memset(&fmt, 0x0, sizeof(struct v4l2_format));
     if (0 == portDefn->nPortIndex) {
         portDefn->eDir =  OMX_DirInput;
         portDefn->nBufferCountActual = drv_ctx.ip_buf.actualcount;
@@ -8343,6 +8721,9 @@
         portDefn->format.video.eCompressionFormat = eCompressionFormat;
         portDefn->bEnabled   = m_inp_bEnabled;
         portDefn->bPopulated = m_inp_bPopulated;
+
+        fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
+        fmt.fmt.pix_mp.pixelformat = output_capability;
     } else if (1 == portDefn->nPortIndex) {
         unsigned int buf_size = 0;
         if (!client_buffers.update_buffer_req()) {
@@ -8364,19 +8745,36 @@
             DEBUG_PRINT_ERROR("Error in getting color format");
             return OMX_ErrorHardware;
         }
+        fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
+        fmt.fmt.pix_mp.pixelformat = capture_capability;
     } else {
         portDefn->eDir = OMX_DirMax;
         DEBUG_PRINT_LOW(" get_parameter: Bad Port idx %d",
                 (int)portDefn->nPortIndex);
         eRet = OMX_ErrorBadPortIndex;
     }
+    if (is_down_scalar_enabled) {
+        int ret = 0;
+        ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_G_FMT, &fmt);
+        if (ret) {
+            DEBUG_PRINT_ERROR("update_portdef : Error in getting port resolution");
+            return OMX_ErrorHardware;
+        } else {
+            portDefn->format.video.nFrameWidth = fmt.fmt.pix_mp.width;
+            portDefn->format.video.nFrameHeight = fmt.fmt.pix_mp.height;
+            portDefn->format.video.nStride = fmt.fmt.pix_mp.plane_fmt[0].bytesperline;
+            portDefn->format.video.nSliceHeight = fmt.fmt.pix_mp.plane_fmt[0].reserved[0];
+        }
+    } else {
     portDefn->format.video.nFrameHeight =  drv_ctx.video_resolution.frame_height;
     portDefn->format.video.nFrameWidth  =  drv_ctx.video_resolution.frame_width;
     portDefn->format.video.nStride = drv_ctx.video_resolution.stride;
     portDefn->format.video.nSliceHeight = drv_ctx.video_resolution.scan_lines;
+    }
+
     if ((portDefn->format.video.eColorFormat == OMX_COLOR_FormatYUV420Planar) ||
        (portDefn->format.video.eColorFormat == OMX_COLOR_FormatYUV420SemiPlanar)) {
-        portDefn->format.video.nStride = drv_ctx.video_resolution.frame_width;
+           portDefn->format.video.nStride = ALIGN(drv_ctx.video_resolution.frame_width, 16);
         portDefn->format.video.nSliceHeight = drv_ctx.video_resolution.frame_height;
     }
     DEBUG_PRINT_HIGH("update_portdef(%u): Width = %u Height = %u Stride = %d "
@@ -8421,11 +8819,11 @@
         nPlatformEntrySize = drv_ctx.op_buf.actualcount *
             sizeof(OMX_QCOM_PLATFORM_PRIVATE_ENTRY);
 
-        DEBUG_PRINT_LOW("TotalBufHdr %d BufHdrSize %d PMEM %d PL %d",nBufHdrSize,
-                sizeof(OMX_BUFFERHEADERTYPE),
+        DEBUG_PRINT_LOW("TotalBufHdr %d BufHdrSize %u PMEM %d PL %d",nBufHdrSize,
+                (unsigned int)sizeof(OMX_BUFFERHEADERTYPE),
                 nPMEMInfoSize,
                 nPlatformListSize);
-        DEBUG_PRINT_LOW("PE %d bmSize %d",nPlatformEntrySize,
+        DEBUG_PRINT_LOW("PE %d bmSize % " PRId64 , nPlatformEntrySize,
                 m_out_bm_count);
         m_out_mem_ptr = (OMX_BUFFERHEADERTYPE  *)calloc(nBufHdrSize,1);
         // Alloc mem for platform specific info
@@ -8438,9 +8836,18 @@
         drv_ctx.ptr_respbuffer = (struct vdec_output_frameinfo  *)\
                      calloc (sizeof (struct vdec_output_frameinfo),
                              drv_ctx.op_buf.actualcount);
+        if (!drv_ctx.ptr_outputbuffer || !drv_ctx.ptr_respbuffer) {
+            DEBUG_PRINT_ERROR("Failed to alloc drv_ctx.ptr_outputbuffer or drv_ctx.ptr_respbuffer");
+            return OMX_ErrorInsufficientResources;
+        }
+
 #ifdef USE_ION
         drv_ctx.op_buf_ion_info = (struct vdec_ion * ) \
                       calloc (sizeof(struct vdec_ion),drv_ctx.op_buf.actualcount);
+        if (!drv_ctx.op_buf_ion_info) {
+            DEBUG_PRINT_ERROR("Failed to alloc drv_ctx.op_buf_ion_info");
+            return OMX_ErrorInsufficientResources;
+        }
 #endif
         if (dynamic_buf_mode) {
             out_dynamic_list = (struct dynamic_buf_list *) \
@@ -8593,7 +9000,7 @@
             && llabs(act_timestamp - prev_ts) > 2000) {
         new_frame_interval = client_set_fps ? frm_int :
             llabs(act_timestamp - prev_ts);
-        if (new_frame_interval < frm_int || frm_int == 0) {
+        if (new_frame_interval != frm_int || frm_int == 0) {
             frm_int = new_frame_interval;
             if (frm_int) {
                 drv_ctx.frame_rate.fps_numerator = 1e6;
@@ -8601,7 +9008,7 @@
                 DEBUG_PRINT_LOW("set_frame_rate: frm_int(%u) fps(%f)",
                         (unsigned int)frm_int, drv_ctx.frame_rate.fps_numerator /
                         (float)drv_ctx.frame_rate.fps_denominator);
-                m_perf_control.request_cores(frm_int);
+                //m_perf_control.request_cores(frm_int);
                 /* We need to report the difference between this FBD and the previous FBD
                  * back to the driver for clock scaling purposes. */
                 struct v4l2_outputparm oparm;
@@ -8631,16 +9038,20 @@
         rst_prev_ts = false;
     } else if (VALID_TS(prev_ts)) {
         bool codec_cond = (drv_ctx.timestamp_adjust)?
-            (!VALID_TS(act_timestamp) || (((act_timestamp > prev_ts)?
-                               (act_timestamp - prev_ts):(prev_ts - act_timestamp)) <= 2000)):
-            (!VALID_TS(act_timestamp) || act_timestamp == prev_ts);
+            (!VALID_TS(act_timestamp) || act_timestamp < prev_ts || llabs(act_timestamp - prev_ts) <= 2000) :
+            (!VALID_TS(act_timestamp) || act_timestamp <= prev_ts);
         if (frm_int > 0 && codec_cond) {
             DEBUG_PRINT_LOW("adjust_timestamp: original ts[%lld]", act_timestamp);
             act_timestamp = prev_ts + frm_int;
             DEBUG_PRINT_LOW("adjust_timestamp: predicted ts[%lld]", act_timestamp);
             prev_ts = act_timestamp;
-        } else
+        } else {
+            if (drv_ctx.picture_order == VDEC_ORDER_DISPLAY && act_timestamp < prev_ts) {
+                // ensure that timestamps can never step backwards when in display order
+                act_timestamp = prev_ts;
+            }
             set_frame_rate(act_timestamp);
+        }
     } else if (frm_int > 0)          // In this case the frame rate was set along
     {                               // with the port definition, start ts with 0
         act_timestamp = prev_ts = 0;  // and correct if a valid ts is received.
@@ -8659,6 +9070,9 @@
     OMX_U32 recovery_sei_flags = 1;
     int enable = 0;
 
+    //TODO: disable extradata
+    return;
+
     int buf_index = p_buf_hdr - m_out_mem_ptr;
     if (buf_index >= drv_ctx.extradata_info.count) {
         DEBUG_PRINT_ERROR("handle_extradata: invalid index(%d) max(%d)",
@@ -8687,6 +9101,7 @@
 
     if (!secure_mode && ((OMX_U8*)p_extra > (pBuffer + p_buf_hdr->nAllocLen))) {
         p_extra = NULL;
+        DEBUG_PRINT_ERROR("Error: out of bound memory access by p_extra");
         return;
     }
     OMX_OTHER_EXTRADATATYPE *data = (struct OMX_OTHER_EXTRADATATYPE *)p_extradata;
@@ -8793,6 +9208,10 @@
                     if (seqdisp_payload) {
                         m_disp_hor_size = seqdisp_payload->disp_width;
                         m_disp_vert_size = seqdisp_payload->disp_height;
+                        if (client_extradata & OMX_MPEG2SEQDISP_EXTRADATA) {
+                            append_mpeg2_seqdisplay_extradata(p_extra, seqdisp_payload);
+                            p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + p_extra->nSize);
+                        }
                     }
                     break;
                 case MSM_VIDC_EXTRADATA_S3D_FRAME_PACKING:
@@ -8850,7 +9269,7 @@
         p_buf_hdr->nFlags |= OMX_BUFFERFLAG_EXTRADATA;
         append_terminator_extradata(p_extra);
     }
-    if (secure_mode) {
+    if (secure_mode && p_extradata && m_other_extradata) {
         struct vdec_output_frameinfo  *ptr_extradatabuff = NULL;
         memcpy(p_extradata, m_other_extradata, drv_ctx.extradata_info.buffer_size);
         ptr_extradatabuff = (struct vdec_output_frameinfo *)p_buf_hdr->pOutputPortPrivate;
@@ -8917,13 +9336,6 @@
             if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
                 DEBUG_PRINT_HIGH("Failed to set panscan extradata");
             }
-            if (output_capability == V4L2_PIX_FMT_MPEG2) {
-                control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
-                control.value =  V4L2_MPEG_VIDC_EXTRADATA_MPEG2_SEQDISP;
-                if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
-                    DEBUG_PRINT_HIGH("Failed to set panscan extradata");
-                }
-                }
             }
         if (requested_extradata & OMX_TIMEINFO_EXTRADATA) {
             control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
@@ -8965,6 +9377,18 @@
                 DEBUG_PRINT_HIGH("Failed to set stream userdata extradata");
             }
         }
+        if (requested_extradata & OMX_MPEG2SEQDISP_EXTRADATA) {
+            if (output_capability == V4L2_PIX_FMT_MPEG2) {
+                DEBUG_PRINT_HIGH("Enable seq display extradata");
+                control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
+                control.value =  V4L2_MPEG_VIDC_EXTRADATA_MPEG2_SEQDISP;
+                if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
+                    DEBUG_PRINT_HIGH("Failed to set seqdisp extradata");
+                }
+            } else {
+                DEBUG_PRINT_HIGH("Seq display extradata is supported for MPEG2 only");
+            }
+        }
     }
     ret = get_buffer_req(&drv_ctx.op_buf);
     return ret;
@@ -9125,6 +9549,14 @@
                 }
         DEBUG_PRINT_HIGH(
                 "=========== End of Userdata ===========");
+    } else if (extra->eType == (OMX_EXTRADATATYPE)OMX_ExtraDataMpeg2SeqDisplay) {
+        OMX_QCOM_EXTRADATA_MPEG2SEQDISPLAY *seq_display = (OMX_QCOM_EXTRADATA_MPEG2SEQDISPLAY*)(void*)extra->data;
+        DEBUG_PRINT_HIGH(
+                "------Mpeg2SeqDisplay ------\n"
+                "     Frame Width: %d\n"
+                "    Frame Height: %d\n"
+                "=========== End of Mpeg2SeqDisplay ===========",
+                seq_display->disp_width, seq_display->disp_height);
     } else if (extra->eType == OMX_ExtraDataNone) {
         DEBUG_PRINT_HIGH("========== End of Terminator ===========");
     } else {
@@ -9173,7 +9605,6 @@
 void omx_vdec::append_frame_dimension_extradata(OMX_OTHER_EXTRADATATYPE *extra)
 {
     OMX_QCOM_EXTRADATA_FRAMEDIMENSION *frame_dimension;
-    OMX_U8* tmp = extra->data;
     if (!(client_extradata & OMX_FRAMEDIMENSION_EXTRADATA)) {
         return;
     }
@@ -9207,7 +9638,6 @@
 {
     OMX_QCOM_EXTRADATA_FRAMEINFO *frame_info = NULL;
     struct msm_vidc_panscan_window *panscan_window;
-    OMX_U8 *tmp = extra->data;
     if (!(client_extradata & OMX_FRAMEINFO_EXTRADATA)) {
         return;
     }
@@ -9269,7 +9699,6 @@
 void omx_vdec::append_portdef_extradata(OMX_OTHER_EXTRADATATYPE *extra)
 {
     OMX_PARAM_PORTDEFINITIONTYPE *portDefn = NULL;
-    OMX_U8 *tmp = extra->data;
     extra->nSize = OMX_PORTDEF_EXTRADATA_SIZE;
     extra->nVersion.nVersion = OMX_SPEC_VERSION;
     extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
@@ -9288,7 +9717,6 @@
         struct msm_vidc_s3d_frame_packing_payload *s3d_frame_packing_payload)
 {
     OMX_QCOM_FRAME_PACK_ARRANGEMENT *framepack;
-    OMX_U8* tmp = extra->data;
     if (FRAME_PACK_SIZE*sizeof(OMX_U32) != sizeof(struct msm_vidc_s3d_frame_packing_payload)) {
         DEBUG_PRINT_ERROR("frame packing size mismatch");
         return;
@@ -9313,7 +9741,6 @@
             struct msm_vidc_frame_qp_payload *qp_payload)
 {
     OMX_QCOM_EXTRADATA_QP * qp = NULL;
-    OMX_U8* tmp = extra->data;
     if (!qp_payload) {
         DEBUG_PRINT_ERROR("QP payload is NULL");
         return;
@@ -9332,7 +9759,6 @@
             struct msm_vidc_frame_bits_info_payload *bits_payload)
 {
     OMX_QCOM_EXTRADATA_BITS_INFO * bits = NULL;
-    OMX_U8* tmp = extra->data;
     if (!bits_payload) {
         DEBUG_PRINT_ERROR("bits info payload is NULL");
         return;
@@ -9353,11 +9779,10 @@
 {
     int userdata_size = 0;
     struct msm_vidc_stream_userdata_payload *userdata_payload = NULL;
-    OMX_U8* tmp = p_user->data;
     userdata_payload =
         (struct msm_vidc_stream_userdata_payload *)(void *)p_user->data;
     userdata_size = p_user->nDataSize;
-    extra->nSize = OMX_USERDATA_EXTRADATA_SIZE;
+    extra->nSize = OMX_USERDATA_EXTRADATA_SIZE + userdata_size;
     extra->nVersion.nVersion = OMX_SPEC_VERSION;
     extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
     extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataMP2UserData;
@@ -9367,6 +9792,20 @@
     print_debug_extradata(extra);
 }
 
+void omx_vdec::append_mpeg2_seqdisplay_extradata(OMX_OTHER_EXTRADATATYPE *extra,
+        struct msm_vidc_mpeg2_seqdisp_payload *seq_display_payload)
+{
+    OMX_QCOM_EXTRADATA_MPEG2SEQDISPLAY *seq_display = NULL;
+    extra->nSize = OMX_MPEG2SEQDISP_EXTRADATA_SIZE;
+    extra->nVersion.nVersion = OMX_SPEC_VERSION;
+    extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
+    extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataMpeg2SeqDisplay;
+    extra->nDataSize = sizeof(OMX_QCOM_EXTRADATA_MPEG2SEQDISPLAY);
+    seq_display = (OMX_QCOM_EXTRADATA_MPEG2SEQDISPLAY *)(void *)extra->data;
+    seq_display->disp_width = seq_display_payload->disp_width;
+    seq_display->disp_height = seq_display_payload->disp_height;
+    print_debug_extradata(extra);
+}
 void omx_vdec::append_terminator_extradata(OMX_OTHER_EXTRADATATYPE *extra)
 {
     if (!client_extradata) {
@@ -9609,8 +10048,9 @@
         if (!src_size || src_size > omx->drv_ctx.op_buf.buffer_size ||
                 !destination_size) {
             DEBUG_PRINT_ERROR("ERROR: Size mismatch in C2D src_size %d"
-                    "driver size %d destination size %d",
-                    src_size,omx->drv_ctx.op_buf.buffer_size,destination_size);
+                    "driver size %u destination size %d",
+                    src_size, (unsigned int)omx->drv_ctx.op_buf.buffer_size,
+                    destination_size);
             status = false;
             c2d.close();
             buffer_size_req = 0;
@@ -9708,6 +10148,7 @@
         bool status;
         if (!omx->in_reconfig && !omx->output_flush_progress && bufadd->nFilledLen) {
             pthread_mutex_lock(&omx->c_lock);
+            cache_clean_buffer(index);
             status = c2d.convert(omx->drv_ctx.ptr_outputbuffer[index].pmem_fd,
                     omx->m_out_mem_ptr->pBuffer, bufadd->pBuffer, pmem_fd[index],
                     pmem_baseaddress[index], pmem_baseaddress[index]);
@@ -9720,6 +10161,7 @@
                 unsigned int filledLen = 0;
                 c2d.get_output_filled_length(filledLen);
                 m_out_mem_ptr_client[index].nFilledLen = filledLen;
+                cache_clean_invalidate_buffer(index);
             }
             pthread_mutex_unlock(&omx->c_lock);
         } else
@@ -9841,16 +10283,19 @@
     }
     if ((temp_bufferHdr - omx->m_out_mem_ptr) >=
             (int)omx->drv_ctx.op_buf.actualcount) {
-        DEBUG_PRINT_ERROR("Invalid header index %d",
-                (temp_bufferHdr - omx->m_out_mem_ptr));
+        DEBUG_PRINT_ERROR("Invalid header index %ld",
+               (long int)(temp_bufferHdr - omx->m_out_mem_ptr));
         return OMX_ErrorUndefined;
     }
     unsigned int i = allocated_count;
 #ifdef USE_ION
+    // Allocate color-conversion buffers as cached to improve software-reading
+    // performance of YUV (thumbnails). NOTE: These buffers will need an explicit
+    // cache invalidation.
     op_buf_ion_info[i].ion_device_fd = omx->alloc_map_ion_memory(
             buffer_size_req,buffer_alignment_req,
             &op_buf_ion_info[i].ion_alloc_data,&op_buf_ion_info[i].fd_ion_data,
-            0);
+            ION_FLAG_CACHED);
     pmem_fd[i] = op_buf_ion_info[i].fd_ion_data.fd;
     if (op_buf_ion_info[i].ion_device_fd < 0) {
         DEBUG_PRINT_ERROR("alloc_map_ion failed in color_convert");
@@ -9867,7 +10312,7 @@
     }
     m_heap_ptr[i].video_heap_ptr = new VideoHeap (
             op_buf_ion_info[i].ion_device_fd,buffer_size_req,
-            pmem_baseaddress[i],(ion_handle*)op_buf_ion_info[i].ion_alloc_data.handle,pmem_fd[i]);
+            pmem_baseaddress[i],op_buf_ion_info[i].ion_alloc_data.handle,pmem_fd[i]);
 #endif
     m_pmem_info_client[i].pmem_fd = (unsigned long)m_heap_ptr[i].video_heap_ptr.get();
     m_pmem_info_client[i].offset = 0;
@@ -9919,10 +10364,59 @@
     return status;
 }
 
+OMX_ERRORTYPE omx_vdec::allocate_color_convert_buf::cache_ops(
+        unsigned int index, unsigned int cmd)
+{
+    if (!enabled) {
+        return OMX_ErrorNone;
+    }
+
+    if (!omx || index >= omx->drv_ctx.op_buf.actualcount) {
+        DEBUG_PRINT_ERROR("%s: Invalid param", __func__);
+        return OMX_ErrorBadParameter;
+    }
+
+    struct ion_flush_data flush_data;
+    struct ion_custom_data custom_data;
+
+    memset(&flush_data, 0x0, sizeof(flush_data));
+    memset(&custom_data, 0x0, sizeof(custom_data));
+
+    flush_data.vaddr = pmem_baseaddress[index];
+    flush_data.fd = op_buf_ion_info[index].fd_ion_data.fd;
+    flush_data.handle = op_buf_ion_info[index].fd_ion_data.handle;
+    flush_data.length = buffer_size_req;
+    custom_data.cmd = cmd;
+    custom_data.arg = (unsigned long)&flush_data;
+
+    DEBUG_PRINT_LOW("Cache %s: fd=%d handle=%d va=%p size=%d",
+            (cmd == ION_IOC_CLEAN_CACHES) ? "Clean" : "Invalidate",
+            flush_data.fd, flush_data.handle, flush_data.vaddr,
+            flush_data.length);
+    int ret = ioctl(op_buf_ion_info[index].ion_device_fd, ION_IOC_CUSTOM, &custom_data);
+    if (ret < 0) {
+        DEBUG_PRINT_ERROR("Cache %s failed: %s\n",
+                (cmd == ION_IOC_CLEAN_CACHES) ? "Clean" : "Invalidate",
+                strerror(errno));
+        return OMX_ErrorUndefined;
+    }
+    return OMX_ErrorNone;
+}
+
 void omx_vdec::buf_ref_add(OMX_U32 fd, OMX_U32 offset)
 {
     unsigned long i = 0;
     bool buf_present = false;
+
+    if (!dynamic_buf_mode) {
+        return;
+    }
+
+    if (!out_dynamic_list) {
+        DEBUG_PRINT_ERROR("buf_ref_add: out_dynamic_list is NULL");
+        return;
+    }
+
     pthread_mutex_lock(&m_lock);
     for (i = 0; i < drv_ctx.op_buf.actualcount; i++) {
         //check the buffer fd, offset, uv addr with list contents
@@ -9956,6 +10450,16 @@
 void omx_vdec::buf_ref_remove(OMX_U32 fd, OMX_U32 offset)
 {
     unsigned long i = 0;
+
+    if (!dynamic_buf_mode) {
+        return;
+    }
+
+    if (!out_dynamic_list) {
+        DEBUG_PRINT_ERROR("buf_ref_add: out_dynamic_list is NULL");
+        return;
+    }
+
     pthread_mutex_lock(&m_lock);
     for (i = 0; i < drv_ctx.op_buf.actualcount; i++) {
         //check the buffer fd, offset, uv addr with list contents
@@ -10084,14 +10588,112 @@
     }
 }
 
+OMX_ERRORTYPE omx_vdec::enable_adaptive_playback(unsigned long nMaxFrameWidth,
+                            unsigned long nMaxFrameHeight)
+{
+
+    OMX_ERRORTYPE eRet = OMX_ErrorNone;
+    int ret = 0;
+    unsigned long min_res_buf_count = 0;
+
+    eRet = enable_smoothstreaming();
+    if (eRet != OMX_ErrorNone) {
+         DEBUG_PRINT_ERROR("Failed to enable Adaptive Playback on driver");
+         return eRet;
+     }
+
+     DEBUG_PRINT_HIGH("Enabling Adaptive playback for %lu x %lu",
+             nMaxFrameWidth,
+             nMaxFrameHeight);
+     m_smoothstreaming_mode = true;
+     m_smoothstreaming_width = nMaxFrameWidth;
+     m_smoothstreaming_height = nMaxFrameHeight;
+
+     //Get upper limit buffer count for min supported resolution
+     struct v4l2_format fmt;
+     fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
+     fmt.fmt.pix_mp.height = m_decoder_capability.min_height;
+     fmt.fmt.pix_mp.width = m_decoder_capability.min_width;
+     fmt.fmt.pix_mp.pixelformat = output_capability;
+
+     ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
+     if (ret) {
+         DEBUG_PRINT_ERROR("Set Resolution failed for HxW = %ux%u",
+                           m_decoder_capability.min_height,
+                           m_decoder_capability.min_width);
+         return OMX_ErrorUnsupportedSetting;
+     }
+
+     eRet = get_buffer_req(&drv_ctx.op_buf);
+     if (eRet != OMX_ErrorNone) {
+         DEBUG_PRINT_ERROR("failed to get_buffer_req");
+         return eRet;
+     }
+
+     min_res_buf_count = drv_ctx.op_buf.mincount;
+     DEBUG_PRINT_LOW("enable adaptive - upper limit buffer count = %lu for HxW %ux%u",
+                     min_res_buf_count, m_decoder_capability.min_height, m_decoder_capability.min_width);
+
+     update_resolution(m_smoothstreaming_width, m_smoothstreaming_height,
+                       m_smoothstreaming_width, m_smoothstreaming_height);
+     eRet = is_video_session_supported();
+     if (eRet != OMX_ErrorNone) {
+         DEBUG_PRINT_ERROR("video session is not supported");
+         return eRet;
+     }
+
+     //Get upper limit buffer size for max smooth streaming resolution set
+     fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
+     fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
+     fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
+     fmt.fmt.pix_mp.pixelformat = output_capability;
+     ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
+     if (ret) {
+         DEBUG_PRINT_ERROR("Set Resolution failed for adaptive playback");
+         return OMX_ErrorUnsupportedSetting;
+     }
+
+     eRet = get_buffer_req(&drv_ctx.op_buf);
+     if (eRet != OMX_ErrorNone) {
+         DEBUG_PRINT_ERROR("failed to get_buffer_req!!");
+         return eRet;
+     }
+     DEBUG_PRINT_LOW("enable adaptive - upper limit buffer size = %u",
+                     (unsigned int)drv_ctx.op_buf.buffer_size);
+
+     drv_ctx.op_buf.mincount = min_res_buf_count;
+     drv_ctx.op_buf.actualcount = min_res_buf_count;
+     eRet = set_buffer_req(&drv_ctx.op_buf);
+     if (eRet != OMX_ErrorNone) {
+         DEBUG_PRINT_ERROR("failed to set_buffer_req");
+         return eRet;
+     }
+
+     eRet = get_buffer_req(&drv_ctx.op_buf);
+     if (eRet != OMX_ErrorNone) {
+         DEBUG_PRINT_ERROR("failed to get_buffer_req!!!");
+         return eRet;
+     }
+     DEBUG_PRINT_HIGH("adaptive playback enabled, buf count = %u bufsize = %u",
+                      drv_ctx.op_buf.mincount, (unsigned int)drv_ctx.op_buf.buffer_size);
+     return eRet;
+}
 
 //static
-OMX_ERRORTYPE omx_vdec::describeColorFormat(DescribeColorFormatParams *params) {
-    if (params == NULL) {
+OMX_ERRORTYPE omx_vdec::describeColorFormat(OMX_PTR pParam) {
+
+#ifndef FLEXYUV_SUPPORTED
+    (void) pParam;
+    return OMX_ErrorUndefined;
+#else
+
+    if (pParam == NULL) {
         DEBUG_PRINT_ERROR("describeColorFormat: invalid params");
         return OMX_ErrorBadParameter;
     }
 
+    DescribeColorFormatParams *params = (DescribeColorFormatParams*)pParam;
+
     MediaImage *img = &(params->sMediaImage);
     switch(params->eColorFormat) {
         case QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m:
@@ -10149,4 +10751,5 @@
                 i, img->mPlane[i].mOffset, img->mPlane[i].mColInc, img->mPlane[i].mRowInc);
     }
     return OMX_ErrorNone;
+#endif //FLEXYUV_SUPPORTED
 }
diff --git a/mm-video-v4l2/vidc/vdec/src/ts_parser.cpp b/mm-video-v4l2/vidc/vdec/src/ts_parser.cpp
old mode 100755
new mode 100644
index ce6779a..809a1f7
--- a/mm-video-v4l2/vidc/vdec/src/ts_parser.cpp
+++ b/mm-video-v4l2/vidc/vdec/src/ts_parser.cpp
@@ -1,5 +1,5 @@
 /*--------------------------------------------------------------------------
-Copyright (c) 2010-2013, The Linux Foundation. All rights reserved.
+Copyright (c) 2010-2015, The Linux Foundation. All rights reserved.
 
 Redistribution and use in source and binary forms, with or without
 modification, are permitted provided that the following conditions are met:
@@ -32,17 +32,20 @@
 
 void omx_time_stamp_reorder::set_timestamp_reorder_mode(bool mode)
 {
+    auto_lock l(&m_lock);
     reorder_ts = mode;
 }
 
 void omx_time_stamp_reorder::enable_debug_print(bool flag)
 {
+    auto_lock l(&m_lock);
     print_debug = flag;
 }
 
 omx_time_stamp_reorder::~omx_time_stamp_reorder()
 {
     delete_list();
+    pthread_mutex_destroy(&m_lock);
 }
 
 omx_time_stamp_reorder::omx_time_stamp_reorder()
@@ -51,6 +54,7 @@
     phead = pcurrent = NULL;
     error = false;
     print_debug = false;
+    pthread_mutex_init(&m_lock, NULL);
 }
 
 void omx_time_stamp_reorder::delete_list()
@@ -143,6 +147,7 @@
 
 bool omx_time_stamp_reorder::insert_timestamp(OMX_BUFFERHEADERTYPE *header)
 {
+    auto_lock l(&m_lock);
     OMX_TICKS *table_entry = NULL;
 
     if (!reorder_ts || error || !header) {
@@ -209,6 +214,7 @@
 
 bool omx_time_stamp_reorder::remove_time_stamp(OMX_TICKS ts, bool is_interlaced = false)
 {
+    auto_lock l(&m_lock);
     unsigned int num_ent_remove = (is_interlaced)?2:1;
 
     if (!reorder_ts || error) {
@@ -241,11 +247,13 @@
 
 void omx_time_stamp_reorder::flush_timestamp()
 {
+    auto_lock l(&m_lock);
     delete_list();
 }
 
 bool omx_time_stamp_reorder::get_next_timestamp(OMX_BUFFERHEADERTYPE *header, bool is_interlaced)
 {
+    auto_lock l(&m_lock);
     timestamp *element = NULL,*duplicate = NULL;
     bool status = false;
 
diff --git a/mm-video-v4l2/vidc/venc.mk b/mm-video-v4l2/vidc/venc.mk
index 5c022a9..1c5ec3e 100644
--- a/mm-video-v4l2/vidc/venc.mk
+++ b/mm-video-v4l2/vidc/venc.mk
@@ -57,7 +57,7 @@
 libmm-venc-def += -D_MSM8974_
 libmm-venc-def += -D_ION_HEAP_MASK_COMPATIBILITY_WA
 endif
-ifeq ($(TARGET_BOARD_PLATFORM),mpq8092)
+ifeq ($(TARGET_BOARD_PLATFORM),msm8992)
 libmm-venc-def += -DMAX_RES_1080P
 libmm-venc-def += -DMAX_RES_1080P_EBI
 libOmxVdec-def += -DPROCESS_EXTRADATA_IN_OUTPUT_PORT
@@ -98,7 +98,7 @@
 
 LOCAL_SRC_FILES   := venc/src/omx_video_base.cpp
 LOCAL_SRC_FILES   += venc/src/omx_video_encoder.cpp
-ifneq ($(filter msm8974 msm8610 msm8226 msm8084 mpq8092,$(TARGET_BOARD_PLATFORM)),)
+ifneq ($(filter msm8974 msm8610 msm8226 msm8084 msm8992,$(TARGET_BOARD_PLATFORM)),)
 LOCAL_SRC_FILES   += venc/src/video_encoder_device_v4l2.cpp
 else
 LOCAL_SRC_FILES   += venc/src/video_encoder_device.cpp
diff --git a/mm-video-v4l2/vidc/venc/inc/omx_video_base.h b/mm-video-v4l2/vidc/venc/inc/omx_video_base.h
old mode 100755
new mode 100644
index 3c482e8..50153ad
--- a/mm-video-v4l2/vidc/venc/inc/omx_video_base.h
+++ b/mm-video-v4l2/vidc/venc/inc/omx_video_base.h
@@ -125,10 +125,10 @@
         (unsigned)((OMX_BUFFERHEADERTYPE *)bufHdr)->nTimeStamp)
 
 // BitMask Management logic
-#define BITS_PER_BYTE        32
-#define BITMASK_SIZE(mIndex) (((mIndex) + BITS_PER_BYTE - 1)/BITS_PER_BYTE)
-#define BITMASK_OFFSET(mIndex) ((mIndex)/BITS_PER_BYTE)
-#define BITMASK_FLAG(mIndex) (1 << ((mIndex) % BITS_PER_BYTE))
+#define BITS_PER_INDEX        64
+#define BITMASK_SIZE(mIndex) (((mIndex) + BITS_PER_INDEX - 1)/BITS_PER_INDEX)
+#define BITMASK_OFFSET(mIndex) ((mIndex)/BITS_PER_INDEX)
+#define BITMASK_FLAG(mIndex) ((uint64_t)1 << ((mIndex) % BITS_PER_INDEX))
 #define BITMASK_CLEAR(mArray,mIndex) (mArray)[BITMASK_OFFSET(mIndex)] \
     &=  ~(BITMASK_FLAG(mIndex))
 #define BITMASK_SET(mArray,mIndex)  (mArray)[BITMASK_OFFSET(mIndex)] \
@@ -142,7 +142,7 @@
 #define BITMASK_ABSENT(mArray,mIndex) (((mArray)[BITMASK_OFFSET(mIndex)] \
             & BITMASK_FLAG(mIndex)) == 0x0)
 #ifdef _ANDROID_ICS_
-#define MAX_NUM_INPUT_BUFFERS 32
+#define MAX_NUM_INPUT_BUFFERS 64
 #endif
 void* message_thread(void *);
 
@@ -155,13 +155,11 @@
         bool c2d_opened;
         encoder_media_buffer_type meta_buffers[MAX_NUM_INPUT_BUFFERS];
         OMX_BUFFERHEADERTYPE *opaque_buffer_hdr[MAX_NUM_INPUT_BUFFERS];
-        bool mUseProxyColorFormat;
-        //RGB or non-native input, and we have pre-allocated conversion buffers
-        bool mUsesColorConversion;
         bool get_syntaxhdr_enable;
         OMX_BUFFERHEADERTYPE  *psource_frame;
         OMX_BUFFERHEADERTYPE  *pdest_frame;
         bool secure_session;
+        bool hier_b_enabled;
         //intermediate conversion buffer queued to encoder in case of invalid EOS input
         OMX_BUFFERHEADERTYPE  *mEmptyEosBuffer;
 
@@ -190,6 +188,11 @@
         omx_c2d_conv c2d_conv;
 #endif
     public:
+
+        bool mUseProxyColorFormat;
+        //RGB or non-native input, and we have pre-allocated conversion buffers
+        bool mUsesColorConversion;
+
         omx_video();  // constructor
         virtual ~omx_video();  // destructor
 
@@ -221,7 +224,7 @@
         virtual bool dev_empty_buf(void *, void *,unsigned,unsigned) = 0;
         virtual bool dev_fill_buf(void *buffer, void *,unsigned,unsigned) = 0;
         virtual bool dev_get_buf_req(OMX_U32 *,OMX_U32 *,OMX_U32 *,OMX_U32) = 0;
-        virtual bool dev_get_seq_hdr(void *, unsigned, OMX_U32 *) = 0;
+        virtual bool dev_get_seq_hdr(void *, unsigned, unsigned *) = 0;
         virtual bool dev_loaded_start(void) = 0;
         virtual bool dev_loaded_stop(void) = 0;
         virtual bool dev_loaded_start_done(void) = 0;
@@ -522,11 +525,22 @@
         inline void omx_report_error () {
             if (m_pCallbacks.EventHandler && !m_error_propogated) {
                 m_error_propogated = true;
+                DEBUG_PRINT_ERROR("ERROR: send OMX_ErrorHardware to Client");
                 m_pCallbacks.EventHandler(&m_cmp,m_app_data,
                         OMX_EventError,OMX_ErrorHardware,0,NULL);
             }
         }
 
+        inline void omx_report_hw_overload ()
+        {
+            if (m_pCallbacks.EventHandler && !m_error_propogated) {
+                m_error_propogated = true;
+                DEBUG_PRINT_ERROR("ERROR: send OMX_ErrorInsufficientResources to Client");
+                m_pCallbacks.EventHandler(&m_cmp, m_app_data,
+                        OMX_EventError, OMX_ErrorInsufficientResources, 0, NULL);
+            }
+        }
+
         inline void omx_report_unsupported_setting () {
             if (m_pCallbacks.EventHandler && !m_error_propogated) {
                 m_error_propogated = true;
@@ -575,6 +589,7 @@
         OMX_VIDEO_PARAM_H263TYPE m_sParamH263;
         OMX_VIDEO_PARAM_AVCTYPE m_sParamAVC;
         OMX_VIDEO_PARAM_VP8TYPE m_sParamVP8;
+        OMX_VIDEO_PARAM_HEVCTYPE m_sParamHEVC;
         OMX_PORT_PARAM_TYPE m_sPortParam_img;
         OMX_PORT_PARAM_TYPE m_sPortParam_audio;
         OMX_VIDEO_CONFIG_BITRATETYPE m_sConfigBitrate;
@@ -623,11 +638,11 @@
         int pending_input_buffers;
         int pending_output_buffers;
 
-        unsigned int m_out_bm_count;
-        unsigned int m_inp_bm_count;
-        unsigned int m_flags;
-        unsigned int m_etb_count;
-        unsigned int m_fbd_count;
+        uint64_t m_out_bm_count;
+        uint64_t m_inp_bm_count;
+        uint64_t m_flags;
+        uint64_t m_etb_count;
+        uint64_t m_fbd_count;
 #ifdef _ANDROID_
         // Heap pointer to frame buffers
         sp<MemoryHeapBase>    m_heap_ptr;
@@ -636,6 +651,7 @@
         bool m_event_port_settings_sent;
         OMX_U8                m_cRole[OMX_MAX_STRINGNAME_SIZE];
         extra_data_handler extra_data_handle;
+        bool hw_overload;
 
 };
 
diff --git a/mm-video-v4l2/vidc/venc/inc/omx_video_encoder.h b/mm-video-v4l2/vidc/venc/inc/omx_video_encoder.h
old mode 100755
new mode 100644
index 0d9c2ff..d7b21db
--- a/mm-video-v4l2/vidc/venc/inc/omx_video_encoder.h
+++ b/mm-video-v4l2/vidc/venc/inc/omx_video_encoder.h
@@ -78,7 +78,7 @@
         bool dev_get_buf_req(OMX_U32 *,OMX_U32 *,OMX_U32 *,OMX_U32);
         bool dev_set_buf_req(OMX_U32 *,OMX_U32 *,OMX_U32 *,OMX_U32);
         bool update_profile_level();
-        bool dev_get_seq_hdr(void *, unsigned, OMX_U32 *);
+        bool dev_get_seq_hdr(void *, unsigned, unsigned *);
         bool dev_loaded_start(void);
         bool dev_loaded_stop(void);
         bool dev_loaded_start_done(void);
diff --git a/mm-video-v4l2/vidc/venc/inc/video_encoder_device.h b/mm-video-v4l2/vidc/venc/inc/video_encoder_device.h
old mode 100755
new mode 100644
index 1289237..fde041d
--- a/mm-video-v4l2/vidc/venc/inc/video_encoder_device.h
+++ b/mm-video-v4l2/vidc/venc/inc/video_encoder_device.h
@@ -73,7 +73,7 @@
         bool venc_set_config(void *configData, OMX_INDEXTYPE index);
         bool venc_get_profile_level(OMX_U32 *eProfile,OMX_U32 *eLevel);
         bool venc_max_allowed_bitrate_check(OMX_U32 nTargetBitrate);
-        bool venc_get_seq_hdr(void *, unsigned, OMX_U32 *);
+        bool venc_get_seq_hdr(void *, unsigned, unsigned *);
         bool venc_loaded_start(void);
         bool venc_loaded_stop(void);
         bool venc_loaded_start_done(void);
diff --git a/mm-video-v4l2/vidc/venc/inc/video_encoder_device_v4l2.h b/mm-video-v4l2/vidc/venc/inc/video_encoder_device_v4l2.h
old mode 100755
new mode 100644
index 64482bf..f97256e
--- a/mm-video-v4l2/vidc/venc/inc/video_encoder_device_v4l2.h
+++ b/mm-video-v4l2/vidc/venc/inc/video_encoder_device_v4l2.h
@@ -38,14 +38,18 @@
 #include "omx_video_base.h"
 #include "omx_video_encoder.h"
 #include <linux/videodev2.h>
-#include <linux/fb.h>
 #include <poll.h>
-#include <gui/ISurfaceComposer.h>
-#include <gui/SurfaceComposerClient.h>
-#include <ui/DisplayInfo.h>
 
 #define TIMEOUT 5*60*1000
+#define BIT(num) (1 << (num))
+#define MAX_HYB_HIERP_LAYERS 6
 
+enum hier_type {
+    HIER_NONE = 0x0,
+    HIER_P = 0x1,
+    HIER_B = 0x2,
+    HIER_P_HYBRID = 0x3,
+};
 
 struct msm_venc_switch {
     unsigned char    status;
@@ -187,6 +191,7 @@
 
 struct msm_venc_hierlayers {
     unsigned int numlayers;
+    enum hier_type hier_mode;
 };
 
 struct msm_venc_ltrinfo {
@@ -206,6 +211,10 @@
     unsigned int peakbitrate;
 };
 
+struct msm_venc_vpx_error_resilience {
+    unsigned int enable;
+};
+
 enum v4l2_ports {
     CAPTURE_PORT,
     OUTPUT_PORT,
@@ -223,6 +232,15 @@
 #endif
 };
 
+enum rc_modes {
+    RC_VBR_VFR = BIT(0),
+    RC_VBR_CFR = BIT(1),
+    RC_CBR_VFR = BIT(2),
+    RC_CBR_CFR = BIT(3),
+    RC_ALL = (RC_VBR_VFR | RC_VBR_CFR
+        | RC_CBR_VFR | RC_CBR_CFR)
+};
+
 class venc_dev
 {
     public:
@@ -255,7 +273,7 @@
         bool venc_set_param(void *,OMX_INDEXTYPE);
         bool venc_set_config(void *configData, OMX_INDEXTYPE index);
         bool venc_get_profile_level(OMX_U32 *eProfile,OMX_U32 *eLevel);
-        bool venc_get_seq_hdr(void *, unsigned, OMX_U32 *);
+        bool venc_get_seq_hdr(void *, unsigned, unsigned *);
         bool venc_loaded_start(void);
         bool venc_loaded_stop(void);
         bool venc_loaded_start_done(void);
@@ -302,6 +320,7 @@
         bool handle_extradata(void *, int);
         int venc_set_format(int);
         bool deinterlace_enabled;
+        bool hw_overload;
     private:
         OMX_U32                             m_codec;
         struct msm_venc_basecfg             m_sVenc_cfg;
@@ -327,10 +346,12 @@
         struct msm_venc_video_capability    capability;
         struct msm_venc_idrperiod           idrperiod;
         struct msm_venc_slice_delivery      slice_mode;
-        struct msm_venc_hierlayers          hier_p_layers;
+        struct msm_venc_hierlayers          hier_layers;
         struct msm_venc_perf_level          performance_level;
         struct msm_venc_vui_timing_info     vui_timing_info;
         struct msm_venc_peak_bitrate        peak_bitrate;
+        struct msm_venc_ltrinfo             ltrinfo;
+        struct msm_venc_vpx_error_resilience vpx_err_resilience;
 
         bool venc_set_profile_level(OMX_U32 eProfile,OMX_U32 eLevel);
         bool venc_set_intra_period(OMX_U32 nPFrames, OMX_U32 nBFrames);
@@ -356,9 +377,9 @@
         bool venc_set_vpe_rotation(OMX_S32 rotation_angle);
         bool venc_set_deinterlace(OMX_U32 enable);
         bool venc_set_ltrmode(OMX_U32 enable, OMX_U32 count);
-        bool venc_set_useltr();
-        bool venc_set_markltr();
 	bool venc_enable_initial_qp(QOMX_EXTNINDEX_VIDEO_INITIALQP* initqp);
+        bool venc_set_useltr(OMX_U32 frameIdx);
+        bool venc_set_markltr(OMX_U32 frameIdx);
         bool venc_set_inband_video_header(OMX_BOOL enable);
         bool venc_set_au_delimiter(OMX_BOOL enable);
         bool venc_set_hier_layers(QOMX_VIDEO_HIERARCHICALCODINGTYPE type, OMX_U32 num_layers);
@@ -366,6 +387,11 @@
         bool venc_set_vui_timing_info(OMX_BOOL enable);
         bool venc_set_peak_bitrate(OMX_U32 nPeakBitrate);
         bool venc_set_searchrange();
+        bool venc_set_vpx_error_resilience(OMX_BOOL enable);
+        bool venc_set_perf_mode(OMX_U32 mode);
+        bool venc_set_hybrid_hierp(OMX_U32 layers);
+        bool venc_calibrate_gop();
+        bool venc_validate_hybridhp_params(OMX_U32 layers, OMX_U32 bFrames, OMX_U32 count, int mode);
 
 #ifdef MAX_RES_1080P
         OMX_U32 pmem_free();
@@ -392,7 +418,8 @@
         int color_format;
         bool is_searchrange_set;
         bool enable_mv_narrow_searchrange;
-        DisplayInfo display_info;
+        int supported_rc_modes;
+        bool camera_mode_enabled;
 };
 
 enum instance_state {
diff --git a/mm-video-v4l2/vidc/venc/src/omx_video_base.cpp b/mm-video-v4l2/vidc/venc/src/omx_video_base.cpp
old mode 100755
new mode 100644
index 4738665..9e3ecbb
--- a/mm-video-v4l2/vidc/venc/src/omx_video_base.cpp
+++ b/mm-video-v4l2/vidc/venc/src/omx_video_base.cpp
@@ -1,5 +1,5 @@
 /*--------------------------------------------------------------------------
-Copyright (c) 2010-2014, Linux Foundation. All rights reserved.
+Copyright (c) 2010-2015, Linux Foundation. All rights reserved.
 
 Redistribution and use in source and binary forms, with or without
 modification, are permitted provided that the following conditions are met:
@@ -38,6 +38,8 @@
 //                             Include Files
 //////////////////////////////////////////////////////////////////////////////
 
+#define __STDC_FORMAT_MACROS //enables the format specifiers in inttypes.h
+#include <inttypes.h>
 #include <string.h>
 #include "omx_video_base.h"
 #include <stdlib.h>
@@ -210,7 +212,6 @@
    ========================================================================== */
 omx_video::omx_video():
     c2d_opened(false),
-    mUsesColorConversion(false),
     psource_frame(NULL),
     pdest_frame(NULL),
     secure_session(false),
@@ -240,7 +241,8 @@
     m_flags(0),
     m_etb_count(0),
     m_fbd_count(0),
-    m_event_port_settings_sent(false)
+    m_event_port_settings_sent(false),
+    hw_overload(false)
 {
     DEBUG_PRINT_HIGH("omx_video(): Inside Constructor()");
     memset(&m_cmp,0,sizeof(m_cmp));
@@ -248,8 +250,10 @@
     async_thread_created = false;
     msg_thread_created = false;
 
+    mUsesColorConversion = false;
     pthread_mutex_init(&m_lock, NULL);
     sem_init(&m_cmd_lock,0,0);
+    DEBUG_PRINT_LOW("meta_buffer_hdr = %p", meta_buffer_hdr);
 }
 
 
@@ -283,10 +287,10 @@
 #endif
     pthread_mutex_destroy(&m_lock);
     sem_destroy(&m_cmd_lock);
-    DEBUG_PRINT_HIGH("m_etb_count = %u, m_fbd_count = %u", m_etb_count,
+    DEBUG_PRINT_HIGH("m_etb_count = %" PRIu64 ", m_fbd_count = %" PRIu64, m_etb_count,
             m_fbd_count);
     DEBUG_PRINT_HIGH("omx_video: Destructor exit");
-    DEBUG_PRINT_HIGH("Exiting 7x30 OMX Video Encoder ...");
+    DEBUG_PRINT_HIGH("Exiting OMX Video Encoder ...");
 }
 
 /* ======================================================================
@@ -405,13 +409,18 @@
                         pThis->omx_report_error ();
                     }
                     break;
-                case OMX_COMPONENT_GENERATE_ETB:
+                case OMX_COMPONENT_GENERATE_ETB: {
+                        OMX_ERRORTYPE iret;
                     DEBUG_PRINT_LOW("OMX_COMPONENT_GENERATE_ETB");
-                    if (pThis->empty_this_buffer_proxy((OMX_HANDLETYPE)p1,\
-                                (OMX_BUFFERHEADERTYPE *)p2) != OMX_ErrorNone) {
-                        DEBUG_PRINT_ERROR("ERROR: ETBProxy() failed!");
+                        iret = pThis->empty_this_buffer_proxy((OMX_HANDLETYPE)p1, (OMX_BUFFERHEADERTYPE *)p2);
+                        if (iret == OMX_ErrorInsufficientResources) {
+                            DEBUG_PRINT_ERROR("empty_this_buffer_proxy failure due to HW overload");
+                            pThis->omx_report_hw_overload ();
+                        } else if (iret != OMX_ErrorNone) {
+                            DEBUG_PRINT_ERROR("empty_this_buffer_proxy failure");
                         pThis->omx_report_error ();
                     }
+                    }
                     break;
 
                 case OMX_COMPONENT_GENERATE_FTB:
@@ -446,7 +455,7 @@
                 case OMX_COMPONENT_GENERATE_EVENT_INPUT_FLUSH:
 
                     pThis->input_flush_progress = false;
-                    DEBUG_PRINT_HIGH("m_etb_count at i/p flush = %u", m_etb_count);
+                    DEBUG_PRINT_HIGH("m_etb_count at i/p flush = %" PRIu64, m_etb_count);
                     m_etb_count = 0;
                     if (pThis->m_pCallbacks.EventHandler) {
                         /*Check if we need generate event for Flush done*/
@@ -473,7 +482,7 @@
                 case OMX_COMPONENT_GENERATE_EVENT_OUTPUT_FLUSH:
 
                     pThis->output_flush_progress = false;
-                    DEBUG_PRINT_HIGH("m_fbd_count at o/p flush = %u", m_fbd_count);
+                    DEBUG_PRINT_HIGH("m_fbd_count at o/p flush = %" PRIu64, m_fbd_count);
                     m_fbd_count = 0;
                     if (pThis->m_pCallbacks.EventHandler) {
                         /*Check if we need generate event for Flush done*/
@@ -526,7 +535,7 @@
                             }
                             BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_LOADED_START_PENDING);
                         } else {
-                            DEBUG_PRINT_LOW("ERROR: unknown flags=%x",pThis->m_flags);
+                            DEBUG_PRINT_LOW("ERROR: unknown flags=%" PRIx64, pThis->m_flags);
                         }
                     } else {
                         DEBUG_PRINT_LOW("Event Handler callback is NULL");
@@ -586,7 +595,7 @@
                             }
                             BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_LOADED_STOP_PENDING);
                         } else {
-                            DEBUG_PRINT_LOW("ERROR: unknown flags=%x",pThis->m_flags);
+                            DEBUG_PRINT_LOW("ERROR: unknown flags=%" PRIx64, pThis->m_flags);
                         }
                     }
 
@@ -1455,10 +1464,12 @@
                     }
 #endif
                 } else if (portDefn->nPortIndex == (OMX_U32) PORT_INDEX_OUT) {
+                    if (m_state != OMX_StateExecuting) {
                     dev_get_buf_req (&m_sOutPortDef.nBufferCountMin,
                             &m_sOutPortDef.nBufferCountActual,
                             &m_sOutPortDef.nBufferSize,
                             m_sOutPortDef.nPortIndex);
+                    }
                     DEBUG_PRINT_LOW("m_sOutPortDef: size = %u, min cnt = %u, actual cnt = %u",
                             (unsigned int)m_sOutPortDef.nBufferSize, (unsigned int)m_sOutPortDef.nBufferCountMin,
                             (unsigned int)m_sOutPortDef.nBufferCountActual);
@@ -1497,7 +1508,7 @@
                         [2] = OMX_COLOR_FormatYUV420SemiPlanar,
                     };
 
-                    if (index >= sizeof(supportedFormats)/sizeof(*supportedFormats))
+                    if (index > (sizeof(supportedFormats)/sizeof(*supportedFormats) - 1))
                         eRet = OMX_ErrorNoMore;
                     else {
                         memcpy(portFmt, &m_sInPortFormat, sizeof(m_sInPortFormat));
@@ -1554,6 +1565,13 @@
                 memcpy(pParam, &m_sParamVP8, sizeof(m_sParamVP8));
                 break;
             }
+        case (OMX_INDEXTYPE)OMX_IndexParamVideoHevc:
+            {
+                OMX_VIDEO_PARAM_HEVCTYPE* pParam = (OMX_VIDEO_PARAM_HEVCTYPE*)paramData;
+                DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoHevc");
+                memcpy(pParam, &m_sParamHEVC, sizeof(m_sParamHEVC));
+                break;
+            }
         case OMX_IndexParamVideoProfileLevelQuerySupported:
             {
                 OMX_VIDEO_PARAM_PROFILELEVELTYPE* pParam = (OMX_VIDEO_PARAM_PROFILELEVELTYPE*)paramData;
@@ -1750,6 +1768,14 @@
                 }
             }
             break;
+        case OMX_QcomIndexParamVideoLTRCount:
+            {
+                DEBUG_PRINT_LOW("get_parameter: OMX_QcomIndexParamVideoLTRCount");
+                OMX_QCOM_VIDEO_PARAM_LTRCOUNT_TYPE *pParam =
+                        reinterpret_cast<OMX_QCOM_VIDEO_PARAM_LTRCOUNT_TYPE*>(paramData);
+                memcpy(pParam, &m_sParamLTRCount, sizeof(m_sParamLTRCount));
+                break;
+            }
 #endif
         case QOMX_IndexParamVideoSyntaxHdr:
             {
@@ -1776,7 +1802,7 @@
                 }
                 if (dev_get_seq_hdr(pParam->pData,
                             (unsigned)(pParam->nSize - sizeof(QOMX_EXTNINDEX_PARAMTYPE)),
-                            (OMX_U32 *)(void *)&pParam->nDataSize)) {
+                            (unsigned *)(void *)&pParam->nDataSize)) {
                     DEBUG_PRINT_HIGH("get syntax header successful (hdrlen = %u)",
                             (unsigned int)pParam->nDataSize);
                     for (unsigned i = 0; i < pParam->nDataSize; i++) {
@@ -1953,6 +1979,20 @@
                memcpy(pParam, &m_sConfigVp8ReferenceFrame, sizeof(m_sConfigVp8ReferenceFrame));
                break;
            }
+        case OMX_QcomIndexConfigPerfLevel:
+            {
+                OMX_U32 perflevel;
+                OMX_QCOM_VIDEO_CONFIG_PERF_LEVEL *pParam =
+                    reinterpret_cast<OMX_QCOM_VIDEO_CONFIG_PERF_LEVEL*>(configData);
+                DEBUG_PRINT_LOW("get_config: OMX_QcomIndexConfigPerfLevel");
+                if (!dev_get_performance_level(&perflevel)) {
+                    DEBUG_PRINT_ERROR("Invalid entry returned from get_performance_level %d",
+                        pParam->ePerfLevel);
+                } else {
+                    pParam->ePerfLevel = (QOMX_VIDEO_PERF_LEVEL)perflevel;
+                }
+                break;
+            }
         default:
             DEBUG_PRINT_ERROR("ERROR: unsupported index %d", (int) configIndex);
             return OMX_ErrorUnsupportedIndex;
@@ -2096,6 +2136,7 @@
             DEBUG_PRINT_ERROR("ERROR: calloc() Failed for m_inp_mem_ptr");
             return OMX_ErrorInsufficientResources;
         }
+        DEBUG_PRINT_LOW("Successfully allocated m_inp_mem_ptr = %p", m_inp_mem_ptr);
 
 
         m_pInput_pmem = (struct pmem *) calloc(sizeof (struct pmem), m_sInPortDef.nBufferCountActual);
@@ -2492,7 +2533,7 @@
         return OMX_ErrorBadParameter;
     }
 
-    index = bufferHdr - ((!mUseProxyColorFormat)?m_inp_mem_ptr:meta_buffer_hdr);
+    index = bufferHdr - ((!meta_mode_enable)?m_inp_mem_ptr:meta_buffer_hdr);
 #ifdef _ANDROID_ICS_
     if (meta_mode_enable) {
         if (index < m_sInPortDef.nBufferCountActual) {
@@ -2571,7 +2612,8 @@
                         m_pOutput_pmem[index].size);
             } else {
                 char *data = (char*) m_pOutput_pmem[index].buffer;
-                native_handle_t *handle = (native_handle_t*) data + 4;
+                native_handle_t *handle = NULL;
+                memcpy(&handle, data + sizeof(OMX_U32), sizeof(native_handle_t*));
                 native_handle_delete(handle);
                 free(m_pOutput_pmem[index].buffer);
             }
@@ -2615,8 +2657,11 @@
         return OMX_ErrorBadParameter;
     }
 
-    if (!m_inp_mem_ptr && !mUseProxyColorFormat)
+    if (!m_inp_mem_ptr && !mUseProxyColorFormat) {
         m_inp_mem_ptr = meta_buffer_hdr;
+        DEBUG_PRINT_LOW("use meta_buffer_hdr (%p) as m_inp_mem_ptr = %p",
+                meta_buffer_hdr, m_inp_mem_ptr);
+    }
     for (index = 0; ((index < m_sInPortDef.nBufferCountActual) &&
                 meta_buffer_hdr[index].pBuffer); index++);
     if (index == m_sInPortDef.nBufferCountActual) {
@@ -2692,6 +2737,7 @@
             return OMX_ErrorInsufficientResources;
         }
 
+        DEBUG_PRINT_LOW("Successfully allocated m_inp_mem_ptr = %p", m_inp_mem_ptr);
         m_pInput_pmem = (struct pmem *) calloc(sizeof (struct pmem), m_sInPortDef.nBufferCountActual);
 
         if (m_pInput_pmem == NULL) {
@@ -2897,7 +2943,7 @@
             align_size = ((m_sOutPortDef.nBufferSize + 4095)/4096) * 4096;
             m_pOutput_ion[i].ion_device_fd = alloc_map_ion_memory(align_size,
                     &m_pOutput_ion[i].ion_alloc_data,
-                    &m_pOutput_ion[i].fd_ion_data,0);
+                    &m_pOutput_ion[i].fd_ion_data, ION_FLAG_CACHED);
 #else
             m_pOutput_ion[i].ion_device_fd = alloc_map_ion_memory(m_sOutPortDef.nBufferSize,
                     &m_pOutput_ion[i].ion_alloc_data,
@@ -2951,8 +2997,8 @@
                 handle->data[0] = m_pOutput_pmem[i].fd;
                 char *data = (char*) m_pOutput_pmem[i].buffer;
                 OMX_U32 type = 1;
-                memcpy(data, &type, 4);
-                memcpy(data + 4, &handle, sizeof(native_handle_t*));
+                memcpy(data, &type, sizeof(OMX_U32));
+                memcpy(data + sizeof(OMX_U32), &handle, sizeof(native_handle_t*));
             }
 
             *bufferHdr = (m_out_mem_ptr + i );
@@ -3097,7 +3143,7 @@
 
     if (port == PORT_INDEX_IN) {
         // check if the buffer is valid
-        nPortIndex = buffer - ((!mUseProxyColorFormat)?m_inp_mem_ptr:meta_buffer_hdr);
+        nPortIndex = buffer - ((!meta_mode_enable)?m_inp_mem_ptr:meta_buffer_hdr);
 
         DEBUG_PRINT_LOW("free_buffer on i/p port - Port idx %u, actual cnt %u",
                 nPortIndex, (unsigned int)m_sInPortDef.nBufferCountActual);
@@ -3207,7 +3253,7 @@
             post_event(OMX_CommandStateSet, OMX_StateLoaded,
                     OMX_COMPONENT_GENERATE_EVENT);
         } else {
-            DEBUG_PRINT_HIGH("in free buffer, release not done, need to free more buffers input 0x%x output 0x%x",
+            DEBUG_PRINT_HIGH("in free buffer, release not done, need to free more buffers input %" PRIx64" output %" PRIx64,
                     m_out_bm_count, m_inp_bm_count);
         }
     }
@@ -3262,7 +3308,7 @@
         return OMX_ErrorIncorrectStateOperation;
     }
 
-    nBufferIndex = buffer - ((!mUseProxyColorFormat)?m_inp_mem_ptr:meta_buffer_hdr);
+    nBufferIndex = buffer - ((!meta_mode_enable)?m_inp_mem_ptr:meta_buffer_hdr);
 
     if (nBufferIndex > m_sInPortDef.nBufferCountActual ) {
         DEBUG_PRINT_ERROR("ERROR: ETB: Invalid buffer index[%d]", nBufferIndex);
@@ -3362,6 +3408,10 @@
     if (meta_mode_enable && !mUseProxyColorFormat) {
         // Camera or Gralloc-source meta-buffers queued with pre-announced color-format
         struct pmem Input_pmem_info;
+        if (!media_buffer) {
+            DEBUG_PRINT_ERROR("%s: invalid media_buffer",__FUNCTION__);
+            return OMX_ErrorBadParameter;
+        }
         if (media_buffer->buffer_type == kMetadataBufferTypeCameraSource) {
             Input_pmem_info.buffer = media_buffer;
             Input_pmem_info.fd = media_buffer->meta_handle->data[0];
@@ -3444,6 +3494,9 @@
         post_event ((unsigned long)buffer,0,OMX_COMPONENT_GENERATE_EBD);
         /*Generate an async error and move to invalid state*/
         pending_input_buffers--;
+        if (hw_overload) {
+            return OMX_ErrorInsufficientResources;
+        }
         return OMX_ErrorBadParameter;
     }
     return ret;
@@ -3689,6 +3742,16 @@
         }
     }
 #endif
+    else if ((!strncmp((char*)m_nkind, "OMX.qcom.video.encoder.hevc", OMX_MAX_STRINGNAME_SIZE)) ||
+            (!strncmp((char*)m_nkind, "OMX.qti.video.encoder.hevc", OMX_MAX_STRINGNAME_SIZE))) {
+        if ((0 == index) && role) {
+            strlcpy((char *)role, "video_encoder.hevc", OMX_MAX_STRINGNAME_SIZE);
+            DEBUG_PRINT_LOW("component_role_enum: role %s", role);
+        } else {
+            DEBUG_PRINT_ERROR("ERROR: No more roles");
+            eRet = OMX_ErrorNoMore;
+        }
+    }
     else {
         DEBUG_PRINT_ERROR("ERROR: Querying Role on Unknown Component");
         eRet = OMX_ErrorInvalidComponentName;
@@ -3956,22 +4019,20 @@
         OMX_BUFFERHEADERTYPE* buffer)
 {
     int buffer_index  = -1;
-    int buffer_index_meta = -1;
 
-    buffer_index = (buffer - m_inp_mem_ptr);
-    buffer_index_meta = (buffer - meta_buffer_hdr);
+    buffer_index = buffer - ((mUseProxyColorFormat && !mUsesColorConversion) ? meta_buffer_hdr : m_inp_mem_ptr);
     DEBUG_PRINT_LOW("empty_buffer_done: buffer[%p]", buffer);
     if (buffer == NULL ||
-            ((buffer_index > (int)m_sInPortDef.nBufferCountActual) &&
-             (buffer_index_meta > (int)m_sInPortDef.nBufferCountActual))) {
+            ((buffer_index > (int)m_sInPortDef.nBufferCountActual))) {
         DEBUG_PRINT_ERROR("ERROR in empty_buffer_done due to index buffer");
         return OMX_ErrorBadParameter;
     }
 
     pending_input_buffers--;
 
-    if (mUseProxyColorFormat && ((OMX_U32)buffer_index < m_sInPortDef.nBufferCountActual)) {
-        if (!pdest_frame  && !input_flush_progress) {
+    if (mUseProxyColorFormat &&
+        (buffer_index >= 0 && (buffer_index < (int)m_sInPortDef.nBufferCountActual))) {
+        if (!pdest_frame  && !input_flush_progress && mUsesColorConversion) {
             pdest_frame = buffer;
             DEBUG_PRINT_LOW("empty_buffer_done pdest_frame address is %p",pdest_frame);
             return push_input_buffer(hComp);
@@ -3992,10 +4053,9 @@
         } else {
             // We are not dealing with color-conversion, Buffer being returned
             // here is client's buffer, return it back to client
-            OMX_BUFFERHEADERTYPE* il_buffer = &meta_buffer_hdr[buffer_index];
-            if (m_pCallbacks.EmptyBufferDone && il_buffer) {
-                m_pCallbacks.EmptyBufferDone(hComp, m_app_data, il_buffer);
-                DEBUG_PRINT_LOW("empty_buffer_done: Returning client buf %p",il_buffer);
+            if (m_pCallbacks.EmptyBufferDone && buffer) {
+                m_pCallbacks.EmptyBufferDone(hComp, m_app_data, buffer);
+                DEBUG_PRINT_LOW("empty_buffer_done: Returning client buf %p", buffer);
             }
         }
     } else if (m_pCallbacks.EmptyBufferDone) {
@@ -4194,6 +4254,18 @@
                 (unsigned int)profileLevelType->nProfileIndex);
                 eRet = OMX_ErrorNoMore;
             }
+        } else if (m_sOutPortDef.format.video.eCompressionFormat == OMX_VIDEO_CodingHEVC) {
+            if (profileLevelType->nProfileIndex == 0) {
+                profileLevelType->eProfile =  OMX_VIDEO_HEVCProfileMain;
+                profileLevelType->eLevel   =  OMX_VIDEO_HEVCMainTierLevel52;
+            } else if (profileLevelType->nProfileIndex == 1) {
+                profileLevelType->eProfile =  OMX_VIDEO_HEVCProfileMain10;
+                profileLevelType->eLevel   =  OMX_VIDEO_HEVCMainTierLevel52;
+            } else {
+                DEBUG_PRINT_LOW("HEVC: get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %u",
+                (unsigned int)profileLevelType->nProfileIndex);
+                eRet = OMX_ErrorNoMore;
+            }
         } else {
             DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported ret NoMore");
             eRet = OMX_ErrorNoMore;
@@ -4232,20 +4304,22 @@
         alloc_data->align = SZ_1M;
         alloc_data->flags = ION_SECURE;
         alloc_data->ION_HEAP_MASK = ION_HEAP(ION_CP_MM_HEAP_ID);
-        DEBUG_PRINT_HIGH("ION ALLOC sec buf: size %d align %d flags %x",
-                alloc_data->len, alloc_data->align,alloc_data->flags);
+        DEBUG_PRINT_HIGH("ION ALLOC sec buf: size %u align %u flags %x",
+                (unsigned int)alloc_data->len, (unsigned int)alloc_data->align,
+                alloc_data->flags);
     } else {
         alloc_data->len = (size + (SZ_4K - 1)) & ~(SZ_4K - 1);
         alloc_data->align = SZ_4K;
         alloc_data->flags = (flag & ION_FLAG_CACHED ? ION_FLAG_CACHED : 0);
 #ifdef MAX_RES_720P
-    alloc_data->ION_HEAP_MASK = ION_HEAP(MEM_HEAP_ID);
+        alloc_data->ION_HEAP_MASK = ION_HEAP(MEM_HEAP_ID);
 #else
-    alloc_data->ION_HEAP_MASK = (ION_HEAP(MEM_HEAP_ID) |
+        alloc_data->ION_HEAP_MASK = (ION_HEAP(MEM_HEAP_ID) |
             ION_HEAP(ION_IOMMU_HEAP_ID));
 #endif
-        DEBUG_PRINT_HIGH("ION ALLOC unsec buf: size %d align %d flags %x",
-                alloc_data->len, alloc_data->align,alloc_data->flags);
+        DEBUG_PRINT_HIGH("ION ALLOC unsec buf: size %u align %u flags %x",
+                (unsigned int)alloc_data->len, (unsigned int)alloc_data->align,
+                alloc_data->flags);
     }
 
     rc = ioctl(ion_device_fd,ION_IOC_ALLOC,alloc_data);
@@ -4484,19 +4558,25 @@
         return OMX_ErrorBadParameter;
     }
     media_buffer = (encoder_media_buffer_type *)buffer->pBuffer;
+    if (!media_buffer || !media_buffer->meta_handle) {
+        DEBUG_PRINT_ERROR("Incorrect Buffer queued media buffer = %p",
+            media_buffer);
+        m_pCallbacks.EmptyBufferDone(hComp, m_app_data, buffer);
+        return OMX_ErrorBadParameter;
+    }
     private_handle_t *handle = (private_handle_t *)media_buffer->meta_handle;
 
     /*Enable following code once private handle color format is
       updated correctly*/
+    mUsesColorConversion = true;
 
-    if (buffer->nFilledLen > 0) {
+    if (buffer->nFilledLen > 0 && handle) {
         if (c2d_opened && handle->format != c2d_conv.get_src_format()) {
             c2d_conv.close();
             c2d_opened = false;
         }
         if (!c2d_opened) {
             if (handle->format == HAL_PIXEL_FORMAT_RGBA_8888) {
-                mUsesColorConversion = true;
                 DEBUG_PRINT_INFO("open Color conv for RGBA888 W: %u, H: %u",
                         (unsigned int)m_sInPortDef.format.video.nFrameWidth,
                         (unsigned int)m_sInPortDef.format.video.nFrameHeight);
@@ -4512,8 +4592,12 @@
                 if (!dev_set_format(handle->format))
                     DEBUG_PRINT_ERROR("cannot set color format for RGBA8888");
 #endif
-            } else if (handle->format != HAL_PIXEL_FORMAT_NV12_ENCODEABLE) {
+            } else if (handle->format == HAL_PIXEL_FORMAT_NV12_ENCODEABLE &&
+                    handle->format != QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m) {
+                mUsesColorConversion = false;
+            } else {
                 DEBUG_PRINT_ERROR("Incorrect color format");
+                mUsesColorConversion = false;
                 m_pCallbacks.EmptyBufferDone(hComp,m_app_data,buffer);
                 return OMX_ErrorBadParameter;
             }
@@ -4667,6 +4751,7 @@
     unsigned long address = 0,p2,id, index = 0;
     OMX_ERRORTYPE ret = OMX_ErrorNone;
 
+    DEBUG_PRINT_LOW("In push input buffer");
     if (!psource_frame && m_opq_meta_q.m_size) {
         m_opq_meta_q.pop_entry(&address,&p2,&id);
         psource_frame = (OMX_BUFFERHEADERTYPE* ) address;
@@ -4712,7 +4797,8 @@
             Input_pmem_info.size = handle->size;
             if (handle->format == HAL_PIXEL_FORMAT_RGBA_8888)
                 ret = convert_queue_buffer(hComp,Input_pmem_info,index);
-            else if (handle->format == HAL_PIXEL_FORMAT_NV12_ENCODEABLE)
+            else if (handle->format == HAL_PIXEL_FORMAT_NV12_ENCODEABLE ||
+                    handle->format == QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m)
                 ret = queue_meta_buffer(hComp,Input_pmem_info);
             else
                 ret = OMX_ErrorBadParameter;
@@ -4725,7 +4811,11 @@
         OMX_BUFFERHEADERTYPE* buffer) {
     OMX_BUFFERHEADERTYPE* opqBuf = NULL;
     OMX_ERRORTYPE retVal = OMX_ErrorNone;
+    unsigned index = 0;
+
+    DEBUG_PRINT_LOW("In push empty eos buffer");
     do {
+        if (mUsesColorConversion) {
         if (pdest_frame) {
             //[1] use a checked out conversion buffer, if one is available
             opqBuf = pdest_frame;
@@ -4736,7 +4826,12 @@
             m_opq_pmem_q.pop_entry(&address,&p2,&id);
             opqBuf = (OMX_BUFFERHEADERTYPE* ) address;
         }
-        unsigned index = opqBuf - m_inp_mem_ptr;
+            index = opqBuf - m_inp_mem_ptr;
+        } else {
+            opqBuf = (OMX_BUFFERHEADERTYPE* ) buffer;
+            index = opqBuf - meta_buffer_hdr;
+        }
+
         if (!opqBuf || index >= m_sInPortDef.nBufferCountActual) {
             DEBUG_PRINT_ERROR("push_empty_eos_buffer: Could not find a "
                     "color-conversion buffer to queue ! defer until available");
@@ -4765,6 +4860,8 @@
         emptyEosBufHdr.nTimeStamp = buffer->nTimeStamp;
         emptyEosBufHdr.nFlags = buffer->nFlags;
         emptyEosBufHdr.pBuffer = NULL;
+        if (!mUsesColorConversion)
+            emptyEosBufHdr.nAllocLen = m_sInPortDef.nBufferSize;
         if (dev_empty_buf(&emptyEosBufHdr, 0, index, m_pInput_pmem[index].fd) != true) {
             DEBUG_PRINT_ERROR("ERROR: in dev_empty_buf for empty eos buffer");
             dev_free_buf(&Input_pmem_info, PORT_INDEX_IN);
diff --git a/mm-video-v4l2/vidc/venc/src/omx_video_encoder.cpp b/mm-video-v4l2/vidc/venc/src/omx_video_encoder.cpp
old mode 100755
new mode 100644
index 63deeeb..e0d788b
--- a/mm-video-v4l2/vidc/venc/src/omx_video_encoder.cpp
+++ b/mm-video-v4l2/vidc/venc/src/omx_video_encoder.cpp
@@ -27,7 +27,6 @@
 --------------------------------------------------------------------------*/
 #include "omx_video_encoder.h"
 #include <string.h>
-#include "video_encoder_device.h"
 #include <stdio.h>
 #ifdef _ANDROID_ICS_
 #include <media/hardware/HardwareAPI.h>
@@ -50,9 +49,10 @@
 (_s_)->nVersion.nVersion = OMX_SPEC_VERSION
 
 extern int m_pipe;
-int debug_level = PRIO_ERROR;
 static int bframes;
 static int entropy;
+static int perfmode;
+static int hybrid_hp;
 // factory function executed by the core to create instances
 void *get_omx_component_factory_fn(void)
 {
@@ -82,6 +82,12 @@
     property_get("vidc.debug.entropy", property_value, "1");
     entropy = !!atoi(property_value);
     property_value[0] = '\0';
+    property_get("vidc.debug.perf.mode", property_value, "0");
+    perfmode = atoi(property_value);
+    property_value[0] = '\0';
+    property_get("vidc.debug.hybrid.hierp", property_value, "0");
+    hybrid_hp = atoi(property_value);
+    property_value[0] = '\0';
 }
 
 omx_venc::~omx_venc()
@@ -149,7 +155,16 @@
         codec_type = OMX_VIDEO_CodingVP8;
     }
 #endif
-    else {
+    else if (!strncmp((char *)m_nkind, "OMX.qcom.video.encoder.hevc",    \
+                OMX_MAX_STRINGNAME_SIZE)) {
+        strlcpy((char *)m_cRole, "video_encoder.hevc", OMX_MAX_STRINGNAME_SIZE);
+        codec_type = OMX_VIDEO_CodingHEVC;
+    } else if (!strncmp((char *)m_nkind, "OMX.qcom.video.encoder.hevc.secure",    \
+                OMX_MAX_STRINGNAME_SIZE)) {
+        strlcpy((char *)m_cRole, "video_encoder.hevc", OMX_MAX_STRINGNAME_SIZE);
+        codec_type = OMX_VIDEO_CodingHEVC;
+        secure_session = true;
+    } else {
         DEBUG_PRINT_ERROR("ERROR: Unknown Component");
         eRet = OMX_ErrorInvalidComponentName;
     }
@@ -208,7 +223,7 @@
     m_sConfigIntraRefreshVOP.IntraRefreshVOP = OMX_FALSE;
 
     OMX_INIT_STRUCT(&m_sConfigFrameRotation, OMX_CONFIG_ROTATIONTYPE);
-    m_sConfigFrameRotation.nPortIndex = (OMX_U32) PORT_INDEX_IN;
+    m_sConfigFrameRotation.nPortIndex = (OMX_U32) PORT_INDEX_OUT;
     m_sConfigFrameRotation.nRotation = 0;
 
     OMX_INIT_STRUCT(&m_sSessionQuantization, OMX_VIDEO_PARAM_QUANTIZATIONTYPE);
@@ -261,6 +276,9 @@
     } else if (codec_type == OMX_VIDEO_CodingVP8) {
         m_sParamProfileLevel.eProfile = (OMX_U32) OMX_VIDEO_VP8ProfileMain;
         m_sParamProfileLevel.eLevel = (OMX_U32) OMX_VIDEO_VP8Level_Version0;
+    } else if (codec_type == OMX_VIDEO_CodingHEVC) {
+        m_sParamProfileLevel.eProfile = (OMX_U32) OMX_VIDEO_HEVCProfileMain;
+        m_sParamProfileLevel.eLevel = (OMX_U32) OMX_VIDEO_HEVCMainTierLevel1;
     }
 
     // Initialize the video parameters for input port
@@ -309,6 +327,8 @@
         m_sOutPortDef.format.video.eCompressionFormat =  OMX_VIDEO_CodingAVC;
     } else if (codec_type == OMX_VIDEO_CodingVP8) {
         m_sOutPortDef.format.video.eCompressionFormat =  OMX_VIDEO_CodingVP8;
+    } else if (codec_type == OMX_VIDEO_CodingHEVC) {
+        m_sOutPortDef.format.video.eCompressionFormat =  OMX_VIDEO_CodingHEVC;
     }
 
     if (dev_get_buf_req(&m_sOutPortDef.nBufferCountMin,
@@ -340,6 +360,8 @@
         m_sOutPortFormat.eCompressionFormat =  OMX_VIDEO_CodingAVC;
     } else if (codec_type == OMX_VIDEO_CodingVP8) {
         m_sOutPortFormat.eCompressionFormat =  OMX_VIDEO_CodingVP8;
+    } else if (codec_type == OMX_VIDEO_CodingHEVC) {
+        m_sOutPortFormat.eCompressionFormat =  OMX_VIDEO_CodingHEVC;
     }
 
 
@@ -419,10 +441,20 @@
     m_sParamVP8.nDCTPartitions = 0;
     m_sParamVP8.bErrorResilientMode = OMX_FALSE;
 
+    // HEVC specific init
+    OMX_INIT_STRUCT(&m_sParamHEVC, OMX_VIDEO_PARAM_HEVCTYPE);
+    m_sParamHEVC.nPortIndex = (OMX_U32) PORT_INDEX_OUT;
+    m_sParamHEVC.eProfile =  OMX_VIDEO_HEVCProfileMain;
+    m_sParamHEVC.eLevel =  OMX_VIDEO_HEVCMainTierLevel1;
+
     OMX_INIT_STRUCT(&m_sParamLTRMode, QOMX_VIDEO_PARAM_LTRMODE_TYPE);
     m_sParamLTRMode.nPortIndex = (OMX_U32) PORT_INDEX_OUT;
     m_sParamLTRMode.eLTRMode = QOMX_VIDEO_LTRMode_Disable;
 
+    OMX_INIT_STRUCT(&m_sParamLTRCount, QOMX_VIDEO_PARAM_LTRCOUNT_TYPE);
+    m_sParamLTRCount.nPortIndex = (OMX_U32) PORT_INDEX_OUT;
+    m_sParamLTRCount.nCount = 0;
+
     OMX_INIT_STRUCT(&m_sConfigDeinterlace, OMX_VIDEO_CONFIG_DEINTERLACE);
     m_sConfigDeinterlace.nPortIndex = (OMX_U32) PORT_INDEX_OUT;
     m_sConfigDeinterlace.nEnable = OMX_FALSE;
@@ -467,6 +499,27 @@
         }
     }
 
+    if (perfmode) {
+        QOMX_EXTNINDEX_VIDEO_PERFMODE pParam;
+        pParam.nPerfMode = perfmode;
+        DEBUG_PRINT_LOW("Perfmode = 0x%x", pParam.nPerfMode);
+        if (!handle->venc_set_config(&pParam, (OMX_INDEXTYPE)OMX_QcomIndexConfigVideoVencPerfMode))
+            DEBUG_PRINT_ERROR("Failed setting PerfMode to %d", pParam.nPerfMode);
+    }
+
+    if (hybrid_hp)
+    {
+        if (hybrid_hp <= MAX_HYB_HIERP_LAYERS) {
+            QOMX_EXTNINDEX_VIDEO_HYBRID_HP_MODE hyb_hp;
+            hyb_hp.nHpLayers = hybrid_hp;
+            DEBUG_PRINT_LOW("hybrid_hp = 0x%x", hyb_hp.nHpLayers);
+            if (!handle->venc_set_param(&hyb_hp, (OMX_INDEXTYPE)OMX_QcomIndexParamVideoHybridHierpMode)) {
+                DEBUG_PRINT_ERROR("Failed setting hybrid_hp to %d", hyb_hp.nHpLayers);
+            }
+        } else {
+            DEBUG_PRINT_ERROR("Max hybrid_hp layers supported is %d", hybrid_hp);
+        }
+    }
     DEBUG_PRINT_INFO("Component_init : %s : return = 0x%x", m_nkind, eRet);
     return eRet;
 }
@@ -700,8 +753,6 @@
 #ifdef _MSM8974_
                     if (pParam->nBFrames || bframes)
                         mp4_param.nBFrames = (pParam->nBFrames > (unsigned int) bframes)? pParam->nBFrames : bframes;
-                    if (mp4_param.nBFrames > 3)
-                        mp4_param.nBFrames = 3;
                     DEBUG_PRINT_HIGH("MPEG4: %u BFrames are being set", (unsigned int)mp4_param.nBFrames);
 #endif
 
@@ -758,18 +809,14 @@
                         avc_param.nBFrames = 0;
                     }
                     if (pParam->nRefFrames != 1) {
-                        DEBUG_PRINT_ERROR("Warning: Only 1 RefFrame is supported, changing RefFrame from %lu to 1)", pParam->nRefFrames);
+                        DEBUG_PRINT_ERROR("Warning: Only 1 RefFrame is supported, changing RefFrame from %u to 1)", (unsigned int)pParam->nRefFrames);
                         avc_param.nRefFrames = 1;
                     }
 #endif
 #ifdef _MSM8974_
                     if (pParam->nBFrames || bframes) {
                         avc_param.nBFrames = (pParam->nBFrames > (unsigned int) bframes)? pParam->nBFrames : bframes;
-                        avc_param.nRefFrames = avc_param.nBFrames + 1;
-                    }
-                    if (avc_param.nBFrames > 3) {
-                        avc_param.nBFrames = 3;
-                        avc_param.nRefFrames = avc_param.nBFrames + 1;
+                        avc_param.nRefFrames = (avc_param.nBFrames < 4)? avc_param.nBFrames + 1 : 4;
                     }
                     DEBUG_PRINT_HIGH("AVC: RefFrames: %u, BFrames: %u", (unsigned int)avc_param.nRefFrames, (unsigned int)avc_param.nBFrames);
 
@@ -813,6 +860,19 @@
                 memcpy(&m_sParamVP8,pParam, sizeof(struct OMX_VIDEO_PARAM_VP8TYPE));
                 break;
             }
+        case (OMX_INDEXTYPE)OMX_IndexParamVideoHevc:
+            {
+                OMX_VIDEO_PARAM_HEVCTYPE* pParam = (OMX_VIDEO_PARAM_HEVCTYPE*)paramData;
+                OMX_VIDEO_PARAM_HEVCTYPE hevc_param;
+                DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoHevc");
+                memcpy(&hevc_param, pParam, sizeof( struct OMX_VIDEO_PARAM_HEVCTYPE));
+                if (handle->venc_set_param(&hevc_param, (OMX_INDEXTYPE)OMX_IndexParamVideoHevc) != true) {
+                    DEBUG_PRINT_ERROR("Failed : set_parameter: OMX_IndexParamVideoHevc");
+                    return OMX_ErrorUnsupportedSetting;
+                }
+                memcpy(&m_sParamHEVC, pParam, sizeof(struct OMX_VIDEO_PARAM_HEVCTYPE));
+                break;
+            }
         case OMX_IndexParamVideoProfileLevelCurrent:
             {
                 OMX_VIDEO_PARAM_PROFILELEVELTYPE* pParam = (OMX_VIDEO_PARAM_PROFILELEVELTYPE*)paramData;
@@ -857,6 +917,14 @@
                     DEBUG_PRINT_LOW("VP8 profile = %d, level = %d", m_sParamVP8.eProfile,
                             m_sParamVP8.eLevel);
                 }
+                else if (!strncmp((char*)m_nkind, "OMX.qcom.video.encoder.hevc",\
+                            OMX_MAX_STRINGNAME_SIZE)) {
+                    m_sParamHEVC.eProfile = (OMX_VIDEO_HEVCPROFILETYPE)m_sParamProfileLevel.eProfile;
+                    m_sParamHEVC.eLevel = (OMX_VIDEO_HEVCLEVELTYPE)m_sParamProfileLevel.eLevel;
+                    DEBUG_PRINT_LOW("HEVC profile = %d, level = %d", m_sParamHEVC.eProfile,
+                            m_sParamHEVC.eLevel);
+                }
+
                 break;
             }
         case OMX_IndexParamStandardComponentRole:
@@ -913,6 +981,15 @@
                     }
                 }
 #endif
+                else if (!strncmp((char*)m_nkind, "OMX.qcom.video.encoder.hevc",OMX_MAX_STRINGNAME_SIZE)) {
+                    if (!strncmp((const char*)comp_role->cRole,"video_encoder.hevc",OMX_MAX_STRINGNAME_SIZE)) {
+                        strlcpy((char*)m_cRole,"video_encoder.hevc",OMX_MAX_STRINGNAME_SIZE);
+                    } else {
+                        DEBUG_PRINT_ERROR("ERROR: Setparameter: unknown Index %s", comp_role->cRole);
+                        eRet = OMX_ErrorUnsupportedSetting;
+                    }
+                }
+
                 else {
                     DEBUG_PRINT_ERROR("ERROR: Setparameter: unknown param %s", m_nkind);
                     eRet = OMX_ErrorInvalidComponentName;
@@ -1278,6 +1355,8 @@
                         DEBUG_PRINT_ERROR("ERROR: Request for setting PlusPType failed");
                         return OMX_ErrorUnsupportedSetting;
                     }
+                if((pParam->eHierarchicalCodingType == QOMX_HIERARCHICALCODING_B) && pParam->nNumLayers)
+                    hier_b_enabled = true;
                     m_sHierLayers.nNumLayers = pParam->nNumLayers;
                     m_sHierLayers.eHierarchicalCodingType = pParam->eHierarchicalCodingType;
                 } else {
@@ -1334,6 +1413,15 @@
                 }
                 break;
             }
+        case OMX_QcomIndexParamVideoHybridHierpMode:
+            {
+               if(!handle->venc_set_param(paramData,
+                         (OMX_INDEXTYPE)OMX_QcomIndexParamVideoHybridHierpMode)) {
+                   DEBUG_PRINT_ERROR("Request to Enable Hybrid Hier-P failed");
+                   return OMX_ErrorUnsupportedSetting;
+                }
+                break;
+            }
         case OMX_IndexParamVideoSliceFMO:
         default:
             {
@@ -1389,6 +1477,14 @@
         DEBUG_PRINT_LOW("VP8 profile = %d, level = %d", m_sParamVP8.eProfile,
                 m_sParamVP8.eLevel);
     }
+    else if (!strncmp((char *)m_nkind, "OMX.qcom.video.encoder.hevc",\
+                OMX_MAX_STRINGNAME_SIZE)) {
+        m_sParamHEVC.eProfile = (OMX_VIDEO_HEVCPROFILETYPE)eProfile;
+        m_sParamHEVC.eLevel = (OMX_VIDEO_HEVCLEVELTYPE)eLevel;
+        DEBUG_PRINT_LOW("HEVC profile = %d, level = %d", m_sParamHEVC.eProfile,
+                m_sParamHEVC.eLevel);
+    }
+
     return true;
 }
 /* ======================================================================
@@ -1481,9 +1577,14 @@
                             (unsigned int)m_sIntraperiod.nPFrames, (unsigned int)m_sIntraperiod.nBFrames,
                             (unsigned int)pParam->nPFrames, (unsigned int)pParam->nBFrames);
                     if (m_sIntraperiod.nBFrames != pParam->nBFrames) {
+                        if(hier_b_enabled && m_state == OMX_StateLoaded) {
+                            DEBUG_PRINT_INFO("B-frames setting is supported if HierB is enabled");
+                        }
+                        else {
                         DEBUG_PRINT_HIGH("Dynamically changing B-frames not supported");
                         return OMX_ErrorUnsupportedSetting;
                     }
+                    }
                     if (handle->venc_set_config(configData, (OMX_INDEXTYPE) QOMX_IndexConfigVideoIntraperiod) != true) {
                         DEBUG_PRINT_ERROR("ERROR: Setting QOMX_IndexConfigVideoIntraperiod failed");
                         return OMX_ErrorUnsupportedSetting;
@@ -1543,7 +1644,7 @@
                     reinterpret_cast<OMX_CONFIG_ROTATIONTYPE*>(configData);
                 OMX_S32 nRotation;
 
-                if (pParam->nPortIndex != PORT_INDEX_IN) {
+                if (pParam->nPortIndex != PORT_INDEX_OUT) {
                     DEBUG_PRINT_ERROR("ERROR: Unsupported port index: %u", (unsigned int)pParam->nPortIndex);
                     return OMX_ErrorBadPortIndex;
                 }
@@ -1567,18 +1668,14 @@
                         return OMX_ErrorUnsupportedSetting;
                     } else {
                         OMX_U32 nFrameWidth;
+                        OMX_U32 nFrameHeight;
 
                         DEBUG_PRINT_HIGH("set_config: updating port Dims");
 
-                        nFrameWidth = m_sInPortDef.format.video.nFrameWidth;
-                        m_sInPortDef.format.video.nFrameWidth =
-                            m_sInPortDef.format.video.nFrameHeight;
-                        m_sInPortDef.format.video.nFrameHeight = nFrameWidth;
-
-                        m_sOutPortDef.format.video.nFrameWidth  =
-                            m_sInPortDef.format.video.nFrameWidth;
-                        m_sOutPortDef.format.video.nFrameHeight =
-                            m_sInPortDef.format.video.nFrameHeight;
+                        nFrameWidth = m_sOutPortDef.format.video.nFrameWidth;
+                        nFrameHeight = m_sOutPortDef.format.video.nFrameHeight;
+                        m_sOutPortDef.format.video.nFrameWidth  = nFrameHeight;
+                        m_sOutPortDef.format.video.nFrameHeight = nFrameWidth;
                         m_sConfigFrameRotation.nRotation = pParam->nRotation;
                     }
                 } else {
@@ -1623,7 +1720,7 @@
         case QOMX_IndexConfigVideoLTRUse:
             {
                 QOMX_VIDEO_CONFIG_LTRUSE_TYPE* pParam = (QOMX_VIDEO_CONFIG_LTRUSE_TYPE*)configData;
-                if (!handle->venc_set_config(configData, (OMX_INDEXTYPE)QOMX_IndexConfigVideoLTRUse)) {
+                if (!handle->venc_set_config(pParam, (OMX_INDEXTYPE)QOMX_IndexConfigVideoLTRUse)) {
                     DEBUG_PRINT_ERROR("ERROR: Setting LTR use failed");
                     return OMX_ErrorUnsupportedSetting;
                 }
@@ -1633,8 +1730,10 @@
         case QOMX_IndexConfigVideoLTRMark:
             {
                 QOMX_VIDEO_CONFIG_LTRMARK_TYPE* pParam = (QOMX_VIDEO_CONFIG_LTRMARK_TYPE*)configData;
-                DEBUG_PRINT_ERROR("Setting ltr mark is not supported");
+                if (!handle->venc_set_config(pParam, (OMX_INDEXTYPE)QOMX_IndexConfigVideoLTRMark)) {
+                    DEBUG_PRINT_ERROR("ERROR: Setting LTR mark failed");
                 return OMX_ErrorUnsupportedSetting;
+                }
                 break;
             }
         case OMX_IndexConfigVideoAVCIntraPeriod:
@@ -1659,6 +1758,15 @@
                 memcpy(&m_sConfigDeinterlace, pParam, sizeof(m_sConfigDeinterlace));
                 break;
             }
+        case OMX_QcomIndexConfigVideoVencPerfMode:
+            {
+                QOMX_EXTNINDEX_VIDEO_PERFMODE* pParam = (QOMX_EXTNINDEX_VIDEO_PERFMODE*)configData;
+                if (!handle->venc_set_config(pParam, (OMX_INDEXTYPE)OMX_QcomIndexConfigVideoVencPerfMode)) {
+                    DEBUG_PRINT_ERROR("ERROR: Setting OMX_QcomIndexConfigVideoVencPerfMode failed");
+                    return OMX_ErrorUnsupportedSetting;
+                }
+                break;
+            }
         default:
             DEBUG_PRINT_ERROR("ERROR: unsupported index %d", (int) configIndex);
             break;
@@ -1784,7 +1892,10 @@
 
 bool omx_venc::dev_empty_buf(void *buffer, void *pmem_data_buf,unsigned index,unsigned fd)
 {
-    return  handle->venc_empty_buf(buffer, pmem_data_buf,index,fd);
+    bool bret = false;
+    bret = handle->venc_empty_buf(buffer, pmem_data_buf,index,fd);
+    hw_overload = handle->hw_overload;
+    return bret;
 }
 
 bool omx_venc::dev_fill_buf(void *buffer, void *pmem_data_buf,unsigned index,unsigned fd)
@@ -1792,7 +1903,7 @@
     return handle->venc_fill_buf(buffer, pmem_data_buf,index,fd);
 }
 
-bool omx_venc::dev_get_seq_hdr(void *buffer, unsigned size, OMX_U32 *hdrlen)
+bool omx_venc::dev_get_seq_hdr(void *buffer, unsigned size, unsigned *hdrlen)
 {
     return handle->venc_get_seq_hdr(buffer, size, hdrlen);
 }
@@ -1924,6 +2035,9 @@
     if (m_sVenc_msg->statuscode != VEN_S_SUCCESS) {
         DEBUG_PRINT_ERROR("ERROR: async_msg_process() - Error statuscode = %lu",
                 m_sVenc_msg->statuscode);
+        if(m_sVenc_msg->msgcode == VEN_MSG_HW_OVERLOAD) {
+            omx->omx_report_hw_overload();
+        } else
         omx->omx_report_error();
     }
 
diff --git a/mm-video-v4l2/vidc/venc/src/video_encoder_device_v4l2.cpp b/mm-video-v4l2/vidc/venc/src/video_encoder_device_v4l2.cpp
old mode 100755
new mode 100644
index 976498f..ea729a5
--- a/mm-video-v4l2/vidc/venc/src/video_encoder_device_v4l2.cpp
+++ b/mm-video-v4l2/vidc/venc/src/video_encoder_device_v4l2.cpp
@@ -48,13 +48,19 @@
 
 #define ALIGN(x, to_align) ((((unsigned long) x) + (to_align - 1)) & ~(to_align - 1))
 #define EXTRADATA_IDX(__num_planes) (__num_planes  - 1)
-
+#define MAXDPB 16
+#define MIN(x,y) (((x) < (y)) ? (x) : (y))
+#define MAX(x,y) (((x) > (y)) ? (x) : (y))
+#define ROUND(__sz, __align) (((__sz) + ((__align>>1))) & (~(__align-1)))
+#define MAX_PROFILE_PARAMS 6
 #define MPEG4_SP_START 0
 #define MPEG4_ASP_START (MPEG4_SP_START + 10)
 #define H263_BP_START 0
 #define H264_BP_START 0
 #define H264_HP_START (H264_BP_START + 17)
 #define H264_MP_START (H264_BP_START + 34)
+#define HEVC_MAIN_START 0
+#define HEVC_MAIN10_START (HEVC_MAIN_START + 12)
 #define POLL_TIMEOUT 1000
 #define MAX_SUPPORTED_SLICES_PER_FRAME 28 /* Max supported slices with 32 output buffers */
 
@@ -62,106 +68,138 @@
 #define SZ_1M 0x100000
 
 /* MPEG4 profile and level table*/
-static const unsigned int mpeg4_profile_level_table[][5]= {
-    /*max mb per frame, max mb per sec, max bitrate, level, profile*/
-    {99,1485,64000,OMX_VIDEO_MPEG4Level0,OMX_VIDEO_MPEG4ProfileSimple},
-    {99,1485,64000,OMX_VIDEO_MPEG4Level1,OMX_VIDEO_MPEG4ProfileSimple},
-    {396,5940,128000,OMX_VIDEO_MPEG4Level2,OMX_VIDEO_MPEG4ProfileSimple},
-    {396,11880,384000,OMX_VIDEO_MPEG4Level3,OMX_VIDEO_MPEG4ProfileSimple},
-    {1200,36000,4000000,OMX_VIDEO_MPEG4Level4a,OMX_VIDEO_MPEG4ProfileSimple},
-    {1620,40500,8000000,OMX_VIDEO_MPEG4Level5,OMX_VIDEO_MPEG4ProfileSimple},
-    {3600,108000,12000000,OMX_VIDEO_MPEG4Level5,OMX_VIDEO_MPEG4ProfileSimple},
-    {32400,972000,20000000,OMX_VIDEO_MPEG4Level5,OMX_VIDEO_MPEG4ProfileSimple},
-    {34560,1036800,20000000,OMX_VIDEO_MPEG4Level5,OMX_VIDEO_MPEG4ProfileSimple},
-    {0,0,0,0,0},
+static const unsigned int mpeg4_profile_level_table[][MAX_PROFILE_PARAMS]= {
+    /*max mb per frame, max mb per sec, max bitrate, level, profile, dpbmbs*/
+    {99,1485,64000,OMX_VIDEO_MPEG4Level0,OMX_VIDEO_MPEG4ProfileSimple,0},
+    {99,1485,64000,OMX_VIDEO_MPEG4Level1,OMX_VIDEO_MPEG4ProfileSimple,0},
+    {396,5940,128000,OMX_VIDEO_MPEG4Level2,OMX_VIDEO_MPEG4ProfileSimple,0},
+    {396,11880,384000,OMX_VIDEO_MPEG4Level3,OMX_VIDEO_MPEG4ProfileSimple,0},
+    {1200,36000,4000000,OMX_VIDEO_MPEG4Level4a,OMX_VIDEO_MPEG4ProfileSimple,0},
+    {1620,40500,8000000,OMX_VIDEO_MPEG4Level5,OMX_VIDEO_MPEG4ProfileSimple,0},
+    {3600,108000,12000000,OMX_VIDEO_MPEG4Level5,OMX_VIDEO_MPEG4ProfileSimple,0},
+    {32400,972000,20000000,OMX_VIDEO_MPEG4Level5,OMX_VIDEO_MPEG4ProfileSimple,0},
+    {34560,1036800,20000000,OMX_VIDEO_MPEG4Level5,OMX_VIDEO_MPEG4ProfileSimple,0},
+    {0,0,0,0,0,0},
 
-    {99,1485,128000,OMX_VIDEO_MPEG4Level0,OMX_VIDEO_MPEG4ProfileAdvancedSimple},
-    {99,1485,128000,OMX_VIDEO_MPEG4Level1,OMX_VIDEO_MPEG4ProfileAdvancedSimple},
-    {396,5940,384000,OMX_VIDEO_MPEG4Level2,OMX_VIDEO_MPEG4ProfileAdvancedSimple},
-    {396,11880,768000,OMX_VIDEO_MPEG4Level3,OMX_VIDEO_MPEG4ProfileAdvancedSimple},
-    {792,23760,3000000,OMX_VIDEO_MPEG4Level4,OMX_VIDEO_MPEG4ProfileAdvancedSimple},
-    {1620,48600,8000000,OMX_VIDEO_MPEG4Level5,OMX_VIDEO_MPEG4ProfileAdvancedSimple},
-    {32400,972000,20000000,OMX_VIDEO_MPEG4Level5,OMX_VIDEO_MPEG4ProfileAdvancedSimple},
-    {34560,1036800,20000000,OMX_VIDEO_MPEG4Level5,OMX_VIDEO_MPEG4ProfileAdvancedSimple},
-    {0,0,0,0,0},
+    {99,1485,128000,OMX_VIDEO_MPEG4Level0,OMX_VIDEO_MPEG4ProfileAdvancedSimple,0},
+    {99,1485,128000,OMX_VIDEO_MPEG4Level1,OMX_VIDEO_MPEG4ProfileAdvancedSimple,0},
+    {396,5940,384000,OMX_VIDEO_MPEG4Level2,OMX_VIDEO_MPEG4ProfileAdvancedSimple,0},
+    {396,11880,768000,OMX_VIDEO_MPEG4Level3,OMX_VIDEO_MPEG4ProfileAdvancedSimple,0},
+    {792,23760,3000000,OMX_VIDEO_MPEG4Level4,OMX_VIDEO_MPEG4ProfileAdvancedSimple,0},
+    {1620,48600,8000000,OMX_VIDEO_MPEG4Level5,OMX_VIDEO_MPEG4ProfileAdvancedSimple,0},
+    {32400,972000,20000000,OMX_VIDEO_MPEG4Level5,OMX_VIDEO_MPEG4ProfileAdvancedSimple,0},
+    {34560,1036800,20000000,OMX_VIDEO_MPEG4Level5,OMX_VIDEO_MPEG4ProfileAdvancedSimple,0},
+    {0,0,0,0,0,0},
 };
 
 /* H264 profile and level table*/
-static const unsigned int h264_profile_level_table[][5]= {
-    /*max mb per frame, max mb per sec, max bitrate, level, profile*/
-    {99,1485,64000,OMX_VIDEO_AVCLevel1,OMX_VIDEO_AVCProfileBaseline},
-    {99,1485,128000,OMX_VIDEO_AVCLevel1b,OMX_VIDEO_AVCProfileBaseline},
-    {396,3000,192000,OMX_VIDEO_AVCLevel11,OMX_VIDEO_AVCProfileBaseline},
-    {396,6000,384000,OMX_VIDEO_AVCLevel12,OMX_VIDEO_AVCProfileBaseline},
-    {396,11880,768000,OMX_VIDEO_AVCLevel13,OMX_VIDEO_AVCProfileBaseline},
-    {396,11880,2000000,OMX_VIDEO_AVCLevel2,OMX_VIDEO_AVCProfileBaseline},
-    {792,19800,4000000,OMX_VIDEO_AVCLevel21,OMX_VIDEO_AVCProfileBaseline},
-    {1620,20250,4000000,OMX_VIDEO_AVCLevel22,OMX_VIDEO_AVCProfileBaseline},
-    {1620,40500,10000000,OMX_VIDEO_AVCLevel3,OMX_VIDEO_AVCProfileBaseline},
-    {3600,108000,14000000,OMX_VIDEO_AVCLevel31,OMX_VIDEO_AVCProfileBaseline},
-    {5120,216000,20000000,OMX_VIDEO_AVCLevel32,OMX_VIDEO_AVCProfileBaseline},
-    {8192,245760,20000000,OMX_VIDEO_AVCLevel4,OMX_VIDEO_AVCProfileBaseline},
-    {8192,245760,50000000,OMX_VIDEO_AVCLevel41,OMX_VIDEO_AVCProfileBaseline},
-    {8704,522240,50000000,OMX_VIDEO_AVCLevel42,OMX_VIDEO_AVCProfileBaseline},
-    {22080,589824,135000000,OMX_VIDEO_AVCLevel5,OMX_VIDEO_AVCProfileBaseline},
-    {36864,983040,240000000,OMX_VIDEO_AVCLevel51,OMX_VIDEO_AVCProfileBaseline},
-    {36864,2073600,240000000,OMX_VIDEO_AVCLevel52,OMX_VIDEO_AVCProfileBaseline},
-    {0,0,0,0,0},
+static const unsigned int h264_profile_level_table[][MAX_PROFILE_PARAMS]= {
+    /*max mb per frame, max mb per sec, max bitrate, level, profile, dpbmbs*/
+    {99,1485,64000,OMX_VIDEO_AVCLevel1,OMX_VIDEO_AVCProfileBaseline,396},
+    {99,1485,128000,OMX_VIDEO_AVCLevel1b,OMX_VIDEO_AVCProfileBaseline,396},
+    {396,3000,192000,OMX_VIDEO_AVCLevel11,OMX_VIDEO_AVCProfileBaseline,900},
+    {396,6000,384000,OMX_VIDEO_AVCLevel12,OMX_VIDEO_AVCProfileBaseline,2376},
+    {396,11880,768000,OMX_VIDEO_AVCLevel13,OMX_VIDEO_AVCProfileBaseline,2376},
+    {396,11880,2000000,OMX_VIDEO_AVCLevel2,OMX_VIDEO_AVCProfileBaseline,2376},
+    {792,19800,4000000,OMX_VIDEO_AVCLevel21,OMX_VIDEO_AVCProfileBaseline,4752},
+    {1620,20250,4000000,OMX_VIDEO_AVCLevel22,OMX_VIDEO_AVCProfileBaseline,8100},
+    {1620,40500,10000000,OMX_VIDEO_AVCLevel3,OMX_VIDEO_AVCProfileBaseline,8100},
+    {3600,108000,14000000,OMX_VIDEO_AVCLevel31,OMX_VIDEO_AVCProfileBaseline,18000},
+    {5120,216000,20000000,OMX_VIDEO_AVCLevel32,OMX_VIDEO_AVCProfileBaseline,20480},
+    {8192,245760,20000000,OMX_VIDEO_AVCLevel4,OMX_VIDEO_AVCProfileBaseline,32768},
+    {8192,245760,50000000,OMX_VIDEO_AVCLevel41,OMX_VIDEO_AVCProfileBaseline,32768},
+    {8704,522240,50000000,OMX_VIDEO_AVCLevel42,OMX_VIDEO_AVCProfileBaseline,34816},
+    {22080,589824,135000000,OMX_VIDEO_AVCLevel5,OMX_VIDEO_AVCProfileBaseline,110400},
+    {36864,983040,240000000,OMX_VIDEO_AVCLevel51,OMX_VIDEO_AVCProfileBaseline,184320},
+    {36864,2073600,240000000,OMX_VIDEO_AVCLevel52,OMX_VIDEO_AVCProfileBaseline,184320},
+    {0,0,0,0,0,0},
 
-    {99,1485,64000,OMX_VIDEO_AVCLevel1,OMX_VIDEO_AVCProfileHigh},
-    {99,1485,160000,OMX_VIDEO_AVCLevel1b,OMX_VIDEO_AVCProfileHigh},
-    {396,3000,240000,OMX_VIDEO_AVCLevel11,OMX_VIDEO_AVCProfileHigh},
-    {396,6000,480000,OMX_VIDEO_AVCLevel12,OMX_VIDEO_AVCProfileHigh},
-    {396,11880,960000,OMX_VIDEO_AVCLevel13,OMX_VIDEO_AVCProfileHigh},
-    {396,11880,2500000,OMX_VIDEO_AVCLevel2,OMX_VIDEO_AVCProfileHigh},
-    {792,19800,5000000,OMX_VIDEO_AVCLevel21,OMX_VIDEO_AVCProfileHigh},
-    {1620,20250,5000000,OMX_VIDEO_AVCLevel22,OMX_VIDEO_AVCProfileHigh},
-    {1620,40500,12500000,OMX_VIDEO_AVCLevel3,OMX_VIDEO_AVCProfileHigh},
-    {3600,108000,17500000,OMX_VIDEO_AVCLevel31,OMX_VIDEO_AVCProfileHigh},
-    {5120,216000,25000000,OMX_VIDEO_AVCLevel32,OMX_VIDEO_AVCProfileHigh},
-    {8192,245760,25000000,OMX_VIDEO_AVCLevel4,OMX_VIDEO_AVCProfileHigh},
-    {8192,245760,50000000,OMX_VIDEO_AVCLevel41,OMX_VIDEO_AVCProfileHigh},
-    {8704,522240,50000000,OMX_VIDEO_AVCLevel42,OMX_VIDEO_AVCProfileHigh},
-    {22080,589824,135000000,OMX_VIDEO_AVCLevel5,OMX_VIDEO_AVCProfileHigh},
-    {36864,983040,240000000,OMX_VIDEO_AVCLevel51,OMX_VIDEO_AVCProfileHigh},
-    {36864,2073600,240000000,OMX_VIDEO_AVCLevel52,OMX_VIDEO_AVCProfileHigh},
-    {0,0,0,0,0},
+    {99,1485,64000,OMX_VIDEO_AVCLevel1,OMX_VIDEO_AVCProfileHigh,396},
+    {99,1485,160000,OMX_VIDEO_AVCLevel1b,OMX_VIDEO_AVCProfileHigh,396},
+    {396,3000,240000,OMX_VIDEO_AVCLevel11,OMX_VIDEO_AVCProfileHigh,900},
+    {396,6000,480000,OMX_VIDEO_AVCLevel12,OMX_VIDEO_AVCProfileHigh,2376},
+    {396,11880,960000,OMX_VIDEO_AVCLevel13,OMX_VIDEO_AVCProfileHigh,2376},
+    {396,11880,2500000,OMX_VIDEO_AVCLevel2,OMX_VIDEO_AVCProfileHigh,2376},
+    {792,19800,5000000,OMX_VIDEO_AVCLevel21,OMX_VIDEO_AVCProfileHigh,4752},
+    {1620,20250,5000000,OMX_VIDEO_AVCLevel22,OMX_VIDEO_AVCProfileHigh,8100},
+    {1620,40500,12500000,OMX_VIDEO_AVCLevel3,OMX_VIDEO_AVCProfileHigh,8100},
+    {3600,108000,17500000,OMX_VIDEO_AVCLevel31,OMX_VIDEO_AVCProfileHigh,18000},
+    {5120,216000,25000000,OMX_VIDEO_AVCLevel32,OMX_VIDEO_AVCProfileHigh,20480},
+    {8192,245760,25000000,OMX_VIDEO_AVCLevel4,OMX_VIDEO_AVCProfileHigh,32768},
+    {8192,245760,50000000,OMX_VIDEO_AVCLevel41,OMX_VIDEO_AVCProfileHigh,32768},
+    {8704,522240,50000000,OMX_VIDEO_AVCLevel42,OMX_VIDEO_AVCProfileHigh,34816},
+    {22080,589824,135000000,OMX_VIDEO_AVCLevel5,OMX_VIDEO_AVCProfileHigh,110400},
+    {36864,983040,240000000,OMX_VIDEO_AVCLevel51,OMX_VIDEO_AVCProfileHigh,184320},
+    {36864,2073600,240000000,OMX_VIDEO_AVCLevel52,OMX_VIDEO_AVCProfileHigh,184320},
+    {0,0,0,0,0,0},
 
-    {99,1485,64000,OMX_VIDEO_AVCLevel1,OMX_VIDEO_AVCProfileMain},
-    {99,1485,128000,OMX_VIDEO_AVCLevel1b,OMX_VIDEO_AVCProfileMain},
-    {396,3000,192000,OMX_VIDEO_AVCLevel11,OMX_VIDEO_AVCProfileMain},
-    {396,6000,384000,OMX_VIDEO_AVCLevel12,OMX_VIDEO_AVCProfileMain},
-    {396,11880,768000,OMX_VIDEO_AVCLevel13,OMX_VIDEO_AVCProfileMain},
-    {396,11880,2000000,OMX_VIDEO_AVCLevel2,OMX_VIDEO_AVCProfileMain},
-    {792,19800,4000000,OMX_VIDEO_AVCLevel21,OMX_VIDEO_AVCProfileMain},
-    {1620,20250,4000000,OMX_VIDEO_AVCLevel22,OMX_VIDEO_AVCProfileMain},
-    {1620,40500,10000000,OMX_VIDEO_AVCLevel3,OMX_VIDEO_AVCProfileMain},
-    {3600,108000,14000000,OMX_VIDEO_AVCLevel31,OMX_VIDEO_AVCProfileMain},
-    {5120,216000,20000000,OMX_VIDEO_AVCLevel32,OMX_VIDEO_AVCProfileMain},
-    {8192,245760,20000000,OMX_VIDEO_AVCLevel4,OMX_VIDEO_AVCProfileMain},
-    {8192,245760,50000000,OMX_VIDEO_AVCLevel41,OMX_VIDEO_AVCProfileMain},
-    {8704,522240,50000000,OMX_VIDEO_AVCLevel42,OMX_VIDEO_AVCProfileMain},
-    {22080,589824,135000000,OMX_VIDEO_AVCLevel5,OMX_VIDEO_AVCProfileMain},
-    {36864,983040,240000000,OMX_VIDEO_AVCLevel51,OMX_VIDEO_AVCProfileMain},
-    {36864,2073600,240000000,OMX_VIDEO_AVCLevel52,OMX_VIDEO_AVCProfileBaseline},
-    {0,0,0,0,0}
+    {99,1485,64000,OMX_VIDEO_AVCLevel1,OMX_VIDEO_AVCProfileMain,396},
+    {99,1485,128000,OMX_VIDEO_AVCLevel1b,OMX_VIDEO_AVCProfileMain,396},
+    {396,3000,192000,OMX_VIDEO_AVCLevel11,OMX_VIDEO_AVCProfileMain,900},
+    {396,6000,384000,OMX_VIDEO_AVCLevel12,OMX_VIDEO_AVCProfileMain,2376},
+    {396,11880,768000,OMX_VIDEO_AVCLevel13,OMX_VIDEO_AVCProfileMain,2376},
+    {396,11880,2000000,OMX_VIDEO_AVCLevel2,OMX_VIDEO_AVCProfileMain,2376},
+    {792,19800,4000000,OMX_VIDEO_AVCLevel21,OMX_VIDEO_AVCProfileMain,4752},
+    {1620,20250,4000000,OMX_VIDEO_AVCLevel22,OMX_VIDEO_AVCProfileMain,8100},
+    {1620,40500,10000000,OMX_VIDEO_AVCLevel3,OMX_VIDEO_AVCProfileMain,8100},
+    {3600,108000,14000000,OMX_VIDEO_AVCLevel31,OMX_VIDEO_AVCProfileMain,18000},
+    {5120,216000,20000000,OMX_VIDEO_AVCLevel32,OMX_VIDEO_AVCProfileMain,20480},
+    {8192,245760,20000000,OMX_VIDEO_AVCLevel4,OMX_VIDEO_AVCProfileMain,32768},
+    {8192,245760,50000000,OMX_VIDEO_AVCLevel41,OMX_VIDEO_AVCProfileMain,32768},
+    {8704,522240,50000000,OMX_VIDEO_AVCLevel42,OMX_VIDEO_AVCProfileMain,34816},
+    {22080,589824,135000000,OMX_VIDEO_AVCLevel5,OMX_VIDEO_AVCProfileMain,110400},
+    {36864,983040,240000000,OMX_VIDEO_AVCLevel51,OMX_VIDEO_AVCProfileMain,184320},
+    {36864,2073600,240000000,OMX_VIDEO_AVCLevel52,OMX_VIDEO_AVCProfileMain,184320},
+    {0,0,0,0,0,0}
 
 };
 
 /* H263 profile and level table*/
-static const unsigned int h263_profile_level_table[][5]= {
+static const unsigned int h263_profile_level_table[][MAX_PROFILE_PARAMS]= {
+    /*max mb per frame, max mb per sec, max bitrate, level, profile, dpbmbs*/
+    {99,1485,64000,OMX_VIDEO_H263Level10,OMX_VIDEO_H263ProfileBaseline,0},
+    {396,5940,128000,OMX_VIDEO_H263Level20,OMX_VIDEO_H263ProfileBaseline,0},
+    {396,11880,384000,OMX_VIDEO_H263Level30,OMX_VIDEO_H263ProfileBaseline,0},
+    {396,11880,2048000,OMX_VIDEO_H263Level40,OMX_VIDEO_H263ProfileBaseline,0},
+    {99,1485,128000,OMX_VIDEO_H263Level45,OMX_VIDEO_H263ProfileBaseline,0},
+    {396,19800,4096000,OMX_VIDEO_H263Level50,OMX_VIDEO_H263ProfileBaseline,0},
+    {810,40500,8192000,OMX_VIDEO_H263Level60,OMX_VIDEO_H263ProfileBaseline,0},
+    {1620,81000,16384000,OMX_VIDEO_H263Level70,OMX_VIDEO_H263ProfileBaseline,0},
+    {32400,972000,20000000,OMX_VIDEO_H263Level70,OMX_VIDEO_H263ProfileBaseline,0},
+    {34560,1036800,20000000,OMX_VIDEO_H263Level70,OMX_VIDEO_H263ProfileBaseline,0},
+    {0,0,0,0,0,0}
+};
+
+/* HEVC profile and level table*/
+static const unsigned int hevc_profile_level_table[][MAX_PROFILE_PARAMS]= {
     /*max mb per frame, max mb per sec, max bitrate, level, profile*/
-    {99,1485,64000,OMX_VIDEO_H263Level10,OMX_VIDEO_H263ProfileBaseline},
-    {396,5940,128000,OMX_VIDEO_H263Level20,OMX_VIDEO_H263ProfileBaseline},
-    {396,11880,384000,OMX_VIDEO_H263Level30,OMX_VIDEO_H263ProfileBaseline},
-    {396,11880,2048000,OMX_VIDEO_H263Level40,OMX_VIDEO_H263ProfileBaseline},
-    {99,1485,128000,OMX_VIDEO_H263Level45,OMX_VIDEO_H263ProfileBaseline},
-    {396,19800,4096000,OMX_VIDEO_H263Level50,OMX_VIDEO_H263ProfileBaseline},
-    {810,40500,8192000,OMX_VIDEO_H263Level60,OMX_VIDEO_H263ProfileBaseline},
-    {1620,81000,16384000,OMX_VIDEO_H263Level70,OMX_VIDEO_H263ProfileBaseline},
-    {32400,972000,20000000,OMX_VIDEO_H263Level70,OMX_VIDEO_H263ProfileBaseline},
-    {34560,1036800,20000000,OMX_VIDEO_H263Level70,OMX_VIDEO_H263ProfileBaseline},
-    {0,0,0,0,0}
+    {99,1485,128000,OMX_VIDEO_HEVCMainTierLevel1,OMX_VIDEO_HEVCProfileMain,0},
+    {396,11880,1500000,OMX_VIDEO_HEVCMainTierLevel2,OMX_VIDEO_HEVCProfileMain,0},
+    {900,27000,3000000,OMX_VIDEO_HEVCMainTierLevel21,OMX_VIDEO_HEVCProfileMain,0},
+    {2025,60750,6000000,OMX_VIDEO_HEVCMainTierLevel3,OMX_VIDEO_HEVCProfileMain,0},
+    {8640,259200,10000000,OMX_VIDEO_HEVCMainTierLevel31,OMX_VIDEO_HEVCProfileMain,0},
+    {34560,1166400,12000000,OMX_VIDEO_HEVCMainTierLevel4,OMX_VIDEO_HEVCProfileMain,0},
+    {138240,4147200,20000000,OMX_VIDEO_HEVCMainTierLevel41,OMX_VIDEO_HEVCProfileMain,0},
+    {138240,8294400,25000000,OMX_VIDEO_HEVCMainTierLevel5,OMX_VIDEO_HEVCProfileMain,0},
+    {138240,4147200,40000000,OMX_VIDEO_HEVCMainTierLevel51,OMX_VIDEO_HEVCProfileMain,0},
+    {138240,4147200,50000000,OMX_VIDEO_HEVCHighTierLevel41,OMX_VIDEO_HEVCProfileMain,0},
+    {138240,4147200,100000000,OMX_VIDEO_HEVCHighTierLevel5,OMX_VIDEO_HEVCProfileMain,0},
+    {138240,4147200,1600000000,OMX_VIDEO_HEVCHighTierLevel51,OMX_VIDEO_HEVCProfileMain,0},
+    {0,0,0,0,0},
+
+    {99,1485,128000,OMX_VIDEO_HEVCMainTierLevel1,OMX_VIDEO_HEVCProfileMain10,0},
+    {396,11880,1500000,OMX_VIDEO_HEVCMainTierLevel2,OMX_VIDEO_HEVCProfileMain10,0},
+    {900,27000,3000000,OMX_VIDEO_HEVCMainTierLevel21,OMX_VIDEO_HEVCProfileMain10,0},
+    {2025,60750,6000000,OMX_VIDEO_HEVCMainTierLevel3,OMX_VIDEO_HEVCProfileMain10,0},
+    {8640,259200,10000000,OMX_VIDEO_HEVCMainTierLevel31,OMX_VIDEO_HEVCProfileMain10,0},
+    {34560,1166400,12000000,OMX_VIDEO_HEVCMainTierLevel4,OMX_VIDEO_HEVCProfileMain10,0},
+    {138240,4147200,20000000,OMX_VIDEO_HEVCMainTierLevel41,OMX_VIDEO_HEVCProfileMain10,0},
+    {138240,8294400,25000000,OMX_VIDEO_HEVCMainTierLevel5,OMX_VIDEO_HEVCProfileMain10,0},
+    {138240,4147200,40000000,OMX_VIDEO_HEVCMainTierLevel51,OMX_VIDEO_HEVCProfileMain10,0},
+    {138240,4147200,50000000,OMX_VIDEO_HEVCHighTierLevel41,OMX_VIDEO_HEVCProfileMain10,0},
+    {138240,4147200,100000000,OMX_VIDEO_HEVCHighTierLevel5,OMX_VIDEO_HEVCProfileMain10,0},
+    {138240,4147200,1600000000,OMX_VIDEO_HEVCHighTierLevel51,OMX_VIDEO_HEVCProfileMain10,0},
+    {0,0,0,0,0},
 };
 
 #define Log2(number, power)  { OMX_U32 temp = number; power = 0; while( (0 == (temp & 0x1)) &&  power < 16) { temp >>=0x1; power++; } }
@@ -184,6 +222,7 @@
     paused = false;
     async_thread_created = false;
     color_format = 0;
+    hw_overload = false;
     pthread_mutex_init(&pause_resume_mlock, NULL);
     pthread_cond_init(&pause_resume_cond, NULL);
     memset(&extradata_info, 0, sizeof(extradata_info));
@@ -207,10 +246,12 @@
     memset(&voptimecfg, 0, sizeof(voptimecfg));
     memset(&capability, 0, sizeof(capability));
     memset(&m_debug,0,sizeof(m_debug));
-    memset(&hier_p_layers,0,sizeof(hier_p_layers));
-    memset(&display_info,0,sizeof(display_info));
+    memset(&hier_layers,0,sizeof(hier_layers));
     is_searchrange_set = false;
     enable_mv_narrow_searchrange = false;
+    supported_rc_modes = RC_ALL;
+    camera_mode_enabled = false;
+    memset(&ltrinfo, 0, sizeof(ltrinfo));
 
     char property_value[PROPERTY_VALUE_MAX] = {0};
     property_get("vidc.enc.log.in", property_value, "0");
@@ -347,7 +388,11 @@
             while (!ioctl(pfd.fd, VIDIOC_DQBUF, &v4l2_buf)) {
                 venc_msg.msgcode=VEN_MSG_INPUT_BUFFER_DONE;
                 venc_msg.statuscode=VEN_S_SUCCESS;
-                omxhdr=omx_venc_base->m_inp_mem_ptr+v4l2_buf.index;
+                if (omx_venc_base->mUseProxyColorFormat && !omx_venc_base->mUsesColorConversion)
+                    omxhdr = &omx_venc_base->meta_buffer_hdr[v4l2_buf.index];
+                else
+                    omxhdr = &omx_venc_base->m_inp_mem_ptr[v4l2_buf.index];
+
                 venc_msg.buf.clientdata=(void*)omxhdr;
                 omx->handle->ebd++;
 
@@ -380,6 +425,15 @@
                     DEBUG_PRINT_ERROR("ERROR: Wrong ioctl message");
                     break;
                 }
+            } else if (dqevent.type == V4L2_EVENT_MSM_VIDC_HW_OVERLOAD) {
+                DEBUG_PRINT_ERROR("HW Overload received");
+                venc_msg.statuscode = VEN_S_EFAIL;
+                venc_msg.msgcode = VEN_MSG_HW_OVERLOAD;
+
+                if (omx->async_message_process(input,&venc_msg) < 0) {
+                    DEBUG_PRINT_ERROR("ERROR: Wrong ioctl message");
+                    break;
+                }
             } else if (dqevent.type == V4L2_EVENT_MSM_VIDC_SYS_ERROR) {
                 DEBUG_PRINT_ERROR("ERROR: Encoder is in bad state");
                 venc_msg.msgcode = VEN_MSG_INDICATION;
@@ -500,6 +554,16 @@
                 p_extra->nDataSize = payloadSize;
                 break;
             }
+            case MSM_VIDC_EXTRADATA_METADATA_LTR:
+            {
+                *p_extra->data = *p_extradata->data;
+                p_extra->nSize = ALIGN(sizeof(OMX_OTHER_EXTRADATATYPE) + p_extradata->data_size, 4);
+                p_extra->nVersion.nVersion = OMX_SPEC_VERSION;
+                p_extra->nPortIndex = OMX_DirOutput;
+                p_extra->eType = (OMX_EXTRADATATYPE) OMX_ExtraDataVideoLTRInfo;
+                p_extra->nDataSize = p_extradata->data_size;
+                break;
+            }
             case MSM_VIDC_EXTRADATA_NONE:
                 p_extra->nSize = ALIGN(sizeof(OMX_OTHER_EXTRADATATYPE), 4);
                 p_extra->nVersion.nVersion = OMX_SPEC_VERSION;
@@ -622,6 +686,9 @@
         } else if(m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264) {
            size = snprintf(m_debug.outfile_name, PROPERTY_VALUE_MAX, "%s/output_enc_%lu_%lu_%p.264",
                            m_debug.log_loc, m_sVenc_cfg.input_width, m_sVenc_cfg.input_height, this);
+        } else if(m_sVenc_cfg.codectype == V4L2_PIX_FMT_HEVC) {
+           size = snprintf(m_debug.outfile_name, PROPERTY_VALUE_MAX, "%s/output_enc_%ld_%ld_%p.265",
+                           m_debug.log_loc, m_sVenc_cfg.input_width, m_sVenc_cfg.input_height, this);
         } else if(m_sVenc_cfg.codectype == V4L2_PIX_FMT_H263) {
            size = snprintf(m_debug.outfile_name, PROPERTY_VALUE_MAX, "%s/output_enc_%lu_%lu_%p.263",
                            m_debug.log_loc, m_sVenc_cfg.input_width, m_sVenc_cfg.input_height, this);
@@ -658,6 +725,9 @@
         } else if(m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264) {
            size = snprintf(m_debug.extradatafile_name, PROPERTY_VALUE_MAX, "%s/extradata_enc_%lu_%lu_%p.264",
                            m_debug.log_loc, m_sVenc_cfg.input_width, m_sVenc_cfg.input_height, this);
+        } else if(m_sVenc_cfg.codectype == V4L2_PIX_FMT_HEVC) {
+           size = snprintf(m_debug.extradatafile_name, PROPERTY_VALUE_MAX, "%s/extradata_enc_%lu_%lu_%p.265",
+                           m_debug.log_loc, m_sVenc_cfg.input_width, m_sVenc_cfg.input_height, this);
         } else if(m_sVenc_cfg.codectype == V4L2_PIX_FMT_H263) {
            size = snprintf(m_debug.extradatafile_name, PROPERTY_VALUE_MAX, "%s/extradata_enc_%lu_%lu_%p.263",
                            m_debug.log_loc, m_sVenc_cfg.input_width, m_sVenc_cfg.input_height, this);
@@ -754,21 +824,17 @@
     int r;
     unsigned int alignment = 0,buffer_size = 0, temp =0;
     struct v4l2_control control;
-    OMX_STRING device_name = (OMX_STRING)"/dev/video/venus_enc";
+    OMX_STRING device_name = (OMX_STRING)"/dev/video33";
+    char property_value[PROPERTY_VALUE_MAX] = {0};
+    char platform_name[PROPERTY_VALUE_MAX] = {0};
 
-    char platform_name[PROPERTY_VALUE_MAX];
     property_get("ro.board.platform", platform_name, "0");
+    property_get("vidc.enc.narrow.searchrange", property_value, "0");
+    enable_mv_narrow_searchrange = atoi(property_value);
 
     if (!strncmp(platform_name, "msm8610", 7)) {
         device_name = (OMX_STRING)"/dev/video/q6_enc";
-    }
-    if (!strncmp(platform_name, "msm8916", 7)) {
-        enable_mv_narrow_searchrange = true;
-        sp<IBinder> display(SurfaceComposerClient::getBuiltInDisplay(
-                        ISurfaceComposer::eDisplayIdMain));
-        SurfaceComposerClient::getDisplayInfo(display, &display_info);
-        DEBUG_PRINT_LOW("Display panel resolution %dX%d",
-            display_info.w, display_info.h);
+        supported_rc_modes = (RC_ALL & ~RC_CBR_CFR);
     }
     m_nDriver_fd = open (device_name, O_RDWR);
 
@@ -818,6 +884,12 @@
         profile_level.level = V4L2_MPEG_VIDC_VIDEO_VP8_VERSION_0;
         session_qp_range.minqp = 1;
         session_qp_range.maxqp = 128;
+    } else if (codec == OMX_VIDEO_CodingHEVC) {
+        m_sVenc_cfg.codectype = V4L2_PIX_FMT_HEVC;
+        session_qp_range.minqp = 1;
+        session_qp_range.maxqp = 51;
+        codec_profile.profile = V4L2_MPEG_VIDC_VIDEO_HEVC_PROFILE_MAIN;
+        profile_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_1;
     }
     session_qp_values.minqp = session_qp_range.minqp;
     session_qp_values.maxqp = session_qp_range.maxqp;
@@ -923,6 +995,7 @@
 
     resume_in_stopped = 0;
     metadatamode = 0;
+    camera_mode_enabled = false;
 
     control.id = V4L2_CID_MPEG_VIDEO_HEADER_MODE;
     control.value = V4L2_MPEG_VIDEO_HEADER_MODE_SEPARATE;
@@ -959,6 +1032,16 @@
             DEBUG_PRINT_ERROR("Failed to set V4L2_CID_MPEG_VIDC_VIDEO_NUM_P_FRAME\n");
     }
 
+    property_get("vidc.debug.turbo", property_value, "0");
+    if (atoi(property_value)) {
+        DEBUG_PRINT_HIGH("Turbo mode debug property enabled");
+        control.id = V4L2_CID_MPEG_VIDC_SET_PERF_LEVEL;
+        control.value = V4L2_CID_MPEG_VIDC_PERF_LEVEL_TURBO;
+        if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) {
+            DEBUG_PRINT_ERROR("Failed to set turbo mode");
+        }
+    }
+
     return true;
 }
 
@@ -1071,7 +1154,7 @@
 }
 
 bool venc_dev::venc_get_seq_hdr(void *buffer,
-        unsigned buffer_size, OMX_U32 *header_len)
+        unsigned buffer_size, unsigned *header_len)
 {
     (void) buffer, (void) buffer_size, (void) header_len;
     return true;
@@ -1101,6 +1184,14 @@
         else
             bufreq.count = 2;
 
+        // Increase buffer-header count for metadata-mode on input port
+        // to improve buffering and reduce bottlenecks in clients
+        if (metadatamode && (bufreq.count < 9)) {
+            DEBUG_PRINT_LOW("FW returned buffer count = %d , overwriting with 16",
+                bufreq.count);
+            bufreq.count = 9;
+        }
+
         bufreq.type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
         ret = ioctl(m_nDriver_fd,VIDIOC_REQBUFS, &bufreq);
 
@@ -1120,7 +1211,7 @@
 #endif
         *buff_size = m_sInput_buff_property.datasize;
     } else {
-        int extra_idx = 0;
+        unsigned int extra_idx = 0;
         fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
         fmt.fmt.pix_mp.height = m_sVenc_cfg.dvs_height;
         fmt.fmt.pix_mp.width = m_sVenc_cfg.dvs_width;
@@ -1194,8 +1285,7 @@
                     if (!venc_set_color_format(portDefn->format.video.eColorFormat)) {
                         return false;
                     }
-                    if ((display_info.w * display_info.h) > (OMX_CORE_720P_WIDTH * OMX_CORE_720P_HEIGHT)
-                        && enable_mv_narrow_searchrange &&
+                    if (enable_mv_narrow_searchrange &&
                         (m_sVenc_cfg.input_width * m_sVenc_cfg.input_height) >=
                         (OMX_CORE_1080P_WIDTH * OMX_CORE_1080P_HEIGHT)) {
                         if (venc_set_searchrange() == false) {
@@ -1467,7 +1557,10 @@
                                         pParam->eProfile, pParam->eLevel);
                     return false;
                 }
-
+                if(venc_set_vpx_error_resilience(pParam->bErrorResilientMode) == false) {
+                    DEBUG_PRINT_ERROR("ERROR: Failed to set vpx error resilience");
+                    return false;
+                 }
                 if(!venc_set_ltrmode(1, 1)) {
                    DEBUG_PRINT_ERROR("ERROR: Failed to enable ltrmode");
                    return false;
@@ -1484,6 +1577,20 @@
 
                 break;
             }
+            case (OMX_INDEXTYPE)OMX_IndexParamVideoHevc:
+            {
+                DEBUG_PRINT_LOW("venc_set_param:OMX_IndexParamVideoHevc");
+                OMX_VIDEO_PARAM_HEVCTYPE* pParam = (OMX_VIDEO_PARAM_HEVCTYPE*)paramData;
+                if (!venc_set_profile_level (pParam->eProfile, pParam->eLevel)) {
+                    DEBUG_PRINT_ERROR("ERROR: Unsuccessful in updating Profile and level %d, %d",
+                                        pParam->eProfile, pParam->eLevel);
+                    return false;
+                }
+                if (!venc_set_inloop_filter(OMX_VIDEO_AVCLoopFilterEnable))
+                    DEBUG_PRINT_HIGH("WARN: Request for setting Inloop filter failed for HEVC encoder");
+
+                break;
+            }
         case OMX_IndexParamVideoIntraRefresh:
             {
                 DEBUG_PRINT_LOW("venc_set_param:OMX_IndexParamVideoIntraRefresh");
@@ -1737,6 +1844,35 @@
                }
             }
             break;
+        case OMX_QcomIndexParamVideoLTRCount:
+            {
+                DEBUG_PRINT_LOW("venc_set_param: OMX_QcomIndexParamVideoLTRCount");
+                OMX_QCOM_VIDEO_PARAM_LTRCOUNT_TYPE* pParam =
+                        (OMX_QCOM_VIDEO_PARAM_LTRCOUNT_TYPE*)paramData;
+                if (pParam->nCount > 0) {
+                    if (venc_set_ltrmode(1, pParam->nCount) == false) {
+                        DEBUG_PRINT_ERROR("ERROR: Enable LTR mode failed");
+                        return false;
+                    }
+                } else {
+                    if (venc_set_ltrmode(0, 0) == false) {
+                        DEBUG_PRINT_ERROR("ERROR: Disable LTR mode failed");
+                        return false;
+                    }
+                }
+                break;
+            }
+        case OMX_QcomIndexParamVideoHybridHierpMode:
+            {
+                QOMX_EXTNINDEX_VIDEO_HYBRID_HP_MODE* pParam =
+                    (QOMX_EXTNINDEX_VIDEO_HYBRID_HP_MODE*)paramData;
+
+                if (!venc_set_hybrid_hierp(pParam->nHpLayers)) {
+                     DEBUG_PRINT_ERROR("Setting hybrid Hier-P mode failed");
+                     return OMX_ErrorUnsupportedSetting;
+                }
+                break;
+            }
         case OMX_IndexParamVideoSliceFMO:
         default:
             DEBUG_PRINT_ERROR("ERROR: Unsupported parameter in venc_set_param: %u",
@@ -1825,6 +1961,9 @@
                 OMX_CONFIG_ROTATIONTYPE *config_rotation =
                     reinterpret_cast<OMX_CONFIG_ROTATIONTYPE*>(configData);
                 OMX_U32 nFrameWidth;
+                if (!config_rotation) {
+                   return false;
+                }
                 if (true == deinterlace_enabled) {
                     DEBUG_PRINT_ERROR("ERROR: Rotation is not supported with deinterlacing");
                     return false;
@@ -1880,13 +2019,13 @@
                 DEBUG_PRINT_LOW("venc_set_config: OMX_IndexConfigVideoVp8ReferenceFrame");
                 if ((vp8refframe->nPortIndex == (OMX_U32)PORT_INDEX_IN) &&
                     (vp8refframe->bUseGoldenFrame)) {
-                    if(venc_set_useltr() == false) {
+                    if(venc_set_useltr(0x1) == false) {
                         DEBUG_PRINT_ERROR("ERROR: use goldenframe failed");
                         return false;
                     }
                 } else if((vp8refframe->nPortIndex == (OMX_U32)PORT_INDEX_IN) &&
                     (vp8refframe->bGoldenFrameRefresh)) {
-                    if(venc_set_markltr() == false) {
+                    if(venc_set_markltr(0x1) == false) {
                         DEBUG_PRINT_ERROR("ERROR: Setting goldenframe failed");
                         return false;
                     }
@@ -1895,6 +2034,57 @@
                 }
                 break;
             }
+        case OMX_QcomIndexConfigVideoLTRUse:
+            {
+                OMX_QCOM_VIDEO_CONFIG_LTRUSE_TYPE* pParam = (OMX_QCOM_VIDEO_CONFIG_LTRUSE_TYPE*)configData;
+                DEBUG_PRINT_LOW("venc_set_config: OMX_QcomIndexConfigVideoLTRUse");
+                if (pParam->nPortIndex == (OMX_U32)PORT_INDEX_IN) {
+                    if (venc_set_useltr(pParam->nID) == false) {
+                        DEBUG_PRINT_ERROR("ERROR: Use LTR failed");
+                        return false;
+                    }
+                } else {
+                    DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_QcomIndexConfigVideoLTRUse");
+                }
+                break;
+            }
+        case OMX_QcomIndexConfigVideoLTRMark:
+            {
+                OMX_QCOM_VIDEO_CONFIG_LTRMARK_TYPE* pParam = (OMX_QCOM_VIDEO_CONFIG_LTRMARK_TYPE*)configData;
+                DEBUG_PRINT_LOW("venc_set_config: OMX_QcomIndexConfigVideoLTRMark");
+                if (pParam->nPortIndex == (OMX_U32)PORT_INDEX_IN) {
+                    if (venc_set_markltr(pParam->nID) == false) {
+                        DEBUG_PRINT_ERROR("ERROR: Mark LTR failed");
+                        return false;
+                    }
+                }  else {
+                    DEBUG_PRINT_ERROR("ERROR: Invalid Port Index for OMX_QcomIndexConfigVideoLTRMark");
+                }
+                break;
+            }
+        case OMX_QcomIndexConfigPerfLevel:
+            {
+                OMX_QCOM_VIDEO_CONFIG_PERF_LEVEL *perf =
+                        (OMX_QCOM_VIDEO_CONFIG_PERF_LEVEL *)configData;
+                DEBUG_PRINT_LOW("Set perf level: %d", perf->ePerfLevel);
+                if (!venc_set_perf_level(perf->ePerfLevel)) {
+                    DEBUG_PRINT_ERROR("ERROR: Failed to set perf level to %d", perf->ePerfLevel);
+                    return false;
+                } else {
+                    performance_level.perflevel = (unsigned int) perf->ePerfLevel;
+                }
+                break;
+            }
+        case OMX_QcomIndexConfigVideoVencPerfMode:
+            {
+                QOMX_EXTNINDEX_VIDEO_PERFMODE *pParam = (QOMX_EXTNINDEX_VIDEO_PERFMODE *) configData;
+                DEBUG_PRINT_LOW("venc_set_config: OMX_QcomIndexConfigVideoVencPerfMode");
+                if (venc_set_perf_mode(pParam->nPerfMode) == false) {
+                    DEBUG_PRINT_ERROR("Failed to set V4L2_CID_MPEG_VIDC_VIDEO_PERF_MODE");
+                    return false;
+                }
+                break;
+            }
         default:
             DEBUG_PRINT_ERROR("Unsupported config index = %u", index);
             break;
@@ -2022,6 +2212,7 @@
 
     DEBUG_PRINT_HIGH("%s(): Check Profile/Level set in driver before start",
             __func__);
+    m_level_set = false;
 
     if (!venc_set_profile_level(0, 0)) {
         DEBUG_PRINT_ERROR("ERROR: %s(): Driver Profile/Level is NOT SET",
@@ -2069,6 +2260,23 @@
     return 0;
 }
 
+inline const char* hiermode_string(int val)
+{
+    switch(val)
+    {
+    case HIER_NONE:
+        return "No Hier";
+    case HIER_P:
+        return "Hier-P";
+    case HIER_B:
+        return "Hier-B";
+    case HIER_P_HYBRID:
+        return "Hybrid Hier-P";
+    default:
+        return "No hier";
+    }
+}
+
 void venc_dev::venc_config_print()
 {
 
@@ -2083,8 +2291,8 @@
             m_sVenc_cfg.dvs_width, m_sVenc_cfg.dvs_height,
             m_sVenc_cfg.fps_num/m_sVenc_cfg.fps_den);
 
-    DEBUG_PRINT_HIGH("ENC_CONFIG: Bitrate: %ld, RC: %ld, I-Period: %ld",
-            bitrate.target_bitrate, rate_ctrl.rcmode, intra_period.num_pframes);
+    DEBUG_PRINT_HIGH("ENC_CONFIG: Bitrate: %ld, RC: %ld, P - Frames : %ld, B - Frames = %ld",
+            bitrate.target_bitrate, rate_ctrl.rcmode, intra_period.num_pframes, intra_period.num_bframes);
 
     DEBUG_PRINT_HIGH("ENC_CONFIG: qpI: %ld, qpP: %ld, qpb: %ld",
             session_qp.iframeqp, session_qp.pframeqp, session_qp.bframeqp);
@@ -2092,9 +2300,6 @@
     DEBUG_PRINT_HIGH("ENC_CONFIG: Init_qpI: %ld, Init_qpP: %ld, Init_qpb: %ld",
             init_qp.iframeqp, init_qp.pframeqp, init_qp.bframeqp);
 
-    DEBUG_PRINT_HIGH("ENC_CONFIG: Init_qpI: %ld, Init_qpP: %ld, Init_qpb: %ld",
-            init_qp.iframeqp, init_qp.pframeqp, init_qp.bframeqp);
-
     DEBUG_PRINT_HIGH("ENC_CONFIG: minQP: %lu, maxQP: %lu",
             session_qp_values.minqp, session_qp_values.maxqp);
 
@@ -2112,7 +2317,11 @@
     DEBUG_PRINT_HIGH("ENC_CONFIG: IntraMB/Frame: %ld, HEC: %ld, IDR Period: %ld",
             intra_refresh.mbcount, hec.header_extension, idrperiod.idrperiod);
 
-    DEBUG_PRINT_HIGH("ENC_CONFIG: Hier-P layers: %d", hier_p_layers.numlayers);
+    DEBUG_PRINT_HIGH("ENC_CONFIG: LTR Enabled: %d, Count: %d",
+            ltrinfo.enabled, ltrinfo.count);
+
+    DEBUG_PRINT_HIGH("ENC_CONFIG: Hier layers: %d, Hier Mode: %s VPX_ErrorResilience: %d",
+            hier_layers.numlayers, hiermode_string(hier_layers.hier_mode), vpx_err_resilience.enable);
 
     DEBUG_PRINT_HIGH("ENC_CONFIG: Performace level: %d", performance_level.perflevel);
 
@@ -2170,7 +2379,8 @@
     struct pmem *pmem_tmp;
     struct v4l2_buffer buf;
     struct v4l2_plane plane[VIDEO_MAX_PLANES];
-    int rc = 0, extra_idx;
+    int rc = 0;
+    unsigned int extra_idx;
 
     pmem_tmp = (struct pmem *)buf_addr;
     DEBUG_PRINT_LOW("venc_use_buf:: pmem_tmp = %p", pmem_tmp);
@@ -2355,6 +2565,7 @@
     struct v4l2_plane plane;
     int rc=0;
     struct OMX_BUFFERHEADERTYPE *bufhdr;
+    struct v4l2_control control;
     encoder_media_buffer_type * meta_buf = NULL;
     temp_buffer = (struct pmem *)buffer;
 
@@ -2401,11 +2612,24 @@
                 }
             } else if (!color_format) {
                 if (meta_buf->buffer_type == kMetadataBufferTypeCameraSource) {
-                    if (meta_buf->meta_handle->data[3] & private_handle_t::PRIV_FLAGS_ITU_R_709)
+                    if (meta_buf->meta_handle->numFds + meta_buf->meta_handle->numInts > 3 &&
+                        meta_buf->meta_handle->data[3] & private_handle_t::PRIV_FLAGS_ITU_R_709)
                         buf.flags = V4L2_MSM_BUF_FLAG_YUV_601_709_CLAMP;
+                    if (meta_buf->meta_handle->numFds + meta_buf->meta_handle->numInts > 2) {
                     plane.data_offset = meta_buf->meta_handle->data[1];
                     plane.length = meta_buf->meta_handle->data[2];
                     plane.bytesused = meta_buf->meta_handle->data[2];
+                    }
+                    if (!camera_mode_enabled) {
+                        camera_mode_enabled = true;
+                        control.id = V4L2_CID_MPEG_VIDC_SET_PERF_LEVEL;
+                        control.value = V4L2_CID_MPEG_VIDC_PERF_LEVEL_NOMINAL;
+                        rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
+                        if (rc)
+                            DEBUG_PRINT_HIGH("Failed to set control for perf level");
+                        DEBUG_PRINT_LOW("Set control id = 0x%x, value = 0x%x, meta_buf type = %d",
+                                control.id, control.value, meta_buf->buffer_type);
+                    }
                     DEBUG_PRINT_LOW("venc_empty_buf: camera buf: fd = %d filled %d of %d flag 0x%x",
                             fd, plane.bytesused, plane.length, buf.flags);
                 } else if (meta_buf->buffer_type == kMetadataBufferTypeGrallocSource) {
@@ -2414,6 +2638,16 @@
                     plane.data_offset = 0;
                     plane.length = handle->size;
                     plane.bytesused = handle->size;
+                    if ((!camera_mode_enabled) && (handle->flags & private_handle_t:: PRIV_FLAGS_CAMERA_WRITE)) {
+                        camera_mode_enabled = true;
+                        control.id = V4L2_CID_MPEG_VIDC_SET_PERF_LEVEL;
+                        control.value = V4L2_CID_MPEG_VIDC_PERF_LEVEL_NOMINAL;
+                        rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
+                        if (rc)
+                            DEBUG_PRINT_HIGH("Failed to set perl level");
+                        DEBUG_PRINT_LOW("Set control id = 0x%x, value = 0x%x, flags = 0x%x",
+                                control.id, control.value, handle->flags);
+                    }
                         DEBUG_PRINT_LOW("venc_empty_buf: Opaque camera buf: fd = %d "
                                 ": filled %d of %d", fd, plane.bytesused, plane.length);
                 }
@@ -2463,6 +2697,9 @@
 
         if (ret) {
             DEBUG_PRINT_ERROR("Failed to call streamon");
+            if (errno == EBUSY) {
+                hw_overload = true;
+            }
             return false;
         } else {
             streaming[OUTPUT_PORT] = true;
@@ -2480,7 +2717,8 @@
     struct venc_buffer  frameinfo;
     struct v4l2_buffer buf;
     struct v4l2_plane plane[VIDEO_MAX_PLANES];
-    int rc = 0, extra_idx;
+    int rc = 0;
+    unsigned int extra_idx;
     struct OMX_BUFFERHEADERTYPE *bufhdr;
 
     if (buffer == NULL)
@@ -2572,23 +2810,76 @@
     return true;
 }
 
+bool venc_dev::venc_validate_hybridhp_params(OMX_U32 layers, OMX_U32 bFrames, OMX_U32 count, int mode)
+{
+    // Check for layers in Hier-p/hier-B with Hier-P-Hybrid
+    if (layers && (mode == HIER_P || mode == HIER_B) && hier_layers.hier_mode == HIER_P_HYBRID)
+        return false;
+
+    // Check for bframes with Hier-P-Hybrid
+    if (bFrames && hier_layers.hier_mode == HIER_P_HYBRID)
+        return false;
+
+    // Check for Hier-P-Hybrid with bframes/LTR/hier-p/Hier-B
+    if (layers && mode == HIER_P_HYBRID && (intra_period.num_bframes || hier_layers.hier_mode == HIER_P ||
+           hier_layers.hier_mode == HIER_B || ltrinfo.count))
+        return false;
+
+    // Check for LTR with Hier-P-Hybrid
+    if (count && hier_layers.hier_mode == HIER_P_HYBRID)
+        return false;
+
+    return true;
+}
+
 bool venc_dev::venc_set_hier_layers(QOMX_VIDEO_HIERARCHICALCODINGTYPE type,
                                     OMX_U32 num_layers)
 {
     struct v4l2_control control;
-    control.id = V4L2_CID_MPEG_VIDC_VIDEO_HIER_P_NUM_LAYERS;
+
+    if (!venc_validate_hybridhp_params(num_layers, 0, 0, (int)type)){
+        DEBUG_PRINT_ERROR("Invalid settings, Hier-pLayers enabled with HybridHP");
+        return false;
+    }
+
     if (type == QOMX_HIERARCHICALCODING_P) {
-        control.value = num_layers;
+        // Reduce layer count by 1 before sending to driver. This avoids
+        // driver doing the same in multiple places.
+        control.id = V4L2_CID_MPEG_VIDC_VIDEO_HIER_P_NUM_LAYERS;
+        control.value = num_layers - 1;
         DEBUG_PRINT_HIGH("Set Hier P num layers: %u", (unsigned int)num_layers);
         if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) {
             DEBUG_PRINT_ERROR("Request to set Hier P num layers failed");
             return false;
         }
-        hier_p_layers.numlayers = num_layers;
+        if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264) {
+            DEBUG_PRINT_LOW("Set H264_SVC_NAL");
+            control.id = V4L2_CID_MPEG_VIDC_VIDEO_H264_NAL_SVC;
+            control.value = V4L2_CID_MPEG_VIDC_VIDEO_H264_NAL_SVC_ENABLED;
+            if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) {
+                DEBUG_PRINT_ERROR("Failed to enable SVC_NAL");
+                return false;
+            }
+        }
+        hier_layers.hier_mode = HIER_P;
+    } else if (type == QOMX_HIERARCHICALCODING_B) {
+        if (m_sVenc_cfg.codectype != V4L2_PIX_FMT_HEVC) {
+            DEBUG_PRINT_ERROR("Failed : Hier B layers supported only for HEVC encode");
+            return false;
+        }
+        control.id = V4L2_CID_MPEG_VIDC_VIDEO_HIER_B_NUM_LAYERS;
+        control.value = num_layers - 1;
+        DEBUG_PRINT_INFO("Set Hier B num layers: %u", (unsigned int)num_layers);
+        if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) {
+            DEBUG_PRINT_ERROR("Request to set Hier P num layers failed");
+            return false;
+        }
+        hier_layers.hier_mode = HIER_B;
     } else {
         DEBUG_PRINT_ERROR("Request to set hier num layers failed for type: %d", type);
         return false;
     }
+    hier_layers.numlayers = num_layers;
     return true;
 }
 
@@ -2773,7 +3064,7 @@
                 control.id, control.value);
         rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
         if (rc) {
-            DEBUG_PRINT_ERROR("Failed to set control\n");
+            DEBUG_PRINT_ERROR("Failed to set control");
             return false;
         }
 
@@ -2787,12 +3078,12 @@
                 control.id, control.value);
         rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
         if (rc) {
-            DEBUG_PRINT_ERROR("Failed to set control\n");
+            DEBUG_PRINT_ERROR("Failed to set control");
             return false;
         }
     } else {
-        DEBUG_PRINT_ERROR("Wrong qp values[%lu %lu], allowed range[%lu %lu]",
-            min_qp, max_qp, session_qp_range.minqp, session_qp_range.maxqp);
+        DEBUG_PRINT_ERROR("Wrong qp values[%u %u], allowed range[%u %u]",
+            (unsigned int)min_qp, (unsigned int)max_qp, (unsigned int)session_qp_range.minqp, (unsigned int)session_qp_range.maxqp);
     }
 
     return true;
@@ -3047,6 +3338,96 @@
                 return false;
                 break;
         }
+    }  else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_HEVC) {
+        if (eProfile == OMX_VIDEO_HEVCProfileMain) {
+            requested_profile.profile = V4L2_MPEG_VIDC_VIDEO_HEVC_PROFILE_MAIN;
+        } else if(eProfile == OMX_VIDEO_HEVCProfileMain10) {
+            requested_profile.profile = V4L2_MPEG_VIDC_VIDEO_HEVC_PROFILE_MAIN10;
+        } else {
+            DEBUG_PRINT_ERROR("ERROR: Unsupported HEVC profile = %lu",
+                    requested_profile.profile);
+            return false;
+        }
+
+        //profile level
+        switch (eLevel) {
+            case OMX_VIDEO_HEVCMainTierLevel1:
+                requested_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_1;
+                break;
+            case OMX_VIDEO_HEVCHighTierLevel1:
+                requested_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_1;
+                break;
+            case OMX_VIDEO_HEVCMainTierLevel2:
+                requested_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_2;
+                break;
+            case OMX_VIDEO_HEVCHighTierLevel2:
+                requested_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_2;
+                break;
+            case OMX_VIDEO_HEVCMainTierLevel21:
+                requested_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_2_1;
+                break;
+            case OMX_VIDEO_HEVCHighTierLevel21:
+                requested_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_2_1;
+                break;
+            case OMX_VIDEO_HEVCMainTierLevel3:
+                requested_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_3;
+                break;
+            case OMX_VIDEO_HEVCHighTierLevel3:
+                requested_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_3;
+                break;
+            case OMX_VIDEO_HEVCMainTierLevel31:
+                requested_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_3_1;
+                break;
+            case OMX_VIDEO_HEVCHighTierLevel31:
+                requested_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_3_1;
+                break;
+            case OMX_VIDEO_HEVCMainTierLevel4:
+                requested_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_4;
+                break;
+            case OMX_VIDEO_HEVCHighTierLevel4:
+                requested_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_4;
+                break;
+            case OMX_VIDEO_HEVCMainTierLevel41:
+                requested_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_4_1;
+                break;
+            case OMX_VIDEO_HEVCHighTierLevel41:
+                requested_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_4_1;
+                break;
+            case OMX_VIDEO_HEVCMainTierLevel5:
+                requested_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_5;
+                break;
+            case OMX_VIDEO_HEVCHighTierLevel5:
+                requested_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_5;
+                break;
+            case OMX_VIDEO_HEVCMainTierLevel51:
+                requested_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_5_1;
+                break;
+            case OMX_VIDEO_HEVCHighTierLevel51:
+                requested_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_5_1;
+                break;
+            case OMX_VIDEO_HEVCMainTierLevel52:
+                requested_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_5_2;
+                break;
+            case OMX_VIDEO_HEVCHighTierLevel52:
+                requested_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_5_2;
+                break;
+            case OMX_VIDEO_HEVCMainTierLevel6:
+                requested_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_6;
+                break;
+            case OMX_VIDEO_HEVCHighTierLevel6:
+                requested_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_6;
+                break;
+            case OMX_VIDEO_HEVCMainTierLevel61:
+                requested_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_6_1;
+                break;
+            case OMX_VIDEO_HEVCHighTierLevel61:
+                requested_level.level = V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_6_1;
+                break;
+            default :
+                DEBUG_PRINT_ERROR("ERROR: Unsupported HEVC level= %lu",
+                        requested_level.level);
+                return false;
+        }
     }
 
     if (!m_profile_set) {
@@ -3059,6 +3440,8 @@
             control.id = V4L2_CID_MPEG_VIDEO_MPEG4_PROFILE;
         } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H263) {
             control.id = V4L2_CID_MPEG_VIDC_VIDEO_H263_PROFILE;
+        } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_HEVC) {
+            control.id = V4L2_CID_MPEG_VIDC_VIDEO_HEVC_PROFILE;
         } else {
             DEBUG_PRINT_ERROR("Wrong CODEC");
             return false;
@@ -3092,6 +3475,8 @@
             control.id = V4L2_CID_MPEG_VIDC_VIDEO_H263_LEVEL;
         } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_VP8) {
             control.id = V4L2_CID_MPEG_VIDC_VIDEO_VP8_PROFILE_LEVEL;
+        } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_HEVC) {
+            control.id = V4L2_CID_MPEG_VIDC_VIDEO_HEVC_TIER_LEVEL;
         } else {
             DEBUG_PRINT_ERROR("Wrong CODEC");
             return false;
@@ -3140,17 +3525,28 @@
 
     if ((codec_profile.profile != V4L2_MPEG_VIDEO_MPEG4_PROFILE_ADVANCED_SIMPLE) &&
             (codec_profile.profile != V4L2_MPEG_VIDEO_H264_PROFILE_MAIN) &&
+            (codec_profile.profile != V4L2_MPEG_VIDC_VIDEO_HEVC_PROFILE_MAIN) &&
+            (codec_profile.profile != V4L2_MPEG_VIDC_VIDEO_HEVC_PROFILE_MAIN10) &&
             (codec_profile.profile != V4L2_MPEG_VIDEO_H264_PROFILE_HIGH)) {
         nBFrames=0;
     }
-    if ((display_info.w * display_info.h > OMX_CORE_720P_WIDTH * OMX_CORE_720P_HEIGHT)
-        && enable_mv_narrow_searchrange && (m_sVenc_cfg.input_width * m_sVenc_cfg.input_height >=
-        OMX_CORE_1080P_WIDTH * OMX_CORE_1080P_HEIGHT || is_searchrange_set)) {
-        nBFrames=0;
+
+    if (!venc_validate_hybridhp_params(0, nBFrames, 0, 0)) {
+        DEBUG_PRINT_ERROR("Invalid settings, bframes cannot be enabled with HybridHP");
+        return false;
+    }
+
+    intra_period.num_pframes = nPFrames;
+    intra_period.num_bframes = nBFrames;
+
+    if (!venc_calibrate_gop())
+    {
+        DEBUG_PRINT_ERROR("Invalid settings, Hybrid HP enabled with LTR OR Hier-pLayers OR bframes");
+        return false;
     }
 
     control.id = V4L2_CID_MPEG_VIDC_VIDEO_NUM_P_FRAMES;
-    control.value = nPFrames;
+    control.value = intra_period.num_pframes;
     rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
 
     if (rc) {
@@ -3160,9 +3556,8 @@
 
     DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
 
-    intra_period.num_pframes = control.value;
     control.id = V4L2_CID_MPEG_VIDC_VIDEO_NUM_B_FRAMES;
-    control.value = nBFrames;
+    control.value = intra_period.num_bframes;
     DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
     rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
 
@@ -3171,7 +3566,6 @@
         return false;
     }
 
-    intra_period.num_bframes = nBFrames;
     DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%lu", control.id, intra_period.num_bframes);
 
     if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264) {
@@ -3357,6 +3751,11 @@
     } else if ((ir_mode == OMX_VIDEO_IntraRefreshBoth) &&
             (irMBs < ((m_sVenc_cfg.dvs_width * m_sVenc_cfg.dvs_height)>>8))) {
         control_mode.value = V4L2_CID_MPEG_VIDC_VIDEO_INTRA_REFRESH_CYCLIC_ADAPTIVE;
+    } else if ((ir_mode == OMX_VIDEO_IntraRefreshRandom) &&
+            (irMBs < ((m_sVenc_cfg.dvs_width * m_sVenc_cfg.dvs_height)>>8))) {
+        control_mode.value = V4L2_CID_MPEG_VIDC_VIDEO_INTRA_REFRESH_RANDOM;
+        control_mbs.id = V4L2_CID_MPEG_VIDC_VIDEO_AIR_MBS;
+        control_mbs.value = irMBs;
     } else {
         DEBUG_PRINT_ERROR("ERROR: Invalid IntraRefresh Parameters:"
                 "mb count: %u, mb mode:%d", (unsigned int)irMBs, ir_mode);
@@ -3668,6 +4067,146 @@
     return true;
 }
 
+bool venc_dev::venc_calibrate_gop()
+{
+    int ratio, sub_gop_size, gop_size, nPframes, nBframes, nLayers;
+    int num_sub_gops_in_a_gop;
+    nPframes = intra_period.num_pframes;
+    nBframes = intra_period.num_bframes;
+    nLayers = hier_layers.numlayers;
+
+    if (!nPframes) {
+        DEBUG_PRINT_ERROR("nPframes should be non-zero\n");
+        return false;
+    }
+
+    if (nLayers > 1) { /*Multi-layer encoding*/
+        sub_gop_size = 1 << (nLayers - 1);
+        /* Actual GOP definition is nPframes + nBframes + 1 but for the sake of
+         * below calculations we are ignoring +1 . Ignoring +1 in below
+         * calculations is not a mistake but intentional.
+         */
+        gop_size = MAX(sub_gop_size, ROUND(nPframes + nBframes, sub_gop_size));
+        num_sub_gops_in_a_gop = gop_size/sub_gop_size;
+        if (nBframes) { /*Hier-B case*/
+        /*
+            * Frame Type--> I  B  B  B  P  B  B  B  P  I  B  B  P ...
+            * Layer -->     0  2  1  2  0  2  1  2  0  0  2  1  2 ...
+            * nPframes = 2, nBframes = 6, nLayers = 3
+            *
+            * Intention is to keep the intraperiod as close as possible to what is desired
+            * by the client while adjusting nPframes and nBframes to meet other constraints.
+            * eg1: Input by client: nPframes =  9, nBframes = 14, nLayers = 2
+            *    Output of this fn: nPframes = 12, nBframes = 12, nLayers = 2
+            *
+            * eg2: Input by client: nPframes = 9, nBframes = 4, nLayers = 2
+            *    Output of this fn: nPframes = 7, nBframes = 7, nLayers = 2
+            */
+            nPframes = num_sub_gops_in_a_gop;
+            nBframes = gop_size - nPframes;
+        } else { /*Hier-P case*/
+            /*
+            * Frame Type--> I  P  P  P  P  P  P  P  I  P  P  P  P ...
+            * Layer-->      0  2  1  2  0  2  1  2  0  2  1  2  0 ...
+            * nPframes =  7, nBframes = 0, nLayers = 3
+            *
+            * Intention is to keep the intraperiod as close as possible to what is desired
+            * by the client while adjusting nPframes and nBframes to meet other constraints.
+            * eg1: Input by client: nPframes = 9, nBframes = 0, nLayers = 3
+            *    Output of this fn: nPframes = 7, nBframes = 0, nLayers = 3
+            *
+            * eg2: Input by client: nPframes = 10, nBframes = 0, nLayers = 3
+            *     Output of this fn:nPframes = 12, nBframes = 0, nLayers = 3
+            */
+            nPframes = gop_size - 1;
+        }
+    } else { /*Single-layer encoding*/
+        if (nBframes) {
+            /* I  P  B  B  B  P  B  B  B   P   B   B   B   I   P   B   B...
+            *  1  2  3  4  5  6  7  8  9  10  11  12  13  14  15  16  17...
+            * nPframes = 3, nBframes = 9, nLayers = 0
+            *
+            * ratio is rounded,
+            * eg1: nPframes = 9, nBframes = 11 => ratio = 1
+            * eg2: nPframes = 9, nBframes = 16 => ratio = 2
+            */
+            ratio = MAX(1, MIN((nBframes + (nPframes >> 1))/nPframes, 3));
+            nBframes = ratio * nPframes;
+        }
+    }
+    DEBUG_PRINT_LOW("P/B Frames changed from: %ld/%ld to %d/%d",
+        intra_period.num_pframes, intra_period.num_bframes, nPframes, nBframes);
+    intra_period.num_pframes = nPframes;
+    intra_period.num_bframes = nBframes;
+    hier_layers.numlayers = nLayers;
+    return true;
+}
+
+bool venc_dev::venc_set_hybrid_hierp(OMX_U32 layers)
+{
+    DEBUG_PRINT_LOW("venc_set_hybrid_hierp layers: %u", layers);
+    struct v4l2_control control;
+    int rc;
+
+    if (!venc_validate_hybridhp_params(layers, 0, 0, (int) HIER_P_HYBRID)) {
+        DEBUG_PRINT_ERROR("Invalid settings, Hybrid HP enabled with LTR OR Hier-pLayers OR bframes");
+        return false;
+    }
+
+    if (!layers || layers > MAX_HYB_HIERP_LAYERS) {
+        DEBUG_PRINT_ERROR("Invalid numbers of layers set: %d (max supported is 6)", layers);
+        return false;
+    }
+
+    hier_layers.numlayers = layers;
+    hier_layers.hier_mode = HIER_P_HYBRID;
+    if (venc_calibrate_gop()) {
+     // Update the driver with the new nPframes and nBframes
+        control.id = V4L2_CID_MPEG_VIDC_VIDEO_NUM_P_FRAMES;
+        control.value = intra_period.num_pframes;
+        rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
+        if (rc) {
+            DEBUG_PRINT_ERROR("Failed to set control");
+            return false;
+        }
+
+        control.id = V4L2_CID_MPEG_VIDC_VIDEO_NUM_B_FRAMES;
+        control.value = intra_period.num_bframes;
+        rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
+        if (rc) {
+            DEBUG_PRINT_ERROR("Failed to set control");
+            return false;
+        }
+        DEBUG_PRINT_LOW("Updated nPframes (%ld) and nBframes (%ld)",
+                         intra_period.num_pframes, intra_period.num_bframes);
+    } else {
+        DEBUG_PRINT_ERROR("Invalid settings, Hybrid HP enabled with LTR OR Hier-pLayers OR bframes");
+        return false;
+    }
+
+    control.id = V4L2_CID_MPEG_VIDC_VIDEO_HYBRID_HIERP_MODE;
+    control.value = layers - 1;
+
+    DEBUG_PRINT_LOW("Calling IOCTL set control for id=%x, val=%d",
+                    control.id, control.value);
+
+    rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
+    if (rc) {
+        DEBUG_PRINT_ERROR("Failed to set hybrid hierp %d", rc);
+        return false;
+    }
+
+    DEBUG_PRINT_LOW("SUCCESS IOCTL set control for id=%x, val=%d",
+                    control.id, control.value);
+    control.id = V4L2_CID_MPEG_VIDC_VIDEO_H264_NAL_SVC;
+    control.value = V4L2_CID_MPEG_VIDC_VIDEO_H264_NAL_SVC_ENABLED;
+    if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) {
+        DEBUG_PRINT_ERROR("Failed to enable SVC_NAL");
+        return false;
+    }
+    return true;
+}
+
 bool venc_dev::venc_set_ltrmode(OMX_U32 enable, OMX_U32 count)
 {
     DEBUG_PRINT_LOW("venc_set_ltrmode: enable = %u", (unsigned int)enable);
@@ -3676,6 +4215,11 @@
     struct v4l2_ext_controls controls;
     int rc;
 
+    if (!venc_validate_hybridhp_params(0, 0, count, 0)) {
+        DEBUG_PRINT_ERROR("Invalid settings, LTR enabled with HybridHP");
+        return false;
+    }
+
     ctrl[0].id = V4L2_CID_MPEG_VIDC_VIDEO_LTRMODE;
     if (enable)
         ctrl[0].value = V4L2_MPEG_VIDC_VIDEO_LTR_MODE_MANUAL;
@@ -3683,10 +4227,12 @@
         ctrl[0].value = V4L2_MPEG_VIDC_VIDEO_LTR_MODE_DISABLE;
 
     ctrl[1].id = V4L2_CID_MPEG_VIDC_VIDEO_LTRCOUNT;
-    if (count)
+    if (enable && count > 0)
         ctrl[1].value = count;
-    else
+    else if (enable)
         ctrl[1].value = 1;
+    else
+        ctrl[1].value = 0;
 
     controls.count = 2;
     controls.ctrl_class = V4L2_CTRL_CLASS_MPEG;
@@ -3701,6 +4247,8 @@
         DEBUG_PRINT_ERROR("Failed to set ltrmode %d", rc);
         return false;
     }
+    ltrinfo.enabled = enable;
+    ltrinfo.count = count;
 
     DEBUG_PRINT_LOW("Success IOCTL set control for id=%x, val=%d id=%x, val=%d",
                     controls.controls[0].id, controls.controls[0].value,
@@ -3713,17 +4261,26 @@
         DEBUG_PRINT_ERROR("ERROR: Request for setting extradata failed");
         return false;
     }
+
+    if (!venc_set_profile_level(0, 0)) {
+        DEBUG_PRINT_ERROR("ERROR: %s(): Driver Profile/Level is NOT SET",
+                __func__);
+    } else {
+        DEBUG_PRINT_HIGH("%s(): Driver Profile[%lu]/Level[%lu] successfully SET",
+                __func__, codec_profile.profile, profile_level.level);
+    }
+
     return true;
 }
 
-bool venc_dev::venc_set_useltr()
+bool venc_dev::venc_set_useltr(OMX_U32 frameIdx)
 {
     DEBUG_PRINT_LOW("venc_use_goldenframe");
     int rc = true;
     struct v4l2_control control;
 
     control.id = V4L2_CID_MPEG_VIDC_VIDEO_USELTRFRAME;
-    control.value = 1;
+    control.value = frameIdx;
 
     rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
     if (rc) {
@@ -3736,14 +4293,14 @@
     return true;
 }
 
-bool venc_dev::venc_set_markltr()
+bool venc_dev::venc_set_markltr(OMX_U32 frameIdx)
 {
     DEBUG_PRINT_LOW("venc_set_goldenframe");
     int rc = true;
     struct v4l2_control control;
 
     control.id = V4L2_CID_MPEG_VIDC_VIDEO_MARKLTRFRAME;
-    control.value = 1;
+    control.value = frameIdx;
 
     rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
     if (rc) {
@@ -3896,16 +4453,24 @@
             control.value=V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL_OFF;
             break;
         case OMX_Video_ControlRateVariableSkipFrames:
-            control.value=V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL_VBR_VFR;
+            (supported_rc_modes & RC_VBR_VFR) ?
+                control.value = V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL_VBR_VFR :
+                status = false;
             break;
         case OMX_Video_ControlRateVariable:
-            control.value=V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL_VBR_CFR;
+            (supported_rc_modes & RC_VBR_CFR) ?
+                control.value = V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL_VBR_CFR :
+                status = false;
             break;
         case OMX_Video_ControlRateConstantSkipFrames:
-            control.value=V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL_CBR_VFR;
+            (supported_rc_modes & RC_CBR_VFR) ?
+                control.value = V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL_CBR_VFR :
+                status = false;
             break;
         case OMX_Video_ControlRateConstant:
-            control.value=V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL_CBR_CFR;
+            (supported_rc_modes & RC_CBR_CFR) ?
+                control.value = V4L2_CID_MPEG_VIDC_VIDEO_RATE_CONTROL_CBR_CFR :
+                status = false;
             break;
         default:
             status = false;
@@ -3963,6 +4528,24 @@
     return status;
 }
 
+bool venc_dev::venc_set_perf_mode(OMX_U32 mode)
+{
+    struct v4l2_control control;
+    if (mode && mode <= V4L2_MPEG_VIDC_VIDEO_PERF_POWER_SAVE) {
+        control.id = V4L2_CID_MPEG_VIDC_VIDEO_PERF_MODE;
+        control.value = mode;
+        DEBUG_PRINT_LOW("Going to set V4L2_CID_MPEG_VIDC_VIDEO_PERF_MODE");
+        if (ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control)) {
+            DEBUG_PRINT_ERROR("Failed to set V4L2_CID_MPEG_VIDC_VIDEO_PERF_MODE");
+            return false;
+        }
+        return true;
+    } else {
+        DEBUG_PRINT_ERROR("Invalid mode set for V4L2_CID_MPEG_VIDC_VIDEO_PERF_MODE: %d", mode);
+        return false;
+    }
+}
+
 bool venc_dev::venc_set_vui_timing_info(OMX_BOOL enable)
 {
     struct v4l2_control control;
@@ -4006,6 +4589,31 @@
     return true;
 }
 
+bool venc_dev::venc_set_vpx_error_resilience(OMX_BOOL enable)
+{
+    struct v4l2_control control;
+    int rc = 0;
+    control.id = V4L2_CID_MPEG_VIDC_VIDEO_VPX_ERROR_RESILIENCE;
+
+    if (enable)
+        control.value = 1;
+    else
+        control.value = 0;
+
+    DEBUG_PRINT_LOW("venc_set_vpx_error_resilience: %d", control.value);
+
+    DEBUG_PRINT_LOW("Calling IOCTL set control for id=%d, val=%d", control.id, control.value);
+
+    rc = ioctl(m_nDriver_fd, VIDIOC_S_CTRL, &control);
+    if (rc) {
+        DEBUG_PRINT_ERROR("Failed to set VPX Error Resilience");
+        return false;
+    }
+    vpx_err_resilience.enable = 1;
+    DEBUG_PRINT_LOW("Success IOCTL set control for id=%d, value=%d", control.id, control.value);
+    return true;
+}
+
 bool venc_dev::venc_get_profile_level(OMX_U32 *eProfile,OMX_U32 *eLevel)
 {
     bool status = true;
@@ -4218,6 +4826,104 @@
                 status = false;
                 break;
         }
+    } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_HEVC) {
+        switch (codec_profile.profile) {
+            case V4L2_MPEG_VIDC_VIDEO_HEVC_PROFILE_MAIN:
+                *eProfile = OMX_VIDEO_HEVCProfileMain;
+                break;
+            case V4L2_MPEG_VIDC_VIDEO_HEVC_PROFILE_MAIN10:
+                *eProfile = OMX_VIDEO_HEVCProfileMain10;
+                break;
+            default:
+                *eProfile = OMX_VIDEO_HEVCProfileMax;
+                status = false;
+                break;
+        }
+        if (!status) {
+            return status;
+        }
+
+        switch (profile_level.level) {
+            case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_1:
+                *eLevel = OMX_VIDEO_HEVCMainTierLevel1;
+                break;
+            case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_1:
+                *eLevel = OMX_VIDEO_HEVCHighTierLevel1;
+                break;
+            case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_2:
+                *eLevel = OMX_VIDEO_HEVCMainTierLevel2;
+                break;
+            case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_2:
+                *eLevel = OMX_VIDEO_HEVCHighTierLevel2;
+                break;
+            case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_2_1:
+                *eLevel = OMX_VIDEO_HEVCMainTierLevel21;
+                break;
+            case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_2_1:
+                *eLevel = OMX_VIDEO_HEVCHighTierLevel21;
+                break;
+            case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_3:
+                *eLevel = OMX_VIDEO_HEVCMainTierLevel3;
+                break;
+            case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_3:
+                *eLevel = OMX_VIDEO_HEVCHighTierLevel3;
+                break;
+            case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_3_1:
+                *eLevel = OMX_VIDEO_HEVCMainTierLevel31;
+                break;
+            case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_3_1:
+                *eLevel = OMX_VIDEO_HEVCHighTierLevel31;
+                break;
+            case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_4:
+                *eLevel = OMX_VIDEO_HEVCMainTierLevel4;
+                break;
+            case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_4:
+                *eLevel = OMX_VIDEO_HEVCHighTierLevel4;
+                break;
+            case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_4_1:
+                *eLevel = OMX_VIDEO_HEVCMainTierLevel41;
+                break;
+            case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_4_1:
+                *eLevel = OMX_VIDEO_HEVCHighTierLevel41;
+                break;
+            case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_5:
+                *eLevel = OMX_VIDEO_HEVCMainTierLevel5;
+                break;
+            case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_5:
+                *eLevel = OMX_VIDEO_HEVCHighTierLevel5;
+                break;
+            case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_5_1:
+                *eLevel = OMX_VIDEO_HEVCMainTierLevel51;
+                break;
+            case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_5_1:
+                *eLevel = OMX_VIDEO_HEVCHighTierLevel51;
+                break;
+            case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_5_2:
+                *eLevel = OMX_VIDEO_HEVCMainTierLevel52;
+                break;
+            case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_5_2:
+                *eLevel = OMX_VIDEO_HEVCHighTierLevel52;
+                break;
+            case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_6:
+                *eLevel = OMX_VIDEO_HEVCMainTierLevel6;
+                break;
+            case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_6:
+                *eLevel = OMX_VIDEO_HEVCHighTierLevel6;
+                break;
+            case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_6_1:
+                *eLevel = OMX_VIDEO_HEVCMainTierLevel61;
+                break;
+            case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_HIGH_TIER_LEVEL_6_1:
+                *eLevel = OMX_VIDEO_HEVCHighTierLevel61;
+                break;
+            case V4L2_MPEG_VIDC_VIDEO_HEVC_LEVEL_MAIN_TIER_LEVEL_6_2:
+                *eLevel = OMX_VIDEO_HEVCMainTierLevel62;
+                break;
+            default:
+                *eLevel = OMX_VIDEO_HEVCLevelMax;
+                status = false;
+                break;
+        }
     }
 
     return status;
@@ -4372,8 +5078,40 @@
             }
         }
         return true;
+    } else if (m_sVenc_cfg.codectype == V4L2_PIX_FMT_HEVC) {
+        if (*eProfile == 0) {
+            if (!m_profile_set) {
+                *eProfile = OMX_VIDEO_HEVCProfileMain;
     } else {
-        DEBUG_PRINT_LOW("Invalid codec type");
+                switch (codec_profile.profile) {
+                    case V4L2_MPEG_VIDC_VIDEO_HEVC_PROFILE_MAIN:
+                        *eProfile = OMX_VIDEO_HEVCProfileMain;
+                        break;
+                    case V4L2_MPEG_VIDC_VIDEO_HEVC_PROFILE_MAIN10:
+                        *eProfile = OMX_VIDEO_HEVCProfileMain10;
+                        break;
+                    default:
+                        DEBUG_PRINT_ERROR("%s(): Unknown Error", __func__);
+                        return false;
+                }
+            }
+        }
+
+        if (*eLevel == 0 && !m_level_set) {
+            *eLevel = OMX_VIDEO_HEVCLevelMax;
+        }
+
+        if (*eProfile == OMX_VIDEO_HEVCProfileMain) {
+            profile_tbl = (unsigned int const *)hevc_profile_level_table;
+        } else if (*eProfile == OMX_VIDEO_HEVCProfileMain10) {
+            profile_tbl = (unsigned int const *)
+                (&hevc_profile_level_table[HEVC_MAIN10_START]);
+        } else {
+            DEBUG_PRINT_ERROR("Unsupported HEVC profile type %u", (unsigned int)*eProfile);
+            return false;
+        }
+    } else {
+        DEBUG_PRINT_ERROR("Invalid codec type");
         return false;
     }
 
@@ -4396,20 +5134,46 @@
 
     mb_per_sec = mb_per_frame * m_sVenc_cfg.fps_num / m_sVenc_cfg.fps_den;
 
+    bool h264, ltr, hlayers;
+    unsigned int hybridp = 0, maxDpb = profile_tbl[5] / mb_per_frame;
+    h264 = m_sVenc_cfg.codectype == V4L2_PIX_FMT_H264;
+    ltr = ltrinfo.enabled && ((ltrinfo.count + 2) <= MIN((unsigned int) (profile_tbl[5] / mb_per_frame), MAXDPB));
+    hlayers = hier_layers.numlayers && hier_layers.hier_mode == HIER_P &&
+     ((intra_period.num_bframes + ltrinfo.count + hier_layers.numlayers + 1) <= (unsigned int) (profile_tbl[5] / profile_tbl[0]));
+
+    /*  Hybrid HP reference buffers:
+        layers = 1, 2 need 1 reference buffer
+        layers = 3, 4 need 2 reference buffers
+        layers = 5, 6 need 3 reference buffers
+    */
+
+    if(hier_layers.hier_mode == HIER_P_HYBRID)
+        hybridp = MIN(MAX(maxDpb, ((hier_layers.numlayers + 1) / 2)), 16);
+
     do {
         if (mb_per_frame <= (unsigned int)profile_tbl[0]) {
             if (mb_per_sec <= (unsigned int)profile_tbl[1]) {
                 if (m_sVenc_cfg.targetbitrate <= (unsigned int)profile_tbl[2]) {
+                    if (h264 && (ltr || hlayers || hybridp)) {
+                        // Update profile and level to adapt to the LTR and Hier-p/Hybrid-HP settings
+                        new_level = (int)profile_tbl[3];
+                        new_profile = (int)profile_tbl[4];
+                        profile_level_found = true;
+                        DEBUG_PRINT_LOW("Appropriate profile/level for LTR count: %u OR Hier-p: %u is %u/%u, maxDPB: %u",
+                                        ltrinfo.count, hier_layers.numlayers, (int)new_profile, (int)new_level,
+                                        MIN((unsigned int) (profile_tbl[5] / mb_per_frame), MAXDPB));
+                        break;
+                    } else {
                     new_level = (int)profile_tbl[3];
                     new_profile = (int)profile_tbl[4];
                     profile_level_found = true;
-                    DEBUG_PRINT_LOW("Appropriate profile/level found %u/%u", (unsigned int)new_profile, (unsigned int)new_level);
+                        DEBUG_PRINT_LOW("Appropriate profile/level found %u/%u", (int) new_profile, (int) new_level);
                     break;
                 }
             }
         }
-
-        profile_tbl = profile_tbl + 5;
+        }
+        profile_tbl = profile_tbl + MAX_PROFILE_PARAMS;
     } while (profile_tbl[0] != 0);
 
     if (profile_level_found != true) {
@@ -4418,7 +5182,8 @@
     }
 
     if ((*eLevel == OMX_VIDEO_MPEG4LevelMax) || (*eLevel == OMX_VIDEO_AVCLevelMax)
-            || (*eLevel == OMX_VIDEO_H263LevelMax || (*eLevel == OMX_VIDEO_VP8ProfileMax))) {
+            || (*eLevel == OMX_VIDEO_H263LevelMax) || (*eLevel == OMX_VIDEO_VP8ProfileMax)
+            || (*eLevel == OMX_VIDEO_HEVCLevelMax)) {
         *eLevel = new_level;
     }