diff --git a/ISV/Android.mk b/ISV/Android.mk
new file mode 100644
index 0000000..12965a9
--- /dev/null
+++ b/ISV/Android.mk
@@ -0,0 +1,49 @@
+ifeq ($(TARGET_HAS_ISV),true)
+
+LOCAL_PATH := $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := \
+    omx/isv_omxcore.cpp \
+    omx/isv_omxcomponent.cpp \
+    base/isv_bufmanager.cpp \
+    base/isv_processor.cpp \
+    base/isv_worker.cpp \
+    profile/isv_profile.cpp
+
+LOCAL_MODULE_TAGS := optional
+LOCAL_MODULE := libisv_omx_core
+LOCAL_32_BIT_ONLY := true
+
+LOCAL_SHARED_LIBRARIES := \
+    libutils \
+    libcutils \
+    libdl \
+    libhardware \
+    libexpat \
+    libva \
+    libva-android
+
+LOCAL_C_INCLUDES := \
+    $(LOCAL_PATH)/include \
+    $(call include-path-for, frameworks-openmax) \
+    $(TARGET_OUT_HEADERS)/libmedia_utils_vpp \
+    $(TARGET_OUT_HEADERS)/display \
+    $(TARGET_OUT_HEADERS)/khronos/openmax \
+    $(TARGET_OUT_HEADERS)/libva \
+    $(TARGET_OUT_HEADERS)/pvr/hal \
+    $(call include-path-for, frameworks-native)/media/openmax
+
+ifeq ($(USE_MEDIASDK),true)
+    LOCAL_CFLAGS += -DUSE_MEDIASDK
+endif
+
+ifeq ($(TARGET_VPP_USE_GEN),true)
+    LOCAL_CFLAGS += -DTARGET_VPP_USE_GEN
+endif
+
+LOCAL_CFLAGS += -Werror
+
+include $(BUILD_SHARED_LIBRARY)
+
+endif
diff --git a/ISV/base/isv_bufmanager.cpp b/ISV/base/isv_bufmanager.cpp
new file mode 100644
index 0000000..f0fdc42
--- /dev/null
+++ b/ISV/base/isv_bufmanager.cpp
@@ -0,0 +1,198 @@
+/*
+ * Copyright (C) 2012 Intel Corporation.  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.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include <media/hardware/HardwareAPI.h>
+#include <system/graphics.h>
+#include "isv_bufmanager.h"
+#include "hal_public.h"
+
+//#define LOG_NDEBUG 0
+#undef LOG_TAG
+#define LOG_TAG "isv-omxil"
+
+using namespace android;
+
+ISVBuffer::~ISVBuffer() {
+    if (mWorker != NULL) {
+        ALOGV("%s: mSurface %d", __func__, mSurface);
+        mWorker->freeSurface(&mSurface);
+    }
+}
+
+status_t ISVBuffer::initBufferInfo()
+{
+    if (mType == ISV_BUFFER_METADATA) {
+        VideoDecoderOutputMetaData *metaData =
+            reinterpret_cast<VideoDecoderOutputMetaData*>(mBuffer);
+
+        if (metaData->eType != kMetadataBufferTypeGrallocSource) {
+            ALOGE("%s: unsupported meta data format eType = %d", __func__, metaData->eType);
+            return UNKNOWN_ERROR;
+        }
+
+        if (mGrallocHandle != 0) {
+            if ((uint32_t)metaData->pHandle != mGrallocHandle) {
+                if (STATUS_OK != mWorker->freeSurface(&mSurface)) {
+                    ALOGE("%s: free surface %d failed.", __func__, mSurface);
+                    return UNKNOWN_ERROR;
+                }
+            } else
+                return OK;
+        }
+        mGrallocHandle = (uint32_t)metaData->pHandle;
+    } else {
+        if (mSurface != -1)
+            return OK;
+        mGrallocHandle = mBuffer;
+    }
+
+#ifdef TARGET_VPP_USE_GEN
+    gralloc_module_t* pGralloc = NULL;
+    ufo_buffer_details_t info;
+
+    memset(&info, 0, sizeof(ufo_buffer_details_t));
+    int err = hw_get_module(GRALLOC_HARDWARE_MODULE_ID, (hw_module_t const**)&pGralloc);
+    if (!pGralloc) err = -1;
+    if (0 == err)
+        err = pGralloc->perform(pGralloc, INTEL_UFO_GRALLOC_MODULE_PERFORM_GET_BO_INFO, handle, &info);
+
+    if (0 != err)
+    {
+        ALOGE("%s: can't get graphic buffer info", __func__);
+    }
+    mWidth = info.width;
+    mHeight = info.height;
+    mStride = info.pitch;
+    mColorFormat = info.format;
+#else
+    IMG_native_handle_t* grallocHandle = (IMG_native_handle_t*)mGrallocHandle;
+    mStride = grallocHandle->iWidth;
+    mColorFormat = grallocHandle->iFormat;
+#endif
+
+    //FIXME: currently, VSP doesn't support YV12 format very well, so diable ISV temporarily
+    if (mColorFormat == HAL_PIXEL_FORMAT_YV12) {
+        ALOGI("%s: VSP doesn't support YV12 very well, so disable ISV", __func__);
+        return BAD_TYPE;
+    }
+
+    if (mWorker == NULL) {
+        ALOGE("%s: mWorker == NULL!!", __func__);
+        return UNKNOWN_ERROR;
+    }
+
+    if (STATUS_OK != mWorker->allocSurface(&mWidth, &mHeight, mStride, mColorFormat, mGrallocHandle, &mSurface)) {
+        ALOGE("%s: alloc surface failed, mGrallocHandle %p", __func__, mGrallocHandle);
+        return UNKNOWN_ERROR;
+    }
+
+    ALOGD_IF(ISV_BUFFER_MANAGER_DEBUG, "%s: mWidth %d, mHeight %d, mStride %d, mColorFormat %d, mGrallocHandle %p, mSurface %d",
+            __func__, mWidth, mHeight, mStride, mColorFormat, mGrallocHandle, mSurface);
+    return OK;
+}
+
+status_t ISVBufferManager::setBufferCount(int32_t size)
+{
+    Mutex::Autolock autoLock(mBufferLock);
+#if 0
+    if (!mBuffers.isEmpty()) {
+        ALOGE("%s: the buffer queue should be empty before we set its size", __func__);
+        return STATUS_ERROR;
+    }
+#endif
+    mBuffers.setCapacity(size);
+
+    return OK;
+}
+
+status_t ISVBufferManager::freeBuffer(uint32_t handle)
+{
+    Mutex::Autolock autoLock(mBufferLock);
+    for (uint32_t i = 0; i < mBuffers.size(); i++) {
+        ISVBuffer* isvBuffer = mBuffers.itemAt(i);
+        if (isvBuffer->getHandle() == (uint32_t)handle) {
+            delete isvBuffer;
+            mBuffers.removeAt(i);
+            ALOGD_IF(ISV_BUFFER_MANAGER_DEBUG, "%s: remove handle 0x%08x, and then mBuffers.size() %d", __func__,
+                    handle, mBuffers.size());
+            return OK;
+        }
+    }
+
+    ALOGW("%s: can't find buffer %u", __func__, handle);
+    return UNKNOWN_ERROR;
+}
+
+status_t ISVBufferManager::useBuffer(uint32_t handle)
+{
+    Mutex::Autolock autoLock(mBufferLock);
+    if (handle == 0 || mBuffers.size() >= mBuffers.capacity())
+        return BAD_VALUE;
+
+    for (uint32_t i = 0; i < mBuffers.size(); i++) {
+        ISVBuffer* isvBuffer = mBuffers.itemAt(i);
+        if (isvBuffer->getHandle() == (uint32_t)handle) {
+            ALOGE("%s: this buffer 0x%08x has already been registered", __func__, handle);
+            return UNKNOWN_ERROR;
+        }
+    }
+
+    ISVBuffer* isvBuffer = new ISVBuffer(mWorker, handle, mMetaDataMode ? ISVBuffer::ISV_BUFFER_METADATA : ISVBuffer::ISV_BUFFER_GRALLOC);
+
+    ALOGD_IF(ISV_BUFFER_MANAGER_DEBUG, "%s: add handle 0x%08x, and then mBuffers.size() %d", __func__,
+            handle, mBuffers.size());
+    mBuffers.push_back(isvBuffer);
+    return OK;
+
+}
+
+status_t ISVBufferManager::useBuffer(const sp<ANativeWindowBuffer> nativeBuffer)
+{
+    Mutex::Autolock autoLock(mBufferLock);
+    if (nativeBuffer == NULL || mBuffers.size() >= mBuffers.capacity())
+        return BAD_VALUE;
+
+    for (uint32_t i = 0; i < mBuffers.size(); i++) {
+        ISVBuffer* isvBuffer = mBuffers.itemAt(i);
+        if (isvBuffer->getHandle() == (uint32_t)nativeBuffer->handle) {
+            ALOGE("%s: this buffer 0x%08x has already been registered", __func__, nativeBuffer->handle);
+            return UNKNOWN_ERROR;
+        }
+    }
+
+    ISVBuffer* isvBuffer = new ISVBuffer(mWorker,
+            (uint32_t)nativeBuffer->handle, (uint32_t)nativeBuffer->handle,
+            nativeBuffer->width, nativeBuffer->height,
+            nativeBuffer->stride, nativeBuffer->format,
+            mMetaDataMode ? ISVBuffer::ISV_BUFFER_METADATA : ISVBuffer::ISV_BUFFER_GRALLOC);
+
+    ALOGD_IF(ISV_BUFFER_MANAGER_DEBUG, "%s: add handle 0x%08x, and then mBuffers.size() %d", __func__,
+            nativeBuffer->handle, mBuffers.size());
+    mBuffers.push_back(isvBuffer);
+    return OK;
+}
+
+ISVBuffer* ISVBufferManager::mapBuffer(uint32_t handle)
+{
+    Mutex::Autolock autoLock(mBufferLock);
+    for (uint32_t i = 0; i < mBuffers.size(); i++) {
+        ISVBuffer* isvBuffer = mBuffers.itemAt(i);
+        if (isvBuffer->getHandle() == (uint32_t)handle)
+            return isvBuffer;
+    }
+    return NULL;
+}
diff --git a/ISV/base/isv_processor.cpp b/ISV/base/isv_processor.cpp
new file mode 100644
index 0000000..1bff29d
--- /dev/null
+++ b/ISV/base/isv_processor.cpp
@@ -0,0 +1,578 @@
+/*
+ * Copyright (C) 2012 Intel Corporation.  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.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include <math.h>
+#include <utils/Errors.h>
+#include "isv_processor.h"
+#include "isv_profile.h"
+#include "isv_omxcomponent.h"
+
+//#define LOG_NDEBUG 0
+#undef LOG_TAG
+#define LOG_TAG "isv-omxil"
+
+using namespace android;
+
+#define MAX_RETRY_NUM   8
+
+ISVProcessor::ISVProcessor(bool canCallJava,
+        sp<ISVBufferManager> bufferManager,
+        sp<ISVProcessorObserver> owner,
+        uint32_t width, uint32_t height)
+    :Thread(canCallJava),
+    mpOwner(owner),
+    mThreadId(NULL),
+    mThreadRunning(false),
+    mISVWorker(NULL),
+    mBufferManager(bufferManager),
+    mOutputProcIdx(0),
+    mInputProcIdx(0),
+    mNumTaskInProcesing(0),
+    mNumRetry(0),
+    mLastTimeStamp(0),
+    mError(false),
+    mbFlush(false),
+    mbBypass(false),
+    mFlagEnd(false),
+    mFilters(0)
+{
+    //FIXME: for 1920 x 1088, we also consider it as 1080p
+    mISVProfile = new ISVProfile(width, (height == 1088) ? 1080 : height);
+
+    // get platform ISV cap first
+    mFilters = mISVProfile->getFilterStatus();
+
+    // turn off filters if dynamic vpp/frc setting is off
+    if (!ISVProfile::isVPPOn())
+        mFilters &= FilterFrameRateConversion;
+
+    if (!ISVProfile::isFRCOn())
+        mFilters &= ~FilterFrameRateConversion;
+
+    //FIXME: move this into profile.
+    if (width > 2048)
+        mFilters &= ~FilterSharpening;
+
+    memset(&mFilterParam, 0, sizeof(mFilterParam));
+    //FIXME: we don't support scaling yet, so set src region equal to dst region
+    mFilterParam.srcWidth = mFilterParam.dstWidth = width;
+    mFilterParam.srcHeight = mFilterParam.dstHeight = height;
+    mOutputBuffers.clear();
+    mInputBuffers.clear();
+}
+
+ISVProcessor::~ISVProcessor() {
+    ALOGV("ISVProcessor is deleted");
+    flush();
+    mOutputBuffers.clear();
+    mInputBuffers.clear();
+
+    mISVProfile = NULL;
+    mFilters = 0;
+    memset(&mFilterParam, 0, sizeof(mFilterParam));
+}
+
+status_t ISVProcessor::readyToRun()
+{
+    mThreadId = androidGetThreadId();
+    //do init ops here
+    return Thread::readyToRun();
+}
+
+void ISVProcessor::start()
+{
+    ALOGD_IF(ISV_THREAD_DEBUG, "ISVProcessor::start");
+
+    if (mISVWorker == NULL) {
+        mISVWorker = new ISVWorker();
+        if (STATUS_OK != mISVWorker->init(mFilterParam.srcWidth, mFilterParam.srcHeight))
+            ALOGE("%s: mISVWorker init failed", __func__);
+    }
+
+    mBufferManager->setWorker(mISVWorker);
+
+    this->run("ISVProcessor", ANDROID_PRIORITY_NORMAL);
+    mThreadRunning = true;
+    return;
+}
+
+void ISVProcessor::stop()
+{
+    ALOGD_IF(ISV_THREAD_DEBUG, "ISVProcessor::stop");
+
+    if(mThreadRunning) {
+        this->requestExit();
+        {
+            Mutex::Autolock autoLock(mLock);
+            mRunCond.signal();
+        }
+        this->requestExitAndWait();
+        mThreadRunning = false;
+    }
+
+    if (STATUS_OK != mISVWorker->deinit())
+        ALOGE("%s: mISVWorker deinit failed", __func__);
+
+    mISVWorker = NULL;
+    return;
+}
+
+bool ISVProcessor::getBufForFirmwareOutput(Vector<ISVBuffer*> *fillBufList,uint32_t *fillBufNum){
+    uint32_t i = 0;
+    // output buffer number for filling
+    *fillBufNum = 0;
+    uint32_t needFillNum = 0;
+    OMX_BUFFERHEADERTYPE *outputBuffer;
+
+    //output data available
+    needFillNum = mISVWorker->getFillBufCount();
+    if (mOutputProcIdx < needFillNum ||
+            mInputProcIdx < 1) {
+        ALOGE("%s: no enough input or output buffer which need to be sync", __func__);
+        return false;
+    }
+
+    if ((needFillNum == 0) || (needFillNum > 4))
+       return false;
+
+    Mutex::Autolock autoLock(mOutputLock);
+    for (i = 0; i < needFillNum; i++) {
+        //fetch the render buffer from the top of output buffer queue
+        outputBuffer = mOutputBuffers.itemAt(i);
+        uint32_t fillHandle = reinterpret_cast<uint32_t>(outputBuffer->pBuffer);
+        ISVBuffer* fillBuf = mBufferManager->mapBuffer(fillHandle);
+        fillBufList->push_back(fillBuf);
+    }
+
+    *fillBufNum  = i;
+    return true;
+}
+
+
+status_t ISVProcessor::updateFirmwareOutputBufStatus(uint32_t fillBufNum) {
+    int64_t timeUs;
+    OMX_BUFFERHEADERTYPE *outputBuffer;
+    OMX_BUFFERHEADERTYPE *inputBuffer;
+    OMX_ERRORTYPE err;
+
+    if (mInputBuffers.empty()) {
+        ALOGE("%s: input buffer queue is empty. no buffer need to be sync", __func__);
+        return UNKNOWN_ERROR;
+    }
+
+    if (mOutputBuffers.size() < fillBufNum) {
+        ALOGE("%s: no enough output buffer which need to be sync", __func__);
+        return UNKNOWN_ERROR;
+    }
+    // remove one buffer from intput buffer queue
+    {
+        Mutex::Autolock autoLock(mInputLock);
+        inputBuffer = mInputBuffers.itemAt(0);
+        err = mpOwner->releaseBuffer(kPortIndexInput, inputBuffer, false);
+        if (err != OMX_ErrorNone) {
+            ALOGE("%s: failed to fillInputBuffer", __func__);
+            return UNKNOWN_ERROR;
+        }
+
+        mInputBuffers.removeAt(0);
+        ALOGD_IF(ISV_THREAD_DEBUG, "%s: fetch buffer %u from input buffer queue for fill to decoder, and then queue size is %d", __func__,
+                inputBuffer, mInputBuffers.size());
+        mInputProcIdx--;
+    }
+
+    //set the time stamp for interpreted frames
+    {
+        Mutex::Autolock autoLock(mOutputLock);
+        timeUs = mOutputBuffers[0]->nTimeStamp;
+
+        for(uint32_t i = 0; i < fillBufNum; i++) {
+            outputBuffer = mOutputBuffers.itemAt(i);
+            if (fillBufNum > 1) {
+                if(mFilterParam.frameRate == 15)
+                    outputBuffer->nTimeStamp = timeUs - 1000000ll * (fillBufNum - i - 1) / 30;
+                else
+                    outputBuffer->nTimeStamp = timeUs - 1000000ll * (fillBufNum - i - 1) / 60;
+            }
+
+            //return filled buffers for rendering
+            err = mpOwner->releaseBuffer(kPortIndexOutput, outputBuffer, false);
+            if (err != OMX_ErrorNone) {
+                ALOGE("%s: failed to releaseOutputBuffer", __func__);
+                return UNKNOWN_ERROR;
+            }
+
+            ALOGD_IF(ISV_THREAD_DEBUG, "%s: fetch buffer %u(timestamp %.2f ms) from output buffer queue for render, and then queue size is %d", __func__,
+                    outputBuffer, outputBuffer->nTimeStamp/1E3, mOutputBuffers.size());
+        }
+        // remove filled buffers from output buffer queue
+        mOutputBuffers.removeItemsAt(0, fillBufNum);
+        mOutputProcIdx -= fillBufNum;
+    }
+    return OK;
+}
+
+
+bool ISVProcessor::getBufForFirmwareInput(Vector<ISVBuffer*> *procBufList,
+                                   ISVBuffer **inputBuf,
+                                   uint32_t *procBufNum)
+{
+    OMX_BUFFERHEADERTYPE *outputBuffer;
+    OMX_BUFFERHEADERTYPE *inputBuffer;
+
+    int32_t procBufCount = mISVWorker->getProcBufCount();
+    if ((procBufCount == 0) || (procBufCount > 4)) {
+       return false;
+    }
+
+    //fetch a input buffer for processing
+    {
+        ALOGD_IF(ISV_COMPONENT_LOCK_DEBUG, "%s: acqiring mInputLock", __func__);
+        Mutex::Autolock autoLock(mInputLock);
+        ALOGD_IF(ISV_COMPONENT_LOCK_DEBUG, "%s: acqired mInputLock", __func__);
+        if (mbFlush) {
+            procBufCount = 1;
+            *inputBuf = NULL;
+        } else {
+            inputBuffer = mInputBuffers.itemAt(mInputProcIdx);
+            uint32_t inputHandle = reinterpret_cast<uint32_t>(inputBuffer->pBuffer);
+            *inputBuf = mBufferManager->mapBuffer(inputHandle);
+        }
+        ALOGD_IF(ISV_COMPONENT_LOCK_DEBUG, "%s: releasing mInputLock", __func__);
+    }
+
+    //fetch output buffers for processing
+    {
+        ALOGD_IF(ISV_COMPONENT_LOCK_DEBUG, "%s: acqiring mOutputLock", __func__);
+        Mutex::Autolock autoLock(mOutputLock);
+        ALOGD_IF(ISV_COMPONENT_LOCK_DEBUG, "%s: acqired mOutputLock", __func__);
+        if (mbFlush) {
+            outputBuffer = mOutputBuffers.itemAt(0);
+            uint32_t outputHandle = reinterpret_cast<uint32_t>(outputBuffer->pBuffer);
+            procBufList->push_back(mBufferManager->mapBuffer(outputHandle));
+        } else {
+            for (int32_t i = 0; i < procBufCount; i++) {
+                outputBuffer = mOutputBuffers.itemAt(mOutputProcIdx + i);
+                uint32_t outputHandle = reinterpret_cast<uint32_t>(outputBuffer->pBuffer);
+                procBufList->push_back(mBufferManager->mapBuffer(outputHandle));
+            }
+        }
+        *procBufNum = procBufCount;
+        ALOGD_IF(ISV_COMPONENT_LOCK_DEBUG, "%s: releasing mOutputLock", __func__);
+    }
+
+    return true;
+}
+
+
+status_t ISVProcessor::updateFirmwareInputBufStatus(uint32_t procBufNum)
+{
+    OMX_BUFFERHEADERTYPE *outputBuffer;
+    OMX_BUFFERHEADERTYPE *inputBuffer;
+
+    inputBuffer = mInputBuffers.itemAt(mInputProcIdx);
+    mInputProcIdx++;
+
+    Mutex::Autolock autoLock(mOutputLock);
+    for(uint32_t i = 0; i < procBufNum; i++) {
+        outputBuffer = mOutputBuffers.editItemAt(mOutputProcIdx + i);
+        // set output buffer timestamp as the same as input
+        outputBuffer->nTimeStamp = inputBuffer->nTimeStamp;
+        outputBuffer->nFilledLen = inputBuffer->nFilledLen;
+        outputBuffer->nOffset = inputBuffer->nOffset;
+        outputBuffer->nFlags = inputBuffer->nFlags;
+        //outputBuffer->nTickCount = inputBuffer->nTickCount;
+        //outputBuffer->pMarkData = intputBuffer->pMarkData;
+    }
+    mOutputProcIdx += procBufNum;
+    return OK;
+}
+
+
+bool ISVProcessor::isReadytoRun()
+{
+    ALOGD_IF(ISV_THREAD_DEBUG, "%s: mISVWorker->getProcBufCount() return %d", __func__,
+            mISVWorker->getProcBufCount());
+    if (mInputProcIdx < mInputBuffers.size()
+            && (mOutputBuffers.size() - mOutputProcIdx) >= mISVWorker->getProcBufCount())
+       return true;
+    else
+       return false;
+}
+
+
+bool ISVProcessor::threadLoop() {
+    uint32_t procBufNum = 0, fillBufNum = 0;
+    ISVBuffer* inputBuf;
+    Vector<ISVBuffer*> procBufList;
+    Vector<ISVBuffer*> fillBufList;
+    uint32_t flags = 0;
+    bool bGetBufSuccess = true;
+
+    Mutex::Autolock autoLock(mLock);
+
+    if (!isReadytoRun() && !mbFlush) {
+        mRunCond.wait(mLock);
+    }
+
+    if (isReadytoRun() || mbFlush) {
+        procBufList.clear();
+        bool bGetInBuf = getBufForFirmwareInput(&procBufList, &inputBuf, &procBufNum);
+        if (bGetInBuf) {
+            if (!mbFlush)
+                flags = mInputBuffers[mInputProcIdx]->nFlags;
+            status_t ret = mISVWorker->process(inputBuf, procBufList, procBufNum, mbFlush, flags);
+            // for seek and EOS
+            if (mbFlush) {
+                mISVWorker->reset();
+                flush();
+
+                mNumTaskInProcesing = 0;
+                mInputProcIdx = 0;
+                mOutputProcIdx = 0;
+
+                mbFlush = false;
+
+                Mutex::Autolock endLock(mEndLock);
+                mEndCond.signal();
+                return true;
+            }
+            if (ret == STATUS_OK) {
+                mNumTaskInProcesing++;
+                updateFirmwareInputBufStatus(procBufNum);
+            } else {
+                mbBypass = true;
+                flush();
+                ALOGE("VSP process error %d .... ISV changes to bypass mode", __LINE__);
+            }
+        }
+    }
+
+    ALOGV("mNumTaskInProcesing %d", mNumTaskInProcesing);
+    while ((mNumTaskInProcesing > 0) && mNumTaskInProcesing >= mISVWorker->mNumForwardReferences && bGetBufSuccess ) {
+        fillBufList.clear();
+        bGetBufSuccess = getBufForFirmwareOutput(&fillBufList, &fillBufNum);
+        ALOGD_IF(ISV_THREAD_DEBUG, "%s: bGetOutput %d, buf num %d", __func__,
+                bGetBufSuccess, fillBufNum);
+        if (bGetBufSuccess) {
+            status_t ret = mISVWorker->fill(fillBufList, fillBufNum);
+            if (ret == STATUS_OK) {
+                mNumTaskInProcesing--;
+                ALOGV("mNumTaskInProcesing: %d ...", mNumTaskInProcesing);
+                updateFirmwareOutputBufStatus(fillBufNum);
+            } else {
+                mError = true;
+                ALOGE("ISV read firmware data error! Thread EXIT...");
+                return false;
+            }
+        }
+    }
+
+    return true;
+}
+
+bool ISVProcessor::isCurrentThread() const {
+    return mThreadId == androidGetThreadId();
+}
+
+inline bool ISVProcessor::isFrameRateValid(uint32_t fps)
+{
+    return (fps == 15 || fps == 24 || fps == 25 || fps == 30 || fps == 50 || fps == 60) ? true : false;
+}
+
+status_t ISVProcessor::configFilters(OMX_BUFFERHEADERTYPE* buffer)
+{
+    if ((mFilters & FilterFrameRateConversion) != 0) {
+        if (!isFrameRateValid(mFilterParam.frameRate)) {
+            if (mNumRetry++ < MAX_RETRY_NUM) {
+                int64_t deltaTime = buffer->nTimeStamp - mLastTimeStamp;
+                mLastTimeStamp = buffer->nTimeStamp;
+                if (deltaTime != 0)
+                    mFilterParam.frameRate = ceil(1.0 / deltaTime * 1E6);
+                if (!isFrameRateValid(mFilterParam.frameRate)) {
+                    return NOT_ENOUGH_DATA;
+                } else {
+                    if (mFilterParam.frameRate == 50 || mFilterParam.frameRate == 60) {
+                        ALOGD_IF(ISV_THREAD_DEBUG, "%s: %d fps don't need do FRC, so disable FRC", __func__,
+                                mFilterParam.frameRate);
+                        mFilters &= ~FilterFrameRateConversion;
+                        mFilterParam.frcRate = FRC_RATE_1X;
+                    } else {
+                        mFilterParam.frcRate = mISVProfile->getFRCRate(mFilterParam.frameRate);
+                        ALOGD_IF(ISV_THREAD_DEBUG, "%s: calculate fps is %d, frc rate is %d", __func__,
+                                mFilterParam.frameRate, mFilterParam.frcRate);
+                    }
+                }
+            } else {
+                ALOGD_IF(ISV_THREAD_DEBUG, "%s: exceed max retry to get a valid frame rate(%d), disable FRC", __func__,
+                        mFilterParam.frameRate);
+                mFilters &= ~FilterFrameRateConversion;
+                mFilterParam.frcRate = FRC_RATE_1X;
+            }
+        }
+    }
+
+    if ((buffer->nFlags & OMX_BUFFERFLAG_TFF) != 0 ||
+            (buffer->nFlags & OMX_BUFFERFLAG_BFF) != 0)
+        mFilters |= FilterDeinterlacing;
+    else
+        mFilters &= ~FilterDeinterlacing;
+
+    if (mFilters == 0) {
+        ALOGI("%s: no filter need to be config, bypass ISV", __func__);
+        return UNKNOWN_ERROR;
+    }
+
+    //config filters to mISVWorker
+    return (mISVWorker->configFilters(mFilters, &mFilterParam) == STATUS_OK) ? OK : UNKNOWN_ERROR;
+}
+
+void ISVProcessor::addInput(OMX_BUFFERHEADERTYPE* input)
+{
+    if (mbFlush) {
+        mpOwner->releaseBuffer(kPortIndexInput, input, true);
+        return;
+    }
+
+    if (mbBypass) {
+        // return this buffer to framework
+        mpOwner->releaseBuffer(kPortIndexOutput, input, false);
+        return;
+    }
+
+    if (input->nFlags & OMX_BUFFERFLAG_EOS) {
+        mpOwner->releaseBuffer(kPortIndexInput, input, true);
+        notifyFlush();
+        return;
+    }
+
+    status_t ret = configFilters(input);
+    if (ret == NOT_ENOUGH_DATA) {
+        // release this buffer if frc is not ready.
+        mpOwner->releaseBuffer(kPortIndexInput, input, false);
+        ALOGD_IF(ISV_THREAD_DEBUG, "%s: frc rate is not ready, release this buffer %u, fps %d", __func__,
+                input, mFilterParam.frameRate);
+        return;
+    } else if (ret == UNKNOWN_ERROR) {
+        ALOGD_IF(ISV_THREAD_DEBUG, "%s: configFilters failed, bypass ISV", __func__);
+        mbBypass = true;
+        mpOwner->releaseBuffer(kPortIndexOutput, input, false);
+        return;
+    }
+
+    {
+        //put the decoded buffer into fill buffer queue
+        ALOGD_IF(ISV_COMPONENT_LOCK_DEBUG, "%s: acqiring mInputLock", __func__);
+        Mutex::Autolock autoLock(mInputLock);
+        ALOGD_IF(ISV_COMPONENT_LOCK_DEBUG, "%s: acqired mInputLock", __func__);
+
+        mInputBuffers.push_back(input);
+        ALOGD_IF(ISV_THREAD_DEBUG, "%s: hold pBuffer %u in input buffer queue. Intput queue size is %d, mInputProIdx %d.\
+                Output queue size is %d, mOutputProcIdx %d", __func__,
+                input, mInputBuffers.size(), mInputProcIdx,
+                mOutputBuffers.size(), mOutputProcIdx);
+        ALOGD_IF(ISV_COMPONENT_LOCK_DEBUG, "%s: releasing mInputLock", __func__);
+    }
+
+    {
+        Mutex::Autolock autoLock(mLock);
+        mRunCond.signal();
+    }
+    return;
+}
+
+void ISVProcessor::addOutput(OMX_BUFFERHEADERTYPE* output)
+{
+    if (mbFlush) {
+        mpOwner->releaseBuffer(kPortIndexOutput, output, true);
+        return;
+    }
+
+    if (mbBypass || mOutputBuffers.size() >= MIN_OUTPUT_NUM) {
+        // return this buffer to decoder
+        mpOwner->releaseBuffer(kPortIndexInput, output, false);
+        return;
+    }
+
+    {
+        //push the buffer into the output queue if it is not full
+        ALOGD_IF(ISV_COMPONENT_LOCK_DEBUG, "%s: acqiring mOutputLock", __func__);
+        Mutex::Autolock autoLock(mOutputLock);
+        ALOGD_IF(ISV_COMPONENT_LOCK_DEBUG, "%s: acqired mOutputLock", __func__);
+
+        mOutputBuffers.push_back(output);
+        ALOGD_IF(ISV_THREAD_DEBUG, "%s: hold pBuffer %u in output buffer queue. Input queue size is %d, mInputProIdx %d.\
+                Output queue size is %d, mOutputProcIdx %d", __func__,
+                output, mInputBuffers.size(), mInputProcIdx,
+                mOutputBuffers.size(), mOutputProcIdx);
+        ALOGD_IF(ISV_COMPONENT_LOCK_DEBUG, "%s: releasing mOutputLock", __func__);
+    }
+
+    {
+        Mutex::Autolock autoLock(mLock);
+        mRunCond.signal();
+    }
+    return;
+}
+
+void ISVProcessor::notifyFlush()
+{
+    if (mInputBuffers.empty() && mOutputBuffers.empty()) {
+        ALOGD_IF(ISV_THREAD_DEBUG, "%s: input and ouput buffer queue is empty, nothing need to do", __func__);
+        return;
+    }
+
+    Mutex::Autolock autoLock(mLock);
+    mbFlush = true;
+    mRunCond.signal();
+    ALOGD_IF(ISV_THREAD_DEBUG, "wake up proc thread");
+    return;
+}
+
+void ISVProcessor::waitFlushFinished()
+{
+    Mutex::Autolock endLock(mEndLock);
+    ALOGD_IF(ISV_THREAD_DEBUG, "waiting mEnd lock(seek finish) ");
+    while(mbFlush) {
+        mEndCond.wait(mEndLock);
+    }
+    return;
+}
+
+void ISVProcessor::flush()
+{
+    OMX_BUFFERHEADERTYPE* pBuffer = NULL;
+    {
+        Mutex::Autolock autoLock(mInputLock);
+        while (!mInputBuffers.empty()) {
+            pBuffer = mInputBuffers.itemAt(0);
+            mpOwner->releaseBuffer(kPortIndexInput, pBuffer, true);
+            ALOGD_IF(ISV_THREAD_DEBUG, "%s: Flush the pBuffer %u in input buffer queue.", __func__, pBuffer);
+            mInputBuffers.removeAt(0);
+        }
+    }
+    {
+        Mutex::Autolock autoLock(mOutputLock);
+        while (!mOutputBuffers.empty()) {
+            pBuffer = mOutputBuffers.itemAt(0);
+            mpOwner->releaseBuffer(kPortIndexOutput, pBuffer, true);
+            ALOGD_IF(ISV_THREAD_DEBUG, "%s: Flush the pBuffer %u in output buffer queue.", __func__, pBuffer);
+            mOutputBuffers.removeAt(0);
+        }
+    }
+    //flush finished.
+    return;
+}
diff --git a/ISV/base/isv_worker.cpp b/ISV/base/isv_worker.cpp
new file mode 100644
index 0000000..bee3536
--- /dev/null
+++ b/ISV/base/isv_worker.cpp
@@ -0,0 +1,1005 @@
+/*
+ * Copyright (C) 2012 Intel Corporation.  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.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+#include <cutils/properties.h>
+#include <system/graphics.h>
+#include "isv_worker.h"
+#ifndef TARGET_VPP_USE_GEN
+#include <hal_public.h>
+#else
+#include <ufo/graphics.h>
+#endif
+
+//#define LOG_NDEBUG 0
+#undef LOG_TAG
+#define LOG_TAG "isv-omxil"
+
+#define CHECK_VASTATUS(str) \
+    do { \
+        if (vaStatus != VA_STATUS_SUCCESS) { \
+                ALOGE("%s failed\n", str); \
+                return STATUS_ERROR;}   \
+        }while(0);
+
+enum STRENGTH {
+    STRENGTH_LOW = 0,
+    STRENGTH_MEDIUM,
+    STRENGTH_HIGH
+};
+
+#define DENOISE_DEBLOCK_STRENGTH STRENGTH_MEDIUM
+#define COLOR_STRENGTH STRENGTH_MEDIUM
+#ifdef TARGET_VPP_USE_GEN
+#define COLOR_NUM 4
+#else
+#define COLOR_NUM 2
+#endif
+
+#define MAX_FRC_OUTPUT 4 /*for frcx4*/
+
+using namespace android;
+
+ISVWorker::ISVWorker()
+    :mNumForwardReferences(0),
+    mVAContext(VA_INVALID_ID),
+    mWidth(0), mHeight(0),
+    mDisplay(NULL), mVADisplay(NULL),
+    mVAConfig(VA_INVALID_ID),
+    mForwardReferences(NULL),
+    mPrevInput(0), mPrevOutput(0),
+    mNumFilterBuffers(0),
+    mFilterFrc(VA_INVALID_ID), mFilters(0),
+    mInputIndex(0), mOutputIndex(0),
+    mOutputCount(0) {
+    memset(&mFilterBuffers, VA_INVALID_ID, VAProcFilterCount * sizeof(VABufferID));
+    memset(&mFilterParam, 0, sizeof(mFilterParam));
+}
+
+bool ISVWorker::isSupport() const {
+    bool support = false;
+
+    int num_entrypoints = vaMaxNumEntrypoints(mVADisplay);
+    VAEntrypoint * entrypoints = (VAEntrypoint *)malloc(num_entrypoints * sizeof(VAEntrypoint));
+    if (entrypoints == NULL) {
+        ALOGE("failed to malloc entrypoints array\n");
+        return false;
+    }
+
+    // check if it contains VPP entry point VAEntrypointVideoProc
+    VAStatus vaStatus = vaQueryConfigEntrypoints(mVADisplay, VAProfileNone, entrypoints, &num_entrypoints);
+    if (vaStatus != VA_STATUS_SUCCESS) {
+        ALOGE("vaQueryConfigEntrypoints failed");
+        return false;
+    }
+    for (int i = 0; !support && i < num_entrypoints; i++) {
+        support = entrypoints[i] == VAEntrypointVideoProc;
+    }
+    free(entrypoints);
+    entrypoints = NULL;
+
+    return support;
+}
+
+uint32_t ISVWorker::getProcBufCount() {
+    return getOutputBufCount(mInputIndex);
+}
+
+uint32_t ISVWorker::getFillBufCount() {
+        return getOutputBufCount(mOutputIndex);
+}
+
+uint32_t ISVWorker::getOutputBufCount(uint32_t index) {
+    uint32_t bufCount = 1;
+    if (((mFilters & FilterFrameRateConversion) != 0)
+            && index > 0)
+            bufCount = mFilterParam.frcRate - (((mFilterParam.frcRate == FRC_RATE_2_5X) ? (index & 1): 0));
+    return bufCount;
+}
+
+
+status_t ISVWorker::init(uint32_t width, uint32_t height) {
+    ALOGV("init");
+
+    if (mDisplay != NULL) {
+        ALOGE("VA is particially started");
+        return STATUS_ERROR;
+    }
+    mDisplay = new Display;
+    *mDisplay = ANDROID_DISPLAY_HANDLE;
+
+    mVADisplay = vaGetDisplay(mDisplay);
+    if (mVADisplay == NULL) {
+        ALOGE("vaGetDisplay failed");
+        return STATUS_ERROR;
+    }
+
+    int majorVersion, minorVersion;
+    VAStatus vaStatus = vaInitialize(mVADisplay, &majorVersion, &minorVersion);
+    CHECK_VASTATUS("vaInitialize");
+
+    // Check if VPP entry point is supported
+    if (!isSupport()) {
+        ALOGE("VPP is not supported on current platform");
+        return STATUS_NOT_SUPPORT;
+    }
+
+    // Find out the format for the target
+    VAConfigAttrib attrib;
+    attrib.type = VAConfigAttribRTFormat;
+    vaStatus = vaGetConfigAttributes(mVADisplay, VAProfileNone, VAEntrypointVideoProc, &attrib, 1);
+    CHECK_VASTATUS("vaGetConfigAttributes");
+
+    if ((attrib.value & VA_RT_FORMAT_YUV420) == 0) {
+        ALOGE("attribute is %x vs wanted %x", attrib.value, VA_RT_FORMAT_YUV420);
+        return STATUS_NOT_SUPPORT;
+    }
+
+    ALOGV("ready to create config");
+    // Create the configuration
+    vaStatus = vaCreateConfig(mVADisplay, VAProfileNone, VAEntrypointVideoProc, &attrib, 1, &mVAConfig);
+    CHECK_VASTATUS("vaCreateConfig");
+
+
+    // Create Context
+    ALOGV("ready to create context");
+    mWidth = width;
+    mHeight = height;
+    vaStatus = vaCreateContext(mVADisplay, mVAConfig, mWidth, mHeight, 0, NULL, 0, &mVAContext);
+    CHECK_VASTATUS("vaCreateContext");
+
+    ALOGV("VA has been successfully started");
+    return STATUS_OK;
+}
+
+status_t ISVWorker::deinit() {
+    {
+        Mutex::Autolock autoLock(mPipelineBufferLock);
+        while (!mPipelineBuffers.isEmpty()) {
+            VABufferID pipelineBuffer = mPipelineBuffers.itemAt(0);
+            if (VA_STATUS_SUCCESS != vaDestroyBuffer(mVADisplay, pipelineBuffer))
+                ALOGW("%s: failed to destroy va buffer id %d", __func__, pipelineBuffer);
+            mPipelineBuffers.removeAt(0);
+        }
+    }
+
+    if (mNumFilterBuffers != 0) {
+        for (uint32_t i = 0; i < mNumFilterBuffers; i++) {
+            if(VA_STATUS_SUCCESS != vaDestroyBuffer(mVADisplay, mFilterBuffers[i]))
+                ALOGW("%s: failed to destroy va buffer id %d", __func__, mFilterBuffers[i]);
+        }
+        mNumFilterBuffers = 0;
+        memset(&mFilterBuffers, VA_INVALID_ID, VAProcFilterCount * sizeof(VABufferID));
+        mFilterFrc = VA_INVALID_ID;
+    }
+
+    if (mForwardReferences != NULL) {
+        free(mForwardReferences);
+        mForwardReferences = NULL;
+        mNumForwardReferences = 0;
+    }
+
+    if (mVAContext != VA_INVALID_ID) {
+         vaDestroyContext(mVADisplay, mVAContext);
+         mVAContext = VA_INVALID_ID;
+    }
+
+    if (mVAConfig != VA_INVALID_ID) {
+        vaDestroyConfig(mVADisplay, mVAConfig);
+        mVAConfig = VA_INVALID_ID;
+    }
+
+    if (mVADisplay) {
+        vaTerminate(mVADisplay);
+        mVADisplay = NULL;
+    }
+
+    if (mDisplay) {
+        delete mDisplay;
+        mDisplay = NULL;
+    }
+
+    return STATUS_OK;
+}
+
+status_t ISVWorker::allocSurface(uint32_t* width, uint32_t* height,
+        uint32_t stride, uint32_t format, uint32_t handle, int32_t* surfaceId)
+{
+    if (mWidth == 0 || mHeight == 0) {
+        ALOGE("%s: isv worker has not been initialized.", __func__);
+        return STATUS_ERROR;
+    }
+
+#ifndef TARGET_VPP_USE_GEN
+    *width = mWidth;
+    *height = mHeight;
+#endif
+    // Create VASurfaces
+    VASurfaceAttrib attribs[3];
+    VASurfaceAttribExternalBuffers vaExtBuf;
+
+    memset(&vaExtBuf, 0, sizeof(VASurfaceAttribExternalBuffers));
+    switch(format) {
+        case HAL_PIXEL_FORMAT_YV12:
+            vaExtBuf.pixel_format = VA_FOURCC_YV12;
+            vaExtBuf.num_planes = 3;
+            vaExtBuf.pitches[0] = stride;
+            vaExtBuf.pitches[1] = stride / 2;
+            vaExtBuf.pitches[2] = stride / 2;
+            vaExtBuf.pitches[3] = 0;
+            vaExtBuf.offsets[0] = 0;
+            vaExtBuf.offsets[1] = stride * *height;
+            vaExtBuf.offsets[2] = vaExtBuf.offsets[1] + (stride / 2) * (*height / 2);
+            vaExtBuf.offsets[3] = 0;
+            break;
+#ifdef TARGET_VPP_USE_GEN
+        case HAL_PIXEL_FORMAT_NV12_Y_TILED_INTEL:
+        case HAL_PIXEL_FORMAT_NV12_X_TILED_INTEL:
+        //it will be removed in future, it indicate the same format with HAL_PIXEL_FORMAT_NV12_Y_TILED_INTEL
+        case HAL_PIXEL_FORMAT_YUV420PackedSemiPlanar_Tiled_INTEL:
+#else
+        case HAL_PIXEL_FORMAT_NV12_VED:
+        case HAL_PIXEL_FORMAT_NV12_VEDT:
+#endif
+            vaExtBuf.pixel_format = VA_FOURCC_NV12;
+            vaExtBuf.num_planes = 2;
+            vaExtBuf.pitches[0] = stride;
+            vaExtBuf.pitches[1] = stride;
+            vaExtBuf.pitches[2] = 0;
+            vaExtBuf.pitches[3] = 0;
+            vaExtBuf.offsets[0] = 0;
+            vaExtBuf.offsets[1] = stride * *height;
+            vaExtBuf.offsets[2] = 0;
+            vaExtBuf.offsets[3] = 0;
+            break;
+        default:
+            ALOGE("%s: can't support this format 0x%08x", __func__, format);
+            return STATUS_ERROR;
+    }
+    vaExtBuf.width = *width;
+    vaExtBuf.height = *height;
+    vaExtBuf.data_size = stride * *height * 1.5;
+    vaExtBuf.num_buffers = 1;
+#ifndef TARGET_VPP_USE_GEN
+    if (format == HAL_PIXEL_FORMAT_NV12_VEDT) {
+        ALOGV("set TILING flag");
+        vaExtBuf.flags |= VA_SURFACE_EXTBUF_DESC_ENABLE_TILING;
+    }
+#endif
+    vaExtBuf.flags |= VA_SURFACE_ATTRIB_MEM_TYPE_ANDROID_GRALLOC;
+    vaExtBuf.buffers = (long unsigned int*)&handle;
+
+    attribs[0].type = (VASurfaceAttribType)VASurfaceAttribMemoryType;
+    attribs[0].flags = VA_SURFACE_ATTRIB_SETTABLE;
+    attribs[0].value.type = VAGenericValueTypeInteger;
+    attribs[0].value.value.i = VA_SURFACE_ATTRIB_MEM_TYPE_ANDROID_GRALLOC;
+
+    attribs[1].type = (VASurfaceAttribType)VASurfaceAttribExternalBufferDescriptor;
+    attribs[1].flags = VA_SURFACE_ATTRIB_SETTABLE;
+    attribs[1].value.type = VAGenericValueTypePointer;
+    attribs[1].value.value.p = &vaExtBuf;
+
+    attribs[2].type = (VASurfaceAttribType)VASurfaceAttribUsageHint;
+    attribs[2].flags = VA_SURFACE_ATTRIB_SETTABLE;
+    attribs[2].value.type = VAGenericValueTypeInteger;
+    attribs[2].value.value.i = VA_SURFACE_ATTRIB_USAGE_HINT_VPP_READ;
+
+    ALOGV("%s: Ext buffer: width %d, height %d, data_size %d, pitch %d", __func__,
+            vaExtBuf.width, vaExtBuf.height, vaExtBuf.data_size, vaExtBuf.pitches[0]);
+    VAStatus vaStatus = vaCreateSurfaces(mVADisplay, VA_RT_FORMAT_YUV420, vaExtBuf.width,
+                                 vaExtBuf.height, (VASurfaceID*)surfaceId, 1, attribs, 3);
+    CHECK_VASTATUS("vaCreateSurfaces");
+
+    return (vaStatus == VA_STATUS_SUCCESS) ? STATUS_OK : STATUS_ERROR;
+}
+
+status_t ISVWorker::freeSurface(int32_t* surfaceId)
+{
+    VAStatus vaStatus = VA_STATUS_SUCCESS;
+    vaDestroySurfaces(mVADisplay, (VASurfaceID*)surfaceId, 1);
+    CHECK_VASTATUS("vaDestroySurfaces");
+
+    return (vaStatus == VA_STATUS_SUCCESS) ? STATUS_OK : STATUS_ERROR;
+}
+
+status_t ISVWorker::configFilters(uint32_t filters,
+                                  const FilterParam* filterParam)
+{
+    status_t ret = STATUS_OK;
+
+    if (!filterParam) {
+        ALOGE("%s: invalid filterParam", __func__);
+        return STATUS_ERROR;
+    }
+
+    if (filters != 0) {
+        mFilterParam.srcWidth = filterParam->srcWidth;
+        mFilterParam.srcHeight = filterParam->srcHeight;
+        mFilterParam.dstWidth = filterParam->dstWidth;
+        mFilterParam.dstHeight = filterParam->dstHeight;
+        mFilterParam.frameRate = filterParam->frameRate;
+        mFilterParam.frcRate = filterParam->frcRate;
+    }
+
+    if (mFilters != filters) {
+        mFilters = filters;
+        ALOGI("%s: mFilters 0x%x, fps %d, frc rate %d", __func__, mFilters, mFilterParam.frameRate, mFilterParam.frcRate);
+        ret = setupFilters();
+    }
+
+    return ret;
+}
+
+bool ISVWorker::isFpsSupport(int32_t fps, int32_t *fpsSet, int32_t fpsSetCnt) {
+    bool ret = false;
+    for (int32_t i = 0; i < fpsSetCnt; i++) {
+        if (fps == fpsSet[i]) {
+            ret = true;
+            break;
+        }
+    }
+
+    return ret;
+}
+
+status_t ISVWorker::setupFilters() {
+    ALOGV("setupFilters");
+    VAProcFilterParameterBuffer deblock, denoise, sharpen;
+    VAProcFilterParameterBufferDeinterlacing deint;
+    VAProcFilterParameterBufferColorBalance color[COLOR_NUM];
+    VAProcFilterParameterBufferFrameRateConversion frc;
+    VABufferID deblockId, denoiseId, deintId, sharpenId, colorId, frcId;
+    uint32_t numCaps;
+    VAProcFilterCap deblockCaps, denoiseCaps, sharpenCaps, frcCaps;
+    VAProcFilterCapDeinterlacing deinterlacingCaps[VAProcDeinterlacingCount];
+    VAProcFilterCapColorBalance colorCaps[COLOR_NUM];
+    VAStatus vaStatus;
+    uint32_t numSupportedFilters = VAProcFilterCount;
+    VAProcFilterType supportedFilters[VAProcFilterCount];
+
+    if (mNumFilterBuffers != 0) {
+        for (uint32_t i = 0; i < mNumFilterBuffers; i++) {
+            if (VA_STATUS_SUCCESS != vaDestroyBuffer(mVADisplay, mFilterBuffers[i]))
+                ALOGW("%s: failed to destroy va buffer %d", __func__, mFilterBuffers[i]);
+                //return STATUS_ERROR;
+        }
+        memset(&mFilterBuffers, VA_INVALID_ID, VAProcFilterCount * sizeof(VABufferID));
+        mFilterFrc = VA_INVALID_ID;
+        mNumFilterBuffers = 0;
+    }
+
+    // query supported filters
+    vaStatus = vaQueryVideoProcFilters(mVADisplay, mVAContext, supportedFilters, &numSupportedFilters);
+    CHECK_VASTATUS("vaQueryVideoProcFilters");
+
+    // create filter buffer for each filter
+    for (uint32_t i = 0; i < numSupportedFilters; i++) {
+        switch (supportedFilters[i]) {
+            case VAProcFilterDeblocking:
+                if ((mFilters & FilterDeblocking) != 0) {
+                    // check filter caps
+                    numCaps = 1;
+                    vaStatus = vaQueryVideoProcFilterCaps(mVADisplay, mVAContext,
+                            VAProcFilterDeblocking,
+                            &deblockCaps,
+                            &numCaps);
+                    CHECK_VASTATUS("vaQueryVideoProcFilterCaps for deblocking");
+                    // create parameter buffer
+                    deblock.type = VAProcFilterDeblocking;
+                    deblock.value = deblockCaps.range.min_value + DENOISE_DEBLOCK_STRENGTH * deblockCaps.range.step;
+                    vaStatus = vaCreateBuffer(mVADisplay, mVAContext,
+                        VAProcFilterParameterBufferType, sizeof(deblock), 1,
+                        &deblock, &deblockId);
+                    CHECK_VASTATUS("vaCreateBuffer for deblocking");
+                    mFilterBuffers[mNumFilterBuffers] = deblockId;
+                    mNumFilterBuffers++;
+                }
+                break;
+            case VAProcFilterNoiseReduction:
+                if((mFilters & FilterNoiseReduction) != 0) {
+                    // check filter caps
+                    numCaps = 1;
+                    vaStatus = vaQueryVideoProcFilterCaps(mVADisplay, mVAContext,
+                            VAProcFilterNoiseReduction,
+                            &denoiseCaps,
+                            &numCaps);
+                    CHECK_VASTATUS("vaQueryVideoProcFilterCaps for denoising");
+                    // create parameter buffer
+                    denoise.type = VAProcFilterNoiseReduction;
+#ifdef TARGET_VPP_USE_GEN
+                    char propValueString[PROPERTY_VALUE_MAX];
+
+                    // placeholder for vpg driver: can't support denoise factor auto adjust, so leave config to user.
+                    property_get("vpp.filter.denoise.factor", propValueString, "64.0");
+                    denoise.value = atof(propValueString);
+                    denoise.value = (denoise.value < 0.0f) ? 0.0f : denoise.value;
+                    denoise.value = (denoise.value > 64.0f) ? 64.0f : denoise.value;
+#else
+                    denoise.value = denoiseCaps.range.min_value + DENOISE_DEBLOCK_STRENGTH * denoiseCaps.range.step;
+#endif
+                    vaStatus = vaCreateBuffer(mVADisplay, mVAContext,
+                        VAProcFilterParameterBufferType, sizeof(denoise), 1,
+                        &denoise, &denoiseId);
+                    CHECK_VASTATUS("vaCreateBuffer for denoising");
+                    mFilterBuffers[mNumFilterBuffers] = denoiseId;
+                    mNumFilterBuffers++;
+                }
+                break;
+            case VAProcFilterDeinterlacing:
+                if ((mFilters & FilterDeinterlacing) != 0) {
+                    numCaps = VAProcDeinterlacingCount;
+                    vaStatus = vaQueryVideoProcFilterCaps(mVADisplay, mVAContext,
+                            VAProcFilterDeinterlacing,
+                            &deinterlacingCaps[0],
+                            &numCaps);
+                    CHECK_VASTATUS("vaQueryVideoProcFilterCaps for deinterlacing");
+                    for (uint32_t i = 0; i < numCaps; i++)
+                    {
+                        VAProcFilterCapDeinterlacing * const cap = &deinterlacingCaps[i];
+                        if (cap->type != VAProcDeinterlacingBob) // desired Deinterlacing Type
+                            continue;
+
+                        deint.type = VAProcFilterDeinterlacing;
+                        deint.algorithm = VAProcDeinterlacingBob;
+                        vaStatus = vaCreateBuffer(mVADisplay,
+                                mVAContext,
+                                VAProcFilterParameterBufferType,
+                                sizeof(deint), 1,
+                                &deint, &deintId);
+                        CHECK_VASTATUS("vaCreateBuffer for deinterlacing");
+                        mFilterBuffers[mNumFilterBuffers] = deintId;
+                        mNumFilterBuffers++;
+                    }
+                }
+                break;
+            case VAProcFilterSharpening:
+                if((mFilters & FilterSharpening) != 0) {
+                    // check filter caps
+                    numCaps = 1;
+                    vaStatus = vaQueryVideoProcFilterCaps(mVADisplay, mVAContext,
+                            VAProcFilterSharpening,
+                            &sharpenCaps,
+                            &numCaps);
+                    CHECK_VASTATUS("vaQueryVideoProcFilterCaps for sharpening");
+                    // create parameter buffer
+                    sharpen.type = VAProcFilterSharpening;
+#ifdef TARGET_VPP_USE_GEN
+                    char propValueString[PROPERTY_VALUE_MAX];
+
+                    // placeholder for vpg driver: can't support sharpness factor auto adjust, so leave config to user.
+                    property_get("vpp.filter.sharpen.factor", propValueString, "10.0");
+                    sharpen.value = atof(propValueString);
+                    sharpen.value = (sharpen.value < 0.0f) ? 0.0f : sharpen.value;
+                    sharpen.value = (sharpen.value > 64.0f) ? 64.0f : sharpen.value;
+#else
+                    sharpen.value = sharpenCaps.range.default_value;
+#endif
+                    vaStatus = vaCreateBuffer(mVADisplay, mVAContext,
+                        VAProcFilterParameterBufferType, sizeof(sharpen), 1,
+                        &sharpen, &sharpenId);
+                    CHECK_VASTATUS("vaCreateBuffer for sharpening");
+                    mFilterBuffers[mNumFilterBuffers] = sharpenId;
+                    mNumFilterBuffers++;
+                }
+                break;
+            case VAProcFilterColorBalance:
+                if((mFilters & FilterColorBalance) != 0) {
+                    uint32_t featureCount = 0;
+                    // check filter caps
+                    // FIXME: it's not used at all!
+                    numCaps = COLOR_NUM;
+                    vaStatus = vaQueryVideoProcFilterCaps(mVADisplay, mVAContext,
+                            VAProcFilterColorBalance,
+                            colorCaps,
+                            &numCaps);
+                    CHECK_VASTATUS("vaQueryVideoProcFilterCaps for color balance");
+                    // create parameter buffer
+                    for (uint32_t i = 0; i < numCaps; i++) {
+                        if (colorCaps[i].type == VAProcColorBalanceAutoSaturation) {
+                            color[i].type = VAProcFilterColorBalance;
+                            color[i].attrib = VAProcColorBalanceAutoSaturation;
+                            color[i].value = colorCaps[i].range.min_value + COLOR_STRENGTH * colorCaps[i].range.step;
+                            featureCount++;
+                        }
+                        else if (colorCaps[i].type == VAProcColorBalanceAutoBrightness) {
+                            color[i].type = VAProcFilterColorBalance;
+                            color[i].attrib = VAProcColorBalanceAutoBrightness;
+                            color[i].value = colorCaps[i].range.min_value + COLOR_STRENGTH * colorCaps[i].range.step;
+                            featureCount++;
+                        }
+                    }
+#ifdef TARGET_VPP_USE_GEN
+                    //TODO: VPG need to support check input value by colorCaps.
+                    enum {kHue = 0, kSaturation, kBrightness, kContrast};
+                    char propValueString[PROPERTY_VALUE_MAX];
+                    color[kHue].type = VAProcFilterColorBalance;
+                    color[kHue].attrib = VAProcColorBalanceHue;
+
+                    // placeholder for vpg driver: can't support auto color balance, so leave config to user.
+                    property_get("vpp.filter.procamp.hue", propValueString, "179.0");
+                    color[kHue].value = atof(propValueString);
+                    color[kHue].value = (color[kHue].value < -180.0f) ? -180.0f : color[kHue].value;
+                    color[kHue].value = (color[kHue].value > 180.0f) ? 180.0f : color[kHue].value;
+                    featureCount++;
+
+                    color[kSaturation].type   = VAProcFilterColorBalance;
+                    color[kSaturation].attrib = VAProcColorBalanceSaturation;
+                    property_get("vpp.filter.procamp.saturation", propValueString, "1.0");
+                    color[kSaturation].value = atof(propValueString);
+                    color[kSaturation].value = (color[kSaturation].value < 0.0f) ? 0.0f : color[kSaturation].value;
+                    color[kSaturation].value = (color[kSaturation].value > 10.0f) ? 10.0f : color[kSaturation].value;
+                    featureCount++;
+
+                    color[kBrightness].type   = VAProcFilterColorBalance;
+                    color[kBrightness].attrib = VAProcColorBalanceBrightness;
+                    property_get("vpp.filter.procamp.brightness", propValueString, "0.0");
+                    color[kBrightness].value = atof(propValueString);
+                    color[kBrightness].value = (color[kBrightness].value < -100.0f) ? -100.0f : color[kBrightness].value;
+                    color[kBrightness].value = (color[kBrightness].value > 100.0f) ? 100.0f : color[kBrightness].value;
+                    featureCount++;
+
+                    color[kContrast].type   = VAProcFilterColorBalance;
+                    color[kContrast].attrib = VAProcColorBalanceContrast;
+                    property_get("vpp.filter.procamp.contrast", propValueString, "1.0");
+                    color[kContrast].value = atof(propValueString);
+                    color[kContrast].value = (color[kContrast].value < 0.0f) ? 0.0f : color[kContrast].value;
+                    color[kContrast].value = (color[kContrast].value > 10.0f) ? 10.0f : color[kContrast].value;
+                    featureCount++;
+#endif
+                    vaStatus = vaCreateBuffer(mVADisplay, mVAContext,
+                        VAProcFilterParameterBufferType, sizeof(*color), featureCount,
+                        color, &colorId);
+                    CHECK_VASTATUS("vaCreateBuffer for color balance");
+                    mFilterBuffers[mNumFilterBuffers] = colorId;
+                    mNumFilterBuffers++;
+                }
+                break;
+            case VAProcFilterFrameRateConversion:
+                if((mFilters & FilterFrameRateConversion) != 0) {
+                    frc.type = VAProcFilterFrameRateConversion;
+                    frc.input_fps = mFilterParam.frameRate;
+                    switch (mFilterParam.frcRate){
+                        case FRC_RATE_1X:
+                            frc.output_fps = frc.input_fps;
+                            break;
+                        case FRC_RATE_2X:
+                            frc.output_fps = frc.input_fps * 2;
+                            break;
+                        case FRC_RATE_2_5X:
+                            frc.output_fps = frc.input_fps * 5/2;
+                            break;
+                        case FRC_RATE_4X:
+                            frc.output_fps = frc.input_fps * 4;
+                            break;
+                    }
+                    vaStatus = vaCreateBuffer(mVADisplay, mVAContext,
+                        VAProcFilterParameterBufferType, sizeof(frc), 1,
+                        &frc, &frcId);
+                    CHECK_VASTATUS("vaCreateBuffer for frc");
+                    mFilterBuffers[mNumFilterBuffers] = frcId;
+                    mNumFilterBuffers++;
+                    mFilterFrc = frcId;
+                }
+                break;
+            default:
+                ALOGE("Not supported filter\n");
+                break;
+        }
+    }
+
+    return setupPipelineCaps();
+}
+
+status_t ISVWorker::setupPipelineCaps() {
+    ALOGV("setupPipelineCaps");
+    //TODO color standards
+    VAProcPipelineCaps pipelineCaps;
+    VAStatus vaStatus;
+    pipelineCaps.input_color_standards = in_color_standards;
+    pipelineCaps.num_input_color_standards = VAProcColorStandardCount;
+    pipelineCaps.output_color_standards = out_color_standards;
+    pipelineCaps.num_output_color_standards = VAProcColorStandardCount;
+
+    vaStatus = vaQueryVideoProcPipelineCaps(mVADisplay, mVAContext,
+        mFilterBuffers, mNumFilterBuffers,
+        &pipelineCaps);
+    CHECK_VASTATUS("vaQueryVideoProcPipelineCaps");
+
+    if (mForwardReferences != NULL) {
+        free(mForwardReferences);
+        mForwardReferences = NULL;
+        mNumForwardReferences = 0;
+    }
+
+    mNumForwardReferences = pipelineCaps.num_forward_references;
+    if (mNumForwardReferences > 0) {
+        mForwardReferences = (VASurfaceID*)malloc(mNumForwardReferences * sizeof(VASurfaceID));
+        if (mForwardReferences == NULL)
+            return STATUS_ALLOCATION_ERROR;
+        memset(mForwardReferences, 0, mNumForwardReferences * sizeof(VASurfaceID));
+    }
+    return STATUS_OK;
+}
+
+status_t ISVWorker::process(ISVBuffer* inputBuffer, Vector<ISVBuffer*> outputBuffer,
+                             uint32_t outputCount, bool isEOS, uint32_t flags) {
+    ALOGV("process: outputCount=%d, mInputIndex=%d", outputCount, mInputIndex);
+    VASurfaceID input;
+    VASurfaceID output[MAX_FRC_OUTPUT];
+    VABufferID pipelineId;
+    VAProcPipelineParameterBuffer *pipeline;
+    VAProcFilterParameterBufferFrameRateConversion *frc;
+    VAStatus vaStatus;
+    uint32_t i;
+
+    if (mFilters == 0) {
+        ALOGE("%s: filters have not been initialized.", __func__);
+        return STATUS_ERROR;
+    }
+
+    if (outputCount < 1) {
+       ALOGE("invalid outputCount");
+       return STATUS_ERROR;
+    }
+
+    if (inputBuffer == NULL)
+        input = VA_INVALID_SURFACE;
+    else
+        input = inputBuffer->getSurface();
+
+    if (input == VA_INVALID_SURFACE && !isEOS) {
+        ALOGE("invalid input buffer");
+        return STATUS_ERROR;
+    }
+    for (i = 0; i < outputCount; i++) {
+        output[i] = outputBuffer[i]->getSurface();
+        if (output[i] == VA_INVALID_SURFACE) {
+            ALOGE("invalid output buffer");
+            return STATUS_ERROR;
+        }
+    }
+
+    // reference frames setting
+    if (mNumForwardReferences > 0) {
+        /* add previous frame into reference array*/
+        for (i = 1; i < mNumForwardReferences; i++) {
+            mForwardReferences[i - 1] = mForwardReferences[i];
+        }
+
+        //make last reference to input
+        mForwardReferences[mNumForwardReferences - 1] = mPrevInput;
+    }
+
+    mPrevInput = input;
+
+    // create pipeline parameter buffer
+    vaStatus = vaCreateBuffer(mVADisplay,
+            mVAContext,
+            VAProcPipelineParameterBufferType,
+            sizeof(VAProcPipelineParameterBuffer),
+            1,
+            NULL,
+            &pipelineId);
+    CHECK_VASTATUS("vaCreateBuffer for VAProcPipelineParameterBufferType");
+
+    ALOGV("before vaBeginPicture");
+    vaStatus = vaBeginPicture(mVADisplay, mVAContext, output[0]);
+    CHECK_VASTATUS("vaBeginPicture");
+
+    // map pipeline paramter buffer
+    vaStatus = vaMapBuffer(mVADisplay, pipelineId, (void**)&pipeline);
+    CHECK_VASTATUS("vaMapBuffer for pipeline parameter buffer");
+
+    // frc pamameter setting
+    if ((mFilters & FilterFrameRateConversion) != 0) {
+        vaStatus = vaMapBuffer(mVADisplay, mFilterFrc, (void **)&frc);
+        CHECK_VASTATUS("vaMapBuffer for frc parameter buffer");
+        if (isEOS)
+            frc->num_output_frames = 0;
+        else
+            frc->num_output_frames = outputCount - 1;
+        frc->output_frames = output + 1;
+    }
+
+    // pipeline parameter setting
+    VARectangle dst_region;
+    dst_region.x = 0;
+    dst_region.y = 0;
+    dst_region.width = mFilterParam.dstWidth;
+    dst_region.height = mFilterParam.dstHeight;
+
+    VARectangle src_region;
+    src_region.x = 0;
+    src_region.y = 0;
+    src_region.width = mFilterParam.srcWidth;
+    src_region.height = mFilterParam.srcHeight;
+
+    if (isEOS) {
+        pipeline->surface = 0;
+        pipeline->pipeline_flags = VA_PIPELINE_FLAG_END;
+    }
+    else {
+        pipeline->surface = input;
+        pipeline->pipeline_flags = 0;
+    }
+#ifdef TARGET_VPP_USE_GEN
+    pipeline->surface_region = &src_region;
+    pipeline->output_region = &dst_region;
+    pipeline->surface_color_standard = VAProcColorStandardBT601;
+    pipeline->output_color_standard = VAProcColorStandardBT601;
+#else
+    pipeline->surface_region = NULL;
+    pipeline->output_region = NULL;//&output_region;
+    pipeline->surface_color_standard = VAProcColorStandardNone;
+    pipeline->output_color_standard = VAProcColorStandardNone;
+    /* real rotate state will be decided in psb video */
+    pipeline->rotation_state = 0;
+#endif
+    /* FIXME: set more meaningful background color */
+    pipeline->output_background_color = 0;
+    pipeline->filters = mFilterBuffers;
+    pipeline->num_filters = mNumFilterBuffers;
+    pipeline->forward_references = mForwardReferences;
+    pipeline->num_forward_references = mNumForwardReferences;
+    pipeline->backward_references = NULL;
+    pipeline->num_backward_references = 0;
+
+    //currently, we only transfer TOP field to frame, no frame rate change.
+    if (flags & (OMX_BUFFERFLAG_TFF | OMX_BUFFERFLAG_BFF)) {
+        pipeline->filter_flags = VA_TOP_FIELD;
+    } else {
+        pipeline->filter_flags = VA_FRAME_PICTURE;
+    }
+
+    if ((mFilters & FilterFrameRateConversion) != 0) {
+        vaStatus = vaUnmapBuffer(mVADisplay, mFilterFrc);
+        CHECK_VASTATUS("vaUnmapBuffer for frc parameter buffer");
+    }
+
+    vaStatus = vaUnmapBuffer(mVADisplay, pipelineId);
+    CHECK_VASTATUS("vaUnmapBuffer for pipeline parameter buffer");
+
+    ALOGV("before vaRenderPicture");
+    // Send parameter to driver
+    vaStatus = vaRenderPicture(mVADisplay, mVAContext, &pipelineId, 1);
+    CHECK_VASTATUS("vaRenderPicture");
+
+    ALOGV("before vaEndPicture");
+    vaStatus = vaEndPicture(mVADisplay, mVAContext);
+    CHECK_VASTATUS("vaEndPicture");
+
+    if (isEOS) {
+        vaStatus = vaSyncSurface(mVADisplay, mPrevOutput);
+        CHECK_VASTATUS("vaSyncSurface");
+        if (VA_STATUS_SUCCESS != vaDestroyBuffer(mVADisplay, pipelineId)) {
+            ALOGE("%s: failed to destroy va buffer %d", __func__, pipelineId);
+            return STATUS_ERROR;
+        }
+        return STATUS_OK;
+    }
+
+    mPrevOutput = output[0];
+    mInputIndex++;
+
+    Mutex::Autolock autoLock(mPipelineBufferLock);
+    mPipelineBuffers.push_back(pipelineId);
+
+    ALOGV("process, exit");
+    return STATUS_OK;
+}
+
+status_t ISVWorker::fill(Vector<ISVBuffer*> outputBuffer, uint32_t outputCount) {
+    ALOGV("fill, outputCount=%d, mOutputIndex=%d",outputCount, mOutputIndex);
+    // get output surface
+    VASurfaceID output[MAX_FRC_OUTPUT];
+    VAStatus vaStatus;
+    VASurfaceStatus surStatus;
+
+    if (outputCount < 1)
+        return STATUS_ERROR;
+    // map GraphicBuffer to VASurface
+    for (uint32_t i = 0; i < outputCount; i++) {
+
+        output[i] = outputBuffer[i]->getSurface();
+        if (output[i] == VA_INVALID_SURFACE) {
+            ALOGE("invalid output buffer");
+            return STATUS_ERROR;
+        }
+        //FIXME: only enable sync mode
+#if 0
+        vaStatus = vaQuerySurfaceStatus(mVADisplay, output[i],&surStatus);
+        CHECK_VASTATUS("vaQuerySurfaceStatus");
+        if (surStatus == VASurfaceRendering) {
+            ALOGV("Rendering %d", i);
+            /* The behavior of driver is: all output of one process task are return in one interruption.
+               The whole outputs of one FRC task are all ready or none of them is ready.
+               If the behavior changed, it hurts the performance.
+            */
+            if (0 != i) {
+                ALOGW("*****Driver behavior changed. The performance is hurt.");
+                ALOGW("Please check driver behavior: all output of one task return in one interruption.");
+            }
+            vaStatus = STATUS_DATA_RENDERING;
+            break;
+        }
+
+        if ((surStatus != VASurfaceRendering) && (surStatus != VASurfaceReady)) {
+            ALOGE("surface statu Error %d", surStatus);
+            vaStatus = STATUS_ERROR;
+        }
+#endif
+        vaStatus = vaSyncSurface(mVADisplay, output[i]);
+        CHECK_VASTATUS("vaSyncSurface");
+        vaStatus = STATUS_OK;
+        mOutputCount++;
+        //dumpYUVFrameData(output[i]);
+    }
+
+    {
+        Mutex::Autolock autoLock(mPipelineBufferLock);
+        if (vaStatus == STATUS_OK) {
+            VABufferID pipelineBuffer = mPipelineBuffers.itemAt(0);
+            if (VA_STATUS_SUCCESS != vaDestroyBuffer(mVADisplay, pipelineBuffer)) {
+                ALOGE("%s: failed to destroy va buffer %d", __func__, pipelineBuffer);
+                return STATUS_ERROR;
+            }
+            mPipelineBuffers.removeAt(0);
+            mOutputIndex++;
+        }
+    }
+
+    ALOGV("fill, exit");
+    return vaStatus;
+}
+
+// Debug only
+#define FRAME_OUTPUT_FILE_NV12 "/storage/sdcard0/vpp_output.nv12"
+status_t ISVWorker::dumpYUVFrameData(VASurfaceID surfaceID) {
+    status_t ret;
+    if (surfaceID == VA_INVALID_SURFACE)
+        return STATUS_ERROR;
+
+    VAStatus vaStatus;
+    VAImage image;
+    unsigned char *data_ptr;
+
+    vaStatus = vaDeriveImage(mVADisplay,
+            surfaceID,
+            &image);
+    CHECK_VASTATUS("vaDeriveImage");
+
+    vaStatus = vaMapBuffer(mVADisplay, image.buf, (void **)&data_ptr);
+    CHECK_VASTATUS("vaMapBuffer");
+
+    ret = writeNV12(mFilterParam.srcWidth, mFilterParam.srcHeight, data_ptr, image.pitches[0], image.pitches[1]);
+    if (ret != STATUS_OK) {
+        ALOGV("writeNV12 error");
+        return STATUS_ERROR;
+    }
+
+    vaStatus = vaUnmapBuffer(mVADisplay, image.buf);
+    CHECK_VASTATUS("vaUnMapBuffer");
+
+    vaStatus = vaDestroyImage(mVADisplay,image.image_id);
+    CHECK_VASTATUS("vaDestroyImage");
+
+    return STATUS_OK;
+}
+
+status_t ISVWorker::reset() {
+    status_t ret;
+    ALOGI("reset");
+    ALOGI("======mVPPInputCount=%d, mVPPRenderCount=%d======",
+            mInputIndex, mOutputCount);
+    mInputIndex = 0;
+    mOutputIndex = 0;
+    mOutputCount = 0;
+
+    {
+        Mutex::Autolock autoLock(mPipelineBufferLock);
+        while (!mPipelineBuffers.isEmpty()) {
+            VABufferID pipelineBuffer = mPipelineBuffers.itemAt(0);
+            if (VA_STATUS_SUCCESS != vaDestroyBuffer(mVADisplay, pipelineBuffer)) {
+                ALOGE("%s: failed to destroy va buffer %d", __func__, pipelineBuffer);
+                return STATUS_ERROR;
+            }
+            mPipelineBuffers.removeAt(0);
+        }
+    }
+
+    if (mNumFilterBuffers != 0) {
+        for (uint32_t i = 0; i < mNumFilterBuffers; i++) {
+            if (VA_STATUS_SUCCESS != vaDestroyBuffer(mVADisplay, mFilterBuffers[i]))
+                ALOGW("%s: failed to destroy va buffer %d", __func__, mFilterBuffers[i]);
+                //return STATUS_ERROR;
+        }
+        mNumFilterBuffers = 0;
+        memset(&mFilterBuffers, VA_INVALID_ID, VAProcFilterCount * sizeof(VABufferID));
+        mFilterFrc = VA_INVALID_ID;
+    }
+
+    // we need to clear the cache for reference surfaces
+    if (mForwardReferences != NULL) {
+        free(mForwardReferences);
+        mForwardReferences = NULL;
+        mNumForwardReferences = 0;
+    }
+
+    if (mVAContext != VA_INVALID_ID) {
+         vaDestroyContext(mVADisplay, mVAContext);
+         mVAContext = VA_INVALID_ID;
+    }
+    VAStatus vaStatus = vaCreateContext(mVADisplay, mVAConfig, mWidth, mHeight, 0, NULL, 0, &mVAContext);
+    CHECK_VASTATUS("vaCreateContext");
+
+    return setupFilters();
+}
+
+uint32_t ISVWorker::getVppOutputFps() {
+    uint32_t outputFps;
+    //mFilterParam.frcRate is 1 if FRC is disabled or input FPS is not changed by VPP.
+    if (FRC_RATE_2_5X == mFilterParam.frcRate) {
+        outputFps = mFilterParam.frameRate * 5 / 2;
+    } else {
+        outputFps = mFilterParam.frameRate * mFilterParam.frcRate;
+    }
+
+    ALOGV("vpp is on in settings %d %d %d", outputFps,  mFilterParam.frameRate, mFilterParam.frcRate);
+    return outputFps;
+}
+
+
+status_t ISVWorker::writeNV12(int width, int height, unsigned char *out_buf, int y_pitch, int uv_pitch) {
+    size_t result;
+    int frame_size;
+    unsigned char *y_start, *uv_start;
+    int h;
+
+    FILE *ofile = fopen(FRAME_OUTPUT_FILE_NV12, "ab");
+    if(ofile == NULL) {
+        ALOGE("Open %s failed!", FRAME_OUTPUT_FILE_NV12);
+        return STATUS_ERROR;
+    }
+
+    if (out_buf == NULL)
+    {
+        fclose(ofile);
+        return STATUS_ERROR;
+    }
+    if ((width % 2) || (height % 2))
+    {
+        fclose(ofile);
+        return STATUS_ERROR;
+    }
+    // Set frame size
+    frame_size = height * width * 3/2;
+
+    /* write y */
+    y_start = out_buf;
+    for (h = 0; h < height; ++h) {
+        result = fwrite(y_start, sizeof(unsigned char), width, ofile);
+        y_start += y_pitch;
+    }
+
+    /* write uv */
+    uv_start = out_buf + uv_pitch * height;
+    for (h = 0; h < height / 2; ++h) {
+        result = fwrite(uv_start, sizeof(unsigned char), width, ofile);
+        uv_start += uv_pitch;
+    }
+    // Close file
+    fclose(ofile);
+    return STATUS_OK;
+}
diff --git a/ISV/include/isv_bufmanager.h b/ISV/include/isv_bufmanager.h
new file mode 100644
index 0000000..3a0df06
--- /dev/null
+++ b/ISV/include/isv_bufmanager.h
@@ -0,0 +1,150 @@
+/*
+ * Copyright (C) 2012 Intel Corporation.  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.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef __ISV_BUFMANAGER_H
+#define __ISV_BUFMANAGER_H
+
+#include <utils/RefBase.h>
+#include <utils/Mutex.h>
+#include <utils/Errors.h>
+#include <utils/Vector.h>
+#include "isv_worker.h"
+
+using namespace android;
+
+#define ISV_BUFFER_MANAGER_DEBUG 0
+
+class ISVWorker;
+
+class ISVBuffer
+{
+public:
+    typedef enum {
+        ISV_BUFFER_GRALLOC,
+        ISV_BUFFER_METADATA,
+    } ISV_BUFFERTYPE;
+private:
+    //FIX ME: copy from ufo gralloc.h
+    typedef struct _ufo_buffer_details_t
+    {
+        int width;       // \see alloc_device_t::alloc
+        int height;      // \see alloc_device_t::alloc
+        int format;      // \see alloc_device_t::alloc
+        int usage;       // \see alloc_device_t::alloc
+        int name;        // flink
+        uint32_t fb;     // framebuffer id
+        int drmformat;   // drm format
+        int pitch;       // buffer pitch (in bytes)
+        int size;        // buffer size (in bytes)
+        int allocWidth;  // allocated buffer width in pixels.
+        int allocHeight; // allocated buffer height in lines.
+        int allocOffsetX;// horizontal pixel offset to content origin within allocated buffer.
+        int allocOffsetY;// vertical line offset to content origin within allocated buffer.
+    } ufo_buffer_details_t;
+
+    enum
+    {
+        INTEL_UFO_GRALLOC_MODULE_PERFORM_GET_BO_INFO = 6 // (buffer_handle_t, buffer_info_t*)
+    };
+
+public:
+    ISVBuffer(sp<ISVWorker> worker,
+            uint32_t buffer, uint32_t grallocHandle,
+            uint32_t width, uint32_t height,
+            uint32_t stride, uint32_t colorFormat,
+            ISV_BUFFERTYPE type)
+        :mWorker(worker),
+        mBuffer(buffer),
+        mGrallocHandle(grallocHandle),
+        mWidth(width),
+        mHeight(height),
+        mStride(stride),
+        mColorFormat(colorFormat),
+        mType(type),
+        mSurface(-1) {}
+
+    ISVBuffer(sp<ISVWorker> worker,
+            uint32_t buffer,
+            ISV_BUFFERTYPE type)
+        :mWorker(worker),
+        mBuffer(buffer),
+        mGrallocHandle(0),
+        mWidth(0),
+        mHeight(0),
+        mStride(0),
+        mColorFormat(0),
+        mType(type),
+        mSurface(-1) {}
+
+    ~ISVBuffer();
+
+    // init buffer info
+    status_t initBufferInfo();
+
+    // get va surface
+    uint32_t getSurface() { return mSurface; }
+    // get buffer handle
+    uint32_t getHandle() { return mBuffer; }
+
+private:
+    sp<ISVWorker> mWorker;
+    uint32_t mBuffer;
+    uint32_t mGrallocHandle;
+    uint32_t mWidth;
+    uint32_t mHeight;
+    uint32_t mStride;
+    uint32_t mColorFormat;
+    ISV_BUFFERTYPE mType;
+    int32_t mSurface;
+};
+
+class ISVBufferManager: public RefBase
+{
+public:
+    ISVBufferManager()
+        :mWorker(NULL),
+        mMetaDataMode(false) {}
+
+    ~ISVBufferManager() {}
+    // set mBuffers size
+    status_t setBufferCount(int32_t size);
+
+    // register/unregister ISVBuffers to mBuffers
+    status_t useBuffer(const sp<ANativeWindowBuffer> nativeBuffer);
+    status_t useBuffer(uint32_t handle);
+    status_t freeBuffer(uint32_t handle);
+
+    // Map to ISVBuffer
+    ISVBuffer* mapBuffer(uint32_t handle);
+    // set isv worker
+    void setWorker(sp<ISVWorker> worker) { mWorker = worker; }
+    void setMetaDataMode(bool metaDataMode) { mMetaDataMode = metaDataMode; }
+private:
+    typedef enum {
+        GRALLOC_BUFFER_MODE = 0,
+        META_DATA_MODE = 1,
+    } ISV_WORK_MODE;
+
+    sp<ISVWorker> mWorker;
+    bool mMetaDataMode;
+    // VPP buffer queue
+    Vector<ISVBuffer*> mBuffers;
+    Mutex mBufferLock; // to protect access to mBuffers
+};
+
+
+#endif //#define __ISV_BUFMANAGER_H
diff --git a/ISV/include/isv_omxcomponent.h b/ISV/include/isv_omxcomponent.h
new file mode 100644
index 0000000..f3e2146
--- /dev/null
+++ b/ISV/include/isv_omxcomponent.h
@@ -0,0 +1,295 @@
+/*
+ * Copyright (C) 2012 Intel Corporation.  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.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+
+#ifndef ISV_OMXCOMPONENT_H_
+
+#define ISV_OMXCOMPONENT_H_
+
+#include <utils/Mutex.h>
+#include <utils/Vector.h>
+#include <utils/RefBase.h>
+#include "isv_omxcore.h"
+#include "isv_processor.h"
+#include "isv_profile.h"
+#include "isv_worker.h"
+#include "isv_bufmanager.h"
+
+#define ISV_COMPONENT_DEBUG 0
+
+#define MIN_INPUT_NUM           (6)    // forward reference frame number is 3 for merrifield/moorefield
+#define MIN_OUTPUT_NUM          (10)   // 2.5FRC need hold 2 + 3 + 2 + 3= 10 buffers, without FRC we set to 6
+#define DECODE_EXTRA_NUM        (9)    //?? i don't know
+#define MIN_ISV_BUFFER_NUM      ((MIN_OUTPUT_NUM) + (MIN_INPUT_NUM) + (DECODE_EXTRA_NUM))
+#define UNDEQUEUED_NUM          (4)   // display system hold 4 buffers
+
+#define SKIP_FRAME_NUM          (30)
+
+using namespace android;
+class ISVComponent;
+
+class ISVProcThreadObserver: public ISVProcessorObserver
+{
+public:
+    ISVProcThreadObserver(OMX_COMPONENTTYPE *pBaseComponent, OMX_COMPONENTTYPE *pComponent, OMX_CALLBACKTYPE *pCallBacks);
+    ~ISVProcThreadObserver();
+
+    virtual OMX_ERRORTYPE releaseBuffer(PORT_INDEX index, OMX_BUFFERHEADERTYPE* pBuffer, bool flush);
+private:
+    OMX_COMPONENTTYPE *mBaseComponent;
+    OMX_COMPONENTTYPE *mComponent;
+    OMX_CALLBACKTYPE *mpCallBacks;
+};
+
+class ISVComponent //: public RefBase
+{
+public:
+    /*
+     * construct & destruct
+     */
+    ISVComponent(OMX_PTR);
+    ~ISVComponent();
+
+    // replace component callbacks
+    OMX_CALLBACKTYPE *getCallBacks(OMX_CALLBACKTYPE*);
+    // pass down the real component&core
+    void setComponent(OMX_COMPONENTTYPE *pComp, ISVOMXCore *pCore){mComponent = pComp; mCore = pCore;return;}
+    // free the real component
+    OMX_ERRORTYPE freeComponent(){return (*(mCore->mFreeHandle))(static_cast<OMX_HANDLETYPE>(mComponent));}
+    // return ISV component handle
+    OMX_COMPONENTTYPE *getBaseComponent(){return &mBaseComponent;}
+
+    static Vector<ISVComponent*> g_isv_components;
+private:
+    /*
+     * component methods & helpers
+     */
+
+    static OMX_ERRORTYPE SendCommand(
+        OMX_IN  OMX_HANDLETYPE hComponent,
+        OMX_IN  OMX_COMMANDTYPE Cmd,
+        OMX_IN  OMX_U32 nParam1,
+        OMX_IN  OMX_PTR pCmdData);
+    OMX_ERRORTYPE ISV_SendCommand(
+        OMX_IN  OMX_COMMANDTYPE Cmd,
+        OMX_IN  OMX_U32 nParam1,
+        OMX_IN  OMX_PTR pCmdData);
+
+    static OMX_ERRORTYPE GetParameter(
+        OMX_IN  OMX_HANDLETYPE hComponent,
+        OMX_IN  OMX_INDEXTYPE nParamIndex,
+        OMX_INOUT OMX_PTR pComponentParameterStructure);
+    OMX_ERRORTYPE ISV_GetParameter(
+        OMX_IN  OMX_INDEXTYPE nParamIndex,
+        OMX_INOUT OMX_PTR pComponentParameterStructure);
+
+    static OMX_ERRORTYPE SetParameter(
+        OMX_IN  OMX_HANDLETYPE hComponent,
+        OMX_IN  OMX_INDEXTYPE nIndex,
+        OMX_IN  OMX_PTR pComponentParameterStructure);
+    OMX_ERRORTYPE ISV_SetParameter(
+        OMX_IN  OMX_INDEXTYPE nIndex,
+        OMX_IN  OMX_PTR pComponentParameterStructure);
+
+    static OMX_ERRORTYPE GetConfig(
+        OMX_IN  OMX_HANDLETYPE hComponent,
+        OMX_IN  OMX_INDEXTYPE nIndex,
+        OMX_INOUT OMX_PTR pComponentConfigStructure);
+    OMX_ERRORTYPE ISV_GetConfig(
+        OMX_IN  OMX_INDEXTYPE nIndex,
+        OMX_INOUT OMX_PTR pComponentConfigStructure);
+
+    static OMX_ERRORTYPE SetConfig(
+        OMX_IN  OMX_HANDLETYPE hComponent,
+        OMX_IN  OMX_INDEXTYPE nIndex,
+        OMX_IN  OMX_PTR pComponentConfigStructure);
+    OMX_ERRORTYPE ISV_SetConfig(
+        OMX_IN  OMX_INDEXTYPE nIndex,
+        OMX_IN  OMX_PTR pComponentConfigStructure);
+
+    static OMX_ERRORTYPE GetExtensionIndex(
+        OMX_IN  OMX_HANDLETYPE hComponent,
+        OMX_IN  OMX_STRING cParameterName,
+        OMX_OUT OMX_INDEXTYPE* pIndexType);
+    OMX_ERRORTYPE ISV_GetExtensionIndex(
+        OMX_IN  OMX_STRING cParameterName,
+        OMX_OUT OMX_INDEXTYPE* pIndexType);
+
+    static OMX_ERRORTYPE GetState(
+        OMX_IN  OMX_HANDLETYPE hComponent,
+        OMX_OUT OMX_STATETYPE* pState);
+    OMX_ERRORTYPE ISV_GetState(
+        OMX_OUT OMX_STATETYPE* pState);
+
+    static OMX_ERRORTYPE UseBuffer(
+        OMX_IN OMX_HANDLETYPE hComponent,
+        OMX_INOUT OMX_BUFFERHEADERTYPE** ppBufferHdr,
+        OMX_IN OMX_U32 nPortIndex,
+        OMX_IN OMX_PTR pAppPrivate,
+        OMX_IN OMX_U32 nSizeBytes,
+        OMX_IN OMX_U8* pBuffer);
+    OMX_ERRORTYPE ISV_UseBuffer(
+        OMX_INOUT OMX_BUFFERHEADERTYPE** ppBufferHdr,
+        OMX_IN OMX_U32 nPortIndex,
+        OMX_IN OMX_PTR pAppPrivate,
+        OMX_IN OMX_U32 nSizeBytes,
+        OMX_IN OMX_U8* pBuffer);
+
+    static OMX_ERRORTYPE AllocateBuffer(
+        OMX_IN OMX_HANDLETYPE hComponent,
+        OMX_INOUT OMX_BUFFERHEADERTYPE** ppBuffer,
+        OMX_IN OMX_U32 nPortIndex,
+        OMX_IN OMX_PTR pAppPrivate,
+        OMX_IN OMX_U32 nSizeBytes);
+    OMX_ERRORTYPE ISV_AllocateBuffer(
+        OMX_INOUT OMX_BUFFERHEADERTYPE** ppBuffer,
+        OMX_IN OMX_U32 nPortIndex,
+        OMX_IN OMX_PTR pAppPrivate,
+        OMX_IN OMX_U32 nSizeBytes);
+
+    static OMX_ERRORTYPE FreeBuffer(
+        OMX_IN  OMX_HANDLETYPE hComponent,
+        OMX_IN  OMX_U32 nPortIndex,
+        OMX_IN  OMX_BUFFERHEADERTYPE* pBuffer);
+    OMX_ERRORTYPE ISV_FreeBuffer(
+        OMX_IN  OMX_U32 nPortIndex,
+        OMX_IN  OMX_BUFFERHEADERTYPE* pBuffer);
+
+    static OMX_ERRORTYPE EmptyThisBuffer(
+        OMX_IN  OMX_HANDLETYPE hComponent,
+        OMX_IN  OMX_BUFFERHEADERTYPE* pBuffer);
+    OMX_ERRORTYPE ISV_EmptyThisBuffer(
+        OMX_IN  OMX_BUFFERHEADERTYPE* pBuffer);
+
+    static OMX_ERRORTYPE FillThisBuffer(
+        OMX_IN  OMX_HANDLETYPE hComponent,
+        OMX_IN  OMX_BUFFERHEADERTYPE* pBuffer);
+    OMX_ERRORTYPE ISV_FillThisBuffer(
+        OMX_IN  OMX_BUFFERHEADERTYPE* pBuffer);
+
+    static OMX_ERRORTYPE SetCallbacks(
+        OMX_IN  OMX_HANDLETYPE hComponent,
+        OMX_IN  OMX_CALLBACKTYPE* pCallbacks,
+        OMX_IN  OMX_PTR pAppData);
+    OMX_ERRORTYPE ISV_SetCallbacks(
+        OMX_IN  OMX_CALLBACKTYPE* pCallbacks,
+        OMX_IN  OMX_PTR pAppData);
+
+    static OMX_ERRORTYPE ComponentRoleEnum(
+        OMX_IN OMX_HANDLETYPE hComponent,
+        OMX_OUT OMX_U8 *cRole,
+        OMX_IN OMX_U32 nIndex);
+    OMX_ERRORTYPE ISV_ComponentRoleEnum(
+        OMX_OUT OMX_U8 *cRole,
+        OMX_IN OMX_U32 nIndex);
+
+    static OMX_ERRORTYPE FillBufferDone(
+        OMX_OUT OMX_HANDLETYPE hComponent,
+        OMX_OUT OMX_PTR pAppData,
+        OMX_OUT OMX_BUFFERHEADERTYPE* pBuffer);
+    OMX_ERRORTYPE ISV_FillBufferDone(
+        OMX_OUT OMX_HANDLETYPE hComponent,
+        OMX_OUT OMX_PTR pAppData,
+        OMX_OUT OMX_BUFFERHEADERTYPE* pBuffer);
+
+    static OMX_ERRORTYPE EventHandler(
+            OMX_IN OMX_HANDLETYPE hComponent,
+            OMX_IN OMX_PTR pAppData,
+            OMX_IN OMX_EVENTTYPE eEvent,
+            OMX_IN OMX_U32 nData1,
+            OMX_IN OMX_U32 nData2,
+            OMX_IN OMX_PTR pEventData);
+    OMX_ERRORTYPE ISV_EventHandler(
+            OMX_IN OMX_HANDLETYPE hComponent,
+            OMX_IN OMX_PTR pAppData,
+            OMX_IN OMX_EVENTTYPE eEvent,
+            OMX_IN OMX_U32 nData1,
+            OMX_IN OMX_U32 nData2,
+            OMX_IN OMX_PTR pEventData);
+    /* end of component methods & helpers */
+
+    void SetTypeHeader(OMX_PTR type, OMX_U32 size);
+
+    // init & deinit functions
+    status_t init(int32_t width, int32_t height);
+    void deinit();
+
+    const static OMX_U8 OMX_SPEC_VERSION_MAJOR = 1;
+    const static OMX_U8 OMX_SPEC_VERSION_MINOR = 0;
+    const static OMX_U8 OMX_SPEC_VERSION_REVISION = 0;
+    const static OMX_U8 OMX_SPEC_VERSION_STEP = 0;
+
+    const static OMX_U32 OMX_SPEC_VERSION = 0
+        | (OMX_SPEC_VERSION_MAJOR << 0)
+        | (OMX_SPEC_VERSION_MINOR << 8)
+        | (OMX_SPEC_VERSION_REVISION << 16)
+        | (OMX_SPEC_VERSION_STEP << 24);
+
+    typedef enum OMX_ISVINDEXEXTTYPE {
+        OMX_IndexISVStartUsed = OMX_IndexVendorStartUnused + 0x0000F000,
+        OMX_IndexExtSetISVMode,                  /**< reference: OMX_U32 */
+    } OMX_ISVINDEXEXTTYPE;
+
+    typedef enum {
+        ISV_DISABLE = 0,
+        ISV_AUTO,
+    } ISV_MODE;
+
+private:
+    OMX_COMPONENTTYPE mBaseComponent;  //returned by GetComponetHandle()
+    OMX_COMPONENTTYPE *mComponent;      // passed from the real OMX core
+    OMX_CALLBACKTYPE *mpCallBacks;
+    ISVOMXCore *mCore;                  // owend by mComponent
+    OMX_CALLBACKTYPE *mpISVCallBacks;
+
+    // buffer manager
+    sp<ISVBufferManager> mISVBufferManager;
+
+    bool mThreadRunning;
+
+    // vpp thread observer
+    sp<ISVProcThreadObserver> mProcThreadObserver;
+
+    // vpp input buffer count + output buffer count
+    int32_t mNumISVBuffers;
+    int32_t mNumDecoderBuffers;
+    int32_t mNumDecoderBuffersBak;
+    int64_t mNumBypassFrames;
+    uint32_t mWidth;
+    uint32_t mHeight;
+    uint32_t mUseAndroidNativeBufferIndex;
+    uint32_t mStoreMetaDataInBuffersIndex;
+
+    bool mUseAndroidNativeBuffer;
+    bool mUseAndroidNativeBuffer2;
+
+    bool mVPPEnabled;
+    bool mVPPOn;
+    bool mVPPFlushing;
+    bool mInitialized;
+#ifdef TARGET_VPP_USE_GEN
+    // vpp thread
+    sp<ISVProcessor> mProcThread;
+#else
+    static sp<ISVProcessor> mProcThread;
+#endif
+    // protect create mProcThread instance
+    bool mOwnProcessor;
+    static pthread_mutex_t ProcThreadInstanceLock;
+};
+
+#endif  // #define ISV_OMXCOMPONENT_H_
diff --git a/ISV/include/isv_omxcore.h b/ISV/include/isv_omxcore.h
new file mode 100644
index 0000000..01d3cea
--- /dev/null
+++ b/ISV/include/isv_omxcore.h
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2012 Intel Corporation.  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.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+#ifndef ISV_OMXCORE_H_
+
+#define ISV_OMXCORE_H_
+
+#define ISV_CORE_DEBUG 0
+
+struct ISVOMXCore {
+    typedef OMX_ERRORTYPE (*InitFunc)();
+    typedef OMX_ERRORTYPE (*DeinitFunc)();
+    typedef OMX_ERRORTYPE (*ComponentNameEnumFunc)(
+            OMX_STRING, OMX_U32, OMX_U32);
+
+    typedef OMX_ERRORTYPE (*GetHandleFunc)(
+            OMX_HANDLETYPE *, OMX_STRING, OMX_PTR, OMX_CALLBACKTYPE *);
+
+    typedef OMX_ERRORTYPE (*FreeHandleFunc)(OMX_HANDLETYPE);
+
+    typedef OMX_ERRORTYPE (*GetRolesOfComponentFunc)(
+            OMX_STRING, OMX_U32 *, OMX_U8 **);
+
+    void *mLibHandle;
+
+    InitFunc mInit;
+    DeinitFunc mDeinit;
+    ComponentNameEnumFunc mComponentNameEnum;
+    GetHandleFunc mGetHandle;
+    FreeHandleFunc mFreeHandle;
+    GetRolesOfComponentFunc mGetRolesOfComponentHandle;
+
+    OMX_U32 mNumComponents;
+};
+
+#endif  //ISV_OMXCORE_H_
diff --git a/ISV/include/isv_processor.h b/ISV/include/isv_processor.h
new file mode 100644
index 0000000..1b0b07c
--- /dev/null
+++ b/ISV/include/isv_processor.h
@@ -0,0 +1,128 @@
+/*
+ * Copyright (C) 2012 Intel Corporation.  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.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef __ISV_PROCESSOR_H
+#define __ISV_PROCESSOR_H
+
+#include <media/stagefright/MetaData.h>
+#include "isv_worker.h"
+
+#include <utils/Mutex.h>
+#include <utils/threads.h>
+#include <utils/Errors.h>
+#include "isv_bufmanager.h"
+#define ISV_COMPONENT_LOCK_DEBUG 0
+#define ISV_THREAD_DEBUG 0
+
+using namespace android;
+
+typedef enum {
+    kPortIndexInput  = 0,
+    kPortIndexOutput = 1
+}PORT_INDEX;
+
+class ISVBufferManager;
+class ISVProcessorObserver: public RefBase
+{
+public:
+    virtual OMX_ERRORTYPE releaseBuffer(PORT_INDEX index, OMX_BUFFERHEADERTYPE* pBuffer, bool bFlush) = 0;
+};
+
+class ISVProcessor : public Thread
+{
+public:
+    ISVProcessor(bool canCallJava, sp<ISVBufferManager> bufferManager, sp<ISVProcessorObserver> observer, uint32_t width, uint32_t height);
+    virtual ~ISVProcessor();
+
+    virtual status_t readyToRun();
+
+    // Derived class must implement threadLoop(). The thread starts its life
+    // here. There are two ways of using the Thread object:
+                                                // 1) loop: if threadLoop() returns true, it will be called again if
+                                                //          requestExit() wasn't called.
+                                                // 2) once: if threadLoop() returns false, the thread will exit upon return.
+    virtual bool threadLoop();
+    bool isCurrentThread() const;
+
+    void start();
+    void stop();
+    bool isReadytoRun();
+
+    //add output buffer into mOutputBuffers
+    void addOutput(OMX_BUFFERHEADERTYPE* output);
+    //add intput buffer into mInputBuffers
+    void addInput(OMX_BUFFERHEADERTYPE* input);
+    //notify flush and wait flush finish
+    void notifyFlush();
+    void waitFlushFinished();
+
+private:
+    bool getBufForFirmwareOutput(Vector<ISVBuffer*> *fillBufList,
+            uint32_t *fillBufNum);
+    status_t updateFirmwareOutputBufStatus(uint32_t fillBufNum);
+    bool getBufForFirmwareInput(Vector<ISVBuffer*> *procBufList,
+            ISVBuffer **inputBuf,
+            uint32_t *procBufNum );
+    status_t updateFirmwareInputBufStatus(uint32_t procBufNum);
+    //flush input&ouput buffer queue
+    void flush();
+    //return whether this fps is valid
+    inline bool isFrameRateValid(uint32_t fps);
+    //config vpp filters
+    status_t configFilters(OMX_BUFFERHEADERTYPE* buffer);
+
+private:
+    sp<ISVProcessorObserver> mpOwner;
+    android_thread_id_t mThreadId;
+    bool mThreadRunning;
+
+    sp<ISVWorker> mISVWorker;
+    sp<ISVProfile> mISVProfile;
+    // buffer manager
+    sp<ISVBufferManager> mBufferManager;
+
+    Vector<OMX_BUFFERHEADERTYPE*> mOutputBuffers;
+    Mutex mOutputLock; // to protect access to mOutputBuffers
+    uint32_t mOutputProcIdx;
+
+    Vector<OMX_BUFFERHEADERTYPE*> mInputBuffers;
+    Mutex mInputLock; // to protect access to mFillBuffers
+    uint32_t mInputProcIdx;
+
+    // conditon for thread running
+    Mutex mLock;
+    Condition mRunCond;
+
+    // condition for seek finish
+    Mutex mEndLock;
+    Condition mEndCond;
+
+    uint32_t mNumTaskInProcesing;
+    uint32_t mNumRetry;
+    int64_t mLastTimeStamp;
+    bool mError;
+    bool mbFlush;
+    bool mbBypass;
+    bool mFlagEnd;
+    bool mFrcOn;
+
+    // ISV filter configuration
+    uint32_t mFilters;
+    FilterParam mFilterParam;
+};
+
+#endif /* __ISV_THREAD_H*/
diff --git a/ISV/include/isv_profile.h b/ISV/include/isv_profile.h
new file mode 100644
index 0000000..a79dbb5
--- /dev/null
+++ b/ISV/include/isv_profile.h
@@ -0,0 +1,150 @@
+/*
+ * Copyright (C) 2014 Intel Corporation.  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.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef __ISV_PROFILE_H
+#define __ISV_PROFILE_H
+
+#define MAX_BUF_SIZE (4 * 1024)
+#define MAX_TAB_SIZE (10)
+#define MAX_STRING_LEN (50)
+
+#include <utils/RefBase.h>
+using namespace android;
+
+typedef enum _FRC_RATE {
+    FRC_RATE_1X = 1,
+    FRC_RATE_2X,
+    FRC_RATE_2_5X,
+    FRC_RATE_4X
+} FRC_RATE;
+
+typedef enum {
+    VPP_COMMON_ON   = 1,        // VPP is on
+    VPP_FRC_ON      = 1 << 1,   // FRC is on
+} VPP_SETTING_STATUS;
+
+typedef struct _ISVParameter {
+    char name[MAX_STRING_LEN];
+    float value;
+} ISVParameter;
+
+typedef struct _ISVConfig {
+    bool enabled;
+    uint32_t minResolution;
+    uint32_t maxResolution;
+    //bool isOn;
+    ISVParameter paraTables[MAX_TAB_SIZE];
+    uint32_t paraSize;
+} ISVConfig;
+
+typedef struct _ISVFRCRate {
+    uint32_t input_fps;
+    FRC_RATE rate;
+} ISVFRCRate;
+
+//FIXME: need align to ProcFilterType
+typedef enum _FilterType {
+    FilterNone                          = 0x00000001,
+    FilterNoiseReduction                = 0x00000002,
+    FilterDeinterlacing                 = 0x00000004,
+    FilterSharpening                    = 0x00000008,
+    FilterColorBalance                  = 0x00000010,
+    FilterDeblocking                    = 0x00000020,
+    FilterFrameRateConversion           = 0x00000040,
+    FilterSkinToneEnhancement           = 0x00000080,
+    FilterTotalColorCorrection          = 0x00000100,
+    FilterNonLinearAnamorphicScaling    = 0x00000200,
+    FilterImageStabilization            = 0x00000400,
+} FilterType;
+
+class ISVProfile : public RefBase
+{
+public:
+    ISVProfile(const uint32_t width, const uint32_t height);
+    ~ISVProfile();
+
+    /* get the global ISV setting status */
+    FRC_RATE getFRCRate(uint32_t inputFps);
+
+    /* get filter config data
+     * the filters' status are saved in uint32_t
+     */
+    uint32_t getFilterStatus();
+
+    /* the global setting for VPP */
+    static bool isVPPOn();
+
+    /* the global setting for FRC */
+    static bool isFRCOn();
+
+private:
+    /* Read the global setting for ISV */
+    static int32_t getGlobalStatus();
+
+    /* Get the config data from XML file */
+    void getDataFromXmlFile(void);
+
+    /* Update the filter status */
+    void updateFilterStatus();
+
+    /* handle the XML file */
+    static void startElement(void *userData, const char *name, const char **atts);
+    static void endElement(void *userData, const char *name);
+    int getFilterID(const char * name);
+    uint32_t getResolution(const char * name);
+    void getConfigData(const char *name, const char **atts);
+    void handleFilterParameter(const char *name, const char **atts);
+
+    /* dump the config data */
+    void dumpConfigData();
+
+    typedef enum _ProcFilterType {
+        ProcFilterNone = 0,
+        ProcFilterNoiseReduction,
+        ProcFilterDeinterlacing,
+        ProcFilterSharpening,
+        ProcFilterColorBalance,
+        ProcFilterDeblocking,
+        ProcFilterFrameRateConversion,
+        ProcFilterSkinToneEnhancement,
+        ProcFilterTotalColorCorrection,
+        ProcFilterNonLinearAnamorphicScaling,
+        ProcFilterImageStabilization,
+        ProcFilterCount
+    } ProcFilterType;
+
+private:
+    uint32_t mWidth;
+    uint32_t mHeight;
+
+    /* the filters' status according to resolution
+     * bit 0  used for ProcFilterNone
+     * bit 1  used for ProcFilterNoiseReduction
+     * ...
+     * bit 10 used for ProcFilterImageStabilization
+     */
+    uint32_t mStatus;
+
+    ISVConfig mConfigs[ProcFilterCount];
+    uint32_t mCurrentFilter; //used by parasing xml file
+    ISVFRCRate mFrcRates[MAX_TAB_SIZE];
+    uint32_t mCurrentFrcTab;
+
+    static const int mBufSize = MAX_BUF_SIZE;
+};
+
+#endif /* __ISV_PROFILE_H */
diff --git a/ISV/include/isv_worker.h b/ISV/include/isv_worker.h
new file mode 100644
index 0000000..3eb97c6
--- /dev/null
+++ b/ISV/include/isv_worker.h
@@ -0,0 +1,196 @@
+/*
+ * Copyright (C) 2012 Intel Corporation.  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.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef __ISVWorker_H_
+#define __ISVWorker_H_
+
+#include <va/va.h>
+#include <va/va_vpp.h>
+#include <va/va_android.h>
+#include <OMX_Component.h>
+#include <utils/RefBase.h>
+#include "isv_profile.h"
+#include "isv_bufmanager.h"
+
+#define ANDROID_DISPLAY_HANDLE 0x18C34078
+#define Display unsigned int
+
+//FIXME: copy from OMX_Core.h
+
+/* interlaced frame flag: This flag is set to indicate the buffer contains a
+ * top and bottom field and display ordering is top field first.
+ * @ingroup buf
+ */
+#define OMX_BUFFERFLAG_TFF 0x00010000
+
+/* interlaced frame flag: This flag is set to indicate the buffer contains a
+ * top and bottom field and display ordering is bottom field first.
+ * @ingroup buf
+ */
+#define OMX_BUFFERFLAG_BFF 0x00020000
+
+using namespace android;
+
+typedef enum
+{
+    STATUS_OK = 0,
+    STATUS_NOT_SUPPORT,
+    STATUS_ALLOCATION_ERROR,
+    STATUS_ERROR,
+    STATUS_DATA_RENDERING
+} vpp_status;
+
+typedef enum
+{
+    DEINTERLACE_BOB = 0,                   // BOB DI
+    DEINTERLACE_ADI = 1,                   // ADI
+} deinterlace_t;
+
+//Avaiable filter types
+typedef enum
+{
+    FILTER_HQ   = 0,                      // high-quality filter (AVS scaling)
+    FILTER_FAST = 1,                      // fast filter (bilinear scaling)
+} filter_t;
+
+typedef struct {
+    uint32_t srcWidth;
+    uint32_t srcHeight;
+    uint32_t dstWidth;
+    uint32_t dstHeight;
+    uint32_t denoiseLevel;
+    uint32_t sharpnessLevel;
+    uint32_t colorBalanceLevel;
+    deinterlace_t deinterlaceType;
+    filter_t scalarType;
+    uint32_t frameRate;
+    uint32_t hasEncoder;
+    FRC_RATE frcRate;
+} FilterParam;
+
+class ISVBuffer;
+
+class ISVWorker : public RefBase
+{
+
+    public:
+        // config filters on or off based on video info
+        status_t configFilters(uint32_t filters, const FilterParam* filterParam);
+
+        // Initialize: setupVA()->setupFilters()->setupPipelineCaps()
+        status_t init(uint32_t width, uint32_t height);
+        status_t deinit();
+
+        // Get output buffer number needed for processing
+        uint32_t getProcBufCount();
+
+        // Get output buffer number needed for filling
+        uint32_t getFillBufCount();
+
+        // Send input and output buffers to VSP to begin processing
+        status_t process(ISVBuffer* input, Vector<ISVBuffer*> output, uint32_t outputCount, bool isEOS, uint32_t flags);
+
+        // Fill output buffers given, it's a blocking call
+        status_t fill(Vector<ISVBuffer*> output, uint32_t outputCount);
+
+        // reset index
+        status_t reset();
+
+        // set video display mode
+        void setDisplayMode(int32_t mode);
+
+        // get video display mode
+        int32_t getDisplayMode();
+
+        // check HDMI connection status
+        bool isHdmiConnected();
+
+        uint32_t getVppOutputFps();
+
+        // alloc/free VA surface
+        status_t allocSurface(uint32_t* width, uint32_t* height,
+                uint32_t stride, uint32_t format, uint32_t handle, int32_t* surfaceId);
+        status_t freeSurface(int32_t* surfaceId);
+
+        ISVWorker();
+        ~ISVWorker() {}
+
+    private:
+        // Check if VPP is supported
+        bool isSupport() const;
+
+        // Get output buffer number needed for processing
+        uint32_t getOutputBufCount(uint32_t index);
+
+        // Check filter caps and create filter buffers
+        status_t setupFilters();
+
+        // Setup pipeline caps
+        status_t setupPipelineCaps();
+
+        //check if the input fps is suportted in array fpsSet.
+        bool isFpsSupport(int32_t fps, int32_t *fpsSet, int32_t fpsSetCnt);
+
+        // Debug only
+        // Dump YUV frame
+        status_t dumpYUVFrameData(VASurfaceID surfaceID);
+        status_t writeNV12(int width, int height, unsigned char *out_buf, int y_pitch, int uv_pitch);
+
+        ISVWorker(const ISVWorker &);
+        ISVWorker &operator=(const ISVWorker &);
+
+    public:
+        uint32_t mNumForwardReferences;
+
+    private:
+        // VA common variables
+        VAContextID mVAContext;
+        uint32_t mWidth;
+        uint32_t mHeight;
+        Display * mDisplay;
+        VADisplay mVADisplay;
+        VAConfigID mVAConfig;
+
+        // Forward References Surfaces
+        Vector<VABufferID> mPipelineBuffers;
+        Mutex mPipelineBufferLock; // to protect access to mPipelineBuffers
+        VASurfaceID *mForwardReferences;
+        VASurfaceID mPrevInput;
+        VASurfaceID mPrevOutput;
+
+        // VPP Filters Buffers
+        uint32_t mNumFilterBuffers;
+        VABufferID mFilterBuffers[VAProcFilterCount];
+
+        // VPP filter configuration
+        VABufferID mFilterFrc;
+
+        // VPP filter configuration
+        uint32_t mFilters;
+        FilterParam mFilterParam;
+
+        // status
+        uint32_t mInputIndex;
+        uint32_t mOutputIndex;
+        uint32_t mOutputCount;
+
+        // FIXME: not very sure how to check color standard
+        VAProcColorStandardType in_color_standards[VAProcColorStandardCount];
+        VAProcColorStandardType out_color_standards[VAProcColorStandardCount];
+};
+
+#endif //__ISVWorker_H_
diff --git a/ISV/omx/isv_omxcomponent.cpp b/ISV/omx/isv_omxcomponent.cpp
new file mode 100644
index 0000000..300cdf3
--- /dev/null
+++ b/ISV/omx/isv_omxcomponent.cpp
@@ -0,0 +1,847 @@
+/*
+ * Copyright (C) 2012 Intel Corporation.  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.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+
+#include <OMX_Component.h>
+#include "isv_omxcomponent.h"
+#include <media/hardware/HardwareAPI.h>
+#include "isv_profile.h"
+#include <OMX_IndexExt.h>
+
+//#define LOG_NDEBUG 0
+#undef LOG_TAG
+#define LOG_TAG "isv-omxil"
+
+using namespace android;
+
+/**********************************************************************************
+ * component methods & helpers
+ */
+#define GET_ISVOMX_COMPONENT(hComponent)                                    \
+    ISVComponent *pComp = static_cast<ISVComponent*>                        \
+        ((static_cast<OMX_COMPONENTTYPE*>(hComponent))->pComponentPrivate); \
+    if (!pComp)                                                             \
+        return OMX_ErrorBadParameter;
+
+Vector<ISVComponent*> ISVComponent::g_isv_components;
+
+#ifndef TARGET_VPP_USE_GEN
+//global, static
+sp<ISVProcessor> ISVComponent::mProcThread = NULL;
+#endif
+
+//global, static
+pthread_mutex_t ISVComponent::ProcThreadInstanceLock = PTHREAD_MUTEX_INITIALIZER;
+
+ISVComponent::ISVComponent(
+        OMX_PTR pAppData)
+    :   mComponent(NULL),
+        mpCallBacks(NULL),
+        mCore(NULL),
+        mpISVCallBacks(NULL),
+        mISVBufferManager(NULL),
+        mThreadRunning(false),
+        mProcThreadObserver(NULL),
+        mNumISVBuffers(MIN_ISV_BUFFER_NUM),
+        mNumDecoderBuffers(0),
+        mNumDecoderBuffersBak(0),
+        mNumBypassFrames(SKIP_FRAME_NUM),
+        mWidth(0),
+        mHeight(0),
+        mUseAndroidNativeBufferIndex(0),
+        mStoreMetaDataInBuffersIndex(0),
+        mUseAndroidNativeBuffer(false),
+        mUseAndroidNativeBuffer2(false),
+        mVPPEnabled(false),
+        mVPPFlushing(false),
+        mInitialized(false),
+#ifdef TARGET_VPP_USE_GEN
+        mProcThread(NULL),
+#endif
+        mOwnProcessor(false)
+{
+    memset(&mBaseComponent, 0, sizeof(OMX_COMPONENTTYPE));
+    /* handle initialization */
+    SetTypeHeader(&mBaseComponent, sizeof(mBaseComponent));
+    mBaseComponent.pApplicationPrivate = pAppData;
+    mBaseComponent.pComponentPrivate = static_cast<OMX_PTR>(this);
+
+    /* connect handle's functions */
+    mBaseComponent.GetComponentVersion = NULL;
+    mBaseComponent.SendCommand = SendCommand;
+    mBaseComponent.GetParameter = GetParameter;
+    mBaseComponent.SetParameter = SetParameter;
+    mBaseComponent.GetConfig = GetConfig;
+    mBaseComponent.SetConfig = SetConfig;
+    mBaseComponent.GetExtensionIndex = GetExtensionIndex;
+    mBaseComponent.GetState = GetState;
+    mBaseComponent.ComponentTunnelRequest = NULL;
+    mBaseComponent.UseBuffer = UseBuffer;
+    mBaseComponent.AllocateBuffer = AllocateBuffer;
+    mBaseComponent.FreeBuffer = FreeBuffer;
+    mBaseComponent.EmptyThisBuffer = EmptyThisBuffer;
+    mBaseComponent.FillThisBuffer = FillThisBuffer;
+    mBaseComponent.SetCallbacks = SetCallbacks;
+    mBaseComponent.ComponentDeInit = NULL;
+    mBaseComponent.UseEGLImage = NULL;
+    mBaseComponent.ComponentRoleEnum = ComponentRoleEnum;
+    g_isv_components.push_back(static_cast<ISVComponent*>(this));
+
+    mVPPOn = ISVProfile::isFRCOn() || ISVProfile::isVPPOn();
+    ALOGI("%s: mVPPOn=%d", __func__, mVPPOn);
+
+    if (mISVBufferManager == NULL) {
+        mISVBufferManager = new ISVBufferManager();
+    }
+
+}
+
+ISVComponent::~ISVComponent()
+{
+    ALOGI("%s", __func__);
+    if (mpISVCallBacks) {
+        free(mpISVCallBacks);
+        mpISVCallBacks = NULL;
+    }
+
+    for (OMX_U32 i = 0; i < g_isv_components.size(); i++) {
+        if (g_isv_components.itemAt(i) == static_cast<ISVComponent*>(this)) {
+            g_isv_components.removeAt(i);
+        }
+    }
+
+    memset(&mBaseComponent, 0, sizeof(OMX_COMPONENTTYPE));
+    deinit();
+    mVPPOn = false;
+    mISVBufferManager = NULL;
+}
+
+status_t ISVComponent::init(int32_t width, int32_t height)
+{
+    if (mInitialized)
+        return STATUS_OK;
+
+    bool frcOn = false;
+    if (mProcThreadObserver == NULL)
+        mProcThreadObserver = new ISVProcThreadObserver(&mBaseComponent, mComponent, mpCallBacks);
+
+    pthread_mutex_lock(&ProcThreadInstanceLock);
+    if (mProcThread == NULL) {
+        mProcThread = new ISVProcessor(false, mISVBufferManager, mProcThreadObserver, width, height);
+        mOwnProcessor = true;
+        mProcThread->start();
+    }
+#ifndef TARGET_VPP_USE_GEN
+    else {
+        mVPPEnabled = false;
+        mOwnProcessor = false;
+        ALOGI("%s: failed to alloc isv processor", __func__);
+        pthread_mutex_unlock(&ProcThreadInstanceLock);
+        return STATUS_ERROR;
+    }
+#endif
+    pthread_mutex_unlock(&ProcThreadInstanceLock);
+
+    mInitialized = true;
+    return STATUS_OK;
+}
+
+void ISVComponent::deinit()
+{
+    pthread_mutex_lock(&ProcThreadInstanceLock);
+    if (mOwnProcessor) {
+        if (mProcThread != NULL) {
+            mProcThread->stop();
+            mProcThread = NULL;
+            ALOGI("%s: delete ISV processor ", __func__);
+        }
+    }
+    pthread_mutex_unlock(&ProcThreadInstanceLock);
+
+    mProcThreadObserver = NULL;
+
+    mInitialized = false;
+}
+
+OMX_CALLBACKTYPE* ISVComponent::getCallBacks(OMX_CALLBACKTYPE* pCallBacks)
+{
+    //reset component callback functions
+    mpCallBacks = pCallBacks;
+    if (mpISVCallBacks) {
+        free(mpISVCallBacks);
+        mpISVCallBacks = NULL;
+    }
+
+    mpISVCallBacks = (OMX_CALLBACKTYPE *)calloc(1, sizeof(OMX_CALLBACKTYPE));
+    if (!mpISVCallBacks) {
+        ALOGE("%s: failed to alloc isv callbacks", __func__);
+        return NULL;
+    }
+    mpISVCallBacks->EventHandler = EventHandler;
+    mpISVCallBacks->EmptyBufferDone = pCallBacks->EmptyBufferDone;
+    mpISVCallBacks->FillBufferDone = FillBufferDone;
+    return mpISVCallBacks;
+}
+
+OMX_ERRORTYPE ISVComponent::SendCommand(
+    OMX_IN  OMX_HANDLETYPE hComponent,
+    OMX_IN  OMX_COMMANDTYPE Cmd,
+    OMX_IN  OMX_U32 nParam1,
+    OMX_IN  OMX_PTR pCmdData)
+{
+    GET_ISVOMX_COMPONENT(hComponent);
+
+    return pComp->ISV_SendCommand(Cmd, nParam1, pCmdData);
+}
+
+OMX_ERRORTYPE ISVComponent::ISV_SendCommand(
+    OMX_IN  OMX_COMMANDTYPE Cmd,
+    OMX_IN  OMX_U32 nParam1,
+    OMX_IN  OMX_PTR pCmdData)
+{
+    ALOGD_IF(ISV_COMPONENT_DEBUG, "%s: Cmd index 0x%08x, nParam1 %d", __func__, Cmd, nParam1);
+
+    if (mVPPEnabled && mVPPOn) {
+        if ((Cmd == OMX_CommandFlush && (nParam1 == kPortIndexOutput || nParam1 == OMX_ALL))
+                || (Cmd == OMX_CommandStateSet && nParam1 == OMX_StateIdle)
+                || (Cmd == OMX_CommandPortDisable && nParam1 == 1)) {
+            ALOGD_IF(ISV_COMPONENT_DEBUG, "%s: receive flush command, notify vpp thread to flush(Seek begin)", __func__);
+            mVPPFlushing = true;
+            mProcThread->notifyFlush();
+        }
+    }
+
+    return OMX_SendCommand(mComponent, Cmd, nParam1, pCmdData);
+}
+
+OMX_ERRORTYPE ISVComponent::GetParameter(
+    OMX_IN  OMX_HANDLETYPE hComponent,
+    OMX_IN  OMX_INDEXTYPE nParamIndex,
+    OMX_INOUT OMX_PTR pComponentParameterStructure)
+{
+    GET_ISVOMX_COMPONENT(hComponent);
+
+    return pComp->ISV_GetParameter(nParamIndex, pComponentParameterStructure);
+}
+
+OMX_ERRORTYPE ISVComponent::ISV_GetParameter(
+    OMX_IN  OMX_INDEXTYPE nParamIndex,
+    OMX_INOUT OMX_PTR pComponentParameterStructure)
+{
+    ALOGD_IF(ISV_COMPONENT_DEBUG, "%s: nIndex 0x%08x", __func__, nParamIndex);
+
+    OMX_ERRORTYPE err = OMX_GetParameter(mComponent, nParamIndex, pComponentParameterStructure);
+
+    if (err == OMX_ErrorNone && mVPPEnabled && mVPPOn) {
+        OMX_PARAM_PORTDEFINITIONTYPE *def =
+            static_cast<OMX_PARAM_PORTDEFINITIONTYPE*>(pComponentParameterStructure);
+
+        if (nParamIndex == OMX_IndexParamPortDefinition
+                && def->nPortIndex == kPortIndexOutput) {
+            ALOGD_IF(ISV_COMPONENT_DEBUG, "%s: orignal bufferCountActual %d, bufferCountMin %d",  __func__, def->nBufferCountActual, def->nBufferCountMin);
+            def->nBufferCountActual += mNumISVBuffers;
+            def->nBufferCountMin += mNumISVBuffers;
+        }
+    }
+
+    return err;
+}
+
+OMX_ERRORTYPE ISVComponent::SetParameter(
+    OMX_IN  OMX_HANDLETYPE hComponent,
+    OMX_IN  OMX_INDEXTYPE nIndex,
+    OMX_IN  OMX_PTR pComponentParameterStructure)
+{
+    GET_ISVOMX_COMPONENT(hComponent);
+
+    return pComp->ISV_SetParameter(nIndex, pComponentParameterStructure);
+}
+
+OMX_ERRORTYPE ISVComponent::ISV_SetParameter(
+    OMX_IN  OMX_INDEXTYPE nIndex,
+    OMX_IN  OMX_PTR pComponentParameterStructure)
+{
+    ALOGD_IF(ISV_COMPONENT_DEBUG, "%s: nIndex 0x%08x", __func__, nIndex);
+
+    if (nIndex == static_cast<OMX_INDEXTYPE>(OMX_IndexExtSetISVMode)) {
+        ISV_MODE* def = static_cast<ISV_MODE*>(pComponentParameterStructure);
+
+        if (*def == ISV_AUTO) {
+            mVPPEnabled = true;
+            ALOGD_IF(ISV_COMPONENT_DEBUG, "%s: mVPPEnabled -->true", __func__);
+        } else if (*def == ISV_DISABLE)
+            mVPPEnabled = false;
+        return OMX_ErrorNone;
+    }
+
+    OMX_ERRORTYPE err = OMX_SetParameter(mComponent, nIndex, pComponentParameterStructure);
+    if (err == OMX_ErrorNone && mVPPEnabled && mVPPOn) {
+        if (nIndex == OMX_IndexParamPortDefinition) {
+            OMX_PARAM_PORTDEFINITIONTYPE *def =
+                static_cast<OMX_PARAM_PORTDEFINITIONTYPE*>(pComponentParameterStructure);
+
+            if (def->nPortIndex == kPortIndexOutput) {
+                //set the buffer count we should fill to decoder before feed buffer to VPP
+                mNumDecoderBuffersBak = mNumDecoderBuffers = def->nBufferCountActual - MIN_OUTPUT_NUM - UNDEQUEUED_NUM;
+                OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def->format.video;
+
+                //FIXME: init itself here
+                if (mWidth != video_def->nFrameWidth
+                        || mHeight != video_def->nFrameHeight) {
+                    deinit();
+                    if (STATUS_OK == init(video_def->nFrameWidth, video_def->nFrameHeight)) {
+                        mWidth = video_def->nFrameWidth;
+                        mHeight = video_def->nFrameHeight;
+                    }
+                }
+                ALOGD_IF(ISV_COMPONENT_DEBUG, "%s: def->nBufferCountActual %d, mNumDecoderBuffersBak %d", __func__,
+                        def->nBufferCountActual, mNumDecoderBuffersBak);
+                if (mISVBufferManager != NULL && OK != mISVBufferManager->setBufferCount(def->nBufferCountActual)) {
+                    ALOGE("%s: failed to set ISV buffer count, set VPPEnabled -->false", __func__);
+                    mVPPEnabled = false;
+                }
+                ALOGD_IF(ISV_COMPONENT_DEBUG, "%s: video frame width %d, height %d",  __func__,
+                        video_def->nFrameWidth, video_def->nFrameHeight);
+            }
+#if 0
+            if (def->nPortIndex == kPortIndexInput) {
+                OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def->format.video;
+                mFilterParam.frameRate = video_def->xFramerate;
+
+                if (mISVProfile != NULL && mFilterParam.frameRate != 0) {
+                    mFilterParam.frcRate = mISVProfile->getFRCRate(mFilterParam.frameRate);
+                }
+                ALOGD_IF(ISV_COMPONENT_DEBUG, "%s: frame rate is set to %d",  __func__, mFilterParam.frameRate);
+            }
+#endif
+        }
+
+        if (mUseAndroidNativeBuffer
+                && nIndex == static_cast<OMX_INDEXTYPE>(mUseAndroidNativeBufferIndex)) {
+            UseAndroidNativeBufferParams *def =
+                static_cast<UseAndroidNativeBufferParams*>(pComponentParameterStructure);
+
+            if (mISVBufferManager != NULL && OK != mISVBufferManager->useBuffer(def->nativeBuffer)) {
+                    ALOGE("%s: failed to register graphic buffers to ISV, set mVPPEnabled -->false", __func__);
+                    mVPPEnabled = false;
+            }
+        }
+
+        if (nIndex == static_cast<OMX_INDEXTYPE>(mStoreMetaDataInBuffersIndex)) {
+            StoreMetaDataInBuffersParams *params = static_cast<StoreMetaDataInBuffersParams*>(pComponentParameterStructure);
+            if (params->nPortIndex == kPortIndexOutput) {
+                if (mISVBufferManager != NULL) {
+                    bool bMetaDataMode = params->bStoreMetaData == OMX_TRUE;
+                    mISVBufferManager->setMetaDataMode(bMetaDataMode);
+                } else {
+                    ALOGE("%s: falied to set Meta Data Mode ", __func__);
+                }
+            }
+            ALOGD_IF(ISV_COMPONENT_DEBUG, "%s: receive ISVStoreMetaDataInBuffers mISVWorkMode %d", __func__, (params->bStoreMetaData == OMX_TRUE));
+        }
+    }
+    return err;
+}
+
+OMX_ERRORTYPE ISVComponent::GetConfig(
+    OMX_IN  OMX_HANDLETYPE hComponent,
+    OMX_IN  OMX_INDEXTYPE nIndex,
+    OMX_INOUT OMX_PTR pComponentConfigStructure)
+{
+    GET_ISVOMX_COMPONENT(hComponent);
+
+    return pComp->ISV_GetConfig(nIndex, pComponentConfigStructure);
+}
+
+OMX_ERRORTYPE ISVComponent::ISV_GetConfig(
+    OMX_IN  OMX_INDEXTYPE nIndex,
+    OMX_INOUT OMX_PTR pComponentConfigStructure)
+{
+    ALOGD_IF(ISV_COMPONENT_DEBUG, "%s: nIndex 0x%08x", __func__, nIndex);
+
+    return OMX_GetConfig(mComponent, nIndex, pComponentConfigStructure);
+}
+
+OMX_ERRORTYPE ISVComponent::SetConfig(
+    OMX_IN  OMX_HANDLETYPE hComponent,
+    OMX_IN  OMX_INDEXTYPE nIndex,
+    OMX_IN  OMX_PTR pComponentConfigStructure)
+{
+    GET_ISVOMX_COMPONENT(hComponent);
+
+    return pComp->ISV_SetConfig(nIndex, pComponentConfigStructure);
+}
+
+OMX_ERRORTYPE ISVComponent::ISV_SetConfig(
+    OMX_IN  OMX_INDEXTYPE nIndex,
+    OMX_IN  OMX_PTR pComponentConfigStructure)
+{
+    ALOGD_IF(ISV_COMPONENT_DEBUG, "%s: nIndex 0x%08x", __func__, nIndex);
+
+    if (nIndex == static_cast<OMX_INDEXTYPE>(OMX_IndexConfigAutoFramerateConversion)) {
+        OMX_CONFIG_BOOLEANTYPE *config = static_cast<OMX_CONFIG_BOOLEANTYPE*>(pComponentConfigStructure);
+        if (config->bEnabled) {
+            mVPPEnabled = true;
+            ALOGI("%s: mVPPEnabled=true", __func__);
+        } else {
+            mVPPEnabled = false;
+            ALOGI("%s: mVPPEnabled=false", __func__);
+        }
+        return OMX_ErrorNone;
+    }
+
+    return OMX_SetConfig(mComponent, nIndex, pComponentConfigStructure);
+}
+
+OMX_ERRORTYPE ISVComponent::GetExtensionIndex(
+    OMX_IN  OMX_HANDLETYPE hComponent,
+    OMX_IN  OMX_STRING cParameterName,
+    OMX_OUT OMX_INDEXTYPE* pIndexType)
+{
+    GET_ISVOMX_COMPONENT(hComponent);
+
+    return pComp->ISV_GetExtensionIndex(cParameterName, pIndexType);
+}
+
+OMX_ERRORTYPE ISVComponent::ISV_GetExtensionIndex(
+    OMX_IN  OMX_STRING cParameterName,
+    OMX_OUT OMX_INDEXTYPE* pIndexType)
+{
+    ALOGD_IF(ISV_COMPONENT_DEBUG, "%s: cParameterName %s", __func__, cParameterName);
+    if(!strncmp(cParameterName, "OMX.intel.index.SetISVMode", strlen(cParameterName))) {
+        *pIndexType = static_cast<OMX_INDEXTYPE>(OMX_IndexExtSetISVMode);
+        return OMX_ErrorNone;
+    }
+
+    OMX_ERRORTYPE err = OMX_GetExtensionIndex(mComponent, cParameterName, pIndexType);
+
+    if(err == OMX_ErrorNone &&
+            !strncmp(cParameterName, "OMX.google.android.index.useAndroidNativeBuffer2", strlen(cParameterName)))
+        mUseAndroidNativeBuffer2 = true;
+
+    if(err == OMX_ErrorNone &&
+            !strncmp(cParameterName, "OMX.google.android.index.useAndroidNativeBuffer", strlen(cParameterName))) {
+        mUseAndroidNativeBuffer = true;
+        mUseAndroidNativeBufferIndex = static_cast<uint32_t>(*pIndexType);
+    }
+
+    if(err == OMX_ErrorNone &&
+            !strncmp(cParameterName, "OMX.google.android.index.storeMetaDataInBuffers", strlen(cParameterName))) {
+        mStoreMetaDataInBuffersIndex = static_cast<uint32_t>(*pIndexType);
+        ALOGD_IF(ISV_COMPONENT_DEBUG, "%s: storeMetaDataInBuffersIndex 0x%08x return %d", __func__, mStoreMetaDataInBuffersIndex, err);
+    }
+    ALOGD_IF(ISV_COMPONENT_DEBUG, "%s: cParameterName %s, nIndex 0x%08x", __func__,
+            cParameterName, *pIndexType);
+    return err;
+}
+
+OMX_ERRORTYPE ISVComponent::GetState(
+    OMX_IN  OMX_HANDLETYPE hComponent,
+    OMX_OUT OMX_STATETYPE* pState)
+{
+    GET_ISVOMX_COMPONENT(hComponent);
+
+    return pComp->ISV_GetState(pState);
+}
+
+OMX_ERRORTYPE ISVComponent::ISV_GetState(
+    OMX_OUT OMX_STATETYPE* pState)
+{
+    ALOGD_IF(ISV_COMPONENT_DEBUG, "%s", __func__);
+
+    return OMX_GetState(mComponent, pState);
+}
+
+OMX_ERRORTYPE ISVComponent::UseBuffer(
+    OMX_IN OMX_HANDLETYPE hComponent,
+    OMX_INOUT OMX_BUFFERHEADERTYPE **ppBufferHdr,
+    OMX_IN OMX_U32 nPortIndex,
+    OMX_IN OMX_PTR pAppPrivate,
+    OMX_IN OMX_U32 nSizeBytes,
+    OMX_IN OMX_U8 *pBuffer)
+{
+    GET_ISVOMX_COMPONENT(hComponent);
+
+    return pComp->ISV_UseBuffer(ppBufferHdr, nPortIndex,
+                                 pAppPrivate, nSizeBytes, pBuffer);
+}
+
+OMX_ERRORTYPE ISVComponent::ISV_UseBuffer(
+    OMX_INOUT OMX_BUFFERHEADERTYPE **ppBufferHdr,
+    OMX_IN OMX_U32 nPortIndex,
+    OMX_IN OMX_PTR pAppPrivate,
+    OMX_IN OMX_U32 nSizeBytes,
+    OMX_IN OMX_U8 *pBuffer)
+{
+    ALOGD_IF(ISV_COMPONENT_DEBUG, "%s", __func__);
+
+    OMX_ERRORTYPE err = OMX_UseBuffer(mComponent, ppBufferHdr, nPortIndex,
+            pAppPrivate, nSizeBytes, pBuffer);
+#ifndef USE_IVP
+    if(err == OMX_ErrorNone
+            && mVPPEnabled
+            && mVPPOn
+            && nPortIndex == kPortIndexOutput
+            /*&& mUseAndroidNativeBuffer2*/) {
+        if (mISVBufferManager != NULL) {
+            if (OK != mISVBufferManager->useBuffer(reinterpret_cast<uint32_t>(pBuffer))) {
+                ALOGE("%s: failed to register graphic buffers to ISV, set mVPPEnabled -->false", __func__);
+                mVPPEnabled = false;
+            } else
+                ALOGD_IF(ISV_COMPONENT_DEBUG, "%s: mVPP useBuffer success. buffer handle %p", __func__, pBuffer);
+        }
+    }
+#endif
+    return err;
+}
+
+OMX_ERRORTYPE ISVComponent::AllocateBuffer(
+    OMX_IN OMX_HANDLETYPE hComponent,
+    OMX_INOUT OMX_BUFFERHEADERTYPE **ppBuffer,
+    OMX_IN OMX_U32 nPortIndex,
+    OMX_IN OMX_PTR pAppPrivate,
+    OMX_IN OMX_U32 nSizeBytes)
+{
+    GET_ISVOMX_COMPONENT(hComponent);
+
+    return pComp->ISV_AllocateBuffer(ppBuffer, nPortIndex,
+                                      pAppPrivate, nSizeBytes);
+}
+
+OMX_ERRORTYPE ISVComponent::ISV_AllocateBuffer(
+    OMX_INOUT OMX_BUFFERHEADERTYPE **ppBuffer,
+    OMX_IN OMX_U32 nPortIndex,
+    OMX_IN OMX_PTR pAppPrivate,
+    OMX_IN OMX_U32 nSizeBytes)
+{
+    ALOGD_IF(ISV_COMPONENT_DEBUG, "%s", __func__);
+
+    return OMX_AllocateBuffer(mComponent, ppBuffer, nPortIndex,
+                                      pAppPrivate, nSizeBytes);
+}
+
+OMX_ERRORTYPE ISVComponent::FreeBuffer(
+    OMX_IN  OMX_HANDLETYPE hComponent,
+    OMX_IN  OMX_U32 nPortIndex,
+    OMX_IN  OMX_BUFFERHEADERTYPE *pBuffer)
+{
+    GET_ISVOMX_COMPONENT(hComponent);
+
+    return pComp->ISV_FreeBuffer(nPortIndex, pBuffer);
+}
+
+OMX_ERRORTYPE ISVComponent::ISV_FreeBuffer(
+    OMX_IN  OMX_U32 nPortIndex,
+    OMX_IN  OMX_BUFFERHEADERTYPE *pBuffer)
+{
+    ALOGD_IF(ISV_COMPONENT_DEBUG, "%s: pBuffer %p", __func__, pBuffer);
+
+    OMX_ERRORTYPE err = OMX_FreeBuffer(mComponent, nPortIndex, pBuffer);
+    if(err == OMX_ErrorNone
+            && mVPPEnabled
+            && mVPPOn
+            && nPortIndex == kPortIndexOutput) {
+        if (mISVBufferManager != NULL && OK != mISVBufferManager->freeBuffer(reinterpret_cast<uint32_t>(pBuffer->pBuffer)))
+            ALOGW("%s: pBuffer %p has not been registered into ISV", __func__, pBuffer);
+    }
+    return err;
+}
+
+OMX_ERRORTYPE ISVComponent::EmptyThisBuffer(
+    OMX_IN  OMX_HANDLETYPE hComponent,
+    OMX_IN  OMX_BUFFERHEADERTYPE* pBuffer)
+{
+    GET_ISVOMX_COMPONENT(hComponent);
+
+    return pComp->ISV_EmptyThisBuffer(pBuffer);
+}
+
+OMX_ERRORTYPE ISVComponent::ISV_EmptyThisBuffer(
+    OMX_IN  OMX_BUFFERHEADERTYPE* pBuffer)
+{
+    ALOGD_IF(ISV_COMPONENT_DEBUG, "%s: pBuffer %p", __func__, pBuffer);
+
+    return OMX_EmptyThisBuffer(mComponent, pBuffer);
+}
+
+OMX_ERRORTYPE ISVComponent::FillThisBuffer(
+    OMX_IN  OMX_HANDLETYPE hComponent,
+    OMX_IN  OMX_BUFFERHEADERTYPE *pBuffer)
+{
+    ALOGD_IF(ISV_COMPONENT_DEBUG, "%s: API entry.", __func__);
+    GET_ISVOMX_COMPONENT(hComponent);
+
+    return pComp->ISV_FillThisBuffer(pBuffer);
+}
+
+OMX_ERRORTYPE ISVComponent::ISV_FillThisBuffer(
+    OMX_IN  OMX_BUFFERHEADERTYPE *pBuffer)
+{
+    if(!mVPPEnabled || !mVPPOn)
+        return OMX_FillThisBuffer(mComponent, pBuffer);
+
+    if (mISVBufferManager != NULL) {
+        ISVBuffer* isvBuffer = mISVBufferManager->mapBuffer(reinterpret_cast<uint32_t>(pBuffer->pBuffer));
+        if (isvBuffer == NULL) {
+            ALOGE("%s: failed to map ISVBuffer, set mVPPEnabled -->false", __func__);
+            mVPPEnabled = false;
+            return OMX_FillThisBuffer(mComponent, pBuffer);
+        }
+
+        if (OK != isvBuffer->initBufferInfo()) {
+            ALOGD_IF(ISV_COMPONENT_DEBUG, "%s: isvBuffer %p failed to initBufferInfo", __func__, isvBuffer);
+            mVPPEnabled = false;
+            return OMX_FillThisBuffer(mComponent, pBuffer);
+        }
+    }
+
+    if (mNumDecoderBuffers > 0) {
+        mNumDecoderBuffers--;
+        ALOGD_IF(ISV_COMPONENT_DEBUG, "%s: fill pBuffer %p to the decoder, decoder still need extra %d buffers", __func__,
+                pBuffer, mNumDecoderBuffers);
+        return OMX_FillThisBuffer(mComponent, pBuffer);
+    }
+    mProcThread->addOutput(pBuffer);
+
+    return OMX_ErrorNone;
+}
+
+OMX_ERRORTYPE ISVComponent::FillBufferDone(
+        OMX_OUT OMX_HANDLETYPE hComponent,
+        OMX_OUT OMX_PTR pAppData,
+        OMX_OUT OMX_BUFFERHEADERTYPE* pBuffer)
+{
+    ALOGD_IF(ISV_COMPONENT_DEBUG, "%s: API entry. ISV component num %d, component handle %p on index 0", __func__,
+            g_isv_components.size(),
+            g_isv_components.itemAt(0));
+    for (OMX_U32 i = 0; i < g_isv_components.size(); i++) {
+        if (static_cast<OMX_HANDLETYPE>(g_isv_components.itemAt(i)->mComponent) == hComponent)
+            return g_isv_components.itemAt(i)->ISV_FillBufferDone(hComponent, pAppData, pBuffer);
+    }
+    return OMX_ErrorUndefined;
+}
+
+OMX_ERRORTYPE ISVComponent::ISV_FillBufferDone(
+        OMX_OUT OMX_HANDLETYPE __maybe_unused hComponent,
+        OMX_OUT OMX_PTR pAppData,
+        OMX_OUT OMX_BUFFERHEADERTYPE* pBuffer)
+{
+    ALOGD_IF(ISV_COMPONENT_DEBUG, "%s: %p <== buffer_handle_t %p. mVPPEnabled %d, mVPPOn %d", __func__,
+            pBuffer, pBuffer->pBuffer, mVPPEnabled, mVPPOn);
+    if (!mpCallBacks) {
+        ALOGE("%s: no call back functions were registered.", __func__);
+        return OMX_ErrorUndefined;
+    }
+
+    if(!mVPPEnabled || !mVPPOn || mVPPFlushing || mNumBypassFrames-- > 0) {
+        ALOGD_IF(ISV_COMPONENT_DEBUG, "%s: FillBufferDone pBuffer %p, timeStamp %.2f ms", __func__, pBuffer, pBuffer->nTimeStamp/1E3);
+        return mpCallBacks->FillBufferDone(&mBaseComponent, pAppData, pBuffer);
+    }
+
+    mProcThread->addInput(pBuffer);
+
+    return OMX_ErrorNone;
+}
+
+OMX_ERRORTYPE ISVComponent::EventHandler(
+        OMX_IN OMX_HANDLETYPE hComponent,
+        OMX_IN OMX_PTR pAppData,
+        OMX_IN OMX_EVENTTYPE eEvent,
+        OMX_IN OMX_U32 nData1,
+        OMX_IN OMX_U32 nData2,
+        OMX_IN OMX_PTR pEventData)
+{
+    ALOGD_IF(ISV_COMPONENT_DEBUG, "%s: API entry. ISV component num %d, component handle %p on index 0", __func__,
+            g_isv_components.size(),
+            g_isv_components.itemAt(0));
+    for (OMX_U32 i = 0; i < g_isv_components.size(); i++) {
+        if (static_cast<OMX_HANDLETYPE>(g_isv_components.itemAt(i)->mComponent) == hComponent)
+            return g_isv_components.itemAt(i)->ISV_EventHandler(hComponent, pAppData, eEvent, nData1, nData2, pEventData);
+    }
+    return OMX_ErrorUndefined;
+}
+
+OMX_ERRORTYPE ISVComponent::ISV_EventHandler(
+        OMX_IN OMX_HANDLETYPE __maybe_unused hComponent,
+        OMX_IN OMX_PTR pAppData,
+        OMX_IN OMX_EVENTTYPE eEvent,
+        OMX_IN OMX_U32 nData1,
+        OMX_IN OMX_U32 nData2,
+        OMX_IN OMX_PTR pEventData)
+{
+    if (!mpCallBacks) {
+        ALOGE("%s: no call back functions were registered.", __func__);
+        return OMX_ErrorUndefined;
+    }
+
+    if(!mVPPEnabled || !mVPPOn)
+        return mpCallBacks->EventHandler(&mBaseComponent, pAppData, eEvent, nData1, nData2, pEventData);
+
+    switch (eEvent) {
+        case OMX_EventCmdComplete:
+        {
+            ALOGD_IF(ISV_COMPONENT_DEBUG, "%s: OMX_EventCmdComplete Cmd type 0x%08x, data2 %d", __func__,
+                    nData1, nData2);
+            if (((OMX_COMMANDTYPE)nData1 == OMX_CommandFlush && (nData2 == kPortIndexOutput || nData2 == OMX_ALL))
+                || ((OMX_COMMANDTYPE)nData1 == OMX_CommandStateSet && nData2 == OMX_StateIdle)
+                || ((OMX_COMMANDTYPE)nData1 == OMX_CommandPortDisable && nData2 == 1)) {
+                mProcThread->waitFlushFinished();
+                mVPPFlushing = false;
+                mNumDecoderBuffers = mNumDecoderBuffersBak;
+            }
+            break;
+        }
+
+        case OMX_EventError:
+        {
+            //do we need do anything here?
+            ALOGE("%s: ERROR(0x%08x, %d)", __func__, nData1, nData2);
+            //mProcThread->flush();
+            break;
+        }
+
+        case OMX_EventPortSettingsChanged:
+        {
+            //FIXME: do we need clear ISV buffer queues for this situation?
+            //mProcThread->notifyFlush();
+            break;
+        }
+
+        default:
+        {
+            ALOGD_IF(ISV_COMPONENT_DEBUG, "%s: EVENT(%d, %ld, %ld)", __func__, eEvent, nData1, nData2);
+            break;
+        }
+    }
+    return mpCallBacks->EventHandler(&mBaseComponent, pAppData, eEvent, nData1, nData2, pEventData);
+}
+
+OMX_ERRORTYPE ISVComponent::SetCallbacks(
+    OMX_IN  OMX_HANDLETYPE hComponent,
+    OMX_IN  OMX_CALLBACKTYPE* pCallbacks,
+    OMX_IN  OMX_PTR pAppData)
+{
+    GET_ISVOMX_COMPONENT(hComponent);
+
+    return pComp->ISV_SetCallbacks(pCallbacks, pAppData);
+}
+
+OMX_ERRORTYPE ISVComponent::ISV_SetCallbacks(
+    OMX_IN  OMX_CALLBACKTYPE* pCallbacks,
+    OMX_IN  OMX_PTR pAppData)
+{
+    ALOGD_IF(ISV_COMPONENT_DEBUG, "%s", __func__);
+
+    if (mVPPEnabled && mVPPOn) {
+        if (mpISVCallBacks == NULL) {
+            mpISVCallBacks = (OMX_CALLBACKTYPE *)calloc(1, sizeof(OMX_CALLBACKTYPE));
+            if (!mpISVCallBacks) {
+                ALOGE("%s: failed to alloc isv callbacks", __func__);
+                return OMX_ErrorUndefined;
+            }
+        }
+        mpISVCallBacks->EventHandler = EventHandler;
+        mpISVCallBacks->EmptyBufferDone = pCallbacks->EmptyBufferDone;
+        mpISVCallBacks->FillBufferDone = FillBufferDone;
+        mpCallBacks = pCallbacks;
+        return mComponent->SetCallbacks(mComponent, mpISVCallBacks, pAppData);
+    }
+    return mComponent->SetCallbacks(mComponent, pCallbacks, pAppData);
+}
+
+OMX_ERRORTYPE ISVComponent::ComponentRoleEnum(
+    OMX_IN OMX_HANDLETYPE hComponent,
+    OMX_OUT OMX_U8 *cRole,
+    OMX_IN OMX_U32 nIndex)
+{
+    GET_ISVOMX_COMPONENT(hComponent);
+
+    return pComp->ISV_ComponentRoleEnum(cRole, nIndex);
+}
+
+OMX_ERRORTYPE ISVComponent::ISV_ComponentRoleEnum(
+    OMX_OUT OMX_U8 *cRole,
+    OMX_IN OMX_U32 nIndex)
+{
+    ALOGD_IF(ISV_COMPONENT_DEBUG, "%s", __func__);
+
+    return mComponent->ComponentRoleEnum(mComponent, cRole, nIndex);
+}
+
+
+void ISVComponent::SetTypeHeader(OMX_PTR type, OMX_U32 size)
+{
+    OMX_U32 *nsize;
+    OMX_VERSIONTYPE *nversion;
+
+    if (!type)
+        return;
+
+    nsize = (OMX_U32 *)type;
+    nversion = (OMX_VERSIONTYPE *)((OMX_U8 *)type + sizeof(OMX_U32));
+
+    *nsize = size;
+    nversion->nVersion = OMX_SPEC_VERSION;
+}
+
+
+ISVProcThreadObserver::ISVProcThreadObserver(
+        OMX_COMPONENTTYPE *pBaseComponent,
+        OMX_COMPONENTTYPE *pComponent,
+        OMX_CALLBACKTYPE *pCallBacks)
+    :   mBaseComponent(pBaseComponent),
+        mComponent(pComponent),
+        mpCallBacks(pCallBacks)
+{
+    ALOGV("VPPProcThreadObserver!");
+}
+
+ISVProcThreadObserver::~ISVProcThreadObserver()
+{
+    ALOGV("~VPPProcThreadObserver!");
+    mBaseComponent = NULL;
+    mComponent = NULL;
+    mpCallBacks = NULL;
+}
+
+OMX_ERRORTYPE ISVProcThreadObserver::releaseBuffer(PORT_INDEX index, OMX_BUFFERHEADERTYPE* pBuffer, bool bFLush)
+{
+    if (!mBaseComponent || !mComponent || !mpCallBacks)
+        return OMX_ErrorUndefined;
+
+    OMX_ERRORTYPE err = OMX_ErrorNone;
+    if (bFLush) {
+        pBuffer->nFilledLen = 0;
+        pBuffer->nOffset = 0;
+        OMX_ERRORTYPE err = mpCallBacks->FillBufferDone(mBaseComponent, mBaseComponent->pApplicationPrivate, pBuffer);
+        ALOGD_IF(ISV_COMPONENT_DEBUG, "%s: flush pBuffer %p", __func__, pBuffer);
+        return err;
+    }
+
+    if (index == kPortIndexInput) {
+        pBuffer->nFilledLen = 0;
+        pBuffer->nOffset = 0;
+        pBuffer->nFlags = 0;
+        err = OMX_FillThisBuffer(mComponent, pBuffer);
+        ALOGD_IF(ISV_COMPONENT_DEBUG, "%s: FillBuffer pBuffer %p", __func__, pBuffer);
+    } else {
+        err = mpCallBacks->FillBufferDone(mBaseComponent, mBaseComponent->pApplicationPrivate, pBuffer);
+        ALOGD_IF(ISV_COMPONENT_DEBUG, "%s: FillBufferDone pBuffer %p, timeStamp %.2f ms", __func__, pBuffer, pBuffer->nTimeStamp/1E3);
+    }
+
+    return err;
+}
diff --git a/ISV/omx/isv_omxcore.cpp b/ISV/omx/isv_omxcore.cpp
new file mode 100644
index 0000000..35e7a87
--- /dev/null
+++ b/ISV/omx/isv_omxcore.cpp
@@ -0,0 +1,330 @@
+/*
+ * Copyright (C) 2012 Intel Corporation.  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.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include <OMX_Core.h>
+#include <OMX_Component.h>
+#include <dlfcn.h>
+
+#include "isv_omxcore.h"
+#include "isv_omxcomponent.h"
+#include "isv_profile.h"
+
+//#define LOG_NDEBUG 0
+#undef LOG_TAG
+#define LOG_TAG "isv-omxil"
+
+#define WRS_CORE_NAME "libwrs_omxil_core_pvwrapped.so"
+#define CORE_NUMBER 1
+#ifdef USE_MEDIASDK
+#define MSDK_CORE_NAME "libmfx_omx_core.so"
+#undef CORE_NUMBER
+#define CORE_NUMBER 2
+#endif
+
+
+using namespace android;
+
+static unsigned int g_initialized = 0;
+static unsigned int g_nr_instances = 0;
+static unsigned int g_nr_comp = 0;
+
+static pthread_mutex_t g_module_lock = PTHREAD_MUTEX_INITIALIZER;
+static ISVOMXCore g_cores[CORE_NUMBER];
+static Vector<ISVComponent*> g_isv_components;
+
+/**********************************************************************************
+ * core entry
+ */
+
+OMX_API OMX_ERRORTYPE OMX_APIENTRY OMX_Init(void)
+{
+    int ret;
+    ALOGD_IF(ISV_CORE_DEBUG, "%s: enter", __func__);
+
+    pthread_mutex_lock(&g_module_lock);
+    if (!g_initialized) {
+        for (OMX_U32 i = 0; i < CORE_NUMBER; i++) {
+
+            void* libHandle = NULL;
+            if (i == 0)
+                libHandle = dlopen(WRS_CORE_NAME, RTLD_LAZY);
+#ifdef USE_MEDIASDK
+            else
+                libHandle = dlopen(MSDK_CORE_NAME, RTLD_LAZY);
+#endif
+            if (libHandle != NULL) {
+                g_cores[i].mLibHandle = libHandle;
+                g_cores[i].mInit = (ISVOMXCore::InitFunc)dlsym(libHandle, "OMX_Init");
+                g_cores[i].mDeinit = (ISVOMXCore::DeinitFunc)dlsym(libHandle, "OMX_Deinit");
+
+                g_cores[i].mComponentNameEnum =
+                    (ISVOMXCore::ComponentNameEnumFunc)dlsym(libHandle, "OMX_ComponentNameEnum");
+
+                g_cores[i].mGetHandle = (ISVOMXCore::GetHandleFunc)dlsym(libHandle, "OMX_GetHandle");
+                g_cores[i].mFreeHandle = (ISVOMXCore::FreeHandleFunc)dlsym(libHandle, "OMX_FreeHandle");
+
+                g_cores[i].mGetRolesOfComponentHandle =
+                    (ISVOMXCore::GetRolesOfComponentFunc)dlsym(
+                            libHandle, "OMX_GetRolesOfComponent");
+                if (g_cores[i].mInit != NULL) {
+                    (*(g_cores[i].mInit))();
+                }
+                if (g_cores[i].mComponentNameEnum != NULL) {
+                    // calculating number of components registered inside given OMX core
+                    char tmpComponentName[OMX_MAX_STRINGNAME_SIZE] = { 0 };
+                    OMX_U32 tmpIndex = 0;
+                    while (OMX_ErrorNone == ((*(g_cores[i].mComponentNameEnum))(tmpComponentName, OMX_MAX_STRINGNAME_SIZE, tmpIndex))) {
+                        tmpIndex++;
+                        ALOGD_IF(ISV_CORE_DEBUG, "OMX IL core: declares component %s", tmpComponentName);
+                    }
+                    g_cores[i].mNumComponents = tmpIndex;
+                    g_nr_comp += g_cores[i].mNumComponents;
+                    ALOGD_IF(ISV_CORE_DEBUG, "OMX IL core: contains %ld components", g_cores[i].mNumComponents);
+                }
+            } else {
+                pthread_mutex_unlock(&g_module_lock);
+                ALOGW("OMX IL core not found");
+                return OMX_ErrorUndefined; // Do we need to return error message
+            }
+        }
+        g_initialized = 1;
+    }
+    pthread_mutex_unlock(&g_module_lock);
+
+    ALOGD_IF(ISV_CORE_DEBUG, "%s: exit done", __func__);
+    return OMX_ErrorNone;
+}
+
+OMX_API OMX_ERRORTYPE OMX_APIENTRY OMX_Deinit(void)
+{
+    ALOGD_IF(ISV_CORE_DEBUG, "%s: enter", __func__);
+    OMX_ERRORTYPE ret = OMX_ErrorNone;
+
+    ALOGV("%s: enter", __func__);
+    if (g_initialized == 0)
+        return OMX_ErrorNone;
+
+    pthread_mutex_lock(&g_module_lock);
+    for (OMX_U32 i = 0; i < CORE_NUMBER; i++) {
+        if (g_cores[i].mDeinit != NULL) {
+            (*(g_cores[i].mDeinit))();
+        }
+    }
+    pthread_mutex_unlock(&g_module_lock);
+
+    g_initialized = 0;
+
+    ALOGD_IF(ISV_CORE_DEBUG, "%s: exit %d", __func__, ret);
+    return ret;
+}
+
+OMX_API OMX_ERRORTYPE OMX_APIENTRY OMX_ComponentNameEnum(
+    OMX_OUT OMX_STRING cComponentName,
+    OMX_IN OMX_U32 nNameLength,
+    OMX_IN OMX_U32 nIndex)
+{
+    ALOGD_IF(ISV_CORE_DEBUG, "%s: enter", __func__);
+    pthread_mutex_lock(&g_module_lock);
+    OMX_U32 relativeIndex = nIndex;
+    if (nIndex >= g_nr_comp) {
+        pthread_mutex_unlock(&g_module_lock);
+        ALOGD_IF(ISV_CORE_DEBUG, "%s: exit done", __func__);
+        return OMX_ErrorNoMore;
+    }
+
+    for (OMX_U32 i = 0; i < CORE_NUMBER; i++) {
+        if (g_cores[i].mLibHandle == NULL) {
+           continue;
+        }
+        if (relativeIndex < g_cores[i].mNumComponents) {
+            pthread_mutex_unlock(&g_module_lock);
+            ALOGD_IF(ISV_CORE_DEBUG, "%s: found %luth component %s", __func__, nIndex, cComponentName);
+            return ((*(g_cores[i].mComponentNameEnum))(cComponentName, nNameLength, relativeIndex));
+        } else relativeIndex -= g_cores[i].mNumComponents;
+    }
+    pthread_mutex_unlock(&g_module_lock);
+    ALOGD_IF(ISV_CORE_DEBUG, "%s: exit error!!!", __func__);
+    return OMX_ErrorUndefined;
+}
+
+OMX_API OMX_ERRORTYPE OMX_APIENTRY OMX_GetHandle(
+    OMX_OUT OMX_HANDLETYPE* pHandle,
+    OMX_IN OMX_STRING cComponentName,
+    OMX_IN OMX_PTR pAppData,
+    OMX_IN OMX_CALLBACKTYPE *pCallBacks)
+{
+    struct list *entry;
+    OMX_ERRORTYPE ret;
+    OMX_HANDLETYPE tempHandle;
+
+    ALOGD_IF(ISV_CORE_DEBUG, "%s: enter, try to get %s", __func__, cComponentName);
+    pthread_mutex_lock(&g_module_lock);
+
+    // create a isv component instant
+    ISVComponent *pISVComponent = new ISVComponent(pAppData);
+    if (!pISVComponent) {
+        ALOGE("%s: failed to alloc isv omx component", __func__);
+        pthread_mutex_unlock(&g_module_lock);
+        return OMX_ErrorInsufficientResources;
+    }
+
+    OMX_CALLBACKTYPE *pISVCallBacks = pISVComponent->getCallBacks(pCallBacks);
+    if (!pISVCallBacks) {
+        ALOGE("%s: failed to get isv callback functions", __func__);
+        pthread_mutex_unlock(&g_module_lock);
+        return OMX_ErrorInsufficientResources;
+    }
+
+    /* find the real component*/
+    for (OMX_U32 i = 0; i < CORE_NUMBER; i++) {
+        if (g_cores[i].mLibHandle == NULL) {
+            continue;
+        }
+
+        OMX_ERRORTYPE omx_res = (*(g_cores[i].mGetHandle))(
+                &tempHandle,
+                const_cast<char *>(cComponentName),
+                pAppData, pISVCallBacks);
+        if(omx_res == OMX_ErrorNone) {
+            pISVComponent->setComponent(static_cast<OMX_COMPONENTTYPE*>(tempHandle), &g_cores[i]);
+            g_isv_components.push_back(pISVComponent);
+
+            *pHandle = pISVComponent->getBaseComponent();
+
+            ALOGD_IF(ISV_CORE_DEBUG, "%s: found component %s, pHandle %p", __func__, cComponentName, *pHandle);
+            pthread_mutex_unlock(&g_module_lock);
+            return OMX_ErrorNone;
+        }
+    }
+    pthread_mutex_unlock(&g_module_lock);
+
+    delete pISVComponent;
+    pISVComponent = NULL;
+    ALOGE("%s(): exit failure, %s not found", __func__, cComponentName);
+    return OMX_ErrorInvalidComponent;
+}
+
+OMX_API OMX_ERRORTYPE OMX_APIENTRY OMX_FreeHandle(
+    OMX_IN OMX_HANDLETYPE hComponent)
+{
+    OMX_ERRORTYPE ret;
+
+    ALOGD_IF(ISV_CORE_DEBUG, "%s: enter, try to free component hanle %p", __func__, hComponent);
+
+    pthread_mutex_lock(&g_module_lock);
+
+    for (OMX_U32 i = 0; i < g_isv_components.size(); i++) {
+        ISVComponent *pComp = g_isv_components.itemAt(i);
+        if (static_cast<OMX_HANDLETYPE>(pComp->getBaseComponent()) == hComponent) {
+            OMX_ERRORTYPE omx_res = pComp->freeComponent();
+            if (omx_res != OMX_ErrorNone) {
+                ALOGE("%s: free OMX handle %p failed", __func__, hComponent);
+                pthread_mutex_unlock(&g_module_lock);
+                return omx_res;
+            }
+            delete pComp;
+            g_isv_components.removeAt(i);
+            ALOGD_IF(ISV_CORE_DEBUG, "%s: free component %p success", __func__, hComponent);
+            pthread_mutex_unlock(&g_module_lock);
+            return OMX_ErrorNone;
+        }
+    }
+    pthread_mutex_unlock(&g_module_lock);
+    ALOGE("%s(): exit failure, component %p not found", __func__, hComponent);
+    return OMX_ErrorInvalidComponent;
+}
+
+OMX_API OMX_ERRORTYPE OMX_APIENTRY OMX_SetupTunnel(
+    OMX_IN OMX_HANDLETYPE __maybe_unused hOutput,
+    OMX_IN OMX_U32 __maybe_unused nPortOutput,
+    OMX_IN OMX_HANDLETYPE __maybe_unused hInput,
+    OMX_IN OMX_U32 __maybe_unused nPortInput)
+{
+    return OMX_ErrorNotImplemented;
+}
+
+OMX_API OMX_ERRORTYPE   OMX_GetContentPipe(
+    OMX_OUT OMX_HANDLETYPE __maybe_unused *hPipe,
+    OMX_IN OMX_STRING __maybe_unused szURI)
+{
+    return OMX_ErrorNotImplemented;
+}
+
+OMX_API OMX_ERRORTYPE OMX_GetComponentsOfRole (
+    OMX_IN OMX_STRING __maybe_unused role,
+    OMX_INOUT OMX_U32 __maybe_unused *pNumComps,
+    OMX_INOUT OMX_U8  __maybe_unused **compNames)
+{
+    ALOGD_IF(ISV_CORE_DEBUG, "%s: enter", __func__);
+    return OMX_ErrorNotImplemented;
+}
+
+OMX_API OMX_ERRORTYPE OMX_GetRolesOfComponent (
+    OMX_IN OMX_STRING compName,
+    OMX_INOUT OMX_U32 *pNumRoles,
+    OMX_OUT OMX_U8 **roles)
+{
+    ALOGD_IF(ISV_CORE_DEBUG, "%s: enter", __func__);
+    pthread_mutex_lock(&g_module_lock);
+    for (OMX_U32 j = 0; j < CORE_NUMBER; j++) {
+        if (g_cores[j].mLibHandle == NULL) {
+           continue;
+        }
+
+        OMX_U32 numRoles;
+        OMX_ERRORTYPE err = (*(g_cores[j].mGetRolesOfComponentHandle))(
+                const_cast<OMX_STRING>(compName), &numRoles, NULL);
+
+        if (err != OMX_ErrorNone) {
+            continue;
+        }
+
+        if (numRoles > 0) {
+            OMX_U8 **array = new OMX_U8 *[numRoles];
+            for (OMX_U32 i = 0; i < numRoles; ++i) {
+                array[i] = new OMX_U8[OMX_MAX_STRINGNAME_SIZE];
+            }
+
+            OMX_U32 numRoles2 = numRoles;
+            err = (*(g_cores[j].mGetRolesOfComponentHandle))(
+                    const_cast<OMX_STRING>(compName), &numRoles2, array);
+
+            *pNumRoles = numRoles;
+
+            for (OMX_U32 i = 0; i < numRoles; i++) {
+                if (i < numRoles-1)
+                    roles[i+1] = roles[i] + OMX_MAX_STRINGNAME_SIZE;
+
+                strncpy((OMX_STRING)&roles[i][0],
+                        (const OMX_STRING)&array[i][0], OMX_MAX_STRINGNAME_SIZE);
+                delete[] array[i];
+                array[i] = NULL;
+            }
+
+            delete[] array;
+            array = NULL;
+        }
+
+        pthread_mutex_unlock(&g_module_lock);
+        ALOGD_IF(ISV_CORE_DEBUG, "%s: exit done", __func__);
+        return OMX_ErrorNone;
+    }
+    pthread_mutex_unlock(&g_module_lock);
+
+    ALOGE("%s: invalid component", __func__);
+    return OMX_ErrorInvalidComponent;
+}
diff --git a/ISV/profile/isv_profile.cpp b/ISV/profile/isv_profile.cpp
new file mode 100644
index 0000000..9cf91c9
--- /dev/null
+++ b/ISV/profile/isv_profile.cpp
@@ -0,0 +1,422 @@
+/*
+ * Copyright (C) 2014 Intel Corporation.  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.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+#include <libexpat/expat.h>
+#include <string.h>
+#include <stdio.h>
+#include <utils/Log.h>
+#include <cutils/properties.h>
+
+#include "isv_profile.h"
+
+#undef LOG_TAG
+#define LOG_TAG "ISVProfile"
+
+#define QCIF_AREA (176 * 144)
+
+using namespace android;
+static const char StatusOn[][5] = {"1frc", "1vpp"};
+
+ISVProfile::ISVProfile(const uint32_t width, const uint32_t height)
+{
+    int i;
+
+    mWidth = width;
+    mHeight = height;
+
+    mCurrentFilter = 0;
+    mCurrentFrcTab = 0;
+    mStatus = 0;
+
+    memset(mConfigs, 0, sizeof(ISVConfig) * ProcFilterCount);
+
+    for (i = 0; i < MAX_TAB_SIZE; i++) {
+        mFrcRates[i].input_fps = 0;
+        mFrcRates[i].rate = FRC_RATE_1X;
+    }
+
+    /* get the vpp global setting */
+    //getGlobalStatus();
+
+    /* load the config data from XML file */
+    getDataFromXmlFile();
+
+    /* update the filter status according to the configs */
+    updateFilterStatus();
+
+    /* dump data for debug */
+    dumpConfigData();
+}
+
+ISVProfile::~ISVProfile()
+{
+}
+
+FRC_RATE ISVProfile::getFRCRate(uint32_t inputFps)
+{
+    FRC_RATE rate = FRC_RATE_1X;
+    int i;
+
+    for (i = 0; i < MAX_TAB_SIZE; i++) {
+        if (mFrcRates[i].input_fps == inputFps) {
+            rate = mFrcRates[i].rate;
+            break;
+        }
+    }
+    return rate;
+}
+
+uint32_t ISVProfile::getFilterStatus()
+{
+    return mStatus;
+}
+
+bool ISVProfile::isVPPOn()
+{
+    int32_t status = getGlobalStatus();
+    if (status == -1) {
+        char value[PROPERTY_VALUE_MAX];
+        if (property_get("persist.intel.isv.vpp", value, NULL) &&
+                (!strcmp("1", value) || !strcasecmp("true", value))) {
+            status = VPP_COMMON_ON;
+        }
+    }
+    return (status & VPP_COMMON_ON);
+}
+
+bool ISVProfile::isFRCOn()
+{
+    int32_t status = getGlobalStatus();
+    if (status == -1) {
+        char value[PROPERTY_VALUE_MAX];
+        if (property_get("persist.intel.isv.frc", value, NULL) &&
+                (!strcmp("1", value) || !strcasecmp("true", value))) {
+            status = VPP_FRC_ON;
+        }
+    }
+    return (status & VPP_FRC_ON);
+}
+
+void ISVProfile::updateFilterStatus() {
+    int i;
+    uint32_t area = mWidth * mHeight;
+
+    for (i = 1; i < ProcFilterCount; i++) {
+        /* check config */
+        if (mConfigs[i].enabled == false)
+            continue;
+
+        if (area > mConfigs[i].minResolution && area <= mConfigs[i].maxResolution)
+            mStatus |= 1 << i;
+        /* we should cover QCIF */
+        else if (area == mConfigs[i].minResolution && area == QCIF_AREA)
+            mStatus |= 1 << i;
+    }
+}
+
+int ISVProfile::getFilterID(const char * name)
+{
+    int index = 0;
+
+    if (strcmp(name, "ProcFilterNoiseReduction") == 0)
+        index = ProcFilterNoiseReduction;
+    else if (strcmp(name, "ProcFilterDeinterlacing") == 0)
+        index = ProcFilterDeinterlacing;
+    else if (strcmp(name, "ProcFilterSharpening") == 0)
+        index = ProcFilterSharpening;
+    else if (strcmp(name, "ProcFilterColorBalance") == 0)
+        index = ProcFilterColorBalance;
+    else if (strcmp(name, "ProcFilterDeblocking") == 0)
+        index = ProcFilterDeblocking;
+    else if (strcmp(name, "ProcFilterFrameRateConversion") == 0)
+        index = ProcFilterFrameRateConversion;
+    else if (strcmp(name, "ProcFilterSkinToneEnhancement") == 0)
+        index = ProcFilterSkinToneEnhancement;
+    else if (strcmp(name, "ProcFilterTotalColorCorrection") == 0)
+        index = ProcFilterTotalColorCorrection;
+    else if (strcmp(name, "ProcFilterNonLinearAnamorphicScaling") == 0)
+        index = ProcFilterNonLinearAnamorphicScaling;
+    else if (strcmp(name, "ProcFilterImageStabilization") == 0)
+        index = ProcFilterImageStabilization;
+    else
+        index = 0;
+
+    mCurrentFilter = index;
+
+    return index;
+}
+
+uint32_t ISVProfile::getResolution(const char * name)
+{
+    uint32_t width = 0, height = 0;
+    char *p = NULL, *str = NULL;
+    int32_t lenth = strlen(name);
+
+    str = (char*)malloc(lenth+1);
+    if (NULL == str) {
+        ALOGE("%s: failed to malloc buffer", __func__);
+        return 0;
+    }
+    strncpy(str, name, lenth);
+    str[lenth] = '\0';
+
+    p = strtok(str, "x");
+    if (p)
+        width = atoi(p);
+    p = strtok(NULL, "x");
+    if (p)
+        height = atoi(p);
+
+    if (str) {
+        free(str);
+        str = NULL;
+    }
+    return width * height;
+}
+
+void ISVProfile::getConfigData(const char *name, const char **atts)
+{
+    int attIndex = 0;
+
+    if (strcmp(name, "VideoPostProcessSettings") == 0) {
+        return;
+    } else if (strcmp(name, "Filter") == 0) {
+        if (strcmp(atts[attIndex], "name") == 0) {
+            if (getFilterID(atts[attIndex + 1]) == 0) {
+                ALOGE("Couldn't parase the filter %s\n", atts[attIndex+1]);
+            }
+        } else {
+            ALOGE("couldn't handle \"%s\" element for Filter\n", name);
+        }
+    } else if (strcmp(name, "enabled") == 0) {
+        if (mCurrentFilter) {
+            if (!strcmp(atts[attIndex], "value") && !strcmp(atts[attIndex + 1], "true"))
+                mConfigs[mCurrentFilter].enabled = true;
+        } else {
+            ALOGE("Skip this element(%s) becaue this filter couldn't be supported\n", name);
+        }
+    } else if (strcmp(name, "minResolution") == 0) {
+        if (mCurrentFilter && !strcmp(atts[attIndex], "value")) {
+            if (!strcmp(atts[attIndex + 1], "0"))
+                mConfigs[mCurrentFilter].minResolution = 0;
+            else if (!strcmp(atts[attIndex + 1], "FFFFFFFF"))
+                mConfigs[mCurrentFilter].minResolution = 0xFFFFFFFF;
+            else
+                mConfigs[mCurrentFilter].minResolution = getResolution(atts[attIndex + 1]);
+        } else {
+            ALOGE("Skip this element(%s) becaue this filter couldn't be supported\n", name);
+        }
+    } else if (strcmp(name, "maxResolution") == 0) {
+        if (mCurrentFilter && !strcmp(atts[attIndex], "value")) {
+            if (!strcmp(atts[attIndex + 1], "0"))
+                mConfigs[mCurrentFilter].maxResolution = 0;
+            else if (!strcmp(atts[attIndex + 1], "FFFFFFFF"))
+                mConfigs[mCurrentFilter].maxResolution = 0xFFFFFFFF;
+            else
+                mConfigs[mCurrentFilter].maxResolution = getResolution(atts[attIndex + 1]);
+        } else {
+            ALOGE("Skip this element(%s) becaue this filter couldn't be supported\n", name);
+        }
+    } else if (strcmp(name, "FRCRate") == 0) {
+        if (mCurrentFilter == ProcFilterFrameRateConversion) {
+            if (!strcmp(atts[attIndex], "input") && !strcmp(atts[attIndex + 2], "rate")) {
+                mFrcRates[mCurrentFrcTab].input_fps = atoi(atts[attIndex + 1]);
+                if (!strcmp(atts[attIndex + 3], "2"))
+                    mFrcRates[mCurrentFrcTab].rate = FRC_RATE_2X;
+                else if (!strcmp(atts[attIndex + 3], "2.5"))
+                    mFrcRates[mCurrentFrcTab].rate = FRC_RATE_2_5X;
+                else if (!strcmp(atts[attIndex + 3], "4"))
+                    mFrcRates[mCurrentFrcTab].rate = FRC_RATE_4X;
+                else
+                     mFrcRates[mCurrentFrcTab].rate = FRC_RATE_1X;
+
+                /* update the pointer */
+                if (mCurrentFrcTab < MAX_TAB_SIZE)
+                    mCurrentFrcTab++;
+            }
+        } else {
+            ALOGE("\"FRCRate\" element is only for ProcFilterFrameRateConversion\n");
+        }
+    } else if (strcmp(name, "parameter") == 0) {
+        handleFilterParameter(name, atts);
+    } else
+        ALOGE("Couldn't handle this element %s!\n", name);
+}
+
+void ISVProfile::handleFilterParameter(const char *name, const char **atts)
+{
+    int attIndex = 0;
+
+    if (!mCurrentFilter) {
+        ALOGE("\"%s\" must be in Filter element\n");
+        return;
+    }
+
+    if (strcmp(atts[attIndex], "name") || strcmp(atts[attIndex + 2], "value")) {
+        ALOGE("\"%s\" or \"%s\" couldn't match the %s format\n", atts[attIndex], atts[attIndex + 2], name);
+        return;
+    }
+
+}
+
+void ISVProfile::startElement(void *userData, const char *name, const char **atts)
+{
+    ISVProfile *profile = (ISVProfile *)userData;
+
+    profile->getConfigData(name, atts);
+}
+
+void ISVProfile::endElement(void *userData, const char *name)
+{
+    ISVProfile *profile = (ISVProfile *)userData;
+
+    if (!strcmp(name, "Filter"))
+        profile->mCurrentFilter = 0;
+}
+
+void ISVProfile::getDataFromXmlFile()
+{
+    int done;
+    void *pBuf = NULL;
+    FILE *fp = NULL;
+
+    static const char *defaultXmlFile = "/etc/video_isv_profile.xml";
+
+    fp = ::fopen(defaultXmlFile, "r");
+    if (NULL == fp) {
+        ALOGE("@%s, line:%d, couldn't open profile %s", __func__, __LINE__, defaultXmlFile);
+        return;
+    }
+
+    XML_Parser parser = ::XML_ParserCreate(NULL);
+    if (NULL == parser) {
+        ALOGE("@%s, line:%d, parser is NULL", __func__, __LINE__);
+        goto exit;
+    }
+    ::XML_SetUserData(parser, this);
+    ::XML_SetElementHandler(parser, startElement, endElement);
+
+    pBuf = malloc(mBufSize);
+    if (NULL == pBuf) {
+        ALOGE("@%s, line:%d, failed to malloc buffer", __func__, __LINE__);
+        goto exit;
+    }
+
+    do {
+        int len = (int)::fread(pBuf, 1, mBufSize, fp);
+        if (!len) {
+            if (ferror(fp)) {
+                clearerr(fp);
+                goto exit;
+            }
+        }
+        done = len < mBufSize;
+        if (XML_Parse(parser, (const char *)pBuf, len, done) == XML_STATUS_ERROR) {
+            ALOGE("@%s, line:%d, XML_Parse error", __func__, __LINE__);
+            goto exit;
+        }
+    } while (!done);
+
+exit:
+    if (parser)
+        ::XML_ParserFree(parser);
+    if (pBuf)
+        free(pBuf);
+    if (fp)
+    ::fclose(fp);
+}
+
+int32_t ISVProfile::getGlobalStatus()
+{
+    char path[80];
+    int userId = 0;
+    int32_t status = 0;
+
+    snprintf(path, 80, "/data/user/%d/com.intel.vpp/shared_prefs/vpp_settings.xml", userId);
+    ALOGI("%s: %s",__func__, path);
+    FILE *handle = fopen(path, "r");
+    if(handle == NULL) {
+        ALOGE("%s: failed to open file %s\n", __func__, path);
+        return -1;
+    }
+
+    const int MAXLEN = 1024;
+    char buf[MAXLEN] = {0};
+    memset(buf, 0 ,MAXLEN);
+    if(fread(buf, 1, MAXLEN, handle) <= 0) {
+        ALOGE("%s: failed to read vpp config file %d", __func__, userId);
+        fclose(handle);
+        return -1;
+    }
+    buf[MAXLEN - 1] = '\0';
+
+    if(strstr(buf, StatusOn[0]) != NULL)
+        status |= VPP_FRC_ON;
+
+    if(strstr(buf, StatusOn[1]) != NULL)
+        status |= VPP_COMMON_ON;
+
+    fclose(handle);
+    return status;
+}
+
+void ISVProfile::dumpConfigData()
+{
+    uint32_t i, j;
+    char filterNames[][50] = {
+        "ProcFilterNone",
+        "ProcFilterNoiseReduction",
+        "ProcFilterDeinterlacing",
+        "ProcFilterSharpening",
+        "ProcFilterColorBalance",
+        "ProcFilterDeblocking",
+        "ProcFilterFrameRateConversion",
+        "ProcFilterSkinToneEnhancement",
+        "ProcFilterTotalColorCorrection",
+        "ProcFilterNonLinearAnamorphicScaling",
+        "ProcFilterImageStabilization"
+    };
+    char rateNames[][20] = {
+        "FRC_RATE_0X",
+        "FRC_RATE_1X",
+        "FRC_RATE_2X",
+        "FRC_RATE_2_5X",
+        "FRC_RATE_4X",
+    };
+
+    ALOGI("========== VPP filter configs:==========\n");
+    for (i = 1; i < ProcFilterCount; i++) {
+        ALOGI("name=%s, enabled=%s, minResolution=%d, maxResolution=%d, isOn=%s\n",
+            filterNames[i],
+            (mConfigs[i].enabled == true) ? "true" : "false",
+            mConfigs[i].minResolution,
+            mConfigs[i].maxResolution,
+            ((mStatus & (1 << i)) == 0) ? "false" : "true");
+        if (mConfigs[i].paraSize) {
+            ALOGI("\t\t parameters: ");
+            for(j = 0; j < mConfigs[i].paraSize; j++)
+                ALOGI("%s=%f,", mConfigs[i].paraTables[j].name, mConfigs[i].paraTables[j].value);
+            ALOGI("\n");
+        }
+    }
+
+    ALOGI("========== FRC rate configs:===========\n");
+    for (i = 0; i < MAX_TAB_SIZE; i++) {
+        if (mFrcRates[i].input_fps == 0)
+            break;
+        ALOGI("input_fps=%d, rate=%s\n", mFrcRates[i].input_fps, rateNames[mFrcRates[i].rate]);
+    }
+}
