【原】CAVLC的个人理解

时间:2022-08-03 15:55:22

4x4数据块经过预测、变换、量化后,非零系数主要集中在低频部分,而高频部分大部分是零。数据经过zig-zag扫描后,从左->右(低频->高频),DC系数附近的系数非常大,而高频的非零系数大部分是+1,-1(why? 应该是通过数据统计得到的。理论上推导暂时不知。)

因此可以得出量化后4x4块的特性有几个:

1)、非零系数一般较少,大部分是零,非零集中在DC附近。

2)、高频非零大部分是+1/-1。

3)、相邻的4x4块是相关的。(意思就是说 上面两点特性有关联,比如左边上边4x4非零系数很多,那么当前块很大的概率也是非零系数很多,小概率出现非零系数少的情况。这就给变长编码提供了概率依据。)

CAVLC各个过程说明。

第一步 对非零系数的数目(TotalCoeffs)以及拖尾系数的书目(TrailingOnes)进行编码。

码表的确定是由NC决定的。(why?因为NC是基于同一个slice左边4x4,上边4x4已经编码过的非零系数求平均。根据特性3),选择不同码表也是符合信息论的编码原则)。

亮度码表总共有4个(见标准表9-5):

0≤NC<2 表倾向于小系数(TotalCoef 0,1)的情况,小系数分配更短的比特

2≤NC<4 表倾向于中等大小系数(TotalCoef 0,1,2,3,4)的情况,中小系数分配更短比特

4≤NC<8 表倾向于较大的系数(TotalCoef 0,1,2,3,4,5,6,7,8)的情况。

8≤NC表 定长表,说明每种出现的概率差不多,这样获得的熵最大(由最大熵定理得到)。    

有人就有疑问,这些码表是怎么设计出来的?个人觉得应该是根据大量的视频数据统计,获得概率模型,然后设计码表。熵编码离不开概率分布。

第二步 对拖尾系数的符号进行编码

第三步 对除拖尾系数以外的非零系数的幅值(Levels)进行编码。

大部分码表设计只考虑 n≥0的情况,如果出现负数,那么我们先要做一个映射才能使用该编码系统。

if code_num ≥0

  levelCode = code_num*2 - 2  把正数映射到大于等于零的偶数上

if code_num <0

  levelCode = -code_num*2 -1  把负数映射到大于零的负数上

映射完后开始编码。

这部分原理跟哥伦布编码差不多,不懂的请看我前面写的一篇文章,里面资料讲的很清楚。

http://www.cnblogs.com/irish/p/3170500.html

第四步 对最后一个非零系数前零的数目(TotalZeros)进行编码

查表得到码字

第五步 对每个非零系数前零个数(RunBefore)进行编码

查表得到码字

 

参考资料:

[1] http://files.cnblogs.com/irish/The_H.264_advanced_video_compression_standard.pdf

[2] http://files.cnblogs.com/irish/CAVLC.pdf