HEVC帧内预测整理
HEVC帧内预测知识&代码整理
前言:2021-02-02
1.这部分主要是用来整理自己最近看的帧内预测部分的知识,为的是形成一个整体的框架,同时方便日后复习。
2.这部分的框架暂时参考书籍的结构来进行,后续可能会再做修改。
2.在看这部分知识和代码的时候,经常困扰我的一个地方就是一些变量和坐标所代表的含义。这篇博客中也会给出一些我自己的理解,望不吝指正。
参考:博主
书籍:
H.265/_HEVC:视频编码新标准及其扩展
新一代高效视频编码H.265/HEVC原理、标准与实现
2020-02-02 此部分还在继续完善,显示为”空链接“的慢慢补上
2020-02-04 空链接的部分基本补完,滤波部分代码在HM8.0中还未找到
目录
1.帧内预测预备知识部分
这一部分主要写帧内预测的一些相关知识,包括帧内部结构的划分、35种模式简介和亮度色度具体模式
1.1 HEVC结构的划分
1.条划分和片划分
左侧图片为条划分,右侧图片为片划分。
每一个条内包含若干个CTU,条的划分是以CTU为边界。条也可以被分为I、P、B,其含义和帧类似。
片划分也是包含若干个CTU。
条和片无从属关系
条划分和片划分的目的是提高并行处理速度和有利于差错控制。
2.HEVC四叉树划分
图示为HEVC里的一个结构划分框图:序列-->图片组-->帧-->编码树块-->编码块-->预测块/变化块
CTU和CU的概念:一个CTU包含1个亮度CTB、2个色度CTB和若干语法元素;一个CU包含1个亮度CB、2个色度CB和若干语法元素。
CTB--> CB的四叉树划分如下图所示:
3.CB的划分
4.PU的划分
预测单元PU是预测运算基本的单元,包含在CU,CU决定了其内部的预测模式——帧内预测/帧间预测。
CU到PU只能进行一次划分,最小的PU为4x4大小。
5.TU的划分
亮度TU的划分如图所示:
色度TU的划分最小为4x4 ,不可以再继续分解。 色度RQT和亮度RQT不同。
6. 注
PU和TU的划分相对独立
1.2 帧内预测相关知识
1.帧内预测的结构划分
帧内预测是基于TU进行的。
2.帧内预测的模式
帧内预测模式被分为两个大类,亮度帧内预测和色度帧内预测。由于人眼对于亮度信息更为敏感,所以着重研究亮度的帧内预测,色度的帧内预测在亮度的基础上进行。
其中亮度帧内预测共计35种模式, 可以被简单的分为三种 :
PLANAR模式(Intra_planar /平面模式/模式0)--水平方向和垂直方向上的线性插值
DC模式(Intra_DC /直流模式/模式1)--当前块所有像素使用一个平均值
角度模式(Intra_Angular/模式2-34)--通过当前像素和参考像素之间的投影关系(角度关系)来确定预测值
色度帧内预测模式号如下图所示:
------------------------本部分完------------------------
2.帧内预测具体过程
这一部分主要讨论帧内预测的过程,更具体地说是亮度的帧内预测过程,色度的帧内预测可以参考亮度来学习。
2.1 参考像素的填充
参考像素的填充是分类进行的。
(1)如果所有相邻点均不可用,则参考样点值均被赋值为DC值,即下图中2^b-1;
(2)如果所有相邻点均可用,则参考样点值都会被赋值为重建Yuv图像中与其位置相同的样点值;
(3)如果不满足上述两个条件,则按照从左下往左上,从左上往右上的扫描顺序进行遍历,(如下图所示),如果第一个点不可用,则使用下一个可用点对应的重建Yuv样点值对其进行赋值;对于除第一个点外的其它邻点,如果该点不可用,则使用它的前一个样点值进行赋值(前一个步骤保证了前一个样点值一定是存在的),直到遍历完毕。
从上面的叙述可以看出,关键就在于”可用相邻点“的个数,只需要对这个数量进行判断,那么我们就可以分类进行操作。
具体代码分析可以看另一篇博客:fillReferenceSamples
2.2 参考像素的滤波
在参考像素填充完成之后,为了减少噪声的影响,所以在预测之前进行一个滤波的操作:常规平滑滤波和强平滑滤波。
进行哪种滤波则需要进行判断:
1.常规平滑滤波:
计算公式
2.强平滑滤波
开启条件
计算公式
3.滤波示意图
滤波这一部分在HM8.0中,暂未找到对应代码,留待日后梳理后再进行分析。
具体的可以参照另一篇博客:滤波代码:空链接
2.3 预测值的计算
1.Planar模式的计算
另外给出另一本参考书的讲解,如下图所示:
具体的代码分析请看另一篇博客:Intra_Planar预测- -函数xPredIntraPlanar
2.DC模式的计算
DCValue是一个直流量,后续用来填充预测像素。
对应的dcVal计算过程可以参见另一篇博客:predIntraGetPredValDC函数
对应的公式4.19-4.21加权处理参见另一篇博客:xDCPredFiltering函数
3.角度模式的计算
在HEVC的帧内预测角度模式中
模式2~18被称为水平方向类预测模式,因为这些方向中水平或者接近水平的方向占据多数;
模式18~34被称作垂直方向类预测模式,因为这些方向中垂直或者接近垂直的方向占据多数。
下面将以垂直方向类为主要研究对象,水平方向类的预测可以通过转换为垂直方向类的预测。
垂直方向类主要有以下几个阶段:
1.获取参考像素数组
一些参数:
ref[x]:角度预测中参考数组
predModeIntra:角度预测中的模式号,从2~34
intraPredAngle:角度预测中模式的“角度”,是指偏移的格数。
具体是指:在垂直方向类中,大于模式26的,该“角度”为+,相对偏移格数即为intraPredAngle;小于模式26的,该”角度“为-,相对偏移格数即为intraPredAngle。
水平方向类与此类似,可以对比理解。
invAngle:被称作是”反角度“,主要是为了避免在构造参考数组时出现的除法操作。通过查表来进行,如下图所示:
下图为具体的参考数组构造框架图:
在书本上是这样定义基础的参考数组的,如下图所示:
公式中出现的-1是因为左上角的像素坐标被设置为(-1,-1)。
在此基础上考虑更复杂的情况,需要对参考数组进行”拓展“。
公式4.23可以理解为如果在预测方向上无参考数组,那么可以考虑将左侧的参考像素进行投影。此公式即为投影公式
下图为参考数组投影一例:
通过上述操作,我们得到了一个一维的参考数组ref[x]。
2.获取Int和Fract
参考数组已经得到,那么我们需要根据预测的角度进行投影,其过程如下图所示:
图中的P(x,y)为待预测像素,R表示相应的参考数组中的元素。可以看到,在投影的过程中,可能正好投影到数组中某一个元素中,也可能投影到数组中某两个元素中间位置。
由于考虑到存在加权内插的情况出现,因此引入了两个变量:Int和Fract(不同的参考书上说法不同,但是大同小异)
具体的计算公式如下图:
iIdx和iFact即为Int和Fract。
之前提到1/32插值精度,这里的32也是与此相关。其具体的解释可以看下图:
Int可以表示格数,Fract可以表示投影点到前面一个像素点的距离,或者是称为权重。
3.预测值的计算
从上一个过程我们得到了两个关键的数值:格数和权重。
那么就可以得到一个加权内插公式:
公式4.34中的w即为之前计算的Fract。
在公式的最后加上16则是为了保证”四舍五入“,这一点在HEVC的各个地方都有用到。
具体的代码分析请看另一篇博客:角度预测
2.4 模式值的编码
1.亮度预测块模式值编码
通过计算代价我们得到了最合适的预测模式,但是如何传递这个模式信息?
HEVC规定了一个方法:
先根据周围的预测块的模式估计出最可能模式MPM。
如果我们计算出的模式在其中,则直接传递MPM中的索引;
如果不在,则我们用5bit的定长码字来传递该模式信息。
下图为详细描述:
以下为MPM的具体设置:
MPM:Most Probable Mode 最可能模式
通过上图可以看到,这里模式值的编码就是对模式值进行一个预测编码
具体的如下图所示:
2.色度预测块模式值编码
相较于亮度预测块,色度预测块模式值编码较为简单。前面提到,色度预测块只有5种模式,我们直接对模式0~4进行编码即可。
以上部分只是帧内编码的一些重要部分,但是具体的实现流程并非如此。实现流程则需要对代码进行梳理。
具体参见博客:帧内预测总体学习
------------------------本部分完-----------------------------
3.代码的学习
第三部分主要是对上面涉及内容的代码进行一些分析,以求加深理解。
具体的版本为HM8.0,下载地址:HEVC官方网站,具体下载过程可以自己百度。
3.1 各个函数的调用关系
对于帧内模式来说,参考博主 @岳麓吹雪的文章,根据自己下载的源码进行调用关系分析。
首先来看xCompressCU之前的调用关系
从上图可以看到程序入口为main函数,然后逐层调用,这也和视频编码的层级结构基本类似。
下面是一些帧内关键函数的调用关系分析:我们可以从常见的xPredIntraPlanar函数入手,查看其调用层次关系
3.2 函数的具体分析
插入链接
函数部分不再赘述,已经附在各个小节.
如何安排函数的顺序,进行函数的注释工作?
进行角度模式、函数调用关系以及一部分代码的分析
进行角度预测部分的代码注释,理解fillReferenceSamples。