📄 vlc.c
字号:
* \brief
* mapping rule for ue(v) syntax elements
* \param
* lenght and info
* \Return: number in the code table
************************************************************************
*/
void mapping_ue(int len, int info, int *value1)
{
*value1 = (int)pow(2,(len/2))+info-1; // *value1 = (int)(2<<(len>>1))+info-1;
}
/*!
************************************************************************
* \brief
* mapping rule for se(v) syntax elements
* \param
* lenght and info
* \Return: signed mvd
************************************************************************
*/
void mapping_se(int len, int info, int *value1)
{
int n;
n = (int)pow(2,(len/2))+info-1;
*value1 = (n+1)/2;
if((n & 0x01)==0) // lsb is signed bit
*value1 = -*value1;
}
/*!
************************************************************************
* \brief
* read_cbp_intra
************************************************************************
*/
void read_cbp_intra(int len,int info,int *cbp)
{
extern const byte NCBP[48][2];
int cbp_idx;
mapping_ue(len,info,&cbp_idx);
*cbp=NCBP[cbp_idx][0];
}
/*!
************************************************************************
* \brief
* read_cbp_inter
************************************************************************
*/
void read_cbp_inter(int len,int info,int *cbp)
{
extern const byte NCBP[48][2];
int cbp_idx;
mapping_ue(len,info,&cbp_idx);
*cbp=NCBP[cbp_idx][1];
}
/*!
************************************************************************
* \brief
* find_level
************************************************************************
*/
void find_level(int sign, int *level, int run, int intra, int tableindex, int abs_level_diff)
{
const byte LEVRUN_INTRA[7][16]= // dongjie
{
{ 4, 3, 2, 2, 2, 2, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0},
{ 6, 4, 3, 2, 2, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{ 6, 4, 4, 2, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{ 8, 5, 3, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{10, 5, 3, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{12, 5, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{15, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
};
const byte LEVRUN_INTER[7][16]= // dongjie
{
{ 4, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0},
{ 5, 3, 2, 2, 2, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0},
{ 5, 3, 3, 2, 2, 2, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0},
{ 6, 4, 3, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{ 7, 4, 3, 2, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{ 9, 5, 3, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{13, 5, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
};
if(intra)
*level = (abs_level_diff+LEVRUN_INTRA[tableindex][run]);
else
*level = (abs_level_diff+LEVRUN_INTER[tableindex][run]);
if(sign == 1)
*level = -(*level);
}
/*!
************************************************************************
* \brief
* find_level_chroma
************************************************************************
*/
void find_level_chroma(int sign, int *level, int run, int tableindex, int abs_level_diff)
{
const byte LEVRUN_CHROMA[4][16]= // dongjie
{
{ 6, 2, 2, 2, 1, 2, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0},
{ 7, 3, 2, 2, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0},
{ 9, 4, 3, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{12, 6, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
};
*level = abs_level_diff + LEVRUN_CHROMA[tableindex/*dongjie*/][run];
if(sign == 1)
*level = -(*level);
}
/*!
************************************************************************
* \brief
* read next UVLC codeword from UVLC-partition and
* map it to the corresponding syntax element
************************************************************************
*/
int read_VLC(SyntaxElement *sym)
{
int frame_bitoffset = currStream->frame_bitoffset;
byte *buf = currStream->streamBuffer;
int BitstreamLengthInBytes = currStream->bitstream_length;
sym->len = GetVLCSymbol (&(sym->inf));
if (sym->len == -1)
return -1;
sym->mapping(sym->len,sym->inf,&(sym->value1));
#if TRACE
tracebits(sym->tracestring, sym->len, sym->inf, sym->value1);
#endif
return 1;
}
/*!
************************************************************************
* \brief
* read next UVLC codeword from UVLC-partition and
* map it to the corresponding syntax element
************************************************************************
*/
int read_UVLC(SyntaxElement *sym)
{
int frame_bitoffset = currStream->frame_bitoffset;
byte *buf = currStream->streamBuffer;
int BitstreamLengthInBytes = currStream->bitstream_length;
if(sym->type == SE_REFFRAME)
{
sym->len = 1;
if ((GetVLCSymbol_refidx(&(sym->inf))) < 0)
return -1;
sym->value1 = sym->inf;
currStream->frame_bitoffset += sym->len;
#if TRACE
tracebits3(sym->tracestring, sym->len, sym->inf, sym->value1);//sym->inf, sym->value1);
#endif
}
else
{
sym->len = GetVLCSymbol (&(sym->inf));
if (sym->len == -1)
return -1;
sym->mapping(sym->len,sym->inf,&(sym->value1));
#if TRACE
tracebits(sym->tracestring, sym->len, sym->inf, sym->value1);
#endif
}
return 1;
}
/*!
************************************************************************
* \brief
* read next VLC codeword for 4x4 Intra Prediction Mode and
* map it to the corresponding Intra Prediction Direction
************************************************************************
*/
int read_Intra4x4PredictionMode(SyntaxElement *sym) //qwang 2004-3-9
{
int frame_bitoffset = currStream->frame_bitoffset;
byte *buf = currStream->streamBuffer;
int BitstreamLengthInBytes = currStream->bitstream_length;
int value1; //temporal varibale
sym->len = GetIntraMode (buf, frame_bitoffset, &(sym->inf), BitstreamLengthInBytes);
if (sym->len == -1)
return -1;
currStream->frame_bitoffset += sym->len;
sym->value1 = sym->len == 1 ? -1 : sym->inf;
//add ctrl bits
if(sym->len == 1)
value1 = 0;
else
value1 = sym->value1 + 8; // add
#if TRACE
//tracebits2(sym->tracestring, sym->len, sym->value1);
tracebits3(sym->tracestring, sym->len, value1,sym->value1);
#endif
return 1;
}
/*!
************************************************************************
* \brief
*
************************************************************************
*/
int GetIntraMode (byte buffer[],int totbitoffset,int *info, int bytecount)
{
register int inf;
long byteoffset; // byte from start of buffer
int bitoffset; // bit from start of byte
int ctr_bit=0; // control bit for current bit posision
int bitcounter=1;
int len;
int info_bit;
byteoffset = totbitoffset/8;
bitoffset = 7-(totbitoffset%8);
ctr_bit = (buffer[byteoffset] & (0x01<<bitoffset)); // set up control bit
len = 1;
//added by MAZHAN
//First bit
if (!ctr_bit) //match the FCD
{
*info = 0;
return bitcounter;
}
else
//len=3;
len = 4; // for intra 9 modes by jx
// make infoword
inf=0; // shortest possible code is 1, then info is always 0
for(info_bit=0;(info_bit<(len-1)); info_bit++)
{
bitcounter++;
bitoffset-=1;
if (bitoffset<0)
{ // finished with current byte ?
bitoffset=bitoffset+8;
byteoffset++;
}
if (byteoffset > bytecount)
{
return -1;
}
inf=(inf<<1);
if(buffer[byteoffset] & (0x01<<(bitoffset)))
inf |=1;
}
*info = inf;
return bitcounter; // return absolute offset in bit from start of frame
}
/*!
************************************************************************
* \brief
* Moves the read pointer of the partition forward by one symbol
************************************************************************
*/
int GetVLCSymbol (int *info)
{
register int inf;
long byteoffset; // byte from start of buffer
int bitoffset; // bit from start of byte
int ctr_bit=0; // control bit for current bit posision
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);
ctr_bit = (buffer[byteoffset] & (0x01<<bitoffset)); // set up control bit
len=1;
while (ctr_bit==0)
{ // find leading 1 bit
len++;
bitoffset-=1;
bitcounter++;
if (bitoffset<0)
{ // finish with current byte ?
bitoffset=bitoffset+8;
byteoffset++;
}
ctr_bit=buffer[byteoffset] & (0x01<<(bitoffset));
}
// make infoword
inf=0; // shortest possible code is 1, then info is always 0
for(info_bit=0;(info_bit<(len-1)); info_bit++)
{
bitcounter++;
bitoffset-=1;
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;
}
*info = inf;
currStream->frame_bitoffset += bitcounter;
return bitcounter; // return absolute offset in bit from start of frame
}
/*!
************************************************************************
* \brief
* get one symbol but not moves the read pointer of the partition forward by one symbol
************************************************************************
*/
int search_ue_code (int totbitoffset)
{
register int inf;
long byteoffset; // byte from start of buffer
int bitoffset; // bit from start of byte
int ctr_bit=0; // control bit for current bit posision
int bitcounter=1;
int len;
int info_bit;
byte *buffer = currStream->streamBuffer;
int bytecount = currStream->bitstream_length;
int symbal;
byteoffset= totbitoffset/8;
bitoffset= 7-(totbitoffset%8);
ctr_bit = (buffer[byteoffset] & (0x01<<bitoffset)); // set up control bit
len=1;
while (ctr_bit==0)
{ // find leading 1 bit
len++;
bitoffset-=1;
bitcounter++;
if (bitoffset<0)
{ // finish with current byte ?
bitoffset=bitoffset+8;
byteoffset++;
}
ctr_bit=buffer[byteoffset] & (0x01<<(bitoffset));
}
// make infoword
inf=0; // shortest possible code is 1, then info is always 0
for(info_bit=0;(info_bit<(len-1)); info_bit++)
{
bitcounter++;
bitoffset-=1;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -