📄 mfcdriver.cpp
字号:
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 + -