天天看点

H264的CAVLC探秘

CAVLC的算法搜索出来的资料比较多,但是怎么理解这个CAVLC呢。

CAVLC=CA+VLC

VLC(Variable-Length Code) 变长编码

想想霍夫曼编码吧。还不明白,google下吧。

CA (Context Adaptivie) 上下文自适应

上下文-就是利用图像的空间冗余性,上边和左边的4x4块残差和当前快的是具有相关性。

那具体怎么设计这个编码算法,我们还是通过历史来学习吧。

H.261

使用的是RUN-LEVEL编码,也就是把残差数据按照0...n分段,0...代表多个0,n是1个非零的数字。

RUN是连续零的个数,LEVEL是n的数值,每个(RUN,LEVEL)作为一个符号按照哈夫曼编码来编码,来保证概率小的分段编码最小。

假设有一个4*4数据块

{

0, 3, -1, 0,

0, -1, 1, 0,

1, 0, 0, 0,

0, 0, 0, 0

}

数据重排列:0,3,0,1,-1,-1,0,1,0

那就分为(1,3)(1,1)(0,1)(0,1)(0,1)(1,1)EOB(End Of Block)这几个分段,查码表

(1,3)等于0010 0101 1

......

EOB等于01 PS:这个是最短的码字哦。

H263

采用的3D VLC 编码方式,把 (last, run, level) 作为一个符号来进行编码,

last=1表示最后非零的参数,这样就不许要EOB这个符号了。

这个也很好理解。因为EOB这个符号采用了最短的码字,但是EOB的概率并没有是最大。

看码表也可以看到同样的RUN-LEVEL下last=1的码字比last=0的长。

H264

开始采用的是UVLC, 针对之前使用H.263采用不同码表统一了码表。

但是缺点就是没有利用上下文的相关性。所以后面改成了CAVLC,在JVT-C028 会议论文中可以看到

这个提案的综述

CVLC is a method of coding transform coefficients. It replaces the UVLC coding of transform coefficients (Tcoeff) for luma as well as chroma. All other elements are identical to the description of UVLC coding.

The motivation for using CVLC can be summarized in the following way:

  • Highly context adaptive coding result in very good coding efficiency over the whole quality range of the standard.
  • Zig-zag scanning is still used. Separation of the coding of Run and Level allows for better adaptivity and thereby better coding efficiency.
  • Separation of Run and Level also result in low complexity with low demand on memory.

The following coding elements are used to replace the Tcoeff elements of the UVLC coding method:

    1. If there are non-zero coefficients, it is typically observed that there is a string of coefficients at the highest frequencies that are +-1. Hence, a common parameter Num-Trail is used that contains the number of coefficients as well as the number of "Trailing 1s" (from now referred to as T1s). For T1s only the sign has to be coded.
    2. For coefficients other than the T1s, Level information is coded. Since this is a one dimensional parameter, coding is simplified and well structured VLCs are used.
    3. Lastly, the Run information is coded. Since the number of coefficients is already known, this sets a limit to the Run, which is used for additional compression. Run is split into Total-run for all coefficients and Run before each non-zero coefficient.

Zig-zag scanning is used, but in the transmission of coefficient data, both levels and runs, the scanning is done in reverse order. Therefore, in the Level information, the signs of T1s appear first (in reverse order), then the Level information of the last coefficient where this is needed, and so on. Run information is coded similarly. First Total number of zeros in Runs is coded, followed by Run before the last nonzero coefficient, and so on.

大概意思讲的就是

CAVLC利用了上下文适配提高了编码效率,分离RUN和LEVEL的编码可以更好的适配上下文,而且可以降低计算复杂度和内存需求。

然后介绍了新引入的几个概念,Num-Trail 非零系数 ,Trailing 1s拖尾系数 ,

这样编码需要编码的元素就有,非零系数,拖尾系数,拖尾系数的符号,每个非零系数-拖尾系数的Level,Run分为总0个数和每个0的run都要编码。

到此,大体CAVLC的来历就清楚了,如果不是想改进这个编码算法,只是为了满足好奇,那到此也就够了。

如果想在这上面有创新,那就需要每一步都仔细研究和计算了。祝各位好运。

继续阅读