目录:
H.264协议CABAC熵编码学习(一)
H.264协议CABAC熵编码学习(二)
H.264协议CABAC熵编码学习(三)
H.264协议CABAC熵编码学习(四)
H.264协议CABAC熵编码学习(五)
在学习cabac之前,需要先掌握一些基础知识。二进制算术编码作为cabac的核心组件,先掌握他,对后续的学习是十分有帮助的。
信息熵
表示一串信息最少可以被多少个比特位表示
其中 χ χ 为有限个事件 x x 的集合, 是定义在 χ χ 上的随机变量。
二进制算术编码
首先,什么是算数编码?这里直接套用维基的说明。
算术编码是一种无损数据压缩方法,也是一种熵编码的方法。和其它熵编码方法不同的地方在于,其他的熵编码方法通常是把输入的消息分区为符号,然后对每个符号进行编码,而算术编码是直接把整个输入的消息编码为一个数,一个满足(0.0 ≤ n < 1.0)的小数n。
那么二进制算术编码,顾名思义,即待编码的数据流中只有0和1。整个流程分为两个部分:
二值化
二进制算术编码
二值化
二值化的目的是将数值使用二进制表示,在H.264协议总共有以下四种二值化方法:
- 一元(U)二值化:如下图,其中binIdx表示二进制下标
截断一元(TU)二值化:即存在一个cMax值,大于或等于cMax,全部binIdx使用1表示;小于cMax的值,使用U方式进行二值化
一元/k阶哥伦布编码(UEGk)联合二值化:存在signedValFlag(0或者1)和uCoff(截断值),数值小于uCoff的部分,使用U的方式进行二值化;大于uCoff的部分,使用k阶哥伦布编码。很明显,此时二值化分为前缀(U部分)和后缀(EGk部分)两部分。signedValFlag用于指明是否只有前缀,满足以下情况,UEGk二值化结果只包含前缀:
若signedValFlag为0,并且前缀比特串长度小于uCoff
若signedValFlag为1,前缀比特串是包含了单个比特值为0的比特串(笔者不是很明白)
否则,UEGk的前缀按照以下的伪代码获得:
/* signedValFlag为规定值,0或者1;synElVal为TQ后的系数值;uCoff为截断值;k为阶 */
if( Abs( synElVal ) >= uCoff ) {
sufS = Abs( synElVal ) − uCoff
stopLoop = 0
do {
if( sufS >= ( 1 << k ) ) {
put( 1 )
sufS = sufS − ( 1<<k )
k++
} else {
put( 0 )
while( k− − )
put( ( sufS >> k ) & 0x01 )
stopLoop = 1
}
} while( !stopLoop )
}
if( signedValFlag && synElVal ! = 0)
if( synElVal > 0 )
put( 0 )
else
put( 1 )
- 定长(FL)二值化:使用固定长度进行二值化,其中cMax变量表示长度
二进制算术编码
该部分,以实例进行讲解。
编码
假设我们已经得到一组二值化数据串: 1010 1010 ,并且比特串中0和1出现的概率是相同的,都是