CAVLC -CAVLC概念

AVLC的全称是Context-Adaptive Varialbe-Length Coding,即基于上下文的自适应变长编码。CAVLC的本质是变长编码,它的特性主要体现在自适应能力上,CAVLC可以根据已编码句法元素的情况动态的选择编码中使用的码表,并且随时更新拖尾系数后缀的长度,从而获得极高的压缩比。H.264标准中使用CAVLC对4×4模块的亮度和色度残差数据进行编码。

CAVLC -CAVLC原理

在H.264标准编码体系中,视频图像在经过了预测、变换及量化编码后表现出如下的特性:4×4块残差数据块比较稀疏,其中非零系数主要集中在低频部分,而高频系数大部分是零;量化后的数据经过zig-zag扫描,DC系数附近的非零系数值较大,而高频位置上的非零系数值大部分是+1和-1;相邻的4×4块的非零系数的数目是相关的。CAVLC就是利用编码后残差数据的这些特性,通过自适应对不同码表的选择,利用较少的编码数据对残差数据进行无损的熵编码,进一步减少了编码数据的冗余和相关性,提高了H.264的压缩效率。

CAVLC -CAVLC编码流程

视频图像在经过预测、变换和量化编码后,需要经过Zig-zag扫描和重新的排序过程,为后序的CAVLC编码进行准备。一个残差数据块的CAVLC熵编码的流程如图所示:

CAVLC熵编码处理流程

1、TotalCoeffs和TrailingOnes的编码

从码流的起始位置开始计算整个编码块中非零系数的数目(TotalCoeffs),非零系数的数目为从0-16,非零系数的数目被赋值给变量TotalCoeffs。
拖尾系数是指码流中正或者负1的个数(+/-1)。拖尾系数的数目(TrailingOnes)被限定在3个以内,如果+/-1的数目超过3个,则只有最后3个被视为拖尾系数,其余的被视为普通的非零系数,拖尾系数的数目被赋值为变量TrailingOnes。

2、判断计算nC值

nC(Number Current 当前块值)值的计算集中体现了CAVLC的基于上下文的思想,通过nC值选择不同H.264标准附录CAVLC码表。

3、查表获得coeff_token编码

根据之前编码和计算过程所得的变量TotalCoeffs、TrailingOnes和nC值可以查H.264标准附录CAVLC码表,即可得出coeff_token编码序列。

4、编码每个拖尾系数的符号:前面的coeff_token编码中已经包含了拖尾系数的总数,还需进一步对拖尾系数的符号进行编码。由于拖尾系数符合为正(+)或负(-),因此,在H.264标准中规定用0表示正1(+1)、1表示负1(-1)。当拖尾系数的数目超过3个只有最后3个被认定为拖尾系数,因此对符号的编码顺序应按照反向扫描的顺序进行。

5、编码除拖尾系数之外的非零系数的幅值(Levels)

非零系数的幅值(Levels)由两个部分组成:前缀(level_prefix)和后缀(level_suffix)。levelCode、levelSuffixsSize和suffixLength是编码过程中需要使用的三个变量,其中levelCode是中间过程中用到的无符号数,levelSuffixsSize表示后缀长度位数,suffixLength代表Level的码表序号。

6、编码最后一个非零系数前零的数目(TotalZeros)

TotalZeros指的是在最后一个非零系数前零的数目,此非零系数指的是按照正向扫描的最后一个非零系数。因为非零系数数目(TotalCoeffs)是已知,这就决定了TotalZeros可能的最大值。根据TotalCoeffs值,H.264标准共提供了25个变长表格供查找,其中编码亮度数据时有15个表格供查找,编码色度DC 2×2块(4:2:0格式)有3个表格、编码色度DC 2×4块(4:2:2格式)有7个表格。

7、编码每个非零系数前零的个数(RunBefore)

在CAVLC中,变量 ZerosLeft表示当前非零系数左边的所有零的个数,ZerosLeft的初始值等于TotalZeros。每个非零系数前零的个数(RunBefore)是按照反序来进行编码的,从最高频的非零系数开始。H.264标准中根据不同ZerosLeft和RunBefore,构建了RunBefore编码表格供编码查找使用。根据表格每编码完一个RunBefore,对ZerosLeft的值进行更新,继续编码下一个RunBefore,直至全部完成所有非零系数前零的个数的编码。当ZerosLeft=0即没有剩余0需要编码时或者只有一个非零系数时,均不需要再进行RunBefore编码。

CAVLC -CAVLC解码流程

CAVLC熵解码是上述CAVLC熵编码的逆过程,CAVLC熵解码的输入数据是来自片层数据的比特流,解码的基本单位是一个4×4的像素块,输出为包含4×4块每个像素点所有幅值的序列。CAVLC解码步骤如下:
1. 初始化所有的系数幅值
2. 解码非零系数个数(TotalCoeff)和拖尾系数个数(TrailingOnes)。
3. 解码拖尾系数符号(trailing_ones_sign_flag)
4. 解码非零系数幅值
5. 解码total_zeros和run_before

6. 组合非零系数幅值和游程信息,得到整个残差数据块

假设有一个 4*4 数据块

(变化,量化后就送入熵编码)
{
   0 , 3 , -1 ,0,
   0, -1,    1,0,
   1 , 0 , 0 ,0,
   0 , 0 , 0 ,0
}
数据重排列: 0 , 3 , 0 , 1 , -1 , -1 , 0 , 1 , 0……

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

2 ) 编码 coeff_token : 
查标准( BSISO/IEC 14496-10:2003 ) Table9-5 ,可得: 
If (TotalCoeffs == 5 &&TrailingOnes == 3 && 0<= NC < 2)
coeff_token = 0000 100;
Code output = 0000100;

3 ) 编码所有 TrailingOnes 的符号: 
逆序编码,三个拖尾系数的符号依次是+( 0 ),-( 1 ),-( 1 ); 
即 :
TrailingOne sign[i–] = 0;
TrailingOne sign[i–] = 1;
TrailingOne sign[i–] = 1;
Code output = 0000100    011;
4 ) 编码除了拖尾系数以外非零系数幅值 Levels :( 毕书这个例子说的不是很细,而且有个小错误)
过程如下: 
( 1 )将有符号的 Level[i] 转换成无符号的 levelCode ; 
如果 Level[ i] 是正的, levelCode = (Level[ i]<<1) –2;  
如果 Level[ i] 是负的, levelCode = - (Level[ i]<<1) – 1;
( 2 )计算 level_prefix : level_prefix= levelCode /(1<<suffixLength) ; 
查表 9-6 可得所对应的 bitstring ; 
( 3 )计算 level_suffix : level_suffix= levelCode %(1<<suffixLength) ; 
( 4 )根据 suffixLength 的值来确定后缀的长度; 
( 5 ) suffixLength    updata : 
If ( suffixLength == 0 )
      suffixLength++ ; 
else if ( levelCode >(3<<suffixLength-1)&& suffixLength<6)

注:大于预置值就 suffixLength++;
     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 output = 0000 100011 1; 
编码下一个Level:Level[0] = 3;
levelCode = 4;level_prefix = 2;查表得bit string = 001;
level_suffix = 0;suffixLength = 1;故码流为0010;
Code output = 0000 100011 1 0010 ; 
i = 0,编码Level结束。

5)编码最后一个非零系数前零的数目(TotalZeros):
查表9-7,当TotalCoeffs = 5,total_zero = 3时,bit string = 111;
Code output = 0000 100011 1 0010 111;

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] 最后一个非零系数不需要码流来表示
Codeoutput = 0000 100 011 1 0010 111 10 1 1 01; 
编码完毕。(CAVLC主要是查表,标准中的表是通过大量实验的出来的!)

解码过程:

接收码流为:0000 1000 1110 0101 1110 1101

计算NC = 1 
解码详细过程如下:
1.      根据Coeff_token和NC查表(见标准表9-5),得到非零系数数目TotalCoeffs和拖尾系数数目TrailingOnes
NC = 1选择对应的表,Coeff_token为0000100,查表得到TotalCoeffs=5TrailingOnes=3
输出序列:无
2. 解析拖尾系数
由第一步得到拖尾系数有3个,输入拖尾系数符号编码码流011,得到两个拖尾系数由先到后是 -1,-1,1
output:-1,-1,1(反序输出) 
3.      解析除拖尾系数外的非零系数的幅值(level)
(1)      确定后缀长度SuffixLength
(2)      根据码流查表9-6得到前缀LevelPrefix
(3)      根据前缀和后缀,得到

LevelCode=(levelprefix<<suffixlength)+levelsuffix
(4)      Levelcode为偶数 level=(level+2)/2
               Levelcode为奇数 level=(-level-1)/2
(5)      根据设定的阈值确定是否update Suffixlegth
回到例子中,按照逆序
i=0, Sufixlegth=0,查表9-6,1对应的前缀levelprefix=0,levelcode=0,

计算得到level=1 , i++ , sufixlegth++(第一次都要加) 
i=1,sufixlegth=1,查表0010(3为前缀,1位后缀 )对应的前缀     levelprefix=2,计算levelcode=4,level=3,i++
i=2 >=TotalCoeffs-TrailingOnes,除拖尾系数外的非零系数解析完毕
output:3,1,-1,-1,1 
4.      解析每个非零系数前零的个数
根据TotalCoeffs=5和输入码流111查表9-7得到TotalZeros=3
初始i=TotalCoeffs-1=4 ,zeroleft=TotalZeros=3 , 5个非零系数前零的数目解析如下:
i=4,zeroleft=3,根据码流10,查表9-10,runbefor=1,

输出序列:3,1,-1,-1,0,1
i=3,zeroleft=3-1=2,根据码流1,查表runbefore=0,

输出序列:3,1,-1,-1,0,1
i=2,zeroleft=2-0=2,根据码流1,查表runbefore=0,

输出序列:3,1,-1,-1,0,1
i=1,zeroleft=2-0=2,根据码流01,查表runbefore=1,

输出序列:3,0,1,-1,-1,0,1
i=0,zeroleft=2-1=1,输出序列:0,3,0,1,-1,-1,0,1
5. 解码完毕,将剩下的元素用0补齐,反序排列就可以得到4*4矩阵。
6. 最后还原为一个4*4数据块
{
   0 , 3 , -1 , 0,
  0,   -1 ,1,   0,
   1,   0 , 0 , 0,
   0,   0 , 0 , 0
}

CAVLC编解码原理与流程相关推荐

  1. 哈夫曼编解码原理与实现【转载】

    1. 哈夫曼编解码原理 霍夫曼编码(Huffman Coding)是一种编码方法,霍夫曼编码是可变字长编码(VLC)的一种. 霍夫曼编码使用变长编码表对源符号(如文件中的一个字母)进行编码,其中变长编 ...

  2. yolov5的anchors及bbox的编解码原理

    yolov5的anchors的编解码原理 yolov5的anchors及bbox的编解码原理 1.anchor的生成 1)base anchor的生成 2)base anchor的平移和复制 2.bb ...

  3. Base64编解码原理并用Java手工实现Base64编解码

    Base64编解码原理 目前Base64已经成为网络上常见的传输8比特字节代码的编码方式之一.在做支付系统时,系统之间的报文交互都需要使用Base64对明文进行转码,然后进行签名或加密,之后再次Bas ...

  4. 一文读懂视频编解码原理

    引子 谈到视频的编解码,我们会自然地想到H.264.HEVC/H.265这些权威的视频编解码标准:谈到标准,有人觉得这个是有专门机构去研究的,我们关心应用就好:即使有兴趣读了标准和相关技术,面对更多的 ...

  5. MPEG4编解码原理

    ### Date: 2017/3/19 ### Author: SoaringLee ###Content: MPEG4 ASP编解码原理 一.MPEG4的编码原理 1 编码原理MPEG-4编码器主要 ...

  6. adpcm编解码原理及其代码实现

    目录 1. 源代码 adpcm.h adpcm.c 2. adpcm编解码原理 1.adpcm编码原理 2.adpcm解码原理 注释说明 3. ADPCM数据存放形式 1. adpcm 数据块介绍 2 ...

  7. WAV系列之二:ADPCM编解码原理及代码实现

    参考自:<adpcm编解码原理及其代码实现> <ADPCM编码与解码学习笔记> <音频编码:ADPCM> 文章目录 1.PCM 1.1.采样 1.2.量化编码 2. ...

  8. 一文读懂视频编解码原理[通俗易懂]

    一文读懂视频编解码原理[通俗易懂] 引子 谈到视频的编解码,我们会自然地想到H.264.HEVC/H.265这些权威的视频编解码标准:谈到标准,有人觉得这个是有专门机构去研究的,我们关心应用就好:即使 ...

  9. ITU-T H.264/MPEG-4 AVC编解码原理介绍

    本文档适合基本了解数字图像处理的初学者,仅用于研究交流,由于资料来源较多,只能尽量在相关章节注明出处. 转载本文请注明出处http://blog.csdn.net/chinadragon76/arti ...

最新文章

  1. 【机器学习】解决中小微企业的信贷决策问题(一)
  2. 北京招聘 | 新浪微博机器学习部门招聘推荐算法开发实习生
  3. java短除法获取二进制_Java十四天零基础入门-Java的数据类型介绍
  4. python ansible模块_python学习-ansible简单使用1
  5. 【英语学习】【Daily English】U07 Restaurant L03 What do you recommend?
  6. linux server 5.5下载地址,《红帽Linux 5.5 for x86 服务器版》(RedHat Enterprise Linux Server 5.5 for x86)...
  7. 值得所有设计师拥有的国内外“设计导航网站”
  8. IT行业最重要的四件宝--我的实习体会
  9. 深度残差网络(ResNet)详解与实现(tensorflow2.x)
  10. MCGS昆仑动态显示屏组态环境搭建介绍
  11. 智慧工地解决方案施工升降机智能监控系统
  12. 数值分析与算法——读书笔记(一)
  13. 创业公司一年工作总结(转)(公司失败原因)
  14. 第十一章 性能与可伸缩性(待续)
  15. 计算机如何寻找ppt文件,电脑上没保存的PPT怎么找回来
  16. 3分钟短文:Laravel的“南天门”,过滤掉七七八八的数据
  17. ​predis操作大全​
  18. Worksoft Certify学习之路
  19. Python爬取网站数据
  20. vivado下ila文件的读取和显示

热门文章

  1. 容器编排技术 -- Pod 安全策略
  2. 一款不错的开源 Laravel 后台面板/CMS系统 —— LaraAdmin
  3. Primefaces,Spring 4 with JPA(Hibernate 4 / EclipseLink)示例教程
  4. mysql 数据库链路_MySQL数据库使用(二):配置、连接远端数据库
  5. 高能解析得时候忽略某个字段_我们什么时候应该忽略批评?
  6. 3d正方体旋转相册代码_3d旋转正方体的多种html和css制作方法和相关知识复习讲解
  7. 关于抽象类与接口的理解
  8. python合并 txt
  9. Flink 有状态计算的状态容错
  10. Python matplotlib绘制雷达图