📄 cmbpbframe.cpp
字号:
#include "stdafx.h"
#include "color.h"
#include "sactable.h"
#include "CBitstream.h"
#include "sac.h"
#include "Ch263class.h"
#include "Chuffman.h"
extern HuffmanCode VLCOD;
extern int *QuantClip,OrValue[6];
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 MMXTransFromMB(short *Data,short *MBPtr);
}
void CH263MB::EncodeBData(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,BData.lum);
Dct(fblock,coeff);
BQuant(coeff,0);
MMXTransFromMB(fblock,BData.lum+8);
Dct(fblock,coeff);
BQuant(coeff,1);
MMXTransFromMB(fblock,BData.lum+128);
Dct(fblock,coeff);
BQuant(coeff,2);
MMXTransFromMB(fblock,BData.lum+136);
Dct(fblock,coeff);
BQuant(coeff,3);
Dct(BData.CB,coeff);
BQuant(coeff,4);
Dct(BData.CR,coeff);
BQuant(coeff,5);
}
void CH263MB::BQuant(short *coeff,int BlockNo)
{ register int i;
short *TempBQC=BQCoeff+64*BlockNo;
register int TempQP=2*QP_B,ZeroValue=2*QP_B+QP_B/2,NegZero=-ZeroValue;
register BOOL NoneZero=FALSE;
MMXSetBlockZero(TempBQC);
for (i=0;i<64;i++)
{if (coeff[i]>=ZeroValue)
{TempBQC[i]=QuantClip[(coeff[i]-QP_B/2)/TempQP];
NoneZero=TRUE;
}
else if (coeff[i]<=NegZero)
{TempBQC[i]=QuantClip[(coeff[i]+QP_B/2)/TempQP];
NoneZero=TRUE;
}
}
if (NoneZero)
MBInfo.CBPB|=OrValue[BlockNo];
}
void CH263MB::DecodeBData(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 (MBInfo.CBPB&32)
{BDeQuant(rcoeff,0);
idct(rcoeff,iblock);
MMXLoadMBData(BData.lum,iblock);
}
else
MMXSetMBDataZero(BData.lum);
if (MBInfo.CBPB&16)
{BDeQuant(rcoeff,1);
idct(rcoeff,iblock);
MMXLoadMBData(BData.lum+8,iblock);
}
else
MMXSetMBDataZero(BData.lum+8);
if (MBInfo.CBPB&8)
{BDeQuant(rcoeff,2);
idct(rcoeff,iblock);
MMXLoadMBData(BData.lum+128,iblock);
}
else
MMXSetMBDataZero(BData.lum+128);
if (MBInfo.CBPB&4)
{BDeQuant(rcoeff,3);
idct(rcoeff,iblock);
MMXLoadMBData(BData.lum+136,iblock);
}
else
MMXSetMBDataZero(BData.lum+136);
if (MBInfo.CBPB&2)
{BDeQuant(rcoeff,4);
idct(rcoeff,BData.CB);
}
else
MMXSetBlockZero(BData.CB);
if (MBInfo.CBPB&1)
{BDeQuant(rcoeff,5);
idct(rcoeff,BData.CR);
}
else
MMXSetBlockZero(BData.CR);
}
void CH263MB::BDeQuant(short *rcoeff,int BlockNo)
{
short *TempBQC=BQCoeff+64*BlockNo;
MMXDeQuant(TempBQC,rcoeff,QP_B);
}
int CH263MB::EncodeBCoeff(CBitStream *OutputStream)
{ int i,BitCount=0;
for (i = 0; i < 6; i++)
if (MBInfo.CBPB&OrValue[i])
BitCount+=CodeBCoeff(i,OutputStream);
return BitCount;
}
int CH263MB::CodeBCoeff(int block,CBitStream *OutputStream)
{ int j, bits;
int prev_run, run, prev_level, level, first;
int prev_ind, ind, prev_s, s, length;
int CodeWord;
short *TempBQC=BQCoeff+64*block;
run = bits = 0;
first = 1;
prev_run = prev_level = prev_ind = level = s = prev_s = ind = 0;
for (j =0; j<64; j++)
{// Increment run if coeff is zero
if (TempBQC[j]==0)
run++;
else
{// code run & level and count bits
s=0;
level=TempBQC[j];
if (level < 0)
{s = 1;
level = -level;
}
ind = level | run<<4;
if (!first)
{// Encode the previous ind
if (prev_level < 13 && prev_run < 64)
{length=VLCOD.Encode(prev_ind,VLCOD.vlc_3d,CodeWord);
OutputStream->PutVarible(CodeWord,length);
}
else
length = 0;
if (length == 0)
{ // Escape coding
if (prev_s == 1)
prev_level = (prev_level^0xff)+1;
VLCOD.Encode(ESCAPE,VLCOD.vlc_3d,CodeWord);
OutputStream->PutVarible(CodeWord,7);
OutputStream->PutOneBit(0);
OutputStream->PutVarible(prev_run,6);
OutputStream->PutVarible(prev_level,8);
bits += 22;
}
else
{OutputStream->PutOneBit(prev_s);
bits += length + 1;
}
}
prev_run = run; prev_s = s;
prev_level = level; prev_ind = ind;
run = first = 0;
}
}
// Encode the last coeff
if (!first)
{prev_ind = prev_ind | 1<<12; /* last coeff */
if (prev_level < 13 && prev_run < 64)
{length =VLCOD.Encode(prev_ind,VLCOD.vlc_3d,CodeWord);
OutputStream->PutVarible(CodeWord,length);
}
else
length = 0;
if (length == 0)
{ /* Escape coding */
if (prev_s == 1)
prev_level = (prev_level^0xff)+1;
VLCOD.Encode(ESCAPE,VLCOD.vlc_3d,CodeWord);
OutputStream->PutVarible(CodeWord,7);
OutputStream->PutOneBit(1);
OutputStream->PutVarible(prev_run,6);
OutputStream->PutVarible(prev_level,8);
bits += 22;
}
else
{OutputStream->PutOneBit(prev_s);
bits += length + 1;
}
}
return bits;
}
int CH263MB::SACEncodeBCoeff(SAC *SACode)
{ int i,BitCount=0;
for (i = 0; i < 6; i++)
if (MBInfo.CBPB&OrValue[i])
BitCount+=SACCodeBCoeff(i,SACode);
return BitCount;
}
int CH263MB::SACCodeBCoeff(int block,SAC *SACode)
{ int j, bits,position,prev_position,mod_index;
int prev_run, run, prev_level, level, first;
int prev_ind, ind, prev_s, s, length;
short *TempBQC=BQCoeff+64*block;
run = bits = 0;
first = 1;
prev_run = prev_level = prev_ind = level = s = prev_s = ind = 0;
position=prev_position=0;
for (j =0; j<64; j++)
{if (TempBQC[j]==0)
run++;
else
{/* code run & level and count bits */
level=TempBQC[j];
s=0;
if (level < 0)
{s = 1;
level = -level;
}
ind = level | run<<4;
position++;
if (!first)
{mod_index=SACode->IndexFN(prev_ind, tcoeftab, 103);
/* Encode the previous ind */
if (prev_level < 13 && prev_run < 64)
length=SACode->CodeTCoef(mod_index, prev_position, FALSE);
else
length = -1;
if (length == -1)
{ /* Escape coding */
if (prev_s == 1)
prev_level = (prev_level^0xff)+1;
mod_index = SACode->IndexFN(ESCAPE, tcoeftab, 103);
bits += SACode->CodeTCoef(mod_index, prev_position,FALSE);
bits += SACode->AR_Encode(SACode->IndexFN(0, lasttab, 2), cumf_LAST);
bits += SACode->AR_Encode(SACode->IndexFN(prev_run, runtab, 64), cumf_RUN);
bits += SACode->AR_Encode(SACode->IndexFN(prev_level, leveltab, 254),
cumf_LEVEL);
}
else
{bits += SACode->AR_Encode(SACode->IndexFN(prev_s, signtab, 2), cumf_SIGN);
bits += length;
}
}
prev_run = run; prev_s = s;
prev_level = level; prev_ind = ind;
run = first = 0;
prev_position = position;
}
}
/* Encode the last coeff */
if (!first)
{prev_ind = prev_ind | 1<<12; /* last coeff */
mod_index = SACode->IndexFN(prev_ind, tcoeftab, 103);
if (prev_level < 13 && prev_run < 64)
length = SACode->CodeTCoef(mod_index, prev_position, FALSE);
else
length = -1;
if (length == -1)
{ /* Escape coding */
if (prev_s == 1)
prev_level = (prev_level^0xff)+1;
mod_index = SACode->IndexFN(ESCAPE, tcoeftab, 103);
bits += SACode->CodeTCoef(mod_index, prev_position, FALSE);
bits += SACode->AR_Encode(SACode->IndexFN(1, lasttab, 2), cumf_LAST);
bits += SACode->AR_Encode(SACode->IndexFN(prev_run, runtab, 64), cumf_RUN);
bits += SACode->AR_Encode(SACode->IndexFN(prev_level, leveltab, 254), cumf_LEVEL);
}
else
{bits += SACode->AR_Encode(SACode->IndexFN(prev_s, signtab, 2), cumf_SIGN);
bits += length;
}
}
return bits;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -