JM中的语法函数分析

1 在H.264的标准文档中,定义了如下的函数用来处理语法元素:

如下描述符规定了每个语法元素的解析处理。对于某些语法元素,需要使用通过竖线分开的两个描述符。在
这些情况下,左边的描述符在entropy_coding_mode_flag 等于0 的时候使用,右边的描述符在
entropy_coding_mode_flag等于1的时候使用。
— ae(v):上下文自适应算术熵编码语法元素。该描述符的解析过程在9.3节中规定。
— b(8):任意形式的8比特字节。该描述符的解析过程通过函数read_bits( 8 )的返回值来规定。
— ce(v):左位在先的上下文自适应可变长度熵编码语法元素。该描述符的解析过程在9.2节中规定。
— f(n):n位固定模式比特串(由左至右),左位在先, 该描述符的解析过程通过函数read_bits( n )的返
回值来规定。
— i(n):使用n比特的有符号整数。在语法表中,如果n是‘v’,其比特数由其它语法元素值确定。解析
过程由函数read_bits(n)的返回值规定,该返回值用最高有效位在前的2的补码表示。

— me(v):映射的指数哥伦布码编码的语法元素,左位在先。解析过程在9.1中定义。
— se(v):有符号整数指数哥伦布码编码的语法元素位在先。解析过程在9.1中定义。
— te(v):舍位指数哥伦布码编码语法元素,左位在先。解析过程在9.1中定义。
— u(n):n位无符号整数。在语法表中,如果n是‘v’,其比特数由其它语法元素值确定。解析过程由函
数read_bits(n)的返回值规定,该返回值用最高有效位在前的二进制表示。
— ue(v):无符号整数指数哥伦布码编码的语法元素,左位在先。解析过程在9.1中定义。

2 在JM代码中,这些函数的具体实现如下,下面我们逐个来分析下。

1) u(v)语法元素

/*!
 *************************************************************************************
 * \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) // 语法元素的长度(单位是位),给trace文件的字符串,要读入的码流;函数的返回值为编码的语法元素的值
{
  SyntaxElement symbol, *sym=&symbol;

  assert (bitstream->streamBuffer != NULL);
  sym->type = SE_HEADER;
  sym->mapping = linfo_ue;   // Mapping rle // mapping是一个函数指针成员
  sym->len = LenInBits;
  SYMTRACESTRING(tracestring);
  readSyntaxElement_FLC (sym, bitstream);
  UsedBits+=sym->len;
  return sym->inf;
};

看在sps的语法元素profile_idc的解析中是如何调用的:

sps->profile_idc                            = u_v  (8, "SPS: profile_idc"                           , s); 

我们来分析下这个readSyntaxElement_FLC(sym,bitstream);这个函数:

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

#if TRACE
  tracebits2(sym->tracestring, sym->len, sym->inf);
#endif

  return 1;
}

分析下GetBits这个函数:

/*!
 ************************************************************************
 * \brief
 *  Reads bits from the bitstream buffer
 *
 * \param buffer
 *    containing VLC-coded data bits
 * \param totbitoffset
 *    bit offset from start of partition
 * \param info
 *    returns value of the read bits
 * \param bytecount
 *    total bytes in bitstream
 * \param numbits
 *    number of bits to read
 *
 ************************************************************************
 */
int GetBits (byte buffer[],int totbitoffset,int *info, int bytecount, int numbits)
{
  register int inf;
  long byteoffset;      // byte from start of buffer 字节偏移
  int bitoffset;      // bit from start of byte 字节内位偏移
  int bitcounter=numbits;
  byteoffset= totbitoffset/8;
  bitoffset= 7-(totbitoffset%8);

  inf=0;
  while (numbits)
  {
    inf <<=1;
    inf |= (buffer[byteoffset] & (0x01<<bitoffset))>>bitoffset;
    numbits--;
    bitoffset--;
    if (bitoffset < 0)
    {
      byteoffset++;
      bitoffset += 8;
      if (byteoffset > bytecount)
      {
        return -1;
      }
    }
  }

  *info = inf;
  return bitcounter;           // return absolute offset in bit from start of frame
}



转载于:https://my.oschina.net/u/1024767/blog/403556

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值