⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 encinternalapi.c

📁 freescale i.mx31 BSP CE5.0全部源码
💻 C
📖 第 1 页 / 共 2 页
字号:
        
        /* 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 + -