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