如何读标准和代码(H.264)

转自 http://bbs.chinavideo.org/viewthread.php?tid=4164&extra=page%3D1%26amp%3Bfilter%3Ddigest

首先,还是要弄清楚编解码的流程和 H.264 的关键技术,看白皮书就知道了,另外 H.264 综述类



的文章和别人的学位论文一般也会讲到;
其次其次,弄清楚代码的各个函数实现的功能,这个可以看看 JM 代码里各个函数前面的函数说明



最后最后,弄清楚标准各个章节讲的什么内容:这里只说重要的。第三章是名词解释,第四章是缩


略语,第五章是一些计算方式和运算符号的说明,第六章是与 H.264 相关的一些视频基础知识和 


H.264 中用到的一些过程推导,第七章是 NALU 及其以下语法结构的语法和语义(如果要知道码流


结构就要看这一章了),第八章是详细说明解码过程中某一个模块的功能怎么完成,第九章是熵编


码,附录 A 是关于 profile 和 level 的具体规定,附录 B 是关于如何从字节流中解析 NALU(


标准没有说明如何在 RTP 流中解析 NALU)。




     有了上面的基本知识,下面我们结合对码流的解析过程来讲讲怎么读标准:
1、如果是字节流的码流当然就首先要对字节流进行解析,这就要看附录 B 了;如果是 RTP 格式的


码流,那首先就要按 RFC3984 来解析了(标准没有规定 RTP 格式码流的解析过程);


2、字节流解析完后提取出来的就是 NALU 了,对 NALU 的解析就要看 7.3.1 小节了。第七章中黑


色的粗体字都是在码流中可能出现的语法元素,解码器的首要任务就是要对这些语法元素进行解析


。对于这些码流中的语法元素我们要进行解析必须知道三个问题:
(1)、什么时候存在于码流中?这样我们才能知道当前解析的是哪个语法元素;
(2)、采用什么样的熵编码方式?这样我们才能知道如何解析;
(3)、含义是什么?这样我们才知道解析出来之后用来干什么。
     三个问题的答案分别是:
(1)、有 if 条件关联的就是可能出现的,没有 if 条件关联的就是必然出现的。例如,7.3.1 小


节表中的 forbidden_zero_bit 就没有 if 条件关联,所以它必然出现在码流中;
(2)、每个语法表最后一列都对所在行语法元素的熵编码方式做了规定,而最后一列各个符号具体


是代表什么编码方式那就去看 7.2 小节最后的部分;
(3)、看 7.4 小节与语法表对应的语义部分,例如你查的语法表是 7.3.1,那么该语法表里出现


的语法元素的解释就在 7.4.1 小节中。


3、NALU 的前面三个语法元素所组成的一个字节我们称为 NALU 头,其余部分(也就是语法表 


7.3.1 中的其余部分)我们称为 NALU 体。对 NALU 体的解析要看 7.3.2 小节。因为 NALU 有很


多种类型,所以要针对 NALU 的不同类型去解析 NALU 体(表 7-1 说明了不同 NALU 对应的语法


表)。例如,如果当前的 NALU 是 SPS,那么当然就要看 7.3.1 小节;如果当前的 NALU 是 DPA


,那么当然就要看 7.3.2.9.1 小节了;


4、对于属于 VCL 的 NALU(哪些 NALU 是 VCL NALU 呢?如果你看了 nal_unit_type 的语义,


你就应该知道),例如表 7-1 中类型为 5 的 NALU,根据表 7-1 我们知道 NALU 体的语法表是 


7.3.2.8。而从 7.3.2.8 我们可以看到,对这种 NALU 的 NALU 体解析实际就是对片级语法进行解


析。语法表 7.3.2.8 显示片级语法解析首先要解析 slice_header()(这种带括号的表示是另一个


语法结构),那么 slice_header() 怎么解析呢?往下看,7.3.3 的所有内容都被第一行的 


slice_header() 包括在内,所以 7.3.3 就是对 slice_header() 这个语法层的码流规定;


5、按照语法表 7.3.2.8 解析完了 slice_header() 就该解析 slice_data() 了。下面以最常见


的 I 帧(CAVLC 熵编码、非 MBAFF)的解析过程为例简单描述怎么继续读标准。这时在码流中出现


的第一个 slice_data() 层的语法元素是语法表 7.3.4 中的 macroblock_layer(),也就是说直


接到了宏块层的语法解析,那就要又要看 7.3.5 小节了;


6、基于我们对编解码流程的了解,我们知道解码是一个预测值加残差得到重建图像的过程,那么我


们下面的解码过程就要分成两步走了:首先,得到预测值;其次,得到残差。基于我们对 H.264 关


键技术的了解,我们知道 intra 宏块(提醒:我们举的例子是 I 帧,因此解析的是 intra 宏块


)的预测值是需要使用到预测模式的,所以我们需要解析语法表 7.3.5 中的 mb_pred(mb_type) 


语法层,那么又去看 7.3.5.1 小节。按照 7.3.5.1 小节解析出宏块或块的预测方式后我们怎么计


算预测值呢?去看标准 8.3 小节;得到预测值后我们继续按照语法表 7.3.5 解析语法元素直到 


residual() 语法层,这就又要去看 7.3.5.3 小节;按照 7.3.5.3 小节解析出残差系数后我们如


何把它还原成真实的残差呢?去看标准 8.5 小节;


7、预测值和残差都有了,加起来就是解码图像了。解码的主要工作到此也算基本完成了。当然,上


面的过程中还会用到标准其他章节的相关内容(例如,8.5 小节会用到 5.7 小节中定义的 


InverseRasterScan),这就留给大家自己去学习了。




      上面讲了如何读标准,那么如何读代码呢?非常简单,因为你现在已经知道了代码中各个函


数所实现的功能以及标准各个章节所涉及的内容,那么你就该知道标准某个部分的内容与代码中的


哪个函数对应,因此对于你想详细了解实现过程的模块,对照标准去仔细啃那个函数吧。对于代码


中不明白的变量或者参数,把程序跑起来,看第 1 个 MB 解码时候该变量的值是多少,第 23 个 


MB 解码时候该变量的值是多少……多做几个观察值,注意不要选择特殊位置,然后总结一下规律,


这样你就自然能分析出该变量的作用和含义了。




      以上讲的是解码过程,编码过程就是解码的反过程,因此同理。








——天之骄子·firstime——
         2008年8月5日
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值