📄 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;
}
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,
Bool bFrame )
{
Int iRun = 0;
UInt uiMbIndex = uiMbY * m_uiWidthInMB + uiMbX;
CoefMap *pcCoefMap = m_pcCoefMap[uiMbIndex].getCoefMap( cIdx );
const UChar* pucScan = (bFrame) ? g_aucFrameScan : g_aucFieldScan;
for( Int iPos = 0; iPos < 16; iPos++ )
{
Int iIndex = pucScan[iPos];
Int iLevel = piCoeff [iIndex];
if( pcCoefMap[iPos] & SIGNIFICANT )
{
ROT( abs(iLevel) > 1 );
}
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,
const S4x4Idx& rcIdx,
UInt uiStart,
Bool bFrame )
{
Int iRun = 0;
Bool bSig = false;
CoefMap* pcCoefMap = m_pcCoefMap[uiMbY * m_uiWidthInMB + uiMbX ].getCoefMap( rcIdx );
const UChar* pucScan = (bFrame) ? g_aucFrameScan : g_aucFieldScan;
for( Int iPos = uiStart; iPos < 16; iPos++ )
{
Int iIndex = pucScan[iPos];
Int iLevel = piCoeff [iIndex];
if( pcCoefMap[iPos] & SIGNIFICANT )
{
ROT( abs(iLevel) > 1 );
}
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 << rcIdx );
}
return Err::m_nOK;
}
ErrVal
RQFGSEncoder::xSetSymbols8x8( TCoeff* piCoeff,
UInt uiMbX,
UInt uiMbY,
UInt& uiCoeffCost,
UInt& ruiCbp,
B8x8Idx cIdx,
Bool bFrame )
{
Int iRun = 0;
Bool bSig = false;
CoefMap* pcCoefMap = m_pcCoefMap[uiMbY * m_uiWidthInMB + uiMbX ].getCoefMap( cIdx );
const UChar* pucScan64 = (bFrame) ? g_aucFrameScan64 : g_aucFieldScan64;
for( Int iPos = 0; iPos < 64; iPos++ )
{
Int iIndex = pucScan64[iPos];
Int iLevel = piCoeff [iIndex];
if( pcCoefMap[iPos] & SIGNIFICANT )
{
ROT( abs(iLevel) > 1 );
}
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();
const PicType eMbPicType = rcMbDataAccess.getMbPicType();
const Bool bFrame = (FRAME == rcMbDataAccess.getMbPicType());
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->getPic( eMbPicType )->getFullPelYuvBuffer() );
//===== luma =====
MbFGSCoefMap* pcMbFGSCoefMap = &m_pcCoefMap[uiMbY * m_uiWidthInMB + uiMbX];
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 ),
pcMbFGSCoefMap->getRefCtx( c8x8Idx ),
pucScaleY, uiAbsSum8x8 ) );
uiAbsSumMb += uiAbsSum8x8;
RNOK( xSetSymbols8x8( rcMbDataAccess .getMbTCoeffs().get8x8( c8x8Idx ),
uiMbX, uiMbY,
uiCoeffCost8x8, uiCbp, c8x8Idx, bFrame ) );
if( uiCbp )
{
#if COEF_SKIP
if( uiCoeffCost8x8 <= 4 && ! bIntra && ! bLowPass )
{
rcMbDataAccess.getMbTCoeffs().clearNewLumaLevels8x8Block( c8x8Idx, rcMbDataAccessBase.getMbTCoeffs(), pcMbFGSCoefMap );
}
else
#endif
{
uiCoeffCostMb += uiCoeffCost8x8;
uiExtCbp += uiCbp;
}
}
}
#if COEF_SKIP
if( uiExtCbp && uiCoeffCostMb <= 5 && ! bIntra && ! bLowPass )
{
rcMbDataAccess.getMbTCoeffs().clearNewLumaLevels( rcMbDataAccessBase.getMbTCoeffs(), pcMbFGSCoefMap, true );
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 ),
pcMbFGSCoefMap->getRefCtx( cIdx ),
pucScaleY,
bIntra16x16,
uiAbsSum4x4 ) );
uiAbsSum8x8 += uiAbsSum4x4;
if ( bIntra16x16 )
uiAbsSum8x8 -= abs( (Int)rcMbDataAccess.getMbTCoeffs().get( cIdx )[0] );
RNOK( xSetSymbols4x4( rcMbDataAccess .getMbTCoeffs().get( cIdx ),
uiMbX, uiMbY,
uiCoeffCost8x8, uiCbp, cIdx, bIntra16x16, bFrame ) );
}
if( uiCbp )
{
#if COEF_SKIP
if( uiCoeffCost8x8 <= 4 && ! bIntra && ! bLowPass && ! bIntra16x16 )
{
rcMbDataAccess.getMbTCoeffs().clearNewLumaLevels8x8( c8x8Idx, rcMbDataAccessBase.getMbTCoeffs(), pcMbFGSCoefMap );
}
else
#endif
{
uiCoeffCostMb += uiCoeffCost8x8;
uiExtCbp += uiCbp;
}
}
uiAbsSumMb += uiAbsSum8x8;
}
if ( bIntra16x16 )
{
UInt uiAbsDc;
MbTransformCoeffs& rcMbTCoeffs = rcMbDataAccess.getMbTCoeffs();
MbTransformCoeffs& rcMbTCoeffsBase = rcMbDataAccessBase.getMbTCoeffs();
// transform and quantization on intra16x16 DC coefficients
m_pcTransform->requantLumaDcCoeffs( rcMbTCoeffs, rcMbTCoeffsBase, *pcMbFGSCoefMap, pucScaleY, uiAbsDc );
for( S4x4Idx cIdx; cIdx.isLegal(); cIdx++ )
{
Int iLevel = rcMbTCoeffs.get( cIdx )[0];
if( pcMbFGSCoefMap->getCoefMap( cIdx )[0] & SIGNIFICANT )
{
AOT( iLevel > 1 || iLevel < -1 );
}
else
{
// WARNING, should have "else" here because CBP is only for new-significant coefficients
// since the DC coefficients are merged with the AC coefficients
// update the cbp information
uiExtCbp |= (iLevel != 0) << cIdx;
}
}
}
#if COEF_SKIP
if( ! bIntra16x16 )
if( uiExtCbp && uiCoeffCostMb <= 5 && ! bIntra && ! bLowPass )
{
rcMbDataAccess.getMbTCoeffs().clearNewLumaLevels( rcMbDataAccessBase.getMbTCoeffs(), pcMbFGSCoefMap, false );
uiExtCbp = 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -