/* SPDX-License-Identifier: LGPL-2.1-only OR BSD-3-Clause */
/******************************************************************************
 *
 * This file is provided under a dual license.  When you use or
 * distribute this software, you may choose to be licensed under
 * version 2.1 of the GNU Lesser General Public License
 * ("LGPLv2.1 License") or BSD License.
 *
 * LGPLv2.1 License
 *
 * Copyright(C) 2019 MediaTek Inc.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of version 2.1 of the GNU Lesser General Public
 * License as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 * See https://www.gnu.org/licenses/old-licenses/lgpl-2.1.html for more
 * details.
 *
 * BSD LICENSE
 *
 * Copyright(C) 2019 MediaTek Inc.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 *  * Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *  * Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *  * Neither the name of the copyright holder nor the names of its
 *    contributors may be used to endorse or promote products derived
 *    from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 *****************************************************************************/

/*-----------------------------------------------------------------------------
 * $RCSfile: vencomx_drv_if.c,v $
 * $Revision$
 * $Author$
 * $SWAuthor: xiaolei li $
 * $MD5HEX:  $
 *---------------------------------------------------------------------------*/

/** @file vencomx_drv_if.c
 */

//-----------------------------------------------------------------------------
// Include files
//-----------------------------------------------------------------------------
#include "vencomx_mod.h"
#include "x_bim.h"
#include <linux/ioctl.h>
#include <linux/fs.h>
#include <asm/uaccess.h>  // for access_ok VERIFY_READ


#ifdef CC_SUPPORT_VENC
#include "x_assert.h"
#include "venc_if.h"
#include "venc_drvif.h"
#include "venc_util_drvif.h"
#include "vdec_drvif.h"

#ifdef CC_SUPPORT_MUXER
#include "muxer_if.h"
#endif

// DI control related header
#include "drv_di.h"
#include "drv_video.h"
#include "vdo_misc.h"
#include "drv_vga.h"
#include "video_def.h"
#include "vdo_if.h"
#include "srm_drvif.h"
#include "drv_scaler.h"

#include "vdp_prescale_drvif.h"
#include "vdo_rm.h"
#include "vdp_if.h"
#include "source_select.h"
#include "source_table.h"
#include "drv_dvi.h"
#include "drv_display.h"
#include "gfx_if.h"

#ifdef VENC_TIME_PROFILE
#include "x_timer.h"
#endif
LINT_EXT_HEADER_BEGIN
#define DEFINE_IS_LOG   VOMX_IsLog
#include "x_debug.h"
LINT_EXT_HEADER_END

#define VENCOMX_DBG(fmt...)    {LOG(3, "%s %s(%d): \n","[vencomx_mod]", __FUNCTION__, __LINE__);  LOG(3, fmt);  }

//-----------------------------------------------------------------------------
// Constant definitions
//-----------------------------------------------------------------------------

#define _VENC_MAX_RES (1280 * 736)
#define _VENC_HALFFPS_THRD (1280 * 720 * 30)
#define COPYDATA_FROME_DRVIER
#define VENC_KEEPDATA_QSIZE (256)


//-----------------------------------------------------------------------------
// Type definitions
//-----------------------------------------------------------------------------

VENC_BUFMGR_DECLARE(VENC_FRM, VENC_FRM_T, 10);

typedef struct _VENCOMX_INFO_T
{
    BOOL                     fgIsCtrlOn;
    BOOL                     fgIsRunning;
    BOOL                     fgInterlace; // for replay
    BOOL                     fg2Usr;
    BOOL                     fgEncOSTG;
    BOOL                     fgAddAud;
    UCHAR                    ucMxId;
    UCHAR                    ucRzId;

    UINT16                   u2SrcCompId; // for vdec

    UINT32                   u4Width;
    UINT32                   u4Height;
    UINT32                   u4Pitch;
    UINT32                   u4Fps;
    UINT32                   u4Bps;
    UINT32                   u4SrcFps;    // for replay
    UINT32                   u4SrcWidth;  // for replay
    UINT32                   u4SrcHeight; // for replay
    UINT32                   u4SyncMode;
    UINT32                   u4EncType;
    UINT32                   u4Profile;
    UINT32                   u4Level;

    VENC_PROFILE_T           eProfileDef;
    VENC_PIX_FMT_T           ePixFmt;
    VENCOMX_SRC_TYPE_T       eSrcType;
    VENCOMX_FMT_TYPE_T       eEncFmt;

    VENC_HANDLE              hVEnc;
    HANDLE_T                 hVencMsgQ;
    VENC_FILTER_T*           ptFilter;
    VENC_BUFMGR_BASE_T*      ptFrmBuffMgr;
    VOID *                   ptTag;
    vencomx_nfy_fct      ptCb;
    INT32 (*SetFmtInfo)      (struct _VENCOMX_INFO_T *, VOID *);
    INT32 (*ConnectInput)    (struct _VENCOMX_INFO_T *);
    INT32 (*DisconnectInput) (struct _VENCOMX_INFO_T *);
    INT32 (*SetInputParam)   (struct _VENCOMX_INFO_T *);
} VENCOMX_INFO_T;

//-----------------------------------------------------------------------------
// Macro definitions
//-----------------------------------------------------------------------------

//lint --e{717} do ... while (0);
#define VENCOMX_SET_VALIDATE(TYPE)         \
do                                      \
{                                       \
    if (NULL == pvData)            \
    {                                   \
        return VENCR_NOT_OK;    \
    }                                   \
                                        \
    if (sizeof(TYPE) > u4Size)  \
    {                                   \
        return VENCR_NOT_OK;    \
    }                                   \
} while (0)

#define USR_SPACE_ACCESS_VALIDATE_ARG(arg, type)                 \
        if (!access_ok(VERIFY_READ, (void __user *)arg,         \
                       sizeof(type)))              \
        {                                                       \
            return -1;                                          \
        }                                                       \

#define COPY_FROM_USER_ARG(ArgUsr, ArgKernel, type)              \
        if (copy_from_user(&ArgKernel, (void __user *)ArgUsr,   \
                           sizeof(type)))          \
        {                                                       \
            return -1;                                          \
        }

#define COPY_TO_USER_ARG(ArgUsr, ArgKernel, type)              \
        if (copy_to_user((void __user *)ArgUsr, &ArgKernel,   \
                           sizeof(type)))          \
        {                                                       \
            return -1;                                          \
        }
#define USR_SPACE_ACCESS_VALIDATE_4ARG(arg)                 \
        if (!access_ok(VERIFY_READ, (void __user *)arg,         \
                       sizeof(VENCOMX_IOCTL_4ARG_T)))              \
        {                                                       \
            return -1;                                          \
        }                                                       \

#define COPY_FROM_USER_4ARG(ArgUsr, ArgKernel)              \
        if (copy_from_user(&ArgKernel, (void __user *)ArgUsr,   \
                           sizeof(VENCOMX_IOCTL_4ARG_T)))          \
        {                                                       \
            return -1;                                          \
        }
#define USR_SPACE_ACCESS_VALIDATE_3ARG(arg)                 \
        if (!access_ok(VERIFY_READ, (void __user *)arg,         \
                       sizeof(VENCOMX_IOCTL_3ARG_T)))              \
        {                                                       \
            return VENCR_ERR_INV;                                          \
        }
#define COPY_FROM_USER_3ARG(ArgUsr, ArgKernel)              \
        if (copy_from_user(&ArgKernel, (void __user *)ArgUsr,   \
                           sizeof(VENCOMX_IOCTL_3ARG_T)))          \
        {                                                       \
            return -1;                                          \
        }
#define USR_SPACE_ACCESS_VALIDATE_2ARG(arg)                 \
        if (!access_ok(VERIFY_READ, (void __user *)arg,         \
                       sizeof(VENCOMX_IOCTL_2ARG_T)))              \
        {                                                       \
            return VENCR_ERR_INV;                                          \
        }
#define COPY_FROM_USER_2ARG(ArgUsr, ArgKernel)              \
        if (copy_from_user(&ArgKernel, (void __user *)ArgUsr,   \
                           sizeof(VENCOMX_IOCTL_2ARG_T)))          \
        {                                                       \
            return VENCR_ERR_INV;                                          \
        }
#define USR_SPACE_ACCESS_VALIDATE_8ARG(arg)                 \
        if (!access_ok(VERIFY_READ, (void __user *)arg,         \
                       sizeof(VENCOMX_IOCTL_8ARG_T)))              \
        {                                                       \
            return VENCR_ERR_INV;                                          \
        }                                                       \

#define COPY_FROM_USER_8ARG(ArgUsr, ArgKernel)              \
        if (copy_from_user(&ArgKernel, (void __user *)ArgUsr,   \
                           sizeof(VENCOMX_IOCTL_8ARG_T)))          \
        {                                                       \
            return VENCR_ERR_INV;                                          \
        }     \

//-----------------------------------------------------------------------------
// Imported functions
//-----------------------------------------------------------------------------

extern UINT32 VENC_EncSeqHdrSync(VENC_HANDLE hEnc, VENC_OUT_PIC_T *ptOut);

//-----------------------------------------------------------------------------
// Static function forward declarations
//-----------------------------------------------------------------------------

//-----------------------------------------------------------------------------

static VENCOMX_INFO_T _arVEncOMXInfo[VENCOMX_COMP_NS];


//-----------------------------------------------------------------------------
// Static functions
//-----------------------------------------------------------------------------

static VENCOMX_INFO_T *_VENCGetInfoInst(UINT16 u2CompId)
{
    ASSERT((UINT16)VENCOMX_COMP_NS > u2CompId);
    return ((UINT16)VENCOMX_COMP_NS > u2CompId)? &_arVEncOMXInfo[u2CompId] : &_arVEncOMXInfo[0];
}

// map from VENC_H264_PIC_TYPE to VENC_H264_PIC_TYPE
static VENC_H264_PIC_TYPE _VENC_PicTypeMap(VENC_H264_PIC_TYPE ePicType)
{
    VENCOMX_H264_PIC_TYPE eType = VENC_PIX_FMT_MAX;

    switch (ePicType)
    {
    default:
        VENCOMX_DBG("Unknown ePicType(%d)\n", ePicType);
        eType = VENCOMX_H264_PIC_TYPE_MAX;
        break;
    case VENC_H264_PIC_TYPE_SPS:
        eType = VENCOMX_H264_PIC_TYPE_SPS;
        break;
    case VENC_H264_PIC_TYPE_PPS:
        eType = VENCOMX_H264_PIC_TYPE_PPS;
        break;
    case VENC_H264_PIC_TYPE_SEI:
        eType = VENCOMX_H264_PIC_TYPE_SEI;
        break;
    case VENC_H264_PIC_TYPE_IDR:
        eType = VENCOMX_H264_PIC_TYPE_IDR;
        break;
    case VENC_H264_PIC_TYPE_I:
        eType = VENCOMX_H264_PIC_TYPE_I;
        break;
    case VENC_H264_PIC_TYPE_P:
        eType = VENCOMX_H264_PIC_TYPE_P;
        break;
    case VENC_H264_PIC_TYPE_B:
        eType = VENCOMX_H264_PIC_TYPE_B;
        break;
    case VENC_PIC_TYPE_EOS:
        eType = VENCOMX_PIC_TYPE_EOS;
        break;
    }

    return eType;
}

static void _VENCOMX_Put_Event(VOID *pvArg, VENCOMX_CB_T* prOmxEvent)
{
    VENCOMX_INFO_T *prVEncOmxInfo = (VENCOMX_INFO_T *)pvArg;
    INT32 i4Ret;
    SIZE_T zMsgSize = sizeof(VENCOMX_CB_T);

    if(NULL_HANDLE != prVEncOmxInfo->hVencMsgQ)
    {

        i4Ret = x_msg_q_send(prVEncOmxInfo->hVencMsgQ, prOmxEvent, zMsgSize, 255);
        while (i4Ret == OSR_TOO_MANY)
        {
            LOG(0, "VEnc SendFrm Queue, OSR_TOO_MANY\n");
            // maybe in irq context ...
            x_thread_delay(10);
            i4Ret = x_msg_q_send(prVEncOmxInfo->hVencMsgQ, prOmxEvent, zMsgSize, 255);
        }

        ASSERT(i4Ret == OSR_OK);
    }
}

INT32 _VENCOMX_Get_Event(unsigned long pvArg)
{
    UINT16 u2MsgQIdx;

    VENCOMX_IOCTL_2ARG_T rArg;
    VENCOMX_CB_T *ptDataUsr, tDataKrnl;
    VENCOMX_INFO_T *prVEncOmxInfo;
    SIZE_T zMsgSize = sizeof(VENCOMX_CB_T);
    VENC_HANDLE hEnc;

    USR_SPACE_ACCESS_VALIDATE_2ARG(pvArg);
    COPY_FROM_USER_2ARG(pvArg, rArg);
#ifdef CONFIG_COMPAT
    if (is_compat_task())
    {
        hEnc = (VENC_HANDLE)(compat_ptr(rArg.ai4Arg[0].compat_value));
    }
    else
#endif
    {
        hEnc = (VENC_HANDLE)rArg.ai4Arg[0].value;

    }
    prVEncOmxInfo = _VENCGetInfoInst(( (UINT16)(UPTR)hEnc - 1));

#ifdef CONFIG_COMPAT
    if (is_compat_task())
    {
        ptDataUsr = (VENCOMX_CB_T *)(compat_ptr(rArg.ai4Arg[1].compat_value));
    }
    else
#endif
    {
        ptDataUsr = (VENCOMX_CB_T *)rArg.ai4Arg[1].value;

    }
    if(prVEncOmxInfo->u4SyncMode == VENC_SMODE_SYNC)
    {
        return -1;
    }

    if(NULL_HANDLE == prVEncOmxInfo->hVencMsgQ)
    {
        return -1;
    }
    if(OSR_OK ==
        x_msg_q_receive(&u2MsgQIdx, (void*)(&tDataKrnl), &zMsgSize, &(prVEncOmxInfo->hVencMsgQ), 1, X_MSGQ_OPTION_WAIT))
        //x_msg_q_receive_timeout(&u2MsgQIdx, (void*)(&tDataKrnl), &zMsgSize, &(prVEncOmxInfo->hVencMsgQ), 1, 100))
    {
        USR_SPACE_ACCESS_VALIDATE_ARG(ptDataUsr,VENCOMX_CB_T);
        COPY_TO_USER_ARG(ptDataUsr,tDataKrnl,VENCOMX_CB_T);

#ifdef VENC_TIME_PROFILE
        {
            HAL_TIME_T rTimeHwS;

            HAL_GetTime(&rTimeHwS);
            LOG(3, "et u4Pts %d  %u.%06u s \n",
                tDataKrnl.u.tOut.u4Pts,rTimeHwS.u4Seconds, rTimeHwS.u4Micros);
        }

#endif
        return 0;
    }
    else
    {
        return -1;
    }

}
static VOID _VENCCb(VOID *pvArg, VENC_IN_PIC_T * ptIn, VENC_OUT_PIC_T * ptOut, UINT32 type)
{
    VENCOMX_INFO_T *prVEncOmxInfo = (VENCOMX_INFO_T *)pvArg;
    VENCOMX_DBG(" prVEncOmxInfo(%p)\n", prVEncOmxInfo);


    if (!(prVEncOmxInfo->fgIsRunning))
    {
        return ;
    }
    if (ptOut && prVEncOmxInfo->fg2Usr)
    {
        VENCOMX_CB_T tVencCb;
        tVencCb.eCond = VENCOMX_COND_DATA;
        tVencCb.u.tOut.eType    = _VENC_PicTypeMap(type);
        tVencCb.u.tOut.u4Pts    = ptOut->u4Pts;
        tVencCb.u.tOut.u4Addr   = ptOut->u4Addr;
        tVencCb.u.tOut.u4Size   = ptOut->u4Size;
        tVencCb.u.tOut.u4RStart = ptOut->u4RStart;
        tVencCb.u.tOut.u4REnd   = ptOut->u4REnd;
        if(prVEncOmxInfo->fgIsRunning)
            tVencCb.tStatus   = VENCOMX_STATUS_RUN;

#if 1
        VENCOMX_DBG("%s() :  - eType    : %d \n", __FUNCTION__, tVencCb.u.tOut.eType);
        VENCOMX_DBG("%s() :  - u4Pts    : 0x%08X \n", __FUNCTION__, ptOut->u4Pts);
        VENCOMX_DBG("%s() :  - u4Addr   : 0x%08X \n", __FUNCTION__, ptOut->u4Addr);
        VENCOMX_DBG("%s() :  - u4Size   : %u \n", __FUNCTION__, ptOut->u4Size);
        VENCOMX_DBG("%s() :  - u4RStart : 0x%08X \n", __FUNCTION__, ptOut->u4RStart);
        VENCOMX_DBG("%s() :  - u4REnd   : 0x%08X \n", __FUNCTION__, ptOut->u4REnd);
#endif
#ifdef VENC_TIME_PROFILE
    {
        HAL_TIME_T rTimeHwS;

        HAL_GetTime(&rTimeHwS);
        LOG(3, "cb u4Pts %d %u.%06u s \n",
            ptOut->u4Pts,rTimeHwS.u4Seconds, rTimeHwS.u4Micros);
    }

#endif

        _VENCOMX_Put_Event(prVEncOmxInfo,&tVencCb);
    }
}


static BOOL fg1stCalled = TRUE;

VENCOMX_RESULT_T _VENCOMX_Init(void)
{
    UINT16 u2CompId;

    VENCOMX_DBG(" - void\n");

    if (!fg1stCalled)
    {
        return VENCR_OK;
    }

    fg1stCalled = FALSE;

    for (u2CompId = 0; u2CompId < VENCOMX_COMP_NS; u2CompId++)
    {
        VENCOMX_INFO_T *prVEncOmxInfo = _VENCGetInfoInst(u2CompId);
        x_memset((VOID *)prVEncOmxInfo, 0, sizeof(VENCOMX_INFO_T));
        prVEncOmxInfo->hVEnc = VENC_NULL_HANDLE;
        prVEncOmxInfo->ucMxId = 0xFF;
        prVEncOmxInfo->hVencMsgQ = NULL_HANDLE;
    }

    return VENCR_OK;
}



VENCOMX_RESULT_T _VENCOMX_Termint(void)
{
    VENCOMX_DBG(" - void\n");
    //add driver implementation code here
    return VENCR_OK;
}


VENCOMX_RESULT_T _VENCOMX_Reset(unsigned long arg)
{
    return VENCR_OK;
}


VENCOMX_RESULT_T _VENCOMX_Set(unsigned long arg)
{
    VENCOMX_IOCTL_4ARG_T rArg;
    UINT16            u2CompId;
    VENCOMX_SET_TYPE_T eSetType;
    VOID*             pvData;
    UINT32            u4Size;

    VENCOMX_DBG(" - _VENCOMX_Set\n");

    USR_SPACE_ACCESS_VALIDATE_4ARG(arg);
    COPY_FROM_USER_4ARG(arg, rArg);
    u2CompId = (UINT16)rArg.ai4Arg[0].compat_value;
    eSetType = (VENCOMX_SET_TYPE_T)rArg.ai4Arg[1].compat_value;
#ifdef CONFIG_COMPAT
    if (is_compat_task())
    {
        pvData = (VOID*)(compat_ptr(rArg.ai4Arg[2].compat_value));
    }
    else
#endif
    {
        pvData = (VOID*)rArg.ai4Arg[2].value;
    }
    u4Size = (UINT32)rArg.ai4Arg[3].compat_value;

    switch (eSetType)
    {
    default:
        VENCOMX_DBG("Invalid set_type - %d\n", eSetType);
        return VENCR_NOT_OK;
    case VENCOMX_SET_TYPE_XMLRESOLUTION:
        {
            VENCOMX_FRAME_RESOLUTION_T tResUsr;
            VENC_PRAM_RES_T res;
            x_memset(&tResUsr, 0, sizeof(tResUsr));
            USR_SPACE_ACCESS_VALIDATE_ARG(pvData,VENCOMX_FRAME_RESOLUTION_T);
            COPY_FROM_USER_ARG(pvData,tResUsr,VENCOMX_FRAME_RESOLUTION_T);

            res.u2Height = (UINT16)tResUsr.u4Height;
            res.u2Width = (UINT16)tResUsr.u4Width;
            {
                FBM_POOL_T *prFbmPool = FBM_GetPoolInfo((UCHAR)FBM_POOL_TYPE_VENC);
                //FBM_POOL_T *prFbmSetCrash = NULL;

                ASSERT(prFbmPool != NULL);
                ASSERT(prFbmPool->u4Addr != 0);
                ASSERT(prFbmPool->u4Size != 0);

                printk("venc prFbmPool(%p) baseaddr: 0x%x totalsize 0x%x\n",
                    prFbmPool, prFbmPool->u4Addr,prFbmPool->u4Size);
                printk("VENCOMX_SET_TYPE_XMLRESOLUTION (%d -%d): \n", tResUsr.u4Height,tResUsr.u4Width);
                if(res.u2Height == 1080 && res.u2Width == 1920 && prFbmPool->u4Size < 0x1700000)
                {
                    printk("\n\n");
                    printk("[vencmode] #################enter Crash Info ########################### \n");
                    printk("[vencmode] Don't worry,it is only VIDEO Encoder configuration problem  \n");
                    printk("[vencmode] please follow the following steps to resolve this crash issue \n");
                    printk("[vencmode] please make sure whether there is a requirement the max resolution of video encoder support 1080p in this BR \n");
                    printk("[vencmode] if Yes,please enlarge venc fbm pool size to 31m \n");
                    printk("[vencmode] if No, please small the venc max resolution  to right value(1920x1080 --> 1280x720) in media_codecs.xml \n");
                    printk("[vencmode] OK,if any question,please contact venc module owner\n");
                    printk("[vencmode] ######################################################### \n");
                    x_thread_delay(1000);

                    do{

                        printk("[vencmode] #################enter Crash Info ########################### \n");
                        printk("[vencmode] Don't worry,it is only VIDEO Encoder configuration problem  \n");
                        printk("[vencmode] please follow the following steps to resolve this crash issue \n");
                        printk("[vencmode] please make sure whether there is a requirement the max resolution of video encoder support 1080p in this BR \n");
                        printk("[vencmode] if Yes,please enlarge venc fbm pool size to 31m \n");
                        printk("[vencmode] if No, please small the venc max resolution  to right value(1920x1080 --> 1280x720) in media_codecs.xml \n");
                        printk("[vencmode] OK,if any question,please contact venc module owner\n");
                        printk("[vencmode] ######################################################### \n");

                        x_thread_delay(1000);

                        printk("\n\n");

                        ASSERT(0); //prFbmSetCrash->u4Addr = 0X1234; //only for crach,don't care the value:0x1234

                    }while(1);
                }
                if(res.u2Height == 720 && res.u2Width == 1280 && prFbmPool->u4Size < 0xA00000)
                {
                    printk("\n\n");
                    printk("[vencmode] #################enter Crash Info ########################### \n");
                    printk("[vencmode] Don't worry,it is only VIDEO Encoder configuration problem  \n");
                    printk("[vencmode] please follow the following steps to resolve this crash issue \n");
                    printk("[vencmode] please make sure whether there is a requirement the max resolution of video encoder support 720p in this BR \n");
                    printk("[vencmode] if Yes,please enlarge venc fbm pool size to 16m \n");
                    printk("[vencmode] if No, please small the venc max resolution  to right value(1280x720 --> 720x5760) in media_codecs.xml \n");
                    printk("[vencmode] OK,if any question,please contact venc module owner\n");
                    printk("[vencmode] ######################################################### \n");
                    x_thread_delay(1000);
                    do{
                        printk("[vencmode] #################enter Crash Info ########################### \n");
                        printk("[vencmode] Don't worry,it is only VIDEO Encoder configuration problem  \n");
                        printk("[vencmode] please follow the following steps to resolve this crash issue \n");
                        printk("[vencmode] please make sure whether there is a requirement the max resolution of video encoder support 720p in this BR \n");
                        printk("[vencmode] if Yes,please enlarge venc fbm pool size to 16m \n");
                        printk("[vencmode] if No, please small the venc max resolution  to right value(1280x720 --> 720x5760) in media_codecs.xml \n");
                        printk("[vencmode] OK,if any question,please contact venc module owner\n");
                        printk("[vencmode] ######################################################### \n");

                        x_thread_delay(1000);

                        printk("\n\n");

                        ASSERT(0); // prFbmSetCrash->u4Addr = 0X1234; //only for crach,don't care the value:0x1234

                    }while(1);
                }
            }
        }
        break;
    }
    return VENCR_OK;
}


VENCOMX_RESULT_T _VENCOMX_Get(unsigned long arg)
{
    VENCOMX_RESULT_T       eRet = VENCR_OK;

    return eRet;
}

#define MAX_VOMX_EVENT (512)

VENCOMX_RESULT_T _VENCOMX_Open(unsigned long arg)
{
    VENCOMX_IOCTL_4ARG_T rArg;
    VENCOMX_RESULT_T       eRet = VENCR_NOT_OK;
    VENCOMX_HANDLE*    phVenc;
    VENCOMX_FMT_TYPE_T eEncFmt;
    VENCOMX_AP_TYPE_T  eProfile;
    BOOL              fgInterlace;
    VENC_HANDLE hEnc = VENC_NULL_HANDLE;
    UINT32 u4Type;
    VENC_PROFILE_T eProfileSet = VENC_PROFILE_MS;
    VENCOMX_INFO_T *prVEncOmxInfo;

    USR_SPACE_ACCESS_VALIDATE_4ARG(arg);
    COPY_FROM_USER_4ARG(arg, rArg);
#ifdef CONFIG_COMPAT
    if (is_compat_task())
    {
        phVenc = (VENCOMX_HANDLE*)(compat_ptr(rArg.ai4Arg[0].compat_value));
    }
    else
#endif
    {
        phVenc = (VENCOMX_HANDLE*)rArg.ai4Arg[0].value;

    }
    eEncFmt = (VENCOMX_FMT_TYPE_T)rArg.ai4Arg[1].compat_value;
    eProfile = (VENCOMX_AP_TYPE_T)rArg.ai4Arg[2].compat_value;
    fgInterlace = (BOOL)rArg.ai4Arg[3].compat_value;

    VENCOMX_DBG(" - phVenc = %p, eEncFmt = %d, eProfile = %d, fgInterlace = %d\n",
        phVenc, (int)eEncFmt, (int)eProfile, (int)fgInterlace);

    //add driver implementation code here
    switch (eEncFmt)
    {
    default:
        VENCOMX_DBG("Unknown eEncFmt(%d)\n", eEncFmt);
        return VENCR_NOT_OK;

    case VENCOMX_FMT_H264:
        u4Type = VENC_H264;
        break;

#ifdef CC_SUPPORT_VENC_VP8
    case VENCOMX_FMT_VP8:
        u4Type = VENC_VP8;
        break;
#endif
    }

    switch (eProfile)
    {
    default:
        VENCOMX_DBG("Unknown eProfile(%d)\n", eProfile);
        return VENCR_NOT_OK;

    case VENCOMX_AP_TYPE_SKYPE:
        eProfileSet = VENC_PROFILE_VPHONE;
        break;

    case VENCOMX_AP_TYPE_ATVPVR:
        eProfileSet = VENC_PROFILE_PVR;
        break;

    case VENCOMX_AP_TYPE_MSI:
        eProfileSet = VENC_PROFILE_MS;
        break;

    case VENCOMX_AP_TYPE_QQ:
        eProfileSet = VENC_PROFILE_VPHONE;
        break;
    }

    hEnc = VENC_Open(u4Type, eProfileSet, fgInterlace);

    if (VENC_NULL_HANDLE == hEnc)
    {
        VENCOMX_DBG("VENC_Open hEnc can be created\n");
        return VENCR_NOT_OK;

    }
    //get hEnc value from 1 to 32
    prVEncOmxInfo = _VENCGetInfoInst(( (UINT16)(UPTR)hEnc - 1));
    prVEncOmxInfo->hVEnc = hEnc;
    prVEncOmxInfo->fgIsRunning = FALSE;
    prVEncOmxInfo->ptFrmBuffMgr = NULL;

    rArg.ai4Arg[0].value = (void *)hEnc;

    if (VENC_NULL_HANDLE != hEnc)
    {
        eRet = VENCR_OK;
#ifdef CONFIG_COMPAT
        if (is_compat_task())
        {
            USR_SPACE_ACCESS_VALIDATE_ARG(phVenc,INT32);
            COPY_TO_USER_ARG(phVenc,hEnc,INT32);
        }
        else
#endif
        {
            USR_SPACE_ACCESS_VALIDATE_ARG(phVenc,VENC_HANDLE);
            COPY_TO_USER_ARG(phVenc,hEnc,VENC_HANDLE);
        }
    }
    return eRet;
}

// map from VENC_PIX_FMT_T to VENC_PIX_FMT_T
static VENC_PIX_FMT_T _VENC_PixFmtMap(VENCOMX_PIX_FMT_T ePixFmt)
{
    VENC_PIX_FMT_T eType = VENC_PIX_FMT_MAX;

    switch (ePixFmt)
    {
    case VENCOMX_PIX_FMT_NV21:
        eType = VENC_PIX_FMT_NV21;
        break;
    case VENCOMX_PIX_FMT_YV12:
        eType = VENC_PIX_FMT_YV12;
        break;
    case VENCOMX_PIX_FMT_NV12:
        eType = VENC_PIX_FMT_NV12;
        break;
    default:
        VENCOMX_DBG("Unknown ePixFmt(%d)\n", ePixFmt);
        eType = VENC_PIX_FMT_NV12;
        break;
    }

    return eType;
}


VENCOMX_RESULT_T _VENCOMX_SetParam(unsigned long arg)
{
    VENCOMX_IOCTL_3ARG_T rArg;
    VENCOMX_RESULT_T       eRet = VENCR_OK;
    VENC_HANDLE hEnc;
    VENCOMX_PRAM_T eParam;
    VOID *pvArg;
    UINT32 u4Ret = VENC_OK;
    VENCOMX_INFO_T *prVEncOmxInfo;

    USR_SPACE_ACCESS_VALIDATE_3ARG(arg);
    COPY_FROM_USER_3ARG(arg, rArg);

#ifdef CONFIG_COMPAT
    if (is_compat_task())
    {
        hEnc = (VENC_HANDLE)(compat_ptr(rArg.ai4Arg[0].compat_value));
    }
    else
#endif
    {
        hEnc = (VENC_HANDLE)rArg.ai4Arg[0].value;

    }
    eParam = (VENCOMX_PRAM_T)rArg.ai4Arg[1].compat_value;
#ifdef CONFIG_COMPAT
    if (is_compat_task())
    {
        pvArg = (VOID*)(compat_ptr(rArg.ai4Arg[2].compat_value));
    }
    else
#endif
    {
        pvArg = (VOID*)rArg.ai4Arg[2].value;

    }

    VENCOMX_DBG(" - eParam = %d hEnc 0x%x\n", (int)eParam,hEnc);
    prVEncOmxInfo = _VENCGetInfoInst(( (UINT16)(UPTR)hEnc - 1));
    if ((hEnc != prVEncOmxInfo->hVEnc) || (prVEncOmxInfo->hVEnc == VENC_NULL_HANDLE))
    {
        LOG(0, "[%s] Invaild hEnc 0x%08X\n", __FUNCTION__, hEnc);
        return VENCR_ERR_INV;
    }

    switch (eParam)
    {
    default:
        VENCOMX_DBG("Unknown eParam(%d)\n", eParam);
        return VENCR_NOT_OK;

    case VENCOMX_PRAM_FRAMERATE:
        if (!prVEncOmxInfo->fgIsRunning)
        {
            UINT32 u4Fps = (UPTR)pvArg;
            u4Ret = VENC_SetParam(hEnc, VENC_PRAM_FRAMERATE, &u4Fps);
            prVEncOmxInfo->u4Fps = u4Fps;
        }
        else
        {
            VENC_RT_PARM_T rRTParm;
            rRTParm.u4Flag      = VENC_RT_PARM_FLAG_FRAMERATE;
            rRTParm.u1Framerate = (UINT8)(UPTR)pvArg;

            u4Ret = (VENC_SMODE_SYNC == prVEncOmxInfo->u4SyncMode)
                ? VENC_SetRtParamSync(prVEncOmxInfo->hVEnc, &rRTParm)
                : VENC_SetRtParamAsync(prVEncOmxInfo->hVEnc, &rRTParm);
        }
        break;

    case VENCOMX_PRAM_BITRATE:
        if (!prVEncOmxInfo->fgIsRunning)
        {
            UINT32 u4Bps = (UPTR)pvArg;
            u4Ret = VENC_SetParam(hEnc, VENC_PRAM_BITRATE, &u4Bps);
            prVEncOmxInfo->u4Bps = u4Bps;
        }
        else
        {
            VENC_RT_PARM_T rRTParm;
            rRTParm.u4Flag      = VENC_RT_PARM_FLAG_BITRATE;
            rRTParm.u4Bitrate   = (UPTR)pvArg;

            u4Ret = (VENC_SMODE_SYNC == prVEncOmxInfo->u4SyncMode)
                ? VENC_SetRtParamSync(prVEncOmxInfo->hVEnc, &rRTParm)
                : VENC_SetRtParamAsync(prVEncOmxInfo->hVEnc, &rRTParm);
        }
        break;

    case VENCOMX_PRAM_PERIOD_OF_INTRA_FRAMES:
        if(!prVEncOmxInfo->fgIsRunning)
        {
            UINT32 u4PeroidOfIDR = (UPTR)pvArg;
            u4Ret = VENC_SetParam(hEnc,VENC_PRAM_PERIOD_OF_INTRA_FRAMES,&u4PeroidOfIDR);

        }
        else
        {
            //set param PeroidOfIDR during RealTime Encoding
        }
        break;

    case VENCOMX_PRAM_RESOLUTION:
        if (!prVEncOmxInfo->fgIsRunning)
        {
            VENCOMX_FRAME_RESOLUTION_T tResUsr;
            VENC_PRAM_RES_T res;

            x_memset(&tResUsr, 0, sizeof(tResUsr));
            USR_SPACE_ACCESS_VALIDATE_ARG(pvArg,VENCOMX_FRAME_RESOLUTION_T);
            COPY_FROM_USER_ARG(pvArg,tResUsr,VENCOMX_FRAME_RESOLUTION_T);

            res.u2Height = (UINT16)tResUsr.u4Height;
            res.u2Width = (UINT16)tResUsr.u4Width;
            u4Ret = VENC_SetParam(hEnc, VENC_PRAM_RESOLUTION, &res);
            prVEncOmxInfo->u4Width = tResUsr.u4Width;
            prVEncOmxInfo->u4Height = tResUsr.u4Height;
        }
        else
        {
            VENCOMX_FRAME_RESOLUTION_T tResUsr;
            VENC_RT_PARM_T rRTParm;

            x_memset(&tResUsr, 0, sizeof(tResUsr));
            USR_SPACE_ACCESS_VALIDATE_ARG(pvArg,VENCOMX_FRAME_RESOLUTION_T);
            COPY_FROM_USER_ARG(pvArg,tResUsr,VENCOMX_FRAME_RESOLUTION_T);

            //RESOLUTION
            rRTParm.u4Flag   = VENC_RT_PARM_FLAG_RES;
            rRTParm.u2Width  = (UINT16)tResUsr.u4Width;
            rRTParm.u2Height = (UINT16)tResUsr.u4Height;
            rRTParm.u2Pitch  = VENC_ALIGN_MASK(tResUsr.u4Width, 15);
                u4Ret = (VENC_SMODE_SYNC == prVEncOmxInfo->u4SyncMode)
                    ? VENC_SetRtParamSync(prVEncOmxInfo->hVEnc, &rRTParm)
                    : VENC_SetRtParamAsync(prVEncOmxInfo->hVEnc, &rRTParm);
            }
            break;

        case VENCOMX_PRAM_PIXAL:
            if (!prVEncOmxInfo->fgIsRunning)
            {
                VENCOMX_FRAME_PIXFMT_T tResUsr;
                VENC_PRAM_PIXFMT_T res;

                x_memset(&tResUsr, 0, sizeof(tResUsr));
                USR_SPACE_ACCESS_VALIDATE_ARG(pvArg,VENCOMX_FRAME_PIXFMT_T);
                COPY_FROM_USER_ARG(pvArg,tResUsr,VENCOMX_FRAME_PIXFMT_T);

                res.ePixFmt = _VENC_PixFmtMap(tResUsr.ePixFmt);
                res.u2Pitch  = VENC_ALIGN_MASK(tResUsr.u4Pitch, 15);
                u4Ret = VENC_SetParam(hEnc, VENC_PRAM_PIX_FMT, &res);
                prVEncOmxInfo->u4Pitch = tResUsr.u4Pitch;
                prVEncOmxInfo->ePixFmt = res.ePixFmt;
            }
            else
            {
                VENCOMX_FRAME_PIXFMT_T tResUsr;
                VENC_RT_PARM_T rRTParm;

                x_memset(&tResUsr, 0, sizeof(tResUsr));
                USR_SPACE_ACCESS_VALIDATE_ARG(pvArg,VENCOMX_FRAME_PIXFMT_T);
                COPY_FROM_USER_ARG(pvArg,tResUsr,VENCOMX_FRAME_PIXFMT_T);

                //RESOLUTION
                rRTParm.u4Flag   = VENC_RT_PARM_FLAG_PIXAL;
                rRTParm.ePixFmt = _VENC_PixFmtMap(tResUsr.ePixFmt);
                rRTParm.u2Pitch  = VENC_ALIGN_MASK(tResUsr.u4Pitch, 15);

            u4Ret = (VENC_SMODE_SYNC == prVEncOmxInfo->u4SyncMode)
                ? VENC_SetRtParamSync(prVEncOmxInfo->hVEnc, &rRTParm)
                : VENC_SetRtParamAsync(prVEncOmxInfo->hVEnc, &rRTParm);
        }
        break;

        case VENCOMX_PRAM_PROFILE_LEVEL:
            if(!prVEncOmxInfo->fgIsRunning)
            {
                VENCOMX_PROFILE_LEVEL_T  tPrfLvlUsr;
                VENC_H264_PRAM_PL_T      tPrfLvl;

                x_memset(&tPrfLvlUsr, 0, sizeof(tPrfLvlUsr));
                USR_SPACE_ACCESS_VALIDATE_ARG(pvArg,VENCOMX_PROFILE_LEVEL_T);
                COPY_FROM_USER_ARG(pvArg,tPrfLvlUsr,VENCOMX_PROFILE_LEVEL_T);

                tPrfLvl.u2Profile = (UINT16)tPrfLvlUsr.e_profile;
                tPrfLvl.u2Level   = (UINT16)tPrfLvlUsr.e_level;

                u4Ret = VENC_SetParam(hEnc,VENC_PRAM_PROFILELEVEL,&tPrfLvl);
            }
            break;
    }

    if (VENC_OK != u4Ret)
    {
        eRet = VENCR_NOT_OK;
        VENCOMX_DBG(" - fail(%d)!!\n", u4Ret);
    }

    return eRet;
}


// map from VENC_SMODE_T to VENC_SMODE_T
static VENC_SMODE_T _VENC_SyncModeMap(VENCOMX_SMODE_T eSmode)
{
    VENC_SMODE_T eType;

    switch (eSmode)
    {
    default:
        VENCOMX_DBG("Unknown eSmode(%d)\n", eSmode);
        eType = VENC_SMODE_DUAL;
        break;
    case VENCOMX_SMODE_SYNC:
        eType = VENC_SMODE_SYNC;
        break;
    case VENCOMX_SMODE_ASYNC:
        eType = VENC_SMODE_ASYNC;
        break;
    case VENCOMX_SMODE_DUAL:
        eType = VENC_SMODE_DUAL;
        break;
    case VENCOMX_SMODE_MAX:
        eType = VENC_SMODE_MAX;
        break;
    }

    return eType;
}

static VOID _Venc_GetThumbnailCb(VOID *pvTag, UPTR u4PhyAddr)
{
    VENCOMX_INFO_T *prVEncOmxInfo = (VENCOMX_INFO_T *)pvTag;
    VENCOMX_CB_T tVencCb;

    if (!prVEncOmxInfo)
    {
        ASSERT(prVEncOmxInfo);
        VENCOMX_DBG("prVEncOmxInfo is NULL!!!\n");
        return;
    }

    tVencCb.eCond = VENCOMX_COND_THUMBNAIL;
    tVencCb.u.u4ThumbnailPhyAddr = u4PhyAddr;
    _VENCOMX_Put_Event(prVEncOmxInfo, &tVencCb);
}

VENCOMX_RESULT_T _VENCOMX_SetCtrl(unsigned long arg)
{
    VENCOMX_IOCTL_3ARG_T rArg;
    VENCOMX_RESULT_T       eRet = VENCR_OK;
    VENC_HANDLE hEnc;
    VENCOMX_CTRL_T eCtrl;
    VOID *pvArg;
    UINT32 u4Ret;
    VENCOMX_INFO_T *prVEncOmxInfo;

    USR_SPACE_ACCESS_VALIDATE_3ARG(arg);
    COPY_FROM_USER_3ARG(arg, rArg);

#ifdef CONFIG_COMPAT
    if (is_compat_task())
    {
        hEnc = (VENC_HANDLE)(compat_ptr(rArg.ai4Arg[0].compat_value));
    }
    else
#endif
    {
        hEnc = (VENC_HANDLE)rArg.ai4Arg[0].value;

    }
    eCtrl = (VENCOMX_CTRL_T)rArg.ai4Arg[1].compat_value;
#ifdef CONFIG_COMPAT
    if (is_compat_task())
    {
        pvArg = (VOID*)(compat_ptr(rArg.ai4Arg[2].compat_value));
    }
    else
#endif
    {
        pvArg = (VOID*)rArg.ai4Arg[2].value;

    }

    VENCOMX_DBG(" - eCtrl = %d hEnc 0x%x\n",(int)eCtrl,hEnc);
    prVEncOmxInfo = _VENCGetInfoInst(( (UINT16)(UPTR)hEnc - 1));
    if ((hEnc != prVEncOmxInfo->hVEnc) || (prVEncOmxInfo->hVEnc == VENC_NULL_HANDLE))
    {
        LOG(0, "[%s] Invaild hEnc 0x%08X\n", __FUNCTION__, hEnc);
        return VENCR_ERR_INV;
    }

    switch (eCtrl)
    {
    default:
        VENCOMX_DBG("Unknown eCtrl(%d)\n", eCtrl);
        return VENCR_NOT_OK;

    case VENCOMX_CTRL_SYNC_MODE:
        {
            UINT32 u4Value = (UPTR)_VENC_SyncModeMap((VENCOMX_SMODE_T)pvArg);
            prVEncOmxInfo->u4SyncMode = u4Value;
            if(VENC_SMODE_ASYNC == prVEncOmxInfo->u4SyncMode)
            {
                if(NULL_HANDLE == prVEncOmxInfo->hVencMsgQ)
                {
                    CHAR szBuf[64];
                    x_snprintf(szBuf, sizeof(szBuf), "OMXEncQ%p", prVEncOmxInfo);
                    VERIFY(OSR_OK == x_msg_q_create(&prVEncOmxInfo->hVencMsgQ, szBuf, sizeof(VENCOMX_CB_T), 255));
                    VENCOMX_DBG("VENC_Open hEnc prVEncOmxInfo->hVencMsgQ 0x%x\n",prVEncOmxInfo->hVencMsgQ);
                }
            }
            u4Ret = VENC_SetCtrl(hEnc, VENC_CTRL_SYNC_MODE, &u4Value);
        }
        break;

    case VENCOMX_CTRL_PIX_FMT:
        {
            VENCOMX_CTRL_PIXFMT_T tPixUsr;
            VENC_CTRL_PIXFMT_T pix;

            x_memset(&tPixUsr, 0, sizeof(tPixUsr));
            USR_SPACE_ACCESS_VALIDATE_ARG(pvArg,VENCOMX_CTRL_PIXFMT_T);
            COPY_FROM_USER_ARG(pvArg,tPixUsr,VENCOMX_CTRL_PIXFMT_T);

            pix.ePixFmt = _VENC_PixFmtMap(tPixUsr.ePixFmt);
            pix.u2Pitch = (UINT16)tPixUsr.u4Pitch;

            prVEncOmxInfo->ePixFmt = pix.ePixFmt;
            prVEncOmxInfo->u4Pitch = pix.u2Pitch;

            u4Ret = VENC_SetCtrl(hEnc, VENC_CTRL_PIX_FMT, &pix);
        }
        break;

    case VENCOMX_CTRL_GET_THUMBNAIL:
        {
            VENCOMX_CTRL_THUMBNAIL_T rThumbnailUsr;
            VENC_CTRL_THUMBNAIL_T rThumbnail;

            x_memset(&rThumbnailUsr, 0, sizeof(rThumbnailUsr));
            USR_SPACE_ACCESS_VALIDATE_ARG(pvArg,VENCOMX_CTRL_PIXFMT_T);
            COPY_FROM_USER_ARG(pvArg,rThumbnailUsr,VENCOMX_CTRL_PIXFMT_T);

            rThumbnail.u4Width = rThumbnailUsr.u4Width;
            rThumbnail.u4Height = rThumbnailUsr.u4Height;
            rThumbnail.pvTag = prVEncOmxInfo;
            rThumbnail.cb = (VOID *)_Venc_GetThumbnailCb;

            u4Ret = VENC_SetCtrl(hEnc, VENC_CTRL_GET_THUMBNAIL, &rThumbnail);
        }
        break;
    }

    if (VENC_OK != u4Ret)
    {
        eRet = VENCR_NOT_OK;
        VENCOMX_DBG(" - fail(%d)!!\n", u4Ret);
    }

    return eRet;
}


VENCOMX_RESULT_T _VENCOMX_DrvInit(unsigned long arg)
{
    VENC_HANDLE hEnc = (VENC_HANDLE)arg;
    UINT32 u4Ret;

    VENCOMX_DBG(" - hEnc = %p\n", hEnc);

    u4Ret = VENC_Init(hEnc);

    if (VENC_OK != u4Ret)
    {
        VENCOMX_DBG("VENC_Init fail(%d)!!\n", u4Ret);
        return VENCR_NOT_OK;
    }

    return VENCR_OK;
}


VENCOMX_RESULT_T _VENCOMX_Run(unsigned long arg)
{
    VENC_HANDLE hEnc = (VENC_HANDLE)arg;
    VENCOMX_INFO_T *prVEncOmxInfo;
    UINT32 u4Ret;

    VENCOMX_DBG(" - hEnc = %p\n", hEnc);
    prVEncOmxInfo = _VENCGetInfoInst(( (UINT16)(UPTR)hEnc - 1));
    if ((hEnc != prVEncOmxInfo->hVEnc) || (prVEncOmxInfo->hVEnc == VENC_NULL_HANDLE))
    {
        LOG(0, "[%s] Invaild hEnc 0x%08X\n", __FUNCTION__, hEnc);
        return VENCR_ERR_INV;
    }

    u4Ret = VENC_Run(hEnc);

    if (VENC_OK != u4Ret)
    {
        VENCOMX_DBG("VENC_Run fail(%d)!!\n", u4Ret);
        return VENCR_NOT_OK;
    }

    prVEncOmxInfo->fgIsRunning = TRUE;

    return VENCR_OK;
}


VENCOMX_RESULT_T _VENCOMX_Stop(unsigned long arg)
{
    VENC_HANDLE hEnc = (VENC_HANDLE)arg;
    VENCOMX_INFO_T *prVEncOmxInfo;
    UINT32 u4Ret;

    VENCOMX_DBG(" - hEnc = %p\n", hEnc);
    prVEncOmxInfo = _VENCGetInfoInst(( (UINT16)(UPTR)hEnc - 1));
    if ((hEnc != prVEncOmxInfo->hVEnc) || (prVEncOmxInfo->hVEnc == VENC_NULL_HANDLE))
    {
        LOG(0, "[%s] Invaild hEnc 0x%08X\n", __FUNCTION__, hEnc);
        return VENCR_ERR_INV;
    }

    if (prVEncOmxInfo->fgIsRunning)
    {
        u4Ret = VENC_Stop(hEnc);

        if (VENC_OK != u4Ret)
        {
            VENCOMX_DBG("VENC_Stop fail(%d)!!\n", u4Ret);
            return VENCR_NOT_OK;
        }
        {
            VENCOMX_CB_T tVencCb;
            tVencCb.tStatus   = VENCOMX_STATUS_STOP;
            _VENCOMX_Put_Event(prVEncOmxInfo,&tVencCb);
        }
        prVEncOmxInfo->fgIsRunning = FALSE;
    }

    return VENCR_OK;
}


VENCOMX_RESULT_T _VENCOMX_Close(unsigned long arg)
{
    VENC_HANDLE hEnc = (VENC_HANDLE)arg;
    VENCOMX_INFO_T *prVEncOmxInfo;
    UINT32 u4Ret;

    VENCOMX_DBG(" - hEnc = %p\n",hEnc);
    prVEncOmxInfo = _VENCGetInfoInst(( (UINT16)(UPTR)hEnc - 1));
    if ((hEnc != prVEncOmxInfo->hVEnc) || (prVEncOmxInfo->hVEnc == VENC_NULL_HANDLE))
    {
        LOG(0, "[%s] Invaild hEnc 0x%08X\n", __FUNCTION__, hEnc);
        return VENCR_ERR_INV;
    }

    if (prVEncOmxInfo->fgIsRunning)
    {
        u4Ret = VENC_Stop(hEnc);

        if (VENC_OK != u4Ret)
        {
            VENCOMX_DBG("VENC_Stop fail(%d)!!\n", u4Ret);
            return VENCR_NOT_OK;
        }

        prVEncOmxInfo->fgIsRunning = FALSE;
    }

    u4Ret = VENC_Close(hEnc);
    if(VENC_SMODE_ASYNC == prVEncOmxInfo->u4SyncMode)
    {
        if(NULL_HANDLE != prVEncOmxInfo->hVencMsgQ)
        {
            VENCOMX_DBG("VENC_Close hEnc prVEncOmxInfo->hVencMsgQ 0x%x\n",prVEncOmxInfo->hVencMsgQ);
            VERIFY(x_msg_q_delete(prVEncOmxInfo->hVencMsgQ)== OSR_OK);
            prVEncOmxInfo->hVencMsgQ = NULL_HANDLE;
        }
    }

    prVEncOmxInfo->hVEnc = VENC_NULL_HANDLE;

    if (VENC_OK != u4Ret)
    {
        VENCOMX_DBG("VENC_Close fail(%d)!!\n", u4Ret);
        return VENCR_NOT_OK;
    }
    x_memset((VOID *)prVEncOmxInfo, 0, sizeof(VENCOMX_INFO_T));
    prVEncOmxInfo->ucMxId = 0xFF;

    return VENCR_OK;
}


VENCOMX_RESULT_T _VENCOMX_EncSeqHdrSync(unsigned long arg)
{
    VENCOMX_IOCTL_2ARG_T rArg;
    VENC_HANDLE hEnc;
    UINT32 u4Ret;
    VENCOMX_OUT_PIC_T *ptOutUsr, tOutKrnl;
    VENC_OUT_PIC_T tOut;
    VENCOMX_INFO_T *prVEncOmxInfo;

    USR_SPACE_ACCESS_VALIDATE_2ARG(arg);
    COPY_FROM_USER_2ARG(arg, rArg);
#ifdef CONFIG_COMPAT
    if (is_compat_task())
    {
        hEnc = (VENC_HANDLE)(compat_ptr(rArg.ai4Arg[0].compat_value));
    }
    else
#endif
    {
        hEnc = (VENC_HANDLE)rArg.ai4Arg[0].value;

    }
#ifdef CONFIG_COMPAT
    if (is_compat_task())
    {
        ptOutUsr = (VENCOMX_OUT_PIC_T *)(compat_ptr(rArg.ai4Arg[1].compat_value));
    }
    else
#endif
    {
        ptOutUsr = (VENCOMX_OUT_PIC_T *)rArg.ai4Arg[1].value;

    }

    prVEncOmxInfo = _VENCGetInfoInst(( (UINT16)(UPTR)hEnc - 1));
    if ((hEnc != prVEncOmxInfo->hVEnc) || (prVEncOmxInfo->hVEnc == VENC_NULL_HANDLE))
    {
        LOG(0, "[%s] Invaild hEnc 0x%08X\n", __FUNCTION__, hEnc);
        return VENCR_ERR_INV;
    }

    x_memset(&tOutKrnl, 0, sizeof(tOutKrnl));
    USR_SPACE_ACCESS_VALIDATE_ARG(ptOutUsr,VENCOMX_OUT_PIC_T);
    COPY_FROM_USER_ARG(ptOutUsr,tOutKrnl,VENCOMX_OUT_PIC_T);
    x_memset(&tOut, 0, sizeof(tOut));
    tOut.u4Pts    = tOutKrnl.u4Pts;
    tOut.u4Addr   = tOutKrnl.u4Addr;
    tOut.u4Size   = tOutKrnl.u4Size;
    tOut.u4RStart = tOutKrnl.u4RStart;
    tOut.u4REnd   = tOutKrnl.u4REnd;

    u4Ret = VENC_EncSeqHdrSync(hEnc, &tOut);

    if (VENC_OK != u4Ret)
    {
        VENCOMX_DBG("VENC_EncSeqHdrSync fail(%d)!!\n", u4Ret);
        return VENCR_NOT_OK;
    }

    tOutKrnl.u4Pts    = tOut.u4Pts;
    tOutKrnl.u4Addr   = tOut.u4Addr;
    tOutKrnl.u4Size   = tOut.u4Size;
    tOutKrnl.u4RStart = tOut.u4RStart;
    tOutKrnl.u4REnd   = tOut.u4REnd;
    USR_SPACE_ACCESS_VALIDATE_ARG(ptOutUsr,VENCOMX_OUT_PIC_T);
    COPY_TO_USER_ARG(ptOutUsr,tOutKrnl,VENCOMX_OUT_PIC_T);

    return VENCR_OK;
}


VENCOMX_RESULT_T _VENCOMX_EncFrameSync(unsigned long arg)
{
    VENCOMX_IOCTL_3ARG_T rArg;
    VENC_HANDLE hEnc;
    UINT32 u4Ret;
    VENCOMX_IN_PIC_T *ptInUsr, tInKrnl;
    VENCOMX_OUT_PIC_T *ptOutUsr, tOutKrnl;
    VENC_IN_PIC_T tIn;
    VENC_OUT_PIC_T tOut;
    VENCOMX_INFO_T *prVEncOmxInfo;

    USR_SPACE_ACCESS_VALIDATE_3ARG(arg);
    COPY_FROM_USER_3ARG(arg, rArg);
#ifdef CONFIG_COMPAT
    if (is_compat_task())
    {
        hEnc = (VENC_HANDLE)(compat_ptr(rArg.ai4Arg[0].compat_value));
    }
    else
#endif
    {
        hEnc = (VENC_HANDLE)rArg.ai4Arg[0].value;

    }
#ifdef CONFIG_COMPAT
    if (is_compat_task())
    {
        ptInUsr = (VENCOMX_IN_PIC_T *)(compat_ptr(rArg.ai4Arg[1].compat_value));
    }
    else
#endif
    {
        ptInUsr = (VENCOMX_IN_PIC_T *)rArg.ai4Arg[1].value;

    }
#ifdef CONFIG_COMPAT
    if (is_compat_task())
    {
        ptOutUsr = (VENCOMX_OUT_PIC_T *)(compat_ptr(rArg.ai4Arg[2].compat_value));
    }
    else
#endif
    {
        ptOutUsr = (VENCOMX_OUT_PIC_T *)rArg.ai4Arg[2].value;

    }

    prVEncOmxInfo = _VENCGetInfoInst(( (UINT16)(UPTR)hEnc - 1));
    if ((hEnc != prVEncOmxInfo->hVEnc) || (prVEncOmxInfo->hVEnc == VENC_NULL_HANDLE))
    {
        LOG(0, "[%s] Invaild hEnc 0x%08X\n", __FUNCTION__, hEnc);
        return VENCR_ERR_INV;
    }

    x_memset(&tInKrnl, 0, sizeof(tInKrnl));
    USR_SPACE_ACCESS_VALIDATE_ARG(ptInUsr,VENCOMX_IN_PIC_T);
    COPY_FROM_USER_ARG(ptInUsr,tInKrnl,VENCOMX_IN_PIC_T);
    x_memset(&tIn, 0, sizeof(tIn));
    tIn.u4YAddr = tInKrnl.u4YAddr;
    tIn.u4CAddr = tInKrnl.u4CAddr;
    tIn.u4Pts   = tInKrnl.u4Pts;

    x_memset(&tOutKrnl, 0, sizeof(tOutKrnl));
    USR_SPACE_ACCESS_VALIDATE_ARG(ptOutUsr,VENCOMX_OUT_PIC_T);
    COPY_FROM_USER_ARG(ptOutUsr,tOutKrnl,VENCOMX_OUT_PIC_T);
    x_memset(&tOut, 0, sizeof(tOut));
    tOut.u4Pts    = tOutKrnl.u4Pts;
    tOut.u4Addr   = tOutKrnl.u4Addr;
    tOut.u4Size   = tOutKrnl.u4Size;
    tOut.u4RStart = tOutKrnl.u4RStart;
    tOut.u4REnd   = tOutKrnl.u4REnd;

    u4Ret = VENC_EncFrameSync(hEnc, &tIn, &tOut);

    if (VENC_OK != u4Ret)
    {
        VENCOMX_DBG("VENC_EncFrameSync fail(%d)!!\n", u4Ret);
        return VENCR_NOT_OK;
    }

    tOutKrnl.u4Pts    = tOut.u4Pts;
    tOutKrnl.u4Addr   = tOut.u4Addr;
    tOutKrnl.u4Size   = tOut.u4Size;
    tOutKrnl.u4RStart = tOut.u4RStart;
    tOutKrnl.u4REnd   = tOut.u4REnd;
    tOutKrnl.eType    = tOut.u4Type;
    USR_SPACE_ACCESS_VALIDATE_ARG(ptOutUsr,VENCOMX_OUT_PIC_T);
    COPY_TO_USER_ARG(ptOutUsr,tOutKrnl,VENCOMX_OUT_PIC_T);

    return VENCR_OK;
}


VENCOMX_RESULT_T _VENCOMX_EncFrameAsync(unsigned long arg)
{
    VENCOMX_IOCTL_2ARG_T rArg;
    VENC_HANDLE hEnc;
    UINT32 u4Ret;
    VENCOMX_IN_PIC_T *ptInUsr, tInKrnl;
    VENC_IN_PIC_T tIn;
    VENCOMX_INFO_T *prVEncOmxInfo;

    USR_SPACE_ACCESS_VALIDATE_2ARG(arg);
    COPY_FROM_USER_2ARG(arg, rArg);

#ifdef CONFIG_COMPAT
    if (is_compat_task())
    {
        hEnc = (VENC_HANDLE)(compat_ptr(rArg.ai4Arg[0].compat_value));
    }
    else
#endif
    {
        hEnc = (VENC_HANDLE)rArg.ai4Arg[0].value;

    }
#ifdef CONFIG_COMPAT
    if (is_compat_task())
    {
        ptInUsr = (VENCOMX_IN_PIC_T *)(compat_ptr(rArg.ai4Arg[1].compat_value));
    }
    else
#endif
    {
        ptInUsr = (VENCOMX_IN_PIC_T *)rArg.ai4Arg[1].value;

    }

    prVEncOmxInfo = _VENCGetInfoInst(( (UINT16)(UPTR)hEnc - 1));
    if ((hEnc != prVEncOmxInfo->hVEnc) || (prVEncOmxInfo->hVEnc == VENC_NULL_HANDLE))
    {
        LOG(0, "[%s] Invaild hEnc 0x%08X\n", __FUNCTION__, hEnc);
        return VENCR_ERR_INV;
    }
    USR_SPACE_ACCESS_VALIDATE_ARG(ptInUsr,VENCOMX_IN_PIC_T);
    COPY_FROM_USER_ARG(ptInUsr,tInKrnl,VENCOMX_IN_PIC_T);

    tIn.u4YAddr = tInKrnl.u4YAddr;
    tIn.u4CAddr = tInKrnl.u4CAddr;
    tIn.u4Pts   = tInKrnl.u4Pts;
    tIn.fgEos   = tInKrnl.fgEos;
#ifdef VENC_TIME_PROFILE
    HAL_GetTime(&tIn.rTimeHwS);
    LOG(3, "as u4Pts %d %u.%06u s \n",
        tIn.u4Pts,tIn.rTimeHwS.u4Seconds, tIn.rTimeHwS.u4Micros);
#endif
    VENCOMX_DBG("VENC_EncFrameAsync tIn.u4YAddr(0x%x)!!\n", tIn.u4YAddr);
    VENCOMX_DBG("VENC_EncFrameAsync tIn.u4CAddr(0x%x)!!\n", tIn.u4CAddr);
    VENCOMX_DBG("VENC_EncFrameAsync tIn.u4Pts(0x%x)!!\n", tIn.u4Pts);
    VENCOMX_DBG("VENC_EncFrameAsync tIn.fgEos(0x%x)!!\n", tIn.fgEos);

    u4Ret = VENC_EncFrameAsync(hEnc, &tIn, NULL);

    if (VENC_OK != u4Ret)
    {
        VENCOMX_DBG("VENC_EncFrameAsync fail(%d)!!\n", u4Ret);
        return VENCR_NOT_OK;
    }

    return VENCR_OK;
}


VENCOMX_RESULT_T _VENCOMX_CreateBuffMgr(unsigned long arg)
{
    VENCOMX_IOCTL_2ARG_T rArg;
    VENC_HANDLE hEnc;
    VENCOMX_HANDLE *ptFrmBuffMgrUsr;
    VENC_FRM_T rFrm;
    UINT32 u4Idx, u4Size;
    VENC_CTRL_BUFF_T buff;
    VENCOMX_INFO_T *prVEncOmxInfo;

    USR_SPACE_ACCESS_VALIDATE_2ARG(arg);
    COPY_FROM_USER_2ARG(arg, rArg);
#ifdef CONFIG_COMPAT
    if (is_compat_task())
    {
        hEnc = (VENC_HANDLE)(compat_ptr(rArg.ai4Arg[0].compat_value));
    }
    else
#endif
    {
        hEnc = (VENC_HANDLE)rArg.ai4Arg[0].value;

    }
#ifdef CONFIG_COMPAT
    if (is_compat_task())
    {
        ptFrmBuffMgrUsr = (VENCOMX_HANDLE *)(compat_ptr(rArg.ai4Arg[1].compat_value));
    }
    else
#endif
    {
        ptFrmBuffMgrUsr = (VENCOMX_HANDLE *)rArg.ai4Arg[1].value;

    }

    VENCOMX_DBG(" - hEnc = %p\n",hEnc);
    prVEncOmxInfo = _VENCGetInfoInst(( (UINT16)(UPTR)hEnc - 1));

    if(NULL == prVEncOmxInfo)
    {
        VENCOMX_DBG(" NULL == prVEncOmxInfo\n");
        return VENCR_NOT_OK;
    }

    if ((hEnc != prVEncOmxInfo->hVEnc) || (prVEncOmxInfo->hVEnc == VENC_NULL_HANDLE))
    {
        LOG(0, "[%s] Invaild hEnc 0x%08X\n", __FUNCTION__, hEnc);
        return VENCR_ERR_INV;
    }

    //raw data buffer
    ASSERT(NULL == prVEncOmxInfo->ptFrmBuffMgr);
    prVEncOmxInfo->ptFrmBuffMgr = (VENC_BUFMGR_BASE_T *)VENC_BUFMGR_OBJ_CREATE(VENC_FRM);
    if (NULL == prVEncOmxInfo->ptFrmBuffMgr)
    {
        ASSERT(prVEncOmxInfo->ptFrmBuffMgr);
        return VENCR_NOT_OK;
    }

    _BUFMGR_OBJ_Reset(prVEncOmxInfo->ptFrmBuffMgr);

    u4Size = VENC_ALIGN_MASK(prVEncOmxInfo->u4Width, 15) * VENC_ALIGN_MASK(prVEncOmxInfo->u4Height, 31);
    //jump the first mem for scale used
    for (u4Idx = 0; u4Idx < VENCOMX_BUFMGR_MAXBUFFERCNT; u4Idx++)
    {
        //use getctrl to get mem
        buff.u4Addr = 0;
        buff.u4Size = u4Size + (u4Size >> 1);;

        VENCOMX_DBG( "\t Y Buff: u4Size0x%x\n", u4Size);
        if (VENC_OK == VENC_GetCtrl(hEnc, VENC_CTRL_INT_GET_BUFFER,(VOID*)&buff))
        {
            VENCOMX_DBG( "\tY Buff: from 0x%x to 0x%x\n", buff.u4Addr, buff.u4Addr + buff.u4Size);
        }
        else
        {
            VENCOMX_DBG("- Set buffer error!\n");
            return VENCR_NOT_OK;
        }

        rFrm.u4YAddr  = buff.u4Addr;
        buff.u4Addr += u4Size;
        buff.u4Size = (u4Size >> 1);

        VENCOMX_DBG( "\t C Buff: u4Size0x%x\n", (u4Size >> 1));
        rFrm.u4UVAddr = buff.u4Addr;
        _BUFMGR_OBJ_Add(prVEncOmxInfo->ptFrmBuffMgr, &rFrm);
    }
#ifdef CONFIG_COMPAT
    if (is_compat_task())
    {
        USR_SPACE_ACCESS_VALIDATE_ARG(ptFrmBuffMgrUsr,INT32);
        COPY_TO_USER_ARG(ptFrmBuffMgrUsr,prVEncOmxInfo->hVEnc,INT32);

        VENCOMX_DBG( "prVEncOmxInfo->hVEnc %x\n", prVEncOmxInfo->hVEnc);
    }
    else
#endif
    {
        USR_SPACE_ACCESS_VALIDATE_ARG(ptFrmBuffMgrUsr,VENC_HANDLE);
        COPY_TO_USER_ARG(ptFrmBuffMgrUsr,prVEncOmxInfo->hVEnc,VENC_HANDLE);
    }

    return VENCR_OK;
}


VENCOMX_RESULT_T _VENCOMX_DeleteBuffMgr(unsigned long arg)
{
    VENCOMX_IOCTL_2ARG_T rArg;
    VENC_HANDLE hEnc;
    VENC_BUFMGR_BASE_T *ptFrmBuffMgr;
    VENCOMX_INFO_T *prVEncOmxInfo;

    USR_SPACE_ACCESS_VALIDATE_2ARG(arg);
    COPY_FROM_USER_2ARG(arg, rArg);
#ifdef CONFIG_COMPAT
    if (is_compat_task())
    {
        hEnc = (VENC_HANDLE)(compat_ptr(rArg.ai4Arg[0].compat_value));
    }
    else
#endif
    {
        hEnc = (VENC_HANDLE)rArg.ai4Arg[0].value;

    }

#ifdef CONFIG_COMPAT
    if (is_compat_task())
    {
        ptFrmBuffMgr = (VENC_BUFMGR_BASE_T *)(compat_ptr(rArg.ai4Arg[1].compat_value));
    }
    else
#endif
    {
        ptFrmBuffMgr = (VENC_BUFMGR_BASE_T *)rArg.ai4Arg[1].value;

    }

    VENCOMX_DBG(" - hEnc = %p\n", hEnc);
    prVEncOmxInfo = _VENCGetInfoInst(( (UINT16)(UPTR)hEnc - 1));
    if ((hEnc != prVEncOmxInfo->hVEnc) || (prVEncOmxInfo->hVEnc == VENC_NULL_HANDLE))
    {
        LOG(0, "[%s] Invaild hEnc 0x%08X\n", __FUNCTION__, hEnc);
        return VENCR_ERR_INV;
    }

    if (ptFrmBuffMgr != prVEncOmxInfo->hVEnc)
    {
        LOG(0, "[%s] Invaild ptFrmBuffMgr 0x%08X, hVEnc=%0x%08X\n", __FUNCTION__, ptFrmBuffMgr, prVEncOmxInfo->hVEnc);
        ASSERT(ptFrmBuffMgr == prVEncOmxInfo->hVEnc);
        return VENCR_ERR_INV;
    }
    if (prVEncOmxInfo->ptFrmBuffMgr)
    {
        VENC_BUFMGR_OBJ_DELETE(VENC_FRM, (VENC_BUFMGR_T(VENC_FRM) *)(prVEncOmxInfo->ptFrmBuffMgr));
        prVEncOmxInfo->ptFrmBuffMgr = NULL;
    }

    return VENCR_OK;
}


VENCOMX_RESULT_T _VENCOMX_BUFMGR_OBJ_Get(unsigned long arg)
{
    VENCOMX_IOCTL_4ARG_T rArg;
    VENC_BUFMGR_BASE_T *ptFrmBuffMgr = NULL;
    VENCOMX_IN_PIC_T *ptDataUsr = NULL, tDataKrnl;
    UINT32 u4Option;
    VENCOMX_INFO_T *prVEncOmxInfo = NULL;
    VENC_FRM_T tFrm;
    UINT32 u4Ret = VENC_BUFMGR_FAIL;
    VENC_HANDLE hEnc;

    x_memset(&tDataKrnl, 0, sizeof(VENCOMX_IN_PIC_T));

    USR_SPACE_ACCESS_VALIDATE_4ARG(arg);
    COPY_FROM_USER_4ARG(arg, rArg);
#ifdef CONFIG_COMPAT
    if (is_compat_task())
    {
        hEnc = (VENC_HANDLE)(compat_ptr(rArg.ai4Arg[0].compat_value));
    }
    else
#endif
    {
        hEnc = (VENC_HANDLE)rArg.ai4Arg[0].value;

    }


#ifdef CONFIG_COMPAT
    if (is_compat_task())
    {
        ptFrmBuffMgr = (VENC_BUFMGR_BASE_T *)(compat_ptr(rArg.ai4Arg[1].compat_value));
    }
    else
#endif
    {
        ptFrmBuffMgr = (VENC_BUFMGR_BASE_T *)rArg.ai4Arg[1].value;

    }
#ifdef CONFIG_COMPAT
    if (is_compat_task())
    {
        ptDataUsr = (VENCOMX_IN_PIC_T *)(compat_ptr(rArg.ai4Arg[2].compat_value));
    }
    else
#endif
    {
        ptDataUsr = (VENCOMX_IN_PIC_T *)rArg.ai4Arg[2].value;

    }
    u4Option = (UPTR)rArg.ai4Arg[3].compat_value;

    VENCOMX_DBG(" - hEnc = %p\n", hEnc);
    prVEncOmxInfo = _VENCGetInfoInst(( (UINT16)(UPTR)hEnc - 1));
    VENCOMX_DBG(" - ptFrmBuffMgr = %d\n",ptFrmBuffMgr);
    if (ptFrmBuffMgr != prVEncOmxInfo->hVEnc)
    {
        LOG(0, "[%s] Invaild ptFrmBuffMgr 0x%08X\n", __FUNCTION__, ptFrmBuffMgr);
        ASSERT(ptFrmBuffMgr == prVEncOmxInfo->hVEnc);
        return VENCR_ERR_INV;
    }
    switch (u4Option)
    {
    default:
        VENCOMX_DBG("Unknown u4Option(%d)\n", u4Option);
        return VENCR_NOT_OK;
    case VENCOMX_BUFMGR_NOWAIT:
        u4Option = VENC_BUFMGR_NOWAIT;
        break;
    case VENCOMX_BUFMGR_WAIT:
        u4Option = VENC_BUFMGR_WAIT;
        break;
    }

    VENCOMX_DBG(" - ptFrmBuffMgr = %d\n",ptFrmBuffMgr);
    u4Ret = _BUFMGR_OBJ_Get(prVEncOmxInfo->ptFrmBuffMgr, (VOID *)&tFrm, u4Option);
    VENCOMX_DBG(" - ptFrmBuffMgr = %d\n",ptFrmBuffMgr);
    if (VENC_BUFMGR_OK != u4Ret)
    {
        VENCOMX_DBG("_BUFMGR_OBJ_Get fail(%d)\n", u4Ret);
        return VENCR_NOT_OK;
    }

    tDataKrnl.u4YAddr = tFrm.u4YAddr;
    tDataKrnl.u4CAddr= tFrm.u4UVAddr;
    USR_SPACE_ACCESS_VALIDATE_ARG(ptDataUsr,VENCOMX_IN_PIC_T);
    COPY_TO_USER_ARG(ptDataUsr,tDataKrnl,VENCOMX_IN_PIC_T);
    VENCOMX_DBG(" - tDataKrnl.u4YAddr = 0x%x\n",tDataKrnl.u4YAddr);
    VENCOMX_DBG(" - tDataKrnl.u4CAddr = 0x%x\n",tDataKrnl.u4CAddr);

    return VENCR_OK;
}


VENCOMX_RESULT_T _VENCOMX_BUFMGR_OBJ_Free(unsigned long arg)
{
    VENCOMX_IOCTL_3ARG_T rArg;
    VENC_BUFMGR_BASE_T *ptFrmBuffMgr;
    VENCOMX_IN_PIC_T *ptDataUsr, tDataKrnl;
    VENCOMX_INFO_T *prVEncOmxInfo;
    VENC_FRM_T tFrm;
    UINT32 u4Ret = VENC_BUFMGR_FAIL;
    VENC_HANDLE hEnc;

    USR_SPACE_ACCESS_VALIDATE_3ARG(arg);
    COPY_FROM_USER_3ARG(arg, rArg);

#ifdef CONFIG_COMPAT
    if (is_compat_task())
    {
        hEnc = (VENC_HANDLE)(compat_ptr(rArg.ai4Arg[0].compat_value));
    }
    else
#endif
    {
        hEnc = (VENC_HANDLE)rArg.ai4Arg[0].value;

    }
#ifdef CONFIG_COMPAT
    if (is_compat_task())
    {
        ptFrmBuffMgr = (VENC_BUFMGR_BASE_T *)(compat_ptr(rArg.ai4Arg[1].compat_value));
    }
    else
#endif
    {
        ptFrmBuffMgr = (VENC_BUFMGR_BASE_T *)rArg.ai4Arg[1].value;

    }
#ifdef CONFIG_COMPAT
    if (is_compat_task())
    {
        ptDataUsr = (VENCOMX_IN_PIC_T *)(compat_ptr(rArg.ai4Arg[2].compat_value));
    }
    else
#endif
    {
        ptDataUsr = (VENCOMX_IN_PIC_T *)rArg.ai4Arg[2].value;

    }

    USR_SPACE_ACCESS_VALIDATE_ARG(ptDataUsr,VENCOMX_IN_PIC_T);
    COPY_FROM_USER_ARG(ptDataUsr,tDataKrnl,VENCOMX_IN_PIC_T);
    tFrm.u4YAddr = tDataKrnl.u4YAddr;
    tFrm.u4UVAddr = tDataKrnl.u4CAddr;

    VENCOMX_DBG(" - hEnc = %p\n",hEnc);
    prVEncOmxInfo = _VENCGetInfoInst(( (UINT16)(UPTR)hEnc - 1));
    if (ptFrmBuffMgr != prVEncOmxInfo->hVEnc)
    {
        LOG(0, "[%s] Invaild ptFrmBuffMgr 0x%08X\n", __FUNCTION__, ptFrmBuffMgr);
        ASSERT(ptFrmBuffMgr == prVEncOmxInfo->hVEnc);
        return VENCR_ERR_INV;
    }
    u4Ret = _BUFMGR_OBJ_Free(prVEncOmxInfo->ptFrmBuffMgr, (VOID *)&tFrm);
    if (VENC_BUFMGR_OK != u4Ret)
    {
        VENCOMX_DBG("_BUFMGR_OBJ_Free fail(%d)\n", u4Ret);
        return VENCR_NOT_OK;
    }

    return VENCR_OK;
}


VENCOMX_RESULT_T _VENCOMX_FlushFb(unsigned long arg)
{
    VENCOMX_IOCTL_3ARG_T rArg;
    UINT32 u4YAddr, u4CAddr, u4FrmSz;

    USR_SPACE_ACCESS_VALIDATE_3ARG(arg);
    COPY_FROM_USER_3ARG(arg, rArg);
    u4YAddr = (UPTR)rArg.ai4Arg[0].compat_value;
    u4CAddr = (UPTR)rArg.ai4Arg[1].compat_value;
    u4FrmSz = (UPTR)rArg.ai4Arg[2].compat_value;

    HalFlushDCacheMultipleLine(VIRTUAL(u4YAddr), u4FrmSz);
    HalFlushDCacheMultipleLine(VIRTUAL(u4CAddr), u4FrmSz >> 1);

    return VENCR_OK;
}


VENCOMX_RESULT_T _VENCOMX_InsertKeyframe(unsigned long arg)
{
    VENC_HANDLE hEnc = (VENC_HANDLE)arg;
    VENC_RT_CTRL_T tCtrl;
    UINT32 u4Ret;
    VENCOMX_INFO_T *prVEncOmxInfo;

    VENCOMX_DBG(" - hEnc = %p\n",hEnc);
    prVEncOmxInfo = _VENCGetInfoInst(( (UINT16)(UPTR)hEnc - 1));
    if ((hEnc != prVEncOmxInfo->hVEnc) || (prVEncOmxInfo->hVEnc == VENC_NULL_HANDLE))
    {
        LOG(0, "[%s] Invaild hEnc 0x%08X\n", __FUNCTION__, hEnc);
        return VENCR_ERR_INV;
    }

    tCtrl.u4Flag = VENC_RT_CTRL_FLAG_INSERT_KEYFRAME;

    if (VENC_SMODE_SYNC == prVEncOmxInfo->u4SyncMode)
    {
        u4Ret = VENC_SetRtCtrlSync(hEnc, &tCtrl);
    }
    else
    {
        u4Ret = VENC_SetRtCtrlAsync(hEnc, &tCtrl);
    }

    if (VENC_OK != u4Ret)
    {
        VENCOMX_DBG("VENC_RT_CTRL_FLAG_INSERT_KEYFRAME fail(%d)!!\n", u4Ret);
        return VENCR_NOT_OK;
    }

    return VENCR_OK;
}


VENCOMX_RESULT_T _VENCOMX_RegCb(unsigned long arg)
{
    VENC_HANDLE hEnc = (VENC_HANDLE)arg;
    UINT32 u4Ret;
    VENCOMX_INFO_T *prVEncOmxInfo;
    VENC_CTRL_OUTCB_T rCb;

    VENCOMX_DBG(" - hEnc = %p\n",hEnc);
    prVEncOmxInfo = _VENCGetInfoInst(( (UINT16)(UPTR)hEnc - 1));
    if ((hEnc != prVEncOmxInfo->hVEnc) || (prVEncOmxInfo->hVEnc == VENC_NULL_HANDLE))
    {
        LOG(0, "[%s] Invaild hEnc 0x%08X\n", __FUNCTION__, hEnc);
        return VENCR_ERR_INV;
    }
    prVEncOmxInfo->fg2Usr = TRUE;

    //Output Callback
    rCb.pvData = (VOID *)prVEncOmxInfo;
    rCb.cb     = _VENCCb;
    u4Ret = VENC_SetCtrl(hEnc, VENC_CTRL_OUT_CB, (VOID*)&rCb);
    if (VENC_OK != u4Ret)
    {
        VENCOMX_DBG(" - fail(%d)!!\n", u4Ret);
        return VENCR_NOT_OK;
    }

    return VENCR_OK;
}


VENCOMX_RESULT_T _VENCOMX_UnlockBuf(unsigned long arg)
{
    VENCOMX_IOCTL_3ARG_T rArg;
    VENC_HANDLE hEnc;
    UINT32 u4Addr, u4Size, u4Ret;
    VENCOMX_INFO_T *prVEncOmxInfo;

    USR_SPACE_ACCESS_VALIDATE_3ARG(arg);
    COPY_FROM_USER_3ARG(arg, rArg);
#ifdef CONFIG_COMPAT
    if (is_compat_task())
    {
        hEnc   = (VENC_HANDLE)(compat_ptr(rArg.ai4Arg[0].compat_value));
    }
    else
#endif
    {
        hEnc   = (VENC_HANDLE)rArg.ai4Arg[0].value;

    }
    prVEncOmxInfo = _VENCGetInfoInst(( (UINT16)(UPTR)hEnc - 1));
    if ((hEnc != prVEncOmxInfo->hVEnc) || (prVEncOmxInfo->hVEnc == VENC_NULL_HANDLE))
    {
        LOG(0, "[%s] Invaild hEnc 0x%08X\n", __FUNCTION__, hEnc);
        return VENCR_ERR_INV;
    }
    u4Addr = rArg.ai4Arg[1].compat_value;
    u4Size = rArg.ai4Arg[2].compat_value;

    u4Ret = VENC_UnlockBuf(hEnc, u4Addr, u4Size);

    return (VENC_OK == u4Ret)? VENCR_OK : VENCR_NOT_OK;
}

VENCOMX_RESULT_T _VENCOMX_CopyData(unsigned long arg)
{
#ifdef COPYDATA_FROME_DRVIER
   return VENCR_OK;
#else
   return VENCR_NOT_OK;
#endif
}
#endif // CC_SUPPORT_VENC




