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

📄 encinternalapi.c

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


#include "mp4encapi.h"
#include "enccontainer.h"
#include "encinternal.h"
#include "encregdrv.h"
#include "encmemory.h"
#include "ewl.h"

static void SetRcParameter(rateControl_s *rc);
static void GetRcParameter(rateControl_s *rc);
static void EndianSwap(u32 *buf, u32 wordCnt);

/*------------------------------------------------------------------------------
    
    Check the config structure for valid values.
    
    Return: 0   OK
            -1  Invalid value

------------------------------------------------------------------------------*/
i32 CheckInitCfg(const MP4EncCfg * pEncCfg)
{

    ASSERT(pEncCfg != NULL);

    if(pEncCfg->width < 6 * 16 ||
       pEncCfg->width > 40 * 16 || (pEncCfg->width / 4) * 4 != pEncCfg->width)
    {
        return -1;
    }

    if(pEncCfg->height < 6 * 16 || pEncCfg->height > (30 * 16))
    {
        return -1;
    }

    if(pEncCfg->frmRateNum == 0 || pEncCfg->frmRateNum >= (1 << 16))
    {
        return -1;
    }
    
    if(pEncCfg->frmRateDenom == 0)
    {
        return -1;
    }

    /* Check that stream type is valid */
    if(pEncCfg->strmType > H263_STRM)
    {
        return -1;
    }

    /* Check that profile and level is valid for MPEG4 stream */
    if((pEncCfg->strmType < H263_STRM) &&
       (pEncCfg->profileAndLevel != MPEG4_SIMPLE_PROFILE_LEVEL_0) &&
       (pEncCfg->profileAndLevel != MPEG4_SIMPLE_PROFILE_LEVEL_0B) &&
       (pEncCfg->profileAndLevel != MPEG4_SIMPLE_PROFILE_LEVEL_1) &&
       (pEncCfg->profileAndLevel != MPEG4_SIMPLE_PROFILE_LEVEL_2) &&
       (pEncCfg->profileAndLevel != MPEG4_SIMPLE_PROFILE_LEVEL_3) &&
       (pEncCfg->profileAndLevel != 50) &&  /* Main profile levels 2 - 4 */
       (pEncCfg->profileAndLevel != 51) &&
       (pEncCfg->profileAndLevel != 52) &&
       (pEncCfg->profileAndLevel != MPEG4_ADV_SIMPLE_PROFILE_LEVEL_3) &&
       (pEncCfg->profileAndLevel != MPEG4_ADV_SIMPLE_PROFILE_LEVEL_4) &&
       (pEncCfg->profileAndLevel != MPEG4_ADV_SIMPLE_PROFILE_LEVEL_5))
    {
        return -1;
    }

    /* Check that profile and level is valid for H263 stream */
    if((pEncCfg->strmType == H263_STRM) &&
       (pEncCfg->profileAndLevel != H263_PROFILE_0_LEVEL_10) &&
       (pEncCfg->profileAndLevel != H263_PROFILE_0_LEVEL_20) &&
       (pEncCfg->profileAndLevel != H263_PROFILE_0_LEVEL_30) &&
       (pEncCfg->profileAndLevel != H263_PROFILE_0_LEVEL_40) &&
       (pEncCfg->profileAndLevel != H263_PROFILE_0_LEVEL_50) &&
       (pEncCfg->profileAndLevel != H263_PROFILE_0_LEVEL_60) &&
       (pEncCfg->profileAndLevel != H263_PROFILE_0_LEVEL_70))
    {
        return -1;
    }

    return 0;
}


/*------------------------------------------------------------------------------
    
    Set ASIC parameters

        Depending on encoding status do:
        - start a new VOP
        - continue previous VOP with new buffer

------------------------------------------------------------------------------*/
MP4EncRet SetVopParameters(EncContainer_t * pEncCont, 
        MP4EncIn * pEncIn, MP4EncOut * pEncOut)
{
    u32 vopType;
    stream_s stream;
    preProcess_s *preProcess;
    rateControl_s *rc;
    vop_s *vop;
    timeCode_s *timeCode;
    svh_s *svh;
    i32 tmp;
    u32 offset;

    preProcess = &pEncCont->inst.preProcess;
    rc = &pEncCont->inst.rateControl;
    vop = &pEncCont->inst.videoObjectPlane;
    timeCode = &pEncCont->inst.timeCode;
    svh = &pEncCont->inst.shortVideoHeader;

    ASSERT(pEncCont);
    ASSERT(pEncIn);
    ASSERT(pEncOut);

    vopType = pEncIn->vopType;

    /* Setup ASIC depending on encoding status */
    switch (pEncCont->encStatus)
    {
    case ENCSTAT_STRM_START:
    case ENCSTAT_GOV_INSERTED:
    case ENCSTAT_NEW_REF_IMG:
        vopType = INTRA_VOP;
        /* Fall through */

    case ENCSTAT_START_VOP:
        /* Starting a new VOP:
         *  - handle GOV header
         *  - update timecodes
         *  - perform rate control
         *  - write VOP headers
         *  - camera stabilization
         *  - set all encoding parameters to registers */

        pEncCont->vopBytes = 0;

        EncSetBuffer(&stream, (u8 *) pEncIn->pOutBuf, pEncIn->outBufSize);

        if (pEncCont->inst.groupOfVideoObjectPlane.header == YES)
        {
            /* Write GOV header and return */
            EncGoVopHdr(&stream, &pEncCont->inst.groupOfVideoObjectPlane);

            if (stream.overflow != 0)
            {
                pEncOut->strmSize = 0;
                pEncOut->vopType = NOTCODED_VOP;
                return ENC_OUTPUT_BUFFER_OVERFLOW;
            }

            /* Insert just once */
            pEncCont->inst.groupOfVideoObjectPlane.header = NO;
            pEncOut->strmSize = stream.byteCnt;
            pEncOut->vopType = NOTCODED_VOP;
            GetTimeCode(timeCode, pEncOut);

            pEncCont->encStatus = ENCSTAT_GOV_INSERTED;
            return ENC_GOV_READY;

        }

        /* Vop time increment */
        EncTimeIncrement(timeCode, pEncIn->timeIncr);

        /* Store previous timecode, it is needed if this VOP is discarded */
        EncCopyTimeCode(&pEncCont->timeCodePrev, timeCode);

        /* VOP type, user define */
        rc->vopTypeCur = (vopType_e)vopType;
        EncBeforeVopRc(rc, timeCode->timeInc);

        if (rc->vopCoded != YES) 
        {
            /* Rate control decided to skip this VOP */
            pEncOut->strmSize = stream.byteCnt;
            pEncOut->vopType = NOTCODED_VOP;
            GetTimeCode(timeCode, pEncOut);
            pEncCont->encStatus = ENCSTAT_START_VOP;
            return ENC_VOP_READY;
        }

        /* Final time code */
        EncTimeCode(timeCode, &pEncCont->inst.groupOfVideoObjectPlane);

        /* ASIC rate control parameters before VOP */
        SetRcParameter(rc);
        SetEncQP(rc->qpHdr);

        /* Round control */
        vop->roundControl ^= 1;
        if ((svh->header == YES) && (svh->plusHeader == NO)) 
            vop->roundControl = 0;
        svh->roundControl = vop->roundControl;
        ASSERT(vop->roundControl <= 1);
        SetEncRoundingCtrl(vop->roundControl);

        /* Write VOP header depending on stream type */
        if (svh->header == YES) 
        {
            svh->tempRef = timeCode->tempRef;
            svh->vopType = rc->vopTypeCur;
            EncSvhHdr(&stream, svh, rc->qpHdr);
            SetEncGobFrmId(EncGobFrameId(&pEncCont->inst.shortVideoHeader));
        } 
        else 
        {
            vop->vopCoded = rc->vopCoded;
            vop->vopType = rc->vopTypeCur;
            vop->moduloTimeBase = timeCode->moduloTimeBase;
            vop->vopTimeInc = timeCode->vopTimeInc;
            EncVopHdr(&stream, vop, rc->qpHdr);
        }

        /* HEC */
        if (vop->hec == YES) 
        {
            tmp = 0;
            SetEncHecEnable(1);
            SetEncModTimeBase(vop->moduloTimeBase);
            while ((1 << ++tmp) < vop->vopTimeIncRes) ;
            SetEncVopTimeIncr(vop->vopTimeInc << (16 - tmp));
            if (tmp == 16)
                tmp = 0;
            SetEncVopTimeIncrBits(tmp);
        } 
        else
            SetEncHecEnable(0);

        /* Clear the ASIC output VP table */
        pEncCont->asic.pVpSizeBuf[0] = 0;

        /* setup the internal image buffers */

        pEncCont->asic.chromaRef ^= 1;  /* swap the chroma buffers */

        /* Chrominance reference base must point to [offset] bytes before 
         * start of image data */
        offset = (pEncCont->asic.width_mb * 16 + 2) * 4;

        if (pEncCont->asic.chromaRef == 0)
        {
            SetEncRefChromaBase(EWL_Virt2Bus(pEncCont->asic.pChromRefImg1) -
                                offset);
            SetEncInternalChromaBase(EWL_Virt2Bus
                                     (pEncCont->asic.pChromRefImg2));
        }
        else
        {
            SetEncRefChromaBase(EWL_Virt2Bus(pEncCont->asic.pChromRefImg2) -
                                offset);
            SetEncInternalChromaBase(EWL_Virt2Bus
                                     (pEncCont->asic.pChromRefImg1));
        }

        /* Setup the new image */
        preProcess->busAddrLumaY = pEncIn->busLuma;

        /* Chrominance input */
        if (pEncIn->busChromaU != 0 && pEncIn->busChromaV != 0)
        {
            preProcess->busAddrChromaU = pEncIn->busChromaU;
            preProcess->busAddrChromaV = pEncIn->busChromaV;
        }
        else
        {
            preProcess->busAddrChromaU = preProcess->busAddrLumaY + 
                preProcess->lumWidthSrc * preProcess->lumHeightSrc;
            preProcess->busAddrChromaV = preProcess->busAddrChromaU + 
                preProcess->chWidthSrc * (preProcess->lumHeightSrc/2);
        }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -