📄 mfcdriver.cpp
字号:
ret = MFCInst_Encode(pMfcInst, &nStrmLen);
Mfc_Clk_Off();
// 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;
}
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:
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;
/*
if (pMfcInst->inbuf_type == DEC_INBUF_LINE_BUF) {
// VC1_DEC doesn't support the 'LINE_BUF' as input buffer type.
RETAILMSG(1, (L"[MFC ERROR] VC-1 Decoding supports the RING_BUF mode only.\n"));
MFC_Mutex_Release();
return FALSE;
}
*/
}
/////////////////////////////
// MFCInst::Initialize //
/////////////////////////////
Mfc_Clk_On();
ret = MFCInst_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;
}
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 (pMfcInst->inbuf_type == DEC_INBUF_LINE_BUF) {
Mfc_Clk_On();
ret = MFCInst_Decode(pMfcInst, args->dec_exe.in_strmSize);
Mfc_Clk_Off();
}
else if (pMfcInst->inbuf_type == DEC_INBUF_RING_BUF) {
Mfc_Clk_On();
ret = MFCInst_Decode_Stream(pMfcInst, args->dec_exe.in_strmSize);
Mfc_Clk_Off();
}
else {
RETAILMSG(1, (L"[MFC ERROR] Buffer type is not defined.\n"));
MFC_Mutex_Release();
args->dec_exe.ret_code = -1;
return FALSE;
}
// Output arguments for IOCTL_MFC_xxx_DEC_EXE
args->dec_exe.ret_code = ret;
break;
case IOCTL_MFC_GET_RING_BUF_ADDR:
ret = MFCInst_GetRingBuf(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;
}
#if (_WIN32_WCE >= 600)
// If the virtual address of the RING_BUF in user process's view is NULL,
// call the VirtualAllocCopyEx.
if (handle->pStrmBuf == NULL) {
if (!args->get_buf_addr.in_usr_data) {
RETAILMSG(1, (L"[MFC ERROR] HANDLE for user process is not valid. (0x%X)", (DWORD) args->get_buf_addr.in_usr_data));
MFC_Mutex_Release();
return FALSE;
}
handle->hUsrProc = (HANDLE) args->get_buf_addr.in_usr_data;
handle->pStrmBuf
= (PBYTE) VirtualAllocCopyEx((HANDLE) GetCurrentProcessId(), // HANDLE hSrcProc
handle->hUsrProc, // HANDLE hDstProc
p_buf, // LPVOID pAddr
MFC_RING_BUF_SIZE, // DWORD cbSize
PAGE_READWRITE); // DWORD dwProtect
p_buf = handle->pStrmBuf;
}
else {
p_buf = handle->pStrmBuf + ((int)p_buf - (int)pMfcInst->pStrmBuf);
}
#endif
// Output arguments for IOCTL_MFC_GET_RING_BUF_ADDR
args->get_buf_addr.out_buf_addr = (int) p_buf;
args->get_buf_addr.out_buf_size = n_bufsize;
break;
case IOCTL_MFC_GET_LINE_BUF_ADDR:
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;
}
#if (_WIN32_WCE >= 600)
if (handle->pStrmBuf == NULL) {
if (!args->get_buf_addr.in_usr_data) {
MFC_Mutex_Release();
RETAILMSG(1, (L"[MFC ERROR] HANDLE for user process is not valid. (0x%X)", (DWORD) args->get_buf_addr.in_usr_data));
return FALSE;
}
handle->hUsrProc = (HANDLE) args->get_buf_addr.in_usr_data;
handle->pStrmBuf
= (PBYTE) VirtualAllocCopyEx((HANDLE) GetCurrentProcessId(), // HANDLE hSrcProc
handle->hUsrProc, // HANDLE hDstProc
p_buf, // LPVOID pAddr
n_bufsize, // DWORD cbSize
PAGE_READWRITE); // DWORD dwProtect
}
p_buf = handle->pStrmBuf;
#endif
// Output arguments for IOCTL_MFC_GET_LINE_BUF_ADDR
args->get_buf_addr.out_buf_addr = (int) p_buf;
args->get_buf_addr.out_buf_size = n_bufsize;
break;
case IOCTL_MFC_GET_FRAM_BUF_ADDR:
// Decoder case
ret = MFCInst_GetFramBuf(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)
if (handle->pFramBuf == NULL) {
if (!args->get_buf_addr.in_usr_data) {
MFC_Mutex_Release();
RETAILMSG(1, (L"[MFC ERROR] HANDLE for user process is not valid. (0x%X)", (DWORD) args->get_buf_addr.in_usr_data));
return FALSE;
}
handle->hUsrProc = (HANDLE) args->get_buf_addr.in_usr_data;
handle->pFramBuf
= (PBYTE) VirtualAllocCopyEx((HANDLE) GetCurrentProcessId(), // HANDLE hSrcProc
handle->hUsrProc, // HANDLE hDstProc
pMfcInst->pFramBuf, // LPVOID pAddr
pMfcInst->nFramBufSize, // DWORD cbSize
PAGE_READWRITE); // DWORD dwProtect
}
args->get_buf_addr.out_buf_addr = (int) (handle->pFramBuf + (pMfcInst->idx * n_bufsize));
#endif
break;
default:
RETAILMSG(1, (L"[MFC IOControl] Requested ioctl command is not defined. (ioctl cmd=0x%X", dwIoControlCode));
MFC_Mutex_Release();
return FALSE;
}
MFC_Mutex_Release();
switch (ret) {
case MFCINST_RET_OK:
return TRUE;
default:
return FALSE;
}
return FALSE;
}
BOOL MFC_PowerUp(DWORD InitHandle)
{
RETAILMSG(1, (L"[MFC_PowerUp] Power Up is invoked.\n"));
// Do nothing
return TRUE;
}
BOOL MFC_PowerDown(DWORD InitHandle)
{
MFCInstCtx *mfcinst_ctx;
int inst_no;
RETAILMSG(1, (L"[MFC_PowerDown] Power Down is invoked. handle = 0x%X\n", InitHandle));
MFC_Mutex_Lock();
// Invalidate all the MFC Instances
for (inst_no = 0; inst_no < MFC_NUM_INSTANCES_MAX; inst_no++) {
mfcinst_ctx = MFCInst_GetCtx(inst_no);
if (mfcinst_ctx) {
MFCInst_Invalidate(mfcinst_ctx);
RETAILMSG(1, (L"[MFC_PowerDown] %d-th instance is invalidated.\n", inst_no));
}
}
// Clock & Power off the MFC block
Mfc_Clk_On();
Mfc_Pwr_Off();
MFC_Mutex_Release();
return TRUE;
}
static HANDLE gMfcIntrEvent;
static HANDLE gMfcIntrThread;
UINT32 g_MfcIrq = IRQ_MFC;
UINT32 g_MfcSysIntr = SYSINTR_UNDEFINED;
extern "C"
static DWORD MFC_IntrThread(void)
{
unsigned int intr_reason;
while (1)
{
// Wait for MFC Interrupt
WaitForSingleObject(gMfcIntrEvent, INFINITE);
// Only SEQ_INIT, SEQ_END, PIC_RUN and BUFFER EMPTY/FULL interrupts
// will be processed.
intr_reason = MfcIntrReason();
if (intr_reason & 0xC00E) {
// On the MFC Interrupt,
// MFC command completion event will be sent.
// This event wakes up the task in WaitInterruptNotification() function.
SendInterruptNotification(intr_reason);
}
// Clearing MFC interrupt bit
MfcClearIntr();
// Notify to Kernel that MFC Interrupt processing is completed.
InterruptDone(g_MfcSysIntr);
}
}
static BOOL InitializeIST()
{
BOOL r;
gMfcIntrEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
if (!gMfcIntrEvent) {
ERRORMSG(1, (L"Unable to create interrupt event"));
return(FALSE);
}
if (!CreateInterruptNotification()) {
ERRORMSG(1, (L"Unable to create interrupt event"));
return(FALSE);
}
r = KernelIoControl(IOCTL_HAL_REQUEST_SYSINTR,
&g_MfcIrq, sizeof(UINT32),
&g_MfcSysIntr, sizeof(UINT32),
NULL);
if (r != TRUE) {
ERRORMSG(1, (L"ERROR: PwrButton: Failed to request sysintr value for sw_reset button interrupt.\r\n"));
return(0);
}
r = InterruptInitialize(g_MfcSysIntr, gMfcIntrEvent, NULL, 0);
if (r != TRUE) {
ERRORMSG(1, (L"Unable to initialize output interrupt"));
return FALSE;
}
gMfcIntrThread = CreateThread((LPSECURITY_ATTRIBUTES)NULL,
0,
(LPTHREAD_START_ROUTINE)MFC_IntrThread,
0,
0,
NULL);
if (!gMfcIntrThread) {
ERRORMSG(1, (L"Unable to create interrupt thread"));
return FALSE;
}
// Bump up the priority since the interrupt must be serviced immediately.
// CeSetThreadPriority(gMfcIntrThread, GetInterruptThreadPriority());
RETAILMSG(1, (L"MFC Interrupt has been initialized.\n"));
return TRUE;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -