📄 mctf.cpp
字号:
*pcOrigFrame, *m_pcFrameTemp,
false, 4, 8, false, rcControlData.getLambda() ) );
}
return Err::m_nOK;
}
ErrVal
MCTF::xMotionCompensation( IntFrame* pcMCFrame,
RefFrameList* pcRefFrameList0,
RefFrameList* pcRefFrameList1,
MbDataCtrl* pcMbDataCtrl,
SliceHeader& rcSH )
{
RNOK( pcMbDataCtrl ->initSlice( rcSH, PRE_PROCESS, false, NULL ) );
RNOK( m_pcMotionEstimation->initSlice( rcSH ) );
for( UInt uiMbIndex = 0; uiMbIndex < m_uiMbNumber; uiMbIndex++ )
{
UInt uiMbY = uiMbIndex / m_uiFrameWidthInMb;
UInt uiMbX = uiMbIndex % m_uiFrameWidthInMb;
MbDataAccess* pcMbDataAccess = 0;
RNOK( pcMbDataCtrl ->initMb ( pcMbDataAccess, uiMbY, uiMbX ) );
RNOK( m_pcYuvFullPelBufferCtrl->initMb ( uiMbY, uiMbX ) );
RNOK( m_pcYuvHalfPelBufferCtrl->initMb ( uiMbY, uiMbX ) );
RNOK( m_pcMotionEstimation ->initMb ( uiMbY, uiMbX, *pcMbDataAccess ) );
RNOK( m_pcMbEncoder->compensatePrediction ( *pcMbDataAccess, pcMCFrame,
*pcRefFrameList0, *pcRefFrameList1,
false, false ) );
}
return Err::m_nOK;
}
ErrVal
MCTF::xGetConnections( Double& rdL0Rate,
Double& rdL1Rate,
Double& rdBiRate )
{
//=== just a guess ===
rdL0Rate = 0.2;
rdL1Rate = 0.2;
rdBiRate = 0.6;
return Err::m_nOK;
}
ErrVal
MCTF::xZeroIntraMacroblocks( IntFrame* pcFrame,
ControlData& rcCtrlData )
{
MbDataCtrl* pcMbDataCtrl = rcCtrlData.getMbDataCtrl ();
SliceHeader* pcSliceHeader = rcCtrlData.getSliceHeader ();
IntYuvPicBuffer* pcPicBuffer = pcFrame ->getFullPelYuvBuffer ();
RNOK( pcMbDataCtrl->initSlice( *pcSliceHeader, PRE_PROCESS, false, NULL ) );
IntYuvMbBuffer cZeroMbBuffer;
cZeroMbBuffer.setAllSamplesToZero();
for( UInt uiMbIndex = 0; uiMbIndex < m_uiMbNumber; uiMbIndex++ )
{
UInt uiMbY = uiMbIndex / m_uiFrameWidthInMb;
UInt uiMbX = uiMbIndex % m_uiFrameWidthInMb;
MbDataAccess* pcMbDataAccess = 0;
RNOK( pcMbDataCtrl ->initMb( pcMbDataAccess, uiMbY, uiMbX ) );
RNOK( m_pcYuvFullPelBufferCtrl->initMb( uiMbY, uiMbX ) );
if( pcMbDataAccess->getMbData().isIntra() )
{
pcPicBuffer->loadBuffer( &cZeroMbBuffer );
}
}
return Err::m_nOK;
}
ErrVal
MCTF::xInitGOP( PicBufferList& rcPicBufferInputList )
{
//========== INITIALIZE DECOMPOSITION STRUCTURES ==========
PicBufferList::iterator cInputIter = rcPicBufferInputList.begin();
UInt uiFrame = 0;
UInt uiOldGOPSize = m_uiGOPSize;
m_uiGOPSize = rcPicBufferInputList.size () - ( m_bFirstGOPCoded ? 0 : 1 );
if( m_bFirstGOPCoded )
{
m_papcFrame[ uiFrame++ ]->copyAll( m_papcFrame[ uiOldGOPSize ] );
}
for( ; uiFrame <= m_uiGOPSize; uiFrame++, cInputIter++ )
{
m_papcFrame[ uiFrame ]->load ( *cInputIter );
}
//========== INITIALIZE SLICE HEADERS (the decomposition structure is determined at this point) ==========
if( ! m_bFirstGOPCoded )
{
RNOK ( xInitSliceHeader( 0, 0 ) );
}
UInt uiTemporalLevel;
for( uiTemporalLevel = 0; uiTemporalLevel <= m_uiDecompositionStages; uiTemporalLevel++ )
{
UInt uiStep = ( 1 << ( m_uiDecompositionStages - uiTemporalLevel ) );
for( UInt uiFrameId = uiStep; uiFrameId <= m_uiGOPSize; uiFrameId += ( uiStep << 1 ) )
{
RNOK( xInitSliceHeader( uiTemporalLevel, uiFrameId ) );
}
}
//========== INITIALIZE SCALING FACTORS ==========
for( uiFrame = 0; uiFrame <= m_uiGOPSize; uiFrame++ )
{
m_pacControlData [ uiFrame ].clear();
m_pacControlData [ uiFrame ].setScalingFactor( 1.0 );
RNOK( m_pacControlData[ uiFrame ].getMbDataCtrl()->reset () );
RNOK( m_pacControlData[ uiFrame ].getMbDataCtrl()->clear () );
}
return Err::m_nOK;
}
ErrVal
MCTF::xGetListSizes( UInt uiTemporalLevel,
UInt uiFrameIdInGOP,
UInt auiPredListSize[2],
UInt aauiUpdListSize[MAX_DSTAGES][2] )
{
//----- clear update list sizes -----
::memset( aauiUpdListSize, 0x00, 2 * MAX_DSTAGES * sizeof( UInt ) );
//----- loop over prediction and update steps -----
for( UInt uiLevel = uiTemporalLevel; uiLevel <= m_uiDecompositionStages; uiLevel++ )
{
//----- get parameters base GOP size and cut-off frame id -----
UInt uiBaseLevel = m_uiDecompositionStages - uiLevel;
UInt uiFrameIdLevel = uiFrameIdInGOP >> uiBaseLevel;
UInt uiBaseGOPSize = ( 1 << m_uiDecompositionStages ) >> uiBaseLevel;
if( uiLevel == uiTemporalLevel )
{
//=========== PREDICTION LIST SIZES ==========
auiPredListSize[0] = ( uiFrameIdLevel + 1 ) >> 1;
UInt uiFrameIdWrap = ( uiFrameIdLevel % uiBaseGOPSize );
if( uiFrameIdWrap > 0 )
{
auiPredListSize[1] = ( uiBaseGOPSize - uiFrameIdWrap + 1 ) >> 1;
}
else
{
auiPredListSize[1] = ( uiFrameIdWrap + 1 ) >> 1;
}
auiPredListSize[0] = min( 1, auiPredListSize[0] );
auiPredListSize[1] = min( 1, auiPredListSize[1] );
UInt uiMaxL1Size = ( ( m_uiGOPSize >> uiBaseLevel ) + 1 - uiFrameIdLevel ) >> 1;
auiPredListSize[1] = min( uiMaxL1Size, auiPredListSize[1] );
}
else
{
//========== UPDATE LIST SIZES ==========
UInt* pauiUpdListSize = aauiUpdListSize[uiLevel-1];
UInt uiFrameIdWrap = ( uiFrameIdLevel == 0 ? 0 : ( ( uiFrameIdLevel - 1 ) % uiBaseGOPSize ) + 1 );
if( uiFrameIdWrap > 0 )
{
pauiUpdListSize[0] = uiFrameIdWrap >> 1;
pauiUpdListSize[1] = ( uiBaseGOPSize - uiFrameIdWrap ) >> 1;
}
else
{
pauiUpdListSize[0] = uiFrameIdWrap >> 1;
pauiUpdListSize[1] = ( uiFrameIdLevel == 0 ? 0 : ( 1 - uiFrameIdWrap ) >> 1 );
}
pauiUpdListSize[0] = min( 1, pauiUpdListSize[0] );
pauiUpdListSize[1] = min( 1, pauiUpdListSize[1] );
UInt uiMaxL1Size = ( ( m_uiGOPSize >> uiBaseLevel ) + 1 - uiFrameIdLevel ) >> 1;
pauiUpdListSize[1] = min( uiMaxL1Size, pauiUpdListSize[1] );
}
}
return Err::m_nOK;
}
ErrVal
MCTF::xInitSliceHeader( UInt uiTemporalLevel,
UInt uiFrameIdInGOP )
{
SliceHeader* pcSliceHeader = m_pacControlData[ uiFrameIdInGOP ].getSliceHeader();
ROF( pcSliceHeader );
//===== get maximum sizes of prediction and update lists ( decomposition structure ) =====
UInt auiPredListSize [2];
UInt aauiUpdListSize[MAX_DSTAGES][2];
RNOK( xGetListSizes( uiTemporalLevel, uiFrameIdInGOP, auiPredListSize, aauiUpdListSize ) );
//===== get slice header parameters =====
SliceType eSliceType = ( auiPredListSize[1] ? B_SLICE : auiPredListSize[0] ? P_SLICE : I_SLICE );
//===== set simple slice header parameters =====
pcSliceHeader->setNalUnitType ( NAL_UNIT_CODED_SLICE_SCALABLE );
pcSliceHeader->setFirstMbInSlice ( 0 );
pcSliceHeader->setLastMbInSlice ( m_uiMbNumber - 1 );
pcSliceHeader->setNumMbsInSlice ( m_uiMbNumber );
pcSliceHeader->setSliceType ( eSliceType );
pcSliceHeader->setDirectSpatialMvPredFlag ( true );
//===== set prediction and update list sizes =====
pcSliceHeader->setNumRefIdxActive( LIST_0, 0 );
pcSliceHeader->setNumRefIdxActive( LIST_1, 0 );
UInt uiMaxLists = ( eSliceType == B_SLICE ? 2 : eSliceType == P_SLICE ? 1 : 0 );
for( UInt uiList = 0; uiList < uiMaxLists; uiList++ )
{
ListIdx eListIdx = ListIdx( uiList );
ROF( auiPredListSize[ uiList ] );
pcSliceHeader->setNumRefIdxActive( eListIdx, auiPredListSize[ uiList ] );
if( pcSliceHeader->getPPS().getNumRefIdxActive( eListIdx ) != auiPredListSize[ uiList ] )
{
pcSliceHeader->setNumRefIdxActiveOverrideFlag( true );
}
}
for( UInt uiLevel = uiTemporalLevel; uiLevel < m_uiDecompositionStages; uiLevel++ )
{
pcSliceHeader->setNumRefIdxUpdate( uiLevel, LIST_0, aauiUpdListSize[uiLevel][0] );
pcSliceHeader->setNumRefIdxUpdate( uiLevel, LIST_1, aauiUpdListSize[uiLevel][1] );
}
//===== pred weights =====
RNOK( pcSliceHeader->getPredWeightTable(LIST_0).uninit() );
RNOK( pcSliceHeader->getPredWeightTable(LIST_1).uninit() );
RNOK( pcSliceHeader->getPredWeightTable(LIST_0).init( pcSliceHeader->getNumRefIdxActive( LIST_0) ) );
RNOK( pcSliceHeader->getPredWeightTable(LIST_1).init( pcSliceHeader->getNumRefIdxActive( LIST_1) ) );
RNOK( pcSliceHeader->getPredWeightTable(LIST_1).initDefaults( pcSliceHeader->getLumaLog2WeightDenom(), pcSliceHeader->getChromaLog2WeightDenom() ) );
RNOK( pcSliceHeader->getPredWeightTable(LIST_0).initDefaults( pcSliceHeader->getLumaLog2WeightDenom(), pcSliceHeader->getChromaLog2WeightDenom() ) );
return Err::m_nOK;
}
ErrVal
MCTF::xSetScalingFactors( UInt uiBaseLevel )
{
Double adRateL0 [( 1 << MAX_DSTAGES )];
Double adRateL1 [( 1 << MAX_DSTAGES )];
Double adRateBi [( 1 << MAX_DSTAGES )];
Double dScalingBase = m_pacControlData[0].getScalingFactor();
Double dScalingLowPass = 0.0;
Int iLowPassSize = ( m_uiGOPSize >> uiBaseLevel );
Int iFrame;
//===== get connection data =====
for( iFrame = 1; iFrame <= iLowPassSize; iFrame += 2 )
{
RNOK( xGetConnections( adRateL0[iFrame], adRateL1[iFrame], adRateBi[iFrame] ) );
}
//===== get low-pass scaling =====
for( iFrame = 0; iFrame <= iLowPassSize; iFrame += 2 )
{
Double dScalLPCurr = 1.0;
if( iFrame > 0 )
{
if( ( iFrame + 1 ) < iLowPassSize )
{
dScalLPCurr = ( adRateBi[iFrame-1] + adRateBi[iFrame+1] ) * ( FACTOR_53_LP - 1.0 ) / 2.0 +
( adRateL1[iFrame-1] + adRateL0[iFrame+1] ) * ( FACTOR_22_LP - 1.0 ) / 2.0 + 1.0;
}
else
{
dScalLPCurr = ( adRateBi[iFrame-1] / 2.0 ) * ( FACTOR_53_LP - 1.0 ) +
( adRateL1[iFrame-1] ) * ( FACTOR_22_LP - 1.0 ) + 1.0;
}
}
else
{
if( iLowPassSize )
{
dScalLPCurr = ( adRateBi[iFrame+1] / 2.0 ) * ( FACTOR_53_LP - 1.0 ) +
( adRateL0[iFrame+1] ) * ( FACTOR_22_LP - 1.0 ) + 1.0;
}
}
dScalingLowPass += dScalLPCurr;
}
dScalingLowPass /= (Double)( 1 + ( iLowPassSize >> 1 ) );
Double dFactor53 = FACTOR_53_HP;
Double dFactor22 = FACTOR_22_HP;
//===== get high-pass scaling and set scaling factors =====
for( iFrame = 0; iFrame <= iLowPassSize; iFrame++ )
{
Double dScal = dScalingBase;
if( iFrame % 2 )
{
dScal *= ( adRateBi[iFrame] ) * ( dFactor53 - 1.0 ) +
( adRateL0[iFrame] + adRateL1[iFrame] ) * ( dFactor22 - 1.0 ) + 1.0;
}
else
{
dScal *= dScalingLowPass;
}
m_pacControlData[ iFrame << uiBaseLevel ].setScalingFactor( dScal );
}
return Err::m_nOK;
}
ErrVal
MCTF::xClearBufferExtensions()
{
for( UInt uiFrame = 0; uiFrame <= m_uiGOPSize; uiFrame++ )
{
RNOK( m_papcFrame [uiFrame]->uninitHalfPel() );
RNOK( m_papcResidual[uiFrame]->uninitHalfPel() );
}
return Err::m_nOK;
}
ErrVal
MCTF::xGetPredictionLists( RefFrameList& rcRefList0,
RefFrameList& rcRefList1,
UInt uiBaseLevel,
UInt uiFrame,
Bool bHalfPel )
{
rcRefList0.reset();
rcRefList1.reset();
UInt uiFrameIdInGOP = ( uiFrame << uiBaseLevel );
SliceHeader* pcSliceHeader = m_pacControlData[uiFrameIdInGOP].getSliceHeader();
UInt uiList0Size = pcSliceHeader->getNumRefIdxActive( LIST_0 );
UInt uiList1Size = pcSliceHeader->getNumRefIdxActive( LIST_1 );
//===== list 0 =====
{
Int iFrameId;
for( iFrameId = Int( uiFrame - 1 ); iFrameId >= 0 && uiList0Size; iFrameId -= 2 )
{
IntFrame* pcFrame = m_papcFrame[ iFrameId << uiBaseLevel ];
if( ! pcFrame->isExtended() )
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -