变长编码

来源:互联网 发布:人民日报英文版软件 编辑:程序博客网 时间:2024/05/01 07:30

Variable length coding and you
变长编码

Filed under: bitstream,CABAC,exponential golomb codes,H.264,variable-length coding ::


Let’s say you want to write a number to a bitstream. The decoder is expecting a number, so it knows exactly what to look for. But how do you format this number?
 
You could write 16 bits no matter what, putting a max of 65535 on this number. This would also waste tons of bits though; what if the number you’re writing here with

your encoder is almost always 0, 1, or 2? Writing 16 bits would seem ridiculous, so it only makes sense to use a variable-length code (VLC). But how would the decoder

know how *long* the code is? Here’s a simple example:
 
5 -> 101
2 -> 10
 
Both will look the same to the decoder, since it doesn’t know whether the code ends after the first bit, the second, the third, etc. But there’s a solution to this

problem; a common one lies in the form of exponential Golomb codes. Here’s an example:
 
0 -> 1
2 -> 011
5 -> 00110
8 -> 0001001

试想一下编码一个整数的情形,解码器期望一个整数,所以解码器知道找什么,但是你如何格式化这个整数呢?
你可以简单的用16个bit表示一个整数,这会耗费很多bit。如果要表示的整数都是0、1或者2,那么用16个bit来表示他们就会显得很愚蠢,这时候变长编码就派上了用场。但是解码器怎么知

道几个bit代表一个整数呢?例如:
5 -> 101
2 -> 10
对于解码器来说他俩是一样的,因为解码器不知道是第一个bit代表一个整数,还是前两个bit代表一个整数,或者3个bit代表一个整数。当然,我们有办法解决这个问题,指数哥伦布编码就

是其中一种解决方法。下面是一个例子:
0 -> 1
2 -> 011
5 -> 00110
8 -> 0001001

 
The number of zeroes is the number of bits in the code, and a 1 is used to terminate the list of zeroes. This may seem inefficient, but in a sense one has no other

choice but to have some sort of coding scheme like this. Of course, exponential golomb codes are only optimal in the case of a specific probability distribution; an

optimal variable-length coding system has code lengths chosen based on the probability of each value. This is the primary reason why MPEG-4 Part 2 (Xvid/DivX) is

superior to MPEG-2; the VLC tables were much better chosen.
 
Of course, the ideal system would be to allow custom VLC tables to be put in the header of the video file; its quite trivial to design a twopass encoder to create

optimal VLC tables for a given video, or even a given frame. H.264 partially does away with this problem with CABAC; while there would be benefit to including a custom

initial CABAC state, the cost of various CABAC modes adapts quickly to the video. Of course, this is not always the case; CABAC still relies on variable-length codes,

because it converts numbers to series of binary digits, which are then written into the context-based arithmetic coder (the “binary” part of CABAC). One result of

this is that even if one has a B-frame made up entirely of intra blocks, the arithmetic coder won’t be able to completely adapt, and each block will still cost more

bits; the variable-length coding for the macroblock type is not chosen in such a way that would allow such “complete” adaptation.

0的个数是bit数,一个1用来结束一串0。这还不够,但是某种程度上,除此之外没有更好的选择。当然指数哥伦布编码只在特定的概率分布情形下(即小的数出现的几率远大于大的数出现的

几率)才是较优的。还有一种变长编码可以基于每个值出现的概率来选择编码长度,这种编码正是MPEG-4 Part 2(xvid/divx)优于MPEG-2的原因,因为VLC码表选择得更好。

当然,理想的编码系统应该允许把自定义的VLC码表放在视频码流文件的头部。设计一个2pass编码器来为一个视频序列创建较优的码表是一件繁琐的事情。h264通过CABAC编码,部分绕过了这

个麻烦。但是,包含一个自定义的初始CABAC状态是有好处的,各种CABAC模式的代价快速的适应这个视频。当然,现实情况并不总是这样,CABAC仍然依赖变长编码,因为它把数字编码成二进

制位,然后把这些二进制位输出给基于上下文的算数编码器。这导致了一个结果就是一个完全由帧内预测宏块组成的B帧,算术编码器无法自适应,使得每个宏块都耗费了更多的bit。

 


指数哥伦布码(指数Golomb码),一种压缩编码方法。
 
用来表示非负整数的k阶指数哥伦布码可用如下步骤生成:
 1.将数字以二进制形式写出,去掉最低的k个比特位,之后加1
 2.计算留下的比特数,将此数减一,即是需要增加的前导零个数
 3.将第一步中去掉的最低k个比特位补回比特串尾部
 
0阶指数哥伦布码如下所示:
  0 => 1 => 1
 1 => 10 => 010
 2 => 11 => 011
 3 => 100 => 00100
 4 => 101 => 00101
 5 => 110 => 00110
 6 => 111 => 00111
 7 => 1000 => 0001000
 8 => 1001 => 0001001

0 0