📄 vlc.cpp
字号:
/*!
************************************************************************
* \file vlc.c
*
* \brief
* VLC support 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>
* - Gabi Blaettermann <blaetter@hhi.de>
************************************************************************
*/
#include "contributors.h"
#include <stdlib.h>
#include <math.h>
#include <string.h>
#include <assert.h>
#include "global.h"
#include "vlc.h"
#include "elements.h"
#include "macroblock.h"
int UsedBits; // for internal statistics, is adjusted by se_v, ue_v, u_1
// Note that all NA values are filled with 0
/*!
*************************************************************************************
* \brief
* ue_v, reads an ue(v) syntax element, the length in bits is stored in
* the global UsedBits variable
*
* \param tracestring
* the string for the trace file
*
* \param bitstream
* the stream to be read from
*
* \return
* the value of the coded syntax element
*
*************************************************************************************
*/
int ue_v (char *tracestring, Bitstream *bitstream)
{
SyntaxElement symbol, *sym=&symbol;
assert (bitstream->streamBuffer != NULL);
sym->type = SE_HEADER;
sym->mapping = linfo_ue; // Mapping rule
readSyntaxElement_VLC (sym, bitstream);
UsedBits+=sym->len;
return sym->value1;
}
/*!
*************************************************************************************
* \brief
* ue_v, reads an se(v) syntax element, the length in bits is stored in
* the global UsedBits variable
*
* \param tracestring
* the string for the trace file
*
* \param bitstream
* the stream to be read from
*
* \return
* the value of the coded syntax element
*
*************************************************************************************
*/
int se_v (char *tracestring, Bitstream *bitstream)
{
SyntaxElement symbol, *sym=&symbol;
assert (bitstream->streamBuffer != NULL);
sym->type = SE_HEADER;
sym->mapping = linfo_se; // Mapping rule: signed integer
readSyntaxElement_VLC (sym, bitstream);
UsedBits+=sym->len;
return sym->value1;
}
/*!
*************************************************************************************
* \brief
* ue_v, reads an u(v) syntax element, the length in bits is stored in
* the global UsedBits variable
*
* \param LenInBits
* length of the syntax element
*
* \param tracestring
* the string for the trace file
*
* \param bitstream
* the stream to be read from
*
* \return
* the value of the coded syntax element
*
*************************************************************************************
*/
int u_v (int LenInBits, char*tracestring, Bitstream *bitstream)
{
SyntaxElement symbol, *sym=&symbol;
assert (bitstream->streamBuffer != NULL);
sym->type = SE_HEADER;
sym->mapping = linfo_ue; // Mapping rule
sym->len = LenInBits;
readSyntaxElement_FLC (sym, bitstream);
UsedBits+=sym->len;
return sym->inf;
};
/*!
*************************************************************************************
* \brief
* ue_v, reads an u(1) syntax element, the length in bits is stored in
* the global UsedBits variable
*
* \param tracestring
* the string for the trace file
*
* \param bitstream
* the stream to be read from
*
* \return
* the value of the coded syntax element
*
*************************************************************************************
*/
Boolean u_1 (char *tracestring, Bitstream *bitstream)
{
assert (bitstream->streamBuffer != NULL);
int frame_bitoffset = bitstream->frame_bitoffset;
byte *buf = bitstream->streamBuffer;
int BitstreamLengthInBytes = bitstream->bitstream_length;
long byteoffset; // byte from start of buffer
int bitoffset; // bit from start of byte
UsedBits++;
byteoffset= frame_bitoffset>>3;
bitoffset= 7-(frame_bitoffset & 0x0007);
bitstream->frame_bitoffset++;
if((buf[byteoffset] & (0x01<<bitoffset))>>bitoffset)
return TRUE;
else
return FALSE;
// return (Boolean)u_v (1, tracestring, bitstream);
}
/*!
************************************************************************
* \brief
* mapping rule for ue(v) syntax elements
* \par Input:
* lenght and info
* \par Output:
* number in the code table
************************************************************************
*/
void linfo_ue(int len, int info, int *value1, int *dummy)
{
*value1 = (int)pow(2,(len>>1))+info-1;
}
/*!
************************************************************************
* \brief
* mapping rule for se(v) syntax elements
* \par Input:
* lenght and info
* \par Output:
* signed mvd
************************************************************************
*/
void linfo_se(int len, int info, int *value1, int *dummy)
{
int n;
n = (int)pow(2,(len>>1))+info;//-1;
*value1 = n>>1 ;//(n+1)/2;
if(((n-1) & 0x01)==0) // lsb is signed bit
*value1 = -*value1;
}
/*!
************************************************************************
* \par Input:
* lenght and info
* \par Output:
* cbp (intra)
************************************************************************
*/
void linfo_cbp_intra(int len,int info,int *cbp, int *dummy)
{
int cbp_idx;
linfo_ue(len,info,&cbp_idx,dummy);
*cbp=NCBP[cbp_idx][0];
}
/*!
************************************************************************
* \par Input:
* lenght and info
* \par Output:
* cbp (inter)
************************************************************************
*/
void linfo_cbp_inter(int len,int info,int *cbp, int *dummy)
{
int cbp_idx;
linfo_ue(len,info,&cbp_idx,dummy);
*cbp=NCBP[cbp_idx][1];
}
/*!
************************************************************************
* \brief
* read next UVLC codeword from UVLC-partition and
* map it to the corresponding syntax element
************************************************************************
*/
int readSyntaxElement_VLC(SyntaxElement *sym, Bitstream *currStream)
{
int frame_bitoffset = currStream->frame_bitoffset;
byte *buf = currStream->streamBuffer;
int BitstreamLengthInBytes = currStream->bitstream_length;
sym->len = GetVLCSymbol (buf, frame_bitoffset, &(sym->inf), BitstreamLengthInBytes);
if (sym->len == -1)
return -1;
currStream->frame_bitoffset += sym->len;
sym->mapping(sym->len,sym->inf,&(sym->value1),&(sym->value2));
return 1;
}
/*!
************************************************************************
* \brief
* read next UVLC codeword from UVLC-partition and
* map it to the corresponding syntax element
************************************************************************
*/
int readSyntaxElement_UVLC(SyntaxElement *sym, struct datapartition *dP)
{
Bitstream *currStream = dP->bitstream;
return (readSyntaxElement_VLC(sym, currStream));
}
/*!
************************************************************************
* \brief
* read next VLC codeword for 4x4 Intra Prediction Mode and
* map it to the corresponding Intra Prediction Direction
************************************************************************
*/
int readSyntaxElement_Intra4x4PredictionMode(SyntaxElement *sym, struct datapartition *dP)
{
Bitstream *currStream = dP->bitstream;
int frame_bitoffset = currStream->frame_bitoffset;
byte *buf = currStream->streamBuffer;
int BitstreamLengthInBytes = currStream->bitstream_length;
sym->len = GetVLCSymbol_IntraMode (buf, frame_bitoffset, &(sym->inf), BitstreamLengthInBytes);
if (sym->len == -1)
return -1;
currStream->frame_bitoffset += sym->len;
sym->value1 = sym->len == 1 ? -1 : sym->inf;
return 1;
}
int GetVLCSymbol_IntraMode (byte buffer[],int totbitoffset,int *info, 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
unsigned char *v;
unsigned int b;
int c;
byteoffset = totbitoffset>>3;
bitoffset = 7-(totbitoffset&7);
ctr_bit = (buffer[byteoffset] & (0x01<<bitoffset)); // set up control bit
//First bit
if (ctr_bit)
{
*info = 0;
return 1;
}
bitoffset--;
if (byteoffset > bytecount)
{
return -1;
}
v = buffer+byteoffset;
b = (v[0]<<24) | (v[1]<<16) | (v[2]<<8) | v[3];
c = bitoffset + 25;
*info = (b>>(c-3)) & msk[3];
return 4; // 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 no more bits available
************************************************************************
*/
bool 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>>3;
bitoffset= 7-(totbitoffset&7);
assert (byteoffset<bytecount);
// there is more until we're in the last byte
if (byteoffset<(bytecount-1)) return FALSE;
// read one bit
ctr_bit = (buffer[byteoffset] & (0x01<<bitoffset));
// a stop bit has to be one
if (ctr_bit==0) return FALSE;
bitoffset--;
while (bitoffset>=0)
{
ctr_bit = (buffer[byteoffset] & (0x01<<bitoffset)); // set up control bit
if (ctr_bit>0)
return FALSE;
bitoffset--;
}
return TRUE;
}
/*!
************************************************************************
* \brief
* Check if there are symbols for the next MB
************************************************************************
*/
int uvlc_startcode_follows(struct img_par *img, 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)
{
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;
unsigned char *v;
unsigned int b;
int c;
byteoffset= totbitoffset>>3;
bitoffset= 7-(totbitoffset &7);
ctr_bit = (buffer[byteoffset] & (0x01<<bitoffset)); // set up control bit
len=0;
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));
}
bitoffset--;
if (byteoffset > bytecount)
{
return -1;
}
v = buffer+byteoffset;
b = (v[0]<<24) | (v[1]<<16) | (v[2]<<8) | v[3];
c = bitoffset + 25;
*info = (b>>(c-len)) & msk[len];
bitcounter = bitcounter+len;
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;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -