H.266/VVC专栏传送
上一篇:H.266/VVC-VTM代码学习-帧内预测03-DC模式下计算预测像素值xPredIntraDc、xGetPredValDc
下一篇:H.266/VVC-VTM代码学习-帧内预测05-Angular模式下计算预测像素值xPredIntraAng
前言
VTM是H.266/VVC视频编码标准的参考软件,研究VTM代码给研究人员解释了VVC编码标准的详细标准规范与细节。
本文是笔者对VTM代码的一点学习记录,成文于笔者刚开始接触VVC期间,期间很多概念和理论框架还很不成熟,若文中存在错误欢迎批评指正,也欢迎广大视频编码学习者沟通交流、共同进步。
VTM代码的下载及编译请参考博文:
【视频编码学习】H.266/VVC参考软件VTM配置运行(VTM-6.0版本)
本文涉及的代码存在于工程下的/lib/CommonLib/SourceFiles/IntraPrediction.cpp文件中。
一、主要函数
1.函数代码
void IntraPrediction::xPredIntraPlanar( const CPelBuf &pSrc, PelBuf &pDst )
{
const uint32_t width = pDst.width;
const uint32_t height = pDst.height;
const uint32_t log2W = floorLog2( width );
const uint32_t log2H = floorLog2( height );
int leftColumn[MAX_CU_SIZE + 1], topRow[MAX_CU_SIZE + 1], bottomRow[MAX_CU_SIZE], rightColumn[MAX_CU_SIZE];
const uint32_t offset = 1 << (log2W + log2H);
// Get left and above reference column and row获取参考像素
CHECK(width > MAX_CU_SIZE, "width greater than limit");
for( int k = 0; k < width + 1; k++ )
{
//获得正上方参考像素值
topRow[k] = pSrc.at( k + 1, 0 );
}
CHECK(height > MAX_CU_SIZE, "height greater than limit");
for( int k = 0; k < height + 1; k++ )
{
//获得正左侧参考像素值
leftColumn[k] = pSrc.at(k + 1, 1);
}
// Prepare intermediate variables used in interpolation准备用于插值的中间变量
//TU左下角参考像素
int bottomLeft = leftColumn[height];
//TU右上角参考像素
int topRight = topRow[width];
//遍历整行
for( int k = 0; k < width; k++ )
{
bottomRow[k] = bottomLeft - topRow[k];//bottomRow = 左下角像素点 - 对应topRow的值
topRow[k] = topRow[k] << log2H;//topRow = topRow * height
}
//遍历整列
for( int k = 0; k < height; k++ )
{
rightColumn[k] = topRight - leftColumn[k];//rightColumn = 右上角像素点 - 对应leftColumn的值
leftColumn[k] = leftColumn[k] << log2W;//leftColumn = leftColumn * width
}
const uint32_t finalShift = 1 + log2W + log2H;
const uint32_t stride = pDst.stride;
Pel* pred = pDst.buf;
//遍历所有行,通过内层循环求各行的水平预测值
for( int y = 0; y < height; y++, pred += stride )
{
//用于存储水平预测值
//leftColumn = leftColumn * width
int horPred = leftColumn[y];
//内层循环遍历当前行,计算对应预测值
for( int x = 0; x < width; x++ )
{
//因为,rightColumn = topRight - leftColumn,leftColumn = leftColumn * width
//所以,水平预测值为(leftColumn * width) + (topRight - leftColumn[k]) * (x + 1)
//x表示当前像素所在列,随着遍历当前行,topRight的权重会对应增加
horPred += rightColumn[y];
//因为,topRow = topRow * height,bottomRow = bottomLeft - topRow
//所以,垂直预测值为(topRow * height) * (y + 1) + (bottomLeft - topRow)
//x表示当前像素所在列,每次遍历到不同行相同列位置,垂直预测值中的bottomLeft权重就会对应增加
topRow[x] += bottomRow[x];
//用于存储垂直预测值
int vertPred = topRow[x];
//最终预测值pred = ((horpred * H) + (vertPred * W)) / (2 * W * H)
pred[x] = ( ( horPred << log2H ) + ( vertPred << log2W ) + offset ) >> finalShift;
}
}
}
2.逻辑结构
1.获取参考像素:分别使用循环获取当前块正上方参考像素和正左侧参考像素值。
2.设置bottomRow和rightColumn分别存储bottomLeft与对应topRow的差值、topRight与对应leftColumn的差值。
3.外层循环遍历所有行。
4.内存循环遍历当前行的所有列,并计算出水平预测值和垂直预测值,再通过将二者求平均直接得到当前像素点的预测值。
上一篇:H.266/VVC-VTM代码学习-帧内预测03-DC模式下计算预测像素值xPredIntraDc、xGetPredValDc
下一篇:H.266/VVC-VTM代码学习-帧内预测05-Angular模式下计算预测像素值xPredIntraAng