vlc.c
资源名称:chapter15.rar [点击查看]
上传用户:hjq518
上传日期:2021-12-09
资源大小:5084k
文件大小:35k
源码类别:
Audio
开发平台:
Visual 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 <math.h>
- #include "global.h"
- #include "enc_statistics.h"
- #include "vlc.h"
- #if TRACE
- #define SYMTRACESTRING(s) strncpy(sym.tracestring,s,TRACESTRING_SIZE)
- #else
- #define SYMTRACESTRING(s) // do nothing
- #endif
- //! gives codeword number from CBP value, both for intra and inter
- static const unsigned char NCBP[2][48][2]=
- {
- { // 0 1 2 3 4 5 6 7 8 9 10 11
- { 1, 0},{10, 1},{11, 2},{ 6, 5},{12, 3},{ 7, 6},{14,14},{ 2,10},{13, 4},{15,15},{ 8, 7},{ 3,11},
- { 9, 8},{ 4,12},{ 5,13},{ 0, 9},{ 0, 0},{ 0, 0},{ 0, 0},{ 0, 0},{ 0, 0},{ 0, 0},{ 0, 0},{ 0, 0},
- { 0, 0},{ 0, 0},{ 0, 0},{ 0, 0},{ 0, 0},{ 0, 0},{ 0, 0},{ 0, 0},{ 0, 0},{ 0, 0},{ 0, 0},{ 0, 0},
- { 0, 0},{ 0, 0},{ 0, 0},{ 0, 0},{ 0, 0},{ 0, 0},{ 0, 0},{ 0, 0},{ 0, 0},{ 0, 0},{ 0, 0},{ 0, 0}
- },
- {
- { 3, 0},{29, 2},{30, 3},{17, 7},{31, 4},{18, 8},{37,17},{ 8,13},{32, 5},{38,18},{19, 9},{ 9,14},
- {20,10},{10,15},{11,16},{ 2,11},{16, 1},{33,32},{34,33},{21,36},{35,34},{22,37},{39,44},{ 4,40},
- {36,35},{40,45},{23,38},{ 5,41},{24,39},{ 6,42},{ 7,43},{ 1,19},{41, 6},{42,24},{43,25},{25,20},
- {44,26},{26,21},{46,46},{12,28},{45,27},{47,47},{27,22},{13,29},{28,23},{14,30},{15,31},{ 0,12}
- }
- };
- /*!
- *************************************************************************************
- * 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.
- *
- *************************************************************************************
- */
- Boolean u_1 (char *tracestring, int value, Bitstream *bitstream)
- {
- SyntaxElement symbol, *sym=&symbol;
- sym->bitpattern = value;
- sym->value1 = value;
- sym->len = 1;
- //assert (bitstream->streamBuffer != NULL);
- writeUVLC2buffer(sym, bitstream);
- #if TRACE
- strncpy(sym->tracestring,tracestring,TRACESTRING_SIZE);
- trace2out (sym);
- #endif
- return ((Boolean) 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->value1 = value;
- sym->len = n;
- //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 =(ue+1)>>1;
- for (i=0; i < 33 && nn != 0; i++)
- {
- nn >>= 1;
- }
- *len = (i << 1) + 1;
- *info = ue + 1 - (1 << 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 sign = (se <= 0) ? 1 : 0;
- int n = iabs(se) << 1; // n+1 is the number in the code table. Based on this we find length and info
- int nn = (n >> 1);
- int i;
- for (i = 0; i < 33 && nn != 0; i++)
- {
- nn >>= 1;
- }
- *len = (i << 1) + 1;
- *info = n - (1 << 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)
- {
- ue_linfo(NCBP[((img->yuv_format!=0)&&(img->yuv_format!=3))][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)
- {
- ue_linfo(NCBP[((img->yuv_format!=0)&&(img->yuv_format!=3))][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)
- {
- static const int NTAB[2][2]=
- {
- {1,5},
- {3,0}
- };
- static const int LEVRUN[4]=
- {
- 2,1,0,0
- };
- int levabs,i,n,sign = 0,nn;
- if (level == 0) // check if the coefficient sign EOB (level=0)
- {
- *len=1;
- return;
- }
- if (level <= 0)
- {
- sign=1;
- }
- levabs = iabs(level);
- if (levabs <= LEVRUN[run])
- {
- n = NTAB[levabs - 1][run] + 1;
- }
- else
- {
- n = (levabs - LEVRUN[run]) * 8 + run * 2;
- }
- nn = n >> 1;
- for (i=0; i < 16 && nn != 0; i++)
- {
- nn >>= 1;
- }
- *len = (i << 1) + 1;
- *info = n - (1 << 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)
- {
- static const byte LEVRUN[16]=
- {
- 4,2,2,1,1,1,1,1,1,1,0,0,0,0,0,0
- };
- static 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},
- };
- static int levabs,i,n,sign,nn;
- if (level == 0) // check for EOB
- {
- *len=1;
- return;
- }
- sign = (level <= 0) ? 1 : 0;
- levabs = iabs(level);
- n = (levabs <= LEVRUN[run]) ? NTAB[levabs - 1][run] + 1 : (levabs - LEVRUN[run]) * 32 + run * 2;
- nn = n >> 1;
- for (i=0; i < 16 && nn != 0; i++)
- {
- nn >>= 1;
- }
- *len = (i << 1) + 1;
- *info = n - (1 << 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 >> 1;
- //assert (suffix_len < 32);
- suffix_len = (1 << suffix_len);
- sym->bitpattern = suffix_len | (sym->inf & (suffix_len - 1));
- return 0;
- }
- /*!
- ************************************************************************
- * brief
- * generates UVLC code and passes the codeword to the buffer
- ************************************************************************
- */
- void writeSE_UVLC(SyntaxElement *se, DataPartition *dp)
- {
- ue_linfo (se->value1,se->value2,&(se->len),&(se->inf));
- symbol2uvlc(se);
- writeUVLC2buffer(se, dp->bitstream);
- if(se->type != SE_HEADER)
- dp->bitstream->write_flag = 1;
- #if TRACE
- if(dp->bitstream->trace_enabled)
- trace2out (se);
- #endif
- }
- /*!
- ************************************************************************
- * brief
- * generates UVLC code and passes the codeword to the buffer
- ************************************************************************
- */
- void writeSE_SVLC(SyntaxElement *se, DataPartition *dp)
- {
- se_linfo (se->value1,se->value2,&(se->len),&(se->inf));
- symbol2uvlc(se);
- writeUVLC2buffer(se, dp->bitstream);
- if(se->type != SE_HEADER)
- dp->bitstream->write_flag = 1;
- #if TRACE
- if(dp->bitstream->trace_enabled)
- trace2out (se);
- #endif
- }
- /*!
- ************************************************************************
- * brief
- * generates UVLC code and passes the codeword to the buffer
- ************************************************************************
- */
- void writeCBP_VLC (Macroblock* currMB, SyntaxElement *se, DataPartition *dp)
- {
- if (IS_OLDINTRA (currMB) || currMB->mb_type == SI4MB || currMB->mb_type == I8MB)
- {
- cbp_linfo_intra (se->value1,se->value2,&(se->len),&(se->inf));
- }
- else
- {
- cbp_linfo_inter (se->value1,se->value2,&(se->len),&(se->inf));
- }
- symbol2uvlc(se);
- writeUVLC2buffer(se, dp->bitstream);
- if(se->type != SE_HEADER)
- dp->bitstream->write_flag = 1;
- #if TRACE
- if(dp->bitstream->trace_enabled)
- trace2out (se);
- #endif
- }
- /*!
- ************************************************************************
- * brief
- * generates code and passes the codeword to the buffer
- ************************************************************************
- */
- void writeIntraPredMode_CAVLC(SyntaxElement *se, DataPartition *dp)
- {
- if (se->value1 == -1)
- {
- se->len = 1;
- se->inf = 1;
- }
- else
- {
- se->len = 4;
- se->inf = se->value1;
- }
- se->bitpattern = se->inf;
- writeUVLC2buffer(se, dp->bitstream);
- if(se->type != SE_HEADER)
- dp->bitstream->write_flag = 1;
- #if TRACE
- if(dp->bitstream->trace_enabled)
- trace2out (se);
- #endif
- return;
- }
- /*!
- ************************************************************************
- * 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)
- {
- unsigned int mask = 1 << (se->len - 1);
- int i;
- //byte *streamBuffer = &currStream->streamBuffer[currStream->byte_pos];
- //assert ((se->len-1) < 32);
- // 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;
- mask >>= 1;
- if ((--currStream->bits_to_go) == 0)
- {
- currStream->bits_to_go = 8;
- currStream->streamBuffer[currStream->byte_pos++] = currStream->byte_buf;
- //currStream->byte_pos++;
- //*(streamBuffer++) = 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
- * generates UVLC code and passes the codeword to the buffer
- * author
- * Tian Dong
- ************************************************************************
- */
- void writeSE_Flag(SyntaxElement *se, DataPartition *dp )
- {
- se->len = 1;
- se->bitpattern = (se->value1 & 1);
- writeUVLC2buffer(se, dp->bitstream );
- #if TRACE
- if(dp->bitstream->trace_enabled)
- trace2out (se);
- #endif
- }
- /*!
- ************************************************************************
- * brief
- * generates UVLC code and passes the codeword to the buffer
- * author
- * Tian Dong
- ************************************************************************
- */
- void writeSE_invFlag(SyntaxElement *se, DataPartition *dp )
- {
- se->len = 1;
- se->bitpattern = 1 - (se->value1 & 1);
- writeUVLC2buffer(se, dp->bitstream );
- #if TRACE
- if(dp->bitstream->trace_enabled)
- trace2out (se);
- #endif
- }
- /*!
- ************************************************************************
- * brief
- * generates UVLC code and passes the codeword to the buffer
- * author
- * Tian Dong
- ************************************************************************
- */
- void writeSE_Dummy(SyntaxElement *se, DataPartition *dp )
- {
- se->len = 0;
- }
- /*!
- ************************************************************************
- * brief
- * generates UVLC code and passes the codeword to the buffer
- * author
- * Tian Dong
- ************************************************************************
- */
- void writeSE_Fix(SyntaxElement *se, Bitstream *bitstream )
- {
- writeUVLC2buffer(se, bitstream);
- #if TRACE
- if(bitstream->trace_enabled)
- trace2out (se);
- #endif
- }
- /*!
- ************************************************************************
- * 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 *dp)
- {
- se->inf = se->value1;
- se->len = se->value2;
- symbol2vlc(se);
- writeUVLC2buffer(se, dp->bitstream);
- if(se->type != SE_HEADER)
- dp->bitstream->write_flag = 1;
- #if TRACE
- if(dp->bitstream->trace_enabled)
- trace2out (se);
- #endif
- return (se->len);
- }
- /*!
- ************************************************************************
- * brief
- * write VLC for NumCoeff and TrailingOnes
- ************************************************************************
- */
- int writeSyntaxElement_NumCoeffTrailingOnes(SyntaxElement *se, DataPartition *dp)
- {
- static const 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},
- },
- };
- static const 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 = 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];
- }
- 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, dp->bitstream);
- if(se->type != SE_HEADER)
- dp->bitstream->write_flag = 1;
- #if TRACE
- if(dp->bitstream->trace_enabled)
- trace2out (se);
- #endif
- return (se->len);
- }
- /*!
- ************************************************************************
- * brief
- * write VLC for NumCoeff and TrailingOnes for Chroma DC
- ************************************************************************
- */
- int writeSyntaxElement_NumCoeffTrailingOnesChromaDC(SyntaxElement *se, DataPartition *dp)
- {
- static const 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}}
- };
- static const 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},
- { 0, 0, 0, 1, 1, 9, 8, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0}},
- //YUV444
- {{ 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}}
- };
- int yuv = img->yuv_format - 1;
- // se->value1 : numcoeff
- // se->value2 : numtrailingones
- se->len = lentab[yuv][se->value2][se->value1];
- se->inf = codtab[yuv][se->value2][se->value1];
- if (se->len == 0)
- {
- printf("ERROR: (numcoeff,trailingones) not valid: (%d, %d)n",
- se->value1, se->value2);
- exit(-1);
- }
- symbol2vlc(se);
- writeUVLC2buffer(se, dp->bitstream);
- if(se->type != SE_HEADER)
- dp->bitstream->write_flag = 1;
- #if TRACE
- if(dp->bitstream->trace_enabled)
- trace2out (se);
- #endif
- return (se->len);
- }
- /*!
- ************************************************************************
- * brief
- * write VLC for TotalZeros
- ************************************************************************
- */
- int writeSyntaxElement_TotalZeros(SyntaxElement *se, DataPartition *dp)
- {
- static const int lentab[TOTRUN_NUM][16] =
- {
- { 1,3,3,4,4,5,5,6,6,7,7,8,8,9,9,9},
- { 3,3,3,3,3,4,4,4,4,5,5,6,6,6,6},
- { 4,3,3,3,4,4,3,3,4,5,5,6,5,6},
- { 5,3,4,4,3,3,3,4,3,4,5,5,5},
- { 4,4,4,3,3,3,3,3,4,5,4,5},
- { 6,5,3,3,3,3,3,3,4,3,6},
- { 6,5,3,3,3,2,3,4,3,6},
- { 6,4,5,3,2,2,3,3,6},
- { 6,6,4,2,2,3,2,5},
- { 5,5,3,2,2,2,4},
- { 4,4,3,3,1,3},
- { 4,4,2,1,3},
- { 3,3,1,2},
- { 2,2,1},
- { 1,1},
- };
- static const int codtab[TOTRUN_NUM][16] =
- {
- {1,3,2,3,2,3,2,3,2,3,2,3,2,3,2,1},
- {7,6,5,4,3,5,4,3,2,3,2,3,2,1,0},
- {5,7,6,5,4,3,4,3,2,3,2,1,1,0},
- {3,7,5,4,6,5,4,3,3,2,2,1,0},
- {5,4,3,7,6,5,4,3,2,1,1,0},
- {1,1,7,6,5,4,3,2,1,1,0},
- {1,1,5,4,3,3,2,1,1,0},
- {1,1,1,3,3,2,2,1,0},
- {1,0,1,3,2,1,1,1,},
- {1,0,1,3,2,1,1,},
- {0,1,1,2,1,3},
- {0,1,1,1,1},
- {0,1,1,1},
- {0,1,1},
- {0,1},
- };
- int vlcnum = se->len;
- // se->value1 : TotalZeros
- se->len = lentab[vlcnum][se->value1];
- se->inf = codtab[vlcnum][se->value1];
- if (se->len == 0)
- {
- printf("ERROR: (TotalZeros) not valid: (%d)n",se->value1);
- exit(-1);
- }
- symbol2vlc(se);
- writeUVLC2buffer(se, dp->bitstream);
- if(se->type != SE_HEADER)
- dp->bitstream->write_flag = 1;
- #if TRACE
- if(dp->bitstream->trace_enabled)
- trace2out (se);
- #endif
- return (se->len);
- }
- /*!
- ************************************************************************
- * brief
- * write VLC for TotalZeros for Chroma DC
- ************************************************************************
- */
- int writeSyntaxElement_TotalZerosChromaDC(SyntaxElement *se, DataPartition *dp)
- {
- static const int lentab[3][TOTRUN_NUM][16] =
- {
- //YUV420
- {{ 1,2,3,3},
- { 1,2,2},
- { 1,1}},
- //YUV422
- {{ 1,3,3,4,4,4,5,5},
- { 3,2,3,3,3,3,3},
- { 3,3,2,2,3,3},
- { 3,2,2,2,3},
- { 2,2,2,2},
- { 2,2,1},
- { 1,1}},
- //YUV444
- {{ 1,3,3,4,4,5,5,6,6,7,7,8,8,9,9,9},
- { 3,3,3,3,3,4,4,4,4,5,5,6,6,6,6},
- { 4,3,3,3,4,4,3,3,4,5,5,6,5,6},
- { 5,3,4,4,3,3,3,4,3,4,5,5,5},
- { 4,4,4,3,3,3,3,3,4,5,4,5},
- { 6,5,3,3,3,3,3,3,4,3,6},
- { 6,5,3,3,3,2,3,4,3,6},
- { 6,4,5,3,2,2,3,3,6},
- { 6,6,4,2,2,3,2,5},
- { 5,5,3,2,2,2,4},
- { 4,4,3,3,1,3},
- { 4,4,2,1,3},
- { 3,3,1,2},
- { 2,2,1},
- { 1,1}}
- };
- static const int codtab[3][TOTRUN_NUM][16] =
- {
- //YUV420
- {{ 1,1,1,0},
- { 1,1,0},
- { 1,0}},
- //YUV422
- {{ 1,2,3,2,3,1,1,0},
- { 0,1,1,4,5,6,7},
- { 0,1,1,2,6,7},
- { 6,0,1,2,7},
- { 0,1,2,3},
- { 0,1,1},
- { 0,1}},
- //YUV444
- {{1,3,2,3,2,3,2,3,2,3,2,3,2,3,2,1},
- {7,6,5,4,3,5,4,3,2,3,2,3,2,1,0},
- {5,7,6,5,4,3,4,3,2,3,2,1,1,0},
- {3,7,5,4,6,5,4,3,3,2,2,1,0},
- {5,4,3,7,6,5,4,3,2,1,1,0},
- {1,1,7,6,5,4,3,2,1,1,0},
- {1,1,5,4,3,3,2,1,1,0},
- {1,1,1,3,3,2,2,1,0},
- {1,0,1,3,2,1,1,1,},
- {1,0,1,3,2,1,1,},
- {0,1,1,2,1,3},
- {0,1,1,1,1},
- {0,1,1,1},
- {0,1,1},
- {0,1}}
- };
- int vlcnum = se->len;
- int yuv = img->yuv_format - 1;
- // se->value1 : TotalZeros
- se->len = lentab[yuv][vlcnum][se->value1];
- se->inf = codtab[yuv][vlcnum][se->value1];
- if (se->len == 0)
- {
- printf("ERROR: (TotalZeros) not valid: (%d)n",se->value1);
- exit(-1);
- }
- symbol2vlc(se);
- writeUVLC2buffer(se, dp->bitstream);
- if(se->type != SE_HEADER)
- dp->bitstream->write_flag = 1;
- #if TRACE
- if(dp->bitstream->trace_enabled)
- trace2out (se);
- #endif
- return (se->len);
- }
- /*!
- ************************************************************************
- * brief
- * write VLC for Run Before Next Coefficient, VLC0
- ************************************************************************
- */
- int writeSyntaxElement_Run(SyntaxElement *se, DataPartition *dp)
- {
- static const int lentab[TOTRUN_NUM][16] =
- {
- {1,1},
- {1,2,2},
- {2,2,2,2},
- {2,2,2,3,3},
- {2,2,3,3,3,3},
- {2,3,3,3,3,3,3},
- {3,3,3,3,3,3,3,4,5,6,7,8,9,10,11},
- };
- static const int codtab[TOTRUN_NUM][16] =
- {
- {1,0},
- {1,1,0},
- {3,2,1,0},
- {3,2,1,1,0},
- {3,2,3,2,1,0},
- {3,0,1,3,2,5,4},
- {7,6,5,4,3,2,1,1,1,1,1,1,1,1,1},
- };
- int vlcnum = se->len;
- // se->value1 : run
- se->len = lentab[vlcnum][se->value1];
- se->inf = codtab[vlcnum][se->value1];
- if (se->len == 0)
- {
- printf("ERROR: (run) not valid: (%d)n",se->value1);
- exit(-1);
- }
- symbol2vlc(se);
- writeUVLC2buffer(se, dp->bitstream);
- if(se->type != SE_HEADER)
- dp->bitstream->write_flag = 1;
- #if TRACE
- if(dp->bitstream->trace_enabled)
- trace2out (se);
- #endif
- return (se->len);
- }
- /*!
- ************************************************************************
- * brief
- * write VLC for Coeff Level (VLC1)
- ************************************************************************
- */
- int writeSyntaxElement_Level_VLC1(SyntaxElement *se, DataPartition *dp, int profile_idc)
- {
- int level = se->value1;
- int sign = (level < 0 ? 1 : 0);
- int levabs = iabs(level);
- if (levabs < 8)
- {
- se->len = levabs * 2 + sign - 1;
- se->inf = 1;
- }
- else if (levabs < 16)
- {
- // escape code1
- se->len = 19;
- se->inf = 16 | ((levabs << 1) - 16) | sign;
- }
- else
- {
- int iMask = 4096, numPrefix = 0;
- int levabsm16 = levabs + 2032;
- // escape code2
- if ((levabsm16) >= 4096)
- {
- numPrefix++;
- while ((levabsm16) >= (4096 << numPrefix))
- {
- numPrefix++;
- }
- }
- iMask <<= numPrefix;
- se->inf = iMask | ((levabsm16 << 1) - iMask) | sign;
- /* Assert to make sure that the code fits in the VLC */
- /* make sure that we are in High Profile to represent level_prefix > 15 */
- if (numPrefix > 0 && !IS_FREXT_PROFILE( profile_idc ))
- {
- //error( "level_prefix must be <= 15 except in High Profilen", 1000 );
- se->len = 0x0000FFFF; // This can be some other big number
- return (se->len);
- }
- se->len = 28 + (numPrefix << 1);
- }
- symbol2vlc(se);
- writeUVLC2buffer(se, dp->bitstream);
- if(se->type != SE_HEADER)
- dp->bitstream->write_flag = 1;
- #if TRACE
- if(dp->bitstream->trace_enabled)
- trace2out (se);
- #endif
- return (se->len);
- }
- /*!
- ************************************************************************
- * brief
- * write VLC for Coeff Level
- ************************************************************************
- */
- int writeSyntaxElement_Level_VLCN(SyntaxElement *se, int vlc, DataPartition *dp, int profile_idc)
- {
- int level = se->value1;
- int sign = (level < 0 ? 1 : 0);
- int levabs = iabs(level) - 1;
- int shift = vlc - 1;
- int escape = (15 << shift);
- if (levabs < escape)
- {
- int sufmask = ~((0xffffffff) << shift);
- int suffix = (levabs) & sufmask;
- se->len = ((levabs) >> shift) + 1 + vlc;
- se->inf = (2 << shift) | (suffix << 1) | sign;
- }
- else
- {
- int iMask = 4096;
- int levabsesc = levabs - escape + 2048;
- int numPrefix = 0;
- if ((levabsesc) >= 4096)
- {
- numPrefix++;
- while ((levabsesc) >= (4096 << numPrefix))
- {
- numPrefix++;
- }
- }
- iMask <<= numPrefix;
- se->inf = iMask | ((levabsesc << 1) - iMask) | sign;
- /* Assert to make sure that the code fits in the VLC */
- /* make sure that we are in High Profile to represent level_prefix > 15 */
- if (numPrefix > 0 && !IS_FREXT_PROFILE( profile_idc ))
- {
- //error( "level_prefix must be <= 15 except in High Profilen", 1000 );
- se->len = 0x0000FFFF; // This can be some other big number
- return (se->len);
- }
- se->len = 28 + (numPrefix << 1);
- }
- symbol2vlc(se);
- writeUVLC2buffer(se, dp->bitstream);
- if(se->type != SE_HEADER)
- dp->bitstream->write_flag = 1;
- #if TRACE
- if(dp->bitstream->trace_enabled)
- trace2out (se);
- #endif
- return (se->len);
- }
- #if TRACE
- int bitcounter = 0;
- /*!
- ************************************************************************
- * brief
- * Write out a trace string on the trace file
- ************************************************************************
- */
- void trace2out(SyntaxElement *sym)
- {
- static
- int i, chars;
- if (p_trace != NULL)
- {
- putc('@', p_trace);
- chars = fprintf(p_trace, "%i", bitcounter);
- while(chars++ < 6)
- putc(' ',p_trace);
- chars += fprintf(p_trace, "%s", sym->tracestring);
- while(chars++ < 55)
- putc(' ',p_trace);
- // align bit pattern
- if(sym->len<15)
- {
- for(i=0 ; i<15-sym->len ; i++)
- fputc(' ', p_trace);
- }
- // print bit pattern
- bitcounter += sym->len;
- for(i=1 ; i<=sym->len ; i++)
- {
- if((sym->bitpattern >> (sym->len-i)) & 0x1)
- fputc('1', p_trace);
- else
- fputc('0', p_trace);
- }
- fprintf(p_trace, " (%3d) n",sym->value1);
- }
- fflush (p_trace);
- }
- void trace2out_cabac(SyntaxElement *sym)
- {
- int chars;
- if (p_trace != NULL)
- {
- putc('@', p_trace);
- chars = fprintf(p_trace, "%i", bitcounter);
- while(chars++ < 6)
- putc(' ',p_trace);
- chars += fprintf(p_trace, "%s", sym->tracestring);
- while(chars++ < 70)
- putc(' ',p_trace);
- fprintf(p_trace, " (%3d) n",sym->value1);
- }
- fflush (p_trace);
- bitcounter += sym->len;
- }
- #endif
- /*!
- ************************************************************************
- * brief
- * puts the less than 8 bits in the byte buffer of the Bitstream into
- * the streamBuffer.
- *
- * param
- * currStream: the Bitstream the alignment should be established
- *
- ************************************************************************
- */
- void writeVlcByteAlign(Bitstream* currStream, StatParameters *cur_stats)
- {
- if (currStream->bits_to_go < 8)
- { // trailing bits to process
- currStream->byte_buf = (currStream->byte_buf << currStream->bits_to_go) | (0xff >> (8 - currStream->bits_to_go));
- currStream->streamBuffer[currStream->byte_pos++] = currStream->byte_buf;
- cur_stats->bit_use_stuffingBits[img->type] += currStream->bits_to_go;
- currStream->bits_to_go = 8;
- }
- }