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 );
}