📄 mfc_instance.c
字号:
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 + -