#include <bsp.h>
#include <drvmsg.h>
#include "postif_proc.h"
#include "post_queue.h"

#define LINESKIP_RATE   3


CAMIFPostIF::CAMIFPostIF() :
        m_isThreadWorking(0),
        m_pWorkingCtxt(NULL),
        CMiniThread (0, TRUE),
        m_PostIntDoneEvent(NULL),
        m_PostRequestEvent(NULL)
{
    m_PostIntDoneEvent = CreateEvent(NULL, FALSE, FALSE, NULL);    // Auto Reset
    m_PostRequestEvent = CreateEvent(NULL, TRUE, FALSE, NULL);    // Auto Reset
    ThreadStart();
    CeSetPriority(100);
}

DWORD CAMIFPostIF::ThreadRun()
{
    DBGMSG(POST_FUNC && POST_USR4,(_T("[POST] ++%s()=0x%x, CamID = %d\r\n"), _T(__FUNCTION__), &CAMIFPostIF::ThreadRun, m_uCamID));
    BOOL bRet = TRUE;
    m_isThreadWorking = 1;
    CRITICAL_SECTION    csLock;
    InitializeCriticalSection(&csLock);
    DWORD time = 0;
    PostProcContext *pCurrentCtxt = NULL;
    while ( !IsTerminated() )
    {

        if(!m_PQ.IsEmpty())
        {
            EnterCriticalSection(&csLock);

            // set processing param part
            pCurrentCtxt = m_PQ.Front();
            DBGMSG(POST_FUNC && POST_USR4 ,(_T("4 [POST] ++%s() is not empty popped Ctxt = 0x%x\n\r"), _T(__FUNCTION__),pCurrentCtxt));
        }
        else
        {
            DBGMSG(POST_FUNC && POST_USR4 ,(_T("[POST] ++%s() is empty So wait PostRequest Event CamID = %d\n\r"), _T(__FUNCTION__), m_uCamID));

            LeaveCriticalSection(&csLock);
            ResetEvent(m_PostRequestEvent);
            WaitForSingleObject(m_PostRequestEvent, INFINITE);
            DBGMSG(POST_FUNC && POST_USR4 ,(_T("3 [POST] ++%s() GetEvent Post Request Event\n\r"), _T(__FUNCTION__)));

            continue;

        }

        time = GetTickCount();
        bRet = Post_Start(pCurrentCtxt);


        if (GetProcessingState() == POST_BUSY)        // Post Processor Running
        {
            if (WAIT_TIMEOUT == WaitForSingleObject(m_PostIntDoneEvent, CAM_POST_CMD_TIMEOUT))
            {
                if (GetProcessingState() == POST_IDLE)
                {
                    // Time Out, But Post Processor Finished
                    DBGMSG(POST_FUNC && POST_USR4, (_T("[POST] ++%s() : CAM_POST_CMD_TIMEOUT But Post Processor Finished\n\r"), _T(__FUNCTION__)));
                }
                else
                {
                    ERRMSG( (_T("[POST:ERR] %s() : CAM_POST_CMD_TIMEOUT : and POST_BUSY So Error\n\r"), _T(__FUNCTION__)));
                    bRet = FALSE;
                    //break;
                }
                DBGMSG(POST_FUNC && POST_USR4,(TEXT("[POST] POST INT Didn't OCCUR!!!!\r\n")));
            }
            else
                DBGMSG(POST_FUNC && POST_USR4,(TEXT("[POST] POST INT OCCUR %d!!!!\r\n"), GetTickCount() - time));
        }

        m_PQ.Dequeue();

        m_pWorkingCtxt->bPostProcessDone = 1;
        DBGMSG(POST_FUNC && POST_USR4 ,(_T("5 [POST] ++%s() SetEvent bPostProcessDone Event Ctxt = 0x%x\n\r"), _T(__FUNCTION__),m_pWorkingCtxt));
        SetEvent(m_pWorkingCtxt->hPostCmdDone);

    }

    m_isThreadWorking = 0;
    DBGMSG(POST_FUNC && POST_USR4,(_T("%s(): Thread Finished"), _T(__FUNCTION__)));
    return 1;
}

DWORD CAMIFPostIF::WaitProcessDone(HANDLE hEvent)
{
    DBGMSG(POST_FUNC && POST_USR2,(_T("[POST] ++%s()\r\n"), _T(__FUNCTION__)));
    return WaitForSingleObject(hEvent, 300);
}

BOOL CAMIFPostIF::Post_Start(PostProcContext *PCtxt)
{
    BOOL bRet = TRUE;
    m_pWorkingCtxt = PCtxt;
    if(PCtxt->bPostParam == TRUE)
    {
        Initialize((POST_OP_MODE)PCtxt->tPostParam.dwOpMode, (POST_SCAN_MODE)PCtxt->tPostParam.dwScanMode, PCtxt->tPostParam.dwRotFlipMode,
                                    (POST_SRC_TYPE)PCtxt->tPostParam.dwSrcType, PCtxt->tPostParam.dwSrcBaseWidth, PCtxt->tPostParam.dwSrcBaseHeight, PCtxt->tPostParam.dwSrcWidth, PCtxt->tPostParam.dwSrcHeight, PCtxt->tPostParam.dwSrcOffsetX, PCtxt->tPostParam.dwSrcOffsetY,
                                    (POST_DST_TYPE)PCtxt->tPostParam.dwDstType, PCtxt->tPostParam.dwDstBaseWidth, PCtxt->tPostParam.dwDstBaseHeight, PCtxt->tPostParam.dwDstWidth, PCtxt->tPostParam.dwDstHeight, PCtxt->tPostParam.dwDstOffsetX, PCtxt->tPostParam.dwDstOffsetY);
        SetDmaMode((CAM_DMA_MODE)(HIWORD(PCtxt->tPostParam.dwDMATileMode)),
                                   (CAM_DMA_MODE)(LOWORD(PCtxt->tPostParam.dwDMATileMode)));
    }


    if(PCtxt->bPostSrcBuffer == TRUE)
    {
        // Set source buffer part
        if(SetSourceBuffer(PCtxt->tPostSrcBuffer.dwBufferRGBY, \
                    PCtxt->tPostSrcBuffer.dwBufferCb, PCtxt->tPostSrcBuffer.dwBufferCr) != POST_SUCCESS)
        {
            ERRMSG( (_T("[CAM:ERR] CAM_Post_API_Proc() : CAM_POST_SET_SOURCE_BUFFER : SetSourceBuffer error! = %d\n\r")));
            bRet = FALSE;
            goto End;
        }

        //EnterCriticalSection(&PCtxt->csLockShadow);
/*
        if(SetNextSourceBuffer(PCtxt->tPostSrcBuffer.dwBufferRGBY, \
                    PCtxt->tPostSrcBuffer.dwBufferCb, PCtxt->tPostSrcBuffer.dwBufferCr) != POST_SUCCESS)
        {
            ERRMSG( (_T("[CAM:ERR] CAM_Post_API_Proc() : CAM_POST_SET_NEXT_SOURCE_BUFFER : SetNextSourceBuffer error! = %d\n\r")));
            bRet = FALSE;
            goto End;
        }
*/
        //LeaveCriticalSection(&PCtxt->csLockShadow);
    }

    if(PCtxt->bPostDstBuffer == TRUE)
    {

        if(Set1stDestinationBuffer(PCtxt->tPostDst1stBuffer.dwBufferRGBY, \
                    PCtxt->tPostDst1stBuffer.dwBufferCb, PCtxt->tPostDst1stBuffer.dwBufferCr) != POST_SUCCESS)
        {
            ERRMSG( (_T("[CAM:ERR] CAM_Post_API_Proc() : CAM_POST_SET_DESTINATION_1ST_BUFFER : Set1stDestinationBuffer error! = %d\n\r")));
            bRet = FALSE;
            goto End;
        }

        if(Set2ndDestinationBuffer(PCtxt->tPostDst2ndBuffer.dwBufferRGBY, \
                    PCtxt->tPostDst2ndBuffer.dwBufferCb, PCtxt->tPostDst2ndBuffer.dwBufferCr) != POST_SUCCESS)
        {
            ERRMSG( (_T("[CAM:ERR] CAM_Post_API_Proc() : CAM_POST_SET_DESTINATION_2ND_BUFFER : Set2ndDestinationBuffer error! = %d\n\r")));
            bRet = FALSE;
            goto End;
        }

        if(Set3rdDestinationBuffer(PCtxt->tPostDst3rdBuffer.dwBufferRGBY, \
                    PCtxt->tPostDst3rdBuffer.dwBufferCb, PCtxt->tPostDst3rdBuffer.dwBufferCr) != POST_SUCCESS)
        {
            ERRMSG( (_T("[CAM:ERR] CAM_Post_API_Proc() : CAM_POST_SET_DESTINATION_3RD_BUFFER : Set3rdDestinationBuffer error! = %d\n\r")));
            bRet = FALSE;
            goto End;
        }

        if(Set4thDestinationBuffer(PCtxt->tPostDst4thBuffer.dwBufferRGBY, \
                    PCtxt->tPostDst4thBuffer.dwBufferCb, PCtxt->tPostDst4thBuffer.dwBufferCr) != POST_SUCCESS)
        {
            ERRMSG((_T("[CAM:ERR] CAM_Post_API_Proc() : CAM_POST_SET_DESTINATION_4TH_BUFFER : Set4thDestinationBuffer error! = %d\n\r")));
            bRet = FALSE;
            goto End;
        }
    }

    //SetPostEvent(PCtxt->hPostCmdDone);

    EnableInterrupt();
    ProcessingStart();

End:

    return bRet;
}

POST_ERROR CAMIFPostIF::SetPostEvent(HANDLE hEvent)
{
    POST_ERROR error = POST_SUCCESS;

    pCameraIF->SetPostEvent(hEvent);

    return error;
}


POST_ERROR CAMIFPostIF::Initialize(POST_OP_MODE Mode, POST_SCAN_MODE Scan, unsigned int RotFlip,
                    POST_SRC_TYPE SrcType, unsigned int SrcBaseWidth, unsigned int SrcBaseHeight,
                    unsigned int SrcWidth, unsigned int SrcHeight, unsigned int SrcOffsetX, unsigned int SrcOffsetY,
                    POST_DST_TYPE DstType, unsigned int DstBaseWidth, unsigned int DstBaseHeight,
                    unsigned int DstWidth, unsigned int DstHeight, unsigned int DstOffsetX, unsigned int DstOffsetY)
{
    POST_ERROR error = POST_SUCCESS;

    DBGMSG(POST_FUNC && POST_USR2 ,(_T("[POST]++%s(%d, %d, %d, %d, [%d, %d, %d, %d, %d, %d], %d, [%d, %d, %d, %d, %d, %d])\n\r"), _T(__FUNCTION__),
                Mode, Scan, SrcType, RotFlip, SrcBaseWidth, SrcBaseHeight, SrcWidth, SrcHeight, SrcOffsetX, SrcOffsetY,
                DstType, DstBaseWidth, DstBaseHeight, DstWidth, DstHeight, DstOffsetX, DstOffsetY));

//    pCameraIF->InterfaceReset(FALSE);
//    pCAMIF->ResetIpForDin();
    
    error = SetMode(Mode, Scan, SrcType, DstType);
    if (error == POST_SUCCESS)
    {
        // work-around for VCLK STOP when scaling down on Local Path State
        /*====================================================================*/
/*        if(Mode == POST_FREE_RUN_MODE)
        {
            if(SrcHeight >= 2*DstHeight)
            {
                int i=2;
                for(i=2;(SrcHeight >= i*DstHeight) && (i<8);i++);
                SrcBaseWidth *= i;
                SrcBaseHeight /= i;
                SrcHeight /= i;
            }
        }
*/        
        /*====================================================================*/

        SetRotationAndFlip(RotFlip);
        SetSourceSize(SrcBaseWidth, SrcBaseHeight, SrcWidth, SrcHeight, SrcOffsetX, SrcOffsetY);
        SetDestinationSize(DstBaseWidth, DstBaseHeight, DstWidth, DstHeight, DstOffsetX, DstOffsetY);
        error = UpdateCondition();
    }

    pCameraIF->SetUsage(USE_FOR_POST);

    DBGMSG(POST_FUNC && POST_USR2 ,(_T("[POST]--%s() : %d\n\r"), _T(__FUNCTION__), error));

    return error;
}

// HIWORD of Rotation is Input Rotation
// LOWORD of Roataion is Output Rotation
// ROT[2], YFLIP[1], XFLIP[0]

#define ROT_BIT     0x4
#define YFLIP_BIT   0x2
#define XFLIP_BIT   0x1
POST_ERROR CAMIFPostIF::SetRotationAndFlip(unsigned int RotFlip)
{
    UINT32 InRotFlip;
    UINT32 OutRotFlip;
    InRotFlip = HIWORD(RotFlip);
    OutRotFlip = LOWORD(RotFlip);

    // Just set Input Rotator
    if(InRotFlip & ROT_BIT)
    {
        pCameraIF->GetCameraSFR()->CITRGFMT |= BM_INROT90;
    }
    else
    {
        pCameraIF->GetCameraSFR()->CITRGFMT &= ~BM_INROT90;        
    }
    pCameraIF->GetCameraSFR()->MSCTRL = (pCameraIF->GetCameraSFR()->MSCTRL & ~(BM_INFLIPMD)) |
                                            ((InRotFlip & (YFLIP_BIT|XFLIP_BIT))<<BP_INFLIPMD);
    if(InRotFlip)
    {
        // Ignore Output Rotator setting (Rotation and Flip)    
        OutRotFlip = 0;
    }

    if(OutRotFlip & ROT_BIT)
    {
        pCameraIF->GetCameraSFR()->CITRGFMT |= BM_OUTROT90;
    }
    else
    {
        pCameraIF->GetCameraSFR()->CITRGFMT &= ~BM_OUTROT90;        
    }
    pCameraIF->GetCameraSFR()->CITRGFMT = (pCameraIF->GetCameraSFR()->CITRGFMT & ~(BM_OUTFLIPMD)) |
                                            ((OutRotFlip & (YFLIP_BIT|XFLIP_BIT))<<BP_OUTFLIPMD);

    m_PostConfig.dwRotFlipMode = MAKELONG(OutRotFlip, InRotFlip);

    return POST_SUCCESS;
    
}

POST_ERROR CAMIFPostIF::SetSourceBuffer(unsigned int AddrY, unsigned int AddrCb, unsigned int AddrCr)
{
    POST_ERROR error = POST_SUCCESS;

    DBGMSG(POST_FUNC && POST_USR2 ,(_T("[POST]++%s(0x%08x, 0x%08x, 0x%08x)\n\r"), _T(__FUNCTION__), AddrY, AddrCb, AddrCr));

    if (m_PostConfig.SrcType == POST_SRC_FIFO_YUV444)
    {
        ERRMSG((_T("[POST:ERR] %s() : FIFO Mode does Not use DMA\n\r"), _T(__FUNCTION__)));
        error = POST_ERROR_ILLEGAL_PARAMETER;
    }
    else
    {
    error = SetDmaAddress(POST_SRC_ADDRESS, AddrY, AddrCb, AddrCr);
    }

    DBGMSG(POST_FUNC && POST_USR2 ,(_T("[POST]--%s() : %d\n\r"), _T(__FUNCTION__), error));

    return error;
}

POST_ERROR CAMIFPostIF::SetNextSourceBuffer(unsigned int AddrY, unsigned int AddrCb, unsigned int AddrCr)
{
    POST_ERROR error = POST_SUCCESS;

    DBGMSG(POST_FUNC && POST_USR2 ,(_T("[POST]++%s(0x%08x, 0x%08x, 0x%08x)\n\r"), _T(__FUNCTION__), AddrY, AddrCb, AddrCr));

    if (m_PostConfig.SrcType == POST_SRC_FIFO_YUV444)
    {
        ERRMSG((_T("[POST:ERR] %s() : FIFO Mode does Not use DMA\n\r"), _T(__FUNCTION__)));
        error = POST_ERROR_ILLEGAL_PARAMETER;
    }
    else
    {
    error = SetDmaAddress(POST_NEXT_SRC_ADDRESS, AddrY, AddrCb, AddrCr);
    }

    DBGMSG(POST_FUNC && POST_USR2 ,(_T("[POST]--%s() : %d\n\r"), _T(__FUNCTION__), error));

    return error;
}

POST_ERROR CAMIFPostIF::SetDestinationBuffer(unsigned int AddrY, unsigned int AddrCb, unsigned int AddrCr)
{
    POST_ERROR error = POST_SUCCESS;

    DBGMSG(POST_FUNC && POST_USR2 ,(_T("[POST]++%s(0x%08x, 0x%08x, 0x%08x)\n\r"), _T(__FUNCTION__), AddrY, AddrCb, AddrCr));

    if (m_PostConfig.DstType == POST_DST_FIFO_RGB888 || m_PostConfig.DstType == POST_DST_FIFO_YUV444)
    {
        ERRMSG((_T("[POST:ERR] %s() : FIFO Mode does Not use DMA\n\r"), _T(__FUNCTION__)));
        error = POST_ERROR_ILLEGAL_PARAMETER;
    }
    else
    {
        error = SetDmaAddress(POST_DST_ADDRESS, AddrY, AddrCb, AddrCr);
    }

    DBGMSG(POST_FUNC && POST_USR2 ,(_T("[POST]--%s() : %d\n\r"), _T(__FUNCTION__), error));

    return error;
}

POST_ERROR CAMIFPostIF::SetNextDestinationBuffer(unsigned int AddrY, unsigned int AddrCb, unsigned int AddrCr)
{
    POST_ERROR error = POST_SUCCESS;

    DBGMSG(POST_FUNC && POST_USR2 ,(_T("[POST]++%s(0x%08x, 0x%08x, 0x%08x)\n\r"), _T(__FUNCTION__), AddrY, AddrCb, AddrCr));

    if (m_PostConfig.DstType == POST_DST_FIFO_RGB888 || m_PostConfig.DstType == POST_DST_FIFO_YUV444)
    {
        ERRMSG((_T("[POST:ERR] %s() : FIFO Mode does Not use DMA\n\r"), _T(__FUNCTION__)));
        error = POST_ERROR_ILLEGAL_PARAMETER;
    }
    else
    {
        error = SetDmaAddress(POST_NEXT_DST_ADDRESS, AddrY, AddrCb, AddrCr);
    }

    DBGMSG(POST_FUNC && POST_USR2 ,(_T("[POST]--%s() : %d\n\r"), _T(__FUNCTION__), error));

    return error;
}

POST_ERROR CAMIFPostIF::Set1stDestinationBuffer(unsigned int AddrY, unsigned int AddrCb, unsigned int AddrCr)
{
    POST_ERROR error = POST_SUCCESS;

    DBGMSG(POST_FUNC && POST_USR2 ,(_T("[POST]++%s(0x%08x, 0x%08x, 0x%08x)\n\r"), _T(__FUNCTION__), AddrY, AddrCb, AddrCr));

    if (m_PostConfig.DstType == POST_DST_FIFO_RGB888 || m_PostConfig.DstType == POST_DST_FIFO_YUV444)
    {
        ERRMSG((_T("[POST:ERR] %s() : FIFO Mode does Not use DMA\n\r"), _T(__FUNCTION__)));
        error = POST_ERROR_ILLEGAL_PARAMETER;
    }
    else
    {
        error = SetDmaAddress(POST_DST_1ST_ADDRESS, AddrY, AddrCb, AddrCr);
    }

    DBGMSG(POST_FUNC && POST_USR2 ,(_T("[POST]--%s() : %d\n\r"), _T(__FUNCTION__), error));

    return error;
}

POST_ERROR CAMIFPostIF::Set2ndDestinationBuffer(unsigned int AddrY, unsigned int AddrCb, unsigned int AddrCr)
{
    POST_ERROR error = POST_SUCCESS;

    DBGMSG(POST_FUNC && POST_USR2 ,(_T("[POST]++%s(0x%08x, 0x%08x, 0x%08x)\n\r"), _T(__FUNCTION__), AddrY, AddrCb, AddrCr));

    if (m_PostConfig.DstType == POST_DST_FIFO_RGB888 || m_PostConfig.DstType == POST_DST_FIFO_YUV444)
    {
        ERRMSG((_T("[POST:ERR] %s() : FIFO Mode does Not use DMA\n\r"), _T(__FUNCTION__)));
        error = POST_ERROR_ILLEGAL_PARAMETER;
    }
    else
    {
        error = SetDmaAddress(POST_DST_2ND_ADDRESS, AddrY, AddrCb, AddrCr);
    }

    DBGMSG(POST_FUNC && POST_USR2 ,(_T("[POST]--%s() : %d\n\r"), _T(__FUNCTION__), error));

    return error;
}

POST_ERROR CAMIFPostIF::Set3rdDestinationBuffer(unsigned int AddrY, unsigned int AddrCb, unsigned int AddrCr)
{
    POST_ERROR error = POST_SUCCESS;

    DBGMSG(POST_FUNC && POST_USR2 ,(_T("[POST]++%s(0x%08x, 0x%08x, 0x%08x)\n\r"), _T(__FUNCTION__), AddrY, AddrCb, AddrCr));

    if (m_PostConfig.DstType == POST_DST_FIFO_RGB888 || m_PostConfig.DstType == POST_DST_FIFO_YUV444)
    {
        ERRMSG((_T("[POST:ERR] %s() : FIFO Mode does Not use DMA\n\r"), _T(__FUNCTION__)));
        error = POST_ERROR_ILLEGAL_PARAMETER;
    }
    else
    {
        error = SetDmaAddress(POST_DST_3RD_ADDRESS, AddrY, AddrCb, AddrCr);
    }

    DBGMSG(POST_FUNC && POST_USR2 ,(_T("[POST]--%s() : %d\n\r"), _T(__FUNCTION__), error));

    return error;
}

POST_ERROR CAMIFPostIF::Set4thDestinationBuffer(unsigned int AddrY, unsigned int AddrCb, unsigned int AddrCr)
{
    POST_ERROR error = POST_SUCCESS;

    DBGMSG(POST_FUNC && POST_USR2 ,(_T("[POST]++%s(0x%08x, 0x%08x, 0x%08x)\n\r"), _T(__FUNCTION__), AddrY, AddrCb, AddrCr));

    if (m_PostConfig.DstType == POST_DST_FIFO_RGB888 || m_PostConfig.DstType == POST_DST_FIFO_YUV444)
    {
        ERRMSG((_T("[POST:ERR] %s() : FIFO Mode does Not use DMA\n\r"), _T(__FUNCTION__)));
        error = POST_ERROR_ILLEGAL_PARAMETER;
    }
    else
    {
        error = SetDmaAddress(POST_DST_4TH_ADDRESS, AddrY, AddrCb, AddrCr);
    }

    DBGMSG(POST_FUNC && POST_USR2 ,(_T("[POST]--%s() : %d\n\r"), _T(__FUNCTION__), error));

    return error;
}

// Just want to run Post(Resizer+CSC)
void CAMIFPostIF::ProcessingStart(void)
{
    DBGMSG(POST_FUNC && POST_USR2 ,(_T("[POST]++%s()\n\r"), _T(__FUNCTION__)));

    pCameraIF->SetOperationMode(POST_PROCESSOR);

    if(m_PostConfig.SrcType != POST_SRC_FIFO_YUV444)
    {
        pCameraIF->ResetSkipFrameCount();
        pCameraIF->ResetIDMABusy();

        pCameraIF->ThreadStart();

        // Check Run MODE
        // Check Input Output
        // Trigger Scaler, CSC, IN_DMA, OUT_DMA
        if (m_PostConfig.Mode == POST_FREE_RUN_MODE)    // for FIFO output mode
        {
            pCameraIF->GetCameraSFR()->CIREAL_ISIZE |= AUTOLOAD_ENABLE;
        }
        pCameraIF->GetCameraSFR()->CIIMGCPT |= SCALER_ENABLE;
        pCameraIF->GetCameraSFR()->CISCCTRL |= SCALER_START;
        pCameraIF->GetCameraSFR()->MSCTRL |= INPUTDMA_START;
    }
    else
    {
        pCameraIF->ResetSkipFrameCount();
        pCameraIF->ThreadStart();

        // Start Scaler
        pCameraIF->GetCameraSFR()->CISCCTRL = (pCameraIF->GetCameraSFR()->CISCCTRL & ~(BM_SCALERSTART)) | SCALER_START;
        // Disable capture frame control
        pCameraIF->GetCameraSFR()->CIIMGCPT = (pCameraIF->GetCameraSFR()->CIIMGCPT & ~(BM_CPT_FREN)) | CPT_FREN_DISABLE;
        // Enable camera interface global capture
        pCameraIF->GetCameraSFR()->CIIMGCPT = (pCameraIF->GetCameraSFR()->CIIMGCPT & ~(BM_IMGCPTEN)) | GLOBAL_CPT_ENABLE;
        // Enable scaler for capture
        pCameraIF->GetCameraSFR()->CIIMGCPT = (pCameraIF->GetCameraSFR()->CIIMGCPT & ~(BM_IMGCPTEN_SC)) | SCALER_ENABLE;
    }

    DBGMSG(POST_FUNC && POST_USR2 ,(_T("[POST]--%s()\n\r"), _T(__FUNCTION__)));
}

void CAMIFPostIF::ProcessingStop(void)
{
    DBGMSG(POST_FUNC && POST_USR2 ,(_T("[POST]++%s()\n\r"), _T(__FUNCTION__)));

    if(m_PostConfig.SrcType != POST_SRC_FIFO_YUV444)
    {
        pCameraIF->ThreadStop();

        if (pCameraIF->GetCameraSFR()->CIREAL_ISIZE & BM_AUTOLOADENABLE)    // for FIFO output mode
        {
            // FIFO mode should be stopped by autoload disable
            pCameraIF->GetCameraSFR()->CIREAL_ISIZE &= ~AUTOLOAD_ENABLE;
        }
           // Not Work // Autoload Disable will make ENVID_M off
              //    while((pCameraIF->GetCameraSFR()->MSCTRL & BM_ENVID_M) != 0x0);
        pCameraIF->GetCameraSFR()->MSCTRL &= ~INPUTDMA_START;
        while((pCameraIF->GetCameraSFR()->MSCTRL & BM_ENVID_M) != 0x0)
            Sleep(10);
    }
    else
    {
        pCameraIF->ThreadStop();

        // Disable camera interface global capture
        pCameraIF->GetCameraSFR()->CIIMGCPT = (pCameraIF->GetCameraSFR()->CIIMGCPT & ~(BM_IMGCPTEN)) | GLOBAL_CPT_DISABLE;
        
        // Stop Scaler
        pCameraIF->GetCameraSFR()->CISCCTRL = (pCameraIF->GetCameraSFR()->CISCCTRL & ~(BM_SCALERSTART)) | SCALER_STOP;
        // Disable scaler for capture
        pCameraIF->GetCameraSFR()->CIIMGCPT = (pCameraIF->GetCameraSFR()->CIIMGCPT & ~(BM_IMGCPTEN_SC)) | SCALER_DISABLE;

        while( ((pCameraIF->GetCameraSFR()->CISTATUS) & \
            (BM_CAM_IMAGECAPTURE_ENABLE|BM_CAM_IMAGECAPTURE_SCALER_ENABLE)) != 0)
            Sleep(10);
    }
    
    // SWRESET
    pCameraIF->InterfaceReset(FALSE);
    
    pCameraIF->SetPowerOn(FALSE);
    pCameraIF->SetCamIFClockOn(FALSE);

    DBGMSG(POST_FUNC && POST_USR2 ,(_T("[POST]--%s()\n\r"), _T(__FUNCTION__)));
}

void CAMIFPostIF::SetAutoload(BOOL bEnable)
{
    DBGMSG(POST_FUNC && POST_USR2 ,(_T("[POST]++%s()\n\r"), _T(__FUNCTION__)));

    if(bEnable)
    {
        pCameraIF->GetCameraSFR()->CIREAL_ISIZE |= AUTOLOAD_ENABLE;    
    }
    else
    {
        pCameraIF->GetCameraSFR()->CIREAL_ISIZE &= ~AUTOLOAD_ENABLE;    
    }
    DBGMSG(POST_FUNC && POST_USR2 ,(_T("[POST]--%s()\n\r"), _T(__FUNCTION__)));
}

POST_STATE CAMIFPostIF::GetProcessingState(void)
{
    POST_STATE state;

    DBGMSG(POST_FUNC && POST_USR2 ,(_T("[POST]++%s()\n\r"), _T(__FUNCTION__)));

//    if (pCameraIF->GetCameraSFR()->CISTATUS & BS_CAM_IRQ_DMA_END)
    if (pCameraIF->GetIDMABusy())
    {
        state = POST_BUSY;
    }
    else
    {
        state = POST_IDLE;
    }

    DBGMSG(POST_FUNC && POST_USR2 ,(_T("[POST]--%s() = %d\n\r"), _T(__FUNCTION__), state));

    return state;
}

void CAMIFPostIF::EnableInterrupt(void)
{
    DBGMSG(POST_FUNC && POST_USR2 ,(_T("[POST]++%s()\n\r"), _T(__FUNCTION__)));

    m_PostConfig.bIntEnable = TRUE;

    //If using Level Interrupt we may need to clear interrupt pending status
    //since S5PV210, only Level interrupt.
    //if(pCameraIF->GetCameraSFR()->CIGCTRL & BM_CAM_IRQ_LEVEL)
    //{
        pCameraIF->GetCameraSFR()->CIGCTRL |= BM_CAM_IRQ_CLR;   
    //}
    pCameraIF->GetCameraSFR()->CIGCTRL |= BM_CAM_IRQ_LEVEL;
    pCameraIF->GetCameraSFR()->CIGCTRL |= BM_CAM_IRQ_ENABLE;

    DBGMSG(POST_FUNC && POST_USR2 ,(_T("[POST]--%s()\n\r"), _T(__FUNCTION__)));
}

void CAMIFPostIF::DisableInterrupt(void)
{
    DBGMSG(POST_FUNC && POST_USR2 ,(_T("[POST]++%s()\n\r"), _T(__FUNCTION__)));

    m_PostConfig.bIntEnable = FALSE;

    pCameraIF->GetCameraSFR()->CIGCTRL &= ~BM_CAM_IRQ_ENABLE;
    // If using Level Interrupt we may need to clear interrupt pending status
    //if(pCameraIF->GetCameraSFR()->CIGCTRL & BM_CAM_IRQ_LEVEL)
    {
        pCameraIF->GetCameraSFR()->CIGCTRL |= BM_CAM_IRQ_CLR;   
    }

    DBGMSG(POST_FUNC && POST_USR2 ,(_T("[POST]--%s()\n\r"), _T(__FUNCTION__)));
}

BOOL CAMIFPostIF::ClearInterruptPending(void)
{
    BOOL bCleared = FALSE;

    DBGMSG(POST_FUNC && POST_USR2 ,(_T("[POST]++%s()\n\r"), _T(__FUNCTION__)));

    // If using Level Interrupt we may need to clear interrupt pending status
    //if(pCameraIF->GetCameraSFR()->CIGCTRL & BM_CAM_IRQ_LEVEL)
    {
        pCameraIF->GetCameraSFR()->CIGCTRL |= BM_CAM_IRQ_CLR;   
        bCleared = TRUE;
    }
    
    DBGMSG(POST_FUNC && POST_USR2 ,(_T("[POST]--%s()\n\r"), _T(__FUNCTION__)));

    return bCleared;
}

POST_ERROR CAMIFPostIF::SetMode(POST_OP_MODE Mode, POST_SCAN_MODE Scan, POST_SRC_TYPE SrcType, POST_DST_TYPE DstType)
{
    POST_ERROR error = POST_SUCCESS;

    DBGMSG(POST_FUNC && POST_USR2 ,(_T("[POST]++%s(%d, %d, %d, %d)\n\r"), _T(__FUNCTION__), Mode, Scan, SrcType, DstType));

    m_PostConfig.Mode = Mode;
    m_PostConfig.Scan = Scan;
    m_PostConfig.SrcType = SrcType;
    m_PostConfig.DstType = DstType;
    m_PostConfig.bIntEnable = TRUE;

    pCameraIF->SetPowerOn(TRUE);
    // For some application PostProcessor May be need to faster CLK
    // Clock Setting
    pCameraIF->SetCamIFClock();
    pCameraIF->SetCamIFClockOn(TRUE);

    
//    if(m_PostConfig.Mode == POST_FREE_RUN_MODE && (m_PostConfig.DstType == POST_DST_FIFO_YUV444 || m_PostConfig.DstType == POST_DST_FIFO_RGB888))
/*    switch(m_uCamID)
    {
        case 0:
            pCameraIF->GetClockControllerSFR()->CLK_SRC2 = (pCameraIF->GetClockControllerSFR()->CLK_SRC2 & ~BM_FIMC0_SEL) | CLKSEL_DOUT_MPLL(FIMC0_SEL);
            pCameraIF->GetClockControllerSFR()->CLK_DIV1 = (pCameraIF->GetClockControllerSFR()->CLK_DIV1 & ~BM_CAM_RATIO) | CLKDIV_CAM_RATIO(1);
            pCameraIF->GetClockControllerSFR()->CLK_DIV3 = (pCameraIF->GetClockControllerSFR()->CLK_DIV3 & ~BM_FIMC0_RATIO) | CLKDIV_FIMC_RATIO(FIMC0_RATIO, 1);
        break;
        case 1:
            pCameraIF->GetClockControllerSFR()->CLK_SRC2 = (pCameraIF->GetClockControllerSFR()->CLK_SRC2 & ~BM_FIMC1_SEL) | CLKSEL_DOUT_MPLL(FIMC1_SEL);
            pCameraIF->GetClockControllerSFR()->CLK_DIV1 = (pCameraIF->GetClockControllerSFR()->CLK_DIV1 & ~BM_CAM_RATIO) | CLKDIV_CAM_RATIO(1);
            pCameraIF->GetClockControllerSFR()->CLK_DIV3 = (pCameraIF->GetClockControllerSFR()->CLK_DIV3 & ~BM_FIMC1_RATIO) | CLKDIV_FIMC_RATIO(FIMC1_RATIO, 1);
        break;
        case 2:
            pCameraIF->GetClockControllerSFR()->CLK_SRC2 = (pCameraIF->GetClockControllerSFR()->CLK_SRC2 & ~BM_FIMC2_SEL) | CLKSEL_DOUT_MPLL(FIMC2_SEL);
            pCameraIF->GetClockControllerSFR()->CLK_DIV1 = (pCameraIF->GetClockControllerSFR()->CLK_DIV1 & ~BM_CAM_RATIO) | CLKDIV_CAM_RATIO(1);
            pCameraIF->GetClockControllerSFR()->CLK_DIV3 = (pCameraIF->GetClockControllerSFR()->CLK_DIV3 & ~BM_FIMC2_RATIO) | CLKDIV_FIMC_RATIO(FIMC2_RATIO, 1);
        break;
    }
*/    
    // Main Scaler Color Space Setting
    pCameraIF->GetCameraSFR()->CISCCTRL = (pCameraIF->GetCameraSFR()->CISCCTRL & ~(BM_CSCR2Y | BM_CSCY2R)) | CSC_R2Y_NARROW | CSC_Y2R_NARROW;
    // Set to LEVEL Interrupt
    //pCameraIF->GetCameraSFR()->CIGCTRL = (pCameraIF->GetCameraSFR()->CIGCTRL & ~(BM_CAM_IRQ_LEVEL)) | IRQ_LEVEL;

    if (m_PostConfig.bIntEnable)
    {
        EnableInterrupt();
    }

    if(m_PostConfig.SrcType != POST_SRC_FIFO_YUV444)
    {
        switch(Mode)
        {
            case POST_PER_FRAME_MODE:
                SetAutoload(FALSE);
                break;
            case POST_FREE_RUN_MODE:
                SetAutoload(TRUE);    
                break;
            default:
                ERRMSG((_T("[POST:ERR] %s() : Unknown Operation Mode %d)\n\r"), _T(__FUNCTION__), Mode));
                return POST_ERROR_ILLEGAL_PARAMETER;
        }
    }
    else
    {
        switch(Mode)
        {
            case POST_PER_FRAME_MODE:
                // TO-DO
                break;
            case POST_FREE_RUN_MODE:
                // TO-DO
                break;
            default:
                ERRMSG((_T("[POST:ERR] %s() : Unknown Operation Mode %d)\n\r"), _T(__FUNCTION__), Mode));
                return POST_ERROR_ILLEGAL_PARAMETER;
        }
    }

    // There are two scan mode setting one is for LCD FIFO Output
    // Another one is CAM input
    if(m_PostConfig.SrcType != POST_SRC_FIFO_YUV444)
    {
        if (Scan == POST_PROGRESSIVE)
        {
            pCameraIF->GetCameraSFR()->CISCCTRL = (pCameraIF->GetCameraSFR()->CISCCTRL & ~(BM_INTERLACE) | PROGRESSIVE);
        }
        else if (Mode == POST_INTERLACE)
        {
            pCameraIF->GetCameraSFR()->CISCCTRL = (pCameraIF->GetCameraSFR()->CISCCTRL & ~(BM_INTERLACE) | INTERLACE);
        }
        else
        {
            ERRMSG((_T("[POST:ERR] %s() : Unknown Scan Mode %d)\n\r"), _T(__FUNCTION__), Scan));
            return POST_ERROR_ILLEGAL_PARAMETER;
        }
    }
    else
    {
        if (Scan == POST_PROGRESSIVE)
        {
            pCameraIF->GetCameraSFR()->CIGCTRL = (pCameraIF->GetCameraSFR()->CIGCTRL & ~(BM_CAM_INTERLACE)) | SCAN_PROGRESSIVE;
        }
        else if (Mode == POST_INTERLACE)
        {
            pCameraIF->GetCameraSFR()->CIGCTRL = (pCameraIF->GetCameraSFR()->CIGCTRL & ~(BM_CAM_INTERLACE)) | SCAN_INTERLACE;    
        }
        else
        {
            ERRMSG((_T("[POST:ERR] %s() : Unknown Scan Mode %d)\n\r"), _T(__FUNCTION__), Scan));
            return POST_ERROR_ILLEGAL_PARAMETER;
        }    
    }

    // General Register Set Flow
    //  Set the Source Format for DMA Input Source Format or Camera Input Source Format
    //  Set Input CSC
    //  Set Scaler Input Source Format
    // Concern about (CISRCFMT) -> MSCTRL -> CISCCTRL
    
    // Always we care about DMA Input
    pCameraIF->GetCameraSFR()->MSCTRL = (pCameraIF->GetCameraSFR()->MSCTRL & ~(BM_SEL_DMA_CAM | BM_WEAVE_IN | BM_ORDER2P_IN)) | INDMA_DMAPATH;
            
    switch(SrcType)
    {
    case POST_SRC_RGB16:
        pCameraIF->GetCameraSFR()->MSCTRL = (pCameraIF->GetCameraSFR()->MSCTRL & ~(BM_INFORMAT_M)) | INDMA_SRCRGB;
        pCameraIF->GetCameraSFR()->CISCCTRL = (pCameraIF->GetCameraSFR()->CISCCTRL & ~(BM_INRGB_FMT)) | SRCRGB_RGB565;
        break;
    case POST_SRC_RGB18:
        pCameraIF->GetCameraSFR()->MSCTRL = (pCameraIF->GetCameraSFR()->MSCTRL & ~(BM_INFORMAT_M)) | INDMA_SRCRGB;
        pCameraIF->GetCameraSFR()->CISCCTRL = (pCameraIF->GetCameraSFR()->CISCCTRL & ~(BM_INRGB_FMT)) | SRCRGB_RGB666;
        break;
    case POST_SRC_RGB24:
        pCameraIF->GetCameraSFR()->MSCTRL = (pCameraIF->GetCameraSFR()->MSCTRL & ~(BM_INFORMAT_M)) | INDMA_SRCRGB;
        pCameraIF->GetCameraSFR()->CISCCTRL = (pCameraIF->GetCameraSFR()->CISCCTRL & ~(BM_INRGB_FMT)) | SRCRGB_RGB888;
        break;
    case POST_SRC_YUV420:
        pCameraIF->GetCameraSFR()->MSCTRL = (pCameraIF->GetCameraSFR()->MSCTRL & ~(BM_INFORMAT_M | BM_C_INT_IN)) | INDMA_SRCYUV420_23PLANE | INDMA_SRCYUV_3PLANE;
        break;
    case POST_SRC_NV12:
        pCameraIF->GetCameraSFR()->MSCTRL = (pCameraIF->GetCameraSFR()->MSCTRL & ~(BM_INFORMAT_M | BM_C_INT_IN)) | INDMA_SRCYUV420_23PLANE | INDMA_SRCYUV_2PLANE;
        break;

    case POST_SRC_NV12_WEAVE:
        pCameraIF->GetCameraSFR()->MSCTRL = (pCameraIF->GetCameraSFR()->MSCTRL & ~(BM_INFORMAT_M | BM_C_INT_IN)) | BM_WEAVE_IN | INDMA_SRCYUV420_23PLANE | INDMA_SRCYUV_2PLANE;
        break;
        
    case POST_SRC_YUV422_YCBYCR:    // 1Plane
        pCameraIF->GetCameraSFR()->MSCTRL = (pCameraIF->GetCameraSFR()->MSCTRL & ~(BM_INFORMAT_M | BM_ORDER422_M)) | INDMA_SRCYUV422_1PLANE | INDMA_SRCYUV422_1PLANE_YCBYCR;
        break;
    case POST_SRC_YUV422_CBYCRY:
        pCameraIF->GetCameraSFR()->MSCTRL = (pCameraIF->GetCameraSFR()->MSCTRL & ~(BM_INFORMAT_M | BM_ORDER422_M)) | INDMA_SRCYUV422_1PLANE | INDMA_SRCYUV422_1PLANE_CBYCRY;    
        break;
    case POST_SRC_YUV422_YCRYCB:
        pCameraIF->GetCameraSFR()->MSCTRL = (pCameraIF->GetCameraSFR()->MSCTRL & ~(BM_INFORMAT_M | BM_ORDER422_M)) | INDMA_SRCYUV422_1PLANE | INDMA_SRCYUV422_1PLANE_YCRYCB;
        break;
    case POST_SRC_YUV422_CRYCBY:
        pCameraIF->GetCameraSFR()->MSCTRL = (pCameraIF->GetCameraSFR()->MSCTRL & ~(BM_INFORMAT_M | BM_ORDER422_M)) | INDMA_SRCYUV422_1PLANE | INDMA_SRCYUV422_1PLANE_CRYCBY;
        break;

    case POST_SRC_YUV422_YCBYCR_2PLANE:    // 2Plane
        pCameraIF->GetCameraSFR()->MSCTRL = (pCameraIF->GetCameraSFR()->MSCTRL & ~(BM_INFORMAT_M | BM_ORDER422_M | BM_C_INT_IN)) | INDMA_SRCYUV422_23PLANE_YCBYCR | INDMA_SRCYUV_2PLANE;
        break;
    case POST_SRC_YUV422_CBYCRY_2PLANE:
        pCameraIF->GetCameraSFR()->MSCTRL = (pCameraIF->GetCameraSFR()->MSCTRL & ~(BM_INFORMAT_M | BM_ORDER422_M | BM_C_INT_IN)) | INDMA_SRCYUV422_23PLANE_CBYCRY | INDMA_SRCYUV_2PLANE;    
        break;
    case POST_SRC_YUV422_YCRYCB_2PLANE:
        pCameraIF->GetCameraSFR()->MSCTRL = (pCameraIF->GetCameraSFR()->MSCTRL & ~(BM_INFORMAT_M | BM_ORDER422_M | BM_C_INT_IN)) | INDMA_SRCYUV422_23PLANE_YCRYCB | INDMA_SRCYUV_2PLANE;
        break;
    case POST_SRC_YUV422_CRYCBY_2PLANE:
        pCameraIF->GetCameraSFR()->MSCTRL = (pCameraIF->GetCameraSFR()->MSCTRL & ~(BM_INFORMAT_M | BM_ORDER422_M | BM_C_INT_IN)) | INDMA_SRCYUV422_23PLANE_CRYCBY | INDMA_SRCYUV_2PLANE;
        break;

    case POST_SRC_YUV422_YCBYCR_3PLANE:    // 3Plane
        pCameraIF->GetCameraSFR()->MSCTRL = (pCameraIF->GetCameraSFR()->MSCTRL & ~(BM_INFORMAT_M | BM_ORDER422_M | BM_C_INT_IN)) | INDMA_SRCYUV422_23PLANE_YCBYCR | INDMA_SRCYUV_3PLANE;
        break;
    case POST_SRC_YUV422_CBYCRY_3PLANE:
        pCameraIF->GetCameraSFR()->MSCTRL = (pCameraIF->GetCameraSFR()->MSCTRL & ~(BM_INFORMAT_M | BM_ORDER422_M | BM_C_INT_IN)) | INDMA_SRCYUV422_23PLANE_CBYCRY | INDMA_SRCYUV_3PLANE;    
        break;
    case POST_SRC_YUV422_YCRYCB_3PLANE:
        pCameraIF->GetCameraSFR()->MSCTRL = (pCameraIF->GetCameraSFR()->MSCTRL & ~(BM_INFORMAT_M | BM_ORDER422_M | BM_C_INT_IN)) | INDMA_SRCYUV422_23PLANE_YCRYCB | INDMA_SRCYUV_3PLANE;
        break;
    case POST_SRC_YUV422_CRYCBY_3PLANE:
        pCameraIF->GetCameraSFR()->MSCTRL = (pCameraIF->GetCameraSFR()->MSCTRL & ~(BM_INFORMAT_M | BM_ORDER422_M | BM_C_INT_IN)) | INDMA_SRCYUV422_23PLANE_CRYCBY | INDMA_SRCYUV_3PLANE;
        break;

        
    case POST_SRC_FIFO_YUV444:
        // Select Camera input path = Direct FIFO input path in Input DMA control
        pCameraIF->GetCameraSFR()->MSCTRL = (pCameraIF->GetCameraSFR()->MSCTRL & ~(BM_SEL_DMA_CAM)) | INDMA_FIFOPATH;
        // Select DMA output path for Scaler
        pCameraIF->GetCameraSFR()->CISCCTRL = (pCameraIF->GetCameraSFR()->CISCCTRL & ~(BM_LCDPATHEN)) | FIFO_OUT_DISABLE;
        // Select Writeback(Direct FIFO) input path in Global control
        pCameraIF->GetCameraSFR()->CIGCTRL = (pCameraIF->GetCameraSFR()->CIGCTRL & ~(BM_CAM_SEL_WB_CAMIF)) | INPUT_WB;
        break;
    default:
        ERRMSG((_T("[POST:ERR] %s() : Unknown Source Type %d)\n\r"), _T(__FUNCTION__), SrcType));
        error = POST_ERROR_ILLEGAL_PARAMETER;
        break;
    }

    // General Register Set Flow
    //  Set Scaler Output Target Format
    //  Set Output CSC  // Check to FIFO(RGB888, YUV444)
    //  Set the Source Format for DMA Output Target Format
    // Concern about CITRGFMT -> CIOCTRL -> CISCCTRL
    switch(DstType)
    {
    case POST_DST_RGB16:    // We don't care about Ext_RGB
        pCameraIF->GetCameraSFR()->CITRGFMT = (pCameraIF->GetCameraSFR()->CITRGFMT & ~(BM_OUTFORMAT)) | OUTFMT_RGB;
        pCameraIF->GetCameraSFR()->CISCCTRL = (pCameraIF->GetCameraSFR()->CISCCTRL & ~(BM_OUTRGB_FMT) & ~(BM_LCDPATHEN) )  | OUTRGB_RGB565 ;
        break;
    case POST_DST_RGB18:
        pCameraIF->GetCameraSFR()->CITRGFMT = (pCameraIF->GetCameraSFR()->CITRGFMT & ~(BM_OUTFORMAT)) | OUTFMT_RGB;
        pCameraIF->GetCameraSFR()->CISCCTRL = (pCameraIF->GetCameraSFR()->CISCCTRL & ~(BM_OUTRGB_FMT) & ~(BM_LCDPATHEN) ) | OUTRGB_RGB666;
        break;
    case POST_DST_RGB24:
        pCameraIF->GetCameraSFR()->CITRGFMT = (pCameraIF->GetCameraSFR()->CITRGFMT & ~(BM_OUTFORMAT)) | OUTFMT_RGB;
        pCameraIF->GetCameraSFR()->CISCCTRL = (pCameraIF->GetCameraSFR()->CISCCTRL & ~(BM_OUTRGB_FMT) & ~(BM_LCDPATHEN) ) | OUTRGB_RGB888;
        break;
    case POST_DST_YUV420:
        pCameraIF->GetCameraSFR()->CITRGFMT = (pCameraIF->GetCameraSFR()->CITRGFMT & ~(BM_OUTFORMAT)) | OUTFMT_YUV420_23PLANE;
        pCameraIF->GetCameraSFR()->CIOCTRL = (pCameraIF->GetCameraSFR()->CIOCTRL & ~(BM_C_INT_OUT)) | OUTDMA_YUV_3PLANE;
        pCameraIF->GetCameraSFR()->CISCCTRL = (pCameraIF->GetCameraSFR()->CISCCTRL & ~(BM_LCDPATHEN)) | FIFO_OUT_DISABLE;
        break;
    case POST_DST_NV12:
        pCameraIF->GetCameraSFR()->CITRGFMT = (pCameraIF->GetCameraSFR()->CITRGFMT & ~(BM_OUTFORMAT)) | OUTFMT_YUV420_23PLANE;
        pCameraIF->GetCameraSFR()->CIOCTRL = (pCameraIF->GetCameraSFR()->CIOCTRL & ~(BM_C_INT_OUT)) | OUTDMA_YUV_2PLANE;
        pCameraIF->GetCameraSFR()->CISCCTRL = (pCameraIF->GetCameraSFR()->CISCCTRL & ~(BM_LCDPATHEN)) | FIFO_OUT_DISABLE;
        break;
    case POST_DST_YUV422_YCBYCR:
        pCameraIF->GetCameraSFR()->CITRGFMT = (pCameraIF->GetCameraSFR()->CITRGFMT & ~(BM_OUTFORMAT)) | OUTFMT_YUV422_1PLANE;
        pCameraIF->GetCameraSFR()->CIOCTRL = (pCameraIF->GetCameraSFR()->CIOCTRL & ~(BM_ORDER422_OUT)) | OUTDMA_YUV422_1PLANE_YCBYCR;
        pCameraIF->GetCameraSFR()->CISCCTRL = (pCameraIF->GetCameraSFR()->CISCCTRL & ~(BM_LCDPATHEN)) | FIFO_OUT_DISABLE;
        break;
    case POST_DST_YUV422_CBYCRY:
        pCameraIF->GetCameraSFR()->CITRGFMT = (pCameraIF->GetCameraSFR()->CITRGFMT & ~(BM_OUTFORMAT)) | OUTFMT_YUV422_1PLANE;
        pCameraIF->GetCameraSFR()->CIOCTRL = (pCameraIF->GetCameraSFR()->CIOCTRL & ~(BM_ORDER422_OUT)) | OUTDMA_YUV422_1PLANE_CBYCRY;
        pCameraIF->GetCameraSFR()->CISCCTRL = (pCameraIF->GetCameraSFR()->CISCCTRL & ~(BM_LCDPATHEN)) | FIFO_OUT_DISABLE;
        break;
    case POST_DST_YUV422_YCRYCB:
        pCameraIF->GetCameraSFR()->CITRGFMT = (pCameraIF->GetCameraSFR()->CITRGFMT & ~(BM_OUTFORMAT)) | OUTFMT_YUV422_1PLANE;
        pCameraIF->GetCameraSFR()->CIOCTRL = (pCameraIF->GetCameraSFR()->CIOCTRL & ~(BM_ORDER422_OUT)) | OUTDMA_YUV422_1PLANE_YCRYCB;
        pCameraIF->GetCameraSFR()->CISCCTRL = (pCameraIF->GetCameraSFR()->CISCCTRL & ~(BM_LCDPATHEN)) | FIFO_OUT_DISABLE;
        break;
    case POST_DST_YUV422_CRYCBY:
        pCameraIF->GetCameraSFR()->CITRGFMT = (pCameraIF->GetCameraSFR()->CITRGFMT & ~(BM_OUTFORMAT)) | OUTFMT_YUV422_1PLANE;
        pCameraIF->GetCameraSFR()->CIOCTRL = (pCameraIF->GetCameraSFR()->CIOCTRL & ~(BM_ORDER422_OUT)) | OUTDMA_YUV422_1PLANE_CRYCBY;
        pCameraIF->GetCameraSFR()->CISCCTRL = (pCameraIF->GetCameraSFR()->CISCCTRL & ~(BM_LCDPATHEN)) | FIFO_OUT_DISABLE;
        break;
    case POST_DST_FIFO_YUV444:
        pCameraIF->GetCameraSFR()->CITRGFMT = (pCameraIF->GetCameraSFR()->CITRGFMT & ~(BM_OUTFORMAT)) | OUTFMT_YUV420_23PLANE;   // Any other except for RGB
        pCameraIF->GetCameraSFR()->CISCCTRL = (pCameraIF->GetCameraSFR()->CISCCTRL & ~(BM_LCDPATHEN)) | FIFO_OUT_ENABLE;
        break;
    case POST_DST_FIFO_RGB888:
        pCameraIF->GetCameraSFR()->CITRGFMT = (pCameraIF->GetCameraSFR()->CITRGFMT & ~(BM_OUTFORMAT)) | OUTFMT_RGB;    
        pCameraIF->GetCameraSFR()->CISCCTRL = (pCameraIF->GetCameraSFR()->CISCCTRL & ~(BM_LCDPATHEN)) | FIFO_OUT_ENABLE;
        break;
    default:
        ERRMSG((_T("[POST:ERR] %s() : Unknown Destination Type %d)\n\r"), _T(__FUNCTION__), DstType));
        error = POST_ERROR_ILLEGAL_PARAMETER;
        break;
    }

    DBGMSG(POST_FUNC && POST_USR2 ,(_T("[POST]--%s() : %d\n\r"), _T(__FUNCTION__), error));

    return error;
}

void CAMIFPostIF::SetSourceSize(unsigned int BaseWidth, unsigned int BaseHeight, unsigned int Width, unsigned int Height, unsigned int OffsetX, unsigned int OffsetY)
{
    // To use Post Processor, Image Width is limited to WORD(4Byte) boundary, 32Bpp->1Pixel, 16Bpp->2Pixel
    // This must be considered from Caller Application    
    DBGMSG(POST_FUNC && POST_USR2 ,(_T("[POST]++%s(%d, %d, %d, %d, %d, %d)\n\r"), _T(__FUNCTION__), BaseWidth, BaseHeight, Width, Height, OffsetX, OffsetY));

    m_PostConfig.SrcBaseWidth = BaseWidth;
    m_PostConfig.SrcBaseHeight = BaseHeight;
    m_PostConfig.SrcWidth = Width;
    m_PostConfig.SrcHeight = Height;
    m_PostConfig.SrcOffsetX = OffsetX;
    m_PostConfig.SrcOffsetY = OffsetY;

    DBGMSG(POST_FUNC && POST_USR2 ,(_T("[POST]--%s()\n\r"), _T(__FUNCTION__)));
}

void CAMIFPostIF::SetDestinationSize(unsigned int BaseWidth, unsigned int BaseHeight, unsigned int Width, unsigned int Height, unsigned int OffsetX, unsigned int OffsetY)
{
    // To use Post Processor, Image Width is limited to WORD(4Byte) boundary, 32Bpp->1Pixel, 16Bpp->2Pixel
    // This must be considered from Caller Application
    DBGMSG(POST_FUNC && POST_USR2 ,(_T("[POST]++%s(%d, %d, %d, %d, %d, %d)\n\r"), _T(__FUNCTION__), BaseWidth, BaseHeight, Width, Height, OffsetX, OffsetY));

    m_PostConfig.DstBaseWidth = BaseWidth;
    m_PostConfig.DstBaseHeight = BaseHeight;
    m_PostConfig.DstWidth = Width;
    m_PostConfig.DstHeight = Height;
    m_PostConfig.DstOffsetX = OffsetX;
    m_PostConfig.DstOffsetY = OffsetY;

    DBGMSG(POST_FUNC && POST_USR2 ,(_T("[POST]--%s()\n\r"), _T(__FUNCTION__)));
}

POST_ERROR CAMIFPostIF::UpdateCondition(void)
{
    POST_ERROR error = POST_SUCCESS;

    unsigned int dwCropInHSize, dwCropInVSize;
    unsigned int dwResizedOutHSize, dwResizedOutVSize;

    DBGMSG(POST_FUNC && POST_USR2 ,(_T("[POST]++%s()\n\r"), _T(__FUNCTION__)));
    
    DBGMSG(POST_FUNC && POST_USR2 ,(_T("[POST] tPostConfig Dump (%d,%d),{%d,[%d,%d,%d,%d,%d,%d],%d,[%d,%d,%d,%d,%d,%d]\r\n"),
            m_PostConfig.Mode,
            m_PostConfig.Scan,
            m_PostConfig.SrcType,
            m_PostConfig.SrcBaseWidth,
            m_PostConfig.SrcBaseHeight,
            m_PostConfig.SrcWidth,
            m_PostConfig.SrcHeight,
            m_PostConfig.SrcOffsetX,
            m_PostConfig.SrcOffsetY,

            m_PostConfig.DstType,
            m_PostConfig.DstBaseWidth,
            m_PostConfig.DstBaseHeight,
            m_PostConfig.DstWidth,
            m_PostConfig.DstHeight,
            m_PostConfig.DstOffsetX,
            m_PostConfig.DstOffsetY));

    if(m_PostConfig.SrcType != POST_SRC_FIFO_YUV444)
    {
        // 1. Input DMA Setting
        // Set Source Original Size = SrcBaseWidth, SrcBaseHeight
        pCameraIF->GetCameraSFR()->ORGISIZE = (pCameraIF->GetCameraSFR()->ORGISIZE & ~(BM_ORG_IN_H | BM_ORG_IN_V)) | 
                                SRC_WIDTH(m_PostConfig.SrcBaseWidth) | SRC_HEIGHT(m_PostConfig.SrcBaseHeight);    // For Input DMA

        // Set Source Cropped Size = SrcWidth, SrcHeight
        if(m_PostConfig.SrcBaseHeight == m_PostConfig.SrcHeight && m_PostConfig.SrcHeight / LINESKIP_RATE > m_PostConfig.DstHeight )
        {
            DBGMSG(POST_FUNC && POST_USR2 ,(_T("\n\n[POST]Try Line Skip!!!!\n\n\n\r")));

            pCameraIF->GetCameraSFR()->CIREAL_ISIZE = (pCameraIF->GetCameraSFR()->CIREAL_ISIZE & ~(BM_REAL_HEIGHT | BM_REAL_WIDTH)) | 
                                INDMA_REAL_WIDTH(m_PostConfig.SrcWidth) | INDMA_REAL_HEIGHT(m_PostConfig.SrcHeight/ LINESKIP_RATE);
            m_PostConfig.SrcHeight = m_PostConfig.SrcHeight / LINESKIP_RATE;
            pCameraIF->GetCameraSFR()->CIILINESKIP_Y = LINESKIP_RATE-1;
            pCameraIF->GetCameraSFR()->CIILINESKIP_CB = LINESKIP_RATE-1;
            pCameraIF->GetCameraSFR()->CIILINESKIP_CR = LINESKIP_RATE-1;
            
        }
        else
        {
        pCameraIF->GetCameraSFR()->CIREAL_ISIZE = (pCameraIF->GetCameraSFR()->CIREAL_ISIZE & ~(BM_REAL_HEIGHT | BM_REAL_WIDTH)) | 
                                INDMA_REAL_WIDTH(m_PostConfig.SrcWidth) | INDMA_REAL_HEIGHT(m_PostConfig.SrcHeight);
            pCameraIF->GetCameraSFR()->CIILINESKIP_Y = 0;
            pCameraIF->GetCameraSFR()->CIILINESKIP_CB = 0;

        }
        
        // Set Source Offset, Does not care about address and offset. instead, use SetDmaAddress function through it's IOCTL
    }
    else
    {
        // Configure original/base input size
        {
            UINT32  uiSrcHSizeLowBits, uiSrcHSizeHighBit;

            uiSrcHSizeLowBits = m_PostConfig.SrcBaseWidth & BW_SRCHSIZE_CAM;
            uiSrcHSizeHighBit = (m_PostConfig.SrcBaseWidth>>BC_SRCHSIZE_CAM) & 0x1;

            pCameraIF->GetCameraSFR()->CISRCFMT = (pCameraIF->GetCameraSFR()->CISRCFMT & ~(BM_SRCHSIZE_CAM)) | (uiSrcHSizeLowBits<<BP_SRCHSIZE_CAM);
            pCameraIF->GetCameraSFR()->CIEXTEN = (pCameraIF->GetCameraSFR()->CIEXTEN & ~(BM_SRCHSIZE_CAM_EXT)) | (uiSrcHSizeHighBit<<BP_SRCHSIZE_CAM_EXT);
            
            pCameraIF->GetCameraSFR()->CISRCFMT = (pCameraIF->GetCameraSFR()->CISRCFMT & ~(BM_SRCVSIZE_CAM)) | ((m_PostConfig.SrcBaseHeight & BW_SRCVSIZE_CAM)<<BP_SRCVSIZE_CAM);
        }

        // Configure start offset
        if( (m_PostConfig.SrcOffsetX == 0) && (m_PostConfig.SrcOffsetY == 0) && 
            (m_PostConfig.SrcWidth == m_PostConfig.SrcBaseWidth) && (m_PostConfig.SrcHeight == m_PostConfig.SrcBaseHeight) )
        {
            // Disable window offset
            pCameraIF->GetCameraSFR()->CIWDOFST = (pCameraIF->GetCameraSFR()->CIWDOFST & ~(BM_WINOFSEN)) | OFFSET_DISABLE;
        }
        else
        {
            // Enable window offset
            pCameraIF->GetCameraSFR()->CIWDOFST = (pCameraIF->GetCameraSFR()->CIWDOFST & ~(BM_WINOFSEN)) | OFFSET_ENABLE;

            // Configure horizontal and vertical offset
            {
                UINT32  uiHorOfstLowBits, uiHorOfstHighBit;

                uiHorOfstLowBits = m_PostConfig.SrcOffsetX & BW_WINHOROFST;
                uiHorOfstHighBit = (m_PostConfig.SrcOffsetX>>BC_WINHOROFST) & 0x1;

                pCameraIF->GetCameraSFR()->CIWDOFST= (pCameraIF->GetCameraSFR()->CIWDOFST & ~(BM_WINHOROFST)) | (uiHorOfstLowBits<<BP_WINHOROFST);
                pCameraIF->GetCameraSFR()->CIEXTEN = (pCameraIF->GetCameraSFR()->CIEXTEN & ~(BM_WINHOROFST_EXT)) | (uiHorOfstHighBit<<BP_WINHOROFST_EXT);
                
                pCameraIF->GetCameraSFR()->CIWDOFST = (pCameraIF->GetCameraSFR()->CIWDOFST & ~(BM_WINVEROFST)) | ((m_PostConfig.SrcOffsetY & BW_WINVEROFST)<<BP_WINVEROFST);
            }

            // Configure horizontal and vertical offset 2
            {
                UINT32  uiHorOfst2, uiVerOfst2;

                uiHorOfst2 = m_PostConfig.SrcBaseWidth - m_PostConfig.SrcOffsetX - m_PostConfig.SrcWidth;
                uiVerOfst2 = m_PostConfig.SrcBaseHeight- m_PostConfig.SrcOffsetY - m_PostConfig.SrcHeight;

                pCameraIF->GetCameraSFR()->CIWDOFST2 = (pCameraIF->GetCameraSFR()->CIWDOFST2 & ~(BM_WINHOROFST2)) | ((uiHorOfst2 & BW_WINHOROFST2)<<BP_WINHOROFST2);
                pCameraIF->GetCameraSFR()->CIWDOFST2 = (pCameraIF->GetCameraSFR()->CIWDOFST2 & ~(BM_WINVEROFST2)) | ((uiVerOfst2 & BW_WINVEROFST2)<<BP_WINVEROFST2);
            }
        }
    }

    // 2. Scaler Setting
    // 2-1. Check Input Rotator configuration
    switch(HIWORD(m_PostConfig.dwRotFlipMode))
    {
    case POST_90_NOFLIP:
    case POST_90_X_FLIP:
    case POST_90_Y_FLIP:
    case POST_90_XY_FLIP:
        dwCropInHSize = m_PostConfig.SrcHeight;
        dwCropInVSize = m_PostConfig.SrcWidth;
        break;
    default:
        dwCropInHSize = m_PostConfig.SrcWidth;
        dwCropInVSize = m_PostConfig.SrcHeight;
    }    
    switch(LOWORD(m_PostConfig.dwRotFlipMode))
    {
    case POST_90_NOFLIP:
    case POST_90_X_FLIP:
    case POST_90_Y_FLIP:
    case POST_90_XY_FLIP:
        dwResizedOutHSize = m_PostConfig.DstHeight;
        dwResizedOutVSize = m_PostConfig.DstWidth;
        break;
    default:
        dwResizedOutHSize = m_PostConfig.DstWidth;
        dwResizedOutVSize = m_PostConfig.DstHeight;
    }    

    pCameraIF->SetScaler(dwCropInHSize, dwCropInVSize, dwResizedOutHSize, dwResizedOutVSize);

    pCameraIF->GetCameraSFR()->CITRGFMT = (pCameraIF->GetCameraSFR()->CITRGFMT & ~(BM_TARGETHSIZE|BM_TARGETVSIZE)) |
                                               TRG_WIDTH(dwResizedOutHSize) | TRG_HEIGHT(dwResizedOutVSize);

    // 3. Output DMA Setting
    pCameraIF->GetCameraSFR()->ORGOSIZE = DST_WIDTH(m_PostConfig.DstBaseWidth) | DST_HEIGHT(m_PostConfig.DstBaseHeight);   // For Ouput DMA

    DBGMSG(POST_FUNC && POST_USR2 ,(_T("[POST]--%s() : %d\n\r"), _T(__FUNCTION__), error));

    return error;
}

void CAMIFPostIF::SetDmaMode(CAM_DMA_MODE InputDMA, CAM_DMA_MODE OutputDMA)
{
    DBGMSG(POST_FUNC && POST_USR2 ,(_T("[POST]++%s(%d, %d)\n\r"), _T(__FUNCTION__), InputDMA, OutputDMA));
    pCameraIF->GetCameraSFR()->CIDMAPARAM = (pCameraIF->GetCameraSFR()->CIDMAPARAM & ~((BW_MODE_R<<BP_MODE_R) | (BW_MODE_W<<BP_MODE_W)))
                                            | (InputDMA<<BP_MODE_R) | (OutputDMA<<BP_MODE_W);

    DBGMSG(POST_FUNC && POST_USR2 ,(_T("[POST]--%s()\n\r"), _T(__FUNCTION__)));                                            
}

POST_ERROR CAMIFPostIF::SetDmaAddress(POST_DMA_ADDRESS DMA, unsigned int AddrY, unsigned int AddrCb, unsigned int AddrCr)
{
    POST_ERROR error = POST_SUCCESS;

    unsigned int AddrStart_Y=0, AddrStart_Cb=0, AddrStart_Cr=0;
    unsigned int OffsetY_SrcWidth = 0, OffsetCb_SrcWidth = 0, OffsetCr_SrcWidth = 0;
    unsigned int OffsetY_SrcHeight = 0, OffsetCb_SrcHeight = 0, OffsetCr_SrcHeight = 0;

    unsigned int OffsetY_DstWidth = 0, OffsetCb_DstWidth = 0, OffsetCr_DstWidth = 0;
    unsigned int OffsetY_DstHeight = 0, OffsetCb_DstHeight = 0, OffsetCr_DstHeight = 0;
    
    DBGMSG(POST_FUNC && POST_USR2 ,(_T("[POST]++%s(%d, 0x%08x, 0x%08x, 0x%08x)\n\r"), _T(__FUNCTION__), DMA, AddrY, AddrCb, AddrCr));

    if (DMA == POST_SRC_ADDRESS || DMA == POST_NEXT_SRC_ADDRESS)
    {
        switch(m_PostConfig.SrcType)
        {
        case POST_SRC_RGB16:
        case POST_SRC_YUV422_YCBYCR:
        case POST_SRC_YUV422_CBYCRY:
        case POST_SRC_YUV422_YCRYCB:
        case POST_SRC_YUV422_CRYCBY:
            OffsetY_SrcWidth = m_PostConfig.SrcOffsetX*2;

            OffsetY_SrcHeight = m_PostConfig.SrcOffsetY;

            AddrStart_Y = AddrY;
            break;
        case POST_SRC_RGB24:
        case POST_SRC_RGB18:
            OffsetY_SrcWidth = m_PostConfig.SrcOffsetX*4;

            OffsetY_SrcHeight = m_PostConfig.SrcOffsetY;

            AddrStart_Y = AddrY;
            break;
        case POST_SRC_YUV420:   // 3Plane
        case POST_SRC_YUV422_YCBYCR_3PLANE:
        case POST_SRC_YUV422_CBYCRY_3PLANE:
        case POST_SRC_YUV422_YCRYCB_3PLANE:
        case POST_SRC_YUV422_CRYCBY_3PLANE:

            OffsetY_SrcWidth = m_PostConfig.SrcOffsetX;
            OffsetCb_SrcWidth = m_PostConfig.SrcOffsetX/2;
            OffsetCr_SrcWidth = m_PostConfig.SrcOffsetX/2;

            OffsetY_SrcHeight = m_PostConfig.SrcOffsetY;
            OffsetCb_SrcHeight = m_PostConfig.SrcOffsetY/2;
            OffsetCr_SrcHeight = m_PostConfig.SrcOffsetY/2;

            AddrStart_Y = AddrY;
            AddrStart_Cb = AddrCb;
            AddrStart_Cr = AddrCr;
            break;
        case POST_SRC_NV12:   // 2Plane
        case POST_SRC_NV12_WEAVE:
        case POST_SRC_YUV422_YCBYCR_2PLANE:
        case POST_SRC_YUV422_CBYCRY_2PLANE:
        case POST_SRC_YUV422_YCRYCB_2PLANE:
        case POST_SRC_YUV422_CRYCBY_2PLANE:

            OffsetY_SrcWidth = m_PostConfig.SrcOffsetX;
            OffsetCb_SrcWidth = m_PostConfig.SrcOffsetX;
            OffsetCr_SrcWidth = m_PostConfig.SrcOffsetX;  // Don't care

            OffsetY_SrcHeight = m_PostConfig.SrcOffsetY;
            OffsetCb_SrcHeight = m_PostConfig.SrcOffsetY/2;
            OffsetCr_SrcHeight = m_PostConfig.SrcOffsetY/2;  // Don't care

            AddrStart_Y = AddrY;
            AddrStart_Cb = AddrCb;
            AddrStart_Cr = AddrCr;    // Don't care
            break;
            
        default:
            ERRMSG((_T("[POST:ERR] %s() : Unknown Format %d\r\n"), _T(__FUNCTION__), m_PostConfig.SrcType));
            return POST_ERROR_ILLEGAL_PARAMETER;
        }
    }
    else if (DMA == POST_DST_ADDRESS || DMA == POST_NEXT_DST_ADDRESS || \
                DMA == POST_DST_1ST_ADDRESS || DMA == POST_DST_2ND_ADDRESS || \
             DMA == POST_DST_3RD_ADDRESS || DMA == POST_DST_4TH_ADDRESS )
    {
        switch(m_PostConfig.DstType)
        {
        case POST_DST_RGB16:
        case POST_DST_YUV422_YCBYCR:
        case POST_DST_YUV422_CBYCRY:
        case POST_DST_YUV422_YCRYCB:
        case POST_DST_YUV422_CRYCBY:
            OffsetY_DstWidth = m_PostConfig.DstOffsetX*2;
            
            OffsetY_DstHeight = m_PostConfig.DstOffsetY;

            AddrStart_Y = AddrY;
            break;
        case POST_DST_RGB24:
        case POST_DST_RGB18:
            OffsetY_DstWidth = m_PostConfig.DstOffsetX*4;

            OffsetY_DstHeight = m_PostConfig.DstOffsetY;

            AddrStart_Y = AddrY;
            break;
        case POST_DST_YUV420:
            OffsetY_DstWidth = m_PostConfig.DstOffsetX;
            OffsetCb_DstWidth = m_PostConfig.DstOffsetX/2;
            OffsetCr_DstWidth = m_PostConfig.DstOffsetX/2;

            OffsetY_DstHeight = m_PostConfig.DstOffsetY;
            OffsetCb_DstHeight = m_PostConfig.DstOffsetY/2;
            OffsetCr_DstHeight = m_PostConfig.DstOffsetY/2;

            AddrStart_Y = AddrY;
            AddrStart_Cb = AddrCb;
            AddrStart_Cr = AddrCr;
            break;
        case POST_DST_NV12:
            OffsetY_DstWidth = m_PostConfig.DstOffsetX;
            OffsetCb_DstWidth = m_PostConfig.DstOffsetX;
            OffsetCr_DstWidth = m_PostConfig.DstOffsetX;

            OffsetY_DstHeight = m_PostConfig.DstOffsetY;
            OffsetCb_DstHeight = m_PostConfig.DstOffsetY/2;
            OffsetCr_DstHeight = m_PostConfig.DstOffsetY/2;

            AddrStart_Y = AddrY;
            AddrStart_Cb = AddrCb;
            AddrStart_Cr = AddrCr;
            break;
        default:
            ERRMSG((_T("[POST:ERR] %s() : Unknown Format %d\r\n"), _T(__FUNCTION__), m_PostConfig.DstType));
            return POST_ERROR_ILLEGAL_PARAMETER;
        }
    }
    else
    {
        ERRMSG((_T("[POST:ERR] %s() : Unknown DMA address %d\r\n"), _T(__FUNCTION__), DMA));
        return POST_ERROR_ILLEGAL_PARAMETER;
    }

    switch(DMA)
    {
    case POST_SRC_ADDRESS:
        LOCK_ADDR_FETCH(pCameraIF->GetCameraSFR());    // To prevent address from changing still in register setting, This will be enabled in EVT1
        pCameraIF->GetCameraSFR()->CIIYSA0   = AddrStart_Y;
        pCameraIF->GetCameraSFR()->CIICBSA0   = AddrStart_Cb;
        pCameraIF->GetCameraSFR()->CIICRSA0   = AddrStart_Cr;
        pCameraIF->GetCameraSFR()->CIIYOFF   = CIIYOFF(OffsetY_SrcHeight,OffsetY_SrcWidth);
        pCameraIF->GetCameraSFR()->CIICBOFF  = CIICBOFF(OffsetCb_SrcHeight,OffsetCb_SrcWidth);
        pCameraIF->GetCameraSFR()->CIICROFF  = CIICROFF(OffsetCr_SrcHeight,OffsetCr_SrcWidth);
        UNLOCK_ADDR_FETCH(pCameraIF->GetCameraSFR());    // Now, address can change, This will be enabled in EVT1
        break;
    case POST_NEXT_SRC_ADDRESS:
        LOCK_ADDR_FETCH(pCameraIF->GetCameraSFR());    // To prevent address from changing still in register setting, This will be enabled in EVT1
        pCameraIF->GetCameraSFR()->CIIYSA0   = AddrStart_Y;
        pCameraIF->GetCameraSFR()->CIICBSA0   = AddrStart_Cb;
        pCameraIF->GetCameraSFR()->CIICRSA0   = AddrStart_Cr;
        pCameraIF->GetCameraSFR()->CIIYOFF   = CIIYOFF(OffsetY_SrcHeight,OffsetY_SrcWidth);
        pCameraIF->GetCameraSFR()->CIICBOFF  = CIICBOFF(OffsetCb_SrcHeight,OffsetCb_SrcWidth);
        pCameraIF->GetCameraSFR()->CIICROFF  = CIICROFF(OffsetCr_SrcHeight,OffsetCr_SrcWidth);
        UNLOCK_ADDR_FETCH(pCameraIF->GetCameraSFR());    // Now, address can change, This will be enabled in EVT1
        break;
#if 1
    case POST_DST_ADDRESS:
    //case POST_NEXT_DST_ADDRESS:
        //LOCK_ADDR_FETCH(pCameraIF->GetCameraSFR());    // To prevent address from changing still in register setting, This will be enabled in EVT1
        pCameraIF->GetCameraSFR()->CIOYSA1   = AddrStart_Y;
        pCameraIF->GetCameraSFR()->CIOCBSA1  = AddrStart_Cb;
        pCameraIF->GetCameraSFR()->CIOCRSA1  = AddrStart_Cr;
        pCameraIF->GetCameraSFR()->CIOYSA3   = AddrStart_Y;
        pCameraIF->GetCameraSFR()->CIOCBSA3  = AddrStart_Cb;
        pCameraIF->GetCameraSFR()->CIOCRSA3  = AddrStart_Cr;
        pCameraIF->GetCameraSFR()->CIOYSA2   = AddrStart_Y;
        pCameraIF->GetCameraSFR()->CIOCBSA2  = AddrStart_Cb;
        pCameraIF->GetCameraSFR()->CIOCRSA2  = AddrStart_Cr;
        pCameraIF->GetCameraSFR()->CIOYSA4   = AddrStart_Y;
        pCameraIF->GetCameraSFR()->CIOCBSA4  = AddrStart_Cb;
        pCameraIF->GetCameraSFR()->CIOCRSA4  = AddrStart_Cr;
        pCameraIF->GetCameraSFR()->CIOYOFF   = CIOYOFF(OffsetY_DstHeight,OffsetY_DstWidth);
        pCameraIF->GetCameraSFR()->CIOCBOFF  = CIOCBOFF(OffsetCb_DstHeight,OffsetCb_DstWidth);
        pCameraIF->GetCameraSFR()->CIOCROFF  = CIOCROFF(OffsetCr_DstHeight,OffsetCr_DstWidth);
        //UNLOCK_ADDR_FETCH(pCameraIF->GetCameraSFR());    // Now, address can change, This will be enabled in EVT1
        break;
    case POST_DST_1ST_ADDRESS:
        //LOCK_ADDR_FETCH(pCameraIF->GetCameraSFR());    // To prevent address from changing still in register setting, This will be enabled in EVT1
        pCameraIF->GetCameraSFR()->CIOYSA1   = AddrStart_Y;
        pCameraIF->GetCameraSFR()->CIOCBSA1  = AddrStart_Cb;
        pCameraIF->GetCameraSFR()->CIOCRSA1  = AddrStart_Cr;
        pCameraIF->GetCameraSFR()->CIOYOFF   = CIOYOFF(OffsetY_DstHeight,OffsetY_DstWidth);
        pCameraIF->GetCameraSFR()->CIOCBOFF  = CIOCBOFF(OffsetCb_DstHeight,OffsetCb_DstWidth);
        pCameraIF->GetCameraSFR()->CIOCROFF  = CIOCROFF(OffsetCr_DstHeight,OffsetCr_DstWidth);
        //UNLOCK_ADDR_FETCH(pCameraIF->GetCameraSFR());    // Now, address can change, This will be enabled in EVT1
        break;
    case POST_DST_2ND_ADDRESS:
        //LOCK_ADDR_FETCH(pCameraIF->GetCameraSFR());    // To prevent address from changing still in register setting, This will be enabled in EVT1
        pCameraIF->GetCameraSFR()->CIOYSA2   = AddrStart_Y;
        pCameraIF->GetCameraSFR()->CIOCBSA2  = AddrStart_Cb;
        pCameraIF->GetCameraSFR()->CIOCRSA2  = AddrStart_Cr;
        pCameraIF->GetCameraSFR()->CIOYOFF   = CIOYOFF(OffsetY_DstHeight,OffsetY_DstWidth);
        pCameraIF->GetCameraSFR()->CIOCBOFF  = CIOCBOFF(OffsetCb_DstHeight,OffsetCb_DstWidth);
        pCameraIF->GetCameraSFR()->CIOCROFF  = CIOCROFF(OffsetCr_DstHeight,OffsetCr_DstWidth);
        //UNLOCK_ADDR_FETCH(pCameraIF->GetCameraSFR());    // Now, address can change, This will be enabled in EVT1
        break;
    case POST_DST_3RD_ADDRESS:
        //LOCK_ADDR_FETCH(pCameraIF->GetCameraSFR());    // To prevent address from changing still in register setting, This will be enabled in EVT1
        pCameraIF->GetCameraSFR()->CIOYSA3   = AddrStart_Y;
        pCameraIF->GetCameraSFR()->CIOCBSA3  = AddrStart_Cb;
        pCameraIF->GetCameraSFR()->CIOCRSA3  = AddrStart_Cr;
        pCameraIF->GetCameraSFR()->CIOYOFF   = CIOYOFF(OffsetY_DstHeight,OffsetY_DstWidth);
        pCameraIF->GetCameraSFR()->CIOCBOFF  = CIOCBOFF(OffsetCb_DstHeight,OffsetCb_DstWidth);
        pCameraIF->GetCameraSFR()->CIOCROFF  = CIOCROFF(OffsetCr_DstHeight,OffsetCr_DstWidth);
        //UNLOCK_ADDR_FETCH(pCameraIF->GetCameraSFR());    // Now, address can change, This will be enabled in EVT1
        break;
    case POST_DST_4TH_ADDRESS:
        //LOCK_ADDR_FETCH(pCameraIF->GetCameraSFR());    // To prevent address from changing still in register setting, This will be enabled in EVT1
        pCameraIF->GetCameraSFR()->CIOYSA4   = AddrStart_Y;
        pCameraIF->GetCameraSFR()->CIOCBSA4  = AddrStart_Cb;
        pCameraIF->GetCameraSFR()->CIOCRSA4  = AddrStart_Cr;
        pCameraIF->GetCameraSFR()->CIOYOFF   = CIOYOFF(OffsetY_DstHeight,OffsetY_DstWidth);
        pCameraIF->GetCameraSFR()->CIOCBOFF  = CIOCBOFF(OffsetCb_DstHeight,OffsetCb_DstWidth);
        pCameraIF->GetCameraSFR()->CIOCROFF  = CIOCROFF(OffsetCr_DstHeight,OffsetCr_DstWidth);
        //UNLOCK_ADDR_FETCH(pCameraIF->GetCameraSFR());    // Now, address can change, This will be enabled in EVT1
        break;
#else
    case POST_DST_ADDRESS:
        LOCK_ADDR_FETCH(pCameraIF->GetCameraSFR());    // To prevent address from changing still in register setting, This will be enabled in EVT1        
        pCameraIF->GetCameraSFR()->CIOYSA1   = AddrStart_Y;
        pCameraIF->GetCameraSFR()->CIOCBSA1  = AddrStart_Cb;
        pCameraIF->GetCameraSFR()->CIOCRSA1  = AddrStart_Cr;
        pCameraIF->GetCameraSFR()->CIOYSA3   = AddrStart_Y;      // We have 4 Address Buffer. but we will use double buffering scheme
        pCameraIF->GetCameraSFR()->CIOCBSA3  = AddrStart_Cb;
        pCameraIF->GetCameraSFR()->CIOCRSA3  = AddrStart_Cr;        
        pCameraIF->GetCameraSFR()->CIOYOFF   = CIOYOFF(OffsetY_DstHeight,OffsetY_DstWidth);
        pCameraIF->GetCameraSFR()->CIOCBOFF  = CIOCBOFF(OffsetCb_DstHeight,OffsetCb_DstWidth);
        pCameraIF->GetCameraSFR()->CIOCROFF  = CIOCROFF(OffsetCr_DstHeight,OffsetCr_DstWidth);
        UNLOCK_ADDR_FETCH(pCameraIF->GetCameraSFR());    // Now, address can change, This will be enabled in EVT1
        break;
    case POST_NEXT_DST_ADDRESS:
        LOCK_ADDR_FETCH(pCameraIF->GetCameraSFR());    // To prevent address from changing still in register setting, This will be enabled in EVT1
        pCameraIF->GetCameraSFR()->CIOYSA2   = AddrStart_Y;
        pCameraIF->GetCameraSFR()->CIOCBSA2  = AddrStart_Cb;
        pCameraIF->GetCameraSFR()->CIOCRSA2  = AddrStart_Cr;
        pCameraIF->GetCameraSFR()->CIOYSA4   = AddrStart_Y;
        pCameraIF->GetCameraSFR()->CIOCBSA4  = AddrStart_Cb;
        pCameraIF->GetCameraSFR()->CIOCRSA4  = AddrStart_Cr;
        pCameraIF->GetCameraSFR()->CIOYOFF   = CIOYOFF(OffsetY_DstHeight,OffsetY_DstWidth);
        pCameraIF->GetCameraSFR()->CIOCBOFF  = CIOCBOFF(OffsetCb_DstHeight,OffsetCb_DstWidth);
        pCameraIF->GetCameraSFR()->CIOCROFF  = CIOCROFF(OffsetCr_DstHeight,OffsetCr_DstWidth);
        UNLOCK_ADDR_FETCH(pCameraIF->GetCameraSFR());    // Now, address can change, This will be enabled in EVT1
        break;
#endif
    default:
        return POST_ERROR_ILLEGAL_PARAMETER;
    }

    DBGMSG(POST_FUNC && POST_USR2 ,(_T("[POST]--%s() : %d\n\r"), _T(__FUNCTION__), error));

    return error;
}

