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

📄 newpb.cpp

📁 这是G.723和G.729的音频编解码的源代码
💻 CPP
📖 第 1 页 / 共 3 页
字号:

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