`
jubincn
  • 浏览: 232511 次
  • 性别: Icon_minigender_1
  • 来自: 宁波
文章分类
社区版块
存档分类
最新评论

如何读H.264的标准和代码

 
阅读更多
原文:bbs.chinavideo.org/viewthread.php?tid=4164

首先,还是要弄清楚编解码的流程和 H.264 的关键技术,看白皮书就知道了,另外 H.264 综述类的文章和别人的学位论文一般也会讲到; 其次,弄清楚代码的各个函数实现的功能,这个可以看看 JM 代码里各个函数前面的函数说明; 最后,弄清楚标准各个章节讲的什么内容:这

首先,还是要弄清楚编解码的流程和 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 解码时候该变量的值是多少……多做几个观察值,注意不要选择特殊位置,然后总结一下规律,这样你就自然能分析出该变量的作用和含义了。

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

分享到:
评论

相关推荐

    H.264学习指南(学习方法介绍;学习资源获取;如何读标准和代码)

    网上收集来的h.264的学习指南,包括学习建议、学习资源和如何读标准和代码,相信对h.264的学习者,尤其是初学者会有帮助

    如何读标准和JM代码

    有人写的关于如何读JM程序的一个简单说明

    linux网路编程 中文 23M 版

    1.2.3 POSIX 标准.....................................................4 1.3 Linux 与 U N I X 的异同.................................................. 5 1 . 4 操作系统类型选择和内核版本的选择..............

    精通Visual C++视频音频编解码技术.part3

    ”(第3章至第7章)重点讲解MPEG-2、H.263、MPEG-4、H.264等视频标准的 编码、解码技术;“音频篇”(第8章至第14章),重点讲解G.711、G.721、 G.723、GSM、G.728和G.729等语音编码的原理和实现方法;“案例篇”(第 ...

    精通Visual C++视频音频编解码技术.part5

    ”(第3章至第7章)重点讲解MPEG-2、H.263、MPEG-4、H.264等视频标准的 编码、解码技术;“音频篇”(第8章至第14章),重点讲解G.711、G.721、 G.723、GSM、G.728和G.729等语音编码的原理和实现方法;“案例篇”(第 ...

    精通Visual C++视频音频编解码技术.part4

    ”(第3章至第7章)重点讲解MPEG-2、H.263、MPEG-4、H.264等视频标准的 编码、解码技术;“音频篇”(第8章至第14章),重点讲解G.711、G.721、 G.723、GSM、G.728和G.729等语音编码的原理和实现方法;“案例篇”(第 ...

    精通Visual C++视频音频编解码技术.part6

    ”(第3章至第7章)重点讲解MPEG-2、H.263、MPEG-4、H.264等视频标准的 编码、解码技术;“音频篇”(第8章至第14章),重点讲解G.711、G.721、 G.723、GSM、G.728和G.729等语音编码的原理和实现方法;“案例篇”(第 ...

    精通Visual C++视频音频编解码技术.part1

    ”(第3章至第7章)重点讲解MPEG-2、H.263、MPEG-4、H.264等视频标准的 编码、解码技术;“音频篇”(第8章至第14章),重点讲解G.711、G.721、 G.723、GSM、G.728和G.729等语音编码的原理和实现方法;“案例篇”(第 ...

    精通Visual C++视频音频编解码技术.part2

    ”(第3章至第7章)重点讲解MPEG-2、H.263、MPEG-4、H.264等视频标准的 编码、解码技术;“音频篇”(第8章至第14章),重点讲解G.711、G.721、 G.723、GSM、G.728和G.729等语音编码的原理和实现方法;“案例篇”(第 ...

    你必须知道的495个C语言问题(PDF)

    2.9 怎样从/向数据文件读/写结构? . . . . . . . . . . . . . . . . . . . 9 2.10 我的编译器在结构中留下了空洞, 这导致空间浪费而且无法与外 部数据文件进行”二进制” 读写。能否关掉填充, 或者控制结构域 的...

    多线程编程指南(系统描述了线程标准 线程同步 多线程编程原则 等)

    符合多线程标准16 多线程的益处17 提高应用程序的响应 17 有效使用多处理器17 改进程序结构17 占用较少的系统资源17 结合线程和RPC(远程过程调用)18 多线程概念18 并发性和并行性 18 多线程结构一览 18 线程调度19...

    Solaris链接程序和库指南

    符合多线程标准 ................................................................................................................................. 16 多线程的益处 ..........................................

    多线程编程指南PDF

    符合多线程标准.........................................................................................................................................16 多线程的益处.....................................

    C语言程序设计标准教程

    在操作系统中,把外部设备也看作是一个文件来进行管理,把它们的输入、输出等同于对磁盘文件的读和写。 通常把显示器定义为标准输出文件, 一般情况下在屏幕上显示有关信息就是向标准输出文件输出。如前面经常使用的...

    VC++6.0核心编程源码.rar

    如果你认为WinError.h中的任何代码都不能正确地反映该错误的性质,那么你可以创建你自己的代码。错误代码是个32位的数字,它可以划分成下表所示的各个域。 位 31-30 29 28 27-16 15-0 内容 严重性 Microsoft/ ...

    软件工程与软件测试自动化教程

    1 有效率的模块级源文件编辑和安全的代码修改 5. 2. 2 帮助代码理解. 检查和通过 5. 2. 3 为单元和系统集成测试增加有序性 5. 2. 4 基于多重度量的复杂性分析的测试计划 5. 2. 5 测试覆盖分析与工程文件(. ...

    xcyx.smart

    02h 31h 31h,30h,46h,36h 30h,34h 33h,34h,31h,32h,43h,44h,41h,42h 03h 34h,39h PLC返回 ACK (06H) 接受正确 NAK (15H) 接受错误 3、位设备强制置位/复位 FORCE ON置位 始 命令 地址 终 和校验 STX CMD ADDRESS ETX...

    linux内核 0.11版本源码 带中文注释

    #include <unistd.h> // *.h 头文件所在的默认目录是include/,则在代码中就不用明确指明位置。 // 如果不是UNIX 的标准头文件,则需要指明所在的目录,并用双引号括住。 // 标准符号常数与类型文件。定义了各种...

Global site tag (gtag.js) - Google Analytics