文档章节

JM中的语法函数分析

zhangyujsj
 zhangyujsj
发布于 2015/04/19 17:07
字数 934
阅读 46
收藏 0

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
}



© 著作权归作者所有

zhangyujsj
粉丝 24
博文 358
码字总数 224241
作品 0
广州
私信 提问
@Jackarain 你不是拿c++搞视频嘛,这里有c和dsp版本的。

我先给出jm版本的代码,这不是我写的: 对应上述函数,分成不同模式,我拆分了,这些是我写的,其中一个是: 当然上述代码也没有考虑效率,只是为了说明逻辑,因为最终需要下面的代码,也是我...

中山野鬼
2013/09/12
859
10
机器学习-GBDT算法总结与源码分析

最近在看Kaggle2014年的一个比赛--Display Advertising Challenge。三个台湾人得了比赛的第一名,他们使用的是FFM算法(这个后面再做总结),在他们比赛的代码中,使用了GBDT算法进行了特征的处...

horizonheart
2017/12/12
0
0
集成学习之Boosting —— Gradient Boosting原理

集成学习之Boosting —— AdaBoost原理 集成学习之Boosting —— AdaBoost实现 集成学习之Boosting —— Gradient Boosting原理 集成学习之Boosting —— Gradient Boosting实现 上一篇介绍了...

massquantity
2018/06/13
0
0
轻量级高性能移动web框架--Javascript Mobile Framework

JM(Javascript Mobile Framework) 是新一代轻量级高性能移动web框架,由腾讯前端团队经项目实践积累沉淀而成。为拥抱移动互联网全新设计,专注为移动web项目,整个框架压缩后只有36K。 新的移...

叶秀兰
2014/09/01
4.6K
0
音视频技术--H.264代码与标准如何对应

总是有人说自己把代码和标准对应不起来。其实是因为你要么不知道标准各个章节讲的什么,要么不知道代码中各个函数的功能,或者两者都不知道。今天再以 X264 的帧内编码为例让大家体会一下读代...

技术小阿哥
2017/11/27
0
0

没有更多内容

加载失败,请刷新页面

加载更多

java通过ServerSocket与Socket实现通信

首先说一下ServerSocket与Socket. 1.ServerSocket ServerSocket是用来监听客户端Socket连接的类,如果没有连接会一直处于等待状态. ServetSocket有三个构造方法: (1) ServerSocket(int port);...

Blueeeeeee
今天
6
0
用 Sphinx 搭建博客时,如何自定义插件?

之前有不少同学看过我的个人博客(http://python-online.cn),也根据我写的教程完成了自己个人站点的搭建。 点此:使用 Python 30分钟 教你快速搭建一个博客 为防有的同学不清楚 Sphinx ,这...

王炳明
昨天
5
0
黑客之道-40本书籍助你快速入门黑客技术免费下载

场景 黑客是一个中文词语,皆源自英文hacker,随着灰鸽子的出现,灰鸽子成为了很多假借黑客名义控制他人电脑的黑客技术,于是出现了“骇客”与"黑客"分家。2012年电影频道节目中心出品的电影...

badaoliumang
昨天
15
0
很遗憾,没有一篇文章能讲清楚线程的生命周期!

(手机横屏看源码更方便) 注:java源码分析部分如无特殊说明均基于 java8 版本。 简介 大家都知道线程是有生命周期,但是彤哥可以认真负责地告诉你网上几乎没有一篇文章讲得是完全正确的。 ...

彤哥读源码
昨天
16
0
jquery--DOM操作基础

本文转载于:专业的前端网站➭jquery--DOM操作基础 元素的访问 元素属性操作 获取:attr(name);$("#my").attr("src"); 设置:attr(name,value);$("#myImg").attr("src","images/1.jpg"); ......

前端老手
昨天
7
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部