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

📄 motioncompute.c

📁 DM642的mpeg4编码
💻 C
📖 第 1 页 / 共 4 页
字号:
	}


}

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 + -