📄 encasic.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 + -