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

📄 mfc_instance.c

📁 Samsung公司S3C6400芯片的BSP源码包
💻 C
📖 第 1 页 / 共 3 页
字号:
/*
 * Project Name MFC DRIVER 
 * Copyright  2007 Samsung Electronics Co, Ltd. All Rights Reserved. 
 *
 * This software is the confidential and proprietary information
 * of Samsung Electronics  ("Confidential Information").   
 * you shall not disclose such Confidential Information and shall use
 * it only in accordance with the terms of the license agreement
 * you entered into with Samsung Electronics 
 *
 * This source file is for initializing the MFC instance.
 *
 * @name MFC DRIVER MODULE Module (MFC_Inst_Init.c)
 * @author name(email address)
 * @date 03-28-07
 */

#include "Mfc.h"
#include "MFC_Instance.h"
#include "MfcMemory.h"
#include "DataBuf.h"
#include "FramBufMgr.h"
#include "LogMsg.h"
#include "MfcConfig.h"
#include "MfcSfr.h"
#include "BitProcBuf.h"
#include "MFC_Inst_Pool.h"



static MFCInstCtx _mfcinst_ctx[MFC_NUM_INSTANCES_MAX];

MFCInstCtx *MFCInst_GetCtx(int inst_no)
{
	if ((inst_no < 0) || (inst_no >= MFC_NUM_INSTANCES_MAX))
		return NULL;

	if (MFCINST_STATE(&(_mfcinst_ctx[inst_no])) >= MFCINST_STATE_CREATED)
		return &(_mfcinst_ctx[inst_no]);
	else
		return NULL;
}



// Filling the pStrmBuf and phyadrStrmBuf variables of the MfcInstCtx structure
// (pStrmBuf and phyadrStrmBuf are the virtual and physical address of STRM_BUF(stream buffer) respectively.)
static void Get_MfcStrmBufAddr(MFCInstCtx *ctx, int isLineBuf)
{
	// LINE BUF
	if (isLineBuf) {
		ctx->pStrmBuf		= (unsigned char *) ( GetDataBufVirAddr() + (ctx->inst_no * MFC_LINE_BUF_SIZE_PER_INSTANCE) );
		ctx->phyadrStrmBuf	= (PHYADDR_VAL) ( GetDataBufPhyAddr() + (ctx->inst_no * MFC_LINE_BUF_SIZE_PER_INSTANCE) );
		ctx->nStrmBufSize   = MFC_LINE_BUF_SIZE_PER_INSTANCE;
	}
	// RING BUF
	else {
#if (MFC_LINE_RING_SHARE == 1)
		ctx->pStrmBuf		= (unsigned char *) GetDataBufVirAddr();
		ctx->phyadrStrmBuf	= (PHYADDR_VAL) GetDataBufPhyAddr();
#elif (MFC_LINE_RING_SHARE == 0)
		ctx->pStrmBuf		= (unsigned char *) ( GetDataBufVirAddr() + MFC_LINE_BUF_SIZE);
		ctx->phyadrStrmBuf	= (PHYADDR_VAL) ( GetDataBufPhyAddr() + MFC_LINE_BUF_SIZE);
#endif
		ctx->nStrmBufSize   = MFC_RING_BUF_SIZE;
	}

	LOG_MSG(LOG_TRACE, "Get_MfcStrmBufAddr", "ctx->pStrmBuf address 0x%08X\n", ctx->pStrmBuf);
	LOG_MSG(LOG_TRACE, "Get_MfcStrmBufAddr", "ctx->phyadrStrmBuf address 0x%08X\n", ctx->phyadrStrmBuf);
}

// Filling the pFramBuf and phyadrFramBuf variables of the MfcInstCtx structure
// (pFramBuf and phyadrFramBuf are the virtual and physical address of FRAM_BUF(frame buffer) respectively.)
static BOOL Get_MfcFramBufAddr(MFCInstCtx *ctx, int buf_size)
{
	unsigned char	*pInstFramBuf;

	pInstFramBuf	= FramBufMgrCommit(ctx->inst_no, buf_size);
	if (pInstFramBuf == NULL) {
		LOG_MSG(LOG_ERROR, "Get_MfcFramBufAddr", "Frame buffer allocation was failed!\r\n");
		return FALSE;
	}

	FramBufMgrPrintCommitInfo();

	ctx->pFramBuf		= pInstFramBuf;	// virtual address of frame buffer	
	ctx->phyadrFramBuf	= S3C6400_BASEADDR_MFC_DATA_BUF + ( (int)pInstFramBuf - (int)GetDataBufVirAddr() );
	ctx->nFramBufSize   = buf_size;

	LOG_MSG(LOG_TRACE, "Get_MfcFramBufAddr", "ctx->inst_no : %d\r\n", ctx->inst_no);
	LOG_MSG(LOG_TRACE, "Get_MfcFramBufAddr", "ctx->pFramBuf : 0x%X\r\n", ctx->pFramBuf);
	LOG_MSG(LOG_TRACE, "Get_MfcFramBufAddr", "ctx->phyadrFramBuf : 0x%X\r\n", ctx->phyadrFramBuf);

	return TRUE;
}


void MFCInst_RingBufAddrCorrection(MFCInstCtx *ctx)
{
	Get_MfcStrmBufAddr(ctx, 0);
}



int MFCInst_GetLineBuf(MFCInstCtx *ctx, unsigned char **ppBuf, int *size)
{
	////////////////////////////
	///    STATE checking    ///
	////////////////////////////
	if (MFCINST_STATE_CHECK(ctx, MFCINST_STATE_DELETED)) {
		LOG_MSG(LOG_ERROR, "MFCInst_GetRingBuf", "MFC instance is deleted.\r\n");
		return MFCINST_ERR_STATE_DELETED;
	}
	if (MFCINST_STATE_CHECK(ctx, MFCINST_STATE_INVALIDATED)) {
		LOG_MSG(LOG_ERROR, "MFCInst_GetRingBuf", "MFC instance is invalidated.\r\n");
		return MFCINST_ERR_STATE_INVALIDATED;
	}


	if (ctx->inbuf_type == DEC_INBUF_NOT_SPECIFIED)
		ctx->inbuf_type = DEC_INBUF_LINE_BUF;
	else if (ctx->inbuf_type == DEC_INBUF_RING_BUF)
		return MFCINST_ERR_ETC;

	*ppBuf = ctx->pStrmBuf;
	*size  = MFC_LINE_BUF_SIZE_PER_INSTANCE;

	return MFCINST_RET_OK;
}

int MFCInst_GetRingBuf(MFCInstCtx *ctx, unsigned char **ppBuf, int *size)
{
	unsigned char  *pRD_PTR, *pWR_PTR;
	int             num_bytes_strm_buf;	// Number of bytes in STRM_BUF (used in IOCTL_MFC_GET_RING_BUF_ADDR)

	MFCInstCtx     *pMfcInstTmp;
	int             inst_no = 0;


	////////////////////////////
	///    STATE checking    ///
	////////////////////////////
	if (MFCINST_STATE_CHECK(ctx, MFCINST_STATE_DELETED)) {
		LOG_MSG(LOG_ERROR, "MFCInst_GetRingBuf", "MFC instance is deleted.\r\n");
		return MFCINST_ERR_STATE_DELETED;
	}
	if (MFCINST_STATE_CHECK(ctx, MFCINST_STATE_INVALIDATED)) {
		LOG_MSG(LOG_ERROR, "MFCInst_GetRingBuf", "MFC instance is invalidated.\r\n");
		return MFCINST_ERR_STATE_INVALIDATED;
	}


	if (ctx->inbuf_type == DEC_INBUF_NOT_SPECIFIED)
		ctx->inbuf_type = DEC_INBUF_RING_BUF;
	else if (ctx->inbuf_type == DEC_INBUF_LINE_BUF)
		return MFCINST_ERR_ETC;


	// state variable checking
	if (MFCINST_STATE_CHECK(ctx, MFCINST_STATE_CREATED)) {

#if (MFC_LINE_RING_SHARE == 1)
		// If LINE_BUF and RING_BUF are shared,
		// there must be no instances other than itself.
		if (MfcInstPool_NumAvail() != (MFC_NUM_INSTANCES_MAX-1))
			return MFCINST_ERR_ETC;

		// Occupy all the instances
		// so that the other instances won't be activated
		// until this VC-1 decode instance will be closed.
		MfcInstPool_OccupyAll();

#elif (MFC_LINE_RING_SHARE == 0)
		// If LINE_BUF and RING_BUF are separated.
		// there must be no other instances using the RING_BUF other than itself.
		if (MfcInstPool_NumAvail() < (MFC_NUM_INSTANCES_MAX-1)) {
			for (inst_no=0; inst_no<MFC_NUM_INSTANCES_MAX; inst_no++) {
				if (inst_no == ctx->inst_no)
					continue;

				pMfcInstTmp = MFCInst_GetCtx(inst_no);
				if (pMfcInstTmp == NULL)
					continue;
				if (pMfcInstTmp->inbuf_type == DEC_INBUF_RING_BUF) {
					return MFCINST_ERR_ETC;
				}
			}
		}

		// If LINE_BUF & RING_BUF are not shared,
		// the RING_BUF address must be different from the LINE_BUF.
		// For this reason, the address needs correction at first.
		MFCInst_RingBufAddrCorrection(ctx);
#endif
	}

	// Get the current positions of RD_PTR and WR_PTR
	MFCInst_GetStreamRWPtrs(ctx, &pRD_PTR, &pWR_PTR);

	// When MFC instance is in the state of MFCINST_STATE_CREATED,
	// the size of data to be filled in RING_BUF is double the PARTUNIT size.
	if (MFCINST_STATE_CHECK(ctx, MFCINST_STATE_CREATED)) {
		*ppBuf = pWR_PTR;
		*size  = MFC_RING_BUF_PARTUNIT_SIZE << 1;

		MFCINST_STATE_BUF_FILL_REQ_SET(ctx);

		return MFCINST_RET_OK;
	}


	*ppBuf = pWR_PTR;
	num_bytes_strm_buf = (int)pWR_PTR - (int)pRD_PTR;
	if (num_bytes_strm_buf <= 0)	// if WR_PTR is behind the RD_PTR.
		num_bytes_strm_buf  += MFC_RING_BUF_SIZE;

	// Num of bytes in RING_BUF is less than MFC_RING_BUF_PARTUNIT_SIZE,
	// then load one more MFC_RING_BUF_PARTUNIT_SIZE unit.
	if ((num_bytes_strm_buf < MFC_RING_BUF_PARTUNIT_SIZE)
			&& MFCINST_STATE_CHECK(ctx, MFCINST_STATE_DEC_PIC_RUN_RING_BUF)) {
		*size = MFC_RING_BUF_PARTUNIT_SIZE;
		MFCINST_STATE_BUF_FILL_REQ_SET(ctx);
	}
	else
		*size = 0;

	
	return MFCINST_RET_OK;
}

int MFCInst_GetFramBuf(MFCInstCtx *ctx, unsigned char **ppBuf, int *size)
{
	////////////////////////////
	///    STATE checking    ///
	////////////////////////////
	if (MFCINST_STATE_CHECK(ctx, MFCINST_STATE_DELETED)) {
		LOG_MSG(LOG_ERROR, "MFCInst_GetFramBuf", "MFC instance is deleted.\r\n");
		return MFCINST_ERR_STATE_DELETED;
	}
	if (MFCINST_STATE_CHECK(ctx, MFCINST_STATE_INVALIDATED)) {
		LOG_MSG(LOG_ERROR, "MFCInst_GetFramBuf", "MFC instance is invalidated.\r\n");
		return MFCINST_ERR_STATE_INVALIDATED;
	}
	if (MFCINST_STATE_CHECK(ctx, MFCINST_STATE_CREATED)) {
		LOG_MSG(LOG_ERROR, "MFCInst_GetFramBuf", "MFC instance is not initialized.\r\n");
		return MFCINST_ERR_STATE_CHK;
	}

	if (ctx->pFramBuf == NULL) {
		LOG_MSG(LOG_ERROR, "MFCInst_GetFramBuf", "MFC Frame buffer is not internally allocated yet.\n");
		return MFCINST_ERR_ETC;
	}


	*size  = (ctx->width * ctx->height * 3) >> 1;	// YUV420 frame size
	*ppBuf = ctx->pFramBuf + (ctx->idx) * (*size);

	return MFCINST_RET_OK;
}


//
// Function Name: MFCInst_GetInstNo
// Description
//      It returns the instance number of the 6400 MFC instance context.
// Parameters
//      ctx[IN]: MFCInstCtx
//
int MFCInst_GetInstNo(MFCInstCtx *ctx)
{
	return ctx->inst_no;
}

//
// Function Name: MFCInst_GetStreamRWPtrs
// Description
//      It returns the virtual address of RD_PTR and WR_PTR.
// Parameters
//      ctx[IN]: MFCInstCtx
//      ppRD_PTR[OUT]: RD_PTR
//      ppWR_PTR[OUT]: WR_PTR
//
BOOL MFCInst_GetStreamRWPtrs(MFCInstCtx *ctx, unsigned char **ppRD_PTR, unsigned char **ppWR_PTR)
{
	S3C6400_MFC_SFR	*mfc_sfr;		// MFC SFR pointer
	int              diff_vir_phy;


	if (MFCINST_STATE(ctx) < MFCINST_STATE_CREATED)
		return FALSE;

	if (MFCINST_STATE_CHECK(ctx, MFCINST_STATE_CREATED)) {
		// If MFCInstCtx is just created and not initialized by MFCInst_Init,
		// then the initial RD_PTR and WR_PTR are the start address of STRM_BUF.
		*ppRD_PTR = ctx->pStrmBuf;
		*ppWR_PTR = ctx->pStrmBuf;
	}
	else {
		// The physical to virtual address conversion of RD_PTR and WR_PTR.
		diff_vir_phy  =  (int) (ctx->pStrmBuf - ctx->phyadrStrmBuf);
		mfc_sfr = (S3C6400_MFC_SFR *) GetMfcSfrVirAddr();
		*ppRD_PTR = (unsigned char *) (diff_vir_phy + mfc_sfr->BIT_STR_BUF_RW_ADDR[ctx->inst_no].BITS_RD_PTR);
		*ppWR_PTR = (unsigned char *) (diff_vir_phy + mfc_sfr->BIT_STR_BUF_RW_ADDR[ctx->inst_no].BITS_WR_PTR);
	}

	return TRUE;
}

BOOL MFCInst_SetInbufType(MFCInstCtx *ctx, MFCINST_DEC_INBUF_TYPE inbuf_type)
{
	ctx->inbuf_type = inbuf_type;

	return TRUE;
}


MFCInstCtx *MFCInst_Create(void)
{
	MFCInstCtx *ctx;
	int		inst_no;

	// Occupy the 'inst_no'.
	// If it fails, it returns NULL.
	inst_no = MfcInstPool_Occupy();
	if (inst_no == -1)
		return NULL;


	ctx = &(_mfcinst_ctx[inst_no]);

	Mem_Set(ctx, 0, sizeof(MFCInstCtx));

	ctx->inst_no     = inst_no;
	ctx->inbuf_type  = DEC_INBUF_NOT_SPECIFIED;
	MFCINST_STATE_TRANSITION(ctx, MFCINST_STATE_CREATED);

	// At first, since it is not known whether it is LINE_BUF or RING_BUF,
	// it assumes to be LINE_BUF.
	// Later, if it turns out to be RING_BUF, correction will be made.
	Get_MfcStrmBufAddr(ctx, 1);

	LOG_MSG(LOG_TRACE, "s3c_mfc_open", "state : %d\n", ctx->state_var);

	
	return ctx;
}


//
// Function Name: MFCInst_Delete
// Description

⌨️ 快捷键说明

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