HEVC学习(三十六) —— 去方块滤波之七

来源:互联网 发布:mysql 临时表空间不足 编辑:程序博客网 时间:2024/06/06 02:39

本文介绍关于去方块滤波的最后一个函数(这一系列基本上只讨论了亮度分量的情况,色度分量的情况类似,不单独做出分析)。

Void TComLoopFilter::xEdgeFilterLuma( TComDataCU* pcCU, UInt uiAbsZorderIdx, UInt uiDepth, Int iDir, Int iEdge  ){  TComPicYuv* pcPicYuvRec = pcCU->getPic()->getPicYuvRec(); //!< 重建图像(滤波前)  Pel* piSrc    = pcPicYuvRec->getLumaAddr( pcCU->getAddr(), uiAbsZorderIdx ); //!< 指向当前PU对应的重建像素的首地址  Pel* piTmpSrc = piSrc;    Int  iStride = pcPicYuvRec->getStride(); //!< 图像的跨度  Int iQP = 0;  Int iQP_P = 0;  Int iQP_Q = 0;  UInt uiNumParts = pcCU->getPic()->getNumPartInWidth()>>uiDepth; //!< 当前PU的以partition为单位的宽度    UInt  uiPelsInPart = g_uiMaxCUWidth >> g_uiMaxCUDepth;  UInt  uiBsAbsIdx = 0, uiBs = 0;  Int   iOffset, iSrcStep;    Bool  bPCMFilter = (pcCU->getSlice()->getSPS()->getUsePCM() && pcCU->getSlice()->getSPS()->getPCMFilterDisableFlag())? true : false;  Bool  bPartPNoFilter = false;  Bool  bPartQNoFilter = false;   UInt  uiPartPIdx = 0;  UInt  uiPartQIdx = 0;  TComDataCU* pcCUP = pcCU;   TComDataCU* pcCUQ = pcCU;  Int  betaOffsetDiv2 = pcCUQ->getSlice()->getDeblockingFilterBetaOffsetDiv2();  Int  tcOffsetDiv2 = pcCUQ->getSlice()->getDeblockingFilterTcOffsetDiv2();  //! iEdge为边界上的PU以partition为单元的序号  if (iDir == EDGE_VER)  {    iOffset = 1;    iSrcStep = iStride;    piTmpSrc += iEdge*uiPelsInPart; //!< 每个8x8滤波单元是不重叠的  }  else  // (iDir == EDGE_HOR)  {    iOffset = iStride;    iSrcStep = 1;    piTmpSrc += iEdge*uiPelsInPart*iStride;  }    for ( UInt iIdx = 0; iIdx < uiNumParts; iIdx++ ) //!< 遍历PU中的每个partition  {    uiBsAbsIdx = xCalcBsIdx( pcCU, uiAbsZorderIdx, iDir, iEdge, iIdx); //!< partition对应的ZScan地址    uiBs = m_aapucBS[iDir][uiBsAbsIdx];    if ( uiBs ) //!< uiBs == 1 or uiBs == 2    {      iQP_Q = pcCU->getQP( uiBsAbsIdx );      uiPartQIdx = uiBsAbsIdx;      // Derive neighboring PU index      if (iDir == EDGE_VER)      {        pcCUP = pcCUQ->getPULeft (uiPartPIdx, uiPartQIdx,!pcCU->getSlice()->getLFCrossSliceBoundaryFlag(), false, !m_bLFCrossTileBoundary);      }      else  // (iDir == EDGE_HOR)      {#if LINEBUF_CLEANUP        pcCUP = pcCUQ->getPUAbove(uiPartPIdx, uiPartQIdx,!pcCU->getSlice()->getLFCrossSliceBoundaryFlag(), false, false, !m_bLFCrossTileBoundary);#else        pcCUP = pcCUQ->getPUAbove(uiPartPIdx, uiPartQIdx,!pcCU->getSlice()->getLFCrossSliceBoundaryFlag(), false, false, false, !m_bLFCrossTileBoundary);#endif      }      iQP_P = pcCUP->getQP(uiPartPIdx);      iQP = (iQP_P + iQP_Q + 1) >> 1;//!< draft (8-264)      Int iBitdepthScale = 1 << (g_bitDepthY-8);            Int iIndexTC = Clip3(0, MAX_QP+DEFAULT_INTRA_TC_OFFSET, Int(iQP + DEFAULT_INTRA_TC_OFFSET*(uiBs-1) + (tcOffsetDiv2 << 1))); //!< draft (8-267)      Int iIndexB = Clip3(0, MAX_QP, iQP + (betaOffsetDiv2 << 1)); //!< draft (8-265)            Int iTc =  tctable_8x8[iIndexTC]*iBitdepthScale; //!< draft (8-268)      Int iBeta = betatable_8x8[iIndexB]*iBitdepthScale; //!< draft (8-266)      Int iSideThreshold = (iBeta+(iBeta>>1))>>3; //!< 阈值      Int iThrCut = iTc*10;      UInt  uiBlocksInPart = uiPelsInPart / 4 ? uiPelsInPart / 4 : 1; //!< 4 / 1 = 1      for (UInt iBlkIdx = 0; iBlkIdx<uiBlocksInPart; iBlkIdx ++)      {        Int dp0 = xCalcDP( piTmpSrc+iSrcStep*(iIdx*uiPelsInPart+iBlkIdx*4+0), iOffset); //!< draft漏标号了        Int dq0 = xCalcDQ( piTmpSrc+iSrcStep*(iIdx*uiPelsInPart+iBlkIdx*4+0), iOffset); //!< draft (8-269)        Int dp3 = xCalcDP( piTmpSrc+iSrcStep*(iIdx*uiPelsInPart+iBlkIdx*4+3), iOffset); //!< draft (8-270)        Int dq3 = xCalcDQ( piTmpSrc+iSrcStep*(iIdx*uiPelsInPart+iBlkIdx*4+3), iOffset); //!< draft (8-271)        Int d0 = dp0 + dq0; //!< draft (8-272)        Int d3 = dp3 + dq3; //!< draft (8-273)                Int dp = dp0 + dp3; //!< draft (8-274)        Int dq = dq0 + dq3; //!< draft (8-275)        Int d =  d0 + d3; //!< draft (8-276)                if (bPCMFilter || pcCU->getSlice()->getPPS()->getTransquantBypassEnableFlag())        {          // Check if each of PUs is I_PCM with LF disabling          bPartPNoFilter = (bPCMFilter && pcCUP->getIPCMFlag(uiPartPIdx));          bPartQNoFilter = (bPCMFilter && pcCUQ->getIPCMFlag(uiPartQIdx));          // check if each of PUs is lossless coded          bPartPNoFilter = bPartPNoFilter || (pcCUP->isLosslessCoded(uiPartPIdx) );          bPartQNoFilter = bPartQNoFilter || (pcCUQ->isLosslessCoded(uiPartQIdx) );        }        if (d < iBeta)        {           Bool bFilterP = (dp < iSideThreshold); //!< dEp          Bool bFilterQ = (dq < iSideThreshold); //!< dEq          //! xUseStrongFiltering对应于draft 8.7.2.4.6          Bool sw =  xUseStrongFiltering( iOffset, 2*d0, iBeta, iTc, piTmpSrc+iSrcStep*(iIdx*uiPelsInPart+iBlkIdx*4+0))          && xUseStrongFiltering( iOffset, 2*d3, iBeta, iTc, piTmpSrc+iSrcStep*(iIdx*uiPelsInPart+iBlkIdx*4+3)); //!< dE          //! sw即strong weak,该函数用于判断最终滤波的强弱          for ( Int i = 0; i < DEBLOCK_SMALLEST_BLOCK/2; i++)          {//! 最终进行真正的滤波            xPelFilterLuma( piTmpSrc+iSrcStep*(iIdx*uiPelsInPart+iBlkIdx*4+i), iOffset, d, iBeta, iTc, sw, bPartPNoFilter, bPartQNoFilter, iThrCut, bFilterP, bFilterQ);          }        }      }    }  }}


 

原创粉丝点击