⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 vlc.cpp

📁 264的播放器
💻 CPP
📖 第 1 页 / 共 2 页
字号:

/*!
 ************************************************************************
 * \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 + -