📄 ch263mb.cpp
字号:
#include <stdlib.h>
#include "stdafx.h"
#include "color.h"
#include "sactable.h"
#include "CBitstream.h"
#include "sac.h"
#include "Ch263class.h"
#include "Chuffman.h"
extern "C"
{void MMXLoadMBData(short *MBPtr, short *Data);
void MMXSetMBDataZero(short *MBPtr);
void MMXSetBlockZero(short *MBPtr);
void MMXDeQuant(short *TempQC,short *rcoeff,int QP);
void MMXStoreMB(BYTE *Loss,short *Data,int pixel);
void MMXStoreBlock(BYTE *Loss,short *Data,int pixel);
void MMXFillMB(BYTE *Src,short *Data,int pixel);
void MMXFillBlock(BYTE *Src,short *Data,int pixel);
void MMXFillMB(BYTE *Src,short *Data,int pixel);
void MMXTransFromMB(short *Data,short *MBPtr);
}
HuffmanCode VLCOD;
int OrValue[6]={32,16,8,4,2,1};
extern int QuantClipTable[512],*QuantClip;
CH263MB::CH263MB(int ww,int hh,CH263Picture * pPic)
{
InitMB();
m_pPic=pPic;
Pic=pPic->PictureInfo;
Width=ww;
Height=hh;
QCoeff=QCoeffData;
if ((int)QCoeff%8)
QCoeff+=(4-(int)QCoeff%8/2);
BQCoeff=BQCoeffData;
if ((int)BQCoeff%8)
BQCoeff+=(4-(int)BQCoeff%8/2);
MBData.lum=MBData.lumData;
if ((int)MBData.lum%8)
MBData.lum+=(4-(int)MBData.lum%8/2);
MBData.CB=MBData.CBData;
if ((int)MBData.CB%8)
MBData.CB+=(4-(int)MBData.CB%8/2);
MBData.CR=MBData.CRData;
if ((int)MBData.CR%8)
MBData.CR+=(4-(int)MBData.CR%8/2);
BData.lum=BData.lumData;
if ((int)BData.lum%8)
BData.lum+=(4-(int)BData.lum%8/2);
BData.CB=BData.CBData;
if ((int)BData.CB%8)
BData.CB+=(4-(int)BData.CB%8/2);
BData.CR=BData.CRData;
if ((int)BData.CR%8)
BData.CR+=(4-(int)BData.CR%8/2);
PredData.lum=PredData.lumData;
if ((int)PredData.lum%8)
PredData.lum+=(8-(int)PredData.lum%8);
PredData.CB=PredData.CBData;
if ((int)PredData.CB%8)
PredData.CB+=(8-(int)PredData.CB%8);
PredData.CR=PredData.CRData;
if ((int)PredData.CR%8)
PredData.CR+=(8-(int)PredData.CR%8);
}
void CH263MB::InitMB(void)
{
CBP=0;
memset(&MBInfo,0,sizeof(MBInfo));
memset(&MBBits,0,sizeof(MBBits));
}
void CH263MB::FillMBData(YUVData Source, int x, int y)
{
MMXFillMB(Source.Y+y*Width+x,MBData.lum,Width);
MMXFillBlock(Source.U+y*Width/4+x/2,MBData.CB,Width/2);
MMXFillBlock(Source.V+y*Width/4+x/2,MBData.CR,Width/2);
}
void CH263MB::EncodeMBData(void)
{
short fblockData[68],coeffData[68];
short *fblock=fblockData,*coeff=coeffData;
if ((int)fblock%8)
fblock+=(4-(int)fblock%8/2);
if ((int)coeff%8)
coeff+=(4-(int)coeff%8/2);
MMXTransFromMB(fblock,MBData.lum);
Dct(fblock,coeff);
Quant(coeff,0);
MMXTransFromMB(fblock,MBData.lum+8);
Dct(fblock,coeff);
Quant(coeff,1);
MMXTransFromMB(fblock,MBData.lum+128);
Dct(fblock,coeff);
Quant(coeff,2);
MMXTransFromMB(fblock,MBData.lum+136);
Dct(fblock,coeff);
Quant(coeff,3);
Dct(MBData.CB,coeff);
Quant(coeff,4);
Dct(MBData.CR,coeff);
Quant(coeff,5);
}
void CH263MB::Quant(short *coeff,int BlockNo)
{ register int ZeroValue=2*QP+QP/2,NegZero=-ZeroValue;
short *TempQC=QCoeff+BlockNo*64;
int i;
int TempQP=2*QP;
register BOOL NoneZero=FALSE;
if (Mode==MODE_INTRA||Mode==MODE_INTRA_Q)
{ // Intra
TempQC[0]=max(1,min(254,coeff[0]/8));
for (i=1;i<64;i++)
if (TempQC[i]=QuantClip[coeff[i]/TempQP])
NoneZero=TRUE;
}
else
{ // non Intra
MMXSetBlockZero(TempQC);
for (i=0;i<64;i++)
{if (coeff[i]>=ZeroValue)
{TempQC[i]=QuantClip[(coeff[i]-QP/2)/TempQP];
NoneZero=TRUE;
}
else if (coeff[i]<=NegZero)
{TempQC[i]=QuantClip[(coeff[i]+QP/2)/TempQP];
NoneZero=TRUE;
}
}
}
if (NoneZero)
CBP|=OrValue[BlockNo];
}
void CH263MB::DecideMBHeader()
{
/* COD */
if (Pic.PictureType==PCT_INTER)
MBBits.CODBits=1;
if (MBInfo.COD)
{memset(&MBBits,0,sizeof(MBBits));
MBBits.CODBits=1;
return; /* not coded */
}
/* MCBPC */
MBInfo.MCBPC= Mode | ((CBP&3)<<4);
if (Pic.PictureType== PCT_INTRA)
MBBits.MCBPCBits=VLCOD.Encode(MBInfo.MCBPC,VLCOD.vlc_cbpcm_intra,MBInfo.MCBPCCW);
else
MBBits.MCBPCBits=VLCOD.Encode(MBInfo.MCBPC,VLCOD.vlc_cbpcm,MBInfo.MCBPCCW);
/* MODB & CBPB */
if (Pic.PBMode)
{switch (MBInfo.MODB)
{case PBMODE_NORMAL:
MBBits.MODBBits=1;
MBInfo.MODBCW=0;
break;
case PBMODE_MVDB:
MBBits.MODBBits=2;
MBInfo.MODBCW=2;
break;
case PBMODE_CBPB_MVDB:
MBBits.MODBBits=2;
MBInfo.MODBCW=3;
/* CBPB */
MBBits.CBPBBits=6;
MBInfo.CBPBCW=MBInfo.CBPB;
break;
}
}
/* CBPY */
MBInfo.CBPY=CBP>>2;
if (Mode == MODE_INTRA || Mode == MODE_INTRA_Q) /* Intra */
MBInfo.CBPY=MBInfo.CBPY^15;
MBBits.CBPYBits=VLCOD.Encode(MBInfo.CBPY,VLCOD.vlc_cbpy,MBInfo.CBPYCW);
/* DQUANT */
if ((Mode == MODE_INTER_Q) || (Mode == MODE_INTRA_Q))
{switch (MBInfo.DQUANT)
{case -1:
MBBits.DQUANTBits=2;
MBInfo.DQUANTCW=0;
break;
case -2:
MBBits.DQUANTBits=2;
MBInfo.DQUANTCW=1;
break;
case 1:
MBBits.DQUANTBits=2;
MBInfo.DQUANTCW=2;
break;
case 2:
MBBits.DQUANTBits=2;
MBInfo.DQUANTCW=3;
break;
}
}
}
int CH263MB::SACEncodeMBHeader(SAC *SACode)
{ int BitCount=0,i;
/* COD */
if (Pic.PictureType== PCT_INTER)
BitCount+=SACode->AR_Encode(MBInfo.COD,cumf_COD);
if (MBInfo.COD)
return BitCount; /* not coded */
/* MCBPC */
MBInfo.MCBPC= Mode | ((CBP&3)<<4);
if (Pic.PictureType== PCT_INTRA)
BitCount+=SACode->AR_Encode(SACode->IndexFN(MBInfo.MCBPC,mcbpc_intratab,9),cumf_MCBPC_intra);
else
BitCount+=SACode->AR_Encode(SACode->IndexFN(MBInfo.MCBPC,mcbpctab,21),cumf_MCBPC);
/* MODB & CBPB */
if (Pic.PBMode)
{switch (MBInfo.MODB)
{case PBMODE_NORMAL:
BitCount+=SACode->AR_Encode(0, cumf_MODB);
break;
case PBMODE_MVDB:
BitCount+=SACode->AR_Encode(1, cumf_MODB);
break;
case PBMODE_CBPB_MVDB:
BitCount+=SACode->AR_Encode(2, cumf_MODB);
/* CBPB */
for(i=5; i>-1; i--)
BitCount+=SACode->AR_Encode(((MBInfo.CBPB&1<<i)>>i),cumf_YCBPB);
break;
}
}
/* CBPY */
MBInfo.CBPY=CBP>>2;
if (Mode == MODE_INTRA || Mode == MODE_INTRA_Q) /* Intra */
BitCount+=SACode->AR_Encode(SACode->IndexFN(MBInfo.CBPY,cbpy_intratab,16),cumf_CBPY_intra);
else
BitCount+=SACode->AR_Encode(SACode->IndexFN(MBInfo.CBPY,cbpytab,16),cumf_CBPY);
/* DQUANT */
if ((Mode == MODE_INTER_Q) || (Mode == MODE_INTRA_Q))
BitCount+=SACode->AR_Encode(SACode->IndexFN(MBInfo.DQUANT+2,dquanttab,4), cumf_DQUANT);
return BitCount;
}
int CH263MB::EncodeMBHeader(CBitStream *OutputStream)
{ int BitCount=0;
if (MBBits.CODBits)
{OutputStream->PutOneBit(MBInfo.COD);
BitCount++;
}
if (MBBits.MCBPCBits)
{OutputStream->PutVarible(MBInfo.MCBPCCW,MBBits.MCBPCBits);
BitCount+=MBBits.MCBPCBits;
}
if (MBBits.MODBBits)
{OutputStream->PutVarible(MBInfo.MODBCW,MBBits.MODBBits);
BitCount+=MBBits.MODBBits;
}
if (MBBits.CBPBBits)
{OutputStream->PutVarible(MBInfo.CBPBCW,MBBits.CBPBBits);
BitCount+=MBBits.CBPBBits;
}
if (MBBits.CBPYBits)
{OutputStream->PutVarible(MBInfo.CBPYCW,MBBits.CBPYBits);
BitCount+=MBBits.CBPYBits;
}
if (MBBits.DQUANTBits)
{OutputStream->PutVarible(MBInfo.DQUANTCW,MBBits.DQUANTBits);
BitCount+=MBBits.DQUANTBits;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -