📄 ch263mb.cpp
字号:
return BitCount;
}
int CH263MB::EncodeCoeff(CBitStream *OutputStream)
{ int i,BitCount=0;
if (Mode == MODE_INTRA || Mode == MODE_INTRA_Q)
for (i = 0; i < 6; i++)
BitCount+=CodeCoeff(i,OutputStream);
else
for (i = 0; i < 6; i++)
if (CBP&OrValue[i])
BitCount+=CodeCoeff(i,OutputStream);
return BitCount;
}
int CH263MB::CodeCoeff(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,start;
short *TempQC=QCoeff+64*block;
run = bits = 0;
first = 1;
prev_run = prev_level = prev_ind = level = s = prev_s = ind = 0;
if (Mode == MODE_INTRA || Mode == MODE_INTRA_Q)
{// DC coeff
if (TempQC[0]!= 128)
OutputStream->PutVarible(TempQC[0],8);
else
OutputStream->PutVarible(255,8);
bits += 8;
if ((CBP&OrValue[block])==0)
return bits;
start=1;
}
else
start=0;
for (j = start; j<64; j++)
{if (TempQC[j]== 0)
run++;
else
{// code run & level and count bits
s=0;
level=TempQC[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::SACEncodeCoeff(SAC *SACode)
{ int i,BitCount=0;
if (Mode == MODE_INTRA || Mode == MODE_INTRA_Q)
for (i = 0; i < 6; i++)
BitCount+=SACCodeCoeff(i,SACode);
else
for (i = 0; i < 6; i++)
if (CBP&OrValue[i])
BitCount+=SACCodeCoeff(i,SACode);
return BitCount;
}
int CH263MB::SACCodeCoeff(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,intra;
short *TempQC=QCoeff+64*block;
run = bits = 0;
first = 1;
prev_run = prev_level = prev_ind = level = s = prev_s = ind = 0;
position=prev_position=0;
intra = (Mode == MODE_INTRA || Mode == MODE_INTRA_Q);
if (intra)
{// DC coeff
if (TempQC[0] != 128)
mod_index = SACode->IndexFN(TempQC[0],intradctab,254);
else
mod_index = SACode->IndexFN(255,intradctab,254);
bits +=SACode->AR_Encode(mod_index, cumf_INTRADC);
if ((CBP&OrValue[block])==0)
return bits;
}
for (j = intra; j<64; j++)
{if (TempQC[j] == 0)
run++;
else
{// code run & level and count bits
s=0;
level=TempQC[j];
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, intra);
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, intra);
if (intra)
{bits += SACode->AR_Encode(SACode->IndexFN(0, lasttab, 2), cumf_LAST_intra);
bits += SACode->AR_Encode(SACode->IndexFN(prev_run, runtab, 64), cumf_RUN_intra);
bits += SACode->AR_Encode(SACode->IndexFN(prev_level, leveltab, 254),cumf_LEVEL_intra);
}
else
{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, intra);
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, intra);
if (intra)
{bits += SACode->AR_Encode(SACode->IndexFN(1, lasttab, 2), cumf_LAST_intra);
bits += SACode->AR_Encode(SACode->IndexFN(prev_run, runtab, 64), cumf_RUN_intra);
bits += SACode->AR_Encode(SACode->IndexFN(prev_level, leveltab, 254), cumf_LEVEL_intra);
}
else
{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;
}
void CH263MB::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 CH263MB::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 CH263MB::FillRecon(YUVData Loss,int x,int y)
{ 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);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -