HM编码器代码阅读(7)——整个编码流程以及相关的函数

来自网上的文档,但是最初来源不知道是哪,谢谢这个作者!

整个流程可以从compressGOP函数开始着手:
1、compressGOP对一整个图像组(GOP)进行编码,主要是遍历GOP中每一帧,对每一帧进行单独编码
2、每一帧又会被划分成若干slice(HM15中,每一帧对应一个slice),因此对每一帧的处理就转换成对每一片的处理。
3、每一个slice都会调用compressSlice来对其进行预测、变换、量化等操作,然后选出最优的参数,最后调用encodeSlice对其进行熵编码!
4、slice的划分。编码slice的时候并不是对整个slice进行处理,而是会继续把slice划分成LCU(最大的CU),然后对每一个CU递归调用compressCU和encodeCU进行编码。其中encodeCU会被compressSlice和encodeSlice调用,在compressSlice中调用encodeCU的目的是为了选择最优的参数,而在encodeSlice中调用encodeCU的目的是对CU进行熵编码。
5、LCU的大小是64x64,一个slice可以划分为若干LCU,而每一个CU(或者LCU)又可以递归地被划分成4个子CU。如何判断某一个CU是否会继续向下划分,可以根据RD(拉格朗日率失真)来判断!
6、compressCU的实质就是对每一个CU递归的调用xCompressCU。在xCompressCU的内部,会根据帧的类型(I帧、P帧、B帧)进行不同的处理。对于I帧,进行的是帧内预测;对于P帧和B帧则进行帧间预测。
7、帧内预测的详解(入口函数:xCheckRDCostIntra):
7.1、对于亮度分量:
7.1.1、调用estIntraPredQT。主要做模式选择的工作,负责选出对于当前PU的最优模式,如DC、planar、角度等模式。
(1)首先对N个候选模式进行粗粒度筛选。代价函数是SATD+λ*ModeBits。选出若干个可能的候选模式。下面是相关的函数。
(2)predIntraLumaAng。计算当前PU的预测值。
(3)calcHAD。计算SATD代价。
(4)xModeBitsIntra。计算当前模式所消耗的比特数。
(5)xUpdateCandList。更新模式的代价,保持前N个模式的代价最小。
(6)选出N个模式之后,这N个模式会进入xRecurIntraCodingQT函数继续处理。
7.1.2、调用xRecurIntraCodingQT。根据选出的模式进行PU的分割,然后进行变换量化等工作。
(1)这个函数会被调用两次,第一次调用直接把PU当作TU,只为算出N个模式的RD代价,从而选出一个最优的,在这个最优的模式被选出后,再次调用这个函数,对这个最优的模式进行PU的分割。下面的是相关的函数。
(2)xIntraCodingLumaBlk。对当前TU进行求残差,对残差进行变换、量化、反量化、反变换、重建等一系列工作,并求出失真。
(3)xGetIntraBitsQT。求出当前模式的所有信息进行熵编码会产生的比特数。
(4)calcRdCos。根据 xIntraCodingLumaBlk得到的失真和 xGetIntraBitsQT产生的比特数进行RD代价的计算,从而比较各个模式的优劣。
(5)xSetIntraResultQT。保存最优模式的数据。
7.2、对于色度分量,过程和亮度大部分一样。
8、帧间预测的详解:
8.1、帧间分为两种方式,一种是默认的inter模式(入口函数xCheckRDCostInter),另一种是merge模式(入口函数xCheckRDCostMerge2Nx2N)。
8.2、inter模式的调用流程:xCheckRDCostInter——>predInterSearch——>encodeResAndCalcRdInterCU
8.3、merge模式的调用流程:xCheckRDCostMerge2Nx2N——>motionCompensation——>encodeResAndCalcRdInterCU
8.4、predInterSearch进行的是ME(运动估计)和MC(运动补偿)的过程。
8.5、motionCompensation进行的是MC的工作。因为merge进行的是MV预测,因此没有ME(运动估计)的过程。
8.6、encodeResAndCalcRdInterCU。根据预测值,求出残差,然后进行TU的划分,然后进行变换、量化等操作以及RD代价的计算。流程图如下:
HM编码器代码阅读(7)——整个编码流程以及相关的函数_第1张图片
8.6.1、encodeSkipFlag。对skip模式的标志进行编码。
8.6.2、encodeMergeIndex。对MVP的索引进行编码。
8.6.3、xEstimateResidualQT。在非skip模式的时候,进行RQT的决定(即应该把PU分割成什么样的TU)。
8.6.4、xAddSymbolBitsInter。计算当前模式在进行熵编码时产生的比特数。
8.6.5、xSetResidualQTData。保存当前最优的残差信息。
9、其他函数相关函数:
9.1、帧内
initPattern :判断周围块的存在性
initAdiPattern:获取周围像素的值当做生成预测值的像素,并开辟出一片缓存  区存储经过多种滤波类型的预测值
getPredictorPtr: 根据不同模式选择经过不同类型滤波的预测集
predIntraLumaAng: 对亮度信号进行预测,里面会调用 xPredIntraPlanar,xPredIntraAng 以及 xDCPredFiltering
predIntraChromaAng : 对色度信号进行预测,里面会调用 xPredIntraPlanar 和xPredIntraAng
xPredIntraPlanar: planar 模式的预测
xPredIntraAng: 角度的方向性预测
xDCPredFiltering: 对 DC 的预测值进行滤波 
getLumaRecPixels: 获取亮度的重建值,为进行 LM 模式的预测做准备
predLMIntraChroma:对 LM 模式进行预测,即利用亮度的相关性,对色度进行预测 
9.2、帧间
getInterMergeCandidates: 获取 merge 的候选运动参数集
motionCompensation:进行运动补偿
xMotionEstimation:进行运动估计
xEstimateMvPredAMVP:选出代价最小的 MVP
xCheckBestMVP:在知道 MV 的情况下比较各个 MVP 的优劣,并保存最优的
xMergeEstimation:在 inter 模式时也可以使用 merge 模式的运动估计方法,这个函数用于计算这种情况时的代价 
9.3、变换
transformNxN:会调用 xT 和 xQuant 函数
invtransformNxN:会调用 xDeQuant 和 xIT 函数
xT: 对残差信号进行变换
xQuant:对变换系数进行量化
xDeQuant :反量化
xIT:反变换
9.4、熵编码(在这节中主要介绍编码端为算 RD 代价而设计的熵编码函数,实际的熵编码函数在后面进行介绍)
9.4.1、帧内熵编码
xEncIntraHeader: 编码 intra 的一些头部信息, 主要包括: 模式号, PU 的分割类型,PCM 标志,如果是 B 或 P slice,还包括 skip 的标志位和编码模式的类型
xEncSubdivCbfQT:会编码 Cbf 和 TU 分割的标志位
xEncCoeffQT:编码每个 TU 的系数
encodeCoeffNxN:调用 codeCoeffNxN 来编码每个 TU 的残差系数
encodeTransformSubdivFlag: 调用codeTransformSubdivFlag来编码TU分割的标志,是否继续分割
encodeQtCbf:编码 cbf 标志位,检查是否有非零的系数
encodePredMode:编码所采用的编码模式
encodePartSize:编码 PU 的分割类型
encodeIntraDirModeLuma:编码 PU 的亮度模式号
encodeIntraDirModeChroma:编码 PU 的色度模式号 
9.4.2、帧间熵编码
encodePredMode:编码所采用的编码模式
encodePredMode:编码所采用的编码模式
encodePartSize:编码 PU 的分割类型
encodePredInfo: 编码运动参数 
(1) merge 的标志位来区别是否采用 merge 模式,具体函数:encodeMergeFlag然后分(2)和(3)两种情况。
(2) merge 模式:只需传输运动候选集的索引,具体函数:encodeMergeIndex
(3) 正常的 inter 模式
A. encodeInterDirPU:编码帧间的预测方向,前向,后向,或多方向
B. encodeRefFrmIdxPU: 编码参考帧索引
C. encodeMvdPU:编码 MV 的残差 MVD
D. encodeMVPIdxPU: 编码 MVP 的索引 
10、熵编码(encodeCU)。encodeCU以LCU为单位进行熵编码。它的内部实际是针对每一个CU递归调用xEncodeCU。流程如下:
HM编码器代码阅读(7)——整个编码流程以及相关的函数_第2张图片
10.1、encodeSkipFlag 编码是否是 skip 模式 
10.2、encodeMergeIndex 如果是 skip 模式会编码选用哪套 MVP 的参数
10.3、encodePredMode 编码 CU 的模式,是 intra 还是 inter
10.4、encodePartSize 编码 CU 中的 PU 的类型
10.5、encodeIPCMInfo 如果选用了 PCM 模式会编码 PCM 模式的信息
10.6、encodePredInfo 编码预测的信息,如果是帧内,编码模式号,如果是帧间,则编码运动信息
10.7、encodeCoeff 编码残差系数
10.8、encodeCoeff 中会编码 TU 的分割标志位,cbf 和残差系数的信息 

你可能感兴趣的:(HEVC编码器HM源码阅读)