📄 encinternalapi.c
字号:
/* Update input image addresses with camera stabilization */
EncPreProcess(preProcess);
SetEncNewLumaBase(preProcess->busAddrLumaY);
SetEncNewChromaUBase(preProcess->busAddrChromaU);
SetEncNewChromaVBase(preProcess->busAddrChromaV);
SetEncOrigRowWidth((preProcess->lumWidthSrc) / 8);
/* Offset in bytes to the last word of VOP header */
offset = (stream.bitCnt / 32) * 4;
/* ASIC stream buffer base is at the last word of VOP header */
SetEncStrmBuf1Base(pEncIn->outBufBusAddress + offset);
/* Stream buffer limit for ASIC in 32-bit units */
SetEncStrmBuf1Lim((pEncIn->outBufSize - offset - MP4ENC_BUF_LIMIT)/4);
SetEncVopHdrLenght(stream.bitCnt);
/* Vop header remainder must be big endian => arrange it so */
{
/* u8 ptr uses system endianess by nature */
u8 *ptr = (u8 *)pEncIn->pOutBuf + offset;
u32 tmp = 0;
tmp |= ptr[0] << 24;
tmp |= ptr[1] << 16;
tmp |= ptr[2] << 8;
tmp |= ptr[3];
SetEncVopHdrLastBits(tmp);
}
/* Header is created in system endianess, check if it needs
* to be swapped to stream endianess */
if (MP4ENC_SYSTEM_ENDIAN != MP4ENC_STREAM_ENDIAN)
EndianSwap(pEncIn->pOutBuf, stream.bitCnt / 32);
/* Set VOP type */
if (rc->vopTypeCur == IVOP)
SetEncVopType(2);
else if(pEncCont->asic.fourMV == 0)
SetEncVopType(0);
else
SetEncVopType(1);
break;
default:
return ENC_INVALID_STATUS;
}
/* Everything is ready to enable ASIC */
return ENC_OK;
}
/*------------------------------------------------------------------------------
Get ASIC status after it has finished.
------------------------------------------------------------------------------*/
MP4EncRet GetVopStatus(EncContainer_t * pEncCont,
MP4EncIn * pEncIn, MP4EncOut * pEncOut)
{
u32 irqStat;
rateControl_s *rc;
timeCode_s *timeCode;
ASSERT(pEncCont);
ASSERT(pEncIn);
ASSERT(pEncOut);
rc = &pEncCont->inst.rateControl;
timeCode = &pEncCont->inst.timeCode;
/* Get the current time code */
GetTimeCode(timeCode, pEncOut);
irqStat = GetEncIrqStat();
if (irqStat & IRQ_ERROR_RESPONSE)
{ /* Bus error */
SetEncEnable(0);
pEncCont->encStatus = ENCSTAT_NEW_REF_IMG;
return ENC_HW_ERROR;
}
/* Set output and status depending on IRQ */
switch (irqStat)
{
case IRQ_VLC_BUF_OVERFLOW:
/* VLC buffer overflow, ASIC stopped -> VOP lost */
SetEncIrqStatClr(IRQ_VLC_BUF_OVERFLOW);
pEncCont->encStatus = ENCSTAT_NEW_REF_IMG;
return ENC_OUTPUT_BUFFER_OVERFLOW;
case IRQ_VOP_RDY:
/* VOP ready */
SetEncIrqStatClr(IRQ_VOP_RDY);
pEncCont->encStatus = ENCSTAT_START_VOP;
EncStabilization(&pEncCont->inst.preProcess); /* update CS */
GetStrmSizeData(pEncCont, pEncOut, pEncIn);
pEncOut->vopType = rc->vopTypeCur;
/* Rate control action after vop */
pEncCont->vopBytes += pEncOut->strmSize;
GetRcParameter(rc);
EncAfterVopRc(rc, GetEncZeroCount()*8, pEncCont->vopBytes);
/* After vbv underflow go back old time, just like not coded vop */
if (rc->videoBuffer.underflow == YES) {
pEncCont->encStatus = ENCSTAT_NEW_REF_IMG;
EncCopyTimeCode(timeCode, &pEncCont->timeCodePrev);
if (pEncIn->pVpSizes != NULL)
pEncIn->pVpSizes[0] = 0;
pEncOut->strmSize = 0;
pEncOut->vopType = NOTCODED_VOP;
return ENC_VOP_READY;
}
/* After vbv overflow you just can't do nothing */
if (rc->videoBuffer.overflow == YES) {
return ENC_VOP_READY_VBV_FAIL;
}
return ENC_VOP_READY;
default:
/* something bad happened to the IRQ status */
SetEncEnable(0);
pEncCont->encStatus = ENCSTAT_NEW_REF_IMG;
return ENC_HW_ERROR;
}
}
/*------------------------------------------------------------------------------
Get the stream size and video packet size values from container
and store them in output and input structures.
------------------------------------------------------------------------------*/
void GetStrmSizeData(EncContainer_t * pEncCont, MP4EncOut * pEncOut,
MP4EncIn *pEncIn)
{
volatile u32 * pVpSizeBuf = pEncCont->asic.pVpSizeBuf;
i32 vp = GetEncVpNr();
u32 strmSize;
/* The last 32-bit address written by ASIC is stored in
* stream buffer base register. Two LSB define how many bytes
* in the 32-bit word is written. If LSB = '00' the whole
* word is written, thus the size must be incremented with 4. */
strmSize = GetEncStrmBuf1Base();
if ((strmSize & 0x3) == 0)
strmSize += 4;
strmSize -= pEncIn->outBufBusAddress;
pEncOut->strmSize = strmSize;
/* Copy VP size table to API output, table ends with zero value
* Only for VP/GOB streams */
if ((pEncIn->pVpSizes != NULL) &&
(pEncCont->inst.videoObjectLayer.resyncMarkerDisable == NO ||
pEncCont->inst.shortVideoHeader.gobPlace != 0))
{
i32 i = 0;
pEncIn->pVpSizes[i] = (i32) pVpSizeBuf[i];
i++;
while (i < vp)
{
pEncIn->pVpSizes[i] = (i32) pVpSizeBuf[i] - pVpSizeBuf[i-1];
i++;
}
pEncIn->pVpSizes[i] = 0;
}
}
/*------------------------------------------------------------------------------
Get the time code of the previously encoded VOP and store it in
output structure.
------------------------------------------------------------------------------*/
void GetTimeCode(const timeCode_s * timeCode, MP4EncOut * pEncOut)
{
pEncOut->timeCode.hours = timeCode->timeCodeHours;
pEncOut->timeCode.minutes = timeCode->timeCodeMinutes;
pEncOut->timeCode.seconds = timeCode->timeCodeSecond;
pEncOut->timeCode.timeIncr = timeCode->vopTimeInc;
pEncOut->timeCode.timeRes = timeCode->vopTimeIncRes;
}
/*------------------------------------------------------------------------------
Set ASIC rate control parameters before VOP
------------------------------------------------------------------------------*/
void SetRcParameter(rateControl_s *rc)
{
/* ASIC uses seed+1 and period-1 */
SetEncCirStart(rc->cir.seed+1);
SetEncCirStep(rc->cir.period-1);
SetEncQP(rc->qpHdr);
SetEncStuffingLim(rc->videoBuffer.stuffWordCnt);
SetEncChkP1MbNr(rc->qpCtrl.checkPoint[0]);
SetEncChkP2MbNr(rc->qpCtrl.checkPoint[1]);
SetEncChkP3MbNr(rc->qpCtrl.checkPoint[2]);
SetEncChkP4MbNr(rc->qpCtrl.checkPoint[3]);
SetEncChkP5MbNr(rc->qpCtrl.checkPoint[4]);
SetEncChkP6MbNr(rc->qpCtrl.checkPoint[5]);
SetEncChkP7MbNr(rc->qpCtrl.checkPoint[6]);
SetEncChkP8MbNr(rc->qpCtrl.checkPoint[7]);
SetEncChkP9MbNr(rc->qpCtrl.checkPoint[8]);
SetEncChkP10MbNr(rc->qpCtrl.checkPoint[9]);
SetEncChkP1Bits(rc->qpCtrl.wordCntTarget[0]);
SetEncChkP2Bits(rc->qpCtrl.wordCntTarget[1]);
SetEncChkP3Bits(rc->qpCtrl.wordCntTarget[2]);
SetEncChkP4Bits(rc->qpCtrl.wordCntTarget[3]);
SetEncChkP5Bits(rc->qpCtrl.wordCntTarget[4]);
SetEncChkP6Bits(rc->qpCtrl.wordCntTarget[5]);
SetEncChkP7Bits(rc->qpCtrl.wordCntTarget[6]);
SetEncChkP8Bits(rc->qpCtrl.wordCntTarget[7]);
SetEncChkP9Bits(rc->qpCtrl.wordCntTarget[8]);
SetEncChkP10Bits(rc->qpCtrl.wordCntTarget[9]);
SetEncBitError1(rc->qpCtrl.wordError[0]);
SetEncBitError2(rc->qpCtrl.wordError[1]);
SetEncBitError3(rc->qpCtrl.wordError[2]);
SetEncBitError4(rc->qpCtrl.wordError[3]);
SetEncBitError5(rc->qpCtrl.wordError[4]);
SetEncBitError6(rc->qpCtrl.wordError[5]);
SetEncDeltaQp1(rc->qpCtrl.qpChange[0]);
SetEncDeltaQp2(rc->qpCtrl.qpChange[1]);
SetEncDeltaQp3(rc->qpCtrl.qpChange[2]);
SetEncDeltaQp4(rc->qpCtrl.qpChange[3]);
SetEncDeltaQp5(rc->qpCtrl.qpChange[4]);
SetEncDeltaQp6(rc->qpCtrl.qpChange[5]);
SetEncDeltaQp7(rc->qpCtrl.qpChange[6]);
}
/*------------------------------------------------------------------------------
Get ASIC rate control parameters after VOP
------------------------------------------------------------------------------*/
void GetRcParameter(rateControl_s *rc)
{
rc->qpSum = GetEncQpSum();
rc->qpCtrl.wordCntPrev[0] = GetEncChkP1Bits();
rc->qpCtrl.wordCntPrev[1] = GetEncChkP2Bits();
rc->qpCtrl.wordCntPrev[2] = GetEncChkP3Bits();
rc->qpCtrl.wordCntPrev[3] = GetEncChkP4Bits();
rc->qpCtrl.wordCntPrev[4] = GetEncChkP5Bits();
rc->qpCtrl.wordCntPrev[5] = GetEncChkP6Bits();
rc->qpCtrl.wordCntPrev[6] = GetEncChkP7Bits();
rc->qpCtrl.wordCntPrev[7] = GetEncChkP8Bits();
rc->qpCtrl.wordCntPrev[8] = GetEncChkP9Bits();
rc->qpCtrl.wordCntPrev[9] = GetEncChkP10Bits();
}
/*------------------------------------------------------------------------------
Swap endianess of buffer
wordCnt is the amount of 32-bit words that are swapped
------------------------------------------------------------------------------*/
void EndianSwap(u32 *buf, u32 wordCnt)
{
u32 i = 0;
while (wordCnt != 0)
{
u32 val = buf[i];
u32 tmp = 0;
tmp |= (val & 0xFF) << 24;
tmp |= (val & 0xFF00) << 8;
tmp |= (val & 0xFF0000) >> 8;
tmp |= (val & 0xFF000000) >> 24;
buf[i] = tmp;
i++;
wordCnt--;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -