📄 mfc_instance.c
字号:
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->run_index = pPARAM_DEC_PIC_RUN->RET_DEC_PIC_IDX;
#if (defined(DIVX_ENABLE) && (DIVX_ENABLE == 1))
ctx->RET_DEC_PIC_RUN_BAK_BYTE_CONSUMED = pPARAM_DEC_PIC_RUN->RET_DEC_PIC_BCNT;
ctx->RET_DEC_PIC_RUN_BAK_MP4ASP_FCODE = pPARAM_DEC_PIC_RUN->RET_DEC_PIC_FCODE_FWD;
ctx->RET_DEC_PIC_RUN_BAK_MP4ASP_TIME_BASE_LAST = pPARAM_DEC_PIC_RUN->RET_DEC_PIC_TIME_BASE_LAST;
ctx->RET_DEC_PIC_RUN_BAK_MP4ASP_NONB_TIME_LAST = pPARAM_DEC_PIC_RUN->RET_DEC_PIC_NONB_TIME_LAST;
ctx->RET_DEC_PIC_RUN_BAK_MP4ASP_MP4ASP_TRD = pPARAM_DEC_PIC_RUN->RET_DEC_PIC_TRD;
#endif
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 ) );
////////////////////////////
/// 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;
}
int MFCInst_Encode(MFCInstCtx *ctx, int *enc_data_size, int *header_size)
{
volatile S3C6410_MFC_PARAM_REG_ENC_PIC_RUN *pPARAM_ENC_PIC_RUN;
S3C6410_MFC_SFR *mfc_sfr;
int hdr_size, hdr_size2,hdr_size3;
unsigned char *hdr_buf_tmp=NULL;
////////////////////////////
/// STATE checking ///
////////////////////////////
if (!MFCINST_STATE_CHECK(ctx, MFCINST_STATE_ENC_INITIALIZED) && !MFCINST_STATE_CHECK(ctx, MFCINST_STATE_ENC_PIC_RUN_LINE_BUF)) {
LOG_MSG(LOG_ERROR, "MFCInst_Encode", "MFC Encoder instance is not initialized or not using the line buffer.\r\n");
return MFCINST_ERR_STATE_CHK;
}
mfc_sfr = (S3C6410_MFC_SFR *) GetMfcSfrVirAddr();
// The 1st call of this function (MFCInst_Encode) will generate the stream header (mpeg4: VOL, h264: SPS/PPS).
//
if (MFCINST_STATE_CHECK(ctx, MFCINST_STATE_ENC_INITIALIZED)) {
if (ctx->codec_mode == MP4_ENC) {
// ENC_HEADER command //
MFCInst_EncHeader(ctx, 1, 0, ctx->phyadrStrmBuf, ctx->nStrmBufSize, &hdr_size); // VOS
MFCInst_EncHeader(ctx, 2, 0, ctx->phyadrStrmBuf + (hdr_size + 3), ctx->nStrmBufSize-(hdr_size+3), &hdr_size2); // VO
MFCInst_EncHeader(ctx, 0, 0, ctx->phyadrStrmBuf + (hdr_size + 3) + (hdr_size2 + 3), ctx->nStrmBufSize-(hdr_size+3)-(hdr_size2 + 3), &hdr_size3); // VOL
LOG_MSG(LOG_TRACE, "Encode", "MPEG4 Header Size : VOS=%d, VO=%d, VOL=%d \r\n", hdr_size, hdr_size2, hdr_size3);
hdr_buf_tmp = Mem_Alloc(hdr_size + 3 + hdr_size2 + 3 + hdr_size3);
Mem_Cpy(hdr_buf_tmp, ctx->pStrmBuf, hdr_size);
InvalidateCacheRange((PBYTE )ctx->pStrmBuf, (PBYTE )(ctx->pStrmBuf + (hdr_size+3) ) );
Mem_Cpy(hdr_buf_tmp + hdr_size, (void *)((unsigned int)(ctx->pStrmBuf + (hdr_size + 3)) & 0xFFFFFFFC), hdr_size2);
InvalidateCacheRange((PBYTE )(ctx->pStrmBuf), (PBYTE )((ctx->pStrmBuf+(hdr_size+3) + (hdr_size2+3))) );
Mem_Cpy(hdr_buf_tmp + hdr_size + hdr_size2, (void *)((unsigned int)(ctx->pStrmBuf + (hdr_size+3) + (hdr_size2+3)) & 0xFFFFFFFC), hdr_size3);
InvalidateCacheRange((PBYTE )(ctx->pStrmBuf), (PBYTE )(ctx->pStrmBuf+(hdr_size+3)+(hdr_size2+3)+hdr_size3) );
hdr_size = hdr_size+hdr_size2+hdr_size3;
}
else if (ctx->codec_mode == AVC_ENC) {
// ENC_HEADER command //
MFCInst_EncHeader(ctx, 0, 0, ctx->phyadrStrmBuf, ctx->nStrmBufSize, &hdr_size); // SPS
MFCInst_EncHeader(ctx, 1, 0, ctx->phyadrStrmBuf + (hdr_size + 3), ctx->nStrmBufSize-(hdr_size+3), &hdr_size2); // PPS
LOG_MSG(LOG_TRACE, "Encode", "MPEG4 Header Size : SPS=%d, PPS=%d \r\n", hdr_size, hdr_size2);
// Backup the stream header in the temporary header buffer.
hdr_buf_tmp = (unsigned char *) Mem_Alloc(hdr_size + 3 + hdr_size2);
if (hdr_buf_tmp)
{
Mem_Cpy(hdr_buf_tmp, ctx->pStrmBuf, hdr_size);
InvalidateCacheRange((PBYTE )ctx->pStrmBuf, (PBYTE )(ctx->pStrmBuf + hdr_size) );
Mem_Cpy(hdr_buf_tmp + hdr_size, (void *)((unsigned int)(ctx->pStrmBuf + (hdr_size + 3)) & 0xFFFFFFFC), hdr_size2);
hdr_size = hdr_size + hdr_size2;
InvalidateCacheRange((PBYTE )ctx->pStrmBuf, (PBYTE )(ctx->pStrmBuf + hdr_size) );
}
else
{
return MFCINST_ERR_MEMORY_ALLOCATION_FAIL;
}
}
}
// SEI message with recovery point
if ((ctx->enc_pic_option & 0x0F000000) && (ctx->codec_mode == AVC_ENC))
{
// Free hdr_seze
if(hdr_buf_tmp)
Mem_Free(hdr_buf_tmp);
// ENC_HEADER command //
MFCInst_EncHeader(ctx, 4, ((ctx->enc_pic_option & 0x0F000000) >> 24), ctx->phyadrStrmBuf, ctx->nStrmBufSize, &hdr_size); // SEI
// Backup the stream header in the temporary header buffer.
hdr_buf_tmp = (unsigned char *) Mem_Alloc(hdr_size);
if (hdr_buf_tmp)
{
Mem_Cpy(hdr_buf_tmp, ctx->pStrmBuf, hdr_size);
InvalidateCacheRange((PBYTE )ctx->pStrmBuf, (PBYTE )(ctx->pStrmBuf + hdr_size) );
}
else
{
return MFCINST_ERR_MEMORY_ALLOCATION_FAIL;
}
}
/*
* Set the address of each component of YUV420
*/
pPARAM_ENC_PIC_RUN = (S3C6410_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->buf_width * ctx->height;
pPARAM_ENC_PIC_RUN->ENC_PIC_SRC_ADDR_CR = ctx->phyadrFramBuf + ((ctx->buf_width * ctx->height * 5) >> 2);
pPARAM_ENC_PIC_RUN->ENC_PIC_ROT_MODE = 0;
pPARAM_ENC_PIC_RUN->ENC_PIC_OPTION = (ctx->enc_pic_option & 0x0000FFFF);
pPARAM_ENC_PIC_RUN->ENC_PIC_BB_START = ctx->phyadrStrmBuf;
pPARAM_ENC_PIC_RUN->ENC_PIC_BB_SIZE = ctx->nStrmBufSize;
if (!MfcIssueCmd(ctx->inst_no, ctx->codec_mode, PIC_RUN)) {
return MFCINST_ERR_ENC_PIC_RUN_CMD_FAIL;
}
ctx->enc_pic_option = 0; // Reset the encoding picture option at every picture
ctx->run_index = 0;
ctx->RET_ENC_PIC_RUN_BAK_PIC_TYPE = pPARAM_ENC_PIC_RUN->RET_ENC_PIC_TYPE;
*enc_data_size = mfc_sfr->BIT_STR_BUF_RW_ADDR[ctx->inst_no].BITS_WR_PTR - ctx->phyadrStrmBuf; // calculte encoded data size
*header_size = 0;
if (hdr_buf_tmp) {
memmove(ctx->pStrmBuf + hdr_size, ctx->pStrmBuf, *enc_data_size);
CleanInvalidateCacheRange((PBYTE )ctx->pStrmBuf, (PBYTE )(ctx->pStrmBuf + *enc_data_size) );
Mem_Cpy(ctx->pStrmBuf, hdr_buf_tmp, hdr_size);
CleanInvalidateCacheRange((PBYTE )ctx->pStrmBuf, (PBYTE )(ctx->pStrmBuf + *enc_data_size) );
Mem_Free(hdr_buf_tmp);
*enc_data_size += hdr_size;
*header_size = hdr_size;
}
////////////////////////////
/// STATE changing ///
////////////////////////////
// state change to MFCINST_STATE_ENC_PIC_RUN_LINE_BUF
MFCINST_STATE_TRANSITION(ctx, MFCINST_STATE_ENC_PIC_RUN_LINE_BUF);
return MFCINST_RET_OK;
}
// hdr_code == 0: SPS
// hdr_code == 1: PPS
// hdr_code == 4: SEI
int MFCInst_EncHeader(MFCInstCtx *ctx, int hdr_code, int hdr_num, unsigned int outbuf_physical_addr, int outbuf_size, int *hdr_size)
{
volatile S3C6410_MFC_PARAM_REG_ENC_HEADER *pPARAM_ENC_HEADER;
S3C6410_MFC_SFR *mfc_sfr;
unsigned int uiEncodeLevel;
if (!MFCINST_STATE_CHECK(ctx, MFCINST_STATE_ENC_INITIALIZED) && !MFCINST_STATE_CHECK(ctx, MFCINST_STATE_ENC_PIC_RUN_LINE_BUF)) {
LOG_MSG(LOG_ERROR, "MFCInst_EncHeader", "MFC Encoder instance is not initialized or not using the line buffer.\r\n");
return MFCINST_ERR_STATE_CHK;
}
if ((ctx->codec_mode != MP4_ENC) && (ctx->codec_mode != AVC_ENC)) {
return MFCINST_ERR_WRONG_CODEC_MODE;
}
// VOS Level in MP4
if((ctx->codec_mode == MP4_ENC) && (hdr_code == 1))
{
uiEncodeLevel = ((ctx->level<<8) | hdr_code);
}
else
{
uiEncodeLevel = hdr_code;
}
//
/*
* Set the address of each component of YUV420
*/
pPARAM_ENC_HEADER = (S3C6410_MFC_PARAM_REG_ENC_HEADER *) MfcGetCmdParamRegion();
pPARAM_ENC_HEADER->ENC_HEADER_CODE = uiEncodeLevel;
pPARAM_ENC_HEADER->ENC_HEADER_BB_START = outbuf_physical_addr & 0xFFFFFFFC;
pPARAM_ENC_HEADER->ENC_HEADER_BB_SIZE = outbuf_size; //ctx->nStrmBufSize;
if (hdr_code == 4) // SEI recovery point
pPARAM_ENC_HEADER->ENC_HEADER_NUM = hdr_num; // recovery point value
mfc_sfr = (S3C6410_MFC_SFR *) GetMfcSfrVirAddr();
if (!MfcIssueCmd(ctx->inst_no, ctx->codec_mode, ENC_HEADER)) {
return MFCINST_ERR_ENC_HEADER_CMD_FAIL;
}
*hdr_size = mfc_sfr->BIT_STR_BUF_RW_ADDR[ctx->inst_no].BITS_WR_PTR - pPARAM_ENC_HEADER->ENC_HEADER_BB_START;
return MFCINST_RET_OK;
}
int MFCInst_EncParamChange(MFCInstCtx *ctx, unsigned int param_change_enable, unsigned int param_change_val)
{
volatile S3C6410_MFC_PARAM_REG_ENC_PARAM_CHANGE *pPARAM_ENC_PARAM_CHANGE;
int num_mbs; // Number of MBs
int slices_mb; // MB number of slice (only if SLICE_MODE_MULTIPLE is selected.)
pPARAM_ENC_PARAM_CHANGE = (S3C6410_MFC_PARAM_REG_ENC_PARAM_CHANGE *) MfcGetCmdParamRegion();
memset((void *)pPARAM_ENC_PARAM_CHANGE, 0, sizeof(S3C6410_MFC_PARAM_REG_ENC_PARAM_CHANGE));
pPARAM_ENC_PARAM_CHANGE->ENC_PARAM_CHANGE_ENABLE = param_change_enable;
// GOP_NUM
if (param_change_enable == (1 << 0)) {
if (param_change_val > 60) {
LOG_MSG(LOG_ERROR, "MFCInst_EncParamChange", "MFC Encoder Parameter change value is invalid.\r\n");
return MFCINST_ERR_ENC_PARAM_CHANGE_INVALID_VALUE;
}
pPARAM_ENC_PARAM_CHANGE->ENC_PARAM_CHANGE_GOP_NUM = param_change_val;
}
// INTRA_QP
else if (param_change_enable == (1 << 1)) {
if (((ctx->codec_mode == MP4_DEC || ctx->codec_mode == H263_DEC) && (param_change_val == 0 || param_change_val > 31))
|| (ctx->codec_mode == AVC_DEC && param_change_val > 51)) {
LOG_MSG(LOG_ERROR, "MFCInst_EncParamChange", "MFC Encoder Parameter change value is invalid.\r\n");
return MFCINST_ERR_ENC_PARAM_CHANGE_INVALID_VALUE;
}
pPARAM_ENC_PARAM_CHANGE->ENC_PARAM_CHANGE_INTRA_QP = param_change_val;
}
// BITRATE
else if (param_change_enable == (1 << 2)) {
if (param_change_val > 0x07FFF) {
LOG_MSG(LOG_ERROR, "MFCInst_EncParamChange", "MFC Encoder Parameter change value is invalid.\r\n");
return MFCINST_ERR_ENC_PARAM_CHANGE_INVALID_VALUE;
}
pPARAM_ENC_PARAM_CHANGE->ENC_PARAM_CHANGE_BITRATE = param_change_val;
}
// F_RATE
else if (param_change_enable == (1 << 3)) {
pPARAM_ENC_PARAM_CHANGE->ENC_PARAM_CHANGE_F_RATE = param_change_val;
}
// INTRA_REFRESH
else if (param_change_enable == (1 << 4)) {
if ((int)param_change_val > ((ctx->width * ctx->height) >> 8)) {
LOG_MSG(LOG_ERROR, "MFCInst_EncParamChange", "MFC Encoder Parameter change value is invalid.\r\n");
return MFCINST_ERR_ENC_PARAM_CHANGE_INVALID_VALUE;
}
pPARAM_ENC_PARAM_CHANGE->ENC_PARAM_CHANGE_INTRA_REFRESH = param_change_val;
}
// SLICE_MODE
else if (param_change_enable == (1 << 5)) {
// 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 = (ctx->width >> 4) * (ctx->height >> 4);
if ((int)param_change_val > 256 || (int)param_change_val > num_mbs) {
LOG_MSG(LOG_ERROR, "MFCInst_EncParamChange", "MFC Encoder Parameter change value is invalid.\r\n");
return MFCINST_ERR_ENC_PARAM_CHANGE_INVALID_VALUE;
}
if (param_change_val == 0) {
pPARAM_ENC_PARAM_CHANGE->ENC_PARAM_CHANGE_SLICE_MODE = SLICE_MODE_ONE;
}
else {
slices_mb = (num_mbs / param_change_val);
ctx->enc_num_slices = param_change_val;
pPARAM_ENC_PARAM_CHANGE->ENC_PARAM_CHANGE_SLICE_MODE = SLICE_MODE_MULTIPLE | (1 << 1) | (slices_mb<< 2);;
}
}
if (!MfcIssueCmd(ctx->inst_no, ctx->codec_mode, ENC_PARAM_CHANGE)) {
return MFCINST_ERR_ENC_HEADER_CMD_FAIL;
}
return MFCINST_RET_OK;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -