Void TComLoopFilter::xSetEdgefilterPU( TComDataCU* pcCU, UInt uiAbsZorderIdx ){ const UInt uiDepth = pcCU->getDepth( uiAbsZorderIdx ); const UInt uiWidthInBaseUnits = pcCU->getPic()->getNumPartInWidth () >> uiDepth; const UInt uiHeightInBaseUnits = pcCU->getPic()->getNumPartInHeight() >> uiDepth; const UInt uiHWidthInBaseUnits = uiWidthInBaseUnits >> 1; //!< half const UInt uiHHeightInBaseUnits = uiHeightInBaseUnits >> 1; //!< half const UInt uiQWidthInBaseUnits = uiWidthInBaseUnits >> 2; //!< quater const UInt uiQHeightInBaseUnits = uiHeightInBaseUnits >> 2; //!< quater //! Void xSetEdgefilterMultiple( TComDataCU* pcCU, UInt uiAbsZorderIdx, UInt uiDepth, Int iDir, Int iEdgeIdx, Bool bValue , //! UInt uiWidthInBaseUnits = 0, UInt uiHeightInBaseUnits = 0 ); xSetEdgefilterMultiple( pcCU, uiAbsZorderIdx, uiDepth, EDGE_VER, 0, m_stLFCUParam.bLeftEdge ); //!< 设置垂直边界 xSetEdgefilterMultiple( pcCU, uiAbsZorderIdx, uiDepth, EDGE_HOR, 0, m_stLFCUParam.bTopEdge ); //!< 设置水平边界 switch ( pcCU->getPartitionSize( uiAbsZorderIdx ) ) //!< PU的划分模式 {//!< 以下根据PU的划分模式对滤波边界进行相应的设置 case SIZE_2Nx2N: { break; } case SIZE_2NxN: { xSetEdgefilterMultiple( pcCU, uiAbsZorderIdx, uiDepth, EDGE_HOR, uiHHeightInBaseUnits, m_stLFCUParam.bInternalEdge ); break; } case SIZE_Nx2N: { xSetEdgefilterMultiple( pcCU, uiAbsZorderIdx, uiDepth, EDGE_VER, uiHWidthInBaseUnits, m_stLFCUParam.bInternalEdge ); break; } case SIZE_NxN: { xSetEdgefilterMultiple( pcCU, uiAbsZorderIdx, uiDepth, EDGE_VER, uiHWidthInBaseUnits, m_stLFCUParam.bInternalEdge ); xSetEdgefilterMultiple( pcCU, uiAbsZorderIdx, uiDepth, EDGE_HOR, uiHHeightInBaseUnits, m_stLFCUParam.bInternalEdge ); break; } case SIZE_2NxnU: { xSetEdgefilterMultiple( pcCU, uiAbsZorderIdx, uiDepth, EDGE_HOR, uiQHeightInBaseUnits, m_stLFCUParam.bInternalEdge ); break; } case SIZE_2NxnD: { xSetEdgefilterMultiple( pcCU, uiAbsZorderIdx, uiDepth, EDGE_HOR, uiHeightInBaseUnits - uiQHeightInBaseUnits, m_stLFCUParam.bInternalEdge ); break; } case SIZE_nLx2N: { xSetEdgefilterMultiple( pcCU, uiAbsZorderIdx, uiDepth, EDGE_VER, uiQWidthInBaseUnits, m_stLFCUParam.bInternalEdge ); break; } case SIZE_nRx2N: { xSetEdgefilterMultiple( pcCU, uiAbsZorderIdx, uiDepth, EDGE_VER, uiWidthInBaseUnits - uiQWidthInBaseUnits, m_stLFCUParam.bInternalEdge ); break; } default: { break; } }}
Void TComLoopFilter::xSetEdgefilterMultiple( TComDataCU* pcCU, UInt uiScanIdx, UInt uiDepth, Int iDir, Int iEdgeIdx, Bool bValue,UInt uiWidthInBaseUnits, UInt uiHeightInBaseUnits ){ if ( uiWidthInBaseUnits == 0 ) //!< 0是默认参数,即实参没有传进该值,此时需要在这里自己计算 { uiWidthInBaseUnits = pcCU->getPic()->getNumPartInWidth () >> uiDepth; } if ( uiHeightInBaseUnits == 0 ) //!< 0是默认参数,即实参没有传进该值,此时需要在这里自己计算 { uiHeightInBaseUnits = pcCU->getPic()->getNumPartInHeight() >> uiDepth; } const UInt uiNumElem = iDir == 0 ? uiHeightInBaseUnits : uiWidthInBaseUnits; assert( uiNumElem > 0 ); assert( uiWidthInBaseUnits > 0 ); assert( uiHeightInBaseUnits > 0 ); for( UInt ui = 0; ui < uiNumElem; ui++ ) { const UInt uiBsIdx = xCalcBsIdx( pcCU, uiScanIdx, iDir, iEdgeIdx, ui ); //!< 计算第ui个partition的ZScan地址 m_aapbEdgeFilter[iDir][0][uiBsIdx] = bValue; //!< Y m_aapbEdgeFilter[iDir][1][uiBsIdx] = bValue; //!< U m_aapbEdgeFilter[iDir][2][uiBsIdx] = bValue; //!< V if (iEdgeIdx == 0) { m_aapucBS[iDir][uiBsIdx] = bValue; } }}
UInt xCalcBsIdx ( TComDataCU* pcCU, UInt uiAbsZorderIdx, Int iDir, Int iEdgeIdx, Int iBaseUnitIdx ) { TComPic* const pcPic = pcCU->getPic(); const UInt uiLCUWidthInBaseUnits = pcPic->getNumPartInWidth(); if( iDir == 0 ) //!< 垂直边界 { return g_auiRasterToZscan[g_auiZscanToRaster[uiAbsZorderIdx] + iBaseUnitIdx * uiLCUWidthInBaseUnits + iEdgeIdx ]; } else //!< 水平边界 { return g_auiRasterToZscan[g_auiZscanToRaster[uiAbsZorderIdx] + iEdgeIdx * uiLCUWidthInBaseUnits + iBaseUnitIdx ]; } }
Void TComLoopFilter::xSetEdgefilterTU( TComDataCU* pcCU, UInt absTUPartIdx, UInt uiAbsZorderIdx, UInt uiDepth ){ if( pcCU->getTransformIdx( uiAbsZorderIdx ) + pcCU->getDepth( uiAbsZorderIdx) > uiDepth ) //!< TU的最大尺寸等于PU的尺寸,实际可能小于PU的尺寸 { const UInt uiCurNumParts = pcCU->getPic()->getNumPartInCU() >> (uiDepth<<1); const UInt uiQNumParts = uiCurNumParts>>2; for ( UInt uiPartIdx = 0; uiPartIdx < 4; uiPartIdx++, uiAbsZorderIdx+=uiQNumParts ) { UInt nsAddr = uiAbsZorderIdx; xSetEdgefilterTU( pcCU,nsAddr, uiAbsZorderIdx, uiDepth + 1 ); } return; } //!< TU的宽和高 Int trWidth = pcCU->getWidth( uiAbsZorderIdx ) >> pcCU->getTransformIdx( uiAbsZorderIdx ); Int trHeight = pcCU->getHeight( uiAbsZorderIdx ) >> pcCU->getTransformIdx( uiAbsZorderIdx ); UInt uiWidthInBaseUnits = trWidth / (g_uiMaxCUWidth >> g_uiMaxCUDepth); UInt uiHeightInBaseUnits = trHeight / (g_uiMaxCUWidth >> g_uiMaxCUDepth); xSetEdgefilterMultiple( pcCU, absTUPartIdx, uiDepth, EDGE_VER, 0, m_stLFCUParam.bInternalEdge, uiWidthInBaseUnits, uiHeightInBaseUnits ); xSetEdgefilterMultiple( pcCU, absTUPartIdx, uiDepth, EDGE_HOR, 0, m_stLFCUParam.bInternalEdge, uiWidthInBaseUnits, uiHeightInBaseUnits );}