📄 mbencoder.cpp
字号:
ErrVal
MbEncoder::xCheckSkipSliceMb( IntMbTempData& rcMbTempData )
{
ROFRS( rcMbTempData.getSH().getSliceSkipFlag(), Err::m_nOK );
//===== re-load prediction signal =====
rcMbTempData.loadLuma ( rcMbTempData.getTempYuvMbBuffer() );
rcMbTempData.loadChroma ( rcMbTempData.getTempYuvMbBuffer() );
//===== clear transform coefficients =====
rcMbTempData.MbTransformCoeffs::clear();
//===== adjust coeffs =====
Bool bBaseTransSize8x8 = rcMbTempData.getMbDataAccess().getMbDataAccessBase()->getMbData().isTransformSize8x8();
if( rcMbTempData.getMbDataAccess().isSCoeffPred() )
{
for( B8x8Idx c8x8Idx; c8x8Idx.isLegal(); c8x8Idx++ )
{
reCalcBlock8x8( rcMbTempData, c8x8Idx, ! bBaseTransSize8x8 );
}
reCalcChroma( rcMbTempData );
}
else if( rcMbTempData.getMbDataAccess().isTCoeffPred() )
{
for( B8x8Idx c8x8Idx; c8x8Idx.isLegal(); c8x8Idx++ )
{
RNOK( reCalcBlock8x8Rewrite( rcMbTempData, c8x8Idx, ! bBaseTransSize8x8 ) );
}
RNOK( reCalcChromaRewrite( rcMbTempData ) );
}
//===== clear parameters =====
rcMbTempData.cbp () = 0;
rcMbTempData.bits () = 0;
rcMbTempData.coeffCost() = 0;
return Err::m_nOK;
}
ErrVal
MbEncoder::xCheckSkipSliceMbIntra4( IntMbTempData& rcMbTempData, LumaIdx c4x4Idx, UInt& ruiAbsSum )
{
ROFRS( rcMbTempData.getSH().getSliceSkipFlag(), Err::m_nOK );
//===== re-load prediction signal of 4x4 block =====
rcMbTempData.loadLuma( rcMbTempData.getTempYuvMbBuffer(), c4x4Idx );
//===== clear transform coefficients =====
rcMbTempData.MbTransformCoeffs::clearLumaLevels4x4( c4x4Idx );
//===== set base layer QP (see G.8.1.5.1.2) =====
UChar ucQp = rcMbTempData.getQp();
UChar ucBaseQp = rcMbTempData.getMbDataAccess().getMbDataAccessBase()->getMbData().getQp();
rcMbTempData .setQp( ucBaseQp );
m_pcTransform->setQp( rcMbTempData, rcMbTempData.getSH().isIntraSlice() );
//===== adjust coeffs =====
RNOK( reCalcBlock4x4Rewrite( rcMbTempData, c4x4Idx ) );
//===== restore QP (will be adjusted later) =====
rcMbTempData .setQp( ucQp );
m_pcTransform->setQp( rcMbTempData, rcMbTempData.getSH().isIntraSlice() );
//===== clear parameters =====
ruiAbsSum = 0;
return Err::m_nOK;
}
ErrVal
MbEncoder::xCheckSkipSliceMbIntra8( IntMbTempData& rcMbTempData, B8x8Idx c8x8Idx, UInt& ruiAbsSum )
{
ROFRS( rcMbTempData.getSH().getSliceSkipFlag(), Err::m_nOK );
//===== re-load prediction signal of 8x8 block =====
rcMbTempData.loadLuma( rcMbTempData.getTempYuvMbBuffer(), c8x8Idx );
//===== clear transform coefficients =====
rcMbTempData.MbTransformCoeffs::clearLumaLevels8x8Block( c8x8Idx );
//===== set base layer QP (see G.8.1.5.1.2) =====
UChar ucQp = rcMbTempData.getQp();
UChar ucBaseQp = rcMbTempData.getMbDataAccess().getMbDataAccessBase()->getMbData().getQp();
rcMbTempData .setQp( ucBaseQp );
m_pcTransform->setQp( rcMbTempData, rcMbTempData.getSH().isIntraSlice() );
//===== adjust coeffs =====
RNOK( reCalcBlock8x8Rewrite( rcMbTempData, c8x8Idx, false ) );
//===== restore QP (will be adjusted later) =====
rcMbTempData .setQp( ucQp );
m_pcTransform->setQp( rcMbTempData, rcMbTempData.getSH().isIntraSlice() );
//===== clear parameters =====
ruiAbsSum = 0;
return Err::m_nOK;
}
ErrVal
MbEncoder::xCheckSkipSliceMbIntra16( IntMbTempData& rcMbTempData, UInt& ruiAcAbs )
{
ROFRS( rcMbTempData.getSH().getSliceSkipFlag(), Err::m_nOK );
//===== re-load luma prediction signal =====
rcMbTempData.loadLuma( rcMbTempData.getTempYuvMbBuffer() );
//===== clear transform coefficients =====
rcMbTempData.MbTransformCoeffs::clearLumaLevels();
//===== set base layer QP (see G.8.1.5.1.2) =====
UChar ucQp = rcMbTempData.getQp();
UChar ucBaseQp = rcMbTempData.getMbDataAccess().getMbDataAccessBase()->getMbData().getQp();
rcMbTempData .setQp( ucBaseQp );
m_pcTransform->setQp( rcMbTempData, rcMbTempData.getSH().isIntraSlice() );
//===== adjust coeffs =====
RNOK( reCalcBlock16x16Rewrite( rcMbTempData ) );
//===== restore QP (will be adjusted later) =====
rcMbTempData .setQp( ucQp );
m_pcTransform->setQp( rcMbTempData, rcMbTempData.getSH().isIntraSlice() );
//===== clear parameters =====
ruiAcAbs = 0;
return Err::m_nOK;
}
ErrVal
MbEncoder::xCheckSkipSliceMbIntraChroma( IntMbTempData& rcMbTempData, UInt& ruiChromaCbp )
{
ROFRS( rcMbTempData.getSH().getSliceSkipFlag(), Err::m_nOK );
ROF ( rcMbTempData.getMbDataAccess().isTCoeffPred() );
ROF ( rcMbTempData.isIntraBL() );
//===== re-load prediction signal of chroma block =====
rcMbTempData.loadChroma( rcMbTempData.getTempYuvMbBuffer() );
//===== clear transform coefficients =====
rcMbTempData.MbTransformCoeffs::clearChromaLevels();
//===== set base layer QP (see G.8.1.5.1.2) =====
UChar ucQp = rcMbTempData.getQp();
UChar ucBaseQp = rcMbTempData.getMbDataAccess().getMbDataAccessBase()->getMbData().getQp();
rcMbTempData .setQp( ucBaseQp );
m_pcTransform->setQp( rcMbTempData, rcMbTempData.getSH().isIntraSlice() );
//===== adjust coeffs =====
RNOK( reCalcChromaRewrite( rcMbTempData ) );
//===== restore QP (will be adjusted later) =====
rcMbTempData .setQp( ucQp );
m_pcTransform->setQp( rcMbTempData, rcMbTempData.getSH().isIntraSlice() );
//===== clear parameters =====
ruiChromaCbp = 0;
return Err::m_nOK;
}
ErrVal
MbEncoder::xAdjustRewriteReconstruction( IntMbTempData& rcMbTempData )
{
ROT ( rcMbTempData.isIntra() ); // do not call this function for intra blocks !!!
ROTRS ( rcMbTempData.getSH().getNoInterLayerPredFlag(), Err::m_nOK );
ROFRS ( rcMbTempData.getSH().getTCoeffLevelPredictionFlag(), Err::m_nOK );
ROTRS ( rcMbTempData.getMbCbp(), Err::m_nOK );
ROFRS ( rcMbTempData.getResidualPredFlag(), Err::m_nOK );
//===== reload prediction signal =====
rcMbTempData.loadLuma ( rcMbTempData.getTempYuvMbBuffer() );
rcMbTempData.loadChroma ( rcMbTempData.getTempYuvMbBuffer() );
//===== set base layer QP (see G.8.1.5.1.2) =====
UChar ucQp = rcMbTempData.getQp();
UChar ucBaseQp = rcMbTempData.getMbDataAccess().getMbDataAccessBase()->getMbData().getQp();
Bool bBase8x8 = rcMbTempData.getMbDataAccess().getMbDataAccessBase()->getMbData().isTransformSize8x8();
rcMbTempData .setQp( ucBaseQp );
m_pcTransform->setQp( rcMbTempData, rcMbTempData.getSH().isIntraSlice() );
//===== recalc signal =====
for( B8x8Idx c8x8Idx; c8x8Idx.isLegal(); c8x8Idx++ )
{
RNOK( reCalcBlock8x8Rewrite( rcMbTempData, c8x8Idx, !bBase8x8 ) );
}
RNOK( reCalcChromaRewrite( rcMbTempData ) );
//===== restore QP (will be adjusted later) =====
rcMbTempData .setQp( ucQp );
m_pcTransform->setQp( rcMbTempData, rcMbTempData.getSH().isIntraSlice() );
return Err::m_nOK;
}
ErrVal
MbEncoder::estimatePrediction( MbDataAccess& rcMbDataAccess,
MbDataAccess* pcMbDataAccessBase,
RefFrameList& rcRefFrameList0,
RefFrameList& rcRefFrameList1,
const Frame* pcBaseLayerFrame,
const Frame* pcBaseLayerResidual,
const Frame& rcOrigFrame,
Frame& 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().getSliceQp ();
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();
YuvPicBuffer* pcOrgPicBuffer = const_cast<Frame&>( rcOrigFrame ).getFullPelYuvBuffer();
m_pcXDistortion->loadOrgMbPelData ( pcOrgPicBuffer, m_pcIntOrgMbPelData );
m_pcTransform ->setQp ( rcMbDataAccess, false );
YuvMbBuffer cBaseLayerBuffer;
ROT( !rcMbDataAccess.getSH().getNoInterLayerPredFlag() && ! pcMbDataAccessBase );
Bool bIsEnhLayer = ! rcMbDataAccess.getSH().getNoInterLayerPredFlag();
Bool bInCropWindow = ( bIsEnhLayer && pcMbDataAccessBase->getMbData().getInCropWindowFlag() );
pcMbDataAccessBase = ( bInCropWindow ? pcMbDataAccessBase : 0 );
Bool bIntraEnable = ! rcMbDataAccess.isFieldMbInMbaffFrame() || rcMbDataAccess.isTopMb() || rcMbDataAccess.getMbDataComplementary().isIntra();
Bool bInterEnable = ! rcMbDataAccess.isFieldMbInMbaffFrame() || rcMbDataAccess.isTopMb() || ! rcMbDataAccess.getMbDataComplementary().isIntra();
if( rcMbDataAccess.isFieldMbInMbaffFrame() && rcMbDataAccess.getMbPicType() == BOT_FIELD && rcMbDataAccess.getMbDataComplementary().isIntra() && bInCropWindow )
{
if( ! pcMbDataAccessBase->getMbData().isIntra() || ! pcMbDataAccessBase->getMbDataComplementary().isIntra() )
{
bInterEnable = true;
}
}
Bool avcRewriteFlag = rcMbDataAccess.getSH().getTCoeffLevelPredictionFlag();
Bool coeffResidualPredFlag = rcMbDataAccess.getCoeffResidualPredFlag();
Bool bDefaultResPredFlag = false;
if( rcMbDataAccess.getSH().getPPS().getEntropyCodingModeFlag() &&
!rcMbDataAccess.getSH().getNoInterLayerPredFlag() &&
rcMbDataAccess.getMbDataAccessBase()->getMbData().getInCropWindowFlag() &&
!rcMbDataAccess.getMbDataAccessBase()->getMbData().isIntra() )
{
ROF( pcBaseLayerResidual );
cBaseLayerBuffer.loadBuffer ( const_cast<Frame*>(pcBaseLayerResidual)->getFullPelYuvBuffer() );
if (!avcRewriteFlag && !coeffResidualPredFlag)
bDefaultResPredFlag = cBaseLayerBuffer.isZero();
}
//===== P_SKIP ====
if( bSkipModeAllowed && ! bBSlice )
{
RNOK( xEstimateMbSkip( m_pcIntMbTempData, m_pcIntMbBestData, rcRefFrameList0, rcRefFrameList1 ) );
}
//===== inter modes with residual prediction =====
if( bInCropWindow && bInterEnable )
{
//--- subtract (upsampled) base layer residual from original macroblock data ---
ROF( pcBaseLayerResidual );
if( avcRewriteFlag )
{
cBaseLayerBuffer.setAllSamplesToZero();
}
else if( coeffResidualPredFlag )
{
pcMbDataAccessBase->getMbTCoeffs().copyPredictionTo( cBaseLayerBuffer );
}
else
{
cBaseLayerBuffer.loadBuffer( const_cast<Frame*>(pcBaseLayerResidual)->getFullPelYuvBuffer() );
}
if( avcRewriteFlag || coeffResidualPredFlag || !cBaseLayerBuffer.isZero() ) // HS: search only with residual prediction, when residual signal is non-zero
{
m_pcIntOrgMbPelData->subtract ( cBaseLayerBuffer );
if( ! pcMbDataAccessBase->getMbData().isIntra() && bBLSkipEnable )
{
RNOK( xEstimateMbBLSkip( m_pcIntMbTempData, m_pcIntMbBestData, rcRefFrameList0, rcRefFrameList1, pcBaseLayerFrame, bBSlice, pcMbDataAccessBase, rcMbDataAccess, true ) );
}
if( rcMbDataAccess.getSH().getAdaptiveBaseModeFlag() )
{
if( m_bUseBDir )
{
RNOK( xEstimateMbDirect ( m_pcIntMbTempData, m_pcIntMbBestData, rcRefFrameList0, rcRefFrameList1, pcMbDataAccessBase, true, rcMbDataAccess.getMbData().getQp(), 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 ---
m_pcIntOrgMbPelData->add( cBaseLayerBuffer );
}
}
//===== intra base layer mode =====
if( bInCropWindow && bIntraEnable && pcMbDataAccessBase->getMbData().isIntra() )
{
RNOK( xEstimateMbIntraBL( rcMbDataAccess, m_pcIntMbTempData, m_pcIntMbBestData, pcBaseLayerFrame, bBSlice, pcMbDataAccessBase ) );
}
//===== inter modes without residual prediction =====
if( bInter
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -