⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mfcdriver.cpp

📁 6410BSP3
💻 CPP
📖 第 1 页 / 共 3 页
字号:
        is_mfc_on = FALSE;
// MOON_PowerManagementOfMultiInstance
        // Check if MFC is being used
        // and change the MFC instance state to PowerOff
        for (int inst_no = 0; inst_no < MFC_NUM_INSTANCES_MAX; inst_no++) {
            MFCInstCtx *mfcinst_ctx = MFCInst_GetCtx(inst_no);
            if (mfcinst_ctx)
            {
                nNumOfInstance++;
                   LOG_MSG(LOG_TRACE, "MFC_IOControl", "[MFC IOCTL_POWER_SET] MFC State = 0x%X \r\n",(DWORD) (MFCINST_STATE(mfcinst_ctx)));        
                if (MFCINST_STATE_CHECK(mfcinst_ctx, MFCINST_STATE_CREATED) || MFCINST_STATE_CHECK(mfcinst_ctx, MFCINST_STATE_DELETED))
                {    
                       LOG_MSG(LOG_TRACE, "MFC_IOControl", "[MFC IOCTL_POWER_SET] MFC doesn't working!!! MFC State = 0x%X \r\n",(DWORD) (MFCINST_STATE(mfcinst_ctx)));        
                       MFCInst_PowerOffState(mfcinst_ctx);
                }
                else
                {
                is_mfc_on = TRUE;
                // On Power Down, the MFC instance is invalidated.
                // Then the MFC operations (DEC_EXE, ENC_EXE, etc.) will not be performed
                // until it is validated by entering Power Up state transition.
                MFCInst_PowerOffState(mfcinst_ctx);
            }
        }
// End MOON_PowerManagementOfMultiInstance
        }

        if (is_mfc_on) {
            Mfc_Clk_On();
            MFC_Sleep();
            // Clock & Power off the MFC block if they are on.
            Mfc_Clk_Off();

            LOG_MSG(LOG_TRACE, "MFC_IOControl", "[MFC IOCTL_POWER_SET] POWER DOWN, handle = 0x%X \r\n",(DWORD) OpenHandle);

        }
    }

    mfc_pwr_state = D4;    // MFC power state is now changed to D4(Sleep) state.

    return mfc_pwr_state;
}

/*
** Function Name : MFC_IOControl
**
** Function Description : This function support any process of MFC instance.
*/
BOOL
MFC_IOControl(
    DWORD OpenHandle,
    DWORD dwIoControlCode,
    PBYTE pInBuf,
    DWORD nInBufSize,
    PBYTE pOutBuf,
    DWORD nOutBufSize,
    PDWORD pBytesReturned
    )
{
    MFC_HANDLE  *handle;
    MFCInstCtx     *pMfcInst;
    MFC_ARGS      *args;

    int ret                       = MFCINST_RET_OK;
    unsigned char  *p_buf         = NULL;
    int n_bufsize                 = 0;
    PVOID pMarshalledInBuf        = NULL;
 
    ULONGLONG    phyAddr;
    BOOL    result = TRUE;

    handle = (MFC_HANDLE *) OpenHandle;
    //args = (MFC_ARGS *) pInBuf;

    /////////////////////
    // Parameter Check //
    /////////////////////
    if (handle == NULL)
    {
        LOG_MSG(LOG_TRACE, "MFC_IOControl", "OpenHandle == NULL\n");
        return FALSE;
    }

    if (handle != gMfcHandlePower)
    {
        if (pInBuf == NULL)
        {
            LOG_MSG(LOG_TRACE, "MFC_IOControl", "pInBuf == NULL\n");
            return FALSE;
        }
        if (nInBufSize == 0)
        {
            LOG_MSG(LOG_TRACE, "MFC_IOControl", "nInBufSize == 0\n");
            return FALSE;
        }
        if ((pOutBuf != NULL) || (nOutBufSize != 0) || (pBytesReturned != NULL))
        {
            LOG_MSG(LOG_TRACE, "MFC_IOControl", "others.....\n");
            return FALSE;
        }
    }

    pMfcInst = handle->mfc_inst;

    MFC_Mutex_Lock();

    switch ( dwIoControlCode )
    {
    case IOCTL_POWER_CAPABILITIES:
        {
            RETAILMSG(1, (L"[MFC IOCTL_POWER_CAPABILITIES]\n"));

            PPOWER_CAPABILITIES ppc;

            __try
            {
                if ( !pBytesReturned || !pOutBuf || (nOutBufSize < sizeof(POWER_CAPABILITIES)) ) {
                    SetLastError (ERROR_INVALID_PARAMETER);
                    MFC_Mutex_Release();
                    return FALSE;
                }

                ppc = (PPOWER_CAPABILITIES)pOutBuf;
                memset(ppc, 0, sizeof(POWER_CAPABILITIES));

                // support D0, D4
                ppc->DeviceDx = DX_MASK(D0) | DX_MASK(D4);

                // no wake
                // no inrush

                // Report our nominal power consumption in uAmps rather than mWatts.
                ppc->Flags = POWER_CAP_PREFIX_MICRO | POWER_CAP_UNIT_AMPS;

                *pBytesReturned = sizeof(POWER_CAPABILITIES);

                RETAILMSG(1, (L"[MFC IOCTL_POWER_CAPABILITIES] leaving...\n"));
            }
            __except(EXCEPTION_EXECUTE_HANDLER)
            {
                RETAILMSG(1, (L"[MFC IOCTL_POWER_CAPABILITIES] exception...\n"));
                MFC_Mutex_Release();
                return FALSE;
            }
            break;
        }

    case IOCTL_POWER_SET:
        CEDEVICE_POWER_STATE NewDx;

        //if caller is not kernel mode, do not allow setting power state
        if (GetDirectCallerProcessId() != GetCurrentProcessId()){
            return ERROR_ACCESS_DENIED;
        }

        __try
        {
            if (pOutBuf == NULL)
            {
                return FALSE;
            }
            NewDx = *(PCEDEVICE_POWER_STATE) pOutBuf;

            RETAILMSG(1, (L"[MFC IOCTL_POWER_SET] newdx = %d\n", NewDx));

            switch ( NewDx )
            {
            case D0:    // Power Up
                *(PCEDEVICE_POWER_STATE)pOutBuf = process_MFC_PowerUp(OpenHandle);
                break;

            case D4:    // Power Down
                *(PCEDEVICE_POWER_STATE)pOutBuf = process_MFC_PowerDown(OpenHandle);
                break;

            default:
                MFC_Mutex_Release();
                return FALSE;
            }

            *pBytesReturned = sizeof(CEDEVICE_POWER_STATE);
        }
        __except(EXCEPTION_EXECUTE_HANDLER)
        {
            RETAILMSG(1, (L"[MFC IOCTL_POWER_SET] exception...\n"));
            MFC_Mutex_Release();
            return FALSE;
        }

        break;

    case IOCTL_MFC_MPEG4_ENC_INIT:
    case IOCTL_MFC_H264_ENC_INIT:
    case IOCTL_MFC_H263_ENC_INIT:
        {
            MFC_CODECMODE   codec_mode;
            enc_info_t      enc_info;

            if (dwIoControlCode == IOCTL_MFC_MPEG4_ENC_INIT)
                codec_mode = MP4_ENC;
            else if (dwIoControlCode == IOCTL_MFC_H264_ENC_INIT)
                codec_mode = AVC_ENC;
            else
                codec_mode = H263_ENC;

            if(FAILED(CeOpenCallerBuffer(&pMarshalledInBuf, pInBuf, nInBufSize, ARG_IO_PTR, TRUE)))
            {
                RETAILMSG(1, (TEXT("MFC_IOControl: CeOpenCallerBuffer failed in IOCTL_MFC_H263_ENC_INIT.\r\n")));
                MFC_Mutex_Release();
                return FALSE;
            }

            args = (MFC_ARGS *)pMarshalledInBuf;

            // Input arguments for IOCTL_MFC_xxx_ENC_INIT
            enc_info.width        = args->enc_init.in_width;
            enc_info.height        = args->enc_init.in_height;
            enc_info.frameRateRes    = args->enc_init.in_frameRateRes;
            enc_info.frameRateDiv    = args->enc_init.in_frameRateDiv;
            enc_info.gopNum        = args->enc_init.in_gopNum;
            enc_info.bitrate        = args->enc_init.in_bitrate;

            enc_info.intraqp        = args->enc_init.in_intraqp;
            enc_info.qpmax        = args->enc_init.in_qpmax;
            enc_info.gamma        = args->enc_init.in_gamma;

            ///////////////////////////////////
            ///   Initialize MFC Instance   ///
            ///////////////////////////////////
            Mfc_Clk_On();
            ret = MFCInst_Enc_Init(pMfcInst, codec_mode, &enc_info);
            Mfc_Clk_Off();

            // Output arguments for IOCTL_MFC_xxx_ENC_INIT
            args->enc_init.ret_code = ret;

            if(FAILED(CeCloseCallerBuffer(pMarshalledInBuf, pInBuf, nInBufSize, ARG_IO_PTR)))
            {
                RETAILMSG(1, (TEXT("MFC_IOControl: CeCloseCallerBuffer failed in IOCTL_MFC_H263_ENC_INIT.\r\n")));
                MFC_Mutex_Release();
                return FALSE;
            }

            break;
        }

    case IOCTL_MFC_MPEG4_ENC_EXE:
    case IOCTL_MFC_H264_ENC_EXE:
    case IOCTL_MFC_H263_ENC_EXE:
        {
            int nStrmLen, nHdrLen;
            if(FAILED(CeOpenCallerBuffer(&pMarshalledInBuf, pInBuf, nInBufSize, ARG_IO_PTR, TRUE)))
            {
                RETAILMSG(1, (TEXT("MFC_IOControl: CeOpenCallerBuffer failed in IOCTL_MFC_H263_ENC_EXE.\r\n")));
                MFC_Mutex_Release();
                return FALSE;
            }

            args = (MFC_ARGS *)pMarshalledInBuf;
            MFCInst_GetFramBuf(pMfcInst, &p_buf, &n_bufsize);
            CleanInvalidateCacheRange((PBYTE )p_buf, (PBYTE )(p_buf + n_bufsize) );
            
            // nStrmLen is size of output stream data
            Mfc_Clk_On();
            ret = MFCInst_Encode(pMfcInst, &nStrmLen, &nHdrLen);
            Mfc_Clk_Off();

            MFCInst_GetLineBuf(pMfcInst, &p_buf, &n_bufsize);
            InvalidateCacheRange((PBYTE )p_buf, (PBYTE )(p_buf + n_bufsize) );
        
            // Output arguments for IOCTL_MFC_xxx_ENC_EXE
            args->enc_exe.ret_code = ret;
            if (ret == MFCINST_RET_OK) {
                args->enc_exe.out_encoded_size = nStrmLen;
                args->enc_exe.out_header_size  = nHdrLen;
            }

            if(FAILED(CeCloseCallerBuffer(pMarshalledInBuf, pInBuf, nInBufSize, ARG_IO_PTR)))
            {
                RETAILMSG(1, (TEXT("MFC_IOControl: CeCloseCallerBuffer failed in IOCTL_MFC_H263_ENC_EXE.\r\n")));
                MFC_Mutex_Release();
                return FALSE;
            }

            break;
        }

    case IOCTL_MFC_MPEG4_DEC_INIT:
    case IOCTL_MFC_H263_DEC_INIT:
    case IOCTL_MFC_H264_DEC_INIT:
    case IOCTL_MFC_VC1_DEC_INIT:
        {
            MFC_CODECMODE   codec_mode;

            if(FAILED(CeOpenCallerBuffer(&pMarshalledInBuf, pInBuf, nInBufSize, ARG_IO_PTR, TRUE)))
            {
                RETAILMSG(1, (TEXT("MFC_IOControl: CeOpenCallerBuffer failed in IOCTL_MFC_VC1_DEC_INIT.\r\n")));
                MFC_Mutex_Release();
                return FALSE;
            }

            args = (MFC_ARGS *)pMarshalledInBuf;

            if (dwIoControlCode == IOCTL_MFC_MPEG4_DEC_INIT) {
                codec_mode = MP4_DEC;
            }
            else if (dwIoControlCode == IOCTL_MFC_H263_DEC_INIT) {
                codec_mode = MP4_DEC;
            }
            else if (dwIoControlCode == IOCTL_MFC_H264_DEC_INIT) {
                codec_mode = AVC_DEC;
            }
            else {
                codec_mode = VC1_DEC;
            }

            /////////////////////////////////
            //   Initialize MFC Instance   //
            /////////////////////////////////
            Mfc_Clk_On();
            ret = MFCInst_Dec_Init(pMfcInst, codec_mode, args->dec_init.in_strmSize);
            Mfc_Clk_Off();

            // Output arguments for IOCTL_MFC_xxx_DEC_INIT
            args->dec_init.ret_code = ret;
            if (ret == MFCINST_RET_OK) {
                args->dec_init.out_width  = pMfcInst->width;
                args->dec_init.out_height = pMfcInst->height;
            }

            if(FAILED(CeCloseCallerBuffer(pMarshalledInBuf, pInBuf, nInBufSize, ARG_IO_PTR)))
            {
                RETAILMSG(1, (TEXT("MFC_IOControl: CeCloseCallerBuffer failed in IOCTL_MFC_VC1_DEC_INIT.\r\n")));
                MFC_Mutex_Release();
                return FALSE;
            }

            break;
        }

    case IOCTL_MFC_MPEG4_DEC_EXE:
    case IOCTL_MFC_H263_DEC_EXE:
    case IOCTL_MFC_H264_DEC_EXE:
    case IOCTL_MFC_VC1_DEC_EXE:

        if(FAILED(CeOpenCallerBuffer(&pMarshalledInBuf, pInBuf, nInBufSize, ARG_IO_PTR, TRUE)))
        {
            RETAILMSG(1, (TEXT("MFC_IOControl: CeOpenCallerBuffer failed in IOCTL_MFC_VC1_DEC_EXE.\r\n")));
            MFC_Mutex_Release();
            return FALSE;
        }

        args = (MFC_ARGS *)pMarshalledInBuf;

        MFCInst_GetLineBuf(pMfcInst, &p_buf, &n_bufsize);
        CleanInvalidateCacheRange((PBYTE )p_buf, (PBYTE )(p_buf + n_bufsize) );

        Mfc_Clk_On();
        ret = MFCInst_Decode(pMfcInst, args->dec_exe.in_strmSize);
        Mfc_Clk_Off();

        // Output arguments for IOCTL_MFC_xxx_DEC_EXE
        args->dec_exe.ret_code = ret;

        if(FAILED(CeCloseCallerBuffer(pMarshalledInBuf, pInBuf, nInBufSize, ARG_IO_PTR)))
        {
            RETAILMSG(1, (TEXT("MFC_IOControl: CeCloseCallerBuffer failed in IOCTL_MFC_VC1_DEC_EXE.\r\n")));
            MFC_Mutex_Release();
            return FALSE;
        }

        break;


    case IOCTL_MFC_GET_LINE_BUF_ADDR:

        if(FAILED(CeOpenCallerBuffer(&pMarshalledInBuf, pInBuf, nInBufSize, ARG_IO_PTR, TRUE)))
        {
            RETAILMSG(1, (TEXT("MFC_IOControl: CeOpenCallerBuffer failed in IOCTL_MFC_GET_LINE_BUF_ADDR.\r\n")));
            MFC_Mutex_Release();
            return FALSE;
        }

        args = (MFC_ARGS *)pMarshalledInBuf;

        ret = MFCInst_GetLineBuf(pMfcInst, &p_buf, &n_bufsize);

        // Output arguments for IOCTL_MFC_xxx_DEC_EXE
        args->get_buf_addr.ret_code = ret;

        if (ret != MFCINST_RET_OK) {
            break;
        }
        // Output arguments for IOCTL_MFC_GET_FRAM_BUF_ADDR
        args->get_buf_addr.out_buf_addr   = (int) p_buf;
        args->get_buf_addr.out_buf_size   = n_bufsize;

#if (_WIN32_WCE >= 600)
#ifdef E2E_MFC
{
    if (handle->pStrmBuf == NULL)
    {
        handle->hUsrProc = (HANDLE) GetDirectCallerProcessId();
        handle->pStrmBuf = (PBYTE) VirtualAllocEx(handle->hUsrProc, NULL,  MFC_LINE_BUF_SIZE_PER_INSTANCE, MEM_RESERVE, PAGE_NOACCESS);                  // HANDLE hDstProc
        phyAddr = S3C6410_BASEADDR_MFC_DATA_BUF+(pMfcInst->inst_no*MFC_LINE_BUF_SIZE_PER_INSTANCE);
        result = VirtualCopyEx(handle->hUsrProc,  // HANDLE hDstProc
                               handle->pStrmBuf,
                               (HANDLE) GetCurrentProcessId(),     // HANDLE hSrcProc
                               (PVOID)(phyAddr >> 8),
                                           MFC_LINE_BUF_SIZE_PER_INSTANCE,
                               PAGE_PHYSICAL | PAGE_READWRITE );
        if (result == FALSE){
            RETAILMSG(1, (L"DD::MFC VirtualCopyEx(pStrmBuf) returns FALSE.\n"));
            args->get_buf_addr.ret_code = MFCINST_ERR_ETC;
            break;
        }
//        handle->pStrmBuf += phyAddr & (UserKInfo[KINX_PAGESIZE] - 1);
    }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -