视频编解码学习之路(H264)

学习视频编解码技术很难吗?视频编解码技术的未来是什么?

    明了的说,无论是软件还是硬件设计,视频编解码技术有很多难点,都需要很长一段时间积累才行。

从一开始接触MPEG-2到最新的H.264标准,可算走过了一段心酸之路。
    90 年代以来,随着internet和数字通信的迅猛发展,视频编解码技术在通信和广播领域获得了日益广泛的应用,特别是在数字电视系统发展中更是展露锋芒。
    从 1984 年 CCITT公布第一个视频编码国际标准以来,至今已有二十多年了。ITU-T 等国际标准化组织陆续颁布了接近十个视频编码国际标准,大大推动了视频通信和数字电视广播的发展,这也是有目共睹的事实。但是严格地讲,这两大领域至今的发展仍不能令人满意,总起来讲,应用的范围不广,主要是视频压缩与质量之间的矛盾不能很好解决。例如,可视电话一直被认为是一种理想的通信设备,可近 30 年来至今未能普及,就是因为性能价格比不高。
    短短的二十几年就有十几个标准的诞生,对设计者来说真是一个知识爆炸的“时代”。我从2003年接触编解码技术,当时真是一头污水,每天寻找资料,书籍,就想把它一点点的学好.

    简单叙述一下我的264学习经过吧
    首先我觉得先要找相关书籍把基本原理搞懂,不要急于看标准和源代码。要知道什么是采样格式,什么是I、P、B,他们的原理是什么,了解CAVLC、CABAC熵编码的实现过程,一定要认认真真。这样各个主要模块攻克之后,你就可以结合标准和源代码一步一步的看下去。

    下面以解码过程为例说一下具体过程:
        1、 过程:码流→NALU→RBSP。





如果是字节流的码流当然就首先要对字节流进行解析,这就要看附录 B 了,如何查找起始码和去除伪起始码(为什么有伪起始码呢?);如果是 RTP 格式的码流,那就要按 RFC3984 来解析了(标准没有规定 RTP 格式码流的解析过程);字节流解析完后提取出来的就是 NALU 了,对 NALU 的解析就要看第七章了。黑色的粗体字都是在码流中可能出现的语法元素,解码器的首要任务就是要对这些语法元素进行解析。对于这些码流中的语法元素我们要进行解析必须知道三个问题:

(1)、什么时候存在于码流中?这样我们才能知道当前解析的是哪个语法元素;

(2)、采用什么样的熵编码方式?这样我们才能知道如何解析;
(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 小节了;
        2、对于属于 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() 这个语法层的码流规定;
        3、按照语法表 7.3.2.8 解析完了 slice_header() 就该解析 slice_data() 了。下面以最常见的 I 帧(CAVLC 熵编码、非 MBAFF)的解析过程为例简单描述怎么继续读标准。这时在码流中出现的第一个 slice_data() 层的语法元素是语法表 7.3.4 中的 macroblock_layer(),也就是说直接到了宏块层的语法解析,那就要又要看 7.3.5 小节了;
     4、基于我们对编解码流程的了解,我们知道解码是一个预测值加残差得到重建图像的过程,那么我们下面的解码过程就要分成两步走了:首先,得到预测值;其次,得到残差。基于我们对 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 小节;
       5、预测值和残差都有了,加起来就是解码图像了。解码的主要工作到此也算基本完成了。当然,上面的过程中还会用到标准其他章节的相关内容(例如,8.5 小节会用到 5.7 小节中定义的 InverseRasterScan)总体过程也就如此吧,详细内容要大家自己去认真的学习
   入门不易,要成为大师很难。要在编解码业修炼成精也要有相当时间磨练和积累。成不了大师会成什么?

   入了门,只要条件能配合,走上专职这条路是相当自然的。这里说的条件是什么呢?个人觉得毅力是第一,再者就是进修,第三是时间,还有是学习环境。大家都知道IT业的演进比换季还快。学校虽尽其可能传授学生最新的知识,但很可能学校所学的一毕业就过时了。乘着工作的机会,接触新知识就成了最重要的进修方式。能不能把握好这些机会,决定着技术层次和前程。
    不是一番寒彻骨,怎得梅花扑鼻香。

    学习技术可以算是枯燥无趣而又很辛苦的,所以你要好好规划自己的路, 不要跟着感觉走!根据个人的理想决策安排,就需要慎重安排自己的轨迹。从某个行业入手,逐渐对该行业深入了解,不要得过且过,治学必须要有精神。同样也不要频繁跳槽,频繁地动荡不是上策,否则你对哪个行业都没有摸透,永远是新手!

 

posted @ 2013-10-05 09:50 rlandjon 阅读(...) 评论(...) 编辑 收藏