📄 vlc.c
字号:
{ // 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
* test if bit buffer contains only stop bit
*
* \param buffer
* buffer containing VLC-coded data bits
* \param totbitoffset
* bit offset from start of partition
* \param bytecount
* buffer length
* \return
* true if more bits available
************************************************************************
*/
int more_rbsp_data (byte buffer[],int totbitoffset,int bytecount)
{
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 cnt=0;
byteoffset= totbitoffset/8;
bitoffset= 7-(totbitoffset%8);
assert (byteoffset<bytecount);
// there is more until we're in the last byte
if (byteoffset<(bytecount-1)) return TRUE;
// read one bit
ctr_bit = (buffer[byteoffset] & (0x01<<bitoffset));
// a stop bit has to be one
if (ctr_bit==0) return TRUE;
bitoffset--;
while (bitoffset>=0)
{
ctr_bit = (buffer[byteoffset] & (0x01<<bitoffset)); // set up control bit
if (ctr_bit>0) cnt++;
bitoffset--;
}
return (0!=cnt);
}
/*!
************************************************************************
* \brief
* Check if there are symbols for the next MB
************************************************************************
*/
int uvlc_startcode_follows(struct img_par *img, struct inp_par *inp, int dummy)
{
int dp_Nr = assignSE2partition[img->currentSlice->dp_mode][SE_MBTYPE];
DataPartition *dP = &(img->currentSlice->partArr[dp_Nr]);
Bitstream *currStream = dP->bitstream;
byte *buf = currStream->streamBuffer;
//KS: new function test for End of Buffer
return (!(more_rbsp_data(buf, currStream->frame_bitoffset,currStream->bitstream_length)));
}
/*!
************************************************************************
* \brief
* read one exp-golomb VLC symbol
*
* \param buffer
* containing VLC-coded data bits
* \param totbitoffset
* bit offset from start of partition
* \param info
* returns the value of the symbol
* \param bytecount
* buffer length
* \return
* bits read
************************************************************************
*/
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
}
extern void tracebits2(const char *trace_str, int len, int info) ;
/*!
************************************************************************
* \brief
* code from bitstream (2d tables)
************************************************************************
*/
int code_from_bitstream_2d(SyntaxElement *sym,
DataPartition *dP,
int *lentab,
int *codtab,
int tabwidth,
int tabheight,
int *code)
{
Bitstream *currStream = dP->bitstream;
int frame_bitoffset = currStream->frame_bitoffset;
byte *buf = currStream->streamBuffer;
int BitstreamLengthInBytes = currStream->bitstream_length;
int i,j;
int len, cod;
// this VLC decoding method is not optimized for speed
for (j = 0; j < tabheight; j++) {
for (i = 0; i < tabwidth; i++)
{
len = lentab[i];
if (!len)
continue;
cod = codtab[i];
if ((ShowBits(buf, frame_bitoffset, BitstreamLengthInBytes, len) == cod))
{
sym->value1 = i;
sym->value2 = j;
currStream->frame_bitoffset += len; // move bitstream pointer
sym->len = len;
goto found_code;
}
}
lentab += tabwidth;
codtab += tabwidth;
}
return -1; // failed to find code
found_code:
*code = cod;
return 0;
}
/*!
************************************************************************
* \brief
* read FLC codeword from UVLC-partition
************************************************************************
*/
int readSyntaxElement_FLC(SyntaxElement *sym, Bitstream *currStream)
{
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
* read NumCoeff/TrailingOnes codeword from UVLC-partition
************************************************************************
*/
int readSyntaxElement_NumCoeffTrailingOnes(SyntaxElement *sym, DataPartition *dP,
char *type)
{
Bitstream *currStream = dP->bitstream;
int frame_bitoffset = currStream->frame_bitoffset;
byte *buf = currStream->streamBuffer;
int BitstreamLengthInBytes = currStream->bitstream_length;
int vlcnum, retval;
int code, *ct, *lt;
int lentab[3][4][17] =
{
{ // 0702
{ 1, 6, 8, 9,10,11,13,13,13,14,14,15,15,16,16,16,16},
{ 0, 2, 6, 8, 9,10,11,13,13,14,14,15,15,15,16,16,16},
{ 0, 0, 3, 7, 8, 9,10,11,13,13,14,14,15,15,16,16,16},
{ 0, 0, 0, 5, 6, 7, 8, 9,10,11,13,14,14,15,15,16,16},
},
{
{ 2, 6, 6, 7, 8, 8, 9,11,11,12,12,12,13,13,13,14,14},
{ 0, 2, 5, 6, 6, 7, 8, 9,11,11,12,12,13,13,14,14,14},
{ 0, 0, 3, 6, 6, 7, 8, 9,11,11,12,12,13,13,13,14,14},
{ 0, 0, 0, 4, 4, 5, 6, 6, 7, 9,11,11,12,13,13,13,14},
},
{
{ 4, 6, 6, 6, 7, 7, 7, 7, 8, 8, 9, 9, 9,10,10,10,10},
{ 0, 4, 5, 5, 5, 5, 6, 6, 7, 8, 8, 9, 9, 9,10,10,10},
{ 0, 0, 4, 5, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9,10,10,10},
{ 0, 0, 0, 4, 4, 4, 4, 4, 5, 6, 7, 8, 8, 9,10,10,10},
},
};
int codtab[3][4][17] =
{
{
{ 1, 5, 7, 7, 7, 7,15,11, 8,15,11,15,11,15,11, 7,4},
{ 0, 1, 4, 6, 6, 6, 6,14,10,14,10,14,10, 1,14,10,6},
{ 0, 0, 1, 5, 5, 5, 5, 5,13, 9,13, 9,13, 9,13, 9,5},
{ 0, 0, 0, 3, 3, 4, 4, 4, 4, 4,12,12, 8,12, 8,12,8},
},
{
{ 3,11, 7, 7, 7, 4, 7,15,11,15,11, 8,15,11, 7, 9,7},
{ 0, 2, 7,10, 6, 6, 6, 6,14,10,14,10,14,10,11, 8,6},
{ 0, 0, 3, 9, 5, 5, 5, 5,13, 9,13, 9,13, 9, 6,10,5},
{ 0, 0, 0, 5, 4, 6, 8, 4, 4, 4,12, 8,12,12, 8, 1,4},
},
{
{15,15,11, 8,15,11, 9, 8,15,11,15,11, 8,13, 9, 5,1},
{ 0,14,15,12,10, 8,14,10,14,14,10,14,10, 7,12, 8,4},
{ 0, 0,13,14,11, 9,13, 9,13,10,13, 9,13, 9,11, 7,3},
{ 0, 0, 0,12,11,10, 9, 8,13,12,12,12, 8,12,10, 6,2},
},
};
vlcnum = sym->value1;
if (vlcnum == 3)
{
// read 6 bit FLC
code = ShowBits(buf, frame_bitoffset, BitstreamLengthInBytes, 6);
currStream->frame_bitoffset += 6;
sym->value2 = code & 3;
sym->value1 = (code >> 2);
if (!sym->value1 && sym->value2 == 3)
{
// #c = 0, #t1 = 3 => #c = 0
sym->value2 = 0;
}
else
sym->value1++;
sym->len = 6;
retval = 0;
}
else
{
lt = &lentab[vlcnum][0][0];
ct = &codtab[vlcnum][0][0];
retval = code_from_bitstream_2d(sym, dP, lt, ct, 17, 4, &code);
}
if (retval)
{
printf("ERROR: failed to find NumCoeff/TrailingOnes\n");
exit(-1);
}
#if TRACE
snprintf(sym->tracestring,
TRACESTRING_SIZE, "%s # c & tr.1s vlc=%d #c=%d #t1=%d",
type, vlcnum, sym->value1, sym->value2);
tracebits2(sym->tracestring, sym->len, code);
#endif
return retval;
}
/*!
************************************************************************
* \brief
* read NumCoeff/TrailingOnes codeword from UVLC-partition ChromaDC
************************************************************************
*/
int readSyntaxElement_NumCoeffTrailingOnesChromaDC(SyntaxElement *sym, DataPartition *dP)
{
int retval;
int code, *ct, *lt;
int lentab[4][5] =
{
{ 2, 6, 6, 6, 6,},
{ 0, 1, 6, 7, 8,},
{ 0, 0, 3, 7, 8,},
{ 0, 0, 0, 6, 7,},
};
int codtab[4][5] =
{
{1,7,4,3,2},
{0,1,6,3,3},
{0,0,1,2,2},
{0,0,0,5,0},
};
lt = &lentab[0][0];
ct = &codtab[0][0];
retval = code_from_bitstream_2d(sym, dP, lt, ct, 5, 4, &code);
if (retval)
{
printf("ERROR: failed to find NumCoeff/TrailingOnes ChromaDC\n");
exit(-1);
}
#if TRACE
snprintf(sym->tracestring,
TRACESTRING_SIZE, "ChrDC # c & tr.1s #c=%d #t1=%d",
sym->value1, sym->value2);
tracebits2(sym->tracestring, sym->len, code);
#endif
return retval;
}
/*!
************************************************************************
* \brief
* read Level VLC0 codeword from UVLC-partition
************************************************************************
*/
int readSyntaxElement_Level_VLC0(SyntaxElement *sym, struct datapartition *dP)
{
Bitstream *currStream = dP->bitstream;
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;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -