《H.264/AVC视频编解码技术详解》视频教程已经在“CSDN学院”上线,视频中详述了H.264的背景、标准协议和实现,并通过一个实战工程的形式对H.264的标准进行解析和实现,欢迎观看!
“纸上得来终觉浅,绝知此事要躬行”,只有自己按照标准文档以代码的形式操作一遍,才能对视频压缩编码标准的思想和方法有足够深刻的理解和体会!
链接地址:H.264/AVC视频编解码技术详解
GitHub代码地址:点击这里
一、视频的时间冗余
在本系列博文的第三篇中,我们初步了解了H.264视频编码技术的基本结构和框架:
在H.264中,预测编码与变换/量化编码、熵编码并列的重要组成部分,对编解码器的性能具有重大影响。预测编码主要包括两部分:帧内预测和帧间预测。在前面的博文中我们讨论了帧内预测编码的基本原理和实现方法:
帧内编码的图像其最主要特点是可以不依赖参考图像,可以独立解码,因而可以作为一个GOP的起点和随机接入点,即IDR帧;然而另一方面,按照帧内编码输出的码率相对较高,即压缩率较低。究其原因在于,帧内编码为了确保可独立解码这一最关键的特性,只利用了图像的空间冗余进行压缩,无法充分利用视频信息前后帧之间的关联。
与帧内编码不同,帧间编码所利用的是视频的时间冗余。通常在视频信息中,每一帧所包含的物体对象与其前后帧之间存在运动关系,这种物体的运动关系即构成帧与帧之间的时间冗余。由于帧与帧之间物体的运动相关性大于一帧内部相邻像素之间的相关性,尤其对于时间相近的图像之间,时间冗余比空间冗余更加明显。
图像之间物体的运动关系可由下图表示:
二、块结构的运动估计和运动补偿
在H.264中,压缩时间冗余并非通过前帧和后帧之间求取整帧差分这种低效率的方法。H.264是一种基于块结构的混合编码标准,因此帧间编码也以像素块的形式实现。同帧内编码类似,帧间编码同样以一个宏块(Macroblock, MB)作为最小单位进行。
在H.264的整体流程中,帧间编码可分为几个步骤执行:
- 预测编码(包括运动估计/运动补偿过程);
- 变换/量化编码;
- 熵编码;
- 参考帧管理;
其中,变换/量化编码和熵编码采用了与帧内编码相同或相似的方案。而预测编码采用了基于块的运动估计(Motion Estimation, ME)和运动补偿(Motion Compensation, MC)的方法,此方法与帧内预测对应,亦称为帧间预测(Inter-Frame Prediction/Inter Prediction)。在H.264框架中表示如下图所示:
三、运动估计
运动估计,有时也称作运动搜索,即在相应参考帧中搜索当前像素块的对应参考像素块,使最终的编码代价最小。为了实现这个目标,相比帧内编码所定义的16×16和8×8两种宏块划分方式,帧间编码定义了更多、更复杂的方法。
3.1 运动估计宏块划分
当一个宏块将按帧间编码进行编码时,该宏块将按照某种预定义的方法进行分割。针对帧间预测,H.264定义了4种宏块分割和4种子宏块分割方式:
- 宏块分割:16×16、16×8、8×16、8×8;
- 子宏块分割:8×8、8×4、4×8、4×3;
帧间预测的宏块分割如下图所示:
当某个宏块配置为8×8形式时,每个8×8宏块将按照子宏块的分割方法来进行进一步分割。
3.2 运动矢量
在一个帧间编码宏块中,每一个分割后的子块都会进行相应的运动搜索,在参考帧中查找对应的相同尺寸的像素块作为参考。当前像素块在当前帧中的位置同参考块在参考帧总的位置之间的相对位置代表了像素块中的物体在两帧之间的运动轨迹。这个相对位置以两个坐标值组成的矢量(MV_x, MV_y)表示,称为运动矢量(Motion Vector, MV)。一个宏块最多可能包含16个MV。一个运动矢量的例子可由下图表示:
在上图中某个像素块在参考帧和当前帧中不存在运动关系,因此运动矢量为(0,0)。
运动矢量预测
对于一个帧间编码宏块,最多可以分割成16个4×4像素大小的子块来进行运动估计。每一个子块都按照实际的运动矢量进行编码和传输需要较多的比特数。为了提升编码的效率,H.264中定义了运动矢量预测的方法。每一个子块的运动矢量MV由计算得到的预测矢量MVP和运动矢量残差MVD得到。其中,MVD从码流中相应的语法元素解析得到,MVP由相邻像素块的信息计算得到。
由于相邻的宏块或者子块通常具有相似的运动关系和空间相关性,因此MVP的值由相邻像素块的MV值计算得到。当前块同相邻块之间的相互关系可由下图表示:
其中,当前块的MVP由A、B和C块的MV取中间值计算得到。如果像素块C不存在,那么以像素块D取而代之。如果当前宏块采用了SKIP模式编码(即码流中不传递相应的数据),则按照16×16模式宏块的方法计算MVP。
运动矢量亚像素差值
为了进一步提升运动估计的精度,提升视频压缩的比率,在比H.264更早的视频压缩标准中就引入了亚像素精度的运动矢量,在H.264中又得到了进一步的继承和发展。在H.264中,亮度分量的MV最高可达1/4像素精度,色度分量的MV最高可达1/8像素精度。无论1/2、1/4或1/8像素位置上的像素值在图像中都是不存在的,只是作为在运动估计过程中的一个临时值存在。
其中,1/2像素精度的亚像素可由下图表示:
1/4像素精度的亚像素可由下图表示:
1/8像素精度的亚像素可由下图表示:
由上图可知,亚像素精度就是根据相邻像素值计算得到的,理论上存在于实际像素之间的一个中间值。其计算方法是由当前相邻的几个像素计算加权均值的方式得到,具体的计算方法定义在标准文档的8.4.2.2.1节中。亮度信息的插值如下图:
在上图中,大写字母A~U表示的是图像中实际存在的整数像素点,其他字母表示的是差值计算得到的亚像素点。对于水平和垂直方向的半像素点b和h,其计算方法为相邻6个像素的加权均值,计算方法为:
b = (( E − 5*F + 20*G + 20*H − 5*I + J) + 16) >> 5;
h = (( A − 5*C + 20*G + 20*M − 5*R + T) + 16) >> 5;
对于四个像素的中间点j,其计算方法与b和h类似,只是用于计算加权均值的像素变为了同方向上的6个半像素点:
j = (( cc − 5*dd + 20*h1 + 20*m1 − 5*ee + ff) + 512) >> 10;或
j = (( aa − 5*bb + 20*b1 + 20*s1 − 5*gg + hh) + 512) >> 10;
上式中的cc等像素点的计算方法类似b或h等半像素点的计算方法中的加权求和方法,已(1, -5, 20, 20, -5, 1)为权值求和。
对于1/4像素位置的值,其计算方法更为简单,即取其相邻的整像素或半像素的值取平均即可。
四、运动搜索快速算法
完全的运动搜索过程是一种极为耗时的操作,其主要原因有:
- 运动搜索过程需要覆盖搜索区中的每个像素和亚像素;
- 运动搜索需要在多个参考帧中进行;
为了解决这个问题,研究人员提出了多种运动搜索的优化算法,旨在降低运动搜索的总运算量。其中比较常见的有:
- 三步搜索法;
- 菱形搜索法;
- 六边形搜索法;
4.1 三步搜索法
三步搜索法对比全搜索只有约1/10的计算量,而算法性能基本一致。三步搜索法如图所示:
三步搜索法运行过程:
- 从搜索窗口中心开始,以4为步长搜索8个点+中心点共9个点,以SAD最小的原则选择一个最佳匹配点;
- 以步骤1得到的最佳匹配点为中心点,以2为步长继续搜索相似的9个点,得到第二个最佳匹配点;
- 从第二个最佳匹配点开始,以1为步长重复上述步骤,得到最终的运动搜索匹配点;
4.2 菱形搜索法
菱形搜索法使用大菱形和小菱形两种模板,大菱形包含9个点,小菱形包含5个点,如下图所示:
菱形搜索法执行步骤:
- 从搜索窗口中心开始,按照大菱形模板搜索9个点,检查菱形中心点是否是大菱形中的最佳匹配点;
- 如果最佳匹配点是菱形的中心点,则进一步按照小菱形模板进行搜索;
- 如果最佳匹配点不是菱形中心点,则按照实际的最佳匹配点继续按大菱形模板搜索,直到找到某个最佳匹配点在大菱形模板的中心点,然后按小菱形模板搜索;
4.3 六边形搜索法
六边形搜索的原理同菱形搜索法类似,区别在于其大模板采用的模板为7个点的六边形形状,而小六边形模板的形状同菱形模板相同,如下图所示:
六边形搜索执行步骤:
- 从搜索窗口中心开始,按照大六边形模板搜索9个点,检查菱形中心点是否是大六边形中的最佳匹配点;
- 如果最佳匹配点是六边形的中心点,则进一步按照小六边形模板搜索;
- 如果最佳匹配点不是六边形中心点,则按照实际的最佳匹配点继续按大六边形模板搜索,直到找到某个最佳匹配点在大六边形模板的中心点,然后按小六边形模板搜索;
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/36344.html