什么是cavlc?
cavlc 是h264视频标准中用到的一种熵编码,全称是基于上下文的可变长编码。可变长编码(vlc),这里就不多说,基本的
精神就是频繁出现的事件用较少的比特表示,出现概率低的用较多的比特表示。cavlc的重点在于基于上下文,至于如何做到
上下文相关,下面会讲到。
什么是拖尾系数?
zigzag扫描后的数据列里,从最后的一个非零系数开始(高频区数据)往前统计,如果非零系数的值是正负1,认为这个非零系数
就是拖尾系数。而且拖尾系数一个块最多只能有3个,最少0个。
为什么拖尾系数只是正负1?
因为一个4x4的图像数据经过整数变换,量化后,高频区会频繁出现0 和正负1。
cavlc的编码过程?
h264中,对变换,量化,zigzag扫描过的数据进行cavlc编码(4x4的亮度数据,2x2的色度数据)。详细的编码过程可参
考(http://blog.csdn.net/sunshine1314/archive/2007/07/12/1685948.aspx),下面我会对过程简单的概括一下,
具体我会解释一下我认为不是很容易理解的一些步骤(只是我觉得比较难于理解的几个步骤,可能每个理解能力不一样,如果
各位看客觉得很好理解,说明我理解能力有问题:))
1.首先把总的非零系数个数(0-16之间)和拖尾系数个数(0-3之间)联合编码,再标准中4个表。至于选择哪个表,就用到了上下文
的概念。这里的上下文是指当前块的左边和上边块的非零系数个数Na和Nb,当前块的非零系数个数Nc。关系如下
Nc = (Na + Nb)/2;左边和上边的块都可以得到
Nc = Na;左边可用
Nc = Nb;上边可用
Nc = 0; 都不可用
然后用Nc 来选择所用的表。
2.编码拖尾系数(也可以认为是编码拖尾系数的符号)
一个比特对应一个,0 表示+ 1表示-
3.编码剩余的非零系数。
假设当前编码的系数为level,先把level映射成codelevel,关系如下:
codelevel = 2 * level - 2;(level > 0)
codelevel = -2 * level-1; (level < 0)
codelevel 其实包含了两个信息,系数的幅度和符号(偶数是正数,奇数是负数,这个信息会在解码端用到)
然后编码codelevel,这里会用到一个变量suffixlength。这个参数会在编码块开始的时候初始化一个值(0,或者1),每次
编码完一个系数,suffixlength会根据当前编码的系数的大小来决定是否自增。suffixlength把codelevel分成两部分
level_prefix和level_suffix。
level_prefix = codelevel>>suffixlength
level_suffix = codelevel & ((1 << suffixlength) - 1)
然后用level_prefix查表,得到比特串,然后接上level_suffix,这个就是编码后的比特串。
最后更新suffixlength,供编码下个系数使用。具体如下
If ( suffixLength == 0 )
suffixLength++;
else if ( abs(level) > (3<<suffixLength-1) && suffixLength <6)
suffixLength++;
个人sunffixlength也有上下文的意思。当前用到了上个非零系数的信息。
注:判断的时候应该用level的绝对值,不是codelevel(具体可看x264中的代码),上面提到的文章中用的是codelevel,应该有
误。
4.编码总的零的个数(是最后一个非零系数之前的总的零的个数)
5.编码每个非零个数之前零的个数(run_before)
编码完毕。
h264之cavlc
最新推荐文章于 2021-07-01 14:48:26 发布