📄 loopfilter.cpp
字号:
//===== filtering of upper macroblock edge =====
if( ! m_bHorMixedMode )
{
//----- any other combination than curr = FRM, above = FLD -----
Int iAboveQp = rcMbDataAccess.getMbData().getFieldFlag() && ( !rcMbDataAccess.isTopMb()||rcMbDataAccess.getMbDataAboveAbove().getFieldFlag() ) ?
rcMbDataAccess.getMbDataAboveAbove().getQpLF() : rcMbDataAccess.getMbDataAbove().getQpLF();
Int iQp = ( iAboveQp + iCurrQp + 1 ) >> 1;
Int iIndexA = gClipMinMax( rcDFP.getSliceAlphaC0Offset() + iQp, 0, 51);
Int iIndexB = gClipMinMax( rcDFP.getSliceBetaOffset() + iQp, 0, 51);
for( Int xBlk = 0; xBlk < 4; xBlk++)
{
const UChar ucBs = m_aaaucBs[HOR][xBlk][0];
if( 0 != ucBs )
{
xFilter( pPelLum, iStride, iIndexA, iIndexB, ucBs, true );
xFilter( pPelLum+1, iStride, iIndexA, iIndexB, ucBs, true );
xFilter( pPelLum+2, iStride, iIndexA, iIndexB, ucBs, true );
xFilter( pPelLum+3, iStride, iIndexA, iIndexB, ucBs, true );
}
pPelLum += 4;
}
pPelLum -= 16;
}
else
{
//----- curr = FRM, above = FLD -----
AOT_DBG( ! rcMbDataAccess.isTopMb() );
AOT_DBG( ! rcMbDataAccess.isAboveMbExisting() );
//===== top field filtering =====
{
XPel* pPelTop = pcYuvBuffer->getMbLumAddr();
Int iTopStride = pcYuvBuffer->getLStride()*2;
Int iAboveQp = rcMbDataAccess.getMbDataAboveAbove().getQpLF();
Int iQp = ( iAboveQp + iCurrQp + 1) >> 1;
Int iIndexA = gClipMinMax( rcDFP.getSliceAlphaC0Offset() + iQp, 0, 51);
Int iIndexB = gClipMinMax( rcDFP.getSliceBetaOffset() + iQp, 0, 51);
for( Int xBlk = 0; xBlk < 4; xBlk++)
{
const UChar ucBs = m_aucBsHorTop[xBlk];
if( 0 != ucBs )
{
xFilter( pPelTop, iTopStride, iIndexA, iIndexB, ucBs, true );
xFilter( pPelTop+1, iTopStride, iIndexA, iIndexB, ucBs, true );
xFilter( pPelTop+2, iTopStride, iIndexA, iIndexB, ucBs, true );
xFilter( pPelTop+3, iTopStride, iIndexA, iIndexB, ucBs, true );
}
pPelTop += 4;
}
}
//===== bottom field filtering =====
{
XPel* pPelBot = pcYuvBuffer->getMbLumAddr()+pcYuvBuffer->getLStride();
Int iBotStride = pcYuvBuffer->getLStride()*2;
Int iAboveQp = rcMbDataAccess.getMbDataAbove().getQpLF();
Int iQp = ( iAboveQp + iCurrQp + 1) >> 1;
Int iIndexA = gClipMinMax( rcDFP.getSliceAlphaC0Offset() + iQp, 0, 51);
Int iIndexB = gClipMinMax( rcDFP.getSliceBetaOffset() + iQp, 0, 51);
for( Int xBlk = 0; xBlk < 4; xBlk++)
{
const UChar ucBs = m_aaaucBs[HOR][xBlk][0];
if( 0 != ucBs )
{
xFilter( pPelBot, iBotStride, iIndexA, iIndexB, ucBs, true );
xFilter( pPelBot+1, iBotStride, iIndexA, iIndexB, ucBs, true );
xFilter( pPelBot+2, iBotStride, iIndexA, iIndexB, ucBs, true );
xFilter( pPelBot+3, iBotStride, iIndexA, iIndexB, ucBs, true );
}
pPelBot += 4;
}
}
}
pPelLum += 4*iStride;
Int iIndexA = gClipMinMax( rcDFP.getSliceAlphaC0Offset() + iCurrQp, 0, 51);
Int iIndexB = gClipMinMax( rcDFP.getSliceBetaOffset() + iCurrQp, 0, 51);
for( Int yBlk = 1; yBlk < 4; yBlk++)
{
for( Int xBlk = 0; xBlk < 4; xBlk++)
{
const UChar ucBs = m_aaaucBs[HOR][xBlk][yBlk];
if( 0 != ucBs )
{
xFilter( pPelLum, iStride, iIndexA, iIndexB, ucBs, true );
xFilter( pPelLum+1, iStride, iIndexA, iIndexB, ucBs, true );
xFilter( pPelLum+2, iStride, iIndexA, iIndexB, ucBs, true );
xFilter( pPelLum+3, iStride, iIndexA, iIndexB, ucBs, true );
}
pPelLum += 4;
}
pPelLum += 4*iStride - 16;
}
return Err::m_nOK;
}
ErrVal
LoopFilter::xChromaHorFiltering( const MbDataAccess& rcMbDataAccess, const DBFilterParameter& rcDFP, YuvPicBuffer* pcYuvBuffer )
{
Int iCurrQp = rcMbDataAccess.getSH().getChromaQp( rcMbDataAccess.getMbData().getQpLF() );
Int iStride = pcYuvBuffer->getCStride();
XPel* pPelCb = pcYuvBuffer->getMbCbAddr();
XPel* pPelCr = pcYuvBuffer->getMbCrAddr();
//===== filtering of upper macroblock edge =====
if( ! m_bHorMixedMode )
{
//----- any other combination than curr = FRM, above = FLD -----
Int iAboveQp = rcMbDataAccess.getMbData().getFieldFlag() && (!rcMbDataAccess.isTopMb()||rcMbDataAccess.getMbDataAboveAbove().getFieldFlag()) ?
rcMbDataAccess.getSH().getChromaQp( rcMbDataAccess.getMbDataAboveAbove().getQpLF()) : rcMbDataAccess.getSH().getChromaQp( rcMbDataAccess.getMbDataAbove().getQpLF());
Int iQp = ( iAboveQp + iCurrQp + 1) >> 1;
Int iIndexA = gClipMinMax( rcDFP.getSliceAlphaC0Offset() + iQp, 0, 51);
Int iIndexB = gClipMinMax( rcDFP.getSliceBetaOffset() + iQp, 0, 51);
for( Int xBlk = 0; xBlk < 4; xBlk++)
{
const UChar ucBs = m_aaaucBs[HOR][xBlk][0];
if( 0 != ucBs )
{
xFilter( pPelCb, iStride, iIndexA, iIndexB, ucBs, false );
xFilter( pPelCb+1, iStride, iIndexA, iIndexB, ucBs, false );
xFilter( pPelCr, iStride, iIndexA, iIndexB, ucBs, false );
xFilter( pPelCr+1, iStride, iIndexA, iIndexB, ucBs, false );
}
pPelCb += 2;
pPelCr += 2;
}
pPelCb -= 8;
pPelCr -= 8;
}
else
{
//----- curr = FRM, above = FLD -----
AOT_DBG( ! rcMbDataAccess.isTopMb() );
//===== top field filtering =====
{
XPel* pPelFieldCb = pcYuvBuffer->getMbCbAddr();
XPel* pPelFieldCr = pcYuvBuffer->getMbCrAddr();
Int iFieldStride = pcYuvBuffer->getCStride() * 2;
Int iAboveQp = rcMbDataAccess.getSH().getChromaQp( rcMbDataAccess.getMbDataAboveAbove().getQpLF() );
Int iQp = ( iAboveQp + iCurrQp + 1) >> 1;
Int iIndexA = gClipMinMax( rcDFP.getSliceAlphaC0Offset() + iQp, 0, 51);
Int iIndexB = gClipMinMax( rcDFP.getSliceBetaOffset() + iQp, 0, 51);
for( Int xBlk = 0; xBlk < 4; xBlk++)
{
const UChar ucBs = m_aucBsHorTop[xBlk];
if( 0 != ucBs )
{
xFilter( pPelFieldCb, iFieldStride, iIndexA, iIndexB, ucBs, false );
xFilter( pPelFieldCb+1, iFieldStride, iIndexA, iIndexB, ucBs, false );
xFilter( pPelFieldCr, iFieldStride, iIndexA, iIndexB, ucBs, false );
xFilter( pPelFieldCr+1, iFieldStride, iIndexA, iIndexB, ucBs, false );
}
pPelFieldCb += 2;
pPelFieldCr += 2;
}
}
//===== bottom field filtering =====
{
XPel* pPelFieldCb = pcYuvBuffer->getMbCbAddr()+pcYuvBuffer->getCStride();
XPel* pPelFieldCr = pcYuvBuffer->getMbCrAddr()+pcYuvBuffer->getCStride();
Int iFieldStride = pcYuvBuffer->getCStride() * 2;
Int iAboveQp = rcMbDataAccess.getSH().getChromaQp( rcMbDataAccess.getMbDataAbove().getQpLF() );
Int iQp = ( iAboveQp + iCurrQp + 1) >> 1;
Int iIndexA = gClipMinMax( rcDFP.getSliceAlphaC0Offset() + iQp, 0, 51);
Int iIndexB = gClipMinMax( rcDFP.getSliceBetaOffset() + iQp, 0, 51);
for( Int xBlk = 0; xBlk < 4; xBlk++)
{
const UChar ucBs = m_aaaucBs[HOR][xBlk][0];
if( 0 != ucBs )
{
xFilter( pPelFieldCb, iFieldStride, iIndexA, iIndexB, ucBs, false );
xFilter( pPelFieldCb+1, iFieldStride, iIndexA, iIndexB, ucBs, false );
xFilter( pPelFieldCr, iFieldStride, iIndexA, iIndexB, ucBs, false );
xFilter( pPelFieldCr+1, iFieldStride, iIndexA, iIndexB, ucBs, false );
}
pPelFieldCb += 2;
pPelFieldCr += 2;
}
}
}
pPelCb += 4*iStride;
pPelCr += 4*iStride;
// now we filter the remaining edge
Int iIndexA = gClipMinMax( rcDFP.getSliceAlphaC0Offset() + iCurrQp, 0, 51);
Int iIndexB = gClipMinMax( rcDFP.getSliceBetaOffset() + iCurrQp, 0, 51);
for( Int xBlk = 0; xBlk < 4; xBlk++)
{
const UChar ucBs = m_aaaucBs[HOR][xBlk][2];
if( 0 != ucBs )
{
xFilter( pPelCb, iStride, iIndexA, iIndexB, ucBs, false );
xFilter( pPelCb+1, iStride, iIndexA, iIndexB, ucBs, false );
xFilter( pPelCr, iStride, iIndexA, iIndexB, ucBs, false );
xFilter( pPelCr+1, iStride, iIndexA, iIndexB, ucBs, false );
}
pPelCb += 2;
pPelCr += 2;
}
return Err::m_nOK;
}
ErrVal
LoopFilter::xChromaVerFiltering( const MbDataAccess& rcMbDataAccess, const DBFilterParameter& rcDFP, YuvPicBuffer* pcYuvBuffer )
{
Int iCurrQp = rcMbDataAccess.getSH().getChromaQp( rcMbDataAccess.getMbData().getQpLF() );
Int iStride = pcYuvBuffer->getCStride();
XPel* pPelCb = pcYuvBuffer->getMbCbAddr();
XPel* pPelCr = pcYuvBuffer->getMbCrAddr();
//===== filtering of left macroblock edge =====
if( ! m_bVerMixedMode )
{
//----- curr == FRM && left == FRM or curr == FLD && left == FLD -----
Int iLeftQp = rcMbDataAccess.getSH().getChromaQp( rcMbDataAccess.getMbDataLeft().getQpLF() );
Int iQp = ( iLeftQp + iCurrQp + 1 ) >> 1;
Int iIndexA = gClipMinMax( rcDFP.getSliceAlphaC0Offset() + iQp, 0, 51);
Int iIndexB = gClipMinMax( rcDFP.getSliceBetaOffset() + iQp, 0, 51);
for( Int yBlk = 0; yBlk < 4; yBlk++)
{
const UChar ucBs = m_aaaucBs[VER][0][yBlk];
if( 0 != ucBs )
{
xFilter( pPelCb, 1, iIndexA, iIndexB, ucBs, false );
xFilter( pPelCb+iStride, 1, iIndexA, iIndexB, ucBs, false );
xFilter( pPelCr, 1, iIndexA, iIndexB, ucBs, false );
xFilter( pPelCr+iStride, 1, iIndexA, iIndexB, ucBs, false );
}
pPelCb += 2*iStride;
pPelCr += 2*iStride;
}
}
else
{
Int iLeftQpTop = rcMbDataAccess.getSH().getChromaQp( rcMbDataAccess.isTopMb() ? rcMbDataAccess.getMbDataLeft ().getQpLF() : rcMbDataAccess.getMbDataAboveLeft().getQpLF() );
Int iLeftQpBot = rcMbDataAccess.getSH().getChromaQp( rcMbDataAccess.isTopMb() ? rcMbDataAccess.getMbDataBelowLeft().getQpLF() : rcMbDataAccess.getMbDataLeft ().getQpLF() );
Int iQpTop = ( iLeftQpTop + iCurrQp + 1) >> 1;
Int iQpBot = ( iLeftQpBot + iCurrQp + 1) >> 1;
Int iIndexATop = gClipMinMax( rcDFP.getSliceAlphaC0Offset() + iQpTop, 0, 51);
Int iIndexABot = gClipMinMax( rcDFP.getSliceAlphaC0Offset() + iQpBot, 0, 51);
Int iIndexBTop = gClipMinMax( rcDFP.getSliceBetaOffset() + iQpTop, 0, 51);
Int iIndexBBot = gClipMinMax( rcDFP.getSliceBetaOffset() + iQpBot, 0, 51);
if( ! rcMbDataAccess.getMbData().getFieldFlag() )
{
//----- curr == FRM && left == FLD -----
for( Int yBlk = 0; yBlk < 4; yBlk++)
{
const UChar ucBsTop = m_aaaucBs[VER][0][yBlk];
const UChar ucBsBot = m_aucBsVerBot[yBlk];
if( 0 != ucBsTop )
{
xFilter( pPelCb, 1, iIndexATop, iIndexBTop, ucBsTop, false );
xFilter( pPelCr, 1, iIndexATop, iIndexBTop, ucBsTop, false );
}
if( 0 != ucBsBot )
{
xFilter( pPelCb+iStride, 1, iIndexABot, iIndexBBot, ucBsBot, false );
xFilter( pPelCr+iStride, 1, iIndexABot, iIndexBBot, ucBsBot, false );
}
pPelCb += 2*iStride;
pPelCr += 2*iStride;
}
}
else
{
//----- curr == FLD && left == FRM -----
Int yBlk;
for( yBlk = 0; yBlk < 2; yBlk++)
{
const UChar ucBsTop = m_aaaucBs[VER][0][yBlk];
const UChar ucBsBot = m_aucBsVerBot[yBlk];
if( 0 != ucBsTop )
{
xFilter( pPelCb, 1, iIndexATop, iIndexBTop, ucBsTop, false );
xFilter( pPelCr, 1, iIndexATop, iIndexBTop, ucBsTop, false );
}
if( 0 != ucBsBot )
{
xFilter( pPelCb+iStride, 1, iIndexATop, iIndexBTop, ucBsBot, false );
xFilter( pPelCr+iStride, 1, iIndexATop, iIndexBTop, ucBsBot, false );
}
pPelCb += 2*iStride;
pPelCr += 2*iStride;
}
for( yBlk = 2; yBlk < 4; yBlk++)
{
const UChar ucBsTop = m_aaaucBs[VER][0][yBlk];
const UChar ucBsBot = m_aucBsVerBot[yBlk];
if( 0 != ucBsTop )
{
xFilter( pPelCb, 1, iIndexABot, iIndexBBot, ucBsTop, false );
xFilter( pPelCr, 1, iIndexABot, iIndexBBot, ucBsTop, false );
}
if( 0 != ucBsBot )
{
xFilter( pPelCb+iStride, 1, iIndexABot, iIndexBBot, ucBsBot, false );
xFilter( pPelCr+iStride, 1, iIndexABot, iIndexBBot, ucBsBot, false );
}
pPelCb += 2*iStride;
pPelCr += 2*iStride;
}
}
}
pPelCb -= 8*iStride-4;
pPelCr -= 8*iStride-4;
Int iIndexA = gClipMinMax( rcDFP.getSliceAlphaC0Offset() + iCurrQp, 0, 51);
Int iIndexB = gClipMinMax( rcDFP.getSliceBetaOffset() + iCurrQp, 0, 51);
for( Int yBlk = 0; yBlk < 4; yBlk++)
{
const UChar ucBs = m_aaaucBs[VER][2][yBlk];
if( 0 != ucBs )
{
xFilter( pPelCb, 1, iIndexA, iIndexB, ucBs, false );
xFilter( pPelCb+iStride, 1, iIndexA, iIndexB, ucBs, false );
xFilter( pPelCr, 1, iIndexA, iIndexB, ucBs, false );
xFilter( pPelCr+iStride, 1, iIndexA, iIndexB, ucBs, false );
}
pPelCb += 2*iStride;
pPelCr += 2*iStride;
}
return Err::m_nOK;
}
H264AVC_NAMESPACE_END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -