📄 fgssubbandencoder.cpp
字号:
}
// FGS FMO ICU/ETRI
ErrVal
RQFGSEncoder::setSliceGroup(Int iSliceGroupID)
{
FMO* pcFMO = m_pcSliceHeader->getFMO();
m_pcSliceHeader->setFirstMbInSlice(pcFMO->getFirstMacroblockInSlice(iSliceGroupID));
m_pcSliceHeader->setLastMbInSlice(pcFMO->getLastMBInSliceGroup(iSliceGroupID));
// JVT-S054 (2) (ADD)
m_pcSliceHeader->setNumMbsInSlice(pcFMO->getNumMbsInSlice(m_pcSliceHeader->getFirstMbInSlice(), m_pcSliceHeader->getLastMbInSlice()));
return Err::m_nOK;
}
// FGS FMO ICU/ETRI
ErrVal
RQFGSEncoder::prepareEncode(UInt uiFrac, UInt uiFracNb)
{
if( ! uiFrac )
{
RNOK ( xMotionEstimation() );
RNOK ( xResidualTransform() );
}
if( uiFracNb )
{
RNOK( xRestoreCodingPath() );
}
return Err::m_nOK;
}
ErrVal
RQFGSEncoder::reconstruct( IntFrame* pcRecResidual )
{
ROF( m_bInit );
ROF( m_bPicInit );
ROF( pcRecResidual );
UInt uiLayer = m_pcSliceHeader->getSPS().getLayerId();
YuvBufferCtrl* pcYuvBufferCtrl = m_papcYuvFullPelBufferCtrl[uiLayer];
IntYuvMbBuffer cMbBuffer;
RNOK( m_pcCurrMbDataCtrl->initSlice ( *m_pcSliceHeader, PRE_PROCESS, false, NULL ) );
for( UInt uiMbY = 0; uiMbY < m_uiHeightInMB; uiMbY++ )
for( UInt uiMbX = 0; uiMbX < m_uiWidthInMB; uiMbX++ )
{
MbDataAccess* pcMbDataAccess = 0;
RNOK( m_pcCurrMbDataCtrl->initMb( pcMbDataAccess, uiMbY, uiMbX ) );
RNOK( pcYuvBufferCtrl ->initMb( uiMbY, uiMbX ) );
RNOK( xReconstructMacroblock ( *pcMbDataAccess, cMbBuffer ) );
RNOK( pcRecResidual->getFullPelYuvBuffer()->loadBuffer( &cMbBuffer ) );
}
return Err::m_nOK;
}
const UChar COEFF_COST[16] =
{
3, 2,2,1, 1,1,0,0,0,0,0,0,0,0,0,0
};
const UChar COEFF_COST8x8[64] =
{
3,3,3,3,2,2,2,2,2,2,2,2,1,1,1,1,
1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
};
const UChar MAX_VALUE = 100;
ErrVal
RQFGSEncoder::xSetSymbolsChroma( TCoeff* piCoeff,
UInt uiMbX,
UInt uiMbY,
UInt& uiCoeffCostDC,
UInt& uiCoeffCostAC,
Bool& bSigDC,
Bool& bSigAC,
ChromaIdx cIdx )
{
Int iRun = 0;
UInt uiPlane = cIdx.plane();
UChar** ppucChromaDCCoefMap = m_aapaucChromaDCCoefMap[uiPlane];
UChar** ppucChromaACCoefMap = m_aapaucChromaACCoefMap[uiPlane];
UInt uiMbIndex = uiMbY * m_uiWidthInMB + uiMbX;
UInt ui8x8Idx = ( 2 * uiMbY + cIdx.y() ) * 2 * m_uiWidthInMB + ( 2 * uiMbX + cIdx.x() );
for( Int iPos = 0; iPos < 16; iPos++ )
{
Int iIndex = g_aucFrameScan[iPos];
Int iLevel = piCoeff [iIndex];
UChar ucSigMap = ( iPos == 0 ) ?
ppucChromaDCCoefMap[cIdx.y()* 2 + cIdx.x()][uiMbIndex] : ppucChromaACCoefMap[iPos][ui8x8Idx];
if( ucSigMap & SIGNIFICANT )
{
if( abs(iLevel) > 1 )
{
iLevel = max( -1, min( 1, iLevel ) );
}
piCoeff[iIndex] = iLevel;
}
else
{
if( iPos == 0 )
{
if( iLevel )
{
if( abs( iLevel) == 1 ) uiCoeffCostDC += COEFF_COST[iRun];
else uiCoeffCostDC += MAX_VALUE;
bSigDC = true;
}
}
else
{
if( iLevel )
{
if( abs( iLevel) == 1 ) uiCoeffCostAC += COEFF_COST[iRun];
else uiCoeffCostAC += MAX_VALUE;
iRun = 0;
bSigAC = true;
}
else
{
iRun++;
}
}
}
}
return Err::m_nOK;
}
ErrVal
RQFGSEncoder::xSetSymbols4x4( TCoeff* piCoeff,
UInt uiMbX,
UInt uiMbY,
UInt& uiCoeffCost,
UInt& ruiCbp,
LumaIdx cIdx,
UInt uiStart )
{
Int iRun = 0;
Bool bSig = false;
for( Int iPos = uiStart; iPos < 16; iPos++ )
{
Int iIndex = g_aucFrameScan[iPos];
Int iLevel = piCoeff [iIndex];
UInt uiBlockIndex = ( uiMbY * 4 + cIdx.y() ) * m_uiWidthInMB * 4 + uiMbX * 4 + cIdx.x();
if( m_apaucLumaCoefMap[iPos][uiBlockIndex] & SIGNIFICANT )
{
if( abs(iLevel) > 1 )
{
iLevel = max( -1, min( 1, iLevel ) );
}
piCoeff[iIndex] = iLevel;
}
else
{
if( iLevel )
{
if( abs( iLevel) == 1 ) uiCoeffCost += COEFF_COST[iRun];
else uiCoeffCost += MAX_VALUE;
iRun = 0;
bSig = true;
}
else
{
iRun++;
}
}
}
if( bSig )
{
ruiCbp |= ( 1 << cIdx );
}
return Err::m_nOK;
}
ErrVal
RQFGSEncoder::xSetSymbols8x8( TCoeff* piCoeff,
UInt uiMbX,
UInt uiMbY,
UInt& uiCoeffCost,
UInt& ruiCbp,
LumaIdx cIdx )
{
Int iRun = 0;
Bool bSig = false;
UInt auiBlockIdx[4] =
{
( uiMbY*4 + cIdx.y() ) * 4 * m_uiWidthInMB + ( uiMbX*4 + cIdx.x() ),
( uiMbY*4 + cIdx.y() ) * 4 * m_uiWidthInMB + ( uiMbX*4 + cIdx.x() + 1 ),
( uiMbY*4 + cIdx.y() + 1 ) * 4 * m_uiWidthInMB + ( uiMbX*4 + cIdx.x() ),
( uiMbY*4 + cIdx.y() + 1 ) * 4 * m_uiWidthInMB + ( uiMbX*4 + cIdx.x() + 1 )
};
for( Int iPos = 0; iPos < 64; iPos++ )
{
Int iIndex = g_aucFrameScan64[iPos];
Int iLevel = piCoeff [iIndex];
if( m_apaucLumaCoefMap[iPos/4][auiBlockIdx[iPos%4]] & SIGNIFICANT )
{
if( abs(iLevel) > 1 )
{
iLevel = max( -1, min( 1, iLevel ) );
}
piCoeff[iIndex] = iLevel;
}
else
{
if( iLevel )
{
if( abs( iLevel) == 1 ) uiCoeffCost += COEFF_COST8x8[iRun];
else uiCoeffCost += MAX_VALUE;
iRun = 0;
bSig = true;
}
else
{
iRun++;
}
}
}
if( bSig )
{
ruiCbp |= ( 0x33 << cIdx );
}
return Err::m_nOK;
}
ErrVal
RQFGSEncoder::xRequantizeMacroblock( MbDataAccess& rcMbDataAccess,
MbDataAccess& rcMbDataAccessBase )
{
#define COEF_SKIP 1
UInt uiExtCbp = 0;
Int iQp = max( 0, rcMbDataAccessBase.getMbData().getQp() - RQ_QP_DELTA );
Bool bIntra = rcMbDataAccessBase.getMbData().isIntra();
Bool bIntra16x16 = rcMbDataAccessBase.getMbData().isIntra16x16();
Bool b8x8 = rcMbDataAccessBase.getMbData().isTransformSize8x8();
Bool bLowPass = m_pcSliceHeader->getTemporalLevel() == 0;
const UChar* pucScaleY = rcMbDataAccessBase.getSH().getScalingMatrix( bIntra ? ( b8x8 ? 6 : 0 ) : ( b8x8 ? 7 : 3 ) );
const UChar* pucScaleU = rcMbDataAccessBase.getSH().getScalingMatrix( bIntra ? 1 : 4 );
const UChar* pucScaleV = rcMbDataAccessBase.getSH().getScalingMatrix( bIntra ? 2 : 5 );
UInt uiMbX = rcMbDataAccess.getMbX();
UInt uiMbY = rcMbDataAccess.getMbY();
rcMbDataAccess.getMbData().setQp( iQp );
//-- JVT-R091
// use intra offset for smoothed reference MB
if ( rcMbDataAccessBase.getMbData().getSmoothedRefFlag() )
{
m_pcTransform->setQp( rcMbDataAccess, true );
}
else
{
m_pcTransform->setQp( rcMbDataAccess, bLowPass || bIntra );
}
//--
IntYuvMbBuffer cMbBuffer;
cMbBuffer .loadBuffer( m_pcOrgResidual ->getFullPelYuvBuffer() );
//===== luma =====
if( b8x8 )
{
UInt uiAbsSumMb = 0;
UInt uiCoeffCostMb = 0;
for( B8x8Idx c8x8Idx; c8x8Idx.isLegal(); c8x8Idx++ )
{
UInt uiCoeffCost8x8 = 0;
UInt uiAbsSum8x8 = 0;
UInt uiCbp = 0;
cMbBuffer.set4x4Block( c8x8Idx );
RNOK( m_pcTransform->requant8x8Block( cMbBuffer,
rcMbDataAccess .getMbTCoeffs().get8x8( c8x8Idx ),
rcMbDataAccessBase.getMbTCoeffs().get8x8( c8x8Idx ),
pucScaleY, uiAbsSum8x8 ) );
uiAbsSumMb += uiAbsSum8x8;
RNOK( xSetSymbols8x8( rcMbDataAccess .getMbTCoeffs().get8x8( c8x8Idx ),
uiMbX, uiMbY,
uiCoeffCost8x8, uiCbp, c8x8Idx ) );
if( uiCbp )
{
#if COEF_SKIP
if( uiCoeffCost8x8 <= 4 && ! bIntra && ! bLowPass )
{
rcMbDataAccess.getMbTCoeffs().clearNewLumaLevels8x8Block( c8x8Idx, rcMbDataAccessBase.getMbTCoeffs() );
}
else
#endif
{
uiCoeffCostMb += uiCoeffCost8x8;
uiExtCbp += uiCbp;
}
}
}
#if COEF_SKIP
if( uiExtCbp && uiCoeffCostMb <= 5 && ! bIntra && ! bLowPass )
{
rcMbDataAccess.getMbTCoeffs().clearNewLumaLevels( rcMbDataAccessBase.getMbTCoeffs() );
uiExtCbp = 0;
}
#endif
}
else
{
UInt uiAbsSumMb = 0;
UInt uiCoeffCostMb = 0;
for( B8x8Idx c8x8Idx; c8x8Idx.isLegal(); c8x8Idx++ )
{
UInt uiCoeffCost8x8 = 0;
UInt uiAbsSum8x8 = 0;
UInt uiCbp = 0;
for( S4x4Idx cIdx( c8x8Idx ); cIdx.isLegal( c8x8Idx ); cIdx++ )
{
UInt uiAbsSum4x4 = 0;
cMbBuffer.set4x4Block( cIdx );
RNOK( m_pcTransform->requant4x4Block( cMbBuffer,
rcMbDataAccess .getMbTCoeffs().get( cIdx ),
rcMbDataAccessBase.getMbTCoeffs().get( cIdx ),
pucScaleY,
bIntra16x16,
uiAbsSum4x4 ) );
uiAbsSum8x8 += uiAbsSum4x4;
if ( bIntra16x16 )
uiAbsSum8x8 -= abs(rcMbDataAccess.getMbTCoeffs().get( cIdx )[0]);
RNOK( xSetSymbols4x4( rcMbDataAccess .getMbTCoeffs().get( cIdx ),
uiMbX, uiMbY,
uiCoeffCost8x8, uiCbp, cIdx, bIntra16x16 ) );
}
if( uiCbp )
{
#if COEF_SKIP
if( uiCoeffCost8x8 <= 4 && ! bIntra && ! bLowPass && ! bIntra16x16 )
{
rcMbDataAccess.getMbTCoeffs().clearNewLumaLevels8x8( c8x8Idx, rcMbDataAccessBase.getMbTCoeffs() );
}
else
#endif
{
uiCoeffCostMb += uiCoeffCost8x8;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -