📄 mbencoder.cpp
字号:
{
if (avcRewriteFlag)
{
m_pcIntMbTempData->setAllSamplesToZero();
m_pcIntMbTempData->setResidualPredFlag( true );
if( m_pcIntMbTempData->getResidualPredFlag( PART_16x16 ) )
{
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
m_pcIntMbTempData->loadBuffer( pcBaseSubband->getFullPelYuvBuffer() );
}
else
{
m_pcIntMbTempData->setAllSamplesToZero();
}
m_pcIntMbTempData ->getTempYuvMbBuffer().loadLuma( *m_pcIntMbTempData );
m_pcIntMbTempData ->setQp( ucQp );
//-- JVT-R091
// note: use intra offset as IntraBL does
if ( bSmoothedRef )
{
m_pcTransform ->setQp( *m_pcIntMbTempData, true );
}
else
{
m_pcTransform ->setQp( *m_pcIntMbTempData, rcMbDataAccess.getSH().isIntra() );
}
//--
//----- 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( !bSmoothedRef && xGetCoeffCost() <= uiB8Thres )
//--
{
m_pcIntMbTempData->loadLuma( m_pcIntMbTempData->getTempYuvMbBuffer(), c8x8Idx );
m_pcIntMbTempData->clearLumaLevels8x8Block( c8x8Idx );
if( avcRewriteFlag && m_pcIntMbTempData->getResidualPredFlag( PART_16x16 ) )
{
TCoeff* pcCoeff = m_pcIntMbTempData->get8x8( c8x8Idx );
UInt uiAbsSum = 0;
RNOK( m_pcTransform->predict8x8Blk( pcCoeff,
m_pcIntMbTempData->getMbDataAccess().getMbDataAccessBase()->getMbTCoeffs().get8x8( c8x8Idx ),
m_pcIntMbTempData->getMbDataAccess().getMbDataAccessBase()->getMbData().getQp(),
uiAbsSum ) );
for( unsigned int i=0; i<64; i++ )
pcCoeff[i] = -pcCoeff[i];
xScale8x8Block( pcCoeff, NULL, m_pcTransform->getLumaQp() );
m_pcTransform->invTransform8x8Blk( m_pcIntMbTempData->getYBlk( c8x8Idx ),
m_pcIntMbTempData->getLStride(), pcCoeff );
m_pcIntMbTempData->clearLumaLevels8x8Block( c8x8Idx );
}
}
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( !bSmoothedRef && xGetCoeffCost() <= uiB8Thres )
//--
{
m_pcIntMbTempData->loadLuma( m_pcIntMbTempData->getTempYuvMbBuffer(), c8x8Idx );
m_pcIntMbTempData->clearLumaLevels8x8( c8x8Idx );
if( avcRewriteFlag && m_pcIntMbTempData->getResidualPredFlag( PART_16x16 ) )
{
for( S4x4Idx cIdx( c8x8Idx ); cIdx.isLegal( c8x8Idx ); cIdx++ )
{
TCoeff* pcCoeff = m_pcIntMbTempData->get( cIdx );
UInt uiAbsSum = 0;
RNOK( m_pcTransform->predict4x4Blk( pcCoeff,
m_pcIntMbTempData->getMbDataAccess().getMbDataAccessBase()->getMbTCoeffs().get( cIdx ),
m_pcIntMbTempData->getMbDataAccess().getMbDataAccessBase()->getMbData().getQp(),
uiAbsSum ) );
for( unsigned int i=0; i<16; i++ )
pcCoeff[i] = -pcCoeff[i];
xScale4x4Block( pcCoeff, NULL, 0, m_pcTransform->getLumaQp() );
m_pcTransform->invTransform4x4Blk( m_pcIntMbTempData->getYBlk( cIdx ),
m_pcIntMbTempData->getLStride(), pcCoeff );
}
m_pcIntMbTempData->clearLumaLevels8x8( c8x8Idx );
}
}
else
{
uiCoeffCost += xGetCoeffCost();
uiExtCbp += uiCbp;
uiMbBits += uiBits;
}
}
}
}
//-- JVT-R091
// note: do not use coefficient skip as IntraBL does
if( !bSmoothedRef && 0 != uiExtCbp && uiCoeffCost <= uiMBThres )
//--
{
m_pcIntMbTempData->loadLuma( m_pcIntMbTempData->getTempYuvMbBuffer() );
uiExtCbp = 0;
m_pcIntMbTempData->clearLumaLevels();
if(avcRewriteFlag && m_pcIntMbTempData->getResidualPredFlag( PART_16x16 ) )
{
for( S4x4Idx cIdx; cIdx.isLegal( ); cIdx++ )
{
TCoeff* pcCoeff = m_pcIntMbTempData->get( cIdx );
UInt uiAbsSum = 0;
RNOK( m_pcTransform->predict4x4Blk( pcCoeff,
m_pcIntMbTempData->getMbDataAccess().getMbDataAccessBase()->getMbTCoeffs().get( cIdx ),
m_pcIntMbTempData->getMbDataAccess().getMbDataAccessBase()->getMbData().getQp(),
uiAbsSum ) );
for( unsigned int i=0; i<16; i++ )
pcCoeff[i] = -pcCoeff[i];
xScale4x4Block( pcCoeff, NULL, 0, m_pcTransform->getLumaQp() );
m_pcTransform->invTransform4x4Blk( m_pcIntMbTempData->getYBlk( cIdx ),
m_pcIntMbTempData->getLStride(), pcCoeff );
}
m_pcIntMbTempData->clearLumaLevels( );
}
}
m_pcIntMbTempData->distY() = m_pcXDistortion->getLum16x16( m_pcIntMbTempData->getMbLumAddr(), m_pcIntMbTempData->getLStride() );
//----- 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;
Bool b8x8Trafo = ( uiTrafo8x8 && ( m_pcIntMbTempData->getMbCbp() & 0x0F ) );
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 || bSmoothedRef || 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().getBaseLayerId() == MSYS_UINT_MAX ? 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 );
//----- set residual prediction flag -----
rcMbDataAccess.getMbData().setResidualPredFlag( iCnt > 0 ? true : ( bPotentialBSkip ? false : bDefaultResPredFlag ) );
//-- JVT-R091
if ( bSmoothedRef )
{
// set flag
rcMbDataAccess.getMbData().setSmoothedRefFlag( true );
}
//--
//>>> fix (skip mode in hierarchical P pictures) - H. Schwarz
bRemovePSkip = bCoefficientsInPSkip;
//<<< fix (skip mode in hierarchical P pictures) - H. Schwarz
}
m_pcIntMbTempData->uninit();
}
}
if (avcRewriteFlag && (dMinCost == 1e30)) // in case, no valide 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 );
//--
}
//>>> 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
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -