mbencoder.cpp
来自「JVT-S203 contains the JSVM 6 reference s」· C++ 代码 · 共 1,628 行 · 第 1/5 页
CPP
1,628 行
//===== residual prediction =====
if( rcMbDataAccess.getSH().getBaseLayerId() != MSYS_UINT_MAX )
{
//--- subtract (upsampled) base layer residual from original macroblock data ---
ROF( pcBaseLayerResidual );
cBaseLayerBuffer .loadBuffer ( const_cast<IntFrame*>(pcBaseLayerResidual)->getFullPelYuvBuffer() );
if( ! cBaseLayerBuffer.isZero() ) // HS: search only with residual prediction, when residual signal is non-zero
{
m_pcIntOrgMbPelData->subtract ( cBaseLayerBuffer );
if( ! pcMbDataAccessBase->getMbData().isIntra() && bBLSkipEnable) // JVT-Q065 EIDR
{
//--- only if base layer is in intra mode ---
// TMM_ESS
if ( pcMbDataAccessBase->getMbData().getInCropWindowFlag() )
RNOK( xEstimateMbBLSkip ( m_pcIntMbTempData, m_pcIntMbBestData, rcRefFrameList0, rcRefFrameList1, pcBaseLayerFrame, bBSlice, iSpatialScalabilityType, pcMbDataAccessBase, true ) );
//-- JVT-R091
if ( pcMbDataAccessBase->getMbData().getInCropWindowFlag() && rcMbDataAccess.isConstrainedInterLayerPred( ) )
RNOK( xEstimateMbSR ( m_pcIntMbTempData, m_pcIntMbBestData, rcRefFrameList0, rcRefFrameList1, pcBaseLayerResidual, pcMbDataAccessBase, true ) );
//--
}
if( rcMbDataAccess.getSH().getAdaptivePredictionFlag() )
{
//S051{
if(m_bUseBDir)
//S051}
RNOK( xEstimateMbDirect ( m_pcIntMbTempData, m_pcIntMbBestData, rcRefFrameList0, rcRefFrameList1, pcMbDataAccessBase, true ) );
RNOK( xEstimateMb16x16 ( m_pcIntMbTempData, m_pcIntMbBestData, rcRefFrameList0, rcRefFrameList1, bBiPredOnly, uiNumMaxIter, uiIterSearchRange, false, pcMbDataAccessBase, true ) );
RNOK( xEstimateMb16x8 ( m_pcIntMbTempData, m_pcIntMbBestData, rcRefFrameList0, rcRefFrameList1, bBiPredOnly, uiNumMaxIter, uiIterSearchRange, false, pcMbDataAccessBase, true ) );
RNOK( xEstimateMb8x16 ( m_pcIntMbTempData, m_pcIntMbBestData, rcRefFrameList0, rcRefFrameList1, bBiPredOnly, uiNumMaxIter, uiIterSearchRange, false, pcMbDataAccessBase, true ) );
RNOK( xEstimateMb8x8 ( m_pcIntMbTempData, m_pcIntMbBestData, rcRefFrameList0, rcRefFrameList1, bBiPredOnly, uiNumMaxIter, uiIterSearchRange, false, pcMbDataAccessBase, true ) );
RNOK( xEstimateMb8x8Frext ( m_pcIntMbTempData, m_pcIntMbBestData, rcRefFrameList0, rcRefFrameList1, bBiPredOnly, uiNumMaxIter, uiIterSearchRange, false, pcMbDataAccessBase, true ) );
}
//--- recover original macroblock data ---
m_pcIntOrgMbPelData->add ( cBaseLayerBuffer );
}
}
//===== intra base layer mode =====
if( rcMbDataAccess.getSH().getBaseLayerId() != MSYS_UINT_MAX )
{
if( pcMbDataAccessBase->getMbData().isIntra() || !rcMbDataAccess.isConstrainedInterLayerPred( ) )
if ( pcMbDataAccessBase->getMbData().getInCropWindowFlag() ) // TMM_ESS
RNOK ( xEstimateMbIntraBL ( m_pcIntMbTempData, m_pcIntMbBestData, pcBaseLayerFrame, bBSlice, pcMbDataAccessBase ) );
}
//===== without residual prediction =====
if( rcMbDataAccess.getSH().getBaseLayerId () == MSYS_UINT_MAX ||
rcMbDataAccess.getSH().getAdaptivePredictionFlag() )
{
if( ( pcMbDataAccessBase && pcMbDataAccessBase->getMbData().isIntra() ) || rcMbDataAccess.getSH().getAdaptivePredictionFlag() )
{
// TMM_ESS
if ( pcMbDataAccessBase->getMbData().getInCropWindowFlag() && bBLSkipEnable) // JVT-Q065 EIDR
RNOK( xEstimateMbBLSkip ( m_pcIntMbTempData, m_pcIntMbBestData, rcRefFrameList0, rcRefFrameList1, pcBaseLayerFrame, bBSlice, iSpatialScalabilityType, pcMbDataAccessBase, bDefaultResPredFlag ) );
}
{
//S051{
if(m_bUseBDir)
//S051}
RNOK ( xEstimateMbDirect ( m_pcIntMbTempData, m_pcIntMbBestData, rcRefFrameList0, rcRefFrameList1, pcMbDataAccessBase, bDefaultResPredFlag ) );
RNOK ( xEstimateMbDirect ( m_pcIntMbTempData, m_pcIntMbBestData, rcRefFrameList0, rcRefFrameList1, pcMbDataAccessBase, false ) ); // skip mode
RNOK ( xEstimateMb16x16 ( m_pcIntMbTempData, m_pcIntMbBestData, rcRefFrameList0, rcRefFrameList1, bBiPredOnly, uiNumMaxIter, uiIterSearchRange, false, pcMbDataAccessBase, bDefaultResPredFlag ) );
RNOK ( xEstimateMb16x8 ( m_pcIntMbTempData, m_pcIntMbBestData, rcRefFrameList0, rcRefFrameList1, bBiPredOnly, uiNumMaxIter, uiIterSearchRange, false, pcMbDataAccessBase, bDefaultResPredFlag ) );
RNOK ( xEstimateMb8x16 ( m_pcIntMbTempData, m_pcIntMbBestData, rcRefFrameList0, rcRefFrameList1, bBiPredOnly, uiNumMaxIter, uiIterSearchRange, false, pcMbDataAccessBase, bDefaultResPredFlag ) );
RNOK ( xEstimateMb8x8 ( m_pcIntMbTempData, m_pcIntMbBestData, rcRefFrameList0, rcRefFrameList1, bBiPredOnly, uiNumMaxIter, uiIterSearchRange, false, pcMbDataAccessBase, bDefaultResPredFlag ) );
RNOK ( xEstimateMb8x8Frext ( m_pcIntMbTempData, m_pcIntMbBestData, rcRefFrameList0, rcRefFrameList1, bBiPredOnly, uiNumMaxIter, uiIterSearchRange, false, pcMbDataAccessBase, bDefaultResPredFlag ) );
}
}
//===== normal intra mode =====
if( rcMbDataAccess.getSH().getBaseLayerId () == MSYS_UINT_MAX ||
rcMbDataAccess.getSH().getAdaptivePredictionFlag() )
{
RNOK ( xEstimateMbIntra16 ( m_pcIntMbTempData, m_pcIntMbBestData, bBSlice ) );
RNOK ( xEstimateMbIntra8 ( m_pcIntMbTempData, m_pcIntMbBestData, bBSlice ) );
RNOK ( xEstimateMbIntra4 ( m_pcIntMbTempData, m_pcIntMbBestData, bBSlice ) );
RNOK ( xEstimateMbPCM ( m_pcIntMbTempData, m_pcIntMbBestData, bBSlice ) );
}
xStoreEstimation( rcMbDataAccess, *m_pcIntMbBestData, NULL, NULL, true, &cBaseLayerBuffer );
//JVT-R057 LA-RDO{
if(m_bLARDOEnable)
{
Int x,y;
MbMode mode=rcMbDataAccess.getMbData().getMbMode();
Bool bInter=rcMbDataAccess.getSH().getBaseLayerId() != MSYS_UINT_MAX;
Int KBlock = m_pcIntPicBuffer->getLWidth()/4;
Int blockX=rcMbDataAccess.getMbX()*4;
Int blockY=rcMbDataAccess.getMbY()*4;
Int ep_ref,ec_rec,ec_ep;
m_pcIntPicBuffer->getYuvBufferCtrl().initMb();
UInt p=1;
UInt q=100;
if(bInter)
{
for(UInt i=0;i<=m_uiLayerID;i++)
{
p=p*(100-m_auiPLR[m_uiLayerID]);
}
q=(UInt)pow(100,(m_uiLayerID+1));
}
else
{
p=100-m_auiPLR[m_uiLayerID];
}
if(mode==INTRA_BL)
{
Int ep_base;
Int blockIndex;
Int xx,yy;
for(y=blockY;y<(blockY+4);y++)
for(x=blockX;x<(blockX+4);x++)
{
if(m_pcFrameEcEp)
ec_ep=m_pcFrameEcEp->getChannelDistortion()[y*KBlock+x];
else
ec_ep=0;
m_pcIntPicBuffer->getYuvBufferCtrl().initMb();
if(m_pcFrameEcEp)
ec_rec=GetEC_REC(m_pcIntPicBuffer,m_pcFrameEcEp->getFullPelYuvBuffer(),x,y);
else
ec_rec=0;
xx=(Int)(x/m_aadRatio[m_uiLayerID][0]);
yy=(Int)(y/m_aadRatio[m_uiLayerID][1]);
blockIndex=yy*(Int)(KBlock/m_aadRatio[m_uiLayerID][0])+xx;
ep_base=const_cast<IntFrame*>(pcBaseLayerFrame)->getChannelDistortion()[blockIndex];
const_cast<IntFrame&>(rcOrigFrame).getChannelDistortion()[y*KBlock+x]=(p*ep_base+(q-p)*(ec_rec+ec_ep))/q;
}
}
else if(mode==MODE_SKIP||mode==MODE_16x16||mode==MODE_16x8||mode==MODE_8x16||mode==MODE_8x8||mode==MODE_8x8ref0)
{
for( Int n = 0; n <16; n++)
{
Int iRefIdx[2];
iRefIdx [0]=rcMbDataAccess.getMbMotionData(LIST_0).getRefIdx(B4x4Idx(n));
iRefIdx [1]=rcMbDataAccess.getMbMotionData(LIST_1).getRefIdx(B4x4Idx(n));
IntFrame* pcRefFrame0 = ( iRefIdx [0] > 0 ? rcRefFrameList0[ iRefIdx [0] ] : NULL );
IntFrame* pcRefFrame1 = ( iRefIdx [1] > 0 ? rcRefFrameList1[ iRefIdx [1] ] : NULL );
Int iMvX;
Int iMvY;
Int iDLIST0=0,iDLIST1=0;
if(pcRefFrame0)
{
iMvX=rcMbDataAccess.getMbMotionData(LIST_0).getMv(B4x4Idx(n)).getHor();
iMvY=rcMbDataAccess.getMbMotionData(LIST_0).getMv(B4x4Idx(n)).getVer();
getChannelDistortion(rcMbDataAccess,*pcRefFrame0,&iDLIST0,iMvX,iMvY,n%4,n/4,1,1);
}
if(pcRefFrame1)
{
iMvX=rcMbDataAccess.getMbMotionData(LIST_1).getMv(B4x4Idx(n)).getHor();
iMvY=rcMbDataAccess.getMbMotionData(LIST_1).getMv(B4x4Idx(n)).getVer();
getChannelDistortion(rcMbDataAccess,*pcRefFrame1,&iDLIST1,iMvX,iMvY,n%4,n/4,1,1);
iDLIST0=(iDLIST0+iDLIST1)/2;
}
ep_ref=iDLIST0;
x=blockX+n%4;
y=blockY+n/4;
if(m_pcFrameEcEp)
ec_ep=m_pcFrameEcEp->getChannelDistortion()[y*KBlock+x];
else
ec_ep=0;
m_pcIntPicBuffer->getYuvBufferCtrl().initMb();
if(m_pcFrameEcEp)
ec_rec=GetEC_REC(m_pcIntPicBuffer,m_pcFrameEcEp->getFullPelYuvBuffer(),x,y);
else
ec_rec=0;
const_cast<IntFrame&>(rcOrigFrame).getChannelDistortion()[y*KBlock+x]=(p*ep_ref+(q-p)*(ec_rec+ec_ep))/q;
}
}
else
{
for(y=blockY;y<(blockY+4);y++)
for(x=blockX;x<(blockX+4);x++)
{
if(m_pcFrameEcEp)
ec_ep=m_pcFrameEcEp->getChannelDistortion()[y*KBlock+x];
else
ec_ep=0;
m_pcIntPicBuffer->getYuvBufferCtrl().initMb();
if(m_pcFrameEcEp)
ec_rec=GetEC_REC(m_pcIntPicBuffer,m_pcFrameEcEp->getFullPelYuvBuffer(),x,y);
else
ec_rec=0;
const_cast<IntFrame&>(rcOrigFrame).getChannelDistortion()[y*KBlock+x]=(q-p)*(ec_rec+ec_ep)/q;
}
}
}
//JVT-R057 LA-RDO}
m_pcIntMbBestData ->uninit();
m_pcIntMbTempData ->uninit();
m_pcIntMbBest8x8Data->uninit();
m_pcIntMbTemp8x8Data->uninit();
return Err::m_nOK;
}
ErrVal MbEncoder::encodeFGS( MbDataAccess& rcMbDataAccess,
MbDataAccess* pcMbDataAccessBase,
RefFrameList& rcRefFrameList0,
RefFrameList& rcRefFrameList1,
const IntFrame& rcOrigFrame,
IntFrame* pcPredSignal,
IntFrame* pcBQPredSignal,
RefFrameList* pcRefFrameListDiff,
FGSCoder* pcFGSCoder,
IntYuvMbBuffer& rcBaseLayerBuffer,
UInt uiNumMaxIter,
UInt uiIterSearchRange,
Double dLambda,
Int iMaxQpDelta )
{
ROF( bInitDone );
Bool bLowPass = pcMbDataAccessBase->getSH().getTemporalLevel() == 0;
Bool bIntra = pcMbDataAccessBase->getMbData().isIntra();
UInt uiQp = rcMbDataAccess.getSH().getPicQp();
RNOK( m_pcRateDistortionIf->setMbQpLambda( rcMbDataAccess, uiQp, dLambda ) );
m_pcIntMbBestIntraChroma = NULL;
m_pcIntMbBestData ->init( rcMbDataAccess );
m_pcIntMbTempData ->init( rcMbDataAccess );
m_pcIntMbBest8x8Data->init( rcMbDataAccess );
m_pcIntMbTemp8x8Data->init( rcMbDataAccess );
m_pcIntPicBuffer = NULL;
IntYuvPicBuffer* pcOrgPicBuffer = const_cast<IntFrame&>( rcOrigFrame ).getFullPelYuvBuffer();
m_pcXDistortion->loadOrgMbPelData ( pcOrgPicBuffer, m_pcIntOrgMbPelData );
m_pcTransform ->setQp ( rcMbDataAccess, bLowPass || bIntra );
ROT( bIntra );
m_pcTransform->setClipMode( false );
if( ! rcBaseLayerBuffer.isZero() )
{
// residual prediction
m_pcIntOrgMbPelData->subtract( rcBaseLayerBuffer );
RNOK ( xEstimateMbDirect ( m_pcIntMbTempData, m_pcIntMbBestData, rcRefFrameList0, rcRefFrameList1, pcMbDataAccessBase, true ) );
RNOK ( xEstimateMb16x16 ( m_pcIntMbTempData, m_pcIntMbBestData, rcRefFrameList0, rcRefFrameList1, false, uiNumMaxIter, uiIterSearchRange, false, pcMbDataAccessBase, true ) );
RNOK ( xEstimateMb16x8 ( m_pcIntMbTempData, m_pcIntMbBestData, rcRefFrameList0, rcRefFrameList1, false, uiNumMaxIter, uiIterSearchRange, false, pcMbDataAccessBase, true ) );
RNOK ( xEstimateMb8x16 ( m_pcIntMbTempData, m_pcIntMbBestData, rcRefFrameList0, rcRefFrameList1, false, uiNumMaxIter, uiIterSearchRange, false, pcMbDataAccessBase, true ) );
RNOK ( xEstimateMb8x8 ( m_pcIntMbTempData, m_pcIntMbBestData, rcRefFrameList0, rcRefFrameList1, false, uiNumMaxIter, uiIterSearchRange, false, pcMbDataAccessBase, true ) );
RNOK ( xEstimateMb8x8Frext ( m_pcIntMbTempData, m_pcIntMbBestData, rcRefFrameList0, rcRefFrameList1, false, uiNumMaxIter, uiIterSearchRange, false, pcMbDataAccessBase, true ) );
m_pcIntOrgMbPelData->add ( rcBaseLayerBuffer );
}
RNOK ( xEstimateMbDirect ( m_pcIntMbTempData, m_pcIntMbBestData, rcRefFrameList0, rcRefFrameList1, pcMbDataAccessBase, false ) );
RNOK ( xEstimateMb16x16 ( m_pcIntMbTempData, m_pcIntMbBestData, rcRefFrameList0, rcRefFrameList1, false, uiNumMaxIter, uiIterSearchRange, false, pcMbDataAccessBase, false ) );
RNOK ( xEstimateMb16x8 ( m_pcIntMbTempData, m_pcIntMbBestData, rcRefFrameList0, rcRefFrameList1, false, uiNumMaxIter, uiIterSearchRange, false, pcMbDataAccessBase, false ) );
RNOK ( xEstimateMb8x16 ( m_pcIntMbTempData, m_pcIntMbBestData, rcRefFrameList0, rcRefFrameList1, false, uiNumMaxIter, uiIterSearchRange, false, pcMbDataAccessBase, false ) );
RNOK ( xEstimateMb8x8 ( m_pcIntMbTempData, m_pcIntMbBestData, rcRefFrameList0, rcRefFrameList1, false, uiNumMaxIter, uiIterSearchRange, false, pcMbDataAccessBase, false ) );
RNOK ( xEstimateMb8x8Frext ( m_pcIntMbTempData, m_pcIntMbBestData, rcRefFrameList0, rcRefFrameList1, false, uiNumMaxIter, uiIterSearchRange, false, pcMbDataAccessBase, false ) );
if( rcMbDataAccess.getSH().getArFgsUsageFlag() )
{
//----- adaptive-reference motion compensation (AR-FGS) -----
ROF( pcBQPredSignal );
if( m_pcIntMbBestData->getResidualPredFlag( PART_16x16 ) )
m_pcIntOrgMbPelData->subtract( rcBaseLayerBuffer );
m_pcIntMbBestData->loadBuffer( pcBQPredSignal->getFullPelYuvBuffer() );
RNOK( m_pcMotionEstimation->adaptiveMotionCompensationMb( m_pcIntMbBestData,
pcRefFrameListDiff,
&m_pcIntMbBestData->getMbDataAccess(),
pcFGSCoder ) );
if( m_pcIntMbBestData->isTransformSize8x8() )
{
RNOK( xSetRdCost8x8InterMb( *m_pcIntMbBestData, pcMbDataAccessBase, rcRefFrameList0, rcRefFrameList1, false, 0, true ) );
}
else
{
RNOK( xSetRdCostInterMb( *m_pcIntMbBestData, pcMbDataAccessBase, rcRefFrameList0, rcRefFrameList1, false, 0, true ) );
}
if( m_pcIntMbBestData->getResidualPredFlag( PART_16x16 ) )
m_pcIntOrgMbPelData->add( rcBaseLayerBuffer );
}
RNOK ( xEstimateMbFGSSkip ( m_pcIntMbTempData, m_pcIntMbBestData, rcRefFrameList0, rcRefFrameList1, pcMbDataAccessBase, rcBaseLayerBuffer, pcPredSignal, iMaxQpDelta ) );
m_pcTransform->setClipMode( true );
xStoreEstimation( rcMbDataAccess, *m_pcIntMbBestData, NULL, m_pcIntMbBestData->getBLSkipFlag() ? NULL : pcPredSignal, false, &rcBaseLayerBuffer );
m_pcIntMbBestData ->uninit();
m_pcIntMbTempData ->uninit();
m_pcIntMbBest8x8Data->uninit();
m_pcIntMbTemp8x8Data->uninit();
return Err::m_nOK;
}
ErrVal
MbEncoder::compensatePrediction( MbDataAccess& rcMbDataAccess,
IntFrame* pcMCFrame,
RefFrameList& rcRefFrameList0,
RefFrameList& rcRefFrameList1,
Bool bCalcMv,
Bool bFaultTolerant )
{
IntYuvMbBuffer cYuvMbBuffer;
if
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?