📄 motioncompute.c
字号:
}
}
void GetMBCodeType(MvSearchData* pData,
MacroBlock * pCurMB,
int x, int y,
short iMBWidth,
short coding_type,
int skip_sad)
{
int mode = MB_INTER;
int inter4v = 1;
const unsigned int iQuant = pCurMB->quant;
const int IsSkip = (coding_type == P_VOP);
int sad;
int InterBias = MBlockInterBias;
if (inter4v == 0 || pData->iMinSad[0] < pData->iMinSad[1] + pData->iMinSad[2] +
pData->iMinSad[3] + pData->iMinSad[4] + IMV * (int)iQuant)
{
mode = MB_INTER;
sad = pData->iMinSad[0];
}
else
{
mode = MB_INTER_4V;
sad = pData->iMinSad[1] + pData->iMinSad[2] +
pData->iMinSad[3] + pData->iMinSad[4] + IMV * (int)iQuant;
pData->iMinSad[0] = sad;
}
if (IsSkip && (skip_sad < (int)iQuant * SadSkip))
{
if ( (100*skip_sad)/(pCurMB->LumMBlockSad+1) > SkipThresh2)
{
mode = MB_SKIP;
sad = 0;
}
}
if (iQuant > 10)
{
InterBias += 60 * (iQuant - 10);
}
if (y != 0)
{
if ((pCurMB - iMBWidth)->mb_type == MB_INTRA)
{
InterBias -= 80;
}
}
if (x != 0)
{
if ((pCurMB - 1)->mb_type == MB_INTRA)
{
InterBias -= 80;
}
}
InterBias += 50;
if (InterBias < sad)
{
int deviation = DevMBlockChro(pData->CurY, pData->iExtWidth);
if (deviation < (sad - InterBias))
{
mode = MB_INTRA;
}
}
pCurMB->cbp = 63;
pCurMB->LumMBlockSad = pCurMB->LumBlockSad[0] = pCurMB->LumBlockSad[1] = pCurMB->LumBlockSad[2] = pCurMB->LumBlockSad[3] = sad;
if (mode == MB_INTER)
{
pCurMB->Mv[0] = pCurMB->Mv[1] = pCurMB->Mv[2] = pCurMB->Mv[3] = pData->CurrentMv[0];
pCurMB->PredMv[0].x = pData->CurrentMv[0].x - pData->PredMV.x;
pCurMB->PredMv[0].y = pData->CurrentMv[0].y - pData->PredMV.y;
}
else if (mode == MB_INTER_4V)
{
}
else
{
SetPframeZeroMB(pCurMB, 0);
}
pCurMB->mb_type = mode;
}
static InitialData(Encoder* pEncoder, MvSearchData* pData)
{
int iSize;
short iExtWidth = pEncoder->pVol->iExtWidth;
short iExtHeight = pEncoder->pVol->iExtHeight;
iSize = iExtWidth * iExtHeight;
pData->rounding = pEncoder->pCurFrameInfo->vop_rounding_type;
pData->iExtWidth = pEncoder->pVol->iExtWidth;
pData->iFcode = pEncoder->pForFrameInfo->vop_fcode_forward;
pData->chromaSAD = 0;
pData->RefQuarl = malloc(sizeof(unsigned char)*iSize/4);
}
unsigned int getMinFcode(int MVmax)
{
unsigned int fcode;
for (fcode = 1; (16 << fcode) <= MVmax; fcode++);
return fcode;
}
//**************************************************************
//
//
//**************************************************************
void pFrameEncode8EDMA(Encoder* pEncoder,Stream* bs)
{
short x, y;
int iTempSad;
int iPosition;
unsigned char* pTemp = NULL;
int iPositionLum,iPositionChro;
short iWidth = pEncoder->pVol->video_object_layer_width;
short iHeight = pEncoder->pVol->video_object_layer_height;
int MVmax = 0, mvSum = 0, mvCount = 0;
Image8* pCurImage = pEncoder->pCurImage8;
Image8* pTempRefImage = pEncoder->pForImage8;
MacroBlock* pCurMB = NULL;
short iMBWidth = pEncoder->pCurFrameInfo->vop_width >> 4;
short iMBHeight = pEncoder->pCurFrameInfo->vop_height >> 4;
short iExtWidth = pEncoder->pCurFrameInfo->vop_extwidth;
short iExtHeight = pEncoder->pCurFrameInfo->vop_extheight;
short iExtWidthHalf=iExtWidth/2;
MvSearchData pData; //
//定义乒乓缓存***********************************
//当前帧的
Image8 BufferPingPong[6];
Image8 *CurrentFrameBufferPing=&BufferPingPong[0];
Image8 *CurrentFrameBufferPong=&BufferPingPong[1];
//前向帧
Image8 *RefFrameBufferPing=&BufferPingPong[2];
Image8 *RefFrameBufferPong=&BufferPingPong[3];
Image8 *CurRecFrameBufferPing=&BufferPingPong[4];
Image8 *CurRecFrameBufferPong=&BufferPingPong[5];
short iExtMBWidth=iMBWidth+4;
unsigned char DMACurrentFlag=0;
unsigned char DMARefFlag=0;
int transferIdY1,transferIdY2;
int transferIdYRec;
//***********************************************
memset(&pData, 0 , sizeof(MvSearchData));
InitialData(pEncoder, &pData);
pTemp = pData.RefQuarl;
pCurImage->Y = pEncoder->pCurImage8->Y;
pCurImage->Cb = pEncoder->pCurImage8->Cb;
pCurImage->Cr = pEncoder->pCurImage8->Cr;
pTempRefImage->Y = pEncoder->pForImage8->Y;
pTempRefImage->Cb = pEncoder->pForImage8->Cb;
pTempRefImage->Cr = pEncoder->pForImage8->Cr;
//为当前帧的乒乓缓冲分配内存
CurrentFrameBufferPing->Y=curentPingBuffer;
CurrentFrameBufferPing->Cb=curentPingBuffer+64*4*iExtMBWidth;
CurrentFrameBufferPing->Cr=curentPingBuffer+64*4*iExtMBWidth+64*iExtMBWidth;
CurrentFrameBufferPong->Y=curentPongBuffer;
CurrentFrameBufferPong->Cb=curentPongBuffer+64*4*iExtMBWidth;
CurrentFrameBufferPong->Cr=curentPongBuffer+64*4*iExtMBWidth+64*iExtMBWidth;
//为参考帧的乒乓缓冲分配内存
RefFrameBufferPing->Y=refPingBuffer;
RefFrameBufferPing->Cb=refPingBuffer+3*64*4*iExtMBWidth;
RefFrameBufferPing->Cr=refPingBuffer+3*64*4*iExtMBWidth+3*64*iExtMBWidth;
RefFrameBufferPong->Y=refPongBuffer;
RefFrameBufferPong->Cb=refPongBuffer+3*64*4*iExtMBWidth;
RefFrameBufferPong->Cr=refPongBuffer+3*64*4*iExtMBWidth+3*64*iExtMBWidth;
CurRecFrameBufferPing->Y=curentRecPingBuffer;
CurRecFrameBufferPing->Cb=curentRecPingBuffer+64*4*iExtMBWidth;
CurRecFrameBufferPing->Cr=curentRecPingBuffer+64*4*iExtMBWidth+64*iExtMBWidth;
CurRecFrameBufferPong->Y=curentRecPongBuffer;
CurRecFrameBufferPong->Cb=curentRecPongBuffer+64*4*iExtMBWidth;
CurRecFrameBufferPong->Cr=curentRecPongBuffer+64*4*iExtMBWidth+64*iExtMBWidth;
//*********************************************
//对参考图象进行扩边处理
SetImage8Edge(pTempRefImage, iExtWidth, iExtHeight, iWidth, iHeight);
iExtWidthHalf = iExtWidth/2;
//lvxu080326*********************************************
StreamPad(bs);
WriteMpeg4VopHeader(bs, pEncoder);
//*************************************************
// ComputBlockSad=ComputBlockSad1;
//将当前帧第一行拷贝到CurrentFrameBufferPong****************************
//先将第一行的宏块拷贝到乓缓冲中
//起始行的地址
iPositionLum = -IMAGE_EDGE;
iPositionChro =-IMAGE_EDGE_HALF;
DAT_copy(iPositionChro + pCurImage->Cb,CurrentFrameBufferPong->Cb,64*iExtMBWidth);
DAT_copy(iPositionChro + pCurImage->Cr,CurrentFrameBufferPong->Cr,64*iExtMBWidth);
transferIdY1=DAT_copy(iPositionLum + pCurImage->Y,CurrentFrameBufferPong->Y,4*64*iExtMBWidth);
DMACurrentFlag=1;
//将参考帧前三行拷贝到参考帧的乓缓冲中
iPositionLum = -IMAGE_EDGE-4*64*iExtMBWidth;
iPositionChro =-IMAGE_EDGE_HALF-64*iExtMBWidth;
DAT_copy(iPositionChro + pTempRefImage->Cb,RefFrameBufferPong->Cb,3*64*iExtMBWidth);
DAT_copy(iPositionChro + pTempRefImage->Cr,RefFrameBufferPong->Cr,3*64*iExtMBWidth);
transferIdY2=DAT_copy(iPositionLum + pTempRefImage->Y,RefFrameBufferPong->Y,3*4*64*iExtMBWidth);
DMARefFlag=1;
//**********************************************************************
//按行为单位进行编码
for (y = 0; y < iMBHeight; y++)
{
//交换乒乓缓冲的指针
DAT_wait(transferIdY1);
DAT_wait(transferIdY2);
SWAP(Image8*,CurrentFrameBufferPing, CurrentFrameBufferPong);
SWAP(Image8*,RefFrameBufferPing, RefFrameBufferPong);
//EDMA将图象的下一次编码的数据从外存搬移到内存
if(y<iMBHeight-1)
{
//当前帧的操作
//起始行的地址
iPositionLum = (y+1) * iExtWidth * 16-IMAGE_EDGE;
iPositionChro =(y+1) * iExtWidthHalf * 8-IMAGE_EDGE_HALF;
DAT_copy(iPositionChro + pCurImage->Cb,CurrentFrameBufferPong->Cb,64*iExtMBWidth);
DAT_copy(iPositionChro + pCurImage->Cr,CurrentFrameBufferPong->Cr,64*iExtMBWidth);
transferIdY1=DAT_copy(iPositionLum + pCurImage->Y,CurrentFrameBufferPong->Y,4*64*iExtMBWidth);
/* memcpy(CurrentFrameBufferPong->Y,iPositionLum + pEncoder->pCurImage8->Y,sizeof(unsigned char)*4*64*iExtMBWidth);
memcpy(CurrentFrameBufferPong->Cb,iPositionChro + pEncoder->pCurImage8->Cb,sizeof(unsigned char)*64*iExtMBWidth);
memcpy(CurrentFrameBufferPong->Cr,iPositionChro + pEncoder->pCurImage8->Cr,sizeof(unsigned char)*64*iExtMBWidth);
DMACurrentFlag=1;
*/
//参考帧的操作
iPositionLum = (y+1) * iExtWidth * 16-IMAGE_EDGE-4*64*iExtMBWidth;
iPositionChro =(y+1) * iExtWidthHalf * 8-IMAGE_EDGE_HALF-64*iExtMBWidth;
DAT_copy(iPositionChro + pTempRefImage->Cb,RefFrameBufferPong->Cb,3*64*iExtMBWidth);
DAT_copy(iPositionChro + pTempRefImage->Cr,RefFrameBufferPong->Cr,3*64*iExtMBWidth);
transferIdY2=DAT_copy(iPositionLum + pTempRefImage->Y,RefFrameBufferPong->Y,3*4*64*iExtMBWidth);
/* memcpy(RefFrameBufferPong->Y,iPositionLum + pTempRefImage->Y,sizeof(unsigned char)*3*4*64*iExtMBWidth);
memcpy(RefFrameBufferPong->Cb,iPositionChro + pTempRefImage->Cb,sizeof(unsigned char)*3*64*iExtMBWidth);
memcpy(RefFrameBufferPong->Cr,iPositionChro + pTempRefImage->Cr,sizeof(unsigned char)*3*64*iExtMBWidth);
DMARefFlag=1;
*/
}
//将图象指向当前编码图象行
//当前图象
CurrentFrameBufferPing->Y+=IMAGE_EDGE;
CurrentFrameBufferPing->Cb+=IMAGE_EDGE_HALF;
CurrentFrameBufferPing->Cr+=IMAGE_EDGE_HALF;
//参考图象
RefFrameBufferPing->Y+=4*64*iExtMBWidth+IMAGE_EDGE;
RefFrameBufferPing->Cb+=64*iExtMBWidth+IMAGE_EDGE_HALF;
RefFrameBufferPing->Cr+=64*iExtMBWidth+IMAGE_EDGE_HALF;
CurRecFrameBufferPong->Y+=IMAGE_EDGE;
CurRecFrameBufferPong->Cb+=IMAGE_EDGE_HALF;
CurRecFrameBufferPong->Cr+=IMAGE_EDGE_HALF;
for (x = 0; x < iMBWidth; x++)
{
pCurMB = &pEncoder->pCurFrameInfo->pMB[y*iMBWidth + x];
pCurMB->quant = pEncoder->pCurFrameInfo->vop_quant;
//计算宏块亮度的SAD值
// pCurMB->LumMBlockSad = ComputMBlockSad(pCurImage->Y + 16*y*iExtWidth + x*16, pTempRefImage->Y + 16*y*iExtWidth + x*16, iExtWidth, pCurMB->LumBlockSad);
iPosition=x*16;
pCurMB->LumMBlockSad = ComputMBlockSad(CurrentFrameBufferPing->Y + iPosition, RefFrameBufferPing->Y + iPosition, iExtWidth, pCurMB->LumBlockSad);
iTempSad = 4*MAX(MAX(pCurMB->LumBlockSad[0], pCurMB->LumBlockSad[1]), MAX(pCurMB->LumBlockSad[2], pCurMB->LumBlockSad[3]));
// compute chro sad
iPosition = 8*x;
//计算色度的SAD
pData.chromaSAD += ComputBlockSad(CurrentFrameBufferPing->Cb + iPosition, RefFrameBufferPing->Cb + iPosition, iExtWidthHalf);
pData.chromaSAD += ComputBlockSad(CurrentFrameBufferPing->Cr + iPosition, RefFrameBufferPing->Cr + iPosition, iExtWidthHalf);
pCurMB->LumMBlockSad += pData.chromaSAD;
iTempSad += pData.chromaSAD;
// skip desicion
if (iTempSad < pCurMB->quant * SkipThesh)
{
if ( SkipModeDecision(RefFrameBufferPing, RefFrameBufferPing, x, y, iExtWidthHalf, pCurMB->quant))
{
SetPframeZeroMB(pCurMB, iTempSad);
pCurMB->mb_type = MB_SKIP;
// continue;
}
}
GetMBParameter(pEncoder,CurrentFrameBufferPing ,RefFrameBufferPing ,pCurMB, &pData, x, y);
GetMBCodeType(&pData, pCurMB, x, y, iMBWidth, pEncoder->pCurFrameInfo->vop_coding_type, iTempSad);
//motionStatsPVOP(&MVmax, &mvCount, &mvSum,pCurMB);
//lvxu080326*****************************
P_MBCoding(bs,pEncoder,CurrentFrameBufferPing,RefFrameBufferPing,CurRecFrameBufferPong,x,y);
//***************************************
}//按宏块进行
/*
CurrentFrameBufferPing->Y-=IMAGE_EDGE;
CurrentFrameBufferPing->Cb-=IMAGE_EDGE_HALF;
CurrentFrameBufferPing->Cr-=IMAGE_EDGE_HALF;
//DMA将重建后的图象行写回外存
//起始行的地址
//iPositionLum = y * iExtWidth * 16-IMAGE_EDGE;
//iPositionChro =y * iExtWidthHalf * 8-IMAGE_EDGE_HALF;
DAT_copy(CurrentFrameBufferPing->Cb,CurRecFrameBufferPing->Cb,64*iExtMBWidth);
DAT_copy(CurrentFrameBufferPing->Cr,CurRecFrameBufferPing->Cr,64*iExtMBWidth);
transferIdY1=DAT_copy(CurrentFrameBufferPing->Y,CurRecFrameBufferPing->Y,4*64*iExtMBWidth);
*/
CurRecFrameBufferPong->Y-=IMAGE_EDGE;
CurRecFrameBufferPong->Cb-=IMAGE_EDGE_HALF;
CurRecFrameBufferPong->Cr-=IMAGE_EDGE_HALF;
/*
if(y>0)
DAT_wait(transferIdYRec);
SWAP(Image8*,CurRecFrameBufferPing, CurRecFrameBufferPong);
*/
//起始行的地址
iPositionLum = y * iExtWidth * 16-IMAGE_EDGE;
iPositionChro =y * iExtWidthHalf * 8-IMAGE_EDGE_HALF;
DAT_copy(CurRecFrameBufferPong->Cb,iPositionChro + pEncoder->pCurImage8->Cb,64*iExtMBWidth);
DAT_copy(CurRecFrameBufferPong->Cr,iPositionChro + pEncoder->pCurImage8->Cr,64*iExtMBWidth);
transferIdYRec=DAT_copy(CurRecFrameBufferPong->Y,iPositionLum + pEncoder->pCurImage8->Y,4*64*iExtMBWidth);
/*
//将图象指向当前编码图象行
//当前图象
CurrentFrameBufferPing->Y-=IMAGE_EDGE;
CurrentFrameBufferPing->Cb-=IMAGE_EDGE_HALF;
CurrentFrameBufferPing->Cr-=IMAGE_EDGE_HALF;
//DMA将重建后的图象行写回外存
//起始行的地址
iPositionLum = y * iExtWidth * 16-IMAGE_EDGE;
iPositionChro =y * iExtWidthHalf * 8-IMAGE_EDGE_HALF;
DAT_copy(CurrentFrameBufferPing->Cb,iPositionChro + pEncoder->pCurImage8->Cb,64*iExtMBWidth);
DAT_copy(CurrentFrameBufferPing->Cr,iPositionChro + pEncoder->pCurImage8->Cr,64*iExtMBWidth);
transferIdY1=DAT_copy(CurrentFrameBufferPing->Y,iPositionLum + pEncoder->pCurImage8->Y,4*64*iExtMBWidth);
*/
/*
memcpy(iPositionLum + pEncoder->pCurImage8->Y,CurrentFrameBufferPing->Y,sizeof(unsigned char)*4*64*iExtMBWidth);
memcpy(iPositionChro + pEncoder->pCurImage8->Cb,CurrentFrameBufferPing->Cb,sizeof(unsigned char)*64*iExtMBWidth);
memcpy(iPositionChro + pEncoder->pCurImage8->Cr,CurrentFrameBufferPing->Cr,sizeof(unsigned char)*64*iExtMBWidth);
*/
//参考图象
RefFrameBufferPing->Y-=(4*64*iExtMBWidth+IMAGE_EDGE);
RefFrameBufferPing->Cb-=(64*iExtMBWidth+IMAGE_EDGE_HALF);
RefFrameBufferPing->Cr-=(64*iExtMBWidth+IMAGE_EDGE_HALF);
}//按行进行
//lvxu080326*****************************
PutBitsPad(bs);
//***************************************
// pEncoder->pCurFrameInfo->vop_fcode_forward = getMinFcode(MVmax);
//printf("\n%4d\n",pEncoder->pCurFrameInfo->vop_fcode_forward);
pData.RefQuarl = pTemp;
free(pData.RefQuarl);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -