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

📄 uvlc.c

📁 h.264/avc 视频编码程序,实现分数像素匹配功能,非原创.
💻 C
📖 第 1 页 / 共 2 页
字号:
  Bitstream *currStream = currSlice->partArr[0].bitstream;
  int *partMap = assignSE2partition[currSlice->dp_mode];
  int frame_bitoffset = currStream->frame_bitoffset = 0;
  SyntaxElement sym;
  int dummy;
  byte *buf = currStream->streamBuffer;

  int len, info;
  int newframe = 0;   //WYK: Oct. 8, 2001, change the method to find a new frame

  memset (buf, 0xff, MAX_CODED_FRAME_SIZE);   // this prevents a buffer full with zeros
  currStream->bitstream_length = GetOneSliceIntoSourceBitBuffer(img, inp, buf);
  if (currStream->bitstream_length > 4)  // More than just a start code
  {
    sym.type = SE_HEADER;
#if TRACE
    strncpy(sym.tracestring, "\nHeaderinfo", TRACESTRING_SIZE);
#endif
    if(img->type == B_IMG_1 || img->type == B_IMG_MULT)
      dP = &(currSlice->partArr[partMap[SE_BFRAME]]);
    else
      dP = &(currSlice->partArr[partMap[sym.type]]);
    len =  GetVLCSymbol (buf, frame_bitoffset, &info, currStream->bitstream_length);
#if TRACE
    tracebits("Startcode", len, info, 0, 0);
#endif

    currStream->frame_bitoffset +=len;

    // read the slice header
    dummy = SliceHeader(img,inp);

    //WYK: Oct. 8, 2001, change the method to find a new frame
    if(img->tr != img->tr_old)
      newframe = 1;
    else 
      newframe = 0;
    img->tr_old = img->tr;
    
    // if the TR of current slice is not identical to the TR  of previous received slice, we have a new frame
    if(newframe)
      return SOP;
    else
      return SOS;

  }
  else    // less than four bytes in file -> cannot be a slice
    return EOS;
  return 0;
}


/*!
 ************************************************************************
 * \brief
 *    read next UVLC codeword from UVLC-partition and
 *    map it to the corresponding syntax element
 ************************************************************************
 */
int readSyntaxElement_UVLC(SyntaxElement *sym, struct img_par *img, struct inp_par *inp, 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 (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));

#if TRACE
  tracebits(sym->tracestring, sym->len, sym->inf, sym->value1, sym->value2);
#endif

  return 1;
}

/*!
 ************************************************************************
 * \brief
 *    Check if there are symbols for the next MB
 ************************************************************************
 */
int uvlc_startcode_follows(struct img_par *img, struct inp_par *inp)
{
  Slice *currSlice = img->currentSlice;
  int dp_Nr = assignSE2partition[currSlice->dp_mode][SE_MBTYPE];
  DataPartition *dP = &(currSlice->partArr[dp_Nr]);
  Bitstream   *currStream = dP->bitstream;
  byte *buf = currStream->streamBuffer;
  int frame_bitoffset = currStream->frame_bitoffset;
  int info;

  if (-1 == GetVLCSymbol (buf, frame_bitoffset, &info, currStream->bitstream_length))
    return TRUE;
  else
    return FALSE;
}


#ifdef _EXP_GOLOMB
/*!
 ************************************************************************
 * \brief
 *  Moves the read pointer of the partition forward by one symbol
 *
 * \param byte buffer[]
 *    containing VLC-coded data bits
 * \param int totbitoffset
 *    bit offset from start of partition
 * \param int type
 *    expected data type (Partiotion ID)
 * \return  int info, len
 *    Length and Value of the next symbol
 *
 * \note
 *    As in both nal_bits.c and nal_part.c all data of one partition, slice,
 *    picture was already read into a buffer, there is no need to read any data
 *    here again.
 * \par
 *    GetVLCInfo was extracted because there should be only one place in the
 *    source code that has knowledge about symbol extraction, regardless of
 *    the number of different NALs.
 * \par
 *    This function could (and should) be optimized considerably
 * \par
 *    If it is ever decided to have different VLC tables for different symbol
 *    types, then this would be the place for the implementation
 * \par
 *    An alternate VLC table is implemented based on exponential Golomb codes.
 *    The define _EXP_GOLOMB selects between the UVLC and the exponential Golomb codes.
 *    The encoder must have a matching define selected.
 *  
 ************************************************************************
 */
int GetVLCSymbol (byte buffer[],int totbitoffset,int *info, int bytecount)
{

  register int inf;
  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;
  int info_bit;

  byteoffset= totbitoffset/8;
  bitoffset= 7-(totbitoffset%8);
  ctr_bit = (buffer[byteoffset] & (0x01<<bitoffset));   // set up control bit

  len=1;
  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));
  }
    // make infoword
  inf=0;                          // shortest possible code is 1, then info is always 0
  for(info_bit=0;(info_bit<(len-1)); info_bit++)
  {
    bitcounter++;
    bitoffset-=1;
    if (bitoffset<0)
    {                 // finished with current byte ?
      bitoffset=bitoffset+8;
      byteoffset++;
    }
    if (byteoffset > bytecount)
    {
      return -1;
    }
    inf=(inf<<1);
    if(buffer[byteoffset] & (0x01<<(bitoffset)))
      inf |=1;
  }

  *info = inf;
  return bitcounter;           // return absolute offset in bit from start of frame
}
#else
/*!
 ************************************************************************
 * \brief
 *  Moves the read pointer of the partition forward by one symbol
 *
 * \param byte buffer[]
 *    containing VLC-coded data bits
 * \param int totbitoffset
 *    bit offset from start of partition
 * \param int type
 *    expected data type (Partiotion ID)
 * \return  int info, len
 *    Length and Value of the next symbol
 *
 * \note
 *    As in both nal_bits.c and nal_part.c all data of one partition, slice,
 *    picture was already read into a buffer, there is no need to read any data
 *    here again.
 * \par
 *    GetVLCInfo was extracted because there should be only one place in the
 *    source code that has knowledge about symbol extraction, regardless of
 *    the number of different NALs.
 * \par
 *    This function could (and should) be optimized considerably
 * \par
 *    If it is ever decided to have different VLC tables for different symbol
 *    types, then this would be the place for the implementation
 ************************************************************************
 */
int GetVLCSymbol (byte buffer[],int totbitoffset,int *info, int bytecount)
{

  register int inf;
  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;

  byteoffset= totbitoffset/8;
  bitoffset= 7-(totbitoffset%8);
  ctr_bit = (buffer[byteoffset] & (0x01<<bitoffset));   // set up control bit

  inf=0;                          // shortest possible code is 1, then info is always 0

  while (ctr_bit==0)
  {                 // repeate until next 0, ref. VLC
    bitoffset-=2;           // from MSB to LSB
    if (bitoffset<0)
    {                 // finish with current byte ?
      bitoffset=bitoffset+8;
      byteoffset++;
    }

    ctr_bit=buffer[byteoffset] & (0x01<<(bitoffset));

    // make infoword

    if(bitoffset>=7)                  // first bit in new byte
      if (buffer[byteoffset-1] & (0x01))        // check last (info)bit of last byte
        inf = ((inf << 1) | 0x01);          // multiply with 2 and add 1, ref VLC
      else
        inf = (inf << 1);             // multiply with 2

    else
      if (buffer[byteoffset] & (0x01<<(bitoffset+1))) // check infobit
        inf = ((inf << 1) | 0x01);
      else
        inf = (inf << 1);
    bitcounter+=2;
    if (byteoffset > bytecount)
    {
      return -1;
    }
  }
  *info = inf;
  return bitcounter;           // return absolute offset in bit from start of frame
}
#endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -