h264CAVLC编码实例

本文通过一个4*4数据块的例子详细解析了H264中CAVLC编码的过程,包括非零系数的数目、拖尾系数的编码、非零系数幅值的编码、最后一个非零系数前零的数目编码以及每个非零系数前零的个数编码等步骤。
摘要由CSDN通过智能技术生成

再来一个例子:

编码过程: 
假设有一个4*4数据块 

0, 3, -1, 0, 
0, -1, 1, 0, 
1, 0, 0, 0, 
0, 0, 0, 0 

数据重排列:0301-1-1010…… //<Z扫描得到的过程

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: 
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 = 0level_prefix = 0; 
查表9-6,可得level_prefix = 0时对应的bit string = 1; 
因为suffixLength初始化为0,故该Level没有后缀; 
因为suffixLength = 0,故suffixLength++; 
Code = 0000 1000 111; 
编码下一个LevelLevel[0] = 3; 
levelCode = 4level_prefix = 2;查表得bit string = 001; 
level_suffix = 0suffixLength = 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 = 5ZerosLeft = 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; 
编码完毕。 

 


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值