📄 vlc.c
字号:
*/
void levrun_linfo_intra(int level,int run,int *len,int *info)
{
const byte LEVRUN[8]=
{
9,3,1,1,1,0,0,0
};
const byte NTAB[9][5] =
{
{ 1, 3, 7,15,17},
{ 5,19, 0, 0, 0},
{ 9,21, 0, 0, 0},
{11, 0, 0, 0, 0},
{13, 0, 0, 0, 0},
{23, 0, 0, 0, 0},
{25, 0, 0, 0, 0},
{27, 0, 0, 0, 0},
{29, 0, 0, 0, 0},
};
int levabs,i,n,sign,nn;
if (level == 0) // check for EOB
{
*len=1;
return;
}
if (level <= 0)
sign=1;
else
sign=0;
levabs=abs(level);
if (levabs <= LEVRUN[run])
{
n=NTAB[levabs-1][run]+1;
}
else
{
n=(levabs-LEVRUN[run])*16 + 16 + run*2;
}
nn=n/2;
for (i=0; i < 16 && nn != 0; i++)
{
nn /= 2;
}
*len= 2*i + 1;
*info=n-(int)pow(2,i)+sign;
}
/*!
************************************************************************
* \brief
* Makes code word and passes it back
* A code word has the following format: 0 0 0 ... 1 Xn ...X2 X1 X0.
*
* \par Input:
* Info : Xn..X2 X1 X0 \n
* Length : Total number of bits in the codeword
************************************************************************
*/
// NOTE this function is called with sym->inf > (1<<(sym->len/2)). The upper bits of inf are junk
int symbol2uvlc(SyntaxElement *sym)
{
int suffix_len=sym->len/2;
sym->bitpattern = (1<<suffix_len)|(sym->inf&((1<<suffix_len)-1));
return 0;
}
/*!
************************************************************************
* \brief
* generates UVLC code and passes the codeword to the buffer
************************************************************************
*/
int writeSyntaxElement_UVLC(SyntaxElement *se, DataPartition *this_dataPart)
{
se->mapping(se->value1,se->value2,&(se->len),&(se->inf));
symbol2uvlc(se);
writeUVLC2buffer(se, this_dataPart->bitstream);
if(se->type != SE_HEADER)
this_dataPart->bitstream->write_flag = 1;
#if TRACE
if(se->type <= 1)
trace2out (se);
#endif
return (se->len);
}
/*!
************************************************************************
* \brief
* passes the fixed codeword to the buffer
************************************************************************
*/
int writeSyntaxElement_fixed(SyntaxElement *se, DataPartition *this_dataPart)
{
writeUVLC2buffer(se, this_dataPart->bitstream);
if(se->type != SE_HEADER)
this_dataPart->bitstream->write_flag = 1;
#if TRACE
if(se->type <= 1)
trace2out (se);
#endif
return (se->len);
}
/*!
************************************************************************
* \brief
* generates code and passes the codeword to the buffer
************************************************************************
*/
int writeSyntaxElement_Intra4x4PredictionMode(SyntaxElement *se, DataPartition *this_dataPart)
{
if (se->value1 == -1)
{
se->len = 1;
se->inf = 1;
}
else
{
se->len = 4;
se->inf = se->value1;
}
se->bitpattern = se->inf;
writeUVLC2buffer(se, this_dataPart->bitstream);
if(se->type != SE_HEADER)
this_dataPart->bitstream->write_flag = 1;
#if TRACE
if(se->type <= 1)
trace2out (se);
#endif
return (se->len);
}
/*!
************************************************************************
* \brief
* generates UVLC code and passes the codeword to the buffer
* \author
* Tian Dong
************************************************************************
*/
int writeSyntaxElement2Buf_UVLC(SyntaxElement *se, Bitstream* this_streamBuffer )
{
se->mapping(se->value1,se->value2,&(se->len),&(se->inf));
symbol2uvlc(se);
writeUVLC2buffer(se, this_streamBuffer );
#if TRACE
if(se->type <= 1)
trace2out (se);
#endif
return (se->len);
}
/*!
************************************************************************
* \brief
* writes UVLC code to the appropriate buffer
************************************************************************
*/
void writeUVLC2buffer(SyntaxElement *se, Bitstream *currStream)
{
int i;
unsigned int mask = 1 << (se->len-1);
// Add the new bits to the bitstream.
// Write out a byte if it is full
for (i=0; i<se->len; i++)
{
currStream->byte_buf <<= 1;
if (se->bitpattern & mask)
currStream->byte_buf |= 1;
currStream->bits_to_go--;
mask >>= 1;
if (currStream->bits_to_go==0)
{
currStream->bits_to_go = 8;
currStream->streamBuffer[currStream->byte_pos++]=currStream->byte_buf;
currStream->byte_buf = 0;
}
}
}
/*!
************************************************************************
* \brief
* generates UVLC code and passes the codeword to the buffer
* \author
* Tian Dong
************************************************************************
*/
int writeSyntaxElement2Buf_Fixed(SyntaxElement *se, Bitstream* this_streamBuffer )
{
writeUVLC2buffer(se, this_streamBuffer );
#if TRACE
if(se->type <= 1)
trace2out (se);
#endif
return (se->len);
}
/*!
************************************************************************
* \brief
* Makes code word and passes it back
*
* \par Input:
* Info : Xn..X2 X1 X0 \n
* Length : Total number of bits in the codeword
************************************************************************
*/
int symbol2vlc(SyntaxElement *sym)
{
int info_len = sym->len;
// Convert info into a bitpattern int
sym->bitpattern = 0;
// vlc coding
while(--info_len >= 0)
{
sym->bitpattern <<= 1;
sym->bitpattern |= (0x01 & (sym->inf >> info_len));
}
return 0;
}
/*!
************************************************************************
* \brief
* generates VLC code and passes the codeword to the buffer
************************************************************************
*/
int writeSyntaxElement_VLC(SyntaxElement *se, DataPartition *this_dataPart)
{
se->inf = se->value1;
se->len = se->value2;
symbol2vlc(se);
writeUVLC2buffer(se, this_dataPart->bitstream);
#if TRACE
if (se->type <= 1)
trace2out (se);
#endif
return (se->len);
}
/*!
************************************************************************
* \brief
* write VLC for NumCoeff and TrailingOnes
************************************************************************
*/
int writeSyntaxElement_NumCoeffTrailingOnes(SyntaxElement *se, DataPartition *this_dataPart)
{
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},
},
};
int vlcnum;
vlcnum = se->len;
// se->value1 : numcoeff
// se->value2 : numtrailingones
if (vlcnum == 3)
{
se->len = 6; // 4 + 2 bit FLC
if (se->value1 > 0)
{
se->inf = ((se->value1-1) << 2) | se->value2;
}
else
{
se->inf = 3;
}
}
else
{
se->len = lentab[vlcnum][se->value2][se->value1];
se->inf = codtab[vlcnum][se->value2][se->value1];
}
//se->inf = 0;
if (se->len == 0)
{
printf("ERROR: (numcoeff,trailingones) not valid: vlc=%d (%d, %d)\n",
vlcnum, se->value1, se->value2);
exit(-1);
}
symbol2vlc(se);
writeUVLC2buffer(se, this_dataPart->bitstream);
#if TRACE
if (se->type <= 1)
trace2out (se);
#endif
return (se->len);
}
/*!
************************************************************************
* \brief
* write VLC for NumCoeff and TrailingOnes for Chroma DC
************************************************************************
*/
int writeSyntaxElement_NumCoeffTrailingOnesChromaDC(SyntaxElement *se, DataPartition *this_dataPart)
{
int lentab[3][4][17] =
{
//YUV420
{{ 2, 6, 6, 6, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{ 0, 1, 6, 7, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{ 0, 0, 3, 7, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{ 0, 0, 0, 6, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}},
//YUV422
{{ 1, 7, 7, 9, 9,10,11,12,13, 0, 0, 0, 0, 0, 0, 0, 0},
{ 0, 2, 7, 7, 9,10,11,12,12, 0, 0, 0, 0, 0, 0, 0, 0},
{ 0, 0, 3, 7, 7, 9,10,11,12, 0, 0, 0, 0, 0, 0, 0, 0},
{ 0, 0, 0, 5, 6, 7, 7,10,11, 0, 0, 0, 0, 0, 0, 0, 0}},
//YUV444
{{ 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}}
};
int codtab[3][4][17] =
{
//YUV420
{{ 1, 7, 4, 3, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{ 0, 1, 6, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{ 0, 0, 1, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{ 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}},
//YUV422
{{ 1,15,14, 7, 6, 7, 7, 7, 7, 0, 0, 0, 0, 0, 0, 0, 0},
{ 0, 1,13,12, 5, 6, 6, 6, 5, 0, 0, 0, 0, 0, 0, 0, 0},
{ 0, 0, 1,11,10, 4, 5, 5, 4, 0, 0, 0, 0, 0, 0, 0, 0},
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -