📄 vlc.c
字号:
byte buffer[]
containing VLC-coded data bits
int totbitoffset
bit offset from start of partition
int type
expected data type (Partiotion ID)
* Output:
* Return: Length and Value of the next symbol
* Attention:As in both nal_bits.c and nal_part.c all data of one partition, slice,
picture was already read into a buffer, there is no need to read any data
here again.
\par
This function could (and should) be optimized considerably
\par
If it is ever decided to have different VLC tables for different symbol
types, then this would be the place for the implementation
\par
An alternate VLC table is implemented based on exponential Golomb codes.
The encoder must have a matching define selected.
\par
GetVLCInfo was extracted because there should be only one place in the
source code that has knowledge about symbol extraction, regardless of
the number of different NALs.
*************************************************************************
*/
int GetVLCSymbol (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;
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)
{
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
}
/*
*************************************************************************
* Function:
* Input:
* Output:
* Return:
* Attention:
*************************************************************************
*/
int GetVLCSymbol_refidx (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 bitcounter=1;
int len;
int info_bit;
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) ;
/*
*************************************************************************
* Function:read FLC codeword from UVLC-partition
* Input:
* Output:
* Return:
* Attention:
*************************************************************************
*/
int readSyntaxElement_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;
}
/*
*************************************************************************
* Function:read Level VLC0 codeword from UVLC-partition
* Input:
* Output:
* Return:
* Attention:
*************************************************************************
*/
int readSyntaxElement_Level_VLC0(SyntaxElement *sym)
{
int frame_bitoffset = currStream->frame_bitoffset;
byte *buf = currStream->streamBuffer;
int BitstreamLengthInBytes = currStream->bitstream_length;
int len, sign, level, code;
len = 0;
while (!ShowBits(buf, frame_bitoffset+len, BitstreamLengthInBytes, 1))
len++;
len++;
code = 1;
frame_bitoffset += len;
if (len < 15)
{
sign = (len - 1) & 1;
level = (len-1) / 2 + 1;
}
else if (len == 15)
{
// escape code
code = (code << 4) | ShowBits(buf, frame_bitoffset, BitstreamLengthInBytes, 4);
len += 4;
frame_bitoffset += 4;
sign = (code & 1);
level = ((code >> 1) & 0x7) + 8;
}
else if (len == 16)
{
// escape code
code = (code << 12) | ShowBits(buf, frame_bitoffset, BitstreamLengthInBytes, 12);
len += 12;
frame_bitoffset += 12;
sign = (code & 1);
level = ((code >> 1) & 0x7ff) + 16;
}
else
{
printf("ERROR reading Level code\n");
exit(-1);
}
if (sign)
level = -level;
sym->inf = level;
sym->len = len;
#if TRACE
tracebits2(sym->tracestring, sym->len, code);
#endif
currStream->frame_bitoffset = frame_bitoffset;
return 0;
}
/*
*************************************************************************
* Function:read Level VLC codeword from UVLC-partition
* Input:
* Output:
* Return:
* Attention:
*************************************************************************
*/
int readSyntaxElement_Level_VLCN(SyntaxElement *sym, int vlc)
{
int frame_bitoffset = currStream->frame_bitoffset;
byte *buf = currStream->streamBuffer;
int BitstreamLengthInBytes = currStream->bitstream_length;
int levabs, sign;
int len = 0;
int code, sb;
int numPrefix;
int shift = vlc-1;
int escape = (15<<shift)+1;
// read pre zeros
numPrefix = 0;
while (!ShowBits(buf, frame_bitoffset+numPrefix, BitstreamLengthInBytes, 1))
numPrefix++;
len = numPrefix+1;
code = 1;
if (numPrefix < 15)
{
levabs = (numPrefix<<shift) + 1;
// read (vlc-1) bits -> suffix
if (vlc-1)
{
sb = ShowBits(buf, frame_bitoffset+len, BitstreamLengthInBytes, vlc-1);
code = (code << (vlc-1) )| sb;
levabs += sb;
len += (vlc-1);
}
// read 1 bit -> sign
sign = ShowBits(buf, frame_bitoffset+len, BitstreamLengthInBytes, 1);
code = (code << 1)| sign;
len ++;
}
else // escape
{
// read 11 bits -> levabs
sb = ShowBits(buf, frame_bitoffset+len, BitstreamLengthInBytes, 11);
code = (code << 11 )| sb;
levabs = sb + escape;
len+=11;
// read 1 bit -> sign
sign = ShowBits(buf, frame_bitoffset+len, BitstreamLengthInBytes, 1);
code = (code << 1)| sign;
len++;
}
sym->inf = (sign)?-levabs:levabs;
sym->len = len;
currStream->frame_bitoffset = frame_bitoffset+len;
#if TRACE
tracebits2(sym->tracestring, sym->len, code);
#endif
return 0;
}
/*
*************************************************************************
* Function:Reads bits from the bitstream buffer
* Input:
byte buffer[]
containing VLC-coded data bits
int totbitoffset
bit offset from start of partition
int bytecount
total bytes in bitstream
int numbits
number of bits to read
* Output:
* Return:
* Attention:
*************************************************************************
*/
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
}
/*
*************************************************************************
* Function:Reads bits from the bitstream buffer
* Input:
byte buffer[]
containing VLC-coded data bits
int totbitoffset
bit offset from start of partition
int bytecount
total bytes in bitstream
int numbits
number of bits to read
* Output:
* Return:
* Attention:
*************************************************************************
*/
int ShowBits (byte buffer[],int totbitoffset,int bytecount, int numbits)
{
register int inf;
long byteoffset; // byte from start of buffer
int bitoffset; // bit from start of byte
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;
}
}
}
return inf; // return absolute offset in bit from start of frame
}
////////////////////////////////////////////////////////////////////////////
// Yulj 2004.07.15
// for decision of slice end.
////////////////////////////////////////////////////////////////////////////
int get_uv (int LenInBits, char*tracestring)
{
SyntaxElement symbol, *sym=&symbol;
assert (currStream->streamBuffer != NULL);
sym->mapping = linfo_ue; // Mapping rule
sym->len = LenInBits;
SYMTRACESTRING(tracestring);
GetSyntaxElement_FLC (sym);
return sym->inf;
}
/////////////////////////////////////////////////////////////
// Yulj 2004.07.15
// for decision of slice end.
/////////////////////////////////////////////////////////////
int GetSyntaxElement_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;
sym->value1 = sym->inf;
#if TRACE
tracebits2(sym->tracestring, sym->len, sym->inf);
#endif
return 1;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -