loopfilter.cpp
来自「JMVM MPEG MVC/3DAV 测试平台 国际通用标准」· C++ 代码 · 共 1,794 行 · 第 1/5 页
CPP
1,794 行
// both ref pic are used for both blocks
if( rcRefPicL1P.getFrame() != rcRefPicL0P.getFrame() )
{
// at least two diff ref pic are in use
if( rcRefPicL1P.getFrame() != rcRefPicL1Q.getFrame() )
{
ROTRS( rcRefPicL1P.getFrame() != rcRefPicL0Q.getFrame(), 1 );
ROTRS( rcRefPicL0P.getFrame() != rcRefPicL1Q.getFrame(), 1 );
// rcRefPicL0P == rcRefPicL1Q && rcRefPicL1P == rcRefPicL0Q
// check the motion vector distance
const Mv& cMvQ0 = rcMbMotionDataL0Q.getMv( cQIdx );
const Mv& cMvP0 = rcMbMotionDataL0P.getMv( cPIdx );
const Mv& cMvQ1 = rcMbMotionDataL1Q.getMv( cQIdx );
const Mv& cMvP1 = rcMbMotionDataL1P.getMv( cPIdx );
ROTRS( cMvP0.getAbsHorDiff( cMvQ1 ) >= sHorMvThr, 1 );
ROTRS( cMvP0.getAbsVerDiff( cMvQ1 ) >= sVerMvThr, 1 );
ROTRS( cMvP1.getAbsHorDiff( cMvQ0 ) >= sHorMvThr, 1 );
ROTRS( cMvP1.getAbsVerDiff( cMvQ0 ) >= sVerMvThr, 1 );
//{{SAMSUNG&KHU (JVT-W024)
#if JMVM_ONLY
if ((rcQMbData.getMbIcp().getIcAct() && rcPMbData.getMbIcp().getIcAct() &&
(rcQMbData.getMbIcp().getIcp().getOffset() != rcPMbData.getMbIcp().getIcp().getOffset())) ||
(rcQMbData.getMbIcp().getIcAct() ^ rcPMbData.getMbIcp().getIcAct()))
{
if ( abs(rcQMbData.getMbIcp().getIcp().getOffset() - rcPMbData.getMbIcp().getIcp().getOffset()) >= T)
return K2;
else
return K1;
}
#endif
//}}
return 0;
}
// rcRefPicL1P == rcRefPicL1Q
ROTRS( rcRefPicL0P.getFrame() != rcRefPicL0Q.getFrame(), 1 );
// rcRefPicL0P == rcRefPicL0Q && rcRefPicL1P == rcRefPicL1Q
// check the motion vector distance
const Mv& cMvQ0 = rcMbMotionDataL0Q.getMv( cQIdx );
const Mv& cMvP0 = rcMbMotionDataL0P.getMv( cPIdx );
const Mv& cMvQ1 = rcMbMotionDataL1Q.getMv( cQIdx );
const Mv& cMvP1 = rcMbMotionDataL1P.getMv( cPIdx );
ROTRS( cMvP0.getAbsHorDiff( cMvQ0 ) >= sHorMvThr, 1 );
ROTRS( cMvP0.getAbsVerDiff( cMvQ0 ) >= sVerMvThr, 1 );
ROTRS( cMvP1.getAbsHorDiff( cMvQ1 ) >= sHorMvThr, 1 );
ROTRS( cMvP1.getAbsVerDiff( cMvQ1 ) >= sVerMvThr, 1 );
//{{SAMSUNG&KHU (JVT-W024)
#if JMVM_ONLY
if ((rcQMbData.getMbIcp().getIcAct() && rcPMbData.getMbIcp().getIcAct() &&
(rcQMbData.getMbIcp().getIcp().getOffset() != rcPMbData.getMbIcp().getIcp().getOffset())) ||
(rcQMbData.getMbIcp().getIcAct() ^ rcPMbData.getMbIcp().getIcAct()))
{
if ( abs(rcQMbData.getMbIcp().getIcp().getOffset() - rcPMbData.getMbIcp().getIcp().getOffset()) >= T)
return K2;
else
return K1;
}
#endif
//}}
return 0;
}
// rcRefPicL1P == rcRefPicL0P
ROTRS( rcRefPicL1Q.getFrame() != rcRefPicL0Q.getFrame(), 1 ) ;
ROTRS( rcRefPicL0P.getFrame() != rcRefPicL0Q.getFrame(), 1 ) ;
// rcRefPicL0P == rcRefPicL0Q == rcRefPicL1P == rcRefPicL1Q
// check the motion vector distance
const Mv& cMvQ0 = rcMbMotionDataL0Q.getMv( cQIdx );
const Mv& cMvP0 = rcMbMotionDataL0P.getMv( cPIdx );
const Mv& cMvQ1 = rcMbMotionDataL1Q.getMv( cQIdx );
const Mv& cMvP1 = rcMbMotionDataL1P.getMv( cPIdx );
Bool bSameListCond = ( (cMvP0.getAbsHorDiff( cMvQ0 ) >= sHorMvThr) );
bSameListCond = ( bSameListCond || ( (cMvP0.getAbsVerDiff( cMvQ0 ) >= sVerMvThr) ) );
bSameListCond = ( bSameListCond || ( (cMvP1.getAbsHorDiff( cMvQ1 ) >= sHorMvThr) ) );
bSameListCond = ( bSameListCond || ( (cMvP1.getAbsVerDiff( cMvQ1 ) >= sVerMvThr) ) );
Bool bDiffListCond = ( (cMvP0.getAbsHorDiff( cMvQ1 ) >= sHorMvThr) );
bDiffListCond = ( bDiffListCond || ( (cMvP0.getAbsVerDiff( cMvQ1 ) >= sVerMvThr) ) );
bDiffListCond = ( bDiffListCond || ( (cMvP1.getAbsHorDiff( cMvQ0 ) >= sHorMvThr) ) );
bDiffListCond = ( bDiffListCond || ( (cMvP1.getAbsVerDiff( cMvQ0 ) >= sVerMvThr) ) );
ROTRS( bSameListCond && bDiffListCond, 1 );
//{{SAMSUNG&KHU (JVT-W024)
#if JMVM_ONLY
if ((rcQMbData.getMbIcp().getIcAct() && rcPMbData.getMbIcp().getIcAct() &&
(rcQMbData.getMbIcp().getIcp().getOffset() != rcPMbData.getMbIcp().getIcp().getOffset())) ||
(rcQMbData.getMbIcp().getIcAct() ^ rcPMbData.getMbIcp().getIcAct()))
{
if ( abs(rcQMbData.getMbIcp().getIcp().getOffset() - rcPMbData.getMbIcp().getIcp().getOffset()) >= T)
return K2;
else
return K1;
}
#endif
//}}
return 0;
}
UChar LoopFilter::xCheckMvDataP( const MbData& rcQMbData, const LumaIdx cQIdx,
const MbData& rcPMbData, const LumaIdx cPIdx,
const Short sHorMvThr, const Short sVerMvThr )
{
const MbMotionData& rcMbMotionDataL0Q = rcQMbData.getMbMotionData( LIST_0 );
const MbMotionData& rcMbMotionDataL0P = rcPMbData.getMbMotionData( LIST_0 );
const RefPic& rcRefPicL0Q = rcMbMotionDataL0Q.getRefPic( cQIdx );
const RefPic& rcRefPicL0P = rcMbMotionDataL0P.getRefPic( cPIdx );
// different reference pictures
ROTRS( rcRefPicL0Q.getFrame() != rcRefPicL0P.getFrame(), 1 );
// check the motion vector distance
const Mv& cMvQ = rcMbMotionDataL0Q.getMv( cQIdx );
const Mv& cMvP = rcMbMotionDataL0P.getMv( cPIdx );
ROTRS( cMvP.getAbsHorDiff( cMvQ ) >= sHorMvThr, 1 );
ROTRS( cMvP.getAbsVerDiff( cMvQ ) >= sVerMvThr, 1 );
//{{SAMSUNG&KHU (JVT-W024)
#if JMVM_ONLY
if ((rcQMbData.getMbIcp().getIcAct() && rcPMbData.getMbIcp().getIcAct() &&
(rcQMbData.getMbIcp().getIcp().getOffset() != rcPMbData.getMbIcp().getIcp().getOffset())) ||
(rcQMbData.getMbIcp().getIcAct() ^ rcPMbData.getMbIcp().getIcAct()))
{
if ( abs(rcQMbData.getMbIcp().getIcp().getOffset() - rcPMbData.getMbIcp().getIcp().getOffset()) >= T)
return K2;
else
return K1;
}
#endif
//}}
return 0;
}
__inline UInt LoopFilter::xGetVerFilterStrength( const MbDataAccess& rcMbDataAccess,
LumaIdx cIdx,
Int iFilterIdc )
{
const MbData& rcMbDataCurr = rcMbDataAccess.getMbDataCurr();
Short sHorMvThr = 4;
Short sVerMvThr = 4;
if( cIdx.x() )
{
// this is a edge inside of a macroblock
ROTRS( rcMbDataCurr.isIntra(), 3 );
if( m_pcHighpassYuvBuffer )
{
ROTRS( m_pcHighpassYuvBuffer->isCurr4x4BlkNotZero ( cIdx ), 2 );
ROTRS( m_pcHighpassYuvBuffer->isCurr4x4BlkNotZero ( cIdx + CURR_MB_LEFT_NEIGHBOUR ), 2 );
}
else
{
ROTRS( rcMbDataCurr.is4x4BlkCoded( cIdx ), 2 );
ROTRS( rcMbDataCurr.is4x4BlkCoded( cIdx + CURR_MB_LEFT_NEIGHBOUR ), 2 );
}
if( rcMbDataCurr.isInterPMb() )
{
return xCheckMvDataP( rcMbDataCurr, cIdx, rcMbDataCurr, cIdx + CURR_MB_LEFT_NEIGHBOUR, sHorMvThr, sVerMvThr );
}
return xCheckMvDataB ( rcMbDataCurr, cIdx, rcMbDataCurr, cIdx + CURR_MB_LEFT_NEIGHBOUR, sHorMvThr, sVerMvThr );
}
// if we get here we are on a macroblock edge
ROTRS( iFilterIdc == 2 && ! rcMbDataAccess.isAvailableLeft(), 0 );
ROTRS( ! rcMbDataAccess.isLeftMbExisting(), 0 );
const MbData& rcMbDataLeft = rcMbDataAccess.getMbDataLeft();
ROTRS( LFM_DEFAULT_FILTER != m_eLFMode && rcMbDataCurr.isIntra() ^ rcMbDataLeft.isIntra(), 0 );
ROTRS( rcMbDataCurr.isIntra(), 4 );
ROTRS( rcMbDataLeft.isIntra(), 4 );
if( m_pcHighpassYuvBuffer )
{
ROTRS( m_pcHighpassYuvBuffer->isCurr4x4BlkNotZero ( cIdx ), 2 );
ROTRS( m_pcHighpassYuvBuffer->isLeft4x4BlkNotZero ( cIdx + LEFT_MB_LEFT_NEIGHBOUR ), 2 );
}
else
{
ROTRS( rcMbDataCurr.is4x4BlkCoded( cIdx ), 2 );
ROTRS( rcMbDataLeft.is4x4BlkCoded( cIdx + LEFT_MB_LEFT_NEIGHBOUR ), 2 );
}
if( rcMbDataCurr.isInterPMb() && rcMbDataLeft.isInterPMb())
{
return xCheckMvDataP( rcMbDataCurr, cIdx, rcMbDataLeft, cIdx + LEFT_MB_LEFT_NEIGHBOUR, sHorMvThr, sVerMvThr );
}
return xCheckMvDataB ( rcMbDataCurr, cIdx, rcMbDataLeft, cIdx + LEFT_MB_LEFT_NEIGHBOUR, sHorMvThr, sVerMvThr );
}
__inline UInt LoopFilter::xGetHorFilterStrength( const MbDataAccess& rcMbDataAccess,
LumaIdx cIdx,
Int iFilterIdc )
{
const MbData& rcMbDataCurr = rcMbDataAccess.getMbDataCurr();
Short sHorMvThr = 4;
Short sVerMvThr = 4;
if( cIdx.y() )
{
// internal edge
ROTRS( rcMbDataCurr.isIntra(), 3 );
if( m_pcHighpassYuvBuffer )
{
ROTRS( m_pcHighpassYuvBuffer->isCurr4x4BlkNotZero ( cIdx ), 2 );
ROTRS( m_pcHighpassYuvBuffer->isCurr4x4BlkNotZero ( cIdx + CURR_MB_ABOVE_NEIGHBOUR ), 2 );
}
else
{
ROTRS( rcMbDataCurr.is4x4BlkCoded( cIdx ), 2 );
ROTRS( rcMbDataCurr.is4x4BlkCoded( cIdx + CURR_MB_ABOVE_NEIGHBOUR ), 2 );
}
if( rcMbDataCurr.isInterPMb() )
{
return xCheckMvDataP( rcMbDataCurr, cIdx, rcMbDataCurr, cIdx + CURR_MB_ABOVE_NEIGHBOUR, sHorMvThr, sVerMvThr );
}
return xCheckMvDataB ( rcMbDataCurr, cIdx, rcMbDataCurr, cIdx + CURR_MB_ABOVE_NEIGHBOUR, sHorMvThr, sVerMvThr );
}
// if we get here we are on a macroblock edge
ROTRS( iFilterIdc == 2 && ! rcMbDataAccess.isAvailableAbove(), 0 );
ROTRS( ! rcMbDataAccess.isAboveMbExisting(), 0 );
const MbData& rcMbDataAbove = rcMbDataAccess.getMbDataAbove();
ROTRS( LFM_DEFAULT_FILTER != m_eLFMode && rcMbDataCurr.isIntra() ^ rcMbDataAbove.isIntra(), 0 );
ROTRS( rcMbDataCurr. isIntra(), 4 );
ROTRS( rcMbDataAbove.isIntra(), 4 );
if( m_pcHighpassYuvBuffer )
{
ROTRS( m_pcHighpassYuvBuffer->isCurr4x4BlkNotZero ( cIdx ), 2 );
ROTRS( m_pcHighpassYuvBuffer->isAbove4x4BlkNotZero ( cIdx + ABOVE_MB_ABOVE_NEIGHBOUR ), 2 );
}
else
{
ROTRS( rcMbDataCurr. is4x4BlkCoded( cIdx ), 2 );
ROTRS( rcMbDataAbove.is4x4BlkCoded( cIdx + ABOVE_MB_ABOVE_NEIGHBOUR ), 2 );
}
if( rcMbDataCurr.isInterPMb() && rcMbDataAbove.isInterPMb())
{
return xCheckMvDataP( rcMbDataCurr, cIdx, rcMbDataAbove, cIdx + ABOVE_MB_ABOVE_NEIGHBOUR, sHorMvThr, sVerMvThr );
}
return xCheckMvDataB ( rcMbDataCurr, cIdx, rcMbDataAbove, cIdx + ABOVE_MB_ABOVE_NEIGHBOUR, sHorMvThr, sVerMvThr );
}
ErrVal LoopFilter::process( SliceHeader& rcSH,
IntFrame* pcFrame,
MbDataCtrl* pcMbDataCtrlMot, // if NULL -> all intra
MbDataCtrl* pcMbDataCtrlRes,
UInt uiMbInRow,
RefFrameList* pcRefFrameList0,
RefFrameList* pcRefFrameList1,
bool bAllSliceDone,
bool spatial_scalable_flg) // SSUN@SHARP
{
ROT( NULL == m_pcControlMngIf );
RNOK( m_pcControlMngIf->initSliceForFiltering ( rcSH ) );
RNOK( pcMbDataCtrlRes ->initSlice ( rcSH, POST_PROCESS, false, NULL ) );
if( pcMbDataCtrlMot )
{
RNOK( pcMbDataCtrlMot ->initSlice ( rcSH, POST_PROCESS, false, NULL ) );
}
//-> ICU/ETRI DS FMO Process
UInt uiFirstMbInSlice;
UInt uiLastMbInSlice;
FMO* pcFMO = rcSH.getFMO();
for(Int iSliceGroupID=0;!pcFMO->SliceGroupCompletelyCoded(iSliceGroupID);iSliceGroupID++)
{
if (false == pcFMO->isCodedSG(iSliceGroupID) && false == bAllSliceDone)
{
continue;
}
uiFirstMbInSlice = pcFMO->getFirstMacroblockInSlice(iSliceGroupID);
uiLastMbInSlice = pcFMO->getLastMBInSliceGroup(iSliceGroupID);
for(UInt uiMbAddress= uiFirstMbInSlice ;uiMbAddress<=uiLastMbInSlice ;)
//===== loop over macroblocks use raster scan =====
{
UInt uiMbY = uiMbAddress / uiMbInRow;
UInt uiMbX = uiMbAddress % uiMbInRow;
MbDataAccess* pcMbDataAccessMot = 0;
MbDataAccess* pcMbDataAccessRes = 0;
if( pcMbDataCtrlMot )
{
RNOK( pcMbDataCtrlMot ->initMb ( pcMbDataAccessMot, uiMbY, uiMbX ) );
}
RNOK( pcMbDataCtrlRes ->initMb ( pcMbDataAccessRes, uiMbY, uiMbX ) );
RNOK( m_pcControlMngIf->initMbForFiltering( uiMbAddress ) );
// Hanke@RWTH
if( m_pcHighpassFrame ) {
m_pcHighpassYuvBuffer = m_pcHighpassFrame->getFullPelYuvBuffer();
}else{
m_pcHighpassYuvBuffer = NULL;
}
if( 0 == (m_eLFMode & LFM_NO_FILTER))
{
RNOK( xFilterMb( pcMbDataAccessMot,
pcMbDataAccessRes,
pcFrame->getFullPelYuvBuffer(),
pcRefFrameList0,
pcRefFrameList1,
spatial_scalable_flg ) ); // SSUN@SHARP
//*/
}
if( m_eLFMode & LFM_EXTEND_INTRA_SUR )
{
UInt uiMask = 0;
RNOK( pcMbDataCtrlRes->getBoundaryMask( uiMbY, uiMbX, uiMask ) );
if( uiMask )
{
IntYuvMbBufferExtension cBuffer;
cBuffer.setAllSamplesToZero();
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?