去方块滤波的详细过程可参看draft 8.7.1 to 8.7.2 。
在compressGOP中可以找到下面一段代码,这里就是调用去方块滤波的地方
//-- Loop filter
Bool bLFCrossTileBoundary = pcSlice->getPPS()->getLoopFilterAcrossTilesEnabledFlag();
m_pcLoopFilter->setCfg(bLFCrossTileBoundary); //!< 设置滤波时是否跨越tiles边界
m_pcLoopFilter->loopFilterPic( pcPic ); //!< 执行去方块滤波
看loopFilterPic的具体实现:
/**
- call deblocking function for every CU
.
\param pcPic picture class (TComPic) pointer
*/
Void TComLoopFilter::loopFilterPic( TComPic* pcPic )
{
// Horizontal filtering
for ( UInt uiCUAddr = 0; uiCUAddr < pcPic->getNumCUsInFrame(); uiCUAddr++ ) //!< 遍历所有CU
{
TComDataCU* pcCU = pcPic->getCU( uiCUAddr );
::memset( m_aapucBS [EDGE_VER], 0, sizeof( UChar ) * m_uiNumPartitions ); //!< 初始化boundary strength
for( Int iPlane = 0; iPlane < 3; iPlane++ ) //!< Y, U, V
{
::memset( m_aapbEdgeFilter[EDGE_VER][iPlane], 0, sizeof( Bool ) * m_uiNumPartitions );
}
// CU-based deblocking
xDeblockCU( pcCU, 0, 0, EDGE_VER ); //!< 垂直边界滤波
}
// Vertical filtering
for ( UInt uiCUAddr = 0; uiCUAddr < pcPic->getNumCUsInFrame(); uiCUAddr++ ) //!< 遍历所有CU
{
TComDataCU* pcCU = pcPic->getCU( uiCUAddr );
::memset( m_aapucBS [EDGE_HOR], 0, sizeof( UChar ) * m_uiNumPartitions ); //!< 初始化boundary strength
for( Int iPlane = 0; iPlane < 3; iPlane++ ) //!< Y, U, V
{
::memset( m_aapbEdgeFilter[EDGE_HOR][iPlane], 0, sizeof( Bool ) * m_uiNumPartitions );
}
// CU-based deblocking
xDeblockCU( pcCU, 0, 0, EDGE_HOR ); //!< 水平边界滤波
}
}
由上可以知道xDeblockCU将是实际进行去方块滤波的核心函数。接下来将重点围绕该函数进行详细研究。
(注:HEVC标准的Deblocking filter与H.264/AVC标准的基本上属于继承关系,当然了,还是有不同的地方的,比如滤波以8x8为单元,而H.264中是以4x4为单元,再比如,HEVC只定义了0到2的三个滤波强度,而H.264定义了5个滤波强度,等等。此外,HEVC对于Deblocking filter的处理过程为先进行垂直边界滤波,再进行水平边界滤波,这样有利于并行的实现。)