📄 mbencoder.cpp
字号:
return Err::m_nOK;
}
ErrVal
MbEncoder::encodeResidual( MbDataAccess& rcMbDataAccess,
MbDataAccess& rcMbDataAccessBL,
MbFGSCoefMap& rcMbFGSCoefMap,
IntFrame* pcResidual,
Double dLambda,
Bool bLowPass,
Int iMaxQpDelta )
{
ROF( bInitDone );
m_pcIntPicBuffer = pcResidual->getFullPelYuvBuffer();
Bool bIntra16x16 = rcMbDataAccessBL.getMbData().isIntra16x16 ();
Bool bIntra8x8 = rcMbDataAccessBL.getMbData().isIntra4x4 () && rcMbDataAccessBL.getMbData().isTransformSize8x8();
Bool bIntra4x4 = rcMbDataAccessBL.getMbData().isIntra4x4 () && !rcMbDataAccessBL.getMbData().isTransformSize8x8();
Bool bIntra = ( bIntra16x16 || bIntra8x8 || bIntra4x4 );
Bool bInter = ! bIntra;
// TMM_INTERLACE
Bool b8x8Ok = rcMbDataAccessBL.getSH().getPPS().getTransform8x8ModeFlag() && ( bInter ? rcMbDataAccess.getMbData().is8x8TrafoFlagPresent(rcMbDataAccess.getSH().getSPS().getDirect8x8InferenceFlag()) : rcMbDataAccessBL.getMbData().is8x8TrafoFlagPresent(rcMbDataAccessBL.getSH().getSPS().getDirect8x8InferenceFlag() ) );
UChar ucMinQp = (UChar)min( MAX_QP, max( MIN_QP, rcMbDataAccess.getMbData().getQp() - iMaxQpDelta ) );
UChar ucMaxQp = (UChar)min( MAX_QP, max( MIN_QP, rcMbDataAccess.getMbData().getQp() + iMaxQpDelta ) );
UInt uiMinTrafo = ( bIntra8x8 ? 1 : 0 );
UInt uiMaxTrafo = ( bIntra8x8 || (bInter && b8x8Ok) ? 2 : 1 );
Double dMinCost = 1e30;
UInt uiDist, uiRate;
Double dCost;
MbFGSCoefMap cMbFGSCoefMap1, *pcMbFGSCoefMapCurr = &cMbFGSCoefMap1;
MbFGSCoefMap cMbFGSCoefMap2, *pcMbFGSCoefMapBest = &cMbFGSCoefMap2;
Bool bBestTrafoIs8x8;
const PicType eMbPicType = rcMbDataAccess.getMbPicType();
m_pcIntPicBuffer = pcResidual->getPic( eMbPicType )->getFullPelYuvBuffer();
m_pcXDistortion->loadOrgMbPelData( m_pcIntPicBuffer, m_pcIntOrgMbPelData );
for( UChar ucQp = ucMinQp; ucQp <= ucMaxQp; ucQp++ )
{
for( UInt uiTrafo8x8 = uiMinTrafo; uiTrafo8x8 < uiMaxTrafo; uiTrafo8x8++ )
{
m_pcIntMbTempData ->init( rcMbDataAccess );
m_pcIntMbTempData ->setAllSamplesToZero();
m_pcIntMbTempData ->getTempYuvMbBuffer().loadLuma( *m_pcIntMbTempData );
m_pcIntMbTempData ->setQp( ucQp );
m_pcTransform ->setQp( *m_pcIntMbTempData, bLowPass || bIntra );
//----- encode luminance signal -----
UInt uiExtCbp = 0;
UInt uiCoeffCost = 0;
UInt uiMbBits = 0;
UInt uiB8Thres = 4;
UInt uiMBThres = 5;
// initialize with values coming from outside
*pcMbFGSCoefMapCurr = rcMbFGSCoefMap;
if( uiTrafo8x8 == 2 )
{
AF();
//===== 16x16 trafo =====
RNOK( xEncode16x16ResidualMB( *m_pcIntMbTempData, uiMbBits, uiExtCbp ) );
uiCoeffCost = 1000;
}
else if( uiTrafo8x8 )
{
for( B8x8Idx c8x8Idx; c8x8Idx.isLegal(); c8x8Idx++ )
{
xSetCoeffCost( 0 );
UInt uiBits = 0;
UInt uiCbp = 0;
RNOK( xEncode8x8InterBlock( *m_pcIntMbTempData, c8x8Idx, uiBits, uiCbp, pcMbFGSCoefMapCurr->getRefCtx( c8x8Idx ) ) );
if( uiCbp )
{
if( xGetCoeffCost() <= uiB8Thres && ! rcMbDataAccess.getSH().isIntra() && ! bLowPass && ! bIntra )
{
m_pcIntMbTempData->loadLuma( m_pcIntMbTempData->getTempYuvMbBuffer(), c8x8Idx );
m_pcIntMbTempData->clearLumaLevels8x8Block( c8x8Idx, pcMbFGSCoefMapCurr );
}
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, pcMbFGSCoefMapCurr->getRefCtx( cIdx ) ) );
}
if( uiCbp )
{
if( xGetCoeffCost() <= uiB8Thres && ! rcMbDataAccess.getSH().isIntra() && ! bLowPass && ! bIntra )
{
m_pcIntMbTempData->loadLuma( m_pcIntMbTempData->getTempYuvMbBuffer(), c8x8Idx );
m_pcIntMbTempData->clearLumaLevels8x8( c8x8Idx, pcMbFGSCoefMapCurr );
}
else
{
uiCoeffCost += xGetCoeffCost();
uiExtCbp += uiCbp;
uiMbBits += uiBits;
}
}
}
}
if( 0 != uiExtCbp && uiCoeffCost <= uiMBThres && ! rcMbDataAccess.getSH().isIntra() && ! bLowPass && ! bIntra )
{
m_pcIntMbTempData->loadLuma( m_pcIntMbTempData->getTempYuvMbBuffer() );
uiExtCbp = 0;
m_pcIntMbTempData->clearLumaLevels( pcMbFGSCoefMapCurr );
}
m_pcIntMbTempData->distY() = m_pcXDistortion->getLum16x16( m_pcIntMbTempData->getMbLumAddr(), m_pcIntMbTempData->getLStride() );
//----- encode chrominance signal -----
RNOK( xEncodeChromaTexture( *m_pcIntMbTempData, uiExtCbp, uiMbBits, pcMbFGSCoefMapCurr ) );
//----- set parameters ----
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();
dCost = (Double)uiDist + dLambda * (Double)uiRate;
if( dCost < dMinCost )
{
MbFGSCoefMap* switchTemp2 = pcMbFGSCoefMapCurr;
pcMbFGSCoefMapCurr = pcMbFGSCoefMapBest;
pcMbFGSCoefMapBest = switchTemp2;
bBestTrafoIs8x8 = uiTrafo8x8 == 1;
dMinCost = dCost;
//----- store parameters to MbDataAccess -----
m_pcIntMbTempData->copyResidualDataTo( rcMbDataAccess );
}
m_pcIntMbTempData->uninit();
}
}
rcMbFGSCoefMap = *pcMbFGSCoefMapBest;
return Err::m_nOK;
}
ErrVal
MbEncoder::estimatePrediction( MbDataAccess& rcMbDataAccess,
MbDataAccess* pcMbDataAccessBase,
Int iSpatialScalabilityType,
RefFrameList& rcRefFrameList0,
RefFrameList& rcRefFrameList1,
const IntFrame* pcBaseLayerFrame,
const IntFrame* pcBaseLayerResidual,
const IntFrame& rcOrigFrame,
IntFrame& rcIntraRecFrame,
Bool bBiPredOnly,
UInt uiNumMaxIter,
UInt uiIterSearchRange,
Bool bBLSkipEnable, // JVT-Q065 EIDR
Double dLambda,
Double& rdCost,
Bool bSkipModeAllowed )
{
ROF( bInitDone );
rcMbDataAccess.setMbDataAccessBase(pcMbDataAccessBase);
Bool bBSlice = rcMbDataAccess.getSH().getSliceType () == B_SLICE;
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 = rcIntraRecFrame.getFullPelYuvBuffer();
IntYuvPicBuffer* pcOrgPicBuffer = const_cast<IntFrame&>( rcOrigFrame ).getFullPelYuvBuffer();
m_pcXDistortion->loadOrgMbPelData ( pcOrgPicBuffer, m_pcIntOrgMbPelData );
m_pcTransform ->setQp ( rcMbDataAccess, false );
IntYuvMbBuffer cBaseLayerBuffer;
Bool bBaseLayerAvailable = (NULL != pcMbDataAccessBase) && (rcMbDataAccess.getSH().getBaseLayerId() != MSYS_UINT_MAX);
Bool bIntraEnable = ! rcMbDataAccess.isFieldMbInMbaffFrame() || rcMbDataAccess.isTopMb() || rcMbDataAccess.getMbDataComplementary().isIntra();
Bool bInterEnable = ! rcMbDataAccess.isFieldMbInMbaffFrame() || rcMbDataAccess.isTopMb() || ! rcMbDataAccess.getMbDataComplementary().isIntra();
//-- JVT-T037
Bool b = false;
if ( rcMbDataAccess.isFieldMbInMbaffFrame() && rcMbDataAccess.getMbPicType() == BOT_FIELD && rcMbDataAccess.getMbDataComplementary().isIntra() )
{
if ( pcMbDataAccessBase )
{
if (!pcMbDataAccessBase->getMbData().isIntra() || !pcMbDataAccessBase->getMbDataComplementary().isIntra() )
{
b = true;
}
}
}
bInterEnable |= b;
//--
Bool avcRewriteFlag = rcMbDataAccess.getSH().getAVCRewriteFlag();
Bool bDefaultResPredFlag = false;
if( rcMbDataAccess.getSH().getPPS().getEntropyCodingModeFlag() &&
rcMbDataAccess.getSH().getBaseLayerId() != MSYS_UINT_MAX )
{
ROF( pcBaseLayerResidual );
cBaseLayerBuffer.loadBuffer ( const_cast<IntFrame*>(pcBaseLayerResidual)->getFullPelYuvBuffer() );
if (!avcRewriteFlag)
bDefaultResPredFlag = cBaseLayerBuffer.isZero();
}
//>>> fix (skip mode in hierarchical P pictures) - H. Schwarz
if( ! rcMbDataAccess.getSH().isMbAff() ) // don't know why, but it doesn't work for MbAff (when there is a layer on top of it)
// looks like the problem lies somewhere else ... may be in intra padding process before upsampling
if( bSkipModeAllowed && ! bBSlice )
{
RNOK( xEstimateMbSkip( m_pcIntMbTempData, m_pcIntMbBestData, rcRefFrameList0, rcRefFrameList1 ) );
}
//<<< fix (skip mode in hierarchical P pictures) - H. Schwarz
//===== residual prediction =====
if( bInterEnable )
if( bBaseLayerAvailable )
{
//--- subtract (upsampled) base layer residual from original macroblock data ---
ROF( pcBaseLayerResidual );
cBaseLayerBuffer .loadBuffer ( const_cast<IntFrame*>(pcBaseLayerResidual)->getFullPelYuvBuffer() );
if( avcRewriteFlag || !cBaseLayerBuffer.isZero() ) // HS: search only with residual prediction, when residual signal is non-zero
{
if (!avcRewriteFlag)
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, rcMbDataAccess, true ) );
//-- JVT-R091
if ( !avcRewriteFlag && pcMbDataAccessBase->getMbData().getInCropWindowFlag() && rcMbDataAccess.isConstrainedInterLayerPred( ) && rcMbDataAccess.useSmoothedRef() )
RNOK( xEstimateMbSR ( m_pcIntMbTempData, m_pcIntMbBestData, rcRefFrameList0, rcRefFrameList1, pcBaseLayerResidual, pcMbDataAccessBase, true,
(IntFrame *)pcBaseLayerFrame) );
//--
}
if( rcMbDataAccess.getSH().getAdaptivePredictionFlag() )
{
//S051{
if(m_bUseBDir)
//S051}
RNOK( xEstimateMbDirect ( m_pcIntMbTempData, m_pcIntMbBestData, rcRefFrameList0, rcRefFrameList1, pcMbDataAccessBase, true, bSkipModeAllowed ) );
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 ---
if (!avcRewriteFlag)
m_pcIntOrgMbPelData->add ( cBaseLayerBuffer );
}
}
//===== intra base layer mode =====
if( bIntraEnable )
if( bBaseLayerAvailable )
{
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( bInterEnable )
if( ! bBaseLayerAvaila
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -