📄 fgssubbandencoder.cpp
字号:
uiExtCbp += uiCbp;
}
}
uiAbsSumMb += uiAbsSum8x8;
}
if ( bIntra16x16 )
{
UInt uiAbsDc;
TCoeff *piCoeff, *piCoeffBase;
// put DC coefficients into buffer
piCoeff = rcMbDataAccess .getMbTCoeffs().get( B4x4Idx(0) );
piCoeffBase = rcMbDataAccessBase.getMbTCoeffs().get( B4x4Idx(0) );
// transform and quantization on intra16x16 DC coefficients
m_pcTransform->requantLumaDcCoeffs( piCoeff, piCoeffBase, pucScaleY, uiAbsDc );
for ( UInt uiDcIdx = 0; uiDcIdx < 16; uiDcIdx ++ )
{
Int iLevel = piCoeff [16 * uiDcIdx];
Int uiBlockIndex = (uiMbY * 4 + uiDcIdx/4)* m_uiWidthInMB * 4 + uiMbX * 4 + (uiDcIdx % 4);
if( m_apaucLumaCoefMap[0][uiBlockIndex] & SIGNIFICANT )
{
if( abs(iLevel) > 1 )
{
iLevel = max( -1, min( 1, iLevel ) );
}
piCoeff[16 * uiDcIdx] = iLevel;
}
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) << uiDcIdx;
}
}
#if COEF_SKIP
if( ! bIntra16x16 )
if( uiExtCbp && uiCoeffCostMb <= 5 && ! bIntra && ! bLowPass )
{
rcMbDataAccess.getMbTCoeffs().clearNewLumaLevels( rcMbDataAccessBase.getMbTCoeffs() );
uiExtCbp = 0;
}
#endif
}
//===== chroma =====
UInt uiDcAbs = 0;
UInt uiAcAbs = 0;
UInt uiCoeffCostDC = 0;
UInt uiCoeffCostAC = 0;
Bool bSigDC = false;
Bool bSigAC_U = false;
Bool bSigAC_V = false;
RNOK( m_pcTransform->requantChroma( cMbBuffer,
rcMbDataAccess .getMbTCoeffs().get( CIdx(0) ),
rcMbDataAccessBase.getMbTCoeffs().get( CIdx(0) ),
pucScaleU, pucScaleV, uiDcAbs, uiAcAbs ) );
//===== chrominance U =====
{
UInt uiCoeffCostAC_U = 0;
for( CIdx cIdxU(0); cIdxU.isLegal(4); cIdxU++ )
{
RNOK( xSetSymbolsChroma( rcMbDataAccess .getMbTCoeffs().get( cIdxU ),
uiMbX, uiMbY,
uiCoeffCostDC, uiCoeffCostAC_U, bSigDC, bSigAC_U, cIdxU ) );
}
#if COEF_SKIP
if( uiCoeffCostAC_U < 4 )
{
for( CIdx cIdxU(0); cIdxU.isLegal(4); cIdxU++ )
{
rcMbDataAccess.getMbTCoeffs().clearNewAcBlk( cIdxU, rcMbDataAccessBase.getMbTCoeffs() );
}
bSigAC_U = false;
}
else
#endif
{
uiCoeffCostAC += uiCoeffCostAC_U;
}
}
//===== chrominance V =====
{
UInt uiCoeffCostAC_V = 0;
for( CIdx cIdxV(4); cIdxV.isLegal(8); cIdxV++ )
{
RNOK( xSetSymbolsChroma( rcMbDataAccess .getMbTCoeffs().get( cIdxV ),
uiMbX, uiMbY,
uiCoeffCostDC, uiCoeffCostAC_V, bSigDC, bSigAC_V, cIdxV ) );
}
#if COEF_SKIP
if( uiCoeffCostAC_V < 4 )
{
for( CIdx cIdxV(4); cIdxV.isLegal(8); cIdxV++ )
{
rcMbDataAccess.getMbTCoeffs().clearNewAcBlk( cIdxV, rcMbDataAccessBase.getMbTCoeffs() );
}
bSigAC_V = false;
}
else
#endif
{
uiCoeffCostAC += uiCoeffCostAC_V;
}
}
//===== set CBP =====
UInt uiChromaCBP = ( bSigAC_U || bSigAC_V ? 2 : bSigDC ? 1 : 0 );
uiExtCbp |= ( uiChromaCBP << 16 );
rcMbDataAccess.getMbData().setAndConvertMbExtCbp( uiExtCbp );
return Err::m_nOK;
#undef COEF_SKIP
}
ErrVal
RQFGSEncoder::xMotionEstimation()
{
RNOK( m_cMbDataCtrlEL .clear () );
RNOK( m_cMbDataCtrlEL .reset () );
RNOK( m_cMbDataCtrlEL .initSlice ( *m_pcSliceHeader, ENCODE_PROCESS, false, NULL ) );
RNOK( m_pcCurrMbDataCtrl->initSlice ( *m_pcSliceHeader, PRE_PROCESS, false, NULL ) );
ROTRS( m_eSliceType == I_SLICE, Err::m_nOK );
UInt uiLayer = m_pcSliceHeader->getSPS().getLayerId();
YuvBufferCtrl* pcYuvFullBufferCtrl = m_papcYuvFullPelBufferCtrl[uiLayer];
YuvBufferCtrl* pcYuvHalfBufferCtrl = m_papcYuvHalfPelBufferCtrl[uiLayer];
m_pcSliceHeader->setSliceType( m_eSliceType );
for( UInt uiMbY = 0; uiMbY < m_uiHeightInMB; uiMbY++ )
for( UInt uiMbX = 0; uiMbX < m_uiWidthInMB; uiMbX++ )
{
MbDataAccess* pcMbDataAccessCurr = 0;
MbDataAccess* pcMbDataAccessEL = 0;
RNOK( m_pcCurrMbDataCtrl ->initMb( pcMbDataAccessCurr, uiMbY, uiMbX ) );
RNOK( m_cMbDataCtrlEL .initMb( pcMbDataAccessEL, uiMbY, uiMbX ) );
RNOK( pcYuvFullBufferCtrl ->initMb( uiMbY, uiMbX ) );
RNOK( pcYuvHalfBufferCtrl ->initMb( uiMbY, uiMbX ) );
RNOK( m_pcMotionEstimation->initMb( uiMbY, uiMbX, *pcMbDataAccessEL ) );
if( pcMbDataAccessCurr->getMbData().isIntra() || ! m_pcSliceHeader->getAdaptivePredictionFlag() )
{
pcMbDataAccessEL->getMbData().copyFrom ( pcMbDataAccessCurr->getMbData() );
RNOK( pcMbDataAccessEL->getMbData().copyMotion( pcMbDataAccessCurr->getMbData() ) );
if( ! pcMbDataAccessCurr->getMbData().isIntra() )
pcMbDataAccessEL->getMbData().setBLSkipFlag( true );
}
else
{
//----- reconstruct base layer -----
IntYuvMbBuffer cBLRecBuffer;
RNOK( xReconstructMacroblock( *pcMbDataAccessCurr, cBLRecBuffer ) );
//----- get new motion data -----
RNOK( m_pcMbEncoder->encodeFGS( *pcMbDataAccessEL,
pcMbDataAccessCurr,
*m_pcRefFrameList0,
*m_pcRefFrameList1,
*m_pcOrgFrame,
m_pcPredSignal,
m_pcFGSPredFrame,
m_pcRefFrameListDiff,
this,
cBLRecBuffer,
m_uiNumMaxIter,
m_uiIterSearchRange,
m_dLambda,
m_iMaxQpDelta ) );
if( ! pcMbDataAccessEL->getMbData().getResidualPredFlag( PART_16x16 ) )
{
ROT( pcMbDataAccessEL->getMbData().getBLSkipFlag() );
//----- motion refinement without residual prediction ===> clear base layer coeffs -----
RNOK( xClearBaseCoeffs( *pcMbDataAccessEL, pcMbDataAccessCurr ) );
}
}
}
m_pcSliceHeader->setSliceType( F_SLICE );
return Err::m_nOK;
}
ErrVal
RQFGSEncoder::xEncodeMotionData( UInt uiMbYIdx, UInt uiMbXIdx )
{
ETRACE_DECLARE( UInt uiMbIndex = uiMbYIdx * m_uiWidthInMB + uiMbXIdx );
MbDataAccess* pcMbDataAccessEL = 0;
MbDataAccess* pcMbDataAccessBL = 0;
RNOK( m_cMbDataCtrlEL .initMb( pcMbDataAccessEL, uiMbYIdx, uiMbXIdx ) );
RNOK( m_pcCurrMbDataCtrl ->initMb( pcMbDataAccessBL, uiMbYIdx, uiMbXIdx ) );
ROT ( pcMbDataAccessBL->getMbData().isIntra() );
ETRACE_NEWMB( uiMbIndex );
m_pcSliceHeader ->setSliceType( m_eSliceType );
RNOK( m_pcMbCoder->encodeMotion( *pcMbDataAccessEL, pcMbDataAccessBL ) );
m_pcSliceHeader ->setSliceType( F_SLICE );
return Err::m_nOK;
}
ErrVal
RQFGSEncoder::xResidualTransform( /*UInt uiBasePos*/ )
{
UInt uiLayer = m_pcSliceHeader->getSPS().getLayerId();
YuvBufferCtrl* pcYuvBufferCtrl = m_papcYuvFullPelBufferCtrl[uiLayer];
Bool bLowPass = m_pcSliceHeader->getTemporalLevel() == 0;
RNOK( m_pcOrgResidual->subtract( m_pcOrgFrame, m_pcPredSignal ) );
RNOK( m_pcOrgResidual->subtract( m_pcOrgResidual, m_pcBaseLayerSbb ) );
// Martin.Winken@hhi.fhg.de: clear, reset, initSlice now done in RQFGSEncoder::xMotionEstimation()
for( UInt uiMbY = 0; uiMbY < m_uiHeightInMB; uiMbY++ )
for( UInt uiMbX = 0; uiMbX < m_uiWidthInMB; uiMbX++ )
{
MbDataAccess* pcMbDataAccessCurr = 0;
MbDataAccess* pcMbDataAccessEL = 0;
RNOK( m_pcCurrMbDataCtrl->initMb( pcMbDataAccessCurr, uiMbY, uiMbX ) );
RNOK( m_cMbDataCtrlEL .initMb( pcMbDataAccessEL, uiMbY, uiMbX ) );
RNOK( pcYuvBufferCtrl ->initMb( uiMbY, uiMbX ) );
if( pcMbDataAccessCurr->getMbData().isIntra16x16() ||
( m_pauiMacroblockMap[uiMbY * m_uiWidthInMB + uiMbX] & SIGNIFICANT ) != 0 )
{
UInt uiMbIndex = uiMbY * m_uiWidthInMB + uiMbX;
Bool bUseTransformSizeFromRDO = ! ( m_pauiMacroblockMap[uiMbIndex] & TRANSFORM_SPECIFIED ) && ! pcMbDataAccessCurr->getMbData().isIntra();
if( bUseTransformSizeFromRDO )
{
//----- set transform size from RDO (i.e., MbEncoder::encodeFGS()) if possible -----
pcMbDataAccessCurr->getMbData().setTransformSize8x8( pcMbDataAccessEL->getMbData().isTransformSize8x8() );
}
//===== requantization =====
RNOK( xRequantizeMacroblock ( *pcMbDataAccessEL, *pcMbDataAccessCurr ) );
if( bUseTransformSizeFromRDO && ( pcMbDataAccessEL->getMbData().getMbCbp() & 0x0F ) == 0 )
{
//----- clear transform size flag if no luma samples coded -----
pcMbDataAccessCurr->getMbData().setTransformSize8x8( false );
}
}
else
{
//===== new encoding =====
m_pcTransform->setClipMode( false );
pcMbDataAccessEL->getMbData().setQp( m_pcSliceHeader->getPicQp() );
Bool bResidualPrediction = pcMbDataAccessEL->getMbData().getResidualPredFlag( PART_16x16 );
RNOK( m_pcMbEncoder->encodeResidual( *pcMbDataAccessEL,
*pcMbDataAccessCurr,
m_pcOrgResidual,
m_dLambda,
bLowPass,
m_iMaxQpDelta ) );
pcMbDataAccessEL->getMbData().setResidualPredFlag( bResidualPrediction );
m_pcTransform->setClipMode( true );
}
}
return Err::m_nOK;
}
ErrVal
RQFGSEncoder::xScaleBaseLayerCoeffs()
{
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( xScaleTCoeffs ( *pcMbDataAccess, true ) );
}
return Err::m_nOK;
}
//JVT-P031
ErrVal RQFGSEncoder::xSaveCodingPath()
{
typedef MbTransformCoeffs* pMbTransformCoeffs;
m_aMyELTransformCoefs = new pMbTransformCoeffs[m_uiHeightInMB*m_uiWidthInMB];
m_aMyBLTransformCoefs = new pMbTransformCoeffs[m_uiHeightInMB*m_uiWidthInMB];
m_auiMbCbpStored = new UInt[m_uiHeightInMB*m_uiWidthInMB];
m_auiBCBPStored = new UInt[m_uiHeightInMB*m_uiWidthInMB];
m_aiBLQP = new Int[m_uiHeightInMB*m_uiWidthInMB];
m_abELtransform8x8 = new Bool[m_uiHeightInMB*m_uiWidthInMB];
for( UInt uiMbY = 0; uiMbY < m_uiHeightInMB; uiMbY++ )
{
for( UInt uiMbX = 0; uiMbX < m_uiWidthInMB; uiMbX++ )
{
m_aMyELTransformCoefs[uiMbY+uiMbX*m_uiHeightInMB] = new MbTransformCoeffs();
m_aMyBLTransformCoefs[uiMbY+uiMbX*m_uiHeightInMB] = new MbTransformCoeffs();
//--- Get MbData for BL and EL
MbDataAccess* pcMbDataAccessBL = 0;
MbDataAccess* pcMbDataAccessEL = 0;
RNOK( m_pcCurrMbDataCtrl->initMb( pcMbDataAccessBL, uiMbY, uiMbX ) );
RNOK( m_cMbDataCtrlEL .initMb( pcMbDataAccessEL, uiMbY, uiMbX ) );
//--------------------------------------------------------
//--- Perform some backup of BL and EL
// coeffs
m_aMyBLTransformCoefs[uiMbY+uiMbX*m_uiHeightInMB]->copyFrom(pcMbDataAccessBL->getMbData().getMbTCoeffs());
m_aMyELTransformCoefs[uiMbY+uiMbX*m_uiHeightInMB]->copyFrom(pcMbDataAccessEL->getMbData().getMbTCoeffs());
// store CBP before update (but it seems not to have any influence)
m_auiMbCbpStored[uiMbY+uiMbX*m_uiHeightInMB] = pcMbDataAccessBL->getMbData().getMbExtCbp();
m_auiBCBPStored[uiMbY+uiMbX*m_uiHeightInMB] = pcMbDataAccessBL->getMbData().getBCBP();
m_aiBLQP[uiMbY+uiMbX*m_uiHeightInMB] = pcMbDataAccessBL->getMbData().getQp();
m_abELtransform8x8[uiMbY+uiMbX*m_uiHeightInMB] = pcMbDataAccessEL->getMbData().isTransformSize8x8();
}
}
return Err::m_nOK;
}
ErrVal RQFGSEncoder::xRestoreCodingPath()
{
//--ICU/ETRI FMO
UInt uiFirstMbInSlice;
UInt uiLastMbInSlice;
if(m_pcSliceHeader !=NULL)
{
uiFirstMbInSlice = m_pcSliceHeader->getFirstMbInSlice();
uiLastMbInSlice = m_pcSliceHeader->getLastMbInSlice();
}
else
{
uiFirstMbInSlice =0;
uiLastMbInSlice = (m_uiWidthInMB*m_uiHeightInMB) -1;
}
for(UInt uiMbAddress= uiFirstMbInSlice ;uiMbAddress<=uiLastMbInSlice ;)
{
UInt uiMbY = uiMbAddress / m_uiWidthInMB;
UInt uiMbX = uiMbAddress % m_uiWidthInMB;
{
{
//-------------------------------------------------------
//--- Get MbData for BL and EL
MbDataAccess* pcMbDataAccessBL = 0;
MbDataAccess* pcMbDataAccessEL = 0;
RNOK( m_pcCurrMbDataCtrl->initMb( pcMbDataAccessBL, uiMbY, uiMbX ) );
RNOK( m_cMbDataCtrlEL .initMb( pcMbDataAccessEL, uiMbY, uiMbX ) );
//----- restore informations on BL and EL
pcMbDataAccessBL->getMbData().setBCBP(m_auiBCBPStored[uiMbY+uiMbX*m_uiHeightInMB]);
pcMbDataAccessBL->getMbData().setMbExtCbp(m_auiMbCbpStored[uiMbY+uiMbX*m_uiHeightInMB]);
pcMbDataAccessBL->getMbData().setQp(m_aiBLQP[uiMbY+uiMbX*m_uiHeightInMB]);
// restore Coeffs
m_cMbDataCtrlEL.getMbData(uiMbX,uiMbY).getMbTCoeffs().copyFrom(*m_aMyELTransformCoefs[uiMbY+uiMbX*m_uiHeightInMB]);
m_pcCurrMbDataCtrl->getMbData(uiMbX,uiMbY).getMbTCoeffs().copyFrom(*m_aMyBLTransformCoefs[uiMbY+uiMbX*m_uiHeightInMB]);
pcMbDataAccessEL->getMbData().setTransformSize8x8( m_abELtransform8x8[uiMbY+uiMbX*m_uiHeightInMB] );
//--ICU/ETRI FMO Implementation
if(m_pcSliceHeader !=NULL)
uiMbAddress = m_pcSliceHeader->getFMO()->getNextMBNr(uiMbAddress );
else
uiMbAddress ++;
}
}
}
delete []m_aMyELTransformCoefs;
delete []m_aMyBLTransformCoefs;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -