cavlc编码level的原理和过程

来源:互联网 发布:discuz 标签 seo 编辑:程序博客网 时间:2024/05/19 19:33
 本帖最后由 wapa 于 2010-12-17 10:03 PM 编辑

cavlc编解码 非trailingone 非零 变换系数幅值的原理与过程:

基本原理:
1. 首先将系数幅值(level)除以某一个值(1<<suffixLenth),然后分别对商值(level_prefix)和余数(level_suffix)进行编码;
2. 对商值level_prefix编码的码流就是前缀level_prefix个0+1: 0...01
3. 对余数level_suffix编码的码流就是levelSuffixSize个bit的level_suffix的二进制值。

具体解码过程:
1. 初始化suffixLength:
   (以下条件暗示了非零幅值系数有可能比较稠密也比较大时,直接除以2,而非1)
   如果总非零系数(TotalCoeff)>10 且 TrailingOnes<3
       suffixLength = 1;
   否则(TotalCoeff<=10 or TrailingOnes==3)
       suffixLength = 0;
2. 循环解码系数幅值:for(i=TrailingOnes; i<TotalCoeff; i++)
(1) 首先从码流中查询连0数,即为level_prefix值;   
(2) 推导余数level_suffix的bit数levelSuffixSize:
如果level_prefix==14 且 suffixLength==0  
    levelSuffixSize = 4; (注:对第一个幅值的levelCode>=14 且小于等于29(14+4bit所能表示的最大值15) 的值进行编码的方法)
如果level_prefix>=15
    levelSuffixSize = level_prefix - 3;
以上两个条件都不成立时
    levelSuffixSize = suffixLength;
(3) 解码余数level_suffix值:
如果levelSuffixSize>0, 从码流中读取levelSuffixSize个bit就是level_suffix的值;
否则(levelSuffixSize==0), 推导出level_suffix=0;
(4) 计算幅值码levelCode
    levelCode = ( min(15, level_prefix) << suffixLength ) + level_suffix;
    即:商值(level_prefix与15的最小值) 乘以 除数(1<<suffixLength) 加上 余数(level_suffix)。
(5) 如果level_prefix>=15 且 suffixLength==0
    levelCode += 15;
(6) 如果level_prefix>=16
    levelCode += ( 1<<(level_prefix-3) ) - 4096;
(7) 如果TrualingOnes<3,则解码的第一个幅值码还要加上2,因为第一个幅值码肯定大于1,为节约bit,在编码时就将它减去了2,故解码时还要恢复出来。
(8) 由幅值码计算幅值:
如果幅值码levelCode为偶数
    level = (levelCode+2)>>1;
否则
    level = (-levelCode-1)>>1;
(9) 更新suffixLength:
如果suffixLength==0
    suffixLength = 1;
如果abs(level) > ( 3<<(suffixLength-1) ) 且 suffixLength < 6
    suffixLength++;
原创粉丝点击