📄 mbencoder.cpp
字号:
{
for( UInt uiTrafo8x8 = uiMinTrafo; uiTrafo8x8 < uiMaxTrafo; uiTrafo8x8++ )
{
m_pcIntMbTempData ->init( rcMbDataAccess );
if( iCnt )
{
if( avcRewriteFlag )
{
cBaseResMbBuffer.setAllSamplesToZero();
}
else if( coeffResidualPredFlag )
{
m_pcIntMbTempData->getMbDataAccess().getMbDataAccessBase()->getMbTCoeffs().copyPredictionTo( cBaseResMbBuffer );
}
else
{
cBaseResMbBuffer.loadBuffer( pcBaseSubband->getFullPelYuvBuffer() );
}
if (avcRewriteFlag || coeffResidualPredFlag)
{
m_pcIntMbTempData->setResidualPredFlag( true );
if( m_pcIntMbTempData->getResidualPredFlag() )
{
Bool bBaseTransSize8x8 = m_pcIntMbTempData->getMbDataAccess().getMbDataAccessBase()->getMbData().isTransformSize8x8();
UInt uiBaseCbp = m_pcIntMbTempData->getMbDataAccess().getMbDataAccessBase()->getMbData().getMbCbp();
// Enforce restrictions on transforms size between layers
if( uiTrafo8x8==0 && bBaseTransSize8x8 )
uiTrafo8x8++;
if( uiTrafo8x8==1 && !bBaseTransSize8x8 && uiBaseCbp)
break;
}
}
}
else
{
cBaseResMbBuffer.setAllSamplesToZero();
}
m_pcIntMbTempData->loadLuma ( cBaseResMbBuffer );
m_pcIntMbTempData->loadChroma ( cBaseResMbBuffer );
m_pcIntMbTempData ->getTempYuvMbBuffer().loadLuma ( *m_pcIntMbTempData );
m_pcIntMbTempData ->getTempYuvMbBuffer().loadChroma ( *m_pcIntMbTempData );
m_pcIntMbTempData ->setQp( ucQp );
m_pcTransform ->setQp( *m_pcIntMbTempData, rcMbDataAccess.getSH().isIntraSlice() );
//----- encode luminance signal -----
UInt uiExtCbp = 0;
UInt uiCoeffCost = 0;
UInt uiMbBits = 0;
UInt uiB8Thres = 4;
UInt uiMBThres = 5;
if( uiTrafo8x8 )
{
for( B8x8Idx c8x8Idx; c8x8Idx.isLegal(); c8x8Idx++ )
{
xSetCoeffCost( 0 );
UInt uiBits = 0;
UInt uiCbp = 0;
RNOK( xEncode8x8InterBlock( *m_pcIntMbTempData, c8x8Idx, uiBits, uiCbp ) );
if( uiCbp )
{
//-- JVT-R091
// note: do not use coefficient skip as IntraBL does
if( xGetCoeffCost() <= uiB8Thres )
//--
{
m_pcIntMbTempData->loadLuma( m_pcIntMbTempData->getTempYuvMbBuffer(), c8x8Idx );
m_pcIntMbTempData->clearLumaLevels8x8Block( c8x8Idx );
if( coeffResidualPredFlag && m_pcIntMbTempData->getResidualPredFlag() )
{
reCalcBlock8x8(*m_pcIntMbTempData, c8x8Idx, 0);
}
else if( avcRewriteFlag && m_pcIntMbTempData->getResidualPredFlag() )
{
reCalcBlock8x8Rewrite(*m_pcIntMbTempData, c8x8Idx, 0);
}
}
else
{
uiCoeffCost += xGetCoeffCost();
uiExtCbp += uiCbp;
uiMbBits += uiBits;
}
}
}
}
else
{
for( B8x8Idx c8x8Idx; c8x8Idx.isLegal(); c8x8Idx++ )
{
xSetCoeffCost( 0 );
UInt uiBits = 0;
UInt uiCbp = 0;
for( S4x4Idx cIdx( c8x8Idx ); cIdx.isLegal( c8x8Idx ); cIdx++ )
{
RNOK( xEncode4x4InterBlock( *m_pcIntMbTempData, cIdx, uiBits, uiCbp ) );
}
if( uiCbp )
{
//-- JVT-R091
// note: do not use coefficient skip as IntraBL does
if( xGetCoeffCost() <= uiB8Thres )
//--
{
m_pcIntMbTempData->loadLuma( m_pcIntMbTempData->getTempYuvMbBuffer(), c8x8Idx );
m_pcIntMbTempData->clearLumaLevels8x8( c8x8Idx );
if( coeffResidualPredFlag && m_pcIntMbTempData->getResidualPredFlag() )
{
reCalcBlock8x8(*m_pcIntMbTempData, c8x8Idx, 1);
}
else if( avcRewriteFlag && m_pcIntMbTempData->getResidualPredFlag() )
{
reCalcBlock8x8Rewrite(*m_pcIntMbTempData, c8x8Idx, 1);
}
}
else
{
uiCoeffCost += xGetCoeffCost();
uiExtCbp += uiCbp;
uiMbBits += uiBits;
}
}
}
}
//-- JVT-R091
// note: do not use coefficient skip as IntraBL does
if( 0 != uiExtCbp && uiCoeffCost <= uiMBThres )
//--
{
m_pcIntMbTempData->loadLuma( m_pcIntMbTempData->getTempYuvMbBuffer() );
uiExtCbp = 0;
m_pcIntMbTempData->clearLumaLevels();
if( coeffResidualPredFlag && m_pcIntMbTempData->getResidualPredFlag() )
{
Bool bBaseTransSize8x8 = m_pcIntMbTempData->getMbDataAccess().getMbDataAccessBase()->getMbData().isTransformSize8x8();
for( B8x8Idx c8x8Idx; c8x8Idx.isLegal(); c8x8Idx++ )
{
reCalcBlock8x8(*m_pcIntMbTempData, c8x8Idx, !bBaseTransSize8x8);
}
}
else if(avcRewriteFlag && m_pcIntMbTempData->getResidualPredFlag() )
{
Bool bBaseTransSize8x8 = m_pcIntMbTempData->getMbDataAccess().getMbDataAccessBase()->getMbData().isTransformSize8x8();
for( B8x8Idx c8x8Idx; c8x8Idx.isLegal(); c8x8Idx++ )
{
reCalcBlock8x8Rewrite(*m_pcIntMbTempData, c8x8Idx, !bBaseTransSize8x8);
}
}
}
//----- encode chrominance signal -----
RNOK( xEncodeChromaTexture( *m_pcIntMbTempData, uiExtCbp, uiMbBits ) );
//----- set parameters ----
bCoded = ( uiExtCbp > 0 );
m_pcIntMbTempData->bits() = uiMbBits;
m_pcIntMbTempData->cbp() = xCalcMbCbp( uiExtCbp );
m_pcIntMbTempData->coeffCost() = uiCoeffCost;
RNOK( xCheckSkipSliceMb( *m_pcIntMbTempData ) );
RNOK( xAdjustRewriteReconstruction( *m_pcIntMbTempData ) );
MbDataAccess* pcMbDataAccessBase = rcMbDataAccess.getMbDataAccessBase();
if(!pcMbDataAccessBase||pcMbDataAccessBase->getMbData().getSafeResPred()||m_pcIntMbTempData->getResidualPredFlag()==false)
m_pcIntMbTempData->distY() = m_pcXDistortion->getLum16x16( m_pcIntMbTempData->getMbLumAddr(), m_pcIntMbTempData->getLStride() );
else
m_pcIntMbTempData->distY() = m_pcXDistortion->getLum16x16RP( m_pcIntMbTempData->getMbLumAddr(), m_pcIntMbTempData->getLStride() );
Bool bCoeffsPresent = ( ( m_pcIntMbTempData->getMbCbp() & 0x0F ) != 0 );
Bool bBaseIs8x8 = ( m_pcIntMbTempData->getResidualPredFlag() && m_pcIntMbTempData->getMbDataAccess().getMbDataAccessBase()->getMbData().isTransformSize8x8() );
Bool b8x8Trafo = ( ( uiTrafo8x8 ) && ( bCoeffsPresent || bBaseIs8x8 ) );
m_pcIntMbTempData ->setTransformSize8x8( b8x8Trafo );
//----- fix QP ------
RNOK( m_pcRateDistortionIf->fixMacroblockQP( *m_pcIntMbTempData ) );
//--- set parameters ---
uiDist = m_pcIntMbTempData->distY ();
uiDist += m_pcXDistortion ->get8x8Cb ( m_pcIntMbTempData->getMbCbAddr (), m_pcIntMbTempData->getCStride() );
uiDist += m_pcXDistortion ->get8x8Cr ( m_pcIntMbTempData->getMbCrAddr (), m_pcIntMbTempData->getCStride() );
RNOK( BitCounter::init() );
RNOK( MbCoder::m_pcMbSymbolWriteIf->cbp( *m_pcIntMbTempData ) );
if( m_pcIntMbTempData->cbp() )
{
RNOK( MbCoder::m_pcMbSymbolWriteIf->deltaQp( *m_pcIntMbTempData ) );
}
uiRate = uiMbBits + BitCounter::getNumberOfWrittenBits();
//>>> fix (skip mode in hierarchical P pictures) - H. Schwarz
Bool bCoefficientsInPSkip = false;
if( rcMbDataAccess.getSH().getSliceType() == P_SLICE &&
rcMbDataAccess.getMbData().getMbMode() == MODE_SKIP &&
( uiExtCbp != 0 || iCnt != 0 ) )
{
// temporarily convert SKIP mode into 16x16 mode
Mv cMvPred, cMvd;
rcMbDataAccess.getMvPredictor( cMvPred, 1, LIST_0 );
cMvd = rcMbDataAccess.getMbMotionData( LIST_0 ).getMv();
cMvd -= cMvPred;
rcMbDataAccess.getMbMvdData( LIST_0 ).setAllMv( cMvd );
rcMbDataAccess.getMbData().setMbMode( MODE_16x16 );
RNOK( BitCounter::init() );
RNOK( MbCoder::m_pcMbSymbolWriteIf->mbMode( rcMbDataAccess ) );
RNOK( MbCoder::xWriteReferenceFrames ( rcMbDataAccess, MODE_16x16, LIST_0 ) );
RNOK( MbCoder::xWriteMotionPredFlags ( rcMbDataAccess, MODE_16x16, LIST_0 ) );
RNOK( MbCoder::xWriteMotionVectors ( rcMbDataAccess, MODE_16x16, LIST_0 ) );
uiRate += BitCounter::getNumberOfWrittenBits();
// reset original SKIP mode
rcMbDataAccess.getMbMvdData( LIST_0 ).setAllMv( Mv::m_cMvZero );
rcMbDataAccess.getMbData().setMbMode( MODE_SKIP );
// set flag
bCoefficientsInPSkip = true;
}
//<<< fix (skip mode in hierarchical P pictures) - H. Schwarz
bPotentialBSkip = false;
if( rcMbDataAccess.getSH().getSliceType() == B_SLICE &&
rcMbDataAccess.getMbData().getMbMode() == MODE_SKIP &&
iCnt == 0 /* no residual prediction */ && uiExtCbp == 0 )
{
uiRate = ( rcMbDataAccess.getSH().getNoInterLayerPredFlag() ? 1 : 0 );
bPotentialBSkip = true;
}
dCost = (Double)uiDist + dLambda * (Double)uiRate;
// QP changed by fixMacroblockQP(), this will cause mismatch when avcRewrite enabled, so do not choose this mode for now
// TODO: need to redo the prediction using the new QP
if (avcRewriteFlag && m_pcIntMbTempData->getQp() != ucQp)
dCost= 1e30;
if( dCost < dMinCost )
{
dMinCost = dCost;
rbCoded = bCoded;
//----- store parameters and reconstructed signal to Frame and MbDataAccess -----
m_pcIntPicBuffer ->loadBuffer ( m_pcIntMbTempData );
pcResidual->getFullPelYuvBuffer() ->loadBuffer ( m_pcIntMbTempData );
m_pcIntMbTempData ->copyResidualDataTo( rcMbDataAccess );
//----- store "base layer" residual prediction signal ----
if( iCnt > 0 )
{
rcMbDataAccess.getMbTCoeffs().copyPredictionFrom( cBaseResMbBuffer );
}
else
{
rcMbDataAccess.getMbTCoeffs().clearPrediction();
}
//----- set residual prediction flag -----
rcMbDataAccess.getMbData().setResidualPredFlag( iCnt > 0 ? true : ( bPotentialBSkip ? false : bDefaultResPredFlag ) );
//>>> fix (skip mode in hierarchical P pictures) - H. Schwarz
bRemovePSkip = bCoefficientsInPSkip;
//<<< fix (skip mode in hierarchical P pictures) - H. Schwarz
// JVT-W043 {
bestuiDist = uiDist;
// JVT-W043 }
}
m_pcIntMbTempData->uninit();
}
}
if (avcRewriteFlag && (dMinCost == 1e30)) // in case, no valid mode is chosen due to we disallow the mode whose QP is changed by fixMacroblockQP()
{
// in rare case, no mode is selected, assign the last mode it
fprintf(stderr, "no mode is selected at poc %d, MB(%d, %d)", rcMbDataAccess.getSH().getPoc(), rcMbDataAccess.getMbY(), rcMbDataAccess.getMbX());
dMinCost = dCost;
rbCoded = bCoded;
//----- store parameters and reconstructed signal to Frame and MbDataAccess -----
m_pcIntPicBuffer ->loadBuffer ( m_pcIntMbTempData );
pcResidual->getFullPelYuvBuffer() ->loadBuffer ( m_pcIntMbTempData );
m_pcIntMbTempData ->copyResidualDataTo( rcMbDataAccess );
//----- set residual prediction flag -----
rcMbDataAccess.getMbData().setResidualPredFlag( iCnt > 0 ? true : ( bPotentialBSkip ? false : bDefaultResPredFlag ) );
}
//-- JVT-R091
// restore original residual
m_pcIntOrgMbPelData->loadLuma ( cOrgMbBuffer );
m_pcIntOrgMbPelData->loadChroma ( cOrgMbBuffer );
//--
}
rcMbDataAccess.getMbData().setQp4LF( rcMbDataAccess.getMbData().getQp() );
//>>> fix (skip mode in hierarchical P pictures) - H. Schwarz
if( bRemovePSkip )
{
// convert SKIP mode into 16x16 mode
Mv cMvPred, cMvd;
rcMbDataAccess.getMvPredictor( cMvPred, 1, LIST_0 );
cMvd = rcMbDataAccess.getMbMotionData( LIST_0 ).getMv();
cMvd -= cMvPred;
rcMbDataAccess.getMbMvdData( LIST_0 ).setAllMv( cMvd );
rcMbDataAccess.getMbData().setMbMode( MODE_16x16 );
}
//<<< fix (skip mode in hierarchical P pictures) - H. Schwarz
// JVT-W043 {
if ( bRateControlEnable && !pcJSVMParams->m_uiLayerId )
{
pcJSVMParams->CurrGopLevel = pcGenericRC->getCurrGopLevel( pcGenericRC->m_pcJSVMParams->current_frame_number );
pcGenericRC->update_rc( bestuiDist );
}
// JVT-W043 }
return Err::m_nOK;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -