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

📄 mfcdriver.cpp

📁 Samsung公司S3C6400芯片的BSP源码包
💻 CPP
📖 第 1 页 / 共 2 页
字号:
		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 + -