📄 mp4encapi.c
字号:
if (pInternalEncCont != pEncCont)
return ENC_INSTANCE_ERROR;
if (length == 0)
return ENC_INVALID_ARGUMENT;
switch (type)
{
case MPEG4_VOS_USER_DATA:
stat = EncUserDataAlloc(&pEncCont->inst.visualObjectSequence.userData,
pBuf, length);
break;
case MPEG4_VO_USER_DATA:
stat = EncUserDataAlloc(&pEncCont->inst.visualObject.userData,
pBuf, length);
break;
case MPEG4_VOL_USER_DATA:
stat = EncUserDataAlloc(&pEncCont->inst.videoObjectLayer.userData,
pBuf, length);
break;
case MPEG4_GOV_USER_DATA:
stat =
EncUserDataAlloc(&pEncCont->inst.groupOfVideoObjectPlane.userData,
pBuf, length);
break;
default:
return ENC_INVALID_ARGUMENT;
}
if (stat != OK)
return ENC_MEMORY_ERROR;
return ENC_OK;
}
/*******************************************************************************
Function name : MP4EncStrmStart
Description :
Return type : MP4EncRet
Argument : MP4EncInst inst
Argument : MP4EncIn * pEncIn
Argument : MP4EncOut *pEncOut
*******************************************************************************/
MP4EncRet MP4EncStrmStart(MP4EncInst inst, MP4EncIn * pEncIn,
MP4EncOut * pEncOut)
{
EncContainer_t *pEncCont = (EncContainer_t *) inst;
u32 byteCnt;
/* Check for illegal inputs */
if ((inst == NULL) || (pEncIn == NULL) || (pEncOut == NULL))
return ENC_NULL_ARGUMENT;
/* Check for existing instance */
if (pInternalEncCont != pEncCont)
return ENC_INSTANCE_ERROR;
if ((pEncIn->pOutBuf == NULL) || (pEncIn->outBufSize < 32))
return ENC_INVALID_ARGUMENT;
if (pEncCont->encStatus != ENCSTAT_INIT)
return ENC_INVALID_STATUS;
EncAsicSetup(pEncCont); /* Update ASIC with the stream parameters */
byteCnt = pEncIn->outBufSize;
if (EncStrmStart(pEncCont, pEncIn->pOutBuf, &byteCnt) != 0)
return ENC_OUTPUT_BUFFER_OVERFLOW;
pEncOut->strmSize = byteCnt; /* bytes generated */
pEncCont->encStatus = ENCSTAT_STRM_START;
return ENC_OK;
}
/*******************************************************************************
Function name : MP4EncStrmEncode
Description :
Return type : MP4EncRet
Argument : MP4EncInst inst
Argument : MP4EncIn * pEncIn
Argument : MP4EncOut *pEncOut
*******************************************************************************/
MP4EncRet MP4EncStrmEncode(MP4EncInst inst, MP4EncIn * pEncIn,
MP4EncOut * pEncOut)
{
EncContainer_t *pEncCont = (EncContainer_t *) inst;
i32 err;
MP4EncRet ret;
#ifdef SET_PADDING
i32 error;
#endif
/* Check for illegal inputs */
if ((inst == NULL) || (pEncIn == NULL) || (pEncOut == NULL))
return ENC_NULL_ARGUMENT;
/* Check for existing instance */
if (pInternalEncCont != pEncCont)
return ENC_INSTANCE_ERROR;
/* Check for invalid parameters */
if ((pEncIn->pOutBuf == NULL) ||
(pEncIn->vopType > PREDICTED_VOP) ||
(pEncIn->timeIncr > 127*pEncCont->inst.timeCode.vopTimeIncRes) )
return ENC_INVALID_ARGUMENT;
/* Minimum size for output buffer is 4k bytes */
if (pEncIn->outBufSize < 4096)
return ENC_INVALID_ARGUMENT;
/* Clear the output structure */
pEncOut->vopType = NOTCODED_VOP;
pEncOut->strmSize = 0;
GetTimeCode(&pEncCont->inst.timeCode, pEncOut);
/* Clear the video packet size table */
if (pEncIn->pVpSizes != NULL)
pEncIn->pVpSizes[0] = 0;
/* Set Vop coding parameters to ASIC registers */
ret = SetVopParameters(pEncCont, pEncIn, pEncOut);
if (ret != ENC_OK)
return ret;
#ifdef SET_PADDING
/* For debugging purposes */
EncAsicSetPadding(pEncCont);
#endif
/* Starting to encode a new VOP, ASIC should be disabled */
if (GetEncEnaStat() == 0)
SetEncEnable(1);
else
{
/* ASIC is already enabled, don't know what has happened */
pEncCont->encStatus = ENCSTAT_NEW_REF_IMG;
return ENC_ERROR;
}
/* Wait until ASIC has finished */
#if MP4ENC_ERR_IRQ_ENABLE && MP4ENC_VOP_IRQ_ENABLE
err = EWL_WaitHwRdy();
#else
{
u32 i;
err = EWL_TIMEOUT;
/* Simple polling/timeout, for testing purposes */
for (i = 0; i < 0x100000; i++)
{
if (GetEncIrqStat() != 0)
{
err = 0;
break;
}
}
}
#endif
#ifdef SET_PADDING
/* For debugging purposes */
if ((error = EncAsicCheckPadding(pEncCont)) != 0)
{
printf("PADDING CORRUPTED %d!\n", error); fflush(stdout);
}
#endif
if (err == EWL_TIMEOUT)
{
SetEncEnable(0);
if(EWL_ResetHwRdy() == EWL_OK)
{
pEncCont->encStatus = ENCSTAT_NEW_REF_IMG;
return ENC_HW_TIMEOUT;
}
else
{
pEncCont->encStatus = ENCSTAT_NEW_REF_IMG;
return ENC_SYSTEM_ERROR;
}
}
/* Get Vop coding status from ASIC */
return GetVopStatus(pEncCont, pEncIn, pEncOut);
}
/*******************************************************************************
Function name : MP4EncStrmEnd
Description :
Return type : MP4EncRet
Argument : MP4EncInst inst
Argument : MP4EncIn * pEncIn
Argument : MP4EncOut *pEncOut
*******************************************************************************/
MP4EncRet MP4EncStrmEnd(MP4EncInst inst, MP4EncIn * pEncIn,
MP4EncOut * pEncOut)
{
EncContainer_t *pEncCont = (EncContainer_t *) inst;
u32 byteCnt;
/* Check for illegal inputs */
if ((inst == NULL) || (pEncIn == NULL) || (pEncOut == NULL))
return ENC_NULL_ARGUMENT;
/* Check for existing instance */
if (pInternalEncCont != pEncCont)
return ENC_INSTANCE_ERROR;
if ((pEncIn->pOutBuf == NULL) || (pEncIn->outBufSize < 4))
return ENC_INVALID_ARGUMENT;
if ((pEncCont->encStatus != ENCSTAT_START_VOP) &&
(pEncCont->encStatus != ENCSTAT_NEW_REF_IMG))
return ENC_INVALID_STATUS;
byteCnt = pEncIn->outBufSize;
if (EncStrmEnd(pEncCont, pEncIn->pOutBuf, &byteCnt) != 0)
return ENC_OUTPUT_BUFFER_OVERFLOW;
pEncOut->strmSize = byteCnt; /* bytes generated */
pEncCont->encStatus = ENCSTAT_INIT;
return ENC_OK;
}
/*******************************************************************************
Function name : MP4EncSetSmooth
Description : Sets the smoothing block on/off
Return type : MP4EncRet
Argument : MP4EncInst inst
Argument : u32 status
*******************************************************************************/
MP4EncRet MP4EncSetSmooth(MP4EncInst inst, u32 status)
{
EncContainer_t *pEncCont = (EncContainer_t *) inst;
/* Check for illegal inputs */
if (inst == NULL)
return ENC_NULL_ARGUMENT;
/* Check for existing instance */
if (pInternalEncCont != pEncCont)
return ENC_INSTANCE_ERROR;
if (status != 0)
{
pEncCont->inst.preProcess.smooth = YES;
SetEncPreProEnable(1);
}
else
{
pEncCont->inst.preProcess.smooth = NO;
SetEncPreProEnable(0);
}
return ENC_OK;
}
/*******************************************************************************
Function name : MP4EncGetSmooth
Description : Retrieves the on/off status of the smoothing block
Return type : MP4EncRet
Argument : MP4EncInst inst
Argument : u32 *status
*******************************************************************************/
MP4EncRet MP4EncGetSmooth(MP4EncInst inst, u32 * status)
{
EncContainer_t *pEncCont = (EncContainer_t *) inst;
/* Check for illegal inputs */
if ((inst == NULL) || (status == NULL))
return ENC_NULL_ARGUMENT;
/* Check for existing instance */
if (pInternalEncCont != pEncCont)
return ENC_INSTANCE_ERROR;
if (pEncCont->inst.preProcess.smooth == NO)
*status = 0;
else
*status = 1;
return ENC_OK;
}
/*******************************************************************************
Function name : MP4EncSetCrop
Description :
Return type : MP4EncRet
Argument : MP4EncInst inst
Argument : MP4EncCropCfg status
*******************************************************************************/
MP4EncRet MP4EncSetCrop(MP4EncInst inst, MP4EncCropCfg * pCropCfg)
{
EncContainer_t *pEncCont = (EncContainer_t *) inst;
preProcess_s pp_tmp;
/* Check for illegal inputs */
if ((inst == NULL) || (pCropCfg == NULL))
return ENC_NULL_ARGUMENT;
/* Check for existing instance */
if (pInternalEncCont != pEncCont)
return ENC_INSTANCE_ERROR;
/* ASIC input image width must be multiple of 8 and
* between 96 and 1016 pixels */
if (((pCropCfg->origWidth & 0x7) != 0) ||
(pCropCfg->origWidth > 1016) ||
(pCropCfg->origHeight > 1016) ||
(pCropCfg->origWidth < 96) ||
(pCropCfg->origHeight < 96))
return ENC_INVALID_ARGUMENT;
pp_tmp.stabFrame = pCropCfg->stabArea;
pp_tmp.lumHeightSrc = pCropCfg->origHeight;
pp_tmp.lumWidthSrc = pCropCfg->origWidth;
pp_tmp.horOffsetSrc = pCropCfg->xOffset - pCropCfg->stabArea;
pp_tmp.verOffsetSrc = pCropCfg->yOffset - pCropCfg->stabArea;
pp_tmp.lumHeight = pEncCont->inst.preProcess.lumHeight;
pp_tmp.lumWidth = pEncCont->inst.preProcess.lumWidth;
/* Check for invalid values */
if (EncPreProcessCheck(&pp_tmp) != OK)
return ENC_INVALID_ARGUMENT;
if (pp_tmp.stabFrame != 0)
SetEncCamStabEnable(1);
else
SetEncCamStabEnable(0);
pEncCont->inst.preProcess.stabFrame = pp_tmp.stabFrame;
pEncCont->inst.preProcess.lumHeightSrc = pp_tmp.lumHeightSrc;
pEncCont->inst.preProcess.lumWidthSrc = pp_tmp.lumWidthSrc;
pEncCont->inst.preProcess.horOffsetSrc = pp_tmp.horOffsetSrc;
pEncCont->inst.preProcess.verOffsetSrc = pp_tmp.verOffsetSrc;
pEncCont->inst.preProcess.horOffset = pp_tmp.stabFrame;
pEncCont->inst.preProcess.verOffset = pp_tmp.stabFrame;
/* Initialize pre processing */
EncPreProcessCheck(&pEncCont->inst.preProcess);
return ENC_OK;
}
/*******************************************************************************
Function name : MP4EncGetCrop
Description :
Return type : MP4EncRet
Argument : MP4EncInst inst
Argument : MP4EncCropCfg * status
*******************************************************************************/
MP4EncRet MP4EncGetCrop(MP4EncInst inst, MP4EncCropCfg * pCropCfg)
{
EncContainer_t *pEncCont = (EncContainer_t *) inst;
/* Check for illegal inputs */
if ((inst == NULL) || (pCropCfg == NULL))
return ENC_NULL_ARGUMENT;
/* Check for existing instance */
if (pInternalEncCont != pEncCont)
return ENC_INSTANCE_ERROR;
pCropCfg->stabArea = pEncCont->inst.preProcess.stabFrame;
pCropCfg->origHeight = pEncCont->inst.preProcess.lumHeightSrc;
pCropCfg->origWidth = pEncCont->inst.preProcess.lumWidthSrc;
pCropCfg->xOffset = pEncCont->inst.preProcess.horOffsetSrc +
pEncCont->inst.preProcess.stabFrame;
pCropCfg->yOffset = pEncCont->inst.preProcess.verOffsetSrc +
pEncCont->inst.preProcess.stabFrame;
return ENC_OK;
}
/*******************************************************************************
Function name : MP4EncGetLastFrmPos
Description :
Return type : MP4EncRet
Argument : MP4EncInst inst
Argument : MP4EncFrmPos * status
*******************************************************************************/
MP4EncRet MP4EncGetLastFrmPos(MP4EncInst inst, MP4EncFrmPos * pFrmPos)
{
EncContainer_t *pEncCont = (EncContainer_t *) inst;
/* Check for illegal inputs */
if ((inst == NULL) || (pFrmPos == NULL))
return ENC_NULL_ARGUMENT;
/* Check for existing instance */
if (pInternalEncCont != pEncCont)
return ENC_INSTANCE_ERROR;
pFrmPos->xOffset =
pEncCont->inst.preProcess.horOffsetSrc +
pEncCont->inst.preProcess.horOffset;
pFrmPos->yOffset =
pEncCont->inst.preProcess.verOffsetSrc +
pEncCont->inst.preProcess.verOffset;
return ENC_OK;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -