ECM8.0——CCCM相关代码
- 概览
- predIntraCCCM
- xCccmCalcModels
- xCccmApplyModel
- xCccmCreateLumaRef
- xCccmGetLumaRefBuf
- xCccmGetLumaPuBuf
- xCccmCalcRefAver
- xCccmCalcRefArea
概览
函数名称 | 函数作用 |
---|---|
predIntraCCCM | 总体代码,根据CCCM技术预测输出 |
xCccmCalcModels | 计算CCCM滤波器系数 |
xCccmApplyModel | 应用滤波器执行CCCM过程 |
xCccmCreateLumaRef | 生成当前块的亮度参考样点 |
xCccmGetLumaRefBuf | 这段代码是用于获取一个降采样的luma buffer(Ref区域) |
xCccmGetLumaPuBuf | 这段代码是用于获取一个降采样的luma buffer (PU区域) |
xCccmCalcRefAver | 计算参考像素中的平均值 |
xCccmCalcRefArea | 计算给定色度块的参考区域 |
predIntraCCCM
函数接受以下参数:predictionunit &pu,pelbuf &predcb,pelbuf &predcr和int intradir。该函数包括以下步骤:
- 如果intradir为lm_chroma_idx、mdlm_l_idx或mdlm_t_idx,则执行单一模式下的xcccmcalcmodels和xcccmapplymodel函数。
- 否则,执行多模式下的xcccmcalcrefaver和xcccmcalcmodels和xcccmapplymodel函数。
xCccmCalcModels
这段代码是视频编码中的帧内预测模块部分,主要用于处理色度信息的矫正。具体来说,它的作用是计算出基于当前像素点和其周围像素点的一组线性变换系数,以矫正参考图像与当前图像之间的色度差异。
这段代码就是用来生产卷积滤波器,如下面这张图这样。
这段代码是一个实现色彩协方差矩阵(cccm)的函数。该函数计算输入图像样本的自相关矩阵和交叉相关向量,并使用ldl分解方法求解滤波器系数。如果定义了jvet_ab0174_cccm_div_free,则将从统计数据中删除色度偏移以更新交叉相关性。最后,将参数调整为所选动态范围并将其存储在给定的cccmmodel结构体中。如下面这张图所示:
xCccmApplyModel
使用xCccmCalcModels计算得到的滤波器参数来进行估计。
这段代码是实现图像帧内预测中cccm模型的应用。cccm模型是一种基于样本相似性的预测方法,其通过对当前像素周围的相邻像素进行采样并应用预设的模型来预测当前像素的值。
函数接受一个predictionunit类型的参数pu,表示待预测的图像块。compid表示颜色分量id,cccmmodel表示cccm模型,modelid和modelthr用于控制采样的样本范围,pipred为输出参数,表示预测结果。
在函数内部,首先获取当前颜色分量的clprng(裁剪范围),然后获取参考图像块的亮度信息reflumablk,并利用循环遍历各个像素。
在遍历过程中,根据modelid和modelthr的设定,选择是否跳过某些像素。然后针对当前像素,将其周围的6个邻近像素及其自身的像素值作为输入,应用cccm模型计算出预测值,并将预测值限制在裁剪范围内,存储在pipred指向的输出缓冲区中。
xCccmCreateLumaRef
这段代码是一种视频编码方式中的图像帧内预测方法,用于生成当前块的亮度参考样点,以便后续进行亮度残差计算。具体实现步骤如下:
-
通过传入的PredictionUnit和CompArea信息计算出当前块需要参考的区域范围。
-
通过调用xCccmGetLumaRefBuf函数获取参考亮度缓冲区域,并计算出该区域的宽高、参考块的大小和位置等信息。根据参考块的大小和当前块的边界信息,对参考亮度缓冲区域进行初始化操作。
-
对当前块需要参考的区域范围内的每个采样点进行逐一遍历,根据像素位置计算出其在参考帧中的位置,并从参考帧中获取相应的亮度值,写入到参考亮度缓冲区域中。
-
对标记有Padding的位置进行填充,以保证后续处理的正确性。
这段代码的作用是在参考亮度缓冲区域的右侧填充一列数据,以保证该区域宽度与当前块的宽度相同。
refLuma是一个二维数组,at函数的参数x和y分别表示所要求取元素的列索引和行索引。该函数根据列索引和行索引计算元素在原始一维数组中的索引位置,并返回该位置上的元素。
在这里,该函数通过循环遍历顶部参考区域中的所有行,在每一行的最右侧(列的索引为areaWidth)填充一个样本。填充样本的值等于参考区域中该行最右侧一个样本的值(refLuma.at(areaWidth - 1, y))。这样就完成了对参考区域右侧的填充,使得该区域宽度等于当前块的宽度,从而方便后续的处理。
这段代码的作用是在当前块的右侧填充一列数据,以规避当该块的宽度小于参考区域宽度时,这一列数据缺失的问题。
refLuma是一个二维数组,at函数的参数x和y分别表示所要求取元素的列索引和行索引。该函数根据列索引和行索引计算元素在原始一维数组中的索引位置,并返回该位置上的元素。
在这里,该函数通过循环遍历从参考区域底部到当前块上边界之间的所有行(即从refSizeY到puBorderY-1),在当前块的最右侧(PU边界的x坐标,即puBorderX)填充一个样本。填充样本的值等于当前块最右侧一列的左侧相邻一个像素的值(refLuma.at(puBorderX - 1, y))。同时,当该块的宽度等于参考区域宽度时,这一步其实是不需要的。该步的目的是为了使得当前块的宽度与参考区域的宽度相同,从而方便后续的处理。
- 在Dualtree编码模式下,利用相邻块的亮度值填充当前块的亮度参考样点,扩大块间预测的可利用范围。
这段代码是用于双树滤波的,它将 luma(亮度)值从当前PU右边和下面的区域采样,并用于双树滤波中。如果当前PU处于图像的CTU(Coding Tree Unit)/图像边界上,则不能采样右侧和下侧的luma值。在代码中,通过一系列的if语句和for循环,获取了采样所需的位置信息,并调用xCccmGetLumaVal函数,获取对应位置的luma值,并填充到refLuma中。
xCccmGetLumaRefBuf
这段代码是用于获取一个降采样的luma buffer,该buffer包含了PU和PU上方和左侧的参考区域。在获取这个luma buffer之前,函数会先通过一些参数计算出参考区域的位置和大小。如果pu.cccmNoSubFlag为true(即不进行亚采样),则使用chromaScaleX和chromaScaleY计算参考区域的位置和大小。在计算出参考区域信息后,函数将返回一个降采样后的luma buffer,该buffer是参考区域包括填充的2D滤波器所需的大小,并将指针指向参考区域左上角。
xCccmGetLumaPuBuf
这段代码是用于获取一个降采样的luma buffer,该buffer包含了PU的像素值以及PU上方和左侧的参考区域的像素值。在获取这个luma buffer之前,函数会根据pu的不同参数计算出参考区域的位置和大小,并计算出PU和参考区域的大小。然后,函数将返回一个降采样后的luma buffer,该buffer是PU及其上方和左侧参考区域所需的大小,并将指针指向PU的左上角。
xCccmGetLumaRefBuf 和 xCccmGetLumaPuBuf 区别:
- 这两个函数都是在帧内预测中使用的,目的是获得参考像素值。它们之间的区别在于xCccmGetLumaRefBuf返回的是参考区域的像素值,而xCccmGetLumaPuBuf返回的是当前处理的预测单元块的像素值。
- 具体来说,xCccmGetLumaRefBuf用于获取参考像素的区域,这个区域通常是在当前处理的块周围的一个更大的块中。该函数返回一个PelBuf,其中包含对应于该参考区域的实际像素值,可以被用作预测时的输入。
- 另一方面,xCccmGetLumaPuBuf用于获取预测单元块本身的像素值。该函数返回一个PelBuf,其中包含了当前处理的预测单元块的实际像素值。这些像素值可以被用作块内/块外预测模式的输入。
- 总之,xCccmGetLumaRefBuf返回的是参考区域的像素值,xCccmGetLumaPuBuf返回的是当前处理的预测单元块的像素值,二者功能和用途略有不同。
xCccmCalcRefAver
这段代码是用于计算参考像素中的平均值,以便在帧内预测过程中进行使用。具体来说,它计算了参考像素中所有可用样本 (Top和Left) 的加权平均值。
首先,xCccmGetLumaRefBuf函数被调用,返回包含参考像素实际值的PelBuf。然后,对于该PelBuf中的每个样本,都将其添加到sumSamples中,同时将numSamples加1。最后,将所有样本的加权平均值计算为sumSamples/numSamples,并以整数形式返回该值。
注意,如果没有可用的样本,则返回默认值512。
xCccmCalcRefArea
这段代码是用于计算给定色度块的参考区域。具体来说,它确定了参考区域的大小和位置,以便在帧内预测过程中使用。
首先,函数获取了关于当前色度块的一些信息,如色度类型、块的大小、最小CU大小等。然后,它计算出一些值,如可用单元格的数量和参考线的数量,这些值将被用于确定参考区域的大小。最后,使用这些计算出的值,函数计算并返回了参考块的位置和大小。
需要注意的是,参考块的大小和位置取决于可用的相邻块。如果可用的相邻块不足,则参考块会相应地缩小。