📄 vlc.c
字号:
if (bitoffset<0)
{
// finished with current byte ?
bitoffset=bitoffset+8;
byteoffset++;
}
if (byteoffset > bytecount)
{
error("parse error", -1);
return -1;
}
inf=(inf<<1);
if(buffer[byteoffset] & (0x01<<(bitoffset)))
inf |=1;
}
mapping_ue(bitcounter,inf,&symbal);
return symbal;
}
/*!
************************************************************************
* \brief
*
************************************************************************
*/
int GetVLCSymbol_refidx (int *info)
{
register int inf;
long byteoffset; // byte from start of buffer
int bitoffset; // bit from start of byte
int bitcounter=1;
int len;
int info_bit;
byte *buffer=currStream->streamBuffer;
int bytecount = currStream->bitstream_length;
int totbitoffset = currStream->frame_bitoffset;
byteoffset= totbitoffset/8;
bitoffset= 7-(totbitoffset%8);
len=1;
inf=0;
for(info_bit=0;(info_bit<len); info_bit++)
{
if (bitoffset<0)
{ // finished with current byte ?
bitoffset=bitoffset+8;
byteoffset++;
}
if (byteoffset > bytecount)
{
return -1;
}
if(buffer[byteoffset] & (0x01<<(bitoffset)))
inf = 1;
bitcounter++;
bitoffset-=1;
}
*info = inf;
return bitcounter; // return absolute offset in bit from start of frame
}
extern void tracebits2(const char *trace_str, int len, int info) ;
/*!
************************************************************************
* \brief
*
************************************************************************
*/
int read_FLC(SyntaxElement *sym)
{
int frame_bitoffset = currStream->frame_bitoffset;
byte *buf = currStream->streamBuffer;
int BitstreamLengthInBytes = currStream->bitstream_length;
if ((GetBits(buf, frame_bitoffset, &(sym->inf), BitstreamLengthInBytes, sym->len)) < 0)
return -1;
currStream->frame_bitoffset += sym->len; // move bitstream pointer
sym->value1 = sym->inf;
#if TRACE
tracebits2(sym->tracestring, sym->len, sym->inf);
#endif
return 1;
}
/*!
************************************************************************
* \brief
* Reads bits from the bitstream buffer
************************************************************************
*/
int GetBits (byte buffer[],int totbitoffset,int *info, int bytecount,
int numbits)
{
register int inf;
long byteoffset; // byte from start of buffer
int bitoffset; // bit from start of byte
int bitcounter=numbits;
byteoffset= totbitoffset/8;
bitoffset= 7-(totbitoffset%8);
inf=0;
while (numbits)
{
inf <<=1;
inf |= (buffer[byteoffset] & (0x01<<bitoffset))>>bitoffset;
numbits--;
bitoffset--;
if (bitoffset < 0)
{
byteoffset++;
bitoffset += 8;
if (byteoffset > bytecount)
{
return -1;
}
}
}
*info = inf;
return bitcounter; // return absolute offset in bit from start of frame
}
/*!
************************************************************************
* \brief
* Read coefficients of one 4x4 block
************************************************************************
*/
void readLumaCoeff_4x4_UVLC(int b8, int b4)
{
int mb_nr = pgImage->current_mb_nr;
SyntaxElement currSE;
int ipos;
int run, level;
int ii,jj,k,i;
int boff_x, boff_y;
int symbol2D,Golomb_se_type;
int intra,vlc_numcoef,buffer_level[17],buffer_run[17],abslevel;
int tableindex;
// dongjie
const char (*table2D)[16],(*table2D_inter)[14];
const char eob_intra[7]={-1,0,0,0,0,0,0}; //MA.Zhan
//const char eob_intra[7]={-1,0,2,0,0,0,0};
int incLevel_intra[7]={0,1,2,3,4,6,3000},incRun_intra[7]={-1,3,17,17,17,17,17};
int incLevel_inter[7]={0,1,1,2,3,5,3000},incRun_inter[7]={-1,3,6,17,17,17,17};
//!< used for table switch
int level1_inter[16]={1,1,1,1,2,2,2,3,3,3,3,3,3,3,3,3};
int level1_intra[16]={1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2};
// end
intra = IS_INTRA(pgcurrMB);
Golomb_se_type = SE_LUM_AC_INTER;
boff_x = (((b8 &1)<<3) + ((b4 &1)<<2));
boff_y = (((b8>>1)<<3) + ((b4>>1)<<2));
tableindex = 0; // table index initialization
//!<make decoder table for VLC_INTRA code
if(VLC_INTRA_dec[0][0][1]<0) // Don't need to set this every time. rewrite later.
{
memset(VLC_INTRA_dec,-1,sizeof(VLC_INTRA_dec)); //!< Table Initializtion
for(i=0;i<7;i++)
{
table2D=VLC_INTRA[i];
for(run=0;run<16;run++)
for(level=0;level<16;level++)
{
ipos=table2D[run][level];
assert(ipos<40);
if(ipos>=0)
{
if(i==0)
{
VLC_INTRA_dec[i][ipos][0]=level+1;
VLC_INTRA_dec[i][ipos][1]=run;
VLC_INTRA_dec[i][ipos+1][0]=-(level+1);
VLC_INTRA_dec[i][ipos+1][1]=run;
}
else
{
VLC_INTRA_dec[i][ipos][0]=level;
VLC_INTRA_dec[i][ipos][1]=run;
if(level)
{
VLC_INTRA_dec[i][ipos+1][0]=-(level);
VLC_INTRA_dec[i][ipos+1][1]=run;
}
}
}
}
}
assert(VLC_INTRA_dec[0][0][1]>=0); //otherwise, tables are bad.
}
//make decoder table for VLC_INTER code
if(VLC_INTER_dec[0][0][1]<0) // Don't need to set this every time. rewrite later.
{
memset(VLC_INTER_dec,-1,sizeof(VLC_INTER_dec));
for(i=0;i<7;i++)
{
table2D_inter=VLC_INTER[i];
for(run=0;run<16;run++)
for(level=0;level<14;level++)
{
ipos=table2D_inter[run][level];
assert(ipos<40);
if(ipos>=0)
{
if(i==0)
{
VLC_INTER_dec[i][ipos][0]=level+1;
VLC_INTER_dec[i][ipos][1]=run;
VLC_INTER_dec[i][ipos+1][0]=-(level+1);
VLC_INTER_dec[i][ipos+1][1]=run;
}
else
{
VLC_INTER_dec[i][ipos][0]=level;
VLC_INTER_dec[i][ipos][1]=run;
if(level)
{
VLC_INTER_dec[i][ipos+1][0]=-(level);
VLC_INTER_dec[i][ipos+1][1]=run;
}
}
}
}
}
assert(VLC_INTER_dec[0][0][1]>=0); //otherwise, tables are bad.
}
ipos = -1;
level = 1; // get inside loop
if(intra)
{
int previousRunCnt = 0; // added by PSL 20041228
for(k=0; k<17; k++)
{
currSE.type = Golomb_se_type;
currSE.golomb_grad = VLC_GC_Order_INTRA[tableindex][0];
currSE.golomb_maxlevels = VLC_GC_Order_INTRA[tableindex][1];
read_GOLOMB(&currSE);
symbol2D = currSE.value1; //
if(symbol2D==eob_intra[tableindex])
{
vlc_numcoef = k;
break;
}
if(symbol2D < CODE2D_ESCAPE_SYMBOL)
{
level = VLC_INTRA_dec[tableindex][symbol2D][0];
run = VLC_INTRA_dec[tableindex][symbol2D][1];
}
else
{
// commented by PSL 20041228
//symbol2D_levrun(&level, &run, intra, tableindex, symbol2D);
// added by PSL 20041228
int abs_lev_diff;
int sign;
if(symbol2D<71)
{
sign = symbol2D&0x1;//MAZHAN for "sign"
run = ((symbol2D-39)%32)/2;
abs_lev_diff = 1;
}
else
{
abs_lev_diff = (symbol2D -71)/2+2;
sign = symbol2D&0x1;//MAZHAN for "sign"
currSE.type = Golomb_se_type;
currSE.golomb_grad = 0;
currSE.golomb_maxlevels = VLC_GC_Order_INTRA[tableindex][1];
read_GOLOMB(&currSE);
symbol2D = currSE.value1;
run = symbol2D;
}
find_level(sign, &level, run, intra, tableindex, abs_lev_diff);
}
#if TRACE //transferred before table switch
snprintf(currSE.tracestring, TRACESTRING_SIZE, "%s (run, level) (%d,%3d) k=%d vlc=%d ",
"LUMA4x4_INTRA" ,run, level, VLC_GC_Order_INTRA[tableindex][0], tableindex);
tracebits(currSE.tracestring,currSE.len,currSE.inf,currSE.value1);
fflush(p_trace);
#endif
// added by PSL 20041228
previousRunCnt += run+1;
buffer_level[k] = level;
buffer_run[k] = run;
abslevel = abs(level);
if(abslevel>=incLevel_intra[tableindex])
{
if(abslevel == 1)
tableindex = (run>incRun_intra[tableindex])?level1_intra[run]:tableindex; //Zhan MA 070705
else if(abslevel < 4)
tableindex = (abslevel+1);
else if(abslevel < 6)
tableindex = 5;
else
tableindex = 6;
}
// added by PSL 20041228
if (previousRunCnt==16)
{
vlc_numcoef = k+1;
break;
}
}//loop for k
ipos = -1;
for(i=(vlc_numcoef-1); i>=0; i--)
{
ipos += (buffer_run[i]+1);
ii = SCAN[ipos][0];
jj = SCAN[ipos][1];
pgImage->m7[boff_x + ii][boff_y + jj] = buffer_level[i];
}
}
else
{
int previousRunCnt = 0; // added by PSL 20041228
for(k=0; k<17; k++)
{
currSE.type = Golomb_se_type;
currSE.golomb_grad = VLC_GC_Order_INTER[tableindex][0];
currSE.golomb_maxlevels = VLC_GC_Order_INTER[tableindex][1];
read_GOLOMB(&currSE);
symbol2D = currSE.value1;
if((symbol2D==0)&&(tableindex!=0))
{
vlc_numcoef = k;
break;
}
if(symbol2D < CODE2D_ESCAPE_SYMBOL)
{
level = VLC_INTER_dec[tableindex][symbol2D][0];
run = VLC_INTER_dec[tableindex][symbol2D][1];
}
else
{
// commented by PSL 20041228
//symbol2D_levrun(&level, &run, intra, tableindex, symbol2D);
// added by PSL 20041228
int abs_lev_diff;
int sign;
if(symbol2D<71)
{
sign = symbol2D&0x1;//MAZHAN for "sign"
run = ((symbol2D-39)%32)/2;
abs_lev_diff = 1;
}
else
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -