CAVLC之手把手教你编码(zz)

来源:互联网 发布:天猫淘宝内部优惠劵 编辑:程序博客网 时间:2024/04/28 14:33

CAVLC之手把手教你编码(zz)

首先声明本文并不是我写的,文章来自本人同学(Sunrise),都是一起做的H264,比较了解,文章内容都是自己整理的,比较可信,因此整理到一起,我也偷个懒哈

再次声明:文中用的标准是BS的正式标准,如果大家发现序号不对,参考着改过来就是了!

编码过程:
假设有一个4*4数据块
{
   0,   3,   -1,   0,
   0,   -1,   1,   0,
   1,   0,     0,   0,
   0,   0,     0,   0
}
数据重排列:0301-1-1010……

1
   初始值设定:
非零系数的数目(TotalCoeffs = 5
拖尾系数的数目(TrailingOnes= 3
最后一个非零系数前零的数目(Total_zeros = 3
变量NC=1;
(说明:NC值的确定:色度的直流系数NC=-1;其他系数类型NC值是根据当前块左边4*4块的非零系数数目(NA)当前块上面4*4块的非零系数数目(NB)求得的,见毕厚杰书P1206.10
suffixLength = 0

i = TotalCoeffs = 5;
2
   编码coeff_token
查标准(BS ISO/IEC 14496-10:2003Table 9-5,可得:
If (TotalCoeffs == 5 && TrailingOnes == 3 && 0 <= NC < 2)
      coeff_token = 0000 100;
      Code = 0000 100;
3
   编码所有TrailingOnes的符号:
逆序编码,三个拖尾系数的符号依次是+(0),-(1),-(1);
:
TrailingOne sign[i--] = 0;
TrailingOne sign[i--] = 1;
TrailingOne sign[i--] = 1;
Code = 0000 1000 11;
4
   编码除了拖尾系数以外非零系数幅值Levels
过程如下:
1)将有符号的Level[i]转换成无符号的levelCode
如果Level[i]是正的,levelCode = (Level[i]<<1) – 2; 
如果Level[i]是负的,levelCode = - (Level[i]<<1) – 1;
2)计算level_prefixlevel_prefix = levelCode / (1<<suffixLength)
       
查表9-6可得所对应的bit string
3)计算level_suffixlevel_suffix = levelCode % (1<<suffixLength)
4)根据suffixLength的值来确定后缀的长度;
5suffixLength updata
If ( suffixLength == 0 )
suffixLength++

         else if ( levelCode > (3<<suffixLength-1) && suffixLength <6)
            suffixLength++;

回到例子中,依然按照逆序,Level[i--] = 1;(此时i = 1
levelCode = 0
level_prefix = 0
查表9-6,可得level_prefix = 0时对应的bit string = 1
因为suffixLength初始化为0,故该Level没有后缀;
因为suffixLength = 0,故suffixLength++
Code = 0000 1000 111

编码下一个LevelLevel[0] = 3
levelCode = 4
level_prefix = 2;查表得bit string = 001
level_suffix = 0
suffixLength = 1;故码流为0010
Code = 0000 1000 1110 010

i = 0
,编码Level结束。
5
)编码最后一个非零系数前零的数目(TotalZeros):
   
查表9-7,当TotalCoeffs = 5total_zero = 3时,bit string = 111
   Code = 0000 1000 1110 0101 11

6
   对每个非零系数前零的个数(RunBefore)进行编码:
i = TotalCoeffs = 5
ZerosLeft = Total_zeros = 3;查表9-10
依然按照逆序编码
ZerosLeft =3, run_before = 1         run_before[4]=10;
ZerosLeft =2, run_before = 0         run_before[3]=1;
ZerosLeft =2, run_before = 0         run_before[2]=1;
ZerosLeft =2, run_before = 1         run_before[1]=01;
ZerosLeft =1, run_before = 1         run_before[0]
不需要码流来表示
Code = 0000 1000 1110 0101 1110 1101

编码完毕。

原创粉丝点击