帧内预测-第一步:fillReferenceSamples函数:
来源:互联网 发布:win7内存优化软件 编辑:程序博客网 时间:2024/06/06 07:42
帧内预测:fillReferenceSamples函数:
主要功能:
是在真正进行帧内预测之前,使用重建后的Yuv图像对当前PU的相邻样点进行赋值,为接下来进行的角度预测提供参考样点值。
过程:
(1)如果所有相邻点均不可用,则参考样点值均被赋值为DC值;
(2)如果所有相邻点均可用,则参考样点值都会被赋值为重建Yuv图像中与其位置相同的样点值;
(3)如果不满足上述两个条件,则按照从左下往左上,从左上往右上的扫描顺序进行遍历,(如下图所示),如果第一个点不可用,则使用下一个可用点对应的重建Yuv样点值对其进行赋值;对于除第一个点外的其它邻点,如果该点不可用,则使用它的前一个样点值进行赋值(前一个步骤保证了前一个样点值一定是存在的),直到遍历完毕
Void TComPattern::fillReferenceSamples( TComDataCU* pcCU, Pel* piRoiOrigin, Int* piAdiTemp, Bool* bNeighborFlags, Int iNumIntraNeighbor, Int iUnitSize, Int iNumUnitsInCu, Int iTotalUnits, UInt uiCuWidth, UInt uiCuHeight, UInt uiWidth, UInt uiHeight, Int iPicStride, Bool bLMmode )
{Pel* piRoiTemp; //!< piRoiOrgin指向重建Yuv图像对应于当前PU所在位置的首地址,piRoiTemp用于指向所感兴趣的重建Yuv的位置,piAdiTemp
Int i, j;
Int iDCValue = ( 1<<( g_uiBitDepth + g_uiBitIncrement - 1) );
if (iNumIntraNeighbor == 0) // all samples are not available
{
// Fill border with DC value
for (i=0; i<uiWidth; i++) //!< AboveLeft + Above + AboveRight
{
piAdiTemp[i] = iDCValue;
}
for (i=1; i<uiHeight; i++) //!< Left + BelowLeft
{
piAdiTemp[i*uiWidth] = iDCValue;
}
}
else if (iNumIntraNeighbor == iTotalUnits) // all samples are available
{
// Fill top-left border with rec. samples
piRoiTemp = piRoiOrigin - iPicStride - 1; //!< 左上
piAdiTemp[0] = piRoiTemp[0];
// Fill left border with rec. samples
piRoiTemp = piRoiOrigin - 1; //!< 左
if (bLMmode) //!< bLMmode 默认值为false
{
piRoiTemp --; // move to the second left column
}
for (i=0; i<uiCuHeight; i++)
{
piAdiTemp[(1+i)*uiWidth] = piRoiTemp[0]; //!< 每个参考样点赋值为对应位置重建Yuv样点值
piRoiTemp += iPicStride; //!< 指向重建Yuv下一行
}
// Fill below left border with rec. samples
for (i=0; i<uiCuHeight; i++) //!< 左下
{
piAdiTemp[(1+uiCuHeight+i)*uiWidth] = piRoiTemp[0]; //!< 每个参考样点赋值为对应位置重建Yuv样点值
piRoiTemp += iPicStride;
}
// Fill top border with rec. samples
piRoiTemp = piRoiOrigin - iPicStride; //!< 重新指向重建Yuv的上方
for (i=0; i<uiCuWidth; i++)
{
piAdiTemp[1+i] = piRoiTemp[i]; //!< 每个参考样点赋值为对应位置重建Yuv样点值
}
// Fill top right border with rec. samples
piRoiTemp = piRoiOrigin - iPicStride + uiCuWidth; //!< 指向右上
for (i=0; i<uiCuWidth; i++)
{
piAdiTemp[1+uiCuWidth+i] = piRoiTemp[i]; //!< 每个参考样点赋值为对应位置重建Yuv样点值
}
}
else // reference samples are partially available
{
Int iNumUnits2 = iNumUnitsInCu<<1;
Int iTotalSamples = iTotalUnits*iUnitSize; //!< neighboring samples的总数,iTotalUnits以4x4块为单位,iUnitSize为块的大小
Pel piAdiLine[5 * MAX_CU_SIZE];
Pel *piAdiLineTemp; //!<临时存储用于填充neighboring samples的样点值
Bool *pbNeighborFlags;
Int iNext, iCurr;
Pel piRef = 0; //!< 存储临时样点值
// Initialize
for (i=0; i<iTotalSamples; i++) //!< 先将所有样点值赋值为DC值
{
piAdiLine[i] = iDCValue;
}
// Fill top-left sample
piRoiTemp = piRoiOrigin - iPicStride - 1; //!< 指向重建Yuv左上角
piAdiLineTemp = piAdiLine + (iNumUnits2*iUnitSize); //!< piAdiLine的扫描顺序为左下到左上,再从左到右上
pbNeighborFlags = bNeighborFlags + iNumUnits2; //!< 标记neighbor可用性的数组同样移动至左上角
if (*pbNeighborFlags) //!< 如果左上角可用,则左上角4个像素点均赋值为重建Yuv左上角的样点值
{
piAdiLineTemp[0] = piRoiTemp[0];
for (i=1; i<iUnitSize; i++)
{
piAdiLineTemp[i] = piAdiLineTemp[0];
}
}
// Fill left & below-left samples
piRoiTemp += iPicStride; //!< piRoiTemp指向重建Yuv的左边界
if (bLMmode)
{
piRoiTemp --; // move the second left column
}
piAdiLineTemp--; //!< 移动指针置左边界
pbNeighborFlags--; //!< 移动指针置左边界
for (j=0; j<iNumUnits2; j++) //!< 从左往左下扫描
{
if (*pbNeighborFlags) //!< 如果可用
{
for (i=0; i<iUnitSize; i++) //!< 每个4x4块里的4个样点分别被赋值为对应位置的重建Yuv的样点值
{
piAdiLineTemp[-i] = piRoiTemp[i*iPicStride];
}
}
piRoiTemp += iUnitSize*iPicStride; //!< 指针挪到下一个行(以4x4块为单位,即实际上下移了4行)
piAdiLineTemp -= iUnitSize; //!< 指针下移
pbNeighborFlags--; //!< 指针下移
}
// Fill above & above-right samples
piRoiTemp = piRoiOrigin - iPicStride; //!< piRoiTemp 指向重建Yuv的上边界
piAdiLineTemp = piAdiLine + ((iNumUnits2+1)*iUnitSize); //!< 指向上边界
pbNeighborFlags = bNeighborFlags + iNumUnits2 + 1; //!< 指向上边界
for (j=0; j<iNumUnits2; j++) //!< 从左扫描至右上
{
if (*pbNeighborFlags)
{
for (i=0; i<iUnitSize; i++)
{
piAdiLineTemp[i] = piRoiTemp[i]; //!< 每个4x4块里的4个样点分别被赋值为对应位置的重建Yuv的样点值
}
}
piRoiTemp += iUnitSize; //!< 指针右移
piAdiLineTemp += iUnitSize; //!< 指针右移
pbNeighborFlags++; //!< 指针右移
}
// Pad reference samples when necessary
iCurr = 0;
iNext = 1;
piAdiLineTemp = piAdiLine; //!< 指向左下角(纵坐标最大的那个位置,即扫描起点)
while (iCurr < iTotalUnits) //!< 遍历所有neighboring samples
{
if (!bNeighborFlags[iCurr]) //!< 该点不可用
{
if(iCurr == 0) //!< 第一个点就不可用
{
while (iNext < iTotalUnits && !bNeighborFlags[iNext]) //!< 找到第1个可用点
{
iNext++;
}
piRef = piAdiLine[iNext*iUnitSize]; //!< 保存该可用点的样点值
// Pad unavailable samples with new value
while (iCurr < iNext) //!< 使用保存下来的第一个可用点的样点值赋值给在其之前被标记为不可用的点
{
for (i=0; i<iUnitSize; i++)
{
piAdiLineTemp[i] = piRef;
}
piAdiLineTemp += iUnitSize;
iCurr++;
}
}
else //!< 当前点不可用且其不是第一个点,则使用该点的前一个可用点的样点值进行赋值
{
piRef = piAdiLine[iCurr*iUnitSize-1];
for (i=0; i<iUnitSize; i++)
{
piAdiLineTemp[i] = piRef;
}
piAdiLineTemp += iUnitSize;
iCurr++;
}
}
else //!< 当前点可用,继续检查下一点
{
piAdiLineTemp += iUnitSize;
iCurr++;
}
}
// Copy processed samples
piAdiLineTemp = piAdiLine + uiHeight + iUnitSize - 2; //!< piAdiLineTemp = (piAdiLine + 128) + 3,跳过之前对左上角扩充的3个像素点
for (i=0; i<uiWidth; i++) //!< 将最终结果拷贝到左上、上、右上边界
{
piAdiTemp[i] = piAdiLineTemp[i];
}
piAdiLineTemp = piAdiLine + uiHeight - 1; //!< uiHeight = uiCUHeight2 + 1
for (i=1; i<uiHeight; i++) //!< 将最终结果拷贝到左和左下边界
{
piAdiTemp[i*uiWidth] = piAdiLineTemp[-i]; //!< piAdiLineTemp下标为-i是因为赋值方向与实际存储方向是相反的
}
}
}
阅读全文
0 0
- 帧内预测-第一步:fillReferenceSamples函数:
- 帧内预测之 fillReferenceSamples函数记录
- (HEVC)帧内预测:fillReferenceSamples函数讲解
- 帧内预测——fillReferenceSamples
- 帧内预测-函数initAdiPattern
- 帧内预测:xPredIntraPlanar函数
- HEVC-帧内预测2: initAdiPattern 函数
- HEVC帧内DC预测函数predIntraGetPredValDC()
- HEVC帧内DC预测函数predIntraGetPredValDC()
- 帧内预测模式预测
- 帧内预测:predIntraLumaAng函数+getPreditorPtr函数+xDCPredFiltering函数
- 帧内预测编码
- 帧内预测
- 帧内预测
- HEVC帧内预测
- hevc帧内预测
- x264帧内预测
- JM8.6 色度帧内预测函数剖析(IntraChromaPrediction8x8)
- VFIO
- Android组件Activity的生命周期
- iOS账号管理,将个人账号转为公司账号
- Linux常用命令大全
- JavaScript——typeof VS instanceof
- 帧内预测-第一步:fillReferenceSamples函数:
- Date日期对象
- 图形验证码生成servlet
- 使用OpenCV对一系列图像生成视频avi
- 第000讲-第006讲 从1000个代码案例中学习人工智能和大数据实战
- getmemory面试题
- log4j详解
- Django知识点快速复习-Django简介和MVT
- webstorm 中如何修改默认注释