HEVC学习(三十四) —— 去方块滤波之五

来源:互联网 发布:c语言指令大全 编辑:程序博客网 时间:2024/06/05 05:16

本文考察实现去方块滤波的核心函数xDeblockCU:

Void TComLoopFilter::xDeblockCU( TComDataCU* pcCU, UInt uiAbsZorderIdx, UInt uiDepth, Int Edge ){  if(pcCU->getPic()==0||pcCU->getPartitionSize(uiAbsZorderIdx)==SIZE_NONE)  {    return;  }  TComPic* pcPic     = pcCU->getPic();  UInt uiCurNumParts = pcPic->getNumPartInCU() >> (uiDepth<<1); //!< 当前CU中的4x4 partition 数目  UInt uiQNumParts   = uiCurNumParts>>2; //!< 将当前CU再次划分成4个CU后每个CU中的4x4 partition 数目    if( pcCU->getDepth(uiAbsZorderIdx) > uiDepth ) //!< 当前CU还没达到经RDO确定下来的最佳划分的深度  {    for ( UInt uiPartIdx = 0; uiPartIdx < 4; uiPartIdx++, uiAbsZorderIdx+=uiQNumParts ) //!< 对每个子CU进行遍历    {      UInt uiLPelX   = pcCU->getCUPelX() + g_auiRasterToPelX[ g_auiZscanToRaster[uiAbsZorderIdx] ];      UInt uiTPelY   = pcCU->getCUPelY() + g_auiRasterToPelY[ g_auiZscanToRaster[uiAbsZorderIdx] ];      if( ( uiLPelX < pcCU->getSlice()->getSPS()->getPicWidthInLumaSamples() ) && ( uiTPelY < pcCU->getSlice()->getSPS()->getPicHeightInLumaSamples() ) )      {        xDeblockCU( pcCU, uiAbsZorderIdx, uiDepth+1, Edge ); //!< 递归调用xDeblockCU,进入下一深度的滤波      }    }    return;  }    xSetLoopfilterParam( pcCU, uiAbsZorderIdx ); //!< 对滤波参数结构体m_stLFCUParam进行设置    xSetEdgefilterTU   ( pcCU, uiAbsZorderIdx , uiAbsZorderIdx, uiDepth ); //!< 设置TU滤波边界参数  xSetEdgefilterPU   ( pcCU, uiAbsZorderIdx ); //!< 设置PU滤波边界参数    Int iDir = Edge;  for( UInt uiPartIdx = uiAbsZorderIdx; uiPartIdx < uiAbsZorderIdx + uiCurNumParts; uiPartIdx++ )  {    UInt uiBSCheck;    if( (g_uiMaxCUWidth >> g_uiMaxCUDepth) == 4 ) //!< 一般情况下该条件成立,即最小CU为4x4    {//! 对于垂直边界滤波的情况,检测partition是否属于左边界;对于水平边界滤波的情况,检测partition是否属于上边界      uiBSCheck = (iDir == EDGE_VER && uiPartIdx%2 == 0) || (iDir == EDGE_HOR && (uiPartIdx-((uiPartIdx>>2)<<2))/2 == 0);    }    else    {      uiBSCheck = 1;    }        if ( m_aapbEdgeFilter[iDir][0][uiPartIdx] && uiBSCheck ) //!< m_aapbEdgeFilter的值在xSetEdgefilterMultiple中设置过    {      xGetBoundaryStrengthSingle ( pcCU, uiAbsZorderIdx, iDir, uiPartIdx ); //!< 设置滤波强度    }  }    UInt uiPelsInPart = g_uiMaxCUWidth >> g_uiMaxCUDepth; //!< partition的尺寸,即4  UInt PartIdxIncr = DEBLOCK_SMALLEST_BLOCK / uiPelsInPart ? DEBLOCK_SMALLEST_BLOCK / uiPelsInPart : 1 ;    UInt uiSizeInPU = pcPic->getNumPartInWidth()>>(uiDepth);    for ( UInt iEdge = 0; iEdge < uiSizeInPU ; iEdge+=PartIdxIncr) //!< 遍历边界上的所有PU  {    xEdgeFilterLuma     ( pcCU, uiAbsZorderIdx, uiDepth, iDir, iEdge ); //!< 对亮度分量进行滤波    if ( (uiPelsInPart>DEBLOCK_SMALLEST_BLOCK) || (iEdge % ( (DEBLOCK_SMALLEST_BLOCK<<1)/uiPelsInPart ) ) == 0 )    {      xEdgeFilterChroma   ( pcCU, uiAbsZorderIdx, uiDepth, iDir, iEdge ); //!< 对色度分量进行滤波    }  }}