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

📄 encasic.c

📁 freescale i.mx31 BSP CE5.0全部源码
💻 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-2005 HANTRO PRODUCTS OY               --
--                            ALL RIGHTS RESERVED                             --
--                                                                            --
--          The entire notice above must be reproduced on all copies.         --
--                                                                            --
--------------------------------------------------------------------------------
--
--  Abstract : ASIC handling routines
--
-------------------------------------------------------------------------------*/

#include "encasic.h"
#include "ewl.h"
#include "encregdrv.h"
#include "encinternal.h"


/* Defines for adding "padding" at the beginning and end of each allocated
 * buffer. The padding area is written with constant values which allows
 * us to see if ASIC writes outside it's allocated area. */
#ifdef SET_PADDING
#define PADDING_WORDS       4       /* Amount of words for padding */
#else
#define PADDING_WORDS       0
#endif

#define PADDING_VALUE   0xABCDABCD  /* Constant value of each padding word */


/*------------------------------------------------------------------------------

    Allocate ASIC memories and initialize the structure

------------------------------------------------------------------------------*/
i32 EncAsicMemAlloc(EncContainer_t * pEncCont)
{
    u32 size;

    ASSERT(pEncCont != NULL);

    /* Clear pointers */
    pEncCont->asic.pLumRefImg    = NULL;
    pEncCont->asic.pChromRefImg1 = NULL;
    pEncCont->asic.pChromRefImg2 = NULL;
    pEncCont->asic.pVpSizeBuf    = NULL;
    pEncCont->asic.pMbBuf2       = NULL;
    pEncCont->asic.pDctBuf3      = NULL;

    /* Init asic structure with default values */
    pEncCont->asic.imgEndianess  = MP4ENC_INPUT_ENDIAN;
    pEncCont->asic.strmEndianess = MP4ENC_STREAM_ENDIAN;


    size = pEncCont->asic.width_mb * pEncCont->asic.height_mb;

    /* these are the internal reference image buffers */
    pEncCont->asic.pLumRefImg = (u32 *) EWL_MallocLinear(size * 4 * 64 +
            PADDING_WORDS*4*2);
    pEncCont->asic.pChromRefImg1 = (u32 *) EWL_MallocLinear(size * 2 * 64 +
            PADDING_WORDS*4*2);
    pEncCont->asic.pChromRefImg2 = (u32 *) EWL_MallocLinear(size * 2 * 64 +
            PADDING_WORDS*4*2);

    if((pEncCont->asic.pLumRefImg == NULL) ||
       (pEncCont->asic.pChromRefImg1 == NULL) ||
       (pEncCont->asic.pChromRefImg1 == NULL))
    {
        EncAsicMemFree(pEncCont);
        return -1;
    }

    pEncCont->asic.pLumRefImg    += PADDING_WORDS;
    pEncCont->asic.pChromRefImg1 += PADDING_WORDS;
    pEncCont->asic.pChromRefImg2 += PADDING_WORDS;

    /* Allocate memory for VP/GOB sizes */ 
    pEncCont->asic.pVpSizeBuf = (u32 *) EWL_MallocLinear(
            (MP4ENC_MAX_VP_NUMBER + 1) * 4 + PADDING_WORDS*4*2);

    if((pEncCont->asic.pVpSizeBuf == NULL))
    {
        EncAsicMemFree(pEncCont);
        return -1;
    }

    pEncCont->asic.pVpSizeBuf += PADDING_WORDS;

    /* this is needed just for data partitioned streams */
    if(pEncCont->inst.videoObjectLayer.dataPart == YES)
    {
        /* set the extra DP mode buffers' sizes */
        pEncCont->asic.MbBuf2Size = MP4ENC_MB_BUF_2_SIZE * size / 8;

        pEncCont->asic.DctBuf3Size = MP4ENC_DCT_BUF_3_SIZE_VP;

        pEncCont->asic.pMbBuf2 =
            (u32 *) EWL_MallocLinear(pEncCont->asic.MbBuf2Size + 
                                     PADDING_WORDS*4*2);
        pEncCont->asic.pDctBuf3 =
            (u32 *) EWL_MallocLinear(pEncCont->asic.DctBuf3Size +
                                     PADDING_WORDS*4*2);
        if((pEncCont->asic.pMbBuf2 == NULL) ||
           (pEncCont->asic.pDctBuf3 == NULL))
        {
            EncAsicMemFree(pEncCont);
            return -1;
        }

        pEncCont->asic.pMbBuf2 += PADDING_WORDS;
        pEncCont->asic.pDctBuf3 += PADDING_WORDS;
    }
    return 0;
}

/*------------------------------------------------------------------------------

    Free ASIC memories

------------------------------------------------------------------------------*/
void EncAsicMemFree(EncContainer_t * pEncCont)
{
    ASSERT(pEncCont != NULL);

    if (pEncCont->asic.pLumRefImg != NULL)
        EWL_FreeLinear(pEncCont->asic.pLumRefImg - PADDING_WORDS);
    pEncCont->asic.pLumRefImg = NULL;
    if (pEncCont->asic.pChromRefImg1 != NULL)
        EWL_FreeLinear(pEncCont->asic.pChromRefImg1 - PADDING_WORDS);
    pEncCont->asic.pChromRefImg1 = NULL;
    if (pEncCont->asic.pChromRefImg2 != NULL)
        EWL_FreeLinear(pEncCont->asic.pChromRefImg2 - PADDING_WORDS);
    pEncCont->asic.pChromRefImg2 = NULL;

    if (pEncCont->asic.pVpSizeBuf != NULL)
        EWL_FreeLinear(pEncCont->asic.pVpSizeBuf - PADDING_WORDS);
    pEncCont->asic.pVpSizeBuf = NULL;

    if (pEncCont->asic.pMbBuf2 != NULL)
        EWL_FreeLinear(pEncCont->asic.pMbBuf2 - PADDING_WORDS);
    pEncCont->asic.pMbBuf2 = NULL;
    if (pEncCont->asic.pDctBuf3 != NULL)
        EWL_FreeLinear(pEncCont->asic.pDctBuf3 - PADDING_WORDS);
    pEncCont->asic.pDctBuf3 = NULL;
}

/*------------------------------------------------------------------------------
    
    Write constant value at all padding words

------------------------------------------------------------------------------*/
void EncAsicSetPadding(EncContainer_t * pEncCont)
{
    i32 i, size, tmp;

    size = pEncCont->asic.width_mb * pEncCont->asic.height_mb;

    tmp = (MP4ENC_MAX_VP_NUMBER + 1) * 4;

    for (i = 0; i < PADDING_WORDS; ++i)
    {
        /* Padding at beginning of each buffer */
        pEncCont->asic.pLumRefImg   [-1-i] =
        pEncCont->asic.pChromRefImg1[-1-i] =
        pEncCont->asic.pChromRefImg2[-1-i] =
        pEncCont->asic.pVpSizeBuf   [-1-i] = PADDING_VALUE;

        if(pEncCont->inst.videoObjectLayer.dataPart == YES)
            pEncCont->asic.pMbBuf2      [-1-i] =
            pEncCont->asic.pDctBuf3     [-1-i] = PADDING_VALUE;

        /* Padding at the end of each buffer */
        pEncCont->asic.pLumRefImg   [size*4*64/4 + i] =
        pEncCont->asic.pChromRefImg1[size*2*64/4 + i] =
        pEncCont->asic.pChromRefImg2[size*2*64/4 + i] =
        pEncCont->asic.pVpSizeBuf   [tmp/4 + i] = PADDING_VALUE;

        if(pEncCont->inst.videoObjectLayer.dataPart == YES)
            pEncCont->asic.pMbBuf2      [pEncCont->asic.MbBuf2Size/4  + i] =
            pEncCont->asic.pDctBuf3     [pEncCont->asic.DctBuf3Size/4 + i] =
                PADDING_VALUE;
    }
}

/*------------------------------------------------------------------------------
    
    Check padding words for constant value

------------------------------------------------------------------------------*/
i32 EncAsicCheckPadding(EncContainer_t *pEncCont)
{
    i32 i, size, tmp;

    size = pEncCont->asic.width_mb * pEncCont->asic.height_mb;

    tmp = (MP4ENC_MAX_VP_NUMBER + 1) * 4;

    for (i = 0; i < PADDING_WORDS; ++i)
    {
        /* Padding at beginning of each buffer */
        if (pEncCont->asic.pLumRefImg   [-1-i] != PADDING_VALUE)
            return -1;
        if (pEncCont->asic.pChromRefImg1[-1-i] != PADDING_VALUE)
            return -2;
        if (pEncCont->asic.pChromRefImg2[-1-i] != PADDING_VALUE)
            return -3;
        if (pEncCont->asic.pVpSizeBuf   [-1-i] != PADDING_VALUE)
            return -4;
        if (pEncCont->inst.videoObjectLayer.dataPart == YES &&
            pEncCont->asic.pMbBuf2      [-1-i] != PADDING_VALUE)
            return -5;
        if (pEncCont->inst.videoObjectLayer.dataPart == YES &&
            pEncCont->asic.pDctBuf3     [-1-i] != PADDING_VALUE)
            return -6;

        /* Padding at the end of each buffer */
        if (pEncCont->asic.pLumRefImg   [size*4*64/4 + i] != PADDING_VALUE)
            return 1;
        if (pEncCont->asic.pChromRefImg1[size*2*64/4 + i] != PADDING_VALUE)
            return 2;
        if (pEncCont->asic.pChromRefImg2[size*2*64/4 + i] != PADDING_VALUE)
            return 3;
        if (pEncCont->asic.pVpSizeBuf   [tmp/4 + i] != PADDING_VALUE)
            return 4;
        if (pEncCont->inst.videoObjectLayer.dataPart == YES &&
            pEncCont->asic.pMbBuf2      [pEncCont->asic.MbBuf2Size/4  + i] !=
                PADDING_VALUE)
            return 5;
        if (pEncCont->inst.videoObjectLayer.dataPart == YES &&
            pEncCont->asic.pDctBuf3     [pEncCont->asic.DctBuf3Size/4 + i] !=
                PADDING_VALUE)
            return 6;

    }
    return 0;
}


/*------------------------------------------------------------------------------
    
    Setup ASIC with general parameters that don't change between VOP

------------------------------------------------------------------------------*/
void EncAsicSetup(EncContainer_t * pEncCont)
{
    instance_s *pInst;


    ASSERT(pEncCont != NULL);

    pInst = &pEncCont->inst;

    /* Initialize internal chroma buffer */
    pEncCont->asic.chromaRef = 0;

    /* Set internal buffer addresses to ASIC, 
     * these addresses don't change between VOPs */

    SetEncRefLumBase(EWL_Virt2Bus(pEncCont->asic.pLumRefImg));

    SetEncVpSizeBase(EWL_Virt2Bus(pEncCont->asic.pVpSizeBuf));

    if(pEncCont->inst.videoObjectLayer.dataPart == YES)
    {
        /* DCT buffer limit in 32 bit units (= 4 bytes) */
        SetEncStrmBuf3Lim((pEncCont->asic.DctBuf3Size - MP4ENC_BUF_3_LIMIT)/4);

        SetEncStrmBuf2Base(EWL_Virt2Bus(pEncCont->asic.pMbBuf2));

        SetEncStrmBuf3Base(EWL_Virt2Bus(pEncCont->asic.pDctBuf3));
    }

    /* Setup all the general coding parameters */

    SetEncIntraDcVlcThr(pInst->videoObjectPlane.intraDcVlcThr);

    if(pInst->shortVideoHeader.header == NO)
    {
        SetEncSVHEnable(0);
    }
    else
    {
        SetEncSVHEnable(1);
    
        if (pEncCont->asic.height_mb <= 25) /* height in macroblocks */
            SetEncGobRows(0);
        else
            SetEncGobRows(1);

        SetEncGobMask(pEncCont->inst.shortVideoHeader.gobPlace);
    }

    SetEncOutsideVopMvEnable(pEncCont->asic.outsideVopMv);

    if(pInst->videoObjectPlane.acPred == NO)
        SetEncAcPredEnable(0);
    else
        SetEncAcPredEnable(1);

    if(pInst->videoObjectLayer.dataPart == NO)
    {
        SetEncDataPEnable(0);
        SetEncRvlcEnable(0);
    }
    else
    {
        SetEncDataPEnable(1);

        if(pInst->videoObjectLayer.rvlc == NO)
            SetEncRvlcEnable(0);
        else
            SetEncRvlcEnable(1);
    }

    SetEncStrmEndianMode(pEncCont->asic.strmEndianess);
    SetEncImgEndianMode(pEncCont->asic.imgEndianess);

    SetEncXFill((pEncCont->asic.width_mb * 16 -
                 pInst->videoObjectLayer.videoObjectLayerWidth + 3) / 4);
    SetEncYFill(pEncCont->asic.height_mb * 16 -
                pInst->videoObjectLayer.videoObjectLayerHeight);

    SetEncMvSadPenalty(pEncCont->asic.mvSadPenalty);
    SetEnc4MvSadPenalty(pEncCont->asic.fourMvSadPenalty);
    SetEncIntraSadPenalty(pEncCont->asic.intraSadPenalty);

    if(pInst->videoObjectLayer.resyncMarkerDisable == NO)
    {
        SetEncVpEnable(1);
        SetEncSizeOfVP(pInst->profile.vpSize);
    }
    else
        SetEncVpEnable(0);

    /* Encoded image's dimensions in macroblocks */
    SetEncMbsInCol(pEncCont->asic.height_mb);
    SetEncMbsInRow(pEncCont->asic.width_mb);

    /* Set IRQ */
    SetEncHWIrqEnable(MP4ENC_ERR_IRQ_ENABLE, MP4ENC_VOP_IRQ_ENABLE);

}

⌨️ 快捷键说明

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