📄 mp4encapi.c
字号:
/*------------------------------------------------------------------------------
-- --
-- This software is confidential and proprietary and may be used --
-- only as expressly authorized by a licensing agreement from --
-- --
-- Hantro Products Oy. --
-- --
-- In the event of publication, the following notice is applicable: --
-- --
-- (C) COPYRIGHT 2003 HANTRO PRODUCTS OY --
-- ALL RIGHTS RESERVED --
-- --
-- The entire notice above must be reproduced on all copies. --
-- --
--------------------------------------------------------------------------------
--
-- Abstract : VGA MPEG4 Encoder main API implementation
--
-------------------------------------------------------------------------------*/
#include "mp4encapi.h"
#include "ewl.h"
#include "enccontainer.h"
#include "encinternal.h"
#include "encregdrv.h"
#include "encmemory.h"
#include "encasic.h"
#include "EncRateControl.h"
/* internal data */
static EncContainer_t *pInternalEncCont = NULL;
/*------------------------------------------------------------------------------
Version Information
------------------------------------------------------------------------------*/
#define MP4ENC_MAJOR_VERSION 3
#define MP4ENC_MINOR_VERSION 1
/*******************************************************************************
Function name : MP4EncGetVersion
Description :
Return type : MP4EncApiVersion
*******************************************************************************/
MP4EncApiVersion MP4EncGetVersion()
{
MP4EncApiVersion ver;
ver.major = MP4ENC_MAJOR_VERSION;
ver.minor = MP4ENC_MINOR_VERSION;
return ver;
}
/*******************************************************************************
Function name : MP4EncInit
Description :
Return type : MP4EncRet
Argument : MP4EncCfg * pEncCfg
Argument : MP4EncInst * instAddr
*******************************************************************************/
MP4EncRet MP4EncInit(MP4EncCfg * pEncCfg, MP4EncInst * instAddr)
{
MP4EncRet ret = ENC_OK;
/* Check for illegal inputs */
if(pEncCfg == NULL || instAddr == NULL)
return ENC_NULL_ARGUMENT;
/* Check for existing instance */
if (pInternalEncCont != NULL)
return ENC_INSTANCE_ERROR;
/* Check for invalid values */
if (CheckInitCfg(pEncCfg) != 0)
return ENC_INVALID_ARGUMENT;
/* Allocate memory for instance structure and initialize to zero */
pInternalEncCont =
(EncContainer_t *) hantro_calloc(sizeof(EncContainer_t), 1);
if (pInternalEncCont == NULL)
return ENC_MEMORY_ERROR;
/* init EWL */
if (EWL_Init() != 0)
{
ret = ENC_EWL_ERROR;
goto end1;
}
/* init stream handling and set default values */
if (EncStrmInit(pInternalEncCont, pEncCfg) != 0)
{
/* Profile and level limitations failed */
ret = ENC_INVALID_ARGUMENT;
goto end2;
}
/* and finaly allocate needed memory */
if (AllocMem(pInternalEncCont) != 0)
{
ret = ENC_EWL_MEMORY_ERROR;
goto end3;
}
/* update return values */
pInternalEncCont->encStatus = ENCSTAT_INIT;
*instAddr = (MP4EncInst) pInternalEncCont;
return ret;
/* free allocated resources on error */
end3:
EncStrmRelease(pInternalEncCont);
end2:
EWL_Release();
end1:
if( pInternalEncCont != NULL )
{
hantro_free(pInternalEncCont);
pInternalEncCont = NULL;
}
*instAddr = NULL;
return ret;
}
/*******************************************************************************
Function name : MP4EncRelease
Description :
Return type : MP4EncRet
Argument : MP4EncInst inst
*******************************************************************************/
MP4EncRet MP4EncRelease(MP4EncInst inst)
{
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;
SetEncEnable(0);
EWL_ResetHwRdy();
/* release everything what shall be released */
EncStrmRelease(pEncCont);
FreeMem(pEncCont);
hantro_free(pEncCont);
pInternalEncCont = NULL;
/* release EWL */
if (EWL_Release() != 0)
return ENC_EWL_ERROR;
return ENC_OK;
}
/*******************************************************************************
Function name : MP4EncSetCodingCtrl
Description :
Return type : MP4EncRet
Argument : MP4EncInst inst
Argument : MP4EncCodingCtrl * pCodeParams
*******************************************************************************/
MP4EncRet MP4EncSetCodingCtrl(MP4EncInst inst,
MP4EncCodingCtrl * pCodeParams)
{
EncContainer_t *pEncCont = (EncContainer_t *) inst;
/* Check for illegal inputs */
if ((inst == NULL) || (pCodeParams == NULL))
return ENC_NULL_ARGUMENT;
/* Check for existing instance */
if (pInternalEncCont != pEncCont)
return ENC_INSTANCE_ERROR;
/* Check for invalid values */
if (pEncCont->inst.videoObjectLayer.resyncMarkerDisable == NO)
{
profile_s profile = pEncCont->inst.profile;
profile.vpSize = pCodeParams->vpSize;
/* Profile limits VP size */
if (EncProfileCheck(&profile) != OK)
return ENC_INVALID_ARGUMENT;
/* Minimum size for the video packet.
* ASIC actually supports size zero: the whole VOP is in
* the same video packet, but the API doesn't */
if (pCodeParams->vpSize < 1)
return ENC_INVALID_ARGUMENT;
/* ASIC limits maximum VP size */
if (pCodeParams->vpSize > 60000)
return ENC_INVALID_ARGUMENT;
}
/* GOV, only for MPEG-4 stream */
if (pEncCont->inst.videoObjectPlane.header == YES)
{
if (pCodeParams->insGOV != 0)
pEncCont->inst.groupOfVideoObjectPlane.header = YES;
else
pEncCont->inst.groupOfVideoObjectPlane.header = NO;
}
/* HEC, only for VP stream */
if (pEncCont->inst.videoObjectLayer.resyncMarkerDisable == NO)
{
if (pCodeParams->insHEC != 0)
pEncCont->inst.videoObjectPlane.hec = YES;
else
pEncCont->inst.videoObjectPlane.hec = NO;
}
/* GOB bitmask, only for SVH/H.263 stream, mask 24 LSB */
if (pEncCont->inst.shortVideoHeader.header == YES)
pEncCont->inst.shortVideoHeader.gobPlace =
(pCodeParams->insGOB & 0xFFFFFF);
/* VP size */
if (pEncCont->inst.videoObjectLayer.resyncMarkerDisable == NO)
pEncCont->inst.profile.vpSize = pCodeParams->vpSize;
return ENC_OK;
}
/*******************************************************************************
Function name : MP4EncGetCodingCtrl
Description :
Return type : MP4EncRet
Argument : MP4EncInst inst
Argument : MP4EncCodingCtrl * pCodeParams
*******************************************************************************/
MP4EncRet MP4EncGetCodingCtrl(MP4EncInst inst,
MP4EncCodingCtrl * pCodeParams)
{
EncContainer_t *pEncCont = (EncContainer_t *) inst;
/* Check for illegal inputs */
if ((inst == NULL) || (pCodeParams == NULL))
return ENC_NULL_ARGUMENT;
/* Check for existing instance */
if (pInternalEncCont != pEncCont)
return ENC_INSTANCE_ERROR;
/* VP size */
pCodeParams->vpSize = (u32) pEncCont->inst.profile.vpSize;
/* GOB */
pCodeParams->insGOB = (u32) pEncCont->inst.shortVideoHeader.gobPlace;
/* HEC */
pCodeParams->insHEC = (u32) pEncCont->inst.videoObjectPlane.hec;
/* GOV */
pCodeParams->insGOV = (u32) pEncCont->inst.groupOfVideoObjectPlane.header;
return ENC_OK;
}
/*******************************************************************************
Function name : MP4EncSetRateCtrl
Description :
Return type : MP4EncRet
Argument : MP4EncInst inst
Argument : MP4EncRateCtrl * pRateCtrl
*******************************************************************************/
MP4EncRet MP4EncSetRateCtrl(MP4EncInst inst, MP4EncRateCtrl * pRateCtrl)
{
EncContainer_t *pEncCont = (EncContainer_t *) inst;
profile_s profile;
rateControl_s *rc;
/* Check for illegal inputs */
if ((inst == NULL) || (pRateCtrl == NULL))
return ENC_NULL_ARGUMENT;
/* Check for existing instance */
if (pInternalEncCont != pEncCont)
return ENC_INSTANCE_ERROR;
if (pRateCtrl->qpHdr < 1 || pRateCtrl->qpHdr > 31)
return ENC_INVALID_ARGUMENT;
if (pRateCtrl->qpHdrMin < 1 || pRateCtrl->qpHdrMin > 31)
return ENC_INVALID_ARGUMENT;
if (pRateCtrl->qpHdrMax < 1 || pRateCtrl->qpHdrMax > 31)
return ENC_INVALID_ARGUMENT;
rc = &pEncCont->inst.rateControl;
/* Check for invalid bitrate */
profile = pEncCont->inst.profile;
profile.bitPerSecond = pRateCtrl->bitPerSecond;
if (EncProfileCheck(&profile) != OK)
return ENC_INVALID_ARGUMENT;
/* Set the video buffer size, 1 == use the maximum value in profile */
pEncCont->inst.profile.videoBufferSize = pRateCtrl->vbv;
/* Calculate the videoBufferSize in bits */
EncInitProfile(&pEncCont->inst.profile);
pEncCont->inst.profile.bitPerSecond = pRateCtrl->bitPerSecond;
/* Set the parameters to rate control */
if (pRateCtrl->vbv != 0)
rc->videoBuffer.vbv = YES;
else
rc->videoBuffer.vbv = NO;
rc->videoBuffer.videoBufferSize =
pEncCont->inst.profile.videoBufferSize;
rc->videoBuffer.videoBufferBitCnt =
pEncCont->inst.profile.videoBufferBitCnt;
if (pRateCtrl->vopRc != 0)
rc->vopRc = YES;
else
rc->vopRc = NO;
if (pRateCtrl->mbRc != 0)
rc->mbRc = YES;
else
rc->mbRc = NO;
if (pRateCtrl->vopSkip != 0)
rc->vopSkip = YES;
else
rc->vopSkip = NO;
rc->qpHdr = rc->qpHdrPrev[0] = rc->qpHdrPrev[1] = pRateCtrl->qpHdr;
rc->qpHdrMin = pRateCtrl->qpHdrMin;
rc->qpHdrMax = pRateCtrl->qpHdrMax;
rc->virtualBuffer.bitPerSecond = pRateCtrl->bitPerSecond;
/* CIR value is the distance between two intra macroblocks */
rc->cir.cir = pRateCtrl->cir;
/* Rate control init depends if this is before the first VOP */
if (pEncCont->encStatus == ENCSTAT_INIT ||
pEncCont->encStatus == ENCSTAT_STRM_START) {
rc->virtualBuffer.setFirstVop = YES;
}
EncRcCheck(rc);
return ENC_OK;
}
/*******************************************************************************
Function name : MP4EncGetRateCtrl
Description :
Return type : MP4EncRet
Argument : MP4EncInst inst
Argument : MP4EncRateCtrl * pRateCtrl
*******************************************************************************/
MP4EncRet MP4EncGetRateCtrl(MP4EncInst inst, MP4EncRateCtrl * pRateCtrl)
{
EncContainer_t *pEncCont = (EncContainer_t *) inst;
rateControl_s *rc;
/* Check for illegal inputs */
if ((inst == NULL) || (pRateCtrl == NULL))
return ENC_NULL_ARGUMENT;
/* Check for existing instance */
if (pInternalEncCont != pEncCont)
return ENC_INSTANCE_ERROR;
rc = &pEncCont->inst.rateControl;
pRateCtrl->vopRc = rc->vopRc;
pRateCtrl->mbRc = rc->mbRc;
pRateCtrl->vopSkip = rc->vopSkip;
pRateCtrl->qpHdr = rc->qpHdr;
pRateCtrl->qpHdrMin = rc->qpHdrMin;
pRateCtrl->qpHdrMax = rc->qpHdrMax;
pRateCtrl->bitPerSecond = rc->virtualBuffer.bitPerSecond;
pRateCtrl->cir = rc->cir.cir;
/* Return the video buffer size in units of 16384 bits */
pRateCtrl->vbv = rc->videoBuffer.videoBufferSize / 16384;
return ENC_OK;
}
/*******************************************************************************
Function name : MP4EncSetUsrData
Description :
Return type : MP4EncRet
Argument : MP4EncInst inst
Argument : u8 * pBuf
Argument : u32 length
Argument : MP4EncUsrDataType type
*******************************************************************************/
MP4EncRet MP4EncSetUsrData(MP4EncInst inst, const u8 * pBuf, u32 length,
MP4EncUsrDataType type)
{
EncContainer_t *pEncCont = (EncContainer_t *) inst;
bool_e stat;
/* Check for illegal inputs */
if ((inst == NULL) || (pBuf == NULL))
return ENC_NULL_ARGUMENT;
/* Check for existing instance */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -