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

简介: 《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视频编解码技术详解中观看。

目录
相关文章
|
10天前
|
机器学习/深度学习 存储 算法
动态规划算法深度解析:0-1背包问题
0-1背包问题是经典的组合优化问题,目标是在给定物品重量和价值及背包容量限制下,选取物品使得总价值最大化且每个物品仅能被选一次。该问题通常采用动态规划方法解决,通过构建二维状态表dp[i][j]记录前i个物品在容量j时的最大价值,利用状态转移方程避免重复计算子问题,从而高效求解最优解。
161 1
|
10天前
|
算法 搜索推荐 Java
贪心算法:部分背包问题深度解析
该Java代码基于贪心算法求解分数背包问题,通过按单位价值降序排序,优先装入高价值物品,并支持部分装入。核心包括冒泡排序优化、分阶段装入策略及精度控制,体现贪心选择性质,适用于可分割资源的最优化场景。
113 1
贪心算法:部分背包问题深度解析
|
10天前
|
机器学习/深度学习 边缘计算 人工智能
粒子群算法模型深度解析与实战应用
蒋星熠Jaxonic是一位深耕智能优化算法领域多年的技术探索者,专注于粒子群优化(PSO)算法的研究与应用。他深入剖析了PSO的数学模型、核心公式及实现方法,并通过大量实践验证了其在神经网络优化、工程设计等复杂问题上的卓越性能。本文全面展示了PSO的理论基础、改进策略与前沿发展方向,为读者提供了一份详尽的技术指南。
34 0
粒子群算法模型深度解析与实战应用
|
10天前
|
机器学习/深度学习 资源调度 算法
遗传算法模型深度解析与实战应用
摘要 遗传算法(GA)作为一种受生物进化启发的优化算法,在复杂问题求解中展现出独特优势。本文系统介绍了GA的核心理论、实现细节和应用经验。算法通过模拟自然选择机制,利用选择、交叉、变异三大操作在解空间中进行全局搜索。与梯度下降等传统方法相比,GA不依赖目标函数的连续性或可微性,特别适合处理离散优化、多目标优化等复杂问题。文中详细阐述了染色体编码、适应度函数设计、遗传操作实现等关键技术,并提供了Python代码实现示例。实践表明,GA的成功应用关键在于平衡探索与开发,通过精心调参维持种群多样性同时确保收敛效率
51 7
机器学习/深度学习 算法 自动驾驶
109 0
|
16天前
|
机器学习/深度学习 人工智能 资源调度
大语言模型的核心算法——简要解析
大语言模型的核心算法基于Transformer架构,以自注意力机制为核心,通过Q、K、V矩阵动态捕捉序列内部关系。多头注意力增强模型表达能力,位置编码(如RoPE)解决顺序信息问题。Flash Attention优化计算效率,GQA平衡性能与资源消耗。训练上,DPO替代RLHF提升效率,MoE架构实现参数扩展,Constitutional AI实现自监督对齐。整体技术推动模型在长序列、低资源下的性能突破。
152 8
|
18天前
|
算法 API 数据安全/隐私保护
深度解析京东图片搜索API:从图像识别到商品匹配的算法实践
京东图片搜索API基于图像识别技术,支持通过上传图片或图片URL搜索相似商品,提供智能匹配、结果筛选、分页查询等功能。适用于比价、竞品分析、推荐系统等场景。支持Python等开发语言,提供详细请求示例与文档。
|
2月前
|
机器学习/深度学习 人工智能 编解码
AI视觉新突破:多角度理解3D世界的算法原理全解析
多视角条件扩散算法通过多张图片输入生成高质量3D模型,克服了单图建模背面细节缺失的问题。该技术模拟人类多角度观察方式,结合跨视图注意力机制与一致性损失优化,大幅提升几何精度与纹理保真度,成为AI 3D生成的重要突破。
171 0
|
2月前
|
机器学习/深度学习 人工智能 自然语言处理
深度学习模型、算法与应用的全方位解析
深度学习,作为人工智能(AI)的一个重要分支,已经在多个领域产生了革命性的影响。从图像识别到自然语言处理,从语音识别到自动驾驶,深度学习无处不在。本篇博客将深入探讨深度学习的模型、算法及其在各个领域的应用。
447 3
|
2月前
|
算法 区块链 数据安全/隐私保护
加密算法:深度解析Ed25519原理
在 Solana 开发过程中,我一直对 Ed25519 加密算法 如何生成公钥、签名以及验证签名的机制感到困惑。为了弄清这一点,我查阅了大量相关资料,终于对其流程有了更清晰的理解。在此记录实现过程,方便日后查阅。
152 1

热门文章

最新文章

推荐镜像

更多
  • DNS