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

📄 mfc_instance.c

📁 Samsung公司S3C6400芯片的BSP源码包
💻 C
📖 第 1 页 / 共 3 页
字号:
			pPARAM_SEQ_INIT->ENC_SEQ_MP4_PARA	= DATA_PART_DISABLE;

			break;

		case H263_ENC:
			pPARAM_SEQ_INIT->ENC_SEQ_COD_STD	= H263_ENCODE;
			pPARAM_SEQ_INIT->ENC_SEQ_263_PARA	= ANNEX_T_ON | ANNEX_J_OFF | ANNEX_K_OFF | ANNEX_I_OFF;
			break;

		case AVC_ENC:
			pPARAM_SEQ_INIT->ENC_SEQ_COD_STD	= H264_ENCODE;
			pPARAM_SEQ_INIT->ENC_SEQ_264_PARA	= ~(0xFFFF);
			
			break;
		
		default:
			LOG_MSG(LOG_ERROR, "MFCInst_Enc_Init", "MFC encoder supports MPEG4, H.264 and H.263.\n");			
			return MFCINST_ERR_INVALID_PARAM;
	}


	// SEQ_INIT command
	MfcIssueCmd(ctx->inst_no, ctx->codec_mode, SEQ_INIT);

	if (pPARAM_SEQ_INIT->RET_ENC_SEQ_SUCCESS == TRUE)
	{
		LOG_MSG(LOG_TRACE, "MFCInst_Enc_Init", "ENC SEQ INIT success\n");			
	}
	else {
		LOG_MSG(LOG_ERROR, "MFCInst_Enc_Init", "ENC SEQ INIT Fail\n");			
		return MFCINST_ERR_ENC_INIT_CMD_FAIL;
	}

	// nFramBufSize is (YUV420 frame size) * (required frame buffer count)
	nFramBufSize = ((ctx->width * ctx->height * 3) >> 1) * (ctx->frambufCnt + 1);
	if ( Get_MfcFramBufAddr(ctx, nFramBufSize) == FALSE ) {
		LOG_MSG(LOG_ERROR, "MFCInst_Enc_Init", "Initialization of MFC Instance failed!\r\n");
		LOG_MSG(LOG_ERROR, "MFCInst_Enc_Init", "MFC Instance init failed! (required frame buffer size = %d)\r\n", nFramBufSize);
		return MFCINST_ERR_ETC;
	}
	ctx->framBufAllocated = 1;

	//////////////////////////////////////////////////////////////////////
	//                                                                  //
	// 5. Set the Parameters in the PARA_BUF for SET_FRAME_BUF command. //
	//                                                                  //
	//////////////////////////////////////////////////////////////////////
	// Buffer address of Y, Cb, Cr will be set in PARAM_BUF.
	pPARAM_BUF = (unsigned char *)GetParamBufVirAddr();
	frame_size = ctx->width * ctx->height;
	for (i=0; i < ctx->frambufCnt; i++)
	{
		*((int *) (pPARAM_BUF + i*3*4))      = ctx->phyadrFramBuf + (i + 1) * ((frame_size * 3) >> 1);
		*((int *) (pPARAM_BUF + i*3*4 + 4))  = ctx->phyadrFramBuf + (i + 1) * ((frame_size * 3) >> 1) + frame_size;
		*((int *) (pPARAM_BUF + i*3*4 + 8))  = ctx->phyadrFramBuf + (i + 1) * ((frame_size * 3) >> 1) + frame_size + (frame_size >> 2);
	}


	////////////////////////////////////////
	//                                    //
	// 6. Issue the SET_FRAME_BUF command //
	//                                    //
	////////////////////////////////////////
	// 'SET_FRAME_BUF_NUM' must be greater than or equal to RET_DEC_SEQ_FRAME_NEED_COUNT.
	pPARAM_SET_FRAME_BUF = (S3C6400_MFC_PARAM_REG_SET_FRAME_BUF *)  MfcGetCmdParamRegion();
	pPARAM_SET_FRAME_BUF->SET_FRAME_BUF_NUM    = ctx->frambufCnt;
	pPARAM_SET_FRAME_BUF->SET_FRAME_BUF_STRIDE = ctx->stride;
	MfcIssueCmd(ctx->inst_no, ctx->codec_mode, SET_FRAME_BUF);


	////////////////////////////
	///    STATE changing    ///
	////////////////////////////
	// state change to MFCINST_STATE_ENC_INITIALIZED
	MFCINST_STATE_TRANSITION(ctx, MFCINST_STATE_ENC_INITIALIZED);

	return MFCINST_RET_OK;
}


void MFCInst_Get_Frame_size(MFCInstCtx *ctx, int arg)
{
	MFC_DECODED_FRAME_INFO tmp;

	tmp.width	= ctx->width;
	tmp.height	= ctx->height;

	Copy_To_User( (MFC_DECODED_FRAME_INFO *)arg, &tmp, sizeof(MFC_DECODED_FRAME_INFO) );
}



//
// Function Name: MFCInst_Decode
// Description
//      This function decodes the input stream and put the decoded frame into the FRAM_BUF.
// Parameters
//      ctx[IN]: MFCInstCtx
//      strm_leng[IN]: stream size
//
int MFCInst_Decode(MFCInstCtx *ctx, unsigned long strm_leng)
{
	volatile S3C6400_MFC_PARAM_REG_DEC_PIC_RUN	*pPARAM_DEC_PIC_RUN;
	S3C6400_MFC_SFR						*mfc_sfr;


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



	mfc_sfr = (S3C6400_MFC_SFR *) GetMfcSfrVirAddr();
	mfc_sfr->BIT_STR_BUF_RW_ADDR[ctx->inst_no].BITS_RD_PTR = ctx->phyadrStrmBuf;
	mfc_sfr->BIT_STR_BUF_RW_ADDR[ctx->inst_no].BITS_WR_PTR = ctx->phyadrStrmBuf  +  strm_leng;



	//////////////////////////////////////////////////////////////////////
	//                                                                  //
	// 13. Set the Parameters in the PARAM_BUF for PIC_RUN command. 	//
	//                                                                  //
	//////////////////////////////////////////////////////////////////////
	pPARAM_DEC_PIC_RUN = (S3C6400_MFC_PARAM_REG_DEC_PIC_RUN *)  MfcGetCmdParamRegion();
	pPARAM_DEC_PIC_RUN->DEC_PIC_ROT_MODE = 0;

	pPARAM_DEC_PIC_RUN->DEC_PIC_BB_START    = ctx->phyadrStrmBuf & 0xFFFFFFFC;
	pPARAM_DEC_PIC_RUN->DEC_PIC_START_BYTE  = ctx->phyadrStrmBuf & 0x00000003;
	pPARAM_DEC_PIC_RUN->DEC_PIC_CHUNK_SIZE  = strm_leng;


	////////////////////////////////////////
	//                                    //
	// 14. Issue the PIC_RUN command	  //
	//                                    //
	////////////////////////////////////////
	if (!MfcIssueCmd(ctx->inst_no, ctx->codec_mode, PIC_RUN)) {
		return MFCINST_ERR_DEC_PIC_RUN_CMD_FAIL;
	}
	if (pPARAM_DEC_PIC_RUN->RET_DEC_PIC_IDX > 30) {

		LOG_MSG(LOG_ERROR, "Decode", "Decoding Fail, ret = %d\r\n", pPARAM_DEC_PIC_RUN->RET_DEC_PIC_IDX);

		return MFCINST_ERR_DEC_DECODE_FAIL;
	}


	ctx->idx = pPARAM_DEC_PIC_RUN->RET_DEC_PIC_IDX;

	////////////////////////////
	///    STATE changing    ///
	////////////////////////////
	// state change to MFCINST_STATE_DEC_PIC_RUN_LINE_BUF
	MFCINST_STATE_TRANSITION(ctx, MFCINST_STATE_DEC_PIC_RUN_LINE_BUF);

	return MFCINST_RET_OK;
}


//
// Function Name: MFCInst_Decode_Stream
// Description
//      This function decodes the input stream and put the decoded frame into the FRAM_BUF.
// Parameters
//      ctx[IN]: MFCInstCtx
//      strm_leng[IN]: stream size
//
int MFCInst_Decode_Stream(MFCInstCtx *ctx, unsigned long strm_leng)
{
	volatile S3C6400_MFC_PARAM_REG_DEC_PIC_RUN	*pPARAM_DEC_PIC_RUN;
	S3C6400_MFC_SFR						*mfc_sfr;
	int									garbage_size = 0;
	unsigned int 						offset = 0;

	int	count = 0;
	

	////////////////////////////
	///    STATE checking    ///
	////////////////////////////
	if (MFCINST_STATE_CHECK(ctx, MFCINST_STATE_DELETED)) {
		LOG_MSG(LOG_ERROR, "MFCInst_Decode", "MFC instance is deleted.\r\n");
		return MFCINST_ERR_STATE_DELETED;
	}
	if (MFCINST_STATE_CHECK(ctx, MFCINST_STATE_INVALIDATED)) {
		LOG_MSG(LOG_ERROR, "MFCInst_Decode", "MFC instance is invalidated.\r\n");
		return MFCINST_ERR_STATE_INVALIDATED;
	}
	if (MFCINST_STATE_CHECK(ctx, MFCINST_STATE_CREATED)) {
		LOG_MSG(LOG_ERROR, "MFCInst_Decode", "MFC instance is not initialized.\r\n");
		return MFCINST_ERR_STATE_CHK;
	}
	if (MFCINST_STATE_CHECK(ctx, MFCINST_STATE_DEC_PIC_END_RING_BUF)) {
		LOG_MSG(LOG_ERROR, "MFCInst_Decode_Stream", "Decode cannot executed after DEC_PIC_END state.\r\n");
		return MFCINST_ERR_STATE_CHK;
	}
/*
	if (MFCINST_STATE_CHECK(ctx, MFCINST_STATE_DEC_PIC_RUN_RING_BUF_LAST_UNITS)) {
		if (strm_leng) {
			LOG_MSG(LOG_ERROR, "MFCInst_Decode_Stream", "No more input stream data is allowed.\r\n");
			return MFCINST_ERR_STATE_CHK;
		}
	}
*/
	if (strm_leng && !MFCINST_STATE_BUF_FILL_REQ_CHECK(ctx)) {
		LOG_MSG(LOG_ERROR, "MFCInst_Decode_Stream", "Buffer should not be filled.\r\n");
		return MFCINST_ERR_STATE_CHK;
	}


	////////////////////////////
	///    STATE changing    ///
	////////////////////////////
	if (MFCINST_STATE_CHECK(ctx, MFCINST_STATE_DEC_INITIALIZED))
		MFCINST_STATE_TRANSITION(ctx, MFCINST_STATE_DEC_PIC_RUN_RING_BUF);

		
	if (strm_leng) {

		// If the input stream length is less than 'MFC_RING_BUF_PARTUNIT_SIZE',
		// this block of input stream is considered as the last unit.
		// MFC instance will not accept any more input stream data,
		// when the state is changed to MFCINST_STATE_DEC_PIC_RUN_RING_BUF_LAST_UNITS.
		// The state is now changing to MFCINST_STATE_DEC_PIC_RUN_RING_BUF_LAST_UNITS.
		if (strm_leng < MFC_RING_BUF_PARTUNIT_SIZE) {
			if (strm_leng & 0x1FF) {
				garbage_size = strm_leng;
				strm_leng = (strm_leng + 512) & 0xFFFFFE00;
				garbage_size = strm_leng - garbage_size;
			}
			MFCINST_STATE_TRANSITION(ctx, MFCINST_STATE_DEC_PIC_RUN_RING_BUF_LAST_UNITS);
			MfcSetEos();
		}
		else if (strm_leng == MFC_RING_BUF_PARTUNIT_SIZE) {
			// state change to MFCINST_STATE_DEC_PIC_RUN_RING_BUF
			MFCINST_STATE_TRANSITION(ctx, MFCINST_STATE_DEC_PIC_RUN_RING_BUF);
		}
		else {	// strm_leng > MFC_RING_BUF_PARTUNIT_SIZE   => ERROR !!
			LOG_MSG(LOG_ERROR, "MFCInst_Decode_Stream", "Size of buffer fill is more than requested.\r\n");
			return MFCINST_ERR_DEC_BUF_FILL_SIZE_WRONG;
		}

		MFCINST_STATE_BUF_FILL_REQ_CLEAR(ctx);
	}


	// Moving the BITS_WR_PTR value by the amount of strm_leng
	mfc_sfr = (S3C6400_MFC_SFR *) GetMfcSfrVirAddr();
	mfc_sfr->BIT_STR_BUF_RW_ADDR[ctx->inst_no].BITS_WR_PTR += strm_leng;
	if (strm_leng > 0 &&
		((mfc_sfr->BIT_STR_BUF_RW_ADDR[ctx->inst_no].BITS_WR_PTR - ctx->phyadrStrmBuf)
			>=  MFC_RING_BUF_SIZE)) {

		mfc_sfr->BIT_STR_BUF_RW_ADDR[ctx->inst_no].BITS_WR_PTR -= MFC_RING_BUF_SIZE;	
	}

	if ( (strm_leng > 0) && (strm_leng < MFC_RING_BUF_PARTUNIT_SIZE) ) {
		mfc_sfr = (S3C6400_MFC_SFR *) GetMfcSfrVirAddr();
		offset = mfc_sfr->BIT_STR_BUF_RW_ADDR[ctx->inst_no].BITS_WR_PTR - GetDataBufPhyAddr();
		Mem_Set((char *)(GetDataBufVirAddr() + offset - garbage_size), 0, garbage_size);
	}
	
	//////////////////////////////////////////////////////////////////////
	//                                                                  //
	// 13. Set the Parameters in the PARAM_BUF for PIC_RUN command. 	//
	//                                                                  //
	//////////////////////////////////////////////////////////////////////
	pPARAM_DEC_PIC_RUN = (S3C6400_MFC_PARAM_REG_DEC_PIC_RUN *)  MfcGetCmdParamRegion();
	pPARAM_DEC_PIC_RUN->DEC_PIC_ROT_MODE = 0;

	////////////////////////////////////////
	//                                    //
	// 14. Issue the PIC_RUN command	  //
	//                                    //
	////////////////////////////////////////
	if (!MfcIssueCmd(ctx->inst_no, ctx->codec_mode, PIC_RUN)) {
		LOG_MSG(LOG_TRACE, "Decode_Stream", "Frame num : %d, pPARAM_DEC_PIC_RUN->RET_DEC_PIC_IDX : %d\n", pPARAM_DEC_PIC_RUN->RET_DEC_PIC_FRAME_NUM, pPARAM_DEC_PIC_RUN->RET_DEC_PIC_IDX);
		return MFCINST_ERR_DEC_PIC_RUN_CMD_FAIL;	// BUFFER empty or full interrupt is raised.
	}



	if (pPARAM_DEC_PIC_RUN->RET_DEC_PIC_IDX > 30) {
		if (MFCINST_STATE_CHECK(ctx, MFCINST_STATE_DEC_PIC_RUN_RING_BUF_LAST_UNITS)
			&& (pPARAM_DEC_PIC_RUN->RET_DEC_PIC_IDX == -1)) {

			LOG_MSG(LOG_WARNING, "Decode", "End of Stream.\r\n");
			return MFCINST_ERR_DEC_EOS;
		}

		LOG_MSG(LOG_ERROR, "Decode", "Decoding Fail, ret = %d\r\n", pPARAM_DEC_PIC_RUN->RET_DEC_PIC_IDX);
		return MFCINST_ERR_DEC_DECODE_FAIL;
	}

	ctx->frame_num = pPARAM_DEC_PIC_RUN->RET_DEC_PIC_FRAME_NUM;
	ctx->idx       = pPARAM_DEC_PIC_RUN->RET_DEC_PIC_IDX;


	return MFCINST_RET_OK;
}


int MFCInst_Encode(MFCInstCtx *ctx, int *enc_data_size)	// arg : stream size
{
	volatile S3C6400_MFC_PARAM_REG_ENC_PIC_RUN	*pPARAM_ENC_PIC_RUN;
	S3C6400_MFC_SFR						*mfc_sfr;


	if (!MFCINST_STATE_CHECK(ctx, MFCINST_STATE_ENC_INITIALIZED)) {

		LOG_MSG(LOG_ERROR, "MFCInst_Encode", "ENC SEQ INIT is NOT complete\r\n");
		return MFCINST_ERR_STATE_CHK;
	}

	/*
	 * Set the address of each component of YUV420
	 */
	pPARAM_ENC_PIC_RUN = (S3C6400_MFC_PARAM_REG_ENC_PIC_RUN *) MfcGetCmdParamRegion();
	pPARAM_ENC_PIC_RUN->ENC_PIC_SRC_ADDR_Y	= ctx->phyadrFramBuf;
	pPARAM_ENC_PIC_RUN->ENC_PIC_SRC_ADDR_CB	= ctx->phyadrFramBuf + ctx->stride * ctx->height;
	pPARAM_ENC_PIC_RUN->ENC_PIC_SRC_ADDR_CR	= ctx->phyadrFramBuf + ((ctx->stride * ctx->height * 5) >> 2);
	pPARAM_ENC_PIC_RUN->ENC_PIC_ROT_MODE	= 0;
	pPARAM_ENC_PIC_RUN->ENC_PIC_OPTION		= 0;


	if (!MfcIssueCmd(ctx->inst_no, ctx->codec_mode, PIC_RUN)) {
		return MFCINST_ERR_ENC_PIC_RUN_CMD_FAIL;
	}

	mfc_sfr = (S3C6400_MFC_SFR *) GetMfcSfrVirAddr();

	ctx->idx = 0;

	*enc_data_size = mfc_sfr->BIT_STR_BUF_RW_ADDR[ctx->inst_no].BITS_WR_PTR - ctx->phyadrStrmBuf;	// calculte encoded data size

	return MFCINST_RET_OK;
}

⌨️ 快捷键说明

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