mfcdriver.cpp
来自「SAMSUNG S3C6410 CPU BSP for winmobile6」· C++ 代码 · 共 847 行 · 第 1/2 页
CPP
847 行
LOG_MSG(LOG_TRACE, "MFC_IOControl", "OpenHandle == NULL\n");
return FALSE;
}
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;
}
handle = (MFC_HANDLE *) OpenHandle;
pMfcInst = handle->mfc_inst;
/*
///////////////////
// MFC_CTX check //
///////////////////
if (MfcCtxIsValid(pMfcInst) == FALSE)
return FALSE;
*/
// IOCTL argument
args = (MFC_ARGS *) pInBuf;
MFC_Mutex_Lock();
switch ( dwIoControlCode ) {
case IOCTL_MFC_MPEG4_ENC_INIT:
case IOCTL_MFC_H264_ENC_INIT:
case IOCTL_MFC_H263_ENC_INIT:
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;
// 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;;
///////////////////////////////////
/// 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;
break;
case IOCTL_MFC_MPEG4_ENC_EXE:
case IOCTL_MFC_H264_ENC_EXE:
case IOCTL_MFC_H263_ENC_EXE:
// nStrmLen is size of output stream data
Mfc_Clk_On();
ret = MFCInst_Encode(pMfcInst, &nStrmLen, &nHdrLen);
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;
args->enc_exe.out_header_size = nHdrLen;
}
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;
}
/////////////////////////////
// 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
}
if (pMfcInst->idx >= 0) {
args->get_buf_addr.out_buf_addr = (int) (handle->pFramBuf + (pMfcInst->idx * n_bufsize));
#if (MFC_ROTATE_ENABLE == 1)
// If PostRotMode is enabled, then the output YUV buffer will be different.
// In VC-1 mode, the rotated output will be the original one.
if ( (pMfcInst->codec_mode != VC1_DEC) && (pMfcInst->PostRotMode & 0x0010) )
args->get_buf_addr.out_buf_addr = (int) (handle->pFramBuf + (pMfcInst->frambufCnt * n_bufsize));
#endif
}
else
args->get_buf_addr.out_buf_addr = 0;
#endif
break;
case IOCTL_MFC_GET_PHY_FRAM_BUF_ADDR:
// Decoder case
ret = MFCInst_GetFramBufPhysical(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;
break;
case IOCTL_MFC_GET_CONFIG:
ret = MFC_GetConfigParams(pMfcInst, args);
break;
case IOCTL_MFC_SET_CONFIG:
ret = MFC_SetConfigParams(pMfcInst, args);
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)
{
return TRUE;
}
BOOL MFC_PowerDown(DWORD InitHandle)
{
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();
RETAILMSG(0, (L"(( MFC Interrupt ) reason = 0x%X\n", intr_reason));
// if (intr_reason & 0xC02E) {
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, 100);
RETAILMSG(1, (L"MFC Interrupt has been initialized.\n"));
return TRUE;
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?