【编解码】从零开始写H264解码器(3) 描述子

1. 引言

在根据起始码找到NALU的位置和获取到NALU的种类之后,接下来我们需要进行的就是对每个NALU的内容进行解析。根据h264的白皮书协议,按照规定的的方法从码流中把协议里的每个参数解析出来,解出来之后再按照参数的含义的作用进行图像的复原,得到YUV图。
所以,这一节的关键点就在于,怎么进行白皮书中参数的解析。
(以T-REC-H.264-201003-I!!PDF-E.pdf为例,最新的协议请到ITU官网下载)

2. 描述子

上一节中我们得到了NALU,并知道NALU有多种类型,那我们打开白皮书,先看一下其中很重要的SPS,sequence parameter set,来看一看这些NALU的内部究竟是些什么。
翻到 43面 7.3.2.1.1 Sequence parameter set data syntax
在这里插入图片描述
可以看到,表格一共分三列:

  • 第一列就是我们要解析的参数,也就是我们需要的结果,profile类别,level类别等等
  • 第二列 C是 category种类,指明了一些参数的包含关系。
  • 第三列 就是最重要的一列:描述子,这一列说明了,我们究竟要用什么办法去解析这个bit流,怎么样的去读取这些0,1的数据,来得到我们需要的参数。

可能看到这里大家会有些疑惑,就这么个简单的表达式,就足够描述所有h264中的编码方式了吗?
别急,让我们先把这些第三列的描述子浏览一遍,看一下有没有什么规律。

简单的过了一遍从42面开始的一些常用NAL的 Syntax in tabular form,我们应该很快就能发现,其实第三列的Descriptor描述子,有很多是一样的,比如u(2), u(5), 我们都可以把他们归为u(n)一类。
总体看下来,一共只有固定几类: f(n), u(n), b(n), ue(v), se(v)……
这些描述子代表了什么?
怎么去解析?
别急,白皮书里同样给了所用到的描述子的所有介绍:
在这里插入图片描述
可以看出,一共分了 10类,对应着不同的解码方式。

  • ae(v):基于上下文自适应的二进制算术熵编码
  • b(8):读进连续的 8 个比特
  • ce(v):基于上下文自适应的可变长熵编码
  • f(n):读进连续的 n 个比特
  • i(n):读进连续的若干比特,并把它们解释为有符号整数
  • me(v):映射指数 Golomb 熵编码
  • se(v):有符号指数 Golomb 熵编码
  • te(v):截断指数 Golomb 熵编码
  • u(n):读进连续的若干比特,并将它们解释为无符号整数
  • ue(v):无符号指数 Golomb 熵编码

其实在我看来,按照大的解码方式来分,我们可以把所有的描述子分为4大类:

方式描述子
二进制读取b(8),f(n),i(n),u(n)
熵编码- 指数哥伦布me(v),se(v),te(v),ue(v)
熵编码- CAVLCce(v)
熵编码- CABACae(v)

2.1 二进制读取

这一类是最简单的解析,从左往右读取n位二进制数,把它解析成一个有符号数或者无符号数即可。
其中,n可能是一个固定值,也可能是根据前面解析过的参数计算出来的值。
比如 下图中的 frame_num,描述子是u(v), 即连续读取v个二进制bit,解析成为无符号数。
具体v的值,就是根据之前解析SPS的时候,得到的log2_max_frame_num_minu4 的 值来确定的。
在这里插入图片描述

2.2 指数哥伦布

这一类包含: me(v),se(v),te(v),ue(v)。
读取的长度是不固定的,但是解析方法是一样的,解出来的值也是确定的。
其中,ue(v)和 se(v)用的较多,me(v)和te(v)使用较少。
具体的解析会在后面文章介绍。

2.3 CAVLC

CAVLC是baseline的内容,是一定会有的,我们后面会重点学习一下熵编码 CAVLC的编解码方法

2.3 CABAC

CABAC是扩展方法,效率更高但是编解码流程更复杂。这个之后也会学习。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值