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

📄 newinter.cpp

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

//h263 inter mode
#include "stdafx.h"
#include "color.h"
#include "sactable.h"
#include "CBitstream.h"
#include "sac.h"
#include "Ch263class.h"
#include "Chuffman.h"

extern "C"
{	void MMXInterColorP(BYTE *Src,BYTE *Dst,int Pixel,int Lines,int ImgSize);
	void MMXInterLumP(BYTE *Src,BYTE *Dst,int Pixel,int Lines,int ImgSize);
}

BOOL EqualVec(MotionVector MV2, MotionVector MV1)
{
	if (MV1.x != MV2.x)
		return FALSE;
	if (MV1.y != MV2.y)
		return FALSE;
	if (MV1.x_half != MV2.x_half)
		return FALSE;
	if (MV1.y_half != MV2.y_half)
		return FALSE;
	return TRUE;
}

int CH263Picture::EncodeINTERPicture(YUVData Source,YUVData Loss,YUVData PrevRec)
{	YUVData PrevInter,EdgeRec;
	int length;
	int i,j,QP_Back,QP_Prev,mvx,mvy,dl;
	MotionVector ZEROMV={0,0,0,0,0,0};
	CBitStream *EncodeStream=new CBitStream;
	SAC *SACode;

	if (PictureInfo.SACMode)
		SACode=new SAC(EncodeStream);

	PictureInfo.PictureType=PCT_INTER;
	PictureInfo.PBMode=FALSE;
	PictureBits.TRBBits=0;
	PictureBits.DBQUANTBits=0;
	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);
		}

	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)
						{MVAP[i*WMB+j][0]=MV[i*WMB+j];
						 MVAP[i*WMB+j][1]=MV[i*WMB+j];
						 MVAP[i*WMB+j][2]=MV[i*WMB+j];
						 MVAP[i*WMB+j][3]=MV[i*WMB+j];
						}

					}
				 else if (MV[i*WMB+j].Mode==MODE_INTRA)
					{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);

			 if ((MB->CBP==0)&&(EqualVec(MV[i*WMB+j],ZEROMV))&&
				(MB->Mode==MODE_INTER||MB->Mode==MODE_INTER_Q))
				{// Skipped MB : CBP 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)
						{if (!PictureInfo.APMode)
							BitVector+=MB->EncodeVectors(j,i,EncodeStream);
						 else
							BitVector+=MB->EncodeAPVectors(j,i,EncodeStream);
						}
	  				 if (MB->CBP ||MB->Mode == MODE_INTRA ||MB->Mode == MODE_INTRA_Q)
						 BitData+=MB->EncodeCoeff(EncodeStream);
					}
				 else
					{BitHead+=MB->SACEncodeMBHeader(SACode);
					 if (MB->Mode == MODE_INTER||MB->Mode == MODE_INTER_Q||MB->Mode==MODE_INTER4V)
						{if (!PictureInfo.APMode)
							BitVector+=MB->SACEncodeVectors(j,i,SACode);
						 else
							BitVector+=MB->SACEncodeAPVectors(j,i,SACode);
						}
          			 if (MB->CBP||MB->Mode == MODE_INTRA ||MB->Mode == MODE_INTRA_Q)
						 BitData+=MB->SACEncodeCoeff(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 CH263Picture::MakeEdgeData(YUVData src,YUVData dst, int width,
		   int height, int edge)
{	int j,UVHeight,UVWidth,UVEdge;
	BYTE *p1,*p2,*o1;
		
	p1 = dst.Y+edge*(width+2*edge)+edge;
	o1 = src.Y;
	for (j = 0; j < height;j++)
		{memcpy(p1,o1,width);
		 p1 +=( width + edge*2);
		 o1 += width;
		}

	p1=dst.Y+edge;
	o1=src.Y;
	for (j=0;j<edge;j++)
		{memcpy(p1,o1,width);
		 p1+=(width+edge*2);
		}
	p1=dst.Y+(width+edge*2)*(height+edge)+edge;
	o1=src.Y+width*(height-1);
	for (j=0;j<edge;j++)
		{memcpy(p1,o1,width);
		 p1+=(width+edge*2);
		}

	p1=dst.Y;
	p2=dst.Y+width+edge;
	for (j=0;j<height+2*edge;j++)
		{memset(p1,*(p1+edge),edge);
		 memset(p2,*(p2-1),edge);
		 p1+=(width+edge*2);
		 p2+=(width+edge*2);
		}

	UVHeight=height/2;
	UVWidth=width/2;
	UVEdge=edge/2;

	p1 = dst.U+UVEdge*(UVWidth+2*UVEdge)+UVEdge;
	o1 = src.U;
	for (j = 0; j < UVHeight;j++)
		{memcpy(p1,o1,UVWidth);
		 p1 +=(UVWidth + UVEdge*2);
		 o1 += UVWidth;
		}

	p1=dst.U+UVEdge;
	o1=src.U;
	for (j=0;j<UVEdge;j++)
		{memcpy(p1,o1,UVWidth);
		 p1+=(UVWidth+UVEdge*2);
		}
	p1=dst.U+(UVWidth+UVEdge*2)*(UVHeight+UVEdge)+UVEdge;
	o1=src.U+UVWidth*(UVHeight-1);
	for (j=0;j<UVEdge;j++)
		{memcpy(p1,o1,UVWidth);
		 p1+=(UVWidth+UVEdge*2);
		}

	p1=dst.U;
	p2=dst.U+UVWidth+UVEdge;
	for (j=0;j<UVHeight+2*UVEdge;j++)
		{memset(p1,*(p1+UVEdge),UVEdge);
		 memset(p2,*(p2-1),UVEdge);
		 p1+=(UVWidth+UVEdge*2);
		 p2+=(UVWidth+UVEdge*2);
		}


	p1 = dst.V+UVEdge*(UVWidth+2*UVEdge)+UVEdge;
	o1 = src.V;
	for (j = 0; j < UVHeight;j++)
		{memcpy(p1,o1,UVWidth);
		 p1 +=(UVWidth + UVEdge*2);
		 o1 += UVWidth;
		}

	p1=dst.V+UVEdge;
	o1=src.V;
	for (j=0;j<UVEdge;j++)
		{memcpy(p1,o1,UVWidth);
		 p1+=(UVWidth+UVEdge*2);
		}
	p1=dst.V+(UVWidth+UVEdge*2)*(UVHeight+UVEdge)+UVEdge;
	o1=src.V+UVWidth*(UVHeight-1);
	for (j=0;j<UVEdge;j++)
		{memcpy(p1,o1,UVWidth);
		 p1+=(UVWidth+UVEdge*2);
		}

	p1=dst.V;
	p2=dst.V+UVWidth+UVEdge;
	for (j=0;j<UVHeight+2*UVEdge;j++)
		{memset(p1,*(p1+UVEdge),UVEdge);
		 memset(p2,*(p2-1),UVEdge);
		 p1+=(UVWidth+UVEdge*2);
		 p2+=(UVWidth+UVEdge*2);
		}

}

void CH263Picture::InterpolateImage(YUVData Reference,YUVData InterFrame,
					int pixels,int lines)
{	BYTE *Src,*Dst;
	int ImgSize;

	StrPrevInt.Lines=lines;
	StrPrevInt.Pixels=pixels;
	StrPrevInt.LumIntPel=Reference.Y;
	StrPrevInt.CBIntPel=Reference.U;
	StrPrevInt.CRIntPel=Reference.V;

	ImgSize=pixels*lines;
	Src=Reference.Y+ImgSize-16;
	Dst=InterFrame.Y+4*ImgSize-16;
	
	MMXInterLumP(Src,Dst,pixels,lines,-ImgSize);

	pixels/=2;
	lines/=2;

	ImgSize=pixels*lines;
	Src=Reference.U+ImgSize-8;
	Dst=InterFrame.U+4*ImgSize-8;

	MMXInterColorP(Src,Dst,pixels,lines,-ImgSize);

	Src=Reference.V+ImgSize-8;
	Dst=InterFrame.V+4*ImgSize-8;

	MMXInterColorP(Src,Dst,pixels,lines,-ImgSize);

}

⌨️ 快捷键说明

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