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

📄 newmc.cpp

📁 这是G.723和G.729的音频编解码的源代码
💻 CPP
字号:

#include "stdafx.h"
#include "color.h"
#include "sactable.h"
#include "CBitstream.h"
#include "sac.h"
#include "Ch263class.h"
#include "commonfunc.h"

#define THRESHOLD_T 300

int AddACMB(BYTE *Curr,int Pixel,int MB_aver);
int AddMB(BYTE *Curr,int Pixel);

extern "C"
	{void MMXLoadBlock(BYTE *MBPtr,BYTE *ImgPtr,int pixel);
	 void MMXLoadMB(BYTE *MBPtr,BYTE *ImgPtr,int pixel);
	 int CalMADLast(BYTE *RefFrame,BYTE *CurFrame,int CurPixels);
	 int CalMADSub(BYTE *RefFrame,BYTE *CurFrame,int RefSubPixels,int CurSubPixels);
	 void GetSub1(BYTE * RF,BYTE *pSubR,int pixels,int lines);
	}

int ChooseMode(BYTE *curr,int pixel,int min_SAD)
{	int MB_mean = 0, A = 0;
	int Mb_aver;
	
	MB_mean=AddMB(curr,pixel);
	Mb_aver=MB_mean/(MB_SIZE*MB_SIZE);
	A=AddACMB(curr,pixel,Mb_aver);
	if (A < (min_SAD - 500)) 
		return MODE_INTRA;
	else
		return MODE_INTER;
}

BOOL CH263Picture::MotionEstimationPicture(BYTE *CurrentFrame,BYTE *ReferFrame,BYTE *InterFrame)
{	BYTE RefFrameData[MB_SIZE*MB_SIZE+8],*RefFrame,*CurFrame;
	BYTE *FSub1R,*FSub1C,*RefSubFrame;
 	int i,j,MinMAD,MAD,OffSearch[4],m,n;
 	int VectorH,VectorW,Bky=Height/MB_SIZE,Bkx=Width/MB_SIZE;
	int yy,xx,oldW,SUB1W=Width/2;
	int RefSize,RefWidth,RefHeight;
 	HANDLE Sub1HR,Sub1HC;

	RefFrame=RefFrameData;
	if ((int)RefFrame%8)
		RefFrame+=(8-(int)RefFrame%8);

	if (PictureInfo.UMVMode)
		{RefSize=(Width+32)*(Height+32)/4;
		 RefWidth=Width+32;
		 RefHeight=Height+32;
		}
	else
		{RefSize=ImageSize/4;
		 RefWidth=Width;
		 RefHeight=Height;
		}
	Sub1HR=GlobalAlloc(GHND,RefSize+8);
	if (!Sub1HR)
		return FALSE;
	FSub1R=(BYTE *)GlobalLock(Sub1HR);
	if ((int)FSub1R%8)
		FSub1R+=(8-(int)FSub1R&8);
	Sub1HC=GlobalAlloc(GHND,ImageSize/4+8);
	if (!Sub1HC)
		return FALSE;
	FSub1C=(BYTE *)GlobalLock(Sub1HC);
	if ((int)FSub1C%8)
		FSub1C+=(8-(int)FSub1C&8);
	GetSub1(ReferFrame,FSub1R,RefWidth,RefHeight);
	GetSub1(CurrentFrame,FSub1C,Width,Height);
	if (PictureInfo.UMVMode)
		FSub1R=FSub1R+8*RefWidth/2+8;

 	for (i=0;i<Bky;i++)
		for (j=0;j<Bkx;j++)
			{CurFrame=CurrentFrame+i*MB_SIZE*Width+j*MB_SIZE;
			 if (PictureInfo.UMVMode)
				RefSubFrame=ReferFrame+16*RefWidth+16+
						 i*MB_SIZE*RefWidth+j*MB_SIZE;
			 else
				RefSubFrame=ReferFrame+i*MB_SIZE*Width+j*MB_SIZE;

			 LoadRefer(RefSubFrame,RefFrame,i*MB_SIZE*2,j*MB_SIZE*2,2*RefWidth,MB_SIZE,StrPrevInt);
			 MinMAD=CalMADLast(RefFrame,CurFrame,Width);
			 if (MinMAD<=THRESHOLD_T)
				{VectorH=0;
				 VectorW=0;
				 goto Assign;
				}

			 OffSearch[0]=-8;
			 OffSearch[1]=8;
			 OffSearch[2]=8;
			 OffSearch[3]=-8;
			 if (!PictureInfo.UMVMode)
				{if (i==0) 
					 OffSearch[0]=0;
				 if (i==(Bky-1)) 
					 OffSearch[2]=0;
				 if (j==0) 
					 OffSearch[3]=0;
				 if (j==(Bkx-1)) 
					 OffSearch[1]=0;
				}
			 MinMAD=INT_MAX;

			 //	One Dimensional Full Search Algorithm
			 xx=j*MB_SIZE/2;yy=i*MB_SIZE/2;
			 VectorH=0;
			 CurFrame=FSub1C+yy*SUB1W+xx;
			 RefSubFrame=FSub1R+(yy+VectorH)*RefWidth/2+(xx+OffSearch[3]);
			 for (n=OffSearch[3];n<=OffSearch[1];n++)
				{MAD=CalMADSub(RefSubFrame,CurFrame,RefWidth/2,SUB1W);
				 if (MinMAD>MAD)
					{MinMAD=MAD;
					 VectorW=n;
					}
				 RefSubFrame++;
				}
			 oldW=VectorW;
			 RefSubFrame=FSub1R+(yy+OffSearch[0])*RefWidth/2+(xx+VectorW);
			 for (m=OffSearch[0];m<=OffSearch[2];m++)
				{MAD=CalMADSub(RefSubFrame,CurFrame,RefWidth/2,SUB1W);
				 if (MinMAD>MAD)
					{MinMAD=MAD;
					 VectorH=m;
					}
				 RefSubFrame+=RefWidth/2;
				}
			 if (VectorH!=0)
				{RefSubFrame=FSub1R+(yy+VectorH)*RefWidth/2+(xx+OffSearch[3]);
				 for (n=OffSearch[3];n<=OffSearch[1];n++)
					{MAD=CalMADSub(RefSubFrame,CurFrame,RefWidth/2,SUB1W);
					 if (MinMAD>MAD)
						{MinMAD=MAD;
						 VectorW=n;
						}
					 RefSubFrame++;
					}
				 if (oldW!=VectorW)
					{RefSubFrame=FSub1R+(yy+OffSearch[0])*RefWidth/2+(xx+VectorW);
					 for (m=OffSearch[0];m<=OffSearch[2];m++)
						{MAD=CalMADSub(RefSubFrame,CurFrame,RefWidth/2,SUB1W);
						 if (MinMAD>MAD)
							{MinMAD=MAD;
							 VectorH=m;
							}
						 RefSubFrame+=RefWidth/2;
						}
					}
				}

			 yy=i*MB_SIZE;xx=j*MB_SIZE;
			 CurFrame=CurrentFrame+Width*yy+xx;
			 OffSearch[0]=2*(VectorH*2)-1;
			 OffSearch[1]=2*(VectorW*2)+1;
			 OffSearch[2]=2*(VectorH*2)+1;
			 OffSearch[3]=2*(VectorW*2)-1;
			 if (!PictureInfo.UMVMode)
				{if (yy*2+OffSearch[0]<0)
					OffSearch[0]=-2*yy;
				 if ((yy+MB_SIZE)*2+OffSearch[2]>Height*2)
					OffSearch[2]=2*(Height-(yy+MB_SIZE));
				 if (xx*2+OffSearch[3]<0)
					OffSearch[3]=-2*xx;
				 if ((xx+MB_SIZE)*2+OffSearch[1]>Width*2)
					OffSearch[1]=2*(Width-(xx+MB_SIZE));
				}
			 MinMAD=INT_MAX;

			 for (m=OffSearch[0];m<=OffSearch[2];m++)
				 {for (n=OffSearch[3];n<=OffSearch[1];n++)
					{LoadRefer(InterFrame,RefFrame,yy*2+m,xx*2+n,2*RefWidth,MB_SIZE,StrPrevInt);
					 MAD=CalMADLast(RefFrame,CurFrame,Width);
					 if (MinMAD>MAD)
						{MinMAD=MAD;
						 VectorH=m;
						 VectorW=n;
						}
					}
				 }
			 VectorH=min(31,max(-32,VectorH));
			 VectorW=min(31,max(-32,VectorW));
Assign:
			 MV[i*WMB+j].y=VectorH/2;
			 MV[i*WMB+j].x=VectorW/2;
			 MV[i*WMB+j].y_half=VectorH%2;
			 MV[i*WMB+j].x_half=VectorW%2;
			 MV[i*WMB+j].min_error=MinMAD;

			 if (PictureInfo.APMode)
				{int sad8,sad16,SmallMAD,k;
				 sad16=MV[i*WMB+j].min_error;

				 for (k=0;k<4;k++)
					 MotionEstimationBlock(j*MB_SIZE,i*MB_SIZE,k,VectorW,VectorH,
						CurrentFrame,InterFrame);

				 sad8=MVAP[i*WMB+j][0].min_error+
					  MVAP[i*WMB+j][1].min_error+
					  MVAP[i*WMB+j][2].min_error+
					  MVAP[i*WMB+j][3].min_error;
				 SmallMAD=min(sad16,sad8);
				 
				 MV[i*WMB+j].Mode=ChooseMode(CurFrame,Width,SmallMAD);

				 if (MV[i*WMB+j].Mode==MODE_INTER)
					{if (sad8 < sad16 - PREF_16_VEC) 
						{MV[i*WMB+j].Mode = MODE_INTER4V;
						 MV[i*WMB+j].min_error = sad8;
						}
					 else
						 for (k=0;k<4;k++)
							MVAP[i*WMB+j][k]=MV[i*WMB+j];
					}
				 else 
					{ZeroVec(MV[i*WMB+j]);
					 for (k=0;k<4;k++)
						 ZeroVec(MVAP[i*WMB+j][k]);
					}
				}
			 else
				{MV[i*WMB+j].Mode=ChooseMode(CurFrame,Width,MinMAD);
				 if (MV[i*WMB+j].Mode==MODE_INTRA && !PictureInfo.PBMode)
					ZeroVec(MV[i*WMB+j]);
				}
			}

	GlobalUnlock(Sub1HR);
	GlobalFree(Sub1HR);
	GlobalUnlock(Sub1HC);
	GlobalFree(Sub1HC);

	return TRUE;
}

void CH263Picture::MotionEstimationBlock(int xx,int yy,int block,int VectorW,
					int VectorH,BYTE *CurFrame,BYTE *InterFrame)
{	int RefWidth,m,n,MinMAD,vmx,vmy,MAD;
	int vmyl=VectorH-2,vmyh=VectorH+2;
	int vmxl=VectorW-2,vmxh=VectorW+2;
	BYTE *pCur,RefFrameData[MB_SIZE*MB_SIZE/4+8],*RefFrame;

	RefFrame=RefFrameData;
	if ((int)RefFrame%8)
		RefFrame+=(8-(int)RefFrame%8);

	if (PictureInfo.UMVMode)
		RefWidth=Width+32;
	else
		RefWidth=Width;

	pCur=CurFrame+(yy+block/2*MB_SIZE/2)*Width
		+xx+(block%2)*MB_SIZE/2;
	if (vmyl<-32)
		vmyl=-32;
	if (vmyh>31)
		vmyh=31;
	if (vmxl<-32)
		vmxl=-32;
	if (vmxh>31)
		vmxh=31;

	if (!PictureInfo.UMVMode)
		{if (yy*2+vmyl<0)
			vmyl=-2*yy;
		 if ((yy+MB_SIZE)*2+vmyh>Height*2)
			vmyh=2*(Height-(yy+MB_SIZE));
		 if (xx*2+vmxl<0)
			vmxl=-2*xx;
		 if ((xx+MB_SIZE)*2+vmxh>Width*2)
			vmxh=2*(Width-(xx+MB_SIZE));
		}
	MinMAD=INT_MAX;

	for (m=vmyl;m<=vmyh;m++)
		for (n=vmxl;n<=vmxh;n++)
			{LoadRefer(InterFrame,RefFrame,(yy+block/2*MB_SIZE/2)*2+m,
				(xx+(block%2)*MB_SIZE/2)*2+n,2*RefWidth,MB_SIZE/2,StrPrevInt);
			 MAD=CalMADSub(RefFrame,pCur,MB_SIZE/2,Width);
			 if (MAD<MinMAD)
				{MinMAD=MAD;
				 vmx=n;
				 vmy=m;
				}
			}

	MVAP[yy/MB_SIZE*WMB+xx/MB_SIZE][block].y=vmy/2;
	MVAP[yy/MB_SIZE*WMB+xx/MB_SIZE][block].x=vmx/2;
	MVAP[yy/MB_SIZE*WMB+xx/MB_SIZE][block].x_half=vmx%2;
	MVAP[yy/MB_SIZE*WMB+xx/MB_SIZE][block].y_half=vmy%2;
	MVAP[yy/MB_SIZE*WMB+xx/MB_SIZE][block].min_error=MinMAD;
}

⌨️ 快捷键说明

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