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

📄 mfc_instance.c

📁 s3c6400 video code,you play video smooth with it,it is hardware codec
💻 C
📖 第 1 页 / 共 4 页
字号:
	ctx->frambufCnt		= 2;


	// This part is not required since the width and the height are checked to be multiples of 16
	// in the beginning of this function.
	if ((ctx->width & 0x0F) == 0)	// 16 aligned (ctx->width%16 == 0)
		ctx->buf_width = ctx->width;
	else
		ctx->buf_width = (ctx->width & 0xFFFFFFF0) + 16;



	// codec_mode
	ctx->codec_mode = codec_mode;
	
	LOG_MSG(LOG_TRACE, "MFCInst_Enc_Init", "  ctx->inst_no = %d\n", ctx->inst_no);
	LOG_MSG(LOG_TRACE, "MFCInst_Enc_Init", "  ctx->codec_mode = %d\n", ctx->codec_mode);


	/*
	 * set stream buffer read/write pointer
	 * At first, stream buffer is empty. so write pointer points start of buffer and read pointer points end of buffer
	 */
	mfc_sfr = (S3C6400_MFC_SFR *) GetMfcSfrVirAddr();
	mfc_sfr->BIT_STR_BUF_RW_ADDR[ctx->inst_no].BITS_WR_PTR = ctx->phyadrStrmBuf;
	mfc_sfr->BIT_STR_BUF_RW_ADDR[ctx->inst_no].BITS_RD_PTR = ctx->phyadrStrmBuf  +  MFC_LINE_BUF_SIZE_PER_INSTANCE;
	mfc_sfr->STRM_BUF_CTRL = 0x1C;	// bit stream buffer is reset at every picture encoding / decoding command

	LOG_MSG(LOG_TRACE, "MFCInst_Enc_Init", "  ctx->phyadrStrmBuf = 0x%X\n", ctx->phyadrStrmBuf);
	LOG_MSG(LOG_TRACE, "MFCInst_Enc_Init", "  ctx->phyadrStrmBuf + = 0x%X\n", ctx->phyadrStrmBuf + MFC_LINE_BUF_SIZE_PER_INSTANCE);


	///////////////////////////////////////////////////////////////////
	//                                                               //
	// 3. Issue the SEQ_INIT command                                 //
	//     (frame width/height will be returned.)                    //
	//                                                               //
	///////////////////////////////////////////////////////////////////
	// Set the Parameters for SEQ_INIT command.
	pPARAM_SEQ_INIT = (S3C6400_MFC_PARAM_REG_ENC_SEQ_INIT *) MfcGetCmdParamRegion();
	pPARAM_SEQ_INIT->ENC_SEQ_BIT_BUF_ADDR	= ctx->phyadrStrmBuf;
	pPARAM_SEQ_INIT->ENC_SEQ_BIT_BUF_SIZE   = MFC_LINE_BUF_SIZE_PER_INSTANCE / 1024;
	pPARAM_SEQ_INIT->ENC_SEQ_OPTION			= MB_BIT_REPORT_DISABLE | SLICE_INFO_REPORT_DISABLE | AUD_DISABLE;
	pPARAM_SEQ_INIT->ENC_SEQ_SRC_SIZE		= (ctx->width << 10) | ctx->height;
	pPARAM_SEQ_INIT->ENC_SEQ_SRC_F_RATE		= (ctx->frameRateDiv << 16) | ctx->frameRateRes;
	pPARAM_SEQ_INIT->ENC_SEQ_SLICE_MODE		= SLICE_MODE_ONE;
	pPARAM_SEQ_INIT->ENC_SEQ_GOP_NUM		= ctx->gopNum;
	pPARAM_SEQ_INIT->ENC_SEQ_RC_PARA		= RC_ENABLE | (ctx->bitrate << 1) | (SKIP_ENABLE << 31);	// set rate control
	pPARAM_SEQ_INIT->ENC_SEQ_INTRA_MB		= 0x0;		// Intra MB refresh is not used
	pPARAM_SEQ_INIT->ENC_SEQ_FMO			= FMO_DISABLE;
	pPARAM_SEQ_INIT->ENC_SEQ_SLICE_MODE		= SLICE_MODE_ONE;

	
	switch(ctx->codec_mode) {
		case MP4_ENC:
			pPARAM_SEQ_INIT->ENC_SEQ_COD_STD	= MPEG4_ENCODE;
			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 	= ctx->h263_annex;

			if (ctx->multiple_slice == 1) {
				pPARAM_SEQ_INIT->ENC_SEQ_SLICE_MODE = SLICE_MODE_MULTIPLE;
				pPARAM_SEQ_INIT->ENC_SEQ_263_PARA 	= ANNEX_K_ON;	
			}
			else if (ctx->enc_num_slices){
				// MB size is 16x16. -> width & height are divided by 16 to get number of MBs. (Division by 16 == shift right by 4-bit)
				num_mbs   = (enc_info->width >> 4) * (enc_info->height >> 4);
				slices_mb = (num_mbs / ctx->enc_num_slices);
				pPARAM_SEQ_INIT->ENC_SEQ_SLICE_MODE = SLICE_MODE_MULTIPLE | (1 << 1) | (slices_mb<< 2);
				pPARAM_SEQ_INIT->ENC_SEQ_263_PARA 	= ctx->h263_annex;
			}
			else if ( ((enc_info->width == 704) && (enc_info->height == 576)) || ((enc_info->width == 352) && (enc_info->height == 288)) || \
					((enc_info->width == 176) && (enc_info->height == 144))  || ((enc_info->width == 128) && (enc_info->height == 96)) ) {
				LOG_MSG(LOG_TRACE, "MFCInst_Enc_Init", "ENC_SEQ_263_PARA = 0x%X\n", pPARAM_SEQ_INIT->ENC_SEQ_263_PARA);
			}
			else if (ctx->h263_annex == 0) {
				LOG_MSG(LOG_ERROR, "MFCInst_Enc_Init", "H.263 Encoder supports 4CIF, CIF, QCIF and Sub-QCIF, when all Annex were off\n");
				return MFCINST_ERR_INVALID_PARAM;
			}
			
			break;

		case AVC_ENC:
			pPARAM_SEQ_INIT->ENC_SEQ_COD_STD	= H264_ENCODE;
			pPARAM_SEQ_INIT->ENC_SEQ_264_PARA	= ~(0xFFFF);

			if (ctx->enc_num_slices) {
				// MB size is 16x16. -> width & height are divided by 16 to get number of MBs. (Division by 16 == shift right by 4-bit)
				num_mbs   = (enc_info->width >> 4) * (enc_info->height >> 4);
				slices_mb = (num_mbs / ctx->enc_num_slices);
				pPARAM_SEQ_INIT->ENC_SEQ_SLICE_MODE = SLICE_MODE_MULTIPLE | (1 << 1) | (slices_mb<< 2);
			}

			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
	LOG_MSG(LOG_TRACE, "MFCInst_Enc_Init", "ANNEX K : 0x%X,  SLICE MODE : 0x%X\n", pPARAM_SEQ_INIT->ENC_SEQ_263_PARA, pPARAM_SEQ_INIT->ENC_SEQ_SLICE_MODE);
	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->buf_width;
	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);

	ctx->multiple_slice 	= 0;


	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;

#if (MFC_ROTATE_ENABLE == 1)
	int              frame_size;	// width * height
#endif

	////////////////////////////
	///    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_PWR_OFF_FLAG_CHECK(ctx)) {
		LOG_MSG(LOG_ERROR, "MFCInst_Decode", "MFC instance is in Power-Off state.\r\n");
		return MFCINST_ERR_STATE_POWER_OFF;
	}
	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;
	}


	pPARAM_DEC_PIC_RUN = (S3C6400_MFC_PARAM_REG_DEC_PIC_RUN *)  MfcGetCmdParamRegion();

	// (strm_leng > 0) means that the video stream is waiting for being decoded in the STRM_LINE_BUF.
	// Otherwise, no more video streams are available and the decode command will flush the decoded YUV data
	// which are postponed because of B-frame (VC-1) or reordering (H.264).
	if (strm_leng > 0) {

		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 = ctx->PostRotMode;
#if (MFC_ROTATE_ENABLE == 1)
	if (ctx->PostRotMode & 0x0010) {	// The bit of 'PostRotEn' is 1.

		frame_size = ctx->buf_width * ctx->buf_height;

		pPARAM_DEC_PIC_RUN->DEC_PIC_ROT_ADDR_Y  = ctx->phyadrFramBuf + ctx->frambufCnt * ((frame_size * 3) >> 1);
		pPARAM_DEC_PIC_RUN->DEC_PIC_ROT_ADDR_CB = pPARAM_DEC_PIC_RUN->DEC_PIC_ROT_ADDR_Y + frame_size;
		pPARAM_DEC_PIC_RUN->DEC_PIC_ROT_ADDR_CR = pPARAM_DEC_PIC_RUN->DEC_PIC_ROT_ADDR_Y + frame_size + (frame_size >> 2);

		// Rotate Angle
		switch (ctx->PostRotMode & 0x0003) {
		case 0:	// 0   degree counterclockwise rotate
		case 2:	// 180 degree counterclockwise rotate
			pPARAM_DEC_PIC_RUN->DEC_PIC_ROT_STRIDE  = ctx->buf_width;
			break;

		case 1:	// 90  degree counterclockwise rotate
		case 3:	// 270 degree counterclockwise rotate
			pPARAM_DEC_PIC_RUN->DEC_PIC_ROT_STRIDE  = ctx->buf_height;
			break;
		}
	}
#endif

	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;

	}
	else {
		pPARAM_DEC_PIC_RUN->DEC_PIC_CHUNK_SIZE  = strm_leng;

		MfcSetEos(1);

	}

	////////////////////////////////////////
	//                                    //
	// 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) {

		if (pPARAM_DEC_PIC_RUN->RET_DEC_PIC_IDX == 0xFFFFFFFF) {		// RET_DEC_PIC_IDX == -1
			LOG_MSG(LOG_WARNING, "Decode", "End of Stream.\r\n");
			return MFCINST_ERR_DEC_EOS;
		}
		else if (pPARAM_DEC_PIC_RUN->RET_DEC_PIC_IDX == 0xFFFFFFFD) {	// RET_DEC_PIC_IDX == -3
			LOG_MSG(LOG_TRACE, "Decode", "No picture to be displayed.\r\n");
		}
		else {
			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_ETC;
		}
	}

	ctx->idx = pPARAM_DEC_PIC_RUN->RET_DEC_PIC_IDX;

#ifdef CNM_PM	
	if( pPARAM_DEC_PIC_RUN->RET_DEC_PIC_ERR_MB_NUM > 0 )
		RETAILMSG( 1, (_T("Report MB Error num=%d\r\n"), pPARAM_DEC_PIC_RUN->RET_DEC_PIC_ERR_MB_NUM ) );
#endif	

	////////////////////////////
	///    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;
	
#if (MFC_ROTATE_ENABLE == 1)
	int              frame_size;	// width * height
#endif
	
	////////////////////////////
	///    STATE checking    ///
	////////////////////////////
	if (MFCINST_STATE_CHECK(ctx, MFCINST_STATE_DELETED)) {
		LOG_MSG(LOG_ERROR, "Decode_Stream", "MFC instance is deleted.\r\n");
		return MFCINST_ERR_STATE_DELETED;
	}
	if (MFCINST_STATE_PWR_OFF_FLAG_CHECK(ctx)) {
		LOG_MSG(LOG_ERROR, "Decode_Stream", "MFC instance is in Power-Off state.\r\n");
		return MFCINST_ERR_STATE_POWER_OFF;
	}
	if (MFCINST_STATE_CHECK(ctx, MFCINST_STATE_CREATED)) {
		LOG_MSG(LOG_ERROR, "Decode_Stream", "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, "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, "Decode_Stream", "Buffer should not be filled.\r\n");

⌨️ 快捷键说明

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