Merge tag android-5.1.0_r1 into AOSP_5.1_MERGE

Change-Id: Ic7fcf708112cd21d3b31abe6384fe4b3478680ba
diff --git a/videocodec/Android.mk b/videocodec/Android.mk
index d63b83b..d3b3366 100644
--- a/videocodec/Android.mk
+++ b/videocodec/Android.mk
@@ -9,8 +9,8 @@
 
 include $(CLEAR_VARS)
 
-ifeq ($(TARGET_HAS_VPP),true)
-LOCAL_CFLAGS += -DTARGET_HAS_VPP
+ifeq ($(TARGET_HAS_ISV),true)
+LOCAL_CFLAGS += -DTARGET_HAS_ISV
 endif
 
 LOCAL_SHARED_LIBRARIES := \
@@ -26,7 +26,8 @@
     $(TARGET_OUT_HEADERS)/libmix_videodecoder \
     $(TARGET_OUT_HEADERS)/libva \
     $(call include-path-for, frameworks-native)/media/hardware \
-    $(call include-path-for, frameworks-native)/media/openmax
+    $(call include-path-for, frameworks-native)/media/openmax \
+    $(call include-path-for, libhardware)
 
 PLATFORM_USE_GEN_HW := \
     baytrail \
@@ -37,9 +38,10 @@
 endif
 
 LOCAL_SRC_FILES := \
-    OMXComponentCodecBase.cpp\
-    OMXVideoDecoderBase.cpp\
+    OMXComponentCodecBase.cpp \
+    OMXVideoDecoderBase.cpp \
     OMXVideoDecoderAVC.cpp
+
 LOCAL_CFLAGS += -Werror
 LOCAL_MODULE_TAGS := optional
 LOCAL_MODULE := libOMXVideoDecoderAVC
@@ -77,8 +79,8 @@
 ifneq ($(filter $(TARGET_BOARD_PLATFORM),$(PLATFORM_SUPPORT_VP8)),)
 include $(CLEAR_VARS)
 
-ifeq ($(TARGET_HAS_VPP),true)
-LOCAL_CFLAGS += -DTARGET_HAS_VPP
+ifeq ($(TARGET_HAS_ISV),true)
+LOCAL_CFLAGS += -DTARGET_HAS_ISV
 endif
 
 LOCAL_SHARED_LIBRARIES := \
@@ -94,12 +96,14 @@
     $(TARGET_OUT_HEADERS)/libmix_videodecoder \
     $(TARGET_OUT_HEADERS)/libva \
     $(call include-path-for, frameworks-native)/media/hardware \
-    $(call include-path-for, frameworks-native)/media/openmax
+    $(call include-path-for, frameworks-native)/media/openmax \
+    $(call include-path-for, libhardware)
 
 LOCAL_SRC_FILES := \
-    OMXComponentCodecBase.cpp\
-    OMXVideoDecoderBase.cpp\
+    OMXComponentCodecBase.cpp \
+    OMXVideoDecoderBase.cpp \
     OMXVideoDecoderVP8.cpp
+
 LOCAL_CFLAGS += -Werror
 LOCAL_MODULE_TAGS := optional
 LOCAL_MODULE := libOMXVideoDecoderVP8
@@ -136,12 +140,11 @@
 # VP9 with SW decode and HW Render
 include $(CLEAR_VARS)
 
-ifeq ($(TARGET_HAS_VPP),true)
-LOCAL_CFLAGS += -DTARGET_HAS_VPP
+ifeq ($(TARGET_HAS_ISV),true)
+LOCAL_CFLAGS += -DTARGET_HAS_ISV
 endif
 
 LOCAL_SHARED_LIBRARIES := \
-    libui \
     libwrs_omxil_common \
     libva_videodecoder \
     liblog \
@@ -161,15 +164,16 @@
     $(LOCAL_PATH)/libvpx_internal/libvpx/vpx_codec \
     $(LOCAL_PATH)/libvpx_internal/libvpx/vpx_ports \
     $(call include-path-for, frameworks-native)/media/hardware \
-    $(call include-path-for, frameworks-native)/media/openmax
+    $(call include-path-for, frameworks-native)/media/openmax \
+    $(call include-path-for, libhardware)
 
 ifeq ($(TARGET_BOARD_PLATFORM),baytrail)
 LOCAL_C_INCLUDES += $(TARGET_OUT_HEADERS)/ufo
 endif
 
 LOCAL_SRC_FILES := \
-    OMXComponentCodecBase.cpp\
-    OMXVideoDecoderBase.cpp\
+    OMXComponentCodecBase.cpp \
+    OMXVideoDecoderBase.cpp \
     OMXVideoDecoderVP9HWR.cpp
 
 LOCAL_CFLAGS += -Werror
@@ -196,7 +200,6 @@
 LOCAL_CFLAGS += -DTARGET_HAS_VPP
 endif
 LOCAL_SHARED_LIBRARIES := \
-    libui \
     libwrs_omxil_common \
     liblog \
     libva_videodecoder \
@@ -208,15 +211,16 @@
     $(TARGET_OUT_HEADERS)/libmix_videodecoder \
     $(TARGET_OUT_HEADERS)/libva \
     $(call include-path-for, frameworks-native)/media/hardware \
-    $(call include-path-for, frameworks-native)/media/openmax
+    $(call include-path-for, frameworks-native)/media/openmax \
+    $(call include-path-for, libhardware)
 
 ifeq ($(TARGET_BOARD_PLATFORM),baytrail)
     LOCAL_C_INCLUDES += $(TARGET_OUT_HEADERS)/ufo
 endif
 
 LOCAL_SRC_FILES := \
-    OMXComponentCodecBase.cpp\
-    OMXVideoDecoderBase.cpp\
+    OMXComponentCodecBase.cpp \
+    OMXVideoDecoderBase.cpp \
     OMXVideoDecoderVP9Hybrid.cpp
 
 LOCAL_CFLAGS += -Werror
@@ -238,8 +242,8 @@
 endif
 
 include $(CLEAR_VARS)
-ifeq ($(TARGET_HAS_VPP),true)
-LOCAL_CFLAGS += -DTARGET_HAS_VPP
+ifeq ($(TARGET_HAS_ISV),true)
+LOCAL_CFLAGS += -DTARGET_HAS_ISV
 endif
 
 LOCAL_SHARED_LIBRARIES := \
@@ -255,7 +259,8 @@
     $(TARGET_OUT_HEADERS)/libmix_videodecoder \
     $(TARGET_OUT_HEADERS)/libva \
     $(call include-path-for, frameworks-native)/media/hardware \
-    $(call include-path-for, frameworks-native)/media/openmax
+    $(call include-path-for, frameworks-native)/media/openmax \
+    $(call include-path-for, libhardware)
 
 PLATFORM_USE_GEN_HW := \
     baytrail \
@@ -266,9 +271,10 @@
 endif
 
 LOCAL_SRC_FILES := \
-    OMXComponentCodecBase.cpp\
-    OMXVideoDecoderBase.cpp\
+    OMXComponentCodecBase.cpp \
+    OMXVideoDecoderBase.cpp \
     OMXVideoDecoderMPEG4.cpp
+
 LOCAL_CFLAGS += -Werror
 LOCAL_MODULE_TAGS := optional
 LOCAL_MODULE := libOMXVideoDecoderMPEG4
@@ -293,8 +299,8 @@
 ################################################################################
 
 include $(CLEAR_VARS)
-ifeq ($(TARGET_HAS_VPP),true)
-LOCAL_CFLAGS += -DTARGET_HAS_VPP
+ifeq ($(TARGET_HAS_ISV),true)
+LOCAL_CFLAGS += -DTARGET_HAS_ISV
 endif
 
 LOCAL_SHARED_LIBRARIES := \
@@ -310,7 +316,8 @@
     $(TARGET_OUT_HEADERS)/libmix_videodecoder \
     $(TARGET_OUT_HEADERS)/libva \
     $(call include-path-for, frameworks-native)/media/hardware \
-    $(call include-path-for, frameworks-native)/media/openmax
+    $(call include-path-for, frameworks-native)/media/openmax \
+    $(call include-path-for, libhardware)
 
 PLATFORM_USE_GEN_HW := \
     baytrail \
@@ -321,9 +328,10 @@
 endif
 
 LOCAL_SRC_FILES := \
-    OMXComponentCodecBase.cpp\
-    OMXVideoDecoderBase.cpp\
+    OMXComponentCodecBase.cpp \
+    OMXVideoDecoderBase.cpp \
     OMXVideoDecoderH263.cpp
+
 LOCAL_CFLAGS += -Werror
 LOCAL_MODULE_TAGS := optional
 LOCAL_MODULE := libOMXVideoDecoderH263
@@ -348,8 +356,8 @@
 ################################################################################
 
 include $(CLEAR_VARS)
-ifeq ($(TARGET_HAS_VPP),true)
-LOCAL_CFLAGS += -DTARGET_HAS_VPP
+ifeq ($(TARGET_HAS_ISV),true)
+LOCAL_CFLAGS += -DTARGET_HAS_ISV
 endif
 
 LOCAL_SHARED_LIBRARIES := \
@@ -365,7 +373,8 @@
     $(TARGET_OUT_HEADERS)/libmix_videodecoder \
     $(TARGET_OUT_HEADERS)/libva \
     $(call include-path-for, frameworks-native)/media/hardware \
-    $(call include-path-for, frameworks-native)/media/openmax
+    $(call include-path-for, frameworks-native)/media/openmax \
+    $(call include-path-for, libhardware)
 
 PLATFORM_USE_GEN_HW := \
     baytrail \
@@ -376,9 +385,10 @@
 endif
 
 LOCAL_SRC_FILES := \
-    OMXComponentCodecBase.cpp\
-    OMXVideoDecoderBase.cpp\
+    OMXComponentCodecBase.cpp \
+    OMXVideoDecoderBase.cpp \
     OMXVideoDecoderWMV.cpp
+
 LOCAL_CFLAGS += -Werror
 LOCAL_MODULE_TAGS := optional
 LOCAL_MODULE := libOMXVideoDecoderWMV
@@ -410,8 +420,8 @@
 ifeq ($(USE_INTEL_SECURE_AVC),true)
 
 include $(CLEAR_VARS)
-ifeq ($(TARGET_HAS_VPP),true)
-LOCAL_CFLAGS += -DTARGET_HAS_VPP
+ifeq ($(TARGET_HAS_ISV),true)
+LOCAL_CFLAGS += -DTARGET_HAS_ISV
 endif
 
 LOCAL_SHARED_LIBRARIES := \
@@ -430,9 +440,10 @@
     $(TARGET_OUT_HEADERS)/libdrm \
     $(call include-path-for, frameworks-native)/media/hardware \
     $(call include-path-for, frameworks-native)/media/openmax \
+    $(call include-path-for, libhardware)
 
 LOCAL_SRC_FILES := \
-    OMXComponentCodecBase.cpp\
+    OMXComponentCodecBase.cpp \
     OMXVideoDecoderBase.cpp
 
 ifeq ($(TARGET_BOARD_PLATFORM),moorefield)
@@ -454,8 +465,8 @@
 ################################################################################
 
 include $(CLEAR_VARS)
-ifeq ($(TARGET_HAS_VPP),true)
-LOCAL_CFLAGS += -DTARGET_HAS_VPP
+ifeq ($(TARGET_HAS_ISV),true)
+LOCAL_CFLAGS += -DTARGET_HAS_ISV
 endif
 
 LOCAL_SHARED_LIBRARIES := \
@@ -492,8 +503,8 @@
 ################################################################################
 
 include $(CLEAR_VARS)
-ifeq ($(TARGET_HAS_VPP),true)
-LOCAL_CFLAGS += -DTARGET_HAS_VPP
+ifeq ($(TARGET_HAS_ISV),true)
+LOCAL_CFLAGS += -DTARGET_HAS_ISV
 endif
 
 LOCAL_SHARED_LIBRARIES := \
@@ -534,8 +545,8 @@
 ################################################################################
 
 include $(CLEAR_VARS)
-ifeq ($(TARGET_HAS_VPP),true)
-LOCAL_CFLAGS += -DTARGET_HAS_VPP
+ifeq ($(TARGET_HAS_ISV),true)
+LOCAL_CFLAGS += -DTARGET_HAS_ISV
 endif
 
 LOCAL_SHARED_LIBRARIES := \
@@ -573,8 +584,8 @@
 ################################################################################
 
 include $(CLEAR_VARS)
-ifeq ($(TARGET_HAS_VPP),true)
-LOCAL_CFLAGS += -DTARGET_HAS_VPP
+ifeq ($(TARGET_HAS_ISV),true)
+LOCAL_CFLAGS += -DTARGET_HAS_ISV
 endif
 
 LOCAL_SHARED_LIBRARIES := \
@@ -590,11 +601,12 @@
     $(TARGET_OUT_HEADERS)/libmix_videodecoder \
     $(TARGET_OUT_HEADERS)/libva \
     $(call include-path-for, frameworks-native)/media/hardware \
-    $(call include-path-for, frameworks-native)/media/openmax
+    $(call include-path-for, frameworks-native)/media/openmax \
+    $(call include-path-for, libhardware)
 
 LOCAL_SRC_FILES := \
-    OMXComponentCodecBase.cpp\
-    OMXVideoDecoderBase.cpp\
+    OMXComponentCodecBase.cpp \
+    OMXVideoDecoderBase.cpp \
     OMXVideoDecoderPAVC.cpp
 
 LOCAL_CFLAGS += -Werror
@@ -617,8 +629,8 @@
 ################################################################################
 
 include $(CLEAR_VARS)
-ifeq ($(TARGET_HAS_VPP),true)
-LOCAL_CFLAGS += -DTARGET_HAS_VPP
+ifeq ($(TARGET_HAS_ISV),true)
+LOCAL_CFLAGS += -DTARGET_HAS_ISV
 endif
 
 LOCAL_SHARED_LIBRARIES := \
diff --git a/videocodec/OMXVideoDecoderBase.cpp b/videocodec/OMXVideoDecoderBase.cpp
index 7087cd4..7d1d830 100644
--- a/videocodec/OMXVideoDecoderBase.cpp
+++ b/videocodec/OMXVideoDecoderBase.cpp
@@ -17,19 +17,22 @@
 //#define LOG_NDEBUG 0
 #define LOG_TAG "OMXVideoDecoder"
 #include <wrs_omxil_core/log.h>
-#include "OMXVideoDecoderBase.h"
+
+#include <hardware/gralloc.h>
 #include <va/va_android.h>
 
+#include "OMXVideoDecoderBase.h"
+
 static const char* VA_RAW_MIME_TYPE = "video/x-raw-va";
 static const uint32_t VA_COLOR_FORMAT = 0x7FA00E00;
 
 OMXVideoDecoderBase::OMXVideoDecoderBase()
     : mRotationDegrees(0),
-      mVideoDecoder(NULL),
-      mNativeBufferCount(OUTPORT_NATIVE_BUFFER_COUNT),
-#ifdef TARGET_HAS_VPP
+#ifdef TARGET_HAS_ISV
       mVppBufferNum(0),
 #endif
+      mVideoDecoder(NULL),
+      mNativeBufferCount(OUTPORT_NATIVE_BUFFER_COUNT),
       mWorkingMode(RAWDATA_MODE),
       mErrorReportEnabled (false) {
       mOMXBufferHeaderTypePtrNum = 0;
@@ -219,7 +222,7 @@
     mOMXBufferHeaderTypePtrNum = 0;
     memset(&mGraphicBufferParam, 0, sizeof(mGraphicBufferParam));
     mRotationDegrees = 0;
-#ifdef TARGET_HAS_VPP
+#ifdef TARGET_HAS_ISV
     mVppBufferNum = 0;
 #endif
     return OMXComponentCodecBase::ProcessorDeinit();
@@ -474,7 +477,7 @@
     }
 
     p->rotationDegrees = mRotationDegrees;
-#ifdef TARGET_HAS_VPP
+#ifdef TARGET_HAS_ISV
     p->vppBufferNum = mVppBufferNum;
 #endif
     p->width = paramPortDefinitionInput->format.video.nFrameWidth;
@@ -631,8 +634,9 @@
     uint32_t strideCropped = widthCropped;
     uint32_t sliceHeightCropped = heightCropped;
     int force_realloc = 0;
+    bool isVP8 = false;
 
-#ifdef TARGET_HAS_VPP
+#ifdef TARGET_HAS_ISV
     LOGI("============== mVppBufferNum = %d\n", mVppBufferNum);
     if (paramPortDefinitionOutput.nBufferCountActual - mVppBufferNum < formatInfo->actualBufferNeeded) {
 #else
@@ -653,6 +657,10 @@
         paramPortDefinitionInput.format.video.nFrameHeight,
         width, height, widthCropped, heightCropped);
 
+    if (paramPortDefinitionInput.format.video.eCompressionFormat == OMX_VIDEO_CodingVP8) {
+        isVP8 = true;
+    }
+
     if (!force_realloc &&
         widthCropped == paramPortDefinitionOutput.format.video.nFrameWidth &&
         heightCropped == paramPortDefinitionOutput.format.video.nFrameHeight) {
@@ -681,11 +689,11 @@
             return OMX_ErrorNone;
         }
 
-        if (width > formatInfo->surfaceWidth ||  height > formatInfo->surfaceHeight) {
+        if (isVP8 || width > formatInfo->surfaceWidth ||  height > formatInfo->surfaceHeight) {
             // update the real decoded resolution to outport instead of display resolution for graphic buffer reallocation
             // when the width and height parsed from ES are larger than allocated graphic buffer in outport,
             paramPortDefinitionOutput.format.video.nFrameWidth = width;
-            paramPortDefinitionOutput.format.video.nFrameHeight = (height + 0x1f) & ~0x1f;
+            paramPortDefinitionOutput.format.video.nFrameHeight = height;
             paramPortDefinitionOutput.format.video.eColorFormat = GetOutputColorFormat(
                     paramPortDefinitionOutput.format.video.nFrameWidth);
             paramPortDefinitionOutput.format.video.nStride = stride;
@@ -703,6 +711,9 @@
     if (mWorkingMode == GRAPHICBUFFER_MODE) {
         // Make sure va_destroySurface is called before graphicbuffer is freed in case of port setting changed
         mVideoDecoder->freeSurfaceBuffers();
+
+        // Also make sure all the reference frames are flushed
+        ProcessorFlush(INPORT_INDEX);
     }
     this->ports[OUTPORT_INDEX]->ReportPortSettingsChanged();
     return OMX_ErrorNone;
@@ -761,7 +772,7 @@
     AddHandler(static_cast<OMX_INDEXTYPE>(OMX_IndexExtUseNativeBuffer), GetNativeBuffer, SetNativeBuffer);
     AddHandler(static_cast<OMX_INDEXTYPE>(OMX_IndexExtEnableNativeBuffer), GetNativeBufferMode, SetNativeBufferMode);
     AddHandler(static_cast<OMX_INDEXTYPE>(OMX_IndexExtRotationDegrees), GetDecoderRotation, SetDecoderRotation);
-#ifdef TARGET_HAS_VPP
+#ifdef TARGET_HAS_ISV
     AddHandler(static_cast<OMX_INDEXTYPE>(OMX_IndexExtVppBufferNum), GetDecoderVppBufferNum, SetDecoderVppBufferNum);
 #endif
     AddHandler(OMX_IndexConfigCommonOutputCrop, GetDecoderOutputCrop, SetDecoderOutputCrop);
@@ -873,16 +884,25 @@
     CHECK_TYPE_HEADER(param);
     CHECK_PORT_INDEX_RANGE(param);
     CHECK_SET_PARAM_STATE();
-    if (!param->enable) {
-        mWorkingMode = RAWDATA_MODE;
-        return OMX_ErrorNone;
-    }
-    mWorkingMode = GRAPHICBUFFER_MODE;
+
     PortVideo *port = NULL;
     port = static_cast<PortVideo *>(this->ports[OUTPORT_INDEX]);
-
     OMX_PARAM_PORTDEFINITIONTYPE port_def;
     memcpy(&port_def,port->GetPortDefinition(),sizeof(port_def));
+
+    if (!param->enable) {
+        mWorkingMode = RAWDATA_MODE;
+        // If it is fallback from native mode the color format has been
+        // already set to INTEL format.
+        // We need to set back the default color format and Native stuff.
+        port_def.format.video.eColorFormat = OMX_COLOR_FormatYUV420SemiPlanar;
+        port_def.format.video.pNativeRender = NULL;
+        port_def.format.video.pNativeWindow = NULL;
+        port->SetPortDefinition(&port_def,true);
+        return OMX_ErrorNone;
+    }
+
+    mWorkingMode = GRAPHICBUFFER_MODE;
     port_def.nBufferCountMin = mNativeBufferCount;
     if (mEnableAdaptivePlayback) {
         SetMaxOutputBufferCount(&port_def);
@@ -916,8 +936,8 @@
     }
 }
 
-#ifdef TARGET_HAS_VPP
-OMX_ERRORTYPE OMXVideoDecoderBase::GetDecoderVppBufferNum(OMX_PTR pStructure) {
+#ifdef TARGET_HAS_ISV
+OMX_ERRORTYPE OMXVideoDecoderBase::GetDecoderVppBufferNum(OMX_PTR) {
     return OMX_ErrorBadParameter;
 }
 OMX_ERRORTYPE OMXVideoDecoderBase::SetDecoderVppBufferNum(OMX_PTR pStructure) {
diff --git a/videocodec/OMXVideoDecoderBase.h b/videocodec/OMXVideoDecoderBase.h
index 556bc23..49610a7 100644
--- a/videocodec/OMXVideoDecoderBase.h
+++ b/videocodec/OMXVideoDecoderBase.h
@@ -80,7 +80,7 @@
     DECLARE_HANDLER(OMXVideoDecoderBase, NativeBufferMode);
     DECLARE_HANDLER(OMXVideoDecoderBase, DecoderRotation);
     DECLARE_HANDLER(OMXVideoDecoderBase, DecoderOutputCrop);
-#ifdef TARGET_HAS_VPP
+#ifdef TARGET_HAS_ISV
     DECLARE_HANDLER(OMXVideoDecoderBase, DecoderVppBufferNum);
 #endif
     DECLARE_HANDLER(OMXVideoDecoderBase, ErrorReportMode);
@@ -107,7 +107,7 @@
         uint32_t graphicBufferColorFormat;
     };
     uint32_t mRotationDegrees;
-#ifdef TARGET_HAS_VPP
+#ifdef TARGET_HAS_ISV
     uint32_t mVppBufferNum;
 #endif
 
diff --git a/videocodec/OMXVideoDecoderVP9HWR.cpp b/videocodec/OMXVideoDecoderVP9HWR.cpp
index 8566913..2170fd0 100644
--- a/videocodec/OMXVideoDecoderVP9HWR.cpp
+++ b/videocodec/OMXVideoDecoderVP9HWR.cpp
@@ -21,8 +21,6 @@
 #include "OMXVideoDecoderVP9HWR.h"
 
 #include <system/window.h>
-#include <ui/GraphicBufferMapper.h>
-#include <ui/Rect.h>
 #include <HardwareAPI.h>
 #include <hardware/hardware.h>
 #include <hardware/gralloc.h>
diff --git a/videocodec/OMXVideoDecoderVP9Hybrid.cpp b/videocodec/OMXVideoDecoderVP9Hybrid.cpp
index e1ff00d..cbca17c 100644
--- a/videocodec/OMXVideoDecoderVP9Hybrid.cpp
+++ b/videocodec/OMXVideoDecoderVP9Hybrid.cpp
@@ -39,6 +39,15 @@
     mDecoderDecode = NULL;
     mCheckBufferAvailable = NULL;
     mGetOutput = NULL;
+    mGetRawDataOutput = NULL;
+    mGetFrameResolution = NULL;
+    mDeinitDecoder = NULL;
+    mLastTimeStamp = 0;
+    mWorkingMode = RAWDATA_MODE;
+    mDecodedImageWidth = 0;
+    mDecodedImageHeight = 0;
+    mDecodedImageNewWidth = 0;
+    mDecodedImageNewHeight = 0;
 }
 
 OMXVideoDecoderVP9Hybrid::~OMXVideoDecoderVP9Hybrid() {
@@ -57,15 +66,28 @@
 }
 
 OMX_ERRORTYPE OMXVideoDecoderVP9Hybrid::ProcessorInit(void) {
-    unsigned int buff[MAX_GRAPHIC_BUFFER_NUM];
-    unsigned int i;
-    int bufferSize = mGraphicBufferParam.graphicBufferStride *
+    uint32_t buff[MAX_GRAPHIC_BUFFER_NUM];
+    uint32_t i, bufferCount;
+    bool gralloc_mode = (mWorkingMode == GRAPHICBUFFER_MODE);
+    uint32_t bufferSize, bufferStride, bufferHeight, bufferWidth;
+    if (!gralloc_mode) {
+        bufferSize = 1920 * 1088 * 1.5;
+        bufferStride = 1920;
+        bufferWidth = 1920;
+        bufferHeight = 1088;
+        bufferCount = 12;
+    } else {
+        bufferSize = mGraphicBufferParam.graphicBufferStride *
                           mGraphicBufferParam.graphicBufferHeight * 1.5;
-    int bufferStride = mGraphicBufferParam.graphicBufferStride;
+        bufferStride = mGraphicBufferParam.graphicBufferStride;
+        bufferCount = mOMXBufferHeaderTypePtrNum;
+        bufferHeight = mGraphicBufferParam.graphicBufferHeight;
+        bufferWidth = mGraphicBufferParam.graphicBufferWidth;
 
-    for (i = 0; i < mOMXBufferHeaderTypePtrNum; i++ ) {
-        OMX_BUFFERHEADERTYPE *buf_hdr = mOMXBufferHeaderTypePtrArray[i];
-        buff[i] = (unsigned int)(buf_hdr->pBuffer);
+        for (i = 0; i < bufferCount; i++ ) {
+            OMX_BUFFERHEADERTYPE *buf_hdr = mOMXBufferHeaderTypePtrArray[i];
+            buff[i] = (uint32_t)(buf_hdr->pBuffer);
+        }
     }
 
     mLibHandle = dlopen("libDecoderVP9Hybrid.so", RTLD_NOW);
@@ -82,10 +104,14 @@
     mDecoderDecode = (DecodeFunc)dlsym(mLibHandle, "Decoder_Decode");
     mCheckBufferAvailable = (IsBufferAvailableFunc)dlsym(mLibHandle, "Decoder_IsBufferAvailable");
     mGetOutput = (GetOutputFunc)dlsym(mLibHandle, "Decoder_GetOutput");
+    mGetRawDataOutput = (GetRawDataOutputFunc)dlsym(mLibHandle, "Decoder_GetRawDataOutput");
+    mGetFrameResolution = (GetFrameResolutionFunc)dlsym(mLibHandle, "Decoder_GetFrameResolution");
+    mDeinitDecoder = (DeinitFunc)dlsym(mLibHandle, "Decoder_Deinit");
     if (mOpenDecoder == NULL || mCloseDecoder == NULL
         || mInitDecoder == NULL || mSingalRenderDone == NULL
         || mDecoderDecode == NULL || mCheckBufferAvailable == NULL
-        || mGetOutput == NULL) {
+        || mGetOutput == NULL || mGetRawDataOutput == NULL
+        || mGetFrameResolution == NULL || mDeinitDecoder == NULL) {
         return OMX_ErrorBadParameter;
     }
 
@@ -94,10 +120,60 @@
         return OMX_ErrorBadParameter;
     }
 
-    mInitDecoder(mHybridCtx,bufferSize,bufferStride,mOMXBufferHeaderTypePtrNum, buff);
+    mInitDecoder(mHybridCtx,bufferSize,bufferStride,bufferWidth, bufferHeight,bufferCount,gralloc_mode, buff);
     return OMX_ErrorNone;
 }
 
+OMX_ERRORTYPE OMXVideoDecoderVP9Hybrid::ProcessorReset(void)
+{
+    uint32_t buff[MAX_GRAPHIC_BUFFER_NUM];
+    uint32_t i, bufferCount;
+    bool gralloc_mode = (mWorkingMode == GRAPHICBUFFER_MODE);
+    uint32_t bufferSize, bufferStride, bufferHeight, bufferWidth;
+    if (!gralloc_mode) {
+        bufferSize = mDecodedImageWidth * mDecodedImageHeight * 1.5;
+        bufferStride = mDecodedImageWidth;
+        bufferWidth = mDecodedImageWidth;
+        bufferHeight = mDecodedImageHeight;
+        bufferCount = 12;
+    } else {
+        bufferSize = mGraphicBufferParam.graphicBufferStride *
+                          mGraphicBufferParam.graphicBufferHeight * 1.5;
+        bufferStride = mGraphicBufferParam.graphicBufferStride;
+        bufferWidth =  mGraphicBufferParam.graphicBufferWidth;
+        bufferCount = mOMXBufferHeaderTypePtrNum;
+        bufferHeight = mGraphicBufferParam.graphicBufferHeight;
+
+        for (i = 0; i < bufferCount; i++ ) {
+            OMX_BUFFERHEADERTYPE *buf_hdr = mOMXBufferHeaderTypePtrArray[i];
+            buff[i] = (uint32_t)(buf_hdr->pBuffer);
+        }
+    }
+    mInitDecoder(mHybridCtx,bufferSize,bufferStride,bufferWidth,bufferHeight,bufferCount,gralloc_mode, buff);
+
+    return OMX_ErrorNone;
+}
+
+bool OMXVideoDecoderVP9Hybrid::isReallocateNeeded(const uint8_t * data,uint32_t data_sz)
+{
+    bool gralloc_mode = (mWorkingMode == GRAPHICBUFFER_MODE);
+    uint32_t width, height;
+    bool ret = true;
+    if (gralloc_mode) {
+        ret = mGetFrameResolution(data,data_sz, &width, &height);
+        if (ret) {
+            ret = width > mGraphicBufferParam.graphicBufferWidth
+                || height > mGraphicBufferParam.graphicBufferHeight;
+            if (ret) {
+                mDecodedImageNewWidth = width;
+                mDecodedImageNewHeight = height;
+                return true;
+            }
+        }
+    }
+    return ret;
+}
+
 OMX_ERRORTYPE OMXVideoDecoderVP9Hybrid::ProcessorDeinit(void) {
     mCloseDecoder(mCtx,mHybridCtx);
     mOMXBufferHeaderTypePtrNum = 0;
@@ -112,7 +188,14 @@
     return OMXComponentCodecBase::ProcessorStop();
 }
 
-OMX_ERRORTYPE OMXVideoDecoderVP9Hybrid::ProcessorFlush(OMX_U32) {
+OMX_ERRORTYPE OMXVideoDecoderVP9Hybrid::ProcessorFlush(OMX_U32 portIndex) {
+    if (portIndex == INPORT_INDEX || portIndex == OMX_ALL) {
+        // end the last frame
+        unsigned int width, height;
+        mDecoderDecode(mCtx,mHybridCtx,NULL,0,true);
+        mGetOutput(mCtx,mHybridCtx, &width, &height);
+        mLastTimeStamp = 0;
+    }
     return OMX_ErrorNone;
 }
 
@@ -121,7 +204,7 @@
     unsigned int i = 0;
 
     if (buffer->nOutputPortIndex == OUTPORT_INDEX){
-        mSingalRenderDone(handle);
+        mSingalRenderDone(mHybridCtx,handle);
     }
     return OMX_ErrorNone;
 }
@@ -134,6 +217,10 @@
     OMX_ERRORTYPE ret;
     OMX_BUFFERHEADERTYPE *inBuffer = *pBuffers[INPORT_INDEX];
     OMX_BUFFERHEADERTYPE *outBuffer = *pBuffers[OUTPORT_INDEX];
+    bool eos = (inBuffer->nFlags & OMX_BUFFERFLAG_EOS)? true:false;
+    OMX_BOOL isResolutionChange = OMX_FALSE;
+
+    eos = eos && (inBuffer->nFilledLen == 0);
 
     if (inBuffer->pBuffer == NULL) {
         LOGE("Buffer to decode is empty.");
@@ -148,22 +235,26 @@
         LOGW("Buffer has OMX_BUFFERFLAG_DECODEONLY flag.");
     }
 
-    if (inBuffer->nFlags & OMX_BUFFERFLAG_EOS) {
-        if (inBuffer->nFilledLen == 0) {
-            (*pBuffers[OUTPORT_INDEX])->nFilledLen = 0;
-            (*pBuffers[OUTPORT_INDEX])->nFlags = OMX_BUFFERFLAG_EOS;
-            return OMX_ErrorNone;
-        }
-    }
-
 #if LOG_TIME == 1
     struct timeval tv_start, tv_end;
     int32_t time_ms;
     gettimeofday(&tv_start,NULL);
 #endif
-    if (mDecoderDecode(mCtx,mHybridCtx,inBuffer->pBuffer + inBuffer->nOffset,inBuffer->nFilledLen) == false) {
-        LOGE("on2 decoder failed to decode frame.");
-        return OMX_ErrorBadParameter;
+    int res = mDecoderDecode(mCtx,mHybridCtx,inBuffer->pBuffer + inBuffer->nOffset,inBuffer->nFilledLen, eos);
+    if (res != 0) {
+        if (res == -2) {
+            if (isReallocateNeeded(inBuffer->pBuffer + inBuffer->nOffset,inBuffer->nFilledLen)) {
+                retains[INPORT_INDEX] = BUFFER_RETAIN_GETAGAIN;
+                HandleFormatChange();
+                return OMX_ErrorNone;
+            }
+            // drain the last frame, keep the current input buffer
+            res = mDecoderDecode(mCtx,mHybridCtx,NULL,0,true);
+            retains[INPORT_INDEX] = BUFFER_RETAIN_GETAGAIN;
+        } else {
+            LOGE("on2 decoder failed to decode frame.");
+            return OMX_ErrorBadParameter;
+        }
     }
 
 #if LOG_TIME == 1
@@ -174,17 +265,22 @@
 
     ret = FillRenderBuffer(pBuffers[OUTPORT_INDEX],
                            &retains[OUTPORT_INDEX],
-                           ((*pBuffers[INPORT_INDEX]))->nFlags);
+                           eos? OMX_BUFFERFLAG_EOS:0,
+                           &isResolutionChange);
 
     if (ret == OMX_ErrorNone) {
-        (*pBuffers[OUTPORT_INDEX])->nTimeStamp = inBuffer->nTimeStamp;
+        (*pBuffers[OUTPORT_INDEX])->nTimeStamp = mLastTimeStamp;
     }
+    mLastTimeStamp = inBuffer->nTimeStamp;
 
+    if (isResolutionChange == OMX_TRUE) {
+        HandleFormatChange();
+    }
     bool inputEoS = ((*pBuffers[INPORT_INDEX])->nFlags & OMX_BUFFERFLAG_EOS);
     bool outputEoS = ((*pBuffers[OUTPORT_INDEX])->nFlags & OMX_BUFFERFLAG_EOS);
     // if output port is not eos, retain the input buffer
     // until all the output buffers are drained.
-    if (inputEoS && !outputEoS) {
+    if (inputEoS && !outputEoS && retains[INPORT_INDEX] != BUFFER_RETAIN_GETAGAIN) {
         retains[INPORT_INDEX] = BUFFER_RETAIN_GETAGAIN;
         // the input buffer is retained for draining purpose.
         // Set nFilledLen to 0 so buffer will not be decoded again.
@@ -206,29 +302,65 @@
 
 OMX_ERRORTYPE OMXVideoDecoderVP9Hybrid::FillRenderBuffer(OMX_BUFFERHEADERTYPE **pBuffer,
                                                       buffer_retain_t *retain,
-                                                      OMX_U32 inportBufferFlags)
+                                                      OMX_U32 inportBufferFlags,
+                                                      OMX_BOOL *isResolutionChange)
 {
     OMX_BUFFERHEADERTYPE *buffer = *pBuffer;
     OMX_BUFFERHEADERTYPE *buffer_orign = buffer;
 
     OMX_ERRORTYPE ret = OMX_ErrorNone;
 
-    if (mWorkingMode != GRAPHICBUFFER_MODE) {
-        LOGE("Working Mode is not GRAPHICBUFFER_MODE");
-        ret = OMX_ErrorBadParameter;
+    int fb_index;
+    if (mWorkingMode == RAWDATA_MODE) {
+        const OMX_PARAM_PORTDEFINITIONTYPE *paramPortDefinitionOutput
+                       = this->ports[OUTPORT_INDEX]->GetPortDefinition();
+        int32_t stride = paramPortDefinitionOutput->format.video.nStride;
+        int32_t height =  paramPortDefinitionOutput->format.video.nFrameHeight;
+        int32_t width = paramPortDefinitionOutput->format.video.nFrameWidth;
+        unsigned char *dst = buffer->pBuffer;
+        fb_index = mGetRawDataOutput(mCtx,mHybridCtx,dst,height,stride);
+        if (fb_index == -1) {
+            if (inportBufferFlags & OMX_BUFFERFLAG_EOS) {
+                // eos frame is non-shown frame
+                buffer->nFlags = OMX_BUFFERFLAG_EOS;
+                buffer->nOffset = 0;
+                buffer->nFilledLen = 0;
+                return OMX_ErrorNone;
+            }
+            LOGV("vpx_codec_get_frame return NULL.");
+            return OMX_ErrorNotReady;
+        }
+        buffer->nOffset = 0;
+        buffer->nFilledLen = stride*height*3/2;
+        if (inportBufferFlags & OMX_BUFFERFLAG_EOS) {
+            buffer->nFlags = OMX_BUFFERFLAG_EOS;
+        }
+        return OMX_ErrorNone;
     }
-    int fb_index = mGetOutput(mCtx);
+
+    fb_index = mGetOutput(mCtx,mHybridCtx, &mDecodedImageNewWidth, &mDecodedImageNewHeight);
     if (fb_index == -1) {
-        LOGE("vpx_codec_get_frame return NULL.");
+        if (inportBufferFlags & OMX_BUFFERFLAG_EOS) {
+            // eos frame is no-shown frame
+            buffer->nFlags = OMX_BUFFERFLAG_EOS;
+            buffer->nOffset = 0;
+            buffer->nFilledLen = 0;
+            return OMX_ErrorNone;
+        }
+        LOGV("vpx_codec_get_frame return NULL.");
         return OMX_ErrorNotReady;
     }
+    if (mDecodedImageHeight == 0 && mDecodedImageWidth == 0) {
+        mDecodedImageWidth = mDecodedImageNewWidth;
+        mDecodedImageHeight = mDecodedImageNewHeight;
+        *isResolutionChange = OMX_TRUE;
+    }
+    if ((mDecodedImageNewWidth != mDecodedImageWidth)
+        || (mDecodedImageNewHeight!= mDecodedImageHeight)) {
+        *isResolutionChange = OMX_TRUE;
+    }
 
     buffer = *pBuffer = mOMXBufferHeaderTypePtrArray[fb_index];
-
-    size_t dst_y_size = mGraphicBufferParam.graphicBufferStride *
-                        mGraphicBufferParam.graphicBufferHeight;
-    size_t dst_c_stride = ALIGN(mGraphicBufferParam.graphicBufferStride / 2, 16);
-    size_t dst_c_size = dst_c_stride * mGraphicBufferParam.graphicBufferHeight / 2;
     buffer->nOffset = 0;
     buffer->nFilledLen = sizeof(OMX_U8*);
     if (inportBufferFlags & OMX_BUFFERFLAG_EOS) {
@@ -268,6 +400,88 @@
     return OMX_ErrorNone;
 }
 
+OMX_ERRORTYPE OMXVideoDecoderVP9Hybrid::HandleFormatChange(void)
+{
+    ALOGI("handle format change from %dx%d to %dx%d",
+        mDecodedImageWidth,mDecodedImageHeight,mDecodedImageNewWidth,mDecodedImageNewHeight);
+    mDecodedImageWidth = mDecodedImageNewWidth;
+    mDecodedImageHeight = mDecodedImageNewHeight;
+    // Sync port definition as it may change.
+    OMX_PARAM_PORTDEFINITIONTYPE paramPortDefinitionInput, paramPortDefinitionOutput;
+
+    memcpy(&paramPortDefinitionInput,
+        this->ports[INPORT_INDEX]->GetPortDefinition(),
+        sizeof(paramPortDefinitionInput));
+
+    memcpy(&paramPortDefinitionOutput,
+        this->ports[OUTPORT_INDEX]->GetPortDefinition(),
+        sizeof(paramPortDefinitionOutput));
+
+    unsigned int width = mDecodedImageWidth;
+    unsigned int height = mDecodedImageHeight;
+    unsigned int stride = mDecodedImageWidth;
+    unsigned int sliceHeight = mDecodedImageHeight;
+
+    unsigned int widthCropped = mDecodedImageWidth;
+    unsigned int heightCropped = mDecodedImageHeight;
+    unsigned int strideCropped = widthCropped;
+    unsigned int sliceHeightCropped = heightCropped;
+
+    if (widthCropped == paramPortDefinitionOutput.format.video.nFrameWidth &&
+        heightCropped == paramPortDefinitionOutput.format.video.nFrameHeight) {
+        if (mWorkingMode == RAWDATA_MODE) {
+            LOGW("Change of portsetting is not reported as size is not changed.");
+            return OMX_ErrorNone;
+        }
+    }
+
+    paramPortDefinitionInput.format.video.nFrameWidth = width;
+    paramPortDefinitionInput.format.video.nFrameHeight = height;
+    paramPortDefinitionInput.format.video.nStride = stride;
+    paramPortDefinitionInput.format.video.nSliceHeight = sliceHeight;
+
+    if (mWorkingMode == RAWDATA_MODE) {
+        paramPortDefinitionOutput.format.video.nFrameWidth = widthCropped;
+        paramPortDefinitionOutput.format.video.nFrameHeight = heightCropped;
+        paramPortDefinitionOutput.format.video.nStride = strideCropped;
+        paramPortDefinitionOutput.format.video.nSliceHeight = sliceHeightCropped;
+    } else if (mWorkingMode == GRAPHICBUFFER_MODE) {
+        // when the width and height ES parse are not larger than allocated graphic buffer in outport,
+        // there is no need to reallocate graphic buffer,just report the crop info to omx client
+        if (width <= mGraphicBufferParam.graphicBufferWidth &&
+            height <= mGraphicBufferParam.graphicBufferHeight) {
+            this->ports[INPORT_INDEX]->SetPortDefinition(&paramPortDefinitionInput, true);
+            this->ports[OUTPORT_INDEX]->ReportOutputCrop();
+            return OMX_ErrorNone;
+        }
+
+        if (width > mGraphicBufferParam.graphicBufferWidth ||
+            height > mGraphicBufferParam.graphicBufferHeight) {
+            // update the real decoded resolution to outport instead of display resolution
+            // for graphic buffer reallocation
+            // when the width and height parsed from ES are larger than allocated graphic buffer in outport,
+            paramPortDefinitionOutput.format.video.nFrameWidth = width;
+            paramPortDefinitionOutput.format.video.nFrameHeight = (height + 0x1f) & ~0x1f;
+            paramPortDefinitionOutput.format.video.eColorFormat = GetOutputColorFormat(
+                    paramPortDefinitionOutput.format.video.nFrameWidth);
+            paramPortDefinitionOutput.format.video.nStride = stride;
+            paramPortDefinitionOutput.format.video.nSliceHeight = sliceHeight;
+       }
+    }
+
+    paramPortDefinitionOutput.bEnabled = (OMX_BOOL)false;
+    mOMXBufferHeaderTypePtrNum = 0;
+    memset(&mGraphicBufferParam, 0, sizeof(mGraphicBufferParam));
+    mDeinitDecoder(mHybridCtx);
+
+    this->ports[INPORT_INDEX]->SetPortDefinition(&paramPortDefinitionInput, true);
+    this->ports[OUTPORT_INDEX]->SetPortDefinition(&paramPortDefinitionOutput, true);
+
+    this->ports[OUTPORT_INDEX]->ReportPortSettingsChanged();
+    return OMX_ErrorNone;
+}
+
+
 OMX_COLOR_FORMATTYPE OMXVideoDecoderVP9Hybrid::GetOutputColorFormat(int) {
     LOGV("Output color format is HAL_PIXEL_FORMAT_YV12.");
     return (OMX_COLOR_FORMATTYPE)HAL_PIXEL_FORMAT_YV12;
@@ -301,7 +515,7 @@
         (android::GetAndroidNativeBufferUsageParams*)pStructure;
     CHECK_TYPE_HEADER(param);
 
-    param->nUsage |= (GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_SW_READ_NEVER \
+    param->nUsage |= (GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_SW_READ_OFTEN
                      | GRALLOC_USAGE_SW_WRITE_OFTEN | GRALLOC_USAGE_EXTERNAL_DISP);
     return OMX_ErrorNone;
 
@@ -317,6 +531,7 @@
 
     if (!param->enable) {
         mWorkingMode = RAWDATA_MODE;
+        LOGI("Raw data mode is used");
         return OMX_ErrorNone;
     }
     mWorkingMode = GRAPHICBUFFER_MODE;
@@ -325,13 +540,13 @@
 
     OMX_PARAM_PORTDEFINITIONTYPE port_def;
     memcpy(&port_def,port->GetPortDefinition(),sizeof(port_def));
-    port_def.nBufferCountMin = mNativeBufferCount;
+    port_def.nBufferCountMin = mNativeBufferCount - 4;
     port_def.nBufferCountActual = mNativeBufferCount;
     port_def.format.video.cMIMEType = (OMX_STRING)VA_VED_RAW_MIME_TYPE;
-    port_def.format.video.eColorFormat = (OMX_COLOR_FORMATTYPE)OMX_INTEL_COLOR_FormatYUV420PackedSemiPlanar;
     // add borders for libvpx decode need.
-    port_def.format.video.nFrameHeight += VPX_DECODE_BORDER * 2;
     port_def.format.video.nFrameWidth += VPX_DECODE_BORDER * 2;
+    mDecodedImageWidth = port_def.format.video.nFrameWidth;
+    mDecodedImageHeight = port_def.format.video.nFrameHeight;
     // make heigth 32bit align
     port_def.format.video.nFrameHeight = (port_def.format.video.nFrameHeight + 0x1f) & ~0x1f;
     port_def.format.video.eColorFormat = GetOutputColorFormat(port_def.format.video.nFrameWidth);
@@ -354,7 +569,7 @@
     if (!port_def->bEnabled) {
         return false;
     }
-    return mCheckBufferAvailable();
+    return mCheckBufferAvailable(mHybridCtx);
 }
 
 DECLARE_OMX_COMPONENT("OMX.Intel.VideoDecoder.VP9.hybrid", "video_decoder.vp9", OMXVideoDecoderVP9Hybrid);
diff --git a/videocodec/OMXVideoDecoderVP9Hybrid.h b/videocodec/OMXVideoDecoderVP9Hybrid.h
index 68b06c1..ad44cc5 100644
--- a/videocodec/OMXVideoDecoderVP9Hybrid.h
+++ b/videocodec/OMXVideoDecoderVP9Hybrid.h
@@ -38,6 +38,7 @@
             OMX_BUFFERHEADERTYPE ***pBuffers,
             buffer_retain_t *retains,
             OMX_U32 numberBuffers);
+    virtual OMX_ERRORTYPE ProcessorReset(void);
 
     virtual OMX_ERRORTYPE ProcessorPreFillBuffer(OMX_BUFFERHEADERTYPE* buffer);
     virtual bool IsAllBufferAvailable(void);
@@ -47,26 +48,35 @@
 
     virtual OMX_ERRORTYPE BuildHandlerList(void);
 
-    virtual OMX_ERRORTYPE FillRenderBuffer(OMX_BUFFERHEADERTYPE **pBuffer,  buffer_retain_t *retain, OMX_U32 inportBufferFlags);
+    virtual OMX_ERRORTYPE FillRenderBuffer(OMX_BUFFERHEADERTYPE **pBuffer,  buffer_retain_t *retain, OMX_U32 inportBufferFlags, OMX_BOOL *isResolutionChange);
 
     virtual OMX_COLOR_FORMATTYPE GetOutputColorFormat(int width);
     virtual OMX_ERRORTYPE GetDecoderOutputCropSpecific(OMX_PTR pStructure);
     virtual OMX_ERRORTYPE GetNativeBufferUsageSpecific(OMX_PTR pStructure);
     virtual OMX_ERRORTYPE SetNativeBufferModeSpecific(OMX_PTR pStructure);
-
+    virtual OMX_ERRORTYPE HandleFormatChange(void);
     DECLARE_HANDLER(OMXVideoDecoderVP9Hybrid, ParamVideoVp9);
 
 private:
+    bool isReallocateNeeded(const uint8_t *data, uint32_t data_sz);
     void *mCtx;
     void *mHybridCtx;
     void *mLibHandle;
+    // These members are for Adaptive playback
+    uint32_t mDecodedImageWidth;
+    uint32_t mDecodedImageHeight;
+    uint32_t mDecodedImageNewWidth;
+    uint32_t mDecodedImageNewHeight;
     typedef bool (*OpenFunc)(void ** , void **);
-    typedef bool (*InitFunc)(void *,unsigned int, unsigned int, int, unsigned int *);
+    typedef bool (*InitFunc)(void *,uint32_t, uint32_t, uint32_t, uint32_t, uint32_t,  bool, uint32_t *);
     typedef bool (*CloseFunc)(void *, void *);
-    typedef bool (*SingalRenderDoneFunc)(unsigned int);
-    typedef bool (*DecodeFunc)(void *, void *, unsigned char *, unsigned int);
-    typedef bool (*IsBufferAvailableFunc)();	
-    typedef int (*GetOutputFunc)(void *);
+    typedef bool (*SingalRenderDoneFunc)(void *, unsigned int);
+    typedef int (*DecodeFunc)(void *, void *, unsigned char *, unsigned int, bool);
+    typedef bool (*IsBufferAvailableFunc)(void *);
+    typedef int (*GetOutputFunc)(void*, void *, unsigned int *, unsigned int *);
+    typedef int (*GetRawDataOutputFunc)(void*, void *, unsigned char *, int, int);
+    typedef void (*DeinitFunc)(void *);
+    typedef bool (*GetFrameResolutionFunc)(const uint8_t *, uint32_t , uint32_t *, uint32_t *);
     OpenFunc mOpenDecoder;
     InitFunc mInitDecoder;
     CloseFunc mCloseDecoder;
@@ -74,12 +84,16 @@
     DecodeFunc mDecoderDecode;
     IsBufferAvailableFunc mCheckBufferAvailable;
     GetOutputFunc mGetOutput;
+    GetRawDataOutputFunc mGetRawDataOutput;
+    GetFrameResolutionFunc mGetFrameResolution;
+    DeinitFunc mDeinitDecoder;
+    int64_t mLastTimeStamp;
     enum {
         // OMX_PARAM_PORTDEFINITIONTYPE
         INPORT_MIN_BUFFER_COUNT = 1,
         INPORT_ACTUAL_BUFFER_COUNT = 5,
         INPORT_BUFFER_SIZE = 1382400,
-        OUTPORT_NATIVE_BUFFER_COUNT = 12, // 8 reference + 1 current + 3 for asynchronized mode
+        OUTPORT_NATIVE_BUFFER_COUNT = 15, // 8 reference + 2 current + 4 for asynchronized mode + 1 free buffer
     };
 
 };
diff --git a/videocodec/OMXVideoEncoderBase.cpp b/videocodec/OMXVideoEncoderBase.cpp
index bc37f4f..5e918c9 100644
--- a/videocodec/OMXVideoEncoderBase.cpp
+++ b/videocodec/OMXVideoEncoderBase.cpp
@@ -172,6 +172,12 @@
     mConfigIntelBitrate.nFrameRate = 0;
     mConfigIntelBitrate.nTemporalID = 0;
 
+    // OMX_VIDEO_CONFIG_BITRATETYPE
+    memset(&mConfigBitrate, 0, sizeof(mConfigBitrate));
+    SetTypeHeader(&mConfigBitrate, sizeof(mConfigBitrate));
+    mConfigBitrate.nPortIndex = OUTPORT_INDEX;
+    mConfigBitrate.nEncodeBitrate = 0; // Maximum bitrate
+
     // OMX_VIDEO_CONFIG_INTEL_AIR
     memset(&mConfigIntelAir, 0, sizeof(mConfigIntelAir));
     SetTypeHeader(&mConfigIntelAir, sizeof(mConfigIntelAir));
@@ -404,6 +410,7 @@
     AddHandler((OMX_INDEXTYPE)OMX_IndexExtSyncEncoding, GetSyncEncoding, SetSyncEncoding);
     AddHandler((OMX_INDEXTYPE)OMX_IndexExtPrependSPSPPS, GetPrependSPSPPS, SetPrependSPSPPS);
     AddHandler((OMX_INDEXTYPE)OMX_IndexExtTemporalLayer, GetTemporalLayer,SetTemporalLayer);
+    AddHandler((OMX_INDEXTYPE)OMX_IndexConfigVideoBitrate, GetConfigVideoBitrate, SetConfigVideoBitrate);
     AddHandler((OMX_INDEXTYPE)OMX_IndexExtRequestBlackFramePointer, GetBlackFramePointer, GetBlackFramePointer);
     return OMX_ErrorNone;
 }
@@ -935,3 +942,41 @@
 OMX_ERRORTYPE OMXVideoEncoderBase::SetBlackFramePointer(OMX_PTR) {
     return OMX_ErrorUnsupportedSetting;
 }
+
+OMX_ERRORTYPE OMXVideoEncoderBase::GetConfigVideoBitrate(OMX_PTR pStructure) {
+
+    OMX_ERRORTYPE ret;
+    OMX_VIDEO_CONFIG_BITRATETYPE *p = (OMX_VIDEO_CONFIG_BITRATETYPE *)pStructure;
+
+    CHECK_TYPE_HEADER(p);
+    CHECK_PORT_INDEX(p, OUTPORT_INDEX);
+    memcpy(p, &mConfigBitrate, sizeof(*p));
+    return OMX_ErrorNone;
+}
+OMX_ERRORTYPE OMXVideoEncoderBase::SetConfigVideoBitrate(OMX_PTR pStructure){
+    OMX_ERRORTYPE ret;
+    Encode_Status retStatus = ENCODE_SUCCESS;
+    if (mParamBitrate.eControlRate == OMX_Video_ControlRateMax){
+        LOGE("SetConfigIntelBitrate failed. Feature is disabled.");
+        return OMX_ErrorUnsupportedIndex;
+    }
+    OMX_VIDEO_CONFIG_BITRATETYPE *p = (OMX_VIDEO_CONFIG_BITRATETYPE *)pStructure;
+    CHECK_TYPE_HEADER(p);
+    CHECK_PORT_INDEX(p, OUTPORT_INDEX);
+
+    // set in either Loaded state (ComponentSetParam) or Executing state (ComponentSetConfig)
+    mConfigBitrate = *p;
+
+    // return OMX_ErrorNone if not in Executing state
+    // TODO: return OMX_ErrorIncorrectStateOperation?
+    // CHECK_SET_CONFIG_STATE();
+
+    VideoConfigBitRate configBitRate;
+    configBitRate.rcParams.bitRate = mConfigBitrate.nEncodeBitrate;
+    configBitRate.rcParams.temporalID = 0;
+    retStatus = mVideoEncoder->setConfig(&configBitRate);
+    if(retStatus != ENCODE_SUCCESS) {
+        LOGW("failed to set IntelBitrate");
+    }
+    return OMX_ErrorNone;
+}
diff --git a/videocodec/OMXVideoEncoderBase.h b/videocodec/OMXVideoEncoderBase.h
index f16b0a3..f2926b3 100644
--- a/videocodec/OMXVideoEncoderBase.h
+++ b/videocodec/OMXVideoEncoderBase.h
@@ -72,6 +72,7 @@
     DECLARE_HANDLER(OMXVideoEncoderBase, SyncEncoding);
     DECLARE_HANDLER(OMXVideoEncoderBase, PrependSPSPPS);
     DECLARE_HANDLER(OMXVideoEncoderBase, TemporalLayer);
+    DECLARE_HANDLER(OMXVideoEncoderBase, ConfigVideoBitrate);
     DECLARE_HANDLER(OMXVideoEncoderBase, BlackFramePointer);
 
 protected:
@@ -86,6 +87,7 @@
     OMX_VIDEO_PARAM_INTEL_ADAPTIVE_SLICE_CONTROL mParamIntelAdaptiveSliceControl;
     OMX_VIDEO_PARAM_PROFILELEVELTYPE mParamProfileLevel;
     OMX_VIDEO_PARAM_INTEL_TEMPORAL_LAYER mTemporalLayer;
+    OMX_VIDEO_CONFIG_BITRATETYPE mConfigBitrate;
 
     IVideoEncoder *mVideoEncoder;
     VideoParamsCommon *mEncoderParams;
diff --git a/videocodec/OMXVideoEncoderVP8.cpp b/videocodec/OMXVideoEncoderVP8.cpp
index d2a2aee..ec1062d 100644
--- a/videocodec/OMXVideoEncoderVP8.cpp
+++ b/videocodec/OMXVideoEncoderVP8.cpp
@@ -6,6 +6,7 @@
 
 OMXVideoEncoderVP8::OMXVideoEncoderVP8() {
     LOGV("OMXVideoEncoderVP8 is constructed.");
+    mLastTimestamp = 0x7FFFFFFFFFFFFFFFLL;
     BuildHandlerList();
     mVideoEncoder = createVideoEncoder(VP8_MIME_TYPE);
     if(!mVideoEncoder) LOGE("OMX_ErrorInsufficientResources");
@@ -82,7 +83,8 @@
     OMX_S64 outtimestamp = 0;
     OMX_U32 outflags = 0;
     OMX_ERRORTYPE oret = OMX_ErrorNone;
-
+    OMX_U32 frameDuration;
+    OMX_U32 this_fps;
     if(buffers[INPORT_INDEX]->nFlags & OMX_BUFFERFLAG_EOS) {
         LOGV("%s(),%d: got OMX_BUFFERFLAG_EOS\n", __func__, __LINE__);
         outflags |= OMX_BUFFERFLAG_EOS;
@@ -98,6 +100,27 @@
     inBuf.type = FTYPE_UNKNOWN;
     inBuf.timeStamp = buffers[INPORT_INDEX]->nTimeStamp;
 
+    if (inBuf.timeStamp > mLastTimestamp) {
+        frameDuration = (OMX_U32)(inBuf.timeStamp - mLastTimestamp);
+    } else {
+        frameDuration = (OMX_U32)(1000000 / mEncoderParams->frameRate.frameRateNum);
+    }
+
+    this_fps = (OMX_U32)((1000000.000 / frameDuration) * 1000 + 1)/1000;
+
+    if(this_fps != mEncoderParams->frameRate.frameRateNum)
+    {// a new FrameRate is coming
+        mConfigFramerate.xEncodeFramerate = this_fps;
+        mEncoderParams->frameRate.frameRateNum = this_fps;
+        VideoConfigFrameRate framerate;
+        mVideoEncoder->getConfig(&framerate);
+        framerate.frameRate.frameRateDenom = 1;
+        framerate.frameRate.frameRateNum = mConfigFramerate.xEncodeFramerate;
+        ret = mVideoEncoder->setConfig(&framerate);
+        if(ret != ENCODE_SUCCESS) {
+               LOGW("Failed to set frame rate config");
+        }
+    }
     outBuf.data =
         buffers[OUTPORT_INDEX]->pBuffer + buffers[OUTPORT_INDEX]->nOffset;
     outBuf.dataSize = 0;
@@ -137,7 +160,7 @@
 
         outfilledlen = outBuf.dataSize;
         outtimestamp = buffers[INPORT_INDEX]->nTimeStamp;
-
+        mLastTimestamp = inBuf.timeStamp;
         if (outBuf.flag & ENCODE_BUFFERFLAG_SYNCFRAME) {
             outflags |= OMX_BUFFERFLAG_SYNCFRAME;
         }
diff --git a/videocodec/OMXVideoEncoderVP8.h b/videocodec/OMXVideoEncoderVP8.h
index afafb7f..f6a6b56 100644
--- a/videocodec/OMXVideoEncoderVP8.h
+++ b/videocodec/OMXVideoEncoderVP8.h
@@ -28,6 +28,8 @@
 
         OMX_VIDEO_PARAM_VP8TYPE mParamVp8;
         OMX_VIDEO_VP8REFERENCEFRAMETYPE mConfigVideoVp8ReferenceFrame;
+        // Last input buffer timestamp
+        OMX_TICKS mLastTimestamp;
 };
 
 #endif /* OMX_VIDEO_ENCODER_VP8_H */
diff --git a/videocodec/securevideo/moorefield/OMXVideoDecoderAVCSecure.cpp b/videocodec/securevideo/moorefield/OMXVideoDecoderAVCSecure.cpp
index 1cee46c..f976e0b 100755
--- a/videocodec/securevideo/moorefield/OMXVideoDecoderAVCSecure.cpp
+++ b/videocodec/securevideo/moorefield/OMXVideoDecoderAVCSecure.cpp
@@ -497,10 +497,21 @@
     OMX_VIDEO_PARAM_PROFILELEVELTYPE *p = (OMX_VIDEO_PARAM_PROFILELEVELTYPE *)pStructure;
     CHECK_TYPE_HEADER(p);
     CHECK_PORT_INDEX(p, INPORT_INDEX);
-    CHECK_ENUMERATION_RANGE(p->nProfileIndex,1);
 
-    p->eProfile = mParamAvc.eProfile;
-    p->eLevel = mParamAvc.eLevel;
+    struct ProfileLevelTable {
+        OMX_U32 profile;
+        OMX_U32 level;
+    } plTable[] = {
+        {OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel42},
+        {OMX_VIDEO_AVCProfileMain, OMX_VIDEO_AVCLevel42},
+        {OMX_VIDEO_AVCProfileHigh, OMX_VIDEO_AVCLevel42}
+    };
+
+    OMX_U32 count = sizeof(plTable)/sizeof(ProfileLevelTable);
+    CHECK_ENUMERATION_RANGE(p->nProfileIndex,count);
+
+    p->eProfile = plTable[p->nProfileIndex].profile;
+    p->eLevel = plTable[p->nProfileIndex].level;
 
     return OMX_ErrorNone;
 }