【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编码的逆过程。

在解析一个宏块残差的时候。首先解析的是残差矩阵的非零系数以及拖尾系数的个数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视频编解码技术具体解释中观看。

时间: 2024-10-10 16:52:17

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

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

<H.264/AVC视频编解码技术详解>视频教程已经在"CSDN学院"上线,视频中详述了H.264的背景.标准协议和实现,并通过一个实战工程的形式对H.264的标准进行解析和实现,欢迎观看! "纸上得来终觉浅,绝知此事要躬行",只有自己按照标准文档以代码的形式操作一遍,才能对视频压缩编码标准的思想和方法有足够深刻的理解和体会! 链接地址:H.264/AVC视频编解码技术详解 GitHub代码地址:点击这里 1. H.264的CAVLC解析宏块残差数据的流

【H.264/AVC视频编解码技术详解】十一、H.264的Slice Header解析

<H.264/AVC视频编解码技术详解>视频教程已经在"CSDN学院"上线,视频中详述了H.264的背景.标准协议和实现,并通过一个实战工程的形式对H.264的标准进行解析和实现,欢迎观看! "纸上得来终觉浅,绝知此事要躬行",只有自己按照标准文档以代码的形式操作一遍,才能对视频压缩编码标准的思想和方法有足够深刻的理解和体会! 链接地址:H.264/AVC视频编解码技术详解 GitHub代码地址:点击这里 H.264中的条带(Slice) 1. Slic

【H.264/AVC视频编解码技术详解】十三、熵编码算法(3):CAVLC原理

<H.264/AVC视频编解码技术详解>视频教程已经在"CSDN学院"上线,视频中详述了H.264的背景.标准协议和实现,并通过一个实战工程的形式对H.264的标准进行解析和实现,欢迎观看! "纸上得来终觉浅,绝知此事要躬行",只有自己按照标准文档以代码的形式操作一遍,才能对视频压缩编码标准的思想和方法有足够深刻的理解和体会! 链接地址:H.264/AVC视频编解码技术详解 GitHub代码地址:点击这里 上下文自适应的变长编码(Context-base

【视频编解码&#183;学习笔记】8. 熵编码算法:基本算法列举 &amp; 指数哥伦布编码

一.H.264中的熵编码基本方法: 熵编码具有消除数据之间统计冗余的功能,在编码端作为最后一道工序,将语法元素写入输出码流 熵解码作为解码过程的第一步,将码流解析出语法元素供后续步骤重建图像使用 在H.264的标准协议中,不同的语法元素指定了不同的熵编码方法.在协议文档中共指定了10种语法元素的描述符,这些描述符表达了码流解析为语法元素值的方法,其中包含了H.264标准所支持的所有熵编码方法: 语法元素描述符 编码方法 b(8) 8位二进制比特位串,用于描述rbsp_byte() f(n) n位

音视频开发的视频编解码技术

2012年8月,爱立信公司推出了首款H.265[1]编解码器,而在仅仅六个月之后,国际电联(ITU)就正式批准通过了HEVC/H.265标准,标准全称为高效视频编码(High Efficiency Video Coding),相较于之前的H.264标准有了相当大的改善,中国华为公司拥有最多的核心专利,是该标准的主导者.国内拥有领先音视频开发技术的AnyChat解决方案,目前采用的是H.264视频编解码技术,相信不久会紧跟趋势采用H.265视频编解码技术. H.265/HEVC的编码架构大致上和H

视频编解码技术详解(H.264、MPEG-4)

一.视频编解码概述 1. 应用场景 视频编码的目的就是压缩视频的占用空间,提高存储和传输的效率,在获得有效的压缩效果的同时,使得压缩过程引起的失真最小.视频压缩算法是通过去除时间.空间的冗余来实现的.通过去除不同类型的冗余,可以明显的压缩数据,代价就是一部分信息失真,可以通过熵编码器(如哈夫曼编码等)进行编码可以获得更高的压缩比.目前主流的图像/视频压缩标准为:JPEG,MPEG,H26X等标准. 2. 主流视频编码标准简介 MPEG-4和H.264(也叫AVC)是目前较为主流的编码标准.每个标

音视频编解码技术的陷阱与出路,一个研发人员的思考

原来做过挺长时间的音视频编解码的东西,该做个总结了.这里就说下关于音视频编码这类工作的得失与取舍,其实主要是舍,有没有道理,权当一听.各位读者自行判断吧. 拿视频编码标准H.264来说,这真是个好事,视频编码标准化之后,兼容问题就“有法可依”了,利于影片.视频等的传播.但是,却给研究人员带来一个大问题.那就是在同样的标准下,各家公司如何竞争的问题.算法一旦标准化,就失去了发挥的灵活性,每个人.每个公司都是做这些东西.同时也成为了实力雄厚的大公司必须争夺的一个技术高地.其它公司如果也想争一下,就基

视频编解码的理论和实践2:Ffmpeg视频编解码

近几年,视频编解码技术在理论及应用方面都取得了重大的进展,越来越多的人想要了解编解码技术.因此,网易云信研发工程师为大家进行了归纳梳理,从理论及实践两个方面简单介绍视频编解码技术. 相关阅读推荐 <视频直播关键技术:流畅.拥塞和延时追赶> <视频直播技术详解:直播的推流调度> <音视频通话:小议音频处理与压缩技术> <视频编解码的理论和实践1:基础知识介绍>   1.Ffmpeg介绍 <视频编解码的理论和实践1:基础知识介绍>介绍了视频编码的基础

【技术案例】Firefly-RK3399多路视频编解码

Firefly-RK3399开源板拥有强大的视像处理器(VPU),能够流畅的实现H.264编解码功能,可以同时进行两路视频编码和五路视频解码.在应用方面,多路编解码功能可以更优秀地应用于同时录像和播放多个视频的场景. 一.多路视频编解码演示需要准备: (1)一台Firefly-RK3399开源板 (2)两个MIPI摄像头 (3)一台LCD显示器 二.把两个摄像头连接到Firefly-RK3399开源板上 三.进入应用列表,打开多路视频编解码应用MultiCodecs 四.打开MultiCodec