📄 dh263mb.cpp
字号:
#include <stdlib.h>
#include "stdafx.h"
#include "color.h"
#include "DBitstream.h"
#include "sactable.h"
#include "sad.h"
#include "Dh263class.h"
#include "Dhuffman.h"
#include "commonfunc.h"
#include "commonvar.h"
extern "C"
{void MMXLoadBlock(BYTE *MBPtr,BYTE *ImgPtr,int pixel);
void MMXLoadMB(BYTE *MBPtr,BYTE *ImgPtr,int pixel);
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 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);
}
const int DQ_Tab[4] = {-1,-2,1,2};
int AndValue[6]={32,16,8,4,2,1};
DH263MB::DH263MB(int ww,int hh,DH263Picture * pPic)
{
m_pPic=pPic;
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 DH263MB::DecodeMBData(void)
{
short iBlockData[68],rCoeffData[68];
short *iblock=iBlockData,*rcoeff=rCoeffData;
if ((int)iblock%8)
iblock+=(4-(int)iblock%8/2);
if ((int)rcoeff%8)
rcoeff+=(4-(int)rcoeff%8/2);
if ((CBP&32)||Mode==MODE_INTRA||Mode==MODE_INTRA_Q)
{DeQuant(rcoeff,0);
idct(rcoeff,iblock);
MMXLoadMBData(MBData.lum,iblock);
}
else
MMXSetMBDataZero(MBData.lum);
if ((CBP&16)||Mode==MODE_INTRA||Mode==MODE_INTRA_Q)
{DeQuant(rcoeff,1);
idct(rcoeff,iblock);
MMXLoadMBData(MBData.lum+8,iblock);
}
else
MMXSetMBDataZero(MBData.lum+8);
if ((CBP&8)||Mode==MODE_INTRA||Mode==MODE_INTRA_Q)
{DeQuant(rcoeff,2);
idct(rcoeff,iblock);
MMXLoadMBData(MBData.lum+128,iblock);
}
else
MMXSetMBDataZero(MBData.lum+128);
if ((CBP&4)||Mode==MODE_INTRA||Mode==MODE_INTRA_Q)
{DeQuant(rcoeff,3);
idct(rcoeff,iblock);
MMXLoadMBData(MBData.lum+136,iblock);
}
else
MMXSetMBDataZero(MBData.lum+136);
if ((CBP&2)||Mode==MODE_INTRA||Mode==MODE_INTRA_Q)
{DeQuant(rcoeff,4);
idct(rcoeff,MBData.CB);
}
else
MMXSetBlockZero(MBData.CB);
if ((CBP&1)||Mode==MODE_INTRA||Mode==MODE_INTRA_Q)
{DeQuant(rcoeff,5);
idct(rcoeff,MBData.CR);
}
else
MMXSetBlockZero(MBData.CR);
}
void DH263MB::DeQuant(short *rcoeff,int BlockNo)
{
short *TempQC=QCoeff+BlockNo*64;
MMXDeQuant(TempQC,rcoeff,QP);
if (Mode == MODE_INTRA || Mode == MODE_INTRA_Q)
rcoeff[0] = TempQC[0]*8;
}
void DH263MB::FillRecon(YUVData Loss,int y,int x)
{
MMXStoreMB(Loss.Y+y*Width+x,MBData.lum,Width);
MMXStoreBlock(Loss.U+y*Width/4+x/2,MBData.CB,Width/2);
MMXStoreBlock(Loss.V+y*Width/4+x/2,MBData.CR,Width/2);
}
int DH263MB::DecodeMBHeader(DBitStream * InputStream,int xpos,int ypos)
{ int oo,startmv,stopmv,mvdbx,mvdby,k,pmvx,pmvy,mvx,mvy;
HuffmanDec VLDec(InputStream);
int Ori=ypos*WMB+xpos;
if (Pic.PictureType==PCT_INTER)
{MBInfo.COD=InputStream->GetOneBit();
if (MBInfo.COD) //MB Not Coded
{CBP=0;
Mode=MODE_INTER;
MBInfo.CBPB=0;
ZeroVec((m_pPic->DMV)[Ori]);
if (Pic.APMode)
{ZeroVec((m_pPic->DMVAP)[Ori][0]);
ZeroVec((m_pPic->DMVAP)[Ori][1]);
ZeroVec((m_pPic->DMVAP)[Ori][2]);
ZeroVec((m_pPic->DMVAP)[Ori][3]);
}
(m_pPic->DMV)[Ori].Mode=MODE_INTER;
mvdbx = 0;
mvdby = 0;
return 0;
}
}
if (Pic.PictureType == PCT_INTRA)
MBInfo.MCBPC = VLDec.GetMCBPCIntra();
else
MBInfo.MCBPC = VLDec.GetMCBPC();
if (MBInfo.MCBPC == -1) //stuffing
return 0;
if (MBInfo.MCBPC == -2) //Invalid MCBPC
return -1;
Mode = MBInfo.MCBPC & 7;
if (Pic.PictureType==PCT_INTER)
(m_pPic->DMV)[Ori].Mode=Mode;
if (Pic.PBMode)
{MBInfo.CBPB = 0;
MBInfo.MODB = VLDec.GetMODB();
if (MBInfo.MODB == PBMODE_CBPB_MVDB)
MBInfo.CBPB=InputStream->GetVarible(MBBits.CBPBBits);
}
MBInfo.CBPY = VLDec.GetCBPY();
if (MBInfo.CBPY==-2)
return -1;
if (Mode == MODE_INTRA || Mode == MODE_INTRA_Q)
MBInfo.CBPY =MBInfo.CBPY^15; /* Intra */
CBP = (MBInfo.CBPY << 2) | (MBInfo.MCBPC >> 4);
if (Mode == MODE_INTER_Q || Mode == MODE_INTRA_Q)
{// Read DQUANT if necessary
MBInfo.DQUANT = InputStream->GetVarible(MBBits.DQUANTBits);
QP=max(Pic.PQUANT,min(31,QP+DQ_Tab[MBInfo.DQUANT]));
}
// motion vectors
if (Mode == MODE_INTER ||Mode == MODE_INTER_Q||
Mode == MODE_INTER4V||Pic.PBMode)
{if (!Pic.APMode)
{mvx = VLDec.GetMV();
mvy = VLDec.GetMV();
FindPMV(xpos,ypos,pmvx,pmvy);
mvx = MotionDecode(mvx, pmvx);
mvy = MotionDecode(mvy, pmvy);
(m_pPic->DMV)[Ori].x=mvx/2;
(m_pPic->DMV)[Ori].y=mvy/2;
(m_pPic->DMV)[Ori].x_half=mvx%2;
(m_pPic->DMV)[Ori].y_half=mvy%2;
(m_pPic->DMV)[Ori].Mode=Mode;
}
else
{if (Mode == MODE_INTER4V)
{startmv = 1;
stopmv = 4;
}
else
{startmv = 0;
stopmv = 0;
}
(m_pPic->DMV)[Ori].Mode=Mode;
for (k = startmv; k <= stopmv; k++)
{mvx = VLDec.GetMV();
mvy = VLDec.GetMV();
if (k>0)
oo=k-1;
else
oo=k;
FindAPPMV(xpos,ypos,pmvx,pmvy,oo);
mvx = MotionDecode(mvx, pmvx);
mvy = MotionDecode(mvy, pmvy);
if (k==0)
{(m_pPic->DMV)[Ori].x=mvx/2;
(m_pPic->DMV)[Ori].y=mvy/2;
(m_pPic->DMV)[Ori].x_half=mvx%2;
(m_pPic->DMV)[Ori].y_half=mvy%2;
(m_pPic->DMVAP)[Ori][0]=(m_pPic->DMV)[ypos*WMB+xpos];
(m_pPic->DMVAP)[Ori][1]=(m_pPic->DMV)[ypos*WMB+xpos];
(m_pPic->DMVAP)[Ori][2]=(m_pPic->DMV)[ypos*WMB+xpos];
(m_pPic->DMVAP)[Ori][3]=(m_pPic->DMV)[ypos*WMB+xpos];
}
else
{(m_pPic->DMVAP)[Ori][oo].x=mvx/2;
(m_pPic->DMVAP)[Ori][oo].y=mvy/2;
(m_pPic->DMVAP)[Ori][oo].x_half=mvx%2;
(m_pPic->DMVAP)[Ori][oo].y_half=mvy%2;
}
}
}
// PB frame delta vectors
if (Pic.PBMode)
{if (MBInfo.MODB == PBMODE_MVDB ||MBInfo. MODB == PBMODE_CBPB_MVDB)
{mvdbx = VLDec.GetMV();
mvdby = VLDec.GetMV();
mvdbx = MotionDecode(mvdbx, 0);
mvdby = MotionDecode(mvdby, 0);
}
else
{mvdbx = 0;
mvdby = 0;
}
(m_pPic->DMVPB)[Ori].x=mvdbx/2;
(m_pPic->DMVPB)[Ori].y=mvdby/2;
(m_pPic->DMVPB)[Ori].x_half=mvdbx%2;
(m_pPic->DMVPB)[Ori].y_half=mvdby%2;
}
}
if (Pic.PictureType==PCT_INTER)
if (Mode == MODE_INTRA || Mode == MODE_INTRA_Q)
if (!Pic.PBMode)
{ZeroVec((m_pPic->DMV)[Ori]);
if (Pic.APMode)
{ZeroVec((m_pPic->DMVAP)[Ori][0]);
ZeroVec((m_pPic->DMVAP)[Ori][1]);
ZeroVec((m_pPic->DMVAP)[Ori][2]);
ZeroVec((m_pPic->DMVAP)[Ori][3]);
}
}
return 1;
}
int DH263MB::SACDecodeMBHeader(SAD *SADeco,int xpos,int ypos)
{ int COD_index,MCBPC_index,MODB_index,CBPY_index;
int YCBPB,YCBPB_index,DQUANT_index;
int i,startmv,stopmv,k,pmvx,pmvy;
int mvx,mvy,mvdbx,mvdby,mvx_index,mvy_index,oo;
int Ori=ypos*WMB+xpos;
if (Pic.PictureType==PCT_INTER)
{COD_index = SADeco->decode_a_symbol(cumf_COD);
MBInfo.COD = codtab[COD_index];
}
else
MBInfo.COD=0;
if (MBInfo.COD) //MB Not Coded
{CBP=0;
Mode=MODE_INTER;
MBInfo.CBPB=0;
ZeroVec((m_pPic->DMV)[Ori]);
if (Pic.APMode)
{ZeroVec((m_pPic->DMVAP)[Ori][0]);
ZeroVec((m_pPic->DMVAP)[Ori][1]);
ZeroVec((m_pPic->DMVAP)[Ori][2]);
ZeroVec((m_pPic->DMVAP)[Ori][3]);
}
(m_pPic->DMV)[Ori].Mode=MODE_INTER;
mvdbx = 0;
mvdby = 0;
return 0;
}
if (Pic.PictureType==PCT_INTER)
{MCBPC_index =SADeco->decode_a_symbol(cumf_MCBPC);
MBInfo.MCBPC = mcbpctab[MCBPC_index];
}
else
{MCBPC_index =SADeco->decode_a_symbol(cumf_MCBPC_intra);
MBInfo.MCBPC = mcbpc_intratab[MCBPC_index];
}
if (MBInfo.MCBPC == -1) //stuffing
return 0;
if (MBInfo.MCBPC == -2) //Invalid MCBPC
return -1;
Mode = MBInfo.MCBPC & 7;
if (Pic.PictureType==PCT_INTER)
(m_pPic->DMV)[Ori].Mode=Mode;
if (Pic.PBMode)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -