📄 newpb.cpp
字号:
#include "stdafx.h"
#include "color.h"
#include "sactable.h"
#include "CBitstream.h"
#include "sac.h"
#include "Ch263class.h"
#include "commonvar.h"
#include "commonfunc.h"
extern "C"
{
void MMXReconBlock(BYTE *Select,BYTE *Source,short *Data,int pixel);
void MMXReconMB(BYTE *Select,BYTE *Source,short *Data,int pixel);
void MMXReconAPBlock(BYTE *Select,BYTE *Source,short *Data,int pixel);
void MMXPredMB(short *Data,BYTE *Select,BYTE *Source,int pixel);
void MMXPredBlock(short *Data,BYTE *Select,BYTE *Source,int pixel);
void MMXPredAPBlock(short *Data,BYTE *Select,BYTE *Source,int pixel);
int CalMADLast(BYTE *RefFrame,BYTE *CurFrame,int CurPixels);
int CalMADSub(BYTE *RefFrame,BYTE *CurFrame,int RefSubPixels,int CurSubPixels);
}
BOOL EqualVec(MotionVector MV2, MotionVector MV1);
extern int *QuantClip,*ReconClip;
void LoadMBRefer(BYTE *pInter,BYTE *pBlock,int y,int x,int pixels,int MBlock,AreaInt & StrPrevInt)
{ register int i;
int HalfX,HalfY,IntX,IntY;
BYTE *Start;
IntX=x/2;
if (x%2)
HalfX=1;
else
HalfX=0;
IntY=y/2;
if (y%2)
HalfY=1;
else
HalfY=0;
if (HalfX && x<0)
IntX--;
if (HalfY && y<0)
IntY--;
pixels=pixels/2;
if (HalfX || HalfY)
Start=pInter+(HalfY*2+HalfX)*StrPrevInt.Lines*pixels
+IntY*pixels+IntX;
else
Start=StrPrevInt.LumIntPel+IntY*pixels+IntX;
for (i=0;i<MBlock/2;i++)
memcpy(pBlock+i*MBlock,Start+i*pixels,MBlock/2);
}
int CH263Picture::EncodePBPicture(YUVData Source,YUVData Loss,YUVData PrevRec,
YUVData BSrc,YUVData BLoss)
{ int i,j,k,length;
MotionVector ZEROMV={0,0,0,0,0,0};
int QP_Back,QP_Prev,mvx,mvy,dl;
YUVData PrevInter,EdgeRec;
CBitStream *EncodeStream=new CBitStream;
SAC *SACode;
if (PictureInfo.SACMode)
SACode=new SAC(EncodeStream);
PictureInfo.PictureType=PCT_INTER;
PictureInfo.PBMode=TRUE;
PictureBits.TRBBits=3;
PictureBits.DBQUANTBits=2;
BitHead+=EncodePictureHeader(EncodeStream);
MB->Pic=PictureInfo;
if (PictureInfo.UMVMode)
{PrevInter.hImage=GlobalAlloc(GHND,6*(Height+32)*(Width+32)+8);
PrevInter.Image=(BYTE *)GlobalLock(PrevInter.hImage);
if ((int)PrevInter.Image%8)
PrevInter.Image+=(8-(int)PrevInter.Image%8);
PrevInter.Y=PrevInter.Image;
PrevInter.U=PrevInter.Image+4*(Width+32)*(Height+32);
PrevInter.V=PrevInter.Image+5*(Width+32)*(Height+32);
EdgeRec.hImage=GlobalAlloc(GHND,(Height+32)*(Width+32)+(Height+32)*(Width+32)/2+8);
EdgeRec.Image=(BYTE *)GlobalLock(EdgeRec.hImage);
if ((int)EdgeRec.Image%8)
EdgeRec.Image+=(8-(int)EdgeRec.Image%8);
EdgeRec.Y=EdgeRec.Image;
EdgeRec.U=EdgeRec.Image+(Width+32)*(Height+32);
EdgeRec.V=EdgeRec.Image+(Width+32)*(Height+32)+(Width+32)*(Height+32)/4;
MakeEdgeData(PrevRec,EdgeRec,Width,Height,16);
InterpolateImage(EdgeRec,PrevInter,Width+32,Height+32);
PrevInter.Y=PrevInter.Image+16*(Width+32)+16;
PrevInter.U=PrevInter.Image+4*(Width+32)*(Height+32)+8*(Width/2+16)+8;
PrevInter.V=PrevInter.Image+5*(Width+32)*(Height+32)+8*(Width/2+16)+8;
StrPrevInt.LumIntPel=EdgeRec.Y+16*(Width+32)+16;
StrPrevInt.CBIntPel=EdgeRec.U+8*(Width/2+16)+8;
StrPrevInt.CRIntPel=EdgeRec.V+8*(Width/2+16)+8;
MotionEstimationPicture(Source.Y,EdgeRec.Y,PrevInter.Y);
}
else
{PrevInter.hImage=GlobalAlloc(GHND,6*ImageSize+8);
PrevInter.Image=(BYTE *)GlobalLock(PrevInter.hImage);
if ((int)PrevInter.Image%8)
PrevInter.Image+=(8-(int)PrevInter.Image%8);
PrevInter.Y=PrevInter.Image;
PrevInter.U=PrevInter.Image+4*ImageSize;
PrevInter.V=PrevInter.Image+5*ImageSize;
InterpolateImage(PrevRec,PrevInter,Width,Height);
MotionEstimationPicture(Source.Y,PrevRec.Y,PrevInter.Y);
}
memset(MVPB,0,sizeof(MVPB));
MB->QP=PictureInfo.PQUANT;
for (i=0;i<HMB;i++)
{if (MB->QP<=PictureInfo.PQUANT)
MB->QP=PictureInfo.PQUANT;
QP_Back=QP_Prev=MB->QP;
if (i)
{Group->GOBInfo.GroupNumber=i;
Group->GOBInfo.GQUANT=QP_Back;
if (PictureInfo.SACMode)
BitHead+=SACode->encode_flush();
BitHead+=Group->EncodeGOBHeader(EncodeStream);
}
for (j=0;j<WMB;j++)
{MB->InitMB();
mvx=2*MV[i*WMB+j].x+MV[i*WMB+j].x_half;
mvy=2*MV[i*WMB+j].y+MV[i*WMB+j].y_half;
dl=mvx*mvx+mvy*mvy;
if(dl>256) MB->MBInfo.DQUANT=-2;
else if(dl>64) MB->MBInfo.DQUANT=-1;
else if(dl<1) MB->MBInfo.DQUANT=1;
else MB->MBInfo.DQUANT=0;
if (MV[i*WMB+j].Mode==MODE_INTRA)
MB->MBInfo.DQUANT=2;
QP_Back=max(PictureInfo.PQUANT,min(31,QP_Prev + MB->MBInfo.DQUANT));
MB->QP=QP_Back;
if (QP_Prev==QP_Back)
MB->MBInfo.DQUANT=0;
MB->Mode=MV[i*WMB+j].Mode;
if (MB->MBInfo.DQUANT!=0)
if (MV[i*WMB+j].Mode==MODE_INTER||MV[i*WMB+j].Mode==MODE_INTER4V)
{MB->Mode=MODE_INTER_Q;
MV[i*WMB+j].Mode=MODE_INTER_Q;
if (PictureInfo.APMode)
for (k=0;k<4;k++)
MVAP[i*WMB+j][k]=MV[i*WMB+j];
}
else
{MB->Mode=MODE_INTRA_Q;
MV[i*WMB+j].Mode=MODE_INTRA_Q;
}
if (MB->Mode==MODE_INTER4V)
MB->Predict_P4V(Source,PrevInter,
j*MB_SIZE,i*MB_SIZE);
else if (MB->Mode==MODE_INTRA||MB->Mode==MODE_INTRA_Q)
MB->FillMBData(Source,j*MB_SIZE,i*MB_SIZE);
else
MB->Predict_P(Source,PrevInter,
j*MB_SIZE,i*MB_SIZE);
// P or INTRA Macroblock
MB->EncodeMBData();
if (MB->CBP==0&&(MB->Mode==MODE_INTER||MB->Mode == MODE_INTER_Q||MB->Mode==MODE_INTER4V))
{memset(MB->MBData.lum,0,sizeof(short)*MB_SIZE*MB_SIZE);
memset(MB->MBData.CB,0,sizeof(short)*MB_SIZE*MB_SIZE/4);
memset(MB->MBData.CR,0,sizeof(short)*MB_SIZE*MB_SIZE/4);
}
else
MB->DecodeMBData();
if (MB->Mode==MODE_INTER4V)
MB->MB_Recon_P4V(Loss,j*MB_SIZE,i*MB_SIZE);
else if (MB->Mode==MODE_INTRA||MB->Mode==MODE_INTRA_Q)
MB->FillRecon(Loss,j*MB_SIZE,i*MB_SIZE);
else
MB->MB_Recon_P(Loss,j*MB_SIZE,i*MB_SIZE);
// Predict B-MB using reconstructed P-MB and prev. recon. image
if (PictureInfo.PBMode)
{MB->Predict_B(BSrc,PrevInter,Loss,
j*MB_SIZE,i*MB_SIZE,2,PictureInfo.TRB);
if (QP_Back == 0)
MB->QP_B = 0;// (QP = 0 means no quantization)
else
MB->QP_B = max(1,min(31,bquant[PictureInfo.DBQUANT]*QP_Back/4));
MB->EncodeBData();
if (MB->MBInfo.CBPB)
MB->DecodeBData();
else
{memset(MB->BData.lum,0,sizeof(short)*MB_SIZE*MB_SIZE);
memset(MB->BData.CB,0,sizeof(short)*MB_SIZE*MB_SIZE/4);
memset(MB->BData.CR,0,sizeof(short)*MB_SIZE*MB_SIZE/4);
}
MB->MB_Recon_B(BLoss,j*MB_SIZE,i*MB_SIZE);
// decide MODB
if (MB->MBInfo.CBPB)
MB->MBInfo.MODB = PBMODE_CBPB_MVDB;
else
if ((2*MVPB[i*WMB+j].x+MVPB[i*WMB+j].x_half)==0 &&
(2*MVPB[i*WMB+j].y+MVPB[i*WMB+j].y_half)==0)
MB->MBInfo.MODB = PBMODE_NORMAL;
else
MB->MBInfo.MODB = PBMODE_MVDB;
}
if ((MB->CBP==0)&&(MB->MBInfo.CBPB==0)&&
(EqualVec(MV[i*WMB+j],ZEROMV))&&(EqualVec(MVPB[i*WMB+j],ZEROMV))&&
(MB->Mode==MODE_INTER||MB->Mode==MODE_INTER_Q))
{// Skipped MB : CBP ,CBPB is zero, 16x16 vector is zero,
if (MB->Mode == MODE_INTER_Q)
{MB->MBInfo.DQUANT = 0;
MB->Mode = MODE_INTER;
}
MB->MBInfo.COD=1;//Not Coded
if (!PictureInfo.SACMode)
{MB->DecideMBHeader();
BitHead+=MB->EncodeMBHeader(EncodeStream);
}
else
BitHead+=MB->SACEncodeMBHeader(SACode);
}
else
{if(!MB->Pic.SACMode)
{MB->DecideMBHeader();
BitHead+=MB->EncodeMBHeader(EncodeStream);
if (MB->Mode == MODE_INTER||MB->Mode == MODE_INTER_Q||MB->Mode==MODE_INTER4V
||PictureInfo.PBMode)
{if (!PictureInfo.APMode)
BitVector+=MB->EncodeVectors(j,i,EncodeStream);
else
BitVector+=MB->EncodeAPVectors(j,i,EncodeStream);
}
if (PictureInfo.PBMode)
BitVector+=MB->EncodePBVectors(j,i,EncodeStream);
if (MB->CBP ||MB->Mode == MODE_INTRA ||MB->Mode == MODE_INTRA_Q)
BitData+=MB->EncodeCoeff(EncodeStream);
if (MB->MBInfo.CBPB)
BitData+=MB->EncodeBCoeff(EncodeStream);
}
else
{BitHead+=MB->SACEncodeMBHeader(SACode);
if (MB->Mode == MODE_INTER||MB->Mode == MODE_INTER_Q||MB->Mode==MODE_INTER4V
||PictureInfo.PBMode)
{if (!PictureInfo.APMode)
BitVector+=MB->SACEncodeVectors(j,i,SACode);
else
BitVector+=MB->SACEncodeAPVectors(j,i,SACode);
}
if (PictureInfo.PBMode)
BitVector+=MB->SACEncodePBVectors(j,i,SACode);
if (MB->CBP||MB->Mode == MODE_INTRA ||MB->Mode == MODE_INTRA_Q)
BitData+=MB->SACEncodeCoeff(SACode);
if (MB->MBInfo.CBPB)
BitData+=MB->SACEncodeBCoeff(SACode);
}
QP_Prev = QP_Back;
}
}
}
if (PictureInfo.SACMode)
BitHead+=SACode->encode_flush();
EncodeStream->PutVarible(PictureInfo.EOS,PictureBits.EOSBits);
BitHead+=PictureBits.EOSBits;
BitHead+=EncodeStream->ZeroFlush();
memcpy(CompressData,EncodeStream->OutputBuffer,EncodeStream->ByteLength);
length=EncodeStream->ByteLength;
if (PictureInfo.SACMode)
delete SACode;
if(EncodeStream) delete EncodeStream;
if (PictureInfo.UMVMode)
{GlobalUnlock(EdgeRec.hImage);
GlobalFree(EdgeRec.hImage);
}
GlobalUnlock(PrevInter.hImage);
GlobalFree(PrevInter.hImage);
return length;
}
void CH263MB::Predict_B(YUVData BSrc,YUVData PrevInter,YUVData CurLoss,
int x, int y,int TRD,int TRB)
{ int RefWidth,Ori,VectorH,VectorW,MAD,MinMAD;
int i,j,k,vmyl,vmyh,vmxl,vmxh,vmx,vmy;
int nh,nv,xstart,xstop,ystart,ystop;
int MVCHR[16]={0,0,0,1,1,1,1,1,1,1,1,1,1,1,2,2};
MotionVector TempMV,MVB;
BYTE *BCur,*pLoss;
if (Pic.UMVMode)
RefWidth=Width+32;
else
RefWidth=Width;
Ori=y/MB_SIZE*WMB+x/MB_SIZE;
if (Mode!=MODE_INTER4V)
{VectorW=TRB*(2*(m_pPic->MV)[Ori].x+(m_pPic->MV)[Ori].x_half)/TRD;
VectorH=TRB*(2*(m_pPic->MV)[Ori].y+(m_pPic->MV)[Ori].y_half)/TRD;
BCur=BSrc.Y+y*Width+x;
LoadRefer(PrevInter.Y,PredData.lum,y*2+VectorH,x*2+VectorW,2*RefWidth,MB_SIZE,(m_pPic->StrPrevInt));
MinMAD=CalMADLast(PredData.lum,BCur,Width);
if (MinMAD<=500)
{ZeroVec((m_pPic->MVPB)[Ori]);
//Luminance Bi-directional prediction
pLoss=CurLoss.Y+y*Width+x;
MVB.x=(TRB-TRD)*(2*(m_pPic->MV)[Ori].x+(m_pPic->MV)[Ori].x_half)/TRD/2;
MVB.x_half=(TRB-TRD)*(2*(m_pPic->MV)[Ori].x+(m_pPic->MV)[Ori].x_half)/TRD%2;
MVB.y=(TRB-TRD)*(2*(m_pPic->MV)[Ori].y+(m_pPic->MV)[Ori].y_half)/TRD/2;
MVB.y_half=(TRB-TRD)*(2*(m_pPic->MV)[Ori].y+(m_pPic->MV)[Ori].y_half)/TRD%2;
for (nv = 0; nv <= 1; nv++)
for (nh = 0; nh <= 1; nh++)
{ystart=nv*8 + max(0,(-MVB.y*2-MVB.y_half+1)/2-nv*8);
ystop=nv*8 + min(7,15-(MVB.y*2+MVB.y_half+1)/2-nv*8);
xstart=nh*8 + max(0,(-MVB.x*2-MVB.x_half+1)/2-nh*8);
xstop=nh*8 + min(7,15-(MVB.x*2+MVB.x_half+1)/2-nh*8);
BiDirLumPred(ystart,ystop,xstart,xstop,pLoss,MVB);
}
MMXPredMB(BData.lum,BCur,PredData.lum,Width);
//CHR component Forward directional prediction
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -