📄 vlc.c
字号:
/*!
***************************************************************************
* \file vlc.c
*
* \brief
* (CA)VLC coding functions
*
* \author
* Main contributors (see contributors.h for copyright, address and affiliation details)
* - Inge Lille-Langoy <inge.lille-langoy@telenor.com>
* - Detlev Marpe <marpe@hhi.de>
* - Stephan Wenger <stewe@cs.tu-berlin.de>
***************************************************************************
*/
#include "contributors.h"
#include <stdlib.h>
#include <math.h>
#include <string.h>
#include <assert.h>
#include "global.h"
#include "vlc.h"
#if TRACE
#define SYMTRACESTRING(s) strncpy(sym.tracestring,s,TRACESTRING_SIZE)
#else
#define SYMTRACESTRING(s) // do nothing
#endif
/*!
*************************************************************************************
* \brief
* ue_v, writes an ue(v) syntax element, returns the length in bits
*
* \param tracestring
* the string for the trace file
* \param value
* the value to be coded
* \param bitstream
* the target bitstream the value should be coded into
*
* \return
* Number of bits used by the coded syntax element
*
* \ note
* This function writes always the bit buffer for the progressive scan flag, and
* should not be used (or should be modified appropriately) for the interlace crap
* When used in the context of the Parameter Sets, this is obviously not a
* problem.
*
*************************************************************************************
*/
int ue_v (char *tracestring, int value, Bitstream *bitstream)
{
SyntaxElement symbol, *sym=&symbol;
sym->value1 = value;
sym->value2 = 0;
assert (bitstream->streamBuffer != NULL);
ue_linfo(sym->value1,sym->value2,&(sym->len),&(sym->inf));
symbol2uvlc(sym);
writeUVLC2buffer (sym, bitstream);
#if TRACE
strncpy(sym->tracestring,tracestring,TRACESTRING_SIZE);
trace2out (sym);
#endif
return (sym->len);
}
/*!
*************************************************************************************
* \brief
* se_v, writes an se(v) syntax element, returns the length in bits
*
* \param tracestring
* the string for the trace file
* \param value
* the value to be coded
* \param bitstream
* the target bitstream the value should be coded into
*
* \return
* Number of bits used by the coded syntax element
*
* \ note
* This function writes always the bit buffer for the progressive scan flag, and
* should not be used (or should be modified appropriately) for the interlace crap
* When used in the context of the Parameter Sets, this is obviously not a
* problem.
*
*************************************************************************************
*/
int se_v (char *tracestring, int value, Bitstream *bitstream)
{
SyntaxElement symbol, *sym=&symbol;
sym->value1 = value;
sym->value2 = 0;
assert (bitstream->streamBuffer != NULL);
se_linfo(sym->value1,sym->value2,&(sym->len),&(sym->inf));
symbol2uvlc(sym);
writeUVLC2buffer (sym, bitstream);
#if TRACE
strncpy(sym->tracestring,tracestring,TRACESTRING_SIZE);
trace2out (sym);
#endif
return (sym->len);
}
/*!
*************************************************************************************
* \brief
* u_1, writes a flag (u(1) syntax element, returns the length in bits,
* always 1
*
* \param tracestring
* the string for the trace file
* \param value
* the value to be coded
* \param bitstream
* the target bitstream the value should be coded into
*
* \return
* Number of bits used by the coded syntax element (always 1)
*
* \ note
* This function writes always the bit buffer for the progressive scan flag, and
* should not be used (or should be modified appropriately) for the interlace crap
* When used in the context of the Parameter Sets, this is obviously not a
* problem.
*
*************************************************************************************
*/
int u_1 (char *tracestring, int value, Bitstream *bitstream)
{
SyntaxElement symbol, *sym=&symbol;
sym->bitpattern = value;
sym->len = 1;
sym->value1 = value;
assert (bitstream->streamBuffer != NULL);
writeUVLC2buffer(sym, bitstream);
#if TRACE
strncpy(sym->tracestring,tracestring,TRACESTRING_SIZE);
trace2out (sym);
#endif
return (sym->len);
}
/*!
*************************************************************************************
* \brief
* u_v, writes a n bit fixed length syntax element, returns the length in bits,
*
* \param n
* length in bits
* \param tracestring
* the string for the trace file
* \param value
* the value to be coded
* \param bitstream
* the target bitstream the value should be coded into
*
* \return
* Number of bits used by the coded syntax element
*
* \ note
* This function writes always the bit buffer for the progressive scan flag, and
* should not be used (or should be modified appropriately) for the interlace crap
* When used in the context of the Parameter Sets, this is obviously not a
* problem.
*
*************************************************************************************
*/
int u_v (int n, char *tracestring, int value, Bitstream *bitstream)
{
SyntaxElement symbol, *sym=&symbol;
sym->bitpattern = value;
sym->len = n;
sym->value1 = value;
assert (bitstream->streamBuffer != NULL);
writeUVLC2buffer(sym, bitstream);
#if TRACE
strncpy(sym->tracestring,tracestring,TRACESTRING_SIZE);
trace2out (sym);
#endif
return (sym->len);
}
/*!
************************************************************************
* \brief
* mapping for ue(v) syntax elements
* \param ue
* value to be mapped
* \param dummy
* dummy parameter
* \param info
* returns mapped value
* \param len
* returns mapped value length
************************************************************************
*/
void ue_linfo(int ue, int dummy, int *len,int *info)
{
int i,nn;
nn=(ue+1)/2;
for (i=0; i < 16 && nn != 0; i++)
{
nn /= 2;
}
*len= 2*i + 1;
*info=ue+1-(int)pow(2,i);
}
/*!
************************************************************************
* \brief
* mapping for se(v) syntax elements
* \param se
* value to be mapped
* \param dummy
* dummy parameter
* \param len
* returns mapped value length
* \param info
* returns mapped value
************************************************************************
*/
void se_linfo(int se, int dummy, int *len,int *info)
{
int i,n,sign,nn;
sign=0;
if (se <= 0)
{
sign=1;
}
n=absm(se) << 1;
/*
n+1 is the number in the code table. Based on this we find length and info
*/
nn=n/2;
for (i=0; i < 16 && nn != 0; i++)
{
nn /= 2;
}
*len=i*2 + 1;
*info=n - (int)pow(2,i) + sign;
}
/*!
************************************************************************
* \par Input:
* Number in the code table
* \par Output:
* length and info
************************************************************************
*/
void cbp_linfo_intra(int cbp, int dummy, int *len,int *info)
{
extern const unsigned char NCBP[2][48][2];
ue_linfo(NCBP[img->yuv_format?1:0][cbp][0], dummy, len, info);
}
/*!
************************************************************************
* \par Input:
* Number in the code table
* \par Output:
* length and info
************************************************************************
*/
void cbp_linfo_inter(int cbp, int dummy, int *len,int *info)
{
extern const unsigned char NCBP[2][48][2];
ue_linfo(NCBP[img->yuv_format?1:0][cbp][1], dummy, len, info);
}
/*!
************************************************************************
* \brief
* 2x2 transform of chroma DC
* \par Input:
* level and run for coefficients
* \par Output:
* length and info
* \note
* see ITU document for bit assignment
************************************************************************
*/
void levrun_linfo_c2x2(int level,int run,int *len,int *info)
{
const int NTAB[2][2]=
{
{1,5},
{3,0}
};
const int LEVRUN[4]=
{
2,1,0,0
};
int levabs,i,n,sign,nn;
if (level == 0) // check if the coefficient sign EOB (level=0)
{
*len=1;
return;
}
sign=0;
if (level <= 0)
{
sign=1;
}
levabs=absm(level);
if (levabs <= LEVRUN[run])
{
n=NTAB[levabs-1][run]+1;
}
else
{
n=(levabs-LEVRUN[run])*8 + 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
* Single scan coefficients
* \par Input:
* level and run for coefficients
* \par Output:
* length and info
* \note
* see ITU document for bit assignment
************************************************************************
*/
void levrun_linfo_inter(int level,int run,int *len,int *info)
{
const byte LEVRUN[16]=
{
4,2,2,1,1,1,1,1,1,1,0,0,0,0,0,0
};
const byte NTAB[4][10]=
{
{ 1, 3, 5, 9,11,13,21,23,25,27},
{ 7,17,19, 0, 0, 0, 0, 0, 0, 0},
{15, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{29, 0, 0, 0, 0, 0, 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=absm(level);
if (levabs <= LEVRUN[run])
{
n=NTAB[levabs-1][run]+1;
}
else
{
n=(levabs-LEVRUN[run])*32 + 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
* Double scan coefficients
* \par Input:
* level and run for coefficients
* \par Output:
* length and info
* \note
* see ITU document for bit assignment
************************************************************************
*/
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=absm(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
* 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;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -