【H.264/AVC视频编解码技术详解】十三、熵编码算法(4):H.264使用CAVLC解析宏块的残差数据

本文涉及的产品
全局流量管理 GTM,标准版 1个月
云解析 DNS,旗舰版 1个月
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
简介: 《H.264/AVC视频编解码技术详解》视频教程已经在“CSDN学院”上线,视频中详述了H.264的背景、标准协议和实现,并通过一个实战工程的形式对H.

《H.264/AVC视频编解码技术详解》视频教程已经在“CSDN学院”上线,视频中详述了H.264的背景、标准协议和实现,并通过一个实战工程的形式对H.264的标准进行解析和实现,欢迎观看!

“纸上得来终觉浅,绝知此事要躬行”,只有自己按照标准文档以代码的形式操作一遍,才能对视频压缩编码标准的思想和方法有足够深刻的理解和体会!

链接地址:H.264/AVC视频编解码技术详解

GitHub代码地址:点击这里


1. H.264的CAVLC解析宏块残差数据的流程

在H.264的解码器在解析宏块的残差数据时,其流程类似于上文提到的CAVLC编码的逆过程。在解析一个宏块残差的时候,首先解析的是残差矩阵的非零系数以及拖尾系数的个数numCoefftrailingOnes。随后是每一个拖尾系数的符号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部分复杂,总体上可以分为以下几个步骤:

  1. 解析过程开始之前,初始化suffixLength的值:当非零系数总数numCoeff大于10且拖尾系数个数trailingOnes等于3时,suffixLength初始化为1,否则初始化为0;
  2. 确定levelSuffixSize的值:通常情况下,levelSuffixSize的值等于当前的suffixLength,除了下列两种意外情况:第一,level_prefix的值等于14且suffixLength为0,此时levelSuffixSize设为4;第二,level_prefix大于等于15,此时levelSuffixSize设为level_prefix-3;
  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视频编解码技术详解中观看。

目录
相关文章
|
21天前
|
存储 算法 安全
.NET 平台 SM2 国密算法 License 证书生成深度解析
授权证书文件的后缀通常取决于其编码格式和具体用途。本文档通过一个示例程序展示了如何在 .NET 平台上使用国密 SM2 算法生成和验证许可证(License)文件。该示例不仅详细演示了 SM2 国密算法的实际应用场景,还提供了关于如何高效处理大规模许可证文件生成任务的技术参考。通过对不同并发策略的性能测试,开发者可以更好地理解如何优化许可证生成流程,以满足高并发和大数据量的需求。 希望这段描述更清晰地传达了程序的功能和技术亮点。
94 13
.NET 平台 SM2 国密算法 License 证书生成深度解析
|
24天前
|
机器学习/深度学习 算法 搜索推荐
联邦学习的未来:深入剖析FedAvg算法与数据不均衡的解决之道
随着数据隐私和数据安全法规的不断加强,传统的集中式机器学习方法受到越来越多的限制。为了在分布式数据场景中高效训练模型,同时保护用户数据隐私,联邦学习(Federated Learning, FL)应运而生。它允许多个参与方在本地数据上训练模型,并通过共享模型参数而非原始数据,实现协同建模。
|
4天前
|
资源调度 算法 数据可视化
基于IEKF迭代扩展卡尔曼滤波算法的数据跟踪matlab仿真,对比EKF和UKF
本项目基于MATLAB2022A实现IEKF迭代扩展卡尔曼滤波算法的数据跟踪仿真,对比EKF和UKF的性能。通过仿真输出误差收敛曲线和误差协方差收敛曲线,展示三种滤波器的精度差异。核心程序包括数据处理、误差计算及可视化展示。IEKF通过多次迭代线性化过程,增强非线性处理能力;UKF避免线性化,使用sigma点直接处理非线性问题;EKF则通过一次线性化简化处理。
|
10天前
|
存储 监控 算法
关于员工上网监控系统中 PHP 关联数组算法的学术解析
在当代企业管理中,员工上网监控系统是维护信息安全和提升工作效率的关键工具。PHP 中的关联数组凭借其灵活的键值对存储方式,在记录员工网络活动、管理访问规则及分析上网行为等方面发挥重要作用。通过关联数组,系统能高效记录每位员工的上网历史,设定网站访问权限,并统计不同类型的网站访问频率,帮助企业洞察员工上网模式,发现潜在问题并采取相应管理措施,从而保障信息安全和提高工作效率。
30 7
|
11天前
|
缓存 监控 算法
基于 C# 网络套接字算法的局域网实时监控技术探究
在数字化办公与网络安全需求增长的背景下,局域网实时监控成为企业管理和安全防护的关键。本文介绍C#网络套接字算法在局域网实时监控中的应用,涵盖套接字创建、绑定监听、连接建立和数据传输等操作,并通过代码示例展示其实现方式。服务端和客户端通过套接字进行屏幕截图等数据的实时传输,保障网络稳定与信息安全。同时,文章探讨了算法的优缺点及优化方向,如异步编程、数据压缩与缓存、错误处理与重传机制,以提升系统性能。
32 2
|
18天前
|
监控 网络协议 算法
基于问题“如何监控局域网内的电脑”——Node.js 的 ARP 扫描算法实现局域网内计算机监控的技术探究
在网络管理与安全领域,监控局域网内计算机至关重要。本文探讨基于Node.js的ARP扫描算法,通过获取IP和MAC地址实现有效监控。使用`arp`库安装(`npm install arp`)并编写代码,可定期扫描并对比设备列表,判断设备上线和下线状态。此技术适用于企业网络管理和家庭网络安全防护,未来有望进一步提升效率与准确性。
33 8
|
17天前
|
算法 图形学 数据安全/隐私保护
基于NURBS曲线的数据拟合算法matlab仿真
本程序基于NURBS曲线实现数据拟合,适用于计算机图形学、CAD/CAM等领域。通过控制顶点和权重,精确表示复杂形状,特别适合真实对象建模和数据点光滑拟合。程序在MATLAB2022A上运行,展示了T1至T7的测试结果,无水印输出。核心算法采用梯度下降等优化技术调整参数,最小化误差函数E,确保迭代收敛,提供高质量的拟合效果。
|
25天前
|
算法 Serverless 数据处理
从集思录可转债数据探秘:Python与C++实现的移动平均算法应用
本文探讨了如何利用移动平均算法分析集思录提供的可转债数据,帮助投资者把握价格趋势。通过Python和C++两种编程语言实现简单移动平均(SMA),展示了数据处理的具体方法。Python代码借助`pandas`库轻松计算5日SMA,而C++代码则通过高效的数据处理展示了SMA的计算过程。集思录平台提供了详尽且及时的可转债数据,助力投资者结合算法与社区讨论,做出更明智的投资决策。掌握这些工具和技术,有助于在复杂多变的金融市场中挖掘更多价值。
47 12
|
16天前
|
存储 监控 算法
公司监控上网软件架构:基于 C++ 链表算法的数据关联机制探讨
在数字化办公时代,公司监控上网软件成为企业管理网络资源和保障信息安全的关键工具。本文深入剖析C++中的链表数据结构及其在该软件中的应用。链表通过节点存储网络访问记录,具备高效插入、删除操作及节省内存的优势,助力企业实时追踪员工上网行为,提升运营效率并降低安全风险。示例代码展示了如何用C++实现链表记录上网行为,并模拟发送至服务器。链表为公司监控上网软件提供了灵活高效的数据管理方式,但实际开发还需考虑安全性、隐私保护等多方面因素。
21 0
公司监控上网软件架构:基于 C++ 链表算法的数据关联机制探讨
|
1月前
|
监控 算法 安全
内网桌面监控软件深度解析:基于 Python 实现的 K-Means 算法研究
内网桌面监控软件通过实时监测员工操作,保障企业信息安全并提升效率。本文深入探讨K-Means聚类算法在该软件中的应用,解析其原理与实现。K-Means通过迭代更新簇中心,将数据划分为K个簇类,适用于行为分析、异常检测、资源优化及安全威胁识别等场景。文中提供了Python代码示例,展示如何实现K-Means算法,并模拟内网监控数据进行聚类分析。
43 10

热门文章

最新文章

推荐镜像

更多