【H.264/AVC视频编解码技术具体解释】十三、熵编码算法(4):H.264使用CAVLC解析宏块的残差数据
《H.264/AVC视频编解码技术具体解释》视频教程已经在“CSDN学院”上线,视频中详述了H.264的背景、标准协议和实现,并通过一个实战project的形式对H.264的标准进行解析和实现,欢迎观看!
“纸上得来终觉浅。绝知此事要躬行”。仅仅有自己依照标准文档以代码的形式操作一遍,才干对视频压缩编码标准的思想和方法有足够深刻的理解和体会。
链接地址:H.264/AVC视频编解码技术具体解释
GitHub代码地址:点击这里
1. H.264的CAVLC解析宏块残差数据的流程
在H.264的解码器在解析宏块的残差数据时。其流程相似于上文提到的CAVLC编码的逆过程。
在解析一个宏块残差的时候。首先解析的是残差矩阵的非零系数以及拖尾系数的个数numCoeff和trailingOnes。随后是每个拖尾系数的符号trailingSigns。而后是每个非拖尾非零系数level的值。然后解析的是最高频非零系数前面的零的总个数totalZeros。最后是每个非零系数前连续零的个数runBefore。
2. 计算CAVLC解析残差的上下文參数
CAVLC编解码过程中的上下文即为当前块值numberCurrent。该值与当前像素块的左側邻块和上方邻块中非零系数的个数有关。
以尺寸为4×4宏块切割方式为例。当前像素块同左側和上方邻块的相对位置关系例如以下图:

对于当前像素块。若其上方和左側相邻块都不可见(unavailable),那么当前像素块的numberCurrent值为0;若上方或左側,有且仅有一个相邻块是可见的。那么当前像素块的numberCurrent值即为这个邻块中非零系数的个数numCoeff;若两个邻块都是可见的,那么当前像素块的numberCurrent值为两个邻块numCoeff的四舍五入平均值。
3. 解析非零系数总个数和拖尾系数个数
在CAVLC的解析过程中。非零系数总个数numCoeff和拖尾系数个数trailingOnes两个值是一起解析出来的。
解析这两个值依据的是标准文档中的表9-5,例如以下表即是表9-5的部分:

依据之前解析出来的numberCurrent值,在这个表格中选择一列作为解码数据的參考。此后,从码流中读取对应长度的二进制码流。与表格中的值相比較。当码流与表格中的值匹配时,表格的前两列作为数组的下标。其值即等于希望解析出来的numCoeff和trailingOnes的值。
4. 解析拖尾系数的符号
我们知道变换系数矩阵中最高频的几个绝对值为1的非零系数称之为拖尾系数,其个数范围为0~3个。
表示每个拖尾系数的符号能够一个bit的trailing_ones_sign_flag表示:
- 当trailing_ones_sign_flag为1,拖尾系数符号为-。
- 当trailing_ones_sign_flag为0,拖尾系数符号为+;
5. 解析非零系数的幅值
非拖尾的非零系数的幅值通常表示为levels。
Levels的解析相对较为复杂。该部分是从最高频開始解析到最低频的非零系数为止。也就是说,levels部分是按频率倒序解析的。
在解析每个level的时候。每个值都会依照前缀(prefix)和后缀(suffix)两部分进行解析。
5.1 解析level_prefix部分:
Level_prefix部分即level的前缀部分,该部分的解析较为简单,以伪代码表示如:
leadingZeroBits = −1
for( b = 0; !b; leadingZeroBits++ )
b = read_bits( 1 )
level_prefix = leadingZeroBits
结合标准文档中的表9-6的表述可知。level的前缀值即为当前码流的下一个比特1之前连续的比特0的个数。
5.2 解析level_suffix部分:
Level_suffix部分的解析比prefix部分复杂,整体上能够分为下面几个步骤:
- 解析过程開始之前。初始化suffixLength的值:当非零系数总数numCoeff大于10且拖尾系数个数trailingOnes等于3时,suffixLength初始化为1,否则初始化为0;
- 确定levelSuffixSize的值:通常情况下,levelSuffixSize的值等于当前的suffixLength。除了下列两种意外情况:第一。level_prefix的值等于14且suffixLength为0,此时levelSuffixSize设为4;第二,level_prefix大于等于15,此时levelSuffixSize设为level_prefix-3。
- 解析level_suffix的值:依据levelSuffixSize的值作为长度。在码流中读取对应的二进制数据作为level_suffix。若levelSuffixSize为0。则level_suffix的值为0;
5.3 由level_prefix和level_suffix部分组合成为levelCode
在解析完毕level_prefix和level_suffix之后,将二者组合生成levelCode。
计算方法为:levelCode=(Min(15,level_prefix)<
5.3 由levelCode计算level
依据计算得到的levelCode的奇偶性。推断level的符号:
- 若levelCode是偶数,返回level值为(levelCode + 2)>>1;
- 若levelCode为奇数,返回level值为(−levelCode−1)>>1;
5.4 更新suffixLength的值
在解析过程中更新suffixLength体现了上下文自适应的思想。
- 当suffixLength = 0时。suffixLength更新为1;
- 当suffixLength小于6。且刚刚解析出来的level值大于阈值threshold时,suffixLength自增1;阈值threshold定义为( 3 << ( suffixLength − 1 ) );
6. 解析零系数信息
变换系数矩阵中的零系数也是重要的信息。CAVLC解析的零系数信息主要分两类:
- totalZeros:每个矩阵一个值,表示最高频非零系数前零系数的总个数;
- runBefore:每个非零系数一个值,表示该非零系数前连续0的总个数。
解析totalZeros的过程与解析numCoeff和trailingOnes相似,都是从一个二维表格中查找某列表格,在从码流中查找与表格中匹配的值。然后索引便是所求的totalZeros值。解析totalZeros的表格为标准文档中的表9-7。下图是表9-7的局部:

在解析totalZeros的过程中。选择表格的索引值等于当前矩阵块的非零系数个数numCoeff。
解析每个非零系数的runBefore时,也是依照从高频到低频逆序处理的。每次解析的runBefore也是依照相似上述的解析方法。从码流中读取对应长度的码流并与表格中的值比对,匹配后返回索引值作为解析的值。解析runBefore參考标准文档的表9-10:

每次解析出一个runBefore后,totalZeros都要减去该值,然后进行下一次处理。若有n个非零系数。则总共须要解析n-1个runBefore。最低频率的非零系数前的runBefore不须要写在码流中,由于能够通过上述信息推算出。
以上就是解析一个宏块的4×4残差系数矩阵对应语法元素的主要思想和过程。当然实际的解析过程比此要复杂得多,更具体的情况可到CSDN学院的课程:H.264/AVC视频编解码技术具体解释中观看。
【H.264/AVC视频编解码技术具体解释】十三、熵编码算法(4):H.264使用CAVLC解析宏块的残差数据的更多相关文章
- 【视频编解码·学习笔记】8. 熵编码算法:基本算法列举 & 指数哥伦布编码
一.H.264中的熵编码基本方法: 熵编码具有消除数据之间统计冗余的功能,在编码端作为最后一道工序,将语法元素写入输出码流 熵解码作为解码过程的第一步,将码流解析出语法元素供后续步骤重建图像使用 在H ...
- 【视频编解码·学习笔记】7. 熵编码算法:基础知识 & 哈夫曼编码
一.熵编码概念: 熵越大越混乱 信息学中的熵: 用于度量消息的平均信息量,和信息的不确定性 越是随机的.前后不相关的信息,其熵越高 信源编码定理: 说明了香农熵越信源符号概率之间的关系 信息的熵为信源 ...
- [转帖]AVS音视频编解码技术了解
AVS高清立体视频编码器 电视技术在经历了从黑白到彩色.从模拟到数字的技术变革之后正在酝酿另一场技术革命,从单纯观看二维场景的平面电视跨越到展现三维场景的立体电视3DTV.3DTV系统的核心问题之一是 ...
- 音视频编解码技术(一):MPEG-4/H.264 AVC 编解码标准
一.H264 概述 H.264,通常也被称之为H.264/AVC(或者H.264/MPEG-4 AVC或MPEG-4/H.264 AVC) 1. H.264视频编解码的意义 H.264的出现就是为了创 ...
- 音视频编解码技术(二):AAC 音频编码技术
一.AAC编码概述 AAC是高级音频编码(Advanced Audio Coding)的缩写,出现于1997年,最初是基于MPEG-2的音频编码技术,目的是取代MP3格式.2000年,MPEG-4标准 ...
- 视频编解码学习之路(H264)
学习视频编解码技术很难吗?视频编解码技术的未来是什么? 明了的说,无论是软件还是硬件设计,视频编解码技术有很多难点,都需要很长一段时间积累才行. 从一开始接触MPEG-2到最新的H.264标准,可算走 ...
- 视频编解码的理论和实践2:Ffmpeg视频编解码
近几年,视频编解码技术在理论及应用方面都取得了重大的进展,越来越多的人想要了解编解码技术.因此,网易云信研发工程师为大家进行了归纳梳理,从理论及实践两个方面简单介绍视频编解码技术. 相关阅读推荐 &l ...
- H.264视频编解码SoC满足高清DVR设计需求
硬盘录像机(DVR)作为监控系统的核心部件之一,在10年里高速发展,从模拟磁带机的替代品演变成具有自己独特价值的专业监控数字平台,并被市场广泛接受.监控系统伴随DVR这些年的发展向着IP化.智能化发展 ...
- 各种音视频编解码学习详解 h264 ,mpeg4 ,aac 等所有音视频格式
编解码学习笔记(一):基本概念 媒体业务是网络的主要业务之间.尤其移动互联网业务的兴起,在运营商和应用开发商中,媒体业务份量极重,其中媒体的编解码服务涉及需求分析.应用开发.释放 license收费等 ...
随机推荐
- 【TP3.2与TP5.0区别】
Tp3.2 和 Tp5.0之间的区别 5.0版本和之前版本的差异较大,本篇对熟悉3.2版本的用户给出了一些5.0的主要区别. URL和路由 5.0的URL访问不再支持普通URL模式,路由也不支持正 ...
- Eclipse默认编码格式设置方式
看图即可 STEP ONE: STEP TWO: STEP THREE: STEP FOUR: 项目右击——>Properties 参阅: eclipse编码格式设置 - AlanLee(Jav ...
- static 与单例模式、auto_ptr与单例模式、const 用法小结、mutable修饰符
一.static 与单例模式 单例模式也就是简单的一种设计模式,它需要: 保证一个类只有一个实例,并提供一个全局访问点 禁止拷贝 C++ Code 1 2 3 4 5 6 7 8 9 10 11 ...
- C++ 编译,执行过程 具体解释。
要更深入了解C++, 必需要知道一个程序从開始到结束都干了些什么, 怎么干的. 所以我从C++编译到执行过程,解析下程序是怎么跑的. 首先,初略的说一下之前C++的编译过程.C++编译过程包含预编译- ...
- hive 分位数函数 percentile(col, p)
注意在偶数情况下,中位数会存在小数,特别注意! hive里面倒是有个percentile函数和percentile_approx函数,其使用方式为percentile(col, p).percenti ...
- java中GET方式提交和POST方式提交
java中GET方式提交的示例: /** * 获取关注列表; * @return */ @SuppressWarnings("unchecked") public static A ...
- django Multi-table inheritance ---- 用于实现基表-子表
SQL中的父子表.在django中可以直接通过模式的继承来完成! 一.django中的model定义如下: 1.django定义 from django.db import models # Crea ...
- atitit.新增编辑功能 跟orm的实现 attilax p31
atitit.新增编辑功能 跟orm的实现 attilax p31 1. 流程的实现 1 2. view的实现(dwr) 1 3. 获取表结构 1 4. grep filt req params 2 ...
- Atitit. 有限状态机 fsm 状态模式
Atitit. 有限状态机 fsm 状态模式 1. 有限状态机 1 2. "状态表"和"状态轮换表" 1 3. 有限状态机概念(状态(State)事件(Even ...
- 使用c++的cocos2d-x-3.0rc1程序公布apk
(如今cocos2dx-x-3.0正式版已经出了.之前用的cocos2d-x-3.0rc1,就先用这个版本号吧) 0. 完毕C++项目 在cmd下使用cocos.py new命令,然后习惯性的在win ...