今天来看下环路滤波部分的代码。
环路滤波
为了便于理解,先来看HEVC编码框架。首先就要来说下混合编码框架,以下引自百度百科:
变换编码和预测编码是两类不同的压缩编码方法,如果将这两种方法组合在一起,就构成新的一类所谓混合编码,通常使用DCT等变换进行空间冗余度的压缩,用帧间预测或运动补偿预测进行时间冗余度的压缩,以达到对活动图像的更高的压缩效率。(百度百科)
HEVC框架如下,沿用了混合编码框架,整体可以分为几个模块:预测、变换量化、环路滤波、熵编码。可以看到预测、变换量化形成了一个环路,在反变换量化后进行了一步滤波处理这就是环路滤波。
这里所说的环路滤波器包含了去块效应滤波器和像素自适应补偿SAO滤波器,是环内滤波,属于环路后处理。还存在环外滤波,实际可以看做对输出视频再次进行滤波,不属于标准内容,具体技术一般由显示设备厂家自行选择。
在编码端环路滤波后的图像会被作为参考图像用于帧间预测,而在解码端就是最终要输出的图像了。
个人对于这部分内容并不熟悉,目前只需要了解整体代码框架,提取所需的去块前后和SAO前后图像,因此只对整体框架进行学习,具体理论后续补充。
DecLib::executeLoopFilters
DecApp::decode
是一个很表层的函数了,其中调用的DecLib::decode
是解码一帧图像的入口函数,解码后会调用DecLib::executeLoopFilters
对解码得到的重构图像进行环路滤波。从这就可以清晰的理解所谓的环路后处理的含义了。这里立个flag吧,之后有时间好好整理下BMS/VTM解码器端的主要函数调用关系。
DecLib::executeLoopFilter
只是一个上层入口函数,其中会调用LoopFilter::loopFilterPic
和SampleAdaptiveOffset::SAOProcess
进行具体的去块滤波和SAO。这里相比HM增加了ALF,不具体说了。
代码分析如下:
//环路滤波
Void DecLib::executeLoopFilters()
{
if( !m_pcPic )
{
return; // nothing to deblock
}
CodingStructure& cs = *m_pcPic->cs; //取cs
// deblocking filter
m_cLoopFilter.loopFilterPic( cs ); //去块滤波
if( cs.sps->getUseSAO() )
{
m_cSAO.SAOProcess( cs, cs.picture->getSAO() ); //SAO
}
#if JEM_TOOLS
if( cs.sps->getSpsNext().getALFEnabled() ) //JEM o Adaptive loop filter(ALF)
{
ALFParam* alfParams = &cs.picture->getALFParam();
const UInt tidxMAX = E0104_ALF_MAX_TEMPLAYERID - 1u;
const UInt tidx = cs.slice->getTLayer();
CHECK( tidx >