📄 fgssubbandencoder.cpp
字号:
#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(),
rcMbDataAccessBase.getMbTCoeffs(),
*pcMbFGSCoefMap, 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, bFrame ) );
}
#if COEF_SKIP
if( uiCoeffCostAC_U < 4 )
{
for( CIdx cIdxU(0); cIdxU.isLegal(4); cIdxU++ )
{
rcMbDataAccess.getMbTCoeffs().clearNewAcBlk( cIdxU, *pcMbFGSCoefMap, 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, bFrame ) );
}
#if COEF_SKIP
if( uiCoeffCostAC_V < 4 )
{
for( CIdx cIdxV(4); cIdxV.isLegal(8); cIdxV++ )
{
rcMbDataAccess.getMbTCoeffs().clearNewAcBlk( cIdxV, *pcMbFGSCoefMap, 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];
const Bool bMbAff = m_pcSliceHeader->isMbAff();// TMM_INTERLACE
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, bMbAff ) );// TMM_INTERLACE
RNOK( pcYuvHalfBufferCtrl ->initMb( uiMbY, uiMbX, bMbAff ) );// TMM_INTERLACE
RNOK( m_pcMotionEstimation->initMb( uiMbY, uiMbX, *pcMbDataAccessEL ) );
if( pcMbDataAccessCurr->getMbData().isIntra() || ! m_pcSliceHeader->getAdaptivePredictionFlag() )
{
pcMbDataAccessEL->getMbData().copyFrom ( pcMbDataAccessCurr->getMbData() );
pcMbDataAccessEL->getMbData().setBCBP ( 0 );
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 uiLayer = m_pcSliceHeader->getSPS().getLayerId();
YuvBufferCtrl* pcYuvBufferCtrl = m_papcYuvFullPelBufferCtrl[uiLayer];
Bool bLowPass = m_pcSliceHeader->getTemporalLevel() == 0;
const PicType ePicType = m_pcSliceHeader->getPicType();
const Bool bMbAff = m_pcSliceHeader->isMbAff ();
if( ePicType!=FRAME )
{
RNOK( m_pcOrgResidual->addFieldBuffer ( ePicType ) );
}
else if( bMbAff )
{
RNOK( m_pcOrgResidual->addFrameFieldBuffer() );
}
RNOK( m_pcOrgResidual->subtract( m_pcOrgFrame, m_pcPredSignal ) );
RNOK( m_pcOrgResidual->subtract( m_pcOrgResidual, m_pcBaseLayerSbb ) );
for( UInt uiMbY = 0; uiMbY < m_uiHeightInMB; uiMbY++ )
for( UInt uiMbX = 0; uiMbX < m_uiWidthInMB; uiMbX++ )
{
MbDataAccess* pcMbDataAccessBL = 0;
MbDataAccess* pcMbDataAccessEL = 0;
RNOK( m_pcCurrMbDataCtrl->initMb( pcMbDataAccessBL, uiMbY, uiMbX ) );
RNOK( m_cMbDataCtrlEL .initMb( pcMbDataAccessEL, uiMbY, uiMbX ) );
if( bMbAff )
{
pcMbDataAccessEL->setFieldMode( pcMbDataAccessBL->getMbData().getFieldFlag() );
}
RNOK( pcYuvBufferCtrl ->initMb ( uiMbY, uiMbX, bMbAff ) );
UInt uiMbIndex = uiMbY * m_uiWidthInMB + uiMbX;
MbFGSCoefMap &rcMbFGSCoefMap = m_pcCoefMap[uiMbIndex];
if( pcMbDataAccessBL->getMbData().isIntra16x16() || (rcMbFGSCoefMap.getMbMap() & SIGNIFICANT) )
{
Bool bUseTransformSizeFromRDO = ! ( rcMbFGSCoefMap.getMbMap() & TRANSFORM_SPECIFIED ) && ! pcMbDataAccessBL->getMbData().isIntra();
if( bUseTransformSizeFromRDO )
{
//----- set transform size from RDO (i.e., MbEncoder::encodeFGS()) if possible -----
pcMbDataAccessBL->getMbData().setTransformSize8x8( pcMbDataAccessEL->getMbData().isTransformSize8x8() );
}
//===== requantization =====
RNOK( xRequantizeMacroblock ( *pcMbDataAccessEL, *pcMbDataAccessBL ) );
if( bUseTransformSizeFromRDO && ( pcMbDataAccessEL->getMbData().getMbCbp() & 0x0F ) == 0 )
{
//----- clear transform size flag if no luma samples coded -----
pcMbDataAccessBL->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,
*pcMbDataAccessBL,
rcMbFGSCoefMap,
m_pcOrgResidual->getPic( m_pcSliceHeader->getPicType() ),
m_dLambda,
bLowPass,
m_iMaxQpDelta ) );
pcMbDataAccessEL->getMbData().setResidualPredFlag( bResidualPrediction );
m_pcTransform->setClipMode( true );
}
pcMbDataAccessEL->getMbData().setBCBP(0);
}
if( ePicType!=FRAME )
{
RNOK( m_pcOrgResidual->removeFieldBuffer ( ePicType ) );
}
else if( bMbAff )
{
RNOK( m_pcOrgResidual->removeFrameFieldBuffer() );
}
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;
delete []m_auiMbCbpStored;
delete []m_auiBCBPStored;
delete []m_aiBLQP;
delete []m_abELtransform8x8;
return Err::m_nOK;
}
ErrVal
RQFGSEncoder::xStoreFGSState(UInt iLumaScanIdx,
UInt iChromaDCScanIdx,
UInt iChromaACScanIdx,
UInt iStartCycle,
UInt iCycle,
UInt uiPass,
UInt uiFragIdx,
UInt uiMbYIdx,
UInt uiMbXIdx,
B8x8Idx c8x8Idx,
S4x4Idx cIdx,
UInt iLastBitsLuma,
UInt uiBitsLast,
UInt uiFGSPart,
CPlaneIdx cCPlaneIdx,
Int iLastQP)
{
m_iLumaScanIdx = iLumaScanIdx;
m_iChromaDCScanIdx = iChromaDCScanIdx;
m_iChromaACScanIdx = iChromaACScanIdx;
m_iStartCycle = iStartCycle;
m_iCycle = iCycle;
m_uiPass = uiPass;
m_uiFragIdx = uiFragIdx;
m_uiMbYIdx = uiMbYIdx;
m_uiMbXIdx = uiMbXIdx;
m_c8x8Idx = c8x8Idx;
m_cIdx = cIdx;
m_iLastBitsLuma = iLastBitsLuma;
m_uiBitsLast = uiBitsLast;
m_uiFGSPart = uiFGSPart;
m_cCPlaneIdx = cCPlaneIdx;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -