本帖最后由 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++; |
cavlc编码level的原理和过程
最新推荐文章于 2024-07-22 14:12:09 发布