📄 h263encode.cpp
字号:
//H263 Encode Program
#include "stdafx.h"
#include "color.h"
#include "sactable.h"
#include "CBitstream.h"
#include "sac.h"
#include "Ch263class.h"
int QuantClipTable[512], *QuantClip;
//extern void InitDCT(void);
void InitCod(void)
{ int i;
QuantClip=&QuantClipTable[256];
for (i=-127;i<127;i++)
QuantClip[i]=i;
for (i=-256;i<-127;i++)
QuantClip[i]=-127;
for (i=127;i<256;i++)
QuantClip[i]=127;
}
CH263Picture::CH263Picture(int SourceFormat,int nCompressOption,int nQuant)
{
Group=new CH263GOB;
MB=new CH263MB(Width,Height,this);
m_pDeblock=new CDeblock ;
InitPicture(SourceFormat,nCompressOption,nQuant);
InitCod();
// InitDCT();
}
void CH263Picture::InitPicture(int nSourceFormat,int nCompressOption,int nQuant)
{
ZeroMemory(MV,sizeof(MV));
ZeroMemory(MVAP,sizeof(MVAP));
ZeroMemory(MVPB,sizeof(MVPB));
ZeroMemory(&StrPrevInt,sizeof(StrPrevInt));
Width=FormatInfo[nSourceFormat].Pixels;
Height=FormatInfo[nSourceFormat].Lines;
ImageSize=FormatInfo[nSourceFormat].TotalBytes;
CurImage.hImage=GlobalAlloc(GHND,ImageSize+ImageSize/2+8);
CurImage.Image=(BYTE *)GlobalLock(CurImage.hImage);
if ((int)CurImage.Image%8)
CurImage.Image+=(8-(int)CurImage.Image%8);
CurImage.Y=CurImage.Image;
CurImage.U=CurImage.Image+ImageSize;
CurImage.V=CurImage.Image+ImageSize+ImageSize/4;
CurRecon.hImage=GlobalAlloc(GHND,ImageSize+ImageSize/2+8);
CurRecon.Image=(BYTE *)GlobalLock(CurRecon.hImage);
if ((int)CurRecon.Image%8)
CurRecon.Image+=(8-(int)CurRecon.Image%8);
CurRecon.Y=CurRecon.Image;
CurRecon.U=CurRecon.Image+ImageSize;
CurRecon.V=CurRecon.Image+ImageSize+ImageSize/4;
PrevRecon.hImage=GlobalAlloc(GHND,ImageSize+ImageSize/2+8);
PrevRecon.Image=(BYTE *)GlobalLock(PrevRecon.hImage);
if ((int)PrevRecon.Image%8)
PrevRecon.Image+=(8-(int)PrevRecon.Image%8);
PrevRecon.Y=PrevRecon.Image;
PrevRecon.U=PrevRecon.Image+ImageSize;
PrevRecon.V=PrevRecon.Image+ImageSize+ImageSize/4;
BImage.hImage=GlobalAlloc(GHND,ImageSize+ImageSize/2+8);
BImage.Image=(BYTE *)GlobalLock(BImage.hImage);
if ((int)BImage.Image%8)
BImage.Image+=(8-(int)BImage.Image%8);
BImage.Y=BImage.Image;
BImage.U=BImage.Image+ImageSize;
BImage.V=BImage.Image+ImageSize+ImageSize/4;
BRecon.hImage=GlobalAlloc(GHND,ImageSize+ImageSize/2+8);
BRecon.Image=(BYTE *)GlobalLock(BRecon.hImage);
if ((int)BRecon.Image%8)
BRecon.Image+=(8-(int)BRecon.Image%8);
BRecon.Y=BRecon.Image;
BRecon.U=BRecon.Image+ImageSize;
BRecon.V=BRecon.Image+ImageSize+ImageSize/4;
DataLength=0;
TotalByte=0;
BitHead=0;
BitData=0;
BitVector=0;
// if (!WriteFile.Open("h263.out",CFile::modeCreate|CFile::modeWrite))
// return;
// else WriteFile.Close();
PictureInfo.PSC=PC_PSC;
PictureInfo.TR=1;
PictureInfo.SplitScreen=FALSE;
PictureInfo.DocumentCamera=FALSE;
PictureInfo.FreezePicture=FALSE;
PictureInfo.SourceFormat=nSourceFormat;
PictureInfo.PictureType=PCT_INTRA;
PictureInfo.UMVMode=(nCompressOption&CF_UMV)?1:0;
PictureInfo.SACMode=(nCompressOption&CF_SAC)?1:0;
PictureInfo.APMode=(nCompressOption&CF_AP)?1:0;
PictureInfo.PBMode=(nCompressOption&CF_PB)?1:0;
PictureInfo.CPM=FALSE;
PictureInfo.PLCI=0;
PictureInfo.PQUANT=nQuant;
PictureInfo.TRB=1;
PictureInfo.DBQUANT=2;
PictureInfo.PEI=FALSE;
PictureInfo.PSPARE=0;
PictureInfo.EOS=PC_EOS;
PictureBits.TotalBits=0;
PictureBits.PSCBits=22;
PictureBits.TRBits=8;
PictureBits.SourceFormatBits=3;
PictureBits.CPMBits=1;
PictureBits.PLCIBits=0;
PictureBits.PQUANTBits=5;
PictureBits.TRBBits=0;
PictureBits.DBQUANTBits=0;
PictureBits.PEIBits=1;
PictureBits.PSPAREBits=0;
PictureBits.EOSBits=22;
//Group=new CH263GOB;
//MB=new CH263MB(Width,Height,this);
MB->Width=Width;
MB->Height=Height;
MB->Pic=PictureInfo;
}
CH263Picture::~CH263Picture(void)
{
FreePicture();
if(MB)
delete MB;
if(Group)
delete Group;
if(m_pDeblock)
delete m_pDeblock;
}
void CH263Picture::FreePicture(void)
{
GlobalUnlock(CurImage.hImage);
GlobalFree(CurImage.hImage);
GlobalUnlock(CurRecon.hImage);
GlobalFree(CurRecon.hImage);
GlobalUnlock(PrevRecon.hImage);
GlobalFree(PrevRecon.hImage);
GlobalUnlock(BImage.hImage);
GlobalFree(BImage.hImage);
GlobalUnlock(BRecon.hImage);
GlobalFree(BRecon.hImage);
// delete MB;
// delete Group;
}
void CH263Picture::SwapPtr(YUVData &Swap1,YUVData &Swap2)
{ BYTE *TempPtr;
TempPtr=Swap1.Image;
Swap1.Image=Swap2.Image;
Swap2.Image=TempPtr;
Swap1.Y=Swap1.Image;
Swap1.U=Swap1.Image+ImageSize;
Swap1.V=Swap1.Image+ImageSize+ImageSize/4;
Swap2.Y=Swap2.Image;
Swap2.U=Swap2.Image+ImageSize;
Swap2.V=Swap2.Image+ImageSize+ImageSize/4;
}
int CH263Picture::EncodePicture(int Mode,int nTotalFrame)
{
PictureInfo.TR=(BYTE)nTotalFrame;
if (Mode==0)//Intra
DataLength=EncodeINTRAPicture(CurImage,CurRecon);
else if (Mode==1)//Inter
DataLength=EncodeINTERPicture(CurImage,CurRecon,PrevRecon);
else //PBMode
DataLength=EncodePBPicture(CurImage,CurRecon,PrevRecon,BImage,BRecon);
// OutputToFile();
m_pDeblock->DeblockPlaneYUV411(CurRecon.Image,PictureInfo.PQUANT,Width,Height);
TotalByte+=DataLength;
return DataLength;
}
BOOL CH263Picture::OutputToFile(void)
{
if (DataLength)
{//WriteFile.Open("h263.out",CFile::modeWrite);
//WriteFile.Seek(0,CFile::end);
//WriteFile.Write(&DataLength,sizeof(DWORD));
//WriteFile.Write(CompressData,DataLength);
//WriteFile.Close();
return TRUE;
}
else
return FALSE;
}
int CH263Picture::EncodePictureHeader(CBitStream * OutputStream)
{
int BitCount=0;
OutputStream->PutVarible(PictureInfo.PSC,PictureBits.PSCBits);
BitCount+=PictureBits.PSCBits;
OutputStream->PutVarible(PictureInfo.TR,PictureBits.TRBits);
BitCount+=PictureBits.TRBits;
OutputStream->PutOneBit(0);//PTYPE Bit 1
OutputStream->PutOneBit(1);//PTYPE Bit 2
OutputStream->PutOneBit(PictureInfo.SplitScreen);//PTYPE Bit 3
OutputStream->PutOneBit(PictureInfo.DocumentCamera);//PTYPE Bit 4
OutputStream->PutOneBit(PictureInfo.FreezePicture);//PTYPE Bit 5
OutputStream->PutVarible(PictureInfo.SourceFormat,PictureBits.SourceFormatBits);
OutputStream->PutOneBit(PictureInfo.PictureType);//PTYPE Bit 9
OutputStream->PutOneBit(PictureInfo.UMVMode);//PTYPE Bit 10
OutputStream->PutOneBit(PictureInfo.SACMode);//PTYPE Bit 11
OutputStream->PutOneBit(PictureInfo.APMode);//PTYPE Bit 12
OutputStream->PutOneBit(PictureInfo.PBMode);//PTYPE Bit 13
BitCount+=13;
OutputStream->PutVarible(PictureInfo.PQUANT,PictureBits.PQUANTBits);
BitCount+=PictureBits.PQUANTBits;
OutputStream->PutOneBit(PictureInfo.CPM);
BitCount++;
if (PictureBits.PLCIBits!=0)
{OutputStream->PutVarible(PictureInfo.PLCI,PictureBits.PLCIBits);
BitCount+=PictureBits.PLCIBits;
}
if (PictureBits.TRBBits!=0)
{OutputStream->PutVarible(PictureInfo.TRB,PictureBits.TRBBits);
BitCount+=PictureBits.TRBBits;
}
if (PictureBits.DBQUANTBits!=0)
{OutputStream->PutVarible(PictureInfo.DBQUANT,PictureBits.DBQUANTBits);
BitCount+=PictureBits.DBQUANTBits;
}
OutputStream->PutOneBit(PictureInfo.PEI);
BitCount++;
if (PictureBits.PSPAREBits!=0)
{OutputStream->PutVarible(PictureInfo.PSPARE,PictureBits.PSPAREBits);
BitCount+=PictureBits.PSPAREBits;
}
return BitCount;
}
int CH263Picture::EncodeINTRAPicture(YUVData Source,YUVData Loss)
{
int i,j,length;
CBitStream *EncodeStream=new CBitStream;
SAC *SACode;
if (PictureInfo.SACMode)
SACode=new SAC(EncodeStream);
PictureInfo.PictureType=PCT_INTRA;
PictureInfo.PBMode=FALSE;
PictureBits.TRBBits=0;
PictureBits.DBQUANTBits=0;
BitHead+=EncodePictureHeader(EncodeStream);
MB->Pic=PictureInfo;
MB->QP=PictureInfo.PQUANT;
MB->Mode=MODE_INTRA;
for (j=0;j<HMB;j++)
{if (j)
{Group->GOBInfo.GQUANT=MB->QP;
Group->GOBInfo.GroupNumber=j;
if (PictureInfo.SACMode)
BitHead+=SACode->encode_flush();
BitHead+=Group->EncodeGOBHeader(EncodeStream);
}
for (i=0;i<WMB;i++)
{MB->InitMB();
MB->MBInfo.COD=0; // Every block is coded in Intra frame
MB->MBBits.CODBits=0;
MB->FillMBData(Source,i*MB_SIZE,j*MB_SIZE);
MB->EncodeMBData();
if (!PictureInfo.SACMode)
{MB->DecideMBHeader();
BitHead+=MB->EncodeMBHeader(EncodeStream);
BitData+=MB->EncodeCoeff(EncodeStream);
}
else
{BitHead+=MB->SACEncodeMBHeader(SACode);
BitData+=MB->SACEncodeCoeff(SACode);
}
MB->DecodeMBData();
MB->FillRecon(Loss,i*MB_SIZE,j*MB_SIZE);
}
}
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;
return length;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -